From 32831edf2514ad04f3962a32d706e600f51c8ce7 Mon Sep 17 00:00:00 2001 From: PiotrParysek Date: Fri, 9 Jun 2017 14:13:44 +0200 Subject: [PATCH] =?UTF-8?q?Usprawnienia=20t=C5=82umacze=C5=84,=20poprawne?= =?UTF-8?q?=20wykonanie=20plik=C3=B3w=20zip=20plugin=C3=B3w,=20usuni=C4=99?= =?UTF-8?q?cie=20niewykorzystywanego=20pluginu=20client-portal,=20aktualiz?= =?UTF-8?q?acja=20profile-bulder?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client-portal.1.0.4.zip | Bin 293883 -> 0 bytes .../assets/logo_landing_pb_2x_red.png | Bin 4662 -> 0 bytes client-portal/assets/style.css | 26 - client-portal/index.php | 555 - client-portal/readme.txt | 57 - client-portal/screenshot-1.png | Bin 161977 -> 0 bytes client-portal/screenshot-2.png | Bin 75060 -> 0 bytes client-portal/screenshot-3.png | Bin 66754 -> 0 bytes dk-pdf.1.9.zip => dk-pdf.zip | Bin 10217340 -> 10242687 bytes ...e-builder.2.6.3.zip => profile-builder.zip | Bin 3480761 -> 3490258 bytes profile-builder/admin/add-ons.php | 735 +- profile-builder/admin/admin-bar.php | 240 +- profile-builder/admin/admin-functions.php | 416 +- profile-builder/admin/basic-info.php | 389 +- profile-builder/admin/general-settings.php | 580 +- profile-builder/admin/manage-fields.php | 2762 ++-- profile-builder/admin/pms-cross-promotion.php | 486 +- profile-builder/admin/register-version.php | 502 +- profile-builder/assets/css/rtl.css | 118 +- .../assets/css/select2/select2.min.css | 2 +- profile-builder/assets/css/serial-notice.css | 88 +- profile-builder/assets/css/style-back-end.css | 1292 +- .../assets/css/style-front-end.css | 1548 +- .../assets/js/jquery-edit-profile.js | 30 +- .../assets/js/jquery-email-confirmation.js | 104 +- profile-builder/assets/js/jquery-epf-rf.js | 330 +- .../js/jquery-manage-fields-live-change.js | 1480 +- .../assets/js/jquery-pb-add-ons.js | 472 +- .../assets/js/jquery-pb-sitewide.js | 266 +- profile-builder/assets/js/select2/i18n/ar.js | 4 +- profile-builder/assets/js/select2/i18n/az.js | 4 +- profile-builder/assets/js/select2/i18n/bg.js | 4 +- profile-builder/assets/js/select2/i18n/ca.js | 4 +- profile-builder/assets/js/select2/i18n/cs.js | 4 +- profile-builder/assets/js/select2/i18n/da.js | 4 +- profile-builder/assets/js/select2/i18n/de.js | 4 +- profile-builder/assets/js/select2/i18n/el.js | 4 +- profile-builder/assets/js/select2/i18n/en.js | 4 +- profile-builder/assets/js/select2/i18n/es.js | 4 +- profile-builder/assets/js/select2/i18n/et.js | 4 +- profile-builder/assets/js/select2/i18n/eu.js | 4 +- profile-builder/assets/js/select2/i18n/fa.js | 4 +- profile-builder/assets/js/select2/i18n/fi.js | 4 +- profile-builder/assets/js/select2/i18n/fr.js | 4 +- profile-builder/assets/js/select2/i18n/gl.js | 4 +- profile-builder/assets/js/select2/i18n/he.js | 4 +- profile-builder/assets/js/select2/i18n/hi.js | 4 +- profile-builder/assets/js/select2/i18n/hr.js | 4 +- profile-builder/assets/js/select2/i18n/hu.js | 4 +- profile-builder/assets/js/select2/i18n/id.js | 4 +- profile-builder/assets/js/select2/i18n/is.js | 4 +- profile-builder/assets/js/select2/i18n/it.js | 4 +- profile-builder/assets/js/select2/i18n/ja.js | 4 +- profile-builder/assets/js/select2/i18n/km.js | 4 +- profile-builder/assets/js/select2/i18n/ko.js | 4 +- profile-builder/assets/js/select2/i18n/lt.js | 4 +- profile-builder/assets/js/select2/i18n/lv.js | 4 +- profile-builder/assets/js/select2/i18n/mk.js | 4 +- profile-builder/assets/js/select2/i18n/ms.js | 4 +- profile-builder/assets/js/select2/i18n/nb.js | 4 +- profile-builder/assets/js/select2/i18n/nl.js | 4 +- profile-builder/assets/js/select2/i18n/pl.js | 4 +- .../assets/js/select2/i18n/pt-BR.js | 4 +- profile-builder/assets/js/select2/i18n/pt.js | 4 +- profile-builder/assets/js/select2/i18n/ro.js | 4 +- profile-builder/assets/js/select2/i18n/ru.js | 4 +- profile-builder/assets/js/select2/i18n/sk.js | 4 +- .../assets/js/select2/i18n/sr-Cyrl.js | 4 +- profile-builder/assets/js/select2/i18n/sr.js | 4 +- profile-builder/assets/js/select2/i18n/sv.js | 4 +- profile-builder/assets/js/select2/i18n/th.js | 4 +- profile-builder/assets/js/select2/i18n/tr.js | 4 +- profile-builder/assets/js/select2/i18n/uk.js | 4 +- profile-builder/assets/js/select2/i18n/vi.js | 4 +- .../assets/js/select2/i18n/zh-CN.js | 4 +- .../assets/js/select2/i18n/zh-TW.js | 4 +- .../assets/js/select2/select2.min.js | 4 +- .../assets/lib/Mustache/Autoloader.php | 150 +- .../assets/lib/Mustache/Compiler.php | 952 +- .../assets/lib/Mustache/Context.php | 298 +- .../assets/lib/Mustache/Engine.php | 1496 +- .../assets/lib/Mustache/Exception.php | 36 +- .../Exception/InvalidArgumentException.php | 36 +- .../lib/Mustache/Exception/LogicException.php | 36 +- .../Mustache/Exception/RuntimeException.php | 36 +- .../Mustache/Exception/SyntaxException.php | 58 +- .../Exception/UnknownFilterException.php | 58 +- .../Exception/UnknownHelperException.php | 58 +- .../Exception/UnknownTemplateException.php | 58 +- .../assets/lib/Mustache/HelperCollection.php | 340 +- .../assets/lib/Mustache/LambdaHelper.php | 98 +- .../assets/lib/Mustache/Loader.php | 56 +- .../lib/Mustache/Loader/ArrayLoader.php | 156 +- .../lib/Mustache/Loader/CascadingLoader.php | 138 +- .../lib/Mustache/Loader/FilesystemLoader.php | 248 +- .../lib/Mustache/Loader/InlineLoader.php | 246 +- .../lib/Mustache/Loader/MutableLoader.php | 64 +- .../lib/Mustache/Loader/StringLoader.php | 80 +- .../assets/lib/Mustache/Logger.php | 270 +- .../lib/Mustache/Logger/AbstractLogger.php | 242 +- .../lib/Mustache/Logger/StreamLogger.php | 386 +- .../assets/lib/Mustache/Parser.php | 388 +- .../assets/lib/Mustache/Template.php | 354 +- .../assets/lib/Mustache/Tokenizer.php | 556 +- profile-builder/assets/lib/class_notices.php | 126 +- profile-builder/assets/lib/codemirror/LICENSE | 38 +- .../assets/lib/codemirror/README.md | 22 +- .../lib/codemirror/addon/comment/comment.js | 290 +- .../addon/comment/continuecomment.js | 108 +- .../lib/codemirror/addon/dialog/dialog.css | 64 +- .../lib/codemirror/addon/dialog/dialog.js | 160 +- .../codemirror/addon/display/fullscreen.css | 12 +- .../codemirror/addon/display/fullscreen.js | 60 +- .../codemirror/addon/display/placeholder.js | 108 +- .../codemirror/addon/edit/closebrackets.js | 164 +- .../lib/codemirror/addon/edit/closetag.js | 174 +- .../lib/codemirror/addon/edit/continuelist.js | 50 +- .../codemirror/addon/edit/matchbrackets.js | 172 +- .../lib/codemirror/addon/edit/matchtags.js | 112 +- .../codemirror/addon/edit/trailingspace.js | 30 +- .../lib/codemirror/addon/fold/brace-fold.js | 186 +- .../lib/codemirror/addon/fold/comment-fold.js | 80 +- .../lib/codemirror/addon/fold/foldcode.js | 146 +- .../lib/codemirror/addon/fold/foldgutter.js | 244 +- .../lib/codemirror/addon/fold/indent-fold.js | 24 +- .../lib/codemirror/addon/fold/xml-fold.js | 334 +- .../lib/codemirror/addon/hint/anyword-hint.js | 68 +- .../lib/codemirror/addon/hint/css-hint.js | 100 +- .../lib/codemirror/addon/hint/html-hint.js | 674 +- .../codemirror/addon/hint/javascript-hint.js | 292 +- .../lib/codemirror/addon/hint/pig-hint.js | 238 +- .../lib/codemirror/addon/hint/python-hint.js | 190 +- .../lib/codemirror/addon/hint/show-hint.css | 76 +- .../lib/codemirror/addon/hint/show-hint.js | 548 +- .../lib/codemirror/addon/hint/xml-hint.js | 136 +- .../addon/lint/coffeescript-lint.js | 50 +- .../lib/codemirror/addon/lint/css-lint.js | 34 +- .../codemirror/addon/lint/javascript-lint.js | 248 +- .../lib/codemirror/addon/lint/json-lint.js | 30 +- .../assets/lib/codemirror/addon/lint/lint.css | 144 +- .../assets/lib/codemirror/addon/lint/lint.js | 406 +- .../addon/merge/dep/diff_match_patch.js | 100 +- .../lib/codemirror/addon/merge/merge.css | 184 +- .../lib/codemirror/addon/merge/merge.js | 946 +- .../lib/codemirror/addon/mode/loadmode.js | 102 +- .../lib/codemirror/addon/mode/multiplex.js | 202 +- .../codemirror/addon/mode/multiplex_test.js | 60 +- .../lib/codemirror/addon/mode/overlay.js | 118 +- .../lib/codemirror/addon/runmode/colorize.js | 58 +- .../addon/runmode/runmode-standalone.js | 264 +- .../lib/codemirror/addon/runmode/runmode.js | 112 +- .../codemirror/addon/runmode/runmode.node.js | 206 +- .../codemirror/addon/scroll/scrollpastend.js | 68 +- .../addon/search/match-highlighter.js | 182 +- .../lib/codemirror/addon/search/search.js | 262 +- .../codemirror/addon/search/searchcursor.js | 286 +- .../codemirror/addon/selection/active-line.js | 78 +- .../addon/selection/mark-selection.js | 216 +- .../assets/lib/codemirror/addon/tern/tern.css | 170 +- .../assets/lib/codemirror/addon/tern/tern.js | 1262 +- .../lib/codemirror/addon/tern/worker.js | 78 +- .../assets/lib/codemirror/lib/codemirror.css | 546 +- .../assets/lib/codemirror/lib/codemirror.js | 11774 ++++++++-------- .../assets/lib/codemirror/mode/css/css.js | 1254 +- .../assets/lib/codemirror/mode/css/index.html | 140 +- .../assets/lib/codemirror/mode/css/scss.html | 314 +- .../lib/codemirror/mode/css/scss_test.js | 160 +- .../assets/lib/codemirror/mode/css/test.js | 252 +- .../mode/htmlembedded/htmlembedded.js | 146 +- .../codemirror/mode/htmlembedded/index.html | 120 +- .../codemirror/mode/htmlmixed/htmlmixed.js | 208 +- .../lib/codemirror/mode/htmlmixed/index.html | 170 +- .../assets/lib/codemirror/mode/http/http.js | 196 +- .../lib/codemirror/mode/http/index.html | 90 +- .../assets/lib/codemirror/mode/index.html | 220 +- .../lib/codemirror/mode/javascript/index.html | 214 +- .../codemirror/mode/javascript/javascript.js | 960 +- .../lib/codemirror/mode/javascript/test.js | 20 +- .../mode/javascript/typescript.html | 122 +- .../assets/lib/codemirror/mode/meta.js | 174 +- .../assets/lib/codemirror/mode/php/index.html | 124 +- .../assets/lib/codemirror/mode/php/php.js | 264 +- .../assets/lib/codemirror/mode/xml/index.html | 114 +- .../assets/lib/codemirror/mode/xml/xml.js | 682 +- .../wck-api/assets/country/country-select.php | 400 +- .../wck-api/assets/datepicker/datepicker.css | 1298 +- .../wck-api/assets/js/tiny_mce/license.txt | 1008 +- .../directionality/editor_plugin_src.js | 162 +- .../plugins/fullscreen/editor_plugin_src.js | 316 +- .../plugins/fullscreen/fullscreen.htm | 220 +- .../plugins/inlinepopups/editor_plugin_src.js | 1398 +- .../inlinepopups/skins/clearlooks2/window.css | 180 +- .../plugins/inlinepopups/template.htm | 774 +- .../js/tiny_mce/plugins/media/css/media.css | 34 +- .../plugins/media/editor_plugin_src.js | 1796 +-- .../js/tiny_mce/plugins/media/js/embed.js | 146 +- .../js/tiny_mce/plugins/media/js/media.js | 940 +- .../js/tiny_mce/plugins/media/langs/en_dlg.js | 2 +- .../js/tiny_mce/plugins/media/media.htm | 1844 +-- .../plugins/paste/editor_plugin_src.js | 1742 +-- .../js/tiny_mce/plugins/paste/js/pastetext.js | 72 +- .../js/tiny_mce/plugins/paste/js/pasteword.js | 102 +- .../js/tiny_mce/plugins/paste/pastetext.htm | 52 +- .../js/tiny_mce/plugins/paste/pasteword.htm | 42 +- .../plugins/spellchecker/css/content.css | 2 +- .../plugins/spellchecker/editor_plugin_src.js | 872 +- .../plugins/tabfocus/editor_plugin_src.js | 244 +- .../plugins/wordcount/editor_plugin_src.js | 244 +- .../js/tiny_mce/themes/advanced/about.htm | 104 +- .../js/tiny_mce/themes/advanced/anchor.htm | 52 +- .../js/tiny_mce/themes/advanced/charmap.htm | 110 +- .../tiny_mce/themes/advanced/color_picker.htm | 140 +- .../themes/advanced/editor_template_src.js | 2974 ++-- .../js/tiny_mce/themes/advanced/image.htm | 160 +- .../js/tiny_mce/themes/advanced/js/about.js | 146 +- .../js/tiny_mce/themes/advanced/js/anchor.js | 112 +- .../js/tiny_mce/themes/advanced/js/charmap.js | 726 +- .../themes/advanced/js/color_picker.js | 690 +- .../js/tiny_mce/themes/advanced/js/image.js | 506 +- .../js/tiny_mce/themes/advanced/js/link.js | 318 +- .../themes/advanced/js/source_editor.js | 156 +- .../tiny_mce/themes/advanced/langs/en_dlg.js | 2 +- .../js/tiny_mce/themes/advanced/link.htm | 114 +- .../js/tiny_mce/themes/advanced/shortcuts.htm | 94 +- .../themes/advanced/skins/default/content.css | 100 +- .../themes/advanced/skins/default/dialog.css | 236 +- .../themes/advanced/skins/default/ui.css | 438 +- .../advanced/skins/wp_theme/content.css | 288 +- .../themes/advanced/skins/wp_theme/dialog.css | 242 +- .../themes/advanced/skins/wp_theme/ui.css | 2 +- .../themes/advanced/source_editor.htm | 50 +- .../assets/js/tiny_mce/tiny_mce_popup.js | 8 +- .../js/tiny_mce/utils/editable_selects.js | 140 +- .../assets/js/tiny_mce/utils/form_utils.js | 420 +- .../assets/js/tiny_mce/utils/mctabs.js | 322 +- .../assets/js/tiny_mce/utils/validate.js | 504 +- .../assets/js/tiny_mce/wck_tiny_mce_init.js | 50 +- .../assets/lib/wck-api/fields/checkbox.php | 106 +- .../lib/wck-api/fields/country select.php | 40 +- .../assets/lib/wck-api/fields/cpt select.php | 50 +- .../assets/lib/wck-api/fields/datepicker.php | 24 +- .../lib/wck-api/fields/nested repeater.php | 16 +- .../assets/lib/wck-api/fields/radio.php | 88 +- .../assets/lib/wck-api/fields/select.php | 100 +- .../assets/lib/wck-api/fields/text.php | 30 +- .../assets/lib/wck-api/fields/textarea.php | 22 +- .../assets/lib/wck-api/fields/upload.js | 260 +- .../assets/lib/wck-api/fields/upload.php | 150 +- .../assets/lib/wck-api/fields/user select.php | 40 +- .../lib/wck-api/fields/wysiwyg editor.php | 18 +- profile-builder/assets/lib/wck-api/readme.txt | 268 +- .../lib/wck-api/wordpress-creation-kit.css | 544 +- .../lib/wck-api/wordpress-creation-kit.js | 806 +- .../lib/wck-api/wordpress-creation-kit.php | 2932 ++-- profile-builder/assets/misc/fallback-page.php | 56 +- .../assets/misc/plugin-compatibilities.php | 617 +- profile-builder/features/class-list-table.php | 1934 +-- .../class-email-confirmation.php | 934 +- .../email-confirmation/email-confirmation.php | 1359 +- profile-builder/features/functions.php | 2019 ++- .../features/login-widget/login-widget.php | 192 +- .../roles-editor/assets/css/roles-editor.css | 960 +- .../roles-editor/assets/font/wppb_re_font.svg | 34 +- .../roles-editor/assets/js/roles-editor.js | 1020 +- .../features/roles-editor/roles-editor.php | 2106 +-- .../features/upgrades/upgrades-functions.php | 1280 +- .../features/upgrades/upgrades.php | 152 +- .../front-end/class-formbuilder.php | 1424 +- .../front-end/default-fields/aim/aim.php | 108 +- .../blog-details/blog-details.php | 462 +- .../default-fields/default-fields.php | 88 +- .../description/description.php | 110 +- .../display-name/display-name.php | 158 +- .../front-end/default-fields/email/email.php | 224 +- .../default-fields/first-name/first-name.php | 110 +- .../headings/about-yourself.php | 22 +- .../default-fields/headings/contact-info.php | 24 +- .../default-fields/headings/name.php | 22 +- .../default-fields/jabber/jabber.php | 108 +- .../default-fields/last-name/last-name.php | 108 +- .../default-fields/nickname/nickname.php | 106 +- .../password-repeat/password-repeat.php | 90 +- .../default-fields/password/password.php | 128 +- .../default-fields/recaptcha/recaptcha.php | 954 +- .../default-fields/user-role/user-role.php | 272 +- .../default-fields/username/username.php | 162 +- .../default-fields/website/website.php | 110 +- .../front-end/default-fields/yim/yim.php | 108 +- profile-builder/front-end/edit-profile.php | 146 +- profile-builder/front-end/login.php | 602 +- profile-builder/front-end/logout.php | 64 +- profile-builder/front-end/recover.php | 788 +- profile-builder/front-end/register.php | 390 +- profile-builder/index.php | 4 +- profile-builder/readme.txt | 6 +- .../translation/profile-builder-pl_PL.mo | Bin 42609 -> 43856 bytes .../translation/profile-builder-pl_PL.po | 219 +- .../translation/profile-builder.pot | 11718 +++++++-------- profile-builder/wpml-config.xml | 48 +- questions.zip | Bin 786289 -> 791914 bytes user-private-files-pl_PL.mo | Bin 2197 -> 0 bytes user-private-files-pl_PL.po | 117 - user-private-files.zip | Bin 7508 -> 188 bytes user-private-files/user-private-files.php | 4 +- 304 files changed, 54129 insertions(+), 54846 deletions(-) delete mode 100644 client-portal.1.0.4.zip delete mode 100644 client-portal/assets/logo_landing_pb_2x_red.png delete mode 100644 client-portal/assets/style.css delete mode 100644 client-portal/index.php delete mode 100644 client-portal/readme.txt delete mode 100644 client-portal/screenshot-1.png delete mode 100644 client-portal/screenshot-2.png delete mode 100644 client-portal/screenshot-3.png rename dk-pdf.1.9.zip => dk-pdf.zip (97%) rename profile-builder.2.6.3.zip => profile-builder.zip (90%) delete mode 100644 user-private-files-pl_PL.mo delete mode 100644 user-private-files-pl_PL.po diff --git a/client-portal.1.0.4.zip b/client-portal.1.0.4.zip deleted file mode 100644 index 5b910879d155adc1a41ada01e9a6f315eb85958f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 293883 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%0AwSag-?NKhTj6XxGD`s_UQamp0yHDh!A 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

U^-XSAMO#0@NK(o5s2HS<*Ala)H?FY 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%0D?HyhGf9I5&c}0t3a7 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

  • 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%0A5k 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 = 'cp-options'; - $this->options = get_option( $this->slug ); - $this->defaults = array( - 'page-slug' => 'private-page', - 'support-comments' => 'no', - 'restricted-message' => __( 'You do not have permission to view this page.', 'client-portal' ), - 'portal-log-in-message' => __( 'Please log in in order to access the client portal.', 'client-portal' ), - 'default-page-content' => '' - ); - - /* register the post type */ - add_action( 'init', array( $this, 'cp_create_post_type' ) ); - /* action to create a private page when a user registers */ - add_action( 'user_register', array( $this, 'cp_create_private_page' ) ); - /* remove the page when a user is deleted */ - add_action( 'deleted_user', array( $this, 'cp_delete_private_page' ), 10, 2 ); - /* restrict the content of the page only to the user */ - add_filter( 'the_content', array( $this, 'cp_restrict_content' ) ); - /* add a link in the Users List Table in admin area to access the page */ - add_filter( 'user_row_actions', array( $this, 'cp_add_link_to_private_page' ), 10, 2); - - /* add bulk action to create private user pages */ - add_filter( 'admin_footer-users.php', array( $this, 'cp_create_private_page_bulk_actions' ) ); - add_action( 'admin_action_create_private_page', array( $this, 'cp_create_private_pages_in_bulk' ) ); - - /* create client portal extra information */ - add_filter('the_content', array( $this, 'cp_add_private_page_info')); - - /* create the shortcode for the main page */ - add_shortcode( 'client-portal', array( $this, 'cp_shortcode' ) ); - - /* create the settings page */ - add_action( 'admin_menu', array( $this, 'cp_add_settings_page' ) ); - /* register the settings */ - add_action( 'admin_init', array( $this, 'cp_register_settings' ) ); - /* show notices on the admin settings page */ - add_action( 'admin_notices', array( $this, 'cp_admin_notices' ) ); - // Enqueue scripts on the admin side - add_action( 'admin_enqueue_scripts', array( $this, 'cp_enqueue_admin_scripts' ) ); - /* flush the rewrite rules when settings saved in case page slug was changed */ - add_action('init', array( $this, 'cp_flush_rules' ), 20 ); - - /* make sure we don't have post navigation on the private pages */ - add_filter( "get_previous_post_where", array( $this, 'cp_exclude_from_post_navigation' ), 10, 5 ); - add_filter( "get_next_post_where", array( $this, 'cp_exclude_from_post_navigation' ), 10, 5 ); - - } - - /** - * Function that registers the post type - */ - function cp_create_post_type() { - - $labels = array( - 'name' => _x( 'Private Pages', 'post type general name', 'client-portal' ), - 'singular_name' => _x( 'Private Page', 'post type singular name', 'client-portal' ), - 'menu_name' => _x( 'Private Page', 'admin menu', 'client-portal' ), - 'name_admin_bar' => _x( 'Private Page', 'add new on admin bar', 'client-portal' ), - 'add_new' => _x( 'Add New', 'private Page', 'client-portal' ), - 'add_new_item' => __( 'Add New Private Page', 'client-portal' ), - 'new_item' => __( 'New Private Page', 'client-portal' ), - 'edit_item' => __( 'Edit Private Page', 'client-portal' ), - 'view_item' => __( 'View Private Page', 'client-portal' ), - 'all_items' => __( 'All Private Pages', 'client-portal' ), - 'search_items' => __( 'Search Private Pages', 'client-portal' ), - 'parent_item_colon' => __( 'Parent Private Page:', 'client-portal' ), - 'not_found' => __( 'No Private Pages found.', 'client-portal' ), - 'not_found_in_trash' => __( 'No Private Pages found in Trash.', 'client-portal' ) - ); - - $args = array( - 'labels' => $labels, - 'description' => __( 'Description.', 'client-portal' ), - 'public' => true, - 'publicly_queryable' => true, - 'show_ui' => true, - 'show_in_menu' => false, - 'query_var' => true, - 'capability_type' => 'post', - 'has_archive' => false, - 'hierarchical' => true, - 'supports' => array( 'title', 'editor', 'thumbnail' ), - 'exclude_from_search' => true - ); - - if( !empty( $this->options['page-slug'] ) ){ - $args['rewrite'] = array( 'slug' => $this->options['page-slug'] ); - } - else{ - $args['rewrite'] = array( 'slug' => $this->defaults['page-slug'] ); - } - - if( !empty( $this->options['support-comments'] ) && $this->options['support-comments'] == 'yes' ) - $args['supports'][] = 'comments'; - - register_post_type( 'private-page', $args ); - } - - /** - * Function that creates the private page for a user - * @param $user_id the id of the user for which to create the page - */ - function cp_create_private_page( $user_id ){ - - /* check to see if we already have a page for the user */ - $users_private_pages = $this->cp_get_private_page_for_user( $user_id ); - if( !empty( $users_private_pages ) ) - return; - - /* make sure get_userdata() is available at this point */ - if(is_admin()) require_once( ABSPATH . 'wp-includes/pluggable.php' ); - - $user = get_userdata( $user_id ); - $display_name = ''; - if( $user ){ - $display_name = ($user->display_name) ? ($user->display_name) : ($user->user_login); - } - - if( !empty( $this->options['default-page-content'] ) ) - $post_content = $this->options['default-page-content']; - else - $post_content = $this->defaults['default-page-content']; - - $private_page = array( - 'post_title' => $display_name, - 'post_status' => 'publish', - 'post_type' => 'private-page', - 'post_author' => $user_id, - 'post_content' => $post_content - ); - - // Insert the post into the database - wp_insert_post( $private_page ); - } - - /** - * Function that deletes the private page when the user is deleted - * @param $id the id of the user which page we are deleting - * @param $reassign - */ - function cp_delete_private_page( $id, $reassign ){ - $private_page_id = $this->cp_get_private_page_for_user( $id ); - if( !empty( $private_page_id ) ){ - wp_delete_post( $private_page_id, true ); - } - } - - /** - * Function that restricts the content only to the author of the page - * @param $content the content of the page - * @return mixed - */ - function cp_restrict_content( $content ){ - global $post; - if( $post->post_type == 'private-page' ){ - - if( !empty( $this->options['restricted-message'] ) ) - $message = $this->options['restricted-message']; - else - $message = $this->defaults['restricted-message']; - - if( is_user_logged_in() ){ - if( ( get_current_user_id() == $post->post_author ) || current_user_can('delete_user') ){ - return $content; - } - else return $message; - } - else return $message; - - } - return $content; - } - - /** - * Function that adds a link in the user listing in admin area to access the private page - * @param $actions The actions available on the user listing in admin area - * @param $user_object The user object - * @return mixed - */ - function cp_add_link_to_private_page( $actions, $user_object ){ - $private_page_id = $this->cp_get_private_page_for_user( $user_object->ID ); - if( !empty( $private_page_id ) ){ - $actions['private_page_link'] = "" . __( 'Private Page', 'client-portal' ) . ""; - } - - return $actions; - } - - /** - * Function that creates a private page extra information div - * @param $content the content of the private page - * @return mixed - */ - function cp_add_private_page_info( $content ){ - global $post; - if ( is_singular('private-page') && is_user_logged_in() ){ - // logout link - $logout_link = wp_loginout( home_url(), false); - - // author display name. Fallback to username if no display name is set. - $author_id=$post->post_author; - $user = get_user_by('id', $author_id); - $display_name = ''; - if( $user ){ - $display_name = ($user->display_name) ? ($user->display_name) : ($user->user_login); - } - - $extra_info = "

    $logout_link - $display_name

    "; - - return $extra_info . $content; - } - - return $content; - } - - /** - * Function that creates a shortcode which redirects the user to its private page - * @param $atts the shortcode attributes - */ - function cp_shortcode( $atts ){ - if( !is_user_logged_in() ){ - if( !empty( $this->options['portal-log-in-message'] ) ) - $message = $this->options['portal-log-in-message']; - else - $message = $this->defaults['portal-log-in-message']; - - return $message; - } - else{ - $user_id = get_current_user_id(); - $private_page_id = $this->cp_get_private_page_for_user( $user_id ); - if( $private_page_id ) { - $private_page_link = get_permalink($private_page_id); - ?> - - cp_create_private_pages_for_all_users(); - } - - ?> -
    - -

    - - - -
    -
    -
    - - slug ); ?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -

    -
    -
    - -

    -
    - "> -

    -
    - -

    -
    - -

    -
    - -

    -
    - - - -
    -
    - -
    -

    Get the most out of Client Portal

    -

    When building a place for your clients to access information, it can take a lot of time simply because there isn't enough flexibility - to build exactly what you need.

    -

    Wouldn't it be nice to be able to build the experience for your clients using simple modules that each does as few things as possible, but well?

    -

    Profile Builder Logo

    -

    Client Portal was designed to work together with - Profile Builder so you can construct the client experience just as you need it. -

    -
      -
    • add a login form with redirect
      [wppb-login redirect_url="http://www.yourdomain.com/page"]
    • -
    • allow users to register [wppb-register]
    • -
    • hide the WordPress admin bar for clients
    • -
    -
    - - -
    - -
    - slug, $this->slug, array( 'sanitize_callback' => array( $this, 'cp_sanitize_options' ) ) ); - } - - /** - * Function that sanitizes the options of the plugin - * @param $options - * @return mixed - */ - function cp_sanitize_options( $options ){ - if( !empty( $options ) ){ - foreach( $options as $key => $value ){ - if( $key == 'page-slug' || $key == 'support-comments' ) - $options[$key] = sanitize_text_field( $value ); - elseif( $key == 'restricted-message' || $key == 'portal-log-in-message' ) - $options[$key] = wp_kses_post( $value ); - } - } - - return $options; - } - - /** - * Function that creates the notice messages on the settings page - */ - function cp_admin_notices(){ - if( !empty( $_GET['page'] ) && $_GET['page'] == 'client_portal_settings' ) { - if( !empty( $_GET['cp_generate_for_all'] ) && $_GET['cp_generate_for_all'] == true ) { - ?> -
    -

    -
    - -
    -

    -
    - post_type == 'private-page' ){ - $where = str_replace( "'private-page'", "'do not show this'", $where ); - } - return $where; - } - - /** - * Function that returns the id for the private page for the provided user - * @param $user_id the user id for which we want to get teh private page for - * @return mixed - */ - function cp_get_private_page_for_user( $user_id ){ - $args = array( - 'author' => $user_id, - 'posts_per_page' => 1, - 'post_type' => 'private-page', - ); - $users_private_pages = get_posts( $args ); - - if( !empty( $users_private_pages ) ){ - foreach( $users_private_pages as $users_private_page ){ - return $users_private_page->ID; - break; - } - } - /* we don't have a page */ - return false; - } - - /** - * Function that returns all the private pages post objects - * @return array - */ - function cp_get_all_private_pages(){ - $args = array( - 'posts_per_page' => -1, - 'numberposts' => -1, - 'post_type' => 'private-page', - ); - - $users_private_pages = get_posts( $args ); - return $users_private_pages; - } - - /** - * Function that creates a custom action in the Bulk Dropdown on the Users screen - */ - function cp_create_private_page_bulk_actions(){ - ?> - - cp_create_private_page( $user_id ); - } - } - } - - /** - * Function that creates private pages for all existing users - */ - function cp_create_private_pages_for_all_users(){ - $all_users = get_users( array( 'fields' => array( 'ID' ) ) ); - if( !empty( $all_users ) ){ - foreach( $all_users as $user ){ - $users_private_pages = $this->cp_get_private_page_for_user( $user->ID ); - if( !$users_private_pages ) { - $this->cp_create_private_page( $user->ID ); - } - } - } - } - -} - -$CP_Object = new CL_Client_Portal(); diff --git a/client-portal/readme.txt b/client-portal/readme.txt deleted file mode 100644 index b124606..0000000 --- a/client-portal/readme.txt +++ /dev/null @@ -1,57 +0,0 @@ -=== Client Portal - Private user pages and login === -Contributors: cozmoslabs, madalin.ungureanu, sareiodata -Donate link: http://www.cozmoslabs.com/ -Tags: client portal, private user page, private pages, private content, private client page, user restricted content - -Requires at least: 3.1 -Tested up to: 4.7.4 -Stable tag: 1.0.4 -License: GPLv2 or later -License URI: http://www.gnu.org/licenses/gpl-2.0.html - -WordPress Client Portal Plugin that creates private pages for all users that only an administrator can edit. - -== Description == - -The WordPress Client Portal plugin creates private pages for each user. The content for that page is accessible on the frontend only by the owner of the page -after he has logged in. - -The plugin doesn't offer a login or registration form and it gives you the possibility to use a plugin of your choice. - -The [client-portal] shortcode can be added to any page and when the logged in user will access that page he will be redirected to its private page. - -For login and registration of users we recommend the free [Profile Builder](https://wordpress.org/plugins/profile-builder/) plugin. - -You can then use the [wppb-login] shortcode in the same page as the [client-portal] shortcode. - -== Installation == - -1. Upload and install the zip file via the built in WordPress plugin installer. -2. Activate the WordPress Client Portal plugin from the "Plugins" admin panel using the "Activate" link. - - -== Screenshots == -1. Access the Private Page in the Users Listing in the admin area: screenshot-1.jpg -2. A Private Page in the admin area: screenshot-2.jpg -3. The Settings Page for the Plugin: screenshot-3.jpg - -== Changelog == -= 1.0.4 = -* We now have a default content option for pages -* Now private pages are excluded from appearing in frontend search -* Fixed a bug where the private page would reload indefinitely if the user hadn't a page created -* Fixed a bug where you could create duplicate pages for the same user - - -= 1.0.3 = -* Minor fixes and security improvements - -= 1.0.2 = -* Added support for bulk Create Private Pages to Users page bulk actions - -= 1.0.1 = -* Added support for comments on private user pages -* Settings page is now stylized - -= 1.0.0 = -* Initial Version of the WordPress Client Portal plugin. \ No newline at end of file diff --git a/client-portal/screenshot-1.png b/client-portal/screenshot-1.png deleted file mode 100644 index bd4fd98fb0a77b6c0738c864a5de67d6a6c360bb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 161977 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�S_NQX`}u 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 vlo~u@N)R+3OJ#~aqdoa)1B2bR?n~fa diff --git a/client-portal/screenshot-2.png b/client-portal/screenshot-2.png deleted file mode 100644 index 92d1435345800d10ace3072b0996425ef65c6e6e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 75060 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 diff --git a/client-portal/screenshot-3.png b/client-portal/screenshot-3.png deleted file mode 100644 index 870bbc97bc5fcb3a628b6a707d292aa0efe617a0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 66754 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 K2mbeysQ&|x2vi&Z diff --git a/dk-pdf.1.9.zip b/dk-pdf.zip similarity index 97% rename from dk-pdf.1.9.zip rename to dk-pdf.zip index 89f66d5b0f5b3e7e1ec02afbe655558ed0edd55e..19a95387a2e1c1ea7a97c1b65840edf9f54919e1 100644 GIT binary patch delta 73931 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
    J)p#y@& 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
    VWr?-?k0QagYrOf^rWcyT{YE~=E(0W_yi3j)~k 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

    e~C4Vbet@gBpA;_I!n$Lvgbvgo!6 z%VYhw35GlWr6{vMpr%fA4UHQXW59nRv~mn9b@vESb^fDaJRbLV)7&FG~R&4eS)g7Zcz8iG}w7%(1_0<@yPp)Kfzuy6Cf;rEG zE@4!Cs899v^B5avK>VUq0rp}hSbgCBAt8pc8M)LZ_>dMWjCvdma!v1-6(5^15gvZa z+T{}U$1zp%Y7jU{w>P^1KLt;sCprSOs}Dc^lwL&R^zzU;R1P>ZGY*H@&`_(_C_@e8 zV!^{VGz6rd&ZHBKup@b2%;7N22L&-P*FeWSczE+cX!mbk^_G<$a8D5|T|H^*iNC4} zdxUDBW>X0R^xm8YPns}hoo0V4r-qg6g&v??8py1(6p!yaG)W$g_T)3J*%zTRBrVSb zeU#$tb&%#55eWKIRXDg=iv&6dF&C8d^EvXS+ zEpvs#!bMEdCvo}L`aPO8uEop5h*7f#=bE-ak13sU#h#oxI?Am-|4YzTLh;B5D0 zYuIC-At9+JmWKqSa@@wB3B4pZUj5jRL(h9qM)eh^T^tC>IHN+?@-9@;xPIbrr<%5*^}FECfg@~r-`aaoPV6thiLVa$DZ-6XRBFdF zMC*7w{D%fAONjv+)IQ5h2Hxi*oIb=$h)R1X-&g=`zRF_q#Xe;6NWh;}g?E1OfpRFo zfj?^rlB&YG87AbLkmTaxBL{f{W3ndjJ*8Z5rO&`FMW6D+dRa<=KIK=m+xU0IuK1H`LUpS?o-yOlQ zj9ez|8f0H$%N&eSN^Xur(OjO5-1yu`pOIi`c|X33DMtI@ZWI9l*twI-7e%q~?AC|! zR#Hx+?+C(MQ-BFHyTpfL@;4tN0WNC?@JR@=s=_Z_;Fn>KENzt{{f6;FiP}zDF=kVo z9wk#`jszKFmcXl0z8h!w!G+8_h7$bWUsC)_Zj(R<^wWkfnPO?)AAVQ%$kI;WC8PT` zj8qDIww@%hmP?O`3=ASnd~M6(V%p7;@&ZKyCfW*ehT^gaF(j#xfkO!{XCU+7wlU&E z=>mRIcjnn}(@6?Z`>w359bg_0_wRKhUzET3OaZ={!{(9l9DYH^yo?NW^VySR3Vf^+AA_FVYa{{i4PTW$aV diff --git a/profile-builder/admin/add-ons.php b/profile-builder/admin/add-ons.php index df23c7d..9bb1818 100644 --- a/profile-builder/admin/add-ons.php +++ b/profile-builder/admin/add-ons.php @@ -1,367 +1,368 @@ - - -

    - $wppb_plugin ) { - - if( strpos( $wppb_plugin['Name'], $wppb_add_on_name ) !== false && strpos( $wppb_plugin['AuthorName'], 'Cozmoslabs' ) !== false ) { - - // Deactivate the add-on if it's active - if( is_plugin_active( $wppb_plugin_key )) { - deactivate_plugins( $wppb_plugin_key ); - } - - // Return the plugin path - echo $wppb_plugin_key; - wp_die(); - } - } - - wp_die(); -} -add_action( 'wp_ajax_wppb_add_on_get_new_plugin_data', 'wppb_add_on_get_new_plugin_data' ); \ No newline at end of file + + +
    + +

    + + + + + + + + + + + active', 'profile-builder' ); ?> + inactive', 'profile-builder' ); ?> + + + + +
    + + $wppb_add_on ) { + + $wppb_add_on_exists = 0; + $wppb_add_on_is_active = 0; + $wppb_add_on_is_network_active = 0; + + // Check to see if add-on is in the plugins folder + foreach ($wppb_get_all_plugins as $wppb_plugin_key => $wppb_plugin) { + if (strpos(strtolower($wppb_plugin['Name']), strtolower($wppb_add_on['name'])) !== false && strpos(strtolower($wppb_plugin['AuthorName']), strtolower('Cozmoslabs')) !== false) { + $wppb_add_on_exists = 1; + + if (in_array($wppb_plugin_key, $wppb_get_active_plugins)) { + $wppb_add_on_is_active = 1; + } + + // Consider the add-on active if it's network active + if (is_plugin_active_for_network($wppb_plugin_key)) { + $wppb_add_on_is_network_active = 1; + $wppb_add_on_is_active = 1; + } + + $wppb_add_on['plugin_file'] = $wppb_plugin_key; + } + } + + echo '
    '; + echo '
    '; + + echo ''; + echo ''; + echo ''; + + echo '

    '; + echo ''; + echo $wppb_add_on['name']; + echo ''; + echo '

    '; + + //echo '

    ' . $wppb_add_on['price'] . '

    '; + /* + if( $wppb_add_on['type'] == 'paid' ) + echo '

    ' . __( 'Available in Hobbyist and Pro Versions', 'profile-builder' ) . '

    '; + else + echo '

    ' . __( 'Available in All Versions', 'profile-builder' ) . '

    '; + */ + echo '

    ' . $wppb_add_on['description'] . '

    '; + + echo '
    '; + + $wppb_version_validation = version_compare(PROFILE_BUILDER_VERSION, $wppb_add_on['product_version']); + + ($wppb_version_validation != -1) ? $wppb_version_validation_class = 'wppb-add-on-compatible' : $wppb_version_validation_class = 'wppb-add-on-not-compatible'; + + echo '
    '; + + // PB minimum version number is all good + if ($wppb_version_validation != -1) { + + // PB version type does match + if (in_array(strtolower($version), $wppb_add_on['product_version_type'])) { + + $ajax_nonce = wp_create_nonce("wppb-activate-addon"); + + if ($wppb_add_on_exists) { + + // Display activate/deactivate buttons + if (!$wppb_add_on_is_active) { + echo '' . __('Activate', 'profile-builder') . ''; + + // If add-on is network activated don't allow deactivation + } elseif (!$wppb_add_on_is_network_active) { + echo '' . __('Deactivate', 'profile-builder') . ''; + } + + // Display message to the user + if (!$wppb_add_on_is_active) { + echo '' . __('Add-On is inactive', 'profile-builder') . ''; + } else { + echo '' . __('Add-On is active', 'profile-builder') . ''; + } + + } else { + + // If we're on a multisite don't add the wpp-add-on-download class to the button so we don't fire the js that + // handles the in-page download + ($wppb_add_on['paid']) ? $wppb_paid_link_class = 'button-primary' : $wppb_paid_link_class = 'button-secondary'; + ($wppb_add_on['paid']) ? $wppb_paid_link_text = __('Learn More', 'profile-builder') : $wppb_paid_link_text = __('Download Now', 'profile-builder'); + + ($wppb_add_on['paid']) ? $wppb_paid_href_utm_text = '?utm_source=wpbackend&utm_medium=clientsite&utm_content=add-on-page-buy-button&utm_campaign=PB' . $version : $wppb_paid_href_utm_text = '?utm_source=wpbackend&utm_medium=clientsite&utm_content=add-on-page&utm_campaign=PB' . $version; + + echo '' . $wppb_paid_link_text . ''; + echo '' . __('Compatible with your version of Profile Builder.', 'profile-builder') . ''; + + } + + echo '
    '; + + // PB version type does not match + } else { + + echo '' . __('Upgrade Profile Builder', 'profile-builder') . ''; + echo '' . __('Not compatible with Profile Builder', 'profile-builder') . ' ' . $version . ''; + + } + + } else { + + // If PB version is older than the minimum required version of the add-on + echo ' ' . '' . __('Update', 'profile-builder') . ''; + echo '' . __('Not compatible with your version of Profile Builder.', 'profile-builder') . '
    '; + echo '' . __('Minimum required Profile Builder version:', 'profile-builder') . ' ' . $wppb_add_on['product_version'] . ''; + + } + + // We had to put this error here because we need the url of the add-on + echo '' . sprintf(__('Could not install add-on. Retry or install manually.', 'profile-builder'), esc_url($wppb_add_on['url'])) . ''; + + echo '
    '; + echo '
    '; + + } /* end $wppb_add_ons foreach */ + } + + ?> +
    + +
    +
    +

    + $wppb_plugin) { + if( strtolower($wppb_plugin['Name']) == strtolower( 'Paid Member Subscriptions' ) && strpos(strtolower($wppb_plugin['AuthorName']), strtolower('Cozmoslabs')) !== false) { + $pms_add_on_exists = 1; + if (in_array($wppb_plugin_key, $wppb_get_active_plugins)) { + $pms_add_on_is_active = 1; + } + // Consider the add-on active if it's network active + if (is_plugin_active_for_network($wppb_plugin_key)) { + $pms_add_on_is_network_active = 1; + $pms_add_on_is_active = 1; + } + $plugin_file = $wppb_plugin_key; + } + } + ?> + +
    + +
    + $wppb_plugin ) { + + if( strpos( $wppb_plugin['Name'], $wppb_add_on_name ) !== false && strpos( $wppb_plugin['AuthorName'], 'Cozmoslabs' ) !== false ) { + + // Deactivate the add-on if it's active + if( is_plugin_active( $wppb_plugin_key )) { + deactivate_plugins( $wppb_plugin_key ); + } + + // Return the plugin path + echo $wppb_plugin_key; + wp_die(); + } + } + + wp_die(); +} +add_action( 'wp_ajax_wppb_add_on_get_new_plugin_data', 'wppb_add_on_get_new_plugin_data' ); diff --git a/profile-builder/admin/admin-bar.php b/profile-builder/admin/admin-bar.php index adefe4e..c35b1c4 100644 --- a/profile-builder/admin/admin-bar.php +++ b/profile-builder/admin/admin-bar.php @@ -1,121 +1,121 @@ - - -
    - -

    -

    -

    - - - - - - - - - - roles as $role ) { - $alt_i++; - $key = $role['name']; - $setting_exists = !empty( $admin_bar_settings[$key] ); - $alt_class = ( ( $alt_i%2 == 0 ) ? ' class="alternate"' : '' ); - - echo' - - - '; - } - ?> - -
    '.translate_user_role($key).' - - - -
    - -
    - -

    - -

    -
    - -
    - -
    - ID != 0 ) { - $my_account_main = $wp_admin_bar->get_node('my-account'); - $new_title1 = str_replace($current_user->display_name, $current_user->user_email, $my_account_main->title); - $wp_admin_bar->add_node(array('id' => 'my-account', 'title' => $new_title1)); - - $my_account_sub = $wp_admin_bar->get_node('user-info'); - $wp_admin_bar->add_node(array('parent' => 'user-actions', 'id' => 'user-info', 'title' => get_avatar($current_user->ID, 64) . "{$current_user->user_email}", 'href' => get_edit_profile_url($current_user->ID), 'meta' => array('tabindex' => -1))); - } - } - - return $wp_admin_bar; -} + + +
    + +

    +

    +

    + + + + + + + + + + roles as $role ) { + $alt_i++; + $key = $role['name']; + $setting_exists = !empty( $admin_bar_settings[$key] ); + $alt_class = ( ( $alt_i%2 == 0 ) ? ' class="alternate"' : '' ); + + echo' + + + '; + } + ?> + +
    '.translate_user_role($key).' + + + +
    + +
    + +

    + +

    +
    + +
    + +
    + ID != 0 ) { + $my_account_main = $wp_admin_bar->get_node('my-account'); + $new_title1 = str_replace($current_user->display_name, $current_user->user_email, $my_account_main->title); + $wp_admin_bar->add_node(array('id' => 'my-account', 'title' => $new_title1)); + + $my_account_sub = $wp_admin_bar->get_node('user-info'); + $wp_admin_bar->add_node(array('parent' => 'user-actions', 'id' => 'user-info', 'title' => get_avatar($current_user->ID, 64) . "{$current_user->user_email}", 'href' => get_edit_profile_url($current_user->ID), 'meta' => array('tabindex' => -1))); + } + } + + return $wp_admin_bar; +} add_filter( 'admin_bar_menu', 'wppb_replace_username_on_admin_bar', 25 ); \ No newline at end of file diff --git a/profile-builder/admin/admin-functions.php b/profile-builder/admin/admin-functions.php index a0ee831..708c206 100644 --- a/profile-builder/admin/admin-functions.php +++ b/profile-builder/admin/admin-functions.php @@ -1,209 +1,209 @@ -' . sprintf(__('Login is set to be done using the E-mail. This field will NOT appear in the front-end! ( you can change these settings under the "%s" tab )', 'profile-builder'), '' . __('General Settings', 'profile-builder') . '') . ''; - } - break; - case 'Default - Display name publicly as': - $form .= '
    ' . __( 'Display name publicly as - only appears on the Edit Profile page!', 'profile-builder' ) . '
    '; - break; - case 'Default - Blog Details': - $form .= '
    ' . __( 'Blog Details - only appears on the Registration page!', 'profile-builder' ) . '
    '; - break; - } - - return $form; -} - -add_filter( 'wck_after_content_element', 'wppb_manage_fields_display_field_title_slug' ); - -/** - * Check if field type is 'Default - Display name publicly as' so we can add a notification for it - * - * @since v.2.2 - * - * @param string $wck_element_class - * @param string $meta - * @param array $results - * @param integer $element_id - * - */ -function wppb_manage_fields_display_name_notice( $wck_element_class, $meta, $results, $element_id ) { - global $wppb_results_field; - - $wppb_results_field = $results[$element_id]['field']; -} -add_filter( 'wck_element_class_wppb_manage_fields', 'wppb_manage_fields_display_name_notice', 10, 4 ); - - - -/** - * Function that adds a custom class to the existing container - * - * @since v.2.0 - * - * @param string $update_container_class - the new class name - * @param string $meta - the name of the meta - * @param array $results - * @param integer $element_id - the ID of the element - * - * @return string - */ -function wppb_update_container_class( $update_container_class, $meta, $results, $element_id ) { - $wppb_element_type = Wordpress_Creation_Kit_PB::wck_generate_slug( $results[$element_id]["field"] ); - - return "class='wck_update_container update_container_$meta update_container_$wppb_element_type element_type_$wppb_element_type'"; -} -add_filter( 'wck_update_container_class_wppb_manage_fields', 'wppb_update_container_class', 10, 4 ); - - -/** - * Function that adds a custom class to the existing element - * - * @since v.2.0 - * - * @param string $element_class - the new class name - * @param string $meta - the name of the meta - * @param array $results - * @param integer $element_id - the ID of the element - * - * @return string - */ -function wppb_element_class( $element_class, $meta, $results, $element_id ){ - $wppb_element_type = Wordpress_Creation_Kit_PB::wck_generate_slug( $results[$element_id]["field"] ); - - return "class='element_type_$wppb_element_type added_fields_list'"; -} -add_filter( 'wck_element_class_wppb_manage_fields', 'wppb_element_class', 10, 4 ); - -/** - * Functions to check password length and strength - * - * @since v.2.0 - */ -/* on add user and update profile from WP admin area */ -add_action( 'user_profile_update_errors', 'wppb_password_check_on_profile_update', 0, 3 ); -function wppb_password_check_on_profile_update( $errors, $update, $user ){ - wppb_password_check_extra_conditions( $errors, $user ); -} - -/* on reset password */ -add_action( 'validate_password_reset', 'wppb_password_check_extra_conditions', 10, 2 ); -function wppb_password_check_extra_conditions( $errors, $user ){ - $password = ( isset( $_POST[ 'pass1' ] ) && trim( $_POST[ 'pass1' ] ) ) ? $_POST[ 'pass1' ] : false; - - if( $password ){ - $wppb_generalSettings = get_option( 'wppb_general_settings' ); - if( !empty( $wppb_generalSettings['minimum_password_length'] ) ){ - if( strlen( $password ) < $wppb_generalSettings['minimum_password_length'] ) - $errors->add( 'pass', sprintf( __( 'ERROR: The password must have the minimum length of %s characters', 'profile-builder' ), $wppb_generalSettings['minimum_password_length'] ) ); - } - - if( isset( $_POST['wppb_password_strength'] ) && !empty( $wppb_generalSettings['minimum_password_strength'] ) ){ - $password_strength_array = array( 'short' => 0, 'bad' => 1, 'good' => 2, 'strong' => 3 ); - $password_strength_text = array( 'short' => __( 'Very weak', 'profile-builder' ), 'bad' => __( 'Weak', 'profile-builder' ), 'good' => __( 'Medium', 'profile-builder' ), 'strong' => __( 'Strong', 'profile-builder' ) ); - - foreach( $password_strength_text as $psr_key => $psr_text ){ - if( $psr_text == sanitize_text_field( $_POST['wppb_password_strength'] ) ){ - $password_strength_result_slug = $psr_key; - break; - } - } - - if( !empty( $password_strength_result_slug ) ){ - if( $password_strength_array[$password_strength_result_slug] < $password_strength_array[$wppb_generalSettings['minimum_password_strength']] ) - $errors->add( 'pass', sprintf( __( 'ERROR: The password must have a minimum strength of %s', 'profile-builder' ), $password_strength_text[$wppb_generalSettings['minimum_password_strength']] ) ); - } - } - } - - return $errors; -} - -/* we need to create a hidden field that contains the results of the password strength from the js strength tester */ -add_action( 'admin_footer', 'wppb_add_hidden_password_strength_on_backend' ); -add_action( 'login_footer', 'wppb_add_hidden_password_strength_on_backend' ); -function wppb_add_hidden_password_strength_on_backend(){ - if( $GLOBALS['pagenow'] == 'profile.php' || $GLOBALS['pagenow'] == 'user-new.php' || ( $GLOBALS['pagenow'] == 'wp-login.php' && isset( $_GET['action'] ) && ( $_GET['action'] == 'rp' || $_GET['action'] == 'resetpass' ) ) ){ - $wppb_generalSettings = get_option( 'wppb_general_settings' ); - if( !empty( $wppb_generalSettings['minimum_password_strength'] ) ){ - ?> - - parent_base == 'profile-builder'){ - $rate_text = sprintf( __( 'If you enjoy using %1$s please rate us on WordPress.org. More happy users means more features, less bugs and better support for everyone. ', 'profile-builder' ), - PROFILE_BUILDER, - 'https://wordpress.org/support/view/plugin-reviews/profile-builder?filter=5#postform' - ); - return '' .$rate_text . ''; - } else { - return $footer_text; - } -} +' . sprintf(__('Login is set to be done using the E-mail. This field will NOT appear in the front-end! ( you can change these settings under the "%s" tab )', 'profile-builder'), '' . __('General Settings', 'profile-builder') . '') . ''; + } + break; + case 'Default - Display name publicly as': + $form .= '
    ' . __( 'Display name publicly as - only appears on the Edit Profile page!', 'profile-builder' ) . '
    '; + break; + case 'Default - Blog Details': + $form .= '
    ' . __( 'Blog Details - only appears on the Registration page!', 'profile-builder' ) . '
    '; + break; + } + + return $form; +} + +add_filter( 'wck_after_content_element', 'wppb_manage_fields_display_field_title_slug' ); + +/** + * Check if field type is 'Default - Display name publicly as' so we can add a notification for it + * + * @since v.2.2 + * + * @param string $wck_element_class + * @param string $meta + * @param array $results + * @param integer $element_id + * + */ +function wppb_manage_fields_display_name_notice( $wck_element_class, $meta, $results, $element_id ) { + global $wppb_results_field; + + $wppb_results_field = $results[$element_id]['field']; +} +add_filter( 'wck_element_class_wppb_manage_fields', 'wppb_manage_fields_display_name_notice', 10, 4 ); + + + +/** + * Function that adds a custom class to the existing container + * + * @since v.2.0 + * + * @param string $update_container_class - the new class name + * @param string $meta - the name of the meta + * @param array $results + * @param integer $element_id - the ID of the element + * + * @return string + */ +function wppb_update_container_class( $update_container_class, $meta, $results, $element_id ) { + $wppb_element_type = Wordpress_Creation_Kit_PB::wck_generate_slug( $results[$element_id]["field"] ); + + return "class='wck_update_container update_container_$meta update_container_$wppb_element_type element_type_$wppb_element_type'"; +} +add_filter( 'wck_update_container_class_wppb_manage_fields', 'wppb_update_container_class', 10, 4 ); + + +/** + * Function that adds a custom class to the existing element + * + * @since v.2.0 + * + * @param string $element_class - the new class name + * @param string $meta - the name of the meta + * @param array $results + * @param integer $element_id - the ID of the element + * + * @return string + */ +function wppb_element_class( $element_class, $meta, $results, $element_id ){ + $wppb_element_type = Wordpress_Creation_Kit_PB::wck_generate_slug( $results[$element_id]["field"] ); + + return "class='element_type_$wppb_element_type added_fields_list'"; +} +add_filter( 'wck_element_class_wppb_manage_fields', 'wppb_element_class', 10, 4 ); + +/** + * Functions to check password length and strength + * + * @since v.2.0 + */ +/* on add user and update profile from WP admin area */ +add_action( 'user_profile_update_errors', 'wppb_password_check_on_profile_update', 0, 3 ); +function wppb_password_check_on_profile_update( $errors, $update, $user ){ + wppb_password_check_extra_conditions( $errors, $user ); +} + +/* on reset password */ +add_action( 'validate_password_reset', 'wppb_password_check_extra_conditions', 10, 2 ); +function wppb_password_check_extra_conditions( $errors, $user ){ + $password = ( isset( $_POST[ 'pass1' ] ) && trim( $_POST[ 'pass1' ] ) ) ? $_POST[ 'pass1' ] : false; + + if( $password ){ + $wppb_generalSettings = get_option( 'wppb_general_settings' ); + if( !empty( $wppb_generalSettings['minimum_password_length'] ) ){ + if( strlen( $password ) < $wppb_generalSettings['minimum_password_length'] ) + $errors->add( 'pass', sprintf( __( 'ERROR: The password must have the minimum length of %s characters', 'profile-builder' ), $wppb_generalSettings['minimum_password_length'] ) ); + } + + if( isset( $_POST['wppb_password_strength'] ) && !empty( $wppb_generalSettings['minimum_password_strength'] ) ){ + $password_strength_array = array( 'short' => 0, 'bad' => 1, 'good' => 2, 'strong' => 3 ); + $password_strength_text = array( 'short' => __( 'Very weak', 'profile-builder' ), 'bad' => __( 'Weak', 'profile-builder' ), 'good' => __( 'Medium', 'profile-builder' ), 'strong' => __( 'Strong', 'profile-builder' ) ); + + foreach( $password_strength_text as $psr_key => $psr_text ){ + if( $psr_text == sanitize_text_field( $_POST['wppb_password_strength'] ) ){ + $password_strength_result_slug = $psr_key; + break; + } + } + + if( !empty( $password_strength_result_slug ) ){ + if( $password_strength_array[$password_strength_result_slug] < $password_strength_array[$wppb_generalSettings['minimum_password_strength']] ) + $errors->add( 'pass', sprintf( __( 'ERROR: The password must have a minimum strength of %s', 'profile-builder' ), $password_strength_text[$wppb_generalSettings['minimum_password_strength']] ) ); + } + } + } + + return $errors; +} + +/* we need to create a hidden field that contains the results of the password strength from the js strength tester */ +add_action( 'admin_footer', 'wppb_add_hidden_password_strength_on_backend' ); +add_action( 'login_footer', 'wppb_add_hidden_password_strength_on_backend' ); +function wppb_add_hidden_password_strength_on_backend(){ + if( $GLOBALS['pagenow'] == 'profile.php' || $GLOBALS['pagenow'] == 'user-new.php' || ( $GLOBALS['pagenow'] == 'wp-login.php' && isset( $_GET['action'] ) && ( $_GET['action'] == 'rp' || $_GET['action'] == 'resetpass' ) ) ){ + $wppb_generalSettings = get_option( 'wppb_general_settings' ); + if( !empty( $wppb_generalSettings['minimum_password_strength'] ) ){ + ?> + + parent_base == 'profile-builder'){ + $rate_text = sprintf( __( 'If you enjoy using %1$s please rate us on WordPress.org. More happy users means more features, less bugs and better support for everyone. ', 'profile-builder' ), + PROFILE_BUILDER, + 'https://wordpress.org/support/view/plugin-reviews/profile-builder?filter=5#postform' + ); + return '' .$rate_text . ''; + } else { + return $footer_text; + } +} add_filter('admin_footer_text','wppb_admin_rate_us'); \ No newline at end of file diff --git a/profile-builder/admin/basic-info.php b/profile-builder/admin/basic-info.php index fc7c523..23e3344 100644 --- a/profile-builder/admin/basic-info.php +++ b/profile-builder/admin/basic-info.php @@ -1,194 +1,195 @@ - -
    -
    -

    Profile Builder ' . $version, 'profile-builder' ); ?>

    -

    -
    -

    -
    -
    -

    -

    [wppb-login]' ); ?>

    -
    -
    -

    -

    [wppb-register]' ); ?>

    -
    -
    -

    -

    [wppb-edit-profile]' ); ?>

    -
    -
    - -
    -
    -

    -

    -

    -
    -
    -
    -

    -

    [wppb-recover-password]' ); ?>

    -
    -
    -

    -

    -
    -
    -

    -

    -
    -
    -

    -

    -
    -
    -

    -

    -
    -
    - - - -
    -
    -
    -

    -

    - -

    - -

    - -
      -
    • -
    • -
    • -
    • -
    • -
    • -
    • -
    • -
    • -
    • -
    - -
      -
    • -
    • -
    • -
    • -
    • -
    • -
    • -
    • -
    • -
    -
    -
    - Profile Builder Extra Fields -
    -
    -
    -
    -

    -

    - -

    - - -

    - -
    -
    -
    -

    - -

    - -

    [wppb-list-users]' ); ?>

    - -
    -
    -

    -

    -
    -
    -

    -

    -
    -
    -
    -
    -

    -

    -
    -
    -

    -

    -
    -
    -

    -

    -
    -
    - - -
    -
    -
    - paid member subscriptions -
    -
    -

    Paid user profiles with Profile Builder and Paid Member Subscriptions

    -

    One of the most requested features in Profile Builder was for users to be able to pay for an account.

    -

    Now that's possible using the free WordPress plugin - Paid Member Subscriptions.

    -

    Find out how

    - -
    -
    -
    -
    -

    Extra Notes

    -
      -
    • ', '' );?>
    • -
    • ', '' );?>
    • -
    -
    -
    - +
    +
    +

    Profile Builder ' . $version, 'profile-builder' ); ?>

    +

    +
    +

    +
    +
    +

    +

    [wppb-login]' ); ?>

    +
    +
    +

    +

    [wppb-register]' ); ?>

    +
    +
    +

    +

    [wppb-edit-profile]' ); ?>

    +
    +
    + +
    +
    +

    +

    +

    +
    +
    +
    +

    +

    [wppb-recover-password]' ); ?>

    +
    +
    +

    +

    +
    +
    +

    +

    +
    +
    +

    +

    +
    +
    +

    +

    +
    +
    + + + +
    +
    +
    +

    +

    + +

    + +

    + +
      +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    + +
      +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    +
    +
    + Profile Builder Extra Fields +
    +
    +
    +
    +

    +

    + +

    + + +

    + +
    +
    +
    +

    + +

    + +

    [wppb-list-users]' ); ?>

    + +
    +
    +

    +

    +
    +
    +

    +

    +
    +
    +
    +
    +

    +

    +
    +
    +

    +

    +
    +
    +

    +

    +
    +
    + + +
    +
    +
    + paid member subscriptions +
    +
    +

    Paid user profiles with Profile Builder and Paid Member Subscriptions

    +

    One of the most requested features in Profile Builder was for users to be able to pay for an account.

    +

    Now that's possible using the free WordPress plugin - Paid Member Subscriptions.

    +

    Find out how

    + +
    +
    +
    +
    +

    Extra Notes

    +
      +
    • ', '' );?>
    • +
    • ', '' );?>
    • +
    +
    +
    + 'default', 'emailConfirmation' => 'no', 'activationLandingPage' => '', 'adminApproval' => 'no', 'loginWith' => 'usernameemail', 'rolesEditor' => 'no' ) ); -} - - -/** - * Function that adds content to the "General Settings" submenu page - * - * @since v.2.0 - * - * @return string - */ -function wppb_general_settings_content() { - wppb_generate_default_settings_defaults(); -?> -
    -
    - - - -

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - -
      -
    • '.dirname( dirname( plugin_basename( __FILE__ ) ) ).'\assets\css\style-front-end.css' ); ?>
    • -
    -
    - - - -
      -
    • - -
    • All Users > Email Confirmation%2$s.', 'profile-builder' ), '', '' )?>
    • - -
    -
    - - - -

    - -

    -
    - - - -
      -
    • All Users > Admin Approval%2$s.', 'profile-builder' ), '', '' )?>
    • -
        -
    - - -
    - $role_name ) { - echo '
    '; - } - } - ?> -
    -
      -
    • -
        -
    - - - -
      -
    • Roles Editor%2$s.', 'profile-builder' ), '', '' )?>
    • -
        -
    - - -

    ', '' )?>

    -
    - - - -
      -
    • -
    • -
    • -
    -
    - - - -
      -
    • -
    -
    - - - -
    - - - - -

    -
    -
    - - $settings_value ){ - if( $settings_name == "minimum_password_length" || $settings_name == "activationLandingPage" ) - $wppb_generalSettings[$settings_name] = filter_var( $settings_value, FILTER_SANITIZE_NUMBER_INT ); - elseif( $settings_name == "extraFieldsLayout" || $settings_name == "emailConfirmation" || $settings_name == "adminApproval" || $settings_name == "loginWith" || $settings_name == "minimum_password_strength" ) - $wppb_generalSettings[$settings_name] = filter_var( $settings_value, FILTER_SANITIZE_STRING ); - elseif( $settings_name == "adminApprovalOnUserRole" ){ - if( is_array( $settings_value ) && !empty( $settings_value ) ){ - foreach( $settings_value as $key => $value ){ - $wppb_generalSettings[$settings_name][$key] = filter_var( $value, FILTER_SANITIZE_STRING ); - } - } - } - } - } - - return $wppb_generalSettings; -} - - -/* - * Function that pushes settings errors to the user - * - * @since v.2.0.7 - */ -function wppb_general_settings_admin_notices() { - settings_errors( 'wppb_general_settings' ); -} -add_action( 'admin_notices', 'wppb_general_settings_admin_notices' ); - - -/* - * Function that return user roles - * - * @since v.2.2.0 - * - * @return array - */ -function wppb_adminApproval_onUserRole() { - global $wp_roles; - - $wp_roles = new WP_Roles(); - - $roles = $wp_roles->get_names(); - - unset( $roles['administrator'] ); - - return $roles; -} + 'default', 'emailConfirmation' => 'no', 'activationLandingPage' => '', 'adminApproval' => 'no', 'loginWith' => 'usernameemail', 'rolesEditor' => 'no' ) ); +} + + +/** + * Function that adds content to the "General Settings" submenu page + * + * @since v.2.0 + * + * @return string + */ +function wppb_general_settings_content() { + wppb_generate_default_settings_defaults(); +?> +
    +
    + + + +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
      +
    • '.dirname( dirname( plugin_basename( __FILE__ ) ) ).'\assets\css\style-front-end.css' ); ?>
    • +
    +
    + + + +
      +
    • + +
    • All Users > Email Confirmation%2$s.', 'profile-builder' ), '', '' )?>
    • + +
    +
    + + + +

    + +

    +
    + + + +
      +
    • All Users > Admin Approval%2$s.', 'profile-builder' ), '', '' )?>
    • +
        +
    + + +
    + $role_name ) { + echo '
    '; + } + } + ?> +
    +
      +
    • +
        +
    + + + +
      +
    • Roles Editor%2$s.', 'profile-builder' ), '', '' )?>
    • +
        +
    + + +

    ', '' )?>

    +
    + + + +
      +
    • +
    • +
    • +
    +
    + + + +
      +
    • +
    +
    + + + +
    + + + + +

    +
    +
    + + $settings_value ){ + if( $settings_name == "minimum_password_length" || $settings_name == "activationLandingPage" ) + $wppb_generalSettings[$settings_name] = filter_var( $settings_value, FILTER_SANITIZE_NUMBER_INT ); + elseif( $settings_name == "extraFieldsLayout" || $settings_name == "emailConfirmation" || $settings_name == "adminApproval" || $settings_name == "loginWith" || $settings_name == "minimum_password_strength" ) + $wppb_generalSettings[$settings_name] = filter_var( $settings_value, FILTER_SANITIZE_STRING ); + elseif( $settings_name == "adminApprovalOnUserRole" ){ + if( is_array( $settings_value ) && !empty( $settings_value ) ){ + foreach( $settings_value as $key => $value ){ + $wppb_generalSettings[$settings_name][$key] = filter_var( $value, FILTER_SANITIZE_STRING ); + } + } + } + } + } + + return $wppb_generalSettings; +} + + +/* + * Function that pushes settings errors to the user + * + * @since v.2.0.7 + */ +function wppb_general_settings_admin_notices() { + settings_errors( 'wppb_general_settings' ); +} +add_action( 'admin_notices', 'wppb_general_settings_admin_notices' ); + + +/* + * Function that return user roles + * + * @since v.2.2.0 + * + * @return array + */ +function wppb_adminApproval_onUserRole() { + global $wp_roles; + + $wp_roles = new WP_Roles(); + + $roles = $wp_roles->get_names(); + + unset( $roles['administrator'] ); + + return $roles; +} diff --git a/profile-builder/admin/manage-fields.php b/profile-builder/admin/manage-fields.php index 2999cd2..dbf92fc 100644 --- a/profile-builder/admin/manage-fields.php +++ b/profile-builder/admin/manage-fields.php @@ -1,1381 +1,1381 @@ - __( 'Manage Fields', 'profile-builder' ), - 'page_title' => __( 'Manage Default and Extra Fields', 'profile-builder' ), - 'menu_slug' => 'manage-fields', - 'page_type' => 'submenu_page', - 'capability' => 'manage_options', - 'priority' => 5, - 'parent_slug' => 'profile-builder' - ); - $all_fields = new WCK_Page_Creator_PB( $args ); - - - // populate this page - $manage_field_types[] = 'Default - Name (Heading)'; - $manage_field_types[] = 'Default - Contact Info (Heading)'; - $manage_field_types[] = 'Default - About Yourself (Heading)'; - $manage_field_types[] = 'Default - Username'; - $manage_field_types[] = 'Default - First Name'; - $manage_field_types[] = 'Default - Last Name'; - $manage_field_types[] = 'Default - Nickname'; - $manage_field_types[] = 'Default - E-mail'; - $manage_field_types[] = 'Default - Website'; - - // Default contact methods were removed in WP 3.6. A filter dictates contact methods. - if ( apply_filters( 'wppb_remove_default_contact_methods', get_site_option( 'initial_db_version' ) < 23588 ) ){ - $manage_field_types[] = 'Default - AIM'; - $manage_field_types[] = 'Default - Yahoo IM'; - $manage_field_types[] = 'Default - Jabber / Google Talk'; - } - - $manage_field_types[] = 'Default - Password'; - $manage_field_types[] = 'Default - Repeat Password'; - $manage_field_types[] = 'Default - Biographical Info'; - $manage_field_types[] = 'Default - Display name publicly as'; - if ( wppb_can_users_signup_blog() ) { - $manage_field_types[] = 'Default - Blog Details'; - } - - /* added recaptcha and user role field since version 2.6.2 */ - $manage_field_types[] = 'reCAPTCHA'; - $manage_field_types[] = 'Select (User Role)'; - - if( PROFILE_BUILDER != 'Profile Builder Free' ) { - $manage_field_types[] = 'Heading'; - $manage_field_types[] = 'Input'; - $manage_field_types[] = 'Number'; - $manage_field_types[] = 'Input (Hidden)'; - $manage_field_types[] = 'Textarea'; - $manage_field_types[] = 'WYSIWYG'; - $manage_field_types[] = 'Phone'; - $manage_field_types[] = 'Select'; - $manage_field_types[] = 'Select (Multiple)'; - $manage_field_types[] = 'Select (Country)'; - $manage_field_types[] = 'Select (Timezone)'; - $manage_field_types[] = 'Select (Currency)'; - $manage_field_types[] = 'Select (CPT)'; - $manage_field_types[] = 'Checkbox'; - $manage_field_types[] = 'Checkbox (Terms and Conditions)'; - $manage_field_types[] = 'Radio'; - $manage_field_types[] = 'Upload'; - $manage_field_types[] = 'Avatar'; - $manage_field_types[] = 'Datepicker'; - $manage_field_types[] = 'Timepicker'; - $manage_field_types[] = 'Colorpicker'; - $manage_field_types[] = 'Validation'; - $manage_field_types[] = 'Map'; - $manage_field_types[] = 'HTML'; - } - - - //Free to Pro call to action on Manage Fields page - $field_description = __('Choose one of the supported field types','profile-builder'); - /*if( PROFILE_BUILDER == 'Profile Builder Free' ) { - $field_description .= sprintf( __('. Extra Field Types are available in Hobbyist or PRO versions.' , 'profile-builder'), esc_url( 'https://www.cozmoslabs.com/wordpress-profile-builder/?utm_source=wpbackend&utm_medium=clientsite&utm_content=manage-fields-link&utm_campaign=PBFree' ) ); - }*/ - - - //user roles - global $wp_roles; - - $user_roles = array(); - foreach( $wp_roles->roles as $user_role_slug => $user_role ) - if( $user_role_slug !== 'administrator' ) - array_push( $user_roles, '%' . $user_role['name'] . '%' . $user_role_slug ); - - - // country select - $default_country_array = wppb_country_select_options( 'back_end' ); - foreach( $default_country_array as $iso_country_code => $country_name ) { - $default_country_values[] = $iso_country_code; - $default_country_options[] = $country_name; - } - - // currency select - $default_currency_array = wppb_get_currencies( 'back_end' ); - array_unshift( $default_currency_array, '' ); - foreach( $default_currency_array as $iso_currency_code => $currency_name ) { - $default_currency_values[] = $iso_currency_code; - $default_currency_options[] = $currency_name; - } - - //cpt select - $post_types = get_post_types( array( 'public' => true ), 'names' ); - - // set up the fields array - $fields = apply_filters( 'wppb_manage_fields', array( - - array( 'type' => 'text', 'slug' => 'field-title', 'title' => __( 'Field Title', 'profile-builder' ), 'description' => __( 'Title of the field', 'profile-builder' ) ), - array( 'type' => 'select', 'slug' => 'field', 'title' => __( 'Field', 'profile-builder' ), 'options' => apply_filters( 'wppb_manage_fields_types', $manage_field_types ), 'default-option' => true, 'description' => $field_description ), - array( 'type' => 'text', 'slug' => 'meta-name', 'title' => __( 'Meta-name', 'profile-builder' ), 'default' => wppb_get_meta_name(), 'description' => __( 'Use this in conjunction with WordPress functions to display the value in the page of your choosing
    Auto-completed but in some cases editable (in which case it must be unique)
    Changing this might take long in case of a very big user-count', 'profile-builder' ) ), - array( 'type' => 'text', 'slug' => 'id', 'title' => __( 'ID', 'profile-builder' ), 'default' => wppb_get_unique_id(), 'description' => __( "A unique, auto-generated ID for this particular field
    You can use this in conjuction with filters to target this element if needed
    Can't be edited", 'profile-builder' ), 'readonly' => true ), - array( 'type' => 'textarea', 'slug' => 'description', 'title' => __( 'Description', 'profile-builder' ), 'description' => __( 'Enter a (detailed) description of the option for end users to read
    Optional', 'profile-builder') ), - array( 'type' => 'text', 'slug' => 'row-count', 'title' => __( 'Row Count', 'profile-builder' ), 'default' => 5, 'description' => __( "Specify the number of rows for a 'Textarea' field
    If not specified, defaults to 5", 'profile-builder' ) ), - array( 'type' => 'text', 'slug' => 'allowed-image-extensions', 'title' => __( 'Allowed Image Extensions', 'profile-builder' ), 'default' => '.*', 'description' => __( 'Specify the extension(s) you want to limit to upload
    Example: .ext1,.ext2,.ext3
    If not specified, defaults to: .jpg,.jpeg,.gif,.png (.*)', 'profile-builder' ) ), - array( 'type' => 'text', 'slug' => 'allowed-upload-extensions', 'title' => __( 'Allowed Upload Extensions', 'profile-builder' ), 'default' => '.*', 'description' => __( 'Specify the extension(s) you want to limit to upload
    Example: .ext1,.ext2,.ext3
    If not specified, defaults to all WordPress allowed file extensions (.*)', 'profile-builder' ) ), - array( 'type' => 'text', 'slug' => 'avatar-size', 'title' => __( 'Avatar Size', 'profile-builder' ), 'default' => 100, 'description' => __( "Enter a value (between 20 and 200) for the size of the 'Avatar'
    If not specified, defaults to 100", 'profile-builder' ) ), - array( 'type' => 'text', 'slug' => 'date-format', 'title' => __( 'Date-format', 'profile-builder' ), 'default' => 'mm/dd/yy', 'description' => __( 'Specify the format of the date when using Datepicker
    Valid options: mm/dd/yy, mm/yy/dd, dd/yy/mm, dd/mm/yy, yy/dd/mm, yy/mm/dd, mm-dd-yy, yy-mm-dd, D, dd M yy, D, d M y, DD, dd-M-y, D, d M yy, @
    If not specified, defaults to mm/dd/yy', 'profile-builder' ) ), - array( 'type' => 'textarea', 'slug' => 'terms-of-agreement', 'title' => __( 'Terms of Agreement', 'profile-builder' ), 'description' => __( 'Enter a detailed description of the temrs of agreement for the user to read.
    Links can be inserted by using standard HTML syntax: <a href="custom_url">custom_text</a>', 'profile-builder' ) ), - array( 'type' => 'text', 'slug' => 'options', 'title' => __( 'Options', 'profile-builder' ), 'description' => __( "Enter a comma separated list of values
    This can be anything, as it is hidden from the user, but should not contain special characters or apostrophes", 'profile-builder' ) ), - array( 'type' => 'text', 'slug' => 'labels', 'title' => __( 'Labels', 'profile-builder' ), 'description' => __( "Enter a comma separated list of labels
    Visible for the user", 'profile-builder' ) ), - array( 'type' => 'text', 'slug' => 'public-key', 'title' => __( 'Site Key', 'profile-builder' ), 'description' => __( 'The site key from Google, www.google.com/recaptcha', 'profile-builder' ) ), - array( 'type' => 'text', 'slug' => 'private-key', 'title' => __( 'Secret Key', 'profile-builder' ), 'description' => __( 'The secret key from Google, www.google.com/recaptcha', 'profile-builder' ) ), - array( 'type' => 'checkbox', 'slug' => 'captcha-pb-forms', 'title' => __( 'Display on PB forms', 'profile-builder' ), 'options' => array( '%'.__('PB Login','profile-builder').'%'.'pb_login', '%'.__('PB Register','profile-builder').'%'.'pb_register', '%'.__('PB Recover Password','profile-builder').'%'.'pb_recover_password' ), 'default' => 'pb_register', 'description' => __( "Select on which Profile Builder forms to display reCAPTCHA", 'profile-builder' ) ), - array( 'type' => 'checkbox', 'slug' => 'captcha-wp-forms', 'title' => __( 'Display on default WP forms', 'profile-builder' ), 'options' => array( '%'.__('Default WP Login', 'profile-builder').'%'.'default_wp_login', '%'.__('Default WP Register', 'profile-builder').'%'.'default_wp_register', '%'.__('Default WP Recover Password', 'profile-builder').'%'.'default_wp_recover_password'), 'default' => 'default_wp_register', 'description' => __( "Select on which default WP forms to display reCAPTCHA", 'profile-builder' ) ), - array( 'type' => 'checkbox', 'slug' => 'user-roles', 'title' => __( 'User Roles', 'profile-builder' ), 'options' => $user_roles, 'description' => __( "Select which user roles to show to the user ( drag and drop to re-order )", 'profile-builder' ) ), - array( 'type' => 'text', 'slug' => 'user-roles-sort-order', 'title' => __( 'User Roles Order', 'profile-builder' ), 'description' => __( "Save the user role order from the user roles checkboxes", 'profile-builder' ) ), - array( 'type' => 'text', 'slug' => 'default-value', 'title' => __( 'Default Value', 'profile-builder' ), 'description' => __( "Default value of the field", 'profile-builder' ) ), - array( 'type' => 'text', 'slug' => 'default-option', 'title' => __( 'Default Option', 'profile-builder' ), 'description' => __( "Specify the option which should be selected by default", 'profile-builder' ) ), - array( 'type' => 'text', 'slug' => 'default-options', 'title' => __( 'Default Option(s)', 'profile-builder' ), 'description' => __( "Specify the option which should be checked by default
    If there are multiple values, separate them with a ',' (comma)", 'profile-builder' ) ), - array( 'type' => 'select', 'slug' => 'default-option-country', 'title' => __( 'Default Option', 'profile-builder' ), 'values' => ( isset( $default_country_values ) ) ? $default_country_values : '', 'options' => ( isset( $default_country_options ) ) ? $default_country_options : '', 'description' => __( "Default option of the field", 'profile-builder' ) ), - array( 'type' => 'select', 'slug' => 'default-option-timezone', 'title' => __( 'Default Option', 'profile-builder' ), 'options' => wppb_timezone_select_options( 'back_end' ), 'description' => __( "Default option of the field", 'profile-builder' ) ), - array( 'type' => 'select', 'slug' => 'default-option-currency', 'title' => __( 'Default Option', 'profile-builder' ), 'values' => ( isset( $default_currency_values ) ) ? $default_currency_values : '', 'options' => ( isset( $default_currency_options ) ) ? $default_currency_options : '', 'description' => __( "Default option of the field", 'profile-builder' ) ), - array( 'type' => 'select', 'slug' => 'show-currency-symbol', 'title' => __( 'Show Currency Symbol', 'profile-builder' ), 'options' => array( 'No', 'Yes' ), 'default' => 'No', 'description' => __( 'Whether the currency symbol should be displayed after the currency name in the select option.', 'profile-builder' ) ), - array( 'type' => 'select', 'slug' => 'cpt', 'title' => __( 'Show Post Type', 'profile-builder' ), 'options' => $post_types, 'default' => 'post', 'description' => __( 'Posts from what post type will be displayed in the select.', 'profile-builder' ) ), - array( 'type' => 'text', 'slug' => 'validation-possible-values', 'title' => __( 'Allowable Values', 'profile-builder' ), 'description' => __( "Enter a comma separated list of possible values. Upon registration if the value provided by the user does not match one of these values, the user will not be registered.", 'profile-builder' ) ), - array( 'type' => 'text', 'slug' => 'custom-error-message', 'title' => __( 'Error Message', 'profile-builder' ), 'description' => __( "Set a custom error message that will be displayed to the user.", 'profile-builder' ) ), - array( 'type' => 'select', 'slug' => 'time-format', 'title' => __( 'Time Format', 'profile-builder' ), 'options' => array( '%12 Hours%12', '%24 Hours%24' ), 'description' => __( 'Specify the time format.', 'profile-builder' ) ), - array( 'type' => 'text', 'slug' => 'map-api-key', 'title' => __( 'Google Maps API Key', 'profile-builder' ), 'description' => __( 'Enter your Google Maps API key ( Get your API key ). If more than one map fields are added to a form the API key from the first map displayed will be used.', 'profile-builder' ) ), - array( 'type' => 'text', 'slug' => 'map-default-lat', 'title' => __( 'Default Latitude', 'profile-builder' ), 'description' => __( "The latitude at which the map should be displayed when no pins are attached.", 'profile-builder' ) ), - array( 'type' => 'text', 'slug' => 'map-default-lng', 'title' => __( 'Default Longitude', 'profile-builder' ), 'description' => __( "The longitude at which the map should be displayed when no pins are attached.", 'profile-builder' ) ), - array( 'type' => 'text', 'slug' => 'map-default-zoom', 'title' => __( 'Default Zoom Level', 'profile-builder' ), 'description' => __( "Add a number from 0 to 19. The higher the number the higher the zoom.", 'profile-builder' ), 'default' => 16 ), - array( 'type' => 'text', 'slug' => 'map-height', 'title' => __( 'Map Height', 'profile-builder' ), 'description' => __( "The height of the map.", 'profile-builder' ), 'default' => 400 ), - array( 'type' => 'textarea', 'slug' => 'default-content', 'title' => __( 'Default Content', 'profile-builder' ), 'description' => __( "Default value of the textarea", 'profile-builder' ) ), - array( 'type' => 'textarea', 'slug' => 'html-content', 'title' => __( 'HTML Content', 'profile-builder' ), 'description' => __( "Add your HTML (or text) content", 'profile-builder' ) ), - array( 'type' => 'text', 'slug' => 'phone-format', 'title' => __( 'Phone Format', 'profile-builder' ), 'default' => '(###) ###-####', 'description' => __( "You can use: # for numbers, parentheses ( ), - sign, + sign, dot . and spaces.", 'profile-builder' ) .'
    '. __( "Eg. (###) ###-####", 'profile-builder' ) .'
    '. __( "Empty field won't check for correct phone number.", 'profile-builder' ) ), - array( 'type' => 'select', 'slug' => 'heading-tag', 'title' => __( 'Heading Tag', 'profile-builder' ), 'options' => array( '%h1 - biggest size%h1', 'h2', 'h3', 'h4', 'h5', '%h6 - smallest size%h6' ), 'default' => 'h4', 'description' => __( 'Change heading field size on front-end forms', 'profile-builder' ) ), - array( 'type' => 'text', 'slug' => 'min-number-value', 'title' => __( 'Min Number Value', 'profile-builder' ), 'description' => __( "Min allowed number value (0 to allow only positive numbers)", 'profile-builder' ) .'
    '. __( "Leave it empty for no min value", 'profile-builder' ) ), - array( 'type' => 'text', 'slug' => 'max-number-value', 'title' => __( 'Max Number Value', 'profile-builder' ), 'description' => __( "Max allowed number value (0 to allow only negative numbers)", 'profile-builder' ) .'
    '. __( "Leave it empty for no max value", 'profile-builder' ) ), - array( 'type' => 'text', 'slug' => 'number-step-value', 'title' => __( 'Number Step Value', 'profile-builder' ), 'description' => __( "Step value 1 to allow only integers, 0.1 to allow integers and numbers with 1 decimal", 'profile-builder' ) .'
    '. __( "To allow multiple decimals use for eg. 0.01 (for 2 deciamls) and so on", 'profile-builder' ) .'
    '. __( "You can also use step value to specify the legal number intervals (eg. step value 2 will allow only -4, -2, 0, 2 and so on)", 'profile-builder' ) .'
    '. __( "Leave it empty for no restriction", 'profile-builder' ) ), - array( 'type' => 'select', 'slug' => 'required', 'title' => __( 'Required', 'profile-builder' ), 'options' => array( 'No', 'Yes' ), 'default' => 'No', 'description' => __( 'Whether the field is required or not', 'profile-builder' ) ), - array( 'type' => 'select', 'slug' => 'overwrite-existing', 'title' => __( 'Overwrite Existing', 'profile-builder' ), 'options' => array( 'No', 'Yes' ), 'default' => 'No', 'description' => __( "Selecting 'Yes' will add the field to the list, but will overwrite any other field in the database that has the same meta-name
    Use this at your own risk", 'profile-builder' ) ), - ) ); - - // create the new submenu with the above options - $args = array( - 'metabox_id' => 'manage-fields', - 'metabox_title' => __( 'Field Properties', 'profile-builder' ), - 'post_type' => 'manage-fields', - 'meta_name' => 'wppb_manage_fields', - 'meta_array' => $fields, - 'context' => 'option' - ); - new Wordpress_Creation_Kit_PB( $args ); - - /* this is redundant but it should have a very low impact and for comfort we leave it here as well */ - wppb_prepopulate_fields(); - - // create the info side meta-box - $args = array( - 'metabox_id' => 'manage-fields-info', - 'metabox_title' => __( 'Registration & Edit Profile', 'profile-builder' ), - 'post_type' => 'manage-fields', - 'meta_name' => 'wppb_manage_fields_info', - 'meta_array' => '', - 'context' => 'option', - 'mb_context' => 'side' - ); - new Wordpress_Creation_Kit_PB( $args ); -} -add_action( 'init', 'wppb_manage_fields_submenu', 10 ); - -/** - * Function that prepopulates the manage fields list with the default fields of WP - * - * @since v.2.0 - * - * @return void - */ -function wppb_prepopulate_fields(){ - $prepopulated_fields[] = array( 'field' => 'Default - Name (Heading)', 'field-title' => __( 'Name', 'profile-builder' ), 'meta-name' => '', 'overwrite-existing' => 'No', 'id' => '1', 'description' => '', 'row-count' => '5', 'allowed-image-extensions' => '.*', 'allowed-upload-extensions' => '.*', 'avatar-size' => '100', 'date-format' => 'mm/dd/yy', 'terms-of-agreement' => '', 'options' => '', 'labels' => '', 'public-key' => '', 'private-key' => '', 'default-value' => '', 'default-option' => '', 'default-options' => '', 'default-content' => '', 'required' => 'No' ); - $prepopulated_fields[] = array( 'field' => 'Default - Username', 'field-title' => __( 'Username', 'profile-builder' ), 'meta-name' => '', 'overwrite-existing' => 'No', 'id' => '2', 'description' => __( 'Usernames cannot be changed.', 'profile-builder' ), 'row-count' => '5', 'allowed-image-extensions' => '.*', 'allowed-upload-extensions' => '.*', 'avatar-size' => '100', 'date-format' => 'mm/dd/yy', 'terms-of-agreement' => '', 'options' => '', 'labels' => '', 'public-key' => '', 'private-key' => '', 'default-value' => '', 'default-option' => '', 'default-options' => '', 'default-content' => '', 'required' => 'Yes' ); - $prepopulated_fields[] = array( 'field' => 'Default - First Name', 'field-title' => __( 'First Name', 'profile-builder' ), 'meta-name' => 'first_name', 'overwrite-existing' => 'No', 'id' => '3', 'description' => '', 'row-count' => '5', 'allowed-image-extensions' => '.*', 'allowed-upload-extensions' => '.*', 'avatar-size' => '100', 'date-format' => 'mm/dd/yy', 'terms-of-agreement' => '', 'options' => '', 'labels' => '', 'public-key' => '', 'private-key' => '', 'default-value' => '', 'default-option' => '', 'default-options' => '', 'default-content' => '', 'required' => 'No' ); - $prepopulated_fields[] = array( 'field' => 'Default - Last Name', 'field-title' => __( 'Last Name', 'profile-builder' ), 'meta-name' => 'last_name', 'overwrite-existing' => 'No', 'id' => '4', 'description' => '', 'row-count' => '5', 'allowed-image-extensions' => '.*', 'allowed-upload-extensions' => '.*', 'avatar-size' => '100', 'date-format' => 'mm/dd/yy', 'terms-of-agreement' => '', 'options' => '', 'labels' => '', 'public-key' => '', 'private-key' => '', 'default-value' => '', 'default-option' => '', 'default-options' => '', 'default-content' => '', 'required' => 'No' ); - $prepopulated_fields[] = array( 'field' => 'Default - Nickname', 'field-title' => __( 'Nickname', 'profile-builder' ), 'meta-name' => 'nickname', 'overwrite-existing' => 'No', 'id' => '5', 'description' => '', 'row-count' => '5', 'allowed-image-extensions' => '.*', 'allowed-upload-extensions' => '.*', 'avatar-size' => '100', 'date-format' => 'mm/dd/yy', 'terms-of-agreement' => '', 'options' => '', 'labels' => '', 'public-key' => '', 'private-key' => '', 'default-value' => '', 'default-option' => '', 'default-options' => '', 'default-content' => '', 'required' => 'Yes' ); - $prepopulated_fields[] = array( 'field' => 'Default - Display name publicly as', 'field-title' => __( 'Display name publicly as', 'profile-builder' ), 'meta-name' => '', 'overwrite-existing' => 'No', 'id' => '6', 'description' => '', 'row-count' => '5', 'allowed-image-extensions' => '.*', 'allowed-upload-extensions' => '.*', 'avatar-size' => '100', 'date-format' => 'mm/dd/yy', 'terms-of-agreement' => '', 'options' => '', 'labels' => '', 'public-key' => '', 'private-key' => '', 'default-value' => '', 'default-option' => '', 'default-options' => '', 'default-content' => '', 'required' => 'No' ); - $prepopulated_fields[] = array( 'field' => 'Default - Contact Info (Heading)', 'field-title' => __( 'Contact Info', 'profile-builder' ), 'meta-name' => '', 'overwrite-existing' => 'No', 'id' => '7', 'description' => '', 'row-count' => '5', 'allowed-image-extensions' => '.*', 'allowed-upload-extensions' => '.*', 'avatar-size' => '100', 'date-format' => 'mm/dd/yy', 'terms-of-agreement' => '', 'options' => '', 'labels' => '', 'public-key' => '', 'private-key' => '', 'default-value' => '', 'default-option' => '', 'default-options' => '', 'default-content' => '', 'required' => 'No' ); - $prepopulated_fields[] = array( 'field' => 'Default - E-mail', 'field-title' => __( 'E-mail', 'profile-builder' ), 'meta-name' => '', 'overwrite-existing' => 'No', 'id' => '8', 'description' => '', 'row-count' => '5', 'allowed-image-extensions' => '.*', 'allowed-upload-extensions' => '.*', 'avatar-size' => '100', 'date-format' => 'mm/dd/yy', 'terms-of-agreement' => '', 'options' => '', 'labels' => '', 'public-key' => '', 'private-key' => '', 'default-value' => '', 'default-option' => '', 'default-options' => '', 'default-content' => '', 'required' => 'Yes' ); - $prepopulated_fields[] = array( 'field' => 'Default - Website', 'field-title' => __( 'Website', 'profile-builder' ), 'meta-name' => '', 'overwrite-existing' => 'No', 'id' => '9', 'description' => '', 'row-count' => '5', 'allowed-image-extensions' => '.*', 'allowed-upload-extensions' => '.*', 'avatar-size' => '100', 'date-format' => 'mm/dd/yy', 'terms-of-agreement' => '', 'options' => '', 'labels' => '', 'public-key' => '', 'private-key' => '', 'default-value' => '', 'default-option' => '', 'default-options' => '', 'default-content' => '', 'required' => 'No' ); - - // Default contact methods were removed in WP 3.6. A filter dictates contact methods. - if ( apply_filters( 'wppb_remove_default_contact_methods', get_site_option( 'initial_db_version' ) < 23588 ) ){ - $prepopulated_fields[] = array( 'field' => 'Default - AIM', 'field-title' => __( 'AIM', 'profile-builder' ), 'meta-name' => 'aim', 'overwrite-existing' => 'No', 'id' => '10', 'description' => '', 'row-count' => '5', 'allowed-image-extensions' => '.*', 'allowed-upload-extensions' => '.*', 'avatar-size' => '100', 'date-format' => 'mm/dd/yy', 'terms-of-agreement' => '', 'options' => '', 'labels' => '', 'public-key' => '', 'private-key' => '', 'default-value' => '', 'default-option' => '', 'default-options' => '', 'default-content' => '', 'required' => 'No' ); - $prepopulated_fields[] = array( 'field' => 'Default - Yahoo IM', 'field-title' => __( 'Yahoo IM', 'profile-builder' ), 'meta-name' => 'yim', 'overwrite-existing' => 'No', 'id' => '11', 'description' => '', 'row-count' => '5', 'allowed-image-extensions' => '.*', 'allowed-upload-extensions' => '.*', 'avatar-size' => '100', 'date-format' => 'mm/dd/yy', 'terms-of-agreement' => '', 'options' => '', 'labels' => '', 'public-key' => '', 'private-key' => '', 'default-value' => '', 'default-option' => '', 'default-options' => '', 'default-content' => '', 'required' => 'No' ); - $prepopulated_fields[] = array( 'field' => 'Default - Jabber / Google Talk', 'field-title' => __( 'Jabber / Google Talk', 'profile-builder' ), 'meta-name' => 'jabber', 'overwrite-existing' => 'No', 'id' => '12', 'description' => '', 'row-count' => '5', 'allowed-image-extensions' => '.*', 'allowed-upload-extensions' => '.*', 'avatar-size' => '100', 'date-format' => 'mm/dd/yy', 'terms-of-agreement' => '', 'options' => '', 'labels' => '', 'public-key' => '', 'private-key' => '', 'default-value' => '', 'default-option' => '', 'default-options' => '', 'default-content' => '', 'required' => 'No' ); - } - - $prepopulated_fields[] = array( 'field' => 'Default - About Yourself (Heading)', 'field-title' => __( 'About Yourself', 'profile-builder' ), 'meta-name' => '', 'overwrite-existing' => 'No', 'id' => '13', 'description' => '', 'row-count' => '5', 'allowed-image-extensions' => '.*', 'allowed-upload-extensions' => '.*', 'avatar-size' => '100', 'date-format' => 'mm/dd/yy', 'terms-of-agreement' => '', 'options' => '', 'labels' => '', 'public-key' => '', 'private-key' => '', 'default-value' => '', 'default-option' => '', 'default-options' => '', 'default-content' => '', 'required' => 'No' ); - $prepopulated_fields[] = array( 'field' => 'Default - Biographical Info', 'field-title' => __( 'Biographical Info', 'profile-builder' ), 'meta-name' => 'description', 'overwrite-existing' => 'No', 'id' => '14', 'description' => __( 'Share a little biographical information to fill out your profile. This may be shown publicly.', 'profile-builder' ), 'row-count' => '5', 'allowed-image-extensions' => '.*', 'allowed-upload-extensions' => '.*', 'avatar-size' => '100', 'date-format' => 'mm/dd/yy', 'terms-of-agreement' => '', 'options' => '', 'labels' => '', 'public-key' => '', 'private-key' => '', 'default-value' => '', 'default-option' => '', 'default-options' => '', 'required' => 'No' ); - $prepopulated_fields[] = array( 'field' => 'Default - Password', 'field-title' => __( 'Password', 'profile-builder' ), 'meta-name' => '', 'overwrite-existing' => 'No', 'id' => '15', 'description' => __( 'Type your password.', 'profile-builder' ), 'row-count' => '5', 'allowed-image-extensions' => '.*', 'allowed-upload-extensions' => '.*', 'avatar-size' => '100', 'date-format' => 'mm/dd/yy', 'terms-of-agreement' => '', 'options' => '', 'labels' => '', 'public-key' => '', 'private-key' => '', 'default-value' => '', 'default-option' => '', 'default-options' => '', 'default-content' => '', 'required' => 'Yes' ); - $prepopulated_fields[] = array( 'field' => 'Default - Repeat Password', 'field-title' => __( 'Repeat Password', 'profile-builder' ), 'meta-name' => '', 'overwrite-existing' => 'No', 'id' => '16', 'description' => __( 'Type your password again. ', 'profile-builder' ), 'row-count' => '5', 'allowed-image-extensions' => '.*', 'allowed-upload-extensions' => '.*', 'avatar-size' => '100', 'date-format' => 'mm/dd/yy', 'terms-of-agreement' => '', 'options' => '', 'labels' => '', 'public-key' => '', 'private-key' => '', 'default-value' => '', 'default-option' => '', 'default-options' => '', 'default-content' => '', 'required' => 'Yes' ); - if ( wppb_can_users_signup_blog() ){ - $prepopulated_fields[] = array( 'field' => 'Default - Blog Details', 'field-title' => __( 'Blog Details', 'profile-builder' ), 'meta-name' => '', 'overwrite-existing' => 'No', 'id' => '17', 'description' => '', 'row-count' => '5', 'allowed-image-extensions' => '.*', 'allowed-upload-extensions' => '.*', 'avatar-size' => '100', 'date-format' => 'mm/dd/yy', 'terms-of-agreement' => '', 'options' => '', 'labels' => '', 'public-key' => '', 'private-key' => '', 'default-value' => '', 'default-option' => '', 'default-options' => '', 'default-content' => '', 'required' => 'No' ); - } - - add_option ( 'wppb_manage_fields', apply_filters ( 'wppb_prepopulated_fields', $prepopulated_fields ) ); -} - -/** - * Function that returns a unique meta-name - * - * @since v.2.0 - * - * @return string - */ -function wppb_get_meta_name( $option = 'wppb_manage_fields', $prefix = 'custom_field_' ){ - $id = 1; - - $wppb_manage_fields = get_option( $option, 'not_found' ); - - if ( ( $wppb_manage_fields === 'not_found' ) || ( empty( $wppb_manage_fields ) ) ){ - return $prefix . $id; - } - else{ - $meta_names = array(); - foreach( $wppb_manage_fields as $value ){ - if ( strpos( $value['meta-name'], $prefix ) === 0 ){ - $meta_names[] = $value['meta-name']; - } - } - - if( !empty( $meta_names ) ){ - $meta_numbers = array(); - foreach( $meta_names as $meta_name ){ - $number = str_replace( $prefix, '', $meta_name ); - /* we should have an underscore present in custom_field_# so remove it */ - $number = str_replace( '_', '', $number ); - - $meta_numbers[] = $number; - } - if( !empty( $meta_numbers ) ){ - rsort( $meta_numbers ); - $id = $meta_numbers[0]++; - } - } - - return $prefix . $id; - } -} - - -/** - * Function that returns an array with countries - * - * @since v.2.0 - * - * @return array - */ -function wppb_country_select_options( $form_location ) { - $country_array = apply_filters( 'wppb_'.$form_location.'_country_select_array', - array( - '' => '', - 'AF' => __( 'Afghanistan', 'profile-builder' ), - 'AX' => __( 'Aland Islands', 'profile-builder' ), - 'AL' => __( 'Albania', 'profile-builder' ), - 'DZ' => __( 'Algeria', 'profile-builder' ), - 'AS' => __( 'American Samoa', 'profile-builder' ), - 'AD' => __( 'Andorra', 'profile-builder' ), - 'AO' => __( 'Angola', 'profile-builder' ), - 'AI' => __( 'Anguilla', 'profile-builder' ), - 'AQ' => __( 'Antarctica', 'profile-builder' ), - 'AG' => __( 'Antigua and Barbuda', 'profile-builder' ), - 'AR' => __( 'Argentina', 'profile-builder' ), - 'AM' => __( 'Armenia', 'profile-builder' ), - 'AW' => __( 'Aruba', 'profile-builder' ), - 'AU' => __( 'Australia', 'profile-builder' ), - 'AT' => __( 'Austria', 'profile-builder' ), - 'AZ' => __( 'Azerbaijan', 'profile-builder' ), - 'BS' => __( 'Bahamas', 'profile-builder' ), - 'BH' => __( 'Bahrain', 'profile-builder' ), - 'BD' => __( 'Bangladesh', 'profile-builder' ), - 'BB' => __( 'Barbados', 'profile-builder' ), - 'BY' => __( 'Belarus', 'profile-builder' ), - 'BE' => __( 'Belgium', 'profile-builder' ), - 'BZ' => __( 'Belize', 'profile-builder' ), - 'BJ' => __( 'Benin', 'profile-builder' ), - 'BM' => __( 'Bermuda', 'profile-builder' ), - 'BT' => __( 'Bhutan', 'profile-builder' ), - 'BO' => __( 'Bolivia', 'profile-builder' ), - 'BQ' => __( 'Bonaire, Saint Eustatius and Saba', 'profile-builder' ), - 'BA' => __( 'Bosnia and Herzegovina', 'profile-builder' ), - 'BW' => __( 'Botswana', 'profile-builder' ), - 'BV' => __( 'Bouvet Island', 'profile-builder' ), - 'BR' => __( 'Brazil', 'profile-builder' ), - 'IO' => __( 'British Indian Ocean Territory', 'profile-builder' ), - 'VG' => __( 'British Virgin Islands', 'profile-builder' ), - 'BN' => __( 'Brunei', 'profile-builder' ), - 'BG' => __( 'Bulgaria', 'profile-builder' ), - 'BF' => __( 'Burkina Faso', 'profile-builder' ), - 'BI' => __( 'Burundi', 'profile-builder' ), - 'KH' => __( 'Cambodia', 'profile-builder' ), - 'CM' => __( 'Cameroon', 'profile-builder' ), - 'CA' => __( 'Canada', 'profile-builder' ), - 'CV' => __( 'Cape Verde', 'profile-builder' ), - 'KY' => __( 'Cayman Islands', 'profile-builder' ), - 'CF' => __( 'Central African Republic', 'profile-builder' ), - 'TD' => __( 'Chad', 'profile-builder' ), - 'CL' => __( 'Chile', 'profile-builder' ), - 'CN' => __( 'China', 'profile-builder' ), - 'CX' => __( 'Christmas Island', 'profile-builder' ), - 'CC' => __( 'Cocos Islands', 'profile-builder' ), - 'CO' => __( 'Colombia', 'profile-builder' ), - 'KM' => __( 'Comoros', 'profile-builder' ), - 'CK' => __( 'Cook Islands', 'profile-builder' ), - 'CR' => __( 'Costa Rica', 'profile-builder' ), - 'HR' => __( 'Croatia', 'profile-builder' ), - 'CU' => __( 'Cuba', 'profile-builder' ), - 'CW' => __( 'Curacao', 'profile-builder' ), - 'CY' => __( 'Cyprus', 'profile-builder' ), - 'CZ' => __( 'Czech Republic', 'profile-builder' ), - 'CD' => __( 'Democratic Republic of the Congo', 'profile-builder' ), - 'DK' => __( 'Denmark', 'profile-builder' ), - 'DJ' => __( 'Djibouti', 'profile-builder' ), - 'DM' => __( 'Dominica', 'profile-builder' ), - 'DO' => __( 'Dominican Republic', 'profile-builder' ), - 'TL' => __( 'East Timor', 'profile-builder' ), - 'EC' => __( 'Ecuador', 'profile-builder' ), - 'EG' => __( 'Egypt', 'profile-builder' ), - 'SV' => __( 'El Salvador', 'profile-builder' ), - 'GQ' => __( 'Equatorial Guinea', 'profile-builder' ), - 'ER' => __( 'Eritrea', 'profile-builder' ), - 'EE' => __( 'Estonia', 'profile-builder' ), - 'ET' => __( 'Ethiopia', 'profile-builder' ), - 'FK' => __( 'Falkland Islands', 'profile-builder' ), - 'FO' => __( 'Faroe Islands', 'profile-builder' ), - 'FJ' => __( 'Fiji', 'profile-builder' ), - 'FI' => __( 'Finland', 'profile-builder' ), - 'FR' => __( 'France', 'profile-builder' ), - 'GF' => __( 'French Guiana', 'profile-builder' ), - 'PF' => __( 'French Polynesia', 'profile-builder' ), - 'TF' => __( 'French Southern Territories', 'profile-builder' ), - 'GA' => __( 'Gabon', 'profile-builder' ), - 'GM' => __( 'Gambia', 'profile-builder' ), - 'GE' => __( 'Georgia', 'profile-builder' ), - 'DE' => __( 'Germany', 'profile-builder' ), - 'GH' => __( 'Ghana', 'profile-builder' ), - 'GI' => __( 'Gibraltar', 'profile-builder' ), - 'GR' => __( 'Greece', 'profile-builder' ), - 'GL' => __( 'Greenland', 'profile-builder' ), - 'GD' => __( 'Grenada', 'profile-builder' ), - 'GP' => __( 'Guadeloupe', 'profile-builder' ), - 'GU' => __( 'Guam', 'profile-builder' ), - 'GT' => __( 'Guatemala', 'profile-builder' ), - 'GG' => __( 'Guernsey', 'profile-builder' ), - 'GN' => __( 'Guinea', 'profile-builder' ), - 'GW' => __( 'Guinea-Bissau', 'profile-builder' ), - 'GY' => __( 'Guyana', 'profile-builder' ), - 'HT' => __( 'Haiti', 'profile-builder' ), - 'HM' => __( 'Heard Island and McDonald Islands', 'profile-builder' ), - 'HN' => __( 'Honduras', 'profile-builder' ), - 'HK' => __( 'Hong Kong', 'profile-builder' ), - 'HU' => __( 'Hungary', 'profile-builder' ), - 'IS' => __( 'Iceland', 'profile-builder' ), - 'IN' => __( 'India', 'profile-builder' ), - 'ID' => __( 'Indonesia', 'profile-builder' ), - 'IR' => __( 'Iran', 'profile-builder' ), - 'IQ' => __( 'Iraq', 'profile-builder' ), - 'IE' => __( 'Ireland', 'profile-builder' ), - 'IM' => __( 'Isle of Man', 'profile-builder' ), - 'IL' => __( 'Israel', 'profile-builder' ), - 'IT' => __( 'Italy', 'profile-builder' ), - 'CI' => __( 'Ivory Coast', 'profile-builder' ), - 'JM' => __( 'Jamaica', 'profile-builder' ), - 'JP' => __( 'Japan', 'profile-builder' ), - 'JE' => __( 'Jersey', 'profile-builder' ), - 'JO' => __( 'Jordan', 'profile-builder' ), - 'KZ' => __( 'Kazakhstan', 'profile-builder' ), - 'KE' => __( 'Kenya', 'profile-builder' ), - 'KI' => __( 'Kiribati', 'profile-builder' ), - 'XK' => __( 'Kosovo', 'profile-builder' ), - 'KW' => __( 'Kuwait', 'profile-builder' ), - 'KG' => __( 'Kyrgyzstan', 'profile-builder' ), - 'LA' => __( 'Laos', 'profile-builder' ), - 'LV' => __( 'Latvia', 'profile-builder' ), - 'LB' => __( 'Lebanon', 'profile-builder' ), - 'LS' => __( 'Lesotho', 'profile-builder' ), - 'LR' => __( 'Liberia', 'profile-builder' ), - 'LY' => __( 'Libya', 'profile-builder' ), - 'LI' => __( 'Liechtenstein', 'profile-builder' ), - 'LT' => __( 'Lithuania', 'profile-builder' ), - 'LU' => __( 'Luxembourg', 'profile-builder' ), - 'MO' => __( 'Macao', 'profile-builder' ), - 'MK' => __( 'Macedonia', 'profile-builder' ), - 'MG' => __( 'Madagascar', 'profile-builder' ), - 'MW' => __( 'Malawi', 'profile-builder' ), - 'MY' => __( 'Malaysia', 'profile-builder' ), - 'MV' => __( 'Maldives', 'profile-builder' ), - 'ML' => __( 'Mali', 'profile-builder' ), - 'MT' => __( 'Malta', 'profile-builder' ), - 'MH' => __( 'Marshall Islands', 'profile-builder' ), - 'MQ' => __( 'Martinique', 'profile-builder' ), - 'MR' => __( 'Mauritania', 'profile-builder' ), - 'MU' => __( 'Mauritius', 'profile-builder' ), - 'YT' => __( 'Mayotte', 'profile-builder' ), - 'MX' => __( 'Mexico', 'profile-builder' ), - 'FM' => __( 'Micronesia', 'profile-builder' ), - 'MD' => __( 'Moldova', 'profile-builder' ), - 'MC' => __( 'Monaco', 'profile-builder' ), - 'MN' => __( 'Mongolia', 'profile-builder' ), - 'ME' => __( 'Montenegro', 'profile-builder' ), - 'MS' => __( 'Montserrat', 'profile-builder' ), - 'MA' => __( 'Morocco', 'profile-builder' ), - 'MZ' => __( 'Mozambique', 'profile-builder' ), - 'MM' => __( 'Myanmar', 'profile-builder' ), - 'NA' => __( 'Namibia', 'profile-builder' ), - 'NR' => __( 'Nauru', 'profile-builder' ), - 'NP' => __( 'Nepal', 'profile-builder' ), - 'NL' => __( 'Netherlands', 'profile-builder' ), - 'NC' => __( 'New Caledonia', 'profile-builder' ), - 'NZ' => __( 'New Zealand', 'profile-builder' ), - 'NI' => __( 'Nicaragua', 'profile-builder' ), - 'NE' => __( 'Niger', 'profile-builder' ), - 'NG' => __( 'Nigeria', 'profile-builder' ), - 'NU' => __( 'Niue', 'profile-builder' ), - 'NF' => __( 'Norfolk Island', 'profile-builder' ), - 'KP' => __( 'North Korea', 'profile-builder' ), - 'MP' => __( 'Northern Mariana Islands', 'profile-builder' ), - 'NO' => __( 'Norway', 'profile-builder' ), - 'OM' => __( 'Oman', 'profile-builder' ), - 'PK' => __( 'Pakistan', 'profile-builder' ), - 'PW' => __( 'Palau', 'profile-builder' ), - 'PS' => __( 'Palestinian Territory', 'profile-builder' ), - 'PA' => __( 'Panama', 'profile-builder' ), - 'PG' => __( 'Papua New Guinea', 'profile-builder' ), - 'PY' => __( 'Paraguay', 'profile-builder' ), - 'PE' => __( 'Peru', 'profile-builder' ), - 'PH' => __( 'Philippines', 'profile-builder' ), - 'PN' => __( 'Pitcairn', 'profile-builder' ), - 'PL' => __( 'Poland', 'profile-builder' ), - 'PT' => __( 'Portugal', 'profile-builder' ), - 'PR' => __( 'Puerto Rico', 'profile-builder' ), - 'QA' => __( 'Qatar', 'profile-builder' ), - 'CG' => __( 'Republic of the Congo', 'profile-builder' ), - 'RE' => __( 'Reunion', 'profile-builder' ), - 'RO' => __( 'Romania', 'profile-builder' ), - 'RU' => __( 'Russia', 'profile-builder' ), - 'RW' => __( 'Rwanda', 'profile-builder' ), - 'BL' => __( 'Saint Barthelemy', 'profile-builder' ), - 'SH' => __( 'Saint Helena', 'profile-builder' ), - 'KN' => __( 'Saint Kitts and Nevis', 'profile-builder' ), - 'LC' => __( 'Saint Lucia', 'profile-builder' ), - 'MF' => __( 'Saint Martin', 'profile-builder' ), - 'PM' => __( 'Saint Pierre and Miquelon', 'profile-builder' ), - 'VC' => __( 'Saint Vincent and the Grenadines', 'profile-builder' ), - 'WS' => __( 'Samoa', 'profile-builder' ), - 'SM' => __( 'San Marino', 'profile-builder' ), - 'ST' => __( 'Sao Tome and Principe', 'profile-builder' ), - 'SA' => __( 'Saudi Arabia', 'profile-builder' ), - 'SN' => __( 'Senegal', 'profile-builder' ), - 'RS' => __( 'Serbia', 'profile-builder' ), - 'SC' => __( 'Seychelles', 'profile-builder' ), - 'SL' => __( 'Sierra Leone', 'profile-builder' ), - 'SG' => __( 'Singapore', 'profile-builder' ), - 'SX' => __( 'Sint Maarten', 'profile-builder' ), - 'SK' => __( 'Slovakia', 'profile-builder' ), - 'SI' => __( 'Slovenia', 'profile-builder' ), - 'SB' => __( 'Solomon Islands', 'profile-builder' ), - 'SO' => __( 'Somalia', 'profile-builder' ), - 'ZA' => __( 'South Africa', 'profile-builder' ), - 'GS' => __( 'South Georgia and the South Sandwich Islands', 'profile-builder' ), - 'KR' => __( 'South Korea', 'profile-builder' ), - 'SS' => __( 'South Sudan', 'profile-builder' ), - 'ES' => __( 'Spain', 'profile-builder' ), - 'LK' => __( 'Sri Lanka', 'profile-builder' ), - 'SD' => __( 'Sudan', 'profile-builder' ), - 'SR' => __( 'Suriname', 'profile-builder' ), - 'SJ' => __( 'Svalbard and Jan Mayen', 'profile-builder' ), - 'SZ' => __( 'Swaziland', 'profile-builder' ), - 'SE' => __( 'Sweden', 'profile-builder' ), - 'CH' => __( 'Switzerland', 'profile-builder' ), - 'SY' => __( 'Syria', 'profile-builder' ), - 'TW' => __( 'Taiwan', 'profile-builder' ), - 'TJ' => __( 'Tajikistan', 'profile-builder' ), - 'TZ' => __( 'Tanzania', 'profile-builder' ), - 'TH' => __( 'Thailand', 'profile-builder' ), - 'TG' => __( 'Togo', 'profile-builder' ), - 'TK' => __( 'Tokelau', 'profile-builder' ), - 'TO' => __( 'Tonga', 'profile-builder' ), - 'TT' => __( 'Trinidad and Tobago', 'profile-builder' ), - 'TN' => __( 'Tunisia', 'profile-builder' ), - 'TR' => __( 'Turkey', 'profile-builder' ), - 'TM' => __( 'Turkmenistan', 'profile-builder' ), - 'TC' => __( 'Turks and Caicos Islands', 'profile-builder' ), - 'TV' => __( 'Tuvalu', 'profile-builder' ), - 'VI' => __( 'U.S. Virgin Islands', 'profile-builder' ), - 'UG' => __( 'Uganda', 'profile-builder' ), - 'UA' => __( 'Ukraine', 'profile-builder' ), - 'AE' => __( 'United Arab Emirates', 'profile-builder' ), - 'GB' => __( 'United Kingdom', 'profile-builder' ), - 'US' => __( 'United States', 'profile-builder' ), - 'UM' => __( 'United States Minor Outlying Islands', 'profile-builder' ), - 'UY' => __( 'Uruguay', 'profile-builder' ), - 'UZ' => __( 'Uzbekistan', 'profile-builder' ), - 'VU' => __( 'Vanuatu', 'profile-builder' ), - 'VA' => __( 'Vatican', 'profile-builder' ), - 'VE' => __( 'Venezuela', 'profile-builder' ), - 'VN' => __( 'Vietnam', 'profile-builder' ), - 'WF' => __( 'Wallis and Futuna', 'profile-builder' ), - 'EH' => __( 'Western Sahara', 'profile-builder' ), - 'YE' => __( 'Yemen', 'profile-builder' ), - 'ZM' => __( 'Zambia', 'profile-builder' ), - 'ZW' => __( 'Zimbabwe', 'profile-builder' ), - ) - ); - - return $country_array; -} - - -/** - * Function that returns an array with timezone options - * - * @since v.2.0 - * - * @return array - */ -function wppb_timezone_select_options( $form_location ) { - $timezone_array = apply_filters( 'wppb_'.$form_location.'_timezone_select_array', array ( '(GMT -12:00) Eniwetok, Kwajalein', '(GMT -11:00) Midway Island, Samoa', '(GMT -10:00) Hawaii', '(GMT -9:00) Alaska', '(GMT -8:00) Pacific Time (US & Canada)', '(GMT -7:00) Mountain Time (US & Canada)', '(GMT -6:00) Central Time (US & Canada), Mexico City', '(GMT -5:00) Eastern Time (US & Canada), Bogota, Lima', '(GMT -4:00) Atlantic Time (Canada), Caracas, La Paz', '(GMT -3:30) Newfoundland', '(GMT -3:00) Brazil, Buenos Aires, Georgetown', '(GMT -2:00) Mid-Atlantic', '(GMT -1:00) Azores, Cape Verde Islands', '(GMT) Western Europe Time, London, Lisbon, Casablanca', '(GMT +1:00) Brussels, Copenhagen, Madrid, Paris', '(GMT +2:00) Kaliningrad, South Africa', '(GMT +3:00) Baghdad, Riyadh, Moscow, St. Petersburg', '(GMT +3:30) Tehran', '(GMT +4:00) Abu Dhabi, Muscat, Baku, Tbilisi', '(GMT +4:30) Kabul', '(GMT +5:00) Ekaterinburg, Islamabad, Karachi, Tashkent', '(GMT +5:30) Bombay, Calcutta, Madras, New Delhi', '(GMT +5:45) Kathmandu', '(GMT +6:00) Almaty, Dhaka, Colombo', '(GMT +7:00) Bangkok, Hanoi, Jakarta', '(GMT +8:00) Beijing, Perth, Singapore, Hong Kong', '(GMT +9:00) Tokyo, Seoul, Osaka, Sapporo, Yakutsk', '(GMT +9:30) Adelaide, Darwin', '(GMT +10:00) Eastern Australia, Guam, Vladivostok', '(GMT +11:00) Magadan, Solomon Islands, New Caledonia', '(GMT +12:00) Auckland, Wellington, Fiji, Kamchatka' ) ); - - return $timezone_array; -} - - -/* - * Array with the currency ISO code and associated currency name - * - * @param string $form_location - * - * @return array - * - */ -function wppb_get_currencies( $form_location = '' ) { - - $currencies = array( - 'ALL' => __( 'Albania Lek', 'profile-builder' ), - 'AFN' => __( 'Afghanistan Afghani', 'profile-builder' ), - 'ARS' => __( 'Argentina Peso', 'profile-builder' ), - 'AWG' => __( 'Aruba Guilder', 'wkc' ), - 'AUD' => __( 'Australia Dollar', 'profile-builder' ), - 'AZN' => __( 'Azerbaijan New Manat', 'profile-builder' ), - 'BSD' => __( 'Bahamas Dollar', 'profile-builder' ), - 'BBD' => __( 'Barbados Dollar','profile-builder' ), - 'BDT' => __( 'Bangladeshi taka','profile-builder' ), - 'BYR' => __( 'Belarus Ruble','profile-builder' ), - 'BZD' => __( 'Belize Dollar','profile-builder' ), - 'BMD' => __( 'Bermuda Dollar','profile-builder' ), - 'BOB' => __( 'Bolivia Boliviano','profile-builder' ), - 'BAM' => __( 'Bosnia and Herzegovina Convertible Marka','profile-builder' ), - 'BWP' => __( 'Botswana Pula','profile-builder' ), - 'BGN' => __( 'Bulgaria Lev','profile-builder' ), - 'BRL' => __( 'Brazil Real','profile-builder' ), - 'BND' => __( 'Brunei Darussalam Dollar','profile-builder' ), - 'KHR' => __( 'Cambodia Riel','profile-builder' ), - 'CAD' => __( 'Canada Dollar','profile-builder' ), - 'KYD' => __( 'Cayman Islands Dollar','profile-builder' ), - 'CLP' => __( 'Chile Peso','profile-builder' ), - 'CNY' => __( 'China Yuan Renminbi','profile-builder' ), - 'COP' => __( 'Colombia Peso','profile-builder' ), - 'CRC' => __( 'Costa Rica Colon','profile-builder' ), - 'HRK' => __( 'Croatia Kuna','profile-builder' ), - 'CUP' => __( 'Cuba Peso','profile-builder' ), - 'CZK' => __( 'Czech Republic Koruna','profile-builder' ), - 'DKK' => __( 'Denmark Krone','profile-builder' ), - 'DOP' => __( 'Dominican Republic Peso','profile-builder' ), - 'XCD' => __( 'East Caribbean Dollar','profile-builder' ), - 'EGP' => __( 'Egypt Pound','profile-builder' ), - 'SVC' => __( 'El Salvador Colon','profile-builder' ), - 'EEK' => __( 'Estonia Kroon','profile-builder' ), - 'EUR' => __( 'Euro','profile-builder' ), - 'FKP' => __( 'Falkland Islands (Malvinas) Pound','profile-builder' ), - 'FJD' => __( 'Fiji Dollar','profile-builder' ), - 'GHC' => __( 'Ghana Cedis','profile-builder' ), - 'GIP' => __( 'Gibraltar Pound','profile-builder' ), - 'GTQ' => __( 'Guatemala Quetzal','profile-builder' ), - 'GGP' => __( 'Guernsey Pound','profile-builder' ), - 'GYD' => __( 'Guyana Dollar','profile-builder' ), - 'HNL' => __( 'Honduras Lempira','profile-builder' ), - 'HKD' => __( 'Hong Kong Dollar','profile-builder' ), - 'HUF' => __( 'Hungary Forint','profile-builder' ), - 'ISK' => __( 'Iceland Krona','profile-builder' ), - 'INR' => __( 'India Rupee','profile-builder' ), - 'IDR' => __( 'Indonesia Rupiah','profile-builder' ), - 'IRR' => __( 'Iran Rial','profile-builder' ), - 'IMP' => __( 'Isle of Man Pound','profile-builder' ), - 'ILS' => __( 'Israel Shekel','profile-builder' ), - 'JMD' => __( 'Jamaica Dollar','profile-builder' ), - 'JPY' => __( 'Japan Yen','profile-builder' ), - 'JEP' => __( 'Jersey Pound','profile-builder' ), - 'KZT' => __( 'Kazakhstan Tenge','profile-builder' ), - 'KPW' => __( 'Korea (North) Won','profile-builder' ), - 'KRW' => __( 'Korea (South) Won','profile-builder' ), - 'KGS' => __( 'Kyrgyzstan Som','profile-builder' ), - 'LAK' => __( 'Laos Kip','profile-builder' ), - 'LVL' => __( 'Latvia Lat','profile-builder' ), - 'LBP' => __( 'Lebanon Pound','profile-builder' ), - 'LRD' => __( 'Liberia Dollar','profile-builder' ), - 'LTL' => __( 'Lithuania Litas','profile-builder' ), - 'MKD' => __( 'Macedonia Denar','profile-builder' ), - 'MYR' => __( 'Malaysia Ringgit','profile-builder' ), - 'MUR' => __( 'Mauritius Rupee','profile-builder' ), - 'MXN' => __( 'Mexico Peso','profile-builder' ), - 'MNT' => __( 'Mongolia Tughrik','profile-builder' ), - 'MZN' => __( 'Mozambique Metical','profile-builder' ), - 'NAD' => __( 'Namibia Dollar','profile-builder' ), - 'NPR' => __( 'Nepal Rupee','profile-builder' ), - 'ANG' => __( 'Netherlands Antilles Guilder','profile-builder' ), - 'NZD' => __( 'New Zealand Dollar','profile-builder' ), - 'NIO' => __( 'Nicaragua Cordoba','profile-builder' ), - 'NGN' => __( 'Nigeria Naira','profile-builder' ), - 'NOK' => __( 'Norway Krone','profile-builder' ), - 'OMR' => __( 'Oman Rial', 'profile-builder' ), - 'PKR' => __( 'Pakistan Rupee', 'profile-builder' ), - 'PAB' => __( 'Panama Balboa', 'profile-builder' ), - 'PYG' => __( 'Paraguay Guarani', 'profile-builder' ), - 'PEN' => __( 'Peru Nuevo Sol', 'profile-builder' ), - 'PHP' => __( 'Philippines Peso', 'profile-builder' ), - 'PLN' => __( 'Poland Zloty', 'profile-builder' ), - 'QAR' => __( 'Qatar Riyal', 'profile-builder' ), - 'RON' => __( 'Romania New Leu', 'profile-builder' ), - 'RUB' => __( 'Russia Ruble', 'profile-builder' ), - 'SHP' => __( 'Saint Helena Pound', 'profile-builder' ), - 'SAR' => __( 'Saudi Arabia Riyal', 'profile-builder' ), - 'RSD' => __( 'Serbia Dinar', 'profile-builder' ), - 'SCR' => __( 'Seychelles Rupee', 'profile-builder' ), - 'SGD' => __( 'Singapore Dollar', 'profile-builder' ), - 'SBD' => __( 'Solomon Islands Dollar', 'profile-builder' ), - 'SOS' => __( 'Somalia Shilling', 'profile-builder' ), - 'ZAR' => __( 'South Africa Rand', 'profile-builder' ), - 'LKR' => __( 'Sri Lanka Rupee', 'profile-builder' ), - 'SEK' => __( 'Sweden Krona', 'profile-builder' ), - 'CHF' => __( 'Switzerland Franc', 'profile-builder' ), - 'SRD' => __( 'Suriname Dollar', 'profile-builder' ), - 'SYP' => __( 'Syria Pound', 'profile-builder' ), - 'TWD' => __( 'Taiwan New Dollar', 'profile-builder' ), - 'THB' => __( 'Thailand Baht', 'profile-builder' ), - 'TTD' => __( 'Trinidad and Tobago Dollar', 'profile-builder' ), - 'TRY' => __( 'Turkey Lira', 'profile-builder' ), - 'TRL' => __( 'Turkey Lira', 'profile-builder' ), - 'TVD' => __( 'Tuvalu Dollar', 'profile-builder' ), - 'UAH' => __( 'Ukraine Hryvna', 'profile-builder' ), - 'GBP' => __( 'United Kingdom Pound', 'profile-builder' ), - 'UGX' => __( 'Uganda Shilling', 'profile-builder' ), - 'USD' => __( 'US Dollar', 'profile-builder' ), - 'UYU' => __( 'Uruguay Peso', 'profile-builder' ), - 'UZS' => __( 'Uzbekistan Som', 'profile-builder' ), - 'VEF' => __( 'Venezuela Bolivar', 'profile-builder' ), - 'VND' => __( 'Viet Nam Dong', 'profile-builder' ), - 'YER' => __( 'Yemen Rial', 'profile-builder' ), - 'ZWD' => __( 'Zimbabwe Dollar', 'profile-builder' ) - ); - - $filter_name = ( empty( $form_location ) ? 'wppb_get_currencies' : 'wppb_get_currencies_' . $form_location ); - - return apply_filters( $filter_name, $currencies ); - -} - - -/* - * Returns the currency symbol for a given currency code - * - * @param string $currency_code - * - * @return string - * - */ -function wppb_get_currency_symbol( $currency_code ) { - - $currency_symbols = array( - 'AED' => 'د.إ', // ? - 'AFN' => 'Af', - 'ALL' => 'Lek', - 'AMD' => '', - 'ANG' => 'ƒ', - 'AOA' => 'Kz', // ? - 'ARS' => '$', - 'AUD' => '$', - 'AWG' => 'ƒ', - 'AZN' => 'ман', - 'BAM' => 'KM', - 'BBD' => '$', - 'BDT' => '৳', // ? - 'BGN' => 'лв', - 'BHD' => '.د.ب', // ? - 'BIF' => 'FBu', // ? - 'BMD' => '$', - 'BND' => '$', - 'BOB' => '$b', - 'BRL' => 'R$', - 'BSD' => '$', - 'BTN' => 'Nu.', // ? - 'BWP' => 'P', - 'BYR' => 'p.', - 'BZD' => 'BZ$', - 'CAD' => '$', - 'CDF' => 'FC', - 'CHF' => 'CHF', - 'CLF' => '', // ? - 'CLP' => '$', - 'CNY' => '¥', - 'COP' => '$', - 'CRC' => '₡', - 'CUP' => '⃌', - 'CVE' => '$', // ? - 'CZK' => 'Kč', - 'DJF' => 'Fdj', // ? - 'DKK' => 'kr', - 'DOP' => 'RD$', - 'DZD' => 'دج', // ? - 'EGP' => '£', - 'ETB' => 'Br', - 'EUR' => '€', - 'FJD' => '$', - 'FKP' => '£', - 'GBP' => '£', - 'GEL' => 'ლ', // ? - 'GHS' => '¢', - 'GIP' => '£', - 'GMD' => 'D', // ? - 'GNF' => 'FG', // ? - 'GTQ' => 'Q', - 'GYD' => '$', - 'HKD' => '$', - 'HNL' => 'L', - 'HRK' => 'kn', - 'HTG' => 'G', // ? - 'HUF' => 'Ft', - 'IDR' => 'Rp', - 'ILS' => '₪', - 'INR' => '₹', - 'IQD' => 'ع.د', // ? - 'IRR' => '﷼', - 'ISK' => 'kr', - 'JEP' => '£', - 'JMD' => 'J$', - 'JOD' => 'JD', // ? - 'JPY' => '¥', - 'KES' => 'KSh', // ? - 'KGS' => 'лв', - 'KHR' => '៛', - 'KMF' => 'CF', // ? - 'KPW' => '₩', - 'KRW' => '₩', - 'KWD' => 'د.ك', // ? - 'KYD' => '$', - 'KZT' => 'лв', - 'LAK' => '₭', - 'LBP' => '£', - 'LKR' => '₨', - 'LRD' => '$', - 'LSL' => 'L', // ? - 'LTL' => 'Lt', - 'LVL' => 'Ls', - 'LYD' => 'ل.د', // ? - 'MAD' => 'د.م.', //? - 'MDL' => 'L', - 'MGA' => 'Ar', // ? - 'MKD' => 'ден', - 'MMK' => 'K', - 'MNT' => '₮', - 'MOP' => 'MOP$', // ? - 'MRO' => 'UM', // ? - 'MUR' => '₨', // ? - 'MVR' => '.ރ', // ? - 'MWK' => 'MK', - 'MXN' => '$', - 'MYR' => 'RM', - 'MZN' => 'MT', - 'NAD' => '$', - 'NGN' => '₦', - 'NIO' => 'C$', - 'NOK' => 'kr', - 'NPR' => '₨', - 'NZD' => '$', - 'OMR' => '﷼', - 'PAB' => 'B/.', - 'PEN' => 'S/.', - 'PGK' => 'K', // ? - 'PHP' => '₱', - 'PKR' => '₨', - 'PLN' => 'zł', - 'PYG' => 'Gs', - 'QAR' => '﷼', - 'RON' => 'lei', - 'RSD' => 'Дин.', - 'RUB' => 'руб', - 'RWF' => 'ر.س', - 'SAR' => '﷼', - 'SBD' => '$', - 'SCR' => '₨', - 'SDG' => '£', // ? - 'SEK' => 'kr', - 'SGD' => '$', - 'SHP' => '£', - 'SLL' => 'Le', // ? - 'SOS' => 'S', - 'SRD' => '$', - 'STD' => 'Db', // ? - 'SVC' => '$', - 'SYP' => '£', - 'SZL' => 'L', // ? - 'THB' => '฿', - 'TJS' => 'TJS', // ? TJS (guess) - 'TMT' => 'm', - 'TND' => 'د.ت', - 'TOP' => 'T$', - 'TRY' => '₤', // New Turkey Lira (old symbol used) - 'TTD' => '$', - 'TWD' => 'NT$', - 'TZS' => '', - 'UAH' => '₴', - 'UGX' => 'USh', - 'USD' => '$', - 'UYU' => '$U', - 'UZS' => 'лв', - 'VEF' => 'Bs', - 'VND' => '₫', - 'VUV' => 'VT', - 'WST' => 'WS$', - 'XAF' => 'FCFA', - 'XCD' => '$', - 'XDR' => '', - 'XOF' => '', - 'XPF' => 'F', - 'YER' => '﷼', - 'ZAR' => 'R', - 'ZMK' => 'ZK', // ? - 'ZWL' => 'Z$', - ); - - if( !empty( $currency_symbols[$currency_code] ) ) - return $currency_symbols[$currency_code]; - else - return ''; - -} - - -/** - * Function that returns a unique, incremented ID - * - * @since v.2.0 - * - * @return integer id - */ -function wppb_get_unique_id(){ - $id = 1; - $wppb_manage_fields = get_option( 'wppb_manage_fields', 'not_found' ); - if ( ( $wppb_manage_fields === 'not_found' ) || ( empty( $wppb_manage_fields ) ) ){ - return $id; - } - else{ - $ids_array = array(); - foreach( $wppb_manage_fields as $value ){ - $ids_array[] = $value['id']; - } - if( !empty( $ids_array ) ){ - rsort( $ids_array ); - $id = $ids_array[0] + 1; - } - } - return apply_filters( 'wppb_field_unique_id', $id, $ids_array, $wppb_manage_fields ); -} - -/** - * Function that checks to see if the id is unique when saving the new field - * - * @param array $values - * - * @return array - */ -function wppb_check_unique_id_on_saving( $values ) { - $wppb_manage_fields = get_option( 'wppb_manage_fields', 'not_found' ); - - if( $wppb_manage_fields != 'not_found' ) { - - $ids_array = array(); - foreach( $wppb_manage_fields as $field ){ - $ids_array[] = $field['id']; - } - - if( in_array( $values['id'], $ids_array ) ) { - rsort( $ids_array ); - $values['id'] = $ids_array[0] + 1; - } - - } - return $values; -} -add_filter( 'wck_add_meta_filter_values_wppb_manage_fields', 'wppb_check_unique_id_on_saving' ); - - -function wppb_return_unique_field_list( $only_default_fields = false ){ - - $unique_field_list[] = 'Default - Name (Heading)'; - $unique_field_list[] = 'Default - Contact Info (Heading)'; - $unique_field_list[] = 'Default - About Yourself (Heading)'; - $unique_field_list[] = 'Default - Username'; - $unique_field_list[] = 'Default - First Name'; - $unique_field_list[] = 'Default - Last Name'; - $unique_field_list[] = 'Default - Nickname'; - $unique_field_list[] = 'Default - E-mail'; - $unique_field_list[] = 'Default - Website'; - - // Default contact methods were removed in WP 3.6. A filter dictates contact methods. - if ( apply_filters( 'wppb_remove_default_contact_methods', get_site_option( 'initial_db_version' ) < 23588 ) ){ - $unique_field_list[] = 'Default - AIM'; - $unique_field_list[] = 'Default - Yahoo IM'; - $unique_field_list[] = 'Default - Jabber / Google Talk'; - } - - $unique_field_list[] = 'Default - Password'; - $unique_field_list[] = 'Default - Repeat Password'; - $unique_field_list[] = 'Default - Biographical Info'; - $unique_field_list[] = 'Default - Display name publicly as'; - - if ( wppb_can_users_signup_blog() ) { - $unique_field_list[] = 'Default - Blog Details'; - } - - if( !$only_default_fields ){ - $unique_field_list[] = 'Avatar'; - $unique_field_list[] = 'reCAPTCHA'; - $unique_field_list[] = 'Select (User Role)'; - } - - return apply_filters ( 'wppb_unique_field_list', $unique_field_list ); -} - - -/** - * Function that checks several things when adding/editing the fields - * - * @since v.2.0 - * - * @param string $message - the message to be displayed - * @param array $fields - the added fields - * @param array $required_fields - * @param string $meta - the meta-name of the option - * @param string $values - The values entered for each option - * @param integer $post_id - * @return boolean - */ -function wppb_check_field_on_edit_add( $message, $fields, $required_fields, $meta_name, $posted_values, $post_id ){ - global $wpdb; - - if ( $meta_name == 'wppb_manage_fields' ){ - - // check for a valid field-type (fallback) - if ( $posted_values['field'] == '' ) - $message .= __( "You must select a field\n", 'profile-builder' ); - // END check for a valid field-type (fallback) - - $unique_field_list = wppb_return_unique_field_list(); - $all_fields = apply_filters( 'wppb_manage_fields_check_field_on_edit_add', get_option ( $meta_name, 'not_set' ), $posted_values ); - - // check if the unique fields are only added once - if( $all_fields != 'not_set' ){ - foreach( $all_fields as $field ){ - if ( ( in_array ( $posted_values['field'], $unique_field_list ) ) && ( $posted_values['field'] == $field['field'] ) && ( $posted_values['id'] != $field['id'] ) ){ - $message .= __( "Please choose a different field type as this one already exists in your form (must be unique)\n", 'profile-builder' ); - break; - } - } - } - // END check if the unique fields are only added once - - // check for avatar size - if ( $posted_values['field'] == 'Avatar' ){ - if ( is_numeric( $posted_values['avatar-size'] ) ){ - if ( ( $posted_values['avatar-size'] < 20 ) || ( $posted_values['avatar-size'] > 200 ) ) - $message .= __( "The entered avatar size is not between 20 and 200\n", 'profile-builder' ); - - }else - $message .= __( "The entered avatar size is not numerical\n", 'profile-builder' ); - - } - // END check for avatar size - - // check for correct row value - if ( ( $posted_values['field'] == 'Default - Biographical Info' ) || ( $posted_values['field'] == 'Textarea' ) ){ - if ( !is_numeric( $posted_values['row-count'] ) ) - $message .= __( "The entered row number is not numerical\n", 'profile-builder' ); - - elseif ( trim( $posted_values['row-count'] ) == '' ) - $message .= __( "You must enter a value for the row number\n", 'profile-builder' ); - } - // END check for correct row value - - - // check for the public and private keys - if ( $posted_values['field'] == 'reCAPTCHA'){ - if ( trim( $posted_values['public-key'] ) == '' ) - $message .= __( "You must enter the site key\n", 'profile-builder' ); - if ( trim( $posted_values['private-key'] ) == '' ) - $message .= __( "You must enter the secret key\n", 'profile-builder' ); - } - // END check for the public and private keys - - // check for the correct the date-format - if ( $posted_values['field'] == 'Datepicker' ){ - $date_format = strtolower( $posted_values['date-format'] ); - if ( trim( $date_format ) != 'mm/dd/yy' && trim( $date_format ) != 'mm/yy/dd' && trim( $date_format ) != 'dd/yy/mm' && - trim( $date_format ) != 'dd/mm/yy' && trim( $date_format ) != 'yy/dd/mm' && trim( $date_format ) != 'yy/mm/dd' && - trim( $date_format ) != 'yy-mm-dd' && trim( $date_format ) != 'DD, dd-M-y' && trim( $date_format ) != 'D, dd M yy' && - trim( $date_format ) != 'D, d M y' && trim( $date_format ) != 'D, d M yy' && trim( $date_format ) != 'mm-dd-yy' && trim( $date_format ) != '@' ) - $message .= __( "The entered value for the Datepicker is not a valid date-format\n", 'profile-builder' ); - - elseif ( trim( $date_format ) == '' ) - $message .= __( "You must enter a value for the date-format\n", 'profile-builder' ); - } - // END check for the correct the date-format - - //check for empty meta-name and duplicate meta-name - if ( $posted_values['overwrite-existing'] == 'No' ){ - $skip_check_for_fields = wppb_return_unique_field_list(true); - $skip_check_for_fields = apply_filters ( 'wppb_skip_check_for_fields', $skip_check_for_fields ); - - if ( !in_array( trim( $posted_values['field'] ), $skip_check_for_fields ) ){ - $unique_meta_name_list = array( 'first_name', 'last_name', 'nickname', 'description' ); - - //check to see if meta-name is empty - $skip_empty_check_for_fields = array( 'Heading', 'Select (User Role)', 'reCAPTCHA', 'HTML' ); - - if( !in_array( $posted_values['field'], $skip_empty_check_for_fields ) && empty( $posted_values['meta-name'] ) ) { - $message .= __( "The meta-name cannot be empty\n", 'profile-builder' ); - } - - // Default contact methods were removed in WP 3.6. A filter dictates contact methods. - if ( apply_filters( 'wppb_remove_default_contact_methods', get_site_option( 'initial_db_version' ) < 23588 ) ){ - $unique_meta_name_list[] = 'aim'; - $unique_meta_name_list[] = 'yim'; - $unique_meta_name_list[] = 'jabber'; - } - - // if the desired meta-name is one of the following, automatically give an error - if ( in_array( trim( $posted_values['meta-name'] ), apply_filters ( 'wppb_unique_meta_name_list', $unique_meta_name_list ) ) ) - $message .= __( "That meta-name is already in use\n", 'profile-builder' ); - - else{ - $found_in_custom_fields = false; - - if( $all_fields != 'not_set' ) - foreach( $all_fields as $field ){ - if ( $posted_values['meta-name'] != '' && ( $field['meta-name'] == $posted_values['meta-name'] ) && ( $field['id'] != $posted_values['id'] ) ){ - $message .= __( "That meta-name is already in use\n", 'profile-builder' ); - $found_in_custom_fields = true; - - }elseif ( ( $field['meta-name'] == $posted_values['meta-name'] ) && ( $field['id'] == $posted_values['id'] ) ) - $found_in_custom_fields = true; - } - - if ( $found_in_custom_fields === false ){ - if( $posted_values['meta-name'] != '' ) { - $found_meta_name = $wpdb->get_row($wpdb->prepare("SELECT * FROM $wpdb->usermeta WHERE meta_key = %s", $posted_values['meta-name'])); - if ($found_meta_name != null) - $message .= __("That meta-name is already in use\n", 'profile-builder'); - } - } - } - } - } - //END check duplicate meta-name - - // check for correct meta name on upload field - if( $posted_values['field'] == 'Upload' ) { - if( ! empty( $posted_values['meta-name'] ) && preg_match( '/([^a-z\d_-])/', $posted_values['meta-name'] ) ) { - $message .= __( "The meta-name can only contain lowercase letters, numbers, _ , - and no spaces.\n", 'profile-builder' ); - } - } - // END check for correct meta name on upload field - - // check for valid default option (checkbox, select, radio) - if ( ( $posted_values['field'] == 'Checkbox' ) || ( $posted_values['field'] == 'Select (Multiple)' ) ) { - $options = array_map( 'trim', explode( ',', $posted_values['options'] ) ); - $default_options = ( ( trim( $posted_values['default-options'] ) == '' ) ? array() : array_map( 'trim', explode( ',', $posted_values['default-options'] ) ) ); - - /* echo ""; - echo ""; */ - - $not_found = ''; - foreach ( $default_options as $key => $value ){ - if ( !in_array( $value, $options ) ) - $not_found .= $value . ', '; - } - - if ( $not_found != '' ) - $message .= sprintf( __( "The following option(s) did not coincide with the ones in the options list: %s\n", 'profile-builder' ), trim( $not_found, ', ' ) ); - - }elseif ( ( $posted_values['field'] == 'Radio' ) || ( $posted_values['field'] == 'Select' ) ){ - if ( ( trim( $posted_values['default-option'] ) != '' ) && ( !in_array( $posted_values['default-option'], array_map( 'trim', explode( ',', $posted_values['options'] ) ) ) ) ) - $message .= sprintf( __( "The following option did not coincide with the ones in the options list: %s\n", 'profile-builder' ), $posted_values['default-option'] ); - } - // END check for valid default option (checkbox, select, radio) - - // check to see if any user role is selected (user-role field) - if( $posted_values['field'] == 'Select (User Role)' ) { - if( empty( $posted_values['user-roles'] ) ) { - $message .= __( "Please select at least one user role\n", 'profile-builder' ); - } - } - // END check to see if Administrator user role has been selected (user-role field) - - $message = apply_filters( 'wppb_check_extra_manage_fields', $message, $posted_values ); - - }elseif ( ( $meta_name == 'wppb_rf_fields' ) || ( $meta_name == 'wppb_epf_fields' ) ){ - if ( $posted_values['field'] == '' ){ - $message .= __( "You must select a field\n", 'profile-builder' ); - - }else{ - $fields_so_far = get_post_meta ( $post_id, $meta_name, true ); - - foreach ( $fields_so_far as $key => $value ){ - if ( $value['id'] == $posted_values['id'] ) - $message .= __( "That field is already added in this form\n", 'profile-builder' ); - } - } - } - return $message; -} -add_filter( 'wck_extra_message', 'wppb_check_field_on_edit_add', 10, 6 ); - - -/** - * Function that calls the wppb_hide_properties_for_already_added_fields after a field-update - * - * @since v.2.0 - * - * @param void - * - * @return string - */ -function wppb_manage_fields_after_refresh_list( $id ){ - echo ""; -} -add_action( "wck_refresh_list_wppb_manage_fields", "wppb_manage_fields_after_refresh_list" ); -add_action( "wck_refresh_entry_wppb_manage_fields", "wppb_manage_fields_after_refresh_list" ); - - -/** - * Function that calls the wppb_hide_all - * - * @since v.2.0 - * - * @param void - * - * @return string - */ -function wppb_hide_all_after_add( $id ){ - echo ""; -} -add_action("wck_ajax_add_form_wppb_manage_fields", "wppb_hide_all_after_add" ); - -/** - * Function that modifies the table header in Manage Fields to add Field Name, Field Type, Meta Key, Required - * - * @since v.2.0 - * - * @param $list, $id - * - * @return string - */ -function wppb_manage_fields_header( $list_header ){ - return '#'. __( '
    Title
    Type
    Meta Name
    Required
    ', 'profile-builder' ) .''. __( 'Edit', 'profile-builder' ) .''. __( 'Delete', 'profile-builder' ) .''; -} -add_action( 'wck_metabox_content_header_wppb_manage_fields', 'wppb_manage_fields_header' ); - -/** - * Add contextual help to the side of manage fields for the shortcodes - * - * @since v.2.0 - * - * @param $hook - * - * @return string - */ -function wppb_add_content_before_manage_fields(){ -?> -

    -
      -
    • [wppb-register]
    • -
    • [wppb-edit-profile]
    • -
    • [wppb-register role="author"]
    • -
    -

    - -

    -wppb_disable_delete_on_default_mandatory_fields();"; - - if ( $meta_name == 'wppb_manage_fields' ) - echo ""; -} -add_action("wck_after_adding_form", "wppb_remove_properties_from_added_form", 10, 3); - -/* - * WPML Support for dynamic strings in Profile Builder. Tags: WPML, fields, translate - */ -add_filter( 'update_option_wppb_manage_fields', 'wppb_wpml_compat_with_fields', 10, 2 ); -function wppb_wpml_compat_with_fields( $oldvalue, $_newvalue ){ - $default_fields = array( - 'Default - Name (Heading)', - 'Default - Contact Info (Heading)', - 'Default - About Yourself (Heading)', - 'Default - Username', - 'Default - First Name', - 'Default - Last Name', - 'Default - Nickname', - 'Default - E-mail', - 'Default - Website', - 'Default - AIM', - 'Default - Yahoo IM', - 'Default - Jabber / Google Talk', - 'Default - Password', - 'Default - Repeat Password', - 'Default - Biographical Info', - 'Default - Blog Details', - 'Default - Display name publicly as' - ); - - if ( is_array( $_newvalue ) ){ - foreach ( $_newvalue as $field ){ - if ( in_array($field['field'], $default_fields) ){ - $prefix = 'default_field_'; - } else { - $prefix = 'custom_field_'; - } - if (function_exists('icl_register_string')){ - if( !empty( $field['field-title'] ) ) - icl_register_string('plugin profile-builder-pro', $prefix . $field['id'].'_title_translation' , $field['field-title'] ); - if( !empty( $field['description'] ) ) - icl_register_string('plugin profile-builder-pro', $prefix . $field['id'].'_description_translation', $field['description'] ); - if( !empty( $field['labels'] ) ) - icl_register_string('plugin profile-builder-pro', $prefix . $field['id'].'_labels_translation', $field['labels'] ); - if( !empty( $field['default-value'] ) ) - icl_register_string('plugin profile-builder-pro', $prefix . $field['id'].'_default_value_translation', $field['default-value'] ); - if( !empty( $field['default-content'] ) ) - icl_register_string('plugin profile-builder-pro', $prefix . $field['id'].'_default_content_translation', $field['default-content'] ); - } - } - } -} - - -/* - * Returns the HTML for a map given the field - * - */ -function wppb_get_map_output( $field, $args ) { - - $defaults = array( - 'markers' => array(), - 'editable' => true, - 'show_search' => true, - 'extra_attr' => '' - ); - - $args = wp_parse_args( $args, $defaults ); - - $return = ''; - - // Search box - // The style:left=-99999px is set to hide the input from the viewport. It will be rewritten when the map gets initialised - if( $args['show_search'] ) - $return .= ''; - - // Map container - $return .= '
    '; - - if( !empty( $args['markers'] ) ) { - foreach( $args['markers'] as $marker ) - $return .= ''; - } - - return $return; - -} - - -/* - * Returns all the saved markers for a map field for a particular user - * - */ -function wppb_get_user_map_markers( $user_id, $meta_name ) { - - global $wpdb; - - $meta_name_underlined = $meta_name . '_'; - - $results = $wpdb->get_results( "SELECT meta_value, meta_key FROM {$wpdb->usermeta} WHERE user_id={$user_id} AND meta_key LIKE '%{$meta_name_underlined}%'", ARRAY_N ); - - $markers = array(); - $i = 0; - - foreach( $results as $key => $result ) { - $pattern = '/^' . $meta_name . '_[0-9]+$/'; - preg_match( $pattern, $result[1], $matches ); - if ( count ($matches) > 0 ) { - $markers[$i] = $result[0]; - $i++; - } - - } - return $markers; - -} - -/* - * Deletes from the database all saved markers - * - */ -function wppb_delete_user_map_markers( $user_id, $meta_name ) { - - global $wpdb; - - $meta_name .= '_'; - - $delete = $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->usermeta} WHERE user_id=%d AND meta_key LIKE %s", $user_id, '%' . $meta_name . '%' ) ); - - wp_cache_delete( $user_id, 'user_meta' ); - -} - -/** - * Disable the add button again after we added a field - */ -add_action( 'wck_ajax_add_form_wppb_manage_fields', 'wppb_redisable_the_add_button' ); -function wppb_redisable_the_add_button(){ - ?> - - __( 'Manage Fields', 'profile-builder' ), + 'page_title' => __( 'Manage Default and Extra Fields', 'profile-builder' ), + 'menu_slug' => 'manage-fields', + 'page_type' => 'submenu_page', + 'capability' => 'manage_options', + 'priority' => 5, + 'parent_slug' => 'profile-builder' + ); + $all_fields = new WCK_Page_Creator_PB( $args ); + + + // populate this page + $manage_field_types[] = 'Default - Name (Heading)'; + $manage_field_types[] = 'Default - Contact Info (Heading)'; + $manage_field_types[] = 'Default - About Yourself (Heading)'; + $manage_field_types[] = 'Default - Username'; + $manage_field_types[] = 'Default - First Name'; + $manage_field_types[] = 'Default - Last Name'; + $manage_field_types[] = 'Default - Nickname'; + $manage_field_types[] = 'Default - E-mail'; + $manage_field_types[] = 'Default - Website'; + + // Default contact methods were removed in WP 3.6. A filter dictates contact methods. + if ( apply_filters( 'wppb_remove_default_contact_methods', get_site_option( 'initial_db_version' ) < 23588 ) ){ + $manage_field_types[] = 'Default - AIM'; + $manage_field_types[] = 'Default - Yahoo IM'; + $manage_field_types[] = 'Default - Jabber / Google Talk'; + } + + $manage_field_types[] = 'Default - Password'; + $manage_field_types[] = 'Default - Repeat Password'; + $manage_field_types[] = 'Default - Biographical Info'; + $manage_field_types[] = 'Default - Display name publicly as'; + if ( wppb_can_users_signup_blog() ) { + $manage_field_types[] = 'Default - Blog Details'; + } + + /* added recaptcha and user role field since version 2.6.2 */ + $manage_field_types[] = 'reCAPTCHA'; + $manage_field_types[] = 'Select (User Role)'; + + if( PROFILE_BUILDER != 'Profile Builder Free' ) { + $manage_field_types[] = 'Heading'; + $manage_field_types[] = 'Input'; + $manage_field_types[] = 'Number'; + $manage_field_types[] = 'Input (Hidden)'; + $manage_field_types[] = 'Textarea'; + $manage_field_types[] = 'WYSIWYG'; + $manage_field_types[] = 'Phone'; + $manage_field_types[] = 'Select'; + $manage_field_types[] = 'Select (Multiple)'; + $manage_field_types[] = 'Select (Country)'; + $manage_field_types[] = 'Select (Timezone)'; + $manage_field_types[] = 'Select (Currency)'; + $manage_field_types[] = 'Select (CPT)'; + $manage_field_types[] = 'Checkbox'; + $manage_field_types[] = 'Checkbox (Terms and Conditions)'; + $manage_field_types[] = 'Radio'; + $manage_field_types[] = 'Upload'; + $manage_field_types[] = 'Avatar'; + $manage_field_types[] = 'Datepicker'; + $manage_field_types[] = 'Timepicker'; + $manage_field_types[] = 'Colorpicker'; + $manage_field_types[] = 'Validation'; + $manage_field_types[] = 'Map'; + $manage_field_types[] = 'HTML'; + } + + + //Free to Pro call to action on Manage Fields page + $field_description = __('Choose one of the supported field types','profile-builder'); + if( PROFILE_BUILDER == 'Profile Builder Free' ) { + $field_description .= sprintf( __('. Extra Field Types are available in Hobbyist or PRO versions.' , 'profile-builder'), esc_url( 'https://www.cozmoslabs.com/wordpress-profile-builder/?utm_source=wpbackend&utm_medium=clientsite&utm_content=manage-fields-link&utm_campaign=PBFree' ) ); + } + + + //user roles + global $wp_roles; + + $user_roles = array(); + foreach( $wp_roles->roles as $user_role_slug => $user_role ) + if( $user_role_slug !== 'administrator' ) + array_push( $user_roles, '%' . $user_role['name'] . '%' . $user_role_slug ); + + + // country select + $default_country_array = wppb_country_select_options( 'back_end' ); + foreach( $default_country_array as $iso_country_code => $country_name ) { + $default_country_values[] = $iso_country_code; + $default_country_options[] = $country_name; + } + + // currency select + $default_currency_array = wppb_get_currencies( 'back_end' ); + array_unshift( $default_currency_array, '' ); + foreach( $default_currency_array as $iso_currency_code => $currency_name ) { + $default_currency_values[] = $iso_currency_code; + $default_currency_options[] = $currency_name; + } + + //cpt select + $post_types = get_post_types( array( 'public' => true ), 'names' ); + + // set up the fields array + $fields = apply_filters( 'wppb_manage_fields', array( + + array( 'type' => 'text', 'slug' => 'field-title', 'title' => __( 'Field Title', 'profile-builder' ), 'description' => __( 'Title of the field', 'profile-builder' ) ), + array( 'type' => 'select', 'slug' => 'field', 'title' => __( 'Field', 'profile-builder' ), 'options' => apply_filters( 'wppb_manage_fields_types', $manage_field_types ), 'default-option' => true, 'description' => $field_description ), + array( 'type' => 'text', 'slug' => 'meta-name', 'title' => __( 'Meta-name', 'profile-builder' ), 'default' => wppb_get_meta_name(), 'description' => __( 'Use this in conjunction with WordPress functions to display the value in the page of your choosing
    Auto-completed but in some cases editable (in which case it must be unique)
    Changing this might take long in case of a very big user-count', 'profile-builder' ) ), + array( 'type' => 'text', 'slug' => 'id', 'title' => __( 'ID', 'profile-builder' ), 'default' => wppb_get_unique_id(), 'description' => __( "A unique, auto-generated ID for this particular field
    You can use this in conjuction with filters to target this element if needed
    Can't be edited", 'profile-builder' ), 'readonly' => true ), + array( 'type' => 'textarea', 'slug' => 'description', 'title' => __( 'Description', 'profile-builder' ), 'description' => __( 'Enter a (detailed) description of the option for end users to read
    Optional', 'profile-builder') ), + array( 'type' => 'text', 'slug' => 'row-count', 'title' => __( 'Row Count', 'profile-builder' ), 'default' => 5, 'description' => __( "Specify the number of rows for a 'Textarea' field
    If not specified, defaults to 5", 'profile-builder' ) ), + array( 'type' => 'text', 'slug' => 'allowed-image-extensions', 'title' => __( 'Allowed Image Extensions', 'profile-builder' ), 'default' => '.*', 'description' => __( 'Specify the extension(s) you want to limit to upload
    Example: .ext1,.ext2,.ext3
    If not specified, defaults to: .jpg,.jpeg,.gif,.png (.*)', 'profile-builder' ) ), + array( 'type' => 'text', 'slug' => 'allowed-upload-extensions', 'title' => __( 'Allowed Upload Extensions', 'profile-builder' ), 'default' => '.*', 'description' => __( 'Specify the extension(s) you want to limit to upload
    Example: .ext1,.ext2,.ext3
    If not specified, defaults to all WordPress allowed file extensions (.*)', 'profile-builder' ) ), + array( 'type' => 'text', 'slug' => 'avatar-size', 'title' => __( 'Avatar Size', 'profile-builder' ), 'default' => 100, 'description' => __( "Enter a value (between 20 and 200) for the size of the 'Avatar'
    If not specified, defaults to 100", 'profile-builder' ) ), + array( 'type' => 'text', 'slug' => 'date-format', 'title' => __( 'Date-format', 'profile-builder' ), 'default' => 'mm/dd/yy', 'description' => __( 'Specify the format of the date when using Datepicker
    Valid options: mm/dd/yy, mm/yy/dd, dd/yy/mm, dd/mm/yy, yy/dd/mm, yy/mm/dd, mm-dd-yy, yy-mm-dd, D, dd M yy, D, d M y, DD, dd-M-y, D, d M yy, @
    If not specified, defaults to mm/dd/yy', 'profile-builder' ) ), + array( 'type' => 'textarea', 'slug' => 'terms-of-agreement', 'title' => __( 'Terms of Agreement', 'profile-builder' ), 'description' => __( 'Enter a detailed description of the temrs of agreement for the user to read.
    Links can be inserted by using standard HTML syntax: <a href="custom_url">custom_text</a>', 'profile-builder' ) ), + array( 'type' => 'text', 'slug' => 'options', 'title' => __( 'Options', 'profile-builder' ), 'description' => __( "Enter a comma separated list of values
    This can be anything, as it is hidden from the user, but should not contain special characters or apostrophes", 'profile-builder' ) ), + array( 'type' => 'text', 'slug' => 'labels', 'title' => __( 'Labels', 'profile-builder' ), 'description' => __( "Enter a comma separated list of labels
    Visible for the user", 'profile-builder' ) ), + array( 'type' => 'text', 'slug' => 'public-key', 'title' => __( 'Site Key', 'profile-builder' ), 'description' => __( 'The site key from Google, www.google.com/recaptcha', 'profile-builder' ) ), + array( 'type' => 'text', 'slug' => 'private-key', 'title' => __( 'Secret Key', 'profile-builder' ), 'description' => __( 'The secret key from Google, www.google.com/recaptcha', 'profile-builder' ) ), + array( 'type' => 'checkbox', 'slug' => 'captcha-pb-forms', 'title' => __( 'Display on PB forms', 'profile-builder' ), 'options' => array( '%'.__('PB Login','profile-builder').'%'.'pb_login', '%'.__('PB Register','profile-builder').'%'.'pb_register', '%'.__('PB Recover Password','profile-builder').'%'.'pb_recover_password' ), 'default' => 'pb_register', 'description' => __( "Select on which Profile Builder forms to display reCAPTCHA", 'profile-builder' ) ), + array( 'type' => 'checkbox', 'slug' => 'captcha-wp-forms', 'title' => __( 'Display on default WP forms', 'profile-builder' ), 'options' => array( '%'.__('Default WP Login', 'profile-builder').'%'.'default_wp_login', '%'.__('Default WP Register', 'profile-builder').'%'.'default_wp_register', '%'.__('Default WP Recover Password', 'profile-builder').'%'.'default_wp_recover_password'), 'default' => 'default_wp_register', 'description' => __( "Select on which default WP forms to display reCAPTCHA", 'profile-builder' ) ), + array( 'type' => 'checkbox', 'slug' => 'user-roles', 'title' => __( 'User Roles', 'profile-builder' ), 'options' => $user_roles, 'description' => __( "Select which user roles to show to the user ( drag and drop to re-order )", 'profile-builder' ) ), + array( 'type' => 'text', 'slug' => 'user-roles-sort-order', 'title' => __( 'User Roles Order', 'profile-builder' ), 'description' => __( "Save the user role order from the user roles checkboxes", 'profile-builder' ) ), + array( 'type' => 'text', 'slug' => 'default-value', 'title' => __( 'Default Value', 'profile-builder' ), 'description' => __( "Default value of the field", 'profile-builder' ) ), + array( 'type' => 'text', 'slug' => 'default-option', 'title' => __( 'Default Option', 'profile-builder' ), 'description' => __( "Specify the option which should be selected by default", 'profile-builder' ) ), + array( 'type' => 'text', 'slug' => 'default-options', 'title' => __( 'Default Option(s)', 'profile-builder' ), 'description' => __( "Specify the option which should be checked by default
    If there are multiple values, separate them with a ',' (comma)", 'profile-builder' ) ), + array( 'type' => 'select', 'slug' => 'default-option-country', 'title' => __( 'Default Option', 'profile-builder' ), 'values' => ( isset( $default_country_values ) ) ? $default_country_values : '', 'options' => ( isset( $default_country_options ) ) ? $default_country_options : '', 'description' => __( "Default option of the field", 'profile-builder' ) ), + array( 'type' => 'select', 'slug' => 'default-option-timezone', 'title' => __( 'Default Option', 'profile-builder' ), 'options' => wppb_timezone_select_options( 'back_end' ), 'description' => __( "Default option of the field", 'profile-builder' ) ), + array( 'type' => 'select', 'slug' => 'default-option-currency', 'title' => __( 'Default Option', 'profile-builder' ), 'values' => ( isset( $default_currency_values ) ) ? $default_currency_values : '', 'options' => ( isset( $default_currency_options ) ) ? $default_currency_options : '', 'description' => __( "Default option of the field", 'profile-builder' ) ), + array( 'type' => 'select', 'slug' => 'show-currency-symbol', 'title' => __( 'Show Currency Symbol', 'profile-builder' ), 'options' => array( 'No', 'Yes' ), 'default' => 'No', 'description' => __( 'Whether the currency symbol should be displayed after the currency name in the select option.', 'profile-builder' ) ), + array( 'type' => 'select', 'slug' => 'cpt', 'title' => __( 'Show Post Type', 'profile-builder' ), 'options' => $post_types, 'default' => 'post', 'description' => __( 'Posts from what post type will be displayed in the select.', 'profile-builder' ) ), + array( 'type' => 'text', 'slug' => 'validation-possible-values', 'title' => __( 'Allowable Values', 'profile-builder' ), 'description' => __( "Enter a comma separated list of possible values. Upon registration if the value provided by the user does not match one of these values, the user will not be registered.", 'profile-builder' ) ), + array( 'type' => 'text', 'slug' => 'custom-error-message', 'title' => __( 'Error Message', 'profile-builder' ), 'description' => __( "Set a custom error message that will be displayed to the user.", 'profile-builder' ) ), + array( 'type' => 'select', 'slug' => 'time-format', 'title' => __( 'Time Format', 'profile-builder' ), 'options' => array( '%12 Hours%12', '%24 Hours%24' ), 'description' => __( 'Specify the time format.', 'profile-builder' ) ), + array( 'type' => 'text', 'slug' => 'map-api-key', 'title' => __( 'Google Maps API Key', 'profile-builder' ), 'description' => __( 'Enter your Google Maps API key ( Get your API key ). If more than one map fields are added to a form the API key from the first map displayed will be used.', 'profile-builder' ) ), + array( 'type' => 'text', 'slug' => 'map-default-lat', 'title' => __( 'Default Latitude', 'profile-builder' ), 'description' => __( "The latitude at which the map should be displayed when no pins are attached.", 'profile-builder' ) ), + array( 'type' => 'text', 'slug' => 'map-default-lng', 'title' => __( 'Default Longitude', 'profile-builder' ), 'description' => __( "The longitude at which the map should be displayed when no pins are attached.", 'profile-builder' ) ), + array( 'type' => 'text', 'slug' => 'map-default-zoom', 'title' => __( 'Default Zoom Level', 'profile-builder' ), 'description' => __( "Add a number from 0 to 19. The higher the number the higher the zoom.", 'profile-builder' ), 'default' => 16 ), + array( 'type' => 'text', 'slug' => 'map-height', 'title' => __( 'Map Height', 'profile-builder' ), 'description' => __( "The height of the map.", 'profile-builder' ), 'default' => 400 ), + array( 'type' => 'textarea', 'slug' => 'default-content', 'title' => __( 'Default Content', 'profile-builder' ), 'description' => __( "Default value of the textarea", 'profile-builder' ) ), + array( 'type' => 'textarea', 'slug' => 'html-content', 'title' => __( 'HTML Content', 'profile-builder' ), 'description' => __( "Add your HTML (or text) content", 'profile-builder' ) ), + array( 'type' => 'text', 'slug' => 'phone-format', 'title' => __( 'Phone Format', 'profile-builder' ), 'default' => '(###) ###-####', 'description' => __( "You can use: # for numbers, parentheses ( ), - sign, + sign, dot . and spaces.", 'profile-builder' ) .'
    '. __( "Eg. (###) ###-####", 'profile-builder' ) .'
    '. __( "Empty field won't check for correct phone number.", 'profile-builder' ) ), + array( 'type' => 'select', 'slug' => 'heading-tag', 'title' => __( 'Heading Tag', 'profile-builder' ), 'options' => array( '%h1 - biggest size%h1', 'h2', 'h3', 'h4', 'h5', '%h6 - smallest size%h6' ), 'default' => 'h4', 'description' => __( 'Change heading field size on front-end forms', 'profile-builder' ) ), + array( 'type' => 'text', 'slug' => 'min-number-value', 'title' => __( 'Min Number Value', 'profile-builder' ), 'description' => __( "Min allowed number value (0 to allow only positive numbers)", 'profile-builder' ) .'
    '. __( "Leave it empty for no min value", 'profile-builder' ) ), + array( 'type' => 'text', 'slug' => 'max-number-value', 'title' => __( 'Max Number Value', 'profile-builder' ), 'description' => __( "Max allowed number value (0 to allow only negative numbers)", 'profile-builder' ) .'
    '. __( "Leave it empty for no max value", 'profile-builder' ) ), + array( 'type' => 'text', 'slug' => 'number-step-value', 'title' => __( 'Number Step Value', 'profile-builder' ), 'description' => __( "Step value 1 to allow only integers, 0.1 to allow integers and numbers with 1 decimal", 'profile-builder' ) .'
    '. __( "To allow multiple decimals use for eg. 0.01 (for 2 deciamls) and so on", 'profile-builder' ) .'
    '. __( "You can also use step value to specify the legal number intervals (eg. step value 2 will allow only -4, -2, 0, 2 and so on)", 'profile-builder' ) .'
    '. __( "Leave it empty for no restriction", 'profile-builder' ) ), + array( 'type' => 'select', 'slug' => 'required', 'title' => __( 'Required', 'profile-builder' ), 'options' => array( 'No', 'Yes' ), 'default' => 'No', 'description' => __( 'Whether the field is required or not', 'profile-builder' ) ), + array( 'type' => 'select', 'slug' => 'overwrite-existing', 'title' => __( 'Overwrite Existing', 'profile-builder' ), 'options' => array( 'No', 'Yes' ), 'default' => 'No', 'description' => __( "Selecting 'Yes' will add the field to the list, but will overwrite any other field in the database that has the same meta-name
    Use this at your own risk", 'profile-builder' ) ), + ) ); + + // create the new submenu with the above options + $args = array( + 'metabox_id' => 'manage-fields', + 'metabox_title' => __( 'Field Properties', 'profile-builder' ), + 'post_type' => 'manage-fields', + 'meta_name' => 'wppb_manage_fields', + 'meta_array' => $fields, + 'context' => 'option' + ); + new Wordpress_Creation_Kit_PB( $args ); + + /* this is redundant but it should have a very low impact and for comfort we leave it here as well */ + wppb_prepopulate_fields(); + + // create the info side meta-box + $args = array( + 'metabox_id' => 'manage-fields-info', + 'metabox_title' => __( 'Registration & Edit Profile', 'profile-builder' ), + 'post_type' => 'manage-fields', + 'meta_name' => 'wppb_manage_fields_info', + 'meta_array' => '', + 'context' => 'option', + 'mb_context' => 'side' + ); + new Wordpress_Creation_Kit_PB( $args ); +} +add_action( 'init', 'wppb_manage_fields_submenu', 10 ); + +/** + * Function that prepopulates the manage fields list with the default fields of WP + * + * @since v.2.0 + * + * @return void + */ +function wppb_prepopulate_fields(){ + $prepopulated_fields[] = array( 'field' => 'Default - Name (Heading)', 'field-title' => __( 'Name', 'profile-builder' ), 'meta-name' => '', 'overwrite-existing' => 'No', 'id' => '1', 'description' => '', 'row-count' => '5', 'allowed-image-extensions' => '.*', 'allowed-upload-extensions' => '.*', 'avatar-size' => '100', 'date-format' => 'mm/dd/yy', 'terms-of-agreement' => '', 'options' => '', 'labels' => '', 'public-key' => '', 'private-key' => '', 'default-value' => '', 'default-option' => '', 'default-options' => '', 'default-content' => '', 'required' => 'No' ); + $prepopulated_fields[] = array( 'field' => 'Default - Username', 'field-title' => __( 'Username', 'profile-builder' ), 'meta-name' => '', 'overwrite-existing' => 'No', 'id' => '2', 'description' => __( 'Usernames cannot be changed.', 'profile-builder' ), 'row-count' => '5', 'allowed-image-extensions' => '.*', 'allowed-upload-extensions' => '.*', 'avatar-size' => '100', 'date-format' => 'mm/dd/yy', 'terms-of-agreement' => '', 'options' => '', 'labels' => '', 'public-key' => '', 'private-key' => '', 'default-value' => '', 'default-option' => '', 'default-options' => '', 'default-content' => '', 'required' => 'Yes' ); + $prepopulated_fields[] = array( 'field' => 'Default - First Name', 'field-title' => __( 'First Name', 'profile-builder' ), 'meta-name' => 'first_name', 'overwrite-existing' => 'No', 'id' => '3', 'description' => '', 'row-count' => '5', 'allowed-image-extensions' => '.*', 'allowed-upload-extensions' => '.*', 'avatar-size' => '100', 'date-format' => 'mm/dd/yy', 'terms-of-agreement' => '', 'options' => '', 'labels' => '', 'public-key' => '', 'private-key' => '', 'default-value' => '', 'default-option' => '', 'default-options' => '', 'default-content' => '', 'required' => 'No' ); + $prepopulated_fields[] = array( 'field' => 'Default - Last Name', 'field-title' => __( 'Last Name', 'profile-builder' ), 'meta-name' => 'last_name', 'overwrite-existing' => 'No', 'id' => '4', 'description' => '', 'row-count' => '5', 'allowed-image-extensions' => '.*', 'allowed-upload-extensions' => '.*', 'avatar-size' => '100', 'date-format' => 'mm/dd/yy', 'terms-of-agreement' => '', 'options' => '', 'labels' => '', 'public-key' => '', 'private-key' => '', 'default-value' => '', 'default-option' => '', 'default-options' => '', 'default-content' => '', 'required' => 'No' ); + $prepopulated_fields[] = array( 'field' => 'Default - Nickname', 'field-title' => __( 'Nickname', 'profile-builder' ), 'meta-name' => 'nickname', 'overwrite-existing' => 'No', 'id' => '5', 'description' => '', 'row-count' => '5', 'allowed-image-extensions' => '.*', 'allowed-upload-extensions' => '.*', 'avatar-size' => '100', 'date-format' => 'mm/dd/yy', 'terms-of-agreement' => '', 'options' => '', 'labels' => '', 'public-key' => '', 'private-key' => '', 'default-value' => '', 'default-option' => '', 'default-options' => '', 'default-content' => '', 'required' => 'Yes' ); + $prepopulated_fields[] = array( 'field' => 'Default - Display name publicly as', 'field-title' => __( 'Display name publicly as', 'profile-builder' ), 'meta-name' => '', 'overwrite-existing' => 'No', 'id' => '6', 'description' => '', 'row-count' => '5', 'allowed-image-extensions' => '.*', 'allowed-upload-extensions' => '.*', 'avatar-size' => '100', 'date-format' => 'mm/dd/yy', 'terms-of-agreement' => '', 'options' => '', 'labels' => '', 'public-key' => '', 'private-key' => '', 'default-value' => '', 'default-option' => '', 'default-options' => '', 'default-content' => '', 'required' => 'No' ); + $prepopulated_fields[] = array( 'field' => 'Default - Contact Info (Heading)', 'field-title' => __( 'Contact Info', 'profile-builder' ), 'meta-name' => '', 'overwrite-existing' => 'No', 'id' => '7', 'description' => '', 'row-count' => '5', 'allowed-image-extensions' => '.*', 'allowed-upload-extensions' => '.*', 'avatar-size' => '100', 'date-format' => 'mm/dd/yy', 'terms-of-agreement' => '', 'options' => '', 'labels' => '', 'public-key' => '', 'private-key' => '', 'default-value' => '', 'default-option' => '', 'default-options' => '', 'default-content' => '', 'required' => 'No' ); + $prepopulated_fields[] = array( 'field' => 'Default - E-mail', 'field-title' => __( 'E-mail', 'profile-builder' ), 'meta-name' => '', 'overwrite-existing' => 'No', 'id' => '8', 'description' => '', 'row-count' => '5', 'allowed-image-extensions' => '.*', 'allowed-upload-extensions' => '.*', 'avatar-size' => '100', 'date-format' => 'mm/dd/yy', 'terms-of-agreement' => '', 'options' => '', 'labels' => '', 'public-key' => '', 'private-key' => '', 'default-value' => '', 'default-option' => '', 'default-options' => '', 'default-content' => '', 'required' => 'Yes' ); + $prepopulated_fields[] = array( 'field' => 'Default - Website', 'field-title' => __( 'Website', 'profile-builder' ), 'meta-name' => '', 'overwrite-existing' => 'No', 'id' => '9', 'description' => '', 'row-count' => '5', 'allowed-image-extensions' => '.*', 'allowed-upload-extensions' => '.*', 'avatar-size' => '100', 'date-format' => 'mm/dd/yy', 'terms-of-agreement' => '', 'options' => '', 'labels' => '', 'public-key' => '', 'private-key' => '', 'default-value' => '', 'default-option' => '', 'default-options' => '', 'default-content' => '', 'required' => 'No' ); + + // Default contact methods were removed in WP 3.6. A filter dictates contact methods. + if ( apply_filters( 'wppb_remove_default_contact_methods', get_site_option( 'initial_db_version' ) < 23588 ) ){ + $prepopulated_fields[] = array( 'field' => 'Default - AIM', 'field-title' => __( 'AIM', 'profile-builder' ), 'meta-name' => 'aim', 'overwrite-existing' => 'No', 'id' => '10', 'description' => '', 'row-count' => '5', 'allowed-image-extensions' => '.*', 'allowed-upload-extensions' => '.*', 'avatar-size' => '100', 'date-format' => 'mm/dd/yy', 'terms-of-agreement' => '', 'options' => '', 'labels' => '', 'public-key' => '', 'private-key' => '', 'default-value' => '', 'default-option' => '', 'default-options' => '', 'default-content' => '', 'required' => 'No' ); + $prepopulated_fields[] = array( 'field' => 'Default - Yahoo IM', 'field-title' => __( 'Yahoo IM', 'profile-builder' ), 'meta-name' => 'yim', 'overwrite-existing' => 'No', 'id' => '11', 'description' => '', 'row-count' => '5', 'allowed-image-extensions' => '.*', 'allowed-upload-extensions' => '.*', 'avatar-size' => '100', 'date-format' => 'mm/dd/yy', 'terms-of-agreement' => '', 'options' => '', 'labels' => '', 'public-key' => '', 'private-key' => '', 'default-value' => '', 'default-option' => '', 'default-options' => '', 'default-content' => '', 'required' => 'No' ); + $prepopulated_fields[] = array( 'field' => 'Default - Jabber / Google Talk', 'field-title' => __( 'Jabber / Google Talk', 'profile-builder' ), 'meta-name' => 'jabber', 'overwrite-existing' => 'No', 'id' => '12', 'description' => '', 'row-count' => '5', 'allowed-image-extensions' => '.*', 'allowed-upload-extensions' => '.*', 'avatar-size' => '100', 'date-format' => 'mm/dd/yy', 'terms-of-agreement' => '', 'options' => '', 'labels' => '', 'public-key' => '', 'private-key' => '', 'default-value' => '', 'default-option' => '', 'default-options' => '', 'default-content' => '', 'required' => 'No' ); + } + + $prepopulated_fields[] = array( 'field' => 'Default - About Yourself (Heading)', 'field-title' => __( 'About Yourself', 'profile-builder' ), 'meta-name' => '', 'overwrite-existing' => 'No', 'id' => '13', 'description' => '', 'row-count' => '5', 'allowed-image-extensions' => '.*', 'allowed-upload-extensions' => '.*', 'avatar-size' => '100', 'date-format' => 'mm/dd/yy', 'terms-of-agreement' => '', 'options' => '', 'labels' => '', 'public-key' => '', 'private-key' => '', 'default-value' => '', 'default-option' => '', 'default-options' => '', 'default-content' => '', 'required' => 'No' ); + $prepopulated_fields[] = array( 'field' => 'Default - Biographical Info', 'field-title' => __( 'Biographical Info', 'profile-builder' ), 'meta-name' => 'description', 'overwrite-existing' => 'No', 'id' => '14', 'description' => __( 'Share a little biographical information to fill out your profile. This may be shown publicly.', 'profile-builder' ), 'row-count' => '5', 'allowed-image-extensions' => '.*', 'allowed-upload-extensions' => '.*', 'avatar-size' => '100', 'date-format' => 'mm/dd/yy', 'terms-of-agreement' => '', 'options' => '', 'labels' => '', 'public-key' => '', 'private-key' => '', 'default-value' => '', 'default-option' => '', 'default-options' => '', 'required' => 'No' ); + $prepopulated_fields[] = array( 'field' => 'Default - Password', 'field-title' => __( 'Password', 'profile-builder' ), 'meta-name' => '', 'overwrite-existing' => 'No', 'id' => '15', 'description' => __( 'Type your password.', 'profile-builder' ), 'row-count' => '5', 'allowed-image-extensions' => '.*', 'allowed-upload-extensions' => '.*', 'avatar-size' => '100', 'date-format' => 'mm/dd/yy', 'terms-of-agreement' => '', 'options' => '', 'labels' => '', 'public-key' => '', 'private-key' => '', 'default-value' => '', 'default-option' => '', 'default-options' => '', 'default-content' => '', 'required' => 'Yes' ); + $prepopulated_fields[] = array( 'field' => 'Default - Repeat Password', 'field-title' => __( 'Repeat Password', 'profile-builder' ), 'meta-name' => '', 'overwrite-existing' => 'No', 'id' => '16', 'description' => __( 'Type your password again. ', 'profile-builder' ), 'row-count' => '5', 'allowed-image-extensions' => '.*', 'allowed-upload-extensions' => '.*', 'avatar-size' => '100', 'date-format' => 'mm/dd/yy', 'terms-of-agreement' => '', 'options' => '', 'labels' => '', 'public-key' => '', 'private-key' => '', 'default-value' => '', 'default-option' => '', 'default-options' => '', 'default-content' => '', 'required' => 'Yes' ); + if ( wppb_can_users_signup_blog() ){ + $prepopulated_fields[] = array( 'field' => 'Default - Blog Details', 'field-title' => __( 'Blog Details', 'profile-builder' ), 'meta-name' => '', 'overwrite-existing' => 'No', 'id' => '17', 'description' => '', 'row-count' => '5', 'allowed-image-extensions' => '.*', 'allowed-upload-extensions' => '.*', 'avatar-size' => '100', 'date-format' => 'mm/dd/yy', 'terms-of-agreement' => '', 'options' => '', 'labels' => '', 'public-key' => '', 'private-key' => '', 'default-value' => '', 'default-option' => '', 'default-options' => '', 'default-content' => '', 'required' => 'No' ); + } + + add_option ( 'wppb_manage_fields', apply_filters ( 'wppb_prepopulated_fields', $prepopulated_fields ) ); +} + +/** + * Function that returns a unique meta-name + * + * @since v.2.0 + * + * @return string + */ +function wppb_get_meta_name( $option = 'wppb_manage_fields', $prefix = 'custom_field_' ){ + $id = 1; + + $wppb_manage_fields = get_option( $option, 'not_found' ); + + if ( ( $wppb_manage_fields === 'not_found' ) || ( empty( $wppb_manage_fields ) ) ){ + return $prefix . $id; + } + else{ + $meta_names = array(); + foreach( $wppb_manage_fields as $value ){ + if ( strpos( $value['meta-name'], $prefix ) === 0 ){ + $meta_names[] = $value['meta-name']; + } + } + + if( !empty( $meta_names ) ){ + $meta_numbers = array(); + foreach( $meta_names as $meta_name ){ + $number = str_replace( $prefix, '', $meta_name ); + /* we should have an underscore present in custom_field_# so remove it */ + $number = str_replace( '_', '', $number ); + + $meta_numbers[] = $number; + } + if( !empty( $meta_numbers ) ){ + rsort( $meta_numbers ); + $id = $meta_numbers[0]++; + } + } + + return $prefix . $id; + } +} + + +/** + * Function that returns an array with countries + * + * @since v.2.0 + * + * @return array + */ +function wppb_country_select_options( $form_location ) { + $country_array = apply_filters( 'wppb_'.$form_location.'_country_select_array', + array( + '' => '', + 'AF' => __( 'Afghanistan', 'profile-builder' ), + 'AX' => __( 'Aland Islands', 'profile-builder' ), + 'AL' => __( 'Albania', 'profile-builder' ), + 'DZ' => __( 'Algeria', 'profile-builder' ), + 'AS' => __( 'American Samoa', 'profile-builder' ), + 'AD' => __( 'Andorra', 'profile-builder' ), + 'AO' => __( 'Angola', 'profile-builder' ), + 'AI' => __( 'Anguilla', 'profile-builder' ), + 'AQ' => __( 'Antarctica', 'profile-builder' ), + 'AG' => __( 'Antigua and Barbuda', 'profile-builder' ), + 'AR' => __( 'Argentina', 'profile-builder' ), + 'AM' => __( 'Armenia', 'profile-builder' ), + 'AW' => __( 'Aruba', 'profile-builder' ), + 'AU' => __( 'Australia', 'profile-builder' ), + 'AT' => __( 'Austria', 'profile-builder' ), + 'AZ' => __( 'Azerbaijan', 'profile-builder' ), + 'BS' => __( 'Bahamas', 'profile-builder' ), + 'BH' => __( 'Bahrain', 'profile-builder' ), + 'BD' => __( 'Bangladesh', 'profile-builder' ), + 'BB' => __( 'Barbados', 'profile-builder' ), + 'BY' => __( 'Belarus', 'profile-builder' ), + 'BE' => __( 'Belgium', 'profile-builder' ), + 'BZ' => __( 'Belize', 'profile-builder' ), + 'BJ' => __( 'Benin', 'profile-builder' ), + 'BM' => __( 'Bermuda', 'profile-builder' ), + 'BT' => __( 'Bhutan', 'profile-builder' ), + 'BO' => __( 'Bolivia', 'profile-builder' ), + 'BQ' => __( 'Bonaire, Saint Eustatius and Saba', 'profile-builder' ), + 'BA' => __( 'Bosnia and Herzegovina', 'profile-builder' ), + 'BW' => __( 'Botswana', 'profile-builder' ), + 'BV' => __( 'Bouvet Island', 'profile-builder' ), + 'BR' => __( 'Brazil', 'profile-builder' ), + 'IO' => __( 'British Indian Ocean Territory', 'profile-builder' ), + 'VG' => __( 'British Virgin Islands', 'profile-builder' ), + 'BN' => __( 'Brunei', 'profile-builder' ), + 'BG' => __( 'Bulgaria', 'profile-builder' ), + 'BF' => __( 'Burkina Faso', 'profile-builder' ), + 'BI' => __( 'Burundi', 'profile-builder' ), + 'KH' => __( 'Cambodia', 'profile-builder' ), + 'CM' => __( 'Cameroon', 'profile-builder' ), + 'CA' => __( 'Canada', 'profile-builder' ), + 'CV' => __( 'Cape Verde', 'profile-builder' ), + 'KY' => __( 'Cayman Islands', 'profile-builder' ), + 'CF' => __( 'Central African Republic', 'profile-builder' ), + 'TD' => __( 'Chad', 'profile-builder' ), + 'CL' => __( 'Chile', 'profile-builder' ), + 'CN' => __( 'China', 'profile-builder' ), + 'CX' => __( 'Christmas Island', 'profile-builder' ), + 'CC' => __( 'Cocos Islands', 'profile-builder' ), + 'CO' => __( 'Colombia', 'profile-builder' ), + 'KM' => __( 'Comoros', 'profile-builder' ), + 'CK' => __( 'Cook Islands', 'profile-builder' ), + 'CR' => __( 'Costa Rica', 'profile-builder' ), + 'HR' => __( 'Croatia', 'profile-builder' ), + 'CU' => __( 'Cuba', 'profile-builder' ), + 'CW' => __( 'Curacao', 'profile-builder' ), + 'CY' => __( 'Cyprus', 'profile-builder' ), + 'CZ' => __( 'Czech Republic', 'profile-builder' ), + 'CD' => __( 'Democratic Republic of the Congo', 'profile-builder' ), + 'DK' => __( 'Denmark', 'profile-builder' ), + 'DJ' => __( 'Djibouti', 'profile-builder' ), + 'DM' => __( 'Dominica', 'profile-builder' ), + 'DO' => __( 'Dominican Republic', 'profile-builder' ), + 'TL' => __( 'East Timor', 'profile-builder' ), + 'EC' => __( 'Ecuador', 'profile-builder' ), + 'EG' => __( 'Egypt', 'profile-builder' ), + 'SV' => __( 'El Salvador', 'profile-builder' ), + 'GQ' => __( 'Equatorial Guinea', 'profile-builder' ), + 'ER' => __( 'Eritrea', 'profile-builder' ), + 'EE' => __( 'Estonia', 'profile-builder' ), + 'ET' => __( 'Ethiopia', 'profile-builder' ), + 'FK' => __( 'Falkland Islands', 'profile-builder' ), + 'FO' => __( 'Faroe Islands', 'profile-builder' ), + 'FJ' => __( 'Fiji', 'profile-builder' ), + 'FI' => __( 'Finland', 'profile-builder' ), + 'FR' => __( 'France', 'profile-builder' ), + 'GF' => __( 'French Guiana', 'profile-builder' ), + 'PF' => __( 'French Polynesia', 'profile-builder' ), + 'TF' => __( 'French Southern Territories', 'profile-builder' ), + 'GA' => __( 'Gabon', 'profile-builder' ), + 'GM' => __( 'Gambia', 'profile-builder' ), + 'GE' => __( 'Georgia', 'profile-builder' ), + 'DE' => __( 'Germany', 'profile-builder' ), + 'GH' => __( 'Ghana', 'profile-builder' ), + 'GI' => __( 'Gibraltar', 'profile-builder' ), + 'GR' => __( 'Greece', 'profile-builder' ), + 'GL' => __( 'Greenland', 'profile-builder' ), + 'GD' => __( 'Grenada', 'profile-builder' ), + 'GP' => __( 'Guadeloupe', 'profile-builder' ), + 'GU' => __( 'Guam', 'profile-builder' ), + 'GT' => __( 'Guatemala', 'profile-builder' ), + 'GG' => __( 'Guernsey', 'profile-builder' ), + 'GN' => __( 'Guinea', 'profile-builder' ), + 'GW' => __( 'Guinea-Bissau', 'profile-builder' ), + 'GY' => __( 'Guyana', 'profile-builder' ), + 'HT' => __( 'Haiti', 'profile-builder' ), + 'HM' => __( 'Heard Island and McDonald Islands', 'profile-builder' ), + 'HN' => __( 'Honduras', 'profile-builder' ), + 'HK' => __( 'Hong Kong', 'profile-builder' ), + 'HU' => __( 'Hungary', 'profile-builder' ), + 'IS' => __( 'Iceland', 'profile-builder' ), + 'IN' => __( 'India', 'profile-builder' ), + 'ID' => __( 'Indonesia', 'profile-builder' ), + 'IR' => __( 'Iran', 'profile-builder' ), + 'IQ' => __( 'Iraq', 'profile-builder' ), + 'IE' => __( 'Ireland', 'profile-builder' ), + 'IM' => __( 'Isle of Man', 'profile-builder' ), + 'IL' => __( 'Israel', 'profile-builder' ), + 'IT' => __( 'Italy', 'profile-builder' ), + 'CI' => __( 'Ivory Coast', 'profile-builder' ), + 'JM' => __( 'Jamaica', 'profile-builder' ), + 'JP' => __( 'Japan', 'profile-builder' ), + 'JE' => __( 'Jersey', 'profile-builder' ), + 'JO' => __( 'Jordan', 'profile-builder' ), + 'KZ' => __( 'Kazakhstan', 'profile-builder' ), + 'KE' => __( 'Kenya', 'profile-builder' ), + 'KI' => __( 'Kiribati', 'profile-builder' ), + 'XK' => __( 'Kosovo', 'profile-builder' ), + 'KW' => __( 'Kuwait', 'profile-builder' ), + 'KG' => __( 'Kyrgyzstan', 'profile-builder' ), + 'LA' => __( 'Laos', 'profile-builder' ), + 'LV' => __( 'Latvia', 'profile-builder' ), + 'LB' => __( 'Lebanon', 'profile-builder' ), + 'LS' => __( 'Lesotho', 'profile-builder' ), + 'LR' => __( 'Liberia', 'profile-builder' ), + 'LY' => __( 'Libya', 'profile-builder' ), + 'LI' => __( 'Liechtenstein', 'profile-builder' ), + 'LT' => __( 'Lithuania', 'profile-builder' ), + 'LU' => __( 'Luxembourg', 'profile-builder' ), + 'MO' => __( 'Macao', 'profile-builder' ), + 'MK' => __( 'Macedonia', 'profile-builder' ), + 'MG' => __( 'Madagascar', 'profile-builder' ), + 'MW' => __( 'Malawi', 'profile-builder' ), + 'MY' => __( 'Malaysia', 'profile-builder' ), + 'MV' => __( 'Maldives', 'profile-builder' ), + 'ML' => __( 'Mali', 'profile-builder' ), + 'MT' => __( 'Malta', 'profile-builder' ), + 'MH' => __( 'Marshall Islands', 'profile-builder' ), + 'MQ' => __( 'Martinique', 'profile-builder' ), + 'MR' => __( 'Mauritania', 'profile-builder' ), + 'MU' => __( 'Mauritius', 'profile-builder' ), + 'YT' => __( 'Mayotte', 'profile-builder' ), + 'MX' => __( 'Mexico', 'profile-builder' ), + 'FM' => __( 'Micronesia', 'profile-builder' ), + 'MD' => __( 'Moldova', 'profile-builder' ), + 'MC' => __( 'Monaco', 'profile-builder' ), + 'MN' => __( 'Mongolia', 'profile-builder' ), + 'ME' => __( 'Montenegro', 'profile-builder' ), + 'MS' => __( 'Montserrat', 'profile-builder' ), + 'MA' => __( 'Morocco', 'profile-builder' ), + 'MZ' => __( 'Mozambique', 'profile-builder' ), + 'MM' => __( 'Myanmar', 'profile-builder' ), + 'NA' => __( 'Namibia', 'profile-builder' ), + 'NR' => __( 'Nauru', 'profile-builder' ), + 'NP' => __( 'Nepal', 'profile-builder' ), + 'NL' => __( 'Netherlands', 'profile-builder' ), + 'NC' => __( 'New Caledonia', 'profile-builder' ), + 'NZ' => __( 'New Zealand', 'profile-builder' ), + 'NI' => __( 'Nicaragua', 'profile-builder' ), + 'NE' => __( 'Niger', 'profile-builder' ), + 'NG' => __( 'Nigeria', 'profile-builder' ), + 'NU' => __( 'Niue', 'profile-builder' ), + 'NF' => __( 'Norfolk Island', 'profile-builder' ), + 'KP' => __( 'North Korea', 'profile-builder' ), + 'MP' => __( 'Northern Mariana Islands', 'profile-builder' ), + 'NO' => __( 'Norway', 'profile-builder' ), + 'OM' => __( 'Oman', 'profile-builder' ), + 'PK' => __( 'Pakistan', 'profile-builder' ), + 'PW' => __( 'Palau', 'profile-builder' ), + 'PS' => __( 'Palestinian Territory', 'profile-builder' ), + 'PA' => __( 'Panama', 'profile-builder' ), + 'PG' => __( 'Papua New Guinea', 'profile-builder' ), + 'PY' => __( 'Paraguay', 'profile-builder' ), + 'PE' => __( 'Peru', 'profile-builder' ), + 'PH' => __( 'Philippines', 'profile-builder' ), + 'PN' => __( 'Pitcairn', 'profile-builder' ), + 'PL' => __( 'Poland', 'profile-builder' ), + 'PT' => __( 'Portugal', 'profile-builder' ), + 'PR' => __( 'Puerto Rico', 'profile-builder' ), + 'QA' => __( 'Qatar', 'profile-builder' ), + 'CG' => __( 'Republic of the Congo', 'profile-builder' ), + 'RE' => __( 'Reunion', 'profile-builder' ), + 'RO' => __( 'Romania', 'profile-builder' ), + 'RU' => __( 'Russia', 'profile-builder' ), + 'RW' => __( 'Rwanda', 'profile-builder' ), + 'BL' => __( 'Saint Barthelemy', 'profile-builder' ), + 'SH' => __( 'Saint Helena', 'profile-builder' ), + 'KN' => __( 'Saint Kitts and Nevis', 'profile-builder' ), + 'LC' => __( 'Saint Lucia', 'profile-builder' ), + 'MF' => __( 'Saint Martin', 'profile-builder' ), + 'PM' => __( 'Saint Pierre and Miquelon', 'profile-builder' ), + 'VC' => __( 'Saint Vincent and the Grenadines', 'profile-builder' ), + 'WS' => __( 'Samoa', 'profile-builder' ), + 'SM' => __( 'San Marino', 'profile-builder' ), + 'ST' => __( 'Sao Tome and Principe', 'profile-builder' ), + 'SA' => __( 'Saudi Arabia', 'profile-builder' ), + 'SN' => __( 'Senegal', 'profile-builder' ), + 'RS' => __( 'Serbia', 'profile-builder' ), + 'SC' => __( 'Seychelles', 'profile-builder' ), + 'SL' => __( 'Sierra Leone', 'profile-builder' ), + 'SG' => __( 'Singapore', 'profile-builder' ), + 'SX' => __( 'Sint Maarten', 'profile-builder' ), + 'SK' => __( 'Slovakia', 'profile-builder' ), + 'SI' => __( 'Slovenia', 'profile-builder' ), + 'SB' => __( 'Solomon Islands', 'profile-builder' ), + 'SO' => __( 'Somalia', 'profile-builder' ), + 'ZA' => __( 'South Africa', 'profile-builder' ), + 'GS' => __( 'South Georgia and the South Sandwich Islands', 'profile-builder' ), + 'KR' => __( 'South Korea', 'profile-builder' ), + 'SS' => __( 'South Sudan', 'profile-builder' ), + 'ES' => __( 'Spain', 'profile-builder' ), + 'LK' => __( 'Sri Lanka', 'profile-builder' ), + 'SD' => __( 'Sudan', 'profile-builder' ), + 'SR' => __( 'Suriname', 'profile-builder' ), + 'SJ' => __( 'Svalbard and Jan Mayen', 'profile-builder' ), + 'SZ' => __( 'Swaziland', 'profile-builder' ), + 'SE' => __( 'Sweden', 'profile-builder' ), + 'CH' => __( 'Switzerland', 'profile-builder' ), + 'SY' => __( 'Syria', 'profile-builder' ), + 'TW' => __( 'Taiwan', 'profile-builder' ), + 'TJ' => __( 'Tajikistan', 'profile-builder' ), + 'TZ' => __( 'Tanzania', 'profile-builder' ), + 'TH' => __( 'Thailand', 'profile-builder' ), + 'TG' => __( 'Togo', 'profile-builder' ), + 'TK' => __( 'Tokelau', 'profile-builder' ), + 'TO' => __( 'Tonga', 'profile-builder' ), + 'TT' => __( 'Trinidad and Tobago', 'profile-builder' ), + 'TN' => __( 'Tunisia', 'profile-builder' ), + 'TR' => __( 'Turkey', 'profile-builder' ), + 'TM' => __( 'Turkmenistan', 'profile-builder' ), + 'TC' => __( 'Turks and Caicos Islands', 'profile-builder' ), + 'TV' => __( 'Tuvalu', 'profile-builder' ), + 'VI' => __( 'U.S. Virgin Islands', 'profile-builder' ), + 'UG' => __( 'Uganda', 'profile-builder' ), + 'UA' => __( 'Ukraine', 'profile-builder' ), + 'AE' => __( 'United Arab Emirates', 'profile-builder' ), + 'GB' => __( 'United Kingdom', 'profile-builder' ), + 'US' => __( 'United States', 'profile-builder' ), + 'UM' => __( 'United States Minor Outlying Islands', 'profile-builder' ), + 'UY' => __( 'Uruguay', 'profile-builder' ), + 'UZ' => __( 'Uzbekistan', 'profile-builder' ), + 'VU' => __( 'Vanuatu', 'profile-builder' ), + 'VA' => __( 'Vatican', 'profile-builder' ), + 'VE' => __( 'Venezuela', 'profile-builder' ), + 'VN' => __( 'Vietnam', 'profile-builder' ), + 'WF' => __( 'Wallis and Futuna', 'profile-builder' ), + 'EH' => __( 'Western Sahara', 'profile-builder' ), + 'YE' => __( 'Yemen', 'profile-builder' ), + 'ZM' => __( 'Zambia', 'profile-builder' ), + 'ZW' => __( 'Zimbabwe', 'profile-builder' ), + ) + ); + + return $country_array; +} + + +/** + * Function that returns an array with timezone options + * + * @since v.2.0 + * + * @return array + */ +function wppb_timezone_select_options( $form_location ) { + $timezone_array = apply_filters( 'wppb_'.$form_location.'_timezone_select_array', array ( '(GMT -12:00) Eniwetok, Kwajalein', '(GMT -11:00) Midway Island, Samoa', '(GMT -10:00) Hawaii', '(GMT -9:00) Alaska', '(GMT -8:00) Pacific Time (US & Canada)', '(GMT -7:00) Mountain Time (US & Canada)', '(GMT -6:00) Central Time (US & Canada), Mexico City', '(GMT -5:00) Eastern Time (US & Canada), Bogota, Lima', '(GMT -4:00) Atlantic Time (Canada), Caracas, La Paz', '(GMT -3:30) Newfoundland', '(GMT -3:00) Brazil, Buenos Aires, Georgetown', '(GMT -2:00) Mid-Atlantic', '(GMT -1:00) Azores, Cape Verde Islands', '(GMT) Western Europe Time, London, Lisbon, Casablanca', '(GMT +1:00) Brussels, Copenhagen, Madrid, Paris', '(GMT +2:00) Kaliningrad, South Africa', '(GMT +3:00) Baghdad, Riyadh, Moscow, St. Petersburg', '(GMT +3:30) Tehran', '(GMT +4:00) Abu Dhabi, Muscat, Baku, Tbilisi', '(GMT +4:30) Kabul', '(GMT +5:00) Ekaterinburg, Islamabad, Karachi, Tashkent', '(GMT +5:30) Bombay, Calcutta, Madras, New Delhi', '(GMT +5:45) Kathmandu', '(GMT +6:00) Almaty, Dhaka, Colombo', '(GMT +7:00) Bangkok, Hanoi, Jakarta', '(GMT +8:00) Beijing, Perth, Singapore, Hong Kong', '(GMT +9:00) Tokyo, Seoul, Osaka, Sapporo, Yakutsk', '(GMT +9:30) Adelaide, Darwin', '(GMT +10:00) Eastern Australia, Guam, Vladivostok', '(GMT +11:00) Magadan, Solomon Islands, New Caledonia', '(GMT +12:00) Auckland, Wellington, Fiji, Kamchatka' ) ); + + return $timezone_array; +} + + +/* + * Array with the currency ISO code and associated currency name + * + * @param string $form_location + * + * @return array + * + */ +function wppb_get_currencies( $form_location = '' ) { + + $currencies = array( + 'ALL' => __( 'Albania Lek', 'profile-builder' ), + 'AFN' => __( 'Afghanistan Afghani', 'profile-builder' ), + 'ARS' => __( 'Argentina Peso', 'profile-builder' ), + 'AWG' => __( 'Aruba Guilder', 'wkc' ), + 'AUD' => __( 'Australia Dollar', 'profile-builder' ), + 'AZN' => __( 'Azerbaijan New Manat', 'profile-builder' ), + 'BSD' => __( 'Bahamas Dollar', 'profile-builder' ), + 'BBD' => __( 'Barbados Dollar','profile-builder' ), + 'BDT' => __( 'Bangladeshi taka','profile-builder' ), + 'BYR' => __( 'Belarus Ruble','profile-builder' ), + 'BZD' => __( 'Belize Dollar','profile-builder' ), + 'BMD' => __( 'Bermuda Dollar','profile-builder' ), + 'BOB' => __( 'Bolivia Boliviano','profile-builder' ), + 'BAM' => __( 'Bosnia and Herzegovina Convertible Marka','profile-builder' ), + 'BWP' => __( 'Botswana Pula','profile-builder' ), + 'BGN' => __( 'Bulgaria Lev','profile-builder' ), + 'BRL' => __( 'Brazil Real','profile-builder' ), + 'BND' => __( 'Brunei Darussalam Dollar','profile-builder' ), + 'KHR' => __( 'Cambodia Riel','profile-builder' ), + 'CAD' => __( 'Canada Dollar','profile-builder' ), + 'KYD' => __( 'Cayman Islands Dollar','profile-builder' ), + 'CLP' => __( 'Chile Peso','profile-builder' ), + 'CNY' => __( 'China Yuan Renminbi','profile-builder' ), + 'COP' => __( 'Colombia Peso','profile-builder' ), + 'CRC' => __( 'Costa Rica Colon','profile-builder' ), + 'HRK' => __( 'Croatia Kuna','profile-builder' ), + 'CUP' => __( 'Cuba Peso','profile-builder' ), + 'CZK' => __( 'Czech Republic Koruna','profile-builder' ), + 'DKK' => __( 'Denmark Krone','profile-builder' ), + 'DOP' => __( 'Dominican Republic Peso','profile-builder' ), + 'XCD' => __( 'East Caribbean Dollar','profile-builder' ), + 'EGP' => __( 'Egypt Pound','profile-builder' ), + 'SVC' => __( 'El Salvador Colon','profile-builder' ), + 'EEK' => __( 'Estonia Kroon','profile-builder' ), + 'EUR' => __( 'Euro','profile-builder' ), + 'FKP' => __( 'Falkland Islands (Malvinas) Pound','profile-builder' ), + 'FJD' => __( 'Fiji Dollar','profile-builder' ), + 'GHC' => __( 'Ghana Cedis','profile-builder' ), + 'GIP' => __( 'Gibraltar Pound','profile-builder' ), + 'GTQ' => __( 'Guatemala Quetzal','profile-builder' ), + 'GGP' => __( 'Guernsey Pound','profile-builder' ), + 'GYD' => __( 'Guyana Dollar','profile-builder' ), + 'HNL' => __( 'Honduras Lempira','profile-builder' ), + 'HKD' => __( 'Hong Kong Dollar','profile-builder' ), + 'HUF' => __( 'Hungary Forint','profile-builder' ), + 'ISK' => __( 'Iceland Krona','profile-builder' ), + 'INR' => __( 'India Rupee','profile-builder' ), + 'IDR' => __( 'Indonesia Rupiah','profile-builder' ), + 'IRR' => __( 'Iran Rial','profile-builder' ), + 'IMP' => __( 'Isle of Man Pound','profile-builder' ), + 'ILS' => __( 'Israel Shekel','profile-builder' ), + 'JMD' => __( 'Jamaica Dollar','profile-builder' ), + 'JPY' => __( 'Japan Yen','profile-builder' ), + 'JEP' => __( 'Jersey Pound','profile-builder' ), + 'KZT' => __( 'Kazakhstan Tenge','profile-builder' ), + 'KPW' => __( 'Korea (North) Won','profile-builder' ), + 'KRW' => __( 'Korea (South) Won','profile-builder' ), + 'KGS' => __( 'Kyrgyzstan Som','profile-builder' ), + 'LAK' => __( 'Laos Kip','profile-builder' ), + 'LVL' => __( 'Latvia Lat','profile-builder' ), + 'LBP' => __( 'Lebanon Pound','profile-builder' ), + 'LRD' => __( 'Liberia Dollar','profile-builder' ), + 'LTL' => __( 'Lithuania Litas','profile-builder' ), + 'MKD' => __( 'Macedonia Denar','profile-builder' ), + 'MYR' => __( 'Malaysia Ringgit','profile-builder' ), + 'MUR' => __( 'Mauritius Rupee','profile-builder' ), + 'MXN' => __( 'Mexico Peso','profile-builder' ), + 'MNT' => __( 'Mongolia Tughrik','profile-builder' ), + 'MZN' => __( 'Mozambique Metical','profile-builder' ), + 'NAD' => __( 'Namibia Dollar','profile-builder' ), + 'NPR' => __( 'Nepal Rupee','profile-builder' ), + 'ANG' => __( 'Netherlands Antilles Guilder','profile-builder' ), + 'NZD' => __( 'New Zealand Dollar','profile-builder' ), + 'NIO' => __( 'Nicaragua Cordoba','profile-builder' ), + 'NGN' => __( 'Nigeria Naira','profile-builder' ), + 'NOK' => __( 'Norway Krone','profile-builder' ), + 'OMR' => __( 'Oman Rial', 'profile-builder' ), + 'PKR' => __( 'Pakistan Rupee', 'profile-builder' ), + 'PAB' => __( 'Panama Balboa', 'profile-builder' ), + 'PYG' => __( 'Paraguay Guarani', 'profile-builder' ), + 'PEN' => __( 'Peru Nuevo Sol', 'profile-builder' ), + 'PHP' => __( 'Philippines Peso', 'profile-builder' ), + 'PLN' => __( 'Poland Zloty', 'profile-builder' ), + 'QAR' => __( 'Qatar Riyal', 'profile-builder' ), + 'RON' => __( 'Romania New Leu', 'profile-builder' ), + 'RUB' => __( 'Russia Ruble', 'profile-builder' ), + 'SHP' => __( 'Saint Helena Pound', 'profile-builder' ), + 'SAR' => __( 'Saudi Arabia Riyal', 'profile-builder' ), + 'RSD' => __( 'Serbia Dinar', 'profile-builder' ), + 'SCR' => __( 'Seychelles Rupee', 'profile-builder' ), + 'SGD' => __( 'Singapore Dollar', 'profile-builder' ), + 'SBD' => __( 'Solomon Islands Dollar', 'profile-builder' ), + 'SOS' => __( 'Somalia Shilling', 'profile-builder' ), + 'ZAR' => __( 'South Africa Rand', 'profile-builder' ), + 'LKR' => __( 'Sri Lanka Rupee', 'profile-builder' ), + 'SEK' => __( 'Sweden Krona', 'profile-builder' ), + 'CHF' => __( 'Switzerland Franc', 'profile-builder' ), + 'SRD' => __( 'Suriname Dollar', 'profile-builder' ), + 'SYP' => __( 'Syria Pound', 'profile-builder' ), + 'TWD' => __( 'Taiwan New Dollar', 'profile-builder' ), + 'THB' => __( 'Thailand Baht', 'profile-builder' ), + 'TTD' => __( 'Trinidad and Tobago Dollar', 'profile-builder' ), + 'TRY' => __( 'Turkey Lira', 'profile-builder' ), + 'TRL' => __( 'Turkey Lira', 'profile-builder' ), + 'TVD' => __( 'Tuvalu Dollar', 'profile-builder' ), + 'UAH' => __( 'Ukraine Hryvna', 'profile-builder' ), + 'GBP' => __( 'United Kingdom Pound', 'profile-builder' ), + 'UGX' => __( 'Uganda Shilling', 'profile-builder' ), + 'USD' => __( 'US Dollar', 'profile-builder' ), + 'UYU' => __( 'Uruguay Peso', 'profile-builder' ), + 'UZS' => __( 'Uzbekistan Som', 'profile-builder' ), + 'VEF' => __( 'Venezuela Bolivar', 'profile-builder' ), + 'VND' => __( 'Viet Nam Dong', 'profile-builder' ), + 'YER' => __( 'Yemen Rial', 'profile-builder' ), + 'ZWD' => __( 'Zimbabwe Dollar', 'profile-builder' ) + ); + + $filter_name = ( empty( $form_location ) ? 'wppb_get_currencies' : 'wppb_get_currencies_' . $form_location ); + + return apply_filters( $filter_name, $currencies ); + +} + + +/* + * Returns the currency symbol for a given currency code + * + * @param string $currency_code + * + * @return string + * + */ +function wppb_get_currency_symbol( $currency_code ) { + + $currency_symbols = array( + 'AED' => 'د.إ', // ? + 'AFN' => 'Af', + 'ALL' => 'Lek', + 'AMD' => '', + 'ANG' => 'ƒ', + 'AOA' => 'Kz', // ? + 'ARS' => '$', + 'AUD' => '$', + 'AWG' => 'ƒ', + 'AZN' => 'ман', + 'BAM' => 'KM', + 'BBD' => '$', + 'BDT' => '৳', // ? + 'BGN' => 'лв', + 'BHD' => '.د.ب', // ? + 'BIF' => 'FBu', // ? + 'BMD' => '$', + 'BND' => '$', + 'BOB' => '$b', + 'BRL' => 'R$', + 'BSD' => '$', + 'BTN' => 'Nu.', // ? + 'BWP' => 'P', + 'BYR' => 'p.', + 'BZD' => 'BZ$', + 'CAD' => '$', + 'CDF' => 'FC', + 'CHF' => 'CHF', + 'CLF' => '', // ? + 'CLP' => '$', + 'CNY' => '¥', + 'COP' => '$', + 'CRC' => '₡', + 'CUP' => '⃌', + 'CVE' => '$', // ? + 'CZK' => 'Kč', + 'DJF' => 'Fdj', // ? + 'DKK' => 'kr', + 'DOP' => 'RD$', + 'DZD' => 'دج', // ? + 'EGP' => '£', + 'ETB' => 'Br', + 'EUR' => '€', + 'FJD' => '$', + 'FKP' => '£', + 'GBP' => '£', + 'GEL' => 'ლ', // ? + 'GHS' => '¢', + 'GIP' => '£', + 'GMD' => 'D', // ? + 'GNF' => 'FG', // ? + 'GTQ' => 'Q', + 'GYD' => '$', + 'HKD' => '$', + 'HNL' => 'L', + 'HRK' => 'kn', + 'HTG' => 'G', // ? + 'HUF' => 'Ft', + 'IDR' => 'Rp', + 'ILS' => '₪', + 'INR' => '₹', + 'IQD' => 'ع.د', // ? + 'IRR' => '﷼', + 'ISK' => 'kr', + 'JEP' => '£', + 'JMD' => 'J$', + 'JOD' => 'JD', // ? + 'JPY' => '¥', + 'KES' => 'KSh', // ? + 'KGS' => 'лв', + 'KHR' => '៛', + 'KMF' => 'CF', // ? + 'KPW' => '₩', + 'KRW' => '₩', + 'KWD' => 'د.ك', // ? + 'KYD' => '$', + 'KZT' => 'лв', + 'LAK' => '₭', + 'LBP' => '£', + 'LKR' => '₨', + 'LRD' => '$', + 'LSL' => 'L', // ? + 'LTL' => 'Lt', + 'LVL' => 'Ls', + 'LYD' => 'ل.د', // ? + 'MAD' => 'د.م.', //? + 'MDL' => 'L', + 'MGA' => 'Ar', // ? + 'MKD' => 'ден', + 'MMK' => 'K', + 'MNT' => '₮', + 'MOP' => 'MOP$', // ? + 'MRO' => 'UM', // ? + 'MUR' => '₨', // ? + 'MVR' => '.ރ', // ? + 'MWK' => 'MK', + 'MXN' => '$', + 'MYR' => 'RM', + 'MZN' => 'MT', + 'NAD' => '$', + 'NGN' => '₦', + 'NIO' => 'C$', + 'NOK' => 'kr', + 'NPR' => '₨', + 'NZD' => '$', + 'OMR' => '﷼', + 'PAB' => 'B/.', + 'PEN' => 'S/.', + 'PGK' => 'K', // ? + 'PHP' => '₱', + 'PKR' => '₨', + 'PLN' => 'zł', + 'PYG' => 'Gs', + 'QAR' => '﷼', + 'RON' => 'lei', + 'RSD' => 'Дин.', + 'RUB' => 'руб', + 'RWF' => 'ر.س', + 'SAR' => '﷼', + 'SBD' => '$', + 'SCR' => '₨', + 'SDG' => '£', // ? + 'SEK' => 'kr', + 'SGD' => '$', + 'SHP' => '£', + 'SLL' => 'Le', // ? + 'SOS' => 'S', + 'SRD' => '$', + 'STD' => 'Db', // ? + 'SVC' => '$', + 'SYP' => '£', + 'SZL' => 'L', // ? + 'THB' => '฿', + 'TJS' => 'TJS', // ? TJS (guess) + 'TMT' => 'm', + 'TND' => 'د.ت', + 'TOP' => 'T$', + 'TRY' => '₤', // New Turkey Lira (old symbol used) + 'TTD' => '$', + 'TWD' => 'NT$', + 'TZS' => '', + 'UAH' => '₴', + 'UGX' => 'USh', + 'USD' => '$', + 'UYU' => '$U', + 'UZS' => 'лв', + 'VEF' => 'Bs', + 'VND' => '₫', + 'VUV' => 'VT', + 'WST' => 'WS$', + 'XAF' => 'FCFA', + 'XCD' => '$', + 'XDR' => '', + 'XOF' => '', + 'XPF' => 'F', + 'YER' => '﷼', + 'ZAR' => 'R', + 'ZMK' => 'ZK', // ? + 'ZWL' => 'Z$', + ); + + if( !empty( $currency_symbols[$currency_code] ) ) + return $currency_symbols[$currency_code]; + else + return ''; + +} + + +/** + * Function that returns a unique, incremented ID + * + * @since v.2.0 + * + * @return integer id + */ +function wppb_get_unique_id(){ + $id = 1; + $wppb_manage_fields = get_option( 'wppb_manage_fields', 'not_found' ); + if ( ( $wppb_manage_fields === 'not_found' ) || ( empty( $wppb_manage_fields ) ) ){ + return $id; + } + else{ + $ids_array = array(); + foreach( $wppb_manage_fields as $value ){ + $ids_array[] = $value['id']; + } + if( !empty( $ids_array ) ){ + rsort( $ids_array ); + $id = $ids_array[0] + 1; + } + } + return apply_filters( 'wppb_field_unique_id', $id, $ids_array, $wppb_manage_fields ); +} + +/** + * Function that checks to see if the id is unique when saving the new field + * + * @param array $values + * + * @return array + */ +function wppb_check_unique_id_on_saving( $values ) { + $wppb_manage_fields = get_option( 'wppb_manage_fields', 'not_found' ); + + if( $wppb_manage_fields != 'not_found' ) { + + $ids_array = array(); + foreach( $wppb_manage_fields as $field ){ + $ids_array[] = $field['id']; + } + + if( in_array( $values['id'], $ids_array ) ) { + rsort( $ids_array ); + $values['id'] = $ids_array[0] + 1; + } + + } + return $values; +} +add_filter( 'wck_add_meta_filter_values_wppb_manage_fields', 'wppb_check_unique_id_on_saving' ); + + +function wppb_return_unique_field_list( $only_default_fields = false ){ + + $unique_field_list[] = 'Default - Name (Heading)'; + $unique_field_list[] = 'Default - Contact Info (Heading)'; + $unique_field_list[] = 'Default - About Yourself (Heading)'; + $unique_field_list[] = 'Default - Username'; + $unique_field_list[] = 'Default - First Name'; + $unique_field_list[] = 'Default - Last Name'; + $unique_field_list[] = 'Default - Nickname'; + $unique_field_list[] = 'Default - E-mail'; + $unique_field_list[] = 'Default - Website'; + + // Default contact methods were removed in WP 3.6. A filter dictates contact methods. + if ( apply_filters( 'wppb_remove_default_contact_methods', get_site_option( 'initial_db_version' ) < 23588 ) ){ + $unique_field_list[] = 'Default - AIM'; + $unique_field_list[] = 'Default - Yahoo IM'; + $unique_field_list[] = 'Default - Jabber / Google Talk'; + } + + $unique_field_list[] = 'Default - Password'; + $unique_field_list[] = 'Default - Repeat Password'; + $unique_field_list[] = 'Default - Biographical Info'; + $unique_field_list[] = 'Default - Display name publicly as'; + + if ( wppb_can_users_signup_blog() ) { + $unique_field_list[] = 'Default - Blog Details'; + } + + if( !$only_default_fields ){ + $unique_field_list[] = 'Avatar'; + $unique_field_list[] = 'reCAPTCHA'; + $unique_field_list[] = 'Select (User Role)'; + } + + return apply_filters ( 'wppb_unique_field_list', $unique_field_list ); +} + + +/** + * Function that checks several things when adding/editing the fields + * + * @since v.2.0 + * + * @param string $message - the message to be displayed + * @param array $fields - the added fields + * @param array $required_fields + * @param string $meta - the meta-name of the option + * @param string $values - The values entered for each option + * @param integer $post_id + * @return boolean + */ +function wppb_check_field_on_edit_add( $message, $fields, $required_fields, $meta_name, $posted_values, $post_id ){ + global $wpdb; + + if ( $meta_name == 'wppb_manage_fields' ){ + + // check for a valid field-type (fallback) + if ( $posted_values['field'] == '' ) + $message .= __( "You must select a field\n", 'profile-builder' ); + // END check for a valid field-type (fallback) + + $unique_field_list = wppb_return_unique_field_list(); + $all_fields = apply_filters( 'wppb_manage_fields_check_field_on_edit_add', get_option ( $meta_name, 'not_set' ), $posted_values ); + + // check if the unique fields are only added once + if( $all_fields != 'not_set' ){ + foreach( $all_fields as $field ){ + if ( ( in_array ( $posted_values['field'], $unique_field_list ) ) && ( $posted_values['field'] == $field['field'] ) && ( $posted_values['id'] != $field['id'] ) ){ + $message .= __( "Please choose a different field type as this one already exists in your form (must be unique)\n", 'profile-builder' ); + break; + } + } + } + // END check if the unique fields are only added once + + // check for avatar size + if ( $posted_values['field'] == 'Avatar' ){ + if ( is_numeric( $posted_values['avatar-size'] ) ){ + if ( ( $posted_values['avatar-size'] < 20 ) || ( $posted_values['avatar-size'] > 200 ) ) + $message .= __( "The entered avatar size is not between 20 and 200\n", 'profile-builder' ); + + }else + $message .= __( "The entered avatar size is not numerical\n", 'profile-builder' ); + + } + // END check for avatar size + + // check for correct row value + if ( ( $posted_values['field'] == 'Default - Biographical Info' ) || ( $posted_values['field'] == 'Textarea' ) ){ + if ( !is_numeric( $posted_values['row-count'] ) ) + $message .= __( "The entered row number is not numerical\n", 'profile-builder' ); + + elseif ( trim( $posted_values['row-count'] ) == '' ) + $message .= __( "You must enter a value for the row number\n", 'profile-builder' ); + } + // END check for correct row value + + + // check for the public and private keys + if ( $posted_values['field'] == 'reCAPTCHA'){ + if ( trim( $posted_values['public-key'] ) == '' ) + $message .= __( "You must enter the site key\n", 'profile-builder' ); + if ( trim( $posted_values['private-key'] ) == '' ) + $message .= __( "You must enter the secret key\n", 'profile-builder' ); + } + // END check for the public and private keys + + // check for the correct the date-format + if ( $posted_values['field'] == 'Datepicker' ){ + $date_format = strtolower( $posted_values['date-format'] ); + if ( trim( $date_format ) != 'mm/dd/yy' && trim( $date_format ) != 'mm/yy/dd' && trim( $date_format ) != 'dd/yy/mm' && + trim( $date_format ) != 'dd/mm/yy' && trim( $date_format ) != 'yy/dd/mm' && trim( $date_format ) != 'yy/mm/dd' && + trim( $date_format ) != 'yy-mm-dd' && trim( $date_format ) != 'DD, dd-M-y' && trim( $date_format ) != 'D, dd M yy' && + trim( $date_format ) != 'D, d M y' && trim( $date_format ) != 'D, d M yy' && trim( $date_format ) != 'mm-dd-yy' && trim( $date_format ) != '@' ) + $message .= __( "The entered value for the Datepicker is not a valid date-format\n", 'profile-builder' ); + + elseif ( trim( $date_format ) == '' ) + $message .= __( "You must enter a value for the date-format\n", 'profile-builder' ); + } + // END check for the correct the date-format + + //check for empty meta-name and duplicate meta-name + if ( $posted_values['overwrite-existing'] == 'No' ){ + $skip_check_for_fields = wppb_return_unique_field_list(true); + $skip_check_for_fields = apply_filters ( 'wppb_skip_check_for_fields', $skip_check_for_fields ); + + if ( !in_array( trim( $posted_values['field'] ), $skip_check_for_fields ) ){ + $unique_meta_name_list = array( 'first_name', 'last_name', 'nickname', 'description' ); + + //check to see if meta-name is empty + $skip_empty_check_for_fields = array( 'Heading', 'Select (User Role)', 'reCAPTCHA', 'HTML' ); + + if( !in_array( $posted_values['field'], $skip_empty_check_for_fields ) && empty( $posted_values['meta-name'] ) ) { + $message .= __( "The meta-name cannot be empty\n", 'profile-builder' ); + } + + // Default contact methods were removed in WP 3.6. A filter dictates contact methods. + if ( apply_filters( 'wppb_remove_default_contact_methods', get_site_option( 'initial_db_version' ) < 23588 ) ){ + $unique_meta_name_list[] = 'aim'; + $unique_meta_name_list[] = 'yim'; + $unique_meta_name_list[] = 'jabber'; + } + + // if the desired meta-name is one of the following, automatically give an error + if ( in_array( trim( $posted_values['meta-name'] ), apply_filters ( 'wppb_unique_meta_name_list', $unique_meta_name_list ) ) ) + $message .= __( "That meta-name is already in use\n", 'profile-builder' ); + + else{ + $found_in_custom_fields = false; + + if( $all_fields != 'not_set' ) + foreach( $all_fields as $field ){ + if ( $posted_values['meta-name'] != '' && ( $field['meta-name'] == $posted_values['meta-name'] ) && ( $field['id'] != $posted_values['id'] ) ){ + $message .= __( "That meta-name is already in use\n", 'profile-builder' ); + $found_in_custom_fields = true; + + }elseif ( ( $field['meta-name'] == $posted_values['meta-name'] ) && ( $field['id'] == $posted_values['id'] ) ) + $found_in_custom_fields = true; + } + + if ( $found_in_custom_fields === false ){ + if( $posted_values['meta-name'] != '' ) { + $found_meta_name = $wpdb->get_row($wpdb->prepare("SELECT * FROM $wpdb->usermeta WHERE meta_key = %s", $posted_values['meta-name'])); + if ($found_meta_name != null) + $message .= __("That meta-name is already in use\n", 'profile-builder'); + } + } + } + } + } + //END check duplicate meta-name + + // check for correct meta name on upload field + if( $posted_values['field'] == 'Upload' ) { + if( ! empty( $posted_values['meta-name'] ) && preg_match( '/([^a-z\d_-])/', $posted_values['meta-name'] ) ) { + $message .= __( "The meta-name can only contain lowercase letters, numbers, _ , - and no spaces.\n", 'profile-builder' ); + } + } + // END check for correct meta name on upload field + + // check for valid default option (checkbox, select, radio) + if ( ( $posted_values['field'] == 'Checkbox' ) || ( $posted_values['field'] == 'Select (Multiple)' ) ) { + $options = array_map( 'trim', explode( ',', $posted_values['options'] ) ); + $default_options = ( ( trim( $posted_values['default-options'] ) == '' ) ? array() : array_map( 'trim', explode( ',', $posted_values['default-options'] ) ) ); + + /* echo ""; + echo ""; */ + + $not_found = ''; + foreach ( $default_options as $key => $value ){ + if ( !in_array( $value, $options ) ) + $not_found .= $value . ', '; + } + + if ( $not_found != '' ) + $message .= sprintf( __( "The following option(s) did not coincide with the ones in the options list: %s\n", 'profile-builder' ), trim( $not_found, ', ' ) ); + + }elseif ( ( $posted_values['field'] == 'Radio' ) || ( $posted_values['field'] == 'Select' ) ){ + if ( ( trim( $posted_values['default-option'] ) != '' ) && ( !in_array( $posted_values['default-option'], array_map( 'trim', explode( ',', $posted_values['options'] ) ) ) ) ) + $message .= sprintf( __( "The following option did not coincide with the ones in the options list: %s\n", 'profile-builder' ), $posted_values['default-option'] ); + } + // END check for valid default option (checkbox, select, radio) + + // check to see if any user role is selected (user-role field) + if( $posted_values['field'] == 'Select (User Role)' ) { + if( empty( $posted_values['user-roles'] ) ) { + $message .= __( "Please select at least one user role\n", 'profile-builder' ); + } + } + // END check to see if Administrator user role has been selected (user-role field) + + $message = apply_filters( 'wppb_check_extra_manage_fields', $message, $posted_values ); + + }elseif ( ( $meta_name == 'wppb_rf_fields' ) || ( $meta_name == 'wppb_epf_fields' ) ){ + if ( $posted_values['field'] == '' ){ + $message .= __( "You must select a field\n", 'profile-builder' ); + + }else{ + $fields_so_far = get_post_meta ( $post_id, $meta_name, true ); + + foreach ( $fields_so_far as $key => $value ){ + if ( $value['id'] == $posted_values['id'] ) + $message .= __( "That field is already added in this form\n", 'profile-builder' ); + } + } + } + return $message; +} +add_filter( 'wck_extra_message', 'wppb_check_field_on_edit_add', 10, 6 ); + + +/** + * Function that calls the wppb_hide_properties_for_already_added_fields after a field-update + * + * @since v.2.0 + * + * @param void + * + * @return string + */ +function wppb_manage_fields_after_refresh_list( $id ){ + echo ""; +} +add_action( "wck_refresh_list_wppb_manage_fields", "wppb_manage_fields_after_refresh_list" ); +add_action( "wck_refresh_entry_wppb_manage_fields", "wppb_manage_fields_after_refresh_list" ); + + +/** + * Function that calls the wppb_hide_all + * + * @since v.2.0 + * + * @param void + * + * @return string + */ +function wppb_hide_all_after_add( $id ){ + echo ""; +} +add_action("wck_ajax_add_form_wppb_manage_fields", "wppb_hide_all_after_add" ); + +/** + * Function that modifies the table header in Manage Fields to add Field Name, Field Type, Meta Key, Required + * + * @since v.2.0 + * + * @param $list, $id + * + * @return string + */ +function wppb_manage_fields_header( $list_header ){ + return '#'. __( '
    Title
    Type
    Meta Name
    Required
    ', 'profile-builder' ) .''. __( 'Edit', 'profile-builder' ) .''. __( 'Delete', 'profile-builder' ) .''; +} +add_action( 'wck_metabox_content_header_wppb_manage_fields', 'wppb_manage_fields_header' ); + +/** + * Add contextual help to the side of manage fields for the shortcodes + * + * @since v.2.0 + * + * @param $hook + * + * @return string + */ +function wppb_add_content_before_manage_fields(){ +?> +

    +
      +
    • [wppb-register]
    • +
    • [wppb-edit-profile]
    • +
    • [wppb-register role="author"]
    • +
    +

    + +

    +wppb_disable_delete_on_default_mandatory_fields();"; + + if ( $meta_name == 'wppb_manage_fields' ) + echo ""; +} +add_action("wck_after_adding_form", "wppb_remove_properties_from_added_form", 10, 3); + +/* + * WPML Support for dynamic strings in Profile Builder. Tags: WPML, fields, translate + */ +add_filter( 'update_option_wppb_manage_fields', 'wppb_wpml_compat_with_fields', 10, 2 ); +function wppb_wpml_compat_with_fields( $oldvalue, $_newvalue ){ + $default_fields = array( + 'Default - Name (Heading)', + 'Default - Contact Info (Heading)', + 'Default - About Yourself (Heading)', + 'Default - Username', + 'Default - First Name', + 'Default - Last Name', + 'Default - Nickname', + 'Default - E-mail', + 'Default - Website', + 'Default - AIM', + 'Default - Yahoo IM', + 'Default - Jabber / Google Talk', + 'Default - Password', + 'Default - Repeat Password', + 'Default - Biographical Info', + 'Default - Blog Details', + 'Default - Display name publicly as' + ); + + if ( is_array( $_newvalue ) ){ + foreach ( $_newvalue as $field ){ + if ( in_array($field['field'], $default_fields) ){ + $prefix = 'default_field_'; + } else { + $prefix = 'custom_field_'; + } + if (function_exists('icl_register_string')){ + if( !empty( $field['field-title'] ) ) + icl_register_string('plugin profile-builder-pro', $prefix . $field['id'].'_title_translation' , $field['field-title'] ); + if( !empty( $field['description'] ) ) + icl_register_string('plugin profile-builder-pro', $prefix . $field['id'].'_description_translation', $field['description'] ); + if( !empty( $field['labels'] ) ) + icl_register_string('plugin profile-builder-pro', $prefix . $field['id'].'_labels_translation', $field['labels'] ); + if( !empty( $field['default-value'] ) ) + icl_register_string('plugin profile-builder-pro', $prefix . $field['id'].'_default_value_translation', $field['default-value'] ); + if( !empty( $field['default-content'] ) ) + icl_register_string('plugin profile-builder-pro', $prefix . $field['id'].'_default_content_translation', $field['default-content'] ); + } + } + } +} + + +/* + * Returns the HTML for a map given the field + * + */ +function wppb_get_map_output( $field, $args ) { + + $defaults = array( + 'markers' => array(), + 'editable' => true, + 'show_search' => true, + 'extra_attr' => '' + ); + + $args = wp_parse_args( $args, $defaults ); + + $return = ''; + + // Search box + // The style:left=-99999px is set to hide the input from the viewport. It will be rewritten when the map gets initialised + if( $args['show_search'] ) + $return .= ''; + + // Map container + $return .= '
    '; + + if( !empty( $args['markers'] ) ) { + foreach( $args['markers'] as $marker ) + $return .= ''; + } + + return $return; + +} + + +/* + * Returns all the saved markers for a map field for a particular user + * + */ +function wppb_get_user_map_markers( $user_id, $meta_name ) { + + global $wpdb; + + $meta_name_underlined = $meta_name . '_'; + + $results = $wpdb->get_results( "SELECT meta_value, meta_key FROM {$wpdb->usermeta} WHERE user_id={$user_id} AND meta_key LIKE '%{$meta_name_underlined}%'", ARRAY_N ); + + $markers = array(); + $i = 0; + + foreach( $results as $key => $result ) { + $pattern = '/^' . $meta_name . '_[0-9]+$/'; + preg_match( $pattern, $result[1], $matches ); + if ( count ($matches) > 0 ) { + $markers[$i] = $result[0]; + $i++; + } + + } + return $markers; + +} + +/* + * Deletes from the database all saved markers + * + */ +function wppb_delete_user_map_markers( $user_id, $meta_name ) { + + global $wpdb; + + $meta_name .= '_'; + + $delete = $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->usermeta} WHERE user_id=%d AND meta_key LIKE %s", $user_id, '%' . $meta_name . '%' ) ); + + wp_cache_delete( $user_id, 'user_meta' ); + +} + +/** + * Disable the add button again after we added a field + */ +add_action( 'wck_ajax_add_form_wppb_manage_fields', 'wppb_redisable_the_add_button' ); +function wppb_redisable_the_add_button(){ + ?> + + -
    -
    -

    Users can pay for an account with
    Profile Builder and Paid Member Subscriptions

    -
    -
    -

    One of the most requested features in Profile Builder was for users to be able to pay for an account.

    -

    Now that's possible using the free WordPress plugin - Paid Member Subscriptions.

    -
    - - -

    -
    -
    -
    -

    -

    Other features of Paid Member Subscriptions are:

    -
      -
    • -
    • -
    • -
    • -
    • -
    • -
    • -
    -
    -
    - -
    - $wppb_plugin) { - if( strtolower($wppb_plugin['Name']) == strtolower( 'Paid Member Subscriptions' ) && strpos(strtolower($wppb_plugin['AuthorName']), strtolower('Cozmoslabs')) !== false) { - $pms_add_on_exists = 1; - if (in_array($wppb_plugin_key, $wppb_get_active_plugins)) { - $pms_add_on_is_active = 1; - } - // Consider the add-on active if it's network active - if (is_plugin_active_for_network($wppb_plugin_key)) { - $pms_add_on_is_network_active = 1; - $pms_add_on_is_active = 1; - } - $plugin_file = $wppb_plugin_key; - } - } - ?> - - - - - - - - - - - active', 'profile-builder' ); ?> - inactive', 'profile-builder' ); ?> - - - - - - -
    - - -
    -
    - -

    -
    -

    Setting up Paid Member Subscriptions opens the door to paid user accounts.

    -
    -

    Create Subscription Plans

    -

    With Paid Member Subscriptions it’s fairly easy to create tiered subscription plans for your users.

    -

    Adding a new subscription gives you access to the following options to set up: subscription name, description, duration, the price, status and user role.

    -
    -
    -

    paid subscription plans

    -
    -
    -
    -

    Add Subscriptions field to Profile Builder -> Manage Fields

    -

    The new Subscription Plans field will add a list of radio buttons with membership details to Profile Builder registration forms.

    -
    -
    -

    manage fields subscription plans

    -
    -
    -
    -

    Start getting user payments

    -

    To finalize registration for a paid account, users will need to complete the payment.

    -

    Members created with Profile Builder registration form will have the user role of the selected subscription.

    -
    -
    -

    register payed accounts

    -
    -
    - - -
    -
    - ' . __('Activate', 'profile-builder') . ''; - - // If add-on is network activated don't allow deactivation - } elseif (!$pms_add_on_is_network_active) { - echo '' . __('Deactivate', 'profile-builder') . ''; - } - - // Display message to the user - if( !$pms_add_on_is_active ){ - echo '' . __('Plugin is inactive', 'profile-builder') . ''; - } else { - echo '' . __('Plugin is active', 'profile-builder') . ''; - } - - } else { - - // If we're on a multisite don't add the wpp-add-on-download class to the button so we don't fire the js that - // handles the in-page download - if (is_multisite()) { - $wppb_paid_link_class = 'button-secondary'; - $wppb_paid_link_text = __('Download Now', 'profile-builder' ); - } else { - $wppb_paid_link_class = 'button-secondary wppb-add-on-download'; - $wppb_paid_link_text = __('Install Now', 'profile-builder'); - } - - echo '' . $wppb_paid_link_text . ''; - echo '' . __('Compatible with your version of Profile Builder.', 'profile-builder') . ''; - } - ?> -
    - install manually.', 'profile-builder'), esc_url( 'http://www.wordpress.org/plugins/paid-member-subscriptions' )) ?>. */ ?> -
    -
    - - -
    -paid accounts with Profile Builder. %1$sFind out how >%2$s %3$sDismiss%4$s', 'profile-builder'), "", "", "", ""), - 'pms-cross-promo'); -} -*/ + +
    +
    +

    Users can pay for an account with
    Profile Builder and Paid Member Subscriptions

    +
    +
    +

    One of the most requested features in Profile Builder was for users to be able to pay for an account.

    +

    Now that's possible using the free WordPress plugin - Paid Member Subscriptions.

    +
    + + +

    +
    +
    +
    +

    +

    Other features of Paid Member Subscriptions are:

    +
      +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    +
    +
    + +
    + $wppb_plugin) { + if( strtolower($wppb_plugin['Name']) == strtolower( 'Paid Member Subscriptions' ) && strpos(strtolower($wppb_plugin['AuthorName']), strtolower('Cozmoslabs')) !== false) { + $pms_add_on_exists = 1; + if (in_array($wppb_plugin_key, $wppb_get_active_plugins)) { + $pms_add_on_is_active = 1; + } + // Consider the add-on active if it's network active + if (is_plugin_active_for_network($wppb_plugin_key)) { + $pms_add_on_is_network_active = 1; + $pms_add_on_is_active = 1; + } + $plugin_file = $wppb_plugin_key; + } + } + ?> + + + + + + + + + + + active', 'profile-builder' ); ?> + inactive', 'profile-builder' ); ?> + + + + + + +
    + + +
    +
    + +

    +
    +

    Setting up Paid Member Subscriptions opens the door to paid user accounts.

    +
    +

    Create Subscription Plans

    +

    With Paid Member Subscriptions it’s fairly easy to create tiered subscription plans for your users.

    +

    Adding a new subscription gives you access to the following options to set up: subscription name, description, duration, the price, status and user role.

    +
    +
    +

    paid subscription plans

    +
    +
    +
    +

    Add Subscriptions field to Profile Builder -> Manage Fields

    +

    The new Subscription Plans field will add a list of radio buttons with membership details to Profile Builder registration forms.

    +
    +
    +

    manage fields subscription plans

    +
    +
    +
    +

    Start getting user payments

    +

    To finalize registration for a paid account, users will need to complete the payment.

    +

    Members created with Profile Builder registration form will have the user role of the selected subscription.

    +
    +
    +

    register payed accounts

    +
    +
    + + +
    +
    + ' . __('Activate', 'profile-builder') . ''; + + // If add-on is network activated don't allow deactivation + } elseif (!$pms_add_on_is_network_active) { + echo '' . __('Deactivate', 'profile-builder') . ''; + } + + // Display message to the user + if( !$pms_add_on_is_active ){ + echo '' . __('Plugin is inactive', 'profile-builder') . ''; + } else { + echo '' . __('Plugin is active', 'profile-builder') . ''; + } + + } else { + + // If we're on a multisite don't add the wpp-add-on-download class to the button so we don't fire the js that + // handles the in-page download + if (is_multisite()) { + $wppb_paid_link_class = 'button-secondary'; + $wppb_paid_link_text = __('Download Now', 'profile-builder' ); + } else { + $wppb_paid_link_class = 'button-secondary wppb-add-on-download'; + $wppb_paid_link_text = __('Install Now', 'profile-builder'); + } + + echo '' . $wppb_paid_link_text . ''; + echo '' . __('Compatible with your version of Profile Builder.', 'profile-builder') . ''; + } + ?> +
    + install manually.', 'profile-builder'), esc_url( 'http://www.wordpress.org/plugins/paid-member-subscriptions' )) ?>. */ ?> +
    +
    + + +
    +paid accounts with Profile Builder. %1$sFind out how >%2$s %3$sDismiss%4$s', 'profile-builder'), "", "", "", ""), + 'pms-cross-promo'); +} +*/ diff --git a/profile-builder/admin/register-version.php b/profile-builder/admin/register-version.php index 08169f0..5576fc2 100644 --- a/profile-builder/admin/register-version.php +++ b/profile-builder/admin/register-version.php @@ -1,252 +1,252 @@ - -
    - - -
    - - -

    - -
    - - - - - -

    -

    -

    - - /> - - '; - elseif ( $wppb_profile_builder_serial_status == 'notFound' ) - echo ''; - elseif ( strpos( $wppb_profile_builder_serial_status, 'aboutToExpire') !== false ) - echo ''. sprintf( __(' Your serial number is about to expire, please %1$s Renew Your License%2$s.','profile-builder'), "", "").''; - elseif ( $wppb_profile_builder_serial_status == 'expired' ) - echo ''. sprintf( __(' Your serial number is expired, please %1$s Renew Your License%2$s.','profile-builder'), "", "").''; - elseif ( $wppb_profile_builder_serial_status == 'serverDown' ) - echo ''; - ?> - -

    - - -
    - -

    - - -

    -
    - -
    -pluginPrefix = $pluginPrefix; - $this->pluginName = $pluginName; - $this->notificaitonMessage = $notificaitonMessage; - $this->pluginSerialStatus = $pluginSerialStatus; - - add_action( 'admin_notices', array( $this, 'add_admin_notice' ) ); - add_action( 'admin_init', array( $this, 'dismiss_notification' ) ); - } - - - // Display a notice that can be dismissed in case the serial number is inactive - function add_admin_notice() { - global $current_user ; - global $pagenow; - - $user_id = $current_user->ID; - - do_action( $this->pluginPrefix.'_before_notification_displayed', $current_user, $pagenow ); - - if ( current_user_can( 'manage_options' ) ){ - - $plugin_serial_status = get_option( $this->pluginSerialStatus ); - if ( $plugin_serial_status != 'found' ){ - // Check that the user hasn't already clicked to ignore the message - if ( ! get_user_meta($user_id, $this->pluginPrefix.'_dismiss_notification' ) ) { - echo $finalMessage = apply_filters($this->pluginPrefix.'_notification_message','
    '.$this->notificaitonMessage.'
    ', $this->notificaitonMessage); - } - } - - do_action( $this->pluginPrefix.'_notification_displayed', $current_user, $pagenow, $plugin_serial_status ); - - } - - do_action( $this->pluginPrefix.'_after_notification_displayed', $current_user, $pagenow ); - - } - - function dismiss_notification() { - global $current_user; - - $user_id = $current_user->ID; - - do_action( $this->pluginPrefix.'_before_notification_dismissed', $current_user ); - - // If user clicks to ignore the notice, add that to their user meta - if ( isset( $_GET[$this->pluginPrefix.'_dismiss_notification']) && '0' == $_GET[$this->pluginPrefix.'_dismiss_notification'] ) - add_user_meta( $user_id, $this->pluginPrefix.'_dismiss_notification', 'true', true ); - - do_action( $this->pluginPrefix.'_after_notification_dismissed', $current_user ); - } -} - -if( is_multisite() && function_exists( 'switch_to_blog' ) ) - switch_to_blog(1); - -if ( PROFILE_BUILDER == 'Profile Builder Pro' ){ - $wppb_profile_builder_pro_hobbyist_serial_status = get_option( 'wppb_profile_builder_pro_serial_status', 'empty' ); - $version = 'pro'; - -} elseif( PROFILE_BUILDER == 'Profile Builder Hobbyist' ) { - $wppb_profile_builder_pro_hobbyist_serial_status = get_option( 'wppb_profile_builder_hobbyist_serial_status', 'empty' ); - $version = 'hobbyist'; -} -if( is_multisite() && function_exists( 'restore_current_blog' ) ) - restore_current_blog(); - -if ( $wppb_profile_builder_pro_hobbyist_serial_status == 'notFound' || $wppb_profile_builder_pro_hobbyist_serial_status == 'empty' ){ - if( !is_multisite() ) - $register_url = 'admin.php?page=profile-builder-register'; - else - $register_url = network_admin_url( 'admin.php?page=profile-builder-register' ); - - new wppb_add_notices( 'wppb', 'profile_builder_pro', sprintf( __( '

    Your Profile Builder serial number is invalid or missing.
    Please %1$sregister your copy%2$s to receive access to automatic updates and support. Need a license key? %3$sPurchase one now%4$s

    ', 'profile-builder'), "", "", "", "" ), 'wppb_profile_builder_pro_serial_status' ); -} -elseif ( $wppb_profile_builder_pro_hobbyist_serial_status == 'expired' ){ - new wppb_add_notices( 'wppb_expired', 'profile_builder_pro', sprintf( __( '

    Your Profile Builder license has expired.
    Please %1$sRenew Your Licence%2$s to continue receiving access to product downloads, automatic updates and support. %3$sRenew now and get 40% off %4$s %5$sDismiss%6$s

    ', 'profile-builder'), "", "", "", "", "", "" ), 'wppb_profile_builder_pro_serial_status' ); -} -elseif( strpos( $wppb_profile_builder_pro_hobbyist_serial_status, 'aboutToExpire' ) === 0 ){ - $serial_status_parts = explode( '#', $wppb_profile_builder_pro_hobbyist_serial_status ); - $date = $serial_status_parts[1]; - new wppb_add_notices( 'wppb_about_to_expire', 'profile_builder_pro', sprintf( __( '

    Your Profile Builder license is about to expire on %5$s.
    Please %1$sRenew Your Licence%2$s to continue receiving access to product downloads, automatic updates and support. %3$sRenew now and get 40% off %4$s %6$sDismiss%7$s

    ', 'profile-builder'), "", "", "", "", $date, "", "" ), 'wppb_profile_builder_pro_serial_status' ); + +
    + + +
    + + +

    + +
    + + + + + +

    +

    +

    + + /> + + '; + elseif ( $wppb_profile_builder_serial_status == 'notFound' ) + echo ''; + elseif ( strpos( $wppb_profile_builder_serial_status, 'aboutToExpire') !== false ) + echo ''. sprintf( __(' Your serial number is about to expire, please %1$s Renew Your License%2$s.','profile-builder'), "", "").''; + elseif ( $wppb_profile_builder_serial_status == 'expired' ) + echo ''. sprintf( __(' Your serial number is expired, please %1$s Renew Your License%2$s.','profile-builder'), "", "").''; + elseif ( $wppb_profile_builder_serial_status == 'serverDown' ) + echo ''; + ?> + +

    + + +
    + +

    + + +

    +
    + +
    +pluginPrefix = $pluginPrefix; + $this->pluginName = $pluginName; + $this->notificaitonMessage = $notificaitonMessage; + $this->pluginSerialStatus = $pluginSerialStatus; + + add_action( 'admin_notices', array( $this, 'add_admin_notice' ) ); + add_action( 'admin_init', array( $this, 'dismiss_notification' ) ); + } + + + // Display a notice that can be dismissed in case the serial number is inactive + function add_admin_notice() { + global $current_user ; + global $pagenow; + + $user_id = $current_user->ID; + + do_action( $this->pluginPrefix.'_before_notification_displayed', $current_user, $pagenow ); + + if ( current_user_can( 'manage_options' ) ){ + + $plugin_serial_status = get_option( $this->pluginSerialStatus ); + if ( $plugin_serial_status != 'found' ){ + // Check that the user hasn't already clicked to ignore the message + if ( ! get_user_meta($user_id, $this->pluginPrefix.'_dismiss_notification' ) ) { + echo $finalMessage = apply_filters($this->pluginPrefix.'_notification_message','
    '.$this->notificaitonMessage.'
    ', $this->notificaitonMessage); + } + } + + do_action( $this->pluginPrefix.'_notification_displayed', $current_user, $pagenow, $plugin_serial_status ); + + } + + do_action( $this->pluginPrefix.'_after_notification_displayed', $current_user, $pagenow ); + + } + + function dismiss_notification() { + global $current_user; + + $user_id = $current_user->ID; + + do_action( $this->pluginPrefix.'_before_notification_dismissed', $current_user ); + + // If user clicks to ignore the notice, add that to their user meta + if ( isset( $_GET[$this->pluginPrefix.'_dismiss_notification']) && '0' == $_GET[$this->pluginPrefix.'_dismiss_notification'] ) + add_user_meta( $user_id, $this->pluginPrefix.'_dismiss_notification', 'true', true ); + + do_action( $this->pluginPrefix.'_after_notification_dismissed', $current_user ); + } +} + +if( is_multisite() && function_exists( 'switch_to_blog' ) ) + switch_to_blog(1); + +if ( PROFILE_BUILDER == 'Profile Builder Pro' ){ + $wppb_profile_builder_pro_hobbyist_serial_status = get_option( 'wppb_profile_builder_pro_serial_status', 'empty' ); + $version = 'pro'; + +} elseif( PROFILE_BUILDER == 'Profile Builder Hobbyist' ) { + $wppb_profile_builder_pro_hobbyist_serial_status = get_option( 'wppb_profile_builder_hobbyist_serial_status', 'empty' ); + $version = 'hobbyist'; +} +if( is_multisite() && function_exists( 'restore_current_blog' ) ) + restore_current_blog(); + +if ( $wppb_profile_builder_pro_hobbyist_serial_status == 'notFound' || $wppb_profile_builder_pro_hobbyist_serial_status == 'empty' ){ + if( !is_multisite() ) + $register_url = 'admin.php?page=profile-builder-register'; + else + $register_url = network_admin_url( 'admin.php?page=profile-builder-register' ); + + new wppb_add_notices( 'wppb', 'profile_builder_pro', sprintf( __( '

    Your Profile Builder serial number is invalid or missing.
    Please %1$sregister your copy%2$s to receive access to automatic updates and support. Need a license key? %3$sPurchase one now%4$s

    ', 'profile-builder'), "", "", "", "" ), 'wppb_profile_builder_pro_serial_status' ); +} +elseif ( $wppb_profile_builder_pro_hobbyist_serial_status == 'expired' ){ + new wppb_add_notices( 'wppb_expired', 'profile_builder_pro', sprintf( __( '

    Your Profile Builder license has expired.
    Please %1$sRenew Your Licence%2$s to continue receiving access to product downloads, automatic updates and support. %3$sRenew now and get 40% off %4$s %5$sDismiss%6$s

    ', 'profile-builder'), "", "", "", "", "", "" ), 'wppb_profile_builder_pro_serial_status' ); +} +elseif( strpos( $wppb_profile_builder_pro_hobbyist_serial_status, 'aboutToExpire' ) === 0 ){ + $serial_status_parts = explode( '#', $wppb_profile_builder_pro_hobbyist_serial_status ); + $date = $serial_status_parts[1]; + new wppb_add_notices( 'wppb_about_to_expire', 'profile_builder_pro', sprintf( __( '

    Your Profile Builder license is about to expire on %5$s.
    Please %1$sRenew Your Licence%2$s to continue receiving access to product downloads, automatic updates and support. %3$sRenew now and get 40% off %4$s %6$sDismiss%7$s

    ', 'profile-builder'), "", "", "", "", $date, "", "" ), 'wppb_profile_builder_pro_serial_status' ); } \ No newline at end of file diff --git a/profile-builder/assets/css/rtl.css b/profile-builder/assets/css/rtl.css index dd4d624..50b8daf 100644 --- a/profile-builder/assets/css/rtl.css +++ b/profile-builder/assets/css/rtl.css @@ -1,60 +1,60 @@ -.wppb-user-forms .wppb-wysiwyg .wp-editor-wrap { - float:right; -} -#wppb-search-fields{ - float:right; -} -.wppb-form-field label, -#wppb-login-wrap .login-username label, -#wppb-login-wrap .login-password label{ - float:right; -} -.wppb-form-field input, -.wppb-form-field input[type="text"], .wppb-form-field input[type="email"], .wppb-form-field input[type="url"], .wppb-form-field input[type="password"], .wppb-form-field input[type="search"], -.wppb-form-field select, -.wppb-form-field textarea, -.wppb-checkboxes, -.wppb-radios, -#wppb-login-wrap .login-username input, -#wppb-login-wrap .login-password input{ - float:right; -} -.wppb-table th{ - text-align: right; -} -ul.wppb-profile li label{ - float:right; -} -ul.wppb-profile li span{ - float:right; -} - -@media screen and ( max-width: 720px ) { - .wppb-table td { - text-align: right; - } - .wppb-table .wppb-posts, - .wppb-table .wppb-moreinfo{ - text-align: left; - } - .wppb-table td:before { - float: right; - } -} - -@media screen and (max-width: 400px) { - .wppb-form-field input, - .wppb-form-field select, - .wppb-form-field textarea, - .wppb-checkboxes, - .wppb-radios, - #wppb-login-wrap .login-username input, - #wppb-login-wrap .login-password input, - ul.wppb-profile li span{ - float:right; - } -} - -#pass-strength-result { - float: right; +.wppb-user-forms .wppb-wysiwyg .wp-editor-wrap { + float:right; +} +#wppb-search-fields{ + float:right; +} +.wppb-form-field label, +#wppb-login-wrap .login-username label, +#wppb-login-wrap .login-password label{ + float:right; +} +.wppb-form-field input, +.wppb-form-field input[type="text"], .wppb-form-field input[type="email"], .wppb-form-field input[type="url"], .wppb-form-field input[type="password"], .wppb-form-field input[type="search"], +.wppb-form-field select, +.wppb-form-field textarea, +.wppb-checkboxes, +.wppb-radios, +#wppb-login-wrap .login-username input, +#wppb-login-wrap .login-password input{ + float:right; +} +.wppb-table th{ + text-align: right; +} +ul.wppb-profile li label{ + float:right; +} +ul.wppb-profile li span{ + float:right; +} + +@media screen and ( max-width: 720px ) { + .wppb-table td { + text-align: right; + } + .wppb-table .wppb-posts, + .wppb-table .wppb-moreinfo{ + text-align: left; + } + .wppb-table td:before { + float: right; + } +} + +@media screen and (max-width: 400px) { + .wppb-form-field input, + .wppb-form-field select, + .wppb-form-field textarea, + .wppb-checkboxes, + .wppb-radios, + #wppb-login-wrap .login-username input, + #wppb-login-wrap .login-password input, + ul.wppb-profile li span{ + float:right; + } +} + +#pass-strength-result { + float: right; } \ No newline at end of file diff --git a/profile-builder/assets/css/select2/select2.min.css b/profile-builder/assets/css/select2/select2.min.css index 76de04d..d2278f9 100644 --- a/profile-builder/assets/css/select2/select2.min.css +++ b/profile-builder/assets/css/select2/select2.min.css @@ -1 +1 @@ -.select2-container{box-sizing:border-box;display:inline-block;margin:0;position:relative;vertical-align:middle}.select2-container .select2-selection--single{box-sizing:border-box;cursor:pointer;display:block;height:28px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--single .select2-selection__rendered{display:block;padding-left:8px;padding-right:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-selection--single .select2-selection__clear{position:relative}.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered{padding-right:8px;padding-left:20px}.select2-container .select2-selection--multiple{box-sizing:border-box;cursor:pointer;display:block;min-height:32px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--multiple .select2-selection__rendered{display:inline-block;overflow:hidden;padding-left:8px;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-search--inline{float:left}.select2-container .select2-search--inline .select2-search__field{box-sizing:border-box;border:none;font-size:100%;margin-top:5px;padding:0}.select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-dropdown{background-color:white;border:1px solid #aaa;border-radius:4px;box-sizing:border-box;display:block;position:absolute;left:-100000px;width:100%;z-index:1051}.select2-results{display:block}.select2-results__options{list-style:none;margin:0;padding:0}.select2-results__option{padding:6px;user-select:none;-webkit-user-select:none}.select2-results__option[aria-selected]{cursor:pointer}.select2-container--open .select2-dropdown{left:0}.select2-container--open .select2-dropdown--above{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--open .select2-dropdown--below{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-search--dropdown{display:block;padding:4px}.select2-search--dropdown .select2-search__field{padding:4px;width:100%;box-sizing:border-box}.select2-search--dropdown .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-search--dropdown.select2-search--hide{display:none}.select2-close-mask{border:0;margin:0;padding:0;display:block;position:fixed;left:0;top:0;min-height:100%;min-width:100%;height:auto;width:auto;opacity:0;z-index:99;background-color:#fff;filter:alpha(opacity=0)}.select2-hidden-accessible{border:0 !important;clip:rect(0 0 0 0) !important;height:1px !important;margin:-1px !important;overflow:hidden !important;padding:0 !important;position:absolute !important;width:1px !important}.select2-container--default .select2-selection--single{background-color:#fff;border:1px solid #aaa;border-radius:4px}.select2-container--default .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--default .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold}.select2-container--default .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--default .select2-selection--single .select2-selection__arrow{height:26px;position:absolute;top:1px;right:1px;width:20px}.select2-container--default .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow{left:1px;right:auto}.select2-container--default.select2-container--disabled .select2-selection--single{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear{display:none}.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--default .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text}.select2-container--default .select2-selection--multiple .select2-selection__rendered{box-sizing:border-box;list-style:none;margin:0;padding:0 5px;width:100%}.select2-container--default .select2-selection--multiple .select2-selection__rendered li{list-style:none}.select2-container--default .select2-selection--multiple .select2-selection__placeholder{color:#999;margin-top:5px;float:left}.select2-container--default .select2-selection--multiple .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-top:5px;margin-right:10px}.select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:#999;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#333}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice,.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder,.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline{float:right}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--default.select2-container--focus .select2-selection--multiple{border:solid black 1px;outline:0}.select2-container--default.select2-container--disabled .select2-selection--multiple{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection__choice__remove{display:none}.select2-container--default.select2-container--open.select2-container--above .select2-selection--single,.select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple{border-top-left-radius:0;border-top-right-radius:0}.select2-container--default.select2-container--open.select2-container--below .select2-selection--single,.select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--default .select2-search--dropdown .select2-search__field{border:1px solid #aaa}.select2-container--default .select2-search--inline .select2-search__field{background:transparent;border:none;outline:0;box-shadow:none;-webkit-appearance:textfield}.select2-container--default .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--default .select2-results__option[role=group]{padding:0}.select2-container--default .select2-results__option[aria-disabled=true]{color:#999}.select2-container--default .select2-results__option[aria-selected=true]{background-color:#ddd}.select2-container--default .select2-results__option .select2-results__option{padding-left:1em}.select2-container--default .select2-results__option .select2-results__option .select2-results__group{padding-left:0}.select2-container--default .select2-results__option .select2-results__option .select2-results__option{margin-left:-1em;padding-left:2em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-2em;padding-left:3em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-3em;padding-left:4em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-4em;padding-left:5em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-5em;padding-left:6em}.select2-container--default .select2-results__option--highlighted[aria-selected]{background-color:#5897fb;color:white}.select2-container--default .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic .select2-selection--single{background-color:#f7f7f7;border:1px solid #aaa;border-radius:4px;outline:0;background-image:-webkit-linear-gradient(top, #fff 50%, #eee 100%);background-image:-o-linear-gradient(top, #fff 50%, #eee 100%);background-image:linear-gradient(to bottom, #fff 50%, #eee 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic .select2-selection--single:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--classic .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-right:10px}.select2-container--classic .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--classic .select2-selection--single .select2-selection__arrow{background-color:#ddd;border:none;border-left:1px solid #aaa;border-top-right-radius:4px;border-bottom-right-radius:4px;height:26px;position:absolute;top:1px;right:1px;width:20px;background-image:-webkit-linear-gradient(top, #eee 50%, #ccc 100%);background-image:-o-linear-gradient(top, #eee 50%, #ccc 100%);background-image:linear-gradient(to bottom, #eee 50%, #ccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0)}.select2-container--classic .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow{border:none;border-right:1px solid #aaa;border-radius:0;border-top-left-radius:4px;border-bottom-left-radius:4px;left:1px;right:auto}.select2-container--classic.select2-container--open .select2-selection--single{border:1px solid #5897fb}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow{background:transparent;border:none}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single{border-top:none;border-top-left-radius:0;border-top-right-radius:0;background-image:-webkit-linear-gradient(top, #fff 0%, #eee 50%);background-image:-o-linear-gradient(top, #fff 0%, #eee 50%);background-image:linear-gradient(to bottom, #fff 0%, #eee 50%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0;background-image:-webkit-linear-gradient(top, #eee 50%, #fff 100%);background-image:-o-linear-gradient(top, #eee 50%, #fff 100%);background-image:linear-gradient(to bottom, #eee 50%, #fff 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0)}.select2-container--classic .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text;outline:0}.select2-container--classic .select2-selection--multiple:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--multiple .select2-selection__rendered{list-style:none;margin:0;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__clear{display:none}.select2-container--classic .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove{color:#888;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover{color:#555}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice{float:right}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--classic.select2-container--open .select2-selection--multiple{border:1px solid #5897fb}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--classic .select2-search--dropdown .select2-search__field{border:1px solid #aaa;outline:0}.select2-container--classic .select2-search--inline .select2-search__field{outline:0;box-shadow:none}.select2-container--classic .select2-dropdown{background-color:#fff;border:1px solid transparent}.select2-container--classic .select2-dropdown--above{border-bottom:none}.select2-container--classic .select2-dropdown--below{border-top:none}.select2-container--classic .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--classic .select2-results__option[role=group]{padding:0}.select2-container--classic .select2-results__option[aria-disabled=true]{color:grey}.select2-container--classic .select2-results__option--highlighted[aria-selected]{background-color:#3875d7;color:#fff}.select2-container--classic .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic.select2-container--open .select2-dropdown{border-color:#5897fb} +.select2-container{box-sizing:border-box;display:inline-block;margin:0;position:relative;vertical-align:middle}.select2-container .select2-selection--single{box-sizing:border-box;cursor:pointer;display:block;height:28px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--single .select2-selection__rendered{display:block;padding-left:8px;padding-right:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-selection--single .select2-selection__clear{position:relative}.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered{padding-right:8px;padding-left:20px}.select2-container .select2-selection--multiple{box-sizing:border-box;cursor:pointer;display:block;min-height:32px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--multiple .select2-selection__rendered{display:inline-block;overflow:hidden;padding-left:8px;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-search--inline{float:left}.select2-container .select2-search--inline .select2-search__field{box-sizing:border-box;border:none;font-size:100%;margin-top:5px;padding:0}.select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-dropdown{background-color:white;border:1px solid #aaa;border-radius:4px;box-sizing:border-box;display:block;position:absolute;left:-100000px;width:100%;z-index:1051}.select2-results{display:block}.select2-results__options{list-style:none;margin:0;padding:0}.select2-results__option{padding:6px;user-select:none;-webkit-user-select:none}.select2-results__option[aria-selected]{cursor:pointer}.select2-container--open .select2-dropdown{left:0}.select2-container--open .select2-dropdown--above{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--open .select2-dropdown--below{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-search--dropdown{display:block;padding:4px}.select2-search--dropdown .select2-search__field{padding:4px;width:100%;box-sizing:border-box}.select2-search--dropdown .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-search--dropdown.select2-search--hide{display:none}.select2-close-mask{border:0;margin:0;padding:0;display:block;position:fixed;left:0;top:0;min-height:100%;min-width:100%;height:auto;width:auto;opacity:0;z-index:99;background-color:#fff;filter:alpha(opacity=0)}.select2-hidden-accessible{border:0 !important;clip:rect(0 0 0 0) !important;height:1px !important;margin:-1px !important;overflow:hidden !important;padding:0 !important;position:absolute !important;width:1px !important}.select2-container--default .select2-selection--single{background-color:#fff;border:1px solid #aaa;border-radius:4px}.select2-container--default .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--default .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold}.select2-container--default .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--default .select2-selection--single .select2-selection__arrow{height:26px;position:absolute;top:1px;right:1px;width:20px}.select2-container--default .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow{left:1px;right:auto}.select2-container--default.select2-container--disabled .select2-selection--single{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear{display:none}.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--default .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text}.select2-container--default .select2-selection--multiple .select2-selection__rendered{box-sizing:border-box;list-style:none;margin:0;padding:0 5px;width:100%}.select2-container--default .select2-selection--multiple .select2-selection__rendered li{list-style:none}.select2-container--default .select2-selection--multiple .select2-selection__placeholder{color:#999;margin-top:5px;float:left}.select2-container--default .select2-selection--multiple .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-top:5px;margin-right:10px}.select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:#999;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#333}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice,.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder,.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline{float:right}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--default.select2-container--focus .select2-selection--multiple{border:solid black 1px;outline:0}.select2-container--default.select2-container--disabled .select2-selection--multiple{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection__choice__remove{display:none}.select2-container--default.select2-container--open.select2-container--above .select2-selection--single,.select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple{border-top-left-radius:0;border-top-right-radius:0}.select2-container--default.select2-container--open.select2-container--below .select2-selection--single,.select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--default .select2-search--dropdown .select2-search__field{border:1px solid #aaa}.select2-container--default .select2-search--inline .select2-search__field{background:transparent;border:none;outline:0;box-shadow:none;-webkit-appearance:textfield}.select2-container--default .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--default .select2-results__option[role=group]{padding:0}.select2-container--default .select2-results__option[aria-disabled=true]{color:#999}.select2-container--default .select2-results__option[aria-selected=true]{background-color:#ddd}.select2-container--default .select2-results__option .select2-results__option{padding-left:1em}.select2-container--default .select2-results__option .select2-results__option .select2-results__group{padding-left:0}.select2-container--default .select2-results__option .select2-results__option .select2-results__option{margin-left:-1em;padding-left:2em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-2em;padding-left:3em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-3em;padding-left:4em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-4em;padding-left:5em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-5em;padding-left:6em}.select2-container--default .select2-results__option--highlighted[aria-selected]{background-color:#5897fb;color:white}.select2-container--default .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic .select2-selection--single{background-color:#f7f7f7;border:1px solid #aaa;border-radius:4px;outline:0;background-image:-webkit-linear-gradient(top, #fff 50%, #eee 100%);background-image:-o-linear-gradient(top, #fff 50%, #eee 100%);background-image:linear-gradient(to bottom, #fff 50%, #eee 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic .select2-selection--single:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--classic .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-right:10px}.select2-container--classic .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--classic .select2-selection--single .select2-selection__arrow{background-color:#ddd;border:none;border-left:1px solid #aaa;border-top-right-radius:4px;border-bottom-right-radius:4px;height:26px;position:absolute;top:1px;right:1px;width:20px;background-image:-webkit-linear-gradient(top, #eee 50%, #ccc 100%);background-image:-o-linear-gradient(top, #eee 50%, #ccc 100%);background-image:linear-gradient(to bottom, #eee 50%, #ccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0)}.select2-container--classic .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow{border:none;border-right:1px solid #aaa;border-radius:0;border-top-left-radius:4px;border-bottom-left-radius:4px;left:1px;right:auto}.select2-container--classic.select2-container--open .select2-selection--single{border:1px solid #5897fb}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow{background:transparent;border:none}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single{border-top:none;border-top-left-radius:0;border-top-right-radius:0;background-image:-webkit-linear-gradient(top, #fff 0%, #eee 50%);background-image:-o-linear-gradient(top, #fff 0%, #eee 50%);background-image:linear-gradient(to bottom, #fff 0%, #eee 50%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0;background-image:-webkit-linear-gradient(top, #eee 50%, #fff 100%);background-image:-o-linear-gradient(top, #eee 50%, #fff 100%);background-image:linear-gradient(to bottom, #eee 50%, #fff 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0)}.select2-container--classic .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text;outline:0}.select2-container--classic .select2-selection--multiple:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--multiple .select2-selection__rendered{list-style:none;margin:0;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__clear{display:none}.select2-container--classic .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove{color:#888;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover{color:#555}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice{float:right}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--classic.select2-container--open .select2-selection--multiple{border:1px solid #5897fb}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--classic .select2-search--dropdown .select2-search__field{border:1px solid #aaa;outline:0}.select2-container--classic .select2-search--inline .select2-search__field{outline:0;box-shadow:none}.select2-container--classic .select2-dropdown{background-color:#fff;border:1px solid transparent}.select2-container--classic .select2-dropdown--above{border-bottom:none}.select2-container--classic .select2-dropdown--below{border-top:none}.select2-container--classic .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--classic .select2-results__option[role=group]{padding:0}.select2-container--classic .select2-results__option[aria-disabled=true]{color:grey}.select2-container--classic .select2-results__option--highlighted[aria-selected]{background-color:#3875d7;color:#fff}.select2-container--classic .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic.select2-container--open .select2-dropdown{border-color:#5897fb} diff --git a/profile-builder/assets/css/serial-notice.css b/profile-builder/assets/css/serial-notice.css index 59c7ab8..f5b965e 100644 --- a/profile-builder/assets/css/serial-notice.css +++ b/profile-builder/assets/css/serial-notice.css @@ -1,44 +1,44 @@ -.wppb-serial-wrap{ - margin:40px 0; -} - -.wppb-dismiss-notification{ - position:absolute; - right:0px; - top:50%; - margin-top:-7px; -} -.pms-cross-promo .wppb-dismiss-notification{ - right: 10px; - margin-top:-10px; -} - -div.wppb-serial-notification p{ - padding-right: 50px; - position:relative; -} -.pms-cross-promo{ - position: relative; - background-color: #fff; - border-left: 4px solid #d54e21; - box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.1); - display: block; - font-size: 14px; - line-height: 19px; - margin: 35px 20px 0 2px; - padding: 11px 15px; - text-align: left; - - color: #fff; - background: #5693d3; -} -.pms-cross-promo a{ - padding: 0 3px; - color:#fff; - border-radius: 2px; -} -.pms-cross-promo a:hover{ - background: #fff; - color: #5693d3; - text-decoration: none; -} +.wppb-serial-wrap{ + margin:40px 0; +} + +.wppb-dismiss-notification{ + position:absolute; + right:0px; + top:50%; + margin-top:-7px; +} +.pms-cross-promo .wppb-dismiss-notification{ + right: 10px; + margin-top:-10px; +} + +div.wppb-serial-notification p{ + padding-right: 50px; + position:relative; +} +.pms-cross-promo{ + position: relative; + background-color: #fff; + border-left: 4px solid #d54e21; + box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.1); + display: block; + font-size: 14px; + line-height: 19px; + margin: 35px 20px 0 2px; + padding: 11px 15px; + text-align: left; + + color: #fff; + background: #5693d3; +} +.pms-cross-promo a{ + padding: 0 3px; + color:#fff; + border-radius: 2px; +} +.pms-cross-promo a:hover{ + background: #fff; + color: #5693d3; + text-decoration: none; +} diff --git a/profile-builder/assets/css/style-back-end.css b/profile-builder/assets/css/style-back-end.css index 8021430..8fa0ece 100644 --- a/profile-builder/assets/css/style-back-end.css +++ b/profile-builder/assets/css/style-back-end.css @@ -1,647 +1,647 @@ -.wppb-wrap{ - clear: both; - margin: 10px 0px 0 2px; -} -.wppb-wrap, -.wppb-wrap p{ - font-size: 15px; - max-width: 1050px; -} -.wppb-info-wrap{ - max-width:1050px; - margin:25px 40px 0 20px; -} - -.wppb-wrap h1 { - color: #333333; - font-size: 2.8em; - font-weight: 400; - line-height: 1.2em; - margin:0; - padding-top:35px; -} - -.wppb-wrap .wppb-callout{ - font-size: 2em; - font-weight: 300; - line-height: 1.3; - margin:1.1em 0 0.2em 0; -} - -.wppb-wrap hr{ - display:block; - clear:both; - margin:20px 0; -} - -.wppb-text{ - font-size:1.1em; - margin-top:0; -} - -.wppb-wrap ul{ - list-style-type:circle; - list-style-position:inside; -} - -.wppb-wrap li.description{ - font-style: italic; -} - -.wppb-badge{ - float: right; - color: #fff; - display: inline-block; - font-size: 14px; - font-weight: 600; - width: 150px; - height: 150px; - margin-bottom: 25px; - text-align: center; - text-rendering: optimizelegibility; -} - -.wppb-badge.Pro{ - background:url(../images/pb-logo-pro.png) center no-repeat; -} - -.wppb-badge.Hobbyist{ - background:url(../images/pb-logo-hobbyist.png) center no-repeat; -} - -.wppb-badge.Free{ - background:url(../images/pb-logo-free.png) center no-repeat; -} - -.wppb-badge.wppb-pb-pms{ - background:url(../images/pb-pms-cross-promotion-icon.png) center center no-repeat; -} - -.wppb-badge { - background-size: cover !important; -} - -.wppb-badge span { - display: inline-block; - text-transform: uppercase; - color: #fff; - margin-top: 110px; - font-size: 90%; -} - -/* Userlist page */ -.wppb-ul-templates > textarea, -.wppb-single-ul-templates > textarea { - float: left; - width: 60%; - max-width: 100%; - height: 400px; -} - -.update_container_wppb_ul_faceted_settings .row-facet-behaviour, -.update_container_wppb_ul_faceted_settings .row-facet-limit, -#container_wppb_ul_faceted_settings .row-facet-behaviour, -#container_wppb_ul_faceted_settings .row-facet-behaviour, -#container_wppb_ul_faceted_settings .row-facet-limit{ - display:none; -} - -#container_wppb_ul_faceted_settings .facet_type_checkboxes .row-facet-behaviour, -#container_wppb_ul_faceted_settings .facet_type_checkboxes .row-facet-limit, -#container_wppb_ul_faceted_settings .update_container_wppb_ul_faceted_settings.facet_checkboxes .row-facet-behaviour, -#container_wppb_ul_faceted_settings .update_container_wppb_ul_faceted_settings.facet_checkboxes .row-facet-limit{ - display:block; -} - - -/* Extra Stuff */ -.nowrap { - white-space: nowrap; -} - -.wppb-fields-image{ - margin-top:60px; -} - - -/* Shortcode */ -.wppb-shortcode { - display: inline-block; - font-size: 13px; - font-weight: bold; - background: #fff !important; - padding: 5px 10px; - margin-top: 5px; - border: 1px solid #e1e1e1; - box-shadow: none !important; - font-family: 'Arial'; -} - -.wppb-shortcode.textarea { - width: 100%; - height: 1px; - resize: none; -} - -.wppb-shortcode:focus { - border-color: #e1e1e1 !important; -} - -.wppb-shortcode-temp { - display: inline-block; - font-size: 13px; - font-weight: bold; - padding: 11px; - font-family: 'Arial'; -} - - -/* Manage Fields page */ -.profile-builder_page_manage-fields .metabox-holder .column-1{ - /* margin-right:0; */ -} - -#container_wppb_manage_fields li strong{ - display:none !important; -} - -#container_wppb_manage_fields li .description strong { - display: inline !important; -} - -#container_wppb_manage_fields .added_fields_list li.row-meta-name{ - display:list-item !important; -} - -#container_wppb_manage_fields li.row-field-title pre, -#container_wppb_manage_fields li.row-meta-name pre{ - min-height:10px; -} - -#wppb_manage_fields .ui-sortable label, -#container_wppb_manage_fields .ui-sortable label { - background: #fff; -} - -#wppb_manage_fields .sortable-handle, -#container_wppb_manage_fields .sortable-handle { - display: inline-block; - width: 16px; - height: 16px; - background: url('../images/sorting-icon-dots.png') no-repeat center center;; - vertical-align: middle; - margin-right: 7px; - cursor: move; - margin-top: -1px; -} - -#container_wppb_manage_fields pre{ - display:block; - float:left; - width:27%; - font-family:"Open Sans", Arial, sans-serif; - font-size:14px; -} - -#container_wppb_manage_fields pre.wppb-mb-head-required, -#container_wppb_manage_fields li.row-required pre{ - width:auto; - text-align: center; -} - -#container_wppb_manage_fields thead tr{ - background:#f1f1f1; -} - -#container_wppb_manage_fields thead tr:hover { - background: #f1f1f1; -} - -#container_wppb_manage_fields tr.update_container_wppb_manage_fields:hover{ - background:#fff; -} - -#container_wppb_manage_fields tr:hover{ - background:#def6ff; -} - -#wppb_manage_fields_info{ - display: none; -} - -/* Extra Registration and Edit Profile fields */ -#container_wppb_epf_fields li strong, -#container_wppb_rf_fields li strong{ - display:none !important; -} - -#container_wppb_epf_fields pre, -#container_wppb_rf_fields pre{ - display:block; - font-family:"Open Sans", Arial, sans-serif; - font-size:14px; - margin-top: 5px; -} - -#container_wppb_epf_fields thead tr, -#container_wppb_rf_fields thead tr { - background: #f1f1f1; -} -#container_wppb_epf_fields thead tr:hover, -#container_wppb_rf_fields thead tr:hover { - background: #f1f1f1; -} -#container_wppb_epf_fields thead .wppb-delete-all-fields, -#container_wppb_rf_fields thead .wppb-delete-all-fields { - color: #333; - text-decoration: underline; -} - -#container_wppb_epf_fields tbody .wck-delete, -#container_wppb_rf_fields tbody .wck-delete { - padding: 8px 16px; -} - -#container_wppb_epf_fields tr.update_container_wppb_epf_fields:hover, -#container_wppb_rf_fields tr.update_container_wppb_rf_fields:hover{ - background:none; -} - -#container_wppb_epf_fields tr:hover, -#container_wppb_rf_fields tr:hover{ - background:#def6ff; -} -#container_wppb_epf_fields .wck-content{ - content: "" !important; -} - -#wppb_rf_page_settings .row-url, #wppb_rf_page_settings .row-display-messages, .update_container_wppb_rf_page_settings.redirect_ .row-url, -.update_container_wppb_rf_page_settings.redirect_ .row-display-messages, .update_container_wppb_rf_page_settings.redirect_no .row-url, -.update_container_wppb_rf_page_settings.redirect_no .row-display-messages{ - display:none; -} - -#wppb_rf_page_settings.update_container_wppb_rf_page_settings.redirect_yes .row-url, #wppb_rf_page_settings.update_container_wppb_rf_page_settings.redirect_yes .row-display-messages{ - display: block; -} - -#wppb_epf_page_settings .row-url, #wppb_epf_page_settings .row-display-messages, .update_container_wppb_epf_page_settings.redirect_ .row-url, -.update_container_wppb_epf_page_settings.redirect_ .row-display-messages, .update_container_wppb_epf_page_settings.redirect_no .row-url, -.update_container_wppb_epf_page_settings.redirect_no .row-display-messages{ - display:none; -} - -#wppb_epf_page_settings.update_container_wppb_epf_page_settings.redirect_yes .row-url, #wppb_epf_page_settings.update_container_wppb_epf_page_settings.redirect_yes .row-display-messages{ - display: block; -} - -/* Columns :) */ -.wppb-row{ - overflow:hidden; -} - -.wppb-3-col > div { - float:left; - width:28%; - margin-right:5%; -} - -.wppb-2-col > div { - float:left; - width:45%; - margin-right:5%; -} - -.wppb-3-col > div:last-child, -.wppb-2-col > div:last-child{ - margin:0; -} - -.wppb-1-3-col > div { - float:left; - width:28%; - margin-right:5%; -} -.wppb-1-3-col > div:last-child{ - float:right; - width: 67%; - margin:0; -} -/* Extra Form Styles */ -.wppb-text{ - min-width: 16.4em; -} -.wppb-select { - min-width:18em; -} - -.wppb-wrap .form-table th { - width: 400px; -} - -.wppb-metabox label{ - display:inline-block; - min-width:15em; -} - -/* Admin Bar Page */ -.wppb-admin-bar label{ - margin-right:30px; - padding:5px; -} - -/* modules Page */ -.wppb-modules label{ - margin-right:30px; - padding:5px; -} - -/* Metabox Clone. We need this in various places to simulate the css of a normal metabox. */ -.wppb-side{ - width:300px; - float:right; - clear:both; -} - -.wppb-metabox h3{ - font-size: 14px; - line-height: 1.4; - margin: 0; - padding:8px 12px; - cursor:default !important; -} - -.wppb-normal{ - margin-right:320px; -} - -.wppb-metabox textarea{ - resize:vertical; - background-color: #ecf8fd; - font-family: Consolas,Monaco,monospace; - font-size: 13px; -} - -.wppb-metabox .inline-wrap{ - width:280px; - float:left; -} -.wppb-highlight{ - background:#333333; - background:#222222; - background:#fff; - padding:20px; -} -.wppb-userlisting-slider, .wppb-list-users-slider{ - display:block; - padding:10px; - border:1px solid #ccc; - font-family: Consolas,Monaco,monospace; - font-size: 13px; - margin-top:20px; -} -#wppb_manage_fields .mb-list-entry-fields .field-label{ - max-width: 179px; -} - -#container_wppb_epf_fields .row-id, -#wppb_epf_fields .row-id, -#container_wppb_rf_fields .row-id, -#wppb_rf_fields .row-id{ - display:none; -} - -.wppb-wrap #serial_number{ - font-weight: 600; - line-height: 1.3; - padding: 20px 10px 20px 0; - text-align: left; - color: #222222; - font-size:14px; -} - -#wppb_profile_builder_pro_serial{ - width:460px; - padding: 5px; -} - -.wppb-wrap .wppb-serialnumber-descr{ - display: block; - padding: 0px 0px 0px 95px -} - -.wppb-backend-notice{ - display: inline-block; - line-height: 16px; - padding: 11px; - font-size: 14px; - text-align: left; - margin: 0 0 5px 0; - background-color: #fff9e8; - border:1px solid #ffba00; - border-radius:3px; -} - -/* hide "View post" link from update messages on internal post types */ -.post-type-wppb-ul-cpt #message.updated a, .post-type-wppb-rf-cpt #message.updated a, .post-type-wppb-epf-cpt #message.updated a{ - display:none; -} - - -#wppb_ul_page_settings .row-visible-to-following-roles, .update_container_wppb_ul_page_settings.visible_to_logged_ .row-visible-to-following-roles{ - display:none; -} - -#wppb_ul_page_settings.update_container_wppb_ul_page_settings.visible_to_logged_yes .row-visible-to-following-roles{ - display: block; -} - -/* Add-Ons page */ -.wppb-add-on-user-messages{ display: none; } - -.wppb-add-on-wrap .plugin-card-bottom:after { - display: block; - content: ''; - clear: both; -} - -.wppb-add-on .spinner { - visibility: visible; -} - -.wppb-add-on a:focus { - box-shadow: none; -} - -.wppb-add-on img { - max-width: 100%; - height: auto; -} - -.wppb-add-on .wppb-add-on-title { - letter-spacing: -0.7px; - margin-bottom: 7px; - margin-top: 7px; -} - -.wppb-add-on .wppb-add-on-title a { - text-decoration: none; - color: inherit; -} - -.wppb-add-on .wppb-add-on-price { - font-size: 1.1em; - letter-spacing: -0.7px; - margin-top: 7px; -} - -.wppb-add-on-compatible span { - line-height: 28px; -} - -.wppb-add-on-not-compatible { - position: relative; -} - -.wppb-add-on-not-compatible:before { - display: block; - content: ''; - position: absolute; - width: 4px; - height: 100%; - background: #d54e21; - top: 0; - left: 0; -} - -.wppb-add-on .button { - position: relative; -} - -.wppb-add-on .button.wppb-add-on-deactivate { - opacity: 0; -} - -.wppb-add-on .spinner { - display: block; - margin-top: 4px; - opacity: 0; -} - -.wppb-add-on-spinner { - opacity: 0; - position: absolute; - top: 50%; - left: 50%; - margin-top: -10px; - margin-left: -10px; - display: block; - width: 20px; - height: 20px; - background: url('../images/spinner.gif') no-repeat center; -} - -.wppb-recommended-plugin{ - width:100%; - margin:0 8px 16px 0; -} - -@media screen and (min-width: 1600px){ - .wppb-recommended-plugin{ - width:66%; - } -} - -.wppb-confirmation-success { - color: #27ae60; -} - -.wppb-confirmation-error { - color: #c0392b; -} - -/* Manage Fields Responsive CSS */ -@media screen and ( max-width: 1125px ) { - /* Manage Fields Responsive */ - #container_wppb_manage_fields th.wck-content pre{ - display:none; - } - #container_wppb_manage_fields li strong{ - display: inline-block !important; - font-size: 14px; - font-family: "Open Sans",Arial,sans-serif; - } - #container_wppb_manage_fields pre{ - display: inline; - float:none; - width:auto; - } - #container_wppb_manage_fields li strong{ - width:100px !important; - } -} -/* Basic Information Buttons - for Free to Pro upgrade*/ -.wppb-button-free { - border-radius: 3px; - border-style: solid; - border-width: 1px; - box-sizing: border-box; - cursor: pointer; - display: inline-block; - font-size: 13px; - height: 29px; - line-height: 26px; - margin: 0; - padding: 0 10px 1px; - text-decoration: none; - white-space: nowrap; - background: none repeat scroll 0 0 #e14d43; - border-color: #b2401b; - -webkit-box-shadow: 0 1px 0 #ba281e !important; - box-shadow: 0 1px 0 #ba281e !important; - color: #fff !important; - vertical-align:top; - text-shadow: 0 -1px 1px #ba281e,1px 0 1px #ba281e,0 1px 1px #ba281e,-1px 0 1px #ba281e !important; -} -p .wppb-button-free { - vertical-align: baseline; -} -.wppb-button-free:hover { - background: #e14d43; - border-color: #ba281e; - color: #fff; -} - -/* PMS Compatibility page */ -#pms-bottom-install .plugin-card-bottom{ - border:none; - background: #e86054; - color:#fff; -} - -#pms-bottom-install .plugin-card-bottom span{ - display: inline-block; - margin-top:7px; -} - -#pms-bottom-install .wppb-add-on-download, #pms-bottom-install a{ - font-size: 130%; - padding: 10px 20px; - height: auto; - color: #e86054; - text-decoration: none; -} - -#pms-bottom-install a:hover{ - background: #fff; - text-decoration: none; -} - -#pms-bottom-install .wppb-confirmation-success{ - color:#FFFFFF; -} - -#wppb_ul_search_settings .wck-checkboxes > div{ - display: inline-block; - margin-left:7px; +.wppb-wrap{ + clear: both; + margin: 10px 0px 0 2px; +} +.wppb-wrap, +.wppb-wrap p{ + font-size: 15px; + max-width: 1050px; +} +.wppb-info-wrap{ + max-width:1050px; + margin:25px 40px 0 20px; +} + +.wppb-wrap h1 { + color: #333333; + font-size: 2.8em; + font-weight: 400; + line-height: 1.2em; + margin:0; + padding-top:35px; +} + +.wppb-wrap .wppb-callout{ + font-size: 2em; + font-weight: 300; + line-height: 1.3; + margin:1.1em 0 0.2em 0; +} + +.wppb-wrap hr{ + display:block; + clear:both; + margin:20px 0; +} + +.wppb-text{ + font-size:1.1em; + margin-top:0; +} + +.wppb-wrap ul{ + list-style-type:circle; + list-style-position:inside; +} + +.wppb-wrap li.description{ + font-style: italic; +} + +.wppb-badge{ + float: right; + color: #fff; + display: inline-block; + font-size: 14px; + font-weight: 600; + width: 150px; + height: 150px; + margin-bottom: 25px; + text-align: center; + text-rendering: optimizelegibility; +} + +.wppb-badge.Pro{ + background:url(../images/pb-logo-pro.png) center no-repeat; +} + +.wppb-badge.Hobbyist{ + background:url(../images/pb-logo-hobbyist.png) center no-repeat; +} + +.wppb-badge.Free{ + background:url(../images/pb-logo-free.png) center no-repeat; +} + +.wppb-badge.wppb-pb-pms{ + background:url(../images/pb-pms-cross-promotion-icon.png) center center no-repeat; +} + +.wppb-badge { + background-size: cover !important; +} + +.wppb-badge span { + display: inline-block; + text-transform: uppercase; + color: #fff; + margin-top: 110px; + font-size: 90%; +} + +/* Userlist page */ +.wppb-ul-templates > textarea, +.wppb-single-ul-templates > textarea { + float: left; + width: 60%; + max-width: 100%; + height: 400px; +} + +.update_container_wppb_ul_faceted_settings .row-facet-behaviour, +.update_container_wppb_ul_faceted_settings .row-facet-limit, +#container_wppb_ul_faceted_settings .row-facet-behaviour, +#container_wppb_ul_faceted_settings .row-facet-behaviour, +#container_wppb_ul_faceted_settings .row-facet-limit{ + display:none; +} + +#container_wppb_ul_faceted_settings .facet_type_checkboxes .row-facet-behaviour, +#container_wppb_ul_faceted_settings .facet_type_checkboxes .row-facet-limit, +#container_wppb_ul_faceted_settings .update_container_wppb_ul_faceted_settings.facet_checkboxes .row-facet-behaviour, +#container_wppb_ul_faceted_settings .update_container_wppb_ul_faceted_settings.facet_checkboxes .row-facet-limit{ + display:block; +} + + +/* Extra Stuff */ +.nowrap { + white-space: nowrap; +} + +.wppb-fields-image{ + margin-top:60px; +} + + +/* Shortcode */ +.wppb-shortcode { + display: inline-block; + font-size: 13px; + font-weight: bold; + background: #fff !important; + padding: 5px 10px; + margin-top: 5px; + border: 1px solid #e1e1e1; + box-shadow: none !important; + font-family: 'Arial'; +} + +.wppb-shortcode.textarea { + width: 100%; + height: 1px; + resize: none; +} + +.wppb-shortcode:focus { + border-color: #e1e1e1 !important; +} + +.wppb-shortcode-temp { + display: inline-block; + font-size: 13px; + font-weight: bold; + padding: 11px; + font-family: 'Arial'; +} + + +/* Manage Fields page */ +.profile-builder_page_manage-fields .metabox-holder .column-1{ + /* margin-right:0; */ +} + +#container_wppb_manage_fields li strong{ + display:none !important; +} + +#container_wppb_manage_fields li .description strong { + display: inline !important; +} + +#container_wppb_manage_fields .added_fields_list li.row-meta-name{ + display:list-item !important; +} + +#container_wppb_manage_fields li.row-field-title pre, +#container_wppb_manage_fields li.row-meta-name pre{ + min-height:10px; +} + +#wppb_manage_fields .ui-sortable label, +#container_wppb_manage_fields .ui-sortable label { + background: #fff; +} + +#wppb_manage_fields .sortable-handle, +#container_wppb_manage_fields .sortable-handle { + display: inline-block; + width: 16px; + height: 16px; + background: url('../images/sorting-icon-dots.png') no-repeat center center;; + vertical-align: middle; + margin-right: 7px; + cursor: move; + margin-top: -1px; +} + +#container_wppb_manage_fields pre{ + display:block; + float:left; + width:27%; + font-family:"Open Sans", Arial, sans-serif; + font-size:14px; +} + +#container_wppb_manage_fields pre.wppb-mb-head-required, +#container_wppb_manage_fields li.row-required pre{ + width:auto; + text-align: center; +} + +#container_wppb_manage_fields thead tr{ + background:#f1f1f1; +} + +#container_wppb_manage_fields thead tr:hover { + background: #f1f1f1; +} + +#container_wppb_manage_fields tr.update_container_wppb_manage_fields:hover{ + background:#fff; +} + +#container_wppb_manage_fields tr:hover{ + background:#def6ff; +} + +#wppb_manage_fields_info{ + display: none; +} + +/* Extra Registration and Edit Profile fields */ +#container_wppb_epf_fields li strong, +#container_wppb_rf_fields li strong{ + display:none !important; +} + +#container_wppb_epf_fields pre, +#container_wppb_rf_fields pre{ + display:block; + font-family:"Open Sans", Arial, sans-serif; + font-size:14px; + margin-top: 5px; +} + +#container_wppb_epf_fields thead tr, +#container_wppb_rf_fields thead tr { + background: #f1f1f1; +} +#container_wppb_epf_fields thead tr:hover, +#container_wppb_rf_fields thead tr:hover { + background: #f1f1f1; +} +#container_wppb_epf_fields thead .wppb-delete-all-fields, +#container_wppb_rf_fields thead .wppb-delete-all-fields { + color: #333; + text-decoration: underline; +} + +#container_wppb_epf_fields tbody .wck-delete, +#container_wppb_rf_fields tbody .wck-delete { + padding: 8px 16px; +} + +#container_wppb_epf_fields tr.update_container_wppb_epf_fields:hover, +#container_wppb_rf_fields tr.update_container_wppb_rf_fields:hover{ + background:none; +} + +#container_wppb_epf_fields tr:hover, +#container_wppb_rf_fields tr:hover{ + background:#def6ff; +} +#container_wppb_epf_fields .wck-content{ + content: "" !important; +} + +#wppb_rf_page_settings .row-url, #wppb_rf_page_settings .row-display-messages, .update_container_wppb_rf_page_settings.redirect_ .row-url, +.update_container_wppb_rf_page_settings.redirect_ .row-display-messages, .update_container_wppb_rf_page_settings.redirect_no .row-url, +.update_container_wppb_rf_page_settings.redirect_no .row-display-messages{ + display:none; +} + +#wppb_rf_page_settings.update_container_wppb_rf_page_settings.redirect_yes .row-url, #wppb_rf_page_settings.update_container_wppb_rf_page_settings.redirect_yes .row-display-messages{ + display: block; +} + +#wppb_epf_page_settings .row-url, #wppb_epf_page_settings .row-display-messages, .update_container_wppb_epf_page_settings.redirect_ .row-url, +.update_container_wppb_epf_page_settings.redirect_ .row-display-messages, .update_container_wppb_epf_page_settings.redirect_no .row-url, +.update_container_wppb_epf_page_settings.redirect_no .row-display-messages{ + display:none; +} + +#wppb_epf_page_settings.update_container_wppb_epf_page_settings.redirect_yes .row-url, #wppb_epf_page_settings.update_container_wppb_epf_page_settings.redirect_yes .row-display-messages{ + display: block; +} + +/* Columns :) */ +.wppb-row{ + overflow:hidden; +} + +.wppb-3-col > div { + float:left; + width:28%; + margin-right:5%; +} + +.wppb-2-col > div { + float:left; + width:45%; + margin-right:5%; +} + +.wppb-3-col > div:last-child, +.wppb-2-col > div:last-child{ + margin:0; +} + +.wppb-1-3-col > div { + float:left; + width:28%; + margin-right:5%; +} +.wppb-1-3-col > div:last-child{ + float:right; + width: 67%; + margin:0; +} +/* Extra Form Styles */ +.wppb-text{ + min-width: 16.4em; +} +.wppb-select { + min-width:18em; +} + +.wppb-wrap .form-table th { + width: 400px; +} + +.wppb-metabox label{ + display:inline-block; + min-width:15em; +} + +/* Admin Bar Page */ +.wppb-admin-bar label{ + margin-right:30px; + padding:5px; +} + +/* modules Page */ +.wppb-modules label{ + margin-right:30px; + padding:5px; +} + +/* Metabox Clone. We need this in various places to simulate the css of a normal metabox. */ +.wppb-side{ + width:300px; + float:right; + clear:both; +} + +.wppb-metabox h3{ + font-size: 14px; + line-height: 1.4; + margin: 0; + padding:8px 12px; + cursor:default !important; +} + +.wppb-normal{ + margin-right:320px; +} + +.wppb-metabox textarea{ + resize:vertical; + background-color: #ecf8fd; + font-family: Consolas,Monaco,monospace; + font-size: 13px; +} + +.wppb-metabox .inline-wrap{ + width:280px; + float:left; +} +.wppb-highlight{ + background:#333333; + background:#222222; + background:#fff; + padding:20px; +} +.wppb-userlisting-slider, .wppb-list-users-slider{ + display:block; + padding:10px; + border:1px solid #ccc; + font-family: Consolas,Monaco,monospace; + font-size: 13px; + margin-top:20px; +} +#wppb_manage_fields .mb-list-entry-fields .field-label{ + max-width: 179px; +} + +#container_wppb_epf_fields .row-id, +#wppb_epf_fields .row-id, +#container_wppb_rf_fields .row-id, +#wppb_rf_fields .row-id{ + display:none; +} + +.wppb-wrap #serial_number{ + font-weight: 600; + line-height: 1.3; + padding: 20px 10px 20px 0; + text-align: left; + color: #222222; + font-size:14px; +} + +#wppb_profile_builder_pro_serial{ + width:460px; + padding: 5px; +} + +.wppb-wrap .wppb-serialnumber-descr{ + display: block; + padding: 0px 0px 0px 95px +} + +.wppb-backend-notice{ + display: inline-block; + line-height: 16px; + padding: 11px; + font-size: 14px; + text-align: left; + margin: 0 0 5px 0; + background-color: #fff9e8; + border:1px solid #ffba00; + border-radius:3px; +} + +/* hide "View post" link from update messages on internal post types */ +.post-type-wppb-ul-cpt #message.updated a, .post-type-wppb-rf-cpt #message.updated a, .post-type-wppb-epf-cpt #message.updated a{ + display:none; +} + + +#wppb_ul_page_settings .row-visible-to-following-roles, .update_container_wppb_ul_page_settings.visible_to_logged_ .row-visible-to-following-roles{ + display:none; +} + +#wppb_ul_page_settings.update_container_wppb_ul_page_settings.visible_to_logged_yes .row-visible-to-following-roles{ + display: block; +} + +/* Add-Ons page */ +.wppb-add-on-user-messages{ display: none; } + +.wppb-add-on-wrap .plugin-card-bottom:after { + display: block; + content: ''; + clear: both; +} + +.wppb-add-on .spinner { + visibility: visible; +} + +.wppb-add-on a:focus { + box-shadow: none; +} + +.wppb-add-on img { + max-width: 100%; + height: auto; +} + +.wppb-add-on .wppb-add-on-title { + letter-spacing: -0.7px; + margin-bottom: 7px; + margin-top: 7px; +} + +.wppb-add-on .wppb-add-on-title a { + text-decoration: none; + color: inherit; +} + +.wppb-add-on .wppb-add-on-price { + font-size: 1.1em; + letter-spacing: -0.7px; + margin-top: 7px; +} + +.wppb-add-on-compatible span { + line-height: 28px; +} + +.wppb-add-on-not-compatible { + position: relative; +} + +.wppb-add-on-not-compatible:before { + display: block; + content: ''; + position: absolute; + width: 4px; + height: 100%; + background: #d54e21; + top: 0; + left: 0; +} + +.wppb-add-on .button { + position: relative; +} + +.wppb-add-on .button.wppb-add-on-deactivate { + opacity: 0; +} + +.wppb-add-on .spinner { + display: block; + margin-top: 4px; + opacity: 0; +} + +.wppb-add-on-spinner { + opacity: 0; + position: absolute; + top: 50%; + left: 50%; + margin-top: -10px; + margin-left: -10px; + display: block; + width: 20px; + height: 20px; + background: url('../images/spinner.gif') no-repeat center; +} + +.wppb-recommended-plugin{ + width:100%; + margin:0 8px 16px 0; +} + +@media screen and (min-width: 1600px){ + .wppb-recommended-plugin{ + width:66%; + } +} + +.wppb-confirmation-success { + color: #27ae60; +} + +.wppb-confirmation-error { + color: #c0392b; +} + +/* Manage Fields Responsive CSS */ +@media screen and ( max-width: 1125px ) { + /* Manage Fields Responsive */ + #container_wppb_manage_fields th.wck-content pre{ + display:none; + } + #container_wppb_manage_fields li strong{ + display: inline-block !important; + font-size: 14px; + font-family: "Open Sans",Arial,sans-serif; + } + #container_wppb_manage_fields pre{ + display: inline; + float:none; + width:auto; + } + #container_wppb_manage_fields li strong{ + width:100px !important; + } +} +/* Basic Information Buttons - for Free to Pro upgrade*/ +.wppb-button-free { + border-radius: 3px; + border-style: solid; + border-width: 1px; + box-sizing: border-box; + cursor: pointer; + display: inline-block; + font-size: 13px; + height: 29px; + line-height: 26px; + margin: 0; + padding: 0 10px 1px; + text-decoration: none; + white-space: nowrap; + background: none repeat scroll 0 0 #e14d43; + border-color: #b2401b; + -webkit-box-shadow: 0 1px 0 #ba281e !important; + box-shadow: 0 1px 0 #ba281e !important; + color: #fff !important; + vertical-align:top; + text-shadow: 0 -1px 1px #ba281e,1px 0 1px #ba281e,0 1px 1px #ba281e,-1px 0 1px #ba281e !important; +} +p .wppb-button-free { + vertical-align: baseline; +} +.wppb-button-free:hover { + background: #e14d43; + border-color: #ba281e; + color: #fff; +} + +/* PMS Compatibility page */ +#pms-bottom-install .plugin-card-bottom{ + border:none; + background: #e86054; + color:#fff; +} + +#pms-bottom-install .plugin-card-bottom span{ + display: inline-block; + margin-top:7px; +} + +#pms-bottom-install .wppb-add-on-download, #pms-bottom-install a{ + font-size: 130%; + padding: 10px 20px; + height: auto; + color: #e86054; + text-decoration: none; +} + +#pms-bottom-install a:hover{ + background: #fff; + text-decoration: none; +} + +#pms-bottom-install .wppb-confirmation-success{ + color:#FFFFFF; +} + +#wppb_ul_search_settings .wck-checkboxes > div{ + display: inline-block; + margin-left:7px; } \ No newline at end of file diff --git a/profile-builder/assets/css/style-front-end.css b/profile-builder/assets/css/style-front-end.css index be940a6..b16f9a7 100644 --- a/profile-builder/assets/css/style-front-end.css +++ b/profile-builder/assets/css/style-front-end.css @@ -1,775 +1,775 @@ -/* Register & Edit Profile Forms*/ - -/*-------------------------------------------------------------- ->>> TABLE OF CONTENTS: ----------------------------------------------------------------- -1.0 - Reset -2.0 - Forms -3.0 - Alignments -4.0 - Errors & Notices -5.0 - User Listing -6.0 - Media Queries ---------------------------------------------------------------*/ - -/*-------------------------------------------------------------- -1.0 Reset ---------------------------------------------------------------*/ -.wppb-user-forms, -.wppb-user-forms *{ - -webkit-box-sizing: border-box !important; /* Safari/Chrome, other WebKit */ - -moz-box-sizing: border-box !important; /* Firefox, other Gecko */ - box-sizing: border-box !important; /* Opera/IE 8+ */ -} - -/*-------------------------------------------------------------- -2.0 Forms ---------------------------------------------------------------*/ -.wppb-user-forms input:not([type="button"]):not([type="reset"]):not([type="submit"]), -.wppb-user-forms select, -.wppb-user-forms textarea{ - font-size: 100%; /* Corrects font size not being inherited in all browsers */ - margin: 0; /* Addresses margins set differently in IE6/7, F3/4, S5, Chrome */ - vertical-align: baseline; /* Improves appearance and consistency in all browsers */ -} -.wppb-user-forms input[type="checkbox"], -.wppb-user-forms input[type="radio"] { - padding: 0; /* Addresses excess padding in IE8/9 */ -} -.wppb-user-forms input[type="search"] { - -webkit-appearance: textfield; /* Addresses appearance set to searchfield in S5, Chrome */ - -webkit-box-sizing: content-box; /* Addresses box sizing set to border-box in S5, Chrome (include -moz to future-proof) */ - -moz-box-sizing: content-box; - box-sizing: content-box; -} -.wppb-user-forms input[type="search"]::-webkit-search-decoration { /* Corrects inner padding displayed oddly in S5, Chrome on OSX */ - -webkit-appearance: none; -} -.wppb-user-forms button::-moz-focus-inner, -.wppb-user-forms input::-moz-focus-inner { /* Corrects inner padding and border displayed oddly in FF3/4 www.sitepen.com/blog/2008/05/14/the-devils-in-the-details-fixing-dojos-toolbar-buttons/ */ - border: 0; - padding: 0; -} -.wppb-user-forms input[type="text"], -.wppb-user-forms input[type="number"], -.wppb-user-forms input[type="email"], -.wppb-user-forms input[type="url"], -.wppb-user-forms input[type="password"], -.wppb-user-forms input[type="search"], -.wppb-user-forms textarea{ - color: #666; - border: 1px solid #ccc; - border-radius: 3px; -} -.wppb-user-forms input[type="text"]:focus, -.wppb-user-forms input[type="number"]:focus, -.wppb-user-forms input[type="email"]:focus, -.wppb-user-forms input[type="url"]:focus, -.wppb-user-forms input[type="password"]:focus, -.wppb-user-forms input[type="search"]:focus, -.wppb-user-forms textarea:focus { - color: #111; -} -.wppb-user-forms input[type="text"], -.wppb-user-forms input[type="number"], -.wppb-user-forms input[type="email"], -.wppb-user-forms input[type="url"], -.wppb-user-forms input[type="password"], -.wppb-user-forms input[type="search"] { - padding: 3px; -} -.wppb-user-forms textarea { - overflow: auto; /* Removes default vertical scrollbar in IE6/7/8/9 */ - padding-left: 3px; - vertical-align: top; /* Improves readability and alignment in all browsers */ - width: 100%; -} -.wppb-user-forms .wppb-wysiwyg .wp-editor-wrap { /* properly align wysiwyg editor among form fields */ - float:left; - width:69.9%; -} -.wppb-user-forms .wppb-wysiwyg button:hover{ /* wysiwyg - overwrite the theme inherited background color on hover*/ - background: none; -} -.wppb-user-forms .wppb-wysiwyg div.mce-tinymce.mce-panel{ /*Display the borders for the TinyMCE editor - Visual tab*/ - border: 1px solid #ccc !important; - color: #666 !important; -} -.wppb-user-forms .wppb-wysiwyg div.mce-panel.mce-first{ - border-width: 0 0 1px 0 !important; -} -.wppb-user-forms .wppb-wysiwyg div.mce-panel.mce-last{ - border-width: 1px 0 !important; -} -.wppb-user-forms .wppb-wysiwyg .quicktags-toolbar { /*Display the borders for the TinyMCE editor - Text tab*/ - border: 1px solid #dedede; - border-bottom: 0; -} -#wp-link label input[type="text"] { /*Fix the looks of the Add Link window for TinyMCE editor*/ - padding: 0px; -} - -#wppb-search-fields{ - min-width: 250px; - float:left; - margin-right:20px; -} - -.wppb-user-forms .wppb-search-button{ - margin-right:10px; - padding:7px 20px; - line-height: 24px; -} - -.wppb-search-users-wrap{ - margin-bottom: 20px; -} - -.wppb-user-forms .extra_field_heading { - margin-bottom: 0; -} - -/*-------------------------------------------------------------- -3.0 Alignments ---------------------------------------------------------------*/ -.wppb-user-forms ul{ - max-width:900px; - list-style:none; - margin-left:0; - margin-right:0; - padding-left:0; - padding-right:0; -} - -.wppb-user-forms ul li{ - list-style:none; -} - -#wppb-login-wrap p, -#select_user_to_edit_form p{ - overflow:hidden; - margin:0; - padding-bottom:14px; -} - -.wppb-user-forms ul li{ - margin:0; - padding-bottom:14px; -} - -.wppb-user-forms ul li:after{ - content: ""; - clear: both; - display: block; -} - -.wppb-user-forms .wppb-input-hidden { - padding-bottom: 0; -} - -.wppb-user-forms.wppb-user-role-administrator .wppb-input-hidden { - padding-bottom: 14px; -} - -.wppb-user-forms .wppb-form-field > ul { - margin-left: 0; -} - -.wppb-form-field label, -#wppb-login-wrap .login-username label, -#wppb-login-wrap .login-password label{ - width:30%; - float:left; - min-height:1px; -} -.wppb-form-field input, -.wppb-form-field input[type="text"], .wppb-form-field input[type="number"], .wppb-form-field input[type="email"], .wppb-form-field input[type="url"], .wppb-form-field input[type="password"], .wppb-form-field input[type="search"], -.wppb-form-field select, -.wppb-form-field textarea, -.wppb-checkboxes, -.wppb-radios, -#wppb-login-wrap .login-username input, -#wppb-login-wrap .login-password input{ - width:69.9%; - float:left; -} - -.wppb-form-field.wppb-timepicker select { - width: auto; - margin-right: 5px; -} - -.wppb-user-forms .wppb-wysiwyg .wp-editor-wrap .wp-editor-tabs *{ - box-sizing: content-box !important; -} - -.wppb-user-forms .wp-editor-wrap input { - float: none; - width: auto; -} - -input#send_credentials_via_email{ - float:none; - width:auto; - margin-right:10px -} - -.wppb-send-credentials-checkbox label{ - width:auto; -} - -.wppb-form-field > span{ - display:block; - clear:both; - margin-left:30%; - font-size:80%; - font-style:italic; -} - -.wppb-form-field > span.custom_field_html { - font-style: normal; - font-size: 100%; -} - -.wppb-form-field.wppb-timepicker > span.wppb-timepicker-separator { - display: inline-block; - float: left; - clear: none; - margin-left: 0; - margin-right: 5px; - font-size: 100%; - font-style: normal; -} - -.wppb_upload_button{ - display:inline-block; -} - -.wppb-user-forms .wppb-checkboxes li, -.wppb-user-forms .wppb-radios li{ - display:inline-block; - padding:0 20px 0 0; -} - -.wppb-form-field .wppb-checkboxes label, -.wppb-form-field .wppb-radios label{ - float:none; - min-width:0; - padding-left:5px; - width:auto; - display:inline-block; -} - -.wppb-checkbox-terms-and-conditions input, -.wppb-checkboxes li input, -.wppb-radios li input{ - min-width:0; - float:none; - width:auto; -} - -.wppb-edit-user .wppb-checkbox-terms-and-conditions { - display:none; -} - -.wppb-form-field.wppb-heading span, -.wppb-default-about-yourself-heading span, -.wppb-default-contact-info-heading span, -.wppb-default-name-heading span, -.wppb-checkbox-terms-and-conditions span{ - margin-left:0; -} - -.wppb-checkbox-terms-and-conditions label { - width: 100%; -} - -.wppb-form-field.wppb-checkbox-terms-and-conditions input[type="checkbox"].custom_field_toa { - float:none; - width:auto; - margin-right:10px -} - - -.g-recaptcha{ - display: inline-block; -} -.g-recaptcha iframe{ - margin-bottom: 0; -} - -.wppb-form-field input.wppb-map-search-box { - position: absolute; - top: 10px !important; - height: 34px; - width: 50%; - min-width: 250px; - background: #fff; - border: 0; - border-radius: 1px; - padding: 0 10px; - box-shadow: 0 1px 1px 0 #c1c1c1; - font-family: 'Roboto', sans-serif; -} - -.wppb-create-new-site{ - width: 100%; -} -input#wppb_create_new_site_checkbox{ - width: auto; - margin-right: 10px; - float: none; -} -label[for=wppb_create_new_site_checkbox]{ - width:100%; -} -label[for=blog-privacy]{ - width:100%; -} - - -/*-------------------------------------------------------------- -4.0 Errors & Notices ---------------------------------------------------------------*/ - -#wppb_general_top_error_message, -.wppb-error, -.wppb-warning { - padding: 6px 9px; - margin: 0 auto 25px; - display: block; - width: 100%; - box-sizing: border-box; - background: #ffebe8; - border: 1px solid #C00; -} - -#wppb_general_top_error_message, -.wppb-error, -.wppb-warning{ - color:#222222; -} - -#wppb_general_top_error_message a, -.wppb-error a, -.wppb-warning a{ - color:#007acc; -} - -.wppb-required{ - color: red; -} - -.wppb-required, -.wppb-checkbox-terms-and-conditions span.wppb-required{ - margin-left:5px; -} - -#wppb_form_success_message, -.wppb-success { - padding: 6px 9px; - margin: 0 auto 25px; - display: block; - width: 100%; - box-sizing: border-box; - background: #e7f7d3; - border: 1px solid #6c3; -} - -.wppb-register-user .wppb-field-error, -.wppb-edit-user .wppb-field-error, -#wppb-recover-password .wppb-field-error{ - background-color: #FFDFDF; - border: 1px dotted #C89797; - margin-bottom: 6px !important; - padding: 6px !important; -} - -.wppb-field-error > input, -.wppb-field-error > select, -.wppb-field-error > textarea, -.wppb-field-error > label{ - margin-bottom: 10px; -} - -.wppb-field-error img{ - box-shadow: none; - -webkit-box-shadow:none; - border:none; - border-radius:0px; - vertical-align: middle; - margin-top: -3px; - padding-left:5px; - width: auto; - height: auto; -} - -.wppb-form-field > span.wppb-form-error{ - margin-top:10px; - padding-top: 5px; - border-top:1px dotted #c89797; - font-size:100%; - margin-left: 0; -} - -/* Remove global Blog Details Field error */ -#wppb-register-user .wppb-default-blog-details.wppb-field-error{ - background-color: transparent !important; - border: 0px !important; -} -.wppb-default-blog-details > span.wppb-form-error{ - display:none; -} -.wppb-blog-details-heading span { - margin-left: 0; -} - - - - -/*-------------------------------------------------------------- -5.0 User Listing ---------------------------------------------------------------*/ -.wppb-table *{ - -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; -} -.wppb-table{ - -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; - border-spacing: 0.5rem; - border-collapse: collapse; - width: 100%; -} - -.wppb-table th{ - background: #f4f4f4; - padding: 7px; - border:1px solid #e1e1e1; - text-align: left; -} - -.wppb-table thead tr:hover{ - background: none; -} - -.wppb-table .wppb-sorting .wppb-sorting-default { - display: inline-block; - width: 16px; - height: 16px; - background: url('../images/sorting-default.png') no-repeat center center; - vertical-align: middle; -} - -.wppb-table .wppb-sorting .wppb-sorting-ascending { - background-image: url('../images/sorting-ascending.png'); -} - -.wppb-table .wppb-sorting .wppb-sorting-descending { - background-image: url('../images/sorting-descending.png'); -} - -.wppb-table tr:hover{ - background: #f1fcff; -} -.wppb-table td{ - padding: 7px; - border:1px solid #e1e1e1; -} - -.wppb-table .wppb-posts, -.wppb-table .wppb-moreinfo{ - text-align: center; -} - -.wppb-avatar img { - max-width: none; -} - -ul.wppb-profile{ - list-style-type: none; - margin-left: 0; - margin-right: 0; - padding-left:0; - padding-right: 0; -} - -ul.wppb-profile li{ - margin-left: 0; - margin-right: 0; - overflow: hidden; -} - -ul.wppb-profile li label{ - display: block; - width:30%; - float:left; - min-height:1px; - font-weight: bold; -} - -ul.wppb-profile li span{ - display: block; - width:69.9%; - float:left; -} - -ul.wppb-profile li h3, -ul.wppb-profile li h3:first-child{ - margin:20px 0; - padding-top:20px; - border-top:1px solid #d2d2d2; -} - -ul.wppb-faceted-list{ - list-style: none; - margin:0 0 20px; -} - -ul.wppb-faceted-list:after{ - visibility: hidden; - display: block; - font-size: 0; - content: " "; - clear: both; - height: 0; -} - -ul.wppb-faceted-list > li{ - float:left; - margin-right: 15px; - max-width: 300px; -} - -ul.wppb-faceted-list > li:first-child{ - float:none; - clear:both; -} - -.wppb-userlisting-container .wppb-faceted-list li h5{ - margin-top: 20px; - margin-bottom: 5px; -} - -ul.wppb-faceted-list label > *{ - vertical-align: middle; -} - -ul.wppb-faceted-list input[type="checkbox"]{ - margin-right: 5px; -} - -.wppb-userlisting-container.wppb-spinner{ - position:relative; - opacity: 0.5 -} - -.wppb-userlisting-container.wppb-spinner:after{ - content: ''; - position: absolute; - top: 50%; - left: 50%; - margin-top: -16px; - margin-left: -16px; - display: block; - width: 32px; - height: 32px; - /*background: url('../images/ajax-loader.gif') no-repeat center;*/ - z-index: 1000; -} - -ul.wppb-faceted-list .hide-this{ - display:none; -} - -#wppb-remove-facets-container{ - list-style: none; - margin: 0; -} - -.wppb-remove-facet:before, .wppb-remove-all-facets:before { - content: "x"; - display: inline-block; - border-right: 1px dotted #D3CCC9; - border-right: 1px dotted #6F6F6F; - padding-right: 5px; - margin-right: 5px; -} - -.wppb-userlisting-container .wppb-ul-range-values{ - padding: 5px 0; -} - -.wppb-userlisting-container:after { - visibility: hidden; - display: block; - font-size: 0; - content: " "; - clear: both; - height: 0; -} - -.wppb-float-left{ - float:left; -} - -.wppb-float-right{ - float:right; -} - -.wppb-facet-float-left{ - float:left; - max-width:300px; -} - -.wppb-facet-float-right{ - float:right; - max-width:300px; -} - - -@media screen and ( max-width: 720px ) { - - .wppb-table { - border: 0; - } - - .wppb-table thead { - display: none - } - - .wppb-table tr { - display: block; - margin-bottom: 30px; - } - - .wppb-table td { - display: block; - text-align: right; - border-bottom: 0; - } - - .wppb-table td:last-of-type { - border-bottom: 1px solid #e1e1e1; - } - - .wppb-table .wppb-posts, - .wppb-table .wppb-moreinfo{ - text-align: right; - } - - .wppb-table td:before { - content: attr(data-label); - float: left; - } - - .wppb-table td:after { - content: ''; - display: block; - clear: both; - } - -} - -/*-------------------------------------------------------------- -6.0 Media Queries ---------------------------------------------------------------*/ - -@media screen and (max-width: 400px) { - - .wppb-form-field label, - #wppb-login-wrap .login-username label, - #wppb-login-wrap .login-password label, - ul.wppb-profile li label{ - width:100%; - display:block; - float:none; - } - - .wppb-form-field input, - .wppb-form-field select, - .wppb-form-field textarea, - .wppb-checkboxes, - .wppb-radios, - #wppb-login-wrap .login-username input, - #wppb-login-wrap .login-password input, - ul.wppb-profile li span{ - width:100%; - float:left; - } - - .wppb-form-field > span{ - margin-left:0; - } - - .wppb-checkboxes li label, - .wppb-radios li label{ - display:inline; - } - - .wppb-form-field .wppb-avatar-nofile, - .wppb-form-field .wppb-avatar-file, - .wppb-form-field .wppb-upload-nofile, - .wppb-form-field .wppb-upload-file{ - margin-left:0; - } - -} - -/*-------------------------------------------------------------- -7.0 Password Strength ---------------------------------------------------------------*/ -#pass-strength-result { - background-color: #eee; - border: 1px solid #ddd; - display: none; - float: left; - margin: 13px 5px 5px 30%; - padding: 3px 5px; - text-align: center; - width: 200px; - height:28px; -} -#pass-strength-result.short { - background-color: #ffa0a0; - border-color: #f04040; -} -#pass-strength-result.bad { - background-color: #ffb78c; - border-color: #ff853c; -} -#pass-strength-result.good { - background-color: #ffec8b; - border-color: #fc0; -} -#pass-strength-result.strong { - background-color: #c3ff88; - border-color: #8dff1c; -} - -/**************************************************/ -/* Profile Builder Subscription Plans Field -/**************************************************/ -.wppb-form-field.wppb-subscription-plans label { - width: 100%; - float: none; -} - -.wppb-form-field.wppb-subscription-plans input { - display: inline-block; - width: auto; - float: none; - margin-right: 10px !important; -} - -.wppb-form-field.wppb-subscription-plans span.description { - display: block; - font-size: 100%; - font-style: italic; - margin-left: 0; - margin-bottom: 1.5em; -} - -/**************************************************/ -/* This is very weird: if in the css there is a rule on table of border-collapse:collapse; then on FFox and Edge the Media upload won't open -/**************************************************/ -table{ - border-collapse:separate; +/* Register & Edit Profile Forms*/ + +/*-------------------------------------------------------------- +>>> TABLE OF CONTENTS: +---------------------------------------------------------------- +1.0 - Reset +2.0 - Forms +3.0 - Alignments +4.0 - Errors & Notices +5.0 - User Listing +6.0 - Media Queries +--------------------------------------------------------------*/ + +/*-------------------------------------------------------------- +1.0 Reset +--------------------------------------------------------------*/ +.wppb-user-forms, +.wppb-user-forms *{ + -webkit-box-sizing: border-box !important; /* Safari/Chrome, other WebKit */ + -moz-box-sizing: border-box !important; /* Firefox, other Gecko */ + box-sizing: border-box !important; /* Opera/IE 8+ */ +} + +/*-------------------------------------------------------------- +2.0 Forms +--------------------------------------------------------------*/ +.wppb-user-forms input:not([type="button"]):not([type="reset"]):not([type="submit"]), +.wppb-user-forms select, +.wppb-user-forms textarea{ + font-size: 100%; /* Corrects font size not being inherited in all browsers */ + margin: 0; /* Addresses margins set differently in IE6/7, F3/4, S5, Chrome */ + vertical-align: baseline; /* Improves appearance and consistency in all browsers */ +} +.wppb-user-forms input[type="checkbox"], +.wppb-user-forms input[type="radio"] { + padding: 0; /* Addresses excess padding in IE8/9 */ +} +.wppb-user-forms input[type="search"] { + -webkit-appearance: textfield; /* Addresses appearance set to searchfield in S5, Chrome */ + -webkit-box-sizing: content-box; /* Addresses box sizing set to border-box in S5, Chrome (include -moz to future-proof) */ + -moz-box-sizing: content-box; + box-sizing: content-box; +} +.wppb-user-forms input[type="search"]::-webkit-search-decoration { /* Corrects inner padding displayed oddly in S5, Chrome on OSX */ + -webkit-appearance: none; +} +.wppb-user-forms button::-moz-focus-inner, +.wppb-user-forms input::-moz-focus-inner { /* Corrects inner padding and border displayed oddly in FF3/4 www.sitepen.com/blog/2008/05/14/the-devils-in-the-details-fixing-dojos-toolbar-buttons/ */ + border: 0; + padding: 0; +} +.wppb-user-forms input[type="text"], +.wppb-user-forms input[type="number"], +.wppb-user-forms input[type="email"], +.wppb-user-forms input[type="url"], +.wppb-user-forms input[type="password"], +.wppb-user-forms input[type="search"], +.wppb-user-forms textarea{ + color: #666; + border: 1px solid #ccc; + border-radius: 3px; +} +.wppb-user-forms input[type="text"]:focus, +.wppb-user-forms input[type="number"]:focus, +.wppb-user-forms input[type="email"]:focus, +.wppb-user-forms input[type="url"]:focus, +.wppb-user-forms input[type="password"]:focus, +.wppb-user-forms input[type="search"]:focus, +.wppb-user-forms textarea:focus { + color: #111; +} +.wppb-user-forms input[type="text"], +.wppb-user-forms input[type="number"], +.wppb-user-forms input[type="email"], +.wppb-user-forms input[type="url"], +.wppb-user-forms input[type="password"], +.wppb-user-forms input[type="search"] { + padding: 3px; +} +.wppb-user-forms textarea { + overflow: auto; /* Removes default vertical scrollbar in IE6/7/8/9 */ + padding-left: 3px; + vertical-align: top; /* Improves readability and alignment in all browsers */ + width: 100%; +} +.wppb-user-forms .wppb-wysiwyg .wp-editor-wrap { /* properly align wysiwyg editor among form fields */ + float:left; + width:69.9%; +} +.wppb-user-forms .wppb-wysiwyg button:hover{ /* wysiwyg - overwrite the theme inherited background color on hover*/ + background: none; +} +.wppb-user-forms .wppb-wysiwyg div.mce-tinymce.mce-panel{ /*Display the borders for the TinyMCE editor - Visual tab*/ + border: 1px solid #ccc !important; + color: #666 !important; +} +.wppb-user-forms .wppb-wysiwyg div.mce-panel.mce-first{ + border-width: 0 0 1px 0 !important; +} +.wppb-user-forms .wppb-wysiwyg div.mce-panel.mce-last{ + border-width: 1px 0 !important; +} +.wppb-user-forms .wppb-wysiwyg .quicktags-toolbar { /*Display the borders for the TinyMCE editor - Text tab*/ + border: 1px solid #dedede; + border-bottom: 0; +} +#wp-link label input[type="text"] { /*Fix the looks of the Add Link window for TinyMCE editor*/ + padding: 0px; +} + +#wppb-search-fields{ + min-width: 250px; + float:left; + margin-right:20px; +} + +.wppb-user-forms .wppb-search-button{ + margin-right:10px; + padding:7px 20px; + line-height: 24px; +} + +.wppb-search-users-wrap{ + margin-bottom: 20px; +} + +.wppb-user-forms .extra_field_heading { + margin-bottom: 0; +} + +/*-------------------------------------------------------------- +3.0 Alignments +--------------------------------------------------------------*/ +.wppb-user-forms ul{ + max-width:900px; + list-style:none; + margin-left:0; + margin-right:0; + padding-left:0; + padding-right:0; +} + +.wppb-user-forms ul li{ + list-style:none; +} + +#wppb-login-wrap p, +#select_user_to_edit_form p{ + overflow:hidden; + margin:0; + padding-bottom:14px; +} + +.wppb-user-forms ul li{ + margin:0; + padding-bottom:14px; +} + +.wppb-user-forms ul li:after{ + content: ""; + clear: both; + display: block; +} + +.wppb-user-forms .wppb-input-hidden { + padding-bottom: 0; +} + +.wppb-user-forms.wppb-user-role-administrator .wppb-input-hidden { + padding-bottom: 14px; +} + +.wppb-user-forms .wppb-form-field > ul { + margin-left: 0; +} + +.wppb-form-field label, +#wppb-login-wrap .login-username label, +#wppb-login-wrap .login-password label{ + width:30%; + float:left; + min-height:1px; +} +.wppb-form-field input, +.wppb-form-field input[type="text"], .wppb-form-field input[type="number"], .wppb-form-field input[type="email"], .wppb-form-field input[type="url"], .wppb-form-field input[type="password"], .wppb-form-field input[type="search"], +.wppb-form-field select, +.wppb-form-field textarea, +.wppb-checkboxes, +.wppb-radios, +#wppb-login-wrap .login-username input, +#wppb-login-wrap .login-password input{ + width:69.9%; + float:left; +} + +.wppb-form-field.wppb-timepicker select { + width: auto; + margin-right: 5px; +} + +.wppb-user-forms .wppb-wysiwyg .wp-editor-wrap .wp-editor-tabs *{ + box-sizing: content-box !important; +} + +.wppb-user-forms .wp-editor-wrap input { + float: none; + width: auto; +} + +input#send_credentials_via_email{ + float:none; + width:auto; + margin-right:10px +} + +.wppb-send-credentials-checkbox label{ + width:auto; +} + +.wppb-form-field > span{ + display:block; + clear:both; + margin-left:30%; + font-size:80%; + font-style:italic; +} + +.wppb-form-field > span.custom_field_html { + font-style: normal; + font-size: 100%; +} + +.wppb-form-field.wppb-timepicker > span.wppb-timepicker-separator { + display: inline-block; + float: left; + clear: none; + margin-left: 0; + margin-right: 5px; + font-size: 100%; + font-style: normal; +} + +.wppb_upload_button{ + display:inline-block; +} + +.wppb-user-forms .wppb-checkboxes li, +.wppb-user-forms .wppb-radios li{ + display:inline-block; + padding:0 20px 0 0; +} + +.wppb-form-field .wppb-checkboxes label, +.wppb-form-field .wppb-radios label{ + float:none; + min-width:0; + padding-left:5px; + width:auto; + display:inline-block; +} + +.wppb-checkbox-terms-and-conditions input, +.wppb-checkboxes li input, +.wppb-radios li input{ + min-width:0; + float:none; + width:auto; +} + +.wppb-edit-user .wppb-checkbox-terms-and-conditions { + display:none; +} + +.wppb-form-field.wppb-heading span, +.wppb-default-about-yourself-heading span, +.wppb-default-contact-info-heading span, +.wppb-default-name-heading span, +.wppb-checkbox-terms-and-conditions span{ + margin-left:0; +} + +.wppb-checkbox-terms-and-conditions label { + width: 100%; +} + +.wppb-form-field.wppb-checkbox-terms-and-conditions input[type="checkbox"].custom_field_toa { + float:none; + width:auto; + margin-right:10px +} + + +.g-recaptcha{ + display: inline-block; +} +.g-recaptcha iframe{ + margin-bottom: 0; +} + +.wppb-form-field input.wppb-map-search-box { + position: absolute; + top: 10px !important; + height: 34px; + width: 50%; + min-width: 250px; + background: #fff; + border: 0; + border-radius: 1px; + padding: 0 10px; + box-shadow: 0 1px 1px 0 #c1c1c1; + font-family: 'Roboto', sans-serif; +} + +.wppb-create-new-site{ + width: 100%; +} +input#wppb_create_new_site_checkbox{ + width: auto; + margin-right: 10px; + float: none; +} +label[for=wppb_create_new_site_checkbox]{ + width:100%; +} +label[for=blog-privacy]{ + width:100%; +} + + +/*-------------------------------------------------------------- +4.0 Errors & Notices +--------------------------------------------------------------*/ + +#wppb_general_top_error_message, +.wppb-error, +.wppb-warning { + padding: 6px 9px; + margin: 0 auto 25px; + display: block; + width: 100%; + box-sizing: border-box; + background: #ffebe8; + border: 1px solid #C00; +} + +#wppb_general_top_error_message, +.wppb-error, +.wppb-warning{ + color:#222222; +} + +#wppb_general_top_error_message a, +.wppb-error a, +.wppb-warning a{ + color:#007acc; +} + +.wppb-required{ + color: red; +} + +.wppb-required, +.wppb-checkbox-terms-and-conditions span.wppb-required{ + margin-left:5px; +} + +#wppb_form_success_message, +.wppb-success { + padding: 6px 9px; + margin: 0 auto 25px; + display: block; + width: 100%; + box-sizing: border-box; + background: #e7f7d3; + border: 1px solid #6c3; +} + +.wppb-register-user .wppb-field-error, +.wppb-edit-user .wppb-field-error, +#wppb-recover-password .wppb-field-error{ + background-color: #FFDFDF; + border: 1px dotted #C89797; + margin-bottom: 6px !important; + padding: 6px !important; +} + +.wppb-field-error > input, +.wppb-field-error > select, +.wppb-field-error > textarea, +.wppb-field-error > label{ + margin-bottom: 10px; +} + +.wppb-field-error img{ + box-shadow: none; + -webkit-box-shadow:none; + border:none; + border-radius:0px; + vertical-align: middle; + margin-top: -3px; + padding-left:5px; + width: auto; + height: auto; +} + +.wppb-form-field > span.wppb-form-error{ + margin-top:10px; + padding-top: 5px; + border-top:1px dotted #c89797; + font-size:100%; + margin-left: 0; +} + +/* Remove global Blog Details Field error */ +#wppb-register-user .wppb-default-blog-details.wppb-field-error{ + background-color: transparent !important; + border: 0px !important; +} +.wppb-default-blog-details > span.wppb-form-error{ + display:none; +} +.wppb-blog-details-heading span { + margin-left: 0; +} + + + + +/*-------------------------------------------------------------- +5.0 User Listing +--------------------------------------------------------------*/ +.wppb-table *{ + -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; +} +.wppb-table{ + -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; + border-spacing: 0.5rem; + border-collapse: collapse; + width: 100%; +} + +.wppb-table th{ + background: #f4f4f4; + padding: 7px; + border:1px solid #e1e1e1; + text-align: left; +} + +.wppb-table thead tr:hover{ + background: none; +} + +.wppb-table .wppb-sorting .wppb-sorting-default { + display: inline-block; + width: 16px; + height: 16px; + background: url('../images/sorting-default.png') no-repeat center center; + vertical-align: middle; +} + +.wppb-table .wppb-sorting .wppb-sorting-ascending { + background-image: url('../images/sorting-ascending.png'); +} + +.wppb-table .wppb-sorting .wppb-sorting-descending { + background-image: url('../images/sorting-descending.png'); +} + +.wppb-table tr:hover{ + background: #f1fcff; +} +.wppb-table td{ + padding: 7px; + border:1px solid #e1e1e1; +} + +.wppb-table .wppb-posts, +.wppb-table .wppb-moreinfo{ + text-align: center; +} + +.wppb-avatar img { + max-width: none; +} + +ul.wppb-profile{ + list-style-type: none; + margin-left: 0; + margin-right: 0; + padding-left:0; + padding-right: 0; +} + +ul.wppb-profile li{ + margin-left: 0; + margin-right: 0; + overflow: hidden; +} + +ul.wppb-profile li label{ + display: block; + width:30%; + float:left; + min-height:1px; + font-weight: bold; +} + +ul.wppb-profile li span{ + display: block; + width:69.9%; + float:left; +} + +ul.wppb-profile li h3, +ul.wppb-profile li h3:first-child{ + margin:20px 0; + padding-top:20px; + border-top:1px solid #d2d2d2; +} + +ul.wppb-faceted-list{ + list-style: none; + margin:0 0 20px; +} + +ul.wppb-faceted-list:after{ + visibility: hidden; + display: block; + font-size: 0; + content: " "; + clear: both; + height: 0; +} + +ul.wppb-faceted-list > li{ + float:left; + margin-right: 15px; + max-width: 300px; +} + +ul.wppb-faceted-list > li:first-child{ + float:none; + clear:both; +} + +.wppb-userlisting-container .wppb-faceted-list li h5{ + margin-top: 20px; + margin-bottom: 5px; +} + +ul.wppb-faceted-list label > *{ + vertical-align: middle; +} + +ul.wppb-faceted-list input[type="checkbox"]{ + margin-right: 5px; +} + +.wppb-userlisting-container.wppb-spinner{ + position:relative; + opacity: 0.5 +} + +.wppb-userlisting-container.wppb-spinner:after{ + content: ''; + position: absolute; + top: 50%; + left: 50%; + margin-top: -16px; + margin-left: -16px; + display: block; + width: 32px; + height: 32px; + /*background: url('../images/ajax-loader.gif') no-repeat center;*/ + z-index: 1000; +} + +ul.wppb-faceted-list .hide-this{ + display:none; +} + +#wppb-remove-facets-container{ + list-style: none; + margin: 0; +} + +.wppb-remove-facet:before, .wppb-remove-all-facets:before { + content: "x"; + display: inline-block; + border-right: 1px dotted #D3CCC9; + border-right: 1px dotted #6F6F6F; + padding-right: 5px; + margin-right: 5px; +} + +.wppb-userlisting-container .wppb-ul-range-values{ + padding: 5px 0; +} + +.wppb-userlisting-container:after { + visibility: hidden; + display: block; + font-size: 0; + content: " "; + clear: both; + height: 0; +} + +.wppb-float-left{ + float:left; +} + +.wppb-float-right{ + float:right; +} + +.wppb-facet-float-left{ + float:left; + max-width:300px; +} + +.wppb-facet-float-right{ + float:right; + max-width:300px; +} + + +@media screen and ( max-width: 720px ) { + + .wppb-table { + border: 0; + } + + .wppb-table thead { + display: none + } + + .wppb-table tr { + display: block; + margin-bottom: 30px; + } + + .wppb-table td { + display: block; + text-align: right; + border-bottom: 0; + } + + .wppb-table td:last-of-type { + border-bottom: 1px solid #e1e1e1; + } + + .wppb-table .wppb-posts, + .wppb-table .wppb-moreinfo{ + text-align: right; + } + + .wppb-table td:before { + content: attr(data-label); + float: left; + } + + .wppb-table td:after { + content: ''; + display: block; + clear: both; + } + +} + +/*-------------------------------------------------------------- +6.0 Media Queries +--------------------------------------------------------------*/ + +@media screen and (max-width: 400px) { + + .wppb-form-field label, + #wppb-login-wrap .login-username label, + #wppb-login-wrap .login-password label, + ul.wppb-profile li label{ + width:100%; + display:block; + float:none; + } + + .wppb-form-field input, + .wppb-form-field select, + .wppb-form-field textarea, + .wppb-checkboxes, + .wppb-radios, + #wppb-login-wrap .login-username input, + #wppb-login-wrap .login-password input, + ul.wppb-profile li span{ + width:100%; + float:left; + } + + .wppb-form-field > span{ + margin-left:0; + } + + .wppb-checkboxes li label, + .wppb-radios li label{ + display:inline; + } + + .wppb-form-field .wppb-avatar-nofile, + .wppb-form-field .wppb-avatar-file, + .wppb-form-field .wppb-upload-nofile, + .wppb-form-field .wppb-upload-file{ + margin-left:0; + } + +} + +/*-------------------------------------------------------------- +7.0 Password Strength +--------------------------------------------------------------*/ +#pass-strength-result { + background-color: #eee; + border: 1px solid #ddd; + display: none; + float: left; + margin: 13px 5px 5px 30%; + padding: 3px 5px; + text-align: center; + width: 200px; + height:28px; +} +#pass-strength-result.short { + background-color: #ffa0a0; + border-color: #f04040; +} +#pass-strength-result.bad { + background-color: #ffb78c; + border-color: #ff853c; +} +#pass-strength-result.good { + background-color: #ffec8b; + border-color: #fc0; +} +#pass-strength-result.strong { + background-color: #c3ff88; + border-color: #8dff1c; +} + +/**************************************************/ +/* Profile Builder Subscription Plans Field +/**************************************************/ +.wppb-form-field.wppb-subscription-plans label { + width: 100%; + float: none; +} + +.wppb-form-field.wppb-subscription-plans input { + display: inline-block; + width: auto; + float: none; + margin-right: 10px !important; +} + +.wppb-form-field.wppb-subscription-plans span.description { + display: block; + font-size: 100%; + font-style: italic; + margin-left: 0; + margin-bottom: 1.5em; +} + +/**************************************************/ +/* This is very weird: if in the css there is a rule on table of border-collapse:collapse; then on FFox and Edge the Media upload won't open +/**************************************************/ +table{ + border-collapse:separate; } \ No newline at end of file diff --git a/profile-builder/assets/js/jquery-edit-profile.js b/profile-builder/assets/js/jquery-edit-profile.js index a386028..91f9cec 100644 --- a/profile-builder/assets/js/jquery-edit-profile.js +++ b/profile-builder/assets/js/jquery-edit-profile.js @@ -1,16 +1,16 @@ -function confirmDelete( nonceField, currentUser, customFieldID, customFieldName, returnTo, ajaxurl, what, fileName, text ) { - if (confirm(text)) { - jQuery.post( ajaxurl , { action:"hook_wppb_delete", currentUser:currentUser, customFieldID:customFieldID, customFieldName:customFieldName, what:what, _ajax_nonce:nonceField }, function( response ) { - if( jQuery.trim(response)=="done" ){ - if ( what == 'avatar' ){ - alert( ep.avatar ); - }else{ - alert( ep.attachment +' '+ fileName ); - } - window.location=returnTo; - }else{ - alert(jQuery.trim(response)); - } - }); - } +function confirmDelete( nonceField, currentUser, customFieldID, customFieldName, returnTo, ajaxurl, what, fileName, text ) { + if (confirm(text)) { + jQuery.post( ajaxurl , { action:"hook_wppb_delete", currentUser:currentUser, customFieldID:customFieldID, customFieldName:customFieldName, what:what, _ajax_nonce:nonceField }, function( response ) { + if( jQuery.trim(response)=="done" ){ + if ( what == 'avatar' ){ + alert( ep.avatar ); + }else{ + alert( ep.attachment +' '+ fileName ); + } + window.location=returnTo; + }else{ + alert(jQuery.trim(response)); + } + }); + } } \ No newline at end of file diff --git a/profile-builder/assets/js/jquery-email-confirmation.js b/profile-builder/assets/js/jquery-email-confirmation.js index 082f36e..bb88d7a 100644 --- a/profile-builder/assets/js/jquery-email-confirmation.js +++ b/profile-builder/assets/js/jquery-email-confirmation.js @@ -1,53 +1,53 @@ -function wppb_display_page_select( value ){ - if ( value == 'yes' ){ - jQuery ( '#wppb-settings-activation-page' ).show(); - jQuery ( '.dynamic1' ).show(); - - }else{ - jQuery ( '#wppb-settings-activation-page' ).hide(); - jQuery ( '.dynamic1' ).hide(); - } -} - - -function wppb_display_page_select_aa( value ){ - if ( value == 'yes' ) - jQuery ( '.dynamic2' ).show(); - - else - jQuery ( '.dynamic2' ).hide(); -} - -function wppb_display_page_select_re( value ){ - if ( value == 'yes' ) - jQuery ( '.dynamic3' ).show(); - - else - jQuery ( '.dynamic3' ).hide(); -} - - -jQuery(function() { - if ( ( jQuery( '#wppb_settings_email_confirmation' ).val() == 'yes' ) || ( jQuery( '#wppb_general_settings_hidden' ).val() == 'multisite' ) ){ - jQuery ( '#wppb-settings-activation-page' ).show(); - jQuery ( '.dynamic1' ).show(); - - }else{ - jQuery ( '#wppb-settings-activation-page' ).hide(); - jQuery ( '.dynamic1' ).hide(); - } - - - if ( jQuery( '#adminApprovalSelect' ).val() == 'yes' ) - jQuery ( '.dynamic2' ).show(); - - else - jQuery ( '.dynamic2' ).hide(); - - - if ( jQuery( '#rolesEditorSelect' ).val() == 'yes' ) - jQuery ( '.dynamic3' ).show(); - - else - jQuery ( '.dynamic3' ).hide(); +function wppb_display_page_select( value ){ + if ( value == 'yes' ){ + jQuery ( '#wppb-settings-activation-page' ).show(); + jQuery ( '.dynamic1' ).show(); + + }else{ + jQuery ( '#wppb-settings-activation-page' ).hide(); + jQuery ( '.dynamic1' ).hide(); + } +} + + +function wppb_display_page_select_aa( value ){ + if ( value == 'yes' ) + jQuery ( '.dynamic2' ).show(); + + else + jQuery ( '.dynamic2' ).hide(); +} + +function wppb_display_page_select_re( value ){ + if ( value == 'yes' ) + jQuery ( '.dynamic3' ).show(); + + else + jQuery ( '.dynamic3' ).hide(); +} + + +jQuery(function() { + if ( ( jQuery( '#wppb_settings_email_confirmation' ).val() == 'yes' ) || ( jQuery( '#wppb_general_settings_hidden' ).val() == 'multisite' ) ){ + jQuery ( '#wppb-settings-activation-page' ).show(); + jQuery ( '.dynamic1' ).show(); + + }else{ + jQuery ( '#wppb-settings-activation-page' ).hide(); + jQuery ( '.dynamic1' ).hide(); + } + + + if ( jQuery( '#adminApprovalSelect' ).val() == 'yes' ) + jQuery ( '.dynamic2' ).show(); + + else + jQuery ( '.dynamic2' ).hide(); + + + if ( jQuery( '#rolesEditorSelect' ).val() == 'yes' ) + jQuery ( '.dynamic3' ).show(); + + else + jQuery ( '.dynamic3' ).hide(); }); \ No newline at end of file diff --git a/profile-builder/assets/js/jquery-epf-rf.js b/profile-builder/assets/js/jquery-epf-rf.js index 2cfdc3d..b51768f 100644 --- a/profile-builder/assets/js/jquery-epf-rf.js +++ b/profile-builder/assets/js/jquery-epf-rf.js @@ -1,166 +1,166 @@ -function wppb_epf_rf_disable_live_select ( selector ){ - jQuery( selector ).attr( 'disabled', true ); -} - -function wppb_rf_epf_change_id( field, container_name, fieldObj ) { - var buttonInContainer = jQuery( '.button-primary', fieldObj.parent().parent().parent() ); - buttonInContainer.attr('disabled',true); - buttonInContainer.attr('tempclick', buttonInContainer.attr("onclick") ); - buttonInContainer.removeAttr('onclick'); - - jQuery.post( ajaxurl , { action:"wppb_handle_rf_epf_id_change", field:field }, function(response) { - - /** - * since version 2.0.2 we have the id directly on the option in the select so this ajax function is a little - redundant but can't be sure of the impact on other features so we will just add this - */ - id = fieldObj.find(":selected").attr( 'data-id' ); - if( !id ){ - id = response; - } - - jQuery( '#id', fieldObj.parent().parent().parent() ).val( id ); - buttonInContainer.attr('onclick', buttonInContainer.attr("tempclick") ); - buttonInContainer.removeAttr('tempclick'); - - if( ( fieldObj.parents('.update_container_wppb_rf_fields').length || fieldObj.parents('.update_container_wppb_epf_fields').length ) && buttonInContainer.attr('disabled') ) { - buttonInContainer.text('Save Changes'); - } - - buttonInContainer.removeAttr('disabled'); - }); -} - -jQuery(function(){ - wppb_disable_delete_on_default_mandatory_fields(); - wppb_disable_select_field_options(); - - jQuery(document).on( 'change', '#wppb_rf_fields .mb-list-entry-fields #field', function () { - wppb_rf_epf_change_id( jQuery(this).val(), '#wppb_rf_fields', jQuery(this) ); - }); - jQuery(document).on( 'change', '.update_container_wppb_rf_fields .mb-list-entry-fields #field', function () { - wppb_rf_epf_change_id( jQuery(this).val(), '.update_container_wppb_rf_fields', jQuery(this) ); - }); - - jQuery(document).on( 'change', '#wppb_epf_fields .mb-list-entry-fields #field', function () { - wppb_rf_epf_change_id( jQuery(this).val(), '#wppb_epf_fields', jQuery(this) ); - }); - - jQuery(document).on( 'change', '.update_container_wppb_epf_fields .mb-list-entry-fields #field', function () { - wppb_rf_epf_change_id( jQuery(this).val(), '.update_container_wppb_epf_fields', jQuery(this) ); - }); -}); - -/* function that removes the delete button and disables changing the field type on edit for username,password and email default fields */ -function wppb_disable_delete_on_default_mandatory_fields(){ - jQuery( '#container_wppb_rf_fields [class$="default-username added_fields_list"] .mbdelete, #container_wppb_rf_fields [class$="default-e-mail added_fields_list"] .mbdelete, #container_wppb_rf_fields [class$="default-password added_fields_list"] .mbdelete' ).hide(); // PB specific line - jQuery( '[class$="default-username"] #field, [class$="default-e-mail"] #field, [class$="default-password"] #field' ).attr( 'disabled', true ); // PB specific line -} - -/* Disables the options in the field select drop-down that are also present in the table below */ -function wppb_disable_select_field_options() { - jQuery('#field option').each( function() { - $optionField = jQuery(this); - $optionField.removeAttr('disabled'); - - var optionFieldId = jQuery(this).attr('data-id'); - - jQuery('#container_wppb_rf_fields .row-id pre, #container_wppb_epf_fields .row-id pre').each( function() { - if( jQuery(this).text() == optionFieldId ) { - $optionField.attr('disabled', true); - } - }); - }); - - wppb_check_options_disabled_add_field(); -} - -/* -* Check to see if the selected field in the add new field to the list select drop-down is disabled -* We don't want this to happen, so select the first option instead -*/ -function wppb_check_options_disabled_add_field() { - if( jQuery('#wppb_rf_fields #field option:selected, #wppb_epf_fields #field option:selected').is(':disabled') ) { - jQuery('#wppb_rf_fields #field option, #wppb_epf_fields #field option').first().attr('selected', true); - } -} - -/* -* Run through all the field drop-downs, in edit mode, and check if the selected option is disabled -* If it is, disable the save button and if the date-id of the selected option matches the id of the field -* change the text of the button -*/ -function wppb_check_options_disabled_edit_field() { - jQuery('.update_container_wppb_rf_fields #field, .update_container_wppb_epf_fields #field').each( function() { - - $selectedOption = jQuery(this).children('option:selected'); - $primaryButton = jQuery(this).parents('.mb-list-entry-fields').find('.button-primary'); - - if( $selectedOption.is(':disabled') ) { - $rowId = parseInt( jQuery(this).parents('tr').prev().find('.row-id pre').text() ); - - $primaryButton.attr('disabled', true); - $primaryButton[0].onclick = null; - - if( $rowId != parseInt( $selectedOption.attr('data-id') ) ) { - $primaryButton.text('This field has already been added to the form'); - } - } else { - $primaryButton.attr('disabled', false); - - var tempBtnOnClick = $primaryButton.attr('onclick'); - $primaryButton.text('Save Changes').removeAttr('onclick').attr('onclick', tempBtnOnClick); - } - - }); -} - -/* - * Check to see if the selected field in the edit field select drop-down is disabled - * If it is we want to disable saving, because no changes have been made - */ -function wppb_check_update_field_options_disabled() { - jQuery('.update_container_wppb_rf_fields #field, .update_container_wppb_epf_fields #field').each( function() { - if( jQuery(this).find('option:selected').is(':disabled') ) { - jQuery(this).parents('.mb-list-entry-fields').find('.button-primary').attr('disabled', true); - jQuery(this).parents('.mb-list-entry-fields').find('.button-primary')[0].onclick = null; - } - }); -} - -/* -* Function that sends an ajax request to delete all items(fields) from a form -* - */ -function wppb_rf_epf_delete_all_fields(event, delete_all_button_id, nonce) { - event.preventDefault(); - $deleteButton = jQuery('#' + delete_all_button_id); - - var response = confirm( "Are you sure you want to delete all items ?" ); - - if( response == true ) { - $tableParent = $deleteButton.parents('table'); - - var meta = $tableParent.attr('id').replace('container_', ''); - var post_id = parseInt( $tableParent.attr('post') ); - - $tableParent.parent().css({'opacity':'0.4', 'position':'relative'}).append('
    '); - - jQuery.post( ajaxurl, { action: "wppb_rf_epf_delete_all_fields", meta: meta, id: post_id, _ajax_nonce: nonce }, function(response) { - - /* refresh the list */ - jQuery.post( wppbWckAjaxurl, { action: "wck_refresh_list"+meta, meta: meta, id: post_id}, function(response) { - jQuery('#container_'+meta).replaceWith(response); - $tableParent = jQuery('#container_'+meta); - - $tableParent.find('tbody td').css('width', function(){ return jQuery(this).width() }); - - mb_sortable_elements(); - $tableParent.parent().css('opacity','1'); - - jQuery('#mb-ajax-loading').remove(); - }); - - }); - } +function wppb_epf_rf_disable_live_select ( selector ){ + jQuery( selector ).attr( 'disabled', true ); +} + +function wppb_rf_epf_change_id( field, container_name, fieldObj ) { + var buttonInContainer = jQuery( '.button-primary', fieldObj.parent().parent().parent() ); + buttonInContainer.attr('disabled',true); + buttonInContainer.attr('tempclick', buttonInContainer.attr("onclick") ); + buttonInContainer.removeAttr('onclick'); + + jQuery.post( ajaxurl , { action:"wppb_handle_rf_epf_id_change", field:field }, function(response) { + + /** + * since version 2.0.2 we have the id directly on the option in the select so this ajax function is a little + redundant but can't be sure of the impact on other features so we will just add this + */ + id = fieldObj.find(":selected").attr( 'data-id' ); + if( !id ){ + id = response; + } + + jQuery( '#id', fieldObj.parent().parent().parent() ).val( id ); + buttonInContainer.attr('onclick', buttonInContainer.attr("tempclick") ); + buttonInContainer.removeAttr('tempclick'); + + if( ( fieldObj.parents('.update_container_wppb_rf_fields').length || fieldObj.parents('.update_container_wppb_epf_fields').length ) && buttonInContainer.attr('disabled') ) { + buttonInContainer.text('Save Changes'); + } + + buttonInContainer.removeAttr('disabled'); + }); +} + +jQuery(function(){ + wppb_disable_delete_on_default_mandatory_fields(); + wppb_disable_select_field_options(); + + jQuery(document).on( 'change', '#wppb_rf_fields .mb-list-entry-fields #field', function () { + wppb_rf_epf_change_id( jQuery(this).val(), '#wppb_rf_fields', jQuery(this) ); + }); + jQuery(document).on( 'change', '.update_container_wppb_rf_fields .mb-list-entry-fields #field', function () { + wppb_rf_epf_change_id( jQuery(this).val(), '.update_container_wppb_rf_fields', jQuery(this) ); + }); + + jQuery(document).on( 'change', '#wppb_epf_fields .mb-list-entry-fields #field', function () { + wppb_rf_epf_change_id( jQuery(this).val(), '#wppb_epf_fields', jQuery(this) ); + }); + + jQuery(document).on( 'change', '.update_container_wppb_epf_fields .mb-list-entry-fields #field', function () { + wppb_rf_epf_change_id( jQuery(this).val(), '.update_container_wppb_epf_fields', jQuery(this) ); + }); +}); + +/* function that removes the delete button and disables changing the field type on edit for username,password and email default fields */ +function wppb_disable_delete_on_default_mandatory_fields(){ + jQuery( '#container_wppb_rf_fields [class$="default-username added_fields_list"] .mbdelete, #container_wppb_rf_fields [class$="default-e-mail added_fields_list"] .mbdelete, #container_wppb_rf_fields [class$="default-password added_fields_list"] .mbdelete' ).hide(); // PB specific line + jQuery( '[class$="default-username"] #field, [class$="default-e-mail"] #field, [class$="default-password"] #field' ).attr( 'disabled', true ); // PB specific line +} + +/* Disables the options in the field select drop-down that are also present in the table below */ +function wppb_disable_select_field_options() { + jQuery('#field option').each( function() { + $optionField = jQuery(this); + $optionField.removeAttr('disabled'); + + var optionFieldId = jQuery(this).attr('data-id'); + + jQuery('#container_wppb_rf_fields .row-id pre, #container_wppb_epf_fields .row-id pre').each( function() { + if( jQuery(this).text() == optionFieldId ) { + $optionField.attr('disabled', true); + } + }); + }); + + wppb_check_options_disabled_add_field(); +} + +/* +* Check to see if the selected field in the add new field to the list select drop-down is disabled +* We don't want this to happen, so select the first option instead +*/ +function wppb_check_options_disabled_add_field() { + if( jQuery('#wppb_rf_fields #field option:selected, #wppb_epf_fields #field option:selected').is(':disabled') ) { + jQuery('#wppb_rf_fields #field option, #wppb_epf_fields #field option').first().attr('selected', true); + } +} + +/* +* Run through all the field drop-downs, in edit mode, and check if the selected option is disabled +* If it is, disable the save button and if the date-id of the selected option matches the id of the field +* change the text of the button +*/ +function wppb_check_options_disabled_edit_field() { + jQuery('.update_container_wppb_rf_fields #field, .update_container_wppb_epf_fields #field').each( function() { + + $selectedOption = jQuery(this).children('option:selected'); + $primaryButton = jQuery(this).parents('.mb-list-entry-fields').find('.button-primary'); + + if( $selectedOption.is(':disabled') ) { + $rowId = parseInt( jQuery(this).parents('tr').prev().find('.row-id pre').text() ); + + $primaryButton.attr('disabled', true); + $primaryButton[0].onclick = null; + + if( $rowId != parseInt( $selectedOption.attr('data-id') ) ) { + $primaryButton.text('This field has already been added to the form'); + } + } else { + $primaryButton.attr('disabled', false); + + var tempBtnOnClick = $primaryButton.attr('onclick'); + $primaryButton.text('Save Changes').removeAttr('onclick').attr('onclick', tempBtnOnClick); + } + + }); +} + +/* + * Check to see if the selected field in the edit field select drop-down is disabled + * If it is we want to disable saving, because no changes have been made + */ +function wppb_check_update_field_options_disabled() { + jQuery('.update_container_wppb_rf_fields #field, .update_container_wppb_epf_fields #field').each( function() { + if( jQuery(this).find('option:selected').is(':disabled') ) { + jQuery(this).parents('.mb-list-entry-fields').find('.button-primary').attr('disabled', true); + jQuery(this).parents('.mb-list-entry-fields').find('.button-primary')[0].onclick = null; + } + }); +} + +/* +* Function that sends an ajax request to delete all items(fields) from a form +* + */ +function wppb_rf_epf_delete_all_fields(event, delete_all_button_id, nonce) { + event.preventDefault(); + $deleteButton = jQuery('#' + delete_all_button_id); + + var response = confirm( "Are you sure you want to delete all items ?" ); + + if( response == true ) { + $tableParent = $deleteButton.parents('table'); + + var meta = $tableParent.attr('id').replace('container_', ''); + var post_id = parseInt( $tableParent.attr('post') ); + + $tableParent.parent().css({'opacity':'0.4', 'position':'relative'}).append('
    '); + + jQuery.post( ajaxurl, { action: "wppb_rf_epf_delete_all_fields", meta: meta, id: post_id, _ajax_nonce: nonce }, function(response) { + + /* refresh the list */ + jQuery.post( wppbWckAjaxurl, { action: "wck_refresh_list"+meta, meta: meta, id: post_id}, function(response) { + jQuery('#container_'+meta).replaceWith(response); + $tableParent = jQuery('#container_'+meta); + + $tableParent.find('tbody td').css('width', function(){ return jQuery(this).width() }); + + mb_sortable_elements(); + $tableParent.parent().css('opacity','1'); + + jQuery('#mb-ajax-loading').remove(); + }); + + }); + } } \ No newline at end of file diff --git a/profile-builder/assets/js/jquery-manage-fields-live-change.js b/profile-builder/assets/js/jquery-manage-fields-live-change.js index fdf7ccd..7f0786c 100644 --- a/profile-builder/assets/js/jquery-manage-fields-live-change.js +++ b/profile-builder/assets/js/jquery-manage-fields-live-change.js @@ -1,741 +1,741 @@ -var fields = { - 'Default - Name (Heading)': { 'show_rows' : [ - '.row-field-title', - '.row-description', - ], - 'properties': { - 'meta_name_value' : '' - } - }, - - 'Default - Contact Info (Heading)': { 'show_rows' : [ - '.row-field-title', - '.row-description', - ], - 'properties': { - 'meta_name_value' : '' - } - }, - - 'Default - About Yourself (Heading)': { 'show_rows' : [ - '.row-field-title', - '.row-description', - ], - 'properties': { - 'meta_name_value' : '' - } - }, - - 'Default - Username': { 'show_rows' : [ - '.row-field-title', - '.row-description', - '.row-default-value', - '.row-required' - ], - 'properties': { - 'meta_name_value' : '' - }, - 'required' : [ - true - ] - }, - - 'Default - First Name': { 'show_rows' : [ - '.row-field-title', - '.row-meta-name', - '.row-description', - '.row-default-value', - '.row-required' - ], - 'properties': { - 'meta_name_value' : 'first_name' - } - }, - - 'Default - Last Name': { 'show_rows' : [ - '.row-field-title', - '.row-meta-name', - '.row-description', - '.row-default-value', - '.row-required' - ], - 'properties': { - 'meta_name_value' : 'last_name' - } - }, - - 'Default - Nickname': { 'show_rows' : [ - '.row-field-title', - '.row-meta-name', - '.row-description', - '.row-default-value', - '.row-required' - ], - 'properties': { - 'meta_name_value' : 'nickname' - }, - 'required' : [ - true - ] - }, - - 'Default - E-mail': { 'show_rows' : [ - '.row-field-title', - '.row-description', - '.row-default-value', - '.row-required' - ], - 'properties': { - 'meta_name_value' : '' - }, - 'required' : [ - true - ] - }, - - 'Default - Website': { 'show_rows' : [ - '.row-field-title', - '.row-description', - '.row-default-value', - '.row-required' - ], - 'properties': { - 'meta_name_value' : '' - } - }, - - 'Default - AIM': { 'show_rows' : [ - '.row-field-title', - '.row-meta-name', - '.row-description', - '.row-default-value', - '.row-required' - ], - 'properties': { - 'meta_name_value' : 'aim' - } - }, - - 'Default - Yahoo IM': { 'show_rows' : [ - '.row-field-title', - '.row-meta-name', - '.row-description', - '.row-default-value', - '.row-required' - ], - 'properties': { - 'meta_name_value' : 'yim' - } - }, - - 'Default - Jabber / Google Talk': { 'show_rows' : [ - '.row-field-title', - '.row-meta-name', - '.row-description', - '.row-default-value', - '.row-required' - ], - 'properties': { - 'meta_name_value' : 'jabber' - } - }, - - 'Default - Password': { 'show_rows' : [ - '.row-field-title', - '.row-description', - '.row-required' - ], - 'properties': { - 'meta_name_value' : '' - }, - 'required' : [ - true - ] - }, - - 'Default - Repeat Password': { 'show_rows' : [ - '.row-field-title', - '.row-description', - '.row-required' - ], - 'properties': { - 'meta_name_value' : '' - }, - 'required' : [ - true - ] - }, - - 'Default - Biographical Info': { 'show_rows' : [ - '.row-field-title', - '.row-meta-name', - '.row-description', - '.row-row-count', - '.row-default-content', - '.row-required' - ], - 'properties': { - 'meta_name_value' : 'description' - } - }, - - 'Default - Display name publicly as': { 'show_rows' : [ - '.row-field-title', - '.row-description', - '.row-default-value', - '.row-required' - ], - 'properties': { - 'meta_name_value' : '' - } - }, - - 'Default - Blog Details': { 'show_rows' : [ - '.row-field-title', - '.row-description' - ], - 'properties': { - 'meta_name_value' : '' - } - }, - - 'Heading': { 'show_rows' : [ - '.row-field-title', - '.row-description', - '.row-heading-tag' - ], - 'properties': { - 'meta_name_value' : '' - } - }, - - 'Input': { 'show_rows' : [ - '.row-field-title', - '.row-meta-name', - '.row-description', - '.row-default-value', - '.row-required', - '.row-overwrite-existing' - ] - }, - - 'Number': { 'show_rows' : [ - '.row-field-title', - '.row-meta-name', - '.row-description', - '.row-default-value', - '.row-min-number-value', - '.row-max-number-value', - '.row-number-step-value', - '.row-required', - '.row-overwrite-existing' - ] - }, - 'Input (Hidden)': { 'show_rows' : [ - '.row-field-title', - '.row-meta-name', - '.row-description', - '.row-default-value', - '.row-overwrite-existing' - ] - }, - - 'Textarea': { 'show_rows' : [ - '.row-field-title', - '.row-meta-name', - '.row-description', - '.row-default-content', - '.row-required', - '.row-row-count', - '.row-overwrite-existing' - ] - }, - 'WYSIWYG': { 'show_rows' : [ - '.row-field-title', - '.row-meta-name', - '.row-description', - '.row-default-content', - '.row-required', - '.row-overwrite-existing' - ] - }, - 'Phone': { 'show_rows' : [ - '.row-field-title', - '.row-meta-name', - '.row-description', - '.row-phone-format', - '.row-required', - '.row-overwrite-existing' - ] - }, - 'Select': { 'show_rows' : [ - '.row-field-title', - '.row-meta-name', - '.row-description', - '.row-default-option', - '.row-required', - '.row-overwrite-existing', - '.row-options', - '.row-labels' - ] - }, - 'Select (Multiple)': { 'show_rows' : [ - '.row-field-title', - '.row-meta-name', - '.row-description', - '.row-default-options', - '.row-required', - '.row-overwrite-existing', - '.row-options', - '.row-labels' - ] - }, - - 'Select (Country)': { 'show_rows' : [ - '.row-field-title', - '.row-meta-name', - '.row-description', - '.row-default-option-country', - '.row-required', - '.row-overwrite-existing' - ] - }, - - 'Select (Currency)': { 'show_rows' : [ - '.row-field-title', - '.row-meta-name', - '.row-description', - '.row-show-currency-symbol', - '.row-default-option-currency', - '.row-required', - '.row-overwrite-existing' - ] - }, - - 'Select (Timezone)': { 'show_rows' : [ - '.row-field-title', - '.row-meta-name', - '.row-description', - '.row-default-option-timezone', - '.row-required', - '.row-overwrite-existing' - ] - }, - 'Select (CPT)': { 'show_rows' : [ - '.row-field-title', - '.row-meta-name', - '.row-description', - '.row-default-option', - '.row-cpt', - '.row-required', - '.row-overwrite-existing' - ] - }, - - 'Checkbox': { 'show_rows' : [ - '.row-field-title', - '.row-meta-name', - '.row-description', - '.row-default-options', - '.row-required', - '.row-overwrite-existing', - '.row-options', - '.row-labels' - ] - }, - - 'Checkbox (Terms and Conditions)': { 'show_rows' : [ - '.row-field-title', - '.row-meta-name', - '.row-description', - '.row-required', - '.row-overwrite-existing' - ], - 'required' : [ - true - ] - }, - - 'Radio': { 'show_rows' : [ - '.row-field-title', - '.row-meta-name', - '.row-description', - '.row-default-option', - '.row-required', - '.row-overwrite-existing', - '.row-options', - '.row-labels' - ] - }, - - 'Upload': { 'show_rows' : [ - '.row-field-title', - '.row-meta-name', - '.row-description', - '.row-allowed-extensions', - '.row-required', - '.row-allowed-upload-extensions' - ] - }, - - 'Avatar': { 'show_rows' : [ - '.row-field-title', - '.row-meta-name', - '.row-description', - '.row-allowed-image-extensions', - '.row-avatar-size', - '.row-required', - '.row-overwrite-existing' - ] - }, - - 'Datepicker': { 'show_rows' : [ - '.row-field-title', - '.row-meta-name', - '.row-description', - '.row-default-value', - '.row-required', - '.row-date-format', - '.row-overwrite-existing' - ] - }, - - - 'Timepicker': { 'show_rows' : [ - '.row-field-title', - '.row-meta-name', - '.row-description', - '.row-required', - '.row-time-format', - '.row-overwrite-existing' - ] - }, - - 'Colorpicker': { 'show_rows' : [ - '.row-field-title', - '.row-meta-name', - '.row-description', - '.row-required', - '.row-overwrite-existing' - ] - }, - - - 'Validation': { 'show_rows' : [ - '.row-field-title', - '.row-meta-name', - '.row-description', - '.row-validation-possible-values', - '.row-custom-error-message', - '.row-required' - ], - 'required' : [ - true - ] - }, - - 'reCAPTCHA': { 'show_rows' : [ - '.row-field-title', - '.row-description', - '.row-public-key', - '.row-private-key', - '.row-captcha-pb-forms', - '.row-captcha-wp-forms', - '.row-required' - ], - 'required' : [ - true - ], - 'properties': { - 'meta_name_value' : '' - } - }, - - 'Select (User Role)': { 'show_rows' : [ - '.row-field-title', - '.row-description', - '.row-user-roles', - '.row-required' - ], - 'properties': { - 'meta_name_value' : '' - } - }, - - 'Map': { 'show_rows' : [ - '.row-field-title', - '.row-meta-name', - '.row-description', - '.row-map-api-key', - '.row-map-default-lat', - '.row-map-default-lng', - '.row-map-default-zoom', - '.row-map-height', - '.row-required' - ] - }, - 'HTML': { 'show_rows' : [ - '.row-field-title', - '.row-description', - '.row-html-content' - ], - 'properties': { - 'meta_name_value' : '' - } - } - } -var fields_to_show = [ - '.row-field-title', - '.row-field', - '.row-meta-name', - '.row-required' -] - -function wppb_hide_properties_for_already_added_fields( container_name ){ - - jQuery( container_name + ' tr:not(.update_container_wppb_manage_fields)' ).each(function() { - - field = jQuery('.row-field pre', this).text(); - - jQuery( 'li', this ).each(function() { - var class_name = ''; - - class_name = jQuery(this).attr('class'); - jQuery(this).hide(); - - if ( ( field in fields ) ){ - var to_show = fields[field]['show_rows']; - for (var key in to_show) { - if ('.'+class_name == fields_to_show[key]){ - jQuery(this).show(); - } - } - } - - }); - }); - - /* hide the delete button for username,password and email fields */ - jQuery( container_name + ' ' + '.element_type_default-e-mail .mbdelete,' + ' ' + container_name + ' ' + '.element_type_default-password .mbdelete,' + ' ' + container_name + ' ' + '.element_type_default-username .mbdelete' ).hide(); // PB specific line -} - - - -function wppb_hide_all ( container_name ){ - jQuery( container_name + ' ' + '.mb-list-entry-fields > li' ).each(function() { - if ( !( ( jQuery(this).hasClass('row-field') ) || ( jQuery(this).children().hasClass('button-primary') ) ) ){ - jQuery(this).hide(); - } - }); - - jQuery( container_name + ' ' + '.mb-list-entry-fields .button-primary' ).attr( 'disabled', true ); - - jQuery( container_name + ' ' + '.element_type_default-e-mail .mbdelete,' + ' ' + container_name + ' ' + '.element_type_default-password .mbdelete,' + ' ' + container_name + ' ' + '.element_type_default-username .mbdelete' ).hide(); // PB specific line - jQuery( container_name + ' ' + '.element_type_default-e-mail #field' + ', ' + container_name + ' ' + '.element_type_default-password #field' + ', ' + container_name + ' ' + '.element_type_default-username #field' + ', ' + container_name + ' ' + '.element_type_default-e-mail #required' + ', ' + container_name + ' ' + '.element_type_default-password #required,' + container_name + ' ' + '.element_type_default-username #required,' + container_name + ' ' + '.element_type_checkbox-terms-and-conditions #required,' + container_name + ' ' + '.element_type_recaptcha #required,' + container_name + ' ' + '.element_type_woocommerce-customer-billing-address #field, ' + container_name + ' ' + '.element_type_woocommerce-customer-shipping-address #field').attr( 'disabled', true ); // PB specific line - -} - - -function wppb_disable_add_entry_button( container_name ){ - jQuery( container_name + ' ' + '.mb-list-entry-fields .button-primary' ).each( function(){ - - //jQuery(this).data('myclick', this.onclick ); - this.onclick = function(event) { - if ( jQuery(this).attr( 'disabled' ) ) { - return false; - } - /* changed this in version 2.5.0 because the commented line generated stack exceeded error when multiple fields were opened with edit */ - if ( typeof( event.currentTarget ) == 'undefined' ){ - // Repeater field triggered the click event of the "Add Field" / "Save changes" buttons, so the onclick attribute is in the target, not currentTarget - eval(event.target.getAttribute('onclick')); - }else { - // normal Manage Fields Add Field button press - eval(event.currentTarget.getAttribute('onclick')); - } - - //jQuery(this).data('myclick').call(this, event || window.event); - }; - }); - -} - - -function wppb_edit_form_properties( container_name, element_id ){ - wppb_hide_all ( container_name ); - wppb_disable_add_entry_button ( container_name ); - - field = jQuery( container_name + ' #' + element_id + ' ' + '#field' ).val(); - - if ( ( field in fields ) ){ - var to_show = fields[jQuery.trim(field)]['show_rows']; - for (var key in to_show) - jQuery( container_name + ' #' + element_id + ' ' + to_show[key] ).show(); - - var properties = fields[ jQuery.trim(field) ]['properties']; - if( typeof properties !== 'undefined' && properties ) { - for( var key in properties ) { - if( typeof properties['meta_name_value'] !== 'undefined' ) { - jQuery( container_name + ' ' + '#meta-name').attr( 'readonly', true ); - } - } - } - - jQuery( container_name + ' ' + '.mb-list-entry-fields .button-primary' ).removeAttr( 'disabled' ); - - //Handle user role sorting - wppb_handle_user_role_field( container_name ); - } -} - - -function wppb_display_needed_fields( index, container_name, current_field_select ){ - var show_rows = fields[jQuery.trim(index)]['show_rows']; - for (var key in show_rows) { - jQuery( show_rows[key], jQuery( current_field_select ).parents( '.mb-list-entry-fields' ) ).show(); - } - - var properties = fields[jQuery.trim(index)]['properties']; - if ( ( ( typeof properties !== 'undefined' ) && ( properties ) ) ) { //the extra (second) condition is a particular case since only the username is defined in our global array that has no meta-name - for (var key in properties) { - if ( ( typeof properties['meta_name_value'] !== 'undefined' ) ){ - jQuery( container_name + ' ' + '#meta-name' ).val( properties['meta_name_value'] ); - jQuery( container_name + ' ' + '#meta-name' ).attr( 'readonly', true ); - } - } - - }else{ - /* meta value when editing a field shouldn't change so we take it from the current entered value which is displayed above the edit form */ - if( jQuery( current_field_select).parents('.update_container_wppb_manage_fields').length != 0 ){ - meta_value = jQuery( '.row-meta-name pre', jQuery( current_field_select).parents( '.update_container_wppb_manage_fields' ).prev() ).text(); - } - /* for the add form it should change */ - else{ - - // Repeater fields have different meta name prefixes, stored in the GET parameter 'wppb_field_metaname_prefix'. - var get_parameter_prefix = wppb_get_parameter_by_name( 'wppb_field_metaname_prefix' ); - var field_metaname_prefix = ( get_parameter_prefix == null ) ? 'custom_field' : get_parameter_prefix; - - numbers = new Array(); - jQuery( '#container_wppb_manage_fields .row-meta-name pre').each(function(){ - meta_name = jQuery(this).text(); - if( meta_name.indexOf( field_metaname_prefix ) !== -1 ){ - var meta_name = meta_name.replace(field_metaname_prefix, '' ); - /* we should have an underscore present in custom_field_# so remove it */ - meta_name = meta_name.replace('_', '' ); - - if( isNaN( meta_name ) ){ - meta_name = Math.floor((Math.random() * 200) + 100); - } - numbers.push( parseInt(meta_name) ); - } - - }); - if( numbers.length > 0 ){ - numbers.sort( function(a, b){return a-b} ); - numbers.reverse(); - meta_number = parseInt(numbers[0])+1; - } - else - meta_number = 1; - - meta_value = field_metaname_prefix + '_' + meta_number; - } - - jQuery( container_name + ' ' + '#meta-name' ).val( meta_value ); - jQuery( container_name + ' ' + '#meta-name' ).attr( 'readonly', false ); - } - - //Handle user role sorting - wppb_handle_user_role_field( container_name ); - - var set_required = fields[jQuery.trim(index)]['required']; - if ( ( typeof set_required !== 'undefined' ) && ( set_required ) ){ - jQuery( container_name + ' ' + '#required' ).val( 'Yes' ); - jQuery( container_name + ' ' + '#required' ).attr( 'disabled', true ); - - }else{ - jQuery( container_name + ' ' + '#required' ).val( 'No' ); - jQuery( container_name + ' ' + '#required' ).attr( 'disabled', false ); - } - - jQuery( container_name + ' ' + '.mb-list-entry-fields .button-primary' ).removeAttr( 'disabled' ); -} - - -function wppb_get_parameter_by_name(name, url) { - if (!url) url = window.location.href; - name = name.replace(/[\[\]]/g, "\\$&"); - var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"), - results = regex.exec(url); - if (!results) return null; - if (!results[2]) return null; - return decodeURIComponent(results[2].replace(/\+/g, " ")); -} - -/* -* Function that handles the sorting of the user roles from the Select (User Role) -* extra field -* - */ -function wppb_handle_user_role_field( container_name ) { - - jQuery( container_name + ' ' + '.row-user-roles .wck-checkboxes').sortable({ - - //Assign a custom handle for the drag and drop - handle: '.sortable-handle', - - create: function( event, ui ) { - - //Add the custom handle for drag and drop - jQuery(this).find('div').each( function() { - jQuery(this).prepend(''); - }); - - $sortOrderInput = jQuery(this).parents('.row-user-roles').siblings('.row-user-roles-sort-order').find('input[type=text]'); - - if( $sortOrderInput.val() == '' ) { - jQuery(this).find('input[type=checkbox]').each( function() { - $sortOrderInput.val( $sortOrderInput.val() + ', ' + jQuery(this).val() ); - }); - } else { - sortOrderElements = $sortOrderInput.val().split(', '); - sortOrderElements.shift(); - - for( var i=0; i < sortOrderElements.length; i++ ) { - jQuery( container_name + ' ' + '.row-user-roles .wck-checkboxes').append( jQuery( container_name + ' ' + '.row-user-roles .wck-checkboxes input[value="' + sortOrderElements[i] + '"]').parent().parent().get(0) ); - } - } - }, - - update: function( event, ui ) { - $sortOrderInput = ui.item.parents('.row-user-roles').siblings('.row-user-roles-sort-order').find('input[type=text]'); - $sortOrderInput.val(''); - - ui.item.parent().find('input[type=checkbox]').each( function() { - $sortOrderInput.val( $sortOrderInput.val() + ', ' + jQuery(this).val() ); - }); - } - }); -} - -function wppb_initialize_live_select( container_name ){ - wppb_hide_all( container_name ); - jQuery(document).on( 'change', container_name + ' ' + '.mb-list-entry-fields #field', function () { - field = jQuery(this).val(); - - if ( field != ''){ - wppb_hide_all( container_name ); - wppb_display_needed_fields( field, container_name, this ); - }else{ - wppb_hide_all( container_name ); - } - }); -} - -jQuery(function(){ - wppb_initialize_live_select ( '#wppb_manage_fields' ); - wppb_initialize_live_select ( '#container_wppb_manage_fields' ); - - wppb_hide_properties_for_already_added_fields( '#container_wppb_manage_fields' ); - wppb_disable_add_entry_button ( '#wppb_manage_fields' ); +var fields = { + 'Default - Name (Heading)': { 'show_rows' : [ + '.row-field-title', + '.row-description', + ], + 'properties': { + 'meta_name_value' : '' + } + }, + + 'Default - Contact Info (Heading)': { 'show_rows' : [ + '.row-field-title', + '.row-description', + ], + 'properties': { + 'meta_name_value' : '' + } + }, + + 'Default - About Yourself (Heading)': { 'show_rows' : [ + '.row-field-title', + '.row-description', + ], + 'properties': { + 'meta_name_value' : '' + } + }, + + 'Default - Username': { 'show_rows' : [ + '.row-field-title', + '.row-description', + '.row-default-value', + '.row-required' + ], + 'properties': { + 'meta_name_value' : '' + }, + 'required' : [ + true + ] + }, + + 'Default - First Name': { 'show_rows' : [ + '.row-field-title', + '.row-meta-name', + '.row-description', + '.row-default-value', + '.row-required' + ], + 'properties': { + 'meta_name_value' : 'first_name' + } + }, + + 'Default - Last Name': { 'show_rows' : [ + '.row-field-title', + '.row-meta-name', + '.row-description', + '.row-default-value', + '.row-required' + ], + 'properties': { + 'meta_name_value' : 'last_name' + } + }, + + 'Default - Nickname': { 'show_rows' : [ + '.row-field-title', + '.row-meta-name', + '.row-description', + '.row-default-value', + '.row-required' + ], + 'properties': { + 'meta_name_value' : 'nickname' + }, + 'required' : [ + true + ] + }, + + 'Default - E-mail': { 'show_rows' : [ + '.row-field-title', + '.row-description', + '.row-default-value', + '.row-required' + ], + 'properties': { + 'meta_name_value' : '' + }, + 'required' : [ + true + ] + }, + + 'Default - Website': { 'show_rows' : [ + '.row-field-title', + '.row-description', + '.row-default-value', + '.row-required' + ], + 'properties': { + 'meta_name_value' : '' + } + }, + + 'Default - AIM': { 'show_rows' : [ + '.row-field-title', + '.row-meta-name', + '.row-description', + '.row-default-value', + '.row-required' + ], + 'properties': { + 'meta_name_value' : 'aim' + } + }, + + 'Default - Yahoo IM': { 'show_rows' : [ + '.row-field-title', + '.row-meta-name', + '.row-description', + '.row-default-value', + '.row-required' + ], + 'properties': { + 'meta_name_value' : 'yim' + } + }, + + 'Default - Jabber / Google Talk': { 'show_rows' : [ + '.row-field-title', + '.row-meta-name', + '.row-description', + '.row-default-value', + '.row-required' + ], + 'properties': { + 'meta_name_value' : 'jabber' + } + }, + + 'Default - Password': { 'show_rows' : [ + '.row-field-title', + '.row-description', + '.row-required' + ], + 'properties': { + 'meta_name_value' : '' + }, + 'required' : [ + true + ] + }, + + 'Default - Repeat Password': { 'show_rows' : [ + '.row-field-title', + '.row-description', + '.row-required' + ], + 'properties': { + 'meta_name_value' : '' + }, + 'required' : [ + true + ] + }, + + 'Default - Biographical Info': { 'show_rows' : [ + '.row-field-title', + '.row-meta-name', + '.row-description', + '.row-row-count', + '.row-default-content', + '.row-required' + ], + 'properties': { + 'meta_name_value' : 'description' + } + }, + + 'Default - Display name publicly as': { 'show_rows' : [ + '.row-field-title', + '.row-description', + '.row-default-value', + '.row-required' + ], + 'properties': { + 'meta_name_value' : '' + } + }, + + 'Default - Blog Details': { 'show_rows' : [ + '.row-field-title', + '.row-description' + ], + 'properties': { + 'meta_name_value' : '' + } + }, + + 'Heading': { 'show_rows' : [ + '.row-field-title', + '.row-description', + '.row-heading-tag' + ], + 'properties': { + 'meta_name_value' : '' + } + }, + + 'Input': { 'show_rows' : [ + '.row-field-title', + '.row-meta-name', + '.row-description', + '.row-default-value', + '.row-required', + '.row-overwrite-existing' + ] + }, + + 'Number': { 'show_rows' : [ + '.row-field-title', + '.row-meta-name', + '.row-description', + '.row-default-value', + '.row-min-number-value', + '.row-max-number-value', + '.row-number-step-value', + '.row-required', + '.row-overwrite-existing' + ] + }, + 'Input (Hidden)': { 'show_rows' : [ + '.row-field-title', + '.row-meta-name', + '.row-description', + '.row-default-value', + '.row-overwrite-existing' + ] + }, + + 'Textarea': { 'show_rows' : [ + '.row-field-title', + '.row-meta-name', + '.row-description', + '.row-default-content', + '.row-required', + '.row-row-count', + '.row-overwrite-existing' + ] + }, + 'WYSIWYG': { 'show_rows' : [ + '.row-field-title', + '.row-meta-name', + '.row-description', + '.row-default-content', + '.row-required', + '.row-overwrite-existing' + ] + }, + 'Phone': { 'show_rows' : [ + '.row-field-title', + '.row-meta-name', + '.row-description', + '.row-phone-format', + '.row-required', + '.row-overwrite-existing' + ] + }, + 'Select': { 'show_rows' : [ + '.row-field-title', + '.row-meta-name', + '.row-description', + '.row-default-option', + '.row-required', + '.row-overwrite-existing', + '.row-options', + '.row-labels' + ] + }, + 'Select (Multiple)': { 'show_rows' : [ + '.row-field-title', + '.row-meta-name', + '.row-description', + '.row-default-options', + '.row-required', + '.row-overwrite-existing', + '.row-options', + '.row-labels' + ] + }, + + 'Select (Country)': { 'show_rows' : [ + '.row-field-title', + '.row-meta-name', + '.row-description', + '.row-default-option-country', + '.row-required', + '.row-overwrite-existing' + ] + }, + + 'Select (Currency)': { 'show_rows' : [ + '.row-field-title', + '.row-meta-name', + '.row-description', + '.row-show-currency-symbol', + '.row-default-option-currency', + '.row-required', + '.row-overwrite-existing' + ] + }, + + 'Select (Timezone)': { 'show_rows' : [ + '.row-field-title', + '.row-meta-name', + '.row-description', + '.row-default-option-timezone', + '.row-required', + '.row-overwrite-existing' + ] + }, + 'Select (CPT)': { 'show_rows' : [ + '.row-field-title', + '.row-meta-name', + '.row-description', + '.row-default-option', + '.row-cpt', + '.row-required', + '.row-overwrite-existing' + ] + }, + + 'Checkbox': { 'show_rows' : [ + '.row-field-title', + '.row-meta-name', + '.row-description', + '.row-default-options', + '.row-required', + '.row-overwrite-existing', + '.row-options', + '.row-labels' + ] + }, + + 'Checkbox (Terms and Conditions)': { 'show_rows' : [ + '.row-field-title', + '.row-meta-name', + '.row-description', + '.row-required', + '.row-overwrite-existing' + ], + 'required' : [ + true + ] + }, + + 'Radio': { 'show_rows' : [ + '.row-field-title', + '.row-meta-name', + '.row-description', + '.row-default-option', + '.row-required', + '.row-overwrite-existing', + '.row-options', + '.row-labels' + ] + }, + + 'Upload': { 'show_rows' : [ + '.row-field-title', + '.row-meta-name', + '.row-description', + '.row-allowed-extensions', + '.row-required', + '.row-allowed-upload-extensions' + ] + }, + + 'Avatar': { 'show_rows' : [ + '.row-field-title', + '.row-meta-name', + '.row-description', + '.row-allowed-image-extensions', + '.row-avatar-size', + '.row-required', + '.row-overwrite-existing' + ] + }, + + 'Datepicker': { 'show_rows' : [ + '.row-field-title', + '.row-meta-name', + '.row-description', + '.row-default-value', + '.row-required', + '.row-date-format', + '.row-overwrite-existing' + ] + }, + + + 'Timepicker': { 'show_rows' : [ + '.row-field-title', + '.row-meta-name', + '.row-description', + '.row-required', + '.row-time-format', + '.row-overwrite-existing' + ] + }, + + 'Colorpicker': { 'show_rows' : [ + '.row-field-title', + '.row-meta-name', + '.row-description', + '.row-required', + '.row-overwrite-existing' + ] + }, + + + 'Validation': { 'show_rows' : [ + '.row-field-title', + '.row-meta-name', + '.row-description', + '.row-validation-possible-values', + '.row-custom-error-message', + '.row-required' + ], + 'required' : [ + true + ] + }, + + 'reCAPTCHA': { 'show_rows' : [ + '.row-field-title', + '.row-description', + '.row-public-key', + '.row-private-key', + '.row-captcha-pb-forms', + '.row-captcha-wp-forms', + '.row-required' + ], + 'required' : [ + true + ], + 'properties': { + 'meta_name_value' : '' + } + }, + + 'Select (User Role)': { 'show_rows' : [ + '.row-field-title', + '.row-description', + '.row-user-roles', + '.row-required' + ], + 'properties': { + 'meta_name_value' : '' + } + }, + + 'Map': { 'show_rows' : [ + '.row-field-title', + '.row-meta-name', + '.row-description', + '.row-map-api-key', + '.row-map-default-lat', + '.row-map-default-lng', + '.row-map-default-zoom', + '.row-map-height', + '.row-required' + ] + }, + 'HTML': { 'show_rows' : [ + '.row-field-title', + '.row-description', + '.row-html-content' + ], + 'properties': { + 'meta_name_value' : '' + } + } + } +var fields_to_show = [ + '.row-field-title', + '.row-field', + '.row-meta-name', + '.row-required' +] + +function wppb_hide_properties_for_already_added_fields( container_name ){ + + jQuery( container_name + ' tr:not(.update_container_wppb_manage_fields)' ).each(function() { + + field = jQuery('.row-field pre', this).text(); + + jQuery( 'li', this ).each(function() { + var class_name = ''; + + class_name = jQuery(this).attr('class'); + jQuery(this).hide(); + + if ( ( field in fields ) ){ + var to_show = fields[field]['show_rows']; + for (var key in to_show) { + if ('.'+class_name == fields_to_show[key]){ + jQuery(this).show(); + } + } + } + + }); + }); + + /* hide the delete button for username,password and email fields */ + jQuery( container_name + ' ' + '.element_type_default-e-mail .mbdelete,' + ' ' + container_name + ' ' + '.element_type_default-password .mbdelete,' + ' ' + container_name + ' ' + '.element_type_default-username .mbdelete' ).hide(); // PB specific line +} + + + +function wppb_hide_all ( container_name ){ + jQuery( container_name + ' ' + '.mb-list-entry-fields > li' ).each(function() { + if ( !( ( jQuery(this).hasClass('row-field') ) || ( jQuery(this).children().hasClass('button-primary') ) ) ){ + jQuery(this).hide(); + } + }); + + jQuery( container_name + ' ' + '.mb-list-entry-fields .button-primary' ).attr( 'disabled', true ); + + jQuery( container_name + ' ' + '.element_type_default-e-mail .mbdelete,' + ' ' + container_name + ' ' + '.element_type_default-password .mbdelete,' + ' ' + container_name + ' ' + '.element_type_default-username .mbdelete' ).hide(); // PB specific line + jQuery( container_name + ' ' + '.element_type_default-e-mail #field' + ', ' + container_name + ' ' + '.element_type_default-password #field' + ', ' + container_name + ' ' + '.element_type_default-username #field' + ', ' + container_name + ' ' + '.element_type_default-e-mail #required' + ', ' + container_name + ' ' + '.element_type_default-password #required,' + container_name + ' ' + '.element_type_default-username #required,' + container_name + ' ' + '.element_type_checkbox-terms-and-conditions #required,' + container_name + ' ' + '.element_type_recaptcha #required,' + container_name + ' ' + '.element_type_woocommerce-customer-billing-address #field, ' + container_name + ' ' + '.element_type_woocommerce-customer-shipping-address #field').attr( 'disabled', true ); // PB specific line + +} + + +function wppb_disable_add_entry_button( container_name ){ + jQuery( container_name + ' ' + '.mb-list-entry-fields .button-primary' ).each( function(){ + + //jQuery(this).data('myclick', this.onclick ); + this.onclick = function(event) { + if ( jQuery(this).attr( 'disabled' ) ) { + return false; + } + /* changed this in version 2.5.0 because the commented line generated stack exceeded error when multiple fields were opened with edit */ + if ( typeof( event.currentTarget ) == 'undefined' ){ + // Repeater field triggered the click event of the "Add Field" / "Save changes" buttons, so the onclick attribute is in the target, not currentTarget + eval(event.target.getAttribute('onclick')); + }else { + // normal Manage Fields Add Field button press + eval(event.currentTarget.getAttribute('onclick')); + } + + //jQuery(this).data('myclick').call(this, event || window.event); + }; + }); + +} + + +function wppb_edit_form_properties( container_name, element_id ){ + wppb_hide_all ( container_name ); + wppb_disable_add_entry_button ( container_name ); + + field = jQuery( container_name + ' #' + element_id + ' ' + '#field' ).val(); + + if ( ( field in fields ) ){ + var to_show = fields[jQuery.trim(field)]['show_rows']; + for (var key in to_show) + jQuery( container_name + ' #' + element_id + ' ' + to_show[key] ).show(); + + var properties = fields[ jQuery.trim(field) ]['properties']; + if( typeof properties !== 'undefined' && properties ) { + for( var key in properties ) { + if( typeof properties['meta_name_value'] !== 'undefined' ) { + jQuery( container_name + ' ' + '#meta-name').attr( 'readonly', true ); + } + } + } + + jQuery( container_name + ' ' + '.mb-list-entry-fields .button-primary' ).removeAttr( 'disabled' ); + + //Handle user role sorting + wppb_handle_user_role_field( container_name ); + } +} + + +function wppb_display_needed_fields( index, container_name, current_field_select ){ + var show_rows = fields[jQuery.trim(index)]['show_rows']; + for (var key in show_rows) { + jQuery( show_rows[key], jQuery( current_field_select ).parents( '.mb-list-entry-fields' ) ).show(); + } + + var properties = fields[jQuery.trim(index)]['properties']; + if ( ( ( typeof properties !== 'undefined' ) && ( properties ) ) ) { //the extra (second) condition is a particular case since only the username is defined in our global array that has no meta-name + for (var key in properties) { + if ( ( typeof properties['meta_name_value'] !== 'undefined' ) ){ + jQuery( container_name + ' ' + '#meta-name' ).val( properties['meta_name_value'] ); + jQuery( container_name + ' ' + '#meta-name' ).attr( 'readonly', true ); + } + } + + }else{ + /* meta value when editing a field shouldn't change so we take it from the current entered value which is displayed above the edit form */ + if( jQuery( current_field_select).parents('.update_container_wppb_manage_fields').length != 0 ){ + meta_value = jQuery( '.row-meta-name pre', jQuery( current_field_select).parents( '.update_container_wppb_manage_fields' ).prev() ).text(); + } + /* for the add form it should change */ + else{ + + // Repeater fields have different meta name prefixes, stored in the GET parameter 'wppb_field_metaname_prefix'. + var get_parameter_prefix = wppb_get_parameter_by_name( 'wppb_field_metaname_prefix' ); + var field_metaname_prefix = ( get_parameter_prefix == null ) ? 'custom_field' : get_parameter_prefix; + + numbers = new Array(); + jQuery( '#container_wppb_manage_fields .row-meta-name pre').each(function(){ + meta_name = jQuery(this).text(); + if( meta_name.indexOf( field_metaname_prefix ) !== -1 ){ + var meta_name = meta_name.replace(field_metaname_prefix, '' ); + /* we should have an underscore present in custom_field_# so remove it */ + meta_name = meta_name.replace('_', '' ); + + if( isNaN( meta_name ) ){ + meta_name = Math.floor((Math.random() * 200) + 100); + } + numbers.push( parseInt(meta_name) ); + } + + }); + if( numbers.length > 0 ){ + numbers.sort( function(a, b){return a-b} ); + numbers.reverse(); + meta_number = parseInt(numbers[0])+1; + } + else + meta_number = 1; + + meta_value = field_metaname_prefix + '_' + meta_number; + } + + jQuery( container_name + ' ' + '#meta-name' ).val( meta_value ); + jQuery( container_name + ' ' + '#meta-name' ).attr( 'readonly', false ); + } + + //Handle user role sorting + wppb_handle_user_role_field( container_name ); + + var set_required = fields[jQuery.trim(index)]['required']; + if ( ( typeof set_required !== 'undefined' ) && ( set_required ) ){ + jQuery( container_name + ' ' + '#required' ).val( 'Yes' ); + jQuery( container_name + ' ' + '#required' ).attr( 'disabled', true ); + + }else{ + jQuery( container_name + ' ' + '#required' ).val( 'No' ); + jQuery( container_name + ' ' + '#required' ).attr( 'disabled', false ); + } + + jQuery( container_name + ' ' + '.mb-list-entry-fields .button-primary' ).removeAttr( 'disabled' ); +} + + +function wppb_get_parameter_by_name(name, url) { + if (!url) url = window.location.href; + name = name.replace(/[\[\]]/g, "\\$&"); + var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"), + results = regex.exec(url); + if (!results) return null; + if (!results[2]) return null; + return decodeURIComponent(results[2].replace(/\+/g, " ")); +} + +/* +* Function that handles the sorting of the user roles from the Select (User Role) +* extra field +* + */ +function wppb_handle_user_role_field( container_name ) { + + jQuery( container_name + ' ' + '.row-user-roles .wck-checkboxes').sortable({ + + //Assign a custom handle for the drag and drop + handle: '.sortable-handle', + + create: function( event, ui ) { + + //Add the custom handle for drag and drop + jQuery(this).find('div').each( function() { + jQuery(this).prepend(''); + }); + + $sortOrderInput = jQuery(this).parents('.row-user-roles').siblings('.row-user-roles-sort-order').find('input[type=text]'); + + if( $sortOrderInput.val() == '' ) { + jQuery(this).find('input[type=checkbox]').each( function() { + $sortOrderInput.val( $sortOrderInput.val() + ', ' + jQuery(this).val() ); + }); + } else { + sortOrderElements = $sortOrderInput.val().split(', '); + sortOrderElements.shift(); + + for( var i=0; i < sortOrderElements.length; i++ ) { + jQuery( container_name + ' ' + '.row-user-roles .wck-checkboxes').append( jQuery( container_name + ' ' + '.row-user-roles .wck-checkboxes input[value="' + sortOrderElements[i] + '"]').parent().parent().get(0) ); + } + } + }, + + update: function( event, ui ) { + $sortOrderInput = ui.item.parents('.row-user-roles').siblings('.row-user-roles-sort-order').find('input[type=text]'); + $sortOrderInput.val(''); + + ui.item.parent().find('input[type=checkbox]').each( function() { + $sortOrderInput.val( $sortOrderInput.val() + ', ' + jQuery(this).val() ); + }); + } + }); +} + +function wppb_initialize_live_select( container_name ){ + wppb_hide_all( container_name ); + jQuery(document).on( 'change', container_name + ' ' + '.mb-list-entry-fields #field', function () { + field = jQuery(this).val(); + + if ( field != ''){ + wppb_hide_all( container_name ); + wppb_display_needed_fields( field, container_name, this ); + }else{ + wppb_hide_all( container_name ); + } + }); +} + +jQuery(function(){ + wppb_initialize_live_select ( '#wppb_manage_fields' ); + wppb_initialize_live_select ( '#container_wppb_manage_fields' ); + + wppb_hide_properties_for_already_added_fields( '#container_wppb_manage_fields' ); + wppb_disable_add_entry_button ( '#wppb_manage_fields' ); }); \ No newline at end of file diff --git a/profile-builder/assets/js/jquery-pb-add-ons.js b/profile-builder/assets/js/jquery-pb-add-ons.js index a7e037c..41399f8 100644 --- a/profile-builder/assets/js/jquery-pb-add-ons.js +++ b/profile-builder/assets/js/jquery-pb-add-ons.js @@ -1,237 +1,237 @@ - -/* - * Function to download/activate add-ons on button click - */ -jQuery('.wppb-add-on .button').on( 'click', function(e) { - if( jQuery(this).attr('disabled') ) { - return false; - } - - // Activate add-on - if( jQuery(this).hasClass('wppb-add-on-activate') ) { - e.preventDefault(); - wppb_add_on_activate( jQuery(this) ); - } - - // Deactivate add-on - if( jQuery(this).hasClass('wppb-add-on-deactivate') ) { - e.preventDefault(); - wppb_add_on_deactivate( jQuery(this) ); - } -}); - - -/* - * Make deactivate button from Add-On is Active message button - */ -jQuery('.wppb-add-on').on( 'hover', function() { - - $button = jQuery(this).find('.wppb-add-on-deactivate'); - - if( $button.length > 0 ) { - $button - .animate({ - opacity: 1 - }, 100); - } -}); - -/* - * Make Add-On is Active message button from deactivate button - */ -jQuery('.wppb-add-on').on( 'mouseleave', function() { - - $button = jQuery(this).find('.wppb-add-on-deactivate'); - - if( $button.length > 0 ) { - $button - .animate({ - opacity: 0 - }, 100); - } -}); - - -/* - * Function that activates the add-on - */ -function wppb_add_on_activate( $button ) { - $activate_button = $button; - - var fade_in_out_speed = 300; - var plugin = $activate_button.attr('href'); - var add_on_index = $activate_button.parents('.wppb-add-on').index('.wppb-add-on'); - var nonce = $activate_button.data('nonce'); - - $activate_button - .attr('disabled', true); - - $spinner = $activate_button.siblings('.spinner'); - - $spinner.animate({ - opacity: 0.7 - }, 100); - - // Remove the current displayed message - wppb_add_on_remove_status_message( $activate_button, fade_in_out_speed); - - jQuery.post( ajaxurl, { action: 'wppb_add_on_activate', wppb_add_on_to_activate: plugin, wppb_add_on_index: add_on_index, nonce: nonce }, function( response ) { - - add_on_index = response; - - $activate_button = jQuery('.wppb-add-on').eq( add_on_index ).find('.button'); - - $activate_button - .blur() - .removeClass('wppb-add-on-activate') - .addClass('wppb-add-on-deactivate') - .removeAttr('disabled') - .text( jQuery('#wppb-add-on-deactivate-button-text').text() ); - - $spinner = $activate_button.siblings('.spinner'); - - $spinner.animate({ - opacity: 0 - }, 0); - - // Set status confirmation message - wppb_add_on_set_status_message( $activate_button, 'dashicons-yes', jQuery('#wppb-add-on-activated-message-text').text(), fade_in_out_speed, 0, true ); - wppb_add_on_remove_status_message( $activate_button, fade_in_out_speed, 2000 ); - - // Set is active message - wppb_add_on_set_status_message( $activate_button, 'dashicons-yes', jQuery('#wppb-add-on-is-active-message-text').html(), fade_in_out_speed, 2000 + fade_in_out_speed ); - }); -} - - - -/* - * Function that deactivates the add-on - */ -function wppb_add_on_deactivate( $button ) { - - var fade_in_out_speed = 300; - var plugin = $button.attr('href'); - var add_on_index = $button.parents('.wppb-add-on').index('.wppb-add-on'); - var nonce = $button.data('nonce'); - - $button - .removeClass('wppb-add-on-deactivate') - .attr('disabled', true); - - $spinner = $button.siblings('.spinner'); - - $spinner.animate({ - opacity: 0.7 - }, 100); - - // Remove the current displayed message - wppb_add_on_remove_status_message( $button, fade_in_out_speed ); - - jQuery.post( ajaxurl, { action: 'wppb_add_on_deactivate', wppb_add_on_to_deactivate: plugin, wppb_add_on_index: add_on_index, nonce: nonce }, function( response ) { - - add_on_index = response; - - $button = jQuery('.wppb-add-on').eq( add_on_index ).find('.button'); - - $button - .blur() - .removeClass('wppb-add-on-is-active') - .addClass('wppb-add-on-activate') - .attr( 'disabled', false ) - .text( jQuery('#wppb-add-on-activate-button-text').text() ); - - $spinner = $button.siblings('.spinner'); - - $spinner.animate({ - opacity: 0 - }, 0); - - // Set status confirmation message - wppb_add_on_set_status_message( $button, 'dashicons-yes', jQuery('#wppb-add-on-deactivated-message-text').text(), fade_in_out_speed, 0, true ); - wppb_add_on_remove_status_message( $button, fade_in_out_speed, 2000 ); - - // Set is active message - wppb_add_on_set_status_message( $button, 'dashicons-no-alt', jQuery('#wppb-add-on-is-not-active-message-text').html(), fade_in_out_speed, 2000 + fade_in_out_speed ); - - }); -} - - -/* - * Function used to remove the status message of an add-on - * - * @param object $button - The jQuery object of the add-on box button that was pressed - * @param int fade_in_out_speed - The speed of the fade in and out animations - * @param int delay - Delay removing of the message - * - */ -function wppb_add_on_remove_status_message( $button, fade_in_out_speed, delay ) { - - if( typeof( delay ) == 'undefined' ) { - delay = 0; - } - - setTimeout( function() { - - $button.siblings('.dashicons') - .animate({ - opacity: 0 - }, fade_in_out_speed ); - - $button.siblings('.wppb-add-on-message') - .animate({ - opacity: 0 - }, fade_in_out_speed ); - - }, delay); - -} - -/* - * Function used to remove the status message of an add-on - * - * @param object $button - The jQuery object of the add-on box button that was pressed - * @param string message_icon_class - The string name of the class we want the icon to have - * @param string message_text - The text we want the user to see - * @param int fade_in_out_speed - The speed of the fade in and out animations - * @param bool success - If true adds a class to style the message as a success one, if false adds a class to style the message as a failure - * - */ -function wppb_add_on_set_status_message( $button, message_icon_class, message_text, fade_in_out_speed, delay, success ) { - - if( typeof( delay ) == 'undefined' ) { - delay = 0; - } - - setTimeout(function() { - - $button.siblings('.dashicons') - .css('opacity', 0) - .attr('class', 'dashicons') - .addClass( message_icon_class ) - .animate({ opacity: 1}, fade_in_out_speed); - - $button.siblings('.wppb-add-on-message') - .css('opacity', 0) - .attr( 'class', 'wppb-add-on-message' ) - .html( message_text ) - .animate({ opacity: 1}, fade_in_out_speed); - - if( typeof( success ) != 'undefined' ) { - if( success == true ) { - $button.siblings('.dashicons') - .addClass('wppb-confirmation-success'); - $button.siblings('.wppb-add-on-message') - .addClass('wppb-confirmation-success'); - } else if( success == false ) { - $button.siblings('.dashicons') - .addClass('wppb-confirmation-error'); - $button.siblings('.wppb-add-on-message') - .addClass('wppb-confirmation-error'); - } - } - - }, delay ); - + +/* + * Function to download/activate add-ons on button click + */ +jQuery('.wppb-add-on .button').on( 'click', function(e) { + if( jQuery(this).attr('disabled') ) { + return false; + } + + // Activate add-on + if( jQuery(this).hasClass('wppb-add-on-activate') ) { + e.preventDefault(); + wppb_add_on_activate( jQuery(this) ); + } + + // Deactivate add-on + if( jQuery(this).hasClass('wppb-add-on-deactivate') ) { + e.preventDefault(); + wppb_add_on_deactivate( jQuery(this) ); + } +}); + + +/* + * Make deactivate button from Add-On is Active message button + */ +jQuery('.wppb-add-on').on( 'hover', function() { + + $button = jQuery(this).find('.wppb-add-on-deactivate'); + + if( $button.length > 0 ) { + $button + .animate({ + opacity: 1 + }, 100); + } +}); + +/* + * Make Add-On is Active message button from deactivate button + */ +jQuery('.wppb-add-on').on( 'mouseleave', function() { + + $button = jQuery(this).find('.wppb-add-on-deactivate'); + + if( $button.length > 0 ) { + $button + .animate({ + opacity: 0 + }, 100); + } +}); + + +/* + * Function that activates the add-on + */ +function wppb_add_on_activate( $button ) { + $activate_button = $button; + + var fade_in_out_speed = 300; + var plugin = $activate_button.attr('href'); + var add_on_index = $activate_button.parents('.wppb-add-on').index('.wppb-add-on'); + var nonce = $activate_button.data('nonce'); + + $activate_button + .attr('disabled', true); + + $spinner = $activate_button.siblings('.spinner'); + + $spinner.animate({ + opacity: 0.7 + }, 100); + + // Remove the current displayed message + wppb_add_on_remove_status_message( $activate_button, fade_in_out_speed); + + jQuery.post( ajaxurl, { action: 'wppb_add_on_activate', wppb_add_on_to_activate: plugin, wppb_add_on_index: add_on_index, nonce: nonce }, function( response ) { + + add_on_index = response; + + $activate_button = jQuery('.wppb-add-on').eq( add_on_index ).find('.button'); + + $activate_button + .blur() + .removeClass('wppb-add-on-activate') + .addClass('wppb-add-on-deactivate') + .removeAttr('disabled') + .text( jQuery('#wppb-add-on-deactivate-button-text').text() ); + + $spinner = $activate_button.siblings('.spinner'); + + $spinner.animate({ + opacity: 0 + }, 0); + + // Set status confirmation message + wppb_add_on_set_status_message( $activate_button, 'dashicons-yes', jQuery('#wppb-add-on-activated-message-text').text(), fade_in_out_speed, 0, true ); + wppb_add_on_remove_status_message( $activate_button, fade_in_out_speed, 2000 ); + + // Set is active message + wppb_add_on_set_status_message( $activate_button, 'dashicons-yes', jQuery('#wppb-add-on-is-active-message-text').html(), fade_in_out_speed, 2000 + fade_in_out_speed ); + }); +} + + + +/* + * Function that deactivates the add-on + */ +function wppb_add_on_deactivate( $button ) { + + var fade_in_out_speed = 300; + var plugin = $button.attr('href'); + var add_on_index = $button.parents('.wppb-add-on').index('.wppb-add-on'); + var nonce = $button.data('nonce'); + + $button + .removeClass('wppb-add-on-deactivate') + .attr('disabled', true); + + $spinner = $button.siblings('.spinner'); + + $spinner.animate({ + opacity: 0.7 + }, 100); + + // Remove the current displayed message + wppb_add_on_remove_status_message( $button, fade_in_out_speed ); + + jQuery.post( ajaxurl, { action: 'wppb_add_on_deactivate', wppb_add_on_to_deactivate: plugin, wppb_add_on_index: add_on_index, nonce: nonce }, function( response ) { + + add_on_index = response; + + $button = jQuery('.wppb-add-on').eq( add_on_index ).find('.button'); + + $button + .blur() + .removeClass('wppb-add-on-is-active') + .addClass('wppb-add-on-activate') + .attr( 'disabled', false ) + .text( jQuery('#wppb-add-on-activate-button-text').text() ); + + $spinner = $button.siblings('.spinner'); + + $spinner.animate({ + opacity: 0 + }, 0); + + // Set status confirmation message + wppb_add_on_set_status_message( $button, 'dashicons-yes', jQuery('#wppb-add-on-deactivated-message-text').text(), fade_in_out_speed, 0, true ); + wppb_add_on_remove_status_message( $button, fade_in_out_speed, 2000 ); + + // Set is active message + wppb_add_on_set_status_message( $button, 'dashicons-no-alt', jQuery('#wppb-add-on-is-not-active-message-text').html(), fade_in_out_speed, 2000 + fade_in_out_speed ); + + }); +} + + +/* + * Function used to remove the status message of an add-on + * + * @param object $button - The jQuery object of the add-on box button that was pressed + * @param int fade_in_out_speed - The speed of the fade in and out animations + * @param int delay - Delay removing of the message + * + */ +function wppb_add_on_remove_status_message( $button, fade_in_out_speed, delay ) { + + if( typeof( delay ) == 'undefined' ) { + delay = 0; + } + + setTimeout( function() { + + $button.siblings('.dashicons') + .animate({ + opacity: 0 + }, fade_in_out_speed ); + + $button.siblings('.wppb-add-on-message') + .animate({ + opacity: 0 + }, fade_in_out_speed ); + + }, delay); + +} + +/* + * Function used to remove the status message of an add-on + * + * @param object $button - The jQuery object of the add-on box button that was pressed + * @param string message_icon_class - The string name of the class we want the icon to have + * @param string message_text - The text we want the user to see + * @param int fade_in_out_speed - The speed of the fade in and out animations + * @param bool success - If true adds a class to style the message as a success one, if false adds a class to style the message as a failure + * + */ +function wppb_add_on_set_status_message( $button, message_icon_class, message_text, fade_in_out_speed, delay, success ) { + + if( typeof( delay ) == 'undefined' ) { + delay = 0; + } + + setTimeout(function() { + + $button.siblings('.dashicons') + .css('opacity', 0) + .attr('class', 'dashicons') + .addClass( message_icon_class ) + .animate({ opacity: 1}, fade_in_out_speed); + + $button.siblings('.wppb-add-on-message') + .css('opacity', 0) + .attr( 'class', 'wppb-add-on-message' ) + .html( message_text ) + .animate({ opacity: 1}, fade_in_out_speed); + + if( typeof( success ) != 'undefined' ) { + if( success == true ) { + $button.siblings('.dashicons') + .addClass('wppb-confirmation-success'); + $button.siblings('.wppb-add-on-message') + .addClass('wppb-confirmation-success'); + } else if( success == false ) { + $button.siblings('.dashicons') + .addClass('wppb-confirmation-error'); + $button.siblings('.wppb-add-on-message') + .addClass('wppb-confirmation-error'); + } + } + + }, delay ); + } \ No newline at end of file diff --git a/profile-builder/assets/js/jquery-pb-sitewide.js b/profile-builder/assets/js/jquery-pb-sitewide.js index 145d03f..459c902 100644 --- a/profile-builder/assets/js/jquery-pb-sitewide.js +++ b/profile-builder/assets/js/jquery-pb-sitewide.js @@ -1,133 +1,133 @@ -/** - * Add a negative letter spacing to Profile Builder email customizer menus. - */ - -jQuery( document ).ready(function(){ - jQuery('li a[href$="admin-email-customizer"]').css("letter-spacing", "-0.7px"); - jQuery('li a[href$="user-email-customizer"]').css("letter-spacing", "-0.7px"); -}); - -/* - * Set the width of the shortcode input based on an element that - * has the width of its contents - */ -function setShortcodeInputWidth( $inputField ) { - var tempSpan = document.createElement('span'); - tempSpan.className = "wppb-shortcode-temp"; - tempSpan.innerHTML = $inputField.val(); - document.body.appendChild(tempSpan); - var tempWidth = tempSpan.scrollWidth; - document.body.removeChild(tempSpan); - - $inputField.outerWidth( tempWidth ); -} - -jQuery( document ).ready( function() { - - jQuery('.wppb-shortcode.input').each( function() { - setShortcodeInputWidth( jQuery(this) ); - }); - - jQuery('.wppb-shortcode.textarea').each( function() { - jQuery(this).outerHeight( jQuery(this)[0].scrollHeight + parseInt( jQuery(this).css('border-top-width') ) * 2 ); - }); - - jQuery('.wppb-shortcode').click( function() { - this.select(); - }); -}); - - -/* make sure that we don;t leave the page without having a title in the Post Title field, otherwise we loose data */ -jQuery( function(){ - if( jQuery( 'body').hasClass('post-new-php') ){ - - if( jQuery( 'body').hasClass('post-type-wppb-rf-cpt') || jQuery( 'body').hasClass('post-type-wppb-epf-cpt') || jQuery( 'body').hasClass('post-type-wppb-ul-cpt') ){ - - if( jQuery('#title').val() == '' ){ - jQuery(window).bind('beforeunload',function() { - return "This page is asking you to confirm that you want to leave - data you have entered may not be saved"; - }); - } - - /* remove beforeunload event when entering a title or pressing the puclish button */ - jQuery( '#title').keypress(function() { - jQuery(window).unbind('beforeunload'); - }); - jQuery( '#publish').click( function() { - jQuery(window).unbind('beforeunload'); - }); - } - } -}); - - -/* show hide fields based on selected options */ -jQuery( function(){ - jQuery( '#wppb-rf-settings-args').on('change', '#redirect', function(){ - if( jQuery(this).val() == 'Yes' ){ - jQuery( '.row-url, .row-display-messages', jQuery(this).parent().parent().parent()).show(); - } - else{ - jQuery( '.row-url, .row-display-messages', jQuery(this).parent().parent().parent()).hide(); - } - }); - - jQuery( '#wppb-epf-settings-args').on('change', '#redirect', function(){ - if( jQuery(this).val() == 'Yes' ){ - jQuery( '.row-url, .row-display-messages', jQuery(this).parent().parent().parent()).show(); - } - else{ - jQuery( '.row-url, .row-display-messages', jQuery(this).parent().parent().parent()).hide(); - } - }); - - - jQuery( '#wppb-ul-settings-args').on('click', '#visible-only-to-logged-in-users_yes', function(){ - jQuery( '.row-visible-to-following-roles', jQuery(this).parent().parent().parent().parent().parent().parent()).toggle(); - }); - - jQuery( '#wppb-ul-faceted-args').on('change', '#facet-type', function(){ - if( jQuery(this).val() == 'checkboxes' ){ - jQuery( '.row-facet-behaviour, .row-facet-limit', jQuery(this).parent().parent().parent()).show(); - } - else{ - jQuery( '.row-facet-behaviour, .row-facet-limit', jQuery(this).parent().parent().parent()).hide(); - jQuery( '.row-facet-behaviour #facet-behaviour', jQuery(this).parent().parent().parent()).val('narrow'); - } - if( jQuery(this).val() == 'search' ){ - jQuery( '#wppb-ul-faceted-args .row-facet-meta #facet-meta option[value="billing_country"] ').hide(); - jQuery( '#wppb-ul-faceted-args .row-facet-meta #facet-meta option[value="shipping_country"] ').hide(); - jQuery( '#wppb-ul-faceted-args .row-facet-meta #facet-meta option[value="billing_state"] ').hide(); - jQuery( '#wppb-ul-faceted-args .row-facet-meta #facet-meta option[value="shipping_state"] ').hide(); - } - else { - jQuery( '#wppb-ul-faceted-args .row-facet-meta #facet-meta option[value="billing_country"] ').show(); - jQuery( '#wppb-ul-faceted-args .row-facet-meta #facet-meta option[value="shipping_country"] ').show(); - jQuery( '#wppb-ul-faceted-args .row-facet-meta #facet-meta option[value="billing_state"] ').show(); - jQuery( '#wppb-ul-faceted-args .row-facet-meta #facet-meta option[value="shipping_state"] ').show() - } - - }); - -}); - -/* - * Dialog boxes throughout Profile Builder - */ -jQuery( function() { - if ( jQuery.fn.dialog ) { - jQuery('.wppb-modal-box').dialog({ - autoOpen: false, - modal: true, - draggable: false, - minWidth: 450, - minHeight: 450 - }); - - jQuery('.wppb-open-modal-box').click(function (e) { - e.preventDefault(); - jQuery('#' + jQuery(this).attr('href')).dialog('open'); - }); - } -}); +/** + * Add a negative letter spacing to Profile Builder email customizer menus. + */ + +jQuery( document ).ready(function(){ + jQuery('li a[href$="admin-email-customizer"]').css("letter-spacing", "-0.7px"); + jQuery('li a[href$="user-email-customizer"]').css("letter-spacing", "-0.7px"); +}); + +/* + * Set the width of the shortcode input based on an element that + * has the width of its contents + */ +function setShortcodeInputWidth( $inputField ) { + var tempSpan = document.createElement('span'); + tempSpan.className = "wppb-shortcode-temp"; + tempSpan.innerHTML = $inputField.val(); + document.body.appendChild(tempSpan); + var tempWidth = tempSpan.scrollWidth; + document.body.removeChild(tempSpan); + + $inputField.outerWidth( tempWidth ); +} + +jQuery( document ).ready( function() { + + jQuery('.wppb-shortcode.input').each( function() { + setShortcodeInputWidth( jQuery(this) ); + }); + + jQuery('.wppb-shortcode.textarea').each( function() { + jQuery(this).outerHeight( jQuery(this)[0].scrollHeight + parseInt( jQuery(this).css('border-top-width') ) * 2 ); + }); + + jQuery('.wppb-shortcode').click( function() { + this.select(); + }); +}); + + +/* make sure that we don;t leave the page without having a title in the Post Title field, otherwise we loose data */ +jQuery( function(){ + if( jQuery( 'body').hasClass('post-new-php') ){ + + if( jQuery( 'body').hasClass('post-type-wppb-rf-cpt') || jQuery( 'body').hasClass('post-type-wppb-epf-cpt') || jQuery( 'body').hasClass('post-type-wppb-ul-cpt') ){ + + if( jQuery('#title').val() == '' ){ + jQuery(window).bind('beforeunload',function() { + return "This page is asking you to confirm that you want to leave - data you have entered may not be saved"; + }); + } + + /* remove beforeunload event when entering a title or pressing the puclish button */ + jQuery( '#title').keypress(function() { + jQuery(window).unbind('beforeunload'); + }); + jQuery( '#publish').click( function() { + jQuery(window).unbind('beforeunload'); + }); + } + } +}); + + +/* show hide fields based on selected options */ +jQuery( function(){ + jQuery( '#wppb-rf-settings-args').on('change', '#redirect', function(){ + if( jQuery(this).val() == 'Yes' ){ + jQuery( '.row-url, .row-display-messages', jQuery(this).parent().parent().parent()).show(); + } + else{ + jQuery( '.row-url, .row-display-messages', jQuery(this).parent().parent().parent()).hide(); + } + }); + + jQuery( '#wppb-epf-settings-args').on('change', '#redirect', function(){ + if( jQuery(this).val() == 'Yes' ){ + jQuery( '.row-url, .row-display-messages', jQuery(this).parent().parent().parent()).show(); + } + else{ + jQuery( '.row-url, .row-display-messages', jQuery(this).parent().parent().parent()).hide(); + } + }); + + + jQuery( '#wppb-ul-settings-args').on('click', '#visible-only-to-logged-in-users_yes', function(){ + jQuery( '.row-visible-to-following-roles', jQuery(this).parent().parent().parent().parent().parent().parent()).toggle(); + }); + + jQuery( '#wppb-ul-faceted-args').on('change', '#facet-type', function(){ + if( jQuery(this).val() == 'checkboxes' ){ + jQuery( '.row-facet-behaviour, .row-facet-limit', jQuery(this).parent().parent().parent()).show(); + } + else{ + jQuery( '.row-facet-behaviour, .row-facet-limit', jQuery(this).parent().parent().parent()).hide(); + jQuery( '.row-facet-behaviour #facet-behaviour', jQuery(this).parent().parent().parent()).val('narrow'); + } + if( jQuery(this).val() == 'search' ){ + jQuery( '#wppb-ul-faceted-args .row-facet-meta #facet-meta option[value="billing_country"] ').hide(); + jQuery( '#wppb-ul-faceted-args .row-facet-meta #facet-meta option[value="shipping_country"] ').hide(); + jQuery( '#wppb-ul-faceted-args .row-facet-meta #facet-meta option[value="billing_state"] ').hide(); + jQuery( '#wppb-ul-faceted-args .row-facet-meta #facet-meta option[value="shipping_state"] ').hide(); + } + else { + jQuery( '#wppb-ul-faceted-args .row-facet-meta #facet-meta option[value="billing_country"] ').show(); + jQuery( '#wppb-ul-faceted-args .row-facet-meta #facet-meta option[value="shipping_country"] ').show(); + jQuery( '#wppb-ul-faceted-args .row-facet-meta #facet-meta option[value="billing_state"] ').show(); + jQuery( '#wppb-ul-faceted-args .row-facet-meta #facet-meta option[value="shipping_state"] ').show() + } + + }); + +}); + +/* + * Dialog boxes throughout Profile Builder + */ +jQuery( function() { + if ( jQuery.fn.dialog ) { + jQuery('.wppb-modal-box').dialog({ + autoOpen: false, + modal: true, + draggable: false, + minWidth: 450, + minHeight: 450 + }); + + jQuery('.wppb-open-modal-box').click(function (e) { + e.preventDefault(); + jQuery('#' + jQuery(this).attr('href')).dialog('open'); + }); + } +}); diff --git a/profile-builder/assets/js/select2/i18n/ar.js b/profile-builder/assets/js/select2/i18n/ar.js index 01a6882..fcf8c4d 100644 --- a/profile-builder/assets/js/select2/i18n/ar.js +++ b/profile-builder/assets/js/select2/i18n/ar.js @@ -1,3 +1,3 @@ -/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ - +/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ + (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/ar",[],function(){return{errorLoading:function(){return"لا يمكن تحميل النتائج"},inputTooLong:function(e){var t=e.input.length-e.maximum,n="الرجاء حذف "+t+" عناصر";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="الرجاء إضافة "+t+" عناصر";return n},loadingMore:function(){return"جاري تحميل نتائج إضافية..."},maximumSelected:function(e){var t="تستطيع إختيار "+e.maximum+" بنود فقط";return t},noResults:function(){return"لم يتم العثور على أي نتائج"},searching:function(){return"جاري البحث…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/profile-builder/assets/js/select2/i18n/az.js b/profile-builder/assets/js/select2/i18n/az.js index 2accb97..81bc81a 100644 --- a/profile-builder/assets/js/select2/i18n/az.js +++ b/profile-builder/assets/js/select2/i18n/az.js @@ -1,3 +1,3 @@ -/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ - +/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ + (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/az",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum;return t+" simvol silin"},inputTooShort:function(e){var t=e.minimum-e.input.length;return t+" simvol daxil edin"},loadingMore:function(){return"Daha çox nəticə yüklənir…"},maximumSelected:function(e){return"Sadəcə "+e.maximum+" element seçə bilərsiniz"},noResults:function(){return"Nəticə tapılmadı"},searching:function(){return"Axtarılır…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/profile-builder/assets/js/select2/i18n/bg.js b/profile-builder/assets/js/select2/i18n/bg.js index 35ae989..07a0956 100644 --- a/profile-builder/assets/js/select2/i18n/bg.js +++ b/profile-builder/assets/js/select2/i18n/bg.js @@ -1,3 +1,3 @@ -/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ - +/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ + (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/bg",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n="Моля въведете с "+t+" по-малко символ";return t>1&&(n+="a"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Моля въведете още "+t+" символ";return t>1&&(n+="a"),n},loadingMore:function(){return"Зареждат се още…"},maximumSelected:function(e){var t="Можете да направите до "+e.maximum+" ";return e.maximum>1?t+="избора":t+="избор",t},noResults:function(){return"Няма намерени съвпадения"},searching:function(){return"Търсене…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/profile-builder/assets/js/select2/i18n/ca.js b/profile-builder/assets/js/select2/i18n/ca.js index fdb5f3d..cd854e3 100644 --- a/profile-builder/assets/js/select2/i18n/ca.js +++ b/profile-builder/assets/js/select2/i18n/ca.js @@ -1,3 +1,3 @@ -/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ - +/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ + (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/ca",[],function(){return{errorLoading:function(){return"La càrrega ha fallat"},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Si us plau, elimina "+t+" car";return t==1?n+="àcter":n+="àcters",n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Si us plau, introdueix "+t+" car";return t==1?n+="àcter":n+="àcters",n},loadingMore:function(){return"Carregant més resultats…"},maximumSelected:function(e){var t="Només es pot seleccionar "+e.maximum+" element";return e.maximum!=1&&(t+="s"),t},noResults:function(){return"No s'han trobat resultats"},searching:function(){return"Cercant…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/profile-builder/assets/js/select2/i18n/cs.js b/profile-builder/assets/js/select2/i18n/cs.js index 9651378..6f139d7 100644 --- a/profile-builder/assets/js/select2/i18n/cs.js +++ b/profile-builder/assets/js/select2/i18n/cs.js @@ -1,3 +1,3 @@ -/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ - +/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ + (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/cs",[],function(){function e(e,t){switch(e){case 2:return t?"dva":"dvě";case 3:return"tři";case 4:return"čtyři"}return""}return{errorLoading:function(){return"Výsledky nemohly být načteny."},inputTooLong:function(t){var n=t.input.length-t.maximum;return n==1?"Prosím zadejte o jeden znak méně":n<=4?"Prosím zadejte o "+e(n,!0)+" znaky méně":"Prosím zadejte o "+n+" znaků méně"},inputTooShort:function(t){var n=t.minimum-t.input.length;return n==1?"Prosím zadejte ještě jeden znak":n<=4?"Prosím zadejte ještě další "+e(n,!0)+" znaky":"Prosím zadejte ještě dalších "+n+" znaků"},loadingMore:function(){return"Načítají se další výsledky…"},maximumSelected:function(t){var n=t.maximum;return n==1?"Můžete zvolit jen jednu položku":n<=4?"Můžete zvolit maximálně "+e(n,!1)+" položky":"Můžete zvolit maximálně "+n+" položek"},noResults:function(){return"Nenalezeny žádné položky"},searching:function(){return"Vyhledávání…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/profile-builder/assets/js/select2/i18n/da.js b/profile-builder/assets/js/select2/i18n/da.js index 501c51e..112eaaf 100644 --- a/profile-builder/assets/js/select2/i18n/da.js +++ b/profile-builder/assets/js/select2/i18n/da.js @@ -1,3 +1,3 @@ -/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ - +/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ + (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/da",[],function(){return{errorLoading:function(){return"Resultaterne kunne ikke indlæses."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Angiv venligst "+t+" tegn mindre";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Angiv venligst "+t+" tegn mere";return n},loadingMore:function(){return"Indlæser flere resultater…"},maximumSelected:function(e){var t="Du kan kun vælge "+e.maximum+" emne";return e.maximum!=1&&(t+="r"),t},noResults:function(){return"Ingen resultater fundet"},searching:function(){return"Søger…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/profile-builder/assets/js/select2/i18n/de.js b/profile-builder/assets/js/select2/i18n/de.js index 9a6d553..7e6e944 100644 --- a/profile-builder/assets/js/select2/i18n/de.js +++ b/profile-builder/assets/js/select2/i18n/de.js @@ -1,3 +1,3 @@ -/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ - +/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ + (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/de",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum;return"Bitte "+t+" Zeichen weniger eingeben"},inputTooShort:function(e){var t=e.minimum-e.input.length;return"Bitte "+t+" Zeichen mehr eingeben"},loadingMore:function(){return"Lade mehr Ergebnisse…"},maximumSelected:function(e){var t="Sie können nur "+e.maximum+" Eintr";return e.maximum===1?t+="ag":t+="äge",t+=" auswählen",t},noResults:function(){return"Keine Übereinstimmungen gefunden"},searching:function(){return"Suche…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/profile-builder/assets/js/select2/i18n/el.js b/profile-builder/assets/js/select2/i18n/el.js index 4735d14..9440588 100644 --- a/profile-builder/assets/js/select2/i18n/el.js +++ b/profile-builder/assets/js/select2/i18n/el.js @@ -1,3 +1,3 @@ -/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ - +/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ + (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/el",[],function(){return{errorLoading:function(){return"Τα αποτελέσματα δεν μπόρεσαν να φορτώσουν."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Παρακαλώ διαγράψτε "+t+" χαρακτήρ";return t==1&&(n+="α"),t!=1&&(n+="ες"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Παρακαλώ συμπληρώστε "+t+" ή περισσότερους χαρακτήρες";return n},loadingMore:function(){return"Φόρτωση περισσότερων αποτελεσμάτων…"},maximumSelected:function(e){var t="Μπορείτε να επιλέξετε μόνο "+e.maximum+" επιλογ";return e.maximum==1&&(t+="ή"),e.maximum!=1&&(t+="ές"),t},noResults:function(){return"Δεν βρέθηκαν αποτελέσματα"},searching:function(){return"Αναζήτηση…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/profile-builder/assets/js/select2/i18n/en.js b/profile-builder/assets/js/select2/i18n/en.js index 8e80ede..2dd1790 100644 --- a/profile-builder/assets/js/select2/i18n/en.js +++ b/profile-builder/assets/js/select2/i18n/en.js @@ -1,3 +1,3 @@ -/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ - +/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ + (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/en",[],function(){return{errorLoading:function(){return"The results could not be loaded."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Please delete "+t+" character";return t!=1&&(n+="s"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Please enter "+t+" or more characters";return n},loadingMore:function(){return"Loading more results…"},maximumSelected:function(e){var t="You can only select "+e.maximum+" item";return e.maximum!=1&&(t+="s"),t},noResults:function(){return"No results found"},searching:function(){return"Searching…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/profile-builder/assets/js/select2/i18n/es.js b/profile-builder/assets/js/select2/i18n/es.js index 0a09650..677a7c0 100644 --- a/profile-builder/assets/js/select2/i18n/es.js +++ b/profile-builder/assets/js/select2/i18n/es.js @@ -1,3 +1,3 @@ -/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ - +/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ + (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/es",[],function(){return{errorLoading:function(){return"La carga falló"},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Por favor, elimine "+t+" car";return t==1?n+="ácter":n+="acteres",n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Por favor, introduzca "+t+" car";return t==1?n+="ácter":n+="acteres",n},loadingMore:function(){return"Cargando más resultados…"},maximumSelected:function(e){var t="Sólo puede seleccionar "+e.maximum+" elemento";return e.maximum!=1&&(t+="s"),t},noResults:function(){return"No se encontraron resultados"},searching:function(){return"Buscando…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/profile-builder/assets/js/select2/i18n/et.js b/profile-builder/assets/js/select2/i18n/et.js index c70f4a5..fbe61bd 100644 --- a/profile-builder/assets/js/select2/i18n/et.js +++ b/profile-builder/assets/js/select2/i18n/et.js @@ -1,3 +1,3 @@ -/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ - +/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ + (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/et",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n="Sisesta "+t+" täht";return t!=1&&(n+="e"),n+=" vähem",n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Sisesta "+t+" täht";return t!=1&&(n+="e"),n+=" rohkem",n},loadingMore:function(){return"Laen tulemusi…"},maximumSelected:function(e){var t="Saad vaid "+e.maximum+" tulemus";return e.maximum==1?t+="e":t+="t",t+=" valida",t},noResults:function(){return"Tulemused puuduvad"},searching:function(){return"Otsin…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/profile-builder/assets/js/select2/i18n/eu.js b/profile-builder/assets/js/select2/i18n/eu.js index 9336053..08703d9 100644 --- a/profile-builder/assets/js/select2/i18n/eu.js +++ b/profile-builder/assets/js/select2/i18n/eu.js @@ -1,3 +1,3 @@ -/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ - +/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ + (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/eu",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n="Idatzi ";return t==1?n+="karaktere bat":n+=t+" karaktere",n+=" gutxiago",n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Idatzi ";return t==1?n+="karaktere bat":n+=t+" karaktere",n+=" gehiago",n},loadingMore:function(){return"Emaitza gehiago kargatzen…"},maximumSelected:function(e){return e.maximum===1?"Elementu bakarra hauta dezakezu":e.maximum+" elementu hauta ditzakezu soilik"},noResults:function(){return"Ez da bat datorrenik aurkitu"},searching:function(){return"Bilatzen…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/profile-builder/assets/js/select2/i18n/fa.js b/profile-builder/assets/js/select2/i18n/fa.js index 5118cd2..a516fd7 100644 --- a/profile-builder/assets/js/select2/i18n/fa.js +++ b/profile-builder/assets/js/select2/i18n/fa.js @@ -1,3 +1,3 @@ -/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ - +/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ + (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/fa",[],function(){return{errorLoading:function(){return"امکان بارگذاری نتایج وجود ندارد."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="لطفاً "+t+" کاراکتر را حذف نمایید";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="لطفاً تعداد "+t+" کاراکتر یا بیشتر وارد نمایید";return n},loadingMore:function(){return"در حال بارگذاری نتایج بیشتر..."},maximumSelected:function(e){var t="شما تنها می‌توانید "+e.maximum+" آیتم را انتخاب نمایید";return t},noResults:function(){return"هیچ نتیجه‌ای یافت نشد"},searching:function(){return"در حال جستجو..."}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/profile-builder/assets/js/select2/i18n/fi.js b/profile-builder/assets/js/select2/i18n/fi.js index 9e60f26..5f25d4e 100644 --- a/profile-builder/assets/js/select2/i18n/fi.js +++ b/profile-builder/assets/js/select2/i18n/fi.js @@ -1,3 +1,3 @@ -/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ - +/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ + (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/fi",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum;return"Ole hyvä ja anna "+t+" merkkiä vähemmän"},inputTooShort:function(e){var t=e.minimum-e.input.length;return"Ole hyvä ja anna "+t+" merkkiä lisää"},loadingMore:function(){return"Ladataan lisää tuloksia…"},maximumSelected:function(e){return"Voit valita ainoastaan "+e.maximum+" kpl"},noResults:function(){return"Ei tuloksia"},searching:function(){}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/profile-builder/assets/js/select2/i18n/fr.js b/profile-builder/assets/js/select2/i18n/fr.js index e4a6650..520f30f 100644 --- a/profile-builder/assets/js/select2/i18n/fr.js +++ b/profile-builder/assets/js/select2/i18n/fr.js @@ -1,3 +1,3 @@ -/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ - +/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ + (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/fr",[],function(){return{errorLoading:function(){return"Les résultats ne peuvent pas être chargés."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Supprimez "+t+" caractère";return t!==1&&(n+="s"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Saisissez "+t+" caractère";return t!==1&&(n+="s"),n},loadingMore:function(){return"Chargement de résultats supplémentaires…"},maximumSelected:function(e){var t="Vous pouvez seulement sélectionner "+e.maximum+" élément";return e.maximum!==1&&(t+="s"),t},noResults:function(){return"Aucun résultat trouvé"},searching:function(){return"Recherche en cours…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/profile-builder/assets/js/select2/i18n/gl.js b/profile-builder/assets/js/select2/i18n/gl.js index 02f258f..35c6a98 100644 --- a/profile-builder/assets/js/select2/i18n/gl.js +++ b/profile-builder/assets/js/select2/i18n/gl.js @@ -1,3 +1,3 @@ -/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ - +/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ + (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/gl",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n="Elimine ";return t===1?n+="un carácter":n+=t+" caracteres",n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Engada ";return t===1?n+="un carácter":n+=t+" caracteres",n},loadingMore:function(){return"Cargando máis resultados…"},maximumSelected:function(e){var t="Só pode ";return e.maximum===1?t+="un elemento":t+=e.maximum+" elementos",t},noResults:function(){return"Non se atoparon resultados"},searching:function(){return"Buscando…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/profile-builder/assets/js/select2/i18n/he.js b/profile-builder/assets/js/select2/i18n/he.js index 881f8d3..6c958c9 100644 --- a/profile-builder/assets/js/select2/i18n/he.js +++ b/profile-builder/assets/js/select2/i18n/he.js @@ -1,3 +1,3 @@ -/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ - +/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ + (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/he",[],function(){return{errorLoading:function(){return"שגיאה בטעינת התוצאות"},inputTooLong:function(e){var t=e.input.length-e.maximum,n="נא למחוק ";return t===1?n+="תו אחד":n+=t+" תווים",n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="נא להכניס ";return t===1?n+="תו אחד":n+=t+" תווים",n+=" או יותר",n},loadingMore:function(){return"טוען תוצאות נוספות…"},maximumSelected:function(e){var t="באפשרותך לבחור עד ";return e.maximum===1?t+="פריט אחד":t+=e.maximum+" פריטים",t},noResults:function(){return"לא נמצאו תוצאות"},searching:function(){return"מחפש…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/profile-builder/assets/js/select2/i18n/hi.js b/profile-builder/assets/js/select2/i18n/hi.js index e829684..6a2096e 100644 --- a/profile-builder/assets/js/select2/i18n/hi.js +++ b/profile-builder/assets/js/select2/i18n/hi.js @@ -1,3 +1,3 @@ -/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ - +/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ + (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/hi",[],function(){return{errorLoading:function(){return"परिणामों को लोड नहीं किया जा सका।"},inputTooLong:function(e){var t=e.input.length-e.maximum,n=t+" अक्षर को हटा दें";return t>1&&(n=t+" अक्षरों को हटा दें "),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="कृपया "+t+" या अधिक अक्षर दर्ज करें";return n},loadingMore:function(){return"अधिक परिणाम लोड हो रहे है..."},maximumSelected:function(e){var t="आप केवल "+e.maximum+" आइटम का चयन कर सकते हैं";return t},noResults:function(){return"कोई परिणाम नहीं मिला"},searching:function(){return"खोज रहा है..."}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/profile-builder/assets/js/select2/i18n/hr.js b/profile-builder/assets/js/select2/i18n/hr.js index 89f7b12..6606445 100644 --- a/profile-builder/assets/js/select2/i18n/hr.js +++ b/profile-builder/assets/js/select2/i18n/hr.js @@ -1,3 +1,3 @@ -/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ - +/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ + (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/hr",[],function(){function e(e){var t=" "+e+" znak";return e%10<5&&e%10>0&&(e%100<5||e%100>19)?e%10>1&&(t+="a"):t+="ova",t}return{errorLoading:function(){return"Preuzimanje nije uspjelo."},inputTooLong:function(t){var n=t.input.length-t.maximum;return"Unesite "+e(n)},inputTooShort:function(t){var n=t.minimum-t.input.length;return"Unesite još "+e(n)},loadingMore:function(){return"Učitavanje rezultata…"},maximumSelected:function(e){return"Maksimalan broj odabranih stavki je "+e.maximum},noResults:function(){return"Nema rezultata"},searching:function(){return"Pretraga…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/profile-builder/assets/js/select2/i18n/hu.js b/profile-builder/assets/js/select2/i18n/hu.js index 74c8a90..fec1e0a 100644 --- a/profile-builder/assets/js/select2/i18n/hu.js +++ b/profile-builder/assets/js/select2/i18n/hu.js @@ -1,3 +1,3 @@ -/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ - +/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ + (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/hu",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum;return"Túl hosszú. "+t+" karakterrel több, mint kellene."},inputTooShort:function(e){var t=e.minimum-e.input.length;return"Túl rövid. Még "+t+" karakter hiányzik."},loadingMore:function(){return"Töltés…"},maximumSelected:function(e){return"Csak "+e.maximum+" elemet lehet kiválasztani."},noResults:function(){return"Nincs találat."},searching:function(){return"Keresés…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/profile-builder/assets/js/select2/i18n/id.js b/profile-builder/assets/js/select2/i18n/id.js index 9586782..d5fa650 100644 --- a/profile-builder/assets/js/select2/i18n/id.js +++ b/profile-builder/assets/js/select2/i18n/id.js @@ -1,3 +1,3 @@ -/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ - +/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ + (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/id",[],function(){return{errorLoading:function(){return"Data tidak boleh diambil."},inputTooLong:function(e){var t=e.input.length-e.maximum;return"Hapuskan "+t+" huruf"},inputTooShort:function(e){var t=e.minimum-e.input.length;return"Masukkan "+t+" huruf lagi"},loadingMore:function(){return"Mengambil data…"},maximumSelected:function(e){return"Anda hanya dapat memilih "+e.maximum+" pilihan"},noResults:function(){return"Tidak ada data yang sesuai"},searching:function(){return"Mencari…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/profile-builder/assets/js/select2/i18n/is.js b/profile-builder/assets/js/select2/i18n/is.js index ab97a14..5266e42 100644 --- a/profile-builder/assets/js/select2/i18n/is.js +++ b/profile-builder/assets/js/select2/i18n/is.js @@ -1,3 +1,3 @@ -/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ - +/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ + (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/is",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n="Vinsamlegast styttið texta um "+t+" staf";return t<=1?n:n+"i"},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Vinsamlegast skrifið "+t+" staf";return t>1&&(n+="i"),n+=" í viðbót",n},loadingMore:function(){return"Sæki fleiri niðurstöður…"},maximumSelected:function(e){return"Þú getur aðeins valið "+e.maximum+" atriði"},noResults:function(){return"Ekkert fannst"},searching:function(){return"Leita…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/profile-builder/assets/js/select2/i18n/it.js b/profile-builder/assets/js/select2/i18n/it.js index 7796b9f..42c8c31 100644 --- a/profile-builder/assets/js/select2/i18n/it.js +++ b/profile-builder/assets/js/select2/i18n/it.js @@ -1,3 +1,3 @@ -/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ - +/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ + (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/it",[],function(){return{errorLoading:function(){return"I risultati non possono essere caricati."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Per favore cancella "+t+" caratter";return t!==1?n+="i":n+="e",n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Per favore inserisci "+t+" o più caratteri";return n},loadingMore:function(){return"Caricando più risultati…"},maximumSelected:function(e){var t="Puoi selezionare solo "+e.maximum+" element";return e.maximum!==1?t+="i":t+="o",t},noResults:function(){return"Nessun risultato trovato"},searching:function(){return"Sto cercando…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/profile-builder/assets/js/select2/i18n/ja.js b/profile-builder/assets/js/select2/i18n/ja.js index 9f4fff6..2e27197 100644 --- a/profile-builder/assets/js/select2/i18n/ja.js +++ b/profile-builder/assets/js/select2/i18n/ja.js @@ -1,3 +1,3 @@ -/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ - +/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ + (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/ja",[],function(){return{errorLoading:function(){return"結果が読み込まれませんでした"},inputTooLong:function(e){var t=e.input.length-e.maximum,n=t+" 文字を削除してください";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="少なくとも "+t+" 文字を入力してください";return n},loadingMore:function(){return"読み込み中…"},maximumSelected:function(e){var t=e.maximum+" 件しか選択できません";return t},noResults:function(){return"対象が見つかりません"},searching:function(){return"検索しています…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/profile-builder/assets/js/select2/i18n/km.js b/profile-builder/assets/js/select2/i18n/km.js index 8e94adc..875b461 100644 --- a/profile-builder/assets/js/select2/i18n/km.js +++ b/profile-builder/assets/js/select2/i18n/km.js @@ -1,3 +1,3 @@ -/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ - +/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ + (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/km",[],function(){return{errorLoading:function(){return"មិនអាចទាញយកទិន្នន័យ"},inputTooLong:function(e){var t=e.input.length-e.maximum,n="សូមលុបចេញ "+t+" អក្សរ";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="សូមបញ្ចូល"+t+" អក្សរ រឺ ច្រើនជាងនេះ";return n},loadingMore:function(){return"កំពុងទាញយកទិន្នន័យបន្ថែម..."},maximumSelected:function(e){var t="អ្នកអាចជ្រើសរើសបានតែ "+e.maximum+" ជម្រើសប៉ុណ្ណោះ";return t},noResults:function(){return"មិនមានលទ្ធផល"},searching:function(){return"កំពុងស្វែងរក..."}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/profile-builder/assets/js/select2/i18n/ko.js b/profile-builder/assets/js/select2/i18n/ko.js index 4ed0321..8bad406 100644 --- a/profile-builder/assets/js/select2/i18n/ko.js +++ b/profile-builder/assets/js/select2/i18n/ko.js @@ -1,3 +1,3 @@ -/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ - +/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ + (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/ko",[],function(){return{errorLoading:function(){return"결과를 불러올 수 없습니다."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="너무 깁니다. "+t+" 글자 지워주세요.";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="너무 짧습니다. "+t+" 글자 더 입력해주세요.";return n},loadingMore:function(){return"불러오는 중…"},maximumSelected:function(e){var t="최대 "+e.maximum+"개까지만 선택 가능합니다.";return t},noResults:function(){return"결과가 없습니다."},searching:function(){return"검색 중…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/profile-builder/assets/js/select2/i18n/lt.js b/profile-builder/assets/js/select2/i18n/lt.js index 05f3a6e..fc83694 100644 --- a/profile-builder/assets/js/select2/i18n/lt.js +++ b/profile-builder/assets/js/select2/i18n/lt.js @@ -1,3 +1,3 @@ -/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ - +/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ + (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/lt",[],function(){function e(e,t,n,r){return e%10===1&&(e%100<11||e%100>19)?t:e%10>=2&&e%10<=9&&(e%100<11||e%100>19)?n:r}return{inputTooLong:function(t){var n=t.input.length-t.maximum,r="Pašalinkite "+n+" simbol";return r+=e(n,"į","ius","ių"),r},inputTooShort:function(t){var n=t.minimum-t.input.length,r="Įrašykite dar "+n+" simbol";return r+=e(n,"į","ius","ių"),r},loadingMore:function(){return"Kraunama daugiau rezultatų…"},maximumSelected:function(t){var n="Jūs galite pasirinkti tik "+t.maximum+" element";return n+=e(t.maximum,"ą","us","ų"),n},noResults:function(){return"Atitikmenų nerasta"},searching:function(){return"Ieškoma…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/profile-builder/assets/js/select2/i18n/lv.js b/profile-builder/assets/js/select2/i18n/lv.js index df8ee94..7746e79 100644 --- a/profile-builder/assets/js/select2/i18n/lv.js +++ b/profile-builder/assets/js/select2/i18n/lv.js @@ -1,3 +1,3 @@ -/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ - +/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ + (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/lv",[],function(){function e(e,t,n,r){return e===11?t:e%10===1?n:r}return{inputTooLong:function(t){var n=t.input.length-t.maximum,r="Lūdzu ievadiet par "+n;return r+=" simbol"+e(n,"iem","u","iem"),r+" mazāk"},inputTooShort:function(t){var n=t.minimum-t.input.length,r="Lūdzu ievadiet vēl "+n;return r+=" simbol"+e(n,"us","u","us"),r},loadingMore:function(){return"Datu ielāde…"},maximumSelected:function(t){var n="Jūs varat izvēlēties ne vairāk kā "+t.maximum;return n+=" element"+e(t.maximum,"us","u","us"),n},noResults:function(){return"Sakritību nav"},searching:function(){return"Meklēšana…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/profile-builder/assets/js/select2/i18n/mk.js b/profile-builder/assets/js/select2/i18n/mk.js index 319ecca..58ae6ad 100644 --- a/profile-builder/assets/js/select2/i18n/mk.js +++ b/profile-builder/assets/js/select2/i18n/mk.js @@ -1,3 +1,3 @@ -/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ - +/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ + (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/mk",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n="Ве молиме внесете "+e.maximum+" помалку карактер";return e.maximum!==1&&(n+="и"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Ве молиме внесете уште "+e.maximum+" карактер";return e.maximum!==1&&(n+="и"),n},loadingMore:function(){return"Вчитување резултати…"},maximumSelected:function(e){var t="Можете да изберете само "+e.maximum+" ставк";return e.maximum===1?t+="а":t+="и",t},noResults:function(){return"Нема пронајдено совпаѓања"},searching:function(){return"Пребарување…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/profile-builder/assets/js/select2/i18n/ms.js b/profile-builder/assets/js/select2/i18n/ms.js index 4258f12..8323d55 100644 --- a/profile-builder/assets/js/select2/i18n/ms.js +++ b/profile-builder/assets/js/select2/i18n/ms.js @@ -1,3 +1,3 @@ -/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ - +/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ + (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/ms",[],function(){return{errorLoading:function(){return"Keputusan tidak berjaya dimuatkan."},inputTooLong:function(e){var t=e.input.length-e.maximum;return"Sila hapuskan "+t+" aksara"},inputTooShort:function(e){var t=e.minimum-e.input.length;return"Sila masukkan "+t+" atau lebih aksara"},loadingMore:function(){return"Sedang memuatkan keputusan…"},maximumSelected:function(e){return"Anda hanya boleh memilih "+e.maximum+" pilihan"},noResults:function(){return"Tiada padanan yang ditemui"},searching:function(){return"Mencari…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/profile-builder/assets/js/select2/i18n/nb.js b/profile-builder/assets/js/select2/i18n/nb.js index 6770087..1c4e333 100644 --- a/profile-builder/assets/js/select2/i18n/nb.js +++ b/profile-builder/assets/js/select2/i18n/nb.js @@ -1,3 +1,3 @@ -/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ - +/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ + (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/nb",[],function(){return{errorLoading:function(){return"Kunne ikke hente resultater."},inputTooLong:function(e){var t=e.input.length-e.maximum;return"Vennligst fjern "+t+" tegn"},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Vennligst skriv inn ";return t>1?n+=" flere tegn":n+=" tegn til",n},loadingMore:function(){return"Laster flere resultater…"},maximumSelected:function(e){return"Du kan velge maks "+e.maximum+" elementer"},noResults:function(){return"Ingen treff"},searching:function(){return"Søker…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/profile-builder/assets/js/select2/i18n/nl.js b/profile-builder/assets/js/select2/i18n/nl.js index 8bd5e3c..46f987d 100644 --- a/profile-builder/assets/js/select2/i18n/nl.js +++ b/profile-builder/assets/js/select2/i18n/nl.js @@ -1,3 +1,3 @@ -/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ - +/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ + (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/nl",[],function(){return{errorLoading:function(){return"De resultaten konden niet worden geladen."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Gelieve "+t+" karakters te verwijderen";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Gelieve "+t+" of meer karakters in te voeren";return n},loadingMore:function(){return"Meer resultaten laden…"},maximumSelected:function(e){var t=e.maximum==1?"kan":"kunnen",n="Er "+t+" maar "+e.maximum+" item";return e.maximum!=1&&(n+="s"),n+=" worden geselecteerd",n},noResults:function(){return"Geen resultaten gevonden…"},searching:function(){return"Zoeken…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/profile-builder/assets/js/select2/i18n/pl.js b/profile-builder/assets/js/select2/i18n/pl.js index 54ba28e..f2407a1 100644 --- a/profile-builder/assets/js/select2/i18n/pl.js +++ b/profile-builder/assets/js/select2/i18n/pl.js @@ -1,3 +1,3 @@ -/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ - +/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ + (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/pl",[],function(){var e=["znak","znaki","znaków"],t=["element","elementy","elementów"],n=function(t,n){if(t===1)return n[0];if(t>1&&t<=4)return n[1];if(t>=5)return n[2]};return{errorLoading:function(){return"Nie można załadować wyników."},inputTooLong:function(t){var r=t.input.length-t.maximum;return"Usuń "+r+" "+n(r,e)},inputTooShort:function(t){var r=t.minimum-t.input.length;return"Podaj przynajmniej "+r+" "+n(r,e)},loadingMore:function(){return"Trwa ładowanie…"},maximumSelected:function(e){return"Możesz zaznaczyć tylko "+e.maximum+" "+n(e.maximum,t)},noResults:function(){return"Brak wyników"},searching:function(){return"Trwa wyszukiwanie…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/profile-builder/assets/js/select2/i18n/pt-BR.js b/profile-builder/assets/js/select2/i18n/pt-BR.js index a6629c8..3db40b6 100644 --- a/profile-builder/assets/js/select2/i18n/pt-BR.js +++ b/profile-builder/assets/js/select2/i18n/pt-BR.js @@ -1,3 +1,3 @@ -/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ - +/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ + (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/pt-BR",[],function(){return{errorLoading:function(){return"Os resultados não puderam ser carregados."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Apague "+t+" caracter";return t!=1&&(n+="es"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Digite "+t+" ou mais caracteres";return n},loadingMore:function(){return"Carregando mais resultados…"},maximumSelected:function(e){var t="Você só pode selecionar "+e.maximum+" ite";return e.maximum==1?t+="m":t+="ns",t},noResults:function(){return"Nenhum resultado encontrado"},searching:function(){return"Buscando…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/profile-builder/assets/js/select2/i18n/pt.js b/profile-builder/assets/js/select2/i18n/pt.js index 0cbda56..0befe03 100644 --- a/profile-builder/assets/js/select2/i18n/pt.js +++ b/profile-builder/assets/js/select2/i18n/pt.js @@ -1,3 +1,3 @@ -/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ - +/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ + (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/pt",[],function(){return{errorLoading:function(){return"Os resultados não puderam ser carregados."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Por favor apague "+t+" ";return n+=t!=1?"caracteres":"carácter",n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Introduza "+t+" ou mais caracteres";return n},loadingMore:function(){return"A carregar mais resultados…"},maximumSelected:function(e){var t="Apenas pode seleccionar "+e.maximum+" ";return t+=e.maximum!=1?"itens":"item",t},noResults:function(){return"Sem resultados"},searching:function(){return"A procurar…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/profile-builder/assets/js/select2/i18n/ro.js b/profile-builder/assets/js/select2/i18n/ro.js index 788a263..e8ebb35 100644 --- a/profile-builder/assets/js/select2/i18n/ro.js +++ b/profile-builder/assets/js/select2/i18n/ro.js @@ -1,3 +1,3 @@ -/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ - +/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ + (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/ro",[],function(){return{errorLoading:function(){return"Rezultatele nu au putut fi incărcate."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Vă rugăm să ștergeți"+t+" caracter";return t!==1&&(n+="e"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Vă rugăm să introduceți "+t+"sau mai multe caractere";return n},loadingMore:function(){return"Se încarcă mai multe rezultate…"},maximumSelected:function(e){var t="Aveți voie să selectați cel mult "+e.maximum;return t+=" element",e.maximum!==1&&(t+="e"),t},noResults:function(){return"Nu au fost găsite rezultate"},searching:function(){return"Căutare…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/profile-builder/assets/js/select2/i18n/ru.js b/profile-builder/assets/js/select2/i18n/ru.js index 9ecab80..6db6893 100644 --- a/profile-builder/assets/js/select2/i18n/ru.js +++ b/profile-builder/assets/js/select2/i18n/ru.js @@ -1,3 +1,3 @@ -/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ - +/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ + (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/ru",[],function(){function e(e,t,n,r){return e%10<5&&e%10>0&&e%100<5||e%100>20?e%10>1?n:t:r}return{errorLoading:function(){return"Невозможно загрузить результаты"},inputTooLong:function(t){var n=t.input.length-t.maximum,r="Пожалуйста, введите на "+n+" символ";return r+=e(n,"","a","ов"),r+=" меньше",r},inputTooShort:function(t){var n=t.minimum-t.input.length,r="Пожалуйста, введите еще хотя бы "+n+" символ";return r+=e(n,"","a","ов"),r},loadingMore:function(){return"Загрузка данных…"},maximumSelected:function(t){var n="Вы можете выбрать не более "+t.maximum+" элемент";return n+=e(t.maximum,"","a","ов"),n},noResults:function(){return"Совпадений не найдено"},searching:function(){return"Поиск…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/profile-builder/assets/js/select2/i18n/sk.js b/profile-builder/assets/js/select2/i18n/sk.js index 82f2941..1fefd70 100644 --- a/profile-builder/assets/js/select2/i18n/sk.js +++ b/profile-builder/assets/js/select2/i18n/sk.js @@ -1,3 +1,3 @@ -/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ - +/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ + (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/sk",[],function(){var e={2:function(e){return e?"dva":"dve"},3:function(){return"tri"},4:function(){return"štyri"}};return{inputTooLong:function(t){var n=t.input.length-t.maximum;return n==1?"Prosím, zadajte o jeden znak menej":n>=2&&n<=4?"Prosím, zadajte o "+e[n](!0)+" znaky menej":"Prosím, zadajte o "+n+" znakov menej"},inputTooShort:function(t){var n=t.minimum-t.input.length;return n==1?"Prosím, zadajte ešte jeden znak":n<=4?"Prosím, zadajte ešte ďalšie "+e[n](!0)+" znaky":"Prosím, zadajte ešte ďalších "+n+" znakov"},loadingMore:function(){return"Loading more results…"},maximumSelected:function(t){return t.maximum==1?"Môžete zvoliť len jednu položku":t.maximum>=2&&t.maximum<=4?"Môžete zvoliť najviac "+e[t.maximum](!1)+" položky":"Môžete zvoliť najviac "+t.maximum+" položiek"},noResults:function(){return"Nenašli sa žiadne položky"},searching:function(){return"Vyhľadávanie…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/profile-builder/assets/js/select2/i18n/sr-Cyrl.js b/profile-builder/assets/js/select2/i18n/sr-Cyrl.js index e945394..7f037b8 100644 --- a/profile-builder/assets/js/select2/i18n/sr-Cyrl.js +++ b/profile-builder/assets/js/select2/i18n/sr-Cyrl.js @@ -1,3 +1,3 @@ -/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ - +/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ + (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/sr-Cyrl",[],function(){function e(e,t,n,r){return e%10==1&&e%100!=11?t:e%10>=2&&e%10<=4&&(e%100<12||e%100>14)?n:r}return{errorLoading:function(){return"Преузимање није успело."},inputTooLong:function(t){var n=t.input.length-t.maximum,r="Обришите "+n+" симбол";return r+=e(n,"","а","а"),r},inputTooShort:function(t){var n=t.minimum-t.input.length,r="Укуцајте бар још "+n+" симбол";return r+=e(n,"","а","а"),r},loadingMore:function(){return"Преузимање још резултата…"},maximumSelected:function(t){var n="Можете изабрати само "+t.maximum+" ставк";return n+=e(t.maximum,"у","е","и"),n},noResults:function(){return"Ништа није пронађено"},searching:function(){return"Претрага…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/profile-builder/assets/js/select2/i18n/sr.js b/profile-builder/assets/js/select2/i18n/sr.js index ac0cc72..90c141b 100644 --- a/profile-builder/assets/js/select2/i18n/sr.js +++ b/profile-builder/assets/js/select2/i18n/sr.js @@ -1,3 +1,3 @@ -/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ - +/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ + (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/sr",[],function(){function e(e,t,n,r){return e%10==1&&e%100!=11?t:e%10>=2&&e%10<=4&&(e%100<12||e%100>14)?n:r}return{errorLoading:function(){return"Preuzimanje nije uspelo."},inputTooLong:function(t){var n=t.input.length-t.maximum,r="Obrišite "+n+" simbol";return r+=e(n,"","a","a"),r},inputTooShort:function(t){var n=t.minimum-t.input.length,r="Ukucajte bar još "+n+" simbol";return r+=e(n,"","a","a"),r},loadingMore:function(){return"Preuzimanje još rezultata…"},maximumSelected:function(t){var n="Možete izabrati samo "+t.maximum+" stavk";return n+=e(t.maximum,"u","e","i"),n},noResults:function(){return"Ništa nije pronađeno"},searching:function(){return"Pretraga…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/profile-builder/assets/js/select2/i18n/sv.js b/profile-builder/assets/js/select2/i18n/sv.js index bedac08..2194e13 100644 --- a/profile-builder/assets/js/select2/i18n/sv.js +++ b/profile-builder/assets/js/select2/i18n/sv.js @@ -1,3 +1,3 @@ -/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ - +/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ + (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/sv",[],function(){return{errorLoading:function(){return"Resultat kunde inte laddas."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Vänligen sudda ut "+t+" tecken";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Vänligen skriv in "+t+" eller fler tecken";return n},loadingMore:function(){return"Laddar fler resultat…"},maximumSelected:function(e){var t="Du kan max välja "+e.maximum+" element";return t},noResults:function(){return"Inga träffar"},searching:function(){return"Söker…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/profile-builder/assets/js/select2/i18n/th.js b/profile-builder/assets/js/select2/i18n/th.js index 097a86c..456520b 100644 --- a/profile-builder/assets/js/select2/i18n/th.js +++ b/profile-builder/assets/js/select2/i18n/th.js @@ -1,3 +1,3 @@ -/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ - +/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ + (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/th",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n="โปรดลบออก "+t+" ตัวอักษร";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="โปรดพิมพ์เพิ่มอีก "+t+" ตัวอักษร";return n},loadingMore:function(){return"กำลังค้นข้อมูลเพิ่ม…"},maximumSelected:function(e){var t="คุณสามารถเลือกได้ไม่เกิน "+e.maximum+" รายการ";return t},noResults:function(){return"ไม่พบข้อมูล"},searching:function(){return"กำลังค้นข้อมูล…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/profile-builder/assets/js/select2/i18n/tr.js b/profile-builder/assets/js/select2/i18n/tr.js index 25d27a8..ff4a591 100644 --- a/profile-builder/assets/js/select2/i18n/tr.js +++ b/profile-builder/assets/js/select2/i18n/tr.js @@ -1,3 +1,3 @@ -/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ - +/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ + (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/tr",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n=t+" karakter daha girmelisiniz";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="En az "+t+" karakter daha girmelisiniz";return n},loadingMore:function(){return"Daha fazla…"},maximumSelected:function(e){var t="Sadece "+e.maximum+" seçim yapabilirsiniz";return t},noResults:function(){return"Sonuç bulunamadı"},searching:function(){return"Aranıyor…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/profile-builder/assets/js/select2/i18n/uk.js b/profile-builder/assets/js/select2/i18n/uk.js index eb3ca89..66a1a8e 100644 --- a/profile-builder/assets/js/select2/i18n/uk.js +++ b/profile-builder/assets/js/select2/i18n/uk.js @@ -1,3 +1,3 @@ -/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ - +/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ + (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/uk",[],function(){function e(e,t,n,r){return e%100>10&&e%100<15?r:e%10===1?t:e%10>1&&e%10<5?n:r}return{errorLoading:function(){return"Неможливо завантажити результати"},inputTooLong:function(t){var n=t.input.length-t.maximum;return"Будь ласка, видаліть "+n+" "+e(t.maximum,"літеру","літери","літер")},inputTooShort:function(e){var t=e.minimum-e.input.length;return"Будь ласка, введіть "+t+" або більше літер"},loadingMore:function(){return"Завантаження інших результатів…"},maximumSelected:function(t){return"Ви можете вибрати лише "+t.maximum+" "+e(t.maximum,"пункт","пункти","пунктів")},noResults:function(){return"Нічого не знайдено"},searching:function(){return"Пошук…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/profile-builder/assets/js/select2/i18n/vi.js b/profile-builder/assets/js/select2/i18n/vi.js index 8975b8a..750fa9d 100644 --- a/profile-builder/assets/js/select2/i18n/vi.js +++ b/profile-builder/assets/js/select2/i18n/vi.js @@ -1,3 +1,3 @@ -/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ - +/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ + (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/vi",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n="Vui lòng nhập ít hơn "+t+" ký tự";return t!=1&&(n+="s"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Vui lòng nhập nhiều hơn "+t+' ký tự"';return n},loadingMore:function(){return"Đang lấy thêm kết quả…"},maximumSelected:function(e){var t="Chỉ có thể chọn được "+e.maximum+" lựa chọn";return t},noResults:function(){return"Không tìm thấy kết quả"},searching:function(){return"Đang tìm…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/profile-builder/assets/js/select2/i18n/zh-CN.js b/profile-builder/assets/js/select2/i18n/zh-CN.js index 2ed9597..fdea008 100644 --- a/profile-builder/assets/js/select2/i18n/zh-CN.js +++ b/profile-builder/assets/js/select2/i18n/zh-CN.js @@ -1,3 +1,3 @@ -/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ - +/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ + (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/zh-CN",[],function(){return{errorLoading:function(){return"无法载入结果。"},inputTooLong:function(e){var t=e.input.length-e.maximum,n="请删除"+t+"个字符";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="请再输入至少"+t+"个字符";return n},loadingMore:function(){return"载入更多结果…"},maximumSelected:function(e){var t="最多只能选择"+e.maximum+"个项目";return t},noResults:function(){return"未找到结果"},searching:function(){return"搜索中…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/profile-builder/assets/js/select2/i18n/zh-TW.js b/profile-builder/assets/js/select2/i18n/zh-TW.js index ea0812e..33eba48 100644 --- a/profile-builder/assets/js/select2/i18n/zh-TW.js +++ b/profile-builder/assets/js/select2/i18n/zh-TW.js @@ -1,3 +1,3 @@ -/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ - +/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */ + (function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/zh-TW",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n="請刪掉"+t+"個字元";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="請再輸入"+t+"個字元";return n},loadingMore:function(){return"載入中…"},maximumSelected:function(e){var t="你只能選擇最多"+e.maximum+"項";return t},noResults:function(){return"沒有找到相符的項目"},searching:function(){return"搜尋中…"}}}),{define:e.define,require:e.require}})(); \ No newline at end of file diff --git a/profile-builder/assets/js/select2/select2.min.js b/profile-builder/assets/js/select2/select2.min.js index 43f0a65..c668840 100644 --- a/profile-builder/assets/js/select2/select2.min.js +++ b/profile-builder/assets/js/select2/select2.min.js @@ -1,3 +1,3 @@ -/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):a("object"==typeof exports?require("jquery"):jQuery)}(function(a){var b=function(){if(a&&a.fn&&a.fn.select2&&a.fn.select2.amd)var b=a.fn.select2.amd;var b;return function(){if(!b||!b.requirejs){b?c=b:b={};var a,c,d;!function(b){function e(a,b){return u.call(a,b)}function f(a,b){var c,d,e,f,g,h,i,j,k,l,m,n=b&&b.split("/"),o=s.map,p=o&&o["*"]||{};if(a&&"."===a.charAt(0))if(b){for(a=a.split("/"),g=a.length-1,s.nodeIdCompat&&w.test(a[g])&&(a[g]=a[g].replace(w,"")),a=n.slice(0,n.length-1).concat(a),k=0;k0&&(a.splice(k-1,2),k-=2)}a=a.join("/")}else 0===a.indexOf("./")&&(a=a.substring(2));if((n||p)&&o){for(c=a.split("/"),k=c.length;k>0;k-=1){if(d=c.slice(0,k).join("/"),n)for(l=n.length;l>0;l-=1)if(e=o[n.slice(0,l).join("/")],e&&(e=e[d])){f=e,h=k;break}if(f)break;!i&&p&&p[d]&&(i=p[d],j=k)}!f&&i&&(f=i,h=j),f&&(c.splice(0,h,f),a=c.join("/"))}return a}function g(a,c){return function(){var d=v.call(arguments,0);return"string"!=typeof d[0]&&1===d.length&&d.push(null),n.apply(b,d.concat([a,c]))}}function h(a){return function(b){return f(b,a)}}function i(a){return function(b){q[a]=b}}function j(a){if(e(r,a)){var c=r[a];delete r[a],t[a]=!0,m.apply(b,c)}if(!e(q,a)&&!e(t,a))throw new Error("No "+a);return q[a]}function k(a){var b,c=a?a.indexOf("!"):-1;return c>-1&&(b=a.substring(0,c),a=a.substring(c+1,a.length)),[b,a]}function l(a){return function(){return s&&s.config&&s.config[a]||{}}}var m,n,o,p,q={},r={},s={},t={},u=Object.prototype.hasOwnProperty,v=[].slice,w=/\.js$/;o=function(a,b){var c,d=k(a),e=d[0];return a=d[1],e&&(e=f(e,b),c=j(e)),e?a=c&&c.normalize?c.normalize(a,h(b)):f(a,b):(a=f(a,b),d=k(a),e=d[0],a=d[1],e&&(c=j(e))),{f:e?e+"!"+a:a,n:a,pr:e,p:c}},p={require:function(a){return g(a)},exports:function(a){var b=q[a];return"undefined"!=typeof b?b:q[a]={}},module:function(a){return{id:a,uri:"",exports:q[a],config:l(a)}}},m=function(a,c,d,f){var h,k,l,m,n,s,u=[],v=typeof d;if(f=f||a,"undefined"===v||"function"===v){for(c=!c.length&&d.length?["require","exports","module"]:c,n=0;n0&&(b.call(arguments,a.prototype.constructor),e=c.prototype.constructor),e.apply(this,arguments)}function e(){this.constructor=d}var f=b(c),g=b(a);c.displayName=a.displayName,d.prototype=new e;for(var h=0;hc;c++)a[c].apply(this,b)},c.Observable=d,c.generateChars=function(a){for(var b="",c=0;a>c;c++){var d=Math.floor(36*Math.random());b+=d.toString(36)}return b},c.bind=function(a,b){return function(){a.apply(b,arguments)}},c._convertData=function(a){for(var b in a){var c=b.split("-"),d=a;if(1!==c.length){for(var e=0;e":">",'"':""","'":"'","/":"/"};return"string"!=typeof a?a:String(a).replace(/[&<>"'\/\\]/g,function(a){return b[a]})},c.appendMany=function(b,c){if("1.7"===a.fn.jquery.substr(0,3)){var d=a();a.map(c,function(a){d=d.add(a)}),c=d}b.append(c)},c}),b.define("select2/results",["jquery","./utils"],function(a,b){function c(a,b,d){this.$element=a,this.data=d,this.options=b,c.__super__.constructor.call(this)}return b.Extend(c,b.Observable),c.prototype.render=function(){var b=a('
      ');return this.options.get("multiple")&&b.attr("aria-multiselectable","true"),this.$results=b,b},c.prototype.clear=function(){this.$results.empty()},c.prototype.displayMessage=function(b){var c=this.options.get("escapeMarkup");this.clear(),this.hideLoading();var d=a('
    • '),e=this.options.get("translations").get(b.message);d.append(c(e(b.args))),d[0].className+=" select2-results__message",this.$results.append(d)},c.prototype.hideMessages=function(){this.$results.find(".select2-results__message").remove()},c.prototype.append=function(a){this.hideLoading();var b=[];if(null==a.results||0===a.results.length)return void(0===this.$results.children().length&&this.trigger("results:message",{message:"noResults"}));a.results=this.sort(a.results);for(var c=0;c0?b.first().trigger("mouseenter"):a.first().trigger("mouseenter"),this.ensureHighlightVisible()},c.prototype.setClasses=function(){var b=this;this.data.current(function(c){var d=a.map(c,function(a){return a.id.toString()}),e=b.$results.find(".select2-results__option[aria-selected]");e.each(function(){var b=a(this),c=a.data(this,"data"),e=""+c.id;null!=c.element&&c.element.selected||null==c.element&&a.inArray(e,d)>-1?b.attr("aria-selected","true"):b.attr("aria-selected","false")})})},c.prototype.showLoading=function(a){this.hideLoading();var b=this.options.get("translations").get("searching"),c={disabled:!0,loading:!0,text:b(a)},d=this.option(c);d.className+=" loading-results",this.$results.prepend(d)},c.prototype.hideLoading=function(){this.$results.find(".loading-results").remove()},c.prototype.option=function(b){var c=document.createElement("li");c.className="select2-results__option";var d={role:"treeitem","aria-selected":"false"};b.disabled&&(delete d["aria-selected"],d["aria-disabled"]="true"),null==b.id&&delete d["aria-selected"],null!=b._resultId&&(c.id=b._resultId),b.title&&(c.title=b.title),b.children&&(d.role="group",d["aria-label"]=b.text,delete d["aria-selected"]);for(var e in d){var f=d[e];c.setAttribute(e,f)}if(b.children){var g=a(c),h=document.createElement("strong");h.className="select2-results__group";a(h);this.template(b,h);for(var i=[],j=0;j",{"class":"select2-results__options select2-results__options--nested"});m.append(i),g.append(h),g.append(m)}else this.template(b,c);return a.data(c,"data",b),c},c.prototype.bind=function(b,c){var d=this,e=b.id+"-results";this.$results.attr("id",e),b.on("results:all",function(a){d.clear(),d.append(a.data),b.isOpen()&&(d.setClasses(),d.highlightFirstItem())}),b.on("results:append",function(a){d.append(a.data),b.isOpen()&&d.setClasses()}),b.on("query",function(a){d.hideMessages(),d.showLoading(a)}),b.on("select",function(){b.isOpen()&&(d.setClasses(),d.highlightFirstItem())}),b.on("unselect",function(){b.isOpen()&&(d.setClasses(),d.highlightFirstItem())}),b.on("open",function(){d.$results.attr("aria-expanded","true"),d.$results.attr("aria-hidden","false"),d.setClasses(),d.ensureHighlightVisible()}),b.on("close",function(){d.$results.attr("aria-expanded","false"),d.$results.attr("aria-hidden","true"),d.$results.removeAttr("aria-activedescendant")}),b.on("results:toggle",function(){var a=d.getHighlightedResults();0!==a.length&&a.trigger("mouseup")}),b.on("results:select",function(){var a=d.getHighlightedResults();if(0!==a.length){var b=a.data("data");"true"==a.attr("aria-selected")?d.trigger("close",{}):d.trigger("select",{data:b})}}),b.on("results:previous",function(){var a=d.getHighlightedResults(),b=d.$results.find("[aria-selected]"),c=b.index(a);if(0!==c){var e=c-1;0===a.length&&(e=0);var f=b.eq(e);f.trigger("mouseenter");var g=d.$results.offset().top,h=f.offset().top,i=d.$results.scrollTop()+(h-g);0===e?d.$results.scrollTop(0):0>h-g&&d.$results.scrollTop(i)}}),b.on("results:next",function(){var a=d.getHighlightedResults(),b=d.$results.find("[aria-selected]"),c=b.index(a),e=c+1;if(!(e>=b.length)){var f=b.eq(e);f.trigger("mouseenter");var g=d.$results.offset().top+d.$results.outerHeight(!1),h=f.offset().top+f.outerHeight(!1),i=d.$results.scrollTop()+h-g;0===e?d.$results.scrollTop(0):h>g&&d.$results.scrollTop(i)}}),b.on("results:focus",function(a){a.element.addClass("select2-results__option--highlighted")}),b.on("results:message",function(a){d.displayMessage(a)}),a.fn.mousewheel&&this.$results.on("mousewheel",function(a){var b=d.$results.scrollTop(),c=d.$results.get(0).scrollHeight-b+a.deltaY,e=a.deltaY>0&&b-a.deltaY<=0,f=a.deltaY<0&&c<=d.$results.height();e?(d.$results.scrollTop(0),a.preventDefault(),a.stopPropagation()):f&&(d.$results.scrollTop(d.$results.get(0).scrollHeight-d.$results.height()),a.preventDefault(),a.stopPropagation())}),this.$results.on("mouseup",".select2-results__option[aria-selected]",function(b){var c=a(this),e=c.data("data");return"true"===c.attr("aria-selected")?void(d.options.get("multiple")?d.trigger("unselect",{originalEvent:b,data:e}):d.trigger("close",{})):void d.trigger("select",{originalEvent:b,data:e})}),this.$results.on("mouseenter",".select2-results__option[aria-selected]",function(b){var c=a(this).data("data");d.getHighlightedResults().removeClass("select2-results__option--highlighted"),d.trigger("results:focus",{data:c,element:a(this)})})},c.prototype.getHighlightedResults=function(){var a=this.$results.find(".select2-results__option--highlighted");return a},c.prototype.destroy=function(){this.$results.remove()},c.prototype.ensureHighlightVisible=function(){var a=this.getHighlightedResults();if(0!==a.length){var b=this.$results.find("[aria-selected]"),c=b.index(a),d=this.$results.offset().top,e=a.offset().top,f=this.$results.scrollTop()+(e-d),g=e-d;f-=2*a.outerHeight(!1),2>=c?this.$results.scrollTop(0):(g>this.$results.outerHeight()||0>g)&&this.$results.scrollTop(f)}},c.prototype.template=function(b,c){var d=this.options.get("templateResult"),e=this.options.get("escapeMarkup"),f=d(b,c);null==f?c.style.display="none":"string"==typeof f?c.innerHTML=e(f):a(c).append(f)},c}),b.define("select2/keys",[],function(){var a={BACKSPACE:8,TAB:9,ENTER:13,SHIFT:16,CTRL:17,ALT:18,ESC:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,DELETE:46};return a}),b.define("select2/selection/base",["jquery","../utils","../keys"],function(a,b,c){function d(a,b){this.$element=a,this.options=b,d.__super__.constructor.call(this)}return b.Extend(d,b.Observable),d.prototype.render=function(){var b=a('');return this._tabindex=0,null!=this.$element.data("old-tabindex")?this._tabindex=this.$element.data("old-tabindex"):null!=this.$element.attr("tabindex")&&(this._tabindex=this.$element.attr("tabindex")),b.attr("title",this.$element.attr("title")),b.attr("tabindex",this._tabindex),this.$selection=b,b},d.prototype.bind=function(a,b){var d=this,e=(a.id+"-container",a.id+"-results");this.container=a,this.$selection.on("focus",function(a){d.trigger("focus",a)}),this.$selection.on("blur",function(a){d._handleBlur(a)}),this.$selection.on("keydown",function(a){d.trigger("keypress",a),a.which===c.SPACE&&a.preventDefault()}),a.on("results:focus",function(a){d.$selection.attr("aria-activedescendant",a.data._resultId)}),a.on("selection:update",function(a){d.update(a.data)}),a.on("open",function(){d.$selection.attr("aria-expanded","true"),d.$selection.attr("aria-owns",e),d._attachCloseHandler(a)}),a.on("close",function(){d.$selection.attr("aria-expanded","false"),d.$selection.removeAttr("aria-activedescendant"),d.$selection.removeAttr("aria-owns"),d.$selection.focus(),d._detachCloseHandler(a)}),a.on("enable",function(){d.$selection.attr("tabindex",d._tabindex)}),a.on("disable",function(){d.$selection.attr("tabindex","-1")})},d.prototype._handleBlur=function(b){var c=this;window.setTimeout(function(){document.activeElement==c.$selection[0]||a.contains(c.$selection[0],document.activeElement)||c.trigger("blur",b)},1)},d.prototype._attachCloseHandler=function(b){a(document.body).on("mousedown.select2."+b.id,function(b){var c=a(b.target),d=c.closest(".select2"),e=a(".select2.select2-container--open");e.each(function(){var b=a(this);if(this!=d[0]){var c=b.data("element");c.select2("close")}})})},d.prototype._detachCloseHandler=function(b){a(document.body).off("mousedown.select2."+b.id)},d.prototype.position=function(a,b){var c=b.find(".selection");c.append(a)},d.prototype.destroy=function(){this._detachCloseHandler(this.container)},d.prototype.update=function(a){throw new Error("The `update` method must be defined in child classes.")},d}),b.define("select2/selection/single",["jquery","./base","../utils","../keys"],function(a,b,c,d){function e(){e.__super__.constructor.apply(this,arguments)}return c.Extend(e,b),e.prototype.render=function(){var a=e.__super__.render.call(this);return a.addClass("select2-selection--single"),a.html(''),a},e.prototype.bind=function(a,b){var c=this;e.__super__.bind.apply(this,arguments);var d=a.id+"-container";this.$selection.find(".select2-selection__rendered").attr("id",d),this.$selection.attr("aria-labelledby",d),this.$selection.on("mousedown",function(a){1===a.which&&c.trigger("toggle",{originalEvent:a})}),this.$selection.on("focus",function(a){}),this.$selection.on("blur",function(a){}),a.on("focus",function(b){a.isOpen()||c.$selection.focus()}),a.on("selection:update",function(a){c.update(a.data)})},e.prototype.clear=function(){this.$selection.find(".select2-selection__rendered").empty()},e.prototype.display=function(a,b){var c=this.options.get("templateSelection"),d=this.options.get("escapeMarkup");return d(c(a,b))},e.prototype.selectionContainer=function(){return a("")},e.prototype.update=function(a){if(0===a.length)return void this.clear();var b=a[0],c=this.$selection.find(".select2-selection__rendered"),d=this.display(b,c);c.empty().append(d),c.prop("title",b.title||b.text)},e}),b.define("select2/selection/multiple",["jquery","./base","../utils"],function(a,b,c){function d(a,b){d.__super__.constructor.apply(this,arguments)}return c.Extend(d,b),d.prototype.render=function(){var a=d.__super__.render.call(this);return a.addClass("select2-selection--multiple"),a.html('
        '),a},d.prototype.bind=function(b,c){var e=this;d.__super__.bind.apply(this,arguments),this.$selection.on("click",function(a){e.trigger("toggle",{originalEvent:a})}),this.$selection.on("click",".select2-selection__choice__remove",function(b){if(!e.options.get("disabled")){var c=a(this),d=c.parent(),f=d.data("data");e.trigger("unselect",{originalEvent:b,data:f})}})},d.prototype.clear=function(){this.$selection.find(".select2-selection__rendered").empty()},d.prototype.display=function(a,b){var c=this.options.get("templateSelection"),d=this.options.get("escapeMarkup");return d(c(a,b))},d.prototype.selectionContainer=function(){var b=a('
      • ×
      • ');return b},d.prototype.update=function(a){if(this.clear(),0!==a.length){for(var b=[],d=0;d1;if(d||c)return a.call(this,b);this.clear();var e=this.createPlaceholder(this.placeholder);this.$selection.find(".select2-selection__rendered").append(e)},b}),b.define("select2/selection/allowClear",["jquery","../keys"],function(a,b){function c(){}return c.prototype.bind=function(a,b,c){var d=this;a.call(this,b,c),null==this.placeholder&&this.options.get("debug")&&window.console&&console.error&&console.error("Select2: The `allowClear` option should be used in combination with the `placeholder` option."),this.$selection.on("mousedown",".select2-selection__clear",function(a){d._handleClear(a)}),b.on("keypress",function(a){d._handleKeyboardClear(a,b)})},c.prototype._handleClear=function(a,b){if(!this.options.get("disabled")){var c=this.$selection.find(".select2-selection__clear");if(0!==c.length){b.stopPropagation();for(var d=c.data("data"),e=0;e0||0===c.length)){var d=a('×');d.data("data",c),this.$selection.find(".select2-selection__rendered").prepend(d)}},c}),b.define("select2/selection/search",["jquery","../utils","../keys"],function(a,b,c){function d(a,b,c){a.call(this,b,c)}return d.prototype.render=function(b){var c=a('');this.$searchContainer=c,this.$search=c.find("input");var d=b.call(this);return this._transferTabIndex(),d},d.prototype.bind=function(a,b,d){var e=this;a.call(this,b,d),b.on("open",function(){e.$search.trigger("focus")}),b.on("close",function(){e.$search.val(""),e.$search.removeAttr("aria-activedescendant"),e.$search.trigger("focus")}),b.on("enable",function(){e.$search.prop("disabled",!1),e._transferTabIndex()}),b.on("disable",function(){e.$search.prop("disabled",!0)}),b.on("focus",function(a){e.$search.trigger("focus")}),b.on("results:focus",function(a){e.$search.attr("aria-activedescendant",a.id)}),this.$selection.on("focusin",".select2-search--inline",function(a){e.trigger("focus",a)}),this.$selection.on("focusout",".select2-search--inline",function(a){e._handleBlur(a)}),this.$selection.on("keydown",".select2-search--inline",function(a){a.stopPropagation(),e.trigger("keypress",a),e._keyUpPrevented=a.isDefaultPrevented();var b=a.which;if(b===c.BACKSPACE&&""===e.$search.val()){var d=e.$searchContainer.prev(".select2-selection__choice");if(d.length>0){var f=d.data("data");e.searchRemoveChoice(f),a.preventDefault()}}});var f=document.documentMode,g=f&&11>=f;this.$selection.on("input.searchcheck",".select2-search--inline",function(a){return g?void e.$selection.off("input.search input.searchcheck"):void e.$selection.off("keyup.search")}),this.$selection.on("keyup.search input.search",".select2-search--inline",function(a){if(g&&"input"===a.type)return void e.$selection.off("input.search input.searchcheck");var b=a.which;b!=c.SHIFT&&b!=c.CTRL&&b!=c.ALT&&b!=c.TAB&&e.handleSearch(a)})},d.prototype._transferTabIndex=function(a){this.$search.attr("tabindex",this.$selection.attr("tabindex")),this.$selection.attr("tabindex","-1")},d.prototype.createPlaceholder=function(a,b){this.$search.attr("placeholder",b.text)},d.prototype.update=function(a,b){var c=this.$search[0]==document.activeElement;this.$search.attr("placeholder",""),a.call(this,b),this.$selection.find(".select2-selection__rendered").append(this.$searchContainer),this.resizeSearch(),c&&this.$search.focus()},d.prototype.handleSearch=function(){if(this.resizeSearch(),!this._keyUpPrevented){var a=this.$search.val();this.trigger("query",{term:a})}this._keyUpPrevented=!1},d.prototype.searchRemoveChoice=function(a,b){this.trigger("unselect",{data:b}),this.$search.val(b.text),this.handleSearch()},d.prototype.resizeSearch=function(){this.$search.css("width","25px");var a="";if(""!==this.$search.attr("placeholder"))a=this.$selection.find(".select2-selection__rendered").innerWidth();else{var b=this.$search.val().length+1;a=.75*b+"em"}this.$search.css("width",a)},d}),b.define("select2/selection/eventRelay",["jquery"],function(a){function b(){}return b.prototype.bind=function(b,c,d){var e=this,f=["open","opening","close","closing","select","selecting","unselect","unselecting"],g=["opening","closing","selecting","unselecting"];b.call(this,c,d),c.on("*",function(b,c){if(-1!==a.inArray(b,f)){c=c||{};var d=a.Event("select2:"+b,{params:c});e.$element.trigger(d),-1!==a.inArray(b,g)&&(c.prevented=d.isDefaultPrevented())}})},b}),b.define("select2/translation",["jquery","require"],function(a,b){function c(a){this.dict=a||{}}return c.prototype.all=function(){return this.dict},c.prototype.get=function(a){return this.dict[a]},c.prototype.extend=function(b){this.dict=a.extend({},b.all(),this.dict)},c._cache={},c.loadPath=function(a){if(!(a in c._cache)){var d=b(a);c._cache[a]=d}return new c(c._cache[a])},c}),b.define("select2/diacritics",[],function(){var a={"Ⓐ":"A","A":"A","À":"A","Á":"A","Â":"A","Ầ":"A","Ấ":"A","Ẫ":"A","Ẩ":"A","Ã":"A","Ā":"A","Ă":"A","Ằ":"A","Ắ":"A","Ẵ":"A","Ẳ":"A","Ȧ":"A","Ǡ":"A","Ä":"A","Ǟ":"A","Ả":"A","Å":"A","Ǻ":"A","Ǎ":"A","Ȁ":"A","Ȃ":"A","Ạ":"A","Ậ":"A","Ặ":"A","Ḁ":"A","Ą":"A","Ⱥ":"A","Ɐ":"A","Ꜳ":"AA","Æ":"AE","Ǽ":"AE","Ǣ":"AE","Ꜵ":"AO","Ꜷ":"AU","Ꜹ":"AV","Ꜻ":"AV","Ꜽ":"AY","Ⓑ":"B","B":"B","Ḃ":"B","Ḅ":"B","Ḇ":"B","Ƀ":"B","Ƃ":"B","Ɓ":"B","Ⓒ":"C","C":"C","Ć":"C","Ĉ":"C","Ċ":"C","Č":"C","Ç":"C","Ḉ":"C","Ƈ":"C","Ȼ":"C","Ꜿ":"C","Ⓓ":"D","D":"D","Ḋ":"D","Ď":"D","Ḍ":"D","Ḑ":"D","Ḓ":"D","Ḏ":"D","Đ":"D","Ƌ":"D","Ɗ":"D","Ɖ":"D","Ꝺ":"D","DZ":"DZ","DŽ":"DZ","Dz":"Dz","Dž":"Dz","Ⓔ":"E","E":"E","È":"E","É":"E","Ê":"E","Ề":"E","Ế":"E","Ễ":"E","Ể":"E","Ẽ":"E","Ē":"E","Ḕ":"E","Ḗ":"E","Ĕ":"E","Ė":"E","Ë":"E","Ẻ":"E","Ě":"E","Ȅ":"E","Ȇ":"E","Ẹ":"E","Ệ":"E","Ȩ":"E","Ḝ":"E","Ę":"E","Ḙ":"E","Ḛ":"E","Ɛ":"E","Ǝ":"E","Ⓕ":"F","F":"F","Ḟ":"F","Ƒ":"F","Ꝼ":"F","Ⓖ":"G","G":"G","Ǵ":"G","Ĝ":"G","Ḡ":"G","Ğ":"G","Ġ":"G","Ǧ":"G","Ģ":"G","Ǥ":"G","Ɠ":"G","Ꞡ":"G","Ᵹ":"G","Ꝿ":"G","Ⓗ":"H","H":"H","Ĥ":"H","Ḣ":"H","Ḧ":"H","Ȟ":"H","Ḥ":"H","Ḩ":"H","Ḫ":"H","Ħ":"H","Ⱨ":"H","Ⱶ":"H","Ɥ":"H","Ⓘ":"I","I":"I","Ì":"I","Í":"I","Î":"I","Ĩ":"I","Ī":"I","Ĭ":"I","İ":"I","Ï":"I","Ḯ":"I","Ỉ":"I","Ǐ":"I","Ȉ":"I","Ȋ":"I","Ị":"I","Į":"I","Ḭ":"I","Ɨ":"I","Ⓙ":"J","J":"J","Ĵ":"J","Ɉ":"J","Ⓚ":"K","K":"K","Ḱ":"K","Ǩ":"K","Ḳ":"K","Ķ":"K","Ḵ":"K","Ƙ":"K","Ⱪ":"K","Ꝁ":"K","Ꝃ":"K","Ꝅ":"K","Ꞣ":"K","Ⓛ":"L","L":"L","Ŀ":"L","Ĺ":"L","Ľ":"L","Ḷ":"L","Ḹ":"L","Ļ":"L","Ḽ":"L","Ḻ":"L","Ł":"L","Ƚ":"L","Ɫ":"L","Ⱡ":"L","Ꝉ":"L","Ꝇ":"L","Ꞁ":"L","LJ":"LJ","Lj":"Lj","Ⓜ":"M","M":"M","Ḿ":"M","Ṁ":"M","Ṃ":"M","Ɱ":"M","Ɯ":"M","Ⓝ":"N","N":"N","Ǹ":"N","Ń":"N","Ñ":"N","Ṅ":"N","Ň":"N","Ṇ":"N","Ņ":"N","Ṋ":"N","Ṉ":"N","Ƞ":"N","Ɲ":"N","Ꞑ":"N","Ꞥ":"N","NJ":"NJ","Nj":"Nj","Ⓞ":"O","O":"O","Ò":"O","Ó":"O","Ô":"O","Ồ":"O","Ố":"O","Ỗ":"O","Ổ":"O","Õ":"O","Ṍ":"O","Ȭ":"O","Ṏ":"O","Ō":"O","Ṑ":"O","Ṓ":"O","Ŏ":"O","Ȯ":"O","Ȱ":"O","Ö":"O","Ȫ":"O","Ỏ":"O","Ő":"O","Ǒ":"O","Ȍ":"O","Ȏ":"O","Ơ":"O","Ờ":"O","Ớ":"O","Ỡ":"O","Ở":"O","Ợ":"O","Ọ":"O","Ộ":"O","Ǫ":"O","Ǭ":"O","Ø":"O","Ǿ":"O","Ɔ":"O","Ɵ":"O","Ꝋ":"O","Ꝍ":"O","Ƣ":"OI","Ꝏ":"OO","Ȣ":"OU","Ⓟ":"P","P":"P","Ṕ":"P","Ṗ":"P","Ƥ":"P","Ᵽ":"P","Ꝑ":"P","Ꝓ":"P","Ꝕ":"P","Ⓠ":"Q","Q":"Q","Ꝗ":"Q","Ꝙ":"Q","Ɋ":"Q","Ⓡ":"R","R":"R","Ŕ":"R","Ṙ":"R","Ř":"R","Ȑ":"R","Ȓ":"R","Ṛ":"R","Ṝ":"R","Ŗ":"R","Ṟ":"R","Ɍ":"R","Ɽ":"R","Ꝛ":"R","Ꞧ":"R","Ꞃ":"R","Ⓢ":"S","S":"S","ẞ":"S","Ś":"S","Ṥ":"S","Ŝ":"S","Ṡ":"S","Š":"S","Ṧ":"S","Ṣ":"S","Ṩ":"S","Ș":"S","Ş":"S","Ȿ":"S","Ꞩ":"S","Ꞅ":"S","Ⓣ":"T","T":"T","Ṫ":"T","Ť":"T","Ṭ":"T","Ț":"T","Ţ":"T","Ṱ":"T","Ṯ":"T","Ŧ":"T","Ƭ":"T","Ʈ":"T","Ⱦ":"T","Ꞇ":"T","Ꜩ":"TZ","Ⓤ":"U","U":"U","Ù":"U","Ú":"U","Û":"U","Ũ":"U","Ṹ":"U","Ū":"U","Ṻ":"U","Ŭ":"U","Ü":"U","Ǜ":"U","Ǘ":"U","Ǖ":"U","Ǚ":"U","Ủ":"U","Ů":"U","Ű":"U","Ǔ":"U","Ȕ":"U","Ȗ":"U","Ư":"U","Ừ":"U","Ứ":"U","Ữ":"U","Ử":"U","Ự":"U","Ụ":"U","Ṳ":"U","Ų":"U","Ṷ":"U","Ṵ":"U","Ʉ":"U","Ⓥ":"V","V":"V","Ṽ":"V","Ṿ":"V","Ʋ":"V","Ꝟ":"V","Ʌ":"V","Ꝡ":"VY","Ⓦ":"W","W":"W","Ẁ":"W","Ẃ":"W","Ŵ":"W","Ẇ":"W","Ẅ":"W","Ẉ":"W","Ⱳ":"W","Ⓧ":"X","X":"X","Ẋ":"X","Ẍ":"X","Ⓨ":"Y","Y":"Y","Ỳ":"Y","Ý":"Y","Ŷ":"Y","Ỹ":"Y","Ȳ":"Y","Ẏ":"Y","Ÿ":"Y","Ỷ":"Y","Ỵ":"Y","Ƴ":"Y","Ɏ":"Y","Ỿ":"Y","Ⓩ":"Z","Z":"Z","Ź":"Z","Ẑ":"Z","Ż":"Z","Ž":"Z","Ẓ":"Z","Ẕ":"Z","Ƶ":"Z","Ȥ":"Z","Ɀ":"Z","Ⱬ":"Z","Ꝣ":"Z","ⓐ":"a","a":"a","ẚ":"a","à":"a","á":"a","â":"a","ầ":"a","ấ":"a","ẫ":"a","ẩ":"a","ã":"a","ā":"a","ă":"a","ằ":"a","ắ":"a","ẵ":"a","ẳ":"a","ȧ":"a","ǡ":"a","ä":"a","ǟ":"a","ả":"a","å":"a","ǻ":"a","ǎ":"a","ȁ":"a","ȃ":"a","ạ":"a","ậ":"a","ặ":"a","ḁ":"a","ą":"a","ⱥ":"a","ɐ":"a","ꜳ":"aa","æ":"ae","ǽ":"ae","ǣ":"ae","ꜵ":"ao","ꜷ":"au","ꜹ":"av","ꜻ":"av","ꜽ":"ay","ⓑ":"b","b":"b","ḃ":"b","ḅ":"b","ḇ":"b","ƀ":"b","ƃ":"b","ɓ":"b","ⓒ":"c","c":"c","ć":"c","ĉ":"c","ċ":"c","č":"c","ç":"c","ḉ":"c","ƈ":"c","ȼ":"c","ꜿ":"c","ↄ":"c","ⓓ":"d","d":"d","ḋ":"d","ď":"d","ḍ":"d","ḑ":"d","ḓ":"d","ḏ":"d","đ":"d","ƌ":"d","ɖ":"d","ɗ":"d","ꝺ":"d","dz":"dz","dž":"dz","ⓔ":"e","e":"e","è":"e","é":"e","ê":"e","ề":"e","ế":"e","ễ":"e","ể":"e","ẽ":"e","ē":"e","ḕ":"e","ḗ":"e","ĕ":"e","ė":"e","ë":"e","ẻ":"e","ě":"e","ȅ":"e","ȇ":"e","ẹ":"e","ệ":"e","ȩ":"e","ḝ":"e","ę":"e","ḙ":"e","ḛ":"e","ɇ":"e","ɛ":"e","ǝ":"e","ⓕ":"f","f":"f","ḟ":"f","ƒ":"f","ꝼ":"f","ⓖ":"g","g":"g","ǵ":"g","ĝ":"g","ḡ":"g","ğ":"g","ġ":"g","ǧ":"g","ģ":"g","ǥ":"g","ɠ":"g","ꞡ":"g","ᵹ":"g","ꝿ":"g","ⓗ":"h","h":"h","ĥ":"h","ḣ":"h","ḧ":"h","ȟ":"h","ḥ":"h","ḩ":"h","ḫ":"h","ẖ":"h","ħ":"h","ⱨ":"h","ⱶ":"h","ɥ":"h","ƕ":"hv","ⓘ":"i","i":"i","ì":"i","í":"i","î":"i","ĩ":"i","ī":"i","ĭ":"i","ï":"i","ḯ":"i","ỉ":"i","ǐ":"i","ȉ":"i","ȋ":"i","ị":"i","į":"i","ḭ":"i","ɨ":"i","ı":"i","ⓙ":"j","j":"j","ĵ":"j","ǰ":"j","ɉ":"j","ⓚ":"k","k":"k","ḱ":"k","ǩ":"k","ḳ":"k","ķ":"k","ḵ":"k","ƙ":"k","ⱪ":"k","ꝁ":"k","ꝃ":"k","ꝅ":"k","ꞣ":"k","ⓛ":"l","l":"l","ŀ":"l","ĺ":"l","ľ":"l","ḷ":"l","ḹ":"l","ļ":"l","ḽ":"l","ḻ":"l","ſ":"l","ł":"l","ƚ":"l","ɫ":"l","ⱡ":"l","ꝉ":"l","ꞁ":"l","ꝇ":"l","lj":"lj","ⓜ":"m","m":"m","ḿ":"m","ṁ":"m","ṃ":"m","ɱ":"m","ɯ":"m","ⓝ":"n","n":"n","ǹ":"n","ń":"n","ñ":"n","ṅ":"n","ň":"n","ṇ":"n","ņ":"n","ṋ":"n","ṉ":"n","ƞ":"n","ɲ":"n","ʼn":"n","ꞑ":"n","ꞥ":"n","nj":"nj","ⓞ":"o","o":"o","ò":"o","ó":"o","ô":"o","ồ":"o","ố":"o","ỗ":"o","ổ":"o","õ":"o","ṍ":"o","ȭ":"o","ṏ":"o","ō":"o","ṑ":"o","ṓ":"o","ŏ":"o","ȯ":"o","ȱ":"o","ö":"o","ȫ":"o","ỏ":"o","ő":"o","ǒ":"o","ȍ":"o","ȏ":"o","ơ":"o","ờ":"o","ớ":"o","ỡ":"o","ở":"o","ợ":"o","ọ":"o","ộ":"o","ǫ":"o","ǭ":"o","ø":"o","ǿ":"o","ɔ":"o","ꝋ":"o","ꝍ":"o","ɵ":"o","ƣ":"oi","ȣ":"ou","ꝏ":"oo","ⓟ":"p","p":"p","ṕ":"p","ṗ":"p","ƥ":"p","ᵽ":"p","ꝑ":"p","ꝓ":"p","ꝕ":"p","ⓠ":"q","q":"q","ɋ":"q","ꝗ":"q","ꝙ":"q","ⓡ":"r","r":"r","ŕ":"r","ṙ":"r","ř":"r","ȑ":"r","ȓ":"r","ṛ":"r","ṝ":"r","ŗ":"r","ṟ":"r","ɍ":"r","ɽ":"r","ꝛ":"r","ꞧ":"r","ꞃ":"r","ⓢ":"s","s":"s","ß":"s","ś":"s","ṥ":"s","ŝ":"s","ṡ":"s","š":"s","ṧ":"s","ṣ":"s","ṩ":"s","ș":"s","ş":"s","ȿ":"s","ꞩ":"s","ꞅ":"s","ẛ":"s","ⓣ":"t","t":"t","ṫ":"t","ẗ":"t","ť":"t","ṭ":"t","ț":"t","ţ":"t","ṱ":"t","ṯ":"t","ŧ":"t","ƭ":"t","ʈ":"t","ⱦ":"t","ꞇ":"t","ꜩ":"tz","ⓤ":"u","u":"u","ù":"u","ú":"u","û":"u","ũ":"u","ṹ":"u","ū":"u","ṻ":"u","ŭ":"u","ü":"u","ǜ":"u","ǘ":"u","ǖ":"u","ǚ":"u","ủ":"u","ů":"u","ű":"u","ǔ":"u","ȕ":"u","ȗ":"u","ư":"u","ừ":"u","ứ":"u","ữ":"u","ử":"u","ự":"u","ụ":"u","ṳ":"u","ų":"u","ṷ":"u","ṵ":"u","ʉ":"u","ⓥ":"v","v":"v","ṽ":"v","ṿ":"v","ʋ":"v","ꝟ":"v","ʌ":"v","ꝡ":"vy","ⓦ":"w","w":"w","ẁ":"w","ẃ":"w","ŵ":"w","ẇ":"w","ẅ":"w","ẘ":"w","ẉ":"w","ⱳ":"w","ⓧ":"x","x":"x","ẋ":"x","ẍ":"x","ⓨ":"y","y":"y","ỳ":"y","ý":"y","ŷ":"y","ỹ":"y","ȳ":"y","ẏ":"y","ÿ":"y","ỷ":"y","ẙ":"y","ỵ":"y","ƴ":"y","ɏ":"y","ỿ":"y","ⓩ":"z","z":"z","ź":"z","ẑ":"z","ż":"z","ž":"z","ẓ":"z","ẕ":"z","ƶ":"z","ȥ":"z","ɀ":"z","ⱬ":"z","ꝣ":"z","Ά":"Α","Έ":"Ε","Ή":"Η","Ί":"Ι","Ϊ":"Ι","Ό":"Ο","Ύ":"Υ","Ϋ":"Υ","Ώ":"Ω","ά":"α","έ":"ε","ή":"η","ί":"ι","ϊ":"ι","ΐ":"ι","ό":"ο","ύ":"υ","ϋ":"υ","ΰ":"υ","ω":"ω","ς":"σ"};return a}),b.define("select2/data/base",["../utils"],function(a){function b(a,c){b.__super__.constructor.call(this)}return a.Extend(b,a.Observable),b.prototype.current=function(a){throw new Error("The `current` method must be defined in child classes.")},b.prototype.query=function(a,b){throw new Error("The `query` method must be defined in child classes.")},b.prototype.bind=function(a,b){},b.prototype.destroy=function(){},b.prototype.generateResultId=function(b,c){var d=b.id+"-result-";return d+=a.generateChars(4),d+=null!=c.id?"-"+c.id.toString():"-"+a.generateChars(4)},b}),b.define("select2/data/select",["./base","../utils","jquery"],function(a,b,c){function d(a,b){this.$element=a,this.options=b,d.__super__.constructor.call(this)}return b.Extend(d,a),d.prototype.current=function(a){var b=[],d=this;this.$element.find(":selected").each(function(){var a=c(this),e=d.item(a);b.push(e)}),a(b)},d.prototype.select=function(a){var b=this;if(a.selected=!0,c(a.element).is("option"))return a.element.selected=!0,void this.$element.trigger("change"); -if(this.$element.prop("multiple"))this.current(function(d){var e=[];a=[a],a.push.apply(a,d);for(var f=0;f=0){var k=f.filter(d(j)),l=this.item(k),m=c.extend(!0,{},j,l),n=this.option(m);k.replaceWith(n)}else{var o=this.option(j);if(j.children){var p=this.convertToOptions(j.children);b.appendMany(o,p)}h.push(o)}}return h},d}),b.define("select2/data/ajax",["./array","../utils","jquery"],function(a,b,c){function d(a,b){this.ajaxOptions=this._applyDefaults(b.get("ajax")),null!=this.ajaxOptions.processResults&&(this.processResults=this.ajaxOptions.processResults),d.__super__.constructor.call(this,a,b)}return b.Extend(d,a),d.prototype._applyDefaults=function(a){var b={data:function(a){return c.extend({},a,{q:a.term})},transport:function(a,b,d){var e=c.ajax(a);return e.then(b),e.fail(d),e}};return c.extend({},b,a,!0)},d.prototype.processResults=function(a){return a},d.prototype.query=function(a,b){function d(){var d=f.transport(f,function(d){var f=e.processResults(d,a);e.options.get("debug")&&window.console&&console.error&&(f&&f.results&&c.isArray(f.results)||console.error("Select2: The AJAX results did not return an array in the `results` key of the response.")),b(f)},function(){d.status&&"0"===d.status||e.trigger("results:message",{message:"errorLoading"})});e._request=d}var e=this;null!=this._request&&(c.isFunction(this._request.abort)&&this._request.abort(),this._request=null);var f=c.extend({type:"GET"},this.ajaxOptions);"function"==typeof f.url&&(f.url=f.url.call(this.$element,a)),"function"==typeof f.data&&(f.data=f.data.call(this.$element,a)),this.ajaxOptions.delay&&null!=a.term?(this._queryTimeout&&window.clearTimeout(this._queryTimeout),this._queryTimeout=window.setTimeout(d,this.ajaxOptions.delay)):d()},d}),b.define("select2/data/tags",["jquery"],function(a){function b(b,c,d){var e=d.get("tags"),f=d.get("createTag");void 0!==f&&(this.createTag=f);var g=d.get("insertTag");if(void 0!==g&&(this.insertTag=g),b.call(this,c,d),a.isArray(e))for(var h=0;h0&&b.term.length>this.maximumInputLength?void this.trigger("results:message",{message:"inputTooLong",args:{maximum:this.maximumInputLength,input:b.term,params:b}}):void a.call(this,b,c)},a}),b.define("select2/data/maximumSelectionLength",[],function(){function a(a,b,c){this.maximumSelectionLength=c.get("maximumSelectionLength"),a.call(this,b,c)}return a.prototype.query=function(a,b,c){var d=this;this.current(function(e){var f=null!=e?e.length:0;return d.maximumSelectionLength>0&&f>=d.maximumSelectionLength?void d.trigger("results:message",{message:"maximumSelected",args:{maximum:d.maximumSelectionLength}}):void a.call(d,b,c)})},a}),b.define("select2/dropdown",["jquery","./utils"],function(a,b){function c(a,b){this.$element=a,this.options=b,c.__super__.constructor.call(this)}return b.Extend(c,b.Observable),c.prototype.render=function(){var b=a('');return b.attr("dir",this.options.get("dir")),this.$dropdown=b,b},c.prototype.bind=function(){},c.prototype.position=function(a,b){},c.prototype.destroy=function(){this.$dropdown.remove()},c}),b.define("select2/dropdown/search",["jquery","../utils"],function(a,b){function c(){}return c.prototype.render=function(b){var c=b.call(this),d=a('');return this.$searchContainer=d,this.$search=d.find("input"),c.prepend(d),c},c.prototype.bind=function(b,c,d){var e=this;b.call(this,c,d),this.$search.on("keydown",function(a){e.trigger("keypress",a),e._keyUpPrevented=a.isDefaultPrevented()}),this.$search.on("input",function(b){a(this).off("keyup")}),this.$search.on("keyup input",function(a){e.handleSearch(a)}),c.on("open",function(){e.$search.attr("tabindex",0),e.$search.focus(),window.setTimeout(function(){e.$search.focus()},0)}),c.on("close",function(){e.$search.attr("tabindex",-1),e.$search.val("")}),c.on("focus",function(){c.isOpen()&&e.$search.focus()}),c.on("results:all",function(a){if(null==a.query.term||""===a.query.term){var b=e.showSearch(a);b?e.$searchContainer.removeClass("select2-search--hide"):e.$searchContainer.addClass("select2-search--hide")}})},c.prototype.handleSearch=function(a){if(!this._keyUpPrevented){var b=this.$search.val();this.trigger("query",{term:b})}this._keyUpPrevented=!1},c.prototype.showSearch=function(a,b){return!0},c}),b.define("select2/dropdown/hidePlaceholder",[],function(){function a(a,b,c,d){this.placeholder=this.normalizePlaceholder(c.get("placeholder")),a.call(this,b,c,d)}return a.prototype.append=function(a,b){b.results=this.removePlaceholder(b.results),a.call(this,b)},a.prototype.normalizePlaceholder=function(a,b){return"string"==typeof b&&(b={id:"",text:b}),b},a.prototype.removePlaceholder=function(a,b){for(var c=b.slice(0),d=b.length-1;d>=0;d--){var e=b[d];this.placeholder.id===e.id&&c.splice(d,1)}return c},a}),b.define("select2/dropdown/infiniteScroll",["jquery"],function(a){function b(a,b,c,d){this.lastParams={},a.call(this,b,c,d),this.$loadingMore=this.createLoadingMore(),this.loading=!1}return b.prototype.append=function(a,b){this.$loadingMore.remove(),this.loading=!1,a.call(this,b),this.showLoadingMore(b)&&this.$results.append(this.$loadingMore)},b.prototype.bind=function(b,c,d){var e=this;b.call(this,c,d),c.on("query",function(a){e.lastParams=a,e.loading=!0}),c.on("query:append",function(a){e.lastParams=a,e.loading=!0}),this.$results.on("scroll",function(){var b=a.contains(document.documentElement,e.$loadingMore[0]);if(!e.loading&&b){var c=e.$results.offset().top+e.$results.outerHeight(!1),d=e.$loadingMore.offset().top+e.$loadingMore.outerHeight(!1);c+50>=d&&e.loadMore()}})},b.prototype.loadMore=function(){this.loading=!0;var b=a.extend({},{page:1},this.lastParams);b.page++,this.trigger("query:append",b)},b.prototype.showLoadingMore=function(a,b){return b.pagination&&b.pagination.more},b.prototype.createLoadingMore=function(){var b=a('
      • '),c=this.options.get("translations").get("loadingMore");return b.html(c(this.lastParams)),b},b}),b.define("select2/dropdown/attachBody",["jquery","../utils"],function(a,b){function c(b,c,d){this.$dropdownParent=d.get("dropdownParent")||a(document.body),b.call(this,c,d)}return c.prototype.bind=function(a,b,c){var d=this,e=!1;a.call(this,b,c),b.on("open",function(){d._showDropdown(),d._attachPositioningHandler(b),e||(e=!0,b.on("results:all",function(){d._positionDropdown(),d._resizeDropdown()}),b.on("results:append",function(){d._positionDropdown(),d._resizeDropdown()}))}),b.on("close",function(){d._hideDropdown(),d._detachPositioningHandler(b)}),this.$dropdownContainer.on("mousedown",function(a){a.stopPropagation()})},c.prototype.destroy=function(a){a.call(this),this.$dropdownContainer.remove()},c.prototype.position=function(a,b,c){b.attr("class",c.attr("class")),b.removeClass("select2"),b.addClass("select2-container--open"),b.css({position:"absolute",top:-999999}),this.$container=c},c.prototype.render=function(b){var c=a(""),d=b.call(this);return c.append(d),this.$dropdownContainer=c,c},c.prototype._hideDropdown=function(a){this.$dropdownContainer.detach()},c.prototype._attachPositioningHandler=function(c,d){var e=this,f="scroll.select2."+d.id,g="resize.select2."+d.id,h="orientationchange.select2."+d.id,i=this.$container.parents().filter(b.hasScroll);i.each(function(){a(this).data("select2-scroll-position",{x:a(this).scrollLeft(),y:a(this).scrollTop()})}),i.on(f,function(b){var c=a(this).data("select2-scroll-position");a(this).scrollTop(c.y)}),a(window).on(f+" "+g+" "+h,function(a){e._positionDropdown(),e._resizeDropdown()})},c.prototype._detachPositioningHandler=function(c,d){var e="scroll.select2."+d.id,f="resize.select2."+d.id,g="orientationchange.select2."+d.id,h=this.$container.parents().filter(b.hasScroll);h.off(e),a(window).off(e+" "+f+" "+g)},c.prototype._positionDropdown=function(){var b=a(window),c=this.$dropdown.hasClass("select2-dropdown--above"),d=this.$dropdown.hasClass("select2-dropdown--below"),e=null,f=this.$container.offset();f.bottom=f.top+this.$container.outerHeight(!1);var g={height:this.$container.outerHeight(!1)};g.top=f.top,g.bottom=f.top+g.height;var h={height:this.$dropdown.outerHeight(!1)},i={top:b.scrollTop(),bottom:b.scrollTop()+b.height()},j=i.topf.bottom+h.height,l={left:f.left,top:g.bottom},m=this.$dropdownParent;"static"===m.css("position")&&(m=m.offsetParent());var n=m.offset();l.top-=n.top,l.left-=n.left,c||d||(e="below"),k||!j||c?!j&&k&&c&&(e="below"):e="above",("above"==e||c&&"below"!==e)&&(l.top=g.top-n.top-h.height),null!=e&&(this.$dropdown.removeClass("select2-dropdown--below select2-dropdown--above").addClass("select2-dropdown--"+e),this.$container.removeClass("select2-container--below select2-container--above").addClass("select2-container--"+e)),this.$dropdownContainer.css(l)},c.prototype._resizeDropdown=function(){var a={width:this.$container.outerWidth(!1)+"px"};this.options.get("dropdownAutoWidth")&&(a.minWidth=a.width,a.position="relative",a.width="auto"),this.$dropdown.css(a)},c.prototype._showDropdown=function(a){this.$dropdownContainer.appendTo(this.$dropdownParent),this._positionDropdown(),this._resizeDropdown()},c}),b.define("select2/dropdown/minimumResultsForSearch",[],function(){function a(b){for(var c=0,d=0;d0&&(l.dataAdapter=j.Decorate(l.dataAdapter,r)),l.maximumInputLength>0&&(l.dataAdapter=j.Decorate(l.dataAdapter,s)),l.maximumSelectionLength>0&&(l.dataAdapter=j.Decorate(l.dataAdapter,t)),l.tags&&(l.dataAdapter=j.Decorate(l.dataAdapter,p)),(null!=l.tokenSeparators||null!=l.tokenizer)&&(l.dataAdapter=j.Decorate(l.dataAdapter,q)),null!=l.query){var C=b(l.amdBase+"compat/query");l.dataAdapter=j.Decorate(l.dataAdapter,C)}if(null!=l.initSelection){var D=b(l.amdBase+"compat/initSelection");l.dataAdapter=j.Decorate(l.dataAdapter,D)}}if(null==l.resultsAdapter&&(l.resultsAdapter=c,null!=l.ajax&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,x)),null!=l.placeholder&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,w)),l.selectOnClose&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,A))),null==l.dropdownAdapter){if(l.multiple)l.dropdownAdapter=u;else{var E=j.Decorate(u,v);l.dropdownAdapter=E}if(0!==l.minimumResultsForSearch&&(l.dropdownAdapter=j.Decorate(l.dropdownAdapter,z)),l.closeOnSelect&&(l.dropdownAdapter=j.Decorate(l.dropdownAdapter,B)),null!=l.dropdownCssClass||null!=l.dropdownCss||null!=l.adaptDropdownCssClass){var F=b(l.amdBase+"compat/dropdownCss");l.dropdownAdapter=j.Decorate(l.dropdownAdapter,F)}l.dropdownAdapter=j.Decorate(l.dropdownAdapter,y)}if(null==l.selectionAdapter){if(l.multiple?l.selectionAdapter=e:l.selectionAdapter=d,null!=l.placeholder&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,f)),l.allowClear&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,g)),l.multiple&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,h)),null!=l.containerCssClass||null!=l.containerCss||null!=l.adaptContainerCssClass){var G=b(l.amdBase+"compat/containerCss");l.selectionAdapter=j.Decorate(l.selectionAdapter,G)}l.selectionAdapter=j.Decorate(l.selectionAdapter,i)}if("string"==typeof l.language)if(l.language.indexOf("-")>0){var H=l.language.split("-"),I=H[0];l.language=[l.language,I]}else l.language=[l.language];if(a.isArray(l.language)){var J=new k;l.language.push("en");for(var K=l.language,L=0;L0){for(var f=a.extend(!0,{},e),g=e.children.length-1;g>=0;g--){var h=e.children[g],i=c(d,h);null==i&&f.children.splice(g,1)}return f.children.length>0?f:c(d,f)}var j=b(e.text).toUpperCase(),k=b(d.term).toUpperCase();return j.indexOf(k)>-1?e:null}this.defaults={amdBase:"./",amdLanguageBase:"./i18n/",closeOnSelect:!0,debug:!1,dropdownAutoWidth:!1,escapeMarkup:j.escapeMarkup,language:C,matcher:c,minimumInputLength:0,maximumInputLength:0,maximumSelectionLength:0,minimumResultsForSearch:0,selectOnClose:!1,sorter:function(a){return a},templateResult:function(a){return a.text},templateSelection:function(a){return a.text},theme:"default",width:"resolve"}},D.prototype.set=function(b,c){var d=a.camelCase(b),e={};e[d]=c;var f=j._convertData(e);a.extend(this.defaults,f)};var E=new D;return E}),b.define("select2/options",["require","jquery","./defaults","./utils"],function(a,b,c,d){function e(b,e){if(this.options=b,null!=e&&this.fromElement(e),this.options=c.apply(this.options),e&&e.is("input")){var f=a(this.get("amdBase")+"compat/inputData");this.options.dataAdapter=d.Decorate(this.options.dataAdapter,f)}}return e.prototype.fromElement=function(a){var c=["select2"];null==this.options.multiple&&(this.options.multiple=a.prop("multiple")),null==this.options.disabled&&(this.options.disabled=a.prop("disabled")),null==this.options.language&&(a.prop("lang")?this.options.language=a.prop("lang").toLowerCase():a.closest("[lang]").prop("lang")&&(this.options.language=a.closest("[lang]").prop("lang"))),null==this.options.dir&&(a.prop("dir")?this.options.dir=a.prop("dir"):a.closest("[dir]").prop("dir")?this.options.dir=a.closest("[dir]").prop("dir"):this.options.dir="ltr"),a.prop("disabled",this.options.disabled),a.prop("multiple",this.options.multiple),a.data("select2Tags")&&(this.options.debug&&window.console&&console.warn&&console.warn('Select2: The `data-select2-tags` attribute has been changed to use the `data-data` and `data-tags="true"` attributes and will be removed in future versions of Select2.'),a.data("data",a.data("select2Tags")),a.data("tags",!0)),a.data("ajaxUrl")&&(this.options.debug&&window.console&&console.warn&&console.warn("Select2: The `data-ajax-url` attribute has been changed to `data-ajax--url` and support for the old attribute will be removed in future versions of Select2."),a.attr("ajax--url",a.data("ajaxUrl")),a.data("ajax--url",a.data("ajaxUrl")));var e={};e=b.fn.jquery&&"1."==b.fn.jquery.substr(0,2)&&a[0].dataset?b.extend(!0,{},a[0].dataset,a.data()):a.data();var f=b.extend(!0,{},e);f=d._convertData(f);for(var g in f)b.inArray(g,c)>-1||(b.isPlainObject(this.options[g])?b.extend(this.options[g],f[g]):this.options[g]=f[g]);return this},e.prototype.get=function(a){return this.options[a]},e.prototype.set=function(a,b){this.options[a]=b},e}),b.define("select2/core",["jquery","./options","./utils","./keys"],function(a,b,c,d){var e=function(a,c){null!=a.data("select2")&&a.data("select2").destroy(),this.$element=a,this.id=this._generateId(a),c=c||{},this.options=new b(c,a),e.__super__.constructor.call(this);var d=a.attr("tabindex")||0;a.data("old-tabindex",d),a.attr("tabindex","-1");var f=this.options.get("dataAdapter");this.dataAdapter=new f(a,this.options);var g=this.render();this._placeContainer(g);var h=this.options.get("selectionAdapter");this.selection=new h(a,this.options),this.$selection=this.selection.render(),this.selection.position(this.$selection,g);var i=this.options.get("dropdownAdapter");this.dropdown=new i(a,this.options),this.$dropdown=this.dropdown.render(),this.dropdown.position(this.$dropdown,g);var j=this.options.get("resultsAdapter");this.results=new j(a,this.options,this.dataAdapter),this.$results=this.results.render(),this.results.position(this.$results,this.$dropdown);var k=this;this._bindAdapters(),this._registerDomEvents(),this._registerDataEvents(),this._registerSelectionEvents(),this._registerDropdownEvents(),this._registerResultsEvents(),this._registerEvents(),this.dataAdapter.current(function(a){k.trigger("selection:update",{data:a})}),a.addClass("select2-hidden-accessible"),a.attr("aria-hidden","true"),this._syncAttributes(),a.data("select2",this)};return c.Extend(e,c.Observable),e.prototype._generateId=function(a){var b="";return b=null!=a.attr("id")?a.attr("id"):null!=a.attr("name")?a.attr("name")+"-"+c.generateChars(2):c.generateChars(4),b=b.replace(/(:|\.|\[|\]|,)/g,""),b="select2-"+b},e.prototype._placeContainer=function(a){a.insertAfter(this.$element);var b=this._resolveWidth(this.$element,this.options.get("width"));null!=b&&a.css("width",b)},e.prototype._resolveWidth=function(a,b){var c=/^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i;if("resolve"==b){var d=this._resolveWidth(a,"style");return null!=d?d:this._resolveWidth(a,"element")}if("element"==b){var e=a.outerWidth(!1);return 0>=e?"auto":e+"px"}if("style"==b){var f=a.attr("style");if("string"!=typeof f)return null;for(var g=f.split(";"),h=0,i=g.length;i>h;h+=1){var j=g[h].replace(/\s/g,""),k=j.match(c);if(null!==k&&k.length>=1)return k[1]}return null}return b},e.prototype._bindAdapters=function(){this.dataAdapter.bind(this,this.$container),this.selection.bind(this,this.$container),this.dropdown.bind(this,this.$container),this.results.bind(this,this.$container)},e.prototype._registerDomEvents=function(){var b=this;this.$element.on("change.select2",function(){b.dataAdapter.current(function(a){b.trigger("selection:update",{data:a})})}),this.$element.on("focus.select2",function(a){b.trigger("focus",a)}),this._syncA=c.bind(this._syncAttributes,this),this._syncS=c.bind(this._syncSubtree,this),this.$element[0].attachEvent&&this.$element[0].attachEvent("onpropertychange",this._syncA);var d=window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver;null!=d?(this._observer=new d(function(c){a.each(c,b._syncA),a.each(c,b._syncS)}),this._observer.observe(this.$element[0],{attributes:!0,childList:!0,subtree:!1})):this.$element[0].addEventListener&&(this.$element[0].addEventListener("DOMAttrModified",b._syncA,!1),this.$element[0].addEventListener("DOMNodeInserted",b._syncS,!1),this.$element[0].addEventListener("DOMNodeRemoved",b._syncS,!1))},e.prototype._registerDataEvents=function(){var a=this;this.dataAdapter.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerSelectionEvents=function(){var b=this,c=["toggle","focus"];this.selection.on("toggle",function(){b.toggleDropdown()}),this.selection.on("focus",function(a){b.focus(a)}),this.selection.on("*",function(d,e){-1===a.inArray(d,c)&&b.trigger(d,e)})},e.prototype._registerDropdownEvents=function(){var a=this;this.dropdown.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerResultsEvents=function(){var a=this;this.results.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerEvents=function(){var a=this;this.on("open",function(){a.$container.addClass("select2-container--open")}),this.on("close",function(){a.$container.removeClass("select2-container--open")}),this.on("enable",function(){a.$container.removeClass("select2-container--disabled")}),this.on("disable",function(){a.$container.addClass("select2-container--disabled")}),this.on("blur",function(){a.$container.removeClass("select2-container--focus")}),this.on("query",function(b){a.isOpen()||a.trigger("open",{}),this.dataAdapter.query(b,function(c){a.trigger("results:all",{data:c,query:b})})}),this.on("query:append",function(b){this.dataAdapter.query(b,function(c){a.trigger("results:append",{data:c,query:b})})}),this.on("keypress",function(b){var c=b.which;a.isOpen()?c===d.ESC||c===d.TAB||c===d.UP&&b.altKey?(a.close(),b.preventDefault()):c===d.ENTER?(a.trigger("results:select",{}),b.preventDefault()):c===d.SPACE&&b.ctrlKey?(a.trigger("results:toggle",{}),b.preventDefault()):c===d.UP?(a.trigger("results:previous",{}),b.preventDefault()):c===d.DOWN&&(a.trigger("results:next",{}),b.preventDefault()):(c===d.ENTER||c===d.SPACE||c===d.DOWN&&b.altKey)&&(a.open(),b.preventDefault())})},e.prototype._syncAttributes=function(){this.options.set("disabled",this.$element.prop("disabled")),this.options.get("disabled")?(this.isOpen()&&this.close(),this.trigger("disable",{})):this.trigger("enable",{})},e.prototype._syncSubtree=function(a,b){var c=!1,d=this;if(!a||!a.target||"OPTION"===a.target.nodeName||"OPTGROUP"===a.target.nodeName){if(b)if(b.addedNodes&&b.addedNodes.length>0)for(var e=0;e0&&(c=!0);else c=!0;c&&this.dataAdapter.current(function(a){d.trigger("selection:update",{data:a})})}},e.prototype.trigger=function(a,b){var c=e.__super__.trigger,d={open:"opening",close:"closing",select:"selecting",unselect:"unselecting"};if(void 0===b&&(b={}),a in d){var f=d[a],g={prevented:!1,name:a,args:b};if(c.call(this,f,g),g.prevented)return void(b.prevented=!0)}c.call(this,a,b)},e.prototype.toggleDropdown=function(){this.options.get("disabled")||(this.isOpen()?this.close():this.open())},e.prototype.open=function(){this.isOpen()||this.trigger("query",{})},e.prototype.close=function(){this.isOpen()&&this.trigger("close",{})},e.prototype.isOpen=function(){return this.$container.hasClass("select2-container--open")},e.prototype.hasFocus=function(){return this.$container.hasClass("select2-container--focus")},e.prototype.focus=function(a){this.hasFocus()||(this.$container.addClass("select2-container--focus"),this.trigger("focus",{}))},e.prototype.enable=function(a){this.options.get("debug")&&window.console&&console.warn&&console.warn('Select2: The `select2("enable")` method has been deprecated and will be removed in later Select2 versions. Use $element.prop("disabled") instead.'),(null==a||0===a.length)&&(a=[!0]);var b=!a[0];this.$element.prop("disabled",b)},e.prototype.data=function(){this.options.get("debug")&&arguments.length>0&&window.console&&console.warn&&console.warn('Select2: Data can no longer be set using `select2("data")`. You should consider setting the value instead using `$element.val()`.');var a=[];return this.dataAdapter.current(function(b){a=b}),a},e.prototype.val=function(b){if(this.options.get("debug")&&window.console&&console.warn&&console.warn('Select2: The `select2("val")` method has been deprecated and will be removed in later Select2 versions. Use $element.val() instead.'),null==b||0===b.length)return this.$element.val();var c=b[0];a.isArray(c)&&(c=a.map(c,function(a){return a.toString()})),this.$element.val(c).trigger("change")},e.prototype.destroy=function(){this.$container.remove(),this.$element[0].detachEvent&&this.$element[0].detachEvent("onpropertychange",this._syncA),null!=this._observer?(this._observer.disconnect(),this._observer=null):this.$element[0].removeEventListener&&(this.$element[0].removeEventListener("DOMAttrModified",this._syncA,!1),this.$element[0].removeEventListener("DOMNodeInserted",this._syncS,!1),this.$element[0].removeEventListener("DOMNodeRemoved",this._syncS,!1)),this._syncA=null,this._syncS=null,this.$element.off(".select2"),this.$element.attr("tabindex",this.$element.data("old-tabindex")),this.$element.removeClass("select2-hidden-accessible"),this.$element.attr("aria-hidden","false"),this.$element.removeData("select2"),this.dataAdapter.destroy(),this.selection.destroy(),this.dropdown.destroy(),this.results.destroy(),this.dataAdapter=null,this.selection=null,this.dropdown=null,this.results=null; +/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):a("object"==typeof exports?require("jquery"):jQuery)}(function(a){var b=function(){if(a&&a.fn&&a.fn.select2&&a.fn.select2.amd)var b=a.fn.select2.amd;var b;return function(){if(!b||!b.requirejs){b?c=b:b={};var a,c,d;!function(b){function e(a,b){return u.call(a,b)}function f(a,b){var c,d,e,f,g,h,i,j,k,l,m,n=b&&b.split("/"),o=s.map,p=o&&o["*"]||{};if(a&&"."===a.charAt(0))if(b){for(a=a.split("/"),g=a.length-1,s.nodeIdCompat&&w.test(a[g])&&(a[g]=a[g].replace(w,"")),a=n.slice(0,n.length-1).concat(a),k=0;k0&&(a.splice(k-1,2),k-=2)}a=a.join("/")}else 0===a.indexOf("./")&&(a=a.substring(2));if((n||p)&&o){for(c=a.split("/"),k=c.length;k>0;k-=1){if(d=c.slice(0,k).join("/"),n)for(l=n.length;l>0;l-=1)if(e=o[n.slice(0,l).join("/")],e&&(e=e[d])){f=e,h=k;break}if(f)break;!i&&p&&p[d]&&(i=p[d],j=k)}!f&&i&&(f=i,h=j),f&&(c.splice(0,h,f),a=c.join("/"))}return a}function g(a,c){return function(){var d=v.call(arguments,0);return"string"!=typeof d[0]&&1===d.length&&d.push(null),n.apply(b,d.concat([a,c]))}}function h(a){return function(b){return f(b,a)}}function i(a){return function(b){q[a]=b}}function j(a){if(e(r,a)){var c=r[a];delete r[a],t[a]=!0,m.apply(b,c)}if(!e(q,a)&&!e(t,a))throw new Error("No "+a);return q[a]}function k(a){var b,c=a?a.indexOf("!"):-1;return c>-1&&(b=a.substring(0,c),a=a.substring(c+1,a.length)),[b,a]}function l(a){return function(){return s&&s.config&&s.config[a]||{}}}var m,n,o,p,q={},r={},s={},t={},u=Object.prototype.hasOwnProperty,v=[].slice,w=/\.js$/;o=function(a,b){var c,d=k(a),e=d[0];return a=d[1],e&&(e=f(e,b),c=j(e)),e?a=c&&c.normalize?c.normalize(a,h(b)):f(a,b):(a=f(a,b),d=k(a),e=d[0],a=d[1],e&&(c=j(e))),{f:e?e+"!"+a:a,n:a,pr:e,p:c}},p={require:function(a){return g(a)},exports:function(a){var b=q[a];return"undefined"!=typeof b?b:q[a]={}},module:function(a){return{id:a,uri:"",exports:q[a],config:l(a)}}},m=function(a,c,d,f){var h,k,l,m,n,s,u=[],v=typeof d;if(f=f||a,"undefined"===v||"function"===v){for(c=!c.length&&d.length?["require","exports","module"]:c,n=0;n0&&(b.call(arguments,a.prototype.constructor),e=c.prototype.constructor),e.apply(this,arguments)}function e(){this.constructor=d}var f=b(c),g=b(a);c.displayName=a.displayName,d.prototype=new e;for(var h=0;hc;c++)a[c].apply(this,b)},c.Observable=d,c.generateChars=function(a){for(var b="",c=0;a>c;c++){var d=Math.floor(36*Math.random());b+=d.toString(36)}return b},c.bind=function(a,b){return function(){a.apply(b,arguments)}},c._convertData=function(a){for(var b in a){var c=b.split("-"),d=a;if(1!==c.length){for(var e=0;e":">",'"':""","'":"'","/":"/"};return"string"!=typeof a?a:String(a).replace(/[&<>"'\/\\]/g,function(a){return b[a]})},c.appendMany=function(b,c){if("1.7"===a.fn.jquery.substr(0,3)){var d=a();a.map(c,function(a){d=d.add(a)}),c=d}b.append(c)},c}),b.define("select2/results",["jquery","./utils"],function(a,b){function c(a,b,d){this.$element=a,this.data=d,this.options=b,c.__super__.constructor.call(this)}return b.Extend(c,b.Observable),c.prototype.render=function(){var b=a('
          ');return this.options.get("multiple")&&b.attr("aria-multiselectable","true"),this.$results=b,b},c.prototype.clear=function(){this.$results.empty()},c.prototype.displayMessage=function(b){var c=this.options.get("escapeMarkup");this.clear(),this.hideLoading();var d=a('
        • '),e=this.options.get("translations").get(b.message);d.append(c(e(b.args))),d[0].className+=" select2-results__message",this.$results.append(d)},c.prototype.hideMessages=function(){this.$results.find(".select2-results__message").remove()},c.prototype.append=function(a){this.hideLoading();var b=[];if(null==a.results||0===a.results.length)return void(0===this.$results.children().length&&this.trigger("results:message",{message:"noResults"}));a.results=this.sort(a.results);for(var c=0;c0?b.first().trigger("mouseenter"):a.first().trigger("mouseenter"),this.ensureHighlightVisible()},c.prototype.setClasses=function(){var b=this;this.data.current(function(c){var d=a.map(c,function(a){return a.id.toString()}),e=b.$results.find(".select2-results__option[aria-selected]");e.each(function(){var b=a(this),c=a.data(this,"data"),e=""+c.id;null!=c.element&&c.element.selected||null==c.element&&a.inArray(e,d)>-1?b.attr("aria-selected","true"):b.attr("aria-selected","false")})})},c.prototype.showLoading=function(a){this.hideLoading();var b=this.options.get("translations").get("searching"),c={disabled:!0,loading:!0,text:b(a)},d=this.option(c);d.className+=" loading-results",this.$results.prepend(d)},c.prototype.hideLoading=function(){this.$results.find(".loading-results").remove()},c.prototype.option=function(b){var c=document.createElement("li");c.className="select2-results__option";var d={role:"treeitem","aria-selected":"false"};b.disabled&&(delete d["aria-selected"],d["aria-disabled"]="true"),null==b.id&&delete d["aria-selected"],null!=b._resultId&&(c.id=b._resultId),b.title&&(c.title=b.title),b.children&&(d.role="group",d["aria-label"]=b.text,delete d["aria-selected"]);for(var e in d){var f=d[e];c.setAttribute(e,f)}if(b.children){var g=a(c),h=document.createElement("strong");h.className="select2-results__group";a(h);this.template(b,h);for(var i=[],j=0;j",{"class":"select2-results__options select2-results__options--nested"});m.append(i),g.append(h),g.append(m)}else this.template(b,c);return a.data(c,"data",b),c},c.prototype.bind=function(b,c){var d=this,e=b.id+"-results";this.$results.attr("id",e),b.on("results:all",function(a){d.clear(),d.append(a.data),b.isOpen()&&(d.setClasses(),d.highlightFirstItem())}),b.on("results:append",function(a){d.append(a.data),b.isOpen()&&d.setClasses()}),b.on("query",function(a){d.hideMessages(),d.showLoading(a)}),b.on("select",function(){b.isOpen()&&(d.setClasses(),d.highlightFirstItem())}),b.on("unselect",function(){b.isOpen()&&(d.setClasses(),d.highlightFirstItem())}),b.on("open",function(){d.$results.attr("aria-expanded","true"),d.$results.attr("aria-hidden","false"),d.setClasses(),d.ensureHighlightVisible()}),b.on("close",function(){d.$results.attr("aria-expanded","false"),d.$results.attr("aria-hidden","true"),d.$results.removeAttr("aria-activedescendant")}),b.on("results:toggle",function(){var a=d.getHighlightedResults();0!==a.length&&a.trigger("mouseup")}),b.on("results:select",function(){var a=d.getHighlightedResults();if(0!==a.length){var b=a.data("data");"true"==a.attr("aria-selected")?d.trigger("close",{}):d.trigger("select",{data:b})}}),b.on("results:previous",function(){var a=d.getHighlightedResults(),b=d.$results.find("[aria-selected]"),c=b.index(a);if(0!==c){var e=c-1;0===a.length&&(e=0);var f=b.eq(e);f.trigger("mouseenter");var g=d.$results.offset().top,h=f.offset().top,i=d.$results.scrollTop()+(h-g);0===e?d.$results.scrollTop(0):0>h-g&&d.$results.scrollTop(i)}}),b.on("results:next",function(){var a=d.getHighlightedResults(),b=d.$results.find("[aria-selected]"),c=b.index(a),e=c+1;if(!(e>=b.length)){var f=b.eq(e);f.trigger("mouseenter");var g=d.$results.offset().top+d.$results.outerHeight(!1),h=f.offset().top+f.outerHeight(!1),i=d.$results.scrollTop()+h-g;0===e?d.$results.scrollTop(0):h>g&&d.$results.scrollTop(i)}}),b.on("results:focus",function(a){a.element.addClass("select2-results__option--highlighted")}),b.on("results:message",function(a){d.displayMessage(a)}),a.fn.mousewheel&&this.$results.on("mousewheel",function(a){var b=d.$results.scrollTop(),c=d.$results.get(0).scrollHeight-b+a.deltaY,e=a.deltaY>0&&b-a.deltaY<=0,f=a.deltaY<0&&c<=d.$results.height();e?(d.$results.scrollTop(0),a.preventDefault(),a.stopPropagation()):f&&(d.$results.scrollTop(d.$results.get(0).scrollHeight-d.$results.height()),a.preventDefault(),a.stopPropagation())}),this.$results.on("mouseup",".select2-results__option[aria-selected]",function(b){var c=a(this),e=c.data("data");return"true"===c.attr("aria-selected")?void(d.options.get("multiple")?d.trigger("unselect",{originalEvent:b,data:e}):d.trigger("close",{})):void d.trigger("select",{originalEvent:b,data:e})}),this.$results.on("mouseenter",".select2-results__option[aria-selected]",function(b){var c=a(this).data("data");d.getHighlightedResults().removeClass("select2-results__option--highlighted"),d.trigger("results:focus",{data:c,element:a(this)})})},c.prototype.getHighlightedResults=function(){var a=this.$results.find(".select2-results__option--highlighted");return a},c.prototype.destroy=function(){this.$results.remove()},c.prototype.ensureHighlightVisible=function(){var a=this.getHighlightedResults();if(0!==a.length){var b=this.$results.find("[aria-selected]"),c=b.index(a),d=this.$results.offset().top,e=a.offset().top,f=this.$results.scrollTop()+(e-d),g=e-d;f-=2*a.outerHeight(!1),2>=c?this.$results.scrollTop(0):(g>this.$results.outerHeight()||0>g)&&this.$results.scrollTop(f)}},c.prototype.template=function(b,c){var d=this.options.get("templateResult"),e=this.options.get("escapeMarkup"),f=d(b,c);null==f?c.style.display="none":"string"==typeof f?c.innerHTML=e(f):a(c).append(f)},c}),b.define("select2/keys",[],function(){var a={BACKSPACE:8,TAB:9,ENTER:13,SHIFT:16,CTRL:17,ALT:18,ESC:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,DELETE:46};return a}),b.define("select2/selection/base",["jquery","../utils","../keys"],function(a,b,c){function d(a,b){this.$element=a,this.options=b,d.__super__.constructor.call(this)}return b.Extend(d,b.Observable),d.prototype.render=function(){var b=a('');return this._tabindex=0,null!=this.$element.data("old-tabindex")?this._tabindex=this.$element.data("old-tabindex"):null!=this.$element.attr("tabindex")&&(this._tabindex=this.$element.attr("tabindex")),b.attr("title",this.$element.attr("title")),b.attr("tabindex",this._tabindex),this.$selection=b,b},d.prototype.bind=function(a,b){var d=this,e=(a.id+"-container",a.id+"-results");this.container=a,this.$selection.on("focus",function(a){d.trigger("focus",a)}),this.$selection.on("blur",function(a){d._handleBlur(a)}),this.$selection.on("keydown",function(a){d.trigger("keypress",a),a.which===c.SPACE&&a.preventDefault()}),a.on("results:focus",function(a){d.$selection.attr("aria-activedescendant",a.data._resultId)}),a.on("selection:update",function(a){d.update(a.data)}),a.on("open",function(){d.$selection.attr("aria-expanded","true"),d.$selection.attr("aria-owns",e),d._attachCloseHandler(a)}),a.on("close",function(){d.$selection.attr("aria-expanded","false"),d.$selection.removeAttr("aria-activedescendant"),d.$selection.removeAttr("aria-owns"),d.$selection.focus(),d._detachCloseHandler(a)}),a.on("enable",function(){d.$selection.attr("tabindex",d._tabindex)}),a.on("disable",function(){d.$selection.attr("tabindex","-1")})},d.prototype._handleBlur=function(b){var c=this;window.setTimeout(function(){document.activeElement==c.$selection[0]||a.contains(c.$selection[0],document.activeElement)||c.trigger("blur",b)},1)},d.prototype._attachCloseHandler=function(b){a(document.body).on("mousedown.select2."+b.id,function(b){var c=a(b.target),d=c.closest(".select2"),e=a(".select2.select2-container--open");e.each(function(){var b=a(this);if(this!=d[0]){var c=b.data("element");c.select2("close")}})})},d.prototype._detachCloseHandler=function(b){a(document.body).off("mousedown.select2."+b.id)},d.prototype.position=function(a,b){var c=b.find(".selection");c.append(a)},d.prototype.destroy=function(){this._detachCloseHandler(this.container)},d.prototype.update=function(a){throw new Error("The `update` method must be defined in child classes.")},d}),b.define("select2/selection/single",["jquery","./base","../utils","../keys"],function(a,b,c,d){function e(){e.__super__.constructor.apply(this,arguments)}return c.Extend(e,b),e.prototype.render=function(){var a=e.__super__.render.call(this);return a.addClass("select2-selection--single"),a.html(''),a},e.prototype.bind=function(a,b){var c=this;e.__super__.bind.apply(this,arguments);var d=a.id+"-container";this.$selection.find(".select2-selection__rendered").attr("id",d),this.$selection.attr("aria-labelledby",d),this.$selection.on("mousedown",function(a){1===a.which&&c.trigger("toggle",{originalEvent:a})}),this.$selection.on("focus",function(a){}),this.$selection.on("blur",function(a){}),a.on("focus",function(b){a.isOpen()||c.$selection.focus()}),a.on("selection:update",function(a){c.update(a.data)})},e.prototype.clear=function(){this.$selection.find(".select2-selection__rendered").empty()},e.prototype.display=function(a,b){var c=this.options.get("templateSelection"),d=this.options.get("escapeMarkup");return d(c(a,b))},e.prototype.selectionContainer=function(){return a("")},e.prototype.update=function(a){if(0===a.length)return void this.clear();var b=a[0],c=this.$selection.find(".select2-selection__rendered"),d=this.display(b,c);c.empty().append(d),c.prop("title",b.title||b.text)},e}),b.define("select2/selection/multiple",["jquery","./base","../utils"],function(a,b,c){function d(a,b){d.__super__.constructor.apply(this,arguments)}return c.Extend(d,b),d.prototype.render=function(){var a=d.__super__.render.call(this);return a.addClass("select2-selection--multiple"),a.html('
            '),a},d.prototype.bind=function(b,c){var e=this;d.__super__.bind.apply(this,arguments),this.$selection.on("click",function(a){e.trigger("toggle",{originalEvent:a})}),this.$selection.on("click",".select2-selection__choice__remove",function(b){if(!e.options.get("disabled")){var c=a(this),d=c.parent(),f=d.data("data");e.trigger("unselect",{originalEvent:b,data:f})}})},d.prototype.clear=function(){this.$selection.find(".select2-selection__rendered").empty()},d.prototype.display=function(a,b){var c=this.options.get("templateSelection"),d=this.options.get("escapeMarkup");return d(c(a,b))},d.prototype.selectionContainer=function(){var b=a('
          • ×
          • ');return b},d.prototype.update=function(a){if(this.clear(),0!==a.length){for(var b=[],d=0;d1;if(d||c)return a.call(this,b);this.clear();var e=this.createPlaceholder(this.placeholder);this.$selection.find(".select2-selection__rendered").append(e)},b}),b.define("select2/selection/allowClear",["jquery","../keys"],function(a,b){function c(){}return c.prototype.bind=function(a,b,c){var d=this;a.call(this,b,c),null==this.placeholder&&this.options.get("debug")&&window.console&&console.error&&console.error("Select2: The `allowClear` option should be used in combination with the `placeholder` option."),this.$selection.on("mousedown",".select2-selection__clear",function(a){d._handleClear(a)}),b.on("keypress",function(a){d._handleKeyboardClear(a,b)})},c.prototype._handleClear=function(a,b){if(!this.options.get("disabled")){var c=this.$selection.find(".select2-selection__clear");if(0!==c.length){b.stopPropagation();for(var d=c.data("data"),e=0;e0||0===c.length)){var d=a('×');d.data("data",c),this.$selection.find(".select2-selection__rendered").prepend(d)}},c}),b.define("select2/selection/search",["jquery","../utils","../keys"],function(a,b,c){function d(a,b,c){a.call(this,b,c)}return d.prototype.render=function(b){var c=a('');this.$searchContainer=c,this.$search=c.find("input");var d=b.call(this);return this._transferTabIndex(),d},d.prototype.bind=function(a,b,d){var e=this;a.call(this,b,d),b.on("open",function(){e.$search.trigger("focus")}),b.on("close",function(){e.$search.val(""),e.$search.removeAttr("aria-activedescendant"),e.$search.trigger("focus")}),b.on("enable",function(){e.$search.prop("disabled",!1),e._transferTabIndex()}),b.on("disable",function(){e.$search.prop("disabled",!0)}),b.on("focus",function(a){e.$search.trigger("focus")}),b.on("results:focus",function(a){e.$search.attr("aria-activedescendant",a.id)}),this.$selection.on("focusin",".select2-search--inline",function(a){e.trigger("focus",a)}),this.$selection.on("focusout",".select2-search--inline",function(a){e._handleBlur(a)}),this.$selection.on("keydown",".select2-search--inline",function(a){a.stopPropagation(),e.trigger("keypress",a),e._keyUpPrevented=a.isDefaultPrevented();var b=a.which;if(b===c.BACKSPACE&&""===e.$search.val()){var d=e.$searchContainer.prev(".select2-selection__choice");if(d.length>0){var f=d.data("data");e.searchRemoveChoice(f),a.preventDefault()}}});var f=document.documentMode,g=f&&11>=f;this.$selection.on("input.searchcheck",".select2-search--inline",function(a){return g?void e.$selection.off("input.search input.searchcheck"):void e.$selection.off("keyup.search")}),this.$selection.on("keyup.search input.search",".select2-search--inline",function(a){if(g&&"input"===a.type)return void e.$selection.off("input.search input.searchcheck");var b=a.which;b!=c.SHIFT&&b!=c.CTRL&&b!=c.ALT&&b!=c.TAB&&e.handleSearch(a)})},d.prototype._transferTabIndex=function(a){this.$search.attr("tabindex",this.$selection.attr("tabindex")),this.$selection.attr("tabindex","-1")},d.prototype.createPlaceholder=function(a,b){this.$search.attr("placeholder",b.text)},d.prototype.update=function(a,b){var c=this.$search[0]==document.activeElement;this.$search.attr("placeholder",""),a.call(this,b),this.$selection.find(".select2-selection__rendered").append(this.$searchContainer),this.resizeSearch(),c&&this.$search.focus()},d.prototype.handleSearch=function(){if(this.resizeSearch(),!this._keyUpPrevented){var a=this.$search.val();this.trigger("query",{term:a})}this._keyUpPrevented=!1},d.prototype.searchRemoveChoice=function(a,b){this.trigger("unselect",{data:b}),this.$search.val(b.text),this.handleSearch()},d.prototype.resizeSearch=function(){this.$search.css("width","25px");var a="";if(""!==this.$search.attr("placeholder"))a=this.$selection.find(".select2-selection__rendered").innerWidth();else{var b=this.$search.val().length+1;a=.75*b+"em"}this.$search.css("width",a)},d}),b.define("select2/selection/eventRelay",["jquery"],function(a){function b(){}return b.prototype.bind=function(b,c,d){var e=this,f=["open","opening","close","closing","select","selecting","unselect","unselecting"],g=["opening","closing","selecting","unselecting"];b.call(this,c,d),c.on("*",function(b,c){if(-1!==a.inArray(b,f)){c=c||{};var d=a.Event("select2:"+b,{params:c});e.$element.trigger(d),-1!==a.inArray(b,g)&&(c.prevented=d.isDefaultPrevented())}})},b}),b.define("select2/translation",["jquery","require"],function(a,b){function c(a){this.dict=a||{}}return c.prototype.all=function(){return this.dict},c.prototype.get=function(a){return this.dict[a]},c.prototype.extend=function(b){this.dict=a.extend({},b.all(),this.dict)},c._cache={},c.loadPath=function(a){if(!(a in c._cache)){var d=b(a);c._cache[a]=d}return new c(c._cache[a])},c}),b.define("select2/diacritics",[],function(){var a={"Ⓐ":"A","A":"A","À":"A","Á":"A","Â":"A","Ầ":"A","Ấ":"A","Ẫ":"A","Ẩ":"A","Ã":"A","Ā":"A","Ă":"A","Ằ":"A","Ắ":"A","Ẵ":"A","Ẳ":"A","Ȧ":"A","Ǡ":"A","Ä":"A","Ǟ":"A","Ả":"A","Å":"A","Ǻ":"A","Ǎ":"A","Ȁ":"A","Ȃ":"A","Ạ":"A","Ậ":"A","Ặ":"A","Ḁ":"A","Ą":"A","Ⱥ":"A","Ɐ":"A","Ꜳ":"AA","Æ":"AE","Ǽ":"AE","Ǣ":"AE","Ꜵ":"AO","Ꜷ":"AU","Ꜹ":"AV","Ꜻ":"AV","Ꜽ":"AY","Ⓑ":"B","B":"B","Ḃ":"B","Ḅ":"B","Ḇ":"B","Ƀ":"B","Ƃ":"B","Ɓ":"B","Ⓒ":"C","C":"C","Ć":"C","Ĉ":"C","Ċ":"C","Č":"C","Ç":"C","Ḉ":"C","Ƈ":"C","Ȼ":"C","Ꜿ":"C","Ⓓ":"D","D":"D","Ḋ":"D","Ď":"D","Ḍ":"D","Ḑ":"D","Ḓ":"D","Ḏ":"D","Đ":"D","Ƌ":"D","Ɗ":"D","Ɖ":"D","Ꝺ":"D","DZ":"DZ","DŽ":"DZ","Dz":"Dz","Dž":"Dz","Ⓔ":"E","E":"E","È":"E","É":"E","Ê":"E","Ề":"E","Ế":"E","Ễ":"E","Ể":"E","Ẽ":"E","Ē":"E","Ḕ":"E","Ḗ":"E","Ĕ":"E","Ė":"E","Ë":"E","Ẻ":"E","Ě":"E","Ȅ":"E","Ȇ":"E","Ẹ":"E","Ệ":"E","Ȩ":"E","Ḝ":"E","Ę":"E","Ḙ":"E","Ḛ":"E","Ɛ":"E","Ǝ":"E","Ⓕ":"F","F":"F","Ḟ":"F","Ƒ":"F","Ꝼ":"F","Ⓖ":"G","G":"G","Ǵ":"G","Ĝ":"G","Ḡ":"G","Ğ":"G","Ġ":"G","Ǧ":"G","Ģ":"G","Ǥ":"G","Ɠ":"G","Ꞡ":"G","Ᵹ":"G","Ꝿ":"G","Ⓗ":"H","H":"H","Ĥ":"H","Ḣ":"H","Ḧ":"H","Ȟ":"H","Ḥ":"H","Ḩ":"H","Ḫ":"H","Ħ":"H","Ⱨ":"H","Ⱶ":"H","Ɥ":"H","Ⓘ":"I","I":"I","Ì":"I","Í":"I","Î":"I","Ĩ":"I","Ī":"I","Ĭ":"I","İ":"I","Ï":"I","Ḯ":"I","Ỉ":"I","Ǐ":"I","Ȉ":"I","Ȋ":"I","Ị":"I","Į":"I","Ḭ":"I","Ɨ":"I","Ⓙ":"J","J":"J","Ĵ":"J","Ɉ":"J","Ⓚ":"K","K":"K","Ḱ":"K","Ǩ":"K","Ḳ":"K","Ķ":"K","Ḵ":"K","Ƙ":"K","Ⱪ":"K","Ꝁ":"K","Ꝃ":"K","Ꝅ":"K","Ꞣ":"K","Ⓛ":"L","L":"L","Ŀ":"L","Ĺ":"L","Ľ":"L","Ḷ":"L","Ḹ":"L","Ļ":"L","Ḽ":"L","Ḻ":"L","Ł":"L","Ƚ":"L","Ɫ":"L","Ⱡ":"L","Ꝉ":"L","Ꝇ":"L","Ꞁ":"L","LJ":"LJ","Lj":"Lj","Ⓜ":"M","M":"M","Ḿ":"M","Ṁ":"M","Ṃ":"M","Ɱ":"M","Ɯ":"M","Ⓝ":"N","N":"N","Ǹ":"N","Ń":"N","Ñ":"N","Ṅ":"N","Ň":"N","Ṇ":"N","Ņ":"N","Ṋ":"N","Ṉ":"N","Ƞ":"N","Ɲ":"N","Ꞑ":"N","Ꞥ":"N","NJ":"NJ","Nj":"Nj","Ⓞ":"O","O":"O","Ò":"O","Ó":"O","Ô":"O","Ồ":"O","Ố":"O","Ỗ":"O","Ổ":"O","Õ":"O","Ṍ":"O","Ȭ":"O","Ṏ":"O","Ō":"O","Ṑ":"O","Ṓ":"O","Ŏ":"O","Ȯ":"O","Ȱ":"O","Ö":"O","Ȫ":"O","Ỏ":"O","Ő":"O","Ǒ":"O","Ȍ":"O","Ȏ":"O","Ơ":"O","Ờ":"O","Ớ":"O","Ỡ":"O","Ở":"O","Ợ":"O","Ọ":"O","Ộ":"O","Ǫ":"O","Ǭ":"O","Ø":"O","Ǿ":"O","Ɔ":"O","Ɵ":"O","Ꝋ":"O","Ꝍ":"O","Ƣ":"OI","Ꝏ":"OO","Ȣ":"OU","Ⓟ":"P","P":"P","Ṕ":"P","Ṗ":"P","Ƥ":"P","Ᵽ":"P","Ꝑ":"P","Ꝓ":"P","Ꝕ":"P","Ⓠ":"Q","Q":"Q","Ꝗ":"Q","Ꝙ":"Q","Ɋ":"Q","Ⓡ":"R","R":"R","Ŕ":"R","Ṙ":"R","Ř":"R","Ȑ":"R","Ȓ":"R","Ṛ":"R","Ṝ":"R","Ŗ":"R","Ṟ":"R","Ɍ":"R","Ɽ":"R","Ꝛ":"R","Ꞧ":"R","Ꞃ":"R","Ⓢ":"S","S":"S","ẞ":"S","Ś":"S","Ṥ":"S","Ŝ":"S","Ṡ":"S","Š":"S","Ṧ":"S","Ṣ":"S","Ṩ":"S","Ș":"S","Ş":"S","Ȿ":"S","Ꞩ":"S","Ꞅ":"S","Ⓣ":"T","T":"T","Ṫ":"T","Ť":"T","Ṭ":"T","Ț":"T","Ţ":"T","Ṱ":"T","Ṯ":"T","Ŧ":"T","Ƭ":"T","Ʈ":"T","Ⱦ":"T","Ꞇ":"T","Ꜩ":"TZ","Ⓤ":"U","U":"U","Ù":"U","Ú":"U","Û":"U","Ũ":"U","Ṹ":"U","Ū":"U","Ṻ":"U","Ŭ":"U","Ü":"U","Ǜ":"U","Ǘ":"U","Ǖ":"U","Ǚ":"U","Ủ":"U","Ů":"U","Ű":"U","Ǔ":"U","Ȕ":"U","Ȗ":"U","Ư":"U","Ừ":"U","Ứ":"U","Ữ":"U","Ử":"U","Ự":"U","Ụ":"U","Ṳ":"U","Ų":"U","Ṷ":"U","Ṵ":"U","Ʉ":"U","Ⓥ":"V","V":"V","Ṽ":"V","Ṿ":"V","Ʋ":"V","Ꝟ":"V","Ʌ":"V","Ꝡ":"VY","Ⓦ":"W","W":"W","Ẁ":"W","Ẃ":"W","Ŵ":"W","Ẇ":"W","Ẅ":"W","Ẉ":"W","Ⱳ":"W","Ⓧ":"X","X":"X","Ẋ":"X","Ẍ":"X","Ⓨ":"Y","Y":"Y","Ỳ":"Y","Ý":"Y","Ŷ":"Y","Ỹ":"Y","Ȳ":"Y","Ẏ":"Y","Ÿ":"Y","Ỷ":"Y","Ỵ":"Y","Ƴ":"Y","Ɏ":"Y","Ỿ":"Y","Ⓩ":"Z","Z":"Z","Ź":"Z","Ẑ":"Z","Ż":"Z","Ž":"Z","Ẓ":"Z","Ẕ":"Z","Ƶ":"Z","Ȥ":"Z","Ɀ":"Z","Ⱬ":"Z","Ꝣ":"Z","ⓐ":"a","a":"a","ẚ":"a","à":"a","á":"a","â":"a","ầ":"a","ấ":"a","ẫ":"a","ẩ":"a","ã":"a","ā":"a","ă":"a","ằ":"a","ắ":"a","ẵ":"a","ẳ":"a","ȧ":"a","ǡ":"a","ä":"a","ǟ":"a","ả":"a","å":"a","ǻ":"a","ǎ":"a","ȁ":"a","ȃ":"a","ạ":"a","ậ":"a","ặ":"a","ḁ":"a","ą":"a","ⱥ":"a","ɐ":"a","ꜳ":"aa","æ":"ae","ǽ":"ae","ǣ":"ae","ꜵ":"ao","ꜷ":"au","ꜹ":"av","ꜻ":"av","ꜽ":"ay","ⓑ":"b","b":"b","ḃ":"b","ḅ":"b","ḇ":"b","ƀ":"b","ƃ":"b","ɓ":"b","ⓒ":"c","c":"c","ć":"c","ĉ":"c","ċ":"c","č":"c","ç":"c","ḉ":"c","ƈ":"c","ȼ":"c","ꜿ":"c","ↄ":"c","ⓓ":"d","d":"d","ḋ":"d","ď":"d","ḍ":"d","ḑ":"d","ḓ":"d","ḏ":"d","đ":"d","ƌ":"d","ɖ":"d","ɗ":"d","ꝺ":"d","dz":"dz","dž":"dz","ⓔ":"e","e":"e","è":"e","é":"e","ê":"e","ề":"e","ế":"e","ễ":"e","ể":"e","ẽ":"e","ē":"e","ḕ":"e","ḗ":"e","ĕ":"e","ė":"e","ë":"e","ẻ":"e","ě":"e","ȅ":"e","ȇ":"e","ẹ":"e","ệ":"e","ȩ":"e","ḝ":"e","ę":"e","ḙ":"e","ḛ":"e","ɇ":"e","ɛ":"e","ǝ":"e","ⓕ":"f","f":"f","ḟ":"f","ƒ":"f","ꝼ":"f","ⓖ":"g","g":"g","ǵ":"g","ĝ":"g","ḡ":"g","ğ":"g","ġ":"g","ǧ":"g","ģ":"g","ǥ":"g","ɠ":"g","ꞡ":"g","ᵹ":"g","ꝿ":"g","ⓗ":"h","h":"h","ĥ":"h","ḣ":"h","ḧ":"h","ȟ":"h","ḥ":"h","ḩ":"h","ḫ":"h","ẖ":"h","ħ":"h","ⱨ":"h","ⱶ":"h","ɥ":"h","ƕ":"hv","ⓘ":"i","i":"i","ì":"i","í":"i","î":"i","ĩ":"i","ī":"i","ĭ":"i","ï":"i","ḯ":"i","ỉ":"i","ǐ":"i","ȉ":"i","ȋ":"i","ị":"i","į":"i","ḭ":"i","ɨ":"i","ı":"i","ⓙ":"j","j":"j","ĵ":"j","ǰ":"j","ɉ":"j","ⓚ":"k","k":"k","ḱ":"k","ǩ":"k","ḳ":"k","ķ":"k","ḵ":"k","ƙ":"k","ⱪ":"k","ꝁ":"k","ꝃ":"k","ꝅ":"k","ꞣ":"k","ⓛ":"l","l":"l","ŀ":"l","ĺ":"l","ľ":"l","ḷ":"l","ḹ":"l","ļ":"l","ḽ":"l","ḻ":"l","ſ":"l","ł":"l","ƚ":"l","ɫ":"l","ⱡ":"l","ꝉ":"l","ꞁ":"l","ꝇ":"l","lj":"lj","ⓜ":"m","m":"m","ḿ":"m","ṁ":"m","ṃ":"m","ɱ":"m","ɯ":"m","ⓝ":"n","n":"n","ǹ":"n","ń":"n","ñ":"n","ṅ":"n","ň":"n","ṇ":"n","ņ":"n","ṋ":"n","ṉ":"n","ƞ":"n","ɲ":"n","ʼn":"n","ꞑ":"n","ꞥ":"n","nj":"nj","ⓞ":"o","o":"o","ò":"o","ó":"o","ô":"o","ồ":"o","ố":"o","ỗ":"o","ổ":"o","õ":"o","ṍ":"o","ȭ":"o","ṏ":"o","ō":"o","ṑ":"o","ṓ":"o","ŏ":"o","ȯ":"o","ȱ":"o","ö":"o","ȫ":"o","ỏ":"o","ő":"o","ǒ":"o","ȍ":"o","ȏ":"o","ơ":"o","ờ":"o","ớ":"o","ỡ":"o","ở":"o","ợ":"o","ọ":"o","ộ":"o","ǫ":"o","ǭ":"o","ø":"o","ǿ":"o","ɔ":"o","ꝋ":"o","ꝍ":"o","ɵ":"o","ƣ":"oi","ȣ":"ou","ꝏ":"oo","ⓟ":"p","p":"p","ṕ":"p","ṗ":"p","ƥ":"p","ᵽ":"p","ꝑ":"p","ꝓ":"p","ꝕ":"p","ⓠ":"q","q":"q","ɋ":"q","ꝗ":"q","ꝙ":"q","ⓡ":"r","r":"r","ŕ":"r","ṙ":"r","ř":"r","ȑ":"r","ȓ":"r","ṛ":"r","ṝ":"r","ŗ":"r","ṟ":"r","ɍ":"r","ɽ":"r","ꝛ":"r","ꞧ":"r","ꞃ":"r","ⓢ":"s","s":"s","ß":"s","ś":"s","ṥ":"s","ŝ":"s","ṡ":"s","š":"s","ṧ":"s","ṣ":"s","ṩ":"s","ș":"s","ş":"s","ȿ":"s","ꞩ":"s","ꞅ":"s","ẛ":"s","ⓣ":"t","t":"t","ṫ":"t","ẗ":"t","ť":"t","ṭ":"t","ț":"t","ţ":"t","ṱ":"t","ṯ":"t","ŧ":"t","ƭ":"t","ʈ":"t","ⱦ":"t","ꞇ":"t","ꜩ":"tz","ⓤ":"u","u":"u","ù":"u","ú":"u","û":"u","ũ":"u","ṹ":"u","ū":"u","ṻ":"u","ŭ":"u","ü":"u","ǜ":"u","ǘ":"u","ǖ":"u","ǚ":"u","ủ":"u","ů":"u","ű":"u","ǔ":"u","ȕ":"u","ȗ":"u","ư":"u","ừ":"u","ứ":"u","ữ":"u","ử":"u","ự":"u","ụ":"u","ṳ":"u","ų":"u","ṷ":"u","ṵ":"u","ʉ":"u","ⓥ":"v","v":"v","ṽ":"v","ṿ":"v","ʋ":"v","ꝟ":"v","ʌ":"v","ꝡ":"vy","ⓦ":"w","w":"w","ẁ":"w","ẃ":"w","ŵ":"w","ẇ":"w","ẅ":"w","ẘ":"w","ẉ":"w","ⱳ":"w","ⓧ":"x","x":"x","ẋ":"x","ẍ":"x","ⓨ":"y","y":"y","ỳ":"y","ý":"y","ŷ":"y","ỹ":"y","ȳ":"y","ẏ":"y","ÿ":"y","ỷ":"y","ẙ":"y","ỵ":"y","ƴ":"y","ɏ":"y","ỿ":"y","ⓩ":"z","z":"z","ź":"z","ẑ":"z","ż":"z","ž":"z","ẓ":"z","ẕ":"z","ƶ":"z","ȥ":"z","ɀ":"z","ⱬ":"z","ꝣ":"z","Ά":"Α","Έ":"Ε","Ή":"Η","Ί":"Ι","Ϊ":"Ι","Ό":"Ο","Ύ":"Υ","Ϋ":"Υ","Ώ":"Ω","ά":"α","έ":"ε","ή":"η","ί":"ι","ϊ":"ι","ΐ":"ι","ό":"ο","ύ":"υ","ϋ":"υ","ΰ":"υ","ω":"ω","ς":"σ"};return a}),b.define("select2/data/base",["../utils"],function(a){function b(a,c){b.__super__.constructor.call(this)}return a.Extend(b,a.Observable),b.prototype.current=function(a){throw new Error("The `current` method must be defined in child classes.")},b.prototype.query=function(a,b){throw new Error("The `query` method must be defined in child classes.")},b.prototype.bind=function(a,b){},b.prototype.destroy=function(){},b.prototype.generateResultId=function(b,c){var d=b.id+"-result-";return d+=a.generateChars(4),d+=null!=c.id?"-"+c.id.toString():"-"+a.generateChars(4)},b}),b.define("select2/data/select",["./base","../utils","jquery"],function(a,b,c){function d(a,b){this.$element=a,this.options=b,d.__super__.constructor.call(this)}return b.Extend(d,a),d.prototype.current=function(a){var b=[],d=this;this.$element.find(":selected").each(function(){var a=c(this),e=d.item(a);b.push(e)}),a(b)},d.prototype.select=function(a){var b=this;if(a.selected=!0,c(a.element).is("option"))return a.element.selected=!0,void this.$element.trigger("change"); +if(this.$element.prop("multiple"))this.current(function(d){var e=[];a=[a],a.push.apply(a,d);for(var f=0;f=0){var k=f.filter(d(j)),l=this.item(k),m=c.extend(!0,{},j,l),n=this.option(m);k.replaceWith(n)}else{var o=this.option(j);if(j.children){var p=this.convertToOptions(j.children);b.appendMany(o,p)}h.push(o)}}return h},d}),b.define("select2/data/ajax",["./array","../utils","jquery"],function(a,b,c){function d(a,b){this.ajaxOptions=this._applyDefaults(b.get("ajax")),null!=this.ajaxOptions.processResults&&(this.processResults=this.ajaxOptions.processResults),d.__super__.constructor.call(this,a,b)}return b.Extend(d,a),d.prototype._applyDefaults=function(a){var b={data:function(a){return c.extend({},a,{q:a.term})},transport:function(a,b,d){var e=c.ajax(a);return e.then(b),e.fail(d),e}};return c.extend({},b,a,!0)},d.prototype.processResults=function(a){return a},d.prototype.query=function(a,b){function d(){var d=f.transport(f,function(d){var f=e.processResults(d,a);e.options.get("debug")&&window.console&&console.error&&(f&&f.results&&c.isArray(f.results)||console.error("Select2: The AJAX results did not return an array in the `results` key of the response.")),b(f)},function(){d.status&&"0"===d.status||e.trigger("results:message",{message:"errorLoading"})});e._request=d}var e=this;null!=this._request&&(c.isFunction(this._request.abort)&&this._request.abort(),this._request=null);var f=c.extend({type:"GET"},this.ajaxOptions);"function"==typeof f.url&&(f.url=f.url.call(this.$element,a)),"function"==typeof f.data&&(f.data=f.data.call(this.$element,a)),this.ajaxOptions.delay&&null!=a.term?(this._queryTimeout&&window.clearTimeout(this._queryTimeout),this._queryTimeout=window.setTimeout(d,this.ajaxOptions.delay)):d()},d}),b.define("select2/data/tags",["jquery"],function(a){function b(b,c,d){var e=d.get("tags"),f=d.get("createTag");void 0!==f&&(this.createTag=f);var g=d.get("insertTag");if(void 0!==g&&(this.insertTag=g),b.call(this,c,d),a.isArray(e))for(var h=0;h0&&b.term.length>this.maximumInputLength?void this.trigger("results:message",{message:"inputTooLong",args:{maximum:this.maximumInputLength,input:b.term,params:b}}):void a.call(this,b,c)},a}),b.define("select2/data/maximumSelectionLength",[],function(){function a(a,b,c){this.maximumSelectionLength=c.get("maximumSelectionLength"),a.call(this,b,c)}return a.prototype.query=function(a,b,c){var d=this;this.current(function(e){var f=null!=e?e.length:0;return d.maximumSelectionLength>0&&f>=d.maximumSelectionLength?void d.trigger("results:message",{message:"maximumSelected",args:{maximum:d.maximumSelectionLength}}):void a.call(d,b,c)})},a}),b.define("select2/dropdown",["jquery","./utils"],function(a,b){function c(a,b){this.$element=a,this.options=b,c.__super__.constructor.call(this)}return b.Extend(c,b.Observable),c.prototype.render=function(){var b=a('');return b.attr("dir",this.options.get("dir")),this.$dropdown=b,b},c.prototype.bind=function(){},c.prototype.position=function(a,b){},c.prototype.destroy=function(){this.$dropdown.remove()},c}),b.define("select2/dropdown/search",["jquery","../utils"],function(a,b){function c(){}return c.prototype.render=function(b){var c=b.call(this),d=a('');return this.$searchContainer=d,this.$search=d.find("input"),c.prepend(d),c},c.prototype.bind=function(b,c,d){var e=this;b.call(this,c,d),this.$search.on("keydown",function(a){e.trigger("keypress",a),e._keyUpPrevented=a.isDefaultPrevented()}),this.$search.on("input",function(b){a(this).off("keyup")}),this.$search.on("keyup input",function(a){e.handleSearch(a)}),c.on("open",function(){e.$search.attr("tabindex",0),e.$search.focus(),window.setTimeout(function(){e.$search.focus()},0)}),c.on("close",function(){e.$search.attr("tabindex",-1),e.$search.val("")}),c.on("focus",function(){c.isOpen()&&e.$search.focus()}),c.on("results:all",function(a){if(null==a.query.term||""===a.query.term){var b=e.showSearch(a);b?e.$searchContainer.removeClass("select2-search--hide"):e.$searchContainer.addClass("select2-search--hide")}})},c.prototype.handleSearch=function(a){if(!this._keyUpPrevented){var b=this.$search.val();this.trigger("query",{term:b})}this._keyUpPrevented=!1},c.prototype.showSearch=function(a,b){return!0},c}),b.define("select2/dropdown/hidePlaceholder",[],function(){function a(a,b,c,d){this.placeholder=this.normalizePlaceholder(c.get("placeholder")),a.call(this,b,c,d)}return a.prototype.append=function(a,b){b.results=this.removePlaceholder(b.results),a.call(this,b)},a.prototype.normalizePlaceholder=function(a,b){return"string"==typeof b&&(b={id:"",text:b}),b},a.prototype.removePlaceholder=function(a,b){for(var c=b.slice(0),d=b.length-1;d>=0;d--){var e=b[d];this.placeholder.id===e.id&&c.splice(d,1)}return c},a}),b.define("select2/dropdown/infiniteScroll",["jquery"],function(a){function b(a,b,c,d){this.lastParams={},a.call(this,b,c,d),this.$loadingMore=this.createLoadingMore(),this.loading=!1}return b.prototype.append=function(a,b){this.$loadingMore.remove(),this.loading=!1,a.call(this,b),this.showLoadingMore(b)&&this.$results.append(this.$loadingMore)},b.prototype.bind=function(b,c,d){var e=this;b.call(this,c,d),c.on("query",function(a){e.lastParams=a,e.loading=!0}),c.on("query:append",function(a){e.lastParams=a,e.loading=!0}),this.$results.on("scroll",function(){var b=a.contains(document.documentElement,e.$loadingMore[0]);if(!e.loading&&b){var c=e.$results.offset().top+e.$results.outerHeight(!1),d=e.$loadingMore.offset().top+e.$loadingMore.outerHeight(!1);c+50>=d&&e.loadMore()}})},b.prototype.loadMore=function(){this.loading=!0;var b=a.extend({},{page:1},this.lastParams);b.page++,this.trigger("query:append",b)},b.prototype.showLoadingMore=function(a,b){return b.pagination&&b.pagination.more},b.prototype.createLoadingMore=function(){var b=a('
          • '),c=this.options.get("translations").get("loadingMore");return b.html(c(this.lastParams)),b},b}),b.define("select2/dropdown/attachBody",["jquery","../utils"],function(a,b){function c(b,c,d){this.$dropdownParent=d.get("dropdownParent")||a(document.body),b.call(this,c,d)}return c.prototype.bind=function(a,b,c){var d=this,e=!1;a.call(this,b,c),b.on("open",function(){d._showDropdown(),d._attachPositioningHandler(b),e||(e=!0,b.on("results:all",function(){d._positionDropdown(),d._resizeDropdown()}),b.on("results:append",function(){d._positionDropdown(),d._resizeDropdown()}))}),b.on("close",function(){d._hideDropdown(),d._detachPositioningHandler(b)}),this.$dropdownContainer.on("mousedown",function(a){a.stopPropagation()})},c.prototype.destroy=function(a){a.call(this),this.$dropdownContainer.remove()},c.prototype.position=function(a,b,c){b.attr("class",c.attr("class")),b.removeClass("select2"),b.addClass("select2-container--open"),b.css({position:"absolute",top:-999999}),this.$container=c},c.prototype.render=function(b){var c=a(""),d=b.call(this);return c.append(d),this.$dropdownContainer=c,c},c.prototype._hideDropdown=function(a){this.$dropdownContainer.detach()},c.prototype._attachPositioningHandler=function(c,d){var e=this,f="scroll.select2."+d.id,g="resize.select2."+d.id,h="orientationchange.select2."+d.id,i=this.$container.parents().filter(b.hasScroll);i.each(function(){a(this).data("select2-scroll-position",{x:a(this).scrollLeft(),y:a(this).scrollTop()})}),i.on(f,function(b){var c=a(this).data("select2-scroll-position");a(this).scrollTop(c.y)}),a(window).on(f+" "+g+" "+h,function(a){e._positionDropdown(),e._resizeDropdown()})},c.prototype._detachPositioningHandler=function(c,d){var e="scroll.select2."+d.id,f="resize.select2."+d.id,g="orientationchange.select2."+d.id,h=this.$container.parents().filter(b.hasScroll);h.off(e),a(window).off(e+" "+f+" "+g)},c.prototype._positionDropdown=function(){var b=a(window),c=this.$dropdown.hasClass("select2-dropdown--above"),d=this.$dropdown.hasClass("select2-dropdown--below"),e=null,f=this.$container.offset();f.bottom=f.top+this.$container.outerHeight(!1);var g={height:this.$container.outerHeight(!1)};g.top=f.top,g.bottom=f.top+g.height;var h={height:this.$dropdown.outerHeight(!1)},i={top:b.scrollTop(),bottom:b.scrollTop()+b.height()},j=i.topf.bottom+h.height,l={left:f.left,top:g.bottom},m=this.$dropdownParent;"static"===m.css("position")&&(m=m.offsetParent());var n=m.offset();l.top-=n.top,l.left-=n.left,c||d||(e="below"),k||!j||c?!j&&k&&c&&(e="below"):e="above",("above"==e||c&&"below"!==e)&&(l.top=g.top-n.top-h.height),null!=e&&(this.$dropdown.removeClass("select2-dropdown--below select2-dropdown--above").addClass("select2-dropdown--"+e),this.$container.removeClass("select2-container--below select2-container--above").addClass("select2-container--"+e)),this.$dropdownContainer.css(l)},c.prototype._resizeDropdown=function(){var a={width:this.$container.outerWidth(!1)+"px"};this.options.get("dropdownAutoWidth")&&(a.minWidth=a.width,a.position="relative",a.width="auto"),this.$dropdown.css(a)},c.prototype._showDropdown=function(a){this.$dropdownContainer.appendTo(this.$dropdownParent),this._positionDropdown(),this._resizeDropdown()},c}),b.define("select2/dropdown/minimumResultsForSearch",[],function(){function a(b){for(var c=0,d=0;d0&&(l.dataAdapter=j.Decorate(l.dataAdapter,r)),l.maximumInputLength>0&&(l.dataAdapter=j.Decorate(l.dataAdapter,s)),l.maximumSelectionLength>0&&(l.dataAdapter=j.Decorate(l.dataAdapter,t)),l.tags&&(l.dataAdapter=j.Decorate(l.dataAdapter,p)),(null!=l.tokenSeparators||null!=l.tokenizer)&&(l.dataAdapter=j.Decorate(l.dataAdapter,q)),null!=l.query){var C=b(l.amdBase+"compat/query");l.dataAdapter=j.Decorate(l.dataAdapter,C)}if(null!=l.initSelection){var D=b(l.amdBase+"compat/initSelection");l.dataAdapter=j.Decorate(l.dataAdapter,D)}}if(null==l.resultsAdapter&&(l.resultsAdapter=c,null!=l.ajax&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,x)),null!=l.placeholder&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,w)),l.selectOnClose&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,A))),null==l.dropdownAdapter){if(l.multiple)l.dropdownAdapter=u;else{var E=j.Decorate(u,v);l.dropdownAdapter=E}if(0!==l.minimumResultsForSearch&&(l.dropdownAdapter=j.Decorate(l.dropdownAdapter,z)),l.closeOnSelect&&(l.dropdownAdapter=j.Decorate(l.dropdownAdapter,B)),null!=l.dropdownCssClass||null!=l.dropdownCss||null!=l.adaptDropdownCssClass){var F=b(l.amdBase+"compat/dropdownCss");l.dropdownAdapter=j.Decorate(l.dropdownAdapter,F)}l.dropdownAdapter=j.Decorate(l.dropdownAdapter,y)}if(null==l.selectionAdapter){if(l.multiple?l.selectionAdapter=e:l.selectionAdapter=d,null!=l.placeholder&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,f)),l.allowClear&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,g)),l.multiple&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,h)),null!=l.containerCssClass||null!=l.containerCss||null!=l.adaptContainerCssClass){var G=b(l.amdBase+"compat/containerCss");l.selectionAdapter=j.Decorate(l.selectionAdapter,G)}l.selectionAdapter=j.Decorate(l.selectionAdapter,i)}if("string"==typeof l.language)if(l.language.indexOf("-")>0){var H=l.language.split("-"),I=H[0];l.language=[l.language,I]}else l.language=[l.language];if(a.isArray(l.language)){var J=new k;l.language.push("en");for(var K=l.language,L=0;L0){for(var f=a.extend(!0,{},e),g=e.children.length-1;g>=0;g--){var h=e.children[g],i=c(d,h);null==i&&f.children.splice(g,1)}return f.children.length>0?f:c(d,f)}var j=b(e.text).toUpperCase(),k=b(d.term).toUpperCase();return j.indexOf(k)>-1?e:null}this.defaults={amdBase:"./",amdLanguageBase:"./i18n/",closeOnSelect:!0,debug:!1,dropdownAutoWidth:!1,escapeMarkup:j.escapeMarkup,language:C,matcher:c,minimumInputLength:0,maximumInputLength:0,maximumSelectionLength:0,minimumResultsForSearch:0,selectOnClose:!1,sorter:function(a){return a},templateResult:function(a){return a.text},templateSelection:function(a){return a.text},theme:"default",width:"resolve"}},D.prototype.set=function(b,c){var d=a.camelCase(b),e={};e[d]=c;var f=j._convertData(e);a.extend(this.defaults,f)};var E=new D;return E}),b.define("select2/options",["require","jquery","./defaults","./utils"],function(a,b,c,d){function e(b,e){if(this.options=b,null!=e&&this.fromElement(e),this.options=c.apply(this.options),e&&e.is("input")){var f=a(this.get("amdBase")+"compat/inputData");this.options.dataAdapter=d.Decorate(this.options.dataAdapter,f)}}return e.prototype.fromElement=function(a){var c=["select2"];null==this.options.multiple&&(this.options.multiple=a.prop("multiple")),null==this.options.disabled&&(this.options.disabled=a.prop("disabled")),null==this.options.language&&(a.prop("lang")?this.options.language=a.prop("lang").toLowerCase():a.closest("[lang]").prop("lang")&&(this.options.language=a.closest("[lang]").prop("lang"))),null==this.options.dir&&(a.prop("dir")?this.options.dir=a.prop("dir"):a.closest("[dir]").prop("dir")?this.options.dir=a.closest("[dir]").prop("dir"):this.options.dir="ltr"),a.prop("disabled",this.options.disabled),a.prop("multiple",this.options.multiple),a.data("select2Tags")&&(this.options.debug&&window.console&&console.warn&&console.warn('Select2: The `data-select2-tags` attribute has been changed to use the `data-data` and `data-tags="true"` attributes and will be removed in future versions of Select2.'),a.data("data",a.data("select2Tags")),a.data("tags",!0)),a.data("ajaxUrl")&&(this.options.debug&&window.console&&console.warn&&console.warn("Select2: The `data-ajax-url` attribute has been changed to `data-ajax--url` and support for the old attribute will be removed in future versions of Select2."),a.attr("ajax--url",a.data("ajaxUrl")),a.data("ajax--url",a.data("ajaxUrl")));var e={};e=b.fn.jquery&&"1."==b.fn.jquery.substr(0,2)&&a[0].dataset?b.extend(!0,{},a[0].dataset,a.data()):a.data();var f=b.extend(!0,{},e);f=d._convertData(f);for(var g in f)b.inArray(g,c)>-1||(b.isPlainObject(this.options[g])?b.extend(this.options[g],f[g]):this.options[g]=f[g]);return this},e.prototype.get=function(a){return this.options[a]},e.prototype.set=function(a,b){this.options[a]=b},e}),b.define("select2/core",["jquery","./options","./utils","./keys"],function(a,b,c,d){var e=function(a,c){null!=a.data("select2")&&a.data("select2").destroy(),this.$element=a,this.id=this._generateId(a),c=c||{},this.options=new b(c,a),e.__super__.constructor.call(this);var d=a.attr("tabindex")||0;a.data("old-tabindex",d),a.attr("tabindex","-1");var f=this.options.get("dataAdapter");this.dataAdapter=new f(a,this.options);var g=this.render();this._placeContainer(g);var h=this.options.get("selectionAdapter");this.selection=new h(a,this.options),this.$selection=this.selection.render(),this.selection.position(this.$selection,g);var i=this.options.get("dropdownAdapter");this.dropdown=new i(a,this.options),this.$dropdown=this.dropdown.render(),this.dropdown.position(this.$dropdown,g);var j=this.options.get("resultsAdapter");this.results=new j(a,this.options,this.dataAdapter),this.$results=this.results.render(),this.results.position(this.$results,this.$dropdown);var k=this;this._bindAdapters(),this._registerDomEvents(),this._registerDataEvents(),this._registerSelectionEvents(),this._registerDropdownEvents(),this._registerResultsEvents(),this._registerEvents(),this.dataAdapter.current(function(a){k.trigger("selection:update",{data:a})}),a.addClass("select2-hidden-accessible"),a.attr("aria-hidden","true"),this._syncAttributes(),a.data("select2",this)};return c.Extend(e,c.Observable),e.prototype._generateId=function(a){var b="";return b=null!=a.attr("id")?a.attr("id"):null!=a.attr("name")?a.attr("name")+"-"+c.generateChars(2):c.generateChars(4),b=b.replace(/(:|\.|\[|\]|,)/g,""),b="select2-"+b},e.prototype._placeContainer=function(a){a.insertAfter(this.$element);var b=this._resolveWidth(this.$element,this.options.get("width"));null!=b&&a.css("width",b)},e.prototype._resolveWidth=function(a,b){var c=/^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i;if("resolve"==b){var d=this._resolveWidth(a,"style");return null!=d?d:this._resolveWidth(a,"element")}if("element"==b){var e=a.outerWidth(!1);return 0>=e?"auto":e+"px"}if("style"==b){var f=a.attr("style");if("string"!=typeof f)return null;for(var g=f.split(";"),h=0,i=g.length;i>h;h+=1){var j=g[h].replace(/\s/g,""),k=j.match(c);if(null!==k&&k.length>=1)return k[1]}return null}return b},e.prototype._bindAdapters=function(){this.dataAdapter.bind(this,this.$container),this.selection.bind(this,this.$container),this.dropdown.bind(this,this.$container),this.results.bind(this,this.$container)},e.prototype._registerDomEvents=function(){var b=this;this.$element.on("change.select2",function(){b.dataAdapter.current(function(a){b.trigger("selection:update",{data:a})})}),this.$element.on("focus.select2",function(a){b.trigger("focus",a)}),this._syncA=c.bind(this._syncAttributes,this),this._syncS=c.bind(this._syncSubtree,this),this.$element[0].attachEvent&&this.$element[0].attachEvent("onpropertychange",this._syncA);var d=window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver;null!=d?(this._observer=new d(function(c){a.each(c,b._syncA),a.each(c,b._syncS)}),this._observer.observe(this.$element[0],{attributes:!0,childList:!0,subtree:!1})):this.$element[0].addEventListener&&(this.$element[0].addEventListener("DOMAttrModified",b._syncA,!1),this.$element[0].addEventListener("DOMNodeInserted",b._syncS,!1),this.$element[0].addEventListener("DOMNodeRemoved",b._syncS,!1))},e.prototype._registerDataEvents=function(){var a=this;this.dataAdapter.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerSelectionEvents=function(){var b=this,c=["toggle","focus"];this.selection.on("toggle",function(){b.toggleDropdown()}),this.selection.on("focus",function(a){b.focus(a)}),this.selection.on("*",function(d,e){-1===a.inArray(d,c)&&b.trigger(d,e)})},e.prototype._registerDropdownEvents=function(){var a=this;this.dropdown.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerResultsEvents=function(){var a=this;this.results.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerEvents=function(){var a=this;this.on("open",function(){a.$container.addClass("select2-container--open")}),this.on("close",function(){a.$container.removeClass("select2-container--open")}),this.on("enable",function(){a.$container.removeClass("select2-container--disabled")}),this.on("disable",function(){a.$container.addClass("select2-container--disabled")}),this.on("blur",function(){a.$container.removeClass("select2-container--focus")}),this.on("query",function(b){a.isOpen()||a.trigger("open",{}),this.dataAdapter.query(b,function(c){a.trigger("results:all",{data:c,query:b})})}),this.on("query:append",function(b){this.dataAdapter.query(b,function(c){a.trigger("results:append",{data:c,query:b})})}),this.on("keypress",function(b){var c=b.which;a.isOpen()?c===d.ESC||c===d.TAB||c===d.UP&&b.altKey?(a.close(),b.preventDefault()):c===d.ENTER?(a.trigger("results:select",{}),b.preventDefault()):c===d.SPACE&&b.ctrlKey?(a.trigger("results:toggle",{}),b.preventDefault()):c===d.UP?(a.trigger("results:previous",{}),b.preventDefault()):c===d.DOWN&&(a.trigger("results:next",{}),b.preventDefault()):(c===d.ENTER||c===d.SPACE||c===d.DOWN&&b.altKey)&&(a.open(),b.preventDefault())})},e.prototype._syncAttributes=function(){this.options.set("disabled",this.$element.prop("disabled")),this.options.get("disabled")?(this.isOpen()&&this.close(),this.trigger("disable",{})):this.trigger("enable",{})},e.prototype._syncSubtree=function(a,b){var c=!1,d=this;if(!a||!a.target||"OPTION"===a.target.nodeName||"OPTGROUP"===a.target.nodeName){if(b)if(b.addedNodes&&b.addedNodes.length>0)for(var e=0;e0&&(c=!0);else c=!0;c&&this.dataAdapter.current(function(a){d.trigger("selection:update",{data:a})})}},e.prototype.trigger=function(a,b){var c=e.__super__.trigger,d={open:"opening",close:"closing",select:"selecting",unselect:"unselecting"};if(void 0===b&&(b={}),a in d){var f=d[a],g={prevented:!1,name:a,args:b};if(c.call(this,f,g),g.prevented)return void(b.prevented=!0)}c.call(this,a,b)},e.prototype.toggleDropdown=function(){this.options.get("disabled")||(this.isOpen()?this.close():this.open())},e.prototype.open=function(){this.isOpen()||this.trigger("query",{})},e.prototype.close=function(){this.isOpen()&&this.trigger("close",{})},e.prototype.isOpen=function(){return this.$container.hasClass("select2-container--open")},e.prototype.hasFocus=function(){return this.$container.hasClass("select2-container--focus")},e.prototype.focus=function(a){this.hasFocus()||(this.$container.addClass("select2-container--focus"),this.trigger("focus",{}))},e.prototype.enable=function(a){this.options.get("debug")&&window.console&&console.warn&&console.warn('Select2: The `select2("enable")` method has been deprecated and will be removed in later Select2 versions. Use $element.prop("disabled") instead.'),(null==a||0===a.length)&&(a=[!0]);var b=!a[0];this.$element.prop("disabled",b)},e.prototype.data=function(){this.options.get("debug")&&arguments.length>0&&window.console&&console.warn&&console.warn('Select2: Data can no longer be set using `select2("data")`. You should consider setting the value instead using `$element.val()`.');var a=[];return this.dataAdapter.current(function(b){a=b}),a},e.prototype.val=function(b){if(this.options.get("debug")&&window.console&&console.warn&&console.warn('Select2: The `select2("val")` method has been deprecated and will be removed in later Select2 versions. Use $element.val() instead.'),null==b||0===b.length)return this.$element.val();var c=b[0];a.isArray(c)&&(c=a.map(c,function(a){return a.toString()})),this.$element.val(c).trigger("change")},e.prototype.destroy=function(){this.$container.remove(),this.$element[0].detachEvent&&this.$element[0].detachEvent("onpropertychange",this._syncA),null!=this._observer?(this._observer.disconnect(),this._observer=null):this.$element[0].removeEventListener&&(this.$element[0].removeEventListener("DOMAttrModified",this._syncA,!1),this.$element[0].removeEventListener("DOMNodeInserted",this._syncS,!1),this.$element[0].removeEventListener("DOMNodeRemoved",this._syncS,!1)),this._syncA=null,this._syncS=null,this.$element.off(".select2"),this.$element.attr("tabindex",this.$element.data("old-tabindex")),this.$element.removeClass("select2-hidden-accessible"),this.$element.attr("aria-hidden","false"),this.$element.removeData("select2"),this.dataAdapter.destroy(),this.selection.destroy(),this.dropdown.destroy(),this.results.destroy(),this.dataAdapter=null,this.selection=null,this.dropdown=null,this.results=null; },e.prototype.render=function(){var b=a('');return b.attr("dir",this.options.get("dir")),this.$container=b,this.$container.addClass("select2-container--"+this.options.get("theme")),b.data("element",this.$element),b},e}),b.define("jquery-mousewheel",["jquery"],function(a){return a}),b.define("jquery.select2",["jquery","jquery-mousewheel","./select2/core","./select2/defaults"],function(a,b,c,d){if(null==a.fn.select2){var e=["open","close","destroy"];a.fn.select2=function(b){if(b=b||{},"object"==typeof b)return this.each(function(){var d=a.extend(!0,{},b);new c(a(this),d)}),this;if("string"==typeof b){var d,f=Array.prototype.slice.call(arguments,1);return this.each(function(){var c=a(this).data("select2");null==c&&window.console&&console.error&&console.error("The select2('"+b+"') method was called on an element that is not using Select2."),d=c[b].apply(c,f)}),a.inArray(b,e)>-1?this:d}throw new Error("Invalid arguments for Select2: "+b)}}return null==a.fn.select2.defaults&&(a.fn.select2.defaults=d),c}),{define:b.define,require:b.require}}(),c=b.require("jquery.select2");return a.fn.select2.amd=b,c}); \ No newline at end of file diff --git a/profile-builder/assets/lib/Mustache/Autoloader.php b/profile-builder/assets/lib/Mustache/Autoloader.php index 2a209dd..fa83e7f 100644 --- a/profile-builder/assets/lib/Mustache/Autoloader.php +++ b/profile-builder/assets/lib/Mustache/Autoloader.php @@ -1,75 +1,75 @@ -baseDir = $realDir; - } else { - $this->baseDir = $baseDir; - } - } - - /** - * Register a new instance as an SPL autoloader. - * - * @param string $baseDir Mustache library base directory (default: dirname(__FILE__).'/..') - * - * @return Mustache_Autoloader Registered Autoloader instance - */ - public static function register($baseDir = null) - { - $loader = new self($baseDir); - spl_autoload_register(array($loader, 'autoload')); - - return $loader; - } - - /** - * Autoload Mustache classes. - * - * @param string $class - */ - public function autoload($class) - { - if ($class[0] === '\\') { - $class = substr($class, 1); - } - - if (strpos($class, 'Mustache') !== 0) { - return; - } - - $file = sprintf('%s/%s.php', $this->baseDir, str_replace('_', '/', $class)); - if (is_file($file)) { - require $file; - } - } -} +baseDir = $realDir; + } else { + $this->baseDir = $baseDir; + } + } + + /** + * Register a new instance as an SPL autoloader. + * + * @param string $baseDir Mustache library base directory (default: dirname(__FILE__).'/..') + * + * @return Mustache_Autoloader Registered Autoloader instance + */ + public static function register($baseDir = null) + { + $loader = new self($baseDir); + spl_autoload_register(array($loader, 'autoload')); + + return $loader; + } + + /** + * Autoload Mustache classes. + * + * @param string $class + */ + public function autoload($class) + { + if ($class[0] === '\\') { + $class = substr($class, 1); + } + + if (strpos($class, 'Mustache') !== 0) { + return; + } + + $file = sprintf('%s/%s.php', $this->baseDir, str_replace('_', '/', $class)); + if (is_file($file)) { + require $file; + } + } +} diff --git a/profile-builder/assets/lib/Mustache/Compiler.php b/profile-builder/assets/lib/Mustache/Compiler.php index a30e6f5..4cfb388 100644 --- a/profile-builder/assets/lib/Mustache/Compiler.php +++ b/profile-builder/assets/lib/Mustache/Compiler.php @@ -1,476 +1,476 @@ -pragmas = array(); - $this->sections = array(); - $this->source = $source; - $this->indentNextLine = true; - $this->customEscape = $customEscape; - $this->entityFlags = $entityFlags; - $this->charset = $charset; - $this->strictCallables = $strictCallables; - - return $this->writeCode($tree, $name); - } - - /** - * Helper function for walking the Mustache token parse tree. - * - * @throws Mustache_Exception_SyntaxException upon encountering unknown token types. - * - * @param array $tree Parse tree of Mustache tokens - * @param int $level (default: 0) - * - * @return string Generated PHP source code - */ - private function walk(array $tree, $level = 0) - { - $code = ''; - $level++; - foreach ($tree as $node) { - switch ($node[Mustache_Tokenizer::TYPE]) { - case Mustache_Tokenizer::T_PRAGMA: - $this->pragmas[$node[Mustache_Tokenizer::NAME]] = true; - break; - - case Mustache_Tokenizer::T_SECTION: - $code .= $this->section( - $node[Mustache_Tokenizer::NODES], - $node[Mustache_Tokenizer::NAME], - $node[Mustache_Tokenizer::INDEX], - $node[Mustache_Tokenizer::END], - $node[Mustache_Tokenizer::OTAG], - $node[Mustache_Tokenizer::CTAG], - $level - ); - break; - - case Mustache_Tokenizer::T_INVERTED: - $code .= $this->invertedSection( - $node[Mustache_Tokenizer::NODES], - $node[Mustache_Tokenizer::NAME], - $level - ); - break; - - case Mustache_Tokenizer::T_PARTIAL: - case Mustache_Tokenizer::T_PARTIAL_2: - $code .= $this->partial( - $node[Mustache_Tokenizer::NAME], - isset($node[Mustache_Tokenizer::INDENT]) ? $node[Mustache_Tokenizer::INDENT] : '', - $level - ); - break; - - case Mustache_Tokenizer::T_UNESCAPED: - case Mustache_Tokenizer::T_UNESCAPED_2: - $code .= $this->variable($node[Mustache_Tokenizer::NAME], false, $level); - break; - - case Mustache_Tokenizer::T_COMMENT: - break; - - case Mustache_Tokenizer::T_ESCAPED: - $code .= $this->variable($node[Mustache_Tokenizer::NAME], true, $level); - break; - - case Mustache_Tokenizer::T_TEXT: - $code .= $this->text($node[Mustache_Tokenizer::VALUE], $level); - break; - - default: - throw new Mustache_Exception_SyntaxException(sprintf('Unknown token type: %s', $node[Mustache_Tokenizer::TYPE]), $node); - } - } - - return $code; - } - - const KLASS = 'lambdaHelper = new Mustache_LambdaHelper($this->mustache, $context); - $buffer = \'\'; - %s - - return $buffer; - } - %s - }'; - - const KLASS_NO_LAMBDAS = 'walk($tree); - $sections = implode("\n", $this->sections); - $klass = empty($this->sections) ? self::KLASS_NO_LAMBDAS : self::KLASS; - $callable = $this->strictCallables ? $this->prepare(self::STRICT_CALLABLE) : ''; - - return sprintf($this->prepare($klass, 0, false, true), $name, $callable, $code, $sections); - } - - const SECTION_CALL = ' - // %s section - $buffer .= $this->section%s($context, $indent, $context->%s(%s)); - '; - - const SECTION = ' - private function section%s(Mustache_Context $context, $indent, $value) - { - $buffer = \'\'; - if (%s) { - $source = %s; - $buffer .= $this->mustache - ->loadLambda((string) call_user_func($value, $source, $this->lambdaHelper)%s) - ->renderInternal($context); - } elseif (!empty($value)) { - $values = $this->isIterable($value) ? $value : array($value); - foreach ($values as $value) { - $context->push($value);%s - $context->pop(); - } - } - - return $buffer; - }'; - - /** - * Generate Mustache Template section PHP source. - * - * @param array $nodes Array of child tokens - * @param string $id Section name - * @param int $start Section start offset - * @param int $end Section end offset - * @param string $otag Current Mustache opening tag - * @param string $ctag Current Mustache closing tag - * @param int $level - * - * @return string Generated section PHP source code - */ - private function section($nodes, $id, $start, $end, $otag, $ctag, $level) - { - $method = $this->getFindMethod($id); - $id = var_export($id, true); - $source = var_export(substr($this->source, $start, $end - $start), true); - $callable = $this->getCallable(); - - if ($otag !== '{{' || $ctag !== '}}') { - $delims = ', '.var_export(sprintf('{{= %s %s =}}', $otag, $ctag), true); - } else { - $delims = ''; - } - - $key = ucfirst(md5($delims."\n".$source)); - - if (!isset($this->sections[$key])) { - $this->sections[$key] = sprintf($this->prepare(self::SECTION), $key, $callable, $source, $delims, $this->walk($nodes, 2)); - } - - return sprintf($this->prepare(self::SECTION_CALL, $level), $id, $key, $method, $id); - } - - const INVERTED_SECTION = ' - // %s inverted section - $value = $context->%s(%s); - if (empty($value)) { - %s - }'; - - /** - * Generate Mustache Template inverted section PHP source. - * - * @param array $nodes Array of child tokens - * @param string $id Section name - * @param int $level - * - * @return string Generated inverted section PHP source code - */ - private function invertedSection($nodes, $id, $level) - { - $method = $this->getFindMethod($id); - $id = var_export($id, true); - - return sprintf($this->prepare(self::INVERTED_SECTION, $level), $id, $method, $id, $this->walk($nodes, $level)); - } - - const PARTIAL = ' - if ($partial = $this->mustache->loadPartial(%s)) { - $buffer .= $partial->renderInternal($context, %s); - } - '; - - /** - * Generate Mustache Template partial call PHP source. - * - * @param string $id Partial name - * @param string $indent Whitespace indent to apply to partial - * @param int $level - * - * @return string Generated partial call PHP source code - */ - private function partial($id, $indent, $level) - { - return sprintf( - $this->prepare(self::PARTIAL, $level), - var_export($id, true), - var_export($indent, true) - ); - } - - const VARIABLE = ' - $value = $this->resolveValue($context->%s(%s), $context, $indent);%s - $buffer .= %s%s; - '; - - /** - * Generate Mustache Template variable interpolation PHP source. - * - * @param string $id Variable name - * @param boolean $escape Escape the variable value for output? - * @param int $level - * - * @return string Generated variable interpolation PHP source - */ - private function variable($id, $escape, $level) - { - $filters = ''; - - if (isset($this->pragmas[Mustache_Engine::PRAGMA_FILTERS])) { - list($id, $filters) = $this->getFilters($id, $level); - } - - $method = $this->getFindMethod($id); - $id = ($method !== 'last') ? var_export($id, true) : ''; - $value = $escape ? $this->getEscape() : '$value'; - - return sprintf($this->prepare(self::VARIABLE, $level), $method, $id, $filters, $this->flushIndent(), $value); - } - - /** - * Generate Mustache Template variable filtering PHP source. - * - * @param string $id Variable name - * @param int $level - * - * @return string Generated variable filtering PHP source - */ - private function getFilters($id, $level) - { - $filters = array_map('trim', explode('|', $id)); - $id = array_shift($filters); - - return array($id, $this->getFilter($filters, $level)); - } - - const FILTER = ' - $filter = $context->%s(%s); - if (!(%s)) { - throw new Mustache_Exception_UnknownFilterException(%s); - } - $value = call_user_func($filter, $value);%s - '; - - /** - * Generate PHP source for a single filter. - * - * @param array $filters - * @param int $level - * - * @return string Generated filter PHP source - */ - private function getFilter(array $filters, $level) - { - if (empty($filters)) { - return ''; - } - - $name = array_shift($filters); - $method = $this->getFindMethod($name); - $filter = ($method !== 'last') ? var_export($name, true) : ''; - $callable = $this->getCallable('$filter'); - $msg = var_export($name, true); - - return sprintf($this->prepare(self::FILTER, $level), $method, $filter, $callable, $msg, $this->getFilter($filters, $level)); - } - - const LINE = '$buffer .= "\n";'; - const TEXT = '$buffer .= %s%s;'; - - /** - * Generate Mustache Template output Buffer call PHP source. - * - * @param string $text - * @param int $level - * - * @return string Generated output Buffer call PHP source - */ - private function text($text, $level) - { - $indentNextLine = (substr($text, -1) === "\n"); - $code = sprintf($this->prepare(self::TEXT, $level), $this->flushIndent(), var_export($text, true)); - $this->indentNextLine = $indentNextLine; - - return $code; - } - - /** - * Prepare PHP source code snippet for output. - * - * @param string $text - * @param int $bonus Additional indent level (default: 0) - * @param boolean $prependNewline Prepend a newline to the snippet? (default: true) - * @param boolean $appendNewline Append a newline to the snippet? (default: false) - * - * @return string PHP source code snippet - */ - private function prepare($text, $bonus = 0, $prependNewline = true, $appendNewline = false) - { - $text = ($prependNewline ? "\n" : '').trim($text); - if ($prependNewline) { - $bonus++; - } - if ($appendNewline) { - $text .= "\n"; - } - - return preg_replace("/\n( {8})?/", "\n".str_repeat(" ", $bonus * 4), $text); - } - - const DEFAULT_ESCAPE = 'htmlspecialchars(%s, %s, %s)'; - const CUSTOM_ESCAPE = 'call_user_func($this->mustache->getEscape(), %s)'; - - /** - * Get the current escaper. - * - * @param string $value (default: '$value') - * - * @return string Either a custom callback, or an inline call to `htmlspecialchars` - */ - private function getEscape($value = '$value') - { - if ($this->customEscape) { - return sprintf(self::CUSTOM_ESCAPE, $value); - } else { - return sprintf(self::DEFAULT_ESCAPE, $value, var_export($this->entityFlags, true), var_export($this->charset, true)); - } - } - - /** - * Select the appropriate Context `find` method for a given $id. - * - * The return value will be one of `find`, `findDot` or `last`. - * - * @see Mustache_Context::find - * @see Mustache_Context::findDot - * @see Mustache_Context::last - * - * @param string $id Variable name - * - * @return string `find` method name - */ - private function getFindMethod($id) - { - if ($id === '.') { - return 'last'; - } elseif (strpos($id, '.') === false) { - return 'find'; - } else { - return 'findDot'; - } - } - - const IS_CALLABLE = '!is_string(%s) && is_callable(%s)'; - const STRICT_IS_CALLABLE = 'is_object(%s) && is_callable(%s)'; - - private function getCallable($variable = '$value') - { - $tpl = $this->strictCallables ? self::STRICT_IS_CALLABLE : self::IS_CALLABLE; - - return sprintf($tpl, $variable, $variable); - } - - const LINE_INDENT = '$indent . '; - - /** - * Get the current $indent prefix to write to the buffer. - * - * @return string "$indent . " or "" - */ - private function flushIndent() - { - if (!$this->indentNextLine) { - return ''; - } - - $this->indentNextLine = false; - - return self::LINE_INDENT; - } -} +pragmas = array(); + $this->sections = array(); + $this->source = $source; + $this->indentNextLine = true; + $this->customEscape = $customEscape; + $this->entityFlags = $entityFlags; + $this->charset = $charset; + $this->strictCallables = $strictCallables; + + return $this->writeCode($tree, $name); + } + + /** + * Helper function for walking the Mustache token parse tree. + * + * @throws Mustache_Exception_SyntaxException upon encountering unknown token types. + * + * @param array $tree Parse tree of Mustache tokens + * @param int $level (default: 0) + * + * @return string Generated PHP source code + */ + private function walk(array $tree, $level = 0) + { + $code = ''; + $level++; + foreach ($tree as $node) { + switch ($node[Mustache_Tokenizer::TYPE]) { + case Mustache_Tokenizer::T_PRAGMA: + $this->pragmas[$node[Mustache_Tokenizer::NAME]] = true; + break; + + case Mustache_Tokenizer::T_SECTION: + $code .= $this->section( + $node[Mustache_Tokenizer::NODES], + $node[Mustache_Tokenizer::NAME], + $node[Mustache_Tokenizer::INDEX], + $node[Mustache_Tokenizer::END], + $node[Mustache_Tokenizer::OTAG], + $node[Mustache_Tokenizer::CTAG], + $level + ); + break; + + case Mustache_Tokenizer::T_INVERTED: + $code .= $this->invertedSection( + $node[Mustache_Tokenizer::NODES], + $node[Mustache_Tokenizer::NAME], + $level + ); + break; + + case Mustache_Tokenizer::T_PARTIAL: + case Mustache_Tokenizer::T_PARTIAL_2: + $code .= $this->partial( + $node[Mustache_Tokenizer::NAME], + isset($node[Mustache_Tokenizer::INDENT]) ? $node[Mustache_Tokenizer::INDENT] : '', + $level + ); + break; + + case Mustache_Tokenizer::T_UNESCAPED: + case Mustache_Tokenizer::T_UNESCAPED_2: + $code .= $this->variable($node[Mustache_Tokenizer::NAME], false, $level); + break; + + case Mustache_Tokenizer::T_COMMENT: + break; + + case Mustache_Tokenizer::T_ESCAPED: + $code .= $this->variable($node[Mustache_Tokenizer::NAME], true, $level); + break; + + case Mustache_Tokenizer::T_TEXT: + $code .= $this->text($node[Mustache_Tokenizer::VALUE], $level); + break; + + default: + throw new Mustache_Exception_SyntaxException(sprintf('Unknown token type: %s', $node[Mustache_Tokenizer::TYPE]), $node); + } + } + + return $code; + } + + const KLASS = 'lambdaHelper = new Mustache_LambdaHelper($this->mustache, $context); + $buffer = \'\'; + %s + + return $buffer; + } + %s + }'; + + const KLASS_NO_LAMBDAS = 'walk($tree); + $sections = implode("\n", $this->sections); + $klass = empty($this->sections) ? self::KLASS_NO_LAMBDAS : self::KLASS; + $callable = $this->strictCallables ? $this->prepare(self::STRICT_CALLABLE) : ''; + + return sprintf($this->prepare($klass, 0, false, true), $name, $callable, $code, $sections); + } + + const SECTION_CALL = ' + // %s section + $buffer .= $this->section%s($context, $indent, $context->%s(%s)); + '; + + const SECTION = ' + private function section%s(Mustache_Context $context, $indent, $value) + { + $buffer = \'\'; + if (%s) { + $source = %s; + $buffer .= $this->mustache + ->loadLambda((string) call_user_func($value, $source, $this->lambdaHelper)%s) + ->renderInternal($context); + } elseif (!empty($value)) { + $values = $this->isIterable($value) ? $value : array($value); + foreach ($values as $value) { + $context->push($value);%s + $context->pop(); + } + } + + return $buffer; + }'; + + /** + * Generate Mustache Template section PHP source. + * + * @param array $nodes Array of child tokens + * @param string $id Section name + * @param int $start Section start offset + * @param int $end Section end offset + * @param string $otag Current Mustache opening tag + * @param string $ctag Current Mustache closing tag + * @param int $level + * + * @return string Generated section PHP source code + */ + private function section($nodes, $id, $start, $end, $otag, $ctag, $level) + { + $method = $this->getFindMethod($id); + $id = var_export($id, true); + $source = var_export(substr($this->source, $start, $end - $start), true); + $callable = $this->getCallable(); + + if ($otag !== '{{' || $ctag !== '}}') { + $delims = ', '.var_export(sprintf('{{= %s %s =}}', $otag, $ctag), true); + } else { + $delims = ''; + } + + $key = ucfirst(md5($delims."\n".$source)); + + if (!isset($this->sections[$key])) { + $this->sections[$key] = sprintf($this->prepare(self::SECTION), $key, $callable, $source, $delims, $this->walk($nodes, 2)); + } + + return sprintf($this->prepare(self::SECTION_CALL, $level), $id, $key, $method, $id); + } + + const INVERTED_SECTION = ' + // %s inverted section + $value = $context->%s(%s); + if (empty($value)) { + %s + }'; + + /** + * Generate Mustache Template inverted section PHP source. + * + * @param array $nodes Array of child tokens + * @param string $id Section name + * @param int $level + * + * @return string Generated inverted section PHP source code + */ + private function invertedSection($nodes, $id, $level) + { + $method = $this->getFindMethod($id); + $id = var_export($id, true); + + return sprintf($this->prepare(self::INVERTED_SECTION, $level), $id, $method, $id, $this->walk($nodes, $level)); + } + + const PARTIAL = ' + if ($partial = $this->mustache->loadPartial(%s)) { + $buffer .= $partial->renderInternal($context, %s); + } + '; + + /** + * Generate Mustache Template partial call PHP source. + * + * @param string $id Partial name + * @param string $indent Whitespace indent to apply to partial + * @param int $level + * + * @return string Generated partial call PHP source code + */ + private function partial($id, $indent, $level) + { + return sprintf( + $this->prepare(self::PARTIAL, $level), + var_export($id, true), + var_export($indent, true) + ); + } + + const VARIABLE = ' + $value = $this->resolveValue($context->%s(%s), $context, $indent);%s + $buffer .= %s%s; + '; + + /** + * Generate Mustache Template variable interpolation PHP source. + * + * @param string $id Variable name + * @param boolean $escape Escape the variable value for output? + * @param int $level + * + * @return string Generated variable interpolation PHP source + */ + private function variable($id, $escape, $level) + { + $filters = ''; + + if (isset($this->pragmas[Mustache_Engine::PRAGMA_FILTERS])) { + list($id, $filters) = $this->getFilters($id, $level); + } + + $method = $this->getFindMethod($id); + $id = ($method !== 'last') ? var_export($id, true) : ''; + $value = $escape ? $this->getEscape() : '$value'; + + return sprintf($this->prepare(self::VARIABLE, $level), $method, $id, $filters, $this->flushIndent(), $value); + } + + /** + * Generate Mustache Template variable filtering PHP source. + * + * @param string $id Variable name + * @param int $level + * + * @return string Generated variable filtering PHP source + */ + private function getFilters($id, $level) + { + $filters = array_map('trim', explode('|', $id)); + $id = array_shift($filters); + + return array($id, $this->getFilter($filters, $level)); + } + + const FILTER = ' + $filter = $context->%s(%s); + if (!(%s)) { + throw new Mustache_Exception_UnknownFilterException(%s); + } + $value = call_user_func($filter, $value);%s + '; + + /** + * Generate PHP source for a single filter. + * + * @param array $filters + * @param int $level + * + * @return string Generated filter PHP source + */ + private function getFilter(array $filters, $level) + { + if (empty($filters)) { + return ''; + } + + $name = array_shift($filters); + $method = $this->getFindMethod($name); + $filter = ($method !== 'last') ? var_export($name, true) : ''; + $callable = $this->getCallable('$filter'); + $msg = var_export($name, true); + + return sprintf($this->prepare(self::FILTER, $level), $method, $filter, $callable, $msg, $this->getFilter($filters, $level)); + } + + const LINE = '$buffer .= "\n";'; + const TEXT = '$buffer .= %s%s;'; + + /** + * Generate Mustache Template output Buffer call PHP source. + * + * @param string $text + * @param int $level + * + * @return string Generated output Buffer call PHP source + */ + private function text($text, $level) + { + $indentNextLine = (substr($text, -1) === "\n"); + $code = sprintf($this->prepare(self::TEXT, $level), $this->flushIndent(), var_export($text, true)); + $this->indentNextLine = $indentNextLine; + + return $code; + } + + /** + * Prepare PHP source code snippet for output. + * + * @param string $text + * @param int $bonus Additional indent level (default: 0) + * @param boolean $prependNewline Prepend a newline to the snippet? (default: true) + * @param boolean $appendNewline Append a newline to the snippet? (default: false) + * + * @return string PHP source code snippet + */ + private function prepare($text, $bonus = 0, $prependNewline = true, $appendNewline = false) + { + $text = ($prependNewline ? "\n" : '').trim($text); + if ($prependNewline) { + $bonus++; + } + if ($appendNewline) { + $text .= "\n"; + } + + return preg_replace("/\n( {8})?/", "\n".str_repeat(" ", $bonus * 4), $text); + } + + const DEFAULT_ESCAPE = 'htmlspecialchars(%s, %s, %s)'; + const CUSTOM_ESCAPE = 'call_user_func($this->mustache->getEscape(), %s)'; + + /** + * Get the current escaper. + * + * @param string $value (default: '$value') + * + * @return string Either a custom callback, or an inline call to `htmlspecialchars` + */ + private function getEscape($value = '$value') + { + if ($this->customEscape) { + return sprintf(self::CUSTOM_ESCAPE, $value); + } else { + return sprintf(self::DEFAULT_ESCAPE, $value, var_export($this->entityFlags, true), var_export($this->charset, true)); + } + } + + /** + * Select the appropriate Context `find` method for a given $id. + * + * The return value will be one of `find`, `findDot` or `last`. + * + * @see Mustache_Context::find + * @see Mustache_Context::findDot + * @see Mustache_Context::last + * + * @param string $id Variable name + * + * @return string `find` method name + */ + private function getFindMethod($id) + { + if ($id === '.') { + return 'last'; + } elseif (strpos($id, '.') === false) { + return 'find'; + } else { + return 'findDot'; + } + } + + const IS_CALLABLE = '!is_string(%s) && is_callable(%s)'; + const STRICT_IS_CALLABLE = 'is_object(%s) && is_callable(%s)'; + + private function getCallable($variable = '$value') + { + $tpl = $this->strictCallables ? self::STRICT_IS_CALLABLE : self::IS_CALLABLE; + + return sprintf($tpl, $variable, $variable); + } + + const LINE_INDENT = '$indent . '; + + /** + * Get the current $indent prefix to write to the buffer. + * + * @return string "$indent . " or "" + */ + private function flushIndent() + { + if (!$this->indentNextLine) { + return ''; + } + + $this->indentNextLine = false; + + return self::LINE_INDENT; + } +} diff --git a/profile-builder/assets/lib/Mustache/Context.php b/profile-builder/assets/lib/Mustache/Context.php index e7783b4..076f6e8 100644 --- a/profile-builder/assets/lib/Mustache/Context.php +++ b/profile-builder/assets/lib/Mustache/Context.php @@ -1,149 +1,149 @@ -stack = array($context); - } - } - - /** - * Push a new Context frame onto the stack. - * - * @param mixed $value Object or array to use for context - */ - public function push($value) - { - array_push($this->stack, $value); - } - - /** - * Pop the last Context frame from the stack. - * - * @return mixed Last Context frame (object or array) - */ - public function pop() - { - return array_pop($this->stack); - } - - /** - * Get the last Context frame. - * - * @return mixed Last Context frame (object or array) - */ - public function last() - { - return end($this->stack); - } - - /** - * Find a variable in the Context stack. - * - * Starting with the last Context frame (the context of the innermost section), and working back to the top-level - * rendering context, look for a variable with the given name: - * - * * If the Context frame is an associative array which contains the key $id, returns the value of that element. - * * If the Context frame is an object, this will check first for a public method, then a public property named - * $id. Failing both of these, it will try `__isset` and `__get` magic methods. - * * If a value named $id is not found in any Context frame, returns an empty string. - * - * @param string $id Variable name - * - * @return mixed Variable value, or '' if not found - */ - public function find($id) - { - return $this->findVariableInStack($id, $this->stack); - } - - /** - * Find a 'dot notation' variable in the Context stack. - * - * Note that dot notation traversal bubbles through scope differently than the regular find method. After finding - * the initial chunk of the dotted name, each subsequent chunk is searched for only within the value of the previous - * result. For example, given the following context stack: - * - * $data = array( - * 'name' => 'Fred', - * 'child' => array( - * 'name' => 'Bob' - * ), - * ); - * - * ... and the Mustache following template: - * - * {{ child.name }} - * - * ... the `name` value is only searched for within the `child` value of the global Context, not within parent - * Context frames. - * - * @param string $id Dotted variable selector - * - * @return mixed Variable value, or '' if not found - */ - public function findDot($id) - { - $chunks = explode('.', $id); - $first = array_shift($chunks); - $value = $this->findVariableInStack($first, $this->stack); - - foreach ($chunks as $chunk) { - if ($value === '') { - return $value; - } - - $value = $this->findVariableInStack($chunk, array($value)); - } - - return $value; - } - - /** - * Helper function to find a variable in the Context stack. - * - * @see Mustache_Context::find - * - * @param string $id Variable name - * @param array $stack Context stack - * - * @return mixed Variable value, or '' if not found - */ - private function findVariableInStack($id, array $stack) - { - for ($i = count($stack) - 1; $i >= 0; $i--) { - if (is_object($stack[$i]) && !$stack[$i] instanceof Closure) { - if (method_exists($stack[$i], $id)) { - return $stack[$i]->$id(); - } elseif (isset($stack[$i]->$id)) { - return $stack[$i]->$id; - } - } elseif (is_array($stack[$i]) && array_key_exists($id, $stack[$i])) { - return $stack[$i][$id]; - } - } - - return ''; - } -} +stack = array($context); + } + } + + /** + * Push a new Context frame onto the stack. + * + * @param mixed $value Object or array to use for context + */ + public function push($value) + { + array_push($this->stack, $value); + } + + /** + * Pop the last Context frame from the stack. + * + * @return mixed Last Context frame (object or array) + */ + public function pop() + { + return array_pop($this->stack); + } + + /** + * Get the last Context frame. + * + * @return mixed Last Context frame (object or array) + */ + public function last() + { + return end($this->stack); + } + + /** + * Find a variable in the Context stack. + * + * Starting with the last Context frame (the context of the innermost section), and working back to the top-level + * rendering context, look for a variable with the given name: + * + * * If the Context frame is an associative array which contains the key $id, returns the value of that element. + * * If the Context frame is an object, this will check first for a public method, then a public property named + * $id. Failing both of these, it will try `__isset` and `__get` magic methods. + * * If a value named $id is not found in any Context frame, returns an empty string. + * + * @param string $id Variable name + * + * @return mixed Variable value, or '' if not found + */ + public function find($id) + { + return $this->findVariableInStack($id, $this->stack); + } + + /** + * Find a 'dot notation' variable in the Context stack. + * + * Note that dot notation traversal bubbles through scope differently than the regular find method. After finding + * the initial chunk of the dotted name, each subsequent chunk is searched for only within the value of the previous + * result. For example, given the following context stack: + * + * $data = array( + * 'name' => 'Fred', + * 'child' => array( + * 'name' => 'Bob' + * ), + * ); + * + * ... and the Mustache following template: + * + * {{ child.name }} + * + * ... the `name` value is only searched for within the `child` value of the global Context, not within parent + * Context frames. + * + * @param string $id Dotted variable selector + * + * @return mixed Variable value, or '' if not found + */ + public function findDot($id) + { + $chunks = explode('.', $id); + $first = array_shift($chunks); + $value = $this->findVariableInStack($first, $this->stack); + + foreach ($chunks as $chunk) { + if ($value === '') { + return $value; + } + + $value = $this->findVariableInStack($chunk, array($value)); + } + + return $value; + } + + /** + * Helper function to find a variable in the Context stack. + * + * @see Mustache_Context::find + * + * @param string $id Variable name + * @param array $stack Context stack + * + * @return mixed Variable value, or '' if not found + */ + private function findVariableInStack($id, array $stack) + { + for ($i = count($stack) - 1; $i >= 0; $i--) { + if (is_object($stack[$i]) && !$stack[$i] instanceof Closure) { + if (method_exists($stack[$i], $id)) { + return $stack[$i]->$id(); + } elseif (isset($stack[$i]->$id)) { + return $stack[$i]->$id; + } + } elseif (is_array($stack[$i]) && array_key_exists($id, $stack[$i])) { + return $stack[$i][$id]; + } + } + + return ''; + } +} diff --git a/profile-builder/assets/lib/Mustache/Engine.php b/profile-builder/assets/lib/Mustache/Engine.php index 5bf9c4d..d64538d 100644 --- a/profile-builder/assets/lib/Mustache/Engine.php +++ b/profile-builder/assets/lib/Mustache/Engine.php @@ -1,748 +1,748 @@ - '__MyTemplates_', - * - * // A cache directory for compiled templates. Mustache will not cache templates unless this is set - * 'cache' => dirname(__FILE__).'/tmp/cache/mustache', - * - * // Override default permissions for cache files. Defaults to using the system-defined umask. It is - * // *strongly* recommended that you configure your umask properly rather than overriding permissions here. - * 'cache_file_mode' => 0666, - * - * // A Mustache template loader instance. Uses a StringLoader if not specified. - * 'loader' => new Mustache_Loader_FilesystemLoader(dirname(__FILE__).'/views'), - * - * // A Mustache loader instance for partials. - * 'partials_loader' => new Mustache_Loader_FilesystemLoader(dirname(__FILE__).'/views/partials'), - * - * // An array of Mustache partials. Useful for quick-and-dirty string template loading, but not as - * // efficient or lazy as a Filesystem (or database) loader. - * 'partials' => array('foo' => file_get_contents(dirname(__FILE__).'/views/partials/foo.mustache')), - * - * // An array of 'helpers'. Helpers can be global variables or objects, closures (e.g. for higher order - * // sections), or any other valid Mustache context value. They will be prepended to the context stack, - * // so they will be available in any template loaded by this Mustache instance. - * 'helpers' => array('i18n' => function($text) { - * // do something translatey here... - * }), - * - * // An 'escape' callback, responsible for escaping double-mustache variables. - * 'escape' => function($value) { - * return htmlspecialchars($buffer, ENT_COMPAT, 'UTF-8'); - * }, - * - * // Type argument for `htmlspecialchars`. Defaults to ENT_COMPAT. You may prefer ENT_QUOTES. - * 'entity_flags' => ENT_QUOTES, - * - * // Character set for `htmlspecialchars`. Defaults to 'UTF-8'. Use 'UTF-8'. - * 'charset' => 'ISO-8859-1', - * - * // A Mustache Logger instance. No logging will occur unless this is set. Using a PSR-3 compatible - * // logging library -- such as Monolog -- is highly recommended. A simple stream logger implementation is - * // available as well: - * 'logger' => new Mustache_Logger_StreamLogger('php://stderr'), - * - * // Only treat Closure instances and invokable classes as callable. If true, values like - * // `array('ClassName', 'methodName')` and `array($classInstance, 'methodName')`, which are traditionally - * // "callable" in PHP, are not called to resolve variables for interpolation or section contexts. This - * // helps protect against arbitrary code execution when user input is passed directly into the template. - * // This currently defaults to false, but will default to true in v3.0. - * 'strict_callables' => true, - * ); - * - * @throws Mustache_Exception_InvalidArgumentException If `escape` option is not callable. - * - * @param array $options (default: array()) - */ - public function __construct(array $options = array()) - { - if (isset($options['template_class_prefix'])) { - $this->templateClassPrefix = $options['template_class_prefix']; - } - - if (isset($options['cache'])) { - $this->cache = $options['cache']; - } - - if (isset($options['cache_file_mode'])) { - $this->cacheFileMode = $options['cache_file_mode']; - } - - if (isset($options['loader'])) { - $this->setLoader($options['loader']); - } - - if (isset($options['partials_loader'])) { - $this->setPartialsLoader($options['partials_loader']); - } - - if (isset($options['partials'])) { - $this->setPartials($options['partials']); - } - - if (isset($options['helpers'])) { - $this->setHelpers($options['helpers']); - } - - if (isset($options['escape'])) { - if (!is_callable($options['escape'])) { - throw new Mustache_Exception_InvalidArgumentException('Mustache Constructor "escape" option must be callable'); - } - - $this->escape = $options['escape']; - } - - if (isset($options['entity_flags'])) { - $this->entityFlags = $options['entity_flags']; - } - - if (isset($options['charset'])) { - $this->charset = $options['charset']; - } - - if (isset($options['logger'])) { - $this->setLogger($options['logger']); - } - - if (isset($options['strict_callables'])) { - $this->strictCallables = $options['strict_callables']; - } - } - - /** - * Shortcut 'render' invocation. - * - * Equivalent to calling `$mustache->loadTemplate($template)->render($context);` - * - * @see Mustache_Engine::loadTemplate - * @see Mustache_Template::render - * - * @param string $template - * @param mixed $context (default: array()) - * - * @return string Rendered template - */ - public function render($template, $context = array()) - { - return $this->loadTemplate($template)->render($context); - } - - /** - * Get the current Mustache escape callback. - * - * @return mixed Callable or null - */ - public function getEscape() - { - return $this->escape; - } - - /** - * Get the current Mustache entitity type to escape. - * - * @return int - */ - public function getEntityFlags() - { - return $this->entityFlags; - } - - /** - * Get the current Mustache character set. - * - * @return string - */ - public function getCharset() - { - return $this->charset; - } - - /** - * Set the Mustache template Loader instance. - * - * @param Mustache_Loader $loader - */ - public function setLoader(Mustache_Loader $loader) - { - $this->loader = $loader; - } - - /** - * Get the current Mustache template Loader instance. - * - * If no Loader instance has been explicitly specified, this method will instantiate and return - * a StringLoader instance. - * - * @return Mustache_Loader - */ - public function getLoader() - { - if (!isset($this->loader)) { - $this->loader = new Mustache_Loader_StringLoader; - } - - return $this->loader; - } - - /** - * Set the Mustache partials Loader instance. - * - * @param Mustache_Loader $partialsLoader - */ - public function setPartialsLoader(Mustache_Loader $partialsLoader) - { - $this->partialsLoader = $partialsLoader; - } - - /** - * Get the current Mustache partials Loader instance. - * - * If no Loader instance has been explicitly specified, this method will instantiate and return - * an ArrayLoader instance. - * - * @return Mustache_Loader - */ - public function getPartialsLoader() - { - if (!isset($this->partialsLoader)) { - $this->partialsLoader = new Mustache_Loader_ArrayLoader; - } - - return $this->partialsLoader; - } - - /** - * Set partials for the current partials Loader instance. - * - * @throws Mustache_Exception_RuntimeException If the current Loader instance is immutable - * - * @param array $partials (default: array()) - */ - public function setPartials(array $partials = array()) - { - if (!isset($this->partialsLoader)) { - $this->partialsLoader = new Mustache_Loader_ArrayLoader; - } - - if (!$this->partialsLoader instanceof Mustache_Loader_MutableLoader) { - throw new Mustache_Exception_RuntimeException('Unable to set partials on an immutable Mustache Loader instance'); - } - - $this->partialsLoader->setTemplates($partials); - } - - /** - * Set an array of Mustache helpers. - * - * An array of 'helpers'. Helpers can be global variables or objects, closures (e.g. for higher order sections), or - * any other valid Mustache context value. They will be prepended to the context stack, so they will be available in - * any template loaded by this Mustache instance. - * - * @throws Mustache_Exception_InvalidArgumentException if $helpers is not an array or Traversable - * - * @param array|Traversable $helpers - */ - public function setHelpers($helpers) - { - if (!is_array($helpers) && !$helpers instanceof Traversable) { - throw new Mustache_Exception_InvalidArgumentException('setHelpers expects an array of helpers'); - } - - $this->getHelpers()->clear(); - - foreach ($helpers as $name => $helper) { - $this->addHelper($name, $helper); - } - } - - /** - * Get the current set of Mustache helpers. - * - * @see Mustache_Engine::setHelpers - * - * @return Mustache_HelperCollection - */ - public function getHelpers() - { - if (!isset($this->helpers)) { - $this->helpers = new Mustache_HelperCollection; - } - - return $this->helpers; - } - - /** - * Add a new Mustache helper. - * - * @see Mustache_Engine::setHelpers - * - * @param string $name - * @param mixed $helper - */ - public function addHelper($name, $helper) - { - $this->getHelpers()->add($name, $helper); - } - - /** - * Get a Mustache helper by name. - * - * @see Mustache_Engine::setHelpers - * - * @param string $name - * - * @return mixed Helper - */ - public function getHelper($name) - { - return $this->getHelpers()->get($name); - } - - /** - * Check whether this Mustache instance has a helper. - * - * @see Mustache_Engine::setHelpers - * - * @param string $name - * - * @return boolean True if the helper is present - */ - public function hasHelper($name) - { - return $this->getHelpers()->has($name); - } - - /** - * Remove a helper by name. - * - * @see Mustache_Engine::setHelpers - * - * @param string $name - */ - public function removeHelper($name) - { - $this->getHelpers()->remove($name); - } - - /** - * Set the Mustache Logger instance. - * - * @throws Mustache_Exception_InvalidArgumentException If logger is not an instance of Mustache_Logger or Psr\Log\LoggerInterface. - * - * @param Mustache_Logger|Psr\Log\LoggerInterface $logger - */ - public function setLogger($logger = null) - { - if ($logger !== null && !($logger instanceof Mustache_Logger || is_a($logger, 'Psr\\Log\\LoggerInterface'))) { - throw new Mustache_Exception_InvalidArgumentException('Expected an instance of Mustache_Logger or Psr\\Log\\LoggerInterface.'); - } - - $this->logger = $logger; - } - - /** - * Get the current Mustache Logger instance. - * - * @return Mustache_Logger|Psr\Log\LoggerInterface - */ - public function getLogger() - { - return $this->logger; - } - - /** - * Set the Mustache Tokenizer instance. - * - * @param Mustache_Tokenizer $tokenizer - */ - public function setTokenizer(Mustache_Tokenizer $tokenizer) - { - $this->tokenizer = $tokenizer; - } - - /** - * Get the current Mustache Tokenizer instance. - * - * If no Tokenizer instance has been explicitly specified, this method will instantiate and return a new one. - * - * @return Mustache_Tokenizer - */ - public function getTokenizer() - { - if (!isset($this->tokenizer)) { - $this->tokenizer = new Mustache_Tokenizer; - } - - return $this->tokenizer; - } - - /** - * Set the Mustache Parser instance. - * - * @param Mustache_Parser $parser - */ - public function setParser(Mustache_Parser $parser) - { - $this->parser = $parser; - } - - /** - * Get the current Mustache Parser instance. - * - * If no Parser instance has been explicitly specified, this method will instantiate and return a new one. - * - * @return Mustache_Parser - */ - public function getParser() - { - if (!isset($this->parser)) { - $this->parser = new Mustache_Parser; - } - - return $this->parser; - } - - /** - * Set the Mustache Compiler instance. - * - * @param Mustache_Compiler $compiler - */ - public function setCompiler(Mustache_Compiler $compiler) - { - $this->compiler = $compiler; - } - - /** - * Get the current Mustache Compiler instance. - * - * If no Compiler instance has been explicitly specified, this method will instantiate and return a new one. - * - * @return Mustache_Compiler - */ - public function getCompiler() - { - if (!isset($this->compiler)) { - $this->compiler = new Mustache_Compiler; - } - - return $this->compiler; - } - - /** - * Helper method to generate a Mustache template class. - * - * @param string $source - * - * @return string Mustache Template class name - */ - public function getTemplateClassName($source) - { - return $this->templateClassPrefix . md5(sprintf( - 'version:%s,escape:%s,entity_flags:%i,charset:%s,strict_callables:%s,source:%s', - self::VERSION, - isset($this->escape) ? 'custom' : 'default', - $this->entityFlags, - $this->charset, - $this->strictCallables ? 'true' : 'false', - $source - )); - } - - /** - * Load a Mustache Template by name. - * - * @param string $name - * - * @return Mustache_Template - */ - public function loadTemplate($name) - { - return $this->loadSource($this->getLoader()->load($name)); - } - - /** - * Load a Mustache partial Template by name. - * - * This is a helper method used internally by Template instances for loading partial templates. You can most likely - * ignore it completely. - * - * @param string $name - * - * @return Mustache_Template - */ - public function loadPartial($name) - { - try { - if (isset($this->partialsLoader)) { - $loader = $this->partialsLoader; - } elseif (isset($this->loader) && !$this->loader instanceof Mustache_Loader_StringLoader) { - $loader = $this->loader; - } else { - throw new Mustache_Exception_UnknownTemplateException($name); - } - - return $this->loadSource($loader->load($name)); - } catch (Mustache_Exception_UnknownTemplateException $e) { - // If the named partial cannot be found, log then return null. - $this->log( - Mustache_Logger::WARNING, - 'Partial not found: "{name}"', - array('name' => $e->getTemplateName()) - ); - } - } - - /** - * Load a Mustache lambda Template by source. - * - * This is a helper method used by Template instances to generate subtemplates for Lambda sections. You can most - * likely ignore it completely. - * - * @param string $source - * @param string $delims (default: null) - * - * @return Mustache_Template - */ - public function loadLambda($source, $delims = null) - { - if ($delims !== null) { - $source = $delims . "\n" . $source; - } - - return $this->loadSource($source); - } - - /** - * Instantiate and return a Mustache Template instance by source. - * - * @see Mustache_Engine::loadTemplate - * @see Mustache_Engine::loadPartial - * @see Mustache_Engine::loadLambda - * - * @param string $source - * - * @return Mustache_Template - */ - private function loadSource($source) - { - $className = $this->getTemplateClassName($source); - - if (!isset($this->templates[$className])) { - if (!class_exists($className, false)) { - if ($fileName = $this->getCacheFilename($source)) { - if (!is_file($fileName)) { - $this->log( - Mustache_Logger::DEBUG, - 'Writing "{className}" class to template cache: "{fileName}"', - array('className' => $className, 'fileName' => $fileName) - ); - - $this->writeCacheFile($fileName, $this->compile($source)); - } - - require_once $fileName; - } else { - $this->log( - Mustache_Logger::WARNING, - 'Template cache disabled, evaluating "{className}" class at runtime', - array('className' => $className) - ); - - eval('?>'.$this->compile($source)); - } - } - - $this->log( - Mustache_Logger::DEBUG, - 'Instantiating template: "{className}"', - array('className' => $className) - ); - - $this->templates[$className] = new $className($this); - } - - return $this->templates[$className]; - } - - /** - * Helper method to tokenize a Mustache template. - * - * @see Mustache_Tokenizer::scan - * - * @param string $source - * - * @return array Tokens - */ - private function tokenize($source) - { - return $this->getTokenizer()->scan($source); - } - - /** - * Helper method to parse a Mustache template. - * - * @see Mustache_Parser::parse - * - * @param string $source - * - * @return array Token tree - */ - private function parse($source) - { - return $this->getParser()->parse($this->tokenize($source)); - } - - /** - * Helper method to compile a Mustache template. - * - * @see Mustache_Compiler::compile - * - * @param string $source - * - * @return string generated Mustache template class code - */ - private function compile($source) - { - $tree = $this->parse($source); - $name = $this->getTemplateClassName($source); - - $this->log( - Mustache_Logger::INFO, - 'Compiling template to "{className}" class', - array('className' => $name) - ); - - return $this->getCompiler()->compile($source, $tree, $name, isset($this->escape), $this->charset, $this->strictCallables, $this->entityFlags); - } - - /** - * Helper method to generate a Mustache Template class cache filename. - * - * @param string $source - * - * @return string Mustache Template class cache filename - */ - private function getCacheFilename($source) - { - if ($this->cache) { - return sprintf('%s/%s.php', $this->cache, $this->getTemplateClassName($source)); - } - } - - /** - * Helper method to dump a generated Mustache Template subclass to the file cache. - * - * @throws Mustache_Exception_RuntimeException if unable to create the cache directory or write to $fileName. - * - * @param string $fileName - * @param string $source - * - * @codeCoverageIgnore - */ - private function writeCacheFile($fileName, $source) - { - $dirName = dirname($fileName); - if (!is_dir($dirName)) { - $this->log( - Mustache_Logger::INFO, - 'Creating Mustache template cache directory: "{dirName}"', - array('dirName' => $dirName) - ); - - @mkdir($dirName, 0777, true); - if (!is_dir($dirName)) { - throw new Mustache_Exception_RuntimeException(sprintf('Failed to create cache directory "%s".', $dirName)); - } - - } - - $this->log( - Mustache_Logger::DEBUG, - 'Caching compiled template to "{fileName}"', - array('fileName' => $fileName) - ); - - $tempFile = tempnam($dirName, basename($fileName)); - if (false !== @file_put_contents($tempFile, $source)) { - if (@rename($tempFile, $fileName)) { - $mode = isset($this->cacheFileMode) ? $this->cacheFileMode : (0666 & ~umask()); - @chmod($fileName, $mode); - - return; - } - - $this->log( - Mustache_Logger::ERROR, - 'Unable to rename Mustache temp cache file: "{tempName}" -> "{fileName}"', - array('tempName' => $tempFile, 'fileName' => $fileName) - ); - } - - throw new Mustache_Exception_RuntimeException(sprintf('Failed to write cache file "%s".', $fileName)); - } - - /** - * Add a log record if logging is enabled. - * - * @param integer $level The logging level - * @param string $message The log message - * @param array $context The log context - */ - private function log($level, $message, array $context = array()) - { - if (isset($this->logger)) { - $this->logger->log($level, $message, $context); - } - } -} + '__MyTemplates_', + * + * // A cache directory for compiled templates. Mustache will not cache templates unless this is set + * 'cache' => dirname(__FILE__).'/tmp/cache/mustache', + * + * // Override default permissions for cache files. Defaults to using the system-defined umask. It is + * // *strongly* recommended that you configure your umask properly rather than overriding permissions here. + * 'cache_file_mode' => 0666, + * + * // A Mustache template loader instance. Uses a StringLoader if not specified. + * 'loader' => new Mustache_Loader_FilesystemLoader(dirname(__FILE__).'/views'), + * + * // A Mustache loader instance for partials. + * 'partials_loader' => new Mustache_Loader_FilesystemLoader(dirname(__FILE__).'/views/partials'), + * + * // An array of Mustache partials. Useful for quick-and-dirty string template loading, but not as + * // efficient or lazy as a Filesystem (or database) loader. + * 'partials' => array('foo' => file_get_contents(dirname(__FILE__).'/views/partials/foo.mustache')), + * + * // An array of 'helpers'. Helpers can be global variables or objects, closures (e.g. for higher order + * // sections), or any other valid Mustache context value. They will be prepended to the context stack, + * // so they will be available in any template loaded by this Mustache instance. + * 'helpers' => array('i18n' => function($text) { + * // do something translatey here... + * }), + * + * // An 'escape' callback, responsible for escaping double-mustache variables. + * 'escape' => function($value) { + * return htmlspecialchars($buffer, ENT_COMPAT, 'UTF-8'); + * }, + * + * // Type argument for `htmlspecialchars`. Defaults to ENT_COMPAT. You may prefer ENT_QUOTES. + * 'entity_flags' => ENT_QUOTES, + * + * // Character set for `htmlspecialchars`. Defaults to 'UTF-8'. Use 'UTF-8'. + * 'charset' => 'ISO-8859-1', + * + * // A Mustache Logger instance. No logging will occur unless this is set. Using a PSR-3 compatible + * // logging library -- such as Monolog -- is highly recommended. A simple stream logger implementation is + * // available as well: + * 'logger' => new Mustache_Logger_StreamLogger('php://stderr'), + * + * // Only treat Closure instances and invokable classes as callable. If true, values like + * // `array('ClassName', 'methodName')` and `array($classInstance, 'methodName')`, which are traditionally + * // "callable" in PHP, are not called to resolve variables for interpolation or section contexts. This + * // helps protect against arbitrary code execution when user input is passed directly into the template. + * // This currently defaults to false, but will default to true in v3.0. + * 'strict_callables' => true, + * ); + * + * @throws Mustache_Exception_InvalidArgumentException If `escape` option is not callable. + * + * @param array $options (default: array()) + */ + public function __construct(array $options = array()) + { + if (isset($options['template_class_prefix'])) { + $this->templateClassPrefix = $options['template_class_prefix']; + } + + if (isset($options['cache'])) { + $this->cache = $options['cache']; + } + + if (isset($options['cache_file_mode'])) { + $this->cacheFileMode = $options['cache_file_mode']; + } + + if (isset($options['loader'])) { + $this->setLoader($options['loader']); + } + + if (isset($options['partials_loader'])) { + $this->setPartialsLoader($options['partials_loader']); + } + + if (isset($options['partials'])) { + $this->setPartials($options['partials']); + } + + if (isset($options['helpers'])) { + $this->setHelpers($options['helpers']); + } + + if (isset($options['escape'])) { + if (!is_callable($options['escape'])) { + throw new Mustache_Exception_InvalidArgumentException('Mustache Constructor "escape" option must be callable'); + } + + $this->escape = $options['escape']; + } + + if (isset($options['entity_flags'])) { + $this->entityFlags = $options['entity_flags']; + } + + if (isset($options['charset'])) { + $this->charset = $options['charset']; + } + + if (isset($options['logger'])) { + $this->setLogger($options['logger']); + } + + if (isset($options['strict_callables'])) { + $this->strictCallables = $options['strict_callables']; + } + } + + /** + * Shortcut 'render' invocation. + * + * Equivalent to calling `$mustache->loadTemplate($template)->render($context);` + * + * @see Mustache_Engine::loadTemplate + * @see Mustache_Template::render + * + * @param string $template + * @param mixed $context (default: array()) + * + * @return string Rendered template + */ + public function render($template, $context = array()) + { + return $this->loadTemplate($template)->render($context); + } + + /** + * Get the current Mustache escape callback. + * + * @return mixed Callable or null + */ + public function getEscape() + { + return $this->escape; + } + + /** + * Get the current Mustache entitity type to escape. + * + * @return int + */ + public function getEntityFlags() + { + return $this->entityFlags; + } + + /** + * Get the current Mustache character set. + * + * @return string + */ + public function getCharset() + { + return $this->charset; + } + + /** + * Set the Mustache template Loader instance. + * + * @param Mustache_Loader $loader + */ + public function setLoader(Mustache_Loader $loader) + { + $this->loader = $loader; + } + + /** + * Get the current Mustache template Loader instance. + * + * If no Loader instance has been explicitly specified, this method will instantiate and return + * a StringLoader instance. + * + * @return Mustache_Loader + */ + public function getLoader() + { + if (!isset($this->loader)) { + $this->loader = new Mustache_Loader_StringLoader; + } + + return $this->loader; + } + + /** + * Set the Mustache partials Loader instance. + * + * @param Mustache_Loader $partialsLoader + */ + public function setPartialsLoader(Mustache_Loader $partialsLoader) + { + $this->partialsLoader = $partialsLoader; + } + + /** + * Get the current Mustache partials Loader instance. + * + * If no Loader instance has been explicitly specified, this method will instantiate and return + * an ArrayLoader instance. + * + * @return Mustache_Loader + */ + public function getPartialsLoader() + { + if (!isset($this->partialsLoader)) { + $this->partialsLoader = new Mustache_Loader_ArrayLoader; + } + + return $this->partialsLoader; + } + + /** + * Set partials for the current partials Loader instance. + * + * @throws Mustache_Exception_RuntimeException If the current Loader instance is immutable + * + * @param array $partials (default: array()) + */ + public function setPartials(array $partials = array()) + { + if (!isset($this->partialsLoader)) { + $this->partialsLoader = new Mustache_Loader_ArrayLoader; + } + + if (!$this->partialsLoader instanceof Mustache_Loader_MutableLoader) { + throw new Mustache_Exception_RuntimeException('Unable to set partials on an immutable Mustache Loader instance'); + } + + $this->partialsLoader->setTemplates($partials); + } + + /** + * Set an array of Mustache helpers. + * + * An array of 'helpers'. Helpers can be global variables or objects, closures (e.g. for higher order sections), or + * any other valid Mustache context value. They will be prepended to the context stack, so they will be available in + * any template loaded by this Mustache instance. + * + * @throws Mustache_Exception_InvalidArgumentException if $helpers is not an array or Traversable + * + * @param array|Traversable $helpers + */ + public function setHelpers($helpers) + { + if (!is_array($helpers) && !$helpers instanceof Traversable) { + throw new Mustache_Exception_InvalidArgumentException('setHelpers expects an array of helpers'); + } + + $this->getHelpers()->clear(); + + foreach ($helpers as $name => $helper) { + $this->addHelper($name, $helper); + } + } + + /** + * Get the current set of Mustache helpers. + * + * @see Mustache_Engine::setHelpers + * + * @return Mustache_HelperCollection + */ + public function getHelpers() + { + if (!isset($this->helpers)) { + $this->helpers = new Mustache_HelperCollection; + } + + return $this->helpers; + } + + /** + * Add a new Mustache helper. + * + * @see Mustache_Engine::setHelpers + * + * @param string $name + * @param mixed $helper + */ + public function addHelper($name, $helper) + { + $this->getHelpers()->add($name, $helper); + } + + /** + * Get a Mustache helper by name. + * + * @see Mustache_Engine::setHelpers + * + * @param string $name + * + * @return mixed Helper + */ + public function getHelper($name) + { + return $this->getHelpers()->get($name); + } + + /** + * Check whether this Mustache instance has a helper. + * + * @see Mustache_Engine::setHelpers + * + * @param string $name + * + * @return boolean True if the helper is present + */ + public function hasHelper($name) + { + return $this->getHelpers()->has($name); + } + + /** + * Remove a helper by name. + * + * @see Mustache_Engine::setHelpers + * + * @param string $name + */ + public function removeHelper($name) + { + $this->getHelpers()->remove($name); + } + + /** + * Set the Mustache Logger instance. + * + * @throws Mustache_Exception_InvalidArgumentException If logger is not an instance of Mustache_Logger or Psr\Log\LoggerInterface. + * + * @param Mustache_Logger|Psr\Log\LoggerInterface $logger + */ + public function setLogger($logger = null) + { + if ($logger !== null && !($logger instanceof Mustache_Logger || is_a($logger, 'Psr\\Log\\LoggerInterface'))) { + throw new Mustache_Exception_InvalidArgumentException('Expected an instance of Mustache_Logger or Psr\\Log\\LoggerInterface.'); + } + + $this->logger = $logger; + } + + /** + * Get the current Mustache Logger instance. + * + * @return Mustache_Logger|Psr\Log\LoggerInterface + */ + public function getLogger() + { + return $this->logger; + } + + /** + * Set the Mustache Tokenizer instance. + * + * @param Mustache_Tokenizer $tokenizer + */ + public function setTokenizer(Mustache_Tokenizer $tokenizer) + { + $this->tokenizer = $tokenizer; + } + + /** + * Get the current Mustache Tokenizer instance. + * + * If no Tokenizer instance has been explicitly specified, this method will instantiate and return a new one. + * + * @return Mustache_Tokenizer + */ + public function getTokenizer() + { + if (!isset($this->tokenizer)) { + $this->tokenizer = new Mustache_Tokenizer; + } + + return $this->tokenizer; + } + + /** + * Set the Mustache Parser instance. + * + * @param Mustache_Parser $parser + */ + public function setParser(Mustache_Parser $parser) + { + $this->parser = $parser; + } + + /** + * Get the current Mustache Parser instance. + * + * If no Parser instance has been explicitly specified, this method will instantiate and return a new one. + * + * @return Mustache_Parser + */ + public function getParser() + { + if (!isset($this->parser)) { + $this->parser = new Mustache_Parser; + } + + return $this->parser; + } + + /** + * Set the Mustache Compiler instance. + * + * @param Mustache_Compiler $compiler + */ + public function setCompiler(Mustache_Compiler $compiler) + { + $this->compiler = $compiler; + } + + /** + * Get the current Mustache Compiler instance. + * + * If no Compiler instance has been explicitly specified, this method will instantiate and return a new one. + * + * @return Mustache_Compiler + */ + public function getCompiler() + { + if (!isset($this->compiler)) { + $this->compiler = new Mustache_Compiler; + } + + return $this->compiler; + } + + /** + * Helper method to generate a Mustache template class. + * + * @param string $source + * + * @return string Mustache Template class name + */ + public function getTemplateClassName($source) + { + return $this->templateClassPrefix . md5(sprintf( + 'version:%s,escape:%s,entity_flags:%i,charset:%s,strict_callables:%s,source:%s', + self::VERSION, + isset($this->escape) ? 'custom' : 'default', + $this->entityFlags, + $this->charset, + $this->strictCallables ? 'true' : 'false', + $source + )); + } + + /** + * Load a Mustache Template by name. + * + * @param string $name + * + * @return Mustache_Template + */ + public function loadTemplate($name) + { + return $this->loadSource($this->getLoader()->load($name)); + } + + /** + * Load a Mustache partial Template by name. + * + * This is a helper method used internally by Template instances for loading partial templates. You can most likely + * ignore it completely. + * + * @param string $name + * + * @return Mustache_Template + */ + public function loadPartial($name) + { + try { + if (isset($this->partialsLoader)) { + $loader = $this->partialsLoader; + } elseif (isset($this->loader) && !$this->loader instanceof Mustache_Loader_StringLoader) { + $loader = $this->loader; + } else { + throw new Mustache_Exception_UnknownTemplateException($name); + } + + return $this->loadSource($loader->load($name)); + } catch (Mustache_Exception_UnknownTemplateException $e) { + // If the named partial cannot be found, log then return null. + $this->log( + Mustache_Logger::WARNING, + 'Partial not found: "{name}"', + array('name' => $e->getTemplateName()) + ); + } + } + + /** + * Load a Mustache lambda Template by source. + * + * This is a helper method used by Template instances to generate subtemplates for Lambda sections. You can most + * likely ignore it completely. + * + * @param string $source + * @param string $delims (default: null) + * + * @return Mustache_Template + */ + public function loadLambda($source, $delims = null) + { + if ($delims !== null) { + $source = $delims . "\n" . $source; + } + + return $this->loadSource($source); + } + + /** + * Instantiate and return a Mustache Template instance by source. + * + * @see Mustache_Engine::loadTemplate + * @see Mustache_Engine::loadPartial + * @see Mustache_Engine::loadLambda + * + * @param string $source + * + * @return Mustache_Template + */ + private function loadSource($source) + { + $className = $this->getTemplateClassName($source); + + if (!isset($this->templates[$className])) { + if (!class_exists($className, false)) { + if ($fileName = $this->getCacheFilename($source)) { + if (!is_file($fileName)) { + $this->log( + Mustache_Logger::DEBUG, + 'Writing "{className}" class to template cache: "{fileName}"', + array('className' => $className, 'fileName' => $fileName) + ); + + $this->writeCacheFile($fileName, $this->compile($source)); + } + + require_once $fileName; + } else { + $this->log( + Mustache_Logger::WARNING, + 'Template cache disabled, evaluating "{className}" class at runtime', + array('className' => $className) + ); + + eval('?>'.$this->compile($source)); + } + } + + $this->log( + Mustache_Logger::DEBUG, + 'Instantiating template: "{className}"', + array('className' => $className) + ); + + $this->templates[$className] = new $className($this); + } + + return $this->templates[$className]; + } + + /** + * Helper method to tokenize a Mustache template. + * + * @see Mustache_Tokenizer::scan + * + * @param string $source + * + * @return array Tokens + */ + private function tokenize($source) + { + return $this->getTokenizer()->scan($source); + } + + /** + * Helper method to parse a Mustache template. + * + * @see Mustache_Parser::parse + * + * @param string $source + * + * @return array Token tree + */ + private function parse($source) + { + return $this->getParser()->parse($this->tokenize($source)); + } + + /** + * Helper method to compile a Mustache template. + * + * @see Mustache_Compiler::compile + * + * @param string $source + * + * @return string generated Mustache template class code + */ + private function compile($source) + { + $tree = $this->parse($source); + $name = $this->getTemplateClassName($source); + + $this->log( + Mustache_Logger::INFO, + 'Compiling template to "{className}" class', + array('className' => $name) + ); + + return $this->getCompiler()->compile($source, $tree, $name, isset($this->escape), $this->charset, $this->strictCallables, $this->entityFlags); + } + + /** + * Helper method to generate a Mustache Template class cache filename. + * + * @param string $source + * + * @return string Mustache Template class cache filename + */ + private function getCacheFilename($source) + { + if ($this->cache) { + return sprintf('%s/%s.php', $this->cache, $this->getTemplateClassName($source)); + } + } + + /** + * Helper method to dump a generated Mustache Template subclass to the file cache. + * + * @throws Mustache_Exception_RuntimeException if unable to create the cache directory or write to $fileName. + * + * @param string $fileName + * @param string $source + * + * @codeCoverageIgnore + */ + private function writeCacheFile($fileName, $source) + { + $dirName = dirname($fileName); + if (!is_dir($dirName)) { + $this->log( + Mustache_Logger::INFO, + 'Creating Mustache template cache directory: "{dirName}"', + array('dirName' => $dirName) + ); + + @mkdir($dirName, 0777, true); + if (!is_dir($dirName)) { + throw new Mustache_Exception_RuntimeException(sprintf('Failed to create cache directory "%s".', $dirName)); + } + + } + + $this->log( + Mustache_Logger::DEBUG, + 'Caching compiled template to "{fileName}"', + array('fileName' => $fileName) + ); + + $tempFile = tempnam($dirName, basename($fileName)); + if (false !== @file_put_contents($tempFile, $source)) { + if (@rename($tempFile, $fileName)) { + $mode = isset($this->cacheFileMode) ? $this->cacheFileMode : (0666 & ~umask()); + @chmod($fileName, $mode); + + return; + } + + $this->log( + Mustache_Logger::ERROR, + 'Unable to rename Mustache temp cache file: "{tempName}" -> "{fileName}"', + array('tempName' => $tempFile, 'fileName' => $fileName) + ); + } + + throw new Mustache_Exception_RuntimeException(sprintf('Failed to write cache file "%s".', $fileName)); + } + + /** + * Add a log record if logging is enabled. + * + * @param integer $level The logging level + * @param string $message The log message + * @param array $context The log context + */ + private function log($level, $message, array $context = array()) + { + if (isset($this->logger)) { + $this->logger->log($level, $message, $context); + } + } +} diff --git a/profile-builder/assets/lib/Mustache/Exception.php b/profile-builder/assets/lib/Mustache/Exception.php index b4f8300..afbf954 100644 --- a/profile-builder/assets/lib/Mustache/Exception.php +++ b/profile-builder/assets/lib/Mustache/Exception.php @@ -1,18 +1,18 @@ -token = $token; - parent::__construct($msg); - } - - public function getToken() - { - return $this->token; - } -} +token = $token; + parent::__construct($msg); + } + + public function getToken() + { + return $this->token; + } +} diff --git a/profile-builder/assets/lib/Mustache/Exception/UnknownFilterException.php b/profile-builder/assets/lib/Mustache/Exception/UnknownFilterException.php index f5c0884..9251a4f 100644 --- a/profile-builder/assets/lib/Mustache/Exception/UnknownFilterException.php +++ b/profile-builder/assets/lib/Mustache/Exception/UnknownFilterException.php @@ -1,29 +1,29 @@ -filterName = $filterName; - parent::__construct(sprintf('Unknown filter: %s', $filterName)); - } - - public function getFilterName() - { - return $this->filterName; - } -} +filterName = $filterName; + parent::__construct(sprintf('Unknown filter: %s', $filterName)); + } + + public function getFilterName() + { + return $this->filterName; + } +} diff --git a/profile-builder/assets/lib/Mustache/Exception/UnknownHelperException.php b/profile-builder/assets/lib/Mustache/Exception/UnknownHelperException.php index 98af13e..45778e0 100644 --- a/profile-builder/assets/lib/Mustache/Exception/UnknownHelperException.php +++ b/profile-builder/assets/lib/Mustache/Exception/UnknownHelperException.php @@ -1,29 +1,29 @@ -helperName = $helperName; - parent::__construct(sprintf('Unknown helper: %s', $helperName)); - } - - public function getHelperName() - { - return $this->helperName; - } -} +helperName = $helperName; + parent::__construct(sprintf('Unknown helper: %s', $helperName)); + } + + public function getHelperName() + { + return $this->helperName; + } +} diff --git a/profile-builder/assets/lib/Mustache/Exception/UnknownTemplateException.php b/profile-builder/assets/lib/Mustache/Exception/UnknownTemplateException.php index 141d372..17f2556 100644 --- a/profile-builder/assets/lib/Mustache/Exception/UnknownTemplateException.php +++ b/profile-builder/assets/lib/Mustache/Exception/UnknownTemplateException.php @@ -1,29 +1,29 @@ -templateName = $templateName; - parent::__construct(sprintf('Unknown template: %s', $templateName)); - } - - public function getTemplateName() - { - return $this->templateName; - } -} +templateName = $templateName; + parent::__construct(sprintf('Unknown template: %s', $templateName)); + } + + public function getTemplateName() + { + return $this->templateName; + } +} diff --git a/profile-builder/assets/lib/Mustache/HelperCollection.php b/profile-builder/assets/lib/Mustache/HelperCollection.php index e991137..957761c 100644 --- a/profile-builder/assets/lib/Mustache/HelperCollection.php +++ b/profile-builder/assets/lib/Mustache/HelperCollection.php @@ -1,170 +1,170 @@ - $helper` pairs. - * - * @throws Mustache_Exception_InvalidArgumentException if the $helpers argument isn't an array or Traversable - * - * @param array|Traversable $helpers (default: null) - */ - public function __construct($helpers = null) - { - if ($helpers !== null) { - if (!is_array($helpers) && !$helpers instanceof Traversable) { - throw new Mustache_Exception_InvalidArgumentException('HelperCollection constructor expects an array of helpers'); - } - - foreach ($helpers as $name => $helper) { - $this->add($name, $helper); - } - } - } - - /** - * Magic mutator. - * - * @see Mustache_HelperCollection::add - * - * @param string $name - * @param mixed $helper - */ - public function __set($name, $helper) - { - $this->add($name, $helper); - } - - /** - * Add a helper to this collection. - * - * @param string $name - * @param mixed $helper - */ - public function add($name, $helper) - { - $this->helpers[$name] = $helper; - } - - /** - * Magic accessor. - * - * @see Mustache_HelperCollection::get - * - * @param string $name - * - * @return mixed Helper - */ - public function __get($name) - { - return $this->get($name); - } - - /** - * Get a helper by name. - * - * @throws Mustache_Exception_UnknownHelperException If helper does not exist. - * - * @param string $name - * - * @return mixed Helper - */ - public function get($name) - { - if (!$this->has($name)) { - throw new Mustache_Exception_UnknownHelperException($name); - } - - return $this->helpers[$name]; - } - - /** - * Magic isset(). - * - * @see Mustache_HelperCollection::has - * - * @param string $name - * - * @return boolean True if helper is present - */ - public function __isset($name) - { - return $this->has($name); - } - - /** - * Check whether a given helper is present in the collection. - * - * @param string $name - * - * @return boolean True if helper is present - */ - public function has($name) - { - return array_key_exists($name, $this->helpers); - } - - /** - * Magic unset(). - * - * @see Mustache_HelperCollection::remove - * - * @param string $name - */ - public function __unset($name) - { - $this->remove($name); - } - - /** - * Check whether a given helper is present in the collection. - * - * @throws Mustache_Exception_UnknownHelperException if the requested helper is not present. - * - * @param string $name - */ - public function remove($name) - { - if (!$this->has($name)) { - throw new Mustache_Exception_UnknownHelperException($name); - } - - unset($this->helpers[$name]); - } - - /** - * Clear the helper collection. - * - * Removes all helpers from this collection - */ - public function clear() - { - $this->helpers = array(); - } - - /** - * Check whether the helper collection is empty. - * - * @return boolean True if the collection is empty - */ - public function isEmpty() - { - return empty($this->helpers); - } -} + $helper` pairs. + * + * @throws Mustache_Exception_InvalidArgumentException if the $helpers argument isn't an array or Traversable + * + * @param array|Traversable $helpers (default: null) + */ + public function __construct($helpers = null) + { + if ($helpers !== null) { + if (!is_array($helpers) && !$helpers instanceof Traversable) { + throw new Mustache_Exception_InvalidArgumentException('HelperCollection constructor expects an array of helpers'); + } + + foreach ($helpers as $name => $helper) { + $this->add($name, $helper); + } + } + } + + /** + * Magic mutator. + * + * @see Mustache_HelperCollection::add + * + * @param string $name + * @param mixed $helper + */ + public function __set($name, $helper) + { + $this->add($name, $helper); + } + + /** + * Add a helper to this collection. + * + * @param string $name + * @param mixed $helper + */ + public function add($name, $helper) + { + $this->helpers[$name] = $helper; + } + + /** + * Magic accessor. + * + * @see Mustache_HelperCollection::get + * + * @param string $name + * + * @return mixed Helper + */ + public function __get($name) + { + return $this->get($name); + } + + /** + * Get a helper by name. + * + * @throws Mustache_Exception_UnknownHelperException If helper does not exist. + * + * @param string $name + * + * @return mixed Helper + */ + public function get($name) + { + if (!$this->has($name)) { + throw new Mustache_Exception_UnknownHelperException($name); + } + + return $this->helpers[$name]; + } + + /** + * Magic isset(). + * + * @see Mustache_HelperCollection::has + * + * @param string $name + * + * @return boolean True if helper is present + */ + public function __isset($name) + { + return $this->has($name); + } + + /** + * Check whether a given helper is present in the collection. + * + * @param string $name + * + * @return boolean True if helper is present + */ + public function has($name) + { + return array_key_exists($name, $this->helpers); + } + + /** + * Magic unset(). + * + * @see Mustache_HelperCollection::remove + * + * @param string $name + */ + public function __unset($name) + { + $this->remove($name); + } + + /** + * Check whether a given helper is present in the collection. + * + * @throws Mustache_Exception_UnknownHelperException if the requested helper is not present. + * + * @param string $name + */ + public function remove($name) + { + if (!$this->has($name)) { + throw new Mustache_Exception_UnknownHelperException($name); + } + + unset($this->helpers[$name]); + } + + /** + * Clear the helper collection. + * + * Removes all helpers from this collection + */ + public function clear() + { + $this->helpers = array(); + } + + /** + * Check whether the helper collection is empty. + * + * @return boolean True if the collection is empty + */ + public function isEmpty() + { + return empty($this->helpers); + } +} diff --git a/profile-builder/assets/lib/Mustache/LambdaHelper.php b/profile-builder/assets/lib/Mustache/LambdaHelper.php index dfd4659..670c4a9 100644 --- a/profile-builder/assets/lib/Mustache/LambdaHelper.php +++ b/profile-builder/assets/lib/Mustache/LambdaHelper.php @@ -1,49 +1,49 @@ -mustache = $mustache; - $this->context = $context; - } - - /** - * Render a string as a Mustache template with the current rendering context. - * - * @param string $string - * - * @return Rendered template. - */ - public function render($string) - { - return $this->mustache - ->loadLambda((string) $string) - ->renderInternal($this->context); - } -} +mustache = $mustache; + $this->context = $context; + } + + /** + * Render a string as a Mustache template with the current rendering context. + * + * @param string $string + * + * @return Rendered template. + */ + public function render($string) + { + return $this->mustache + ->loadLambda((string) $string) + ->renderInternal($this->context); + } +} diff --git a/profile-builder/assets/lib/Mustache/Loader.php b/profile-builder/assets/lib/Mustache/Loader.php index f659a1d..0a8d9b3 100644 --- a/profile-builder/assets/lib/Mustache/Loader.php +++ b/profile-builder/assets/lib/Mustache/Loader.php @@ -1,28 +1,28 @@ - '{{ bar }}', - * 'baz' => 'Hey {{ qux }}!' - * ); - * - * $tpl = $loader->load('foo'); // '{{ bar }}' - * - * The ArrayLoader is used internally as a partials loader by Mustache_Engine instance when an array of partials - * is set. It can also be used as a quick-and-dirty Template loader. - */ -class Mustache_Loader_ArrayLoader implements Mustache_Loader, Mustache_Loader_MutableLoader -{ - - /** - * ArrayLoader constructor. - * - * @param array $templates Associative array of Template source (default: array()) - */ - public function __construct(array $templates = array()) - { - $this->templates = $templates; - } - - /** - * Load a Template. - * - * @throws Mustache_Exception_UnknownTemplateException If a template file is not found. - * - * @param string $name - * - * @return string Mustache Template source - */ - public function load($name) - { - if (!isset($this->templates[$name])) { - throw new Mustache_Exception_UnknownTemplateException($name); - } - - return $this->templates[$name]; - } - - /** - * Set an associative array of Template sources for this loader. - * - * @param array $templates - */ - public function setTemplates(array $templates) - { - $this->templates = $templates; - } - - /** - * Set a Template source by name. - * - * @param string $name - * @param string $template Mustache Template source - */ - public function setTemplate($name, $template) - { - $this->templates[$name] = $template; - } -} + '{{ bar }}', + * 'baz' => 'Hey {{ qux }}!' + * ); + * + * $tpl = $loader->load('foo'); // '{{ bar }}' + * + * The ArrayLoader is used internally as a partials loader by Mustache_Engine instance when an array of partials + * is set. It can also be used as a quick-and-dirty Template loader. + */ +class Mustache_Loader_ArrayLoader implements Mustache_Loader, Mustache_Loader_MutableLoader +{ + + /** + * ArrayLoader constructor. + * + * @param array $templates Associative array of Template source (default: array()) + */ + public function __construct(array $templates = array()) + { + $this->templates = $templates; + } + + /** + * Load a Template. + * + * @throws Mustache_Exception_UnknownTemplateException If a template file is not found. + * + * @param string $name + * + * @return string Mustache Template source + */ + public function load($name) + { + if (!isset($this->templates[$name])) { + throw new Mustache_Exception_UnknownTemplateException($name); + } + + return $this->templates[$name]; + } + + /** + * Set an associative array of Template sources for this loader. + * + * @param array $templates + */ + public function setTemplates(array $templates) + { + $this->templates = $templates; + } + + /** + * Set a Template source by name. + * + * @param string $name + * @param string $template Mustache Template source + */ + public function setTemplate($name, $template) + { + $this->templates[$name] = $template; + } +} diff --git a/profile-builder/assets/lib/Mustache/Loader/CascadingLoader.php b/profile-builder/assets/lib/Mustache/Loader/CascadingLoader.php index 192edb9..7595885 100644 --- a/profile-builder/assets/lib/Mustache/Loader/CascadingLoader.php +++ b/profile-builder/assets/lib/Mustache/Loader/CascadingLoader.php @@ -1,69 +1,69 @@ -loaders = array(); - foreach ($loaders as $loader) { - $this->addLoader($loader); - } - } - - /** - * Add a Loader instance. - * - * @param Mustache_Loader $loader A Mustache Loader instance - */ - public function addLoader(Mustache_Loader $loader) - { - $this->loaders[] = $loader; - } - - /** - * Load a Template by name. - * - * @throws Mustache_Exception_UnknownTemplateException If a template file is not found. - * - * @param string $name - * - * @return string Mustache Template source - */ - public function load($name) - { - foreach ($this->loaders as $loader) { - try { - return $loader->load($name); - } catch (Mustache_Exception_UnknownTemplateException $e) { - // do nothing, check the next loader. - } - } - - throw new Mustache_Exception_UnknownTemplateException($name); - } -} +loaders = array(); + foreach ($loaders as $loader) { + $this->addLoader($loader); + } + } + + /** + * Add a Loader instance. + * + * @param Mustache_Loader $loader A Mustache Loader instance + */ + public function addLoader(Mustache_Loader $loader) + { + $this->loaders[] = $loader; + } + + /** + * Load a Template by name. + * + * @throws Mustache_Exception_UnknownTemplateException If a template file is not found. + * + * @param string $name + * + * @return string Mustache Template source + */ + public function load($name) + { + foreach ($this->loaders as $loader) { + try { + return $loader->load($name); + } catch (Mustache_Exception_UnknownTemplateException $e) { + // do nothing, check the next loader. + } + } + + throw new Mustache_Exception_UnknownTemplateException($name); + } +} diff --git a/profile-builder/assets/lib/Mustache/Loader/FilesystemLoader.php b/profile-builder/assets/lib/Mustache/Loader/FilesystemLoader.php index c30149c..e756ada 100644 --- a/profile-builder/assets/lib/Mustache/Loader/FilesystemLoader.php +++ b/profile-builder/assets/lib/Mustache/Loader/FilesystemLoader.php @@ -1,124 +1,124 @@ -load('foo'); // equivalent to `file_get_contents(dirname(__FILE__).'/views/foo.mustache'); - * - * This is probably the most useful Mustache Loader implementation. It can be used for partials and normal Templates: - * - * $m = new Mustache(array( - * 'loader' => new Mustache_Loader_FilesystemLoader(dirname(__FILE__).'/views'), - * 'partials_loader' => new Mustache_Loader_FilesystemLoader(dirname(__FILE__).'/views/partials'), - * )); - */ -class Mustache_Loader_FilesystemLoader implements Mustache_Loader -{ - private $baseDir; - private $extension = '.mustache'; - private $templates = array(); - - /** - * Mustache filesystem Loader constructor. - * - * Passing an $options array allows overriding certain Loader options during instantiation: - * - * $options = array( - * // The filename extension used for Mustache templates. Defaults to '.mustache' - * 'extension' => '.ms', - * ); - * - * @throws Mustache_Exception_RuntimeException if $baseDir does not exist. - * - * @param string $baseDir Base directory containing Mustache template files. - * @param array $options Array of Loader options (default: array()) - */ - public function __construct($baseDir, array $options = array()) - { - $this->baseDir = $baseDir; - - if (strpos($this->baseDir, '://') === -1) { - $this->baseDir = realpath($this->baseDir); - } - - if (!is_dir($this->baseDir)) { - throw new Mustache_Exception_RuntimeException(sprintf('FilesystemLoader baseDir must be a directory: %s', $baseDir)); - } - - if (array_key_exists('extension', $options)) { - if (empty($options['extension'])) { - $this->extension = ''; - } else { - $this->extension = '.' . ltrim($options['extension'], '.'); - } - } - } - - /** - * Load a Template by name. - * - * $loader = new Mustache_Loader_FilesystemLoader(dirname(__FILE__).'/views'); - * $loader->load('admin/dashboard'); // loads "./views/admin/dashboard.mustache"; - * - * @param string $name - * - * @return string Mustache Template source - */ - public function load($name) - { - if (!isset($this->templates[$name])) { - $this->templates[$name] = $this->loadFile($name); - } - - return $this->templates[$name]; - } - - /** - * Helper function for loading a Mustache file by name. - * - * @throws Mustache_Exception_UnknownTemplateException If a template file is not found. - * - * @param string $name - * - * @return string Mustache Template source - */ - protected function loadFile($name) - { - $fileName = $this->getFileName($name); - - if (!file_exists($fileName)) { - throw new Mustache_Exception_UnknownTemplateException($name); - } - - return file_get_contents($fileName); - } - - /** - * Helper function for getting a Mustache template file name. - * - * @param string $name - * - * @return string Template file name - */ - protected function getFileName($name) - { - $fileName = $this->baseDir . '/' . $name; - if (substr($fileName, 0 - strlen($this->extension)) !== $this->extension) { - $fileName .= $this->extension; - } - - return $fileName; - } -} +load('foo'); // equivalent to `file_get_contents(dirname(__FILE__).'/views/foo.mustache'); + * + * This is probably the most useful Mustache Loader implementation. It can be used for partials and normal Templates: + * + * $m = new Mustache(array( + * 'loader' => new Mustache_Loader_FilesystemLoader(dirname(__FILE__).'/views'), + * 'partials_loader' => new Mustache_Loader_FilesystemLoader(dirname(__FILE__).'/views/partials'), + * )); + */ +class Mustache_Loader_FilesystemLoader implements Mustache_Loader +{ + private $baseDir; + private $extension = '.mustache'; + private $templates = array(); + + /** + * Mustache filesystem Loader constructor. + * + * Passing an $options array allows overriding certain Loader options during instantiation: + * + * $options = array( + * // The filename extension used for Mustache templates. Defaults to '.mustache' + * 'extension' => '.ms', + * ); + * + * @throws Mustache_Exception_RuntimeException if $baseDir does not exist. + * + * @param string $baseDir Base directory containing Mustache template files. + * @param array $options Array of Loader options (default: array()) + */ + public function __construct($baseDir, array $options = array()) + { + $this->baseDir = $baseDir; + + if (strpos($this->baseDir, '://') === -1) { + $this->baseDir = realpath($this->baseDir); + } + + if (!is_dir($this->baseDir)) { + throw new Mustache_Exception_RuntimeException(sprintf('FilesystemLoader baseDir must be a directory: %s', $baseDir)); + } + + if (array_key_exists('extension', $options)) { + if (empty($options['extension'])) { + $this->extension = ''; + } else { + $this->extension = '.' . ltrim($options['extension'], '.'); + } + } + } + + /** + * Load a Template by name. + * + * $loader = new Mustache_Loader_FilesystemLoader(dirname(__FILE__).'/views'); + * $loader->load('admin/dashboard'); // loads "./views/admin/dashboard.mustache"; + * + * @param string $name + * + * @return string Mustache Template source + */ + public function load($name) + { + if (!isset($this->templates[$name])) { + $this->templates[$name] = $this->loadFile($name); + } + + return $this->templates[$name]; + } + + /** + * Helper function for loading a Mustache file by name. + * + * @throws Mustache_Exception_UnknownTemplateException If a template file is not found. + * + * @param string $name + * + * @return string Mustache Template source + */ + protected function loadFile($name) + { + $fileName = $this->getFileName($name); + + if (!file_exists($fileName)) { + throw new Mustache_Exception_UnknownTemplateException($name); + } + + return file_get_contents($fileName); + } + + /** + * Helper function for getting a Mustache template file name. + * + * @param string $name + * + * @return string Template file name + */ + protected function getFileName($name) + { + $fileName = $this->baseDir . '/' . $name; + if (substr($fileName, 0 - strlen($this->extension)) !== $this->extension) { + $fileName .= $this->extension; + } + + return $fileName; + } +} diff --git a/profile-builder/assets/lib/Mustache/Loader/InlineLoader.php b/profile-builder/assets/lib/Mustache/Loader/InlineLoader.php index e08852e..263daf1 100644 --- a/profile-builder/assets/lib/Mustache/Loader/InlineLoader.php +++ b/profile-builder/assets/lib/Mustache/Loader/InlineLoader.php @@ -1,123 +1,123 @@ -load('hello'); - * $goodbye = $loader->load('goodbye'); - * - * __halt_compiler(); - * - * @@ hello - * Hello, {{ planet }}! - * - * @@ goodbye - * Goodbye, cruel {{ planet }} - * - * Templates are deliniated by lines containing only `@@ name`. - * - * The InlineLoader is well-suited to micro-frameworks such as Silex: - * - * $app->register(new MustacheServiceProvider, array( - * 'mustache.loader' => new Mustache_Loader_InlineLoader(__FILE__, __COMPILER_HALT_OFFSET__) - * )); - * - * $app->get('/{name}', function($name) use ($app) { - * return $app['mustache']->render('hello', compact('name')); - * }) - * ->value('name', 'world'); - * - * // ... - * - * __halt_compiler(); - * - * @@ hello - * Hello, {{ name }}! - * - */ -class Mustache_Loader_InlineLoader implements Mustache_Loader -{ - protected $fileName; - protected $offset; - protected $templates; - - /** - * The InlineLoader requires a filename and offset to process templates. - * The magic constants `__FILE__` and `__COMPILER_HALT_OFFSET__` are usually - * perfectly suited to the job: - * - * $loader = new Mustache_Loader_InlineLoader(__FILE__, __COMPILER_HALT_OFFSET__); - * - * Note that this only works if the loader is instantiated inside the same - * file as the inline templates. If the templates are located in another - * file, it would be necessary to manually specify the filename and offset. - * - * @param string $fileName The file to parse for inline templates - * @param int $offset A string offset for the start of the templates. - * This usually coincides with the `__halt_compiler` - * call, and the `__COMPILER_HALT_OFFSET__`. - */ - public function __construct($fileName, $offset) - { - if (!is_file($fileName)) { - throw new Mustache_Exception_InvalidArgumentException('InlineLoader expects a valid filename.'); - } - - if (!is_int($offset) || $offset < 0) { - throw new Mustache_Exception_InvalidArgumentException('InlineLoader expects a valid file offset.'); - } - - $this->fileName = $fileName; - $this->offset = $offset; - } - - /** - * Load a Template by name. - * - * @throws Mustache_Exception_UnknownTemplateException If a template file is not found. - * - * @param string $name - * - * @return string Mustache Template source - */ - public function load($name) - { - $this->loadTemplates(); - - if (!array_key_exists($name, $this->templates)) { - throw new Mustache_Exception_UnknownTemplateException($name); - } - - return $this->templates[$name]; - } - - /** - * Parse and load templates from the end of a source file. - */ - protected function loadTemplates() - { - if ($this->templates === null) { - $this->templates = array(); - $data = file_get_contents($this->fileName, false, null, $this->offset); - foreach (preg_split("/^@@(?= [\w\d\.]+$)/m", $data, -1) as $chunk) { - if (trim($chunk)) { - list($name, $content) = explode("\n", $chunk, 2); - $this->templates[trim($name)] = trim($content); - } - } - } - } -} +load('hello'); + * $goodbye = $loader->load('goodbye'); + * + * __halt_compiler(); + * + * @@ hello + * Hello, {{ planet }}! + * + * @@ goodbye + * Goodbye, cruel {{ planet }} + * + * Templates are deliniated by lines containing only `@@ name`. + * + * The InlineLoader is well-suited to micro-frameworks such as Silex: + * + * $app->register(new MustacheServiceProvider, array( + * 'mustache.loader' => new Mustache_Loader_InlineLoader(__FILE__, __COMPILER_HALT_OFFSET__) + * )); + * + * $app->get('/{name}', function($name) use ($app) { + * return $app['mustache']->render('hello', compact('name')); + * }) + * ->value('name', 'world'); + * + * // ... + * + * __halt_compiler(); + * + * @@ hello + * Hello, {{ name }}! + * + */ +class Mustache_Loader_InlineLoader implements Mustache_Loader +{ + protected $fileName; + protected $offset; + protected $templates; + + /** + * The InlineLoader requires a filename and offset to process templates. + * The magic constants `__FILE__` and `__COMPILER_HALT_OFFSET__` are usually + * perfectly suited to the job: + * + * $loader = new Mustache_Loader_InlineLoader(__FILE__, __COMPILER_HALT_OFFSET__); + * + * Note that this only works if the loader is instantiated inside the same + * file as the inline templates. If the templates are located in another + * file, it would be necessary to manually specify the filename and offset. + * + * @param string $fileName The file to parse for inline templates + * @param int $offset A string offset for the start of the templates. + * This usually coincides with the `__halt_compiler` + * call, and the `__COMPILER_HALT_OFFSET__`. + */ + public function __construct($fileName, $offset) + { + if (!is_file($fileName)) { + throw new Mustache_Exception_InvalidArgumentException('InlineLoader expects a valid filename.'); + } + + if (!is_int($offset) || $offset < 0) { + throw new Mustache_Exception_InvalidArgumentException('InlineLoader expects a valid file offset.'); + } + + $this->fileName = $fileName; + $this->offset = $offset; + } + + /** + * Load a Template by name. + * + * @throws Mustache_Exception_UnknownTemplateException If a template file is not found. + * + * @param string $name + * + * @return string Mustache Template source + */ + public function load($name) + { + $this->loadTemplates(); + + if (!array_key_exists($name, $this->templates)) { + throw new Mustache_Exception_UnknownTemplateException($name); + } + + return $this->templates[$name]; + } + + /** + * Parse and load templates from the end of a source file. + */ + protected function loadTemplates() + { + if ($this->templates === null) { + $this->templates = array(); + $data = file_get_contents($this->fileName, false, null, $this->offset); + foreach (preg_split("/^@@(?= [\w\d\.]+$)/m", $data, -1) as $chunk) { + if (trim($chunk)) { + list($name, $content) = explode("\n", $chunk, 2); + $this->templates[trim($name)] = trim($content); + } + } + } + } +} diff --git a/profile-builder/assets/lib/Mustache/Loader/MutableLoader.php b/profile-builder/assets/lib/Mustache/Loader/MutableLoader.php index 02bb207..952db2f 100644 --- a/profile-builder/assets/lib/Mustache/Loader/MutableLoader.php +++ b/profile-builder/assets/lib/Mustache/Loader/MutableLoader.php @@ -1,32 +1,32 @@ -load('{{ foo }}'); // '{{ foo }}' - * - * This is the default Template Loader instance used by Mustache: - * - * $m = new Mustache; - * $tpl = $m->loadTemplate('{{ foo }}'); - * echo $tpl->render(array('foo' => 'bar')); // "bar" - */ -class Mustache_Loader_StringLoader implements Mustache_Loader -{ - - /** - * Load a Template by source. - * - * @param string $name Mustache Template source - * - * @return string Mustache Template source - */ - public function load($name) - { - return $name; - } -} +load('{{ foo }}'); // '{{ foo }}' + * + * This is the default Template Loader instance used by Mustache: + * + * $m = new Mustache; + * $tpl = $m->loadTemplate('{{ foo }}'); + * echo $tpl->render(array('foo' => 'bar')); // "bar" + */ +class Mustache_Loader_StringLoader implements Mustache_Loader +{ + + /** + * Load a Template by source. + * + * @param string $name Mustache Template source + * + * @return string Mustache Template source + */ + public function load($name) + { + return $name; + } +} diff --git a/profile-builder/assets/lib/Mustache/Logger.php b/profile-builder/assets/lib/Mustache/Logger.php index e08359a..71c11b5 100644 --- a/profile-builder/assets/lib/Mustache/Logger.php +++ b/profile-builder/assets/lib/Mustache/Logger.php @@ -1,135 +1,135 @@ -log(Mustache_Logger::EMERGENCY, $message, $context); - } - - /** - * Action must be taken immediately. - * - * Example: Entire website down, database unavailable, etc. This should - * trigger the SMS alerts and wake you up. - * - * @param string $message - * @param array $context - */ - public function alert($message, array $context = array()) - { - $this->log(Mustache_Logger::ALERT, $message, $context); - } - - /** - * Critical conditions. - * - * Example: Application component unavailable, unexpected exception. - * - * @param string $message - * @param array $context - */ - public function critical($message, array $context = array()) - { - $this->log(Mustache_Logger::CRITICAL, $message, $context); - } - - /** - * Runtime errors that do not require immediate action but should typically - * be logged and monitored. - * - * @param string $message - * @param array $context - */ - public function error($message, array $context = array()) - { - $this->log(Mustache_Logger::ERROR, $message, $context); - } - - /** - * Exceptional occurrences that are not errors. - * - * Example: Use of deprecated APIs, poor use of an API, undesirable things - * that are not necessarily wrong. - * - * @param string $message - * @param array $context - */ - public function warning($message, array $context = array()) - { - $this->log(Mustache_Logger::WARNING, $message, $context); - } - - /** - * Normal but significant events. - * - * @param string $message - * @param array $context - */ - public function notice($message, array $context = array()) - { - $this->log(Mustache_Logger::NOTICE, $message, $context); - } - - /** - * Interesting events. - * - * Example: User logs in, SQL logs. - * - * @param string $message - * @param array $context - */ - public function info($message, array $context = array()) - { - $this->log(Mustache_Logger::INFO, $message, $context); - } - - /** - * Detailed debug information. - * - * @param string $message - * @param array $context - */ - public function debug($message, array $context = array()) - { - $this->log(Mustache_Logger::DEBUG, $message, $context); - } -} +log(Mustache_Logger::EMERGENCY, $message, $context); + } + + /** + * Action must be taken immediately. + * + * Example: Entire website down, database unavailable, etc. This should + * trigger the SMS alerts and wake you up. + * + * @param string $message + * @param array $context + */ + public function alert($message, array $context = array()) + { + $this->log(Mustache_Logger::ALERT, $message, $context); + } + + /** + * Critical conditions. + * + * Example: Application component unavailable, unexpected exception. + * + * @param string $message + * @param array $context + */ + public function critical($message, array $context = array()) + { + $this->log(Mustache_Logger::CRITICAL, $message, $context); + } + + /** + * Runtime errors that do not require immediate action but should typically + * be logged and monitored. + * + * @param string $message + * @param array $context + */ + public function error($message, array $context = array()) + { + $this->log(Mustache_Logger::ERROR, $message, $context); + } + + /** + * Exceptional occurrences that are not errors. + * + * Example: Use of deprecated APIs, poor use of an API, undesirable things + * that are not necessarily wrong. + * + * @param string $message + * @param array $context + */ + public function warning($message, array $context = array()) + { + $this->log(Mustache_Logger::WARNING, $message, $context); + } + + /** + * Normal but significant events. + * + * @param string $message + * @param array $context + */ + public function notice($message, array $context = array()) + { + $this->log(Mustache_Logger::NOTICE, $message, $context); + } + + /** + * Interesting events. + * + * Example: User logs in, SQL logs. + * + * @param string $message + * @param array $context + */ + public function info($message, array $context = array()) + { + $this->log(Mustache_Logger::INFO, $message, $context); + } + + /** + * Detailed debug information. + * + * @param string $message + * @param array $context + */ + public function debug($message, array $context = array()) + { + $this->log(Mustache_Logger::DEBUG, $message, $context); + } +} diff --git a/profile-builder/assets/lib/Mustache/Logger/StreamLogger.php b/profile-builder/assets/lib/Mustache/Logger/StreamLogger.php index da771f9..b56e7da 100644 --- a/profile-builder/assets/lib/Mustache/Logger/StreamLogger.php +++ b/profile-builder/assets/lib/Mustache/Logger/StreamLogger.php @@ -1,193 +1,193 @@ - 100, - self::INFO => 200, - self::NOTICE => 250, - self::WARNING => 300, - self::ERROR => 400, - self::CRITICAL => 500, - self::ALERT => 550, - self::EMERGENCY => 600, - ); - - protected $stream = null; - protected $url = null; - - /** - * @throws InvalidArgumentException if the logging level is unknown. - * - * @param string $stream Resource instance or URL - * @param integer $level The minimum logging level at which this handler will be triggered - */ - public function __construct($stream, $level = Mustache_Logger::ERROR) - { - $this->setLevel($level); - - if (is_resource($stream)) { - $this->stream = $stream; - } else { - $this->url = $stream; - } - } - - /** - * Close stream resources. - */ - public function __destruct() - { - if (is_resource($this->stream)) { - fclose($this->stream); - } - } - - /** - * Set the minimum logging level. - * - * @throws Mustache_Exception_InvalidArgumentException if the logging level is unknown. - * - * @param integer $level The minimum logging level which will be written - */ - public function setLevel($level) - { - if (!array_key_exists($level, self::$levels)) { - throw new Mustache_Exception_InvalidArgumentException(sprintf('Unexpected logging level: %s', $level)); - } - - $this->level = $level; - } - - /** - * Get the current minimum logging level. - * - * @return integer - */ - public function getLevel() - { - return $this->level; - } - - /** - * Logs with an arbitrary level. - * - * @throws Mustache_Exception_InvalidArgumentException if the logging level is unknown. - * - * @param mixed $level - * @param string $message - * @param array $context - */ - public function log($level, $message, array $context = array()) - { - if (!array_key_exists($level, self::$levels)) { - throw new Mustache_Exception_InvalidArgumentException(sprintf('Unexpected logging level: %s', $level)); - } - - if (self::$levels[$level] >= self::$levels[$this->level]) { - $this->writeLog($level, $message, $context); - } - } - - /** - * Write a record to the log. - * - * @throws Mustache_Exception_LogicException If neither a stream resource nor url is present. - * @throws Mustache_Exception_RuntimeException If the stream url cannot be opened. - * - * @param integer $level The logging level - * @param string $message The log message - * @param array $context The log context - */ - protected function writeLog($level, $message, array $context = array()) - { - if (!is_resource($this->stream)) { - if (!isset($this->url)) { - throw new Mustache_Exception_LogicException('Missing stream url, the stream can not be opened. This may be caused by a premature call to close().'); - } - - $this->stream = fopen($this->url, 'a'); - if (!is_resource($this->stream)) { - // @codeCoverageIgnoreStart - throw new Mustache_Exception_RuntimeException(sprintf('The stream or file "%s" could not be opened.', $this->url)); - // @codeCoverageIgnoreEnd - } - } - - fwrite($this->stream, self::formatLine($level, $message, $context)); - } - - /** - * Gets the name of the logging level. - * - * @throws InvalidArgumentException if the logging level is unknown. - * - * @param integer $level - * - * @return string - */ - protected static function getLevelName($level) - { - return strtoupper($level); - } - - /** - * Format a log line for output. - * - * @param integer $level The logging level - * @param string $message The log message - * @param array $context The log context - * - * @return string - */ - protected static function formatLine($level, $message, array $context = array()) - { - return sprintf( - "%s: %s\n", - self::getLevelName($level), - self::interpolateMessage($message, $context) - ); - } - - /** - * Interpolate context values into the message placeholders. - * - * @param string $message - * @param array $context - * - * @return string - */ - protected static function interpolateMessage($message, array $context = array()) - { - if (strpos($message, '{') === false) { - return $message; - } - - // build a replacement array with braces around the context keys - $replace = array(); - foreach ($context as $key => $val) { - $replace['{' . $key . '}'] = $val; - } - - // interpolate replacement values into the the message and return - return strtr($message, $replace); - } -} + 100, + self::INFO => 200, + self::NOTICE => 250, + self::WARNING => 300, + self::ERROR => 400, + self::CRITICAL => 500, + self::ALERT => 550, + self::EMERGENCY => 600, + ); + + protected $stream = null; + protected $url = null; + + /** + * @throws InvalidArgumentException if the logging level is unknown. + * + * @param string $stream Resource instance or URL + * @param integer $level The minimum logging level at which this handler will be triggered + */ + public function __construct($stream, $level = Mustache_Logger::ERROR) + { + $this->setLevel($level); + + if (is_resource($stream)) { + $this->stream = $stream; + } else { + $this->url = $stream; + } + } + + /** + * Close stream resources. + */ + public function __destruct() + { + if (is_resource($this->stream)) { + fclose($this->stream); + } + } + + /** + * Set the minimum logging level. + * + * @throws Mustache_Exception_InvalidArgumentException if the logging level is unknown. + * + * @param integer $level The minimum logging level which will be written + */ + public function setLevel($level) + { + if (!array_key_exists($level, self::$levels)) { + throw new Mustache_Exception_InvalidArgumentException(sprintf('Unexpected logging level: %s', $level)); + } + + $this->level = $level; + } + + /** + * Get the current minimum logging level. + * + * @return integer + */ + public function getLevel() + { + return $this->level; + } + + /** + * Logs with an arbitrary level. + * + * @throws Mustache_Exception_InvalidArgumentException if the logging level is unknown. + * + * @param mixed $level + * @param string $message + * @param array $context + */ + public function log($level, $message, array $context = array()) + { + if (!array_key_exists($level, self::$levels)) { + throw new Mustache_Exception_InvalidArgumentException(sprintf('Unexpected logging level: %s', $level)); + } + + if (self::$levels[$level] >= self::$levels[$this->level]) { + $this->writeLog($level, $message, $context); + } + } + + /** + * Write a record to the log. + * + * @throws Mustache_Exception_LogicException If neither a stream resource nor url is present. + * @throws Mustache_Exception_RuntimeException If the stream url cannot be opened. + * + * @param integer $level The logging level + * @param string $message The log message + * @param array $context The log context + */ + protected function writeLog($level, $message, array $context = array()) + { + if (!is_resource($this->stream)) { + if (!isset($this->url)) { + throw new Mustache_Exception_LogicException('Missing stream url, the stream can not be opened. This may be caused by a premature call to close().'); + } + + $this->stream = fopen($this->url, 'a'); + if (!is_resource($this->stream)) { + // @codeCoverageIgnoreStart + throw new Mustache_Exception_RuntimeException(sprintf('The stream or file "%s" could not be opened.', $this->url)); + // @codeCoverageIgnoreEnd + } + } + + fwrite($this->stream, self::formatLine($level, $message, $context)); + } + + /** + * Gets the name of the logging level. + * + * @throws InvalidArgumentException if the logging level is unknown. + * + * @param integer $level + * + * @return string + */ + protected static function getLevelName($level) + { + return strtoupper($level); + } + + /** + * Format a log line for output. + * + * @param integer $level The logging level + * @param string $message The log message + * @param array $context The log context + * + * @return string + */ + protected static function formatLine($level, $message, array $context = array()) + { + return sprintf( + "%s: %s\n", + self::getLevelName($level), + self::interpolateMessage($message, $context) + ); + } + + /** + * Interpolate context values into the message placeholders. + * + * @param string $message + * @param array $context + * + * @return string + */ + protected static function interpolateMessage($message, array $context = array()) + { + if (strpos($message, '{') === false) { + return $message; + } + + // build a replacement array with braces around the context keys + $replace = array(); + foreach ($context as $key => $val) { + $replace['{' . $key . '}'] = $val; + } + + // interpolate replacement values into the the message and return + return strtr($message, $replace); + } +} diff --git a/profile-builder/assets/lib/Mustache/Parser.php b/profile-builder/assets/lib/Mustache/Parser.php index 697ce7f..e7a3df9 100644 --- a/profile-builder/assets/lib/Mustache/Parser.php +++ b/profile-builder/assets/lib/Mustache/Parser.php @@ -1,194 +1,194 @@ -lineNum = -1; - $this->lineTokens = 0; - - return $this->buildTree($tokens); - } - - /** - * Helper method for recursively building a parse tree. - * - * @throws Mustache_Exception_SyntaxException when nesting errors or mismatched section tags are encountered. - * - * @param array &$tokens Set of Mustache tokens - * @param array $parent Parent token (default: null) - * - * @return array Mustache Token parse tree - */ - private function buildTree(array &$tokens, array $parent = null) - { - $nodes = array(); - - while (!empty($tokens)) { - $token = array_shift($tokens); - - if ($token[Mustache_Tokenizer::LINE] === $this->lineNum) { - $this->lineTokens++; - } else { - $this->lineNum = $token[Mustache_Tokenizer::LINE]; - $this->lineTokens = 0; - } - - switch ($token[Mustache_Tokenizer::TYPE]) { - case Mustache_Tokenizer::T_DELIM_CHANGE: - $this->clearStandaloneLines($nodes, $tokens); - break; - - case Mustache_Tokenizer::T_SECTION: - case Mustache_Tokenizer::T_INVERTED: - $this->clearStandaloneLines($nodes, $tokens); - $nodes[] = $this->buildTree($tokens, $token); - break; - - case Mustache_Tokenizer::T_END_SECTION: - if (!isset($parent)) { - $msg = sprintf('Unexpected closing tag: /%s', $token[Mustache_Tokenizer::NAME]); - throw new Mustache_Exception_SyntaxException($msg, $token); - } - - if ($token[Mustache_Tokenizer::NAME] !== $parent[Mustache_Tokenizer::NAME]) { - $msg = sprintf('Nesting error: %s vs. %s', $parent[Mustache_Tokenizer::NAME], $token[Mustache_Tokenizer::NAME]); - throw new Mustache_Exception_SyntaxException($msg, $token); - } - - $this->clearStandaloneLines($nodes, $tokens); - $parent[Mustache_Tokenizer::END] = $token[Mustache_Tokenizer::INDEX]; - $parent[Mustache_Tokenizer::NODES] = $nodes; - - return $parent; - break; - - case Mustache_Tokenizer::T_PARTIAL: - case Mustache_Tokenizer::T_PARTIAL_2: - // store the whitespace prefix for laters! - if ($indent = $this->clearStandaloneLines($nodes, $tokens)) { - $token[Mustache_Tokenizer::INDENT] = $indent[Mustache_Tokenizer::VALUE]; - } - $nodes[] = $token; - break; - - case Mustache_Tokenizer::T_PRAGMA: - case Mustache_Tokenizer::T_COMMENT: - $this->clearStandaloneLines($nodes, $tokens); - $nodes[] = $token; - break; - - default: - $nodes[] = $token; - break; - } - } - - if (isset($parent)) { - $msg = sprintf('Missing closing tag: %s', $parent[Mustache_Tokenizer::NAME]); - throw new Mustache_Exception_SyntaxException($msg, $parent); - } - - return $nodes; - } - - /** - * Clear standalone line tokens. - * - * Returns a whitespace token for indenting partials, if applicable. - * - * @param array $nodes Parsed nodes. - * @param array $tokens Tokens to be parsed. - * - * @return array Resulting indent token, if any. - */ - private function clearStandaloneLines(array &$nodes, array &$tokens) - { - if ($this->lineTokens > 1) { - // this is the third or later node on this line, so it can't be standalone - return; - } - - $prev = null; - if ($this->lineTokens === 1) { - // this is the second node on this line, so it can't be standalone - // unless the previous node is whitespace. - if ($prev = end($nodes)) { - if (!$this->tokenIsWhitespace($prev)) { - return; - } - } - } - - $next = null; - if ($next = reset($tokens)) { - // If we're on a new line, bail. - if ($next[Mustache_Tokenizer::LINE] !== $this->lineNum) { - return; - } - - // If the next token isn't whitespace, bail. - if (!$this->tokenIsWhitespace($next)) { - return; - } - - if (count($tokens) !== 1) { - // Unless it's the last token in the template, the next token - // must end in newline for this to be standalone. - if (substr($next[Mustache_Tokenizer::VALUE], -1) !== "\n") { - return; - } - } - - // Discard the whitespace suffix - array_shift($tokens); - } - - if ($prev) { - // Return the whitespace prefix, if any - return array_pop($nodes); - } - } - - /** - * Check whether token is a whitespace token. - * - * True if token type is T_TEXT and value is all whitespace characters. - * - * @param array $token - * - * @return boolean True if token is a whitespace token - */ - private function tokenIsWhitespace(array $token) - { - if ($token[Mustache_Tokenizer::TYPE] == Mustache_Tokenizer::T_TEXT) { - return preg_match('/^\s*$/', $token[Mustache_Tokenizer::VALUE]); - } - - return false; - } -} +lineNum = -1; + $this->lineTokens = 0; + + return $this->buildTree($tokens); + } + + /** + * Helper method for recursively building a parse tree. + * + * @throws Mustache_Exception_SyntaxException when nesting errors or mismatched section tags are encountered. + * + * @param array &$tokens Set of Mustache tokens + * @param array $parent Parent token (default: null) + * + * @return array Mustache Token parse tree + */ + private function buildTree(array &$tokens, array $parent = null) + { + $nodes = array(); + + while (!empty($tokens)) { + $token = array_shift($tokens); + + if ($token[Mustache_Tokenizer::LINE] === $this->lineNum) { + $this->lineTokens++; + } else { + $this->lineNum = $token[Mustache_Tokenizer::LINE]; + $this->lineTokens = 0; + } + + switch ($token[Mustache_Tokenizer::TYPE]) { + case Mustache_Tokenizer::T_DELIM_CHANGE: + $this->clearStandaloneLines($nodes, $tokens); + break; + + case Mustache_Tokenizer::T_SECTION: + case Mustache_Tokenizer::T_INVERTED: + $this->clearStandaloneLines($nodes, $tokens); + $nodes[] = $this->buildTree($tokens, $token); + break; + + case Mustache_Tokenizer::T_END_SECTION: + if (!isset($parent)) { + $msg = sprintf('Unexpected closing tag: /%s', $token[Mustache_Tokenizer::NAME]); + throw new Mustache_Exception_SyntaxException($msg, $token); + } + + if ($token[Mustache_Tokenizer::NAME] !== $parent[Mustache_Tokenizer::NAME]) { + $msg = sprintf('Nesting error: %s vs. %s', $parent[Mustache_Tokenizer::NAME], $token[Mustache_Tokenizer::NAME]); + throw new Mustache_Exception_SyntaxException($msg, $token); + } + + $this->clearStandaloneLines($nodes, $tokens); + $parent[Mustache_Tokenizer::END] = $token[Mustache_Tokenizer::INDEX]; + $parent[Mustache_Tokenizer::NODES] = $nodes; + + return $parent; + break; + + case Mustache_Tokenizer::T_PARTIAL: + case Mustache_Tokenizer::T_PARTIAL_2: + // store the whitespace prefix for laters! + if ($indent = $this->clearStandaloneLines($nodes, $tokens)) { + $token[Mustache_Tokenizer::INDENT] = $indent[Mustache_Tokenizer::VALUE]; + } + $nodes[] = $token; + break; + + case Mustache_Tokenizer::T_PRAGMA: + case Mustache_Tokenizer::T_COMMENT: + $this->clearStandaloneLines($nodes, $tokens); + $nodes[] = $token; + break; + + default: + $nodes[] = $token; + break; + } + } + + if (isset($parent)) { + $msg = sprintf('Missing closing tag: %s', $parent[Mustache_Tokenizer::NAME]); + throw new Mustache_Exception_SyntaxException($msg, $parent); + } + + return $nodes; + } + + /** + * Clear standalone line tokens. + * + * Returns a whitespace token for indenting partials, if applicable. + * + * @param array $nodes Parsed nodes. + * @param array $tokens Tokens to be parsed. + * + * @return array Resulting indent token, if any. + */ + private function clearStandaloneLines(array &$nodes, array &$tokens) + { + if ($this->lineTokens > 1) { + // this is the third or later node on this line, so it can't be standalone + return; + } + + $prev = null; + if ($this->lineTokens === 1) { + // this is the second node on this line, so it can't be standalone + // unless the previous node is whitespace. + if ($prev = end($nodes)) { + if (!$this->tokenIsWhitespace($prev)) { + return; + } + } + } + + $next = null; + if ($next = reset($tokens)) { + // If we're on a new line, bail. + if ($next[Mustache_Tokenizer::LINE] !== $this->lineNum) { + return; + } + + // If the next token isn't whitespace, bail. + if (!$this->tokenIsWhitespace($next)) { + return; + } + + if (count($tokens) !== 1) { + // Unless it's the last token in the template, the next token + // must end in newline for this to be standalone. + if (substr($next[Mustache_Tokenizer::VALUE], -1) !== "\n") { + return; + } + } + + // Discard the whitespace suffix + array_shift($tokens); + } + + if ($prev) { + // Return the whitespace prefix, if any + return array_pop($nodes); + } + } + + /** + * Check whether token is a whitespace token. + * + * True if token type is T_TEXT and value is all whitespace characters. + * + * @param array $token + * + * @return boolean True if token is a whitespace token + */ + private function tokenIsWhitespace(array $token) + { + if ($token[Mustache_Tokenizer::TYPE] == Mustache_Tokenizer::T_TEXT) { + return preg_match('/^\s*$/', $token[Mustache_Tokenizer::VALUE]); + } + + return false; + } +} diff --git a/profile-builder/assets/lib/Mustache/Template.php b/profile-builder/assets/lib/Mustache/Template.php index aeee42d..eaaf137 100644 --- a/profile-builder/assets/lib/Mustache/Template.php +++ b/profile-builder/assets/lib/Mustache/Template.php @@ -1,177 +1,177 @@ -mustache = $mustache; - } - - /** - * Mustache Template instances can be treated as a function and rendered by simply calling them: - * - * $m = new Mustache_Engine; - * $tpl = $m->loadTemplate('Hello, {{ name }}!'); - * echo $tpl(array('name' => 'World')); // "Hello, World!" - * - * @see Mustache_Template::render - * - * @param mixed $context Array or object rendering context (default: array()) - * - * @return string Rendered template - */ - public function __invoke($context = array()) - { - return $this->render($context); - } - - /** - * Render this template given the rendering context. - * - * @param mixed $context Array or object rendering context (default: array()) - * - * @return string Rendered template - */ - public function render($context = array()) - { - return $this->renderInternal($this->prepareContextStack($context)); - } - - /** - * Internal rendering method implemented by Mustache Template concrete subclasses. - * - * This is where the magic happens :) - * - * NOTE: This method is not part of the Mustache.php public API. - * - * @param Mustache_Context $context - * @param string $indent (default: '') - * - * @return string Rendered template - */ - abstract public function renderInternal(Mustache_Context $context, $indent = ''); - - /** - * Tests whether a value should be iterated over (e.g. in a section context). - * - * In most languages there are two distinct array types: list and hash (or whatever you want to call them). Lists - * should be iterated, hashes should be treated as objects. Mustache follows this paradigm for Ruby, Javascript, - * Java, Python, etc. - * - * PHP, however, treats lists and hashes as one primitive type: array. So Mustache.php needs a way to distinguish - * between between a list of things (numeric, normalized array) and a set of variables to be used as section context - * (associative array). In other words, this will be iterated over: - * - * $items = array( - * array('name' => 'foo'), - * array('name' => 'bar'), - * array('name' => 'baz'), - * ); - * - * ... but this will be used as a section context block: - * - * $items = array( - * 1 => array('name' => 'foo'), - * 'banana' => array('name' => 'bar'), - * 42 => array('name' => 'baz'), - * ); - * - * @param mixed $value - * - * @return boolean True if the value is 'iterable' - */ - protected function isIterable($value) - { - if (is_object($value)) { - return $value instanceof Traversable; - } elseif (is_array($value)) { - $i = 0; - foreach ($value as $k => $v) { - if ($k !== $i++) { - return false; - } - } - - return true; - } else { - return false; - } - } - - /** - * Helper method to prepare the Context stack. - * - * Adds the Mustache HelperCollection to the stack's top context frame if helpers are present. - * - * @param mixed $context Optional first context frame (default: null) - * - * @return Mustache_Context - */ - protected function prepareContextStack($context = null) - { - $stack = new Mustache_Context; - - $helpers = $this->mustache->getHelpers(); - if (!$helpers->isEmpty()) { - $stack->push($helpers); - } - - if (!empty($context)) { - $stack->push($context); - } - - return $stack; - } - - /** - * Resolve a context value. - * - * Invoke the value if it is callable, otherwise return the value. - * - * @param mixed $value - * @param Mustache_Context $context - * @param string $indent - * - * @return string - */ - protected function resolveValue($value, Mustache_Context $context, $indent = '') - { - if (($this->strictCallables ? is_object($value) : !is_string($value)) && is_callable($value)) { - return $this->mustache - ->loadLambda((string) call_user_func($value)) - ->renderInternal($context, $indent); - } - - return $value; - } -} +mustache = $mustache; + } + + /** + * Mustache Template instances can be treated as a function and rendered by simply calling them: + * + * $m = new Mustache_Engine; + * $tpl = $m->loadTemplate('Hello, {{ name }}!'); + * echo $tpl(array('name' => 'World')); // "Hello, World!" + * + * @see Mustache_Template::render + * + * @param mixed $context Array or object rendering context (default: array()) + * + * @return string Rendered template + */ + public function __invoke($context = array()) + { + return $this->render($context); + } + + /** + * Render this template given the rendering context. + * + * @param mixed $context Array or object rendering context (default: array()) + * + * @return string Rendered template + */ + public function render($context = array()) + { + return $this->renderInternal($this->prepareContextStack($context)); + } + + /** + * Internal rendering method implemented by Mustache Template concrete subclasses. + * + * This is where the magic happens :) + * + * NOTE: This method is not part of the Mustache.php public API. + * + * @param Mustache_Context $context + * @param string $indent (default: '') + * + * @return string Rendered template + */ + abstract public function renderInternal(Mustache_Context $context, $indent = ''); + + /** + * Tests whether a value should be iterated over (e.g. in a section context). + * + * In most languages there are two distinct array types: list and hash (or whatever you want to call them). Lists + * should be iterated, hashes should be treated as objects. Mustache follows this paradigm for Ruby, Javascript, + * Java, Python, etc. + * + * PHP, however, treats lists and hashes as one primitive type: array. So Mustache.php needs a way to distinguish + * between between a list of things (numeric, normalized array) and a set of variables to be used as section context + * (associative array). In other words, this will be iterated over: + * + * $items = array( + * array('name' => 'foo'), + * array('name' => 'bar'), + * array('name' => 'baz'), + * ); + * + * ... but this will be used as a section context block: + * + * $items = array( + * 1 => array('name' => 'foo'), + * 'banana' => array('name' => 'bar'), + * 42 => array('name' => 'baz'), + * ); + * + * @param mixed $value + * + * @return boolean True if the value is 'iterable' + */ + protected function isIterable($value) + { + if (is_object($value)) { + return $value instanceof Traversable; + } elseif (is_array($value)) { + $i = 0; + foreach ($value as $k => $v) { + if ($k !== $i++) { + return false; + } + } + + return true; + } else { + return false; + } + } + + /** + * Helper method to prepare the Context stack. + * + * Adds the Mustache HelperCollection to the stack's top context frame if helpers are present. + * + * @param mixed $context Optional first context frame (default: null) + * + * @return Mustache_Context + */ + protected function prepareContextStack($context = null) + { + $stack = new Mustache_Context; + + $helpers = $this->mustache->getHelpers(); + if (!$helpers->isEmpty()) { + $stack->push($helpers); + } + + if (!empty($context)) { + $stack->push($context); + } + + return $stack; + } + + /** + * Resolve a context value. + * + * Invoke the value if it is callable, otherwise return the value. + * + * @param mixed $value + * @param Mustache_Context $context + * @param string $indent + * + * @return string + */ + protected function resolveValue($value, Mustache_Context $context, $indent = '') + { + if (($this->strictCallables ? is_object($value) : !is_string($value)) && is_callable($value)) { + return $this->mustache + ->loadLambda((string) call_user_func($value)) + ->renderInternal($context, $indent); + } + + return $value; + } +} diff --git a/profile-builder/assets/lib/Mustache/Tokenizer.php b/profile-builder/assets/lib/Mustache/Tokenizer.php index e065622..f1f9727 100644 --- a/profile-builder/assets/lib/Mustache/Tokenizer.php +++ b/profile-builder/assets/lib/Mustache/Tokenizer.php @@ -1,278 +1,278 @@ -'; - const T_PARTIAL_2 = '<'; - const T_DELIM_CHANGE = '='; - const T_ESCAPED = '_v'; - const T_UNESCAPED = '{'; - const T_UNESCAPED_2 = '&'; - const T_TEXT = '_t'; - const T_PRAGMA = '%'; - - // Valid token types - private static $tagTypes = array( - self::T_SECTION => true, - self::T_INVERTED => true, - self::T_END_SECTION => true, - self::T_COMMENT => true, - self::T_PARTIAL => true, - self::T_PARTIAL_2 => true, - self::T_DELIM_CHANGE => true, - self::T_ESCAPED => true, - self::T_UNESCAPED => true, - self::T_UNESCAPED_2 => true, - self::T_PRAGMA => true, - ); - - // Interpolated tags - private static $interpolatedTags = array( - self::T_ESCAPED => true, - self::T_UNESCAPED => true, - self::T_UNESCAPED_2 => true, - ); - - // Token properties - const TYPE = 'type'; - const NAME = 'name'; - const OTAG = 'otag'; - const CTAG = 'ctag'; - const LINE = 'line'; - const INDEX = 'index'; - const END = 'end'; - const INDENT = 'indent'; - const NODES = 'nodes'; - const VALUE = 'value'; - - private $state; - private $tagType; - private $tag; - private $buffer; - private $tokens; - private $seenTag; - private $line; - private $otag; - private $ctag; - - /** - * Scan and tokenize template source. - * - * @param string $text Mustache template source to tokenize - * @param string $delimiters Optionally, pass initial opening and closing delimiters (default: null) - * - * @return array Set of Mustache tokens - */ - public function scan($text, $delimiters = null) - { - $this->reset(); - - if ($delimiters = trim($delimiters)) { - list($otag, $ctag) = explode(' ', $delimiters); - $this->otag = $otag; - $this->ctag = $ctag; - } - - $len = strlen($text); - for ($i = 0; $i < $len; $i++) { - switch ($this->state) { - case self::IN_TEXT: - if ($this->tagChange($this->otag, $text, $i)) { - $i--; - $this->flushBuffer(); - $this->state = self::IN_TAG_TYPE; - } else { - $char = substr($text, $i, 1); - $this->buffer .= $char; - if ($char == "\n") { - $this->flushBuffer(); - $this->line++; - } - } - break; - - case self::IN_TAG_TYPE: - $i += strlen($this->otag) - 1; - $char = substr($text, $i + 1, 1); - if (isset(self::$tagTypes[$char])) { - $tag = $char; - $this->tagType = $tag; - } else { - $tag = null; - $this->tagType = self::T_ESCAPED; - } - - if ($this->tagType === self::T_DELIM_CHANGE) { - $i = $this->changeDelimiters($text, $i); - $this->state = self::IN_TEXT; - } elseif ($this->tagType === self::T_PRAGMA) { - $i = $this->addPragma($text, $i); - $this->state = self::IN_TEXT; - } else { - if ($tag !== null) { - $i++; - } - $this->state = self::IN_TAG; - } - $this->seenTag = $i; - break; - - default: - if ($this->tagChange($this->ctag, $text, $i)) { - $this->tokens[] = array( - self::TYPE => $this->tagType, - self::NAME => trim($this->buffer), - self::OTAG => $this->otag, - self::CTAG => $this->ctag, - self::LINE => $this->line, - self::INDEX => ($this->tagType == self::T_END_SECTION) ? $this->seenTag - strlen($this->otag) : $i + strlen($this->ctag) - ); - - $this->buffer = ''; - $i += strlen($this->ctag) - 1; - $this->state = self::IN_TEXT; - if ($this->tagType == self::T_UNESCAPED) { - if ($this->ctag == '}}') { - $i++; - } else { - // Clean up `{{{ tripleStache }}}` style tokens. - $lastName = $this->tokens[count($this->tokens) - 1][self::NAME]; - if (substr($lastName, -1) === '}') { - $this->tokens[count($this->tokens) - 1][self::NAME] = trim(substr($lastName, 0, -1)); - } - } - } - } else { - $this->buffer .= substr($text, $i, 1); - } - break; - } - } - - $this->flushBuffer(); - - return $this->tokens; - } - - /** - * Helper function to reset tokenizer internal state. - */ - private function reset() - { - $this->state = self::IN_TEXT; - $this->tagType = null; - $this->tag = null; - $this->buffer = ''; - $this->tokens = array(); - $this->seenTag = false; - $this->line = 0; - $this->otag = '{{'; - $this->ctag = '}}'; - } - - /** - * Flush the current buffer to a token. - */ - private function flushBuffer() - { - if (!empty($this->buffer)) { - $this->tokens[] = array( - self::TYPE => self::T_TEXT, - self::LINE => $this->line, - self::VALUE => $this->buffer - ); - $this->buffer = ''; - } - } - - /** - * Change the current Mustache delimiters. Set new `otag` and `ctag` values. - * - * @param string $text Mustache template source - * @param int $index Current tokenizer index - * - * @return int New index value - */ - private function changeDelimiters($text, $index) - { - $startIndex = strpos($text, '=', $index) + 1; - $close = '='.$this->ctag; - $closeIndex = strpos($text, $close, $index); - - list($otag, $ctag) = explode(' ', trim(substr($text, $startIndex, $closeIndex - $startIndex))); - $this->otag = $otag; - $this->ctag = $ctag; - - $this->tokens[] = array( - self::TYPE => self::T_DELIM_CHANGE, - self::LINE => $this->line, - ); - - return $closeIndex + strlen($close) - 1; - } - - /** - * Add pragma token. - * - * Pragmas are hoisted to the front of the template, so all pragma tokens - * will appear at the front of the token list. - * - * @param string $text - * @param int $index - * - * @return int New index value - */ - private function addPragma($text, $index) - { - $end = strpos($text, $this->ctag, $index); - $pragma = trim(substr($text, $index + 2, $end - $index - 2)); - - // Pragmas are hoisted to the front of the template. - array_unshift($this->tokens, array( - self::TYPE => self::T_PRAGMA, - self::NAME => $pragma, - self::LINE => 0, - )); - - return $end + strlen($this->ctag) - 1; - } - - /** - * Test whether it's time to change tags. - * - * @param string $tag Current tag name - * @param string $text Mustache template source - * @param int $index Current tokenizer index - * - * @return boolean True if this is a closing section tag - */ - private function tagChange($tag, $text, $index) - { - return substr($text, $index, strlen($tag)) === $tag; - } -} +'; + const T_PARTIAL_2 = '<'; + const T_DELIM_CHANGE = '='; + const T_ESCAPED = '_v'; + const T_UNESCAPED = '{'; + const T_UNESCAPED_2 = '&'; + const T_TEXT = '_t'; + const T_PRAGMA = '%'; + + // Valid token types + private static $tagTypes = array( + self::T_SECTION => true, + self::T_INVERTED => true, + self::T_END_SECTION => true, + self::T_COMMENT => true, + self::T_PARTIAL => true, + self::T_PARTIAL_2 => true, + self::T_DELIM_CHANGE => true, + self::T_ESCAPED => true, + self::T_UNESCAPED => true, + self::T_UNESCAPED_2 => true, + self::T_PRAGMA => true, + ); + + // Interpolated tags + private static $interpolatedTags = array( + self::T_ESCAPED => true, + self::T_UNESCAPED => true, + self::T_UNESCAPED_2 => true, + ); + + // Token properties + const TYPE = 'type'; + const NAME = 'name'; + const OTAG = 'otag'; + const CTAG = 'ctag'; + const LINE = 'line'; + const INDEX = 'index'; + const END = 'end'; + const INDENT = 'indent'; + const NODES = 'nodes'; + const VALUE = 'value'; + + private $state; + private $tagType; + private $tag; + private $buffer; + private $tokens; + private $seenTag; + private $line; + private $otag; + private $ctag; + + /** + * Scan and tokenize template source. + * + * @param string $text Mustache template source to tokenize + * @param string $delimiters Optionally, pass initial opening and closing delimiters (default: null) + * + * @return array Set of Mustache tokens + */ + public function scan($text, $delimiters = null) + { + $this->reset(); + + if ($delimiters = trim($delimiters)) { + list($otag, $ctag) = explode(' ', $delimiters); + $this->otag = $otag; + $this->ctag = $ctag; + } + + $len = strlen($text); + for ($i = 0; $i < $len; $i++) { + switch ($this->state) { + case self::IN_TEXT: + if ($this->tagChange($this->otag, $text, $i)) { + $i--; + $this->flushBuffer(); + $this->state = self::IN_TAG_TYPE; + } else { + $char = substr($text, $i, 1); + $this->buffer .= $char; + if ($char == "\n") { + $this->flushBuffer(); + $this->line++; + } + } + break; + + case self::IN_TAG_TYPE: + $i += strlen($this->otag) - 1; + $char = substr($text, $i + 1, 1); + if (isset(self::$tagTypes[$char])) { + $tag = $char; + $this->tagType = $tag; + } else { + $tag = null; + $this->tagType = self::T_ESCAPED; + } + + if ($this->tagType === self::T_DELIM_CHANGE) { + $i = $this->changeDelimiters($text, $i); + $this->state = self::IN_TEXT; + } elseif ($this->tagType === self::T_PRAGMA) { + $i = $this->addPragma($text, $i); + $this->state = self::IN_TEXT; + } else { + if ($tag !== null) { + $i++; + } + $this->state = self::IN_TAG; + } + $this->seenTag = $i; + break; + + default: + if ($this->tagChange($this->ctag, $text, $i)) { + $this->tokens[] = array( + self::TYPE => $this->tagType, + self::NAME => trim($this->buffer), + self::OTAG => $this->otag, + self::CTAG => $this->ctag, + self::LINE => $this->line, + self::INDEX => ($this->tagType == self::T_END_SECTION) ? $this->seenTag - strlen($this->otag) : $i + strlen($this->ctag) + ); + + $this->buffer = ''; + $i += strlen($this->ctag) - 1; + $this->state = self::IN_TEXT; + if ($this->tagType == self::T_UNESCAPED) { + if ($this->ctag == '}}') { + $i++; + } else { + // Clean up `{{{ tripleStache }}}` style tokens. + $lastName = $this->tokens[count($this->tokens) - 1][self::NAME]; + if (substr($lastName, -1) === '}') { + $this->tokens[count($this->tokens) - 1][self::NAME] = trim(substr($lastName, 0, -1)); + } + } + } + } else { + $this->buffer .= substr($text, $i, 1); + } + break; + } + } + + $this->flushBuffer(); + + return $this->tokens; + } + + /** + * Helper function to reset tokenizer internal state. + */ + private function reset() + { + $this->state = self::IN_TEXT; + $this->tagType = null; + $this->tag = null; + $this->buffer = ''; + $this->tokens = array(); + $this->seenTag = false; + $this->line = 0; + $this->otag = '{{'; + $this->ctag = '}}'; + } + + /** + * Flush the current buffer to a token. + */ + private function flushBuffer() + { + if (!empty($this->buffer)) { + $this->tokens[] = array( + self::TYPE => self::T_TEXT, + self::LINE => $this->line, + self::VALUE => $this->buffer + ); + $this->buffer = ''; + } + } + + /** + * Change the current Mustache delimiters. Set new `otag` and `ctag` values. + * + * @param string $text Mustache template source + * @param int $index Current tokenizer index + * + * @return int New index value + */ + private function changeDelimiters($text, $index) + { + $startIndex = strpos($text, '=', $index) + 1; + $close = '='.$this->ctag; + $closeIndex = strpos($text, $close, $index); + + list($otag, $ctag) = explode(' ', trim(substr($text, $startIndex, $closeIndex - $startIndex))); + $this->otag = $otag; + $this->ctag = $ctag; + + $this->tokens[] = array( + self::TYPE => self::T_DELIM_CHANGE, + self::LINE => $this->line, + ); + + return $closeIndex + strlen($close) - 1; + } + + /** + * Add pragma token. + * + * Pragmas are hoisted to the front of the template, so all pragma tokens + * will appear at the front of the token list. + * + * @param string $text + * @param int $index + * + * @return int New index value + */ + private function addPragma($text, $index) + { + $end = strpos($text, $this->ctag, $index); + $pragma = trim(substr($text, $index + 2, $end - $index - 2)); + + // Pragmas are hoisted to the front of the template. + array_unshift($this->tokens, array( + self::TYPE => self::T_PRAGMA, + self::NAME => $pragma, + self::LINE => 0, + )); + + return $end + strlen($this->ctag) - 1; + } + + /** + * Test whether it's time to change tags. + * + * @param string $tag Current tag name + * @param string $text Mustache template source + * @param int $index Current tokenizer index + * + * @return boolean True if this is a closing section tag + */ + private function tagChange($tag, $text, $index) + { + return substr($text, $index, strlen($tag)) === $tag; + } +} diff --git a/profile-builder/assets/lib/class_notices.php b/profile-builder/assets/lib/class_notices.php index f85caf6..6f75d72 100644 --- a/profile-builder/assets/lib/class_notices.php +++ b/profile-builder/assets/lib/class_notices.php @@ -1,64 +1,64 @@ -notificationId = $notificationId; - $this->notificationMessage = $notificationMessage; - $this->notificationClass = $notificationClass; - - if( !empty( $startDate ) && time() < strtotime( $startDate ) ) - return; - - if( !empty( $endDate ) && time() > strtotime( $endDate ) ) - return; - - add_action( 'admin_notices', array( $this, 'add_admin_notice' ) ); - add_action( 'admin_init', array( $this, 'dismiss_notification' ) ); - } - - - // Display a notice that can be dismissed in case the serial number is inactive - function add_admin_notice() { - global $current_user ; - global $pagenow; - - $user_id = $current_user->ID; - do_action( $this->notificationId.'_before_notification_displayed', $current_user, $pagenow ); - - if ( current_user_can( 'manage_options' ) ){ - // Check that the user hasn't already clicked to ignore the message - if ( ! get_user_meta($user_id, $this->notificationId.'_dismiss_notification' ) ) { - echo $finalMessage = apply_filters($this->notificationId.'_notification_message','
            '.$this->notificationMessage.'
            ', $this->notificationMessage); - } - do_action( $this->notificationId.'_notification_displayed', $current_user, $pagenow ); - } - do_action( $this->notificationId.'_after_notification_displayed', $current_user, $pagenow ); - } - - function dismiss_notification() { - global $current_user; - - $user_id = $current_user->ID; - - do_action( $this->notificationId.'_before_notification_dismissed', $current_user ); - - // If user clicks to ignore the notice, add that to their user meta - if ( isset( $_GET[$this->notificationId.'_dismiss_notification']) && '0' == $_GET[$this->notificationId.'_dismiss_notification'] ) - add_user_meta( $user_id, $this->notificationId.'_dismiss_notification', 'true', true ); - - do_action( $this->notificationId.'_after_notification_dismissed', $current_user ); - } -} +notificationId = $notificationId; + $this->notificationMessage = $notificationMessage; + $this->notificationClass = $notificationClass; + + if( !empty( $startDate ) && time() < strtotime( $startDate ) ) + return; + + if( !empty( $endDate ) && time() > strtotime( $endDate ) ) + return; + + add_action( 'admin_notices', array( $this, 'add_admin_notice' ) ); + add_action( 'admin_init', array( $this, 'dismiss_notification' ) ); + } + + + // Display a notice that can be dismissed in case the serial number is inactive + function add_admin_notice() { + global $current_user ; + global $pagenow; + + $user_id = $current_user->ID; + do_action( $this->notificationId.'_before_notification_displayed', $current_user, $pagenow ); + + if ( current_user_can( 'manage_options' ) ){ + // Check that the user hasn't already clicked to ignore the message + if ( ! get_user_meta($user_id, $this->notificationId.'_dismiss_notification' ) ) { + echo $finalMessage = apply_filters($this->notificationId.'_notification_message','
            '.$this->notificationMessage.'
            ', $this->notificationMessage); + } + do_action( $this->notificationId.'_notification_displayed', $current_user, $pagenow ); + } + do_action( $this->notificationId.'_after_notification_displayed', $current_user, $pagenow ); + } + + function dismiss_notification() { + global $current_user; + + $user_id = $current_user->ID; + + do_action( $this->notificationId.'_before_notification_dismissed', $current_user ); + + // If user clicks to ignore the notice, add that to their user meta + if ( isset( $_GET[$this->notificationId.'_dismiss_notification']) && '0' == $_GET[$this->notificationId.'_dismiss_notification'] ) + add_user_meta( $user_id, $this->notificationId.'_dismiss_notification', 'true', true ); + + do_action( $this->notificationId.'_after_notification_dismissed', $current_user ); + } +} ?> \ No newline at end of file diff --git a/profile-builder/assets/lib/codemirror/LICENSE b/profile-builder/assets/lib/codemirror/LICENSE index 442d11c..4f1e9d1 100644 --- a/profile-builder/assets/lib/codemirror/LICENSE +++ b/profile-builder/assets/lib/codemirror/LICENSE @@ -1,19 +1,19 @@ -Copyright (C) 2013 by Marijn Haverbeke and others - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. +Copyright (C) 2013 by Marijn Haverbeke and others + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/profile-builder/assets/lib/codemirror/README.md b/profile-builder/assets/lib/codemirror/README.md index 61f6b64..915ded5 100644 --- a/profile-builder/assets/lib/codemirror/README.md +++ b/profile-builder/assets/lib/codemirror/README.md @@ -1,11 +1,11 @@ -# CodeMirror -[![Build Status](https://secure.travis-ci.org/marijnh/CodeMirror.png?branch=master)](http://travis-ci.org/marijnh/CodeMirror) -[![NPM version](https://badge.fury.io/js/codemirror.png)](http://badge.fury.io/js/codemirror) - -CodeMirror is a JavaScript component that provides a code editor in -the browser. When a mode is available for the language you are coding -in, it will color your code, and optionally help with indentation. - -The project page is http://codemirror.net -The manual is at http://codemirror.net/doc/manual.html -The contributing guidelines are in [CONTRIBUTING.md](https://github.com/marijnh/CodeMirror/blob/master/CONTRIBUTING.md) +# CodeMirror +[![Build Status](https://secure.travis-ci.org/marijnh/CodeMirror.png?branch=master)](http://travis-ci.org/marijnh/CodeMirror) +[![NPM version](https://badge.fury.io/js/codemirror.png)](http://badge.fury.io/js/codemirror) + +CodeMirror is a JavaScript component that provides a code editor in +the browser. When a mode is available for the language you are coding +in, it will color your code, and optionally help with indentation. + +The project page is http://codemirror.net +The manual is at http://codemirror.net/doc/manual.html +The contributing guidelines are in [CONTRIBUTING.md](https://github.com/marijnh/CodeMirror/blob/master/CONTRIBUTING.md) diff --git a/profile-builder/assets/lib/codemirror/addon/comment/comment.js b/profile-builder/assets/lib/codemirror/addon/comment/comment.js index cd2123e..a401ff1 100644 --- a/profile-builder/assets/lib/codemirror/addon/comment/comment.js +++ b/profile-builder/assets/lib/codemirror/addon/comment/comment.js @@ -1,145 +1,145 @@ -(function() { - "use strict"; - - var noOptions = {}; - var nonWS = /[^\s\u00a0]/; - var Pos = CodeMirror.Pos; - - function firstNonWS(str) { - var found = str.search(nonWS); - return found == -1 ? 0 : found; - } - - CodeMirror.commands.toggleComment = function(cm) { - var from = cm.getCursor("start"), to = cm.getCursor("end"); - cm.uncomment(from, to) || cm.lineComment(from, to); - }; - - CodeMirror.defineExtension("lineComment", function(from, to, options) { - if (!options) options = noOptions; - var self = this, mode = self.getModeAt(from); - var commentString = options.lineComment || mode.lineComment; - if (!commentString) { - if (options.blockCommentStart || mode.blockCommentStart) { - options.fullLines = true; - self.blockComment(from, to, options); - } - return; - } - var firstLine = self.getLine(from.line); - if (firstLine == null) return; - var end = Math.min(to.ch != 0 || to.line == from.line ? to.line + 1 : to.line, self.lastLine() + 1); - var pad = options.padding == null ? " " : options.padding; - var blankLines = options.commentBlankLines || from.line == to.line; - - self.operation(function() { - if (options.indent) { - var baseString = firstLine.slice(0, firstNonWS(firstLine)); - for (var i = from.line; i < end; ++i) { - var line = self.getLine(i), cut = baseString.length; - if (!blankLines && !nonWS.test(line)) continue; - if (line.slice(0, cut) != baseString) cut = firstNonWS(line); - self.replaceRange(baseString + commentString + pad, Pos(i, 0), Pos(i, cut)); - } - } else { - for (var i = from.line; i < end; ++i) { - if (blankLines || nonWS.test(self.getLine(i))) - self.replaceRange(commentString + pad, Pos(i, 0)); - } - } - }); - }); - - CodeMirror.defineExtension("blockComment", function(from, to, options) { - if (!options) options = noOptions; - var self = this, mode = self.getModeAt(from); - var startString = options.blockCommentStart || mode.blockCommentStart; - var endString = options.blockCommentEnd || mode.blockCommentEnd; - if (!startString || !endString) { - if ((options.lineComment || mode.lineComment) && options.fullLines != false) - self.lineComment(from, to, options); - return; - } - - var end = Math.min(to.line, self.lastLine()); - if (end != from.line && to.ch == 0 && nonWS.test(self.getLine(end))) --end; - - var pad = options.padding == null ? " " : options.padding; - if (from.line > end) return; - - self.operation(function() { - if (options.fullLines != false) { - var lastLineHasText = nonWS.test(self.getLine(end)); - self.replaceRange(pad + endString, Pos(end)); - self.replaceRange(startString + pad, Pos(from.line, 0)); - var lead = options.blockCommentLead || mode.blockCommentLead; - if (lead != null) for (var i = from.line + 1; i <= end; ++i) - if (i != end || lastLineHasText) - self.replaceRange(lead + pad, Pos(i, 0)); - } else { - self.replaceRange(endString, to); - self.replaceRange(startString, from); - } - }); - }); - - CodeMirror.defineExtension("uncomment", function(from, to, options) { - if (!options) options = noOptions; - var self = this, mode = self.getModeAt(from); - var end = Math.min(to.line, self.lastLine()), start = Math.min(from.line, end); - - // Try finding line comments - var lineString = options.lineComment || mode.lineComment, lines = []; - var pad = options.padding == null ? " " : options.padding, didSomething; - lineComment: { - if (!lineString) break lineComment; - for (var i = start; i <= end; ++i) { - var line = self.getLine(i); - var found = line.indexOf(lineString); - if (found == -1 && (i != end || i == start) && nonWS.test(line)) break lineComment; - if (i != start && found > -1 && nonWS.test(line.slice(0, found))) break lineComment; - lines.push(line); - } - self.operation(function() { - for (var i = start; i <= end; ++i) { - var line = lines[i - start]; - var pos = line.indexOf(lineString), endPos = pos + lineString.length; - if (pos < 0) continue; - if (line.slice(endPos, endPos + pad.length) == pad) endPos += pad.length; - didSomething = true; - self.replaceRange("", Pos(i, pos), Pos(i, endPos)); - } - }); - if (didSomething) return true; - } - - // Try block comments - var startString = options.blockCommentStart || mode.blockCommentStart; - var endString = options.blockCommentEnd || mode.blockCommentEnd; - if (!startString || !endString) return false; - var lead = options.blockCommentLead || mode.blockCommentLead; - var startLine = self.getLine(start), endLine = end == start ? startLine : self.getLine(end); - var open = startLine.indexOf(startString), close = endLine.lastIndexOf(endString); - if (close == -1 && start != end) { - endLine = self.getLine(--end); - close = endLine.lastIndexOf(endString); - } - if (open == -1 || close == -1) return false; - - self.operation(function() { - self.replaceRange("", Pos(end, close - (pad && endLine.slice(close - pad.length, close) == pad ? pad.length : 0)), - Pos(end, close + endString.length)); - var openEnd = open + startString.length; - if (pad && startLine.slice(openEnd, openEnd + pad.length) == pad) openEnd += pad.length; - self.replaceRange("", Pos(start, open), Pos(start, openEnd)); - if (lead) for (var i = start + 1; i <= end; ++i) { - var line = self.getLine(i), found = line.indexOf(lead); - if (found == -1 || nonWS.test(line.slice(0, found))) continue; - var foundEnd = found + lead.length; - if (pad && line.slice(foundEnd, foundEnd + pad.length) == pad) foundEnd += pad.length; - self.replaceRange("", Pos(i, found), Pos(i, foundEnd)); - } - }); - return true; - }); -})(); +(function() { + "use strict"; + + var noOptions = {}; + var nonWS = /[^\s\u00a0]/; + var Pos = CodeMirror.Pos; + + function firstNonWS(str) { + var found = str.search(nonWS); + return found == -1 ? 0 : found; + } + + CodeMirror.commands.toggleComment = function(cm) { + var from = cm.getCursor("start"), to = cm.getCursor("end"); + cm.uncomment(from, to) || cm.lineComment(from, to); + }; + + CodeMirror.defineExtension("lineComment", function(from, to, options) { + if (!options) options = noOptions; + var self = this, mode = self.getModeAt(from); + var commentString = options.lineComment || mode.lineComment; + if (!commentString) { + if (options.blockCommentStart || mode.blockCommentStart) { + options.fullLines = true; + self.blockComment(from, to, options); + } + return; + } + var firstLine = self.getLine(from.line); + if (firstLine == null) return; + var end = Math.min(to.ch != 0 || to.line == from.line ? to.line + 1 : to.line, self.lastLine() + 1); + var pad = options.padding == null ? " " : options.padding; + var blankLines = options.commentBlankLines || from.line == to.line; + + self.operation(function() { + if (options.indent) { + var baseString = firstLine.slice(0, firstNonWS(firstLine)); + for (var i = from.line; i < end; ++i) { + var line = self.getLine(i), cut = baseString.length; + if (!blankLines && !nonWS.test(line)) continue; + if (line.slice(0, cut) != baseString) cut = firstNonWS(line); + self.replaceRange(baseString + commentString + pad, Pos(i, 0), Pos(i, cut)); + } + } else { + for (var i = from.line; i < end; ++i) { + if (blankLines || nonWS.test(self.getLine(i))) + self.replaceRange(commentString + pad, Pos(i, 0)); + } + } + }); + }); + + CodeMirror.defineExtension("blockComment", function(from, to, options) { + if (!options) options = noOptions; + var self = this, mode = self.getModeAt(from); + var startString = options.blockCommentStart || mode.blockCommentStart; + var endString = options.blockCommentEnd || mode.blockCommentEnd; + if (!startString || !endString) { + if ((options.lineComment || mode.lineComment) && options.fullLines != false) + self.lineComment(from, to, options); + return; + } + + var end = Math.min(to.line, self.lastLine()); + if (end != from.line && to.ch == 0 && nonWS.test(self.getLine(end))) --end; + + var pad = options.padding == null ? " " : options.padding; + if (from.line > end) return; + + self.operation(function() { + if (options.fullLines != false) { + var lastLineHasText = nonWS.test(self.getLine(end)); + self.replaceRange(pad + endString, Pos(end)); + self.replaceRange(startString + pad, Pos(from.line, 0)); + var lead = options.blockCommentLead || mode.blockCommentLead; + if (lead != null) for (var i = from.line + 1; i <= end; ++i) + if (i != end || lastLineHasText) + self.replaceRange(lead + pad, Pos(i, 0)); + } else { + self.replaceRange(endString, to); + self.replaceRange(startString, from); + } + }); + }); + + CodeMirror.defineExtension("uncomment", function(from, to, options) { + if (!options) options = noOptions; + var self = this, mode = self.getModeAt(from); + var end = Math.min(to.line, self.lastLine()), start = Math.min(from.line, end); + + // Try finding line comments + var lineString = options.lineComment || mode.lineComment, lines = []; + var pad = options.padding == null ? " " : options.padding, didSomething; + lineComment: { + if (!lineString) break lineComment; + for (var i = start; i <= end; ++i) { + var line = self.getLine(i); + var found = line.indexOf(lineString); + if (found == -1 && (i != end || i == start) && nonWS.test(line)) break lineComment; + if (i != start && found > -1 && nonWS.test(line.slice(0, found))) break lineComment; + lines.push(line); + } + self.operation(function() { + for (var i = start; i <= end; ++i) { + var line = lines[i - start]; + var pos = line.indexOf(lineString), endPos = pos + lineString.length; + if (pos < 0) continue; + if (line.slice(endPos, endPos + pad.length) == pad) endPos += pad.length; + didSomething = true; + self.replaceRange("", Pos(i, pos), Pos(i, endPos)); + } + }); + if (didSomething) return true; + } + + // Try block comments + var startString = options.blockCommentStart || mode.blockCommentStart; + var endString = options.blockCommentEnd || mode.blockCommentEnd; + if (!startString || !endString) return false; + var lead = options.blockCommentLead || mode.blockCommentLead; + var startLine = self.getLine(start), endLine = end == start ? startLine : self.getLine(end); + var open = startLine.indexOf(startString), close = endLine.lastIndexOf(endString); + if (close == -1 && start != end) { + endLine = self.getLine(--end); + close = endLine.lastIndexOf(endString); + } + if (open == -1 || close == -1) return false; + + self.operation(function() { + self.replaceRange("", Pos(end, close - (pad && endLine.slice(close - pad.length, close) == pad ? pad.length : 0)), + Pos(end, close + endString.length)); + var openEnd = open + startString.length; + if (pad && startLine.slice(openEnd, openEnd + pad.length) == pad) openEnd += pad.length; + self.replaceRange("", Pos(start, open), Pos(start, openEnd)); + if (lead) for (var i = start + 1; i <= end; ++i) { + var line = self.getLine(i), found = line.indexOf(lead); + if (found == -1 || nonWS.test(line.slice(0, found))) continue; + var foundEnd = found + lead.length; + if (pad && line.slice(foundEnd, foundEnd + pad.length) == pad) foundEnd += pad.length; + self.replaceRange("", Pos(i, found), Pos(i, foundEnd)); + } + }); + return true; + }); +})(); diff --git a/profile-builder/assets/lib/codemirror/addon/comment/continuecomment.js b/profile-builder/assets/lib/codemirror/addon/comment/continuecomment.js index 94e5a37..ac08f95 100644 --- a/profile-builder/assets/lib/codemirror/addon/comment/continuecomment.js +++ b/profile-builder/assets/lib/codemirror/addon/comment/continuecomment.js @@ -1,54 +1,54 @@ -(function() { - var modes = ["clike", "css", "javascript"]; - for (var i = 0; i < modes.length; ++i) - CodeMirror.extendMode(modes[i], {blockCommentContinue: " * "}); - - function continueComment(cm) { - var pos = cm.getCursor(), token = cm.getTokenAt(pos); - if (token.type != "comment") return CodeMirror.Pass; - var mode = CodeMirror.innerMode(cm.getMode(), token.state).mode; - - var insert; - if (mode.blockCommentStart && mode.blockCommentContinue) { - var end = token.string.indexOf(mode.blockCommentEnd); - var full = cm.getRange(CodeMirror.Pos(pos.line, 0), CodeMirror.Pos(pos.line, token.end)), found; - if (end != -1 && end == token.string.length - mode.blockCommentEnd.length) { - // Comment ended, don't continue it - } else if (token.string.indexOf(mode.blockCommentStart) == 0) { - insert = full.slice(0, token.start); - if (!/^\s*$/.test(insert)) { - insert = ""; - for (var i = 0; i < token.start; ++i) insert += " "; - } - } else if ((found = full.indexOf(mode.blockCommentContinue)) != -1 && - found + mode.blockCommentContinue.length > token.start && - /^\s*$/.test(full.slice(0, found))) { - insert = full.slice(0, found); - } - if (insert != null) insert += mode.blockCommentContinue; - } - if (insert == null && mode.lineComment) { - var line = cm.getLine(pos.line), found = line.indexOf(mode.lineComment); - if (found > -1) { - insert = line.slice(0, found); - if (/\S/.test(insert)) insert = null; - else insert += mode.lineComment + line.slice(found + mode.lineComment.length).match(/^\s*/)[0]; - } - } - - if (insert != null) - cm.replaceSelection("\n" + insert, "end"); - else - return CodeMirror.Pass; - } - - CodeMirror.defineOption("continueComments", null, function(cm, val, prev) { - if (prev && prev != CodeMirror.Init) - cm.removeKeyMap("continueComment"); - if (val) { - var map = {name: "continueComment"}; - map[typeof val == "string" ? val : "Enter"] = continueComment; - cm.addKeyMap(map); - } - }); -})(); +(function() { + var modes = ["clike", "css", "javascript"]; + for (var i = 0; i < modes.length; ++i) + CodeMirror.extendMode(modes[i], {blockCommentContinue: " * "}); + + function continueComment(cm) { + var pos = cm.getCursor(), token = cm.getTokenAt(pos); + if (token.type != "comment") return CodeMirror.Pass; + var mode = CodeMirror.innerMode(cm.getMode(), token.state).mode; + + var insert; + if (mode.blockCommentStart && mode.blockCommentContinue) { + var end = token.string.indexOf(mode.blockCommentEnd); + var full = cm.getRange(CodeMirror.Pos(pos.line, 0), CodeMirror.Pos(pos.line, token.end)), found; + if (end != -1 && end == token.string.length - mode.blockCommentEnd.length) { + // Comment ended, don't continue it + } else if (token.string.indexOf(mode.blockCommentStart) == 0) { + insert = full.slice(0, token.start); + if (!/^\s*$/.test(insert)) { + insert = ""; + for (var i = 0; i < token.start; ++i) insert += " "; + } + } else if ((found = full.indexOf(mode.blockCommentContinue)) != -1 && + found + mode.blockCommentContinue.length > token.start && + /^\s*$/.test(full.slice(0, found))) { + insert = full.slice(0, found); + } + if (insert != null) insert += mode.blockCommentContinue; + } + if (insert == null && mode.lineComment) { + var line = cm.getLine(pos.line), found = line.indexOf(mode.lineComment); + if (found > -1) { + insert = line.slice(0, found); + if (/\S/.test(insert)) insert = null; + else insert += mode.lineComment + line.slice(found + mode.lineComment.length).match(/^\s*/)[0]; + } + } + + if (insert != null) + cm.replaceSelection("\n" + insert, "end"); + else + return CodeMirror.Pass; + } + + CodeMirror.defineOption("continueComments", null, function(cm, val, prev) { + if (prev && prev != CodeMirror.Init) + cm.removeKeyMap("continueComment"); + if (val) { + var map = {name: "continueComment"}; + map[typeof val == "string" ? val : "Enter"] = continueComment; + cm.addKeyMap(map); + } + }); +})(); diff --git a/profile-builder/assets/lib/codemirror/addon/dialog/dialog.css b/profile-builder/assets/lib/codemirror/addon/dialog/dialog.css index 2e7c0fc..43e1212 100644 --- a/profile-builder/assets/lib/codemirror/addon/dialog/dialog.css +++ b/profile-builder/assets/lib/codemirror/addon/dialog/dialog.css @@ -1,32 +1,32 @@ -.CodeMirror-dialog { - position: absolute; - left: 0; right: 0; - background: white; - z-index: 15; - padding: .1em .8em; - overflow: hidden; - color: #333; -} - -.CodeMirror-dialog-top { - border-bottom: 1px solid #eee; - top: 0; -} - -.CodeMirror-dialog-bottom { - border-top: 1px solid #eee; - bottom: 0; -} - -.CodeMirror-dialog input { - border: none; - outline: none; - background: transparent; - width: 20em; - color: inherit; - font-family: monospace; -} - -.CodeMirror-dialog button { - font-size: 70%; -} +.CodeMirror-dialog { + position: absolute; + left: 0; right: 0; + background: white; + z-index: 15; + padding: .1em .8em; + overflow: hidden; + color: #333; +} + +.CodeMirror-dialog-top { + border-bottom: 1px solid #eee; + top: 0; +} + +.CodeMirror-dialog-bottom { + border-top: 1px solid #eee; + bottom: 0; +} + +.CodeMirror-dialog input { + border: none; + outline: none; + background: transparent; + width: 20em; + color: inherit; + font-family: monospace; +} + +.CodeMirror-dialog button { + font-size: 70%; +} diff --git a/profile-builder/assets/lib/codemirror/addon/dialog/dialog.js b/profile-builder/assets/lib/codemirror/addon/dialog/dialog.js index 71e2287..2c03baf 100644 --- a/profile-builder/assets/lib/codemirror/addon/dialog/dialog.js +++ b/profile-builder/assets/lib/codemirror/addon/dialog/dialog.js @@ -1,80 +1,80 @@ -// Open simple dialogs on top of an editor. Relies on dialog.css. - -(function() { - function dialogDiv(cm, template, bottom) { - var wrap = cm.getWrapperElement(); - var dialog; - dialog = wrap.appendChild(document.createElement("div")); - if (bottom) { - dialog.className = "CodeMirror-dialog CodeMirror-dialog-bottom"; - } else { - dialog.className = "CodeMirror-dialog CodeMirror-dialog-top"; - } - dialog.innerHTML = template; - return dialog; - } - - CodeMirror.defineExtension("openDialog", function(template, callback, options) { - var dialog = dialogDiv(this, template, options && options.bottom); - var closed = false, me = this; - function close() { - if (closed) return; - closed = true; - dialog.parentNode.removeChild(dialog); - } - var inp = dialog.getElementsByTagName("input")[0], button; - if (inp) { - CodeMirror.on(inp, "keydown", function(e) { - if (options && options.onKeyDown && options.onKeyDown(e, inp.value, close)) { return; } - if (e.keyCode == 13 || e.keyCode == 27) { - CodeMirror.e_stop(e); - close(); - me.focus(); - if (e.keyCode == 13) callback(inp.value); - } - }); - if (options && options.onKeyUp) { - CodeMirror.on(inp, "keyup", function(e) {options.onKeyUp(e, inp.value, close);}); - } - if (options && options.value) inp.value = options.value; - inp.focus(); - CodeMirror.on(inp, "blur", close); - } else if (button = dialog.getElementsByTagName("button")[0]) { - CodeMirror.on(button, "click", function() { - close(); - me.focus(); - }); - button.focus(); - CodeMirror.on(button, "blur", close); - } - return close; - }); - - CodeMirror.defineExtension("openConfirm", function(template, callbacks, options) { - var dialog = dialogDiv(this, template, options && options.bottom); - var buttons = dialog.getElementsByTagName("button"); - var closed = false, me = this, blurring = 1; - function close() { - if (closed) return; - closed = true; - dialog.parentNode.removeChild(dialog); - me.focus(); - } - buttons[0].focus(); - for (var i = 0; i < buttons.length; ++i) { - var b = buttons[i]; - (function(callback) { - CodeMirror.on(b, "click", function(e) { - CodeMirror.e_preventDefault(e); - close(); - if (callback) callback(me); - }); - })(callbacks[i]); - CodeMirror.on(b, "blur", function() { - --blurring; - setTimeout(function() { if (blurring <= 0) close(); }, 200); - }); - CodeMirror.on(b, "focus", function() { ++blurring; }); - } - }); -})(); +// Open simple dialogs on top of an editor. Relies on dialog.css. + +(function() { + function dialogDiv(cm, template, bottom) { + var wrap = cm.getWrapperElement(); + var dialog; + dialog = wrap.appendChild(document.createElement("div")); + if (bottom) { + dialog.className = "CodeMirror-dialog CodeMirror-dialog-bottom"; + } else { + dialog.className = "CodeMirror-dialog CodeMirror-dialog-top"; + } + dialog.innerHTML = template; + return dialog; + } + + CodeMirror.defineExtension("openDialog", function(template, callback, options) { + var dialog = dialogDiv(this, template, options && options.bottom); + var closed = false, me = this; + function close() { + if (closed) return; + closed = true; + dialog.parentNode.removeChild(dialog); + } + var inp = dialog.getElementsByTagName("input")[0], button; + if (inp) { + CodeMirror.on(inp, "keydown", function(e) { + if (options && options.onKeyDown && options.onKeyDown(e, inp.value, close)) { return; } + if (e.keyCode == 13 || e.keyCode == 27) { + CodeMirror.e_stop(e); + close(); + me.focus(); + if (e.keyCode == 13) callback(inp.value); + } + }); + if (options && options.onKeyUp) { + CodeMirror.on(inp, "keyup", function(e) {options.onKeyUp(e, inp.value, close);}); + } + if (options && options.value) inp.value = options.value; + inp.focus(); + CodeMirror.on(inp, "blur", close); + } else if (button = dialog.getElementsByTagName("button")[0]) { + CodeMirror.on(button, "click", function() { + close(); + me.focus(); + }); + button.focus(); + CodeMirror.on(button, "blur", close); + } + return close; + }); + + CodeMirror.defineExtension("openConfirm", function(template, callbacks, options) { + var dialog = dialogDiv(this, template, options && options.bottom); + var buttons = dialog.getElementsByTagName("button"); + var closed = false, me = this, blurring = 1; + function close() { + if (closed) return; + closed = true; + dialog.parentNode.removeChild(dialog); + me.focus(); + } + buttons[0].focus(); + for (var i = 0; i < buttons.length; ++i) { + var b = buttons[i]; + (function(callback) { + CodeMirror.on(b, "click", function(e) { + CodeMirror.e_preventDefault(e); + close(); + if (callback) callback(me); + }); + })(callbacks[i]); + CodeMirror.on(b, "blur", function() { + --blurring; + setTimeout(function() { if (blurring <= 0) close(); }, 200); + }); + CodeMirror.on(b, "focus", function() { ++blurring; }); + } + }); +})(); diff --git a/profile-builder/assets/lib/codemirror/addon/display/fullscreen.css b/profile-builder/assets/lib/codemirror/addon/display/fullscreen.css index 437acd8..cbd5539 100644 --- a/profile-builder/assets/lib/codemirror/addon/display/fullscreen.css +++ b/profile-builder/assets/lib/codemirror/addon/display/fullscreen.css @@ -1,6 +1,6 @@ -.CodeMirror-fullscreen { - position: fixed; - top: 0; left: 0; right: 0; bottom: 0; - height: auto; - z-index: 9; -} +.CodeMirror-fullscreen { + position: fixed; + top: 0; left: 0; right: 0; bottom: 0; + height: auto; + z-index: 9; +} diff --git a/profile-builder/assets/lib/codemirror/addon/display/fullscreen.js b/profile-builder/assets/lib/codemirror/addon/display/fullscreen.js index 3c31e97..2baeb88 100644 --- a/profile-builder/assets/lib/codemirror/addon/display/fullscreen.js +++ b/profile-builder/assets/lib/codemirror/addon/display/fullscreen.js @@ -1,30 +1,30 @@ -(function() { - "use strict"; - - CodeMirror.defineOption("fullScreen", false, function(cm, val, old) { - if (old == CodeMirror.Init) old = false; - if (!old == !val) return; - if (val) setFullscreen(cm); - else setNormal(cm); - }); - - function setFullscreen(cm) { - var wrap = cm.getWrapperElement(); - cm.state.fullScreenRestore = {scrollTop: window.pageYOffset, scrollLeft: window.pageXOffset, - width: wrap.style.width, height: wrap.style.height}; - wrap.style.width = wrap.style.height = ""; - wrap.className += " CodeMirror-fullscreen"; - document.documentElement.style.overflow = "hidden"; - cm.refresh(); - } - - function setNormal(cm) { - var wrap = cm.getWrapperElement(); - wrap.className = wrap.className.replace(/\s*CodeMirror-fullscreen\b/, ""); - document.documentElement.style.overflow = ""; - var info = cm.state.fullScreenRestore; - wrap.style.width = info.width; wrap.style.height = info.height; - window.scrollTo(info.scrollLeft, info.scrollTop); - cm.refresh(); - } -})(); +(function() { + "use strict"; + + CodeMirror.defineOption("fullScreen", false, function(cm, val, old) { + if (old == CodeMirror.Init) old = false; + if (!old == !val) return; + if (val) setFullscreen(cm); + else setNormal(cm); + }); + + function setFullscreen(cm) { + var wrap = cm.getWrapperElement(); + cm.state.fullScreenRestore = {scrollTop: window.pageYOffset, scrollLeft: window.pageXOffset, + width: wrap.style.width, height: wrap.style.height}; + wrap.style.width = wrap.style.height = ""; + wrap.className += " CodeMirror-fullscreen"; + document.documentElement.style.overflow = "hidden"; + cm.refresh(); + } + + function setNormal(cm) { + var wrap = cm.getWrapperElement(); + wrap.className = wrap.className.replace(/\s*CodeMirror-fullscreen\b/, ""); + document.documentElement.style.overflow = ""; + var info = cm.state.fullScreenRestore; + wrap.style.width = info.width; wrap.style.height = info.height; + window.scrollTo(info.scrollLeft, info.scrollTop); + cm.refresh(); + } +})(); diff --git a/profile-builder/assets/lib/codemirror/addon/display/placeholder.js b/profile-builder/assets/lib/codemirror/addon/display/placeholder.js index 18f9dff..a2ad6b1 100644 --- a/profile-builder/assets/lib/codemirror/addon/display/placeholder.js +++ b/profile-builder/assets/lib/codemirror/addon/display/placeholder.js @@ -1,54 +1,54 @@ -(function() { - CodeMirror.defineOption("placeholder", "", function(cm, val, old) { - var prev = old && old != CodeMirror.Init; - if (val && !prev) { - cm.on("focus", onFocus); - cm.on("blur", onBlur); - cm.on("change", onChange); - onChange(cm); - } else if (!val && prev) { - cm.off("focus", onFocus); - cm.off("blur", onBlur); - cm.off("change", onChange); - clearPlaceholder(cm); - var wrapper = cm.getWrapperElement(); - wrapper.className = wrapper.className.replace(" CodeMirror-empty", ""); - } - - if (val && !cm.hasFocus()) onBlur(cm); - }); - - function clearPlaceholder(cm) { - if (cm.state.placeholder) { - cm.state.placeholder.parentNode.removeChild(cm.state.placeholder); - cm.state.placeholder = null; - } - } - function setPlaceholder(cm) { - clearPlaceholder(cm); - var elt = cm.state.placeholder = document.createElement("pre"); - elt.style.cssText = "height: 0; overflow: visible"; - elt.className = "CodeMirror-placeholder"; - elt.appendChild(document.createTextNode(cm.getOption("placeholder"))); - cm.display.lineSpace.insertBefore(elt, cm.display.lineSpace.firstChild); - } - - function onFocus(cm) { - clearPlaceholder(cm); - } - function onBlur(cm) { - if (isEmpty(cm)) setPlaceholder(cm); - } - function onChange(cm) { - var wrapper = cm.getWrapperElement(), empty = isEmpty(cm); - wrapper.className = wrapper.className.replace(" CodeMirror-empty", "") + (empty ? " CodeMirror-empty" : ""); - - if (cm.hasFocus()) return; - if (empty) setPlaceholder(cm); - else clearPlaceholder(cm); - } - - function isEmpty(cm) { - return (cm.lineCount() === 1) && (cm.getLine(0) === ""); - } -})(); +(function() { + CodeMirror.defineOption("placeholder", "", function(cm, val, old) { + var prev = old && old != CodeMirror.Init; + if (val && !prev) { + cm.on("focus", onFocus); + cm.on("blur", onBlur); + cm.on("change", onChange); + onChange(cm); + } else if (!val && prev) { + cm.off("focus", onFocus); + cm.off("blur", onBlur); + cm.off("change", onChange); + clearPlaceholder(cm); + var wrapper = cm.getWrapperElement(); + wrapper.className = wrapper.className.replace(" CodeMirror-empty", ""); + } + + if (val && !cm.hasFocus()) onBlur(cm); + }); + + function clearPlaceholder(cm) { + if (cm.state.placeholder) { + cm.state.placeholder.parentNode.removeChild(cm.state.placeholder); + cm.state.placeholder = null; + } + } + function setPlaceholder(cm) { + clearPlaceholder(cm); + var elt = cm.state.placeholder = document.createElement("pre"); + elt.style.cssText = "height: 0; overflow: visible"; + elt.className = "CodeMirror-placeholder"; + elt.appendChild(document.createTextNode(cm.getOption("placeholder"))); + cm.display.lineSpace.insertBefore(elt, cm.display.lineSpace.firstChild); + } + + function onFocus(cm) { + clearPlaceholder(cm); + } + function onBlur(cm) { + if (isEmpty(cm)) setPlaceholder(cm); + } + function onChange(cm) { + var wrapper = cm.getWrapperElement(), empty = isEmpty(cm); + wrapper.className = wrapper.className.replace(" CodeMirror-empty", "") + (empty ? " CodeMirror-empty" : ""); + + if (cm.hasFocus()) return; + if (empty) setPlaceholder(cm); + else clearPlaceholder(cm); + } + + function isEmpty(cm) { + return (cm.lineCount() === 1) && (cm.getLine(0) === ""); + } +})(); diff --git a/profile-builder/assets/lib/codemirror/addon/edit/closebrackets.js b/profile-builder/assets/lib/codemirror/addon/edit/closebrackets.js index 88718b7..eda1181 100644 --- a/profile-builder/assets/lib/codemirror/addon/edit/closebrackets.js +++ b/profile-builder/assets/lib/codemirror/addon/edit/closebrackets.js @@ -1,82 +1,82 @@ -(function() { - var DEFAULT_BRACKETS = "()[]{}''\"\""; - var DEFAULT_EXPLODE_ON_ENTER = "[]{}"; - var SPACE_CHAR_REGEX = /\s/; - - CodeMirror.defineOption("autoCloseBrackets", false, function(cm, val, old) { - if (old != CodeMirror.Init && old) - cm.removeKeyMap("autoCloseBrackets"); - if (!val) return; - var pairs = DEFAULT_BRACKETS, explode = DEFAULT_EXPLODE_ON_ENTER; - if (typeof val == "string") pairs = val; - else if (typeof val == "object") { - if (val.pairs != null) pairs = val.pairs; - if (val.explode != null) explode = val.explode; - } - var map = buildKeymap(pairs); - if (explode) map.Enter = buildExplodeHandler(explode); - cm.addKeyMap(map); - }); - - function charsAround(cm, pos) { - var str = cm.getRange(CodeMirror.Pos(pos.line, pos.ch - 1), - CodeMirror.Pos(pos.line, pos.ch + 1)); - return str.length == 2 ? str : null; - } - - function buildKeymap(pairs) { - var map = { - name : "autoCloseBrackets", - Backspace: function(cm) { - if (cm.somethingSelected()) return CodeMirror.Pass; - var cur = cm.getCursor(), around = charsAround(cm, cur); - if (around && pairs.indexOf(around) % 2 == 0) - cm.replaceRange("", CodeMirror.Pos(cur.line, cur.ch - 1), CodeMirror.Pos(cur.line, cur.ch + 1)); - else - return CodeMirror.Pass; - } - }; - var closingBrackets = ""; - for (var i = 0; i < pairs.length; i += 2) (function(left, right) { - if (left != right) closingBrackets += right; - function surround(cm) { - var selection = cm.getSelection(); - cm.replaceSelection(left + selection + right); - } - function maybeOverwrite(cm) { - var cur = cm.getCursor(), ahead = cm.getRange(cur, CodeMirror.Pos(cur.line, cur.ch + 1)); - if (ahead != right || cm.somethingSelected()) return CodeMirror.Pass; - else cm.execCommand("goCharRight"); - } - map["'" + left + "'"] = function(cm) { - if (left == "'" && cm.getTokenAt(cm.getCursor()).type == "comment") - return CodeMirror.Pass; - if (cm.somethingSelected()) return surround(cm); - if (left == right && maybeOverwrite(cm) != CodeMirror.Pass) return; - var cur = cm.getCursor(), ahead = CodeMirror.Pos(cur.line, cur.ch + 1); - var line = cm.getLine(cur.line), nextChar = line.charAt(cur.ch), curChar = cur.ch > 0 ? line.charAt(cur.ch - 1) : ""; - if (left == right && CodeMirror.isWordChar(curChar)) - return CodeMirror.Pass; - if (line.length == cur.ch || closingBrackets.indexOf(nextChar) >= 0 || SPACE_CHAR_REGEX.test(nextChar)) - cm.replaceSelection(left + right, {head: ahead, anchor: ahead}); - else - return CodeMirror.Pass; - }; - if (left != right) map["'" + right + "'"] = maybeOverwrite; - })(pairs.charAt(i), pairs.charAt(i + 1)); - return map; - } - - function buildExplodeHandler(pairs) { - return function(cm) { - var cur = cm.getCursor(), around = charsAround(cm, cur); - if (!around || pairs.indexOf(around) % 2 != 0) return CodeMirror.Pass; - cm.operation(function() { - var newPos = CodeMirror.Pos(cur.line + 1, 0); - cm.replaceSelection("\n\n", {anchor: newPos, head: newPos}, "+input"); - cm.indentLine(cur.line + 1, null, true); - cm.indentLine(cur.line + 2, null, true); - }); - }; - } -})(); +(function() { + var DEFAULT_BRACKETS = "()[]{}''\"\""; + var DEFAULT_EXPLODE_ON_ENTER = "[]{}"; + var SPACE_CHAR_REGEX = /\s/; + + CodeMirror.defineOption("autoCloseBrackets", false, function(cm, val, old) { + if (old != CodeMirror.Init && old) + cm.removeKeyMap("autoCloseBrackets"); + if (!val) return; + var pairs = DEFAULT_BRACKETS, explode = DEFAULT_EXPLODE_ON_ENTER; + if (typeof val == "string") pairs = val; + else if (typeof val == "object") { + if (val.pairs != null) pairs = val.pairs; + if (val.explode != null) explode = val.explode; + } + var map = buildKeymap(pairs); + if (explode) map.Enter = buildExplodeHandler(explode); + cm.addKeyMap(map); + }); + + function charsAround(cm, pos) { + var str = cm.getRange(CodeMirror.Pos(pos.line, pos.ch - 1), + CodeMirror.Pos(pos.line, pos.ch + 1)); + return str.length == 2 ? str : null; + } + + function buildKeymap(pairs) { + var map = { + name : "autoCloseBrackets", + Backspace: function(cm) { + if (cm.somethingSelected()) return CodeMirror.Pass; + var cur = cm.getCursor(), around = charsAround(cm, cur); + if (around && pairs.indexOf(around) % 2 == 0) + cm.replaceRange("", CodeMirror.Pos(cur.line, cur.ch - 1), CodeMirror.Pos(cur.line, cur.ch + 1)); + else + return CodeMirror.Pass; + } + }; + var closingBrackets = ""; + for (var i = 0; i < pairs.length; i += 2) (function(left, right) { + if (left != right) closingBrackets += right; + function surround(cm) { + var selection = cm.getSelection(); + cm.replaceSelection(left + selection + right); + } + function maybeOverwrite(cm) { + var cur = cm.getCursor(), ahead = cm.getRange(cur, CodeMirror.Pos(cur.line, cur.ch + 1)); + if (ahead != right || cm.somethingSelected()) return CodeMirror.Pass; + else cm.execCommand("goCharRight"); + } + map["'" + left + "'"] = function(cm) { + if (left == "'" && cm.getTokenAt(cm.getCursor()).type == "comment") + return CodeMirror.Pass; + if (cm.somethingSelected()) return surround(cm); + if (left == right && maybeOverwrite(cm) != CodeMirror.Pass) return; + var cur = cm.getCursor(), ahead = CodeMirror.Pos(cur.line, cur.ch + 1); + var line = cm.getLine(cur.line), nextChar = line.charAt(cur.ch), curChar = cur.ch > 0 ? line.charAt(cur.ch - 1) : ""; + if (left == right && CodeMirror.isWordChar(curChar)) + return CodeMirror.Pass; + if (line.length == cur.ch || closingBrackets.indexOf(nextChar) >= 0 || SPACE_CHAR_REGEX.test(nextChar)) + cm.replaceSelection(left + right, {head: ahead, anchor: ahead}); + else + return CodeMirror.Pass; + }; + if (left != right) map["'" + right + "'"] = maybeOverwrite; + })(pairs.charAt(i), pairs.charAt(i + 1)); + return map; + } + + function buildExplodeHandler(pairs) { + return function(cm) { + var cur = cm.getCursor(), around = charsAround(cm, cur); + if (!around || pairs.indexOf(around) % 2 != 0) return CodeMirror.Pass; + cm.operation(function() { + var newPos = CodeMirror.Pos(cur.line + 1, 0); + cm.replaceSelection("\n\n", {anchor: newPos, head: newPos}, "+input"); + cm.indentLine(cur.line + 1, null, true); + cm.indentLine(cur.line + 2, null, true); + }); + }; + } +})(); diff --git a/profile-builder/assets/lib/codemirror/addon/edit/closetag.js b/profile-builder/assets/lib/codemirror/addon/edit/closetag.js index 0bc3e8b..ae9973d 100644 --- a/profile-builder/assets/lib/codemirror/addon/edit/closetag.js +++ b/profile-builder/assets/lib/codemirror/addon/edit/closetag.js @@ -1,87 +1,87 @@ -/** - * Tag-closer extension for CodeMirror. - * - * This extension adds an "autoCloseTags" option that can be set to - * either true to get the default behavior, or an object to further - * configure its behavior. - * - * These are supported options: - * - * `whenClosing` (default true) - * Whether to autoclose when the '/' of a closing tag is typed. - * `whenOpening` (default true) - * Whether to autoclose the tag when the final '>' of an opening - * tag is typed. - * `dontCloseTags` (default is empty tags for HTML, none for XML) - * An array of tag names that should not be autoclosed. - * `indentTags` (default is block tags for HTML, none for XML) - * An array of tag names that should, when opened, cause a - * blank line to be added inside the tag, and the blank line and - * closing line to be indented. - * - * See demos/closetag.html for a usage example. - */ - -(function() { - CodeMirror.defineOption("autoCloseTags", false, function(cm, val, old) { - if (val && (old == CodeMirror.Init || !old)) { - var map = {name: "autoCloseTags"}; - if (typeof val != "object" || val.whenClosing) - map["'/'"] = function(cm) { return autoCloseSlash(cm); }; - if (typeof val != "object" || val.whenOpening) - map["'>'"] = function(cm) { return autoCloseGT(cm); }; - cm.addKeyMap(map); - } else if (!val && (old != CodeMirror.Init && old)) { - cm.removeKeyMap("autoCloseTags"); - } - }); - - var htmlDontClose = ["area", "base", "br", "col", "command", "embed", "hr", "img", "input", "keygen", "link", "meta", "param", - "source", "track", "wbr"]; - var htmlIndent = ["applet", "blockquote", "body", "button", "div", "dl", "fieldset", "form", "frameset", "h1", "h2", "h3", "h4", - "h5", "h6", "head", "html", "iframe", "layer", "legend", "object", "ol", "p", "select", "table", "ul"]; - - function autoCloseGT(cm) { - var pos = cm.getCursor(), tok = cm.getTokenAt(pos); - var inner = CodeMirror.innerMode(cm.getMode(), tok.state), state = inner.state; - if (inner.mode.name != "xml" || !state.tagName) return CodeMirror.Pass; - - var opt = cm.getOption("autoCloseTags"), html = inner.mode.configuration == "html"; - var dontCloseTags = (typeof opt == "object" && opt.dontCloseTags) || (html && htmlDontClose); - var indentTags = (typeof opt == "object" && opt.indentTags) || (html && htmlIndent); - - var tagName = state.tagName; - if (tok.end > pos.ch) tagName = tagName.slice(0, tagName.length - tok.end + pos.ch); - var lowerTagName = tagName.toLowerCase(); - // Don't process the '>' at the end of an end-tag or self-closing tag - if (tok.type == "tag" && state.type == "closeTag" || - tok.string.indexOf("/") == (tok.string.length - 1) || // match something like - dontCloseTags && indexOf(dontCloseTags, lowerTagName) > -1) - return CodeMirror.Pass; - - var doIndent = indentTags && indexOf(indentTags, lowerTagName) > -1; - var curPos = doIndent ? CodeMirror.Pos(pos.line + 1, 0) : CodeMirror.Pos(pos.line, pos.ch + 1); - cm.replaceSelection(">" + (doIndent ? "\n\n" : "") + "", - {head: curPos, anchor: curPos}); - if (doIndent) { - cm.indentLine(pos.line + 1); - cm.indentLine(pos.line + 2); - } - } - - function autoCloseSlash(cm) { - var pos = cm.getCursor(), tok = cm.getTokenAt(pos); - var inner = CodeMirror.innerMode(cm.getMode(), tok.state), state = inner.state; - if (tok.string.charAt(0) != "<" || inner.mode.name != "xml") return CodeMirror.Pass; - - var tagName = state.context && state.context.tagName; - if (tagName) cm.replaceSelection("/" + tagName + ">", "end"); - } - - function indexOf(collection, elt) { - if (collection.indexOf) return collection.indexOf(elt); - for (var i = 0, e = collection.length; i < e; ++i) - if (collection[i] == elt) return i; - return -1; - } -})(); +/** + * Tag-closer extension for CodeMirror. + * + * This extension adds an "autoCloseTags" option that can be set to + * either true to get the default behavior, or an object to further + * configure its behavior. + * + * These are supported options: + * + * `whenClosing` (default true) + * Whether to autoclose when the '/' of a closing tag is typed. + * `whenOpening` (default true) + * Whether to autoclose the tag when the final '>' of an opening + * tag is typed. + * `dontCloseTags` (default is empty tags for HTML, none for XML) + * An array of tag names that should not be autoclosed. + * `indentTags` (default is block tags for HTML, none for XML) + * An array of tag names that should, when opened, cause a + * blank line to be added inside the tag, and the blank line and + * closing line to be indented. + * + * See demos/closetag.html for a usage example. + */ + +(function() { + CodeMirror.defineOption("autoCloseTags", false, function(cm, val, old) { + if (val && (old == CodeMirror.Init || !old)) { + var map = {name: "autoCloseTags"}; + if (typeof val != "object" || val.whenClosing) + map["'/'"] = function(cm) { return autoCloseSlash(cm); }; + if (typeof val != "object" || val.whenOpening) + map["'>'"] = function(cm) { return autoCloseGT(cm); }; + cm.addKeyMap(map); + } else if (!val && (old != CodeMirror.Init && old)) { + cm.removeKeyMap("autoCloseTags"); + } + }); + + var htmlDontClose = ["area", "base", "br", "col", "command", "embed", "hr", "img", "input", "keygen", "link", "meta", "param", + "source", "track", "wbr"]; + var htmlIndent = ["applet", "blockquote", "body", "button", "div", "dl", "fieldset", "form", "frameset", "h1", "h2", "h3", "h4", + "h5", "h6", "head", "html", "iframe", "layer", "legend", "object", "ol", "p", "select", "table", "ul"]; + + function autoCloseGT(cm) { + var pos = cm.getCursor(), tok = cm.getTokenAt(pos); + var inner = CodeMirror.innerMode(cm.getMode(), tok.state), state = inner.state; + if (inner.mode.name != "xml" || !state.tagName) return CodeMirror.Pass; + + var opt = cm.getOption("autoCloseTags"), html = inner.mode.configuration == "html"; + var dontCloseTags = (typeof opt == "object" && opt.dontCloseTags) || (html && htmlDontClose); + var indentTags = (typeof opt == "object" && opt.indentTags) || (html && htmlIndent); + + var tagName = state.tagName; + if (tok.end > pos.ch) tagName = tagName.slice(0, tagName.length - tok.end + pos.ch); + var lowerTagName = tagName.toLowerCase(); + // Don't process the '>' at the end of an end-tag or self-closing tag + if (tok.type == "tag" && state.type == "closeTag" || + tok.string.indexOf("/") == (tok.string.length - 1) || // match something like + dontCloseTags && indexOf(dontCloseTags, lowerTagName) > -1) + return CodeMirror.Pass; + + var doIndent = indentTags && indexOf(indentTags, lowerTagName) > -1; + var curPos = doIndent ? CodeMirror.Pos(pos.line + 1, 0) : CodeMirror.Pos(pos.line, pos.ch + 1); + cm.replaceSelection(">" + (doIndent ? "\n\n" : "") + "", + {head: curPos, anchor: curPos}); + if (doIndent) { + cm.indentLine(pos.line + 1); + cm.indentLine(pos.line + 2); + } + } + + function autoCloseSlash(cm) { + var pos = cm.getCursor(), tok = cm.getTokenAt(pos); + var inner = CodeMirror.innerMode(cm.getMode(), tok.state), state = inner.state; + if (tok.string.charAt(0) != "<" || inner.mode.name != "xml") return CodeMirror.Pass; + + var tagName = state.context && state.context.tagName; + if (tagName) cm.replaceSelection("/" + tagName + ">", "end"); + } + + function indexOf(collection, elt) { + if (collection.indexOf) return collection.indexOf(elt); + for (var i = 0, e = collection.length; i < e; ++i) + if (collection[i] == elt) return i; + return -1; + } +})(); diff --git a/profile-builder/assets/lib/codemirror/addon/edit/continuelist.js b/profile-builder/assets/lib/codemirror/addon/edit/continuelist.js index fb1fc38..a1cbd81 100644 --- a/profile-builder/assets/lib/codemirror/addon/edit/continuelist.js +++ b/profile-builder/assets/lib/codemirror/addon/edit/continuelist.js @@ -1,25 +1,25 @@ -(function() { - 'use strict'; - - var listRE = /^(\s*)([*+-]|(\d+)\.)(\s*)/, - unorderedBullets = '*+-'; - - CodeMirror.commands.newlineAndIndentContinueMarkdownList = function(cm) { - var pos = cm.getCursor(), - inList = cm.getStateAfter(pos.line).list, - match; - - if (!inList || !(match = cm.getLine(pos.line).match(listRE))) { - cm.execCommand('newlineAndIndent'); - return; - } - - var indent = match[1], after = match[4]; - var bullet = unorderedBullets.indexOf(match[2]) >= 0 - ? match[2] - : (parseInt(match[3], 10) + 1) + '.'; - - cm.replaceSelection('\n' + indent + bullet + after, 'end'); - }; - -}()); +(function() { + 'use strict'; + + var listRE = /^(\s*)([*+-]|(\d+)\.)(\s*)/, + unorderedBullets = '*+-'; + + CodeMirror.commands.newlineAndIndentContinueMarkdownList = function(cm) { + var pos = cm.getCursor(), + inList = cm.getStateAfter(pos.line).list, + match; + + if (!inList || !(match = cm.getLine(pos.line).match(listRE))) { + cm.execCommand('newlineAndIndent'); + return; + } + + var indent = match[1], after = match[4]; + var bullet = unorderedBullets.indexOf(match[2]) >= 0 + ? match[2] + : (parseInt(match[3], 10) + 1) + '.'; + + cm.replaceSelection('\n' + indent + bullet + after, 'end'); + }; + +}()); diff --git a/profile-builder/assets/lib/codemirror/addon/edit/matchbrackets.js b/profile-builder/assets/lib/codemirror/addon/edit/matchbrackets.js index 131fe83..6a14f92 100644 --- a/profile-builder/assets/lib/codemirror/addon/edit/matchbrackets.js +++ b/profile-builder/assets/lib/codemirror/addon/edit/matchbrackets.js @@ -1,86 +1,86 @@ -(function() { - var ie_lt8 = /MSIE \d/.test(navigator.userAgent) && - (document.documentMode == null || document.documentMode < 8); - - var Pos = CodeMirror.Pos; - - var matching = {"(": ")>", ")": "(<", "[": "]>", "]": "[<", "{": "}>", "}": "{<"}; - function findMatchingBracket(cm, where, strict) { - var state = cm.state.matchBrackets; - var maxScanLen = (state && state.maxScanLineLength) || 10000; - - var cur = where || cm.getCursor(), line = cm.getLineHandle(cur.line), pos = cur.ch - 1; - var match = (pos >= 0 && matching[line.text.charAt(pos)]) || matching[line.text.charAt(++pos)]; - if (!match) return null; - var forward = match.charAt(1) == ">", d = forward ? 1 : -1; - if (strict && forward != (pos == cur.ch)) return null; - var style = cm.getTokenTypeAt(Pos(cur.line, pos + 1)); - - var stack = [line.text.charAt(pos)], re = /[(){}[\]]/; - function scan(line, lineNo, start) { - if (!line.text) return; - var pos = forward ? 0 : line.text.length - 1, end = forward ? line.text.length : -1; - if (line.text.length > maxScanLen) return null; - if (start != null) pos = start + d; - for (; pos != end; pos += d) { - var ch = line.text.charAt(pos); - if (re.test(ch) && cm.getTokenTypeAt(Pos(lineNo, pos + 1)) == style) { - var match = matching[ch]; - if (match.charAt(1) == ">" == forward) stack.push(ch); - else if (stack.pop() != match.charAt(0)) return {pos: pos, match: false}; - else if (!stack.length) return {pos: pos, match: true}; - } - } - } - for (var i = cur.line, found, e = forward ? Math.min(i + 100, cm.lineCount()) : Math.max(-1, i - 100); i != e; i+=d) { - if (i == cur.line) found = scan(line, i, pos); - else found = scan(cm.getLineHandle(i), i); - if (found) break; - } - return {from: Pos(cur.line, pos), to: found && Pos(i, found.pos), - match: found && found.match, forward: forward}; - } - - function matchBrackets(cm, autoclear) { - // Disable brace matching in long lines, since it'll cause hugely slow updates - var maxHighlightLen = cm.state.matchBrackets.maxHighlightLineLength || 1000; - var found = findMatchingBracket(cm); - if (!found || cm.getLine(found.from.line).length > maxHighlightLen || - found.to && cm.getLine(found.to.line).length > maxHighlightLen) - return; - - var style = found.match ? "CodeMirror-matchingbracket" : "CodeMirror-nonmatchingbracket"; - var one = cm.markText(found.from, Pos(found.from.line, found.from.ch + 1), {className: style}); - var two = found.to && cm.markText(found.to, Pos(found.to.line, found.to.ch + 1), {className: style}); - // Kludge to work around the IE bug from issue #1193, where text - // input stops going to the textare whever this fires. - if (ie_lt8 && cm.state.focused) cm.display.input.focus(); - var clear = function() { - cm.operation(function() { one.clear(); two && two.clear(); }); - }; - if (autoclear) setTimeout(clear, 800); - else return clear; - } - - var currentlyHighlighted = null; - function doMatchBrackets(cm) { - cm.operation(function() { - if (currentlyHighlighted) {currentlyHighlighted(); currentlyHighlighted = null;} - if (!cm.somethingSelected()) currentlyHighlighted = matchBrackets(cm, false); - }); - } - - CodeMirror.defineOption("matchBrackets", false, function(cm, val, old) { - if (old && old != CodeMirror.Init) - cm.off("cursorActivity", doMatchBrackets); - if (val) { - cm.state.matchBrackets = typeof val == "object" ? val : {}; - cm.on("cursorActivity", doMatchBrackets); - } - }); - - CodeMirror.defineExtension("matchBrackets", function() {matchBrackets(this, true);}); - CodeMirror.defineExtension("findMatchingBracket", function(pos, strict){ - return findMatchingBracket(this, pos, strict); - }); -})(); +(function() { + var ie_lt8 = /MSIE \d/.test(navigator.userAgent) && + (document.documentMode == null || document.documentMode < 8); + + var Pos = CodeMirror.Pos; + + var matching = {"(": ")>", ")": "(<", "[": "]>", "]": "[<", "{": "}>", "}": "{<"}; + function findMatchingBracket(cm, where, strict) { + var state = cm.state.matchBrackets; + var maxScanLen = (state && state.maxScanLineLength) || 10000; + + var cur = where || cm.getCursor(), line = cm.getLineHandle(cur.line), pos = cur.ch - 1; + var match = (pos >= 0 && matching[line.text.charAt(pos)]) || matching[line.text.charAt(++pos)]; + if (!match) return null; + var forward = match.charAt(1) == ">", d = forward ? 1 : -1; + if (strict && forward != (pos == cur.ch)) return null; + var style = cm.getTokenTypeAt(Pos(cur.line, pos + 1)); + + var stack = [line.text.charAt(pos)], re = /[(){}[\]]/; + function scan(line, lineNo, start) { + if (!line.text) return; + var pos = forward ? 0 : line.text.length - 1, end = forward ? line.text.length : -1; + if (line.text.length > maxScanLen) return null; + if (start != null) pos = start + d; + for (; pos != end; pos += d) { + var ch = line.text.charAt(pos); + if (re.test(ch) && cm.getTokenTypeAt(Pos(lineNo, pos + 1)) == style) { + var match = matching[ch]; + if (match.charAt(1) == ">" == forward) stack.push(ch); + else if (stack.pop() != match.charAt(0)) return {pos: pos, match: false}; + else if (!stack.length) return {pos: pos, match: true}; + } + } + } + for (var i = cur.line, found, e = forward ? Math.min(i + 100, cm.lineCount()) : Math.max(-1, i - 100); i != e; i+=d) { + if (i == cur.line) found = scan(line, i, pos); + else found = scan(cm.getLineHandle(i), i); + if (found) break; + } + return {from: Pos(cur.line, pos), to: found && Pos(i, found.pos), + match: found && found.match, forward: forward}; + } + + function matchBrackets(cm, autoclear) { + // Disable brace matching in long lines, since it'll cause hugely slow updates + var maxHighlightLen = cm.state.matchBrackets.maxHighlightLineLength || 1000; + var found = findMatchingBracket(cm); + if (!found || cm.getLine(found.from.line).length > maxHighlightLen || + found.to && cm.getLine(found.to.line).length > maxHighlightLen) + return; + + var style = found.match ? "CodeMirror-matchingbracket" : "CodeMirror-nonmatchingbracket"; + var one = cm.markText(found.from, Pos(found.from.line, found.from.ch + 1), {className: style}); + var two = found.to && cm.markText(found.to, Pos(found.to.line, found.to.ch + 1), {className: style}); + // Kludge to work around the IE bug from issue #1193, where text + // input stops going to the textare whever this fires. + if (ie_lt8 && cm.state.focused) cm.display.input.focus(); + var clear = function() { + cm.operation(function() { one.clear(); two && two.clear(); }); + }; + if (autoclear) setTimeout(clear, 800); + else return clear; + } + + var currentlyHighlighted = null; + function doMatchBrackets(cm) { + cm.operation(function() { + if (currentlyHighlighted) {currentlyHighlighted(); currentlyHighlighted = null;} + if (!cm.somethingSelected()) currentlyHighlighted = matchBrackets(cm, false); + }); + } + + CodeMirror.defineOption("matchBrackets", false, function(cm, val, old) { + if (old && old != CodeMirror.Init) + cm.off("cursorActivity", doMatchBrackets); + if (val) { + cm.state.matchBrackets = typeof val == "object" ? val : {}; + cm.on("cursorActivity", doMatchBrackets); + } + }); + + CodeMirror.defineExtension("matchBrackets", function() {matchBrackets(this, true);}); + CodeMirror.defineExtension("findMatchingBracket", function(pos, strict){ + return findMatchingBracket(this, pos, strict); + }); +})(); diff --git a/profile-builder/assets/lib/codemirror/addon/edit/matchtags.js b/profile-builder/assets/lib/codemirror/addon/edit/matchtags.js index f189c1f..8ebf9d5 100644 --- a/profile-builder/assets/lib/codemirror/addon/edit/matchtags.js +++ b/profile-builder/assets/lib/codemirror/addon/edit/matchtags.js @@ -1,56 +1,56 @@ -(function() { - "use strict"; - - CodeMirror.defineOption("matchTags", false, function(cm, val, old) { - if (old && old != CodeMirror.Init) { - cm.off("cursorActivity", doMatchTags); - cm.off("viewportChange", maybeUpdateMatch); - clear(cm); - } - if (val) { - cm.state.matchBothTags = typeof val == "object" && val.bothTags; - cm.on("cursorActivity", doMatchTags); - cm.on("viewportChange", maybeUpdateMatch); - doMatchTags(cm); - } - }); - - function clear(cm) { - if (cm.state.tagHit) cm.state.tagHit.clear(); - if (cm.state.tagOther) cm.state.tagOther.clear(); - cm.state.tagHit = cm.state.tagOther = null; - } - - function doMatchTags(cm) { - cm.state.failedTagMatch = false; - cm.operation(function() { - clear(cm); - if (cm.somethingSelected()) return; - var cur = cm.getCursor(), range = cm.getViewport(); - range.from = Math.min(range.from, cur.line); range.to = Math.max(cur.line + 1, range.to); - var match = CodeMirror.findMatchingTag(cm, cur, range); - if (!match) return; - if (cm.state.matchBothTags) { - var hit = match.at == "open" ? match.open : match.close; - if (hit) cm.state.tagHit = cm.markText(hit.from, hit.to, {className: "CodeMirror-matchingtag"}); - } - var other = match.at == "close" ? match.open : match.close; - if (other) - cm.state.tagOther = cm.markText(other.from, other.to, {className: "CodeMirror-matchingtag"}); - else - cm.state.failedTagMatch = true; - }); - } - - function maybeUpdateMatch(cm) { - if (cm.state.failedTagMatch) doMatchTags(cm); - } - - CodeMirror.commands.toMatchingTag = function(cm) { - var found = CodeMirror.findMatchingTag(cm, cm.getCursor()); - if (found) { - var other = found.at == "close" ? found.open : found.close; - if (other) cm.setSelection(other.to, other.from); - } - }; -})(); +(function() { + "use strict"; + + CodeMirror.defineOption("matchTags", false, function(cm, val, old) { + if (old && old != CodeMirror.Init) { + cm.off("cursorActivity", doMatchTags); + cm.off("viewportChange", maybeUpdateMatch); + clear(cm); + } + if (val) { + cm.state.matchBothTags = typeof val == "object" && val.bothTags; + cm.on("cursorActivity", doMatchTags); + cm.on("viewportChange", maybeUpdateMatch); + doMatchTags(cm); + } + }); + + function clear(cm) { + if (cm.state.tagHit) cm.state.tagHit.clear(); + if (cm.state.tagOther) cm.state.tagOther.clear(); + cm.state.tagHit = cm.state.tagOther = null; + } + + function doMatchTags(cm) { + cm.state.failedTagMatch = false; + cm.operation(function() { + clear(cm); + if (cm.somethingSelected()) return; + var cur = cm.getCursor(), range = cm.getViewport(); + range.from = Math.min(range.from, cur.line); range.to = Math.max(cur.line + 1, range.to); + var match = CodeMirror.findMatchingTag(cm, cur, range); + if (!match) return; + if (cm.state.matchBothTags) { + var hit = match.at == "open" ? match.open : match.close; + if (hit) cm.state.tagHit = cm.markText(hit.from, hit.to, {className: "CodeMirror-matchingtag"}); + } + var other = match.at == "close" ? match.open : match.close; + if (other) + cm.state.tagOther = cm.markText(other.from, other.to, {className: "CodeMirror-matchingtag"}); + else + cm.state.failedTagMatch = true; + }); + } + + function maybeUpdateMatch(cm) { + if (cm.state.failedTagMatch) doMatchTags(cm); + } + + CodeMirror.commands.toMatchingTag = function(cm) { + var found = CodeMirror.findMatchingTag(cm, cm.getCursor()); + if (found) { + var other = found.at == "close" ? found.open : found.close; + if (other) cm.setSelection(other.to, other.from); + } + }; +})(); diff --git a/profile-builder/assets/lib/codemirror/addon/edit/trailingspace.js b/profile-builder/assets/lib/codemirror/addon/edit/trailingspace.js index f6bb026..264b59f 100644 --- a/profile-builder/assets/lib/codemirror/addon/edit/trailingspace.js +++ b/profile-builder/assets/lib/codemirror/addon/edit/trailingspace.js @@ -1,15 +1,15 @@ -CodeMirror.defineOption("showTrailingSpace", false, function(cm, val, prev) { - if (prev == CodeMirror.Init) prev = false; - if (prev && !val) - cm.removeOverlay("trailingspace"); - else if (!prev && val) - cm.addOverlay({ - token: function(stream) { - for (var l = stream.string.length, i = l; i && /\s/.test(stream.string.charAt(i - 1)); --i) {} - if (i > stream.pos) { stream.pos = i; return null; } - stream.pos = l; - return "trailingspace"; - }, - name: "trailingspace" - }); -}); +CodeMirror.defineOption("showTrailingSpace", false, function(cm, val, prev) { + if (prev == CodeMirror.Init) prev = false; + if (prev && !val) + cm.removeOverlay("trailingspace"); + else if (!prev && val) + cm.addOverlay({ + token: function(stream) { + for (var l = stream.string.length, i = l; i && /\s/.test(stream.string.charAt(i - 1)); --i) {} + if (i > stream.pos) { stream.pos = i; return null; } + stream.pos = l; + return "trailingspace"; + }, + name: "trailingspace" + }); +}); diff --git a/profile-builder/assets/lib/codemirror/addon/fold/brace-fold.js b/profile-builder/assets/lib/codemirror/addon/fold/brace-fold.js index 2560b2b..ccbb3a2 100644 --- a/profile-builder/assets/lib/codemirror/addon/fold/brace-fold.js +++ b/profile-builder/assets/lib/codemirror/addon/fold/brace-fold.js @@ -1,93 +1,93 @@ -CodeMirror.registerHelper("fold", "brace", function(cm, start) { - var line = start.line, lineText = cm.getLine(line); - var startCh, tokenType; - - function findOpening(openCh) { - for (var at = start.ch, pass = 0;;) { - var found = at <= 0 ? -1 : lineText.lastIndexOf(openCh, at - 1); - if (found == -1) { - if (pass == 1) break; - pass = 1; - at = lineText.length; - continue; - } - if (pass == 1 && found < start.ch) break; - tokenType = cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1)); - if (!/^(comment|string)/.test(tokenType)) return found + 1; - at = found - 1; - } - } - - var startToken = "{", endToken = "}", startCh = findOpening("{"); - if (startCh == null) { - startToken = "[", endToken = "]"; - startCh = findOpening("["); - } - - if (startCh == null) return; - var count = 1, lastLine = cm.lastLine(), end, endCh; - outer: for (var i = line; i <= lastLine; ++i) { - var text = cm.getLine(i), pos = i == line ? startCh : 0; - for (;;) { - var nextOpen = text.indexOf(startToken, pos), nextClose = text.indexOf(endToken, pos); - if (nextOpen < 0) nextOpen = text.length; - if (nextClose < 0) nextClose = text.length; - pos = Math.min(nextOpen, nextClose); - if (pos == text.length) break; - if (cm.getTokenTypeAt(CodeMirror.Pos(i, pos + 1)) == tokenType) { - if (pos == nextOpen) ++count; - else if (!--count) { end = i; endCh = pos; break outer; } - } - ++pos; - } - } - if (end == null || line == end && endCh == startCh) return; - return {from: CodeMirror.Pos(line, startCh), - to: CodeMirror.Pos(end, endCh)}; -}); -CodeMirror.braceRangeFinder = CodeMirror.fold.brace; // deprecated - -CodeMirror.registerHelper("fold", "import", function(cm, start) { - function hasImport(line) { - if (line < cm.firstLine() || line > cm.lastLine()) return null; - var start = cm.getTokenAt(CodeMirror.Pos(line, 1)); - if (!/\S/.test(start.string)) start = cm.getTokenAt(CodeMirror.Pos(line, start.end + 1)); - if (start.type != "keyword" || start.string != "import") return null; - // Now find closing semicolon, return its position - for (var i = line, e = Math.min(cm.lastLine(), line + 10); i <= e; ++i) { - var text = cm.getLine(i), semi = text.indexOf(";"); - if (semi != -1) return {startCh: start.end, end: CodeMirror.Pos(i, semi)}; - } - } - - var start = start.line, has = hasImport(start), prev; - if (!has || hasImport(start - 1) || ((prev = hasImport(start - 2)) && prev.end.line == start - 1)) - return null; - for (var end = has.end;;) { - var next = hasImport(end.line + 1); - if (next == null) break; - end = next.end; - } - return {from: cm.clipPos(CodeMirror.Pos(start, has.startCh + 1)), to: end}; -}); -CodeMirror.importRangeFinder = CodeMirror.fold["import"]; // deprecated - -CodeMirror.registerHelper("fold", "include", function(cm, start) { - function hasInclude(line) { - if (line < cm.firstLine() || line > cm.lastLine()) return null; - var start = cm.getTokenAt(CodeMirror.Pos(line, 1)); - if (!/\S/.test(start.string)) start = cm.getTokenAt(CodeMirror.Pos(line, start.end + 1)); - if (start.type == "meta" && start.string.slice(0, 8) == "#include") return start.start + 8; - } - - var start = start.line, has = hasInclude(start); - if (has == null || hasInclude(start - 1) != null) return null; - for (var end = start;;) { - var next = hasInclude(end + 1); - if (next == null) break; - ++end; - } - return {from: CodeMirror.Pos(start, has + 1), - to: cm.clipPos(CodeMirror.Pos(end))}; -}); -CodeMirror.includeRangeFinder = CodeMirror.fold.include; // deprecated +CodeMirror.registerHelper("fold", "brace", function(cm, start) { + var line = start.line, lineText = cm.getLine(line); + var startCh, tokenType; + + function findOpening(openCh) { + for (var at = start.ch, pass = 0;;) { + var found = at <= 0 ? -1 : lineText.lastIndexOf(openCh, at - 1); + if (found == -1) { + if (pass == 1) break; + pass = 1; + at = lineText.length; + continue; + } + if (pass == 1 && found < start.ch) break; + tokenType = cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1)); + if (!/^(comment|string)/.test(tokenType)) return found + 1; + at = found - 1; + } + } + + var startToken = "{", endToken = "}", startCh = findOpening("{"); + if (startCh == null) { + startToken = "[", endToken = "]"; + startCh = findOpening("["); + } + + if (startCh == null) return; + var count = 1, lastLine = cm.lastLine(), end, endCh; + outer: for (var i = line; i <= lastLine; ++i) { + var text = cm.getLine(i), pos = i == line ? startCh : 0; + for (;;) { + var nextOpen = text.indexOf(startToken, pos), nextClose = text.indexOf(endToken, pos); + if (nextOpen < 0) nextOpen = text.length; + if (nextClose < 0) nextClose = text.length; + pos = Math.min(nextOpen, nextClose); + if (pos == text.length) break; + if (cm.getTokenTypeAt(CodeMirror.Pos(i, pos + 1)) == tokenType) { + if (pos == nextOpen) ++count; + else if (!--count) { end = i; endCh = pos; break outer; } + } + ++pos; + } + } + if (end == null || line == end && endCh == startCh) return; + return {from: CodeMirror.Pos(line, startCh), + to: CodeMirror.Pos(end, endCh)}; +}); +CodeMirror.braceRangeFinder = CodeMirror.fold.brace; // deprecated + +CodeMirror.registerHelper("fold", "import", function(cm, start) { + function hasImport(line) { + if (line < cm.firstLine() || line > cm.lastLine()) return null; + var start = cm.getTokenAt(CodeMirror.Pos(line, 1)); + if (!/\S/.test(start.string)) start = cm.getTokenAt(CodeMirror.Pos(line, start.end + 1)); + if (start.type != "keyword" || start.string != "import") return null; + // Now find closing semicolon, return its position + for (var i = line, e = Math.min(cm.lastLine(), line + 10); i <= e; ++i) { + var text = cm.getLine(i), semi = text.indexOf(";"); + if (semi != -1) return {startCh: start.end, end: CodeMirror.Pos(i, semi)}; + } + } + + var start = start.line, has = hasImport(start), prev; + if (!has || hasImport(start - 1) || ((prev = hasImport(start - 2)) && prev.end.line == start - 1)) + return null; + for (var end = has.end;;) { + var next = hasImport(end.line + 1); + if (next == null) break; + end = next.end; + } + return {from: cm.clipPos(CodeMirror.Pos(start, has.startCh + 1)), to: end}; +}); +CodeMirror.importRangeFinder = CodeMirror.fold["import"]; // deprecated + +CodeMirror.registerHelper("fold", "include", function(cm, start) { + function hasInclude(line) { + if (line < cm.firstLine() || line > cm.lastLine()) return null; + var start = cm.getTokenAt(CodeMirror.Pos(line, 1)); + if (!/\S/.test(start.string)) start = cm.getTokenAt(CodeMirror.Pos(line, start.end + 1)); + if (start.type == "meta" && start.string.slice(0, 8) == "#include") return start.start + 8; + } + + var start = start.line, has = hasInclude(start); + if (has == null || hasInclude(start - 1) != null) return null; + for (var end = start;;) { + var next = hasInclude(end + 1); + if (next == null) break; + ++end; + } + return {from: CodeMirror.Pos(start, has + 1), + to: cm.clipPos(CodeMirror.Pos(end))}; +}); +CodeMirror.includeRangeFinder = CodeMirror.fold.include; // deprecated diff --git a/profile-builder/assets/lib/codemirror/addon/fold/comment-fold.js b/profile-builder/assets/lib/codemirror/addon/fold/comment-fold.js index a064cf8..41ec813 100644 --- a/profile-builder/assets/lib/codemirror/addon/fold/comment-fold.js +++ b/profile-builder/assets/lib/codemirror/addon/fold/comment-fold.js @@ -1,40 +1,40 @@ -CodeMirror.registerHelper("fold", "comment", function(cm, start) { - var mode = cm.getModeAt(start), startToken = mode.blockCommentStart, endToken = mode.blockCommentEnd; - if (!startToken || !endToken) return; - var line = start.line, lineText = cm.getLine(line); - - var startCh; - for (var at = start.ch, pass = 0;;) { - var found = at <= 0 ? -1 : lineText.lastIndexOf(startToken, at - 1); - if (found == -1) { - if (pass == 1) return; - pass = 1; - at = lineText.length; - continue; - } - if (pass == 1 && found < start.ch) return; - if (/comment/.test(cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1)))) { - startCh = found + startToken.length; - break; - } - at = found - 1; - } - - var depth = 1, lastLine = cm.lastLine(), end, endCh; - outer: for (var i = line; i <= lastLine; ++i) { - var text = cm.getLine(i), pos = i == line ? startCh : 0; - for (;;) { - var nextOpen = text.indexOf(startToken, pos), nextClose = text.indexOf(endToken, pos); - if (nextOpen < 0) nextOpen = text.length; - if (nextClose < 0) nextClose = text.length; - pos = Math.min(nextOpen, nextClose); - if (pos == text.length) break; - if (pos == nextOpen) ++depth; - else if (!--depth) { end = i; endCh = pos; break outer; } - ++pos; - } - } - if (end == null || line == end && endCh == startCh) return; - return {from: CodeMirror.Pos(line, startCh), - to: CodeMirror.Pos(end, endCh)}; -}); +CodeMirror.registerHelper("fold", "comment", function(cm, start) { + var mode = cm.getModeAt(start), startToken = mode.blockCommentStart, endToken = mode.blockCommentEnd; + if (!startToken || !endToken) return; + var line = start.line, lineText = cm.getLine(line); + + var startCh; + for (var at = start.ch, pass = 0;;) { + var found = at <= 0 ? -1 : lineText.lastIndexOf(startToken, at - 1); + if (found == -1) { + if (pass == 1) return; + pass = 1; + at = lineText.length; + continue; + } + if (pass == 1 && found < start.ch) return; + if (/comment/.test(cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1)))) { + startCh = found + startToken.length; + break; + } + at = found - 1; + } + + var depth = 1, lastLine = cm.lastLine(), end, endCh; + outer: for (var i = line; i <= lastLine; ++i) { + var text = cm.getLine(i), pos = i == line ? startCh : 0; + for (;;) { + var nextOpen = text.indexOf(startToken, pos), nextClose = text.indexOf(endToken, pos); + if (nextOpen < 0) nextOpen = text.length; + if (nextClose < 0) nextClose = text.length; + pos = Math.min(nextOpen, nextClose); + if (pos == text.length) break; + if (pos == nextOpen) ++depth; + else if (!--depth) { end = i; endCh = pos; break outer; } + ++pos; + } + } + if (end == null || line == end && endCh == startCh) return; + return {from: CodeMirror.Pos(line, startCh), + to: CodeMirror.Pos(end, endCh)}; +}); diff --git a/profile-builder/assets/lib/codemirror/addon/fold/foldcode.js b/profile-builder/assets/lib/codemirror/addon/fold/foldcode.js index 931c372..063dcbd 100644 --- a/profile-builder/assets/lib/codemirror/addon/fold/foldcode.js +++ b/profile-builder/assets/lib/codemirror/addon/fold/foldcode.js @@ -1,73 +1,73 @@ -(function() { - "use strict"; - - function doFold(cm, pos, options) { - var finder = options && (options.call ? options : options.rangeFinder); - if (!finder) finder = cm.getHelper(pos, "fold"); - if (!finder) return; - if (typeof pos == "number") pos = CodeMirror.Pos(pos, 0); - var minSize = options && options.minFoldSize || 0; - - function getRange(allowFolded) { - var range = finder(cm, pos); - if (!range || range.to.line - range.from.line < minSize) return null; - var marks = cm.findMarksAt(range.from); - for (var i = 0; i < marks.length; ++i) { - if (marks[i].__isFold) { - if (!allowFolded) return null; - range.cleared = true; - marks[i].clear(); - } - } - return range; - } - - var range = getRange(true); - if (options && options.scanUp) while (!range && pos.line > cm.firstLine()) { - pos = CodeMirror.Pos(pos.line - 1, 0); - range = getRange(false); - } - if (!range || range.cleared) return; - - var myWidget = makeWidget(options); - CodeMirror.on(myWidget, "mousedown", function() { myRange.clear(); }); - var myRange = cm.markText(range.from, range.to, { - replacedWith: myWidget, - clearOnEnter: true, - __isFold: true - }); - myRange.on("clear", function(from, to) { - CodeMirror.signal(cm, "unfold", cm, from, to); - }); - CodeMirror.signal(cm, "fold", cm, range.from, range.to); - } - - function makeWidget(options) { - var widget = (options && options.widget) || "\u2194"; - if (typeof widget == "string") { - var text = document.createTextNode(widget); - widget = document.createElement("span"); - widget.appendChild(text); - widget.className = "CodeMirror-foldmarker"; - } - return widget; - } - - // Clumsy backwards-compatible interface - CodeMirror.newFoldFunction = function(rangeFinder, widget) { - return function(cm, pos) { doFold(cm, pos, {rangeFinder: rangeFinder, widget: widget}); }; - }; - - // New-style interface - CodeMirror.defineExtension("foldCode", function(pos, options) { doFold(this, pos, options); }); - - CodeMirror.registerHelper("fold", "combine", function() { - var funcs = Array.prototype.slice.call(arguments, 0); - return function(cm, start) { - for (var i = 0; i < funcs.length; ++i) { - var found = funcs[i](cm, start); - if (found) return found; - } - }; - }); -})(); +(function() { + "use strict"; + + function doFold(cm, pos, options) { + var finder = options && (options.call ? options : options.rangeFinder); + if (!finder) finder = cm.getHelper(pos, "fold"); + if (!finder) return; + if (typeof pos == "number") pos = CodeMirror.Pos(pos, 0); + var minSize = options && options.minFoldSize || 0; + + function getRange(allowFolded) { + var range = finder(cm, pos); + if (!range || range.to.line - range.from.line < minSize) return null; + var marks = cm.findMarksAt(range.from); + for (var i = 0; i < marks.length; ++i) { + if (marks[i].__isFold) { + if (!allowFolded) return null; + range.cleared = true; + marks[i].clear(); + } + } + return range; + } + + var range = getRange(true); + if (options && options.scanUp) while (!range && pos.line > cm.firstLine()) { + pos = CodeMirror.Pos(pos.line - 1, 0); + range = getRange(false); + } + if (!range || range.cleared) return; + + var myWidget = makeWidget(options); + CodeMirror.on(myWidget, "mousedown", function() { myRange.clear(); }); + var myRange = cm.markText(range.from, range.to, { + replacedWith: myWidget, + clearOnEnter: true, + __isFold: true + }); + myRange.on("clear", function(from, to) { + CodeMirror.signal(cm, "unfold", cm, from, to); + }); + CodeMirror.signal(cm, "fold", cm, range.from, range.to); + } + + function makeWidget(options) { + var widget = (options && options.widget) || "\u2194"; + if (typeof widget == "string") { + var text = document.createTextNode(widget); + widget = document.createElement("span"); + widget.appendChild(text); + widget.className = "CodeMirror-foldmarker"; + } + return widget; + } + + // Clumsy backwards-compatible interface + CodeMirror.newFoldFunction = function(rangeFinder, widget) { + return function(cm, pos) { doFold(cm, pos, {rangeFinder: rangeFinder, widget: widget}); }; + }; + + // New-style interface + CodeMirror.defineExtension("foldCode", function(pos, options) { doFold(this, pos, options); }); + + CodeMirror.registerHelper("fold", "combine", function() { + var funcs = Array.prototype.slice.call(arguments, 0); + return function(cm, start) { + for (var i = 0; i < funcs.length; ++i) { + var found = funcs[i](cm, start); + if (found) return found; + } + }; + }); +})(); diff --git a/profile-builder/assets/lib/codemirror/addon/fold/foldgutter.js b/profile-builder/assets/lib/codemirror/addon/fold/foldgutter.js index b809c93..b992f24 100644 --- a/profile-builder/assets/lib/codemirror/addon/fold/foldgutter.js +++ b/profile-builder/assets/lib/codemirror/addon/fold/foldgutter.js @@ -1,122 +1,122 @@ -(function() { - "use strict"; - - CodeMirror.defineOption("foldGutter", false, function(cm, val, old) { - if (old && old != CodeMirror.Init) { - cm.clearGutter(cm.state.foldGutter.options.gutter); - cm.state.foldGutter = null; - cm.off("gutterClick", onGutterClick); - cm.off("change", onChange); - cm.off("viewportChange", onViewportChange); - cm.off("fold", onFold); - cm.off("unfold", onFold); - } - if (val) { - cm.state.foldGutter = new State(parseOptions(val)); - updateInViewport(cm); - cm.on("gutterClick", onGutterClick); - cm.on("change", onChange); - cm.on("viewportChange", onViewportChange); - cm.on("fold", onFold); - cm.on("unfold", onFold); - } - }); - - var Pos = CodeMirror.Pos; - - function State(options) { - this.options = options; - this.from = this.to = 0; - } - - function parseOptions(opts) { - if (opts === true) opts = {}; - if (opts.gutter == null) opts.gutter = "CodeMirror-foldgutter"; - if (opts.indicatorOpen == null) opts.indicatorOpen = "CodeMirror-foldgutter-open"; - if (opts.indicatorFolded == null) opts.indicatorFolded = "CodeMirror-foldgutter-folded"; - return opts; - } - - function isFolded(cm, line) { - var marks = cm.findMarksAt(Pos(line)); - for (var i = 0; i < marks.length; ++i) - if (marks[i].__isFold && marks[i].find().from.line == line) return true; - } - - function marker(spec) { - if (typeof spec == "string") { - var elt = document.createElement("div"); - elt.className = spec; - return elt; - } else { - return spec.cloneNode(true); - } - } - - function updateFoldInfo(cm, from, to) { - var opts = cm.state.foldGutter.options, cur = from; - cm.eachLine(from, to, function(line) { - var mark = null; - if (isFolded(cm, cur)) { - mark = marker(opts.indicatorFolded); - } else { - var pos = Pos(cur, 0), func = opts.rangeFinder || cm.getHelper(pos, "fold"); - var range = func && func(cm, pos); - if (range && range.from.line + 1 < range.to.line) - mark = marker(opts.indicatorOpen); - } - cm.setGutterMarker(line, opts.gutter, mark); - ++cur; - }); - } - - function updateInViewport(cm) { - var vp = cm.getViewport(), state = cm.state.foldGutter; - if (!state) return; - cm.operation(function() { - updateFoldInfo(cm, vp.from, vp.to); - }); - state.from = vp.from; state.to = vp.to; - } - - function onGutterClick(cm, line, gutter) { - var opts = cm.state.foldGutter.options; - if (gutter != opts.gutter) return; - cm.foldCode(Pos(line, 0), opts.rangeFinder); - } - - function onChange(cm) { - var state = cm.state.foldGutter; - state.from = state.to = 0; - clearTimeout(state.changeUpdate); - state.changeUpdate = setTimeout(function() { updateInViewport(cm); }, 600); - } - - function onViewportChange(cm) { - var state = cm.state.foldGutter; - clearTimeout(state.changeUpdate); - state.changeUpdate = setTimeout(function() { - var vp = cm.getViewport(); - if (state.from == state.to || vp.from - state.to > 20 || state.from - vp.to > 20) { - updateInViewport(cm); - } else { - cm.operation(function() { - if (vp.from < state.from) { - updateFoldInfo(cm, vp.from, state.from); - state.from = vp.from; - } - if (vp.to > state.to) { - updateFoldInfo(cm, state.to, vp.to); - state.to = vp.to; - } - }); - } - }, 400); - } - - function onFold(cm, from) { - var state = cm.state.foldGutter, line = from.line; - if (line >= state.from && line < state.to) - updateFoldInfo(cm, line, line + 1); - } -})(); +(function() { + "use strict"; + + CodeMirror.defineOption("foldGutter", false, function(cm, val, old) { + if (old && old != CodeMirror.Init) { + cm.clearGutter(cm.state.foldGutter.options.gutter); + cm.state.foldGutter = null; + cm.off("gutterClick", onGutterClick); + cm.off("change", onChange); + cm.off("viewportChange", onViewportChange); + cm.off("fold", onFold); + cm.off("unfold", onFold); + } + if (val) { + cm.state.foldGutter = new State(parseOptions(val)); + updateInViewport(cm); + cm.on("gutterClick", onGutterClick); + cm.on("change", onChange); + cm.on("viewportChange", onViewportChange); + cm.on("fold", onFold); + cm.on("unfold", onFold); + } + }); + + var Pos = CodeMirror.Pos; + + function State(options) { + this.options = options; + this.from = this.to = 0; + } + + function parseOptions(opts) { + if (opts === true) opts = {}; + if (opts.gutter == null) opts.gutter = "CodeMirror-foldgutter"; + if (opts.indicatorOpen == null) opts.indicatorOpen = "CodeMirror-foldgutter-open"; + if (opts.indicatorFolded == null) opts.indicatorFolded = "CodeMirror-foldgutter-folded"; + return opts; + } + + function isFolded(cm, line) { + var marks = cm.findMarksAt(Pos(line)); + for (var i = 0; i < marks.length; ++i) + if (marks[i].__isFold && marks[i].find().from.line == line) return true; + } + + function marker(spec) { + if (typeof spec == "string") { + var elt = document.createElement("div"); + elt.className = spec; + return elt; + } else { + return spec.cloneNode(true); + } + } + + function updateFoldInfo(cm, from, to) { + var opts = cm.state.foldGutter.options, cur = from; + cm.eachLine(from, to, function(line) { + var mark = null; + if (isFolded(cm, cur)) { + mark = marker(opts.indicatorFolded); + } else { + var pos = Pos(cur, 0), func = opts.rangeFinder || cm.getHelper(pos, "fold"); + var range = func && func(cm, pos); + if (range && range.from.line + 1 < range.to.line) + mark = marker(opts.indicatorOpen); + } + cm.setGutterMarker(line, opts.gutter, mark); + ++cur; + }); + } + + function updateInViewport(cm) { + var vp = cm.getViewport(), state = cm.state.foldGutter; + if (!state) return; + cm.operation(function() { + updateFoldInfo(cm, vp.from, vp.to); + }); + state.from = vp.from; state.to = vp.to; + } + + function onGutterClick(cm, line, gutter) { + var opts = cm.state.foldGutter.options; + if (gutter != opts.gutter) return; + cm.foldCode(Pos(line, 0), opts.rangeFinder); + } + + function onChange(cm) { + var state = cm.state.foldGutter; + state.from = state.to = 0; + clearTimeout(state.changeUpdate); + state.changeUpdate = setTimeout(function() { updateInViewport(cm); }, 600); + } + + function onViewportChange(cm) { + var state = cm.state.foldGutter; + clearTimeout(state.changeUpdate); + state.changeUpdate = setTimeout(function() { + var vp = cm.getViewport(); + if (state.from == state.to || vp.from - state.to > 20 || state.from - vp.to > 20) { + updateInViewport(cm); + } else { + cm.operation(function() { + if (vp.from < state.from) { + updateFoldInfo(cm, vp.from, state.from); + state.from = vp.from; + } + if (vp.to > state.to) { + updateFoldInfo(cm, state.to, vp.to); + state.to = vp.to; + } + }); + } + }, 400); + } + + function onFold(cm, from) { + var state = cm.state.foldGutter, line = from.line; + if (line >= state.from && line < state.to) + updateFoldInfo(cm, line, line + 1); + } +})(); diff --git a/profile-builder/assets/lib/codemirror/addon/fold/indent-fold.js b/profile-builder/assets/lib/codemirror/addon/fold/indent-fold.js index fcbff96..bdf3ef5 100644 --- a/profile-builder/assets/lib/codemirror/addon/fold/indent-fold.js +++ b/profile-builder/assets/lib/codemirror/addon/fold/indent-fold.js @@ -1,12 +1,12 @@ -CodeMirror.registerHelper("fold", "indent", function(cm, start) { - var tabSize = cm.getOption("tabSize"), firstLine = cm.getLine(start.line); - var myIndent = CodeMirror.countColumn(firstLine, null, tabSize); - for (var i = start.line + 1, end = cm.lineCount(); i < end; ++i) { - var curLine = cm.getLine(i); - if (CodeMirror.countColumn(curLine, null, tabSize) < myIndent && - CodeMirror.countColumn(cm.getLine(i-1), null, tabSize) > myIndent) - return {from: CodeMirror.Pos(start.line, firstLine.length), - to: CodeMirror.Pos(i, curLine.length)}; - } -}); -CodeMirror.indentRangeFinder = CodeMirror.fold.indent; // deprecated +CodeMirror.registerHelper("fold", "indent", function(cm, start) { + var tabSize = cm.getOption("tabSize"), firstLine = cm.getLine(start.line); + var myIndent = CodeMirror.countColumn(firstLine, null, tabSize); + for (var i = start.line + 1, end = cm.lineCount(); i < end; ++i) { + var curLine = cm.getLine(i); + if (CodeMirror.countColumn(curLine, null, tabSize) < myIndent && + CodeMirror.countColumn(cm.getLine(i-1), null, tabSize) > myIndent) + return {from: CodeMirror.Pos(start.line, firstLine.length), + to: CodeMirror.Pos(i, curLine.length)}; + } +}); +CodeMirror.indentRangeFinder = CodeMirror.fold.indent; // deprecated diff --git a/profile-builder/assets/lib/codemirror/addon/fold/xml-fold.js b/profile-builder/assets/lib/codemirror/addon/fold/xml-fold.js index 88a107c..d992c3d 100644 --- a/profile-builder/assets/lib/codemirror/addon/fold/xml-fold.js +++ b/profile-builder/assets/lib/codemirror/addon/fold/xml-fold.js @@ -1,167 +1,167 @@ -(function() { - "use strict"; - - var Pos = CodeMirror.Pos; - function cmp(a, b) { return a.line - b.line || a.ch - b.ch; } - - var nameStartChar = "A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD"; - var nameChar = nameStartChar + "\-\:\.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040"; - var xmlTagStart = new RegExp("<(/?)([" + nameStartChar + "][" + nameChar + "]*)", "g"); - - function Iter(cm, line, ch, range) { - this.line = line; this.ch = ch; - this.cm = cm; this.text = cm.getLine(line); - this.min = range ? range.from : cm.firstLine(); - this.max = range ? range.to - 1 : cm.lastLine(); - } - - function tagAt(iter, ch) { - var type = iter.cm.getTokenTypeAt(Pos(iter.line, ch)); - return type && /\btag\b/.test(type); - } - - function nextLine(iter) { - if (iter.line >= iter.max) return; - iter.ch = 0; - iter.text = iter.cm.getLine(++iter.line); - return true; - } - function prevLine(iter) { - if (iter.line <= iter.min) return; - iter.text = iter.cm.getLine(--iter.line); - iter.ch = iter.text.length; - return true; - } - - function toTagEnd(iter) { - for (;;) { - var gt = iter.text.indexOf(">", iter.ch); - if (gt == -1) { if (nextLine(iter)) continue; else return; } - if (!tagAt(iter, gt + 1)) { iter.ch = gt + 1; continue; } - var lastSlash = iter.text.lastIndexOf("/", gt); - var selfClose = lastSlash > -1 && !/\S/.test(iter.text.slice(lastSlash + 1, gt)); - iter.ch = gt + 1; - return selfClose ? "selfClose" : "regular"; - } - } - function toTagStart(iter) { - for (;;) { - var lt = iter.ch ? iter.text.lastIndexOf("<", iter.ch - 1) : -1; - if (lt == -1) { if (prevLine(iter)) continue; else return; } - if (!tagAt(iter, lt + 1)) { iter.ch = lt; continue; } - xmlTagStart.lastIndex = lt; - iter.ch = lt; - var match = xmlTagStart.exec(iter.text); - if (match && match.index == lt) return match; - } - } - - function toNextTag(iter) { - for (;;) { - xmlTagStart.lastIndex = iter.ch; - var found = xmlTagStart.exec(iter.text); - if (!found) { if (nextLine(iter)) continue; else return; } - if (!tagAt(iter, found.index + 1)) { iter.ch = found.index + 1; continue; } - iter.ch = found.index + found[0].length; - return found; - } - } - function toPrevTag(iter) { - for (;;) { - var gt = iter.ch ? iter.text.lastIndexOf(">", iter.ch - 1) : -1; - if (gt == -1) { if (prevLine(iter)) continue; else return; } - if (!tagAt(iter, gt + 1)) { iter.ch = gt; continue; } - var lastSlash = iter.text.lastIndexOf("/", gt); - var selfClose = lastSlash > -1 && !/\S/.test(iter.text.slice(lastSlash + 1, gt)); - iter.ch = gt + 1; - return selfClose ? "selfClose" : "regular"; - } - } - - function findMatchingClose(iter, tag) { - var stack = []; - for (;;) { - var next = toNextTag(iter), end, startLine = iter.line, startCh = iter.ch - (next ? next[0].length : 0); - if (!next || !(end = toTagEnd(iter))) return; - if (end == "selfClose") continue; - if (next[1]) { // closing tag - for (var i = stack.length - 1; i >= 0; --i) if (stack[i] == next[2]) { - stack.length = i; - break; - } - if (i < 0 && (!tag || tag == next[2])) return { - tag: next[2], - from: Pos(startLine, startCh), - to: Pos(iter.line, iter.ch) - }; - } else { // opening tag - stack.push(next[2]); - } - } - } - function findMatchingOpen(iter, tag) { - var stack = []; - for (;;) { - var prev = toPrevTag(iter); - if (!prev) return; - if (prev == "selfClose") { toTagStart(iter); continue; } - var endLine = iter.line, endCh = iter.ch; - var start = toTagStart(iter); - if (!start) return; - if (start[1]) { // closing tag - stack.push(start[2]); - } else { // opening tag - for (var i = stack.length - 1; i >= 0; --i) if (stack[i] == start[2]) { - stack.length = i; - break; - } - if (i < 0 && (!tag || tag == start[2])) return { - tag: start[2], - from: Pos(iter.line, iter.ch), - to: Pos(endLine, endCh) - }; - } - } - } - - CodeMirror.registerHelper("fold", "xml", function(cm, start) { - var iter = new Iter(cm, start.line, 0); - for (;;) { - var openTag = toNextTag(iter), end; - if (!openTag || iter.line != start.line || !(end = toTagEnd(iter))) return; - if (!openTag[1] && end != "selfClose") { - var start = Pos(iter.line, iter.ch); - var close = findMatchingClose(iter, openTag[2]); - return close && {from: start, to: close.from}; - } - } - }); - CodeMirror.tagRangeFinder = CodeMirror.fold.xml; // deprecated - - CodeMirror.findMatchingTag = function(cm, pos, range) { - var iter = new Iter(cm, pos.line, pos.ch, range); - if (iter.text.indexOf(">") == -1 && iter.text.indexOf("<") == -1) return; - var end = toTagEnd(iter), to = end && Pos(iter.line, iter.ch); - var start = end && toTagStart(iter); - if (!end || end == "selfClose" || !start || cmp(iter, pos) > 0) return; - var here = {from: Pos(iter.line, iter.ch), to: to, tag: start[2]}; - - if (start[1]) { // closing tag - return {open: findMatchingOpen(iter, start[2]), close: here, at: "close"}; - } else { // opening tag - iter = new Iter(cm, to.line, to.ch, range); - return {open: here, close: findMatchingClose(iter, start[2]), at: "open"}; - } - }; - - CodeMirror.findEnclosingTag = function(cm, pos, range) { - var iter = new Iter(cm, pos.line, pos.ch, range); - for (;;) { - var open = findMatchingOpen(iter); - if (!open) break; - var forward = new Iter(cm, pos.line, pos.ch, range); - var close = findMatchingClose(forward, open.tag); - if (close) return {open: open, close: close}; - } - }; -})(); +(function() { + "use strict"; + + var Pos = CodeMirror.Pos; + function cmp(a, b) { return a.line - b.line || a.ch - b.ch; } + + var nameStartChar = "A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD"; + var nameChar = nameStartChar + "\-\:\.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040"; + var xmlTagStart = new RegExp("<(/?)([" + nameStartChar + "][" + nameChar + "]*)", "g"); + + function Iter(cm, line, ch, range) { + this.line = line; this.ch = ch; + this.cm = cm; this.text = cm.getLine(line); + this.min = range ? range.from : cm.firstLine(); + this.max = range ? range.to - 1 : cm.lastLine(); + } + + function tagAt(iter, ch) { + var type = iter.cm.getTokenTypeAt(Pos(iter.line, ch)); + return type && /\btag\b/.test(type); + } + + function nextLine(iter) { + if (iter.line >= iter.max) return; + iter.ch = 0; + iter.text = iter.cm.getLine(++iter.line); + return true; + } + function prevLine(iter) { + if (iter.line <= iter.min) return; + iter.text = iter.cm.getLine(--iter.line); + iter.ch = iter.text.length; + return true; + } + + function toTagEnd(iter) { + for (;;) { + var gt = iter.text.indexOf(">", iter.ch); + if (gt == -1) { if (nextLine(iter)) continue; else return; } + if (!tagAt(iter, gt + 1)) { iter.ch = gt + 1; continue; } + var lastSlash = iter.text.lastIndexOf("/", gt); + var selfClose = lastSlash > -1 && !/\S/.test(iter.text.slice(lastSlash + 1, gt)); + iter.ch = gt + 1; + return selfClose ? "selfClose" : "regular"; + } + } + function toTagStart(iter) { + for (;;) { + var lt = iter.ch ? iter.text.lastIndexOf("<", iter.ch - 1) : -1; + if (lt == -1) { if (prevLine(iter)) continue; else return; } + if (!tagAt(iter, lt + 1)) { iter.ch = lt; continue; } + xmlTagStart.lastIndex = lt; + iter.ch = lt; + var match = xmlTagStart.exec(iter.text); + if (match && match.index == lt) return match; + } + } + + function toNextTag(iter) { + for (;;) { + xmlTagStart.lastIndex = iter.ch; + var found = xmlTagStart.exec(iter.text); + if (!found) { if (nextLine(iter)) continue; else return; } + if (!tagAt(iter, found.index + 1)) { iter.ch = found.index + 1; continue; } + iter.ch = found.index + found[0].length; + return found; + } + } + function toPrevTag(iter) { + for (;;) { + var gt = iter.ch ? iter.text.lastIndexOf(">", iter.ch - 1) : -1; + if (gt == -1) { if (prevLine(iter)) continue; else return; } + if (!tagAt(iter, gt + 1)) { iter.ch = gt; continue; } + var lastSlash = iter.text.lastIndexOf("/", gt); + var selfClose = lastSlash > -1 && !/\S/.test(iter.text.slice(lastSlash + 1, gt)); + iter.ch = gt + 1; + return selfClose ? "selfClose" : "regular"; + } + } + + function findMatchingClose(iter, tag) { + var stack = []; + for (;;) { + var next = toNextTag(iter), end, startLine = iter.line, startCh = iter.ch - (next ? next[0].length : 0); + if (!next || !(end = toTagEnd(iter))) return; + if (end == "selfClose") continue; + if (next[1]) { // closing tag + for (var i = stack.length - 1; i >= 0; --i) if (stack[i] == next[2]) { + stack.length = i; + break; + } + if (i < 0 && (!tag || tag == next[2])) return { + tag: next[2], + from: Pos(startLine, startCh), + to: Pos(iter.line, iter.ch) + }; + } else { // opening tag + stack.push(next[2]); + } + } + } + function findMatchingOpen(iter, tag) { + var stack = []; + for (;;) { + var prev = toPrevTag(iter); + if (!prev) return; + if (prev == "selfClose") { toTagStart(iter); continue; } + var endLine = iter.line, endCh = iter.ch; + var start = toTagStart(iter); + if (!start) return; + if (start[1]) { // closing tag + stack.push(start[2]); + } else { // opening tag + for (var i = stack.length - 1; i >= 0; --i) if (stack[i] == start[2]) { + stack.length = i; + break; + } + if (i < 0 && (!tag || tag == start[2])) return { + tag: start[2], + from: Pos(iter.line, iter.ch), + to: Pos(endLine, endCh) + }; + } + } + } + + CodeMirror.registerHelper("fold", "xml", function(cm, start) { + var iter = new Iter(cm, start.line, 0); + for (;;) { + var openTag = toNextTag(iter), end; + if (!openTag || iter.line != start.line || !(end = toTagEnd(iter))) return; + if (!openTag[1] && end != "selfClose") { + var start = Pos(iter.line, iter.ch); + var close = findMatchingClose(iter, openTag[2]); + return close && {from: start, to: close.from}; + } + } + }); + CodeMirror.tagRangeFinder = CodeMirror.fold.xml; // deprecated + + CodeMirror.findMatchingTag = function(cm, pos, range) { + var iter = new Iter(cm, pos.line, pos.ch, range); + if (iter.text.indexOf(">") == -1 && iter.text.indexOf("<") == -1) return; + var end = toTagEnd(iter), to = end && Pos(iter.line, iter.ch); + var start = end && toTagStart(iter); + if (!end || end == "selfClose" || !start || cmp(iter, pos) > 0) return; + var here = {from: Pos(iter.line, iter.ch), to: to, tag: start[2]}; + + if (start[1]) { // closing tag + return {open: findMatchingOpen(iter, start[2]), close: here, at: "close"}; + } else { // opening tag + iter = new Iter(cm, to.line, to.ch, range); + return {open: here, close: findMatchingClose(iter, start[2]), at: "open"}; + } + }; + + CodeMirror.findEnclosingTag = function(cm, pos, range) { + var iter = new Iter(cm, pos.line, pos.ch, range); + for (;;) { + var open = findMatchingOpen(iter); + if (!open) break; + var forward = new Iter(cm, pos.line, pos.ch, range); + var close = findMatchingClose(forward, open.tag); + if (close) return {open: open, close: close}; + } + }; +})(); diff --git a/profile-builder/assets/lib/codemirror/addon/hint/anyword-hint.js b/profile-builder/assets/lib/codemirror/addon/hint/anyword-hint.js index 36ff618..d278467 100644 --- a/profile-builder/assets/lib/codemirror/addon/hint/anyword-hint.js +++ b/profile-builder/assets/lib/codemirror/addon/hint/anyword-hint.js @@ -1,34 +1,34 @@ -(function() { - "use strict"; - - var WORD = /[\w$]+/, RANGE = 500; - - CodeMirror.registerHelper("hint", "anyword", function(editor, options) { - var word = options && options.word || WORD; - var range = options && options.range || RANGE; - var cur = editor.getCursor(), curLine = editor.getLine(cur.line); - var start = cur.ch, end = start; - while (end < curLine.length && word.test(curLine.charAt(end))) ++end; - while (start && word.test(curLine.charAt(start - 1))) --start; - var curWord = start != end && curLine.slice(start, end); - - var list = [], seen = {}; - function scan(dir) { - var line = cur.line, end = Math.min(Math.max(line + dir * range, editor.firstLine()), editor.lastLine()) + dir; - for (; line != end; line += dir) { - var text = editor.getLine(line), m; - var re = new RegExp(word.source, "g"); - while (m = re.exec(text)) { - if (line == cur.line && m[0] === curWord) continue; - if ((!curWord || m[0].indexOf(curWord) == 0) && !seen.hasOwnProperty(m[0])) { - seen[m[0]] = true; - list.push(m[0]); - } - } - } - } - scan(-1); - scan(1); - return {list: list, from: CodeMirror.Pos(cur.line, start), to: CodeMirror.Pos(cur.line, end)}; - }); -})(); +(function() { + "use strict"; + + var WORD = /[\w$]+/, RANGE = 500; + + CodeMirror.registerHelper("hint", "anyword", function(editor, options) { + var word = options && options.word || WORD; + var range = options && options.range || RANGE; + var cur = editor.getCursor(), curLine = editor.getLine(cur.line); + var start = cur.ch, end = start; + while (end < curLine.length && word.test(curLine.charAt(end))) ++end; + while (start && word.test(curLine.charAt(start - 1))) --start; + var curWord = start != end && curLine.slice(start, end); + + var list = [], seen = {}; + function scan(dir) { + var line = cur.line, end = Math.min(Math.max(line + dir * range, editor.firstLine()), editor.lastLine()) + dir; + for (; line != end; line += dir) { + var text = editor.getLine(line), m; + var re = new RegExp(word.source, "g"); + while (m = re.exec(text)) { + if (line == cur.line && m[0] === curWord) continue; + if ((!curWord || m[0].indexOf(curWord) == 0) && !seen.hasOwnProperty(m[0])) { + seen[m[0]] = true; + list.push(m[0]); + } + } + } + } + scan(-1); + scan(1); + return {list: list, from: CodeMirror.Pos(cur.line, start), to: CodeMirror.Pos(cur.line, end)}; + }); +})(); diff --git a/profile-builder/assets/lib/codemirror/addon/hint/css-hint.js b/profile-builder/assets/lib/codemirror/addon/hint/css-hint.js index 2b15300..8837ffd 100644 --- a/profile-builder/assets/lib/codemirror/addon/hint/css-hint.js +++ b/profile-builder/assets/lib/codemirror/addon/hint/css-hint.js @@ -1,50 +1,50 @@ -(function () { - "use strict"; - - function getHints(cm) { - var cur = cm.getCursor(), token = cm.getTokenAt(cur); - var inner = CodeMirror.innerMode(cm.getMode(), token.state); - if (inner.mode.name != "css") return; - - // If it's not a 'word-style' token, ignore the token. - if (!/^[\w$_-]*$/.test(token.string)) { - token = { - start: cur.ch, end: cur.ch, string: "", state: token.state, - type: null - }; - var stack = token.state.stack; - var lastToken = stack && stack.length > 0 ? stack[stack.length - 1] : ""; - if (token.string == ":" || lastToken.indexOf("property") == 0) - token.type = "variable"; - else if (token.string == "{" || lastToken.indexOf("rule") == 0) - token.type = "property"; - } - - if (!token.type) - return; - - var spec = CodeMirror.resolveMode("text/css"); - var keywords = null; - if (token.type.indexOf("property") == 0) - keywords = spec.propertyKeywords; - else if (token.type.indexOf("variable") == 0) - keywords = spec.valueKeywords; - - if (!keywords) - return; - - var result = []; - for (var name in keywords) { - if (name.indexOf(token.string) == 0 /* > -1 */) - result.push(name); - } - - return { - list: result, - from: CodeMirror.Pos(cur.line, token.start), - to: CodeMirror.Pos(cur.line, token.end) - }; - } - - CodeMirror.registerHelper("hint", "css", getHints); -})(); +(function () { + "use strict"; + + function getHints(cm) { + var cur = cm.getCursor(), token = cm.getTokenAt(cur); + var inner = CodeMirror.innerMode(cm.getMode(), token.state); + if (inner.mode.name != "css") return; + + // If it's not a 'word-style' token, ignore the token. + if (!/^[\w$_-]*$/.test(token.string)) { + token = { + start: cur.ch, end: cur.ch, string: "", state: token.state, + type: null + }; + var stack = token.state.stack; + var lastToken = stack && stack.length > 0 ? stack[stack.length - 1] : ""; + if (token.string == ":" || lastToken.indexOf("property") == 0) + token.type = "variable"; + else if (token.string == "{" || lastToken.indexOf("rule") == 0) + token.type = "property"; + } + + if (!token.type) + return; + + var spec = CodeMirror.resolveMode("text/css"); + var keywords = null; + if (token.type.indexOf("property") == 0) + keywords = spec.propertyKeywords; + else if (token.type.indexOf("variable") == 0) + keywords = spec.valueKeywords; + + if (!keywords) + return; + + var result = []; + for (var name in keywords) { + if (name.indexOf(token.string) == 0 /* > -1 */) + result.push(name); + } + + return { + list: result, + from: CodeMirror.Pos(cur.line, token.start), + to: CodeMirror.Pos(cur.line, token.end) + }; + } + + CodeMirror.registerHelper("hint", "css", getHints); +})(); diff --git a/profile-builder/assets/lib/codemirror/addon/hint/html-hint.js b/profile-builder/assets/lib/codemirror/addon/hint/html-hint.js index cf25685..2bae7f9 100644 --- a/profile-builder/assets/lib/codemirror/addon/hint/html-hint.js +++ b/profile-builder/assets/lib/codemirror/addon/hint/html-hint.js @@ -1,337 +1,337 @@ -(function () { - var langs = "ab aa af ak sq am ar an hy as av ae ay az bm ba eu be bn bh bi bs br bg my ca ch ce ny zh cv kw co cr hr cs da dv nl dz en eo et ee fo fj fi fr ff gl ka de el gn gu ht ha he hz hi ho hu ia id ie ga ig ik io is it iu ja jv kl kn kr ks kk km ki rw ky kv kg ko ku kj la lb lg li ln lo lt lu lv gv mk mg ms ml mt mi mr mh mn na nv nb nd ne ng nn no ii nr oc oj cu om or os pa pi fa pl ps pt qu rm rn ro ru sa sc sd se sm sg sr gd sn si sk sl so st es su sw ss sv ta te tg th ti bo tk tl tn to tr ts tt tw ty ug uk ur uz ve vi vo wa cy wo fy xh yi yo za zu".split(" "); - var targets = ["_blank", "_self", "_top", "_parent"]; - var charsets = ["ascii", "utf-8", "utf-16", "latin1", "latin1"]; - var methods = ["get", "post", "put", "delete"]; - var encs = ["application/x-www-form-urlencoded", "multipart/form-data", "text/plain"]; - var media = ["all", "screen", "print", "embossed", "braille", "handheld", "print", "projection", "screen", "tty", "tv", "speech", - "3d-glasses", "resolution [>][<][=] [X]", "device-aspect-ratio: X/Y", "orientation:portrait", - "orientation:landscape", "device-height: [X]", "device-width: [X]"]; - var s = { attrs: {} }; // Simple tag, reused for a whole lot of tags - - var data = { - a: { - attrs: { - href: null, ping: null, type: null, - media: media, - target: targets, - hreflang: langs - } - }, - abbr: s, - acronym: s, - address: s, - applet: s, - area: { - attrs: { - alt: null, coords: null, href: null, target: null, ping: null, - media: media, hreflang: langs, type: null, - shape: ["default", "rect", "circle", "poly"] - } - }, - article: s, - aside: s, - audio: { - attrs: { - src: null, mediagroup: null, - crossorigin: ["anonymous", "use-credentials"], - preload: ["none", "metadata", "auto"], - autoplay: ["", "autoplay"], - loop: ["", "loop"], - controls: ["", "controls"] - } - }, - b: s, - base: { attrs: { href: null, target: targets } }, - basefont: s, - bdi: s, - bdo: s, - big: s, - blockquote: { attrs: { cite: null } }, - body: s, - br: s, - button: { - attrs: { - form: null, formaction: null, name: null, value: null, - autofocus: ["", "autofocus"], - disabled: ["", "autofocus"], - formenctype: encs, - formmethod: methods, - formnovalidate: ["", "novalidate"], - formtarget: targets, - type: ["submit", "reset", "button"] - } - }, - canvas: { attrs: { width: null, height: null } }, - caption: s, - center: s, - cite: s, - code: s, - col: { attrs: { span: null } }, - colgroup: { attrs: { span: null } }, - command: { - attrs: { - type: ["command", "checkbox", "radio"], - label: null, icon: null, radiogroup: null, command: null, title: null, - disabled: ["", "disabled"], - checked: ["", "checked"] - } - }, - data: { attrs: { value: null } }, - datagrid: { attrs: { disabled: ["", "disabled"], multiple: ["", "multiple"] } }, - datalist: { attrs: { data: null } }, - dd: s, - del: { attrs: { cite: null, datetime: null } }, - details: { attrs: { open: ["", "open"] } }, - dfn: s, - dir: s, - div: s, - dl: s, - dt: s, - em: s, - embed: { attrs: { src: null, type: null, width: null, height: null } }, - eventsource: { attrs: { src: null } }, - fieldset: { attrs: { disabled: ["", "disabled"], form: null, name: null } }, - figcaption: s, - figure: s, - font: s, - footer: s, - form: { - attrs: { - action: null, name: null, - "accept-charset": charsets, - autocomplete: ["on", "off"], - enctype: encs, - method: methods, - novalidate: ["", "novalidate"], - target: targets - } - }, - frame: s, - frameset: s, - h1: s, h2: s, h3: s, h4: s, h5: s, h6: s, - head: { - attrs: {}, - children: ["title", "base", "link", "style", "meta", "script", "noscript", "command"] - }, - header: s, - hgroup: s, - hr: s, - html: { - attrs: { manifest: null }, - children: ["head", "body"] - }, - i: s, - iframe: { - attrs: { - src: null, srcdoc: null, name: null, width: null, height: null, - sandbox: ["allow-top-navigation", "allow-same-origin", "allow-forms", "allow-scripts"], - seamless: ["", "seamless"] - } - }, - img: { - attrs: { - alt: null, src: null, ismap: null, usemap: null, width: null, height: null, - crossorigin: ["anonymous", "use-credentials"] - } - }, - input: { - attrs: { - alt: null, dirname: null, form: null, formaction: null, - height: null, list: null, max: null, maxlength: null, min: null, - name: null, pattern: null, placeholder: null, size: null, src: null, - step: null, value: null, width: null, - accept: ["audio/*", "video/*", "image/*"], - autocomplete: ["on", "off"], - autofocus: ["", "autofocus"], - checked: ["", "checked"], - disabled: ["", "disabled"], - formenctype: encs, - formmethod: methods, - formnovalidate: ["", "novalidate"], - formtarget: targets, - multiple: ["", "multiple"], - readonly: ["", "readonly"], - required: ["", "required"], - type: ["hidden", "text", "search", "tel", "url", "email", "password", "datetime", "date", "month", - "week", "time", "datetime-local", "number", "range", "color", "checkbox", "radio", - "file", "submit", "image", "reset", "button"] - } - }, - ins: { attrs: { cite: null, datetime: null } }, - kbd: s, - keygen: { - attrs: { - challenge: null, form: null, name: null, - autofocus: ["", "autofocus"], - disabled: ["", "disabled"], - keytype: ["RSA"] - } - }, - label: { attrs: { "for": null, form: null } }, - legend: s, - li: { attrs: { value: null } }, - link: { - attrs: { - href: null, type: null, - hreflang: langs, - media: media, - sizes: ["all", "16x16", "16x16 32x32", "16x16 32x32 64x64"] - } - }, - map: { attrs: { name: null } }, - mark: s, - menu: { attrs: { label: null, type: ["list", "context", "toolbar"] } }, - meta: { - attrs: { - content: null, - charset: charsets, - name: ["viewport", "application-name", "author", "description", "generator", "keywords"], - "http-equiv": ["content-language", "content-type", "default-style", "refresh"] - } - }, - meter: { attrs: { value: null, min: null, low: null, high: null, max: null, optimum: null } }, - nav: s, - noframes: s, - noscript: s, - object: { - attrs: { - data: null, type: null, name: null, usemap: null, form: null, width: null, height: null, - typemustmatch: ["", "typemustmatch"] - } - }, - ol: { attrs: { reversed: ["", "reversed"], start: null, type: ["1", "a", "A", "i", "I"] } }, - optgroup: { attrs: { disabled: ["", "disabled"], label: null } }, - option: { attrs: { disabled: ["", "disabled"], label: null, selected: ["", "selected"], value: null } }, - output: { attrs: { "for": null, form: null, name: null } }, - p: s, - param: { attrs: { name: null, value: null } }, - pre: s, - progress: { attrs: { value: null, max: null } }, - q: { attrs: { cite: null } }, - rp: s, - rt: s, - ruby: s, - s: s, - samp: s, - script: { - attrs: { - type: ["text/javascript"], - src: null, - async: ["", "async"], - defer: ["", "defer"], - charset: charsets - } - }, - section: s, - select: { - attrs: { - form: null, name: null, size: null, - autofocus: ["", "autofocus"], - disabled: ["", "disabled"], - multiple: ["", "multiple"] - } - }, - small: s, - source: { attrs: { src: null, type: null, media: null } }, - span: s, - strike: s, - strong: s, - style: { - attrs: { - type: ["text/css"], - media: media, - scoped: null - } - }, - sub: s, - summary: s, - sup: s, - table: s, - tbody: s, - td: { attrs: { colspan: null, rowspan: null, headers: null } }, - textarea: { - attrs: { - dirname: null, form: null, maxlength: null, name: null, placeholder: null, - rows: null, cols: null, - autofocus: ["", "autofocus"], - disabled: ["", "disabled"], - readonly: ["", "readonly"], - required: ["", "required"], - wrap: ["soft", "hard"] - } - }, - tfoot: s, - th: { attrs: { colspan: null, rowspan: null, headers: null, scope: ["row", "col", "rowgroup", "colgroup"] } }, - thead: s, - time: { attrs: { datetime: null } }, - title: s, - tr: s, - track: { - attrs: { - src: null, label: null, "default": null, - kind: ["subtitles", "captions", "descriptions", "chapters", "metadata"], - srclang: langs - } - }, - tt: s, - u: s, - ul: s, - "var": s, - video: { - attrs: { - src: null, poster: null, width: null, height: null, - crossorigin: ["anonymous", "use-credentials"], - preload: ["auto", "metadata", "none"], - autoplay: ["", "autoplay"], - mediagroup: ["movie"], - muted: ["", "muted"], - controls: ["", "controls"] - } - }, - wbr: s - }; - - var globalAttrs = { - accesskey: ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"], - "class": null, - contenteditable: ["true", "false"], - contextmenu: null, - dir: ["ltr", "rtl", "auto"], - draggable: ["true", "false", "auto"], - dropzone: ["copy", "move", "link", "string:", "file:"], - hidden: ["hidden"], - id: null, - inert: ["inert"], - itemid: null, - itemprop: null, - itemref: null, - itemscope: ["itemscope"], - itemtype: null, - lang: ["en", "es"], - spellcheck: ["true", "false"], - style: null, - tabindex: ["1", "2", "3", "4", "5", "6", "7", "8", "9"], - title: null, - translate: ["yes", "no"], - onclick: null, - rel: ["stylesheet", "alternate", "author", "bookmark", "help", "license", "next", "nofollow", "noreferrer", "prefetch", "prev", "search", "tag"] - }; - function populate(obj) { - for (var attr in globalAttrs) if (globalAttrs.hasOwnProperty(attr)) - obj.attrs[attr] = globalAttrs[attr]; - } - - populate(s); - for (var tag in data) if (data.hasOwnProperty(tag) && data[tag] != s) - populate(data[tag]); - - CodeMirror.htmlSchema = data; - function htmlHint(cm, options) { - var local = {schemaInfo: data}; - if (options) for (var opt in options) local[opt] = options[opt]; - return CodeMirror.hint.xml(cm, local); - } - CodeMirror.htmlHint = htmlHint; // deprecated - CodeMirror.registerHelper("hint", "html", htmlHint); -})(); +(function () { + var langs = "ab aa af ak sq am ar an hy as av ae ay az bm ba eu be bn bh bi bs br bg my ca ch ce ny zh cv kw co cr hr cs da dv nl dz en eo et ee fo fj fi fr ff gl ka de el gn gu ht ha he hz hi ho hu ia id ie ga ig ik io is it iu ja jv kl kn kr ks kk km ki rw ky kv kg ko ku kj la lb lg li ln lo lt lu lv gv mk mg ms ml mt mi mr mh mn na nv nb nd ne ng nn no ii nr oc oj cu om or os pa pi fa pl ps pt qu rm rn ro ru sa sc sd se sm sg sr gd sn si sk sl so st es su sw ss sv ta te tg th ti bo tk tl tn to tr ts tt tw ty ug uk ur uz ve vi vo wa cy wo fy xh yi yo za zu".split(" "); + var targets = ["_blank", "_self", "_top", "_parent"]; + var charsets = ["ascii", "utf-8", "utf-16", "latin1", "latin1"]; + var methods = ["get", "post", "put", "delete"]; + var encs = ["application/x-www-form-urlencoded", "multipart/form-data", "text/plain"]; + var media = ["all", "screen", "print", "embossed", "braille", "handheld", "print", "projection", "screen", "tty", "tv", "speech", + "3d-glasses", "resolution [>][<][=] [X]", "device-aspect-ratio: X/Y", "orientation:portrait", + "orientation:landscape", "device-height: [X]", "device-width: [X]"]; + var s = { attrs: {} }; // Simple tag, reused for a whole lot of tags + + var data = { + a: { + attrs: { + href: null, ping: null, type: null, + media: media, + target: targets, + hreflang: langs + } + }, + abbr: s, + acronym: s, + address: s, + applet: s, + area: { + attrs: { + alt: null, coords: null, href: null, target: null, ping: null, + media: media, hreflang: langs, type: null, + shape: ["default", "rect", "circle", "poly"] + } + }, + article: s, + aside: s, + audio: { + attrs: { + src: null, mediagroup: null, + crossorigin: ["anonymous", "use-credentials"], + preload: ["none", "metadata", "auto"], + autoplay: ["", "autoplay"], + loop: ["", "loop"], + controls: ["", "controls"] + } + }, + b: s, + base: { attrs: { href: null, target: targets } }, + basefont: s, + bdi: s, + bdo: s, + big: s, + blockquote: { attrs: { cite: null } }, + body: s, + br: s, + button: { + attrs: { + form: null, formaction: null, name: null, value: null, + autofocus: ["", "autofocus"], + disabled: ["", "autofocus"], + formenctype: encs, + formmethod: methods, + formnovalidate: ["", "novalidate"], + formtarget: targets, + type: ["submit", "reset", "button"] + } + }, + canvas: { attrs: { width: null, height: null } }, + caption: s, + center: s, + cite: s, + code: s, + col: { attrs: { span: null } }, + colgroup: { attrs: { span: null } }, + command: { + attrs: { + type: ["command", "checkbox", "radio"], + label: null, icon: null, radiogroup: null, command: null, title: null, + disabled: ["", "disabled"], + checked: ["", "checked"] + } + }, + data: { attrs: { value: null } }, + datagrid: { attrs: { disabled: ["", "disabled"], multiple: ["", "multiple"] } }, + datalist: { attrs: { data: null } }, + dd: s, + del: { attrs: { cite: null, datetime: null } }, + details: { attrs: { open: ["", "open"] } }, + dfn: s, + dir: s, + div: s, + dl: s, + dt: s, + em: s, + embed: { attrs: { src: null, type: null, width: null, height: null } }, + eventsource: { attrs: { src: null } }, + fieldset: { attrs: { disabled: ["", "disabled"], form: null, name: null } }, + figcaption: s, + figure: s, + font: s, + footer: s, + form: { + attrs: { + action: null, name: null, + "accept-charset": charsets, + autocomplete: ["on", "off"], + enctype: encs, + method: methods, + novalidate: ["", "novalidate"], + target: targets + } + }, + frame: s, + frameset: s, + h1: s, h2: s, h3: s, h4: s, h5: s, h6: s, + head: { + attrs: {}, + children: ["title", "base", "link", "style", "meta", "script", "noscript", "command"] + }, + header: s, + hgroup: s, + hr: s, + html: { + attrs: { manifest: null }, + children: ["head", "body"] + }, + i: s, + iframe: { + attrs: { + src: null, srcdoc: null, name: null, width: null, height: null, + sandbox: ["allow-top-navigation", "allow-same-origin", "allow-forms", "allow-scripts"], + seamless: ["", "seamless"] + } + }, + img: { + attrs: { + alt: null, src: null, ismap: null, usemap: null, width: null, height: null, + crossorigin: ["anonymous", "use-credentials"] + } + }, + input: { + attrs: { + alt: null, dirname: null, form: null, formaction: null, + height: null, list: null, max: null, maxlength: null, min: null, + name: null, pattern: null, placeholder: null, size: null, src: null, + step: null, value: null, width: null, + accept: ["audio/*", "video/*", "image/*"], + autocomplete: ["on", "off"], + autofocus: ["", "autofocus"], + checked: ["", "checked"], + disabled: ["", "disabled"], + formenctype: encs, + formmethod: methods, + formnovalidate: ["", "novalidate"], + formtarget: targets, + multiple: ["", "multiple"], + readonly: ["", "readonly"], + required: ["", "required"], + type: ["hidden", "text", "search", "tel", "url", "email", "password", "datetime", "date", "month", + "week", "time", "datetime-local", "number", "range", "color", "checkbox", "radio", + "file", "submit", "image", "reset", "button"] + } + }, + ins: { attrs: { cite: null, datetime: null } }, + kbd: s, + keygen: { + attrs: { + challenge: null, form: null, name: null, + autofocus: ["", "autofocus"], + disabled: ["", "disabled"], + keytype: ["RSA"] + } + }, + label: { attrs: { "for": null, form: null } }, + legend: s, + li: { attrs: { value: null } }, + link: { + attrs: { + href: null, type: null, + hreflang: langs, + media: media, + sizes: ["all", "16x16", "16x16 32x32", "16x16 32x32 64x64"] + } + }, + map: { attrs: { name: null } }, + mark: s, + menu: { attrs: { label: null, type: ["list", "context", "toolbar"] } }, + meta: { + attrs: { + content: null, + charset: charsets, + name: ["viewport", "application-name", "author", "description", "generator", "keywords"], + "http-equiv": ["content-language", "content-type", "default-style", "refresh"] + } + }, + meter: { attrs: { value: null, min: null, low: null, high: null, max: null, optimum: null } }, + nav: s, + noframes: s, + noscript: s, + object: { + attrs: { + data: null, type: null, name: null, usemap: null, form: null, width: null, height: null, + typemustmatch: ["", "typemustmatch"] + } + }, + ol: { attrs: { reversed: ["", "reversed"], start: null, type: ["1", "a", "A", "i", "I"] } }, + optgroup: { attrs: { disabled: ["", "disabled"], label: null } }, + option: { attrs: { disabled: ["", "disabled"], label: null, selected: ["", "selected"], value: null } }, + output: { attrs: { "for": null, form: null, name: null } }, + p: s, + param: { attrs: { name: null, value: null } }, + pre: s, + progress: { attrs: { value: null, max: null } }, + q: { attrs: { cite: null } }, + rp: s, + rt: s, + ruby: s, + s: s, + samp: s, + script: { + attrs: { + type: ["text/javascript"], + src: null, + async: ["", "async"], + defer: ["", "defer"], + charset: charsets + } + }, + section: s, + select: { + attrs: { + form: null, name: null, size: null, + autofocus: ["", "autofocus"], + disabled: ["", "disabled"], + multiple: ["", "multiple"] + } + }, + small: s, + source: { attrs: { src: null, type: null, media: null } }, + span: s, + strike: s, + strong: s, + style: { + attrs: { + type: ["text/css"], + media: media, + scoped: null + } + }, + sub: s, + summary: s, + sup: s, + table: s, + tbody: s, + td: { attrs: { colspan: null, rowspan: null, headers: null } }, + textarea: { + attrs: { + dirname: null, form: null, maxlength: null, name: null, placeholder: null, + rows: null, cols: null, + autofocus: ["", "autofocus"], + disabled: ["", "disabled"], + readonly: ["", "readonly"], + required: ["", "required"], + wrap: ["soft", "hard"] + } + }, + tfoot: s, + th: { attrs: { colspan: null, rowspan: null, headers: null, scope: ["row", "col", "rowgroup", "colgroup"] } }, + thead: s, + time: { attrs: { datetime: null } }, + title: s, + tr: s, + track: { + attrs: { + src: null, label: null, "default": null, + kind: ["subtitles", "captions", "descriptions", "chapters", "metadata"], + srclang: langs + } + }, + tt: s, + u: s, + ul: s, + "var": s, + video: { + attrs: { + src: null, poster: null, width: null, height: null, + crossorigin: ["anonymous", "use-credentials"], + preload: ["auto", "metadata", "none"], + autoplay: ["", "autoplay"], + mediagroup: ["movie"], + muted: ["", "muted"], + controls: ["", "controls"] + } + }, + wbr: s + }; + + var globalAttrs = { + accesskey: ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"], + "class": null, + contenteditable: ["true", "false"], + contextmenu: null, + dir: ["ltr", "rtl", "auto"], + draggable: ["true", "false", "auto"], + dropzone: ["copy", "move", "link", "string:", "file:"], + hidden: ["hidden"], + id: null, + inert: ["inert"], + itemid: null, + itemprop: null, + itemref: null, + itemscope: ["itemscope"], + itemtype: null, + lang: ["en", "es"], + spellcheck: ["true", "false"], + style: null, + tabindex: ["1", "2", "3", "4", "5", "6", "7", "8", "9"], + title: null, + translate: ["yes", "no"], + onclick: null, + rel: ["stylesheet", "alternate", "author", "bookmark", "help", "license", "next", "nofollow", "noreferrer", "prefetch", "prev", "search", "tag"] + }; + function populate(obj) { + for (var attr in globalAttrs) if (globalAttrs.hasOwnProperty(attr)) + obj.attrs[attr] = globalAttrs[attr]; + } + + populate(s); + for (var tag in data) if (data.hasOwnProperty(tag) && data[tag] != s) + populate(data[tag]); + + CodeMirror.htmlSchema = data; + function htmlHint(cm, options) { + var local = {schemaInfo: data}; + if (options) for (var opt in options) local[opt] = options[opt]; + return CodeMirror.hint.xml(cm, local); + } + CodeMirror.htmlHint = htmlHint; // deprecated + CodeMirror.registerHelper("hint", "html", htmlHint); +})(); diff --git a/profile-builder/assets/lib/codemirror/addon/hint/javascript-hint.js b/profile-builder/assets/lib/codemirror/addon/hint/javascript-hint.js index 042fe13..6b15266 100644 --- a/profile-builder/assets/lib/codemirror/addon/hint/javascript-hint.js +++ b/profile-builder/assets/lib/codemirror/addon/hint/javascript-hint.js @@ -1,146 +1,146 @@ -(function () { - var Pos = CodeMirror.Pos; - - function forEach(arr, f) { - for (var i = 0, e = arr.length; i < e; ++i) f(arr[i]); - } - - function arrayContains(arr, item) { - if (!Array.prototype.indexOf) { - var i = arr.length; - while (i--) { - if (arr[i] === item) { - return true; - } - } - return false; - } - return arr.indexOf(item) != -1; - } - - function scriptHint(editor, keywords, getToken, options) { - // Find the token at the cursor - var cur = editor.getCursor(), token = getToken(editor, cur), tprop = token; - token.state = CodeMirror.innerMode(editor.getMode(), token.state).state; - - // If it's not a 'word-style' token, ignore the token. - if (!/^[\w$_]*$/.test(token.string)) { - token = tprop = {start: cur.ch, end: cur.ch, string: "", state: token.state, - type: token.string == "." ? "property" : null}; - } - // If it is a property, find out what it is a property of. - while (tprop.type == "property") { - tprop = getToken(editor, Pos(cur.line, tprop.start)); - if (tprop.string != ".") return; - tprop = getToken(editor, Pos(cur.line, tprop.start)); - if (tprop.string == ')') { - var level = 1; - do { - tprop = getToken(editor, Pos(cur.line, tprop.start)); - switch (tprop.string) { - case ')': level++; break; - case '(': level--; break; - default: break; - } - } while (level > 0); - tprop = getToken(editor, Pos(cur.line, tprop.start)); - if (tprop.type.indexOf("variable") === 0) - tprop.type = "function"; - else return; // no clue - } - if (!context) var context = []; - context.push(tprop); - } - return {list: getCompletions(token, context, keywords, options), - from: Pos(cur.line, token.start), - to: Pos(cur.line, token.end)}; - } - - function javascriptHint(editor, options) { - return scriptHint(editor, javascriptKeywords, - function (e, cur) {return e.getTokenAt(cur);}, - options); - }; - CodeMirror.javascriptHint = javascriptHint; // deprecated - CodeMirror.registerHelper("hint", "javascript", javascriptHint); - - function getCoffeeScriptToken(editor, cur) { - // This getToken, it is for coffeescript, imitates the behavior of - // getTokenAt method in javascript.js, that is, returning "property" - // type and treat "." as indepenent token. - var token = editor.getTokenAt(cur); - if (cur.ch == token.start + 1 && token.string.charAt(0) == '.') { - token.end = token.start; - token.string = '.'; - token.type = "property"; - } - else if (/^\.[\w$_]*$/.test(token.string)) { - token.type = "property"; - token.start++; - token.string = token.string.replace(/\./, ''); - } - return token; - } - - function coffeescriptHint(editor, options) { - return scriptHint(editor, coffeescriptKeywords, getCoffeeScriptToken, options); - } - CodeMirror.coffeescriptHint = coffeescriptHint; // deprecated - CodeMirror.registerHelper("hint", "coffeescript", coffeescriptHint); - - var stringProps = ("charAt charCodeAt indexOf lastIndexOf substring substr slice trim trimLeft trimRight " + - "toUpperCase toLowerCase split concat match replace search").split(" "); - var arrayProps = ("length concat join splice push pop shift unshift slice reverse sort indexOf " + - "lastIndexOf every some filter forEach map reduce reduceRight ").split(" "); - var funcProps = "prototype apply call bind".split(" "); - var javascriptKeywords = ("break case catch continue debugger default delete do else false finally for function " + - "if in instanceof new null return switch throw true try typeof var void while with").split(" "); - var coffeescriptKeywords = ("and break catch class continue delete do else extends false finally for " + - "if in instanceof isnt new no not null of off on or return switch then throw true try typeof until void while with yes").split(" "); - - function getCompletions(token, context, keywords, options) { - var found = [], start = token.string; - function maybeAdd(str) { - if (str.indexOf(start) == 0 && !arrayContains(found, str)) found.push(str); - } - function gatherCompletions(obj) { - if (typeof obj == "string") forEach(stringProps, maybeAdd); - else if (obj instanceof Array) forEach(arrayProps, maybeAdd); - else if (obj instanceof Function) forEach(funcProps, maybeAdd); - for (var name in obj) maybeAdd(name); - } - - if (context) { - // If this is a property, see if it belongs to some object we can - // find in the current environment. - var obj = context.pop(), base; - if (obj.type.indexOf("variable") === 0) { - if (options && options.additionalContext) - base = options.additionalContext[obj.string]; - base = base || window[obj.string]; - } else if (obj.type == "string") { - base = ""; - } else if (obj.type == "atom") { - base = 1; - } else if (obj.type == "function") { - if (window.jQuery != null && (obj.string == '$' || obj.string == 'jQuery') && - (typeof window.jQuery == 'function')) - base = window.jQuery(); - else if (window._ != null && (obj.string == '_') && (typeof window._ == 'function')) - base = window._(); - } - while (base != null && context.length) - base = base[context.pop().string]; - if (base != null) gatherCompletions(base); - } - else { - // If not, just look in the window object and any local scope - // (reading into JS mode internals to get at the local and global variables) - for (var v = token.state.localVars; v; v = v.next) maybeAdd(v.name); - for (var v = token.state.globalVars; v; v = v.next) maybeAdd(v.name); - gatherCompletions(window); - forEach(keywords, maybeAdd); - } - return found; - } -})(); +(function () { + var Pos = CodeMirror.Pos; + + function forEach(arr, f) { + for (var i = 0, e = arr.length; i < e; ++i) f(arr[i]); + } + + function arrayContains(arr, item) { + if (!Array.prototype.indexOf) { + var i = arr.length; + while (i--) { + if (arr[i] === item) { + return true; + } + } + return false; + } + return arr.indexOf(item) != -1; + } + + function scriptHint(editor, keywords, getToken, options) { + // Find the token at the cursor + var cur = editor.getCursor(), token = getToken(editor, cur), tprop = token; + token.state = CodeMirror.innerMode(editor.getMode(), token.state).state; + + // If it's not a 'word-style' token, ignore the token. + if (!/^[\w$_]*$/.test(token.string)) { + token = tprop = {start: cur.ch, end: cur.ch, string: "", state: token.state, + type: token.string == "." ? "property" : null}; + } + // If it is a property, find out what it is a property of. + while (tprop.type == "property") { + tprop = getToken(editor, Pos(cur.line, tprop.start)); + if (tprop.string != ".") return; + tprop = getToken(editor, Pos(cur.line, tprop.start)); + if (tprop.string == ')') { + var level = 1; + do { + tprop = getToken(editor, Pos(cur.line, tprop.start)); + switch (tprop.string) { + case ')': level++; break; + case '(': level--; break; + default: break; + } + } while (level > 0); + tprop = getToken(editor, Pos(cur.line, tprop.start)); + if (tprop.type.indexOf("variable") === 0) + tprop.type = "function"; + else return; // no clue + } + if (!context) var context = []; + context.push(tprop); + } + return {list: getCompletions(token, context, keywords, options), + from: Pos(cur.line, token.start), + to: Pos(cur.line, token.end)}; + } + + function javascriptHint(editor, options) { + return scriptHint(editor, javascriptKeywords, + function (e, cur) {return e.getTokenAt(cur);}, + options); + }; + CodeMirror.javascriptHint = javascriptHint; // deprecated + CodeMirror.registerHelper("hint", "javascript", javascriptHint); + + function getCoffeeScriptToken(editor, cur) { + // This getToken, it is for coffeescript, imitates the behavior of + // getTokenAt method in javascript.js, that is, returning "property" + // type and treat "." as indepenent token. + var token = editor.getTokenAt(cur); + if (cur.ch == token.start + 1 && token.string.charAt(0) == '.') { + token.end = token.start; + token.string = '.'; + token.type = "property"; + } + else if (/^\.[\w$_]*$/.test(token.string)) { + token.type = "property"; + token.start++; + token.string = token.string.replace(/\./, ''); + } + return token; + } + + function coffeescriptHint(editor, options) { + return scriptHint(editor, coffeescriptKeywords, getCoffeeScriptToken, options); + } + CodeMirror.coffeescriptHint = coffeescriptHint; // deprecated + CodeMirror.registerHelper("hint", "coffeescript", coffeescriptHint); + + var stringProps = ("charAt charCodeAt indexOf lastIndexOf substring substr slice trim trimLeft trimRight " + + "toUpperCase toLowerCase split concat match replace search").split(" "); + var arrayProps = ("length concat join splice push pop shift unshift slice reverse sort indexOf " + + "lastIndexOf every some filter forEach map reduce reduceRight ").split(" "); + var funcProps = "prototype apply call bind".split(" "); + var javascriptKeywords = ("break case catch continue debugger default delete do else false finally for function " + + "if in instanceof new null return switch throw true try typeof var void while with").split(" "); + var coffeescriptKeywords = ("and break catch class continue delete do else extends false finally for " + + "if in instanceof isnt new no not null of off on or return switch then throw true try typeof until void while with yes").split(" "); + + function getCompletions(token, context, keywords, options) { + var found = [], start = token.string; + function maybeAdd(str) { + if (str.indexOf(start) == 0 && !arrayContains(found, str)) found.push(str); + } + function gatherCompletions(obj) { + if (typeof obj == "string") forEach(stringProps, maybeAdd); + else if (obj instanceof Array) forEach(arrayProps, maybeAdd); + else if (obj instanceof Function) forEach(funcProps, maybeAdd); + for (var name in obj) maybeAdd(name); + } + + if (context) { + // If this is a property, see if it belongs to some object we can + // find in the current environment. + var obj = context.pop(), base; + if (obj.type.indexOf("variable") === 0) { + if (options && options.additionalContext) + base = options.additionalContext[obj.string]; + base = base || window[obj.string]; + } else if (obj.type == "string") { + base = ""; + } else if (obj.type == "atom") { + base = 1; + } else if (obj.type == "function") { + if (window.jQuery != null && (obj.string == '$' || obj.string == 'jQuery') && + (typeof window.jQuery == 'function')) + base = window.jQuery(); + else if (window._ != null && (obj.string == '_') && (typeof window._ == 'function')) + base = window._(); + } + while (base != null && context.length) + base = base[context.pop().string]; + if (base != null) gatherCompletions(base); + } + else { + // If not, just look in the window object and any local scope + // (reading into JS mode internals to get at the local and global variables) + for (var v = token.state.localVars; v; v = v.next) maybeAdd(v.name); + for (var v = token.state.globalVars; v; v = v.next) maybeAdd(v.name); + gatherCompletions(window); + forEach(keywords, maybeAdd); + } + return found; + } +})(); diff --git a/profile-builder/assets/lib/codemirror/addon/hint/pig-hint.js b/profile-builder/assets/lib/codemirror/addon/hint/pig-hint.js index 155973f..9dcf21b 100644 --- a/profile-builder/assets/lib/codemirror/addon/hint/pig-hint.js +++ b/profile-builder/assets/lib/codemirror/addon/hint/pig-hint.js @@ -1,119 +1,119 @@ -(function () { - function forEach(arr, f) { - for (var i = 0, e = arr.length; i < e; ++i) f(arr[i]); - } - - function arrayContains(arr, item) { - if (!Array.prototype.indexOf) { - var i = arr.length; - while (i--) { - if (arr[i] === item) { - return true; - } - } - return false; - } - return arr.indexOf(item) != -1; - } - - function scriptHint(editor, _keywords, getToken) { - // Find the token at the cursor - var cur = editor.getCursor(), token = getToken(editor, cur), tprop = token; - // If it's not a 'word-style' token, ignore the token. - - if (!/^[\w$_]*$/.test(token.string)) { - token = tprop = {start: cur.ch, end: cur.ch, string: "", state: token.state, - className: token.string == ":" ? "pig-type" : null}; - } - - if (!context) var context = []; - context.push(tprop); - - var completionList = getCompletions(token, context); - completionList = completionList.sort(); - //prevent autocomplete for last word, instead show dropdown with one word - if(completionList.length == 1) { - completionList.push(" "); - } - - return {list: completionList, - from: CodeMirror.Pos(cur.line, token.start), - to: CodeMirror.Pos(cur.line, token.end)}; - } - - function pigHint(editor) { - return scriptHint(editor, pigKeywordsU, function (e, cur) {return e.getTokenAt(cur);}); - } - CodeMirror.pigHint = pigHint; // deprecated - CodeMirror.registerHelper("hint", "pig", hinter); - - var pigKeywords = "VOID IMPORT RETURNS DEFINE LOAD FILTER FOREACH ORDER CUBE DISTINCT COGROUP " - + "JOIN CROSS UNION SPLIT INTO IF OTHERWISE ALL AS BY USING INNER OUTER ONSCHEMA PARALLEL " - + "PARTITION GROUP AND OR NOT GENERATE FLATTEN ASC DESC IS STREAM THROUGH STORE MAPREDUCE " - + "SHIP CACHE INPUT OUTPUT STDERROR STDIN STDOUT LIMIT SAMPLE LEFT RIGHT FULL EQ GT LT GTE LTE " - + "NEQ MATCHES TRUE FALSE"; - var pigKeywordsU = pigKeywords.split(" "); - var pigKeywordsL = pigKeywords.toLowerCase().split(" "); - - var pigTypes = "BOOLEAN INT LONG FLOAT DOUBLE CHARARRAY BYTEARRAY BAG TUPLE MAP"; - var pigTypesU = pigTypes.split(" "); - var pigTypesL = pigTypes.toLowerCase().split(" "); - - var pigBuiltins = "ABS ACOS ARITY ASIN ATAN AVG BAGSIZE BINSTORAGE BLOOM BUILDBLOOM CBRT CEIL " - + "CONCAT COR COS COSH COUNT COUNT_STAR COV CONSTANTSIZE CUBEDIMENSIONS DIFF DISTINCT DOUBLEABS " - + "DOUBLEAVG DOUBLEBASE DOUBLEMAX DOUBLEMIN DOUBLEROUND DOUBLESUM EXP FLOOR FLOATABS FLOATAVG " - + "FLOATMAX FLOATMIN FLOATROUND FLOATSUM GENERICINVOKER INDEXOF INTABS INTAVG INTMAX INTMIN " - + "INTSUM INVOKEFORDOUBLE INVOKEFORFLOAT INVOKEFORINT INVOKEFORLONG INVOKEFORSTRING INVOKER " - + "ISEMPTY JSONLOADER JSONMETADATA JSONSTORAGE LAST_INDEX_OF LCFIRST LOG LOG10 LOWER LONGABS " - + "LONGAVG LONGMAX LONGMIN LONGSUM MAX MIN MAPSIZE MONITOREDUDF NONDETERMINISTIC OUTPUTSCHEMA " - + "PIGSTORAGE PIGSTREAMING RANDOM REGEX_EXTRACT REGEX_EXTRACT_ALL REPLACE ROUND SIN SINH SIZE " - + "SQRT STRSPLIT SUBSTRING SUM STRINGCONCAT STRINGMAX STRINGMIN STRINGSIZE TAN TANH TOBAG " - + "TOKENIZE TOMAP TOP TOTUPLE TRIM TEXTLOADER TUPLESIZE UCFIRST UPPER UTF8STORAGECONVERTER"; - var pigBuiltinsU = pigBuiltins.split(" ").join("() ").split(" "); - var pigBuiltinsL = pigBuiltins.toLowerCase().split(" ").join("() ").split(" "); - var pigBuiltinsC = ("BagSize BinStorage Bloom BuildBloom ConstantSize CubeDimensions DoubleAbs " - + "DoubleAvg DoubleBase DoubleMax DoubleMin DoubleRound DoubleSum FloatAbs FloatAvg FloatMax " - + "FloatMin FloatRound FloatSum GenericInvoker IntAbs IntAvg IntMax IntMin IntSum " - + "InvokeForDouble InvokeForFloat InvokeForInt InvokeForLong InvokeForString Invoker " - + "IsEmpty JsonLoader JsonMetadata JsonStorage LongAbs LongAvg LongMax LongMin LongSum MapSize " - + "MonitoredUDF Nondeterministic OutputSchema PigStorage PigStreaming StringConcat StringMax " - + "StringMin StringSize TextLoader TupleSize Utf8StorageConverter").split(" ").join("() ").split(" "); - - function getCompletions(token, context) { - var found = [], start = token.string; - function maybeAdd(str) { - if (str.indexOf(start) == 0 && !arrayContains(found, str)) found.push(str); - } - - function gatherCompletions(obj) { - if(obj == ":") { - forEach(pigTypesL, maybeAdd); - } - else { - forEach(pigBuiltinsU, maybeAdd); - forEach(pigBuiltinsL, maybeAdd); - forEach(pigBuiltinsC, maybeAdd); - forEach(pigTypesU, maybeAdd); - forEach(pigTypesL, maybeAdd); - forEach(pigKeywordsU, maybeAdd); - forEach(pigKeywordsL, maybeAdd); - } - } - - if (context) { - // If this is a property, see if it belongs to some object we can - // find in the current environment. - var obj = context.pop(), base; - - if (obj.type == "variable") - base = obj.string; - else if(obj.type == "variable-3") - base = ":" + obj.string; - - while (base != null && context.length) - base = base[context.pop().string]; - if (base != null) gatherCompletions(base); - } - return found; - } -})(); +(function () { + function forEach(arr, f) { + for (var i = 0, e = arr.length; i < e; ++i) f(arr[i]); + } + + function arrayContains(arr, item) { + if (!Array.prototype.indexOf) { + var i = arr.length; + while (i--) { + if (arr[i] === item) { + return true; + } + } + return false; + } + return arr.indexOf(item) != -1; + } + + function scriptHint(editor, _keywords, getToken) { + // Find the token at the cursor + var cur = editor.getCursor(), token = getToken(editor, cur), tprop = token; + // If it's not a 'word-style' token, ignore the token. + + if (!/^[\w$_]*$/.test(token.string)) { + token = tprop = {start: cur.ch, end: cur.ch, string: "", state: token.state, + className: token.string == ":" ? "pig-type" : null}; + } + + if (!context) var context = []; + context.push(tprop); + + var completionList = getCompletions(token, context); + completionList = completionList.sort(); + //prevent autocomplete for last word, instead show dropdown with one word + if(completionList.length == 1) { + completionList.push(" "); + } + + return {list: completionList, + from: CodeMirror.Pos(cur.line, token.start), + to: CodeMirror.Pos(cur.line, token.end)}; + } + + function pigHint(editor) { + return scriptHint(editor, pigKeywordsU, function (e, cur) {return e.getTokenAt(cur);}); + } + CodeMirror.pigHint = pigHint; // deprecated + CodeMirror.registerHelper("hint", "pig", hinter); + + var pigKeywords = "VOID IMPORT RETURNS DEFINE LOAD FILTER FOREACH ORDER CUBE DISTINCT COGROUP " + + "JOIN CROSS UNION SPLIT INTO IF OTHERWISE ALL AS BY USING INNER OUTER ONSCHEMA PARALLEL " + + "PARTITION GROUP AND OR NOT GENERATE FLATTEN ASC DESC IS STREAM THROUGH STORE MAPREDUCE " + + "SHIP CACHE INPUT OUTPUT STDERROR STDIN STDOUT LIMIT SAMPLE LEFT RIGHT FULL EQ GT LT GTE LTE " + + "NEQ MATCHES TRUE FALSE"; + var pigKeywordsU = pigKeywords.split(" "); + var pigKeywordsL = pigKeywords.toLowerCase().split(" "); + + var pigTypes = "BOOLEAN INT LONG FLOAT DOUBLE CHARARRAY BYTEARRAY BAG TUPLE MAP"; + var pigTypesU = pigTypes.split(" "); + var pigTypesL = pigTypes.toLowerCase().split(" "); + + var pigBuiltins = "ABS ACOS ARITY ASIN ATAN AVG BAGSIZE BINSTORAGE BLOOM BUILDBLOOM CBRT CEIL " + + "CONCAT COR COS COSH COUNT COUNT_STAR COV CONSTANTSIZE CUBEDIMENSIONS DIFF DISTINCT DOUBLEABS " + + "DOUBLEAVG DOUBLEBASE DOUBLEMAX DOUBLEMIN DOUBLEROUND DOUBLESUM EXP FLOOR FLOATABS FLOATAVG " + + "FLOATMAX FLOATMIN FLOATROUND FLOATSUM GENERICINVOKER INDEXOF INTABS INTAVG INTMAX INTMIN " + + "INTSUM INVOKEFORDOUBLE INVOKEFORFLOAT INVOKEFORINT INVOKEFORLONG INVOKEFORSTRING INVOKER " + + "ISEMPTY JSONLOADER JSONMETADATA JSONSTORAGE LAST_INDEX_OF LCFIRST LOG LOG10 LOWER LONGABS " + + "LONGAVG LONGMAX LONGMIN LONGSUM MAX MIN MAPSIZE MONITOREDUDF NONDETERMINISTIC OUTPUTSCHEMA " + + "PIGSTORAGE PIGSTREAMING RANDOM REGEX_EXTRACT REGEX_EXTRACT_ALL REPLACE ROUND SIN SINH SIZE " + + "SQRT STRSPLIT SUBSTRING SUM STRINGCONCAT STRINGMAX STRINGMIN STRINGSIZE TAN TANH TOBAG " + + "TOKENIZE TOMAP TOP TOTUPLE TRIM TEXTLOADER TUPLESIZE UCFIRST UPPER UTF8STORAGECONVERTER"; + var pigBuiltinsU = pigBuiltins.split(" ").join("() ").split(" "); + var pigBuiltinsL = pigBuiltins.toLowerCase().split(" ").join("() ").split(" "); + var pigBuiltinsC = ("BagSize BinStorage Bloom BuildBloom ConstantSize CubeDimensions DoubleAbs " + + "DoubleAvg DoubleBase DoubleMax DoubleMin DoubleRound DoubleSum FloatAbs FloatAvg FloatMax " + + "FloatMin FloatRound FloatSum GenericInvoker IntAbs IntAvg IntMax IntMin IntSum " + + "InvokeForDouble InvokeForFloat InvokeForInt InvokeForLong InvokeForString Invoker " + + "IsEmpty JsonLoader JsonMetadata JsonStorage LongAbs LongAvg LongMax LongMin LongSum MapSize " + + "MonitoredUDF Nondeterministic OutputSchema PigStorage PigStreaming StringConcat StringMax " + + "StringMin StringSize TextLoader TupleSize Utf8StorageConverter").split(" ").join("() ").split(" "); + + function getCompletions(token, context) { + var found = [], start = token.string; + function maybeAdd(str) { + if (str.indexOf(start) == 0 && !arrayContains(found, str)) found.push(str); + } + + function gatherCompletions(obj) { + if(obj == ":") { + forEach(pigTypesL, maybeAdd); + } + else { + forEach(pigBuiltinsU, maybeAdd); + forEach(pigBuiltinsL, maybeAdd); + forEach(pigBuiltinsC, maybeAdd); + forEach(pigTypesU, maybeAdd); + forEach(pigTypesL, maybeAdd); + forEach(pigKeywordsU, maybeAdd); + forEach(pigKeywordsL, maybeAdd); + } + } + + if (context) { + // If this is a property, see if it belongs to some object we can + // find in the current environment. + var obj = context.pop(), base; + + if (obj.type == "variable") + base = obj.string; + else if(obj.type == "variable-3") + base = ":" + obj.string; + + while (base != null && context.length) + base = base[context.pop().string]; + if (base != null) gatherCompletions(base); + } + return found; + } +})(); diff --git a/profile-builder/assets/lib/codemirror/addon/hint/python-hint.js b/profile-builder/assets/lib/codemirror/addon/hint/python-hint.js index 98d2a58..428c77d 100644 --- a/profile-builder/assets/lib/codemirror/addon/hint/python-hint.js +++ b/profile-builder/assets/lib/codemirror/addon/hint/python-hint.js @@ -1,95 +1,95 @@ -(function () { - function forEach(arr, f) { - for (var i = 0, e = arr.length; i < e; ++i) f(arr[i]); - } - - function arrayContains(arr, item) { - if (!Array.prototype.indexOf) { - var i = arr.length; - while (i--) { - if (arr[i] === item) { - return true; - } - } - return false; - } - return arr.indexOf(item) != -1; - } - - function scriptHint(editor, _keywords, getToken) { - // Find the token at the cursor - var cur = editor.getCursor(), token = getToken(editor, cur), tprop = token; - // If it's not a 'word-style' token, ignore the token. - - if (!/^[\w$_]*$/.test(token.string)) { - token = tprop = {start: cur.ch, end: cur.ch, string: "", state: token.state, - className: token.string == ":" ? "python-type" : null}; - } - - if (!context) var context = []; - context.push(tprop); - - var completionList = getCompletions(token, context); - completionList = completionList.sort(); - //prevent autocomplete for last word, instead show dropdown with one word - if(completionList.length == 1) { - completionList.push(" "); - } - - return {list: completionList, - from: CodeMirror.Pos(cur.line, token.start), - to: CodeMirror.Pos(cur.line, token.end)}; - } - - function pythonHint(editor) { - return scriptHint(editor, pythonKeywordsU, function (e, cur) {return e.getTokenAt(cur);}); - } - CodeMirror.pythonHint = pythonHint; // deprecated - CodeMirror.registerHelper("hint", "python", pythonHint); - - var pythonKeywords = "and del from not while as elif global or with assert else if pass yield" -+ "break except import print class exec in raise continue finally is return def for lambda try"; - var pythonKeywordsL = pythonKeywords.split(" "); - var pythonKeywordsU = pythonKeywords.toUpperCase().split(" "); - - var pythonBuiltins = "abs divmod input open staticmethod all enumerate int ord str " -+ "any eval isinstance pow sum basestring execfile issubclass print super" -+ "bin file iter property tuple bool filter len range type" -+ "bytearray float list raw_input unichr callable format locals reduce unicode" -+ "chr frozenset long reload vars classmethod getattr map repr xrange" -+ "cmp globals max reversed zip compile hasattr memoryview round __import__" -+ "complex hash min set apply delattr help next setattr buffer" -+ "dict hex object slice coerce dir id oct sorted intern "; - var pythonBuiltinsL = pythonBuiltins.split(" ").join("() ").split(" "); - var pythonBuiltinsU = pythonBuiltins.toUpperCase().split(" ").join("() ").split(" "); - - function getCompletions(token, context) { - var found = [], start = token.string; - function maybeAdd(str) { - if (str.indexOf(start) == 0 && !arrayContains(found, str)) found.push(str); - } - - function gatherCompletions(_obj) { - forEach(pythonBuiltinsL, maybeAdd); - forEach(pythonBuiltinsU, maybeAdd); - forEach(pythonKeywordsL, maybeAdd); - forEach(pythonKeywordsU, maybeAdd); - } - - if (context) { - // If this is a property, see if it belongs to some object we can - // find in the current environment. - var obj = context.pop(), base; - - if (obj.type == "variable") - base = obj.string; - else if(obj.type == "variable-3") - base = ":" + obj.string; - - while (base != null && context.length) - base = base[context.pop().string]; - if (base != null) gatherCompletions(base); - } - return found; - } -})(); +(function () { + function forEach(arr, f) { + for (var i = 0, e = arr.length; i < e; ++i) f(arr[i]); + } + + function arrayContains(arr, item) { + if (!Array.prototype.indexOf) { + var i = arr.length; + while (i--) { + if (arr[i] === item) { + return true; + } + } + return false; + } + return arr.indexOf(item) != -1; + } + + function scriptHint(editor, _keywords, getToken) { + // Find the token at the cursor + var cur = editor.getCursor(), token = getToken(editor, cur), tprop = token; + // If it's not a 'word-style' token, ignore the token. + + if (!/^[\w$_]*$/.test(token.string)) { + token = tprop = {start: cur.ch, end: cur.ch, string: "", state: token.state, + className: token.string == ":" ? "python-type" : null}; + } + + if (!context) var context = []; + context.push(tprop); + + var completionList = getCompletions(token, context); + completionList = completionList.sort(); + //prevent autocomplete for last word, instead show dropdown with one word + if(completionList.length == 1) { + completionList.push(" "); + } + + return {list: completionList, + from: CodeMirror.Pos(cur.line, token.start), + to: CodeMirror.Pos(cur.line, token.end)}; + } + + function pythonHint(editor) { + return scriptHint(editor, pythonKeywordsU, function (e, cur) {return e.getTokenAt(cur);}); + } + CodeMirror.pythonHint = pythonHint; // deprecated + CodeMirror.registerHelper("hint", "python", pythonHint); + + var pythonKeywords = "and del from not while as elif global or with assert else if pass yield" ++ "break except import print class exec in raise continue finally is return def for lambda try"; + var pythonKeywordsL = pythonKeywords.split(" "); + var pythonKeywordsU = pythonKeywords.toUpperCase().split(" "); + + var pythonBuiltins = "abs divmod input open staticmethod all enumerate int ord str " ++ "any eval isinstance pow sum basestring execfile issubclass print super" ++ "bin file iter property tuple bool filter len range type" ++ "bytearray float list raw_input unichr callable format locals reduce unicode" ++ "chr frozenset long reload vars classmethod getattr map repr xrange" ++ "cmp globals max reversed zip compile hasattr memoryview round __import__" ++ "complex hash min set apply delattr help next setattr buffer" ++ "dict hex object slice coerce dir id oct sorted intern "; + var pythonBuiltinsL = pythonBuiltins.split(" ").join("() ").split(" "); + var pythonBuiltinsU = pythonBuiltins.toUpperCase().split(" ").join("() ").split(" "); + + function getCompletions(token, context) { + var found = [], start = token.string; + function maybeAdd(str) { + if (str.indexOf(start) == 0 && !arrayContains(found, str)) found.push(str); + } + + function gatherCompletions(_obj) { + forEach(pythonBuiltinsL, maybeAdd); + forEach(pythonBuiltinsU, maybeAdd); + forEach(pythonKeywordsL, maybeAdd); + forEach(pythonKeywordsU, maybeAdd); + } + + if (context) { + // If this is a property, see if it belongs to some object we can + // find in the current environment. + var obj = context.pop(), base; + + if (obj.type == "variable") + base = obj.string; + else if(obj.type == "variable-3") + base = ":" + obj.string; + + while (base != null && context.length) + base = base[context.pop().string]; + if (base != null) gatherCompletions(base); + } + return found; + } +})(); diff --git a/profile-builder/assets/lib/codemirror/addon/hint/show-hint.css b/profile-builder/assets/lib/codemirror/addon/hint/show-hint.css index 8a4ff05..7141752 100644 --- a/profile-builder/assets/lib/codemirror/addon/hint/show-hint.css +++ b/profile-builder/assets/lib/codemirror/addon/hint/show-hint.css @@ -1,38 +1,38 @@ -.CodeMirror-hints { - position: absolute; - z-index: 10; - overflow: hidden; - list-style: none; - - margin: 0; - padding: 2px; - - -webkit-box-shadow: 2px 3px 5px rgba(0,0,0,.2); - -moz-box-shadow: 2px 3px 5px rgba(0,0,0,.2); - box-shadow: 2px 3px 5px rgba(0,0,0,.2); - border-radius: 3px; - border: 1px solid silver; - - background: white; - font-size: 90%; - font-family: monospace; - - max-height: 20em; - overflow-y: auto; -} - -.CodeMirror-hint { - margin: 0; - padding: 0 4px; - border-radius: 2px; - max-width: 19em; - overflow: hidden; - white-space: pre; - color: black; - cursor: pointer; -} - -.CodeMirror-hint-active { - background: #08f; - color: white; -} +.CodeMirror-hints { + position: absolute; + z-index: 10; + overflow: hidden; + list-style: none; + + margin: 0; + padding: 2px; + + -webkit-box-shadow: 2px 3px 5px rgba(0,0,0,.2); + -moz-box-shadow: 2px 3px 5px rgba(0,0,0,.2); + box-shadow: 2px 3px 5px rgba(0,0,0,.2); + border-radius: 3px; + border: 1px solid silver; + + background: white; + font-size: 90%; + font-family: monospace; + + max-height: 20em; + overflow-y: auto; +} + +.CodeMirror-hint { + margin: 0; + padding: 0 4px; + border-radius: 2px; + max-width: 19em; + overflow: hidden; + white-space: pre; + color: black; + cursor: pointer; +} + +.CodeMirror-hint-active { + background: #08f; + color: white; +} diff --git a/profile-builder/assets/lib/codemirror/addon/hint/show-hint.js b/profile-builder/assets/lib/codemirror/addon/hint/show-hint.js index dbf4155..a9d31f3 100644 --- a/profile-builder/assets/lib/codemirror/addon/hint/show-hint.js +++ b/profile-builder/assets/lib/codemirror/addon/hint/show-hint.js @@ -1,274 +1,274 @@ -(function() { - "use strict"; - - CodeMirror.showHint = function(cm, getHints, options) { - // We want a single cursor position. - if (cm.somethingSelected()) return; - if (getHints == null) getHints = cm.getHelper(cm.getCursor(), "hint"); - if (getHints == null) return; - - if (cm.state.completionActive) cm.state.completionActive.close(); - - var completion = cm.state.completionActive = new Completion(cm, getHints, options || {}); - CodeMirror.signal(cm, "startCompletion", cm); - if (completion.options.async) - getHints(cm, function(hints) { completion.showHints(hints); }, completion.options); - else - return completion.showHints(getHints(cm, completion.options)); - }; - - function Completion(cm, getHints, options) { - this.cm = cm; - this.getHints = getHints; - this.options = options; - this.widget = this.onClose = null; - } - - Completion.prototype = { - close: function() { - if (!this.active()) return; - this.cm.state.completionActive = null; - - if (this.widget) this.widget.close(); - if (this.onClose) this.onClose(); - CodeMirror.signal(this.cm, "endCompletion", this.cm); - }, - - active: function() { - return this.cm.state.completionActive == this; - }, - - pick: function(data, i) { - var completion = data.list[i]; - if (completion.hint) completion.hint(this.cm, data, completion); - else this.cm.replaceRange(getText(completion), data.from, data.to); - this.close(); - }, - - showHints: function(data) { - if (!data || !data.list.length || !this.active()) return this.close(); - - if (this.options.completeSingle != false && data.list.length == 1) - this.pick(data, 0); - else - this.showWidget(data); - }, - - showWidget: function(data) { - this.widget = new Widget(this, data); - CodeMirror.signal(data, "shown"); - - var debounce = null, completion = this, finished; - var closeOn = this.options.closeCharacters || /[\s()\[\]{};:>,]/; - var startPos = this.cm.getCursor(), startLen = this.cm.getLine(startPos.line).length; - - function done() { - if (finished) return; - finished = true; - completion.close(); - completion.cm.off("cursorActivity", activity); - if (data) CodeMirror.signal(data, "close"); - } - - function update() { - if (finished) return; - CodeMirror.signal(data, "update"); - if (completion.options.async) - completion.getHints(completion.cm, finishUpdate, completion.options); - else - finishUpdate(completion.getHints(completion.cm, completion.options)); - } - function finishUpdate(data_) { - data = data_; - if (finished) return; - if (!data || !data.list.length) return done(); - completion.widget = new Widget(completion, data); - } - - function activity() { - clearTimeout(debounce); - var pos = completion.cm.getCursor(), line = completion.cm.getLine(pos.line); - if (pos.line != startPos.line || line.length - pos.ch != startLen - startPos.ch || - pos.ch < startPos.ch || completion.cm.somethingSelected() || - (pos.ch && closeOn.test(line.charAt(pos.ch - 1)))) { - completion.close(); - } else { - debounce = setTimeout(update, 170); - if (completion.widget) completion.widget.close(); - } - } - this.cm.on("cursorActivity", activity); - this.onClose = done; - } - }; - - function getText(completion) { - if (typeof completion == "string") return completion; - else return completion.text; - } - - function buildKeyMap(options, handle) { - var baseMap = { - Up: function() {handle.moveFocus(-1);}, - Down: function() {handle.moveFocus(1);}, - PageUp: function() {handle.moveFocus(-handle.menuSize() + 1, true);}, - PageDown: function() {handle.moveFocus(handle.menuSize() - 1, true);}, - Home: function() {handle.setFocus(0);}, - End: function() {handle.setFocus(handle.length - 1);}, - Enter: handle.pick, - Tab: handle.pick, - Esc: handle.close - }; - var ourMap = options.customKeys ? {} : baseMap; - function addBinding(key, val) { - var bound; - if (typeof val != "string") - bound = function(cm) { return val(cm, handle); }; - // This mechanism is deprecated - else if (baseMap.hasOwnProperty(val)) - bound = baseMap[val]; - else - bound = val; - ourMap[key] = bound; - } - if (options.customKeys) - for (var key in options.customKeys) if (options.customKeys.hasOwnProperty(key)) - addBinding(key, options.customKeys[key]); - if (options.extraKeys) - for (var key in options.extraKeys) if (options.extraKeys.hasOwnProperty(key)) - addBinding(key, options.extraKeys[key]); - return ourMap; - } - - function Widget(completion, data) { - this.completion = completion; - this.data = data; - var widget = this, cm = completion.cm, options = completion.options; - - var hints = this.hints = document.createElement("ul"); - hints.className = "CodeMirror-hints"; - this.selectedHint = 0; - - var completions = data.list; - for (var i = 0; i < completions.length; ++i) { - var elt = hints.appendChild(document.createElement("li")), cur = completions[i]; - var className = "CodeMirror-hint" + (i ? "" : " CodeMirror-hint-active"); - if (cur.className != null) className = cur.className + " " + className; - elt.className = className; - if (cur.render) cur.render(elt, data, cur); - else elt.appendChild(document.createTextNode(cur.displayText || getText(cur))); - elt.hintId = i; - } - - var pos = cm.cursorCoords(options.alignWithWord !== false ? data.from : null); - var left = pos.left, top = pos.bottom, below = true; - hints.style.left = left + "px"; - hints.style.top = top + "px"; - // If we're at the edge of the screen, then we want the menu to appear on the left of the cursor. - var winW = window.innerWidth || Math.max(document.body.offsetWidth, document.documentElement.offsetWidth); - var winH = window.innerHeight || Math.max(document.body.offsetHeight, document.documentElement.offsetHeight); - (options.container || document.body).appendChild(hints); - var box = hints.getBoundingClientRect(); - var overlapX = box.right - winW, overlapY = box.bottom - winH; - if (overlapX > 0) { - if (box.right - box.left > winW) { - hints.style.width = (winW - 5) + "px"; - overlapX -= (box.right - box.left) - winW; - } - hints.style.left = (left = pos.left - overlapX) + "px"; - } - if (overlapY > 0) { - var height = box.bottom - box.top; - if (box.top - (pos.bottom - pos.top) - height > 0) { - overlapY = height + (pos.bottom - pos.top); - below = false; - } else if (height > winH) { - hints.style.height = (winH - 5) + "px"; - overlapY -= height - winH; - } - hints.style.top = (top = pos.bottom - overlapY) + "px"; - } - - cm.addKeyMap(this.keyMap = buildKeyMap(options, { - moveFocus: function(n, avoidWrap) { widget.changeActive(widget.selectedHint + n, avoidWrap); }, - setFocus: function(n) { widget.changeActive(n); }, - menuSize: function() { return widget.screenAmount(); }, - length: completions.length, - close: function() { completion.close(); }, - pick: function() { widget.pick(); } - })); - - if (options.closeOnUnfocus !== false) { - var closingOnBlur; - cm.on("blur", this.onBlur = function() { closingOnBlur = setTimeout(function() { completion.close(); }, 100); }); - cm.on("focus", this.onFocus = function() { clearTimeout(closingOnBlur); }); - } - - var startScroll = cm.getScrollInfo(); - cm.on("scroll", this.onScroll = function() { - var curScroll = cm.getScrollInfo(), editor = cm.getWrapperElement().getBoundingClientRect(); - var newTop = top + startScroll.top - curScroll.top; - var point = newTop - (window.pageYOffset || (document.documentElement || document.body).scrollTop); - if (!below) point += hints.offsetHeight; - if (point <= editor.top || point >= editor.bottom) return completion.close(); - hints.style.top = newTop + "px"; - hints.style.left = (left + startScroll.left - curScroll.left) + "px"; - }); - - CodeMirror.on(hints, "dblclick", function(e) { - var t = e.target || e.srcElement; - if (t.hintId != null) {widget.changeActive(t.hintId); widget.pick();} - }); - CodeMirror.on(hints, "click", function(e) { - var t = e.target || e.srcElement; - if (t.hintId != null) widget.changeActive(t.hintId); - }); - CodeMirror.on(hints, "mousedown", function() { - setTimeout(function(){cm.focus();}, 20); - }); - - CodeMirror.signal(data, "select", completions[0], hints.firstChild); - return true; - } - - Widget.prototype = { - close: function() { - if (this.completion.widget != this) return; - this.completion.widget = null; - this.hints.parentNode.removeChild(this.hints); - this.completion.cm.removeKeyMap(this.keyMap); - - var cm = this.completion.cm; - if (this.completion.options.closeOnUnfocus !== false) { - cm.off("blur", this.onBlur); - cm.off("focus", this.onFocus); - } - cm.off("scroll", this.onScroll); - }, - - pick: function() { - this.completion.pick(this.data, this.selectedHint); - }, - - changeActive: function(i, avoidWrap) { - if (i >= this.data.list.length) - i = avoidWrap ? this.data.list.length - 1 : 0; - else if (i < 0) - i = avoidWrap ? 0 : this.data.list.length - 1; - if (this.selectedHint == i) return; - var node = this.hints.childNodes[this.selectedHint]; - node.className = node.className.replace(" CodeMirror-hint-active", ""); - node = this.hints.childNodes[this.selectedHint = i]; - node.className += " CodeMirror-hint-active"; - if (node.offsetTop < this.hints.scrollTop) - this.hints.scrollTop = node.offsetTop - 3; - else if (node.offsetTop + node.offsetHeight > this.hints.scrollTop + this.hints.clientHeight) - this.hints.scrollTop = node.offsetTop + node.offsetHeight - this.hints.clientHeight + 3; - CodeMirror.signal(this.data, "select", this.data.list[this.selectedHint], node); - }, - - screenAmount: function() { - return Math.floor(this.hints.clientHeight / this.hints.firstChild.offsetHeight) || 1; - } - }; -})(); +(function() { + "use strict"; + + CodeMirror.showHint = function(cm, getHints, options) { + // We want a single cursor position. + if (cm.somethingSelected()) return; + if (getHints == null) getHints = cm.getHelper(cm.getCursor(), "hint"); + if (getHints == null) return; + + if (cm.state.completionActive) cm.state.completionActive.close(); + + var completion = cm.state.completionActive = new Completion(cm, getHints, options || {}); + CodeMirror.signal(cm, "startCompletion", cm); + if (completion.options.async) + getHints(cm, function(hints) { completion.showHints(hints); }, completion.options); + else + return completion.showHints(getHints(cm, completion.options)); + }; + + function Completion(cm, getHints, options) { + this.cm = cm; + this.getHints = getHints; + this.options = options; + this.widget = this.onClose = null; + } + + Completion.prototype = { + close: function() { + if (!this.active()) return; + this.cm.state.completionActive = null; + + if (this.widget) this.widget.close(); + if (this.onClose) this.onClose(); + CodeMirror.signal(this.cm, "endCompletion", this.cm); + }, + + active: function() { + return this.cm.state.completionActive == this; + }, + + pick: function(data, i) { + var completion = data.list[i]; + if (completion.hint) completion.hint(this.cm, data, completion); + else this.cm.replaceRange(getText(completion), data.from, data.to); + this.close(); + }, + + showHints: function(data) { + if (!data || !data.list.length || !this.active()) return this.close(); + + if (this.options.completeSingle != false && data.list.length == 1) + this.pick(data, 0); + else + this.showWidget(data); + }, + + showWidget: function(data) { + this.widget = new Widget(this, data); + CodeMirror.signal(data, "shown"); + + var debounce = null, completion = this, finished; + var closeOn = this.options.closeCharacters || /[\s()\[\]{};:>,]/; + var startPos = this.cm.getCursor(), startLen = this.cm.getLine(startPos.line).length; + + function done() { + if (finished) return; + finished = true; + completion.close(); + completion.cm.off("cursorActivity", activity); + if (data) CodeMirror.signal(data, "close"); + } + + function update() { + if (finished) return; + CodeMirror.signal(data, "update"); + if (completion.options.async) + completion.getHints(completion.cm, finishUpdate, completion.options); + else + finishUpdate(completion.getHints(completion.cm, completion.options)); + } + function finishUpdate(data_) { + data = data_; + if (finished) return; + if (!data || !data.list.length) return done(); + completion.widget = new Widget(completion, data); + } + + function activity() { + clearTimeout(debounce); + var pos = completion.cm.getCursor(), line = completion.cm.getLine(pos.line); + if (pos.line != startPos.line || line.length - pos.ch != startLen - startPos.ch || + pos.ch < startPos.ch || completion.cm.somethingSelected() || + (pos.ch && closeOn.test(line.charAt(pos.ch - 1)))) { + completion.close(); + } else { + debounce = setTimeout(update, 170); + if (completion.widget) completion.widget.close(); + } + } + this.cm.on("cursorActivity", activity); + this.onClose = done; + } + }; + + function getText(completion) { + if (typeof completion == "string") return completion; + else return completion.text; + } + + function buildKeyMap(options, handle) { + var baseMap = { + Up: function() {handle.moveFocus(-1);}, + Down: function() {handle.moveFocus(1);}, + PageUp: function() {handle.moveFocus(-handle.menuSize() + 1, true);}, + PageDown: function() {handle.moveFocus(handle.menuSize() - 1, true);}, + Home: function() {handle.setFocus(0);}, + End: function() {handle.setFocus(handle.length - 1);}, + Enter: handle.pick, + Tab: handle.pick, + Esc: handle.close + }; + var ourMap = options.customKeys ? {} : baseMap; + function addBinding(key, val) { + var bound; + if (typeof val != "string") + bound = function(cm) { return val(cm, handle); }; + // This mechanism is deprecated + else if (baseMap.hasOwnProperty(val)) + bound = baseMap[val]; + else + bound = val; + ourMap[key] = bound; + } + if (options.customKeys) + for (var key in options.customKeys) if (options.customKeys.hasOwnProperty(key)) + addBinding(key, options.customKeys[key]); + if (options.extraKeys) + for (var key in options.extraKeys) if (options.extraKeys.hasOwnProperty(key)) + addBinding(key, options.extraKeys[key]); + return ourMap; + } + + function Widget(completion, data) { + this.completion = completion; + this.data = data; + var widget = this, cm = completion.cm, options = completion.options; + + var hints = this.hints = document.createElement("ul"); + hints.className = "CodeMirror-hints"; + this.selectedHint = 0; + + var completions = data.list; + for (var i = 0; i < completions.length; ++i) { + var elt = hints.appendChild(document.createElement("li")), cur = completions[i]; + var className = "CodeMirror-hint" + (i ? "" : " CodeMirror-hint-active"); + if (cur.className != null) className = cur.className + " " + className; + elt.className = className; + if (cur.render) cur.render(elt, data, cur); + else elt.appendChild(document.createTextNode(cur.displayText || getText(cur))); + elt.hintId = i; + } + + var pos = cm.cursorCoords(options.alignWithWord !== false ? data.from : null); + var left = pos.left, top = pos.bottom, below = true; + hints.style.left = left + "px"; + hints.style.top = top + "px"; + // If we're at the edge of the screen, then we want the menu to appear on the left of the cursor. + var winW = window.innerWidth || Math.max(document.body.offsetWidth, document.documentElement.offsetWidth); + var winH = window.innerHeight || Math.max(document.body.offsetHeight, document.documentElement.offsetHeight); + (options.container || document.body).appendChild(hints); + var box = hints.getBoundingClientRect(); + var overlapX = box.right - winW, overlapY = box.bottom - winH; + if (overlapX > 0) { + if (box.right - box.left > winW) { + hints.style.width = (winW - 5) + "px"; + overlapX -= (box.right - box.left) - winW; + } + hints.style.left = (left = pos.left - overlapX) + "px"; + } + if (overlapY > 0) { + var height = box.bottom - box.top; + if (box.top - (pos.bottom - pos.top) - height > 0) { + overlapY = height + (pos.bottom - pos.top); + below = false; + } else if (height > winH) { + hints.style.height = (winH - 5) + "px"; + overlapY -= height - winH; + } + hints.style.top = (top = pos.bottom - overlapY) + "px"; + } + + cm.addKeyMap(this.keyMap = buildKeyMap(options, { + moveFocus: function(n, avoidWrap) { widget.changeActive(widget.selectedHint + n, avoidWrap); }, + setFocus: function(n) { widget.changeActive(n); }, + menuSize: function() { return widget.screenAmount(); }, + length: completions.length, + close: function() { completion.close(); }, + pick: function() { widget.pick(); } + })); + + if (options.closeOnUnfocus !== false) { + var closingOnBlur; + cm.on("blur", this.onBlur = function() { closingOnBlur = setTimeout(function() { completion.close(); }, 100); }); + cm.on("focus", this.onFocus = function() { clearTimeout(closingOnBlur); }); + } + + var startScroll = cm.getScrollInfo(); + cm.on("scroll", this.onScroll = function() { + var curScroll = cm.getScrollInfo(), editor = cm.getWrapperElement().getBoundingClientRect(); + var newTop = top + startScroll.top - curScroll.top; + var point = newTop - (window.pageYOffset || (document.documentElement || document.body).scrollTop); + if (!below) point += hints.offsetHeight; + if (point <= editor.top || point >= editor.bottom) return completion.close(); + hints.style.top = newTop + "px"; + hints.style.left = (left + startScroll.left - curScroll.left) + "px"; + }); + + CodeMirror.on(hints, "dblclick", function(e) { + var t = e.target || e.srcElement; + if (t.hintId != null) {widget.changeActive(t.hintId); widget.pick();} + }); + CodeMirror.on(hints, "click", function(e) { + var t = e.target || e.srcElement; + if (t.hintId != null) widget.changeActive(t.hintId); + }); + CodeMirror.on(hints, "mousedown", function() { + setTimeout(function(){cm.focus();}, 20); + }); + + CodeMirror.signal(data, "select", completions[0], hints.firstChild); + return true; + } + + Widget.prototype = { + close: function() { + if (this.completion.widget != this) return; + this.completion.widget = null; + this.hints.parentNode.removeChild(this.hints); + this.completion.cm.removeKeyMap(this.keyMap); + + var cm = this.completion.cm; + if (this.completion.options.closeOnUnfocus !== false) { + cm.off("blur", this.onBlur); + cm.off("focus", this.onFocus); + } + cm.off("scroll", this.onScroll); + }, + + pick: function() { + this.completion.pick(this.data, this.selectedHint); + }, + + changeActive: function(i, avoidWrap) { + if (i >= this.data.list.length) + i = avoidWrap ? this.data.list.length - 1 : 0; + else if (i < 0) + i = avoidWrap ? 0 : this.data.list.length - 1; + if (this.selectedHint == i) return; + var node = this.hints.childNodes[this.selectedHint]; + node.className = node.className.replace(" CodeMirror-hint-active", ""); + node = this.hints.childNodes[this.selectedHint = i]; + node.className += " CodeMirror-hint-active"; + if (node.offsetTop < this.hints.scrollTop) + this.hints.scrollTop = node.offsetTop - 3; + else if (node.offsetTop + node.offsetHeight > this.hints.scrollTop + this.hints.clientHeight) + this.hints.scrollTop = node.offsetTop + node.offsetHeight - this.hints.clientHeight + 3; + CodeMirror.signal(this.data, "select", this.data.list[this.selectedHint], node); + }, + + screenAmount: function() { + return Math.floor(this.hints.clientHeight / this.hints.firstChild.offsetHeight) || 1; + } + }; +})(); diff --git a/profile-builder/assets/lib/codemirror/addon/hint/xml-hint.js b/profile-builder/assets/lib/codemirror/addon/hint/xml-hint.js index b6c1da2..00d5902 100644 --- a/profile-builder/assets/lib/codemirror/addon/hint/xml-hint.js +++ b/profile-builder/assets/lib/codemirror/addon/hint/xml-hint.js @@ -1,68 +1,68 @@ -(function() { - "use strict"; - - var Pos = CodeMirror.Pos; - - function getHints(cm, options) { - var tags = options && options.schemaInfo; - var quote = (options && options.quoteChar) || '"'; - if (!tags) return; - var cur = cm.getCursor(), token = cm.getTokenAt(cur); - var inner = CodeMirror.innerMode(cm.getMode(), token.state); - if (inner.mode.name != "xml") return; - var result = [], replaceToken = false, prefix; - var isTag = token.string.charAt(0) == "<"; - if (!inner.state.tagName || isTag) { // Tag completion - if (isTag) { - prefix = token.string.slice(1); - replaceToken = true; - } - var cx = inner.state.context, curTag = cx && tags[cx.tagName]; - var childList = cx ? curTag && curTag.children : tags["!top"]; - if (childList) { - for (var i = 0; i < childList.length; ++i) if (!prefix || childList[i].indexOf(prefix) == 0) - result.push("<" + childList[i]); - } else { - for (var name in tags) if (tags.hasOwnProperty(name) && name != "!top" && (!prefix || name.indexOf(prefix) == 0)) - result.push("<" + name); - } - if (cx && (!prefix || ("/" + cx.tagName).indexOf(prefix) == 0)) - result.push(""); - } else { - // Attribute completion - var curTag = tags[inner.state.tagName], attrs = curTag && curTag.attrs; - if (!attrs) return; - if (token.type == "string" || token.string == "=") { // A value - var before = cm.getRange(Pos(cur.line, Math.max(0, cur.ch - 60)), - Pos(cur.line, token.type == "string" ? token.start : token.end)); - var atName = before.match(/([^\s\u00a0=<>\"\']+)=$/), atValues; - if (!atName || !attrs.hasOwnProperty(atName[1]) || !(atValues = attrs[atName[1]])) return; - if (token.type == "string") { - prefix = token.string; - if (/['"]/.test(token.string.charAt(0))) { - quote = token.string.charAt(0); - prefix = token.string.slice(1); - } - replaceToken = true; - } - for (var i = 0; i < atValues.length; ++i) if (!prefix || atValues[i].indexOf(prefix) == 0) - result.push(quote + atValues[i] + quote); - } else { // An attribute name - if (token.type == "attribute") { - prefix = token.string; - replaceToken = true; - } - for (var attr in attrs) if (attrs.hasOwnProperty(attr) && (!prefix || attr.indexOf(prefix) == 0)) - result.push(attr); - } - } - return { - list: result, - from: replaceToken ? Pos(cur.line, token.start) : cur, - to: replaceToken ? Pos(cur.line, token.end) : cur - }; - } - - CodeMirror.xmlHint = getHints; // deprecated - CodeMirror.registerHelper("hint", "xml", getHints); -})(); +(function() { + "use strict"; + + var Pos = CodeMirror.Pos; + + function getHints(cm, options) { + var tags = options && options.schemaInfo; + var quote = (options && options.quoteChar) || '"'; + if (!tags) return; + var cur = cm.getCursor(), token = cm.getTokenAt(cur); + var inner = CodeMirror.innerMode(cm.getMode(), token.state); + if (inner.mode.name != "xml") return; + var result = [], replaceToken = false, prefix; + var isTag = token.string.charAt(0) == "<"; + if (!inner.state.tagName || isTag) { // Tag completion + if (isTag) { + prefix = token.string.slice(1); + replaceToken = true; + } + var cx = inner.state.context, curTag = cx && tags[cx.tagName]; + var childList = cx ? curTag && curTag.children : tags["!top"]; + if (childList) { + for (var i = 0; i < childList.length; ++i) if (!prefix || childList[i].indexOf(prefix) == 0) + result.push("<" + childList[i]); + } else { + for (var name in tags) if (tags.hasOwnProperty(name) && name != "!top" && (!prefix || name.indexOf(prefix) == 0)) + result.push("<" + name); + } + if (cx && (!prefix || ("/" + cx.tagName).indexOf(prefix) == 0)) + result.push(""); + } else { + // Attribute completion + var curTag = tags[inner.state.tagName], attrs = curTag && curTag.attrs; + if (!attrs) return; + if (token.type == "string" || token.string == "=") { // A value + var before = cm.getRange(Pos(cur.line, Math.max(0, cur.ch - 60)), + Pos(cur.line, token.type == "string" ? token.start : token.end)); + var atName = before.match(/([^\s\u00a0=<>\"\']+)=$/), atValues; + if (!atName || !attrs.hasOwnProperty(atName[1]) || !(atValues = attrs[atName[1]])) return; + if (token.type == "string") { + prefix = token.string; + if (/['"]/.test(token.string.charAt(0))) { + quote = token.string.charAt(0); + prefix = token.string.slice(1); + } + replaceToken = true; + } + for (var i = 0; i < atValues.length; ++i) if (!prefix || atValues[i].indexOf(prefix) == 0) + result.push(quote + atValues[i] + quote); + } else { // An attribute name + if (token.type == "attribute") { + prefix = token.string; + replaceToken = true; + } + for (var attr in attrs) if (attrs.hasOwnProperty(attr) && (!prefix || attr.indexOf(prefix) == 0)) + result.push(attr); + } + } + return { + list: result, + from: replaceToken ? Pos(cur.line, token.start) : cur, + to: replaceToken ? Pos(cur.line, token.end) : cur + }; + } + + CodeMirror.xmlHint = getHints; // deprecated + CodeMirror.registerHelper("hint", "xml", getHints); +})(); diff --git a/profile-builder/assets/lib/codemirror/addon/lint/coffeescript-lint.js b/profile-builder/assets/lib/codemirror/addon/lint/coffeescript-lint.js index 75f8db6..a67b756 100644 --- a/profile-builder/assets/lib/codemirror/addon/lint/coffeescript-lint.js +++ b/profile-builder/assets/lib/codemirror/addon/lint/coffeescript-lint.js @@ -1,25 +1,25 @@ -// Depends on coffeelint.js from http://www.coffeelint.org/js/coffeelint.js - -CodeMirror.registerHelper("lint", "coffeescript", function(text) { - var found = []; - var parseError = function(err) { - var loc = err.lineNumber; - found.push({from: CodeMirror.Pos(loc-1, 0), - to: CodeMirror.Pos(loc, 0), - severity: err.level, - message: err.message}); - }; - try { - var res = coffeelint.lint(text); - for(var i = 0; i < res.length; i++) { - parseError(res[i]); - } - } catch(e) { - found.push({from: CodeMirror.Pos(e.location.first_line, 0), - to: CodeMirror.Pos(e.location.last_line, e.location.last_column), - severity: 'error', - message: e.message}); - } - return found; -}); -CodeMirror.coffeeValidator = CodeMirror.lint.coffeescript; // deprecated +// Depends on coffeelint.js from http://www.coffeelint.org/js/coffeelint.js + +CodeMirror.registerHelper("lint", "coffeescript", function(text) { + var found = []; + var parseError = function(err) { + var loc = err.lineNumber; + found.push({from: CodeMirror.Pos(loc-1, 0), + to: CodeMirror.Pos(loc, 0), + severity: err.level, + message: err.message}); + }; + try { + var res = coffeelint.lint(text); + for(var i = 0; i < res.length; i++) { + parseError(res[i]); + } + } catch(e) { + found.push({from: CodeMirror.Pos(e.location.first_line, 0), + to: CodeMirror.Pos(e.location.last_line, e.location.last_column), + severity: 'error', + message: e.message}); + } + return found; +}); +CodeMirror.coffeeValidator = CodeMirror.lint.coffeescript; // deprecated diff --git a/profile-builder/assets/lib/codemirror/addon/lint/css-lint.js b/profile-builder/assets/lib/codemirror/addon/lint/css-lint.js index ba650f6..b19a4f7 100644 --- a/profile-builder/assets/lib/codemirror/addon/lint/css-lint.js +++ b/profile-builder/assets/lib/codemirror/addon/lint/css-lint.js @@ -1,17 +1,17 @@ -// Depends on csslint.js from https://github.com/stubbornella/csslint - -CodeMirror.registerHelper("lint", "css", function(text) { - var found = []; - var results = CSSLint.verify(text), messages = results.messages, message = null; - for ( var i = 0; i < messages.length; i++) { - message = messages[i]; - var startLine = message.line -1, endLine = message.line -1, startCol = message.col -1, endCol = message.col; - found.push({ - from: CodeMirror.Pos(startLine, startCol), - to: CodeMirror.Pos(endLine, endCol), - message: message.message, - severity : message.type - }); - } - return found; -}); +// Depends on csslint.js from https://github.com/stubbornella/csslint + +CodeMirror.registerHelper("lint", "css", function(text) { + var found = []; + var results = CSSLint.verify(text), messages = results.messages, message = null; + for ( var i = 0; i < messages.length; i++) { + message = messages[i]; + var startLine = message.line -1, endLine = message.line -1, startCol = message.col -1, endCol = message.col; + found.push({ + from: CodeMirror.Pos(startLine, startCol), + to: CodeMirror.Pos(endLine, endCol), + message: message.message, + severity : message.type + }); + } + return found; +}); diff --git a/profile-builder/assets/lib/codemirror/addon/lint/javascript-lint.js b/profile-builder/assets/lib/codemirror/addon/lint/javascript-lint.js index d7a6f6a..0aae3cc 100644 --- a/profile-builder/assets/lib/codemirror/addon/lint/javascript-lint.js +++ b/profile-builder/assets/lib/codemirror/addon/lint/javascript-lint.js @@ -1,124 +1,124 @@ -(function() { - - var bogus = [ "Dangerous comment" ]; - - var warnings = [ [ "Expected '{'", - "Statement body should be inside '{ }' braces." ] ]; - - var errors = [ "Missing semicolon", "Extra comma", "Missing property name", - "Unmatched ", " and instead saw", " is not defined", - "Unclosed string", "Stopping, unable to continue" ]; - - function validator(text, options) { - JSHINT(text, options); - var errors = JSHINT.data().errors, result = []; - if (errors) parseErrors(errors, result); - return result; - } - - CodeMirror.registerHelper("lint", "javascript", validator); - CodeMirror.javascriptValidator = CodeMirror.lint.javascript; // deprecated - - function cleanup(error) { - // All problems are warnings by default - fixWith(error, warnings, "warning", true); - fixWith(error, errors, "error"); - - return isBogus(error) ? null : error; - } - - function fixWith(error, fixes, severity, force) { - var description, fix, find, replace, found; - - description = error.description; - - for ( var i = 0; i < fixes.length; i++) { - fix = fixes[i]; - find = (typeof fix === "string" ? fix : fix[0]); - replace = (typeof fix === "string" ? null : fix[1]); - found = description.indexOf(find) !== -1; - - if (force || found) { - error.severity = severity; - } - if (found && replace) { - error.description = replace; - } - } - } - - function isBogus(error) { - var description = error.description; - for ( var i = 0; i < bogus.length; i++) { - if (description.indexOf(bogus[i]) !== -1) { - return true; - } - } - return false; - } - - function parseErrors(errors, output) { - for ( var i = 0; i < errors.length; i++) { - var error = errors[i]; - if (error) { - var linetabpositions, index; - - linetabpositions = []; - - // This next block is to fix a problem in jshint. Jshint - // replaces - // all tabs with spaces then performs some checks. The error - // positions (character/space) are then reported incorrectly, - // not taking the replacement step into account. Here we look - // at the evidence line and try to adjust the character position - // to the correct value. - if (error.evidence) { - // Tab positions are computed once per line and cached - var tabpositions = linetabpositions[error.line]; - if (!tabpositions) { - var evidence = error.evidence; - tabpositions = []; - // ugggh phantomjs does not like this - // forEachChar(evidence, function(item, index) { - Array.prototype.forEach.call(evidence, function(item, - index) { - if (item === '\t') { - // First col is 1 (not 0) to match error - // positions - tabpositions.push(index + 1); - } - }); - linetabpositions[error.line] = tabpositions; - } - if (tabpositions.length > 0) { - var pos = error.character; - tabpositions.forEach(function(tabposition) { - if (pos > tabposition) pos -= 1; - }); - error.character = pos; - } - } - - var start = error.character - 1, end = start + 1; - if (error.evidence) { - index = error.evidence.substring(start).search(/.\b/); - if (index > -1) { - end += index; - } - } - - // Convert to format expected by validation service - error.description = error.reason;// + "(jshint)"; - error.start = error.character; - error.end = end; - error = cleanup(error); - - if (error) - output.push({message: error.description, - severity: error.severity, - from: CodeMirror.Pos(error.line - 1, start), - to: CodeMirror.Pos(error.line - 1, end)}); - } - } - } -})(); +(function() { + + var bogus = [ "Dangerous comment" ]; + + var warnings = [ [ "Expected '{'", + "Statement body should be inside '{ }' braces." ] ]; + + var errors = [ "Missing semicolon", "Extra comma", "Missing property name", + "Unmatched ", " and instead saw", " is not defined", + "Unclosed string", "Stopping, unable to continue" ]; + + function validator(text, options) { + JSHINT(text, options); + var errors = JSHINT.data().errors, result = []; + if (errors) parseErrors(errors, result); + return result; + } + + CodeMirror.registerHelper("lint", "javascript", validator); + CodeMirror.javascriptValidator = CodeMirror.lint.javascript; // deprecated + + function cleanup(error) { + // All problems are warnings by default + fixWith(error, warnings, "warning", true); + fixWith(error, errors, "error"); + + return isBogus(error) ? null : error; + } + + function fixWith(error, fixes, severity, force) { + var description, fix, find, replace, found; + + description = error.description; + + for ( var i = 0; i < fixes.length; i++) { + fix = fixes[i]; + find = (typeof fix === "string" ? fix : fix[0]); + replace = (typeof fix === "string" ? null : fix[1]); + found = description.indexOf(find) !== -1; + + if (force || found) { + error.severity = severity; + } + if (found && replace) { + error.description = replace; + } + } + } + + function isBogus(error) { + var description = error.description; + for ( var i = 0; i < bogus.length; i++) { + if (description.indexOf(bogus[i]) !== -1) { + return true; + } + } + return false; + } + + function parseErrors(errors, output) { + for ( var i = 0; i < errors.length; i++) { + var error = errors[i]; + if (error) { + var linetabpositions, index; + + linetabpositions = []; + + // This next block is to fix a problem in jshint. Jshint + // replaces + // all tabs with spaces then performs some checks. The error + // positions (character/space) are then reported incorrectly, + // not taking the replacement step into account. Here we look + // at the evidence line and try to adjust the character position + // to the correct value. + if (error.evidence) { + // Tab positions are computed once per line and cached + var tabpositions = linetabpositions[error.line]; + if (!tabpositions) { + var evidence = error.evidence; + tabpositions = []; + // ugggh phantomjs does not like this + // forEachChar(evidence, function(item, index) { + Array.prototype.forEach.call(evidence, function(item, + index) { + if (item === '\t') { + // First col is 1 (not 0) to match error + // positions + tabpositions.push(index + 1); + } + }); + linetabpositions[error.line] = tabpositions; + } + if (tabpositions.length > 0) { + var pos = error.character; + tabpositions.forEach(function(tabposition) { + if (pos > tabposition) pos -= 1; + }); + error.character = pos; + } + } + + var start = error.character - 1, end = start + 1; + if (error.evidence) { + index = error.evidence.substring(start).search(/.\b/); + if (index > -1) { + end += index; + } + } + + // Convert to format expected by validation service + error.description = error.reason;// + "(jshint)"; + error.start = error.character; + error.end = end; + error = cleanup(error); + + if (error) + output.push({message: error.description, + severity: error.severity, + from: CodeMirror.Pos(error.line - 1, start), + to: CodeMirror.Pos(error.line - 1, end)}); + } + } + } +})(); diff --git a/profile-builder/assets/lib/codemirror/addon/lint/json-lint.js b/profile-builder/assets/lib/codemirror/addon/lint/json-lint.js index 1dfc6b8..346479e 100644 --- a/profile-builder/assets/lib/codemirror/addon/lint/json-lint.js +++ b/profile-builder/assets/lib/codemirror/addon/lint/json-lint.js @@ -1,15 +1,15 @@ -// Depends on jsonlint.js from https://github.com/zaach/jsonlint - -CodeMirror.registerHelper("lint", "json", function(text) { - var found = []; - jsonlint.parseError = function(str, hash) { - var loc = hash.loc; - found.push({from: CodeMirror.Pos(loc.first_line - 1, loc.first_column), - to: CodeMirror.Pos(loc.last_line - 1, loc.last_column), - message: str}); - }; - try { jsonlint.parse(text); } - catch(e) {} - return found; -}); -CodeMirror.jsonValidator = CodeMirror.lint.json; // deprecated +// Depends on jsonlint.js from https://github.com/zaach/jsonlint + +CodeMirror.registerHelper("lint", "json", function(text) { + var found = []; + jsonlint.parseError = function(str, hash) { + var loc = hash.loc; + found.push({from: CodeMirror.Pos(loc.first_line - 1, loc.first_column), + to: CodeMirror.Pos(loc.last_line - 1, loc.last_column), + message: str}); + }; + try { jsonlint.parse(text); } + catch(e) {} + return found; +}); +CodeMirror.jsonValidator = CodeMirror.lint.json; // deprecated diff --git a/profile-builder/assets/lib/codemirror/addon/lint/lint.css b/profile-builder/assets/lib/codemirror/addon/lint/lint.css index e592b36..ce29661 100644 --- a/profile-builder/assets/lib/codemirror/addon/lint/lint.css +++ b/profile-builder/assets/lib/codemirror/addon/lint/lint.css @@ -1,72 +1,72 @@ -/* The lint marker gutter */ -.CodeMirror-lint-markers { - width: 16px; -} - -.CodeMirror-lint-tooltip { - background-color: infobackground; - border: 1px solid black; - border-radius: 4px 4px 4px 4px; - color: infotext; - font-family: monospace; - font-size: 10pt; - overflow: hidden; - padding: 2px 5px; - position: fixed; - white-space: pre; - z-index: 100; - max-width: 600px; - opacity: 0; - transition: opacity .4s; - -moz-transition: opacity .4s; - -webkit-transition: opacity .4s; - -o-transition: opacity .4s; - -ms-transition: opacity .4s; -} - -.CodeMirror-lint-mark-error, .CodeMirror-lint-mark-warning { - background-position: left bottom; - background-repeat: repeat-x; -} - -.CodeMirror-lint-mark-error { - background-image: - url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJDw4cOCW1/KIAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAHElEQVQI12NggIL/DAz/GdA5/xkY/qPKMDAwAADLZwf5rvm+LQAAAABJRU5ErkJggg==") - ; -} - -.CodeMirror-lint-mark-warning { - background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJFhQXEbhTg7YAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAMklEQVQI12NkgIIvJ3QXMjAwdDN+OaEbysDA4MPAwNDNwMCwiOHLCd1zX07o6kBVGQEAKBANtobskNMAAAAASUVORK5CYII="); -} - -.CodeMirror-lint-marker-error, .CodeMirror-lint-marker-warning { - background-position: center center; - background-repeat: no-repeat; - cursor: pointer; - display: inline-block; - height: 16px; - width: 16px; - vertical-align: middle; - position: relative; -} - -.CodeMirror-lint-message-error, .CodeMirror-lint-message-warning { - padding-left: 18px; - background-position: top left; - background-repeat: no-repeat; -} - -.CodeMirror-lint-marker-error, .CodeMirror-lint-message-error { - background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAHlBMVEW7AAC7AACxAAC7AAC7AAAAAAC4AAC5AAD///+7AAAUdclpAAAABnRSTlMXnORSiwCK0ZKSAAAATUlEQVR42mWPOQ7AQAgDuQLx/z8csYRmPRIFIwRGnosRrpamvkKi0FTIiMASR3hhKW+hAN6/tIWhu9PDWiTGNEkTtIOucA5Oyr9ckPgAWm0GPBog6v4AAAAASUVORK5CYII="); -} - -.CodeMirror-lint-marker-warning, .CodeMirror-lint-message-warning { - background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAANlBMVEX/uwDvrwD/uwD/uwD/uwD/uwD/uwD/uwD/uwD6twD/uwAAAADurwD2tQD7uAD+ugAAAAD/uwDhmeTRAAAADHRSTlMJ8mN1EYcbmiixgACm7WbuAAAAVklEQVR42n3PUQqAIBBFUU1LLc3u/jdbOJoW1P08DA9Gba8+YWJ6gNJoNYIBzAA2chBth5kLmG9YUoG0NHAUwFXwO9LuBQL1giCQb8gC9Oro2vp5rncCIY8L8uEx5ZkAAAAASUVORK5CYII="); -} - -.CodeMirror-lint-marker-multiple { - background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAMAAADzjKfhAAAACVBMVEUAAAAAAAC/v7914kyHAAAAAXRSTlMAQObYZgAAACNJREFUeNo1ioEJAAAIwmz/H90iFFSGJgFMe3gaLZ0od+9/AQZ0ADosbYraAAAAAElFTkSuQmCC"); - background-repeat: no-repeat; - background-position: right bottom; - width: 100%; height: 100%; -} +/* The lint marker gutter */ +.CodeMirror-lint-markers { + width: 16px; +} + +.CodeMirror-lint-tooltip { + background-color: infobackground; + border: 1px solid black; + border-radius: 4px 4px 4px 4px; + color: infotext; + font-family: monospace; + font-size: 10pt; + overflow: hidden; + padding: 2px 5px; + position: fixed; + white-space: pre; + z-index: 100; + max-width: 600px; + opacity: 0; + transition: opacity .4s; + -moz-transition: opacity .4s; + -webkit-transition: opacity .4s; + -o-transition: opacity .4s; + -ms-transition: opacity .4s; +} + +.CodeMirror-lint-mark-error, .CodeMirror-lint-mark-warning { + background-position: left bottom; + background-repeat: repeat-x; +} + +.CodeMirror-lint-mark-error { + background-image: + url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJDw4cOCW1/KIAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAHElEQVQI12NggIL/DAz/GdA5/xkY/qPKMDAwAADLZwf5rvm+LQAAAABJRU5ErkJggg==") + ; +} + +.CodeMirror-lint-mark-warning { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJFhQXEbhTg7YAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAMklEQVQI12NkgIIvJ3QXMjAwdDN+OaEbysDA4MPAwNDNwMCwiOHLCd1zX07o6kBVGQEAKBANtobskNMAAAAASUVORK5CYII="); +} + +.CodeMirror-lint-marker-error, .CodeMirror-lint-marker-warning { + background-position: center center; + background-repeat: no-repeat; + cursor: pointer; + display: inline-block; + height: 16px; + width: 16px; + vertical-align: middle; + position: relative; +} + +.CodeMirror-lint-message-error, .CodeMirror-lint-message-warning { + padding-left: 18px; + background-position: top left; + background-repeat: no-repeat; +} + +.CodeMirror-lint-marker-error, .CodeMirror-lint-message-error { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAHlBMVEW7AAC7AACxAAC7AAC7AAAAAAC4AAC5AAD///+7AAAUdclpAAAABnRSTlMXnORSiwCK0ZKSAAAATUlEQVR42mWPOQ7AQAgDuQLx/z8csYRmPRIFIwRGnosRrpamvkKi0FTIiMASR3hhKW+hAN6/tIWhu9PDWiTGNEkTtIOucA5Oyr9ckPgAWm0GPBog6v4AAAAASUVORK5CYII="); +} + +.CodeMirror-lint-marker-warning, .CodeMirror-lint-message-warning { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAANlBMVEX/uwDvrwD/uwD/uwD/uwD/uwD/uwD/uwD/uwD6twD/uwAAAADurwD2tQD7uAD+ugAAAAD/uwDhmeTRAAAADHRSTlMJ8mN1EYcbmiixgACm7WbuAAAAVklEQVR42n3PUQqAIBBFUU1LLc3u/jdbOJoW1P08DA9Gba8+YWJ6gNJoNYIBzAA2chBth5kLmG9YUoG0NHAUwFXwO9LuBQL1giCQb8gC9Oro2vp5rncCIY8L8uEx5ZkAAAAASUVORK5CYII="); +} + +.CodeMirror-lint-marker-multiple { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAMAAADzjKfhAAAACVBMVEUAAAAAAAC/v7914kyHAAAAAXRSTlMAQObYZgAAACNJREFUeNo1ioEJAAAIwmz/H90iFFSGJgFMe3gaLZ0od+9/AQZ0ADosbYraAAAAAElFTkSuQmCC"); + background-repeat: no-repeat; + background-position: right bottom; + width: 100%; height: 100%; +} diff --git a/profile-builder/assets/lib/codemirror/addon/lint/lint.js b/profile-builder/assets/lib/codemirror/addon/lint/lint.js index b502ee4..a317a5e 100644 --- a/profile-builder/assets/lib/codemirror/addon/lint/lint.js +++ b/profile-builder/assets/lib/codemirror/addon/lint/lint.js @@ -1,203 +1,203 @@ -(function() { - "use strict"; - var GUTTER_ID = "CodeMirror-lint-markers"; - var SEVERITIES = /^(?:error|warning)$/; - - function showTooltip(e, content) { - var tt = document.createElement("div"); - tt.className = "CodeMirror-lint-tooltip"; - tt.appendChild(content.cloneNode(true)); - document.body.appendChild(tt); - - function position(e) { - if (!tt.parentNode) return CodeMirror.off(document, "mousemove", position); - tt.style.top = Math.max(0, e.clientY - tt.offsetHeight - 5) + "px"; - tt.style.left = (e.clientX + 5) + "px"; - } - CodeMirror.on(document, "mousemove", position); - position(e); - if (tt.style.opacity != null) tt.style.opacity = 1; - return tt; - } - function rm(elt) { - if (elt.parentNode) elt.parentNode.removeChild(elt); - } - function hideTooltip(tt) { - if (!tt.parentNode) return; - if (tt.style.opacity == null) rm(tt); - tt.style.opacity = 0; - setTimeout(function() { rm(tt); }, 600); - } - - function showTooltipFor(e, content, node) { - var tooltip = showTooltip(e, content); - function hide() { - CodeMirror.off(node, "mouseout", hide); - if (tooltip) { hideTooltip(tooltip); tooltip = null; } - } - var poll = setInterval(function() { - if (tooltip) for (var n = node;; n = n.parentNode) { - if (n == document.body) return; - if (!n) { hide(); break; } - } - if (!tooltip) return clearInterval(poll); - }, 400); - CodeMirror.on(node, "mouseout", hide); - } - - function LintState(cm, options, hasGutter) { - this.marked = []; - this.options = options; - this.timeout = null; - this.hasGutter = hasGutter; - this.onMouseOver = function(e) { onMouseOver(cm, e); }; - } - - function parseOptions(cm, options) { - if (options instanceof Function) return {getAnnotations: options}; - if (!options || options === true) options = {}; - if (!options.getAnnotations) options.getAnnotations = cm.getHelper(CodeMirror.Pos(0, 0), "lint"); - if (!options.getAnnotations) throw new Error("Required option 'getAnnotations' missing (lint addon)"); - return options; - } - - function clearMarks(cm) { - var state = cm.state.lint; - if (state.hasGutter) cm.clearGutter(GUTTER_ID); - for (var i = 0; i < state.marked.length; ++i) - state.marked[i].clear(); - state.marked.length = 0; - } - - function makeMarker(labels, severity, multiple, tooltips) { - var marker = document.createElement("div"), inner = marker; - marker.className = "CodeMirror-lint-marker-" + severity; - if (multiple) { - inner = marker.appendChild(document.createElement("div")); - inner.className = "CodeMirror-lint-marker-multiple"; - } - - if (tooltips != false) CodeMirror.on(inner, "mouseover", function(e) { - showTooltipFor(e, labels, inner); - }); - - return marker; - } - - function getMaxSeverity(a, b) { - if (a == "error") return a; - else return b; - } - - function groupByLine(annotations) { - var lines = []; - for (var i = 0; i < annotations.length; ++i) { - var ann = annotations[i], line = ann.from.line; - (lines[line] || (lines[line] = [])).push(ann); - } - return lines; - } - - function annotationTooltip(ann) { - var severity = ann.severity; - if (!SEVERITIES.test(severity)) severity = "error"; - var tip = document.createElement("div"); - tip.className = "CodeMirror-lint-message-" + severity; - tip.appendChild(document.createTextNode(ann.message)); - return tip; - } - - function startLinting(cm) { - var state = cm.state.lint, options = state.options; - if (options.async) - options.getAnnotations(cm, updateLinting, options); - else - updateLinting(cm, options.getAnnotations(cm.getValue(), options)); - } - - function updateLinting(cm, annotationsNotSorted) { - clearMarks(cm); - var state = cm.state.lint, options = state.options; - - var annotations = groupByLine(annotationsNotSorted); - - for (var line = 0; line < annotations.length; ++line) { - var anns = annotations[line]; - if (!anns) continue; - - var maxSeverity = null; - var tipLabel = state.hasGutter && document.createDocumentFragment(); - - for (var i = 0; i < anns.length; ++i) { - var ann = anns[i]; - var severity = ann.severity; - if (!SEVERITIES.test(severity)) severity = "error"; - maxSeverity = getMaxSeverity(maxSeverity, severity); - - if (options.formatAnnotation) ann = options.formatAnnotation(ann); - if (state.hasGutter) tipLabel.appendChild(annotationTooltip(ann)); - - if (ann.to) state.marked.push(cm.markText(ann.from, ann.to, { - className: "CodeMirror-lint-mark-" + severity, - __annotation: ann - })); - } - - if (state.hasGutter) - cm.setGutterMarker(line, GUTTER_ID, makeMarker(tipLabel, maxSeverity, anns.length > 1, - state.options.tooltips)); - } - if (options.onUpdateLinting) options.onUpdateLinting(annotationsNotSorted, annotations, cm); - } - - function onChange(cm) { - var state = cm.state.lint; - clearTimeout(state.timeout); - state.timeout = setTimeout(function(){startLinting(cm);}, state.options.delay || 500); - } - - function popupSpanTooltip(ann, e) { - var target = e.target || e.srcElement; - showTooltipFor(e, annotationTooltip(ann), target); - } - - // When the mouseover fires, the cursor might not actually be over - // the character itself yet. These pairs of x,y offsets are used to - // probe a few nearby points when no suitable marked range is found. - var nearby = [0, 0, 0, 5, 0, -5, 5, 0, -5, 0]; - - function onMouseOver(cm, e) { - if (!/\bCodeMirror-lint-mark-/.test((e.target || e.srcElement).className)) return; - for (var i = 0; i < nearby.length; i += 2) { - var spans = cm.findMarksAt(cm.coordsChar({left: e.clientX + nearby[i], - top: e.clientY + nearby[i + 1]})); - for (var j = 0; j < spans.length; ++j) { - var span = spans[j], ann = span.__annotation; - if (ann) return popupSpanTooltip(ann, e); - } - } - } - - function optionHandler(cm, val, old) { - if (old && old != CodeMirror.Init) { - clearMarks(cm); - cm.off("change", onChange); - CodeMirror.off(cm.getWrapperElement(), "mouseover", cm.state.lint.onMouseOver); - delete cm.state.lint; - } - - if (val) { - var gutters = cm.getOption("gutters"), hasLintGutter = false; - for (var i = 0; i < gutters.length; ++i) if (gutters[i] == GUTTER_ID) hasLintGutter = true; - var state = cm.state.lint = new LintState(cm, parseOptions(cm, val), hasLintGutter); - cm.on("change", onChange); - if (state.options.tooltips != false) - CodeMirror.on(cm.getWrapperElement(), "mouseover", state.onMouseOver); - - startLinting(cm); - } - } - - CodeMirror.defineOption("lintWith", false, optionHandler); // deprecated - CodeMirror.defineOption("lint", false, optionHandler); // deprecated -})(); +(function() { + "use strict"; + var GUTTER_ID = "CodeMirror-lint-markers"; + var SEVERITIES = /^(?:error|warning)$/; + + function showTooltip(e, content) { + var tt = document.createElement("div"); + tt.className = "CodeMirror-lint-tooltip"; + tt.appendChild(content.cloneNode(true)); + document.body.appendChild(tt); + + function position(e) { + if (!tt.parentNode) return CodeMirror.off(document, "mousemove", position); + tt.style.top = Math.max(0, e.clientY - tt.offsetHeight - 5) + "px"; + tt.style.left = (e.clientX + 5) + "px"; + } + CodeMirror.on(document, "mousemove", position); + position(e); + if (tt.style.opacity != null) tt.style.opacity = 1; + return tt; + } + function rm(elt) { + if (elt.parentNode) elt.parentNode.removeChild(elt); + } + function hideTooltip(tt) { + if (!tt.parentNode) return; + if (tt.style.opacity == null) rm(tt); + tt.style.opacity = 0; + setTimeout(function() { rm(tt); }, 600); + } + + function showTooltipFor(e, content, node) { + var tooltip = showTooltip(e, content); + function hide() { + CodeMirror.off(node, "mouseout", hide); + if (tooltip) { hideTooltip(tooltip); tooltip = null; } + } + var poll = setInterval(function() { + if (tooltip) for (var n = node;; n = n.parentNode) { + if (n == document.body) return; + if (!n) { hide(); break; } + } + if (!tooltip) return clearInterval(poll); + }, 400); + CodeMirror.on(node, "mouseout", hide); + } + + function LintState(cm, options, hasGutter) { + this.marked = []; + this.options = options; + this.timeout = null; + this.hasGutter = hasGutter; + this.onMouseOver = function(e) { onMouseOver(cm, e); }; + } + + function parseOptions(cm, options) { + if (options instanceof Function) return {getAnnotations: options}; + if (!options || options === true) options = {}; + if (!options.getAnnotations) options.getAnnotations = cm.getHelper(CodeMirror.Pos(0, 0), "lint"); + if (!options.getAnnotations) throw new Error("Required option 'getAnnotations' missing (lint addon)"); + return options; + } + + function clearMarks(cm) { + var state = cm.state.lint; + if (state.hasGutter) cm.clearGutter(GUTTER_ID); + for (var i = 0; i < state.marked.length; ++i) + state.marked[i].clear(); + state.marked.length = 0; + } + + function makeMarker(labels, severity, multiple, tooltips) { + var marker = document.createElement("div"), inner = marker; + marker.className = "CodeMirror-lint-marker-" + severity; + if (multiple) { + inner = marker.appendChild(document.createElement("div")); + inner.className = "CodeMirror-lint-marker-multiple"; + } + + if (tooltips != false) CodeMirror.on(inner, "mouseover", function(e) { + showTooltipFor(e, labels, inner); + }); + + return marker; + } + + function getMaxSeverity(a, b) { + if (a == "error") return a; + else return b; + } + + function groupByLine(annotations) { + var lines = []; + for (var i = 0; i < annotations.length; ++i) { + var ann = annotations[i], line = ann.from.line; + (lines[line] || (lines[line] = [])).push(ann); + } + return lines; + } + + function annotationTooltip(ann) { + var severity = ann.severity; + if (!SEVERITIES.test(severity)) severity = "error"; + var tip = document.createElement("div"); + tip.className = "CodeMirror-lint-message-" + severity; + tip.appendChild(document.createTextNode(ann.message)); + return tip; + } + + function startLinting(cm) { + var state = cm.state.lint, options = state.options; + if (options.async) + options.getAnnotations(cm, updateLinting, options); + else + updateLinting(cm, options.getAnnotations(cm.getValue(), options)); + } + + function updateLinting(cm, annotationsNotSorted) { + clearMarks(cm); + var state = cm.state.lint, options = state.options; + + var annotations = groupByLine(annotationsNotSorted); + + for (var line = 0; line < annotations.length; ++line) { + var anns = annotations[line]; + if (!anns) continue; + + var maxSeverity = null; + var tipLabel = state.hasGutter && document.createDocumentFragment(); + + for (var i = 0; i < anns.length; ++i) { + var ann = anns[i]; + var severity = ann.severity; + if (!SEVERITIES.test(severity)) severity = "error"; + maxSeverity = getMaxSeverity(maxSeverity, severity); + + if (options.formatAnnotation) ann = options.formatAnnotation(ann); + if (state.hasGutter) tipLabel.appendChild(annotationTooltip(ann)); + + if (ann.to) state.marked.push(cm.markText(ann.from, ann.to, { + className: "CodeMirror-lint-mark-" + severity, + __annotation: ann + })); + } + + if (state.hasGutter) + cm.setGutterMarker(line, GUTTER_ID, makeMarker(tipLabel, maxSeverity, anns.length > 1, + state.options.tooltips)); + } + if (options.onUpdateLinting) options.onUpdateLinting(annotationsNotSorted, annotations, cm); + } + + function onChange(cm) { + var state = cm.state.lint; + clearTimeout(state.timeout); + state.timeout = setTimeout(function(){startLinting(cm);}, state.options.delay || 500); + } + + function popupSpanTooltip(ann, e) { + var target = e.target || e.srcElement; + showTooltipFor(e, annotationTooltip(ann), target); + } + + // When the mouseover fires, the cursor might not actually be over + // the character itself yet. These pairs of x,y offsets are used to + // probe a few nearby points when no suitable marked range is found. + var nearby = [0, 0, 0, 5, 0, -5, 5, 0, -5, 0]; + + function onMouseOver(cm, e) { + if (!/\bCodeMirror-lint-mark-/.test((e.target || e.srcElement).className)) return; + for (var i = 0; i < nearby.length; i += 2) { + var spans = cm.findMarksAt(cm.coordsChar({left: e.clientX + nearby[i], + top: e.clientY + nearby[i + 1]})); + for (var j = 0; j < spans.length; ++j) { + var span = spans[j], ann = span.__annotation; + if (ann) return popupSpanTooltip(ann, e); + } + } + } + + function optionHandler(cm, val, old) { + if (old && old != CodeMirror.Init) { + clearMarks(cm); + cm.off("change", onChange); + CodeMirror.off(cm.getWrapperElement(), "mouseover", cm.state.lint.onMouseOver); + delete cm.state.lint; + } + + if (val) { + var gutters = cm.getOption("gutters"), hasLintGutter = false; + for (var i = 0; i < gutters.length; ++i) if (gutters[i] == GUTTER_ID) hasLintGutter = true; + var state = cm.state.lint = new LintState(cm, parseOptions(cm, val), hasLintGutter); + cm.on("change", onChange); + if (state.options.tooltips != false) + CodeMirror.on(cm.getWrapperElement(), "mouseover", state.onMouseOver); + + startLinting(cm); + } + } + + CodeMirror.defineOption("lintWith", false, optionHandler); // deprecated + CodeMirror.defineOption("lint", false, optionHandler); // deprecated +})(); diff --git a/profile-builder/assets/lib/codemirror/addon/merge/dep/diff_match_patch.js b/profile-builder/assets/lib/codemirror/addon/merge/dep/diff_match_patch.js index ac34105..ae7e3aa 100644 --- a/profile-builder/assets/lib/codemirror/addon/merge/dep/diff_match_patch.js +++ b/profile-builder/assets/lib/codemirror/addon/merge/dep/diff_match_patch.js @@ -1,50 +1,50 @@ -// From https://code.google.com/p/google-diff-match-patch/ , licensed under the Apache License 2.0 -(function(){function diff_match_patch(){this.Diff_Timeout=1;this.Diff_EditCost=4;this.Match_Threshold=0.5;this.Match_Distance=1E3;this.Patch_DeleteThreshold=0.5;this.Patch_Margin=4;this.Match_MaxBits=32} -diff_match_patch.prototype.diff_main=function(a,b,c,d){"undefined"==typeof d&&(d=0>=this.Diff_Timeout?Number.MAX_VALUE:(new Date).getTime()+1E3*this.Diff_Timeout);if(null==a||null==b)throw Error("Null input. (diff_main)");if(a==b)return a?[[0,a]]:[];"undefined"==typeof c&&(c=!0);var e=c,f=this.diff_commonPrefix(a,b);c=a.substring(0,f);a=a.substring(f);b=b.substring(f);var f=this.diff_commonSuffix(a,b),g=a.substring(a.length-f);a=a.substring(0,a.length-f);b=b.substring(0,b.length-f);a=this.diff_compute_(a, -b,e,d);c&&a.unshift([0,c]);g&&a.push([0,g]);this.diff_cleanupMerge(a);return a}; -diff_match_patch.prototype.diff_compute_=function(a,b,c,d){if(!a)return[[1,b]];if(!b)return[[-1,a]];var e=a.length>b.length?a:b,f=a.length>b.length?b:a,g=e.indexOf(f);return-1!=g?(c=[[1,e.substring(0,g)],[0,f],[1,e.substring(g+f.length)]],a.length>b.length&&(c[0][0]=c[2][0]=-1),c):1==f.length?[[-1,a],[1,b]]:(e=this.diff_halfMatch_(a,b))?(f=e[0],a=e[1],g=e[2],b=e[3],e=e[4],f=this.diff_main(f,g,c,d),c=this.diff_main(a,b,c,d),f.concat([[0,e]],c)):c&&100c);v++){for(var n=-v+r;n<=v-t;n+=2){var l=g+n,m;m=n==-v||n!=v&&j[l-1]d)t+=2;else if(s>e)r+=2;else if(q&&(l=g+k-n,0<=l&&l= -u)return this.diff_bisectSplit_(a,b,m,s,c)}}for(n=-v+p;n<=v-w;n+=2){l=g+n;u=n==-v||n!=v&&i[l-1]d)w+=2;else if(m>e)p+=2;else if(!q&&(l=g+k-n,0<=l&&(l=u)))return this.diff_bisectSplit_(a,b,m,s,c)}}return[[-1,a],[1,b]]}; -diff_match_patch.prototype.diff_bisectSplit_=function(a,b,c,d,e){var f=a.substring(0,c),g=b.substring(0,d);a=a.substring(c);b=b.substring(d);f=this.diff_main(f,g,!1,e);e=this.diff_main(a,b,!1,e);return f.concat(e)}; -diff_match_patch.prototype.diff_linesToChars_=function(a,b){function c(a){for(var b="",c=0,f=-1,g=d.length;fd?a=a.substring(c-d):c=a.length?[h,j,n,l,g]:null}if(0>=this.Diff_Timeout)return null; -var d=a.length>b.length?a:b,e=a.length>b.length?b:a;if(4>d.length||2*e.lengthd[4].length?g:d:d:g;var j;a.length>b.length?(g=h[0],d=h[1],e=h[2],j=h[3]):(e=h[0],j=h[1],g=h[2],d=h[3]);h=h[4];return[g,d,e,j,h]}; -diff_match_patch.prototype.diff_cleanupSemantic=function(a){for(var b=!1,c=[],d=0,e=null,f=0,g=0,h=0,j=0,i=0;f=e){if(d>=b.length/2||d>=c.length/2)a.splice(f,0,[0,c.substring(0,d)]),a[f-1][1]=b.substring(0,b.length-d),a[f+1][1]=c.substring(d),f++}else if(e>=b.length/2||e>=c.length/2)a.splice(f,0,[0,b.substring(0,e)]),a[f-1][0]=1,a[f-1][1]=c.substring(0,c.length-e),a[f+1][0]=-1,a[f+1][1]=b.substring(e),f++;f++}f++}}; -diff_match_patch.prototype.diff_cleanupSemanticLossless=function(a){function b(a,b){if(!a||!b)return 6;var c=a.charAt(a.length-1),d=b.charAt(0),e=c.match(diff_match_patch.nonAlphaNumericRegex_),f=d.match(diff_match_patch.nonAlphaNumericRegex_),g=e&&c.match(diff_match_patch.whitespaceRegex_),h=f&&d.match(diff_match_patch.whitespaceRegex_),c=g&&c.match(diff_match_patch.linebreakRegex_),d=h&&d.match(diff_match_patch.linebreakRegex_),i=c&&a.match(diff_match_patch.blanklineEndRegex_),j=d&&b.match(diff_match_patch.blanklineStartRegex_); -return i||j?5:c||d?4:e&&!g&&h?3:g||h?2:e||f?1:0}for(var c=1;c=i&&(i=k,g=d,h=e,j=f)}a[c-1][1]!=g&&(g?a[c-1][1]=g:(a.splice(c-1,1),c--),a[c][1]= -h,j?a[c+1][1]=j:(a.splice(c+1,1),c--))}c++}};diff_match_patch.nonAlphaNumericRegex_=/[^a-zA-Z0-9]/;diff_match_patch.whitespaceRegex_=/\s/;diff_match_patch.linebreakRegex_=/[\r\n]/;diff_match_patch.blanklineEndRegex_=/\n\r?\n$/;diff_match_patch.blanklineStartRegex_=/^\r?\n\r?\n/; -diff_match_patch.prototype.diff_cleanupEfficiency=function(a){for(var b=!1,c=[],d=0,e=null,f=0,g=!1,h=!1,j=!1,i=!1;fb)break;e=c;f=d}return a.length!=g&&-1===a[g][0]?f:f+(b-e)}; -diff_match_patch.prototype.diff_prettyHtml=function(a){for(var b=[],c=/&/g,d=//g,f=/\n/g,g=0;g");switch(h){case 1:b[g]=''+j+"";break;case -1:b[g]=''+j+"";break;case 0:b[g]=""+j+""}}return b.join("")}; -diff_match_patch.prototype.diff_text1=function(a){for(var b=[],c=0;cthis.Match_MaxBits)throw Error("Pattern too long for this browser.");var e=this.match_alphabet_(b),f=this,g=this.Match_Threshold,h=a.indexOf(b,c);-1!=h&&(g=Math.min(d(0,h),g),h=a.lastIndexOf(b,c+b.length),-1!=h&&(g=Math.min(d(0,h),g)));for(var j=1<=i;p--){var w=e[a.charAt(p-1)];k[p]=0===t?(k[p+1]<<1|1)&w:(k[p+1]<<1|1)&w|((r[p+1]|r[p])<<1|1)|r[p+1];if(k[p]&j&&(w=d(t,p-1),w<=g))if(g=w,h=p-1,h>c)i=Math.max(1,2*c-h);else break}if(d(t+1,c)>g)break;r=k}return h}; -diff_match_patch.prototype.match_alphabet_=function(a){for(var b={},c=0;c=2*this.Patch_Margin&& -e&&(this.patch_addContext_(a,h),c.push(a),a=new diff_match_patch.patch_obj,e=0,h=d,f=g)}1!==i&&(f+=k.length);-1!==i&&(g+=k.length)}e&&(this.patch_addContext_(a,h),c.push(a));return c};diff_match_patch.prototype.patch_deepCopy=function(a){for(var b=[],c=0;cthis.Match_MaxBits){if(j=this.match_main(b,h.substring(0,this.Match_MaxBits),g),-1!=j&&(i=this.match_main(b,h.substring(h.length-this.Match_MaxBits),g+h.length-this.Match_MaxBits),-1==i||j>=i))j=-1}else j=this.match_main(b,h,g); -if(-1==j)e[f]=!1,d-=a[f].length2-a[f].length1;else if(e[f]=!0,d=j-g,g=-1==i?b.substring(j,j+h.length):b.substring(j,i+this.Match_MaxBits),h==g)b=b.substring(0,j)+this.diff_text2(a[f].diffs)+b.substring(j+h.length);else if(g=this.diff_main(h,g,!1),h.length>this.Match_MaxBits&&this.diff_levenshtein(g)/h.length>this.Patch_DeleteThreshold)e[f]=!1;else{this.diff_cleanupSemanticLossless(g);for(var h=0,k,i=0;ie[0][1].length){var f=b-e[0][1].length;e[0][1]=c.substring(e[0][1].length)+e[0][1];d.start1-=f;d.start2-=f;d.length1+=f;d.length2+=f}d=a[a.length-1];e=d.diffs;0==e.length||0!=e[e.length-1][0]?(e.push([0, -c]),d.length1+=b,d.length2+=b):b>e[e.length-1][1].length&&(f=b-e[e.length-1][1].length,e[e.length-1][1]+=c.substring(0,f),d.length1+=f,d.length2+=f);return c}; -diff_match_patch.prototype.patch_splitMax=function(a){for(var b=this.Match_MaxBits,c=0;c2*b?(h.length1+=i.length,e+=i.length,j=!1,h.diffs.push([g,i]),d.diffs.shift()):(i=i.substring(0,b-h.length1-this.Patch_Margin),h.length1+=i.length,e+=i.length,0===g?(h.length2+=i.length,f+=i.length):j=!1,h.diffs.push([g,i]),i==d.diffs[0][1]?d.diffs.shift():d.diffs[0][1]=d.diffs[0][1].substring(i.length))}g=this.diff_text2(h.diffs);g=g.substring(g.length-this.Patch_Margin);i=this.diff_text1(d.diffs).substring(0,this.Patch_Margin);""!==i&& -(h.length1+=i.length,h.length2+=i.length,0!==h.diffs.length&&0===h.diffs[h.diffs.length-1][0]?h.diffs[h.diffs.length-1][1]+=i:h.diffs.push([0,i]));j||a.splice(++c,0,h)}}};diff_match_patch.prototype.patch_toText=function(a){for(var b=[],c=0;c=this.Diff_Timeout?Number.MAX_VALUE:(new Date).getTime()+1E3*this.Diff_Timeout);if(null==a||null==b)throw Error("Null input. (diff_main)");if(a==b)return a?[[0,a]]:[];"undefined"==typeof c&&(c=!0);var e=c,f=this.diff_commonPrefix(a,b);c=a.substring(0,f);a=a.substring(f);b=b.substring(f);var f=this.diff_commonSuffix(a,b),g=a.substring(a.length-f);a=a.substring(0,a.length-f);b=b.substring(0,b.length-f);a=this.diff_compute_(a, +b,e,d);c&&a.unshift([0,c]);g&&a.push([0,g]);this.diff_cleanupMerge(a);return a}; +diff_match_patch.prototype.diff_compute_=function(a,b,c,d){if(!a)return[[1,b]];if(!b)return[[-1,a]];var e=a.length>b.length?a:b,f=a.length>b.length?b:a,g=e.indexOf(f);return-1!=g?(c=[[1,e.substring(0,g)],[0,f],[1,e.substring(g+f.length)]],a.length>b.length&&(c[0][0]=c[2][0]=-1),c):1==f.length?[[-1,a],[1,b]]:(e=this.diff_halfMatch_(a,b))?(f=e[0],a=e[1],g=e[2],b=e[3],e=e[4],f=this.diff_main(f,g,c,d),c=this.diff_main(a,b,c,d),f.concat([[0,e]],c)):c&&100c);v++){for(var n=-v+r;n<=v-t;n+=2){var l=g+n,m;m=n==-v||n!=v&&j[l-1]d)t+=2;else if(s>e)r+=2;else if(q&&(l=g+k-n,0<=l&&l= +u)return this.diff_bisectSplit_(a,b,m,s,c)}}for(n=-v+p;n<=v-w;n+=2){l=g+n;u=n==-v||n!=v&&i[l-1]d)w+=2;else if(m>e)p+=2;else if(!q&&(l=g+k-n,0<=l&&(l=u)))return this.diff_bisectSplit_(a,b,m,s,c)}}return[[-1,a],[1,b]]}; +diff_match_patch.prototype.diff_bisectSplit_=function(a,b,c,d,e){var f=a.substring(0,c),g=b.substring(0,d);a=a.substring(c);b=b.substring(d);f=this.diff_main(f,g,!1,e);e=this.diff_main(a,b,!1,e);return f.concat(e)}; +diff_match_patch.prototype.diff_linesToChars_=function(a,b){function c(a){for(var b="",c=0,f=-1,g=d.length;fd?a=a.substring(c-d):c=a.length?[h,j,n,l,g]:null}if(0>=this.Diff_Timeout)return null; +var d=a.length>b.length?a:b,e=a.length>b.length?b:a;if(4>d.length||2*e.lengthd[4].length?g:d:d:g;var j;a.length>b.length?(g=h[0],d=h[1],e=h[2],j=h[3]):(e=h[0],j=h[1],g=h[2],d=h[3]);h=h[4];return[g,d,e,j,h]}; +diff_match_patch.prototype.diff_cleanupSemantic=function(a){for(var b=!1,c=[],d=0,e=null,f=0,g=0,h=0,j=0,i=0;f=e){if(d>=b.length/2||d>=c.length/2)a.splice(f,0,[0,c.substring(0,d)]),a[f-1][1]=b.substring(0,b.length-d),a[f+1][1]=c.substring(d),f++}else if(e>=b.length/2||e>=c.length/2)a.splice(f,0,[0,b.substring(0,e)]),a[f-1][0]=1,a[f-1][1]=c.substring(0,c.length-e),a[f+1][0]=-1,a[f+1][1]=b.substring(e),f++;f++}f++}}; +diff_match_patch.prototype.diff_cleanupSemanticLossless=function(a){function b(a,b){if(!a||!b)return 6;var c=a.charAt(a.length-1),d=b.charAt(0),e=c.match(diff_match_patch.nonAlphaNumericRegex_),f=d.match(diff_match_patch.nonAlphaNumericRegex_),g=e&&c.match(diff_match_patch.whitespaceRegex_),h=f&&d.match(diff_match_patch.whitespaceRegex_),c=g&&c.match(diff_match_patch.linebreakRegex_),d=h&&d.match(diff_match_patch.linebreakRegex_),i=c&&a.match(diff_match_patch.blanklineEndRegex_),j=d&&b.match(diff_match_patch.blanklineStartRegex_); +return i||j?5:c||d?4:e&&!g&&h?3:g||h?2:e||f?1:0}for(var c=1;c=i&&(i=k,g=d,h=e,j=f)}a[c-1][1]!=g&&(g?a[c-1][1]=g:(a.splice(c-1,1),c--),a[c][1]= +h,j?a[c+1][1]=j:(a.splice(c+1,1),c--))}c++}};diff_match_patch.nonAlphaNumericRegex_=/[^a-zA-Z0-9]/;diff_match_patch.whitespaceRegex_=/\s/;diff_match_patch.linebreakRegex_=/[\r\n]/;diff_match_patch.blanklineEndRegex_=/\n\r?\n$/;diff_match_patch.blanklineStartRegex_=/^\r?\n\r?\n/; +diff_match_patch.prototype.diff_cleanupEfficiency=function(a){for(var b=!1,c=[],d=0,e=null,f=0,g=!1,h=!1,j=!1,i=!1;fb)break;e=c;f=d}return a.length!=g&&-1===a[g][0]?f:f+(b-e)}; +diff_match_patch.prototype.diff_prettyHtml=function(a){for(var b=[],c=/&/g,d=//g,f=/\n/g,g=0;g");switch(h){case 1:b[g]=''+j+"";break;case -1:b[g]=''+j+"";break;case 0:b[g]=""+j+""}}return b.join("")}; +diff_match_patch.prototype.diff_text1=function(a){for(var b=[],c=0;cthis.Match_MaxBits)throw Error("Pattern too long for this browser.");var e=this.match_alphabet_(b),f=this,g=this.Match_Threshold,h=a.indexOf(b,c);-1!=h&&(g=Math.min(d(0,h),g),h=a.lastIndexOf(b,c+b.length),-1!=h&&(g=Math.min(d(0,h),g)));for(var j=1<=i;p--){var w=e[a.charAt(p-1)];k[p]=0===t?(k[p+1]<<1|1)&w:(k[p+1]<<1|1)&w|((r[p+1]|r[p])<<1|1)|r[p+1];if(k[p]&j&&(w=d(t,p-1),w<=g))if(g=w,h=p-1,h>c)i=Math.max(1,2*c-h);else break}if(d(t+1,c)>g)break;r=k}return h}; +diff_match_patch.prototype.match_alphabet_=function(a){for(var b={},c=0;c=2*this.Patch_Margin&& +e&&(this.patch_addContext_(a,h),c.push(a),a=new diff_match_patch.patch_obj,e=0,h=d,f=g)}1!==i&&(f+=k.length);-1!==i&&(g+=k.length)}e&&(this.patch_addContext_(a,h),c.push(a));return c};diff_match_patch.prototype.patch_deepCopy=function(a){for(var b=[],c=0;cthis.Match_MaxBits){if(j=this.match_main(b,h.substring(0,this.Match_MaxBits),g),-1!=j&&(i=this.match_main(b,h.substring(h.length-this.Match_MaxBits),g+h.length-this.Match_MaxBits),-1==i||j>=i))j=-1}else j=this.match_main(b,h,g); +if(-1==j)e[f]=!1,d-=a[f].length2-a[f].length1;else if(e[f]=!0,d=j-g,g=-1==i?b.substring(j,j+h.length):b.substring(j,i+this.Match_MaxBits),h==g)b=b.substring(0,j)+this.diff_text2(a[f].diffs)+b.substring(j+h.length);else if(g=this.diff_main(h,g,!1),h.length>this.Match_MaxBits&&this.diff_levenshtein(g)/h.length>this.Patch_DeleteThreshold)e[f]=!1;else{this.diff_cleanupSemanticLossless(g);for(var h=0,k,i=0;ie[0][1].length){var f=b-e[0][1].length;e[0][1]=c.substring(e[0][1].length)+e[0][1];d.start1-=f;d.start2-=f;d.length1+=f;d.length2+=f}d=a[a.length-1];e=d.diffs;0==e.length||0!=e[e.length-1][0]?(e.push([0, +c]),d.length1+=b,d.length2+=b):b>e[e.length-1][1].length&&(f=b-e[e.length-1][1].length,e[e.length-1][1]+=c.substring(0,f),d.length1+=f,d.length2+=f);return c}; +diff_match_patch.prototype.patch_splitMax=function(a){for(var b=this.Match_MaxBits,c=0;c2*b?(h.length1+=i.length,e+=i.length,j=!1,h.diffs.push([g,i]),d.diffs.shift()):(i=i.substring(0,b-h.length1-this.Patch_Margin),h.length1+=i.length,e+=i.length,0===g?(h.length2+=i.length,f+=i.length):j=!1,h.diffs.push([g,i]),i==d.diffs[0][1]?d.diffs.shift():d.diffs[0][1]=d.diffs[0][1].substring(i.length))}g=this.diff_text2(h.diffs);g=g.substring(g.length-this.Patch_Margin);i=this.diff_text1(d.diffs).substring(0,this.Patch_Margin);""!==i&& +(h.length1+=i.length,h.length2+=i.length,0!==h.diffs.length&&0===h.diffs[h.diffs.length-1][0]?h.diffs[h.diffs.length-1][1]+=i:h.diffs.push([0,i]));j||a.splice(++c,0,h)}}};diff_match_patch.prototype.patch_toText=function(a){for(var b=[],c=0;c now) return false; - - var sInfo = editor.getScrollInfo(), halfScreen = .5 * sInfo.clientHeight, midY = sInfo.top + halfScreen; - var mid = editor.lineAtHeight(midY, "local"); - var around = chunkBoundariesAround(dv.diff, mid, type == DIFF_INSERT); - var off = getOffsets(editor, type == DIFF_INSERT ? around.edit : around.orig); - var offOther = getOffsets(other, type == DIFF_INSERT ? around.orig : around.edit); - var ratio = (midY - off.top) / (off.bot - off.top); - var targetPos = (offOther.top - halfScreen) + ratio * (offOther.bot - offOther.top); - - var botDist, mix; - // Some careful tweaking to make sure no space is left out of view - // when scrolling to top or bottom. - if (targetPos > sInfo.top && (mix = sInfo.top / halfScreen) < 1) { - targetPos = targetPos * mix + sInfo.top * (1 - mix); - } else if ((botDist = sInfo.height - sInfo.clientHeight - sInfo.top) < halfScreen) { - var otherInfo = other.getScrollInfo(); - var botDistOther = otherInfo.height - otherInfo.clientHeight - targetPos; - if (botDistOther > botDist && (mix = botDist / halfScreen) < 1) - targetPos = targetPos * mix + (otherInfo.height - otherInfo.clientHeight - botDist) * (1 - mix); - } - - other.scrollTo(sInfo.left, targetPos); - other.state.scrollSetAt = now; - other.state.scrollSetBy = dv; - return true; - } - - function getOffsets(editor, around) { - var bot = around.after; - if (bot == null) bot = editor.lastLine() + 1; - return {top: editor.heightAtLine(around.before || 0, "local"), - bot: editor.heightAtLine(bot, "local")}; - } - - function setScrollLock(dv, val, action) { - dv.lockScroll = val; - if (val && action != false) syncScroll(dv, DIFF_INSERT) && drawConnectors(dv); - dv.lockButton.innerHTML = val ? "\u21db\u21da" : "\u21db  \u21da"; - } - - // Updating the marks for editor content - - function clearMarks(editor, arr, classes) { - for (var i = 0; i < arr.length; ++i) { - var mark = arr[i]; - if (mark instanceof CodeMirror.TextMarker) { - mark.clear(); - } else { - editor.removeLineClass(mark, "background", classes.chunk); - editor.removeLineClass(mark, "background", classes.start); - editor.removeLineClass(mark, "background", classes.end); - } - } - arr.length = 0; - } - - // FIXME maybe add a margin around viewport to prevent too many updates - function updateMarks(editor, diff, state, type, classes) { - var vp = editor.getViewport(); - editor.operation(function() { - if (state.from == state.to || vp.from - state.to > 20 || state.from - vp.to > 20) { - clearMarks(editor, state.marked, classes); - markChanges(editor, diff, type, state.marked, vp.from, vp.to, classes); - state.from = vp.from; state.to = vp.to; - } else { - if (vp.from < state.from) { - markChanges(editor, diff, type, state.marked, vp.from, state.from, classes); - state.from = vp.from; - } - if (vp.to > state.to) { - markChanges(editor, diff, type, state.marked, state.to, vp.to, classes); - state.to = vp.to; - } - } - }); - } - - function markChanges(editor, diff, type, marks, from, to, classes) { - var pos = Pos(0, 0); - var top = Pos(from, 0), bot = editor.clipPos(Pos(to - 1)); - var cls = type == DIFF_DELETE ? classes.del : classes.insert; - function markChunk(start, end) { - var bfrom = Math.max(from, start), bto = Math.min(to, end); - for (var i = bfrom; i < bto; ++i) { - var line = editor.addLineClass(i, "background", classes.chunk); - if (i == start) editor.addLineClass(line, "background", classes.start); - if (i == end - 1) editor.addLineClass(line, "background", classes.end); - marks.push(line); - } - // When the chunk is empty, make sure a horizontal line shows up - if (start == end && bfrom == end && bto == end) { - if (bfrom) - marks.push(editor.addLineClass(bfrom - 1, "background", classes.end)); - else - marks.push(editor.addLineClass(bfrom, "background", classes.start)); - } - } - - var chunkStart = 0; - for (var i = 0; i < diff.length; ++i) { - var part = diff[i], tp = part[0], str = part[1]; - if (tp == DIFF_EQUAL) { - var cleanFrom = pos.line + (startOfLineClean(diff, i) ? 0 : 1); - moveOver(pos, str); - var cleanTo = pos.line + (endOfLineClean(diff, i) ? 1 : 0); - if (cleanTo > cleanFrom) { - if (i) markChunk(chunkStart, cleanFrom); - chunkStart = cleanTo; - } - } else { - if (tp == type) { - var end = moveOver(pos, str, true); - var a = posMax(top, pos), b = posMin(bot, end); - if (!posEq(a, b)) - marks.push(editor.markText(a, b, {className: cls})); - pos = end; - } - } - } - if (chunkStart <= pos.line) markChunk(chunkStart, pos.line + 1); - } - - // Updating the gap between editor and original - - function drawConnectors(dv) { - if (!dv.showDifferences) return; - - if (dv.svg) { - clear(dv.svg); - var w = dv.gap.offsetWidth; - attrs(dv.svg, "width", w, "height", dv.gap.offsetHeight); - } - clear(dv.copyButtons); - - var flip = dv.type == "left"; - var vpEdit = dv.edit.getViewport(), vpOrig = dv.orig.getViewport(); - var sTopEdit = dv.edit.getScrollInfo().top, sTopOrig = dv.orig.getScrollInfo().top; - iterateChunks(dv.diff, function(topOrig, botOrig, topEdit, botEdit) { - if (topEdit > vpEdit.to || botEdit < vpEdit.from || - topOrig > vpOrig.to || botOrig < vpOrig.from) - return; - var topLpx = dv.orig.heightAtLine(topOrig, "local") - sTopOrig, top = topLpx; - if (dv.svg) { - var topRpx = dv.edit.heightAtLine(topEdit, "local") - sTopEdit; - if (flip) { var tmp = topLpx; topLpx = topRpx; topRpx = tmp; } - var botLpx = dv.orig.heightAtLine(botOrig, "local") - sTopOrig; - var botRpx = dv.edit.heightAtLine(botEdit, "local") - sTopEdit; - if (flip) { var tmp = botLpx; botLpx = botRpx; botRpx = tmp; } - var curveTop = " C " + w/2 + " " + topRpx + " " + w/2 + " " + topLpx + " " + (w + 2) + " " + topLpx; - var curveBot = " C " + w/2 + " " + botLpx + " " + w/2 + " " + botRpx + " -1 " + botRpx; - attrs(dv.svg.appendChild(document.createElementNS(svgNS, "path")), - "d", "M -1 " + topRpx + curveTop + " L " + (w + 2) + " " + botLpx + curveBot + " z", - "class", dv.classes.connect); - } - var copy = dv.copyButtons.appendChild(elt("div", dv.type == "left" ? "\u21dd" : "\u21dc", - "CodeMirror-merge-copy")); - copy.title = "Revert chunk"; - copy.chunk = {topEdit: topEdit, botEdit: botEdit, topOrig: topOrig, botOrig: botOrig}; - copy.style.top = top + "px"; - }); - } - - function copyChunk(dv, chunk) { - if (dv.diffOutOfDate) return; - dv.edit.replaceRange(dv.orig.getRange(Pos(chunk.topOrig, 0), Pos(chunk.botOrig, 0)), - Pos(chunk.topEdit, 0), Pos(chunk.botEdit, 0)); - } - - // Merge view, containing 0, 1, or 2 diff views. - - var MergeView = CodeMirror.MergeView = function(node, options) { - if (!(this instanceof MergeView)) return new MergeView(node, options); - - var origLeft = options.origLeft, origRight = options.origRight == null ? options.orig : options.origRight; - var hasLeft = origLeft != null, hasRight = origRight != null; - var panes = 1 + (hasLeft ? 1 : 0) + (hasRight ? 1 : 0); - var wrap = [], left = this.left = null, right = this.right = null; - - if (hasLeft) { - left = this.left = new DiffView(this, "left"); - var leftPane = elt("div", null, "CodeMirror-merge-pane"); - wrap.push(leftPane); - wrap.push(buildGap(left)); - } - - var editPane = elt("div", null, "CodeMirror-merge-pane"); - wrap.push(editPane); - - if (hasRight) { - right = this.right = new DiffView(this, "right"); - wrap.push(buildGap(right)); - var rightPane = elt("div", null, "CodeMirror-merge-pane"); - wrap.push(rightPane); - } - - (hasRight ? rightPane : editPane).className += " CodeMirror-merge-pane-rightmost"; - - wrap.push(elt("div", null, null, "height: 0; clear: both;")); - var wrapElt = this.wrap = node.appendChild(elt("div", wrap, "CodeMirror-merge CodeMirror-merge-" + panes + "pane")); - this.edit = CodeMirror(editPane, copyObj(options)); - - if (left) left.init(leftPane, origLeft, options); - if (right) right.init(rightPane, origRight, options); - - var onResize = function() { - if (left) drawConnectors(left); - if (right) drawConnectors(right); - }; - CodeMirror.on(window, "resize", onResize); - var resizeInterval = setInterval(function() { - for (var p = wrapElt.parentNode; p && p != document.body; p = p.parentNode) {} - if (!p) { clearInterval(resizeInterval); CodeMirror.off(window, "resize", onResize); } - }, 5000); - }; - - function buildGap(dv) { - var lock = dv.lockButton = elt("div", null, "CodeMirror-merge-scrolllock"); - lock.title = "Toggle locked scrolling"; - var lockWrap = elt("div", [lock], "CodeMirror-merge-scrolllock-wrap"); - CodeMirror.on(lock, "click", function() { setScrollLock(dv, !dv.lockScroll); }); - dv.copyButtons = elt("div", null, "CodeMirror-merge-copybuttons-" + dv.type); - CodeMirror.on(dv.copyButtons, "click", function(e) { - var node = e.target || e.srcElement; - if (node.chunk) copyChunk(dv, node.chunk); - }); - var gapElts = [dv.copyButtons, lockWrap]; - var svg = document.createElementNS && document.createElementNS(svgNS, "svg"); - if (svg && !svg.createSVGRect) svg = null; - dv.svg = svg; - if (svg) gapElts.push(svg); - - return dv.gap = elt("div", gapElts, "CodeMirror-merge-gap"); - } - - MergeView.prototype = { - constuctor: MergeView, - editor: function() { return this.edit; }, - rightOriginal: function() { return this.right && this.right.orig; }, - leftOriginal: function() { return this.left && this.left.orig; }, - setShowDifferences: function(val) { - if (this.right) this.right.setShowDifferences(val); - if (this.left) this.left.setShowDifferences(val); - } - }; - - // Operations on diffs - - var dmp = new diff_match_patch(); - function getDiff(a, b) { - var diff = dmp.diff_main(a, b); - dmp.diff_cleanupSemantic(diff); - // The library sometimes leaves in empty parts, which confuse the algorithm - for (var i = 0; i < diff.length; ++i) { - var part = diff[i]; - if (!part[1]) { - diff.splice(i--, 1); - } else if (i && diff[i - 1][0] == part[0]) { - diff.splice(i--, 1); - diff[i][1] += part[1]; - } - } - return diff; - } - - function iterateChunks(diff, f) { - var startEdit = 0, startOrig = 0; - var edit = Pos(0, 0), orig = Pos(0, 0); - for (var i = 0; i < diff.length; ++i) { - var part = diff[i], tp = part[0]; - if (tp == DIFF_EQUAL) { - var startOff = startOfLineClean(diff, i) ? 0 : 1; - var cleanFromEdit = edit.line + startOff, cleanFromOrig = orig.line + startOff; - moveOver(edit, part[1], null, orig); - var endOff = endOfLineClean(diff, i) ? 1 : 0; - var cleanToEdit = edit.line + endOff, cleanToOrig = orig.line + endOff; - if (cleanToEdit > cleanFromEdit) { - if (i) f(startOrig, cleanFromOrig, startEdit, cleanFromEdit); - startEdit = cleanToEdit; startOrig = cleanToOrig; - } - } else { - moveOver(tp == DIFF_INSERT ? edit : orig, part[1]); - } - } - if (startEdit <= edit.line || startOrig <= orig.line) - f(startOrig, orig.line + 1, startEdit, edit.line + 1); - } - - function endOfLineClean(diff, i) { - if (i == diff.length - 1) return true; - var next = diff[i + 1][1]; - if (next.length == 1 || next.charCodeAt(0) != 10) return false; - if (i == diff.length - 2) return true; - next = diff[i + 2][1]; - return next.length > 1 && next.charCodeAt(0) == 10; - } - - function startOfLineClean(diff, i) { - if (i == 0) return true; - var last = diff[i - 1][1]; - if (last.charCodeAt(last.length - 1) != 10) return false; - if (i == 1) return true; - last = diff[i - 2][1]; - return last.charCodeAt(last.length - 1) == 10; - } - - function chunkBoundariesAround(diff, n, nInEdit) { - var beforeE, afterE, beforeO, afterO; - iterateChunks(diff, function(fromOrig, toOrig, fromEdit, toEdit) { - var fromLocal = nInEdit ? fromEdit : fromOrig; - var toLocal = nInEdit ? toEdit : toOrig; - if (afterE == null) { - if (fromLocal > n) { afterE = fromEdit; afterO = fromOrig; } - else if (toLocal > n) { afterE = toEdit; afterO = toOrig; } - } - if (toLocal <= n) { beforeE = toEdit; beforeO = toOrig; } - else if (fromLocal <= n) { beforeE = fromEdit; beforeO = fromOrig; } - }); - return {edit: {before: beforeE, after: afterE}, orig: {before: beforeO, after: afterO}}; - } - - // General utilities - - function elt(tag, content, className, style) { - var e = document.createElement(tag); - if (className) e.className = className; - if (style) e.style.cssText = style; - if (typeof content == "string") e.appendChild(document.createTextNode(content)); - else if (content) for (var i = 0; i < content.length; ++i) e.appendChild(content[i]); - return e; - } - - function clear(node) { - for (var count = node.childNodes.length; count > 0; --count) - node.removeChild(node.firstChild); - } - - function attrs(elt) { - for (var i = 1; i < arguments.length; i += 2) - elt.setAttribute(arguments[i], arguments[i+1]); - } - - function copyObj(obj, target) { - if (!target) target = {}; - for (var prop in obj) if (obj.hasOwnProperty(prop)) target[prop] = obj[prop]; - return target; - } - - function moveOver(pos, str, copy, other) { - var out = copy ? Pos(pos.line, pos.ch) : pos, at = 0; - for (;;) { - var nl = str.indexOf("\n", at); - if (nl == -1) break; - ++out.line; - if (other) ++other.line; - at = nl + 1; - } - out.ch = (at ? 0 : out.ch) + (str.length - at); - if (other) other.ch = (at ? 0 : other.ch) + (str.length - at); - return out; - } - - function posMin(a, b) { return (a.line - b.line || a.ch - b.ch) < 0 ? a : b; } - function posMax(a, b) { return (a.line - b.line || a.ch - b.ch) > 0 ? a : b; } - function posEq(a, b) { return a.line == b.line && a.ch == b.ch; } -})(); +(function() { + "use strict"; + + var Pos = CodeMirror.Pos; + var svgNS = "http://www.w3.org/2000/svg"; + + function DiffView(mv, type) { + this.mv = mv; + this.type = type; + this.classes = type == "left" + ? {chunk: "CodeMirror-merge-l-chunk", + start: "CodeMirror-merge-l-chunk-start", + end: "CodeMirror-merge-l-chunk-end", + insert: "CodeMirror-merge-l-inserted", + del: "CodeMirror-merge-l-deleted", + connect: "CodeMirror-merge-l-connect"} + : {chunk: "CodeMirror-merge-r-chunk", + start: "CodeMirror-merge-r-chunk-start", + end: "CodeMirror-merge-r-chunk-end", + insert: "CodeMirror-merge-r-inserted", + del: "CodeMirror-merge-r-deleted", + connect: "CodeMirror-merge-r-connect"}; + } + + DiffView.prototype = { + constructor: DiffView, + init: function(pane, orig, options) { + this.edit = this.mv.edit; + this.orig = CodeMirror(pane, copyObj({value: orig, readOnly: true}, copyObj(options))); + + this.diff = getDiff(orig, options.value); + this.diffOutOfDate = false; + + this.showDifferences = options.showDifferences !== false; + this.forceUpdate = registerUpdate(this); + setScrollLock(this, true, false); + registerScroll(this); + }, + setShowDifferences: function(val) { + val = val !== false; + if (val != this.showDifferences) { + this.showDifferences = val; + this.forceUpdate("full"); + } + } + }; + + function registerUpdate(dv) { + var edit = {from: 0, to: 0, marked: []}; + var orig = {from: 0, to: 0, marked: []}; + var debounceChange; + function update(mode) { + if (mode == "full") { + if (dv.svg) clear(dv.svg); + clear(dv.copyButtons); + clearMarks(dv.edit, edit.marked, dv.classes); + clearMarks(dv.orig, orig.marked, dv.classes); + edit.from = edit.to = orig.from = orig.to = 0; + } + if (dv.diffOutOfDate) { + dv.diff = getDiff(dv.orig.getValue(), dv.edit.getValue()); + dv.diffOutOfDate = false; + CodeMirror.signal(dv.edit, "updateDiff", dv.diff); + } + if (dv.showDifferences) { + updateMarks(dv.edit, dv.diff, edit, DIFF_INSERT, dv.classes); + updateMarks(dv.orig, dv.diff, orig, DIFF_DELETE, dv.classes); + } + drawConnectors(dv); + } + function set(slow) { + clearTimeout(debounceChange); + debounceChange = setTimeout(update, slow == true ? 250 : 100); + } + function change() { + if (!dv.diffOutOfDate) { + dv.diffOutOfDate = true; + edit.from = edit.to = orig.from = orig.to = 0; + } + set(true); + } + dv.edit.on("change", change); + dv.orig.on("change", change); + dv.edit.on("viewportChange", set); + dv.orig.on("viewportChange", set); + update(); + return update; + } + + function registerScroll(dv) { + dv.edit.on("scroll", function() { + syncScroll(dv, DIFF_INSERT) && drawConnectors(dv); + }); + dv.orig.on("scroll", function() { + syncScroll(dv, DIFF_DELETE) && drawConnectors(dv); + }); + } + + function syncScroll(dv, type) { + // Change handler will do a refresh after a timeout when diff is out of date + if (dv.diffOutOfDate) return false; + if (!dv.lockScroll) return true; + var editor, other, now = +new Date; + if (type == DIFF_INSERT) { editor = dv.edit; other = dv.orig; } + else { editor = dv.orig; other = dv.edit; } + // Don't take action if the position of this editor was recently set + // (to prevent feedback loops) + if (editor.state.scrollSetBy == dv && (editor.state.scrollSetAt || 0) + 50 > now) return false; + + var sInfo = editor.getScrollInfo(), halfScreen = .5 * sInfo.clientHeight, midY = sInfo.top + halfScreen; + var mid = editor.lineAtHeight(midY, "local"); + var around = chunkBoundariesAround(dv.diff, mid, type == DIFF_INSERT); + var off = getOffsets(editor, type == DIFF_INSERT ? around.edit : around.orig); + var offOther = getOffsets(other, type == DIFF_INSERT ? around.orig : around.edit); + var ratio = (midY - off.top) / (off.bot - off.top); + var targetPos = (offOther.top - halfScreen) + ratio * (offOther.bot - offOther.top); + + var botDist, mix; + // Some careful tweaking to make sure no space is left out of view + // when scrolling to top or bottom. + if (targetPos > sInfo.top && (mix = sInfo.top / halfScreen) < 1) { + targetPos = targetPos * mix + sInfo.top * (1 - mix); + } else if ((botDist = sInfo.height - sInfo.clientHeight - sInfo.top) < halfScreen) { + var otherInfo = other.getScrollInfo(); + var botDistOther = otherInfo.height - otherInfo.clientHeight - targetPos; + if (botDistOther > botDist && (mix = botDist / halfScreen) < 1) + targetPos = targetPos * mix + (otherInfo.height - otherInfo.clientHeight - botDist) * (1 - mix); + } + + other.scrollTo(sInfo.left, targetPos); + other.state.scrollSetAt = now; + other.state.scrollSetBy = dv; + return true; + } + + function getOffsets(editor, around) { + var bot = around.after; + if (bot == null) bot = editor.lastLine() + 1; + return {top: editor.heightAtLine(around.before || 0, "local"), + bot: editor.heightAtLine(bot, "local")}; + } + + function setScrollLock(dv, val, action) { + dv.lockScroll = val; + if (val && action != false) syncScroll(dv, DIFF_INSERT) && drawConnectors(dv); + dv.lockButton.innerHTML = val ? "\u21db\u21da" : "\u21db  \u21da"; + } + + // Updating the marks for editor content + + function clearMarks(editor, arr, classes) { + for (var i = 0; i < arr.length; ++i) { + var mark = arr[i]; + if (mark instanceof CodeMirror.TextMarker) { + mark.clear(); + } else { + editor.removeLineClass(mark, "background", classes.chunk); + editor.removeLineClass(mark, "background", classes.start); + editor.removeLineClass(mark, "background", classes.end); + } + } + arr.length = 0; + } + + // FIXME maybe add a margin around viewport to prevent too many updates + function updateMarks(editor, diff, state, type, classes) { + var vp = editor.getViewport(); + editor.operation(function() { + if (state.from == state.to || vp.from - state.to > 20 || state.from - vp.to > 20) { + clearMarks(editor, state.marked, classes); + markChanges(editor, diff, type, state.marked, vp.from, vp.to, classes); + state.from = vp.from; state.to = vp.to; + } else { + if (vp.from < state.from) { + markChanges(editor, diff, type, state.marked, vp.from, state.from, classes); + state.from = vp.from; + } + if (vp.to > state.to) { + markChanges(editor, diff, type, state.marked, state.to, vp.to, classes); + state.to = vp.to; + } + } + }); + } + + function markChanges(editor, diff, type, marks, from, to, classes) { + var pos = Pos(0, 0); + var top = Pos(from, 0), bot = editor.clipPos(Pos(to - 1)); + var cls = type == DIFF_DELETE ? classes.del : classes.insert; + function markChunk(start, end) { + var bfrom = Math.max(from, start), bto = Math.min(to, end); + for (var i = bfrom; i < bto; ++i) { + var line = editor.addLineClass(i, "background", classes.chunk); + if (i == start) editor.addLineClass(line, "background", classes.start); + if (i == end - 1) editor.addLineClass(line, "background", classes.end); + marks.push(line); + } + // When the chunk is empty, make sure a horizontal line shows up + if (start == end && bfrom == end && bto == end) { + if (bfrom) + marks.push(editor.addLineClass(bfrom - 1, "background", classes.end)); + else + marks.push(editor.addLineClass(bfrom, "background", classes.start)); + } + } + + var chunkStart = 0; + for (var i = 0; i < diff.length; ++i) { + var part = diff[i], tp = part[0], str = part[1]; + if (tp == DIFF_EQUAL) { + var cleanFrom = pos.line + (startOfLineClean(diff, i) ? 0 : 1); + moveOver(pos, str); + var cleanTo = pos.line + (endOfLineClean(diff, i) ? 1 : 0); + if (cleanTo > cleanFrom) { + if (i) markChunk(chunkStart, cleanFrom); + chunkStart = cleanTo; + } + } else { + if (tp == type) { + var end = moveOver(pos, str, true); + var a = posMax(top, pos), b = posMin(bot, end); + if (!posEq(a, b)) + marks.push(editor.markText(a, b, {className: cls})); + pos = end; + } + } + } + if (chunkStart <= pos.line) markChunk(chunkStart, pos.line + 1); + } + + // Updating the gap between editor and original + + function drawConnectors(dv) { + if (!dv.showDifferences) return; + + if (dv.svg) { + clear(dv.svg); + var w = dv.gap.offsetWidth; + attrs(dv.svg, "width", w, "height", dv.gap.offsetHeight); + } + clear(dv.copyButtons); + + var flip = dv.type == "left"; + var vpEdit = dv.edit.getViewport(), vpOrig = dv.orig.getViewport(); + var sTopEdit = dv.edit.getScrollInfo().top, sTopOrig = dv.orig.getScrollInfo().top; + iterateChunks(dv.diff, function(topOrig, botOrig, topEdit, botEdit) { + if (topEdit > vpEdit.to || botEdit < vpEdit.from || + topOrig > vpOrig.to || botOrig < vpOrig.from) + return; + var topLpx = dv.orig.heightAtLine(topOrig, "local") - sTopOrig, top = topLpx; + if (dv.svg) { + var topRpx = dv.edit.heightAtLine(topEdit, "local") - sTopEdit; + if (flip) { var tmp = topLpx; topLpx = topRpx; topRpx = tmp; } + var botLpx = dv.orig.heightAtLine(botOrig, "local") - sTopOrig; + var botRpx = dv.edit.heightAtLine(botEdit, "local") - sTopEdit; + if (flip) { var tmp = botLpx; botLpx = botRpx; botRpx = tmp; } + var curveTop = " C " + w/2 + " " + topRpx + " " + w/2 + " " + topLpx + " " + (w + 2) + " " + topLpx; + var curveBot = " C " + w/2 + " " + botLpx + " " + w/2 + " " + botRpx + " -1 " + botRpx; + attrs(dv.svg.appendChild(document.createElementNS(svgNS, "path")), + "d", "M -1 " + topRpx + curveTop + " L " + (w + 2) + " " + botLpx + curveBot + " z", + "class", dv.classes.connect); + } + var copy = dv.copyButtons.appendChild(elt("div", dv.type == "left" ? "\u21dd" : "\u21dc", + "CodeMirror-merge-copy")); + copy.title = "Revert chunk"; + copy.chunk = {topEdit: topEdit, botEdit: botEdit, topOrig: topOrig, botOrig: botOrig}; + copy.style.top = top + "px"; + }); + } + + function copyChunk(dv, chunk) { + if (dv.diffOutOfDate) return; + dv.edit.replaceRange(dv.orig.getRange(Pos(chunk.topOrig, 0), Pos(chunk.botOrig, 0)), + Pos(chunk.topEdit, 0), Pos(chunk.botEdit, 0)); + } + + // Merge view, containing 0, 1, or 2 diff views. + + var MergeView = CodeMirror.MergeView = function(node, options) { + if (!(this instanceof MergeView)) return new MergeView(node, options); + + var origLeft = options.origLeft, origRight = options.origRight == null ? options.orig : options.origRight; + var hasLeft = origLeft != null, hasRight = origRight != null; + var panes = 1 + (hasLeft ? 1 : 0) + (hasRight ? 1 : 0); + var wrap = [], left = this.left = null, right = this.right = null; + + if (hasLeft) { + left = this.left = new DiffView(this, "left"); + var leftPane = elt("div", null, "CodeMirror-merge-pane"); + wrap.push(leftPane); + wrap.push(buildGap(left)); + } + + var editPane = elt("div", null, "CodeMirror-merge-pane"); + wrap.push(editPane); + + if (hasRight) { + right = this.right = new DiffView(this, "right"); + wrap.push(buildGap(right)); + var rightPane = elt("div", null, "CodeMirror-merge-pane"); + wrap.push(rightPane); + } + + (hasRight ? rightPane : editPane).className += " CodeMirror-merge-pane-rightmost"; + + wrap.push(elt("div", null, null, "height: 0; clear: both;")); + var wrapElt = this.wrap = node.appendChild(elt("div", wrap, "CodeMirror-merge CodeMirror-merge-" + panes + "pane")); + this.edit = CodeMirror(editPane, copyObj(options)); + + if (left) left.init(leftPane, origLeft, options); + if (right) right.init(rightPane, origRight, options); + + var onResize = function() { + if (left) drawConnectors(left); + if (right) drawConnectors(right); + }; + CodeMirror.on(window, "resize", onResize); + var resizeInterval = setInterval(function() { + for (var p = wrapElt.parentNode; p && p != document.body; p = p.parentNode) {} + if (!p) { clearInterval(resizeInterval); CodeMirror.off(window, "resize", onResize); } + }, 5000); + }; + + function buildGap(dv) { + var lock = dv.lockButton = elt("div", null, "CodeMirror-merge-scrolllock"); + lock.title = "Toggle locked scrolling"; + var lockWrap = elt("div", [lock], "CodeMirror-merge-scrolllock-wrap"); + CodeMirror.on(lock, "click", function() { setScrollLock(dv, !dv.lockScroll); }); + dv.copyButtons = elt("div", null, "CodeMirror-merge-copybuttons-" + dv.type); + CodeMirror.on(dv.copyButtons, "click", function(e) { + var node = e.target || e.srcElement; + if (node.chunk) copyChunk(dv, node.chunk); + }); + var gapElts = [dv.copyButtons, lockWrap]; + var svg = document.createElementNS && document.createElementNS(svgNS, "svg"); + if (svg && !svg.createSVGRect) svg = null; + dv.svg = svg; + if (svg) gapElts.push(svg); + + return dv.gap = elt("div", gapElts, "CodeMirror-merge-gap"); + } + + MergeView.prototype = { + constuctor: MergeView, + editor: function() { return this.edit; }, + rightOriginal: function() { return this.right && this.right.orig; }, + leftOriginal: function() { return this.left && this.left.orig; }, + setShowDifferences: function(val) { + if (this.right) this.right.setShowDifferences(val); + if (this.left) this.left.setShowDifferences(val); + } + }; + + // Operations on diffs + + var dmp = new diff_match_patch(); + function getDiff(a, b) { + var diff = dmp.diff_main(a, b); + dmp.diff_cleanupSemantic(diff); + // The library sometimes leaves in empty parts, which confuse the algorithm + for (var i = 0; i < diff.length; ++i) { + var part = diff[i]; + if (!part[1]) { + diff.splice(i--, 1); + } else if (i && diff[i - 1][0] == part[0]) { + diff.splice(i--, 1); + diff[i][1] += part[1]; + } + } + return diff; + } + + function iterateChunks(diff, f) { + var startEdit = 0, startOrig = 0; + var edit = Pos(0, 0), orig = Pos(0, 0); + for (var i = 0; i < diff.length; ++i) { + var part = diff[i], tp = part[0]; + if (tp == DIFF_EQUAL) { + var startOff = startOfLineClean(diff, i) ? 0 : 1; + var cleanFromEdit = edit.line + startOff, cleanFromOrig = orig.line + startOff; + moveOver(edit, part[1], null, orig); + var endOff = endOfLineClean(diff, i) ? 1 : 0; + var cleanToEdit = edit.line + endOff, cleanToOrig = orig.line + endOff; + if (cleanToEdit > cleanFromEdit) { + if (i) f(startOrig, cleanFromOrig, startEdit, cleanFromEdit); + startEdit = cleanToEdit; startOrig = cleanToOrig; + } + } else { + moveOver(tp == DIFF_INSERT ? edit : orig, part[1]); + } + } + if (startEdit <= edit.line || startOrig <= orig.line) + f(startOrig, orig.line + 1, startEdit, edit.line + 1); + } + + function endOfLineClean(diff, i) { + if (i == diff.length - 1) return true; + var next = diff[i + 1][1]; + if (next.length == 1 || next.charCodeAt(0) != 10) return false; + if (i == diff.length - 2) return true; + next = diff[i + 2][1]; + return next.length > 1 && next.charCodeAt(0) == 10; + } + + function startOfLineClean(diff, i) { + if (i == 0) return true; + var last = diff[i - 1][1]; + if (last.charCodeAt(last.length - 1) != 10) return false; + if (i == 1) return true; + last = diff[i - 2][1]; + return last.charCodeAt(last.length - 1) == 10; + } + + function chunkBoundariesAround(diff, n, nInEdit) { + var beforeE, afterE, beforeO, afterO; + iterateChunks(diff, function(fromOrig, toOrig, fromEdit, toEdit) { + var fromLocal = nInEdit ? fromEdit : fromOrig; + var toLocal = nInEdit ? toEdit : toOrig; + if (afterE == null) { + if (fromLocal > n) { afterE = fromEdit; afterO = fromOrig; } + else if (toLocal > n) { afterE = toEdit; afterO = toOrig; } + } + if (toLocal <= n) { beforeE = toEdit; beforeO = toOrig; } + else if (fromLocal <= n) { beforeE = fromEdit; beforeO = fromOrig; } + }); + return {edit: {before: beforeE, after: afterE}, orig: {before: beforeO, after: afterO}}; + } + + // General utilities + + function elt(tag, content, className, style) { + var e = document.createElement(tag); + if (className) e.className = className; + if (style) e.style.cssText = style; + if (typeof content == "string") e.appendChild(document.createTextNode(content)); + else if (content) for (var i = 0; i < content.length; ++i) e.appendChild(content[i]); + return e; + } + + function clear(node) { + for (var count = node.childNodes.length; count > 0; --count) + node.removeChild(node.firstChild); + } + + function attrs(elt) { + for (var i = 1; i < arguments.length; i += 2) + elt.setAttribute(arguments[i], arguments[i+1]); + } + + function copyObj(obj, target) { + if (!target) target = {}; + for (var prop in obj) if (obj.hasOwnProperty(prop)) target[prop] = obj[prop]; + return target; + } + + function moveOver(pos, str, copy, other) { + var out = copy ? Pos(pos.line, pos.ch) : pos, at = 0; + for (;;) { + var nl = str.indexOf("\n", at); + if (nl == -1) break; + ++out.line; + if (other) ++other.line; + at = nl + 1; + } + out.ch = (at ? 0 : out.ch) + (str.length - at); + if (other) other.ch = (at ? 0 : other.ch) + (str.length - at); + return out; + } + + function posMin(a, b) { return (a.line - b.line || a.ch - b.ch) < 0 ? a : b; } + function posMax(a, b) { return (a.line - b.line || a.ch - b.ch) > 0 ? a : b; } + function posEq(a, b) { return a.line == b.line && a.ch == b.ch; } +})(); diff --git a/profile-builder/assets/lib/codemirror/addon/mode/loadmode.js b/profile-builder/assets/lib/codemirror/addon/mode/loadmode.js index 60fafbb..a6c56f7 100644 --- a/profile-builder/assets/lib/codemirror/addon/mode/loadmode.js +++ b/profile-builder/assets/lib/codemirror/addon/mode/loadmode.js @@ -1,51 +1,51 @@ -(function() { - if (!CodeMirror.modeURL) CodeMirror.modeURL = "../mode/%N/%N.js"; - - var loading = {}; - function splitCallback(cont, n) { - var countDown = n; - return function() { if (--countDown == 0) cont(); }; - } - function ensureDeps(mode, cont) { - var deps = CodeMirror.modes[mode].dependencies; - if (!deps) return cont(); - var missing = []; - for (var i = 0; i < deps.length; ++i) { - if (!CodeMirror.modes.hasOwnProperty(deps[i])) - missing.push(deps[i]); - } - if (!missing.length) return cont(); - var split = splitCallback(cont, missing.length); - for (var i = 0; i < missing.length; ++i) - CodeMirror.requireMode(missing[i], split); - } - - CodeMirror.requireMode = function(mode, cont) { - if (typeof mode != "string") mode = mode.name; - if (CodeMirror.modes.hasOwnProperty(mode)) return ensureDeps(mode, cont); - if (loading.hasOwnProperty(mode)) return loading[mode].push(cont); - - var script = document.createElement("script"); - script.src = CodeMirror.modeURL.replace(/%N/g, mode); - var others = document.getElementsByTagName("script")[0]; - others.parentNode.insertBefore(script, others); - var list = loading[mode] = [cont]; - var count = 0, poll = setInterval(function() { - if (++count > 100) return clearInterval(poll); - if (CodeMirror.modes.hasOwnProperty(mode)) { - clearInterval(poll); - loading[mode] = null; - ensureDeps(mode, function() { - for (var i = 0; i < list.length; ++i) list[i](); - }); - } - }, 200); - }; - - CodeMirror.autoLoadMode = function(instance, mode) { - if (!CodeMirror.modes.hasOwnProperty(mode)) - CodeMirror.requireMode(mode, function() { - instance.setOption("mode", instance.getOption("mode")); - }); - }; -}()); +(function() { + if (!CodeMirror.modeURL) CodeMirror.modeURL = "../mode/%N/%N.js"; + + var loading = {}; + function splitCallback(cont, n) { + var countDown = n; + return function() { if (--countDown == 0) cont(); }; + } + function ensureDeps(mode, cont) { + var deps = CodeMirror.modes[mode].dependencies; + if (!deps) return cont(); + var missing = []; + for (var i = 0; i < deps.length; ++i) { + if (!CodeMirror.modes.hasOwnProperty(deps[i])) + missing.push(deps[i]); + } + if (!missing.length) return cont(); + var split = splitCallback(cont, missing.length); + for (var i = 0; i < missing.length; ++i) + CodeMirror.requireMode(missing[i], split); + } + + CodeMirror.requireMode = function(mode, cont) { + if (typeof mode != "string") mode = mode.name; + if (CodeMirror.modes.hasOwnProperty(mode)) return ensureDeps(mode, cont); + if (loading.hasOwnProperty(mode)) return loading[mode].push(cont); + + var script = document.createElement("script"); + script.src = CodeMirror.modeURL.replace(/%N/g, mode); + var others = document.getElementsByTagName("script")[0]; + others.parentNode.insertBefore(script, others); + var list = loading[mode] = [cont]; + var count = 0, poll = setInterval(function() { + if (++count > 100) return clearInterval(poll); + if (CodeMirror.modes.hasOwnProperty(mode)) { + clearInterval(poll); + loading[mode] = null; + ensureDeps(mode, function() { + for (var i = 0; i < list.length; ++i) list[i](); + }); + } + }, 200); + }; + + CodeMirror.autoLoadMode = function(instance, mode) { + if (!CodeMirror.modes.hasOwnProperty(mode)) + CodeMirror.requireMode(mode, function() { + instance.setOption("mode", instance.getOption("mode")); + }); + }; +}()); diff --git a/profile-builder/assets/lib/codemirror/addon/mode/multiplex.js b/profile-builder/assets/lib/codemirror/addon/mode/multiplex.js index 32cc579..41fa484 100644 --- a/profile-builder/assets/lib/codemirror/addon/mode/multiplex.js +++ b/profile-builder/assets/lib/codemirror/addon/mode/multiplex.js @@ -1,101 +1,101 @@ -CodeMirror.multiplexingMode = function(outer /*, others */) { - // Others should be {open, close, mode [, delimStyle] [, innerStyle]} objects - var others = Array.prototype.slice.call(arguments, 1); - var n_others = others.length; - - function indexOf(string, pattern, from) { - if (typeof pattern == "string") return string.indexOf(pattern, from); - var m = pattern.exec(from ? string.slice(from) : string); - return m ? m.index + from : -1; - } - - return { - startState: function() { - return { - outer: CodeMirror.startState(outer), - innerActive: null, - inner: null - }; - }, - - copyState: function(state) { - return { - outer: CodeMirror.copyState(outer, state.outer), - innerActive: state.innerActive, - inner: state.innerActive && CodeMirror.copyState(state.innerActive.mode, state.inner) - }; - }, - - token: function(stream, state) { - if (!state.innerActive) { - var cutOff = Infinity, oldContent = stream.string; - for (var i = 0; i < n_others; ++i) { - var other = others[i]; - var found = indexOf(oldContent, other.open, stream.pos); - if (found == stream.pos) { - stream.match(other.open); - state.innerActive = other; - state.inner = CodeMirror.startState(other.mode, outer.indent ? outer.indent(state.outer, "") : 0); - return other.delimStyle; - } else if (found != -1 && found < cutOff) { - cutOff = found; - } - } - if (cutOff != Infinity) stream.string = oldContent.slice(0, cutOff); - var outerToken = outer.token(stream, state.outer); - if (cutOff != Infinity) stream.string = oldContent; - return outerToken; - } else { - var curInner = state.innerActive, oldContent = stream.string; - var found = indexOf(oldContent, curInner.close, stream.pos); - if (found == stream.pos) { - stream.match(curInner.close); - state.innerActive = state.inner = null; - return curInner.delimStyle; - } - if (found > -1) stream.string = oldContent.slice(0, found); - var innerToken = curInner.mode.token(stream, state.inner); - if (found > -1) stream.string = oldContent; - var cur = stream.current(), found = cur.indexOf(curInner.close); - if (found > -1) stream.backUp(cur.length - found); - - if (curInner.innerStyle) { - if (innerToken) innerToken = innerToken + ' ' + curInner.innerStyle; - else innerToken = curInner.innerStyle; - } - - return innerToken; - } - }, - - indent: function(state, textAfter) { - var mode = state.innerActive ? state.innerActive.mode : outer; - if (!mode.indent) return CodeMirror.Pass; - return mode.indent(state.innerActive ? state.inner : state.outer, textAfter); - }, - - blankLine: function(state) { - var mode = state.innerActive ? state.innerActive.mode : outer; - if (mode.blankLine) { - mode.blankLine(state.innerActive ? state.inner : state.outer); - } - if (!state.innerActive) { - for (var i = 0; i < n_others; ++i) { - var other = others[i]; - if (other.open === "\n") { - state.innerActive = other; - state.inner = CodeMirror.startState(other.mode, mode.indent ? mode.indent(state.outer, "") : 0); - } - } - } else if (state.innerActive.close === "\n") { - state.innerActive = state.inner = null; - } - }, - - electricChars: outer.electricChars, - - innerMode: function(state) { - return state.inner ? {state: state.inner, mode: state.innerActive.mode} : {state: state.outer, mode: outer}; - } - }; -}; +CodeMirror.multiplexingMode = function(outer /*, others */) { + // Others should be {open, close, mode [, delimStyle] [, innerStyle]} objects + var others = Array.prototype.slice.call(arguments, 1); + var n_others = others.length; + + function indexOf(string, pattern, from) { + if (typeof pattern == "string") return string.indexOf(pattern, from); + var m = pattern.exec(from ? string.slice(from) : string); + return m ? m.index + from : -1; + } + + return { + startState: function() { + return { + outer: CodeMirror.startState(outer), + innerActive: null, + inner: null + }; + }, + + copyState: function(state) { + return { + outer: CodeMirror.copyState(outer, state.outer), + innerActive: state.innerActive, + inner: state.innerActive && CodeMirror.copyState(state.innerActive.mode, state.inner) + }; + }, + + token: function(stream, state) { + if (!state.innerActive) { + var cutOff = Infinity, oldContent = stream.string; + for (var i = 0; i < n_others; ++i) { + var other = others[i]; + var found = indexOf(oldContent, other.open, stream.pos); + if (found == stream.pos) { + stream.match(other.open); + state.innerActive = other; + state.inner = CodeMirror.startState(other.mode, outer.indent ? outer.indent(state.outer, "") : 0); + return other.delimStyle; + } else if (found != -1 && found < cutOff) { + cutOff = found; + } + } + if (cutOff != Infinity) stream.string = oldContent.slice(0, cutOff); + var outerToken = outer.token(stream, state.outer); + if (cutOff != Infinity) stream.string = oldContent; + return outerToken; + } else { + var curInner = state.innerActive, oldContent = stream.string; + var found = indexOf(oldContent, curInner.close, stream.pos); + if (found == stream.pos) { + stream.match(curInner.close); + state.innerActive = state.inner = null; + return curInner.delimStyle; + } + if (found > -1) stream.string = oldContent.slice(0, found); + var innerToken = curInner.mode.token(stream, state.inner); + if (found > -1) stream.string = oldContent; + var cur = stream.current(), found = cur.indexOf(curInner.close); + if (found > -1) stream.backUp(cur.length - found); + + if (curInner.innerStyle) { + if (innerToken) innerToken = innerToken + ' ' + curInner.innerStyle; + else innerToken = curInner.innerStyle; + } + + return innerToken; + } + }, + + indent: function(state, textAfter) { + var mode = state.innerActive ? state.innerActive.mode : outer; + if (!mode.indent) return CodeMirror.Pass; + return mode.indent(state.innerActive ? state.inner : state.outer, textAfter); + }, + + blankLine: function(state) { + var mode = state.innerActive ? state.innerActive.mode : outer; + if (mode.blankLine) { + mode.blankLine(state.innerActive ? state.inner : state.outer); + } + if (!state.innerActive) { + for (var i = 0; i < n_others; ++i) { + var other = others[i]; + if (other.open === "\n") { + state.innerActive = other; + state.inner = CodeMirror.startState(other.mode, mode.indent ? mode.indent(state.outer, "") : 0); + } + } + } else if (state.innerActive.close === "\n") { + state.innerActive = state.inner = null; + } + }, + + electricChars: outer.electricChars, + + innerMode: function(state) { + return state.inner ? {state: state.inner, mode: state.innerActive.mode} : {state: state.outer, mode: outer}; + } + }; +}; diff --git a/profile-builder/assets/lib/codemirror/addon/mode/multiplex_test.js b/profile-builder/assets/lib/codemirror/addon/mode/multiplex_test.js index c065635..c4ad4b3 100644 --- a/profile-builder/assets/lib/codemirror/addon/mode/multiplex_test.js +++ b/profile-builder/assets/lib/codemirror/addon/mode/multiplex_test.js @@ -1,30 +1,30 @@ -(function() { - CodeMirror.defineMode("markdown_with_stex", function(){ - var inner = CodeMirror.getMode({}, "stex"); - var outer = CodeMirror.getMode({}, "markdown"); - - var innerOptions = { - open: '$', - close: '$', - mode: inner, - delimStyle: 'delim', - innerStyle: 'inner' - }; - - return CodeMirror.multiplexingMode(outer, innerOptions); - }); - - var mode = CodeMirror.getMode({}, "markdown_with_stex"); - - function MT(name) { - test.mode( - name, - mode, - Array.prototype.slice.call(arguments, 1), - 'multiplexing'); - } - - MT( - "stexInsideMarkdown", - "[strong **Equation:**] [delim $][inner&tag \\pi][delim $]"); -})(); +(function() { + CodeMirror.defineMode("markdown_with_stex", function(){ + var inner = CodeMirror.getMode({}, "stex"); + var outer = CodeMirror.getMode({}, "markdown"); + + var innerOptions = { + open: '$', + close: '$', + mode: inner, + delimStyle: 'delim', + innerStyle: 'inner' + }; + + return CodeMirror.multiplexingMode(outer, innerOptions); + }); + + var mode = CodeMirror.getMode({}, "markdown_with_stex"); + + function MT(name) { + test.mode( + name, + mode, + Array.prototype.slice.call(arguments, 1), + 'multiplexing'); + } + + MT( + "stexInsideMarkdown", + "[strong **Equation:**] [delim $][inner&tag \\pi][delim $]"); +})(); diff --git a/profile-builder/assets/lib/codemirror/addon/mode/overlay.js b/profile-builder/assets/lib/codemirror/addon/mode/overlay.js index b7928a7..ee9afcb 100644 --- a/profile-builder/assets/lib/codemirror/addon/mode/overlay.js +++ b/profile-builder/assets/lib/codemirror/addon/mode/overlay.js @@ -1,59 +1,59 @@ -// Utility function that allows modes to be combined. The mode given -// as the base argument takes care of most of the normal mode -// functionality, but a second (typically simple) mode is used, which -// can override the style of text. Both modes get to parse all of the -// text, but when both assign a non-null style to a piece of code, the -// overlay wins, unless the combine argument was true, in which case -// the styles are combined. - -// overlayParser is the old, deprecated name -CodeMirror.overlayMode = CodeMirror.overlayParser = function(base, overlay, combine) { - return { - startState: function() { - return { - base: CodeMirror.startState(base), - overlay: CodeMirror.startState(overlay), - basePos: 0, baseCur: null, - overlayPos: 0, overlayCur: null - }; - }, - copyState: function(state) { - return { - base: CodeMirror.copyState(base, state.base), - overlay: CodeMirror.copyState(overlay, state.overlay), - basePos: state.basePos, baseCur: null, - overlayPos: state.overlayPos, overlayCur: null - }; - }, - - token: function(stream, state) { - if (stream.start == state.basePos) { - state.baseCur = base.token(stream, state.base); - state.basePos = stream.pos; - } - if (stream.start == state.overlayPos) { - stream.pos = stream.start; - state.overlayCur = overlay.token(stream, state.overlay); - state.overlayPos = stream.pos; - } - stream.pos = Math.min(state.basePos, state.overlayPos); - if (stream.eol()) state.basePos = state.overlayPos = 0; - - if (state.overlayCur == null) return state.baseCur; - if (state.baseCur != null && combine) return state.baseCur + " " + state.overlayCur; - else return state.overlayCur; - }, - - indent: base.indent && function(state, textAfter) { - return base.indent(state.base, textAfter); - }, - electricChars: base.electricChars, - - innerMode: function(state) { return {state: state.base, mode: base}; }, - - blankLine: function(state) { - if (base.blankLine) base.blankLine(state.base); - if (overlay.blankLine) overlay.blankLine(state.overlay); - } - }; -}; +// Utility function that allows modes to be combined. The mode given +// as the base argument takes care of most of the normal mode +// functionality, but a second (typically simple) mode is used, which +// can override the style of text. Both modes get to parse all of the +// text, but when both assign a non-null style to a piece of code, the +// overlay wins, unless the combine argument was true, in which case +// the styles are combined. + +// overlayParser is the old, deprecated name +CodeMirror.overlayMode = CodeMirror.overlayParser = function(base, overlay, combine) { + return { + startState: function() { + return { + base: CodeMirror.startState(base), + overlay: CodeMirror.startState(overlay), + basePos: 0, baseCur: null, + overlayPos: 0, overlayCur: null + }; + }, + copyState: function(state) { + return { + base: CodeMirror.copyState(base, state.base), + overlay: CodeMirror.copyState(overlay, state.overlay), + basePos: state.basePos, baseCur: null, + overlayPos: state.overlayPos, overlayCur: null + }; + }, + + token: function(stream, state) { + if (stream.start == state.basePos) { + state.baseCur = base.token(stream, state.base); + state.basePos = stream.pos; + } + if (stream.start == state.overlayPos) { + stream.pos = stream.start; + state.overlayCur = overlay.token(stream, state.overlay); + state.overlayPos = stream.pos; + } + stream.pos = Math.min(state.basePos, state.overlayPos); + if (stream.eol()) state.basePos = state.overlayPos = 0; + + if (state.overlayCur == null) return state.baseCur; + if (state.baseCur != null && combine) return state.baseCur + " " + state.overlayCur; + else return state.overlayCur; + }, + + indent: base.indent && function(state, textAfter) { + return base.indent(state.base, textAfter); + }, + electricChars: base.electricChars, + + innerMode: function(state) { return {state: state.base, mode: base}; }, + + blankLine: function(state) { + if (base.blankLine) base.blankLine(state.base); + if (overlay.blankLine) overlay.blankLine(state.overlay); + } + }; +}; diff --git a/profile-builder/assets/lib/codemirror/addon/runmode/colorize.js b/profile-builder/assets/lib/codemirror/addon/runmode/colorize.js index 62286d2..ab3af17 100644 --- a/profile-builder/assets/lib/codemirror/addon/runmode/colorize.js +++ b/profile-builder/assets/lib/codemirror/addon/runmode/colorize.js @@ -1,29 +1,29 @@ -CodeMirror.colorize = (function() { - - var isBlock = /^(p|li|div|h\\d|pre|blockquote|td)$/; - - function textContent(node, out) { - if (node.nodeType == 3) return out.push(node.nodeValue); - for (var ch = node.firstChild; ch; ch = ch.nextSibling) { - textContent(ch, out); - if (isBlock.test(node.nodeType)) out.push("\n"); - } - } - - return function(collection, defaultMode) { - if (!collection) collection = document.body.getElementsByTagName("pre"); - - for (var i = 0; i < collection.length; ++i) { - var node = collection[i]; - var mode = node.getAttribute("data-lang") || defaultMode; - if (!mode) continue; - - var text = []; - textContent(node, text); - node.innerHTML = ""; - CodeMirror.runMode(text.join(""), mode, node); - - node.className += " cm-s-default"; - } - }; -})(); +CodeMirror.colorize = (function() { + + var isBlock = /^(p|li|div|h\\d|pre|blockquote|td)$/; + + function textContent(node, out) { + if (node.nodeType == 3) return out.push(node.nodeValue); + for (var ch = node.firstChild; ch; ch = ch.nextSibling) { + textContent(ch, out); + if (isBlock.test(node.nodeType)) out.push("\n"); + } + } + + return function(collection, defaultMode) { + if (!collection) collection = document.body.getElementsByTagName("pre"); + + for (var i = 0; i < collection.length; ++i) { + var node = collection[i]; + var mode = node.getAttribute("data-lang") || defaultMode; + if (!mode) continue; + + var text = []; + textContent(node, text); + node.innerHTML = ""; + CodeMirror.runMode(text.join(""), mode, node); + + node.className += " cm-s-default"; + } + }; +})(); diff --git a/profile-builder/assets/lib/codemirror/addon/runmode/runmode-standalone.js b/profile-builder/assets/lib/codemirror/addon/runmode/runmode-standalone.js index 0fb98a9..adc6fce 100644 --- a/profile-builder/assets/lib/codemirror/addon/runmode/runmode-standalone.js +++ b/profile-builder/assets/lib/codemirror/addon/runmode/runmode-standalone.js @@ -1,132 +1,132 @@ -/* Just enough of CodeMirror to run runMode under node.js */ - -window.CodeMirror = {}; - -function splitLines(string){ return string.split(/\r?\n|\r/); }; - -function StringStream(string) { - this.pos = this.start = 0; - this.string = string; -} -StringStream.prototype = { - eol: function() {return this.pos >= this.string.length;}, - sol: function() {return this.pos == 0;}, - peek: function() {return this.string.charAt(this.pos) || null;}, - next: function() { - if (this.pos < this.string.length) - return this.string.charAt(this.pos++); - }, - eat: function(match) { - var ch = this.string.charAt(this.pos); - if (typeof match == "string") var ok = ch == match; - else var ok = ch && (match.test ? match.test(ch) : match(ch)); - if (ok) {++this.pos; return ch;} - }, - eatWhile: function(match) { - var start = this.pos; - while (this.eat(match)){} - return this.pos > start; - }, - eatSpace: function() { - var start = this.pos; - while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos; - return this.pos > start; - }, - skipToEnd: function() {this.pos = this.string.length;}, - skipTo: function(ch) { - var found = this.string.indexOf(ch, this.pos); - if (found > -1) {this.pos = found; return true;} - }, - backUp: function(n) {this.pos -= n;}, - column: function() {return this.start;}, - indentation: function() {return 0;}, - match: function(pattern, consume, caseInsensitive) { - if (typeof pattern == "string") { - var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;}; - var substr = this.string.substr(this.pos, pattern.length); - if (cased(substr) == cased(pattern)) { - if (consume !== false) this.pos += pattern.length; - return true; - } - } else { - var match = this.string.slice(this.pos).match(pattern); - if (match && match.index > 0) return null; - if (match && consume !== false) this.pos += match[0].length; - return match; - } - }, - current: function(){return this.string.slice(this.start, this.pos);} -}; -CodeMirror.StringStream = StringStream; - -CodeMirror.startState = function (mode, a1, a2) { - return mode.startState ? mode.startState(a1, a2) : true; -}; - -var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {}; -CodeMirror.defineMode = function (name, mode) { modes[name] = mode; }; -CodeMirror.defineMIME = function (mime, spec) { mimeModes[mime] = spec; }; -CodeMirror.getMode = function (options, spec) { - if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) - spec = mimeModes[spec]; - if (typeof spec == "string") - var mname = spec, config = {}; - else if (spec != null) - var mname = spec.name, config = spec; - var mfactory = modes[mname]; - if (!mfactory) throw new Error("Unknown mode: " + spec); - return mfactory(options, config || {}); -}; - -CodeMirror.runMode = function (string, modespec, callback, options) { - var mode = CodeMirror.getMode({ indentUnit: 2 }, modespec); - - if (callback.nodeType == 1) { - var tabSize = (options && options.tabSize) || 4; - var node = callback, col = 0; - node.innerHTML = ""; - callback = function (text, style) { - if (text == "\n") { - node.appendChild(document.createElement("br")); - col = 0; - return; - } - var content = ""; - // replace tabs - for (var pos = 0; ;) { - var idx = text.indexOf("\t", pos); - if (idx == -1) { - content += text.slice(pos); - col += text.length - pos; - break; - } else { - col += idx - pos; - content += text.slice(pos, idx); - var size = tabSize - col % tabSize; - col += size; - for (var i = 0; i < size; ++i) content += " "; - pos = idx + 1; - } - } - - if (style) { - var sp = node.appendChild(document.createElement("span")); - sp.className = "cm-" + style.replace(/ +/g, " cm-"); - sp.appendChild(document.createTextNode(content)); - } else { - node.appendChild(document.createTextNode(content)); - } - }; - } - - var lines = splitLines(string), state = CodeMirror.startState(mode); - for (var i = 0, e = lines.length; i < e; ++i) { - if (i) callback("\n"); - var stream = new CodeMirror.StringStream(lines[i]); - while (!stream.eol()) { - var style = mode.token(stream, state); - callback(stream.current(), style, i, stream.start, state); - stream.start = stream.pos; - } - } -}; +/* Just enough of CodeMirror to run runMode under node.js */ + +window.CodeMirror = {}; + +function splitLines(string){ return string.split(/\r?\n|\r/); }; + +function StringStream(string) { + this.pos = this.start = 0; + this.string = string; +} +StringStream.prototype = { + eol: function() {return this.pos >= this.string.length;}, + sol: function() {return this.pos == 0;}, + peek: function() {return this.string.charAt(this.pos) || null;}, + next: function() { + if (this.pos < this.string.length) + return this.string.charAt(this.pos++); + }, + eat: function(match) { + var ch = this.string.charAt(this.pos); + if (typeof match == "string") var ok = ch == match; + else var ok = ch && (match.test ? match.test(ch) : match(ch)); + if (ok) {++this.pos; return ch;} + }, + eatWhile: function(match) { + var start = this.pos; + while (this.eat(match)){} + return this.pos > start; + }, + eatSpace: function() { + var start = this.pos; + while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos; + return this.pos > start; + }, + skipToEnd: function() {this.pos = this.string.length;}, + skipTo: function(ch) { + var found = this.string.indexOf(ch, this.pos); + if (found > -1) {this.pos = found; return true;} + }, + backUp: function(n) {this.pos -= n;}, + column: function() {return this.start;}, + indentation: function() {return 0;}, + match: function(pattern, consume, caseInsensitive) { + if (typeof pattern == "string") { + var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;}; + var substr = this.string.substr(this.pos, pattern.length); + if (cased(substr) == cased(pattern)) { + if (consume !== false) this.pos += pattern.length; + return true; + } + } else { + var match = this.string.slice(this.pos).match(pattern); + if (match && match.index > 0) return null; + if (match && consume !== false) this.pos += match[0].length; + return match; + } + }, + current: function(){return this.string.slice(this.start, this.pos);} +}; +CodeMirror.StringStream = StringStream; + +CodeMirror.startState = function (mode, a1, a2) { + return mode.startState ? mode.startState(a1, a2) : true; +}; + +var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {}; +CodeMirror.defineMode = function (name, mode) { modes[name] = mode; }; +CodeMirror.defineMIME = function (mime, spec) { mimeModes[mime] = spec; }; +CodeMirror.getMode = function (options, spec) { + if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) + spec = mimeModes[spec]; + if (typeof spec == "string") + var mname = spec, config = {}; + else if (spec != null) + var mname = spec.name, config = spec; + var mfactory = modes[mname]; + if (!mfactory) throw new Error("Unknown mode: " + spec); + return mfactory(options, config || {}); +}; + +CodeMirror.runMode = function (string, modespec, callback, options) { + var mode = CodeMirror.getMode({ indentUnit: 2 }, modespec); + + if (callback.nodeType == 1) { + var tabSize = (options && options.tabSize) || 4; + var node = callback, col = 0; + node.innerHTML = ""; + callback = function (text, style) { + if (text == "\n") { + node.appendChild(document.createElement("br")); + col = 0; + return; + } + var content = ""; + // replace tabs + for (var pos = 0; ;) { + var idx = text.indexOf("\t", pos); + if (idx == -1) { + content += text.slice(pos); + col += text.length - pos; + break; + } else { + col += idx - pos; + content += text.slice(pos, idx); + var size = tabSize - col % tabSize; + col += size; + for (var i = 0; i < size; ++i) content += " "; + pos = idx + 1; + } + } + + if (style) { + var sp = node.appendChild(document.createElement("span")); + sp.className = "cm-" + style.replace(/ +/g, " cm-"); + sp.appendChild(document.createTextNode(content)); + } else { + node.appendChild(document.createTextNode(content)); + } + }; + } + + var lines = splitLines(string), state = CodeMirror.startState(mode); + for (var i = 0, e = lines.length; i < e; ++i) { + if (i) callback("\n"); + var stream = new CodeMirror.StringStream(lines[i]); + while (!stream.eol()) { + var style = mode.token(stream, state); + callback(stream.current(), style, i, stream.start, state); + stream.start = stream.pos; + } + } +}; diff --git a/profile-builder/assets/lib/codemirror/addon/runmode/runmode.js b/profile-builder/assets/lib/codemirror/addon/runmode/runmode.js index 7aafa2a..220b2c6 100644 --- a/profile-builder/assets/lib/codemirror/addon/runmode/runmode.js +++ b/profile-builder/assets/lib/codemirror/addon/runmode/runmode.js @@ -1,56 +1,56 @@ -CodeMirror.runMode = function(string, modespec, callback, options) { - var mode = CodeMirror.getMode(CodeMirror.defaults, modespec); - var ie = /MSIE \d/.test(navigator.userAgent); - var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9); - - if (callback.nodeType == 1) { - var tabSize = (options && options.tabSize) || CodeMirror.defaults.tabSize; - var node = callback, col = 0; - node.innerHTML = ""; - callback = function(text, style) { - if (text == "\n") { - // Emitting LF or CRLF on IE8 or earlier results in an incorrect display. - // Emitting a carriage return makes everything ok. - node.appendChild(document.createTextNode(ie_lt9 ? '\r' : text)); - col = 0; - return; - } - var content = ""; - // replace tabs - for (var pos = 0;;) { - var idx = text.indexOf("\t", pos); - if (idx == -1) { - content += text.slice(pos); - col += text.length - pos; - break; - } else { - col += idx - pos; - content += text.slice(pos, idx); - var size = tabSize - col % tabSize; - col += size; - for (var i = 0; i < size; ++i) content += " "; - pos = idx + 1; - } - } - - if (style) { - var sp = node.appendChild(document.createElement("span")); - sp.className = "cm-" + style.replace(/ +/g, " cm-"); - sp.appendChild(document.createTextNode(content)); - } else { - node.appendChild(document.createTextNode(content)); - } - }; - } - - var lines = CodeMirror.splitLines(string), state = CodeMirror.startState(mode); - for (var i = 0, e = lines.length; i < e; ++i) { - if (i) callback("\n"); - var stream = new CodeMirror.StringStream(lines[i]); - while (!stream.eol()) { - var style = mode.token(stream, state); - callback(stream.current(), style, i, stream.start, state); - stream.start = stream.pos; - } - } -}; +CodeMirror.runMode = function(string, modespec, callback, options) { + var mode = CodeMirror.getMode(CodeMirror.defaults, modespec); + var ie = /MSIE \d/.test(navigator.userAgent); + var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9); + + if (callback.nodeType == 1) { + var tabSize = (options && options.tabSize) || CodeMirror.defaults.tabSize; + var node = callback, col = 0; + node.innerHTML = ""; + callback = function(text, style) { + if (text == "\n") { + // Emitting LF or CRLF on IE8 or earlier results in an incorrect display. + // Emitting a carriage return makes everything ok. + node.appendChild(document.createTextNode(ie_lt9 ? '\r' : text)); + col = 0; + return; + } + var content = ""; + // replace tabs + for (var pos = 0;;) { + var idx = text.indexOf("\t", pos); + if (idx == -1) { + content += text.slice(pos); + col += text.length - pos; + break; + } else { + col += idx - pos; + content += text.slice(pos, idx); + var size = tabSize - col % tabSize; + col += size; + for (var i = 0; i < size; ++i) content += " "; + pos = idx + 1; + } + } + + if (style) { + var sp = node.appendChild(document.createElement("span")); + sp.className = "cm-" + style.replace(/ +/g, " cm-"); + sp.appendChild(document.createTextNode(content)); + } else { + node.appendChild(document.createTextNode(content)); + } + }; + } + + var lines = CodeMirror.splitLines(string), state = CodeMirror.startState(mode); + for (var i = 0, e = lines.length; i < e; ++i) { + if (i) callback("\n"); + var stream = new CodeMirror.StringStream(lines[i]); + while (!stream.eol()) { + var style = mode.token(stream, state); + callback(stream.current(), style, i, stream.start, state); + stream.start = stream.pos; + } + } +}; diff --git a/profile-builder/assets/lib/codemirror/addon/runmode/runmode.node.js b/profile-builder/assets/lib/codemirror/addon/runmode/runmode.node.js index 0f1088f..136b3f7 100644 --- a/profile-builder/assets/lib/codemirror/addon/runmode/runmode.node.js +++ b/profile-builder/assets/lib/codemirror/addon/runmode/runmode.node.js @@ -1,103 +1,103 @@ -/* Just enough of CodeMirror to run runMode under node.js */ - -function splitLines(string){ return string.split(/\r?\n|\r/); }; - -function StringStream(string) { - this.pos = this.start = 0; - this.string = string; -} -StringStream.prototype = { - eol: function() {return this.pos >= this.string.length;}, - sol: function() {return this.pos == 0;}, - peek: function() {return this.string.charAt(this.pos) || null;}, - next: function() { - if (this.pos < this.string.length) - return this.string.charAt(this.pos++); - }, - eat: function(match) { - var ch = this.string.charAt(this.pos); - if (typeof match == "string") var ok = ch == match; - else var ok = ch && (match.test ? match.test(ch) : match(ch)); - if (ok) {++this.pos; return ch;} - }, - eatWhile: function(match) { - var start = this.pos; - while (this.eat(match)){} - return this.pos > start; - }, - eatSpace: function() { - var start = this.pos; - while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos; - return this.pos > start; - }, - skipToEnd: function() {this.pos = this.string.length;}, - skipTo: function(ch) { - var found = this.string.indexOf(ch, this.pos); - if (found > -1) {this.pos = found; return true;} - }, - backUp: function(n) {this.pos -= n;}, - column: function() {return this.start;}, - indentation: function() {return 0;}, - match: function(pattern, consume, caseInsensitive) { - if (typeof pattern == "string") { - var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;}; - var substr = this.string.substr(this.pos, pattern.length); - if (cased(substr) == cased(pattern)) { - if (consume !== false) this.pos += pattern.length; - return true; - } - } else { - var match = this.string.slice(this.pos).match(pattern); - if (match && match.index > 0) return null; - if (match && consume !== false) this.pos += match[0].length; - return match; - } - }, - current: function(){return this.string.slice(this.start, this.pos);} -}; -exports.StringStream = StringStream; - -exports.startState = function(mode, a1, a2) { - return mode.startState ? mode.startState(a1, a2) : true; -}; - -var modes = exports.modes = {}, mimeModes = exports.mimeModes = {}; -exports.defineMode = function(name, mode) { - if (arguments.length > 2) { - mode.dependencies = []; - for (var i = 2; i < arguments.length; ++i) mode.dependencies.push(arguments[i]); - } - modes[name] = mode; -}; -exports.defineMIME = function(mime, spec) { mimeModes[mime] = spec; }; - -exports.defineMode("null", function() { - return {token: function(stream) {stream.skipToEnd();}}; -}); -exports.defineMIME("text/plain", "null"); - -exports.getMode = function(options, spec) { - if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) - spec = mimeModes[spec]; - if (typeof spec == "string") - var mname = spec, config = {}; - else if (spec != null) - var mname = spec.name, config = spec; - var mfactory = modes[mname]; - if (!mfactory) throw new Error("Unknown mode: " + spec); - return mfactory(options, config || {}); -}; - -exports.runMode = function(string, modespec, callback) { - var mode = exports.getMode({indentUnit: 2}, modespec); - var lines = splitLines(string), state = exports.startState(mode); - for (var i = 0, e = lines.length; i < e; ++i) { - if (i) callback("\n"); - var stream = new exports.StringStream(lines[i]); - while (!stream.eol()) { - var style = mode.token(stream, state); - callback(stream.current(), style, i, stream.start, state); - stream.start = stream.pos; - } - } -}; +/* Just enough of CodeMirror to run runMode under node.js */ + +function splitLines(string){ return string.split(/\r?\n|\r/); }; + +function StringStream(string) { + this.pos = this.start = 0; + this.string = string; +} +StringStream.prototype = { + eol: function() {return this.pos >= this.string.length;}, + sol: function() {return this.pos == 0;}, + peek: function() {return this.string.charAt(this.pos) || null;}, + next: function() { + if (this.pos < this.string.length) + return this.string.charAt(this.pos++); + }, + eat: function(match) { + var ch = this.string.charAt(this.pos); + if (typeof match == "string") var ok = ch == match; + else var ok = ch && (match.test ? match.test(ch) : match(ch)); + if (ok) {++this.pos; return ch;} + }, + eatWhile: function(match) { + var start = this.pos; + while (this.eat(match)){} + return this.pos > start; + }, + eatSpace: function() { + var start = this.pos; + while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos; + return this.pos > start; + }, + skipToEnd: function() {this.pos = this.string.length;}, + skipTo: function(ch) { + var found = this.string.indexOf(ch, this.pos); + if (found > -1) {this.pos = found; return true;} + }, + backUp: function(n) {this.pos -= n;}, + column: function() {return this.start;}, + indentation: function() {return 0;}, + match: function(pattern, consume, caseInsensitive) { + if (typeof pattern == "string") { + var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;}; + var substr = this.string.substr(this.pos, pattern.length); + if (cased(substr) == cased(pattern)) { + if (consume !== false) this.pos += pattern.length; + return true; + } + } else { + var match = this.string.slice(this.pos).match(pattern); + if (match && match.index > 0) return null; + if (match && consume !== false) this.pos += match[0].length; + return match; + } + }, + current: function(){return this.string.slice(this.start, this.pos);} +}; +exports.StringStream = StringStream; + +exports.startState = function(mode, a1, a2) { + return mode.startState ? mode.startState(a1, a2) : true; +}; + +var modes = exports.modes = {}, mimeModes = exports.mimeModes = {}; +exports.defineMode = function(name, mode) { + if (arguments.length > 2) { + mode.dependencies = []; + for (var i = 2; i < arguments.length; ++i) mode.dependencies.push(arguments[i]); + } + modes[name] = mode; +}; +exports.defineMIME = function(mime, spec) { mimeModes[mime] = spec; }; + +exports.defineMode("null", function() { + return {token: function(stream) {stream.skipToEnd();}}; +}); +exports.defineMIME("text/plain", "null"); + +exports.getMode = function(options, spec) { + if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) + spec = mimeModes[spec]; + if (typeof spec == "string") + var mname = spec, config = {}; + else if (spec != null) + var mname = spec.name, config = spec; + var mfactory = modes[mname]; + if (!mfactory) throw new Error("Unknown mode: " + spec); + return mfactory(options, config || {}); +}; + +exports.runMode = function(string, modespec, callback) { + var mode = exports.getMode({indentUnit: 2}, modespec); + var lines = splitLines(string), state = exports.startState(mode); + for (var i = 0, e = lines.length; i < e; ++i) { + if (i) callback("\n"); + var stream = new exports.StringStream(lines[i]); + while (!stream.eol()) { + var style = mode.token(stream, state); + callback(stream.current(), style, i, stream.start, state); + stream.start = stream.pos; + } + } +}; diff --git a/profile-builder/assets/lib/codemirror/addon/scroll/scrollpastend.js b/profile-builder/assets/lib/codemirror/addon/scroll/scrollpastend.js index 14d7d5a..470cdf2 100644 --- a/profile-builder/assets/lib/codemirror/addon/scroll/scrollpastend.js +++ b/profile-builder/assets/lib/codemirror/addon/scroll/scrollpastend.js @@ -1,34 +1,34 @@ -(function() { - "use strict"; - - CodeMirror.defineOption("scrollPastEnd", false, function(cm, val, old) { - if (old && old != CodeMirror.Init) { - cm.off("change", onChange); - cm.display.lineSpace.parentNode.style.paddingBottom = ""; - cm.state.scrollPastEndPadding = null; - } - if (val) { - cm.on("change", onChange); - updateBottomMargin(cm); - } - }); - - function onChange(cm, change) { - if (CodeMirror.changeEnd(change).line == cm.lastLine()) - updateBottomMargin(cm); - } - - function updateBottomMargin(cm) { - var padding = ""; - if (cm.lineCount() > 1) { - var totalH = cm.display.scroller.clientHeight - 30, - lastLineH = cm.getLineHandle(cm.lastLine()).height; - padding = (totalH - lastLineH) + "px"; - } - if (cm.state.scrollPastEndPadding != padding) { - cm.state.scrollPastEndPadding = padding; - cm.display.lineSpace.parentNode.style.paddingBottom = padding; - cm.setSize(); - } - } -})(); +(function() { + "use strict"; + + CodeMirror.defineOption("scrollPastEnd", false, function(cm, val, old) { + if (old && old != CodeMirror.Init) { + cm.off("change", onChange); + cm.display.lineSpace.parentNode.style.paddingBottom = ""; + cm.state.scrollPastEndPadding = null; + } + if (val) { + cm.on("change", onChange); + updateBottomMargin(cm); + } + }); + + function onChange(cm, change) { + if (CodeMirror.changeEnd(change).line == cm.lastLine()) + updateBottomMargin(cm); + } + + function updateBottomMargin(cm) { + var padding = ""; + if (cm.lineCount() > 1) { + var totalH = cm.display.scroller.clientHeight - 30, + lastLineH = cm.getLineHandle(cm.lastLine()).height; + padding = (totalH - lastLineH) + "px"; + } + if (cm.state.scrollPastEndPadding != padding) { + cm.state.scrollPastEndPadding = padding; + cm.display.lineSpace.parentNode.style.paddingBottom = padding; + cm.setSize(); + } + } +})(); diff --git a/profile-builder/assets/lib/codemirror/addon/search/match-highlighter.js b/profile-builder/assets/lib/codemirror/addon/search/match-highlighter.js index e5cbeac..b23f4f3 100644 --- a/profile-builder/assets/lib/codemirror/addon/search/match-highlighter.js +++ b/profile-builder/assets/lib/codemirror/addon/search/match-highlighter.js @@ -1,91 +1,91 @@ -// Highlighting text that matches the selection -// -// Defines an option highlightSelectionMatches, which, when enabled, -// will style strings that match the selection throughout the -// document. -// -// The option can be set to true to simply enable it, or to a -// {minChars, style, showToken} object to explicitly configure it. -// minChars is the minimum amount of characters that should be -// selected for the behavior to occur, and style is the token style to -// apply to the matches. This will be prefixed by "cm-" to create an -// actual CSS class name. showToken, when enabled, will cause the -// current token to be highlighted when nothing is selected. - -(function() { - var DEFAULT_MIN_CHARS = 2; - var DEFAULT_TOKEN_STYLE = "matchhighlight"; - var DEFAULT_DELAY = 100; - - function State(options) { - if (typeof options == "object") { - this.minChars = options.minChars; - this.style = options.style; - this.showToken = options.showToken; - this.delay = options.delay; - } - if (this.style == null) this.style = DEFAULT_TOKEN_STYLE; - if (this.minChars == null) this.minChars = DEFAULT_MIN_CHARS; - if (this.delay == null) this.delay = DEFAULT_DELAY; - this.overlay = this.timeout = null; - } - - CodeMirror.defineOption("highlightSelectionMatches", false, function(cm, val, old) { - if (old && old != CodeMirror.Init) { - var over = cm.state.matchHighlighter.overlay; - if (over) cm.removeOverlay(over); - clearTimeout(cm.state.matchHighlighter.timeout); - cm.state.matchHighlighter = null; - cm.off("cursorActivity", cursorActivity); - } - if (val) { - cm.state.matchHighlighter = new State(val); - highlightMatches(cm); - cm.on("cursorActivity", cursorActivity); - } - }); - - function cursorActivity(cm) { - var state = cm.state.matchHighlighter; - clearTimeout(state.timeout); - state.timeout = setTimeout(function() {highlightMatches(cm);}, state.delay); - } - - function highlightMatches(cm) { - cm.operation(function() { - var state = cm.state.matchHighlighter; - if (state.overlay) { - cm.removeOverlay(state.overlay); - state.overlay = null; - } - if (!cm.somethingSelected() && state.showToken) { - var re = state.showToken === true ? /[\w$]/ : state.showToken; - var cur = cm.getCursor(), line = cm.getLine(cur.line), start = cur.ch, end = start; - while (start && re.test(line.charAt(start - 1))) --start; - while (end < line.length && re.test(line.charAt(end))) ++end; - if (start < end) - cm.addOverlay(state.overlay = makeOverlay(line.slice(start, end), re, state.style)); - return; - } - if (cm.getCursor("head").line != cm.getCursor("anchor").line) return; - var selection = cm.getSelection().replace(/^\s+|\s+$/g, ""); - if (selection.length >= state.minChars) - cm.addOverlay(state.overlay = makeOverlay(selection, false, state.style)); - }); - } - - function boundariesAround(stream, re) { - return (!stream.start || !re.test(stream.string.charAt(stream.start - 1))) && - (stream.pos == stream.string.length || !re.test(stream.string.charAt(stream.pos))); - } - - function makeOverlay(query, hasBoundary, style) { - return {token: function(stream) { - if (stream.match(query) && - (!hasBoundary || boundariesAround(stream, hasBoundary))) - return style; - stream.next(); - stream.skipTo(query.charAt(0)) || stream.skipToEnd(); - }}; - } -})(); +// Highlighting text that matches the selection +// +// Defines an option highlightSelectionMatches, which, when enabled, +// will style strings that match the selection throughout the +// document. +// +// The option can be set to true to simply enable it, or to a +// {minChars, style, showToken} object to explicitly configure it. +// minChars is the minimum amount of characters that should be +// selected for the behavior to occur, and style is the token style to +// apply to the matches. This will be prefixed by "cm-" to create an +// actual CSS class name. showToken, when enabled, will cause the +// current token to be highlighted when nothing is selected. + +(function() { + var DEFAULT_MIN_CHARS = 2; + var DEFAULT_TOKEN_STYLE = "matchhighlight"; + var DEFAULT_DELAY = 100; + + function State(options) { + if (typeof options == "object") { + this.minChars = options.minChars; + this.style = options.style; + this.showToken = options.showToken; + this.delay = options.delay; + } + if (this.style == null) this.style = DEFAULT_TOKEN_STYLE; + if (this.minChars == null) this.minChars = DEFAULT_MIN_CHARS; + if (this.delay == null) this.delay = DEFAULT_DELAY; + this.overlay = this.timeout = null; + } + + CodeMirror.defineOption("highlightSelectionMatches", false, function(cm, val, old) { + if (old && old != CodeMirror.Init) { + var over = cm.state.matchHighlighter.overlay; + if (over) cm.removeOverlay(over); + clearTimeout(cm.state.matchHighlighter.timeout); + cm.state.matchHighlighter = null; + cm.off("cursorActivity", cursorActivity); + } + if (val) { + cm.state.matchHighlighter = new State(val); + highlightMatches(cm); + cm.on("cursorActivity", cursorActivity); + } + }); + + function cursorActivity(cm) { + var state = cm.state.matchHighlighter; + clearTimeout(state.timeout); + state.timeout = setTimeout(function() {highlightMatches(cm);}, state.delay); + } + + function highlightMatches(cm) { + cm.operation(function() { + var state = cm.state.matchHighlighter; + if (state.overlay) { + cm.removeOverlay(state.overlay); + state.overlay = null; + } + if (!cm.somethingSelected() && state.showToken) { + var re = state.showToken === true ? /[\w$]/ : state.showToken; + var cur = cm.getCursor(), line = cm.getLine(cur.line), start = cur.ch, end = start; + while (start && re.test(line.charAt(start - 1))) --start; + while (end < line.length && re.test(line.charAt(end))) ++end; + if (start < end) + cm.addOverlay(state.overlay = makeOverlay(line.slice(start, end), re, state.style)); + return; + } + if (cm.getCursor("head").line != cm.getCursor("anchor").line) return; + var selection = cm.getSelection().replace(/^\s+|\s+$/g, ""); + if (selection.length >= state.minChars) + cm.addOverlay(state.overlay = makeOverlay(selection, false, state.style)); + }); + } + + function boundariesAround(stream, re) { + return (!stream.start || !re.test(stream.string.charAt(stream.start - 1))) && + (stream.pos == stream.string.length || !re.test(stream.string.charAt(stream.pos))); + } + + function makeOverlay(query, hasBoundary, style) { + return {token: function(stream) { + if (stream.match(query) && + (!hasBoundary || boundariesAround(stream, hasBoundary))) + return style; + stream.next(); + stream.skipTo(query.charAt(0)) || stream.skipToEnd(); + }}; + } +})(); diff --git a/profile-builder/assets/lib/codemirror/addon/search/search.js b/profile-builder/assets/lib/codemirror/addon/search/search.js index c30922d..6b9e17e 100644 --- a/profile-builder/assets/lib/codemirror/addon/search/search.js +++ b/profile-builder/assets/lib/codemirror/addon/search/search.js @@ -1,131 +1,131 @@ -// Define search commands. Depends on dialog.js or another -// implementation of the openDialog method. - -// Replace works a little oddly -- it will do the replace on the next -// Ctrl-G (or whatever is bound to findNext) press. You prevent a -// replace by making sure the match is no longer selected when hitting -// Ctrl-G. - -(function() { - function searchOverlay(query) { - if (typeof query == "string") return {token: function(stream) { - if (stream.match(query)) return "searching"; - stream.next(); - stream.skipTo(query.charAt(0)) || stream.skipToEnd(); - }}; - return {token: function(stream) { - if (stream.match(query)) return "searching"; - while (!stream.eol()) { - stream.next(); - if (stream.match(query, false)) break; - } - }}; - } - - function SearchState() { - this.posFrom = this.posTo = this.query = null; - this.overlay = null; - } - function getSearchState(cm) { - return cm.state.search || (cm.state.search = new SearchState()); - } - function getSearchCursor(cm, query, pos) { - // Heuristic: if the query string is all lowercase, do a case insensitive search. - return cm.getSearchCursor(query, pos, typeof query == "string" && query == query.toLowerCase()); - } - function dialog(cm, text, shortText, f) { - if (cm.openDialog) cm.openDialog(text, f); - else f(prompt(shortText, "")); - } - function confirmDialog(cm, text, shortText, fs) { - if (cm.openConfirm) cm.openConfirm(text, fs); - else if (confirm(shortText)) fs[0](); - } - function parseQuery(query) { - var isRE = query.match(/^\/(.*)\/([a-z]*)$/); - return isRE ? new RegExp(isRE[1], isRE[2].indexOf("i") == -1 ? "" : "i") : query; - } - var queryDialog = - 'Search: (Use /re/ syntax for regexp search)'; - function doSearch(cm, rev) { - var state = getSearchState(cm); - if (state.query) return findNext(cm, rev); - dialog(cm, queryDialog, "Search for:", function(query) { - cm.operation(function() { - if (!query || state.query) return; - state.query = parseQuery(query); - cm.removeOverlay(state.overlay); - state.overlay = searchOverlay(state.query); - cm.addOverlay(state.overlay); - state.posFrom = state.posTo = cm.getCursor(); - findNext(cm, rev); - }); - }); - } - function findNext(cm, rev) {cm.operation(function() { - var state = getSearchState(cm); - var cursor = getSearchCursor(cm, state.query, rev ? state.posFrom : state.posTo); - if (!cursor.find(rev)) { - cursor = getSearchCursor(cm, state.query, rev ? CodeMirror.Pos(cm.lastLine()) : CodeMirror.Pos(cm.firstLine(), 0)); - if (!cursor.find(rev)) return; - } - cm.setSelection(cursor.from(), cursor.to()); - state.posFrom = cursor.from(); state.posTo = cursor.to(); - });} - function clearSearch(cm) {cm.operation(function() { - var state = getSearchState(cm); - if (!state.query) return; - state.query = null; - cm.removeOverlay(state.overlay); - });} - - var replaceQueryDialog = - 'Replace: (Use /re/ syntax for regexp search)'; - var replacementQueryDialog = 'With: '; - var doReplaceConfirm = "Replace? "; - function replace(cm, all) { - dialog(cm, replaceQueryDialog, "Replace:", function(query) { - if (!query) return; - query = parseQuery(query); - dialog(cm, replacementQueryDialog, "Replace with:", function(text) { - if (all) { - cm.operation(function() { - for (var cursor = getSearchCursor(cm, query); cursor.findNext();) { - if (typeof query != "string") { - var match = cm.getRange(cursor.from(), cursor.to()).match(query); - cursor.replace(text.replace(/\$(\d)/, function(_, i) {return match[i];})); - } else cursor.replace(text); - } - }); - } else { - clearSearch(cm); - var cursor = getSearchCursor(cm, query, cm.getCursor()); - var advance = function() { - var start = cursor.from(), match; - if (!(match = cursor.findNext())) { - cursor = getSearchCursor(cm, query); - if (!(match = cursor.findNext()) || - (start && cursor.from().line == start.line && cursor.from().ch == start.ch)) return; - } - cm.setSelection(cursor.from(), cursor.to()); - confirmDialog(cm, doReplaceConfirm, "Replace?", - [function() {doReplace(match);}, advance]); - }; - var doReplace = function(match) { - cursor.replace(typeof query == "string" ? text : - text.replace(/\$(\d)/, function(_, i) {return match[i];})); - advance(); - }; - advance(); - } - }); - }); - } - - CodeMirror.commands.find = function(cm) {clearSearch(cm); doSearch(cm);}; - CodeMirror.commands.findNext = doSearch; - CodeMirror.commands.findPrev = function(cm) {doSearch(cm, true);}; - CodeMirror.commands.clearSearch = clearSearch; - CodeMirror.commands.replace = replace; - CodeMirror.commands.replaceAll = function(cm) {replace(cm, true);}; -})(); +// Define search commands. Depends on dialog.js or another +// implementation of the openDialog method. + +// Replace works a little oddly -- it will do the replace on the next +// Ctrl-G (or whatever is bound to findNext) press. You prevent a +// replace by making sure the match is no longer selected when hitting +// Ctrl-G. + +(function() { + function searchOverlay(query) { + if (typeof query == "string") return {token: function(stream) { + if (stream.match(query)) return "searching"; + stream.next(); + stream.skipTo(query.charAt(0)) || stream.skipToEnd(); + }}; + return {token: function(stream) { + if (stream.match(query)) return "searching"; + while (!stream.eol()) { + stream.next(); + if (stream.match(query, false)) break; + } + }}; + } + + function SearchState() { + this.posFrom = this.posTo = this.query = null; + this.overlay = null; + } + function getSearchState(cm) { + return cm.state.search || (cm.state.search = new SearchState()); + } + function getSearchCursor(cm, query, pos) { + // Heuristic: if the query string is all lowercase, do a case insensitive search. + return cm.getSearchCursor(query, pos, typeof query == "string" && query == query.toLowerCase()); + } + function dialog(cm, text, shortText, f) { + if (cm.openDialog) cm.openDialog(text, f); + else f(prompt(shortText, "")); + } + function confirmDialog(cm, text, shortText, fs) { + if (cm.openConfirm) cm.openConfirm(text, fs); + else if (confirm(shortText)) fs[0](); + } + function parseQuery(query) { + var isRE = query.match(/^\/(.*)\/([a-z]*)$/); + return isRE ? new RegExp(isRE[1], isRE[2].indexOf("i") == -1 ? "" : "i") : query; + } + var queryDialog = + 'Search: (Use /re/ syntax for regexp search)'; + function doSearch(cm, rev) { + var state = getSearchState(cm); + if (state.query) return findNext(cm, rev); + dialog(cm, queryDialog, "Search for:", function(query) { + cm.operation(function() { + if (!query || state.query) return; + state.query = parseQuery(query); + cm.removeOverlay(state.overlay); + state.overlay = searchOverlay(state.query); + cm.addOverlay(state.overlay); + state.posFrom = state.posTo = cm.getCursor(); + findNext(cm, rev); + }); + }); + } + function findNext(cm, rev) {cm.operation(function() { + var state = getSearchState(cm); + var cursor = getSearchCursor(cm, state.query, rev ? state.posFrom : state.posTo); + if (!cursor.find(rev)) { + cursor = getSearchCursor(cm, state.query, rev ? CodeMirror.Pos(cm.lastLine()) : CodeMirror.Pos(cm.firstLine(), 0)); + if (!cursor.find(rev)) return; + } + cm.setSelection(cursor.from(), cursor.to()); + state.posFrom = cursor.from(); state.posTo = cursor.to(); + });} + function clearSearch(cm) {cm.operation(function() { + var state = getSearchState(cm); + if (!state.query) return; + state.query = null; + cm.removeOverlay(state.overlay); + });} + + var replaceQueryDialog = + 'Replace: (Use /re/ syntax for regexp search)'; + var replacementQueryDialog = 'With: '; + var doReplaceConfirm = "Replace? "; + function replace(cm, all) { + dialog(cm, replaceQueryDialog, "Replace:", function(query) { + if (!query) return; + query = parseQuery(query); + dialog(cm, replacementQueryDialog, "Replace with:", function(text) { + if (all) { + cm.operation(function() { + for (var cursor = getSearchCursor(cm, query); cursor.findNext();) { + if (typeof query != "string") { + var match = cm.getRange(cursor.from(), cursor.to()).match(query); + cursor.replace(text.replace(/\$(\d)/, function(_, i) {return match[i];})); + } else cursor.replace(text); + } + }); + } else { + clearSearch(cm); + var cursor = getSearchCursor(cm, query, cm.getCursor()); + var advance = function() { + var start = cursor.from(), match; + if (!(match = cursor.findNext())) { + cursor = getSearchCursor(cm, query); + if (!(match = cursor.findNext()) || + (start && cursor.from().line == start.line && cursor.from().ch == start.ch)) return; + } + cm.setSelection(cursor.from(), cursor.to()); + confirmDialog(cm, doReplaceConfirm, "Replace?", + [function() {doReplace(match);}, advance]); + }; + var doReplace = function(match) { + cursor.replace(typeof query == "string" ? text : + text.replace(/\$(\d)/, function(_, i) {return match[i];})); + advance(); + }; + advance(); + } + }); + }); + } + + CodeMirror.commands.find = function(cm) {clearSearch(cm); doSearch(cm);}; + CodeMirror.commands.findNext = doSearch; + CodeMirror.commands.findPrev = function(cm) {doSearch(cm, true);}; + CodeMirror.commands.clearSearch = clearSearch; + CodeMirror.commands.replace = replace; + CodeMirror.commands.replaceAll = function(cm) {replace(cm, true);}; +})(); diff --git a/profile-builder/assets/lib/codemirror/addon/search/searchcursor.js b/profile-builder/assets/lib/codemirror/addon/search/searchcursor.js index c034d58..265aa01 100644 --- a/profile-builder/assets/lib/codemirror/addon/search/searchcursor.js +++ b/profile-builder/assets/lib/codemirror/addon/search/searchcursor.js @@ -1,143 +1,143 @@ -(function(){ - var Pos = CodeMirror.Pos; - - function SearchCursor(doc, query, pos, caseFold) { - this.atOccurrence = false; this.doc = doc; - if (caseFold == null && typeof query == "string") caseFold = false; - - pos = pos ? doc.clipPos(pos) : Pos(0, 0); - this.pos = {from: pos, to: pos}; - - // The matches method is filled in based on the type of query. - // It takes a position and a direction, and returns an object - // describing the next occurrence of the query, or null if no - // more matches were found. - if (typeof query != "string") { // Regexp match - if (!query.global) query = new RegExp(query.source, query.ignoreCase ? "ig" : "g"); - this.matches = function(reverse, pos) { - if (reverse) { - query.lastIndex = 0; - var line = doc.getLine(pos.line).slice(0, pos.ch), cutOff = 0, match, start; - for (;;) { - query.lastIndex = cutOff; - var newMatch = query.exec(line); - if (!newMatch) break; - match = newMatch; - start = match.index; - cutOff = match.index + (match[0].length || 1); - if (cutOff == line.length) break; - } - var matchLen = (match && match[0].length) || 0; - if (!matchLen) { - if (start == 0 && line.length == 0) {match = undefined;} - else if (start != doc.getLine(pos.line).length) { - matchLen++; - } - } - } else { - query.lastIndex = pos.ch; - var line = doc.getLine(pos.line), match = query.exec(line); - var matchLen = (match && match[0].length) || 0; - var start = match && match.index; - if (start + matchLen != line.length && !matchLen) matchLen = 1; - } - if (match && matchLen) - return {from: Pos(pos.line, start), - to: Pos(pos.line, start + matchLen), - match: match}; - }; - } else { // String query - if (caseFold) query = query.toLowerCase(); - var fold = caseFold ? function(str){return str.toLowerCase();} : function(str){return str;}; - var target = query.split("\n"); - // Different methods for single-line and multi-line queries - if (target.length == 1) { - if (!query.length) { - // Empty string would match anything and never progress, so - // we define it to match nothing instead. - this.matches = function() {}; - } else { - this.matches = function(reverse, pos) { - var line = fold(doc.getLine(pos.line)), len = query.length, match; - if (reverse ? (pos.ch >= len && (match = line.lastIndexOf(query, pos.ch - len)) != -1) - : (match = line.indexOf(query, pos.ch)) != -1) - return {from: Pos(pos.line, match), - to: Pos(pos.line, match + len)}; - }; - } - } else { - this.matches = function(reverse, pos) { - var ln = pos.line, idx = (reverse ? target.length - 1 : 0), match = target[idx], line = fold(doc.getLine(ln)); - var offsetA = (reverse ? line.indexOf(match) + match.length : line.lastIndexOf(match)); - if (reverse ? offsetA > pos.ch || offsetA != match.length - : offsetA < pos.ch || offsetA != line.length - match.length) - return; - for (;;) { - if (reverse ? !ln : ln == doc.lineCount() - 1) return; - line = fold(doc.getLine(ln += reverse ? -1 : 1)); - match = target[reverse ? --idx : ++idx]; - if (idx > 0 && idx < target.length - 1) { - if (line != match) return; - else continue; - } - var offsetB = (reverse ? line.lastIndexOf(match) : line.indexOf(match) + match.length); - if (reverse ? offsetB != line.length - match.length : offsetB != match.length) - return; - var start = Pos(pos.line, offsetA), end = Pos(ln, offsetB); - return {from: reverse ? end : start, to: reverse ? start : end}; - } - }; - } - } - } - - SearchCursor.prototype = { - findNext: function() {return this.find(false);}, - findPrevious: function() {return this.find(true);}, - - find: function(reverse) { - var self = this, pos = this.doc.clipPos(reverse ? this.pos.from : this.pos.to); - function savePosAndFail(line) { - var pos = Pos(line, 0); - self.pos = {from: pos, to: pos}; - self.atOccurrence = false; - return false; - } - - for (;;) { - if (this.pos = this.matches(reverse, pos)) { - if (!this.pos.from || !this.pos.to) { console.log(this.matches, this.pos); } - this.atOccurrence = true; - return this.pos.match || true; - } - if (reverse) { - if (!pos.line) return savePosAndFail(0); - pos = Pos(pos.line-1, this.doc.getLine(pos.line-1).length); - } - else { - var maxLine = this.doc.lineCount(); - if (pos.line == maxLine - 1) return savePosAndFail(maxLine); - pos = Pos(pos.line + 1, 0); - } - } - }, - - from: function() {if (this.atOccurrence) return this.pos.from;}, - to: function() {if (this.atOccurrence) return this.pos.to;}, - - replace: function(newText) { - if (!this.atOccurrence) return; - var lines = CodeMirror.splitLines(newText); - this.doc.replaceRange(lines, this.pos.from, this.pos.to); - this.pos.to = Pos(this.pos.from.line + lines.length - 1, - lines[lines.length - 1].length + (lines.length == 1 ? this.pos.from.ch : 0)); - } - }; - - CodeMirror.defineExtension("getSearchCursor", function(query, pos, caseFold) { - return new SearchCursor(this.doc, query, pos, caseFold); - }); - CodeMirror.defineDocExtension("getSearchCursor", function(query, pos, caseFold) { - return new SearchCursor(this, query, pos, caseFold); - }); -})(); +(function(){ + var Pos = CodeMirror.Pos; + + function SearchCursor(doc, query, pos, caseFold) { + this.atOccurrence = false; this.doc = doc; + if (caseFold == null && typeof query == "string") caseFold = false; + + pos = pos ? doc.clipPos(pos) : Pos(0, 0); + this.pos = {from: pos, to: pos}; + + // The matches method is filled in based on the type of query. + // It takes a position and a direction, and returns an object + // describing the next occurrence of the query, or null if no + // more matches were found. + if (typeof query != "string") { // Regexp match + if (!query.global) query = new RegExp(query.source, query.ignoreCase ? "ig" : "g"); + this.matches = function(reverse, pos) { + if (reverse) { + query.lastIndex = 0; + var line = doc.getLine(pos.line).slice(0, pos.ch), cutOff = 0, match, start; + for (;;) { + query.lastIndex = cutOff; + var newMatch = query.exec(line); + if (!newMatch) break; + match = newMatch; + start = match.index; + cutOff = match.index + (match[0].length || 1); + if (cutOff == line.length) break; + } + var matchLen = (match && match[0].length) || 0; + if (!matchLen) { + if (start == 0 && line.length == 0) {match = undefined;} + else if (start != doc.getLine(pos.line).length) { + matchLen++; + } + } + } else { + query.lastIndex = pos.ch; + var line = doc.getLine(pos.line), match = query.exec(line); + var matchLen = (match && match[0].length) || 0; + var start = match && match.index; + if (start + matchLen != line.length && !matchLen) matchLen = 1; + } + if (match && matchLen) + return {from: Pos(pos.line, start), + to: Pos(pos.line, start + matchLen), + match: match}; + }; + } else { // String query + if (caseFold) query = query.toLowerCase(); + var fold = caseFold ? function(str){return str.toLowerCase();} : function(str){return str;}; + var target = query.split("\n"); + // Different methods for single-line and multi-line queries + if (target.length == 1) { + if (!query.length) { + // Empty string would match anything and never progress, so + // we define it to match nothing instead. + this.matches = function() {}; + } else { + this.matches = function(reverse, pos) { + var line = fold(doc.getLine(pos.line)), len = query.length, match; + if (reverse ? (pos.ch >= len && (match = line.lastIndexOf(query, pos.ch - len)) != -1) + : (match = line.indexOf(query, pos.ch)) != -1) + return {from: Pos(pos.line, match), + to: Pos(pos.line, match + len)}; + }; + } + } else { + this.matches = function(reverse, pos) { + var ln = pos.line, idx = (reverse ? target.length - 1 : 0), match = target[idx], line = fold(doc.getLine(ln)); + var offsetA = (reverse ? line.indexOf(match) + match.length : line.lastIndexOf(match)); + if (reverse ? offsetA > pos.ch || offsetA != match.length + : offsetA < pos.ch || offsetA != line.length - match.length) + return; + for (;;) { + if (reverse ? !ln : ln == doc.lineCount() - 1) return; + line = fold(doc.getLine(ln += reverse ? -1 : 1)); + match = target[reverse ? --idx : ++idx]; + if (idx > 0 && idx < target.length - 1) { + if (line != match) return; + else continue; + } + var offsetB = (reverse ? line.lastIndexOf(match) : line.indexOf(match) + match.length); + if (reverse ? offsetB != line.length - match.length : offsetB != match.length) + return; + var start = Pos(pos.line, offsetA), end = Pos(ln, offsetB); + return {from: reverse ? end : start, to: reverse ? start : end}; + } + }; + } + } + } + + SearchCursor.prototype = { + findNext: function() {return this.find(false);}, + findPrevious: function() {return this.find(true);}, + + find: function(reverse) { + var self = this, pos = this.doc.clipPos(reverse ? this.pos.from : this.pos.to); + function savePosAndFail(line) { + var pos = Pos(line, 0); + self.pos = {from: pos, to: pos}; + self.atOccurrence = false; + return false; + } + + for (;;) { + if (this.pos = this.matches(reverse, pos)) { + if (!this.pos.from || !this.pos.to) { console.log(this.matches, this.pos); } + this.atOccurrence = true; + return this.pos.match || true; + } + if (reverse) { + if (!pos.line) return savePosAndFail(0); + pos = Pos(pos.line-1, this.doc.getLine(pos.line-1).length); + } + else { + var maxLine = this.doc.lineCount(); + if (pos.line == maxLine - 1) return savePosAndFail(maxLine); + pos = Pos(pos.line + 1, 0); + } + } + }, + + from: function() {if (this.atOccurrence) return this.pos.from;}, + to: function() {if (this.atOccurrence) return this.pos.to;}, + + replace: function(newText) { + if (!this.atOccurrence) return; + var lines = CodeMirror.splitLines(newText); + this.doc.replaceRange(lines, this.pos.from, this.pos.to); + this.pos.to = Pos(this.pos.from.line + lines.length - 1, + lines[lines.length - 1].length + (lines.length == 1 ? this.pos.from.ch : 0)); + } + }; + + CodeMirror.defineExtension("getSearchCursor", function(query, pos, caseFold) { + return new SearchCursor(this.doc, query, pos, caseFold); + }); + CodeMirror.defineDocExtension("getSearchCursor", function(query, pos, caseFold) { + return new SearchCursor(this, query, pos, caseFold); + }); +})(); diff --git a/profile-builder/assets/lib/codemirror/addon/selection/active-line.js b/profile-builder/assets/lib/codemirror/addon/selection/active-line.js index e505086..f9f3496 100644 --- a/profile-builder/assets/lib/codemirror/addon/selection/active-line.js +++ b/profile-builder/assets/lib/codemirror/addon/selection/active-line.js @@ -1,39 +1,39 @@ -// Because sometimes you need to style the cursor's line. -// -// Adds an option 'styleActiveLine' which, when enabled, gives the -// active line's wrapping
            the CSS class "CodeMirror-activeline", -// and gives its background
            the class "CodeMirror-activeline-background". - -(function() { - "use strict"; - var WRAP_CLASS = "CodeMirror-activeline"; - var BACK_CLASS = "CodeMirror-activeline-background"; - - CodeMirror.defineOption("styleActiveLine", false, function(cm, val, old) { - var prev = old && old != CodeMirror.Init; - if (val && !prev) { - updateActiveLine(cm); - cm.on("cursorActivity", updateActiveLine); - } else if (!val && prev) { - cm.off("cursorActivity", updateActiveLine); - clearActiveLine(cm); - delete cm.state.activeLine; - } - }); - - function clearActiveLine(cm) { - if ("activeLine" in cm.state) { - cm.removeLineClass(cm.state.activeLine, "wrap", WRAP_CLASS); - cm.removeLineClass(cm.state.activeLine, "background", BACK_CLASS); - } - } - - function updateActiveLine(cm) { - var line = cm.getLineHandleVisualStart(cm.getCursor().line); - if (cm.state.activeLine == line) return; - clearActiveLine(cm); - cm.addLineClass(line, "wrap", WRAP_CLASS); - cm.addLineClass(line, "background", BACK_CLASS); - cm.state.activeLine = line; - } -})(); +// Because sometimes you need to style the cursor's line. +// +// Adds an option 'styleActiveLine' which, when enabled, gives the +// active line's wrapping
            the CSS class "CodeMirror-activeline", +// and gives its background
            the class "CodeMirror-activeline-background". + +(function() { + "use strict"; + var WRAP_CLASS = "CodeMirror-activeline"; + var BACK_CLASS = "CodeMirror-activeline-background"; + + CodeMirror.defineOption("styleActiveLine", false, function(cm, val, old) { + var prev = old && old != CodeMirror.Init; + if (val && !prev) { + updateActiveLine(cm); + cm.on("cursorActivity", updateActiveLine); + } else if (!val && prev) { + cm.off("cursorActivity", updateActiveLine); + clearActiveLine(cm); + delete cm.state.activeLine; + } + }); + + function clearActiveLine(cm) { + if ("activeLine" in cm.state) { + cm.removeLineClass(cm.state.activeLine, "wrap", WRAP_CLASS); + cm.removeLineClass(cm.state.activeLine, "background", BACK_CLASS); + } + } + + function updateActiveLine(cm) { + var line = cm.getLineHandleVisualStart(cm.getCursor().line); + if (cm.state.activeLine == line) return; + clearActiveLine(cm); + cm.addLineClass(line, "wrap", WRAP_CLASS); + cm.addLineClass(line, "background", BACK_CLASS); + cm.state.activeLine = line; + } +})(); diff --git a/profile-builder/assets/lib/codemirror/addon/selection/mark-selection.js b/profile-builder/assets/lib/codemirror/addon/selection/mark-selection.js index c97776e..eb5e7d5 100644 --- a/profile-builder/assets/lib/codemirror/addon/selection/mark-selection.js +++ b/profile-builder/assets/lib/codemirror/addon/selection/mark-selection.js @@ -1,108 +1,108 @@ -// Because sometimes you need to mark the selected *text*. -// -// Adds an option 'styleSelectedText' which, when enabled, gives -// selected text the CSS class given as option value, or -// "CodeMirror-selectedtext" when the value is not a string. - -(function() { - "use strict"; - - CodeMirror.defineOption("styleSelectedText", false, function(cm, val, old) { - var prev = old && old != CodeMirror.Init; - if (val && !prev) { - cm.state.markedSelection = []; - cm.state.markedSelectionStyle = typeof val == "string" ? val : "CodeMirror-selectedtext"; - reset(cm); - cm.on("cursorActivity", onCursorActivity); - cm.on("change", onChange); - } else if (!val && prev) { - cm.off("cursorActivity", onCursorActivity); - cm.off("change", onChange); - clear(cm); - cm.state.markedSelection = cm.state.markedSelectionStyle = null; - } - }); - - function onCursorActivity(cm) { - cm.operation(function() { update(cm); }); - } - - function onChange(cm) { - if (cm.state.markedSelection.length) - cm.operation(function() { clear(cm); }); - } - - var CHUNK_SIZE = 8; - var Pos = CodeMirror.Pos; - - function cmp(pos1, pos2) { - return pos1.line - pos2.line || pos1.ch - pos2.ch; - } - - function coverRange(cm, from, to, addAt) { - if (cmp(from, to) == 0) return; - var array = cm.state.markedSelection; - var cls = cm.state.markedSelectionStyle; - for (var line = from.line;;) { - var start = line == from.line ? from : Pos(line, 0); - var endLine = line + CHUNK_SIZE, atEnd = endLine >= to.line; - var end = atEnd ? to : Pos(endLine, 0); - var mark = cm.markText(start, end, {className: cls}); - if (addAt == null) array.push(mark); - else array.splice(addAt++, 0, mark); - if (atEnd) break; - line = endLine; - } - } - - function clear(cm) { - var array = cm.state.markedSelection; - for (var i = 0; i < array.length; ++i) array[i].clear(); - array.length = 0; - } - - function reset(cm) { - clear(cm); - var from = cm.getCursor("start"), to = cm.getCursor("end"); - coverRange(cm, from, to); - } - - function update(cm) { - var from = cm.getCursor("start"), to = cm.getCursor("end"); - if (cmp(from, to) == 0) return clear(cm); - - var array = cm.state.markedSelection; - if (!array.length) return coverRange(cm, from, to); - - var coverStart = array[0].find(), coverEnd = array[array.length - 1].find(); - if (!coverStart || !coverEnd || to.line - from.line < CHUNK_SIZE || - cmp(from, coverEnd.to) >= 0 || cmp(to, coverStart.from) <= 0) - return reset(cm); - - while (cmp(from, coverStart.from) > 0) { - array.shift().clear(); - coverStart = array[0].find(); - } - if (cmp(from, coverStart.from) < 0) { - if (coverStart.to.line - from.line < CHUNK_SIZE) { - array.shift().clear(); - coverRange(cm, from, coverStart.to, 0); - } else { - coverRange(cm, from, coverStart.from, 0); - } - } - - while (cmp(to, coverEnd.to) < 0) { - array.pop().clear(); - coverEnd = array[array.length - 1].find(); - } - if (cmp(to, coverEnd.to) > 0) { - if (to.line - coverEnd.from.line < CHUNK_SIZE) { - array.pop().clear(); - coverRange(cm, coverEnd.from, to); - } else { - coverRange(cm, coverEnd.to, to); - } - } - } -})(); +// Because sometimes you need to mark the selected *text*. +// +// Adds an option 'styleSelectedText' which, when enabled, gives +// selected text the CSS class given as option value, or +// "CodeMirror-selectedtext" when the value is not a string. + +(function() { + "use strict"; + + CodeMirror.defineOption("styleSelectedText", false, function(cm, val, old) { + var prev = old && old != CodeMirror.Init; + if (val && !prev) { + cm.state.markedSelection = []; + cm.state.markedSelectionStyle = typeof val == "string" ? val : "CodeMirror-selectedtext"; + reset(cm); + cm.on("cursorActivity", onCursorActivity); + cm.on("change", onChange); + } else if (!val && prev) { + cm.off("cursorActivity", onCursorActivity); + cm.off("change", onChange); + clear(cm); + cm.state.markedSelection = cm.state.markedSelectionStyle = null; + } + }); + + function onCursorActivity(cm) { + cm.operation(function() { update(cm); }); + } + + function onChange(cm) { + if (cm.state.markedSelection.length) + cm.operation(function() { clear(cm); }); + } + + var CHUNK_SIZE = 8; + var Pos = CodeMirror.Pos; + + function cmp(pos1, pos2) { + return pos1.line - pos2.line || pos1.ch - pos2.ch; + } + + function coverRange(cm, from, to, addAt) { + if (cmp(from, to) == 0) return; + var array = cm.state.markedSelection; + var cls = cm.state.markedSelectionStyle; + for (var line = from.line;;) { + var start = line == from.line ? from : Pos(line, 0); + var endLine = line + CHUNK_SIZE, atEnd = endLine >= to.line; + var end = atEnd ? to : Pos(endLine, 0); + var mark = cm.markText(start, end, {className: cls}); + if (addAt == null) array.push(mark); + else array.splice(addAt++, 0, mark); + if (atEnd) break; + line = endLine; + } + } + + function clear(cm) { + var array = cm.state.markedSelection; + for (var i = 0; i < array.length; ++i) array[i].clear(); + array.length = 0; + } + + function reset(cm) { + clear(cm); + var from = cm.getCursor("start"), to = cm.getCursor("end"); + coverRange(cm, from, to); + } + + function update(cm) { + var from = cm.getCursor("start"), to = cm.getCursor("end"); + if (cmp(from, to) == 0) return clear(cm); + + var array = cm.state.markedSelection; + if (!array.length) return coverRange(cm, from, to); + + var coverStart = array[0].find(), coverEnd = array[array.length - 1].find(); + if (!coverStart || !coverEnd || to.line - from.line < CHUNK_SIZE || + cmp(from, coverEnd.to) >= 0 || cmp(to, coverStart.from) <= 0) + return reset(cm); + + while (cmp(from, coverStart.from) > 0) { + array.shift().clear(); + coverStart = array[0].find(); + } + if (cmp(from, coverStart.from) < 0) { + if (coverStart.to.line - from.line < CHUNK_SIZE) { + array.shift().clear(); + coverRange(cm, from, coverStart.to, 0); + } else { + coverRange(cm, from, coverStart.from, 0); + } + } + + while (cmp(to, coverEnd.to) < 0) { + array.pop().clear(); + coverEnd = array[array.length - 1].find(); + } + if (cmp(to, coverEnd.to) > 0) { + if (to.line - coverEnd.from.line < CHUNK_SIZE) { + array.pop().clear(); + coverRange(cm, coverEnd.from, to); + } else { + coverRange(cm, coverEnd.to, to); + } + } + } +})(); diff --git a/profile-builder/assets/lib/codemirror/addon/tern/tern.css b/profile-builder/assets/lib/codemirror/addon/tern/tern.css index eacc2f0..9f5ac1c 100644 --- a/profile-builder/assets/lib/codemirror/addon/tern/tern.css +++ b/profile-builder/assets/lib/codemirror/addon/tern/tern.css @@ -1,85 +1,85 @@ -.CodeMirror-Tern-completion { - padding-left: 22px; - position: relative; -} -.CodeMirror-Tern-completion:before { - position: absolute; - left: 2px; - bottom: 2px; - border-radius: 50%; - font-size: 12px; - font-weight: bold; - height: 15px; - width: 15px; - line-height: 16px; - text-align: center; - color: white; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -.CodeMirror-Tern-completion-unknown:before { - content: "?"; - background: #4bb; -} -.CodeMirror-Tern-completion-object:before { - content: "O"; - background: #77c; -} -.CodeMirror-Tern-completion-fn:before { - content: "F"; - background: #7c7; -} -.CodeMirror-Tern-completion-array:before { - content: "A"; - background: #c66; -} -.CodeMirror-Tern-completion-number:before { - content: "1"; - background: #999; -} -.CodeMirror-Tern-completion-string:before { - content: "S"; - background: #999; -} -.CodeMirror-Tern-completion-bool:before { - content: "B"; - background: #999; -} - -.CodeMirror-Tern-completion-guess { - color: #999; -} - -.CodeMirror-Tern-tooltip { - border: 1px solid silver; - border-radius: 3px; - color: #444; - padding: 2px 5px; - font-size: 90%; - font-family: monospace; - background-color: white; - white-space: pre-wrap; - - max-width: 40em; - position: absolute; - z-index: 10; - -webkit-box-shadow: 2px 3px 5px rgba(0,0,0,.2); - -moz-box-shadow: 2px 3px 5px rgba(0,0,0,.2); - box-shadow: 2px 3px 5px rgba(0,0,0,.2); - - transition: opacity 1s; - -moz-transition: opacity 1s; - -webkit-transition: opacity 1s; - -o-transition: opacity 1s; - -ms-transition: opacity 1s; -} - -.CodeMirror-Tern-hint-doc { - max-width: 25em; -} - -.CodeMirror-Tern-fname { color: black; } -.CodeMirror-Tern-farg { color: #70a; } -.CodeMirror-Tern-farg-current { text-decoration: underline; } -.CodeMirror-Tern-type { color: #07c; } -.CodeMirror-Tern-fhint-guess { opacity: .7; } +.CodeMirror-Tern-completion { + padding-left: 22px; + position: relative; +} +.CodeMirror-Tern-completion:before { + position: absolute; + left: 2px; + bottom: 2px; + border-radius: 50%; + font-size: 12px; + font-weight: bold; + height: 15px; + width: 15px; + line-height: 16px; + text-align: center; + color: white; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.CodeMirror-Tern-completion-unknown:before { + content: "?"; + background: #4bb; +} +.CodeMirror-Tern-completion-object:before { + content: "O"; + background: #77c; +} +.CodeMirror-Tern-completion-fn:before { + content: "F"; + background: #7c7; +} +.CodeMirror-Tern-completion-array:before { + content: "A"; + background: #c66; +} +.CodeMirror-Tern-completion-number:before { + content: "1"; + background: #999; +} +.CodeMirror-Tern-completion-string:before { + content: "S"; + background: #999; +} +.CodeMirror-Tern-completion-bool:before { + content: "B"; + background: #999; +} + +.CodeMirror-Tern-completion-guess { + color: #999; +} + +.CodeMirror-Tern-tooltip { + border: 1px solid silver; + border-radius: 3px; + color: #444; + padding: 2px 5px; + font-size: 90%; + font-family: monospace; + background-color: white; + white-space: pre-wrap; + + max-width: 40em; + position: absolute; + z-index: 10; + -webkit-box-shadow: 2px 3px 5px rgba(0,0,0,.2); + -moz-box-shadow: 2px 3px 5px rgba(0,0,0,.2); + box-shadow: 2px 3px 5px rgba(0,0,0,.2); + + transition: opacity 1s; + -moz-transition: opacity 1s; + -webkit-transition: opacity 1s; + -o-transition: opacity 1s; + -ms-transition: opacity 1s; +} + +.CodeMirror-Tern-hint-doc { + max-width: 25em; +} + +.CodeMirror-Tern-fname { color: black; } +.CodeMirror-Tern-farg { color: #70a; } +.CodeMirror-Tern-farg-current { text-decoration: underline; } +.CodeMirror-Tern-type { color: #07c; } +.CodeMirror-Tern-fhint-guess { opacity: .7; } diff --git a/profile-builder/assets/lib/codemirror/addon/tern/tern.js b/profile-builder/assets/lib/codemirror/addon/tern/tern.js index 5084539..3b5735d 100644 --- a/profile-builder/assets/lib/codemirror/addon/tern/tern.js +++ b/profile-builder/assets/lib/codemirror/addon/tern/tern.js @@ -1,631 +1,631 @@ -// Glue code between CodeMirror and Tern. -// -// Create a CodeMirror.TernServer to wrap an actual Tern server, -// register open documents (CodeMirror.Doc instances) with it, and -// call its methods to activate the assisting functions that Tern -// provides. -// -// Options supported (all optional): -// * defs: An array of JSON definition data structures. -// * plugins: An object mapping plugin names to configuration -// options. -// * getFile: A function(name, c) that can be used to access files in -// the project that haven't been loaded yet. Simply do c(null) to -// indicate that a file is not available. -// * fileFilter: A function(value, docName, doc) that will be applied -// to documents before passing them on to Tern. -// * switchToDoc: A function(name) that should, when providing a -// multi-file view, switch the view or focus to the named file. -// * showError: A function(editor, message) that can be used to -// override the way errors are displayed. -// * completionTip: Customize the content in tooltips for completions. -// Is passed a single argument—the completion's data as returned by -// Tern—and may return a string, DOM node, or null to indicate that -// no tip should be shown. By default the docstring is shown. -// * typeTip: Like completionTip, but for the tooltips shown for type -// queries. -// * responseFilter: A function(doc, query, request, error, data) that -// will be applied to the Tern responses before treating them -// -// -// It is possible to run the Tern server in a web worker by specifying -// these additional options: -// * useWorker: Set to true to enable web worker mode. You'll probably -// want to feature detect the actual value you use here, for example -// !!window.Worker. -// * workerScript: The main script of the worker. Point this to -// wherever you are hosting worker.js from this directory. -// * workerDeps: An array of paths pointing (relative to workerScript) -// to the Acorn and Tern libraries and any Tern plugins you want to -// load. Or, if you minified those into a single script and included -// them in the workerScript, simply leave this undefined. - -(function() { - "use strict"; - - CodeMirror.TernServer = function(options) { - var self = this; - this.options = options || {}; - var plugins = this.options.plugins || (this.options.plugins = {}); - if (!plugins.doc_comment) plugins.doc_comment = true; - if (this.options.useWorker) { - this.server = new WorkerServer(this); - } else { - this.server = new tern.Server({ - getFile: function(name, c) { return getFile(self, name, c); }, - async: true, - defs: this.options.defs || [], - plugins: plugins - }); - } - this.docs = Object.create(null); - this.trackChange = function(doc, change) { trackChange(self, doc, change); }; - - this.cachedArgHints = null; - this.activeArgHints = null; - this.jumpStack = []; - }; - - CodeMirror.TernServer.prototype = { - addDoc: function(name, doc) { - var data = {doc: doc, name: name, changed: null}; - this.server.addFile(name, docValue(this, data)); - CodeMirror.on(doc, "change", this.trackChange); - return this.docs[name] = data; - }, - - delDoc: function(name) { - var found = this.docs[name]; - if (!found) return; - CodeMirror.off(found.doc, "change", this.trackChange); - delete this.docs[name]; - this.server.delFile(name); - }, - - hideDoc: function(name) { - closeArgHints(this); - var found = this.docs[name]; - if (found && found.changed) sendDoc(this, found); - }, - - complete: function(cm) { - var self = this; - CodeMirror.showHint(cm, function(cm, c) { return hint(self, cm, c); }, {async: true}); - }, - - getHint: function(cm, c) { return hint(this, cm, c); }, - - showType: function(cm) { showType(this, cm); }, - - updateArgHints: function(cm) { updateArgHints(this, cm); }, - - jumpToDef: function(cm) { jumpToDef(this, cm); }, - - jumpBack: function(cm) { jumpBack(this, cm); }, - - rename: function(cm) { rename(this, cm); }, - - request: function (cm, query, c) { - var self = this; - var doc = findDoc(this, cm.getDoc()); - var request = buildRequest(this, doc, query); - - this.server.request(request, function (error, data) { - if (!error && self.options.responseFilter) - data = self.options.responseFilter(doc, query, request, error, data); - c(error, data); - }); - } - }; - - var Pos = CodeMirror.Pos; - var cls = "CodeMirror-Tern-"; - var bigDoc = 250; - - function getFile(ts, name, c) { - var buf = ts.docs[name]; - if (buf) - c(docValue(ts, buf)); - else if (ts.options.getFile) - ts.options.getFile(name, c); - else - c(null); - } - - function findDoc(ts, doc, name) { - for (var n in ts.docs) { - var cur = ts.docs[n]; - if (cur.doc == doc) return cur; - } - if (!name) for (var i = 0;; ++i) { - n = "[doc" + (i || "") + "]"; - if (!ts.docs[n]) { name = n; break; } - } - return ts.addDoc(name, doc); - } - - function trackChange(ts, doc, change) { - var data = findDoc(ts, doc); - - var argHints = ts.cachedArgHints; - if (argHints && argHints.doc == doc && cmpPos(argHints.start, change.to) <= 0) - ts.cachedArgHints = null; - - var changed = data.changed; - if (changed == null) - data.changed = changed = {from: change.from.line, to: change.from.line}; - var end = change.from.line + (change.text.length - 1); - if (change.from.line < changed.to) changed.to = changed.to - (change.to.line - end); - if (end >= changed.to) changed.to = end + 1; - if (changed.from > change.from.line) changed.from = change.from.line; - - if (doc.lineCount() > bigDoc && change.to - changed.from > 100) setTimeout(function() { - if (data.changed && data.changed.to - data.changed.from > 100) sendDoc(ts, data); - }, 200); - } - - function sendDoc(ts, doc) { - ts.server.request({files: [{type: "full", name: doc.name, text: docValue(ts, doc)}]}, function(error) { - if (error) console.error(error); - else doc.changed = null; - }); - } - - // Completion - - function hint(ts, cm, c) { - ts.request(cm, {type: "completions", types: true, docs: true, urls: true}, function(error, data) { - if (error) return showError(ts, cm, error); - var completions = [], after = ""; - var from = data.start, to = data.end; - if (cm.getRange(Pos(from.line, from.ch - 2), from) == "[\"" && - cm.getRange(to, Pos(to.line, to.ch + 2)) != "\"]") - after = "\"]"; - - for (var i = 0; i < data.completions.length; ++i) { - var completion = data.completions[i], className = typeToIcon(completion.type); - if (data.guess) className += " " + cls + "guess"; - completions.push({text: completion.name + after, - displayText: completion.name, - className: className, - data: completion}); - } - - var obj = {from: from, to: to, list: completions}; - var tooltip = null; - CodeMirror.on(obj, "close", function() { remove(tooltip); }); - CodeMirror.on(obj, "update", function() { remove(tooltip); }); - CodeMirror.on(obj, "select", function(cur, node) { - remove(tooltip); - var content = ts.options.completionTip ? ts.options.completionTip(cur.data) : cur.data.doc; - if (content) { - tooltip = makeTooltip(node.parentNode.getBoundingClientRect().right + window.pageXOffset, - node.getBoundingClientRect().top + window.pageYOffset, content); - tooltip.className += " " + cls + "hint-doc"; - } - }); - c(obj); - }); - } - - function typeToIcon(type) { - var suffix; - if (type == "?") suffix = "unknown"; - else if (type == "number" || type == "string" || type == "bool") suffix = type; - else if (/^fn\(/.test(type)) suffix = "fn"; - else if (/^\[/.test(type)) suffix = "array"; - else suffix = "object"; - return cls + "completion " + cls + "completion-" + suffix; - } - - // Type queries - - function showType(ts, cm) { - ts.request(cm, "type", function(error, data) { - if (error) return showError(ts, cm, error); - if (ts.options.typeTip) { - var tip = ts.options.typeTip(data); - } else { - var tip = elt("span", null, elt("strong", null, data.type || "not found")); - if (data.doc) - tip.appendChild(document.createTextNode(" — " + data.doc)); - if (data.url) { - tip.appendChild(document.createTextNode(" ")); - tip.appendChild(elt("a", null, "[docs]")).href = data.url; - } - } - tempTooltip(cm, tip); - }); - } - - // Maintaining argument hints - - function updateArgHints(ts, cm) { - closeArgHints(ts); - - if (cm.somethingSelected()) return; - var state = cm.getTokenAt(cm.getCursor()).state; - var inner = CodeMirror.innerMode(cm.getMode(), state); - if (inner.mode.name != "javascript") return; - var lex = inner.state.lexical; - if (lex.info != "call") return; - - var ch, pos = lex.pos || 0, tabSize = cm.getOption("tabSize"); - for (var line = cm.getCursor().line, e = Math.max(0, line - 9), found = false; line >= e; --line) { - var str = cm.getLine(line), extra = 0; - for (var pos = 0;;) { - var tab = str.indexOf("\t", pos); - if (tab == -1) break; - extra += tabSize - (tab + extra) % tabSize - 1; - pos = tab + 1; - } - ch = lex.column - extra; - if (str.charAt(ch) == "(") {found = true; break;} - } - if (!found) return; - - var start = Pos(line, ch); - var cache = ts.cachedArgHints; - if (cache && cache.doc == cm.getDoc() && cmpPos(start, cache.start) == 0) - return showArgHints(ts, cm, pos); - - ts.request(cm, {type: "type", preferFunction: true, end: start}, function(error, data) { - if (error || !data.type || !(/^fn\(/).test(data.type)) return; - ts.cachedArgHints = { - start: pos, - type: parseFnType(data.type), - name: data.exprName || data.name || "fn", - guess: data.guess, - doc: cm.getDoc() - }; - showArgHints(ts, cm, pos); - }); - } - - function showArgHints(ts, cm, pos) { - closeArgHints(ts); - - var cache = ts.cachedArgHints, tp = cache.type; - var tip = elt("span", cache.guess ? cls + "fhint-guess" : null, - elt("span", cls + "fname", cache.name), "("); - for (var i = 0; i < tp.args.length; ++i) { - if (i) tip.appendChild(document.createTextNode(", ")); - var arg = tp.args[i]; - tip.appendChild(elt("span", cls + "farg" + (i == pos ? " " + cls + "farg-current" : ""), arg.name || "?")); - if (arg.type != "?") { - tip.appendChild(document.createTextNode(":\u00a0")); - tip.appendChild(elt("span", cls + "type", arg.type)); - } - } - tip.appendChild(document.createTextNode(tp.rettype ? ") ->\u00a0" : ")")); - if (tp.rettype) tip.appendChild(elt("span", cls + "type", tp.rettype)); - var place = cm.cursorCoords(null, "page"); - ts.activeArgHints = makeTooltip(place.right + 1, place.bottom, tip); - } - - function parseFnType(text) { - var args = [], pos = 3; - - function skipMatching(upto) { - var depth = 0, start = pos; - for (;;) { - var next = text.charAt(pos); - if (upto.test(next) && !depth) return text.slice(start, pos); - if (/[{\[\(]/.test(next)) ++depth; - else if (/[}\]\)]/.test(next)) --depth; - ++pos; - } - } - - // Parse arguments - if (text.charAt(pos) != ")") for (;;) { - var name = text.slice(pos).match(/^([^, \(\[\{]+): /); - if (name) { - pos += name[0].length; - name = name[1]; - } - args.push({name: name, type: skipMatching(/[\),]/)}); - if (text.charAt(pos) == ")") break; - pos += 2; - } - - var rettype = text.slice(pos).match(/^\) -> (.*)$/); - - return {args: args, rettype: rettype && rettype[1]}; - } - - // Moving to the definition of something - - function jumpToDef(ts, cm) { - function inner(varName) { - var req = {type: "definition", variable: varName || null}; - var doc = findDoc(ts, cm.getDoc()); - ts.server.request(buildRequest(ts, doc, req), function(error, data) { - if (error) return showError(ts, cm, error); - if (!data.file && data.url) { window.open(data.url); return; } - - if (data.file) { - var localDoc = ts.docs[data.file], found; - if (localDoc && (found = findContext(localDoc.doc, data))) { - ts.jumpStack.push({file: doc.name, - start: cm.getCursor("from"), - end: cm.getCursor("to")}); - moveTo(ts, doc, localDoc, found.start, found.end); - return; - } - } - showError(ts, cm, "Could not find a definition."); - }); - } - - if (!atInterestingExpression(cm)) - dialog(cm, "Jump to variable", function(name) { if (name) inner(name); }); - else - inner(); - } - - function jumpBack(ts, cm) { - var pos = ts.jumpStack.pop(), doc = pos && ts.docs[pos.file]; - if (!doc) return; - moveTo(ts, findDoc(ts, cm.getDoc()), doc, pos.start, pos.end); - } - - function moveTo(ts, curDoc, doc, start, end) { - doc.doc.setSelection(end, start); - if (curDoc != doc && ts.options.switchToDoc) { - closeArgHints(ts); - ts.options.switchToDoc(doc.name); - } - } - - // The {line,ch} representation of positions makes this rather awkward. - function findContext(doc, data) { - var before = data.context.slice(0, data.contextOffset).split("\n"); - var startLine = data.start.line - (before.length - 1); - var start = Pos(startLine, (before.length == 1 ? data.start.ch : doc.getLine(startLine).length) - before[0].length); - - var text = doc.getLine(startLine).slice(start.ch); - for (var cur = startLine + 1; cur < doc.lineCount() && text.length < data.context.length; ++cur) - text += "\n" + doc.getLine(cur); - if (text.slice(0, data.context.length) == data.context) return data; - - var cursor = doc.getSearchCursor(data.context, 0, false); - var nearest, nearestDist = Infinity; - while (cursor.findNext()) { - var from = cursor.from(), dist = Math.abs(from.line - start.line) * 10000; - if (!dist) dist = Math.abs(from.ch - start.ch); - if (dist < nearestDist) { nearest = from; nearestDist = dist; } - } - if (!nearest) return null; - - if (before.length == 1) - nearest.ch += before[0].length; - else - nearest = Pos(nearest.line + (before.length - 1), before[before.length - 1].length); - if (data.start.line == data.end.line) - var end = Pos(nearest.line, nearest.ch + (data.end.ch - data.start.ch)); - else - var end = Pos(nearest.line + (data.end.line - data.start.line), data.end.ch); - return {start: nearest, end: end}; - } - - function atInterestingExpression(cm) { - var pos = cm.getCursor("end"), tok = cm.getTokenAt(pos); - if (tok.start < pos.ch && (tok.type == "comment" || tok.type == "string")) return false; - return /\w/.test(cm.getLine(pos.line).slice(Math.max(pos.ch - 1, 0), pos.ch + 1)); - } - - // Variable renaming - - function rename(ts, cm) { - var token = cm.getTokenAt(cm.getCursor()); - if (!/\w/.test(token.string)) showError(ts, cm, "Not at a variable"); - dialog(cm, "New name for " + token.string, function(newName) { - ts.request(cm, {type: "rename", newName: newName, fullDocs: true}, function(error, data) { - if (error) return showError(ts, cm, error); - applyChanges(ts, data.changes); - }); - }); - } - - var nextChangeOrig = 0; - function applyChanges(ts, changes) { - var perFile = Object.create(null); - for (var i = 0; i < changes.length; ++i) { - var ch = changes[i]; - (perFile[ch.file] || (perFile[ch.file] = [])).push(ch); - } - for (var file in perFile) { - var known = ts.docs[file], chs = perFile[file];; - if (!known) continue; - chs.sort(function(a, b) { return cmpPos(b, a); }); - var origin = "*rename" + (++nextChangeOrig); - for (var i = 0; i < chs.length; ++i) { - var ch = chs[i]; - known.doc.replaceRange(ch.text, ch.start, ch.end, origin); - } - } - } - - // Generic request-building helper - - function buildRequest(ts, doc, query) { - var files = [], offsetLines = 0, allowFragments = !query.fullDocs; - if (!allowFragments) delete query.fullDocs; - if (typeof query == "string") query = {type: query}; - query.lineCharPositions = true; - if (query.end == null) { - query.end = doc.doc.getCursor("end"); - if (doc.doc.somethingSelected()) - query.start = doc.doc.getCursor("start"); - } - var startPos = query.start || query.end; - - if (doc.changed) { - if (doc.doc.lineCount() > bigDoc && allowFragments !== false && - doc.changed.to - doc.changed.from < 100 && - doc.changed.from <= startPos.line && doc.changed.to > query.end.line) { - files.push(getFragmentAround(doc, startPos, query.end)); - query.file = "#0"; - var offsetLines = files[0].offsetLines; - if (query.start != null) query.start = Pos(query.start.line - -offsetLines, query.start.ch); - query.end = Pos(query.end.line - offsetLines, query.end.ch); - } else { - files.push({type: "full", - name: doc.name, - text: docValue(ts, doc)}); - query.file = doc.name; - doc.changed = null; - } - } else { - query.file = doc.name; - } - for (var name in ts.docs) { - var cur = ts.docs[name]; - if (cur.changed && cur != doc) { - files.push({type: "full", name: cur.name, text: docValue(ts, cur)}); - cur.changed = null; - } - } - - return {query: query, files: files}; - } - - function getFragmentAround(data, start, end) { - var doc = data.doc; - var minIndent = null, minLine = null, endLine, tabSize = 4; - for (var p = start.line - 1, min = Math.max(0, p - 50); p >= min; --p) { - var line = doc.getLine(p), fn = line.search(/\bfunction\b/); - if (fn < 0) continue; - var indent = CodeMirror.countColumn(line, null, tabSize); - if (minIndent != null && minIndent <= indent) continue; - minIndent = indent; - minLine = p; - } - if (minLine == null) minLine = min; - var max = Math.min(doc.lastLine(), end.line + 20); - if (minIndent == null || minIndent == CodeMirror.countColumn(doc.getLine(start.line), null, tabSize)) - endLine = max; - else for (endLine = end.line + 1; endLine < max; ++endLine) { - var indent = CodeMirror.countColumn(doc.getLine(endLine), null, tabSize); - if (indent <= minIndent) break; - } - var from = Pos(minLine, 0); - - return {type: "part", - name: data.name, - offsetLines: from.line, - text: doc.getRange(from, Pos(endLine, 0))}; - } - - // Generic utilities - - function cmpPos(a, b) { return a.line - b.line || a.ch - b.ch; } - - function elt(tagname, cls /*, ... elts*/) { - var e = document.createElement(tagname); - if (cls) e.className = cls; - for (var i = 2; i < arguments.length; ++i) { - var elt = arguments[i]; - if (typeof elt == "string") elt = document.createTextNode(elt); - e.appendChild(elt); - } - return e; - } - - function dialog(cm, text, f) { - if (cm.openDialog) - cm.openDialog(text + ": ", f); - else - f(prompt(text, "")); - } - - // Tooltips - - function tempTooltip(cm, content) { - var where = cm.cursorCoords(); - var tip = makeTooltip(where.right + 1, where.bottom, content); - function clear() { - if (!tip.parentNode) return; - cm.off("cursorActivity", clear); - fadeOut(tip); - } - setTimeout(clear, 1700); - cm.on("cursorActivity", clear); - } - - function makeTooltip(x, y, content) { - var node = elt("div", cls + "tooltip", content); - node.style.left = x + "px"; - node.style.top = y + "px"; - document.body.appendChild(node); - return node; - } - - function remove(node) { - var p = node && node.parentNode; - if (p) p.removeChild(node); - } - - function fadeOut(tooltip) { - tooltip.style.opacity = "0"; - setTimeout(function() { remove(tooltip); }, 1100); - } - - function showError(ts, cm, msg) { - if (ts.options.showError) - ts.options.showError(cm, msg); - else - tempTooltip(cm, String(msg)); - } - - function closeArgHints(ts) { - if (ts.activeArgHints) { remove(ts.activeArgHints); ts.activeArgHints = null; } - } - - function docValue(ts, doc) { - var val = doc.doc.getValue(); - if (ts.options.fileFilter) val = ts.options.fileFilter(val, doc.name, doc.doc); - return val; - } - - // Worker wrapper - - function WorkerServer(ts) { - var worker = new Worker(ts.options.workerScript); - worker.postMessage({type: "init", - defs: ts.options.defs, - plugins: ts.options.plugins, - scripts: ts.options.workerDeps}); - var msgId = 0, pending = {}; - - function send(data, c) { - if (c) { - data.id = ++msgId; - pending[msgId] = c; - } - worker.postMessage(data); - } - worker.onmessage = function(e) { - var data = e.data; - if (data.type == "getFile") { - getFile(ts, name, function(err, text) { - send({type: "getFile", err: String(err), text: text, id: data.id}); - }); - } else if (data.type == "debug") { - console.log(data.message); - } else if (data.id && pending[data.id]) { - pending[data.id](data.err, data.body); - delete pending[data.id]; - } - }; - worker.onerror = function(e) { - for (var id in pending) pending[id](e); - pending = {}; - }; - - this.addFile = function(name, text) { send({type: "add", name: name, text: text}); }; - this.delFile = function(name) { send({type: "del", name: name}); }; - this.request = function(body, c) { send({type: "req", body: body}, c); }; - } -})(); +// Glue code between CodeMirror and Tern. +// +// Create a CodeMirror.TernServer to wrap an actual Tern server, +// register open documents (CodeMirror.Doc instances) with it, and +// call its methods to activate the assisting functions that Tern +// provides. +// +// Options supported (all optional): +// * defs: An array of JSON definition data structures. +// * plugins: An object mapping plugin names to configuration +// options. +// * getFile: A function(name, c) that can be used to access files in +// the project that haven't been loaded yet. Simply do c(null) to +// indicate that a file is not available. +// * fileFilter: A function(value, docName, doc) that will be applied +// to documents before passing them on to Tern. +// * switchToDoc: A function(name) that should, when providing a +// multi-file view, switch the view or focus to the named file. +// * showError: A function(editor, message) that can be used to +// override the way errors are displayed. +// * completionTip: Customize the content in tooltips for completions. +// Is passed a single argument—the completion's data as returned by +// Tern—and may return a string, DOM node, or null to indicate that +// no tip should be shown. By default the docstring is shown. +// * typeTip: Like completionTip, but for the tooltips shown for type +// queries. +// * responseFilter: A function(doc, query, request, error, data) that +// will be applied to the Tern responses before treating them +// +// +// It is possible to run the Tern server in a web worker by specifying +// these additional options: +// * useWorker: Set to true to enable web worker mode. You'll probably +// want to feature detect the actual value you use here, for example +// !!window.Worker. +// * workerScript: The main script of the worker. Point this to +// wherever you are hosting worker.js from this directory. +// * workerDeps: An array of paths pointing (relative to workerScript) +// to the Acorn and Tern libraries and any Tern plugins you want to +// load. Or, if you minified those into a single script and included +// them in the workerScript, simply leave this undefined. + +(function() { + "use strict"; + + CodeMirror.TernServer = function(options) { + var self = this; + this.options = options || {}; + var plugins = this.options.plugins || (this.options.plugins = {}); + if (!plugins.doc_comment) plugins.doc_comment = true; + if (this.options.useWorker) { + this.server = new WorkerServer(this); + } else { + this.server = new tern.Server({ + getFile: function(name, c) { return getFile(self, name, c); }, + async: true, + defs: this.options.defs || [], + plugins: plugins + }); + } + this.docs = Object.create(null); + this.trackChange = function(doc, change) { trackChange(self, doc, change); }; + + this.cachedArgHints = null; + this.activeArgHints = null; + this.jumpStack = []; + }; + + CodeMirror.TernServer.prototype = { + addDoc: function(name, doc) { + var data = {doc: doc, name: name, changed: null}; + this.server.addFile(name, docValue(this, data)); + CodeMirror.on(doc, "change", this.trackChange); + return this.docs[name] = data; + }, + + delDoc: function(name) { + var found = this.docs[name]; + if (!found) return; + CodeMirror.off(found.doc, "change", this.trackChange); + delete this.docs[name]; + this.server.delFile(name); + }, + + hideDoc: function(name) { + closeArgHints(this); + var found = this.docs[name]; + if (found && found.changed) sendDoc(this, found); + }, + + complete: function(cm) { + var self = this; + CodeMirror.showHint(cm, function(cm, c) { return hint(self, cm, c); }, {async: true}); + }, + + getHint: function(cm, c) { return hint(this, cm, c); }, + + showType: function(cm) { showType(this, cm); }, + + updateArgHints: function(cm) { updateArgHints(this, cm); }, + + jumpToDef: function(cm) { jumpToDef(this, cm); }, + + jumpBack: function(cm) { jumpBack(this, cm); }, + + rename: function(cm) { rename(this, cm); }, + + request: function (cm, query, c) { + var self = this; + var doc = findDoc(this, cm.getDoc()); + var request = buildRequest(this, doc, query); + + this.server.request(request, function (error, data) { + if (!error && self.options.responseFilter) + data = self.options.responseFilter(doc, query, request, error, data); + c(error, data); + }); + } + }; + + var Pos = CodeMirror.Pos; + var cls = "CodeMirror-Tern-"; + var bigDoc = 250; + + function getFile(ts, name, c) { + var buf = ts.docs[name]; + if (buf) + c(docValue(ts, buf)); + else if (ts.options.getFile) + ts.options.getFile(name, c); + else + c(null); + } + + function findDoc(ts, doc, name) { + for (var n in ts.docs) { + var cur = ts.docs[n]; + if (cur.doc == doc) return cur; + } + if (!name) for (var i = 0;; ++i) { + n = "[doc" + (i || "") + "]"; + if (!ts.docs[n]) { name = n; break; } + } + return ts.addDoc(name, doc); + } + + function trackChange(ts, doc, change) { + var data = findDoc(ts, doc); + + var argHints = ts.cachedArgHints; + if (argHints && argHints.doc == doc && cmpPos(argHints.start, change.to) <= 0) + ts.cachedArgHints = null; + + var changed = data.changed; + if (changed == null) + data.changed = changed = {from: change.from.line, to: change.from.line}; + var end = change.from.line + (change.text.length - 1); + if (change.from.line < changed.to) changed.to = changed.to - (change.to.line - end); + if (end >= changed.to) changed.to = end + 1; + if (changed.from > change.from.line) changed.from = change.from.line; + + if (doc.lineCount() > bigDoc && change.to - changed.from > 100) setTimeout(function() { + if (data.changed && data.changed.to - data.changed.from > 100) sendDoc(ts, data); + }, 200); + } + + function sendDoc(ts, doc) { + ts.server.request({files: [{type: "full", name: doc.name, text: docValue(ts, doc)}]}, function(error) { + if (error) console.error(error); + else doc.changed = null; + }); + } + + // Completion + + function hint(ts, cm, c) { + ts.request(cm, {type: "completions", types: true, docs: true, urls: true}, function(error, data) { + if (error) return showError(ts, cm, error); + var completions = [], after = ""; + var from = data.start, to = data.end; + if (cm.getRange(Pos(from.line, from.ch - 2), from) == "[\"" && + cm.getRange(to, Pos(to.line, to.ch + 2)) != "\"]") + after = "\"]"; + + for (var i = 0; i < data.completions.length; ++i) { + var completion = data.completions[i], className = typeToIcon(completion.type); + if (data.guess) className += " " + cls + "guess"; + completions.push({text: completion.name + after, + displayText: completion.name, + className: className, + data: completion}); + } + + var obj = {from: from, to: to, list: completions}; + var tooltip = null; + CodeMirror.on(obj, "close", function() { remove(tooltip); }); + CodeMirror.on(obj, "update", function() { remove(tooltip); }); + CodeMirror.on(obj, "select", function(cur, node) { + remove(tooltip); + var content = ts.options.completionTip ? ts.options.completionTip(cur.data) : cur.data.doc; + if (content) { + tooltip = makeTooltip(node.parentNode.getBoundingClientRect().right + window.pageXOffset, + node.getBoundingClientRect().top + window.pageYOffset, content); + tooltip.className += " " + cls + "hint-doc"; + } + }); + c(obj); + }); + } + + function typeToIcon(type) { + var suffix; + if (type == "?") suffix = "unknown"; + else if (type == "number" || type == "string" || type == "bool") suffix = type; + else if (/^fn\(/.test(type)) suffix = "fn"; + else if (/^\[/.test(type)) suffix = "array"; + else suffix = "object"; + return cls + "completion " + cls + "completion-" + suffix; + } + + // Type queries + + function showType(ts, cm) { + ts.request(cm, "type", function(error, data) { + if (error) return showError(ts, cm, error); + if (ts.options.typeTip) { + var tip = ts.options.typeTip(data); + } else { + var tip = elt("span", null, elt("strong", null, data.type || "not found")); + if (data.doc) + tip.appendChild(document.createTextNode(" — " + data.doc)); + if (data.url) { + tip.appendChild(document.createTextNode(" ")); + tip.appendChild(elt("a", null, "[docs]")).href = data.url; + } + } + tempTooltip(cm, tip); + }); + } + + // Maintaining argument hints + + function updateArgHints(ts, cm) { + closeArgHints(ts); + + if (cm.somethingSelected()) return; + var state = cm.getTokenAt(cm.getCursor()).state; + var inner = CodeMirror.innerMode(cm.getMode(), state); + if (inner.mode.name != "javascript") return; + var lex = inner.state.lexical; + if (lex.info != "call") return; + + var ch, pos = lex.pos || 0, tabSize = cm.getOption("tabSize"); + for (var line = cm.getCursor().line, e = Math.max(0, line - 9), found = false; line >= e; --line) { + var str = cm.getLine(line), extra = 0; + for (var pos = 0;;) { + var tab = str.indexOf("\t", pos); + if (tab == -1) break; + extra += tabSize - (tab + extra) % tabSize - 1; + pos = tab + 1; + } + ch = lex.column - extra; + if (str.charAt(ch) == "(") {found = true; break;} + } + if (!found) return; + + var start = Pos(line, ch); + var cache = ts.cachedArgHints; + if (cache && cache.doc == cm.getDoc() && cmpPos(start, cache.start) == 0) + return showArgHints(ts, cm, pos); + + ts.request(cm, {type: "type", preferFunction: true, end: start}, function(error, data) { + if (error || !data.type || !(/^fn\(/).test(data.type)) return; + ts.cachedArgHints = { + start: pos, + type: parseFnType(data.type), + name: data.exprName || data.name || "fn", + guess: data.guess, + doc: cm.getDoc() + }; + showArgHints(ts, cm, pos); + }); + } + + function showArgHints(ts, cm, pos) { + closeArgHints(ts); + + var cache = ts.cachedArgHints, tp = cache.type; + var tip = elt("span", cache.guess ? cls + "fhint-guess" : null, + elt("span", cls + "fname", cache.name), "("); + for (var i = 0; i < tp.args.length; ++i) { + if (i) tip.appendChild(document.createTextNode(", ")); + var arg = tp.args[i]; + tip.appendChild(elt("span", cls + "farg" + (i == pos ? " " + cls + "farg-current" : ""), arg.name || "?")); + if (arg.type != "?") { + tip.appendChild(document.createTextNode(":\u00a0")); + tip.appendChild(elt("span", cls + "type", arg.type)); + } + } + tip.appendChild(document.createTextNode(tp.rettype ? ") ->\u00a0" : ")")); + if (tp.rettype) tip.appendChild(elt("span", cls + "type", tp.rettype)); + var place = cm.cursorCoords(null, "page"); + ts.activeArgHints = makeTooltip(place.right + 1, place.bottom, tip); + } + + function parseFnType(text) { + var args = [], pos = 3; + + function skipMatching(upto) { + var depth = 0, start = pos; + for (;;) { + var next = text.charAt(pos); + if (upto.test(next) && !depth) return text.slice(start, pos); + if (/[{\[\(]/.test(next)) ++depth; + else if (/[}\]\)]/.test(next)) --depth; + ++pos; + } + } + + // Parse arguments + if (text.charAt(pos) != ")") for (;;) { + var name = text.slice(pos).match(/^([^, \(\[\{]+): /); + if (name) { + pos += name[0].length; + name = name[1]; + } + args.push({name: name, type: skipMatching(/[\),]/)}); + if (text.charAt(pos) == ")") break; + pos += 2; + } + + var rettype = text.slice(pos).match(/^\) -> (.*)$/); + + return {args: args, rettype: rettype && rettype[1]}; + } + + // Moving to the definition of something + + function jumpToDef(ts, cm) { + function inner(varName) { + var req = {type: "definition", variable: varName || null}; + var doc = findDoc(ts, cm.getDoc()); + ts.server.request(buildRequest(ts, doc, req), function(error, data) { + if (error) return showError(ts, cm, error); + if (!data.file && data.url) { window.open(data.url); return; } + + if (data.file) { + var localDoc = ts.docs[data.file], found; + if (localDoc && (found = findContext(localDoc.doc, data))) { + ts.jumpStack.push({file: doc.name, + start: cm.getCursor("from"), + end: cm.getCursor("to")}); + moveTo(ts, doc, localDoc, found.start, found.end); + return; + } + } + showError(ts, cm, "Could not find a definition."); + }); + } + + if (!atInterestingExpression(cm)) + dialog(cm, "Jump to variable", function(name) { if (name) inner(name); }); + else + inner(); + } + + function jumpBack(ts, cm) { + var pos = ts.jumpStack.pop(), doc = pos && ts.docs[pos.file]; + if (!doc) return; + moveTo(ts, findDoc(ts, cm.getDoc()), doc, pos.start, pos.end); + } + + function moveTo(ts, curDoc, doc, start, end) { + doc.doc.setSelection(end, start); + if (curDoc != doc && ts.options.switchToDoc) { + closeArgHints(ts); + ts.options.switchToDoc(doc.name); + } + } + + // The {line,ch} representation of positions makes this rather awkward. + function findContext(doc, data) { + var before = data.context.slice(0, data.contextOffset).split("\n"); + var startLine = data.start.line - (before.length - 1); + var start = Pos(startLine, (before.length == 1 ? data.start.ch : doc.getLine(startLine).length) - before[0].length); + + var text = doc.getLine(startLine).slice(start.ch); + for (var cur = startLine + 1; cur < doc.lineCount() && text.length < data.context.length; ++cur) + text += "\n" + doc.getLine(cur); + if (text.slice(0, data.context.length) == data.context) return data; + + var cursor = doc.getSearchCursor(data.context, 0, false); + var nearest, nearestDist = Infinity; + while (cursor.findNext()) { + var from = cursor.from(), dist = Math.abs(from.line - start.line) * 10000; + if (!dist) dist = Math.abs(from.ch - start.ch); + if (dist < nearestDist) { nearest = from; nearestDist = dist; } + } + if (!nearest) return null; + + if (before.length == 1) + nearest.ch += before[0].length; + else + nearest = Pos(nearest.line + (before.length - 1), before[before.length - 1].length); + if (data.start.line == data.end.line) + var end = Pos(nearest.line, nearest.ch + (data.end.ch - data.start.ch)); + else + var end = Pos(nearest.line + (data.end.line - data.start.line), data.end.ch); + return {start: nearest, end: end}; + } + + function atInterestingExpression(cm) { + var pos = cm.getCursor("end"), tok = cm.getTokenAt(pos); + if (tok.start < pos.ch && (tok.type == "comment" || tok.type == "string")) return false; + return /\w/.test(cm.getLine(pos.line).slice(Math.max(pos.ch - 1, 0), pos.ch + 1)); + } + + // Variable renaming + + function rename(ts, cm) { + var token = cm.getTokenAt(cm.getCursor()); + if (!/\w/.test(token.string)) showError(ts, cm, "Not at a variable"); + dialog(cm, "New name for " + token.string, function(newName) { + ts.request(cm, {type: "rename", newName: newName, fullDocs: true}, function(error, data) { + if (error) return showError(ts, cm, error); + applyChanges(ts, data.changes); + }); + }); + } + + var nextChangeOrig = 0; + function applyChanges(ts, changes) { + var perFile = Object.create(null); + for (var i = 0; i < changes.length; ++i) { + var ch = changes[i]; + (perFile[ch.file] || (perFile[ch.file] = [])).push(ch); + } + for (var file in perFile) { + var known = ts.docs[file], chs = perFile[file];; + if (!known) continue; + chs.sort(function(a, b) { return cmpPos(b, a); }); + var origin = "*rename" + (++nextChangeOrig); + for (var i = 0; i < chs.length; ++i) { + var ch = chs[i]; + known.doc.replaceRange(ch.text, ch.start, ch.end, origin); + } + } + } + + // Generic request-building helper + + function buildRequest(ts, doc, query) { + var files = [], offsetLines = 0, allowFragments = !query.fullDocs; + if (!allowFragments) delete query.fullDocs; + if (typeof query == "string") query = {type: query}; + query.lineCharPositions = true; + if (query.end == null) { + query.end = doc.doc.getCursor("end"); + if (doc.doc.somethingSelected()) + query.start = doc.doc.getCursor("start"); + } + var startPos = query.start || query.end; + + if (doc.changed) { + if (doc.doc.lineCount() > bigDoc && allowFragments !== false && + doc.changed.to - doc.changed.from < 100 && + doc.changed.from <= startPos.line && doc.changed.to > query.end.line) { + files.push(getFragmentAround(doc, startPos, query.end)); + query.file = "#0"; + var offsetLines = files[0].offsetLines; + if (query.start != null) query.start = Pos(query.start.line - -offsetLines, query.start.ch); + query.end = Pos(query.end.line - offsetLines, query.end.ch); + } else { + files.push({type: "full", + name: doc.name, + text: docValue(ts, doc)}); + query.file = doc.name; + doc.changed = null; + } + } else { + query.file = doc.name; + } + for (var name in ts.docs) { + var cur = ts.docs[name]; + if (cur.changed && cur != doc) { + files.push({type: "full", name: cur.name, text: docValue(ts, cur)}); + cur.changed = null; + } + } + + return {query: query, files: files}; + } + + function getFragmentAround(data, start, end) { + var doc = data.doc; + var minIndent = null, minLine = null, endLine, tabSize = 4; + for (var p = start.line - 1, min = Math.max(0, p - 50); p >= min; --p) { + var line = doc.getLine(p), fn = line.search(/\bfunction\b/); + if (fn < 0) continue; + var indent = CodeMirror.countColumn(line, null, tabSize); + if (minIndent != null && minIndent <= indent) continue; + minIndent = indent; + minLine = p; + } + if (minLine == null) minLine = min; + var max = Math.min(doc.lastLine(), end.line + 20); + if (minIndent == null || minIndent == CodeMirror.countColumn(doc.getLine(start.line), null, tabSize)) + endLine = max; + else for (endLine = end.line + 1; endLine < max; ++endLine) { + var indent = CodeMirror.countColumn(doc.getLine(endLine), null, tabSize); + if (indent <= minIndent) break; + } + var from = Pos(minLine, 0); + + return {type: "part", + name: data.name, + offsetLines: from.line, + text: doc.getRange(from, Pos(endLine, 0))}; + } + + // Generic utilities + + function cmpPos(a, b) { return a.line - b.line || a.ch - b.ch; } + + function elt(tagname, cls /*, ... elts*/) { + var e = document.createElement(tagname); + if (cls) e.className = cls; + for (var i = 2; i < arguments.length; ++i) { + var elt = arguments[i]; + if (typeof elt == "string") elt = document.createTextNode(elt); + e.appendChild(elt); + } + return e; + } + + function dialog(cm, text, f) { + if (cm.openDialog) + cm.openDialog(text + ": ", f); + else + f(prompt(text, "")); + } + + // Tooltips + + function tempTooltip(cm, content) { + var where = cm.cursorCoords(); + var tip = makeTooltip(where.right + 1, where.bottom, content); + function clear() { + if (!tip.parentNode) return; + cm.off("cursorActivity", clear); + fadeOut(tip); + } + setTimeout(clear, 1700); + cm.on("cursorActivity", clear); + } + + function makeTooltip(x, y, content) { + var node = elt("div", cls + "tooltip", content); + node.style.left = x + "px"; + node.style.top = y + "px"; + document.body.appendChild(node); + return node; + } + + function remove(node) { + var p = node && node.parentNode; + if (p) p.removeChild(node); + } + + function fadeOut(tooltip) { + tooltip.style.opacity = "0"; + setTimeout(function() { remove(tooltip); }, 1100); + } + + function showError(ts, cm, msg) { + if (ts.options.showError) + ts.options.showError(cm, msg); + else + tempTooltip(cm, String(msg)); + } + + function closeArgHints(ts) { + if (ts.activeArgHints) { remove(ts.activeArgHints); ts.activeArgHints = null; } + } + + function docValue(ts, doc) { + var val = doc.doc.getValue(); + if (ts.options.fileFilter) val = ts.options.fileFilter(val, doc.name, doc.doc); + return val; + } + + // Worker wrapper + + function WorkerServer(ts) { + var worker = new Worker(ts.options.workerScript); + worker.postMessage({type: "init", + defs: ts.options.defs, + plugins: ts.options.plugins, + scripts: ts.options.workerDeps}); + var msgId = 0, pending = {}; + + function send(data, c) { + if (c) { + data.id = ++msgId; + pending[msgId] = c; + } + worker.postMessage(data); + } + worker.onmessage = function(e) { + var data = e.data; + if (data.type == "getFile") { + getFile(ts, name, function(err, text) { + send({type: "getFile", err: String(err), text: text, id: data.id}); + }); + } else if (data.type == "debug") { + console.log(data.message); + } else if (data.id && pending[data.id]) { + pending[data.id](data.err, data.body); + delete pending[data.id]; + } + }; + worker.onerror = function(e) { + for (var id in pending) pending[id](e); + pending = {}; + }; + + this.addFile = function(name, text) { send({type: "add", name: name, text: text}); }; + this.delFile = function(name) { send({type: "del", name: name}); }; + this.request = function(body, c) { send({type: "req", body: body}, c); }; + } +})(); diff --git a/profile-builder/assets/lib/codemirror/addon/tern/worker.js b/profile-builder/assets/lib/codemirror/addon/tern/worker.js index 0164762..8954d24 100644 --- a/profile-builder/assets/lib/codemirror/addon/tern/worker.js +++ b/profile-builder/assets/lib/codemirror/addon/tern/worker.js @@ -1,39 +1,39 @@ -var server; - -this.onmessage = function(e) { - var data = e.data; - switch (data.type) { - case "init": return startServer(data.defs, data.plugins, data.scripts); - case "add": return server.addFile(data.name, data.text); - case "del": return server.delFile(data.name); - case "req": return server.request(data.body, function(err, reqData) { - postMessage({id: data.id, body: reqData, err: err && String(err)}); - }); - case "getFile": - var c = pending[data.id]; - delete pending[data.id]; - return c(data.err, data.text); - default: throw new Error("Unknown message type: " + data.type); - } -}; - -var nextId = 0, pending = {}; -function getFile(file, c) { - postMessage({type: "getFile", name: file, id: ++nextId}); - pending[nextId] = c; -} - -function startServer(defs, plugins, scripts) { - if (scripts) importScripts.apply(null, scripts); - - server = new tern.Server({ - getFile: getFile, - async: true, - defs: defs, - plugins: plugins - }); -} - -var console = { - log: function(v) { postMessage({type: "debug", message: v}); } -}; +var server; + +this.onmessage = function(e) { + var data = e.data; + switch (data.type) { + case "init": return startServer(data.defs, data.plugins, data.scripts); + case "add": return server.addFile(data.name, data.text); + case "del": return server.delFile(data.name); + case "req": return server.request(data.body, function(err, reqData) { + postMessage({id: data.id, body: reqData, err: err && String(err)}); + }); + case "getFile": + var c = pending[data.id]; + delete pending[data.id]; + return c(data.err, data.text); + default: throw new Error("Unknown message type: " + data.type); + } +}; + +var nextId = 0, pending = {}; +function getFile(file, c) { + postMessage({type: "getFile", name: file, id: ++nextId}); + pending[nextId] = c; +} + +function startServer(defs, plugins, scripts) { + if (scripts) importScripts.apply(null, scripts); + + server = new tern.Server({ + getFile: getFile, + async: true, + defs: defs, + plugins: plugins + }); +} + +var console = { + log: function(v) { postMessage({type: "debug", message: v}); } +}; diff --git a/profile-builder/assets/lib/codemirror/lib/codemirror.css b/profile-builder/assets/lib/codemirror/lib/codemirror.css index e784f9e..db1183e 100644 --- a/profile-builder/assets/lib/codemirror/lib/codemirror.css +++ b/profile-builder/assets/lib/codemirror/lib/codemirror.css @@ -1,273 +1,273 @@ -/* BASICS */ - -.CodeMirror { - /* Set height, width, borders, and global font properties here */ - font-family: monospace; - height: 300px; -} -.CodeMirror-scroll { - /* Set scrolling behaviour here */ - overflow: auto; -} - -/* PADDING */ - -.CodeMirror-lines { - padding: 4px 0; /* Vertical padding around content */ -} -.CodeMirror pre { - padding: 0 4px; /* Horizontal padding of content */ -} - -.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler { - background-color: white; /* The little square between H and V scrollbars */ -} - -/* GUTTER */ - -.CodeMirror-gutters { - border-right: 1px solid #ddd; - background-color: #f7f7f7; - white-space: nowrap; -} -.CodeMirror-linenumbers {} -.CodeMirror-linenumber { - padding: 0 3px 0 5px; - min-width: 20px; - text-align: right; - color: #999; -} - -/* CURSOR */ - -.CodeMirror div.CodeMirror-cursor { - border-left: 1px solid black; - z-index: 3; -} -/* Shown when moving in bi-directional text */ -.CodeMirror div.CodeMirror-secondarycursor { - border-left: 1px solid silver; -} -.CodeMirror.cm-keymap-fat-cursor div.CodeMirror-cursor { - width: auto; - border: 0; - background: #7e7; - z-index: 1; -} -/* Can style cursor different in overwrite (non-insert) mode */ -.CodeMirror div.CodeMirror-cursor.CodeMirror-overwrite {} - -.cm-tab { display: inline-block; } - -/* DEFAULT THEME */ - -.cm-s-default .cm-keyword {color: #708;} -.cm-s-default .cm-atom {color: #219;} -.cm-s-default .cm-number {color: #164;} -.cm-s-default .cm-def {color: #00f;} -.cm-s-default .cm-variable {color: black;} -.cm-s-default .cm-variable-2 {color: #05a;} -.cm-s-default .cm-variable-3 {color: #085;} -.cm-s-default .cm-property {color: black;} -.cm-s-default .cm-operator {color: black;} -.cm-s-default .cm-comment {color: #a50;} -.cm-s-default .cm-string {color: #a11;} -.cm-s-default .cm-string-2 {color: #f50;} -.cm-s-default .cm-meta {color: #555;} -.cm-s-default .cm-error {color: #f00;} -.cm-s-default .cm-qualifier {color: #555;} -.cm-s-default .cm-builtin {color: #30a;} -.cm-s-default .cm-bracket {color: #997;} -.cm-s-default .cm-tag {color: #170;} -.cm-s-default .cm-attribute {color: #00c;} -.cm-s-default .cm-header {color: blue;} -.cm-s-default .cm-quote {color: #090;} -.cm-s-default .cm-hr {color: #999;} -.cm-s-default .cm-link {color: #00c;} - -.cm-negative {color: #d44;} -.cm-positive {color: #292;} -.cm-header, .cm-strong {font-weight: bold;} -.cm-em {font-style: italic;} -.cm-link {text-decoration: underline;} - -.cm-invalidchar {color: #f00;} - -div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;} -div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;} -.CodeMirror-activeline-background {background: #e8f2ff;} - -/* STOP */ - -/* The rest of this file contains styles related to the mechanics of - the editor. You probably shouldn't touch them. */ - -.CodeMirror { - line-height: 1; - position: relative; - overflow: hidden; - background: white; - color: black; -} - -.CodeMirror-scroll { - /* 30px is the magic margin used to hide the element's real scrollbars */ - /* See overflow: hidden in .CodeMirror */ - margin-bottom: -30px; margin-right: -30px; - padding-bottom: 30px; padding-right: 30px; - height: 100%; - outline: none; /* Prevent dragging from highlighting the element */ - position: relative; - -moz-box-sizing: content-box; - box-sizing: content-box; -} -.CodeMirror-sizer { - position: relative; -} - -/* The fake, visible scrollbars. Used to force redraw during scrolling - before actuall scrolling happens, thus preventing shaking and - flickering artifacts. */ -.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler { - position: absolute; - z-index: 6; - display: none; -} -.CodeMirror-vscrollbar { - right: 0; top: 0; - overflow-x: hidden; - overflow-y: scroll; -} -.CodeMirror-hscrollbar { - bottom: 0; left: 0; - overflow-y: hidden; - overflow-x: scroll; -} -.CodeMirror-scrollbar-filler { - right: 0; bottom: 0; -} -.CodeMirror-gutter-filler { - left: 0; bottom: 0; -} - -.CodeMirror-gutters { - position: absolute; left: 0; top: 0; - padding-bottom: 30px; - z-index: 3; -} -.CodeMirror-gutter { - white-space: normal; - height: 100%; - -moz-box-sizing: content-box; - box-sizing: content-box; - padding-bottom: 30px; - margin-bottom: -32px; - display: inline-block; - /* Hack to make IE7 behave */ - *zoom:1; - *display:inline; -} -.CodeMirror-gutter-elt { - position: absolute; - cursor: default; - z-index: 4; -} - -.CodeMirror-lines { - cursor: text; -} -.CodeMirror pre { - /* Reset some styles that the rest of the page might have set */ - -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0; - border-width: 0; - background: transparent; - font-family: inherit; - font-size: inherit; - margin: 0; - white-space: pre; - word-wrap: normal; - line-height: inherit; - color: inherit; - z-index: 2; - position: relative; - overflow: visible; -} -.CodeMirror-wrap pre { - word-wrap: break-word; - white-space: pre-wrap; - word-break: normal; -} -.CodeMirror-code pre { - border-right: 30px solid transparent; - width: -webkit-fit-content; - width: -moz-fit-content; - width: fit-content; -} -.CodeMirror-wrap .CodeMirror-code pre { - border-right: none; - width: auto; -} -.CodeMirror-linebackground { - position: absolute; - left: 0; right: 0; top: 0; bottom: 0; - z-index: 0; -} - -.CodeMirror-linewidget { - position: relative; - z-index: 2; - overflow: auto; -} - -.CodeMirror-widget {} - -.CodeMirror-wrap .CodeMirror-scroll { - overflow-x: hidden; -} - -.CodeMirror-measure { - position: absolute; - width: 100%; - height: 0; - overflow: hidden; - visibility: hidden; -} -.CodeMirror-measure pre { position: static; } - -.CodeMirror div.CodeMirror-cursor { - position: absolute; - visibility: hidden; - border-right: none; - width: 0; -} -.CodeMirror-focused div.CodeMirror-cursor { - visibility: visible; -} - -.CodeMirror-selected { background: #d9d9d9; } -.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; } - -.cm-searching { - background: #ffa; - background: rgba(255, 255, 0, .4); -} - -/* IE7 hack to prevent it from returning funny offsetTops on the spans */ -.CodeMirror span { *vertical-align: text-bottom; } - -@media print { - /* Hide the cursor when printing */ - .CodeMirror div.CodeMirror-cursor { - visibility: hidden; - } -} - - -/* fullscreen adapted code */ -.CodeMirror-fullscreen { - position: fixed; - top: 0; left: 0; right: 0; bottom: 0; - height: auto; - width:auto !important; - z-index: 999999; -} +/* BASICS */ + +.CodeMirror { + /* Set height, width, borders, and global font properties here */ + font-family: monospace; + height: 300px; +} +.CodeMirror-scroll { + /* Set scrolling behaviour here */ + overflow: auto; +} + +/* PADDING */ + +.CodeMirror-lines { + padding: 4px 0; /* Vertical padding around content */ +} +.CodeMirror pre { + padding: 0 4px; /* Horizontal padding of content */ +} + +.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler { + background-color: white; /* The little square between H and V scrollbars */ +} + +/* GUTTER */ + +.CodeMirror-gutters { + border-right: 1px solid #ddd; + background-color: #f7f7f7; + white-space: nowrap; +} +.CodeMirror-linenumbers {} +.CodeMirror-linenumber { + padding: 0 3px 0 5px; + min-width: 20px; + text-align: right; + color: #999; +} + +/* CURSOR */ + +.CodeMirror div.CodeMirror-cursor { + border-left: 1px solid black; + z-index: 3; +} +/* Shown when moving in bi-directional text */ +.CodeMirror div.CodeMirror-secondarycursor { + border-left: 1px solid silver; +} +.CodeMirror.cm-keymap-fat-cursor div.CodeMirror-cursor { + width: auto; + border: 0; + background: #7e7; + z-index: 1; +} +/* Can style cursor different in overwrite (non-insert) mode */ +.CodeMirror div.CodeMirror-cursor.CodeMirror-overwrite {} + +.cm-tab { display: inline-block; } + +/* DEFAULT THEME */ + +.cm-s-default .cm-keyword {color: #708;} +.cm-s-default .cm-atom {color: #219;} +.cm-s-default .cm-number {color: #164;} +.cm-s-default .cm-def {color: #00f;} +.cm-s-default .cm-variable {color: black;} +.cm-s-default .cm-variable-2 {color: #05a;} +.cm-s-default .cm-variable-3 {color: #085;} +.cm-s-default .cm-property {color: black;} +.cm-s-default .cm-operator {color: black;} +.cm-s-default .cm-comment {color: #a50;} +.cm-s-default .cm-string {color: #a11;} +.cm-s-default .cm-string-2 {color: #f50;} +.cm-s-default .cm-meta {color: #555;} +.cm-s-default .cm-error {color: #f00;} +.cm-s-default .cm-qualifier {color: #555;} +.cm-s-default .cm-builtin {color: #30a;} +.cm-s-default .cm-bracket {color: #997;} +.cm-s-default .cm-tag {color: #170;} +.cm-s-default .cm-attribute {color: #00c;} +.cm-s-default .cm-header {color: blue;} +.cm-s-default .cm-quote {color: #090;} +.cm-s-default .cm-hr {color: #999;} +.cm-s-default .cm-link {color: #00c;} + +.cm-negative {color: #d44;} +.cm-positive {color: #292;} +.cm-header, .cm-strong {font-weight: bold;} +.cm-em {font-style: italic;} +.cm-link {text-decoration: underline;} + +.cm-invalidchar {color: #f00;} + +div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;} +div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;} +.CodeMirror-activeline-background {background: #e8f2ff;} + +/* STOP */ + +/* The rest of this file contains styles related to the mechanics of + the editor. You probably shouldn't touch them. */ + +.CodeMirror { + line-height: 1; + position: relative; + overflow: hidden; + background: white; + color: black; +} + +.CodeMirror-scroll { + /* 30px is the magic margin used to hide the element's real scrollbars */ + /* See overflow: hidden in .CodeMirror */ + margin-bottom: -30px; margin-right: -30px; + padding-bottom: 30px; padding-right: 30px; + height: 100%; + outline: none; /* Prevent dragging from highlighting the element */ + position: relative; + -moz-box-sizing: content-box; + box-sizing: content-box; +} +.CodeMirror-sizer { + position: relative; +} + +/* The fake, visible scrollbars. Used to force redraw during scrolling + before actuall scrolling happens, thus preventing shaking and + flickering artifacts. */ +.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler { + position: absolute; + z-index: 6; + display: none; +} +.CodeMirror-vscrollbar { + right: 0; top: 0; + overflow-x: hidden; + overflow-y: scroll; +} +.CodeMirror-hscrollbar { + bottom: 0; left: 0; + overflow-y: hidden; + overflow-x: scroll; +} +.CodeMirror-scrollbar-filler { + right: 0; bottom: 0; +} +.CodeMirror-gutter-filler { + left: 0; bottom: 0; +} + +.CodeMirror-gutters { + position: absolute; left: 0; top: 0; + padding-bottom: 30px; + z-index: 3; +} +.CodeMirror-gutter { + white-space: normal; + height: 100%; + -moz-box-sizing: content-box; + box-sizing: content-box; + padding-bottom: 30px; + margin-bottom: -32px; + display: inline-block; + /* Hack to make IE7 behave */ + *zoom:1; + *display:inline; +} +.CodeMirror-gutter-elt { + position: absolute; + cursor: default; + z-index: 4; +} + +.CodeMirror-lines { + cursor: text; +} +.CodeMirror pre { + /* Reset some styles that the rest of the page might have set */ + -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0; + border-width: 0; + background: transparent; + font-family: inherit; + font-size: inherit; + margin: 0; + white-space: pre; + word-wrap: normal; + line-height: inherit; + color: inherit; + z-index: 2; + position: relative; + overflow: visible; +} +.CodeMirror-wrap pre { + word-wrap: break-word; + white-space: pre-wrap; + word-break: normal; +} +.CodeMirror-code pre { + border-right: 30px solid transparent; + width: -webkit-fit-content; + width: -moz-fit-content; + width: fit-content; +} +.CodeMirror-wrap .CodeMirror-code pre { + border-right: none; + width: auto; +} +.CodeMirror-linebackground { + position: absolute; + left: 0; right: 0; top: 0; bottom: 0; + z-index: 0; +} + +.CodeMirror-linewidget { + position: relative; + z-index: 2; + overflow: auto; +} + +.CodeMirror-widget {} + +.CodeMirror-wrap .CodeMirror-scroll { + overflow-x: hidden; +} + +.CodeMirror-measure { + position: absolute; + width: 100%; + height: 0; + overflow: hidden; + visibility: hidden; +} +.CodeMirror-measure pre { position: static; } + +.CodeMirror div.CodeMirror-cursor { + position: absolute; + visibility: hidden; + border-right: none; + width: 0; +} +.CodeMirror-focused div.CodeMirror-cursor { + visibility: visible; +} + +.CodeMirror-selected { background: #d9d9d9; } +.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; } + +.cm-searching { + background: #ffa; + background: rgba(255, 255, 0, .4); +} + +/* IE7 hack to prevent it from returning funny offsetTops on the spans */ +.CodeMirror span { *vertical-align: text-bottom; } + +@media print { + /* Hide the cursor when printing */ + .CodeMirror div.CodeMirror-cursor { + visibility: hidden; + } +} + + +/* fullscreen adapted code */ +.CodeMirror-fullscreen { + position: fixed; + top: 0; left: 0; right: 0; bottom: 0; + height: auto; + width:auto !important; + z-index: 999999; +} diff --git a/profile-builder/assets/lib/codemirror/lib/codemirror.js b/profile-builder/assets/lib/codemirror/lib/codemirror.js index 0a3aede..207d64a 100644 --- a/profile-builder/assets/lib/codemirror/lib/codemirror.js +++ b/profile-builder/assets/lib/codemirror/lib/codemirror.js @@ -1,5887 +1,5887 @@ -// CodeMirror version 3.17 -// -// CodeMirror is the only global var we claim -window.CodeMirror = (function() { - "use strict"; - - // BROWSER SNIFFING - - // Crude, but necessary to handle a number of hard-to-feature-detect - // bugs and behavior differences. - var gecko = /gecko\/\d/i.test(navigator.userAgent); - var ie = /MSIE \d/.test(navigator.userAgent); - var ie_lt8 = ie && (document.documentMode == null || document.documentMode < 8); - var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9); - var webkit = /WebKit\//.test(navigator.userAgent); - var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(navigator.userAgent); - var chrome = /Chrome\//.test(navigator.userAgent); - var opera = /Opera\//.test(navigator.userAgent); - var safari = /Apple Computer/.test(navigator.vendor); - var khtml = /KHTML\//.test(navigator.userAgent); - var mac_geLion = /Mac OS X 1\d\D([7-9]|\d\d)\D/.test(navigator.userAgent); - var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(navigator.userAgent); - var phantom = /PhantomJS/.test(navigator.userAgent); - - var ios = /AppleWebKit/.test(navigator.userAgent) && /Mobile\/\w+/.test(navigator.userAgent); - // This is woefully incomplete. Suggestions for alternative methods welcome. - var mobile = ios || /Android|webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(navigator.userAgent); - var mac = ios || /Mac/.test(navigator.platform); - var windows = /win/i.test(navigator.platform); - - var opera_version = opera && navigator.userAgent.match(/Version\/(\d*\.\d*)/); - if (opera_version) opera_version = Number(opera_version[1]); - if (opera_version && opera_version >= 15) { opera = false; webkit = true; } - // Some browsers use the wrong event properties to signal cmd/ctrl on OS X - var flipCtrlCmd = mac && (qtwebkit || opera && (opera_version == null || opera_version < 12.11)); - var captureMiddleClick = gecko || (ie && !ie_lt9); - - // Optimize some code when these features are not used - var sawReadOnlySpans = false, sawCollapsedSpans = false; - - // CONSTRUCTOR - - function CodeMirror(place, options) { - if (!(this instanceof CodeMirror)) return new CodeMirror(place, options); - - this.options = options = options || {}; - // Determine effective options based on given values and defaults. - for (var opt in defaults) if (!options.hasOwnProperty(opt) && defaults.hasOwnProperty(opt)) - options[opt] = defaults[opt]; - setGuttersForLineNumbers(options); - - var docStart = typeof options.value == "string" ? 0 : options.value.first; - var display = this.display = makeDisplay(place, docStart); - display.wrapper.CodeMirror = this; - updateGutters(this); - if (options.autofocus && !mobile) focusInput(this); - - this.state = {keyMaps: [], - overlays: [], - modeGen: 0, - overwrite: false, focused: false, - suppressEdits: false, pasteIncoming: false, - draggingText: false, - highlight: new Delayed()}; - - themeChanged(this); - if (options.lineWrapping) - this.display.wrapper.className += " CodeMirror-wrap"; - - var doc = options.value; - if (typeof doc == "string") doc = new Doc(options.value, options.mode); - operation(this, attachDoc)(this, doc); - - // Override magic textarea content restore that IE sometimes does - // on our hidden textarea on reload - if (ie) setTimeout(bind(resetInput, this, true), 20); - - registerEventHandlers(this); - // IE throws unspecified error in certain cases, when - // trying to access activeElement before onload - var hasFocus; try { hasFocus = (document.activeElement == display.input); } catch(e) { } - if (hasFocus || (options.autofocus && !mobile)) setTimeout(bind(onFocus, this), 20); - else onBlur(this); - - operation(this, function() { - for (var opt in optionHandlers) - if (optionHandlers.propertyIsEnumerable(opt)) - optionHandlers[opt](this, options[opt], Init); - for (var i = 0; i < initHooks.length; ++i) initHooks[i](this); - })(); - } - - // DISPLAY CONSTRUCTOR - - function makeDisplay(place, docStart) { - var d = {}; - - var input = d.input = elt("textarea", null, null, "position: absolute; padding: 0; width: 1px; height: 1em; outline: none; font-size: 4px;"); - if (webkit) input.style.width = "1000px"; - else input.setAttribute("wrap", "off"); - // if border: 0; -- iOS fails to open keyboard (issue #1287) - if (ios) input.style.border = "1px solid black"; - input.setAttribute("autocorrect", "off"); input.setAttribute("autocapitalize", "off"); input.setAttribute("spellcheck", "false"); - - // Wraps and hides input textarea - d.inputDiv = elt("div", [input], null, "overflow: hidden; position: relative; width: 3px; height: 0px;"); - // The actual fake scrollbars. - d.scrollbarH = elt("div", [elt("div", null, null, "height: 1px")], "CodeMirror-hscrollbar"); - d.scrollbarV = elt("div", [elt("div", null, null, "width: 1px")], "CodeMirror-vscrollbar"); - d.scrollbarFiller = elt("div", null, "CodeMirror-scrollbar-filler"); - d.gutterFiller = elt("div", null, "CodeMirror-gutter-filler"); - // DIVs containing the selection and the actual code - d.lineDiv = elt("div", null, "CodeMirror-code"); - d.selectionDiv = elt("div", null, null, "position: relative; z-index: 1"); - // Blinky cursor, and element used to ensure cursor fits at the end of a line - d.cursor = elt("div", "\u00a0", "CodeMirror-cursor"); - // Secondary cursor, shown when on a 'jump' in bi-directional text - d.otherCursor = elt("div", "\u00a0", "CodeMirror-cursor CodeMirror-secondarycursor"); - // Used to measure text size - d.measure = elt("div", null, "CodeMirror-measure"); - // Wraps everything that needs to exist inside the vertically-padded coordinate system - d.lineSpace = elt("div", [d.measure, d.selectionDiv, d.lineDiv, d.cursor, d.otherCursor], - null, "position: relative; outline: none"); - // Moved around its parent to cover visible view - d.mover = elt("div", [elt("div", [d.lineSpace], "CodeMirror-lines")], null, "position: relative"); - // Set to the height of the text, causes scrolling - d.sizer = elt("div", [d.mover], "CodeMirror-sizer"); - // D is needed because behavior of elts with overflow: auto and padding is inconsistent across browsers - d.heightForcer = elt("div", null, null, "position: absolute; height: " + scrollerCutOff + "px; width: 1px;"); - // Will contain the gutters, if any - d.gutters = elt("div", null, "CodeMirror-gutters"); - d.lineGutter = null; - // Provides scrolling - d.scroller = elt("div", [d.sizer, d.heightForcer, d.gutters], "CodeMirror-scroll"); - d.scroller.setAttribute("tabIndex", "-1"); - // The element in which the editor lives. - d.wrapper = elt("div", [d.inputDiv, d.scrollbarH, d.scrollbarV, - d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror"); - // Work around IE7 z-index bug - if (ie_lt8) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0; } - if (place.appendChild) place.appendChild(d.wrapper); else place(d.wrapper); - - // Needed to hide big blue blinking cursor on Mobile Safari - if (ios) input.style.width = "0px"; - if (!webkit) d.scroller.draggable = true; - // Needed to handle Tab key in KHTML - if (khtml) { d.inputDiv.style.height = "1px"; d.inputDiv.style.position = "absolute"; } - // Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8). - else if (ie_lt8) d.scrollbarH.style.minWidth = d.scrollbarV.style.minWidth = "18px"; - - // Current visible range (may be bigger than the view window). - d.viewOffset = d.lastSizeC = 0; - d.showingFrom = d.showingTo = docStart; - - // Used to only resize the line number gutter when necessary (when - // the amount of lines crosses a boundary that makes its width change) - d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null; - // See readInput and resetInput - d.prevInput = ""; - // Set to true when a non-horizontal-scrolling widget is added. As - // an optimization, widget aligning is skipped when d is false. - d.alignWidgets = false; - // Flag that indicates whether we currently expect input to appear - // (after some event like 'keypress' or 'input') and are polling - // intensively. - d.pollingFast = false; - // Self-resetting timeout for the poller - d.poll = new Delayed(); - - d.cachedCharWidth = d.cachedTextHeight = null; - d.measureLineCache = []; - d.measureLineCachePos = 0; - - // Tracks when resetInput has punted to just putting a short - // string instead of the (large) selection. - d.inaccurateSelection = false; - - // Tracks the maximum line length so that the horizontal scrollbar - // can be kept static when scrolling. - d.maxLine = null; - d.maxLineLength = 0; - d.maxLineChanged = false; - - // Used for measuring wheel scrolling granularity - d.wheelDX = d.wheelDY = d.wheelStartX = d.wheelStartY = null; - - return d; - } - - // STATE UPDATES - - // Used to get the editor into a consistent state again when options change. - - function loadMode(cm) { - cm.doc.mode = CodeMirror.getMode(cm.options, cm.doc.modeOption); - cm.doc.iter(function(line) { - if (line.stateAfter) line.stateAfter = null; - if (line.styles) line.styles = null; - }); - cm.doc.frontier = cm.doc.first; - startWorker(cm, 100); - cm.state.modeGen++; - if (cm.curOp) regChange(cm); - } - - function wrappingChanged(cm) { - if (cm.options.lineWrapping) { - cm.display.wrapper.className += " CodeMirror-wrap"; - cm.display.sizer.style.minWidth = ""; - } else { - cm.display.wrapper.className = cm.display.wrapper.className.replace(" CodeMirror-wrap", ""); - computeMaxLength(cm); - } - estimateLineHeights(cm); - regChange(cm); - clearCaches(cm); - setTimeout(function(){updateScrollbars(cm);}, 100); - } - - function estimateHeight(cm) { - var th = textHeight(cm.display), wrapping = cm.options.lineWrapping; - var perLine = wrapping && Math.max(5, cm.display.scroller.clientWidth / charWidth(cm.display) - 3); - return function(line) { - if (lineIsHidden(cm.doc, line)) - return 0; - else if (wrapping) - return (Math.ceil(line.text.length / perLine) || 1) * th; - else - return th; - }; - } - - function estimateLineHeights(cm) { - var doc = cm.doc, est = estimateHeight(cm); - doc.iter(function(line) { - var estHeight = est(line); - if (estHeight != line.height) updateLineHeight(line, estHeight); - }); - } - - function keyMapChanged(cm) { - var map = keyMap[cm.options.keyMap], style = map.style; - cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-keymap-\S+/g, "") + - (style ? " cm-keymap-" + style : ""); - cm.state.disableInput = map.disableInput; - } - - function themeChanged(cm) { - cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-s-\S+/g, "") + - cm.options.theme.replace(/(^|\s)\s*/g, " cm-s-"); - clearCaches(cm); - } - - function guttersChanged(cm) { - updateGutters(cm); - regChange(cm); - setTimeout(function(){alignHorizontally(cm);}, 20); - } - - function updateGutters(cm) { - var gutters = cm.display.gutters, specs = cm.options.gutters; - removeChildren(gutters); - for (var i = 0; i < specs.length; ++i) { - var gutterClass = specs[i]; - var gElt = gutters.appendChild(elt("div", null, "CodeMirror-gutter " + gutterClass)); - if (gutterClass == "CodeMirror-linenumbers") { - cm.display.lineGutter = gElt; - gElt.style.width = (cm.display.lineNumWidth || 1) + "px"; - } - } - gutters.style.display = i ? "" : "none"; - } - - function lineLength(doc, line) { - if (line.height == 0) return 0; - var len = line.text.length, merged, cur = line; - while (merged = collapsedSpanAtStart(cur)) { - var found = merged.find(); - cur = getLine(doc, found.from.line); - len += found.from.ch - found.to.ch; - } - cur = line; - while (merged = collapsedSpanAtEnd(cur)) { - var found = merged.find(); - len -= cur.text.length - found.from.ch; - cur = getLine(doc, found.to.line); - len += cur.text.length - found.to.ch; - } - return len; - } - - function computeMaxLength(cm) { - var d = cm.display, doc = cm.doc; - d.maxLine = getLine(doc, doc.first); - d.maxLineLength = lineLength(doc, d.maxLine); - d.maxLineChanged = true; - doc.iter(function(line) { - var len = lineLength(doc, line); - if (len > d.maxLineLength) { - d.maxLineLength = len; - d.maxLine = line; - } - }); - } - - // Make sure the gutters options contains the element - // "CodeMirror-linenumbers" when the lineNumbers option is true. - function setGuttersForLineNumbers(options) { - var found = indexOf(options.gutters, "CodeMirror-linenumbers"); - if (found == -1 && options.lineNumbers) { - options.gutters = options.gutters.concat(["CodeMirror-linenumbers"]); - } else if (found > -1 && !options.lineNumbers) { - options.gutters = options.gutters.slice(0); - options.gutters.splice(i, 1); - } - } - - // SCROLLBARS - - // Re-synchronize the fake scrollbars with the actual size of the - // content. Optionally force a scrollTop. - function updateScrollbars(cm) { - var d = cm.display, docHeight = cm.doc.height; - var totalHeight = docHeight + paddingVert(d); - d.sizer.style.minHeight = d.heightForcer.style.top = totalHeight + "px"; - d.gutters.style.height = Math.max(totalHeight, d.scroller.clientHeight - scrollerCutOff) + "px"; - var scrollHeight = Math.max(totalHeight, d.scroller.scrollHeight); - var needsH = d.scroller.scrollWidth > (d.scroller.clientWidth + 1); - var needsV = scrollHeight > (d.scroller.clientHeight + 1); - if (needsV) { - d.scrollbarV.style.display = "block"; - d.scrollbarV.style.bottom = needsH ? scrollbarWidth(d.measure) + "px" : "0"; - d.scrollbarV.firstChild.style.height = - (scrollHeight - d.scroller.clientHeight + d.scrollbarV.clientHeight) + "px"; - } else { - d.scrollbarV.style.display = ""; - d.scrollbarV.firstChild.style.height = "0"; - } - if (needsH) { - d.scrollbarH.style.display = "block"; - d.scrollbarH.style.right = needsV ? scrollbarWidth(d.measure) + "px" : "0"; - d.scrollbarH.firstChild.style.width = - (d.scroller.scrollWidth - d.scroller.clientWidth + d.scrollbarH.clientWidth) + "px"; - } else { - d.scrollbarH.style.display = ""; - d.scrollbarH.firstChild.style.width = "0"; - } - if (needsH && needsV) { - d.scrollbarFiller.style.display = "block"; - d.scrollbarFiller.style.height = d.scrollbarFiller.style.width = scrollbarWidth(d.measure) + "px"; - } else d.scrollbarFiller.style.display = ""; - if (needsH && cm.options.coverGutterNextToScrollbar && cm.options.fixedGutter) { - d.gutterFiller.style.display = "block"; - d.gutterFiller.style.height = scrollbarWidth(d.measure) + "px"; - d.gutterFiller.style.width = d.gutters.offsetWidth + "px"; - } else d.gutterFiller.style.display = ""; - - if (mac_geLion && scrollbarWidth(d.measure) === 0) - d.scrollbarV.style.minWidth = d.scrollbarH.style.minHeight = mac_geMountainLion ? "18px" : "12px"; - } - - function visibleLines(display, doc, viewPort) { - var top = display.scroller.scrollTop, height = display.wrapper.clientHeight; - if (typeof viewPort == "number") top = viewPort; - else if (viewPort) {top = viewPort.top; height = viewPort.bottom - viewPort.top;} - top = Math.floor(top - paddingTop(display)); - var bottom = Math.ceil(top + height); - return {from: lineAtHeight(doc, top), to: lineAtHeight(doc, bottom)}; - } - - // LINE NUMBERS - - function alignHorizontally(cm) { - var display = cm.display; - if (!display.alignWidgets && (!display.gutters.firstChild || !cm.options.fixedGutter)) return; - var comp = compensateForHScroll(display) - display.scroller.scrollLeft + cm.doc.scrollLeft; - var gutterW = display.gutters.offsetWidth, l = comp + "px"; - for (var n = display.lineDiv.firstChild; n; n = n.nextSibling) if (n.alignable) { - for (var i = 0, a = n.alignable; i < a.length; ++i) a[i].style.left = l; - } - if (cm.options.fixedGutter) - display.gutters.style.left = (comp + gutterW) + "px"; - } - - function maybeUpdateLineNumberWidth(cm) { - if (!cm.options.lineNumbers) return false; - var doc = cm.doc, last = lineNumberFor(cm.options, doc.first + doc.size - 1), display = cm.display; - if (last.length != display.lineNumChars) { - var test = display.measure.appendChild(elt("div", [elt("div", last)], - "CodeMirror-linenumber CodeMirror-gutter-elt")); - var innerW = test.firstChild.offsetWidth, padding = test.offsetWidth - innerW; - display.lineGutter.style.width = ""; - display.lineNumInnerWidth = Math.max(innerW, display.lineGutter.offsetWidth - padding); - display.lineNumWidth = display.lineNumInnerWidth + padding; - display.lineNumChars = display.lineNumInnerWidth ? last.length : -1; - display.lineGutter.style.width = display.lineNumWidth + "px"; - return true; - } - return false; - } - - function lineNumberFor(options, i) { - return String(options.lineNumberFormatter(i + options.firstLineNumber)); - } - function compensateForHScroll(display) { - return getRect(display.scroller).left - getRect(display.sizer).left; - } - - // DISPLAY DRAWING - - function updateDisplay(cm, changes, viewPort, forced) { - var oldFrom = cm.display.showingFrom, oldTo = cm.display.showingTo, updated; - var visible = visibleLines(cm.display, cm.doc, viewPort); - for (var first = true;; first = false) { - var oldWidth = cm.display.scroller.clientWidth; - if (!updateDisplayInner(cm, changes, visible, forced)) break; - updated = true; - changes = []; - updateSelection(cm); - updateScrollbars(cm); - if (first && cm.options.lineWrapping && oldWidth != cm.display.scroller.clientWidth) { - forced = true; - continue; - } - forced = false; - - // Clip forced viewport to actual scrollable area - if (viewPort) - viewPort = Math.min(cm.display.scroller.scrollHeight - cm.display.scroller.clientHeight, - typeof viewPort == "number" ? viewPort : viewPort.top); - visible = visibleLines(cm.display, cm.doc, viewPort); - if (visible.from >= cm.display.showingFrom && visible.to <= cm.display.showingTo) - break; - } - - if (updated) { - signalLater(cm, "update", cm); - if (cm.display.showingFrom != oldFrom || cm.display.showingTo != oldTo) - signalLater(cm, "viewportChange", cm, cm.display.showingFrom, cm.display.showingTo); - } - return updated; - } - - // Uses a set of changes plus the current scroll position to - // determine which DOM updates have to be made, and makes the - // updates. - function updateDisplayInner(cm, changes, visible, forced) { - var display = cm.display, doc = cm.doc; - if (!display.wrapper.clientWidth) { - display.showingFrom = display.showingTo = doc.first; - display.viewOffset = 0; - return; - } - - // Bail out if the visible area is already rendered and nothing changed. - if (!forced && changes.length == 0 && - visible.from > display.showingFrom && visible.to < display.showingTo) - return; - - if (maybeUpdateLineNumberWidth(cm)) - changes = [{from: doc.first, to: doc.first + doc.size}]; - var gutterW = display.sizer.style.marginLeft = display.gutters.offsetWidth + "px"; - display.scrollbarH.style.left = cm.options.fixedGutter ? gutterW : "0"; - - // Used to determine which lines need their line numbers updated - var positionsChangedFrom = Infinity; - if (cm.options.lineNumbers) - for (var i = 0; i < changes.length; ++i) - if (changes[i].diff && changes[i].from < positionsChangedFrom) { positionsChangedFrom = changes[i].from; } - - var end = doc.first + doc.size; - var from = Math.max(visible.from - cm.options.viewportMargin, doc.first); - var to = Math.min(end, visible.to + cm.options.viewportMargin); - if (display.showingFrom < from && from - display.showingFrom < 20) from = Math.max(doc.first, display.showingFrom); - if (display.showingTo > to && display.showingTo - to < 20) to = Math.min(end, display.showingTo); - if (sawCollapsedSpans) { - from = lineNo(visualLine(doc, getLine(doc, from))); - while (to < end && lineIsHidden(doc, getLine(doc, to))) ++to; - } - - // Create a range of theoretically intact lines, and punch holes - // in that using the change info. - var intact = [{from: Math.max(display.showingFrom, doc.first), - to: Math.min(display.showingTo, end)}]; - if (intact[0].from >= intact[0].to) intact = []; - else intact = computeIntact(intact, changes); - // When merged lines are present, we might have to reduce the - // intact ranges because changes in continued fragments of the - // intact lines do require the lines to be redrawn. - if (sawCollapsedSpans) - for (var i = 0; i < intact.length; ++i) { - var range = intact[i], merged; - while (merged = collapsedSpanAtEnd(getLine(doc, range.to - 1))) { - var newTo = merged.find().from.line; - if (newTo > range.from) range.to = newTo; - else { intact.splice(i--, 1); break; } - } - } - - // Clip off the parts that won't be visible - var intactLines = 0; - for (var i = 0; i < intact.length; ++i) { - var range = intact[i]; - if (range.from < from) range.from = from; - if (range.to > to) range.to = to; - if (range.from >= range.to) intact.splice(i--, 1); - else intactLines += range.to - range.from; - } - if (!forced && intactLines == to - from && from == display.showingFrom && to == display.showingTo) { - updateViewOffset(cm); - return; - } - intact.sort(function(a, b) {return a.from - b.from;}); - - // Avoid crashing on IE's "unspecified error" when in iframes - try { - var focused = document.activeElement; - } catch(e) {} - if (intactLines < (to - from) * .7) display.lineDiv.style.display = "none"; - patchDisplay(cm, from, to, intact, positionsChangedFrom); - display.lineDiv.style.display = ""; - if (focused && document.activeElement != focused && focused.offsetHeight) focused.focus(); - - var different = from != display.showingFrom || to != display.showingTo || - display.lastSizeC != display.wrapper.clientHeight; - // This is just a bogus formula that detects when the editor is - // resized or the font size changes. - if (different) { - display.lastSizeC = display.wrapper.clientHeight; - startWorker(cm, 400); - } - display.showingFrom = from; display.showingTo = to; - - updateHeightsInViewport(cm); - updateViewOffset(cm); - - return true; - } - - function updateHeightsInViewport(cm) { - var display = cm.display; - var prevBottom = display.lineDiv.offsetTop; - for (var node = display.lineDiv.firstChild, height; node; node = node.nextSibling) if (node.lineObj) { - if (ie_lt8) { - var bot = node.offsetTop + node.offsetHeight; - height = bot - prevBottom; - prevBottom = bot; - } else { - var box = getRect(node); - height = box.bottom - box.top; - } - var diff = node.lineObj.height - height; - if (height < 2) height = textHeight(display); - if (diff > .001 || diff < -.001) { - updateLineHeight(node.lineObj, height); - var widgets = node.lineObj.widgets; - if (widgets) for (var i = 0; i < widgets.length; ++i) - widgets[i].height = widgets[i].node.offsetHeight; - } - } - } - - function updateViewOffset(cm) { - var off = cm.display.viewOffset = heightAtLine(cm, getLine(cm.doc, cm.display.showingFrom)); - // Position the mover div to align with the current virtual scroll position - cm.display.mover.style.top = off + "px"; - } - - function computeIntact(intact, changes) { - for (var i = 0, l = changes.length || 0; i < l; ++i) { - var change = changes[i], intact2 = [], diff = change.diff || 0; - for (var j = 0, l2 = intact.length; j < l2; ++j) { - var range = intact[j]; - if (change.to <= range.from && change.diff) { - intact2.push({from: range.from + diff, to: range.to + diff}); - } else if (change.to <= range.from || change.from >= range.to) { - intact2.push(range); - } else { - if (change.from > range.from) - intact2.push({from: range.from, to: change.from}); - if (change.to < range.to) - intact2.push({from: change.to + diff, to: range.to + diff}); - } - } - intact = intact2; - } - return intact; - } - - function getDimensions(cm) { - var d = cm.display, left = {}, width = {}; - for (var n = d.gutters.firstChild, i = 0; n; n = n.nextSibling, ++i) { - left[cm.options.gutters[i]] = n.offsetLeft; - width[cm.options.gutters[i]] = n.offsetWidth; - } - return {fixedPos: compensateForHScroll(d), - gutterTotalWidth: d.gutters.offsetWidth, - gutterLeft: left, - gutterWidth: width, - wrapperWidth: d.wrapper.clientWidth}; - } - - function patchDisplay(cm, from, to, intact, updateNumbersFrom) { - var dims = getDimensions(cm); - var display = cm.display, lineNumbers = cm.options.lineNumbers; - if (!intact.length && (!webkit || !cm.display.currentWheelTarget)) - removeChildren(display.lineDiv); - var container = display.lineDiv, cur = container.firstChild; - - function rm(node) { - var next = node.nextSibling; - if (webkit && mac && cm.display.currentWheelTarget == node) { - node.style.display = "none"; - node.lineObj = null; - } else { - node.parentNode.removeChild(node); - } - return next; - } - - var nextIntact = intact.shift(), lineN = from; - cm.doc.iter(from, to, function(line) { - if (nextIntact && nextIntact.to == lineN) nextIntact = intact.shift(); - if (lineIsHidden(cm.doc, line)) { - if (line.height != 0) updateLineHeight(line, 0); - if (line.widgets && cur && cur.previousSibling) for (var i = 0; i < line.widgets.length; ++i) { - var w = line.widgets[i]; - if (w.showIfHidden) { - var prev = cur.previousSibling; - if (/pre/i.test(prev.nodeName)) { - var wrap = elt("div", null, null, "position: relative"); - prev.parentNode.replaceChild(wrap, prev); - wrap.appendChild(prev); - prev = wrap; - } - var wnode = prev.appendChild(elt("div", [w.node], "CodeMirror-linewidget")); - if (!w.handleMouseEvents) wnode.ignoreEvents = true; - positionLineWidget(w, wnode, prev, dims); - } - } - } else if (nextIntact && nextIntact.from <= lineN && nextIntact.to > lineN) { - // This line is intact. Skip to the actual node. Update its - // line number if needed. - while (cur.lineObj != line) cur = rm(cur); - if (lineNumbers && updateNumbersFrom <= lineN && cur.lineNumber) - setTextContent(cur.lineNumber, lineNumberFor(cm.options, lineN)); - cur = cur.nextSibling; - } else { - // For lines with widgets, make an attempt to find and reuse - // the existing element, so that widgets aren't needlessly - // removed and re-inserted into the dom - if (line.widgets) for (var j = 0, search = cur, reuse; search && j < 20; ++j, search = search.nextSibling) - if (search.lineObj == line && /div/i.test(search.nodeName)) { reuse = search; break; } - // This line needs to be generated. - var lineNode = buildLineElement(cm, line, lineN, dims, reuse); - if (lineNode != reuse) { - container.insertBefore(lineNode, cur); - } else { - while (cur != reuse) cur = rm(cur); - cur = cur.nextSibling; - } - - lineNode.lineObj = line; - } - ++lineN; - }); - while (cur) cur = rm(cur); - } - - function buildLineElement(cm, line, lineNo, dims, reuse) { - var built = buildLineContent(cm, line), lineElement = built.pre; - var markers = line.gutterMarkers, display = cm.display, wrap; - - var bgClass = built.bgClass ? built.bgClass + " " + (line.bgClass || "") : line.bgClass; - if (!cm.options.lineNumbers && !markers && !bgClass && !line.wrapClass && !line.widgets) - return lineElement; - - // Lines with gutter elements, widgets or a background class need - // to be wrapped again, and have the extra elements added to the - // wrapper div - - if (reuse) { - reuse.alignable = null; - var isOk = true, widgetsSeen = 0, insertBefore = null; - for (var n = reuse.firstChild, next; n; n = next) { - next = n.nextSibling; - if (!/\bCodeMirror-linewidget\b/.test(n.className)) { - reuse.removeChild(n); - } else { - for (var i = 0; i < line.widgets.length; ++i) { - var widget = line.widgets[i]; - if (widget.node == n.firstChild) { - if (!widget.above && !insertBefore) insertBefore = n; - positionLineWidget(widget, n, reuse, dims); - ++widgetsSeen; - break; - } - } - if (i == line.widgets.length) { isOk = false; break; } - } - } - reuse.insertBefore(lineElement, insertBefore); - if (isOk && widgetsSeen == line.widgets.length) { - wrap = reuse; - reuse.className = line.wrapClass || ""; - } - } - if (!wrap) { - wrap = elt("div", null, line.wrapClass, "position: relative"); - wrap.appendChild(lineElement); - } - // Kludge to make sure the styled element lies behind the selection (by z-index) - if (bgClass) - wrap.insertBefore(elt("div", null, bgClass + " CodeMirror-linebackground"), wrap.firstChild); - if (cm.options.lineNumbers || markers) { - var gutterWrap = wrap.insertBefore(elt("div", null, null, "position: absolute; left: " + - (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px"), - wrap.firstChild); - if (cm.options.fixedGutter) (wrap.alignable || (wrap.alignable = [])).push(gutterWrap); - if (cm.options.lineNumbers && (!markers || !markers["CodeMirror-linenumbers"])) - wrap.lineNumber = gutterWrap.appendChild( - elt("div", lineNumberFor(cm.options, lineNo), - "CodeMirror-linenumber CodeMirror-gutter-elt", - "left: " + dims.gutterLeft["CodeMirror-linenumbers"] + "px; width: " - + display.lineNumInnerWidth + "px")); - if (markers) - for (var k = 0; k < cm.options.gutters.length; ++k) { - var id = cm.options.gutters[k], found = markers.hasOwnProperty(id) && markers[id]; - if (found) - gutterWrap.appendChild(elt("div", [found], "CodeMirror-gutter-elt", "left: " + - dims.gutterLeft[id] + "px; width: " + dims.gutterWidth[id] + "px")); - } - } - if (ie_lt8) wrap.style.zIndex = 2; - if (line.widgets && wrap != reuse) for (var i = 0, ws = line.widgets; i < ws.length; ++i) { - var widget = ws[i], node = elt("div", [widget.node], "CodeMirror-linewidget"); - if (!widget.handleMouseEvents) node.ignoreEvents = true; - positionLineWidget(widget, node, wrap, dims); - if (widget.above) - wrap.insertBefore(node, cm.options.lineNumbers && line.height != 0 ? gutterWrap : lineElement); - else - wrap.appendChild(node); - signalLater(widget, "redraw"); - } - return wrap; - } - - function positionLineWidget(widget, node, wrap, dims) { - if (widget.noHScroll) { - (wrap.alignable || (wrap.alignable = [])).push(node); - var width = dims.wrapperWidth; - node.style.left = dims.fixedPos + "px"; - if (!widget.coverGutter) { - width -= dims.gutterTotalWidth; - node.style.paddingLeft = dims.gutterTotalWidth + "px"; - } - node.style.width = width + "px"; - } - if (widget.coverGutter) { - node.style.zIndex = 5; - node.style.position = "relative"; - if (!widget.noHScroll) node.style.marginLeft = -dims.gutterTotalWidth + "px"; - } - } - - // SELECTION / CURSOR - - function updateSelection(cm) { - var display = cm.display; - var collapsed = posEq(cm.doc.sel.from, cm.doc.sel.to); - if (collapsed || cm.options.showCursorWhenSelecting) - updateSelectionCursor(cm); - else - display.cursor.style.display = display.otherCursor.style.display = "none"; - if (!collapsed) - updateSelectionRange(cm); - else - display.selectionDiv.style.display = "none"; - - // Move the hidden textarea near the cursor to prevent scrolling artifacts - if (cm.options.moveInputWithCursor) { - var headPos = cursorCoords(cm, cm.doc.sel.head, "div"); - var wrapOff = getRect(display.wrapper), lineOff = getRect(display.lineDiv); - display.inputDiv.style.top = Math.max(0, Math.min(display.wrapper.clientHeight - 10, - headPos.top + lineOff.top - wrapOff.top)) + "px"; - display.inputDiv.style.left = Math.max(0, Math.min(display.wrapper.clientWidth - 10, - headPos.left + lineOff.left - wrapOff.left)) + "px"; - } - } - - // No selection, plain cursor - function updateSelectionCursor(cm) { - var display = cm.display, pos = cursorCoords(cm, cm.doc.sel.head, "div"); - display.cursor.style.left = pos.left + "px"; - display.cursor.style.top = pos.top + "px"; - display.cursor.style.height = Math.max(0, pos.bottom - pos.top) * cm.options.cursorHeight + "px"; - display.cursor.style.display = ""; - - if (pos.other) { - display.otherCursor.style.display = ""; - display.otherCursor.style.left = pos.other.left + "px"; - display.otherCursor.style.top = pos.other.top + "px"; - display.otherCursor.style.height = (pos.other.bottom - pos.other.top) * .85 + "px"; - } else { display.otherCursor.style.display = "none"; } - } - - // Highlight selection - function updateSelectionRange(cm) { - var display = cm.display, doc = cm.doc, sel = cm.doc.sel; - var fragment = document.createDocumentFragment(); - var clientWidth = display.lineSpace.offsetWidth, pl = paddingLeft(cm.display); - - function add(left, top, width, bottom) { - if (top < 0) top = 0; - fragment.appendChild(elt("div", null, "CodeMirror-selected", "position: absolute; left: " + left + - "px; top: " + top + "px; width: " + (width == null ? clientWidth - left : width) + - "px; height: " + (bottom - top) + "px")); - } - - function drawForLine(line, fromArg, toArg) { - var lineObj = getLine(doc, line); - var lineLen = lineObj.text.length; - var start, end; - function coords(ch, bias) { - return charCoords(cm, Pos(line, ch), "div", lineObj, bias); - } - - iterateBidiSections(getOrder(lineObj), fromArg || 0, toArg == null ? lineLen : toArg, function(from, to, dir) { - var leftPos = coords(from, "left"), rightPos, left, right; - if (from == to) { - rightPos = leftPos; - left = right = leftPos.left; - } else { - rightPos = coords(to - 1, "right"); - if (dir == "rtl") { var tmp = leftPos; leftPos = rightPos; rightPos = tmp; } - left = leftPos.left; - right = rightPos.right; - } - if (fromArg == null && from == 0) left = pl; - if (rightPos.top - leftPos.top > 3) { // Different lines, draw top part - add(left, leftPos.top, null, leftPos.bottom); - left = pl; - if (leftPos.bottom < rightPos.top) add(left, leftPos.bottom, null, rightPos.top); - } - if (toArg == null && to == lineLen) right = clientWidth; - if (!start || leftPos.top < start.top || leftPos.top == start.top && leftPos.left < start.left) - start = leftPos; - if (!end || rightPos.bottom > end.bottom || rightPos.bottom == end.bottom && rightPos.right > end.right) - end = rightPos; - if (left < pl + 1) left = pl; - add(left, rightPos.top, right - left, rightPos.bottom); - }); - return {start: start, end: end}; - } - - if (sel.from.line == sel.to.line) { - drawForLine(sel.from.line, sel.from.ch, sel.to.ch); - } else { - var fromLine = getLine(doc, sel.from.line), toLine = getLine(doc, sel.to.line); - var singleVLine = visualLine(doc, fromLine) == visualLine(doc, toLine); - var leftEnd = drawForLine(sel.from.line, sel.from.ch, singleVLine ? fromLine.text.length : null).end; - var rightStart = drawForLine(sel.to.line, singleVLine ? 0 : null, sel.to.ch).start; - if (singleVLine) { - if (leftEnd.top < rightStart.top - 2) { - add(leftEnd.right, leftEnd.top, null, leftEnd.bottom); - add(pl, rightStart.top, rightStart.left, rightStart.bottom); - } else { - add(leftEnd.right, leftEnd.top, rightStart.left - leftEnd.right, leftEnd.bottom); - } - } - if (leftEnd.bottom < rightStart.top) - add(pl, leftEnd.bottom, null, rightStart.top); - } - - removeChildrenAndAdd(display.selectionDiv, fragment); - display.selectionDiv.style.display = ""; - } - - // Cursor-blinking - function restartBlink(cm) { - if (!cm.state.focused) return; - var display = cm.display; - clearInterval(display.blinker); - var on = true; - display.cursor.style.visibility = display.otherCursor.style.visibility = ""; - if (cm.options.cursorBlinkRate > 0) - display.blinker = setInterval(function() { - display.cursor.style.visibility = display.otherCursor.style.visibility = (on = !on) ? "" : "hidden"; - }, cm.options.cursorBlinkRate); - } - - // HIGHLIGHT WORKER - - function startWorker(cm, time) { - if (cm.doc.mode.startState && cm.doc.frontier < cm.display.showingTo) - cm.state.highlight.set(time, bind(highlightWorker, cm)); - } - - function highlightWorker(cm) { - var doc = cm.doc; - if (doc.frontier < doc.first) doc.frontier = doc.first; - if (doc.frontier >= cm.display.showingTo) return; - var end = +new Date + cm.options.workTime; - var state = copyState(doc.mode, getStateBefore(cm, doc.frontier)); - var changed = [], prevChange; - doc.iter(doc.frontier, Math.min(doc.first + doc.size, cm.display.showingTo + 500), function(line) { - if (doc.frontier >= cm.display.showingFrom) { // Visible - var oldStyles = line.styles; - line.styles = highlightLine(cm, line, state); - var ischange = !oldStyles || oldStyles.length != line.styles.length; - for (var i = 0; !ischange && i < oldStyles.length; ++i) ischange = oldStyles[i] != line.styles[i]; - if (ischange) { - if (prevChange && prevChange.end == doc.frontier) prevChange.end++; - else changed.push(prevChange = {start: doc.frontier, end: doc.frontier + 1}); - } - line.stateAfter = copyState(doc.mode, state); - } else { - processLine(cm, line, state); - line.stateAfter = doc.frontier % 5 == 0 ? copyState(doc.mode, state) : null; - } - ++doc.frontier; - if (+new Date > end) { - startWorker(cm, cm.options.workDelay); - return true; - } - }); - if (changed.length) - operation(cm, function() { - for (var i = 0; i < changed.length; ++i) - regChange(this, changed[i].start, changed[i].end); - })(); - } - - // Finds the line to start with when starting a parse. Tries to - // find a line with a stateAfter, so that it can start with a - // valid state. If that fails, it returns the line with the - // smallest indentation, which tends to need the least context to - // parse correctly. - function findStartLine(cm, n, precise) { - var minindent, minline, doc = cm.doc, maxScan = cm.doc.mode.innerMode ? 1000 : 100; - for (var search = n, lim = n - maxScan; search > lim; --search) { - if (search <= doc.first) return doc.first; - var line = getLine(doc, search - 1); - if (line.stateAfter && (!precise || search <= doc.frontier)) return search; - var indented = countColumn(line.text, null, cm.options.tabSize); - if (minline == null || minindent > indented) { - minline = search - 1; - minindent = indented; - } - } - return minline; - } - - function getStateBefore(cm, n, precise) { - var doc = cm.doc, display = cm.display; - if (!doc.mode.startState) return true; - var pos = findStartLine(cm, n, precise), state = pos > doc.first && getLine(doc, pos-1).stateAfter; - if (!state) state = startState(doc.mode); - else state = copyState(doc.mode, state); - doc.iter(pos, n, function(line) { - processLine(cm, line, state); - var save = pos == n - 1 || pos % 5 == 0 || pos >= display.showingFrom && pos < display.showingTo; - line.stateAfter = save ? copyState(doc.mode, state) : null; - ++pos; - }); - return state; - } - - // POSITION MEASUREMENT - - function paddingTop(display) {return display.lineSpace.offsetTop;} - function paddingVert(display) {return display.mover.offsetHeight - display.lineSpace.offsetHeight;} - function paddingLeft(display) { - var e = removeChildrenAndAdd(display.measure, elt("pre", null, null, "text-align: left")).appendChild(elt("span", "x")); - return e.offsetLeft; - } - - function measureChar(cm, line, ch, data, bias) { - var dir = -1; - data = data || measureLine(cm, line); - if (data.crude) { - var left = data.left + ch * data.width; - return {left: left, right: left + data.width, top: data.top, bottom: data.bottom}; - } - - for (var pos = ch;; pos += dir) { - var r = data[pos]; - if (r) break; - if (dir < 0 && pos == 0) dir = 1; - } - bias = pos > ch ? "left" : pos < ch ? "right" : bias; - if (bias == "left" && r.leftSide) r = r.leftSide; - else if (bias == "right" && r.rightSide) r = r.rightSide; - return {left: pos < ch ? r.right : r.left, - right: pos > ch ? r.left : r.right, - top: r.top, - bottom: r.bottom}; - } - - function findCachedMeasurement(cm, line) { - var cache = cm.display.measureLineCache; - for (var i = 0; i < cache.length; ++i) { - var memo = cache[i]; - if (memo.text == line.text && memo.markedSpans == line.markedSpans && - cm.display.scroller.clientWidth == memo.width && - memo.classes == line.textClass + "|" + line.wrapClass) - return memo; - } - } - - function clearCachedMeasurement(cm, line) { - var exists = findCachedMeasurement(cm, line); - if (exists) exists.text = exists.measure = exists.markedSpans = null; - } - - function measureLine(cm, line) { - // First look in the cache - var cached = findCachedMeasurement(cm, line); - if (cached) return cached.measure; - - // Failing that, recompute and store result in cache - var measure = measureLineInner(cm, line); - var cache = cm.display.measureLineCache; - var memo = {text: line.text, width: cm.display.scroller.clientWidth, - markedSpans: line.markedSpans, measure: measure, - classes: line.textClass + "|" + line.wrapClass}; - if (cache.length == 16) cache[++cm.display.measureLineCachePos % 16] = memo; - else cache.push(memo); - return measure; - } - - function measureLineInner(cm, line) { - if (!cm.options.lineWrapping && line.text.length >= cm.options.crudeMeasuringFrom) - return crudelyMeasureLine(cm, line); - - var display = cm.display, measure = emptyArray(line.text.length); - var pre = buildLineContent(cm, line, measure, true).pre; - - // IE does not cache element positions of inline elements between - // calls to getBoundingClientRect. This makes the loop below, - // which gathers the positions of all the characters on the line, - // do an amount of layout work quadratic to the number of - // characters. When line wrapping is off, we try to improve things - // by first subdividing the line into a bunch of inline blocks, so - // that IE can reuse most of the layout information from caches - // for those blocks. This does interfere with line wrapping, so it - // doesn't work when wrapping is on, but in that case the - // situation is slightly better, since IE does cache line-wrapping - // information and only recomputes per-line. - if (ie && !ie_lt8 && !cm.options.lineWrapping && pre.childNodes.length > 100) { - var fragment = document.createDocumentFragment(); - var chunk = 10, n = pre.childNodes.length; - for (var i = 0, chunks = Math.ceil(n / chunk); i < chunks; ++i) { - var wrap = elt("div", null, null, "display: inline-block"); - for (var j = 0; j < chunk && n; ++j) { - wrap.appendChild(pre.firstChild); - --n; - } - fragment.appendChild(wrap); - } - pre.appendChild(fragment); - } - - removeChildrenAndAdd(display.measure, pre); - - var outer = getRect(display.lineDiv); - var vranges = [], data = emptyArray(line.text.length), maxBot = pre.offsetHeight; - // Work around an IE7/8 bug where it will sometimes have randomly - // replaced our pre with a clone at this point. - if (ie_lt9 && display.measure.first != pre) - removeChildrenAndAdd(display.measure, pre); - - function measureRect(rect) { - var top = rect.top - outer.top, bot = rect.bottom - outer.top; - if (bot > maxBot) bot = maxBot; - if (top < 0) top = 0; - for (var i = vranges.length - 2; i >= 0; i -= 2) { - var rtop = vranges[i], rbot = vranges[i+1]; - if (rtop > bot || rbot < top) continue; - if (rtop <= top && rbot >= bot || - top <= rtop && bot >= rbot || - Math.min(bot, rbot) - Math.max(top, rtop) >= (bot - top) >> 1) { - vranges[i] = Math.min(top, rtop); - vranges[i+1] = Math.max(bot, rbot); - break; - } - } - if (i < 0) { i = vranges.length; vranges.push(top, bot); } - return {left: rect.left - outer.left, - right: rect.right - outer.left, - top: i, bottom: null}; - } - function finishRect(rect) { - rect.bottom = vranges[rect.top+1]; - rect.top = vranges[rect.top]; - } - - for (var i = 0, cur; i < measure.length; ++i) if (cur = measure[i]) { - var node = cur, rect = null; - // A widget might wrap, needs special care - if (/\bCodeMirror-widget\b/.test(cur.className) && cur.getClientRects) { - if (cur.firstChild.nodeType == 1) node = cur.firstChild; - var rects = node.getClientRects(); - if (rects.length > 1) { - rect = data[i] = measureRect(rects[0]); - rect.rightSide = measureRect(rects[rects.length - 1]); - } - } - if (!rect) rect = data[i] = measureRect(getRect(node)); - if (cur.measureRight) rect.right = getRect(cur.measureRight).left; - if (cur.leftSide) rect.leftSide = measureRect(getRect(cur.leftSide)); - } - removeChildren(cm.display.measure); - for (var i = 0, cur; i < data.length; ++i) if (cur = data[i]) { - finishRect(cur); - if (cur.leftSide) finishRect(cur.leftSide); - if (cur.rightSide) finishRect(cur.rightSide); - } - return data; - } - - function crudelyMeasureLine(cm, line) { - var copy = new Line(line.text.slice(0, 100), null); - if (line.textClass) copy.textClass = line.textClass; - var measure = measureLineInner(cm, copy); - var left = measureChar(cm, copy, 0, measure, "left"); - var right = measureChar(cm, copy, 99, measure, "right"); - return {crude: true, top: left.top, left: left.left, bottom: left.bottom, width: (right.right - left.left) / 100}; - } - - function measureLineWidth(cm, line) { - var hasBadSpan = false; - if (line.markedSpans) for (var i = 0; i < line.markedSpans; ++i) { - var sp = line.markedSpans[i]; - if (sp.collapsed && (sp.to == null || sp.to == line.text.length)) hasBadSpan = true; - } - var cached = !hasBadSpan && findCachedMeasurement(cm, line); - if (cached || line.text.length >= cm.options.crudeMeasuringFrom) - return measureChar(cm, line, line.text.length, cached && cached.measure, "right").right; - - var pre = buildLineContent(cm, line, null, true).pre; - var end = pre.appendChild(zeroWidthElement(cm.display.measure)); - removeChildrenAndAdd(cm.display.measure, pre); - return getRect(end).right - getRect(cm.display.lineDiv).left; - } - - function clearCaches(cm) { - cm.display.measureLineCache.length = cm.display.measureLineCachePos = 0; - cm.display.cachedCharWidth = cm.display.cachedTextHeight = null; - if (!cm.options.lineWrapping) cm.display.maxLineChanged = true; - cm.display.lineNumChars = null; - } - - function pageScrollX() { return window.pageXOffset || (document.documentElement || document.body).scrollLeft; } - function pageScrollY() { return window.pageYOffset || (document.documentElement || document.body).scrollTop; } - - // Context is one of "line", "div" (display.lineDiv), "local"/null (editor), or "page" - function intoCoordSystem(cm, lineObj, rect, context) { - if (lineObj.widgets) for (var i = 0; i < lineObj.widgets.length; ++i) if (lineObj.widgets[i].above) { - var size = widgetHeight(lineObj.widgets[i]); - rect.top += size; rect.bottom += size; - } - if (context == "line") return rect; - if (!context) context = "local"; - var yOff = heightAtLine(cm, lineObj); - if (context == "local") yOff += paddingTop(cm.display); - else yOff -= cm.display.viewOffset; - if (context == "page" || context == "window") { - var lOff = getRect(cm.display.lineSpace); - yOff += lOff.top + (context == "window" ? 0 : pageScrollY()); - var xOff = lOff.left + (context == "window" ? 0 : pageScrollX()); - rect.left += xOff; rect.right += xOff; - } - rect.top += yOff; rect.bottom += yOff; - return rect; - } - - // Context may be "window", "page", "div", or "local"/null - // Result is in "div" coords - function fromCoordSystem(cm, coords, context) { - if (context == "div") return coords; - var left = coords.left, top = coords.top; - // First move into "page" coordinate system - if (context == "page") { - left -= pageScrollX(); - top -= pageScrollY(); - } else if (context == "local" || !context) { - var localBox = getRect(cm.display.sizer); - left += localBox.left; - top += localBox.top; - } - - var lineSpaceBox = getRect(cm.display.lineSpace); - return {left: left - lineSpaceBox.left, top: top - lineSpaceBox.top}; - } - - function charCoords(cm, pos, context, lineObj, bias) { - if (!lineObj) lineObj = getLine(cm.doc, pos.line); - return intoCoordSystem(cm, lineObj, measureChar(cm, lineObj, pos.ch, null, bias), context); - } - - function cursorCoords(cm, pos, context, lineObj, measurement) { - lineObj = lineObj || getLine(cm.doc, pos.line); - if (!measurement) measurement = measureLine(cm, lineObj); - function get(ch, right) { - var m = measureChar(cm, lineObj, ch, measurement, right ? "right" : "left"); - if (right) m.left = m.right; else m.right = m.left; - return intoCoordSystem(cm, lineObj, m, context); - } - function getBidi(ch, partPos) { - var part = order[partPos], right = part.level % 2; - if (ch == bidiLeft(part) && partPos && part.level < order[partPos - 1].level) { - part = order[--partPos]; - ch = bidiRight(part) - (part.level % 2 ? 0 : 1); - right = true; - } else if (ch == bidiRight(part) && partPos < order.length - 1 && part.level < order[partPos + 1].level) { - part = order[++partPos]; - ch = bidiLeft(part) - part.level % 2; - right = false; - } - if (right && ch == part.to && ch > part.from) return get(ch - 1); - return get(ch, right); - } - var order = getOrder(lineObj), ch = pos.ch; - if (!order) return get(ch); - var partPos = getBidiPartAt(order, ch); - var val = getBidi(ch, partPos); - if (bidiOther != null) val.other = getBidi(ch, bidiOther); - return val; - } - - function PosWithInfo(line, ch, outside, xRel) { - var pos = new Pos(line, ch); - pos.xRel = xRel; - if (outside) pos.outside = true; - return pos; - } - - // Coords must be lineSpace-local - function coordsChar(cm, x, y) { - var doc = cm.doc; - y += cm.display.viewOffset; - if (y < 0) return PosWithInfo(doc.first, 0, true, -1); - var lineNo = lineAtHeight(doc, y), last = doc.first + doc.size - 1; - if (lineNo > last) - return PosWithInfo(doc.first + doc.size - 1, getLine(doc, last).text.length, true, 1); - if (x < 0) x = 0; - - for (;;) { - var lineObj = getLine(doc, lineNo); - var found = coordsCharInner(cm, lineObj, lineNo, x, y); - var merged = collapsedSpanAtEnd(lineObj); - var mergedPos = merged && merged.find(); - if (merged && (found.ch > mergedPos.from.ch || found.ch == mergedPos.from.ch && found.xRel > 0)) - lineNo = mergedPos.to.line; - else - return found; - } - } - - function coordsCharInner(cm, lineObj, lineNo, x, y) { - var innerOff = y - heightAtLine(cm, lineObj); - var wrongLine = false, adjust = 2 * cm.display.wrapper.clientWidth; - var measurement = measureLine(cm, lineObj); - - function getX(ch) { - var sp = cursorCoords(cm, Pos(lineNo, ch), "line", - lineObj, measurement); - wrongLine = true; - if (innerOff > sp.bottom) return sp.left - adjust; - else if (innerOff < sp.top) return sp.left + adjust; - else wrongLine = false; - return sp.left; - } - - var bidi = getOrder(lineObj), dist = lineObj.text.length; - var from = lineLeft(lineObj), to = lineRight(lineObj); - var fromX = getX(from), fromOutside = wrongLine, toX = getX(to), toOutside = wrongLine; - - if (x > toX) return PosWithInfo(lineNo, to, toOutside, 1); - // Do a binary search between these bounds. - for (;;) { - if (bidi ? to == from || to == moveVisually(lineObj, from, 1) : to - from <= 1) { - var ch = x < fromX || x - fromX <= toX - x ? from : to; - var xDiff = x - (ch == from ? fromX : toX); - while (isExtendingChar.test(lineObj.text.charAt(ch))) ++ch; - var pos = PosWithInfo(lineNo, ch, ch == from ? fromOutside : toOutside, - xDiff < 0 ? -1 : xDiff ? 1 : 0); - return pos; - } - var step = Math.ceil(dist / 2), middle = from + step; - if (bidi) { - middle = from; - for (var i = 0; i < step; ++i) middle = moveVisually(lineObj, middle, 1); - } - var middleX = getX(middle); - if (middleX > x) {to = middle; toX = middleX; if (toOutside = wrongLine) toX += 1000; dist = step;} - else {from = middle; fromX = middleX; fromOutside = wrongLine; dist -= step;} - } - } - - var measureText; - function textHeight(display) { - if (display.cachedTextHeight != null) return display.cachedTextHeight; - if (measureText == null) { - measureText = elt("pre"); - // Measure a bunch of lines, for browsers that compute - // fractional heights. - for (var i = 0; i < 49; ++i) { - measureText.appendChild(document.createTextNode("x")); - measureText.appendChild(elt("br")); - } - measureText.appendChild(document.createTextNode("x")); - } - removeChildrenAndAdd(display.measure, measureText); - var height = measureText.offsetHeight / 50; - if (height > 3) display.cachedTextHeight = height; - removeChildren(display.measure); - return height || 1; - } - - function charWidth(display) { - if (display.cachedCharWidth != null) return display.cachedCharWidth; - var anchor = elt("span", "x"); - var pre = elt("pre", [anchor]); - removeChildrenAndAdd(display.measure, pre); - var width = anchor.offsetWidth; - if (width > 2) display.cachedCharWidth = width; - return width || 10; - } - - // OPERATIONS - - // Operations are used to wrap changes in such a way that each - // change won't have to update the cursor and display (which would - // be awkward, slow, and error-prone), but instead updates are - // batched and then all combined and executed at once. - - var nextOpId = 0; - function startOperation(cm) { - cm.curOp = { - // An array of ranges of lines that have to be updated. See - // updateDisplay. - changes: [], - forceUpdate: false, - updateInput: null, - userSelChange: null, - textChanged: null, - selectionChanged: false, - cursorActivity: false, - updateMaxLine: false, - updateScrollPos: false, - id: ++nextOpId - }; - if (!delayedCallbackDepth++) delayedCallbacks = []; - } - - function endOperation(cm) { - var op = cm.curOp, doc = cm.doc, display = cm.display; - cm.curOp = null; - - if (op.updateMaxLine) computeMaxLength(cm); - if (display.maxLineChanged && !cm.options.lineWrapping && display.maxLine) { - var width = measureLineWidth(cm, display.maxLine); - display.sizer.style.minWidth = Math.max(0, width + 3 + scrollerCutOff) + "px"; - display.maxLineChanged = false; - var maxScrollLeft = Math.max(0, display.sizer.offsetLeft + display.sizer.offsetWidth - display.scroller.clientWidth); - if (maxScrollLeft < doc.scrollLeft && !op.updateScrollPos) - setScrollLeft(cm, Math.min(display.scroller.scrollLeft, maxScrollLeft), true); - } - var newScrollPos, updated; - if (op.updateScrollPos) { - newScrollPos = op.updateScrollPos; - } else if (op.selectionChanged && display.scroller.clientHeight) { // don't rescroll if not visible - var coords = cursorCoords(cm, doc.sel.head); - newScrollPos = calculateScrollPos(cm, coords.left, coords.top, coords.left, coords.bottom); - } - if (op.changes.length || op.forceUpdate || newScrollPos && newScrollPos.scrollTop != null) { - updated = updateDisplay(cm, op.changes, newScrollPos && newScrollPos.scrollTop, op.forceUpdate); - if (cm.display.scroller.offsetHeight) cm.doc.scrollTop = cm.display.scroller.scrollTop; - } - if (!updated && op.selectionChanged) updateSelection(cm); - if (op.updateScrollPos) { - display.scroller.scrollTop = display.scrollbarV.scrollTop = doc.scrollTop = newScrollPos.scrollTop; - display.scroller.scrollLeft = display.scrollbarH.scrollLeft = doc.scrollLeft = newScrollPos.scrollLeft; - alignHorizontally(cm); - if (op.scrollToPos) - scrollPosIntoView(cm, clipPos(cm.doc, op.scrollToPos), op.scrollToPosMargin); - } else if (newScrollPos) { - scrollCursorIntoView(cm); - } - if (op.selectionChanged) restartBlink(cm); - - if (cm.state.focused && op.updateInput) - resetInput(cm, op.userSelChange); - - var hidden = op.maybeHiddenMarkers, unhidden = op.maybeUnhiddenMarkers; - if (hidden) for (var i = 0; i < hidden.length; ++i) - if (!hidden[i].lines.length) signal(hidden[i], "hide"); - if (unhidden) for (var i = 0; i < unhidden.length; ++i) - if (unhidden[i].lines.length) signal(unhidden[i], "unhide"); - - var delayed; - if (!--delayedCallbackDepth) { - delayed = delayedCallbacks; - delayedCallbacks = null; - } - if (op.textChanged) - signal(cm, "change", cm, op.textChanged); - if (op.cursorActivity) signal(cm, "cursorActivity", cm); - if (delayed) for (var i = 0; i < delayed.length; ++i) delayed[i](); - } - - // Wraps a function in an operation. Returns the wrapped function. - function operation(cm1, f) { - return function() { - var cm = cm1 || this, withOp = !cm.curOp; - if (withOp) startOperation(cm); - try { var result = f.apply(cm, arguments); } - finally { if (withOp) endOperation(cm); } - return result; - }; - } - function docOperation(f) { - return function() { - var withOp = this.cm && !this.cm.curOp, result; - if (withOp) startOperation(this.cm); - try { result = f.apply(this, arguments); } - finally { if (withOp) endOperation(this.cm); } - return result; - }; - } - function runInOp(cm, f) { - var withOp = !cm.curOp, result; - if (withOp) startOperation(cm); - try { result = f(); } - finally { if (withOp) endOperation(cm); } - return result; - } - - function regChange(cm, from, to, lendiff) { - if (from == null) from = cm.doc.first; - if (to == null) to = cm.doc.first + cm.doc.size; - cm.curOp.changes.push({from: from, to: to, diff: lendiff}); - } - - // INPUT HANDLING - - function slowPoll(cm) { - if (cm.display.pollingFast) return; - cm.display.poll.set(cm.options.pollInterval, function() { - readInput(cm); - if (cm.state.focused) slowPoll(cm); - }); - } - - function fastPoll(cm) { - var missed = false; - cm.display.pollingFast = true; - function p() { - var changed = readInput(cm); - if (!changed && !missed) {missed = true; cm.display.poll.set(60, p);} - else {cm.display.pollingFast = false; slowPoll(cm);} - } - cm.display.poll.set(20, p); - } - - // prevInput is a hack to work with IME. If we reset the textarea - // on every change, that breaks IME. So we look for changes - // compared to the previous content instead. (Modern browsers have - // events that indicate IME taking place, but these are not widely - // supported or compatible enough yet to rely on.) - function readInput(cm) { - var input = cm.display.input, prevInput = cm.display.prevInput, doc = cm.doc, sel = doc.sel; - if (!cm.state.focused || hasSelection(input) || isReadOnly(cm) || cm.state.disableInput) return false; - if (cm.state.pasteIncoming && cm.state.fakedLastChar) { - input.value = input.value.substring(0, input.value.length - 1); - cm.state.fakedLastChar = false; - } - var text = input.value; - if (text == prevInput && posEq(sel.from, sel.to)) return false; - if (ie && !ie_lt9 && cm.display.inputHasSelection === text) { - resetInput(cm, true); - return false; - } - - var withOp = !cm.curOp; - if (withOp) startOperation(cm); - sel.shift = false; - var same = 0, l = Math.min(prevInput.length, text.length); - while (same < l && prevInput.charCodeAt(same) == text.charCodeAt(same)) ++same; - var from = sel.from, to = sel.to; - if (same < prevInput.length) - from = Pos(from.line, from.ch - (prevInput.length - same)); - else if (cm.state.overwrite && posEq(from, to) && !cm.state.pasteIncoming) - to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + (text.length - same))); - - var updateInput = cm.curOp.updateInput; - var changeEvent = {from: from, to: to, text: splitLines(text.slice(same)), - origin: cm.state.pasteIncoming ? "paste" : "+input"}; - makeChange(cm.doc, changeEvent, "end"); - cm.curOp.updateInput = updateInput; - signalLater(cm, "inputRead", cm, changeEvent); - - if (text.length > 1000 || text.indexOf("\n") > -1) input.value = cm.display.prevInput = ""; - else cm.display.prevInput = text; - if (withOp) endOperation(cm); - cm.state.pasteIncoming = false; - return true; - } - - function resetInput(cm, user) { - var minimal, selected, doc = cm.doc; - if (!posEq(doc.sel.from, doc.sel.to)) { - cm.display.prevInput = ""; - minimal = hasCopyEvent && - (doc.sel.to.line - doc.sel.from.line > 100 || (selected = cm.getSelection()).length > 1000); - var content = minimal ? "-" : selected || cm.getSelection(); - cm.display.input.value = content; - if (cm.state.focused) selectInput(cm.display.input); - if (ie && !ie_lt9) cm.display.inputHasSelection = content; - } else if (user) { - cm.display.prevInput = cm.display.input.value = ""; - if (ie && !ie_lt9) cm.display.inputHasSelection = null; - } - cm.display.inaccurateSelection = minimal; - } - - function focusInput(cm) { - if (cm.options.readOnly != "nocursor" && (!mobile || document.activeElement != cm.display.input)) - cm.display.input.focus(); - } - - function isReadOnly(cm) { - return cm.options.readOnly || cm.doc.cantEdit; - } - - // EVENT HANDLERS - - function registerEventHandlers(cm) { - var d = cm.display; - on(d.scroller, "mousedown", operation(cm, onMouseDown)); - if (ie) - on(d.scroller, "dblclick", operation(cm, function(e) { - if (signalDOMEvent(cm, e)) return; - var pos = posFromMouse(cm, e); - if (!pos || clickInGutter(cm, e) || eventInWidget(cm.display, e)) return; - e_preventDefault(e); - var word = findWordAt(getLine(cm.doc, pos.line).text, pos); - extendSelection(cm.doc, word.from, word.to); - })); - else - on(d.scroller, "dblclick", function(e) { signalDOMEvent(cm, e) || e_preventDefault(e); }); - on(d.lineSpace, "selectstart", function(e) { - if (!eventInWidget(d, e)) e_preventDefault(e); - }); - // Gecko browsers fire contextmenu *after* opening the menu, at - // which point we can't mess with it anymore. Context menu is - // handled in onMouseDown for Gecko. - if (!captureMiddleClick) on(d.scroller, "contextmenu", function(e) {onContextMenu(cm, e);}); - - on(d.scroller, "scroll", function() { - if (d.scroller.clientHeight) { - setScrollTop(cm, d.scroller.scrollTop); - setScrollLeft(cm, d.scroller.scrollLeft, true); - signal(cm, "scroll", cm); - } - }); - on(d.scrollbarV, "scroll", function() { - if (d.scroller.clientHeight) setScrollTop(cm, d.scrollbarV.scrollTop); - }); - on(d.scrollbarH, "scroll", function() { - if (d.scroller.clientHeight) setScrollLeft(cm, d.scrollbarH.scrollLeft); - }); - - on(d.scroller, "mousewheel", function(e){onScrollWheel(cm, e);}); - on(d.scroller, "DOMMouseScroll", function(e){onScrollWheel(cm, e);}); - - function reFocus() { if (cm.state.focused) setTimeout(bind(focusInput, cm), 0); } - on(d.scrollbarH, "mousedown", reFocus); - on(d.scrollbarV, "mousedown", reFocus); - // Prevent wrapper from ever scrolling - on(d.wrapper, "scroll", function() { d.wrapper.scrollTop = d.wrapper.scrollLeft = 0; }); - - var resizeTimer; - function onResize() { - if (resizeTimer == null) resizeTimer = setTimeout(function() { - resizeTimer = null; - // Might be a text scaling operation, clear size caches. - d.cachedCharWidth = d.cachedTextHeight = knownScrollbarWidth = null; - clearCaches(cm); - runInOp(cm, bind(regChange, cm)); - }, 100); - } - on(window, "resize", onResize); - // Above handler holds on to the editor and its data structures. - // Here we poll to unregister it when the editor is no longer in - // the document, so that it can be garbage-collected. - function unregister() { - for (var p = d.wrapper.parentNode; p && p != document.body; p = p.parentNode) {} - if (p) setTimeout(unregister, 5000); - else off(window, "resize", onResize); - } - setTimeout(unregister, 5000); - - on(d.input, "keyup", operation(cm, function(e) { - if (signalDOMEvent(cm, e) || cm.options.onKeyEvent && cm.options.onKeyEvent(cm, addStop(e))) return; - if (e.keyCode == 16) cm.doc.sel.shift = false; - })); - on(d.input, "input", function() { - if (ie && !ie_lt9 && cm.display.inputHasSelection) cm.display.inputHasSelection = null; - fastPoll(cm); - }); - on(d.input, "keydown", operation(cm, onKeyDown)); - on(d.input, "keypress", operation(cm, onKeyPress)); - on(d.input, "focus", bind(onFocus, cm)); - on(d.input, "blur", bind(onBlur, cm)); - - function drag_(e) { - if (signalDOMEvent(cm, e) || cm.options.onDragEvent && cm.options.onDragEvent(cm, addStop(e))) return; - e_stop(e); - } - if (cm.options.dragDrop) { - on(d.scroller, "dragstart", function(e){onDragStart(cm, e);}); - on(d.scroller, "dragenter", drag_); - on(d.scroller, "dragover", drag_); - on(d.scroller, "drop", operation(cm, onDrop)); - } - on(d.scroller, "paste", function(e) { - if (eventInWidget(d, e)) return; - focusInput(cm); - fastPoll(cm); - }); - on(d.input, "paste", function() { - // Workaround for webkit bug https://bugs.webkit.org/show_bug.cgi?id=90206 - // Add a char to the end of textarea before paste occur so that - // selection doesn't span to the end of textarea. - if (webkit && !cm.state.fakedLastChar && !(new Date - cm.state.lastMiddleDown < 200)) { - var start = d.input.selectionStart, end = d.input.selectionEnd; - d.input.value += "$"; - d.input.selectionStart = start; - d.input.selectionEnd = end; - cm.state.fakedLastChar = true; - } - cm.state.pasteIncoming = true; - fastPoll(cm); - }); - - function prepareCopy() { - if (d.inaccurateSelection) { - d.prevInput = ""; - d.inaccurateSelection = false; - d.input.value = cm.getSelection(); - selectInput(d.input); - } - } - on(d.input, "cut", prepareCopy); - on(d.input, "copy", prepareCopy); - - // Needed to handle Tab key in KHTML - if (khtml) on(d.sizer, "mouseup", function() { - if (document.activeElement == d.input) d.input.blur(); - focusInput(cm); - }); - } - - function eventInWidget(display, e) { - for (var n = e_target(e); n != display.wrapper; n = n.parentNode) { - if (!n || n.ignoreEvents || n.parentNode == display.sizer && n != display.mover) return true; - } - } - - function posFromMouse(cm, e, liberal) { - var display = cm.display; - if (!liberal) { - var target = e_target(e); - if (target == display.scrollbarH || target == display.scrollbarH.firstChild || - target == display.scrollbarV || target == display.scrollbarV.firstChild || - target == display.scrollbarFiller || target == display.gutterFiller) return null; - } - var x, y, space = getRect(display.lineSpace); - // Fails unpredictably on IE[67] when mouse is dragged around quickly. - try { x = e.clientX; y = e.clientY; } catch (e) { return null; } - return coordsChar(cm, x - space.left, y - space.top); - } - - var lastClick, lastDoubleClick; - function onMouseDown(e) { - if (signalDOMEvent(this, e)) return; - var cm = this, display = cm.display, doc = cm.doc, sel = doc.sel; - sel.shift = e.shiftKey; - - if (eventInWidget(display, e)) { - if (!webkit) { - display.scroller.draggable = false; - setTimeout(function(){display.scroller.draggable = true;}, 100); - } - return; - } - if (clickInGutter(cm, e)) return; - var start = posFromMouse(cm, e); - - switch (e_button(e)) { - case 3: - if (captureMiddleClick) onContextMenu.call(cm, cm, e); - return; - case 2: - if (webkit) cm.state.lastMiddleDown = +new Date; - if (start) extendSelection(cm.doc, start); - setTimeout(bind(focusInput, cm), 20); - e_preventDefault(e); - return; - } - // For button 1, if it was clicked inside the editor - // (posFromMouse returning non-null), we have to adjust the - // selection. - if (!start) {if (e_target(e) == display.scroller) e_preventDefault(e); return;} - - if (!cm.state.focused) onFocus(cm); - - var now = +new Date, type = "single"; - if (lastDoubleClick && lastDoubleClick.time > now - 400 && posEq(lastDoubleClick.pos, start)) { - type = "triple"; - e_preventDefault(e); - setTimeout(bind(focusInput, cm), 20); - selectLine(cm, start.line); - } else if (lastClick && lastClick.time > now - 400 && posEq(lastClick.pos, start)) { - type = "double"; - lastDoubleClick = {time: now, pos: start}; - e_preventDefault(e); - var word = findWordAt(getLine(doc, start.line).text, start); - extendSelection(cm.doc, word.from, word.to); - } else { lastClick = {time: now, pos: start}; } - - var last = start; - if (cm.options.dragDrop && dragAndDrop && !isReadOnly(cm) && !posEq(sel.from, sel.to) && - !posLess(start, sel.from) && !posLess(sel.to, start) && type == "single") { - var dragEnd = operation(cm, function(e2) { - if (webkit) display.scroller.draggable = false; - cm.state.draggingText = false; - off(document, "mouseup", dragEnd); - off(display.scroller, "drop", dragEnd); - if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) { - e_preventDefault(e2); - extendSelection(cm.doc, start); - focusInput(cm); - } - }); - // Let the drag handler handle this. - if (webkit) display.scroller.draggable = true; - cm.state.draggingText = dragEnd; - // IE's approach to draggable - if (display.scroller.dragDrop) display.scroller.dragDrop(); - on(document, "mouseup", dragEnd); - on(display.scroller, "drop", dragEnd); - return; - } - e_preventDefault(e); - if (type == "single") extendSelection(cm.doc, clipPos(doc, start)); - - var startstart = sel.from, startend = sel.to, lastPos = start; - - function doSelect(cur) { - if (posEq(lastPos, cur)) return; - lastPos = cur; - - if (type == "single") { - extendSelection(cm.doc, clipPos(doc, start), cur); - return; - } - - startstart = clipPos(doc, startstart); - startend = clipPos(doc, startend); - if (type == "double") { - var word = findWordAt(getLine(doc, cur.line).text, cur); - if (posLess(cur, startstart)) extendSelection(cm.doc, word.from, startend); - else extendSelection(cm.doc, startstart, word.to); - } else if (type == "triple") { - if (posLess(cur, startstart)) extendSelection(cm.doc, startend, clipPos(doc, Pos(cur.line, 0))); - else extendSelection(cm.doc, startstart, clipPos(doc, Pos(cur.line + 1, 0))); - } - } - - var editorSize = getRect(display.wrapper); - // Used to ensure timeout re-tries don't fire when another extend - // happened in the meantime (clearTimeout isn't reliable -- at - // least on Chrome, the timeouts still happen even when cleared, - // if the clear happens after their scheduled firing time). - var counter = 0; - - function extend(e) { - var curCount = ++counter; - var cur = posFromMouse(cm, e, true); - if (!cur) return; - if (!posEq(cur, last)) { - if (!cm.state.focused) onFocus(cm); - last = cur; - doSelect(cur); - var visible = visibleLines(display, doc); - if (cur.line >= visible.to || cur.line < visible.from) - setTimeout(operation(cm, function(){if (counter == curCount) extend(e);}), 150); - } else { - var outside = e.clientY < editorSize.top ? -20 : e.clientY > editorSize.bottom ? 20 : 0; - if (outside) setTimeout(operation(cm, function() { - if (counter != curCount) return; - display.scroller.scrollTop += outside; - extend(e); - }), 50); - } - } - - function done(e) { - counter = Infinity; - e_preventDefault(e); - focusInput(cm); - off(document, "mousemove", move); - off(document, "mouseup", up); - } - - var move = operation(cm, function(e) { - if (!ie && !e_button(e)) done(e); - else extend(e); - }); - var up = operation(cm, done); - on(document, "mousemove", move); - on(document, "mouseup", up); - } - - function gutterEvent(cm, e, type, prevent, signalfn) { - try { var mX = e.clientX, mY = e.clientY; } - catch(e) { return false; } - if (mX >= Math.floor(getRect(cm.display.gutters).right)) return false; - if (prevent) e_preventDefault(e); - - var display = cm.display; - var lineBox = getRect(display.lineDiv); - - if (mY > lineBox.bottom || !hasHandler(cm, type)) return e_defaultPrevented(e); - mY -= lineBox.top - display.viewOffset; - - for (var i = 0; i < cm.options.gutters.length; ++i) { - var g = display.gutters.childNodes[i]; - if (g && getRect(g).right >= mX) { - var line = lineAtHeight(cm.doc, mY); - var gutter = cm.options.gutters[i]; - signalfn(cm, type, cm, line, gutter, e); - return e_defaultPrevented(e); - } - } - } - - function contextMenuInGutter(cm, e) { - if (!hasHandler(cm, "gutterContextMenu")) return false; - return gutterEvent(cm, e, "gutterContextMenu", false, signal); - } - - function clickInGutter(cm, e) { - return gutterEvent(cm, e, "gutterClick", true, signalLater); - } - - // Kludge to work around strange IE behavior where it'll sometimes - // re-fire a series of drag-related events right after the drop (#1551) - var lastDrop = 0; - - function onDrop(e) { - var cm = this; - if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e) || (cm.options.onDragEvent && cm.options.onDragEvent(cm, addStop(e)))) - return; - e_preventDefault(e); - if (ie) lastDrop = +new Date; - var pos = posFromMouse(cm, e, true), files = e.dataTransfer.files; - if (!pos || isReadOnly(cm)) return; - if (files && files.length && window.FileReader && window.File) { - var n = files.length, text = Array(n), read = 0; - var loadFile = function(file, i) { - var reader = new FileReader; - reader.onload = function() { - text[i] = reader.result; - if (++read == n) { - pos = clipPos(cm.doc, pos); - makeChange(cm.doc, {from: pos, to: pos, text: splitLines(text.join("\n")), origin: "paste"}, "around"); - } - }; - reader.readAsText(file); - }; - for (var i = 0; i < n; ++i) loadFile(files[i], i); - } else { - // Don't do a replace if the drop happened inside of the selected text. - if (cm.state.draggingText && !(posLess(pos, cm.doc.sel.from) || posLess(cm.doc.sel.to, pos))) { - cm.state.draggingText(e); - // Ensure the editor is re-focused - setTimeout(bind(focusInput, cm), 20); - return; - } - try { - var text = e.dataTransfer.getData("Text"); - if (text) { - var curFrom = cm.doc.sel.from, curTo = cm.doc.sel.to; - setSelection(cm.doc, pos, pos); - if (cm.state.draggingText) replaceRange(cm.doc, "", curFrom, curTo, "paste"); - cm.replaceSelection(text, null, "paste"); - focusInput(cm); - onFocus(cm); - } - } - catch(e){} - } - } - - function onDragStart(cm, e) { - if (ie && (!cm.state.draggingText || +new Date - lastDrop < 100)) { e_stop(e); return; } - if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) return; - - var txt = cm.getSelection(); - e.dataTransfer.setData("Text", txt); - - // Use dummy image instead of default browsers image. - // Recent Safari (~6.0.2) have a tendency to segfault when this happens, so we don't do it there. - if (e.dataTransfer.setDragImage && !safari) { - var img = elt("img", null, null, "position: fixed; left: 0; top: 0;"); - img.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="; - if (opera) { - img.width = img.height = 1; - cm.display.wrapper.appendChild(img); - // Force a relayout, or Opera won't use our image for some obscure reason - img._top = img.offsetTop; - } - e.dataTransfer.setDragImage(img, 0, 0); - if (opera) img.parentNode.removeChild(img); - } - } - - function setScrollTop(cm, val) { - if (Math.abs(cm.doc.scrollTop - val) < 2) return; - cm.doc.scrollTop = val; - if (!gecko) updateDisplay(cm, [], val); - if (cm.display.scroller.scrollTop != val) cm.display.scroller.scrollTop = val; - if (cm.display.scrollbarV.scrollTop != val) cm.display.scrollbarV.scrollTop = val; - if (gecko) updateDisplay(cm, []); - startWorker(cm, 100); - } - function setScrollLeft(cm, val, isScroller) { - if (isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) return; - val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth); - cm.doc.scrollLeft = val; - alignHorizontally(cm); - if (cm.display.scroller.scrollLeft != val) cm.display.scroller.scrollLeft = val; - if (cm.display.scrollbarH.scrollLeft != val) cm.display.scrollbarH.scrollLeft = val; - } - - // Since the delta values reported on mouse wheel events are - // unstandardized between browsers and even browser versions, and - // generally horribly unpredictable, this code starts by measuring - // the scroll effect that the first few mouse wheel events have, - // and, from that, detects the way it can convert deltas to pixel - // offsets afterwards. - // - // The reason we want to know the amount a wheel event will scroll - // is that it gives us a chance to update the display before the - // actual scrolling happens, reducing flickering. - - var wheelSamples = 0, wheelPixelsPerUnit = null; - // Fill in a browser-detected starting value on browsers where we - // know one. These don't have to be accurate -- the result of them - // being wrong would just be a slight flicker on the first wheel - // scroll (if it is large enough). - if (ie) wheelPixelsPerUnit = -.53; - else if (gecko) wheelPixelsPerUnit = 15; - else if (chrome) wheelPixelsPerUnit = -.7; - else if (safari) wheelPixelsPerUnit = -1/3; - - function onScrollWheel(cm, e) { - var dx = e.wheelDeltaX, dy = e.wheelDeltaY; - if (dx == null && e.detail && e.axis == e.HORIZONTAL_AXIS) dx = e.detail; - if (dy == null && e.detail && e.axis == e.VERTICAL_AXIS) dy = e.detail; - else if (dy == null) dy = e.wheelDelta; - - var display = cm.display, scroll = display.scroller; - // Quit if there's nothing to scroll here - if (!(dx && scroll.scrollWidth > scroll.clientWidth || - dy && scroll.scrollHeight > scroll.clientHeight)) return; - - // Webkit browsers on OS X abort momentum scrolls when the target - // of the scroll event is removed from the scrollable element. - // This hack (see related code in patchDisplay) makes sure the - // element is kept around. - if (dy && mac && webkit) { - for (var cur = e.target; cur != scroll; cur = cur.parentNode) { - if (cur.lineObj) { - cm.display.currentWheelTarget = cur; - break; - } - } - } - - // On some browsers, horizontal scrolling will cause redraws to - // happen before the gutter has been realigned, causing it to - // wriggle around in a most unseemly way. When we have an - // estimated pixels/delta value, we just handle horizontal - // scrolling entirely here. It'll be slightly off from native, but - // better than glitching out. - if (dx && !gecko && !opera && wheelPixelsPerUnit != null) { - if (dy) - setScrollTop(cm, Math.max(0, Math.min(scroll.scrollTop + dy * wheelPixelsPerUnit, scroll.scrollHeight - scroll.clientHeight))); - setScrollLeft(cm, Math.max(0, Math.min(scroll.scrollLeft + dx * wheelPixelsPerUnit, scroll.scrollWidth - scroll.clientWidth))); - e_preventDefault(e); - display.wheelStartX = null; // Abort measurement, if in progress - return; - } - - if (dy && wheelPixelsPerUnit != null) { - var pixels = dy * wheelPixelsPerUnit; - var top = cm.doc.scrollTop, bot = top + display.wrapper.clientHeight; - if (pixels < 0) top = Math.max(0, top + pixels - 50); - else bot = Math.min(cm.doc.height, bot + pixels + 50); - updateDisplay(cm, [], {top: top, bottom: bot}); - } - - if (wheelSamples < 20) { - if (display.wheelStartX == null) { - display.wheelStartX = scroll.scrollLeft; display.wheelStartY = scroll.scrollTop; - display.wheelDX = dx; display.wheelDY = dy; - setTimeout(function() { - if (display.wheelStartX == null) return; - var movedX = scroll.scrollLeft - display.wheelStartX; - var movedY = scroll.scrollTop - display.wheelStartY; - var sample = (movedY && display.wheelDY && movedY / display.wheelDY) || - (movedX && display.wheelDX && movedX / display.wheelDX); - display.wheelStartX = display.wheelStartY = null; - if (!sample) return; - wheelPixelsPerUnit = (wheelPixelsPerUnit * wheelSamples + sample) / (wheelSamples + 1); - ++wheelSamples; - }, 200); - } else { - display.wheelDX += dx; display.wheelDY += dy; - } - } - } - - function doHandleBinding(cm, bound, dropShift) { - if (typeof bound == "string") { - bound = commands[bound]; - if (!bound) return false; - } - // Ensure previous input has been read, so that the handler sees a - // consistent view of the document - if (cm.display.pollingFast && readInput(cm)) cm.display.pollingFast = false; - var doc = cm.doc, prevShift = doc.sel.shift, done = false; - try { - if (isReadOnly(cm)) cm.state.suppressEdits = true; - if (dropShift) doc.sel.shift = false; - done = bound(cm) != Pass; - } finally { - doc.sel.shift = prevShift; - cm.state.suppressEdits = false; - } - return done; - } - - function allKeyMaps(cm) { - var maps = cm.state.keyMaps.slice(0); - if (cm.options.extraKeys) maps.push(cm.options.extraKeys); - maps.push(cm.options.keyMap); - return maps; - } - - var maybeTransition; - function handleKeyBinding(cm, e) { - // Handle auto keymap transitions - var startMap = getKeyMap(cm.options.keyMap), next = startMap.auto; - clearTimeout(maybeTransition); - if (next && !isModifierKey(e)) maybeTransition = setTimeout(function() { - if (getKeyMap(cm.options.keyMap) == startMap) { - cm.options.keyMap = (next.call ? next.call(null, cm) : next); - keyMapChanged(cm); - } - }, 50); - - var name = keyName(e, true), handled = false; - if (!name) return false; - var keymaps = allKeyMaps(cm); - - if (e.shiftKey) { - // First try to resolve full name (including 'Shift-'). Failing - // that, see if there is a cursor-motion command (starting with - // 'go') bound to the keyname without 'Shift-'. - handled = lookupKey("Shift-" + name, keymaps, function(b) {return doHandleBinding(cm, b, true);}) - || lookupKey(name, keymaps, function(b) { - if (typeof b == "string" ? /^go[A-Z]/.test(b) : b.motion) - return doHandleBinding(cm, b); - }); - } else { - handled = lookupKey(name, keymaps, function(b) { return doHandleBinding(cm, b); }); - } - - if (handled) { - e_preventDefault(e); - restartBlink(cm); - if (ie_lt9) { e.oldKeyCode = e.keyCode; e.keyCode = 0; } - signalLater(cm, "keyHandled", cm, name, e); - } - return handled; - } - - function handleCharBinding(cm, e, ch) { - var handled = lookupKey("'" + ch + "'", allKeyMaps(cm), - function(b) { return doHandleBinding(cm, b, true); }); - if (handled) { - e_preventDefault(e); - restartBlink(cm); - signalLater(cm, "keyHandled", cm, "'" + ch + "'", e); - } - return handled; - } - - var lastStoppedKey = null; - function onKeyDown(e) { - var cm = this; - if (!cm.state.focused) onFocus(cm); - if (signalDOMEvent(cm, e) || cm.options.onKeyEvent && cm.options.onKeyEvent(cm, addStop(e))) return; - if (ie && e.keyCode == 27) e.returnValue = false; - var code = e.keyCode; - // IE does strange things with escape. - cm.doc.sel.shift = code == 16 || e.shiftKey; - // First give onKeyEvent option a chance to handle this. - var handled = handleKeyBinding(cm, e); - if (opera) { - lastStoppedKey = handled ? code : null; - // Opera has no cut event... we try to at least catch the key combo - if (!handled && code == 88 && !hasCopyEvent && (mac ? e.metaKey : e.ctrlKey)) - cm.replaceSelection(""); - } - } - - function onKeyPress(e) { - var cm = this; - if (signalDOMEvent(cm, e) || cm.options.onKeyEvent && cm.options.onKeyEvent(cm, addStop(e))) return; - var keyCode = e.keyCode, charCode = e.charCode; - if (opera && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return;} - if (((opera && (!e.which || e.which < 10)) || khtml) && handleKeyBinding(cm, e)) return; - var ch = String.fromCharCode(charCode == null ? keyCode : charCode); - if (this.options.electricChars && this.doc.mode.electricChars && - this.options.smartIndent && !isReadOnly(this) && - this.doc.mode.electricChars.indexOf(ch) > -1) - setTimeout(operation(cm, function() {indentLine(cm, cm.doc.sel.to.line, "smart");}), 75); - if (handleCharBinding(cm, e, ch)) return; - if (ie && !ie_lt9) cm.display.inputHasSelection = null; - fastPoll(cm); - } - - function onFocus(cm) { - if (cm.options.readOnly == "nocursor") return; - if (!cm.state.focused) { - signal(cm, "focus", cm); - cm.state.focused = true; - if (cm.display.wrapper.className.search(/\bCodeMirror-focused\b/) == -1) - cm.display.wrapper.className += " CodeMirror-focused"; - if (!cm.curOp) { - resetInput(cm, true); - if (webkit) setTimeout(bind(resetInput, cm, true), 0); // Issue #1730 - } - } - slowPoll(cm); - restartBlink(cm); - } - function onBlur(cm) { - if (cm.state.focused) { - signal(cm, "blur", cm); - cm.state.focused = false; - cm.display.wrapper.className = cm.display.wrapper.className.replace(" CodeMirror-focused", ""); - } - clearInterval(cm.display.blinker); - setTimeout(function() {if (!cm.state.focused) cm.doc.sel.shift = false;}, 150); - } - - var detectingSelectAll; - function onContextMenu(cm, e) { - if (signalDOMEvent(cm, e, "contextmenu")) return; - var display = cm.display, sel = cm.doc.sel; - if (eventInWidget(display, e) || contextMenuInGutter(cm, e)) return; - - var pos = posFromMouse(cm, e), scrollPos = display.scroller.scrollTop; - if (!pos || opera) return; // Opera is difficult. - if (posEq(sel.from, sel.to) || posLess(pos, sel.from) || !posLess(pos, sel.to)) - operation(cm, setSelection)(cm.doc, pos, pos); - - var oldCSS = display.input.style.cssText; - display.inputDiv.style.position = "absolute"; - display.input.style.cssText = "position: fixed; width: 30px; height: 30px; top: " + (e.clientY - 5) + - "px; left: " + (e.clientX - 5) + "px; z-index: 1000; background: white; outline: none;" + - "border-width: 0; outline: none; overflow: hidden; opacity: .05; -ms-opacity: .05; filter: alpha(opacity=5);"; - focusInput(cm); - resetInput(cm, true); - // Adds "Select all" to context menu in FF - if (posEq(sel.from, sel.to)) display.input.value = display.prevInput = " "; - - function prepareSelectAllHack() { - if (display.input.selectionStart != null) { - var extval = display.input.value = "\u200b" + (posEq(sel.from, sel.to) ? "" : display.input.value); - display.prevInput = "\u200b"; - display.input.selectionStart = 1; display.input.selectionEnd = extval.length; - } - } - function rehide() { - display.inputDiv.style.position = "relative"; - display.input.style.cssText = oldCSS; - if (ie_lt9) display.scrollbarV.scrollTop = display.scroller.scrollTop = scrollPos; - slowPoll(cm); - - // Try to detect the user choosing select-all - if (display.input.selectionStart != null) { - if (!ie || ie_lt9) prepareSelectAllHack(); - clearTimeout(detectingSelectAll); - var i = 0, poll = function(){ - if (display.prevInput == " " && display.input.selectionStart == 0) - operation(cm, commands.selectAll)(cm); - else if (i++ < 10) detectingSelectAll = setTimeout(poll, 500); - else resetInput(cm); - }; - detectingSelectAll = setTimeout(poll, 200); - } - } - - if (ie && !ie_lt9) prepareSelectAllHack(); - if (captureMiddleClick) { - e_stop(e); - var mouseup = function() { - off(window, "mouseup", mouseup); - setTimeout(rehide, 20); - }; - on(window, "mouseup", mouseup); - } else { - setTimeout(rehide, 50); - } - } - - // UPDATING - - var changeEnd = CodeMirror.changeEnd = function(change) { - if (!change.text) return change.to; - return Pos(change.from.line + change.text.length - 1, - lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0)); - }; - - // Make sure a position will be valid after the given change. - function clipPostChange(doc, change, pos) { - if (!posLess(change.from, pos)) return clipPos(doc, pos); - var diff = (change.text.length - 1) - (change.to.line - change.from.line); - if (pos.line > change.to.line + diff) { - var preLine = pos.line - diff, lastLine = doc.first + doc.size - 1; - if (preLine > lastLine) return Pos(lastLine, getLine(doc, lastLine).text.length); - return clipToLen(pos, getLine(doc, preLine).text.length); - } - if (pos.line == change.to.line + diff) - return clipToLen(pos, lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0) + - getLine(doc, change.to.line).text.length - change.to.ch); - var inside = pos.line - change.from.line; - return clipToLen(pos, change.text[inside].length + (inside ? 0 : change.from.ch)); - } - - // Hint can be null|"end"|"start"|"around"|{anchor,head} - function computeSelAfterChange(doc, change, hint) { - if (hint && typeof hint == "object") // Assumed to be {anchor, head} object - return {anchor: clipPostChange(doc, change, hint.anchor), - head: clipPostChange(doc, change, hint.head)}; - - if (hint == "start") return {anchor: change.from, head: change.from}; - - var end = changeEnd(change); - if (hint == "around") return {anchor: change.from, head: end}; - if (hint == "end") return {anchor: end, head: end}; - - // hint is null, leave the selection alone as much as possible - var adjustPos = function(pos) { - if (posLess(pos, change.from)) return pos; - if (!posLess(change.to, pos)) return end; - - var line = pos.line + change.text.length - (change.to.line - change.from.line) - 1, ch = pos.ch; - if (pos.line == change.to.line) ch += end.ch - change.to.ch; - return Pos(line, ch); - }; - return {anchor: adjustPos(doc.sel.anchor), head: adjustPos(doc.sel.head)}; - } - - function filterChange(doc, change, update) { - var obj = { - canceled: false, - from: change.from, - to: change.to, - text: change.text, - origin: change.origin, - cancel: function() { this.canceled = true; } - }; - if (update) obj.update = function(from, to, text, origin) { - if (from) this.from = clipPos(doc, from); - if (to) this.to = clipPos(doc, to); - if (text) this.text = text; - if (origin !== undefined) this.origin = origin; - }; - signal(doc, "beforeChange", doc, obj); - if (doc.cm) signal(doc.cm, "beforeChange", doc.cm, obj); - - if (obj.canceled) return null; - return {from: obj.from, to: obj.to, text: obj.text, origin: obj.origin}; - } - - // Replace the range from from to to by the strings in replacement. - // change is a {from, to, text [, origin]} object - function makeChange(doc, change, selUpdate, ignoreReadOnly) { - if (doc.cm) { - if (!doc.cm.curOp) return operation(doc.cm, makeChange)(doc, change, selUpdate, ignoreReadOnly); - if (doc.cm.state.suppressEdits) return; - } - - if (hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange")) { - change = filterChange(doc, change, true); - if (!change) return; - } - - // Possibly split or suppress the update based on the presence - // of read-only spans in its range. - var split = sawReadOnlySpans && !ignoreReadOnly && removeReadOnlyRanges(doc, change.from, change.to); - if (split) { - for (var i = split.length - 1; i >= 1; --i) - makeChangeNoReadonly(doc, {from: split[i].from, to: split[i].to, text: [""]}); - if (split.length) - makeChangeNoReadonly(doc, {from: split[0].from, to: split[0].to, text: change.text}, selUpdate); - } else { - makeChangeNoReadonly(doc, change, selUpdate); - } - } - - function makeChangeNoReadonly(doc, change, selUpdate) { - if (change.text.length == 1 && change.text[0] == "" && posEq(change.from, change.to)) return; - var selAfter = computeSelAfterChange(doc, change, selUpdate); - addToHistory(doc, change, selAfter, doc.cm ? doc.cm.curOp.id : NaN); - - makeChangeSingleDoc(doc, change, selAfter, stretchSpansOverChange(doc, change)); - var rebased = []; - - linkedDocs(doc, function(doc, sharedHist) { - if (!sharedHist && indexOf(rebased, doc.history) == -1) { - rebaseHist(doc.history, change); - rebased.push(doc.history); - } - makeChangeSingleDoc(doc, change, null, stretchSpansOverChange(doc, change)); - }); - } - - function makeChangeFromHistory(doc, type) { - if (doc.cm && doc.cm.state.suppressEdits) return; - - var hist = doc.history; - var event = (type == "undo" ? hist.done : hist.undone).pop(); - if (!event) return; - - var anti = {changes: [], anchorBefore: event.anchorAfter, headBefore: event.headAfter, - anchorAfter: event.anchorBefore, headAfter: event.headBefore, - generation: hist.generation}; - (type == "undo" ? hist.undone : hist.done).push(anti); - hist.generation = event.generation || ++hist.maxGeneration; - - var filter = hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange"); - - for (var i = event.changes.length - 1; i >= 0; --i) { - var change = event.changes[i]; - change.origin = type; - if (filter && !filterChange(doc, change, false)) { - (type == "undo" ? hist.done : hist.undone).length = 0; - return; - } - - anti.changes.push(historyChangeFromChange(doc, change)); - - var after = i ? computeSelAfterChange(doc, change, null) - : {anchor: event.anchorBefore, head: event.headBefore}; - makeChangeSingleDoc(doc, change, after, mergeOldSpans(doc, change)); - var rebased = []; - - linkedDocs(doc, function(doc, sharedHist) { - if (!sharedHist && indexOf(rebased, doc.history) == -1) { - rebaseHist(doc.history, change); - rebased.push(doc.history); - } - makeChangeSingleDoc(doc, change, null, mergeOldSpans(doc, change)); - }); - } - } - - function shiftDoc(doc, distance) { - function shiftPos(pos) {return Pos(pos.line + distance, pos.ch);} - doc.first += distance; - if (doc.cm) regChange(doc.cm, doc.first, doc.first, distance); - doc.sel.head = shiftPos(doc.sel.head); doc.sel.anchor = shiftPos(doc.sel.anchor); - doc.sel.from = shiftPos(doc.sel.from); doc.sel.to = shiftPos(doc.sel.to); - } - - function makeChangeSingleDoc(doc, change, selAfter, spans) { - if (doc.cm && !doc.cm.curOp) - return operation(doc.cm, makeChangeSingleDoc)(doc, change, selAfter, spans); - - if (change.to.line < doc.first) { - shiftDoc(doc, change.text.length - 1 - (change.to.line - change.from.line)); - return; - } - if (change.from.line > doc.lastLine()) return; - - // Clip the change to the size of this doc - if (change.from.line < doc.first) { - var shift = change.text.length - 1 - (doc.first - change.from.line); - shiftDoc(doc, shift); - change = {from: Pos(doc.first, 0), to: Pos(change.to.line + shift, change.to.ch), - text: [lst(change.text)], origin: change.origin}; - } - var last = doc.lastLine(); - if (change.to.line > last) { - change = {from: change.from, to: Pos(last, getLine(doc, last).text.length), - text: [change.text[0]], origin: change.origin}; - } - - change.removed = getBetween(doc, change.from, change.to); - - if (!selAfter) selAfter = computeSelAfterChange(doc, change, null); - if (doc.cm) makeChangeSingleDocInEditor(doc.cm, change, spans, selAfter); - else updateDoc(doc, change, spans, selAfter); - } - - function makeChangeSingleDocInEditor(cm, change, spans, selAfter) { - var doc = cm.doc, display = cm.display, from = change.from, to = change.to; - - var recomputeMaxLength = false, checkWidthStart = from.line; - if (!cm.options.lineWrapping) { - checkWidthStart = lineNo(visualLine(doc, getLine(doc, from.line))); - doc.iter(checkWidthStart, to.line + 1, function(line) { - if (line == display.maxLine) { - recomputeMaxLength = true; - return true; - } - }); - } - - if (!posLess(doc.sel.head, change.from) && !posLess(change.to, doc.sel.head)) - cm.curOp.cursorActivity = true; - - updateDoc(doc, change, spans, selAfter, estimateHeight(cm)); - - if (!cm.options.lineWrapping) { - doc.iter(checkWidthStart, from.line + change.text.length, function(line) { - var len = lineLength(doc, line); - if (len > display.maxLineLength) { - display.maxLine = line; - display.maxLineLength = len; - display.maxLineChanged = true; - recomputeMaxLength = false; - } - }); - if (recomputeMaxLength) cm.curOp.updateMaxLine = true; - } - - // Adjust frontier, schedule worker - doc.frontier = Math.min(doc.frontier, from.line); - startWorker(cm, 400); - - var lendiff = change.text.length - (to.line - from.line) - 1; - // Remember that these lines changed, for updating the display - regChange(cm, from.line, to.line + 1, lendiff); - - if (hasHandler(cm, "change")) { - var changeObj = {from: from, to: to, - text: change.text, - removed: change.removed, - origin: change.origin}; - if (cm.curOp.textChanged) { - for (var cur = cm.curOp.textChanged; cur.next; cur = cur.next) {} - cur.next = changeObj; - } else cm.curOp.textChanged = changeObj; - } - } - - function replaceRange(doc, code, from, to, origin) { - if (!to) to = from; - if (posLess(to, from)) { var tmp = to; to = from; from = tmp; } - if (typeof code == "string") code = splitLines(code); - makeChange(doc, {from: from, to: to, text: code, origin: origin}, null); - } - - // POSITION OBJECT - - function Pos(line, ch) { - if (!(this instanceof Pos)) return new Pos(line, ch); - this.line = line; this.ch = ch; - } - CodeMirror.Pos = Pos; - - function posEq(a, b) {return a.line == b.line && a.ch == b.ch;} - function posLess(a, b) {return a.line < b.line || (a.line == b.line && a.ch < b.ch);} - function copyPos(x) {return Pos(x.line, x.ch);} - - // SELECTION - - function clipLine(doc, n) {return Math.max(doc.first, Math.min(n, doc.first + doc.size - 1));} - function clipPos(doc, pos) { - if (pos.line < doc.first) return Pos(doc.first, 0); - var last = doc.first + doc.size - 1; - if (pos.line > last) return Pos(last, getLine(doc, last).text.length); - return clipToLen(pos, getLine(doc, pos.line).text.length); - } - function clipToLen(pos, linelen) { - var ch = pos.ch; - if (ch == null || ch > linelen) return Pos(pos.line, linelen); - else if (ch < 0) return Pos(pos.line, 0); - else return pos; - } - function isLine(doc, l) {return l >= doc.first && l < doc.first + doc.size;} - - // If shift is held, this will move the selection anchor. Otherwise, - // it'll set the whole selection. - function extendSelection(doc, pos, other, bias) { - if (doc.sel.shift || doc.sel.extend) { - var anchor = doc.sel.anchor; - if (other) { - var posBefore = posLess(pos, anchor); - if (posBefore != posLess(other, anchor)) { - anchor = pos; - pos = other; - } else if (posBefore != posLess(pos, other)) { - pos = other; - } - } - setSelection(doc, anchor, pos, bias); - } else { - setSelection(doc, pos, other || pos, bias); - } - if (doc.cm) doc.cm.curOp.userSelChange = true; - } - - function filterSelectionChange(doc, anchor, head) { - var obj = {anchor: anchor, head: head}; - signal(doc, "beforeSelectionChange", doc, obj); - if (doc.cm) signal(doc.cm, "beforeSelectionChange", doc.cm, obj); - obj.anchor = clipPos(doc, obj.anchor); obj.head = clipPos(doc, obj.head); - return obj; - } - - // Update the selection. Last two args are only used by - // updateDoc, since they have to be expressed in the line - // numbers before the update. - function setSelection(doc, anchor, head, bias, checkAtomic) { - if (!checkAtomic && hasHandler(doc, "beforeSelectionChange") || doc.cm && hasHandler(doc.cm, "beforeSelectionChange")) { - var filtered = filterSelectionChange(doc, anchor, head); - head = filtered.head; - anchor = filtered.anchor; - } - - var sel = doc.sel; - sel.goalColumn = null; - if (bias == null) bias = posLess(head, sel.head) ? -1 : 1; - // Skip over atomic spans. - if (checkAtomic || !posEq(anchor, sel.anchor)) - anchor = skipAtomic(doc, anchor, bias, checkAtomic != "push"); - if (checkAtomic || !posEq(head, sel.head)) - head = skipAtomic(doc, head, bias, checkAtomic != "push"); - - if (posEq(sel.anchor, anchor) && posEq(sel.head, head)) return; - - sel.anchor = anchor; sel.head = head; - var inv = posLess(head, anchor); - sel.from = inv ? head : anchor; - sel.to = inv ? anchor : head; - - if (doc.cm) - doc.cm.curOp.updateInput = doc.cm.curOp.selectionChanged = - doc.cm.curOp.cursorActivity = true; - - signalLater(doc, "cursorActivity", doc); - } - - function reCheckSelection(cm) { - setSelection(cm.doc, cm.doc.sel.from, cm.doc.sel.to, null, "push"); - } - - function skipAtomic(doc, pos, bias, mayClear) { - var flipped = false, curPos = pos; - var dir = bias || 1; - doc.cantEdit = false; - search: for (;;) { - var line = getLine(doc, curPos.line); - if (line.markedSpans) { - for (var i = 0; i < line.markedSpans.length; ++i) { - var sp = line.markedSpans[i], m = sp.marker; - if ((sp.from == null || (m.inclusiveLeft ? sp.from <= curPos.ch : sp.from < curPos.ch)) && - (sp.to == null || (m.inclusiveRight ? sp.to >= curPos.ch : sp.to > curPos.ch))) { - if (mayClear) { - signal(m, "beforeCursorEnter"); - if (m.explicitlyCleared) { - if (!line.markedSpans) break; - else {--i; continue;} - } - } - if (!m.atomic) continue; - var newPos = m.find()[dir < 0 ? "from" : "to"]; - if (posEq(newPos, curPos)) { - newPos.ch += dir; - if (newPos.ch < 0) { - if (newPos.line > doc.first) newPos = clipPos(doc, Pos(newPos.line - 1)); - else newPos = null; - } else if (newPos.ch > line.text.length) { - if (newPos.line < doc.first + doc.size - 1) newPos = Pos(newPos.line + 1, 0); - else newPos = null; - } - if (!newPos) { - if (flipped) { - // Driven in a corner -- no valid cursor position found at all - // -- try again *with* clearing, if we didn't already - if (!mayClear) return skipAtomic(doc, pos, bias, true); - // Otherwise, turn off editing until further notice, and return the start of the doc - doc.cantEdit = true; - return Pos(doc.first, 0); - } - flipped = true; newPos = pos; dir = -dir; - } - } - curPos = newPos; - continue search; - } - } - } - return curPos; - } - } - - // SCROLLING - - function scrollCursorIntoView(cm) { - var coords = scrollPosIntoView(cm, cm.doc.sel.head, cm.options.cursorScrollMargin); - if (!cm.state.focused) return; - var display = cm.display, box = getRect(display.sizer), doScroll = null; - if (coords.top + box.top < 0) doScroll = true; - else if (coords.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) doScroll = false; - if (doScroll != null && !phantom) { - var hidden = display.cursor.style.display == "none"; - if (hidden) { - display.cursor.style.display = ""; - display.cursor.style.left = coords.left + "px"; - display.cursor.style.top = (coords.top - display.viewOffset) + "px"; - } - display.cursor.scrollIntoView(doScroll); - if (hidden) display.cursor.style.display = "none"; - } - } - - function scrollPosIntoView(cm, pos, margin) { - if (margin == null) margin = 0; - for (;;) { - var changed = false, coords = cursorCoords(cm, pos); - var scrollPos = calculateScrollPos(cm, coords.left, coords.top - margin, coords.left, coords.bottom + margin); - var startTop = cm.doc.scrollTop, startLeft = cm.doc.scrollLeft; - if (scrollPos.scrollTop != null) { - setScrollTop(cm, scrollPos.scrollTop); - if (Math.abs(cm.doc.scrollTop - startTop) > 1) changed = true; - } - if (scrollPos.scrollLeft != null) { - setScrollLeft(cm, scrollPos.scrollLeft); - if (Math.abs(cm.doc.scrollLeft - startLeft) > 1) changed = true; - } - if (!changed) return coords; - } - } - - function scrollIntoView(cm, x1, y1, x2, y2) { - var scrollPos = calculateScrollPos(cm, x1, y1, x2, y2); - if (scrollPos.scrollTop != null) setScrollTop(cm, scrollPos.scrollTop); - if (scrollPos.scrollLeft != null) setScrollLeft(cm, scrollPos.scrollLeft); - } - - function calculateScrollPos(cm, x1, y1, x2, y2) { - var display = cm.display, snapMargin = textHeight(cm.display); - if (y1 < 0) y1 = 0; - var screen = display.scroller.clientHeight - scrollerCutOff, screentop = display.scroller.scrollTop, result = {}; - var docBottom = cm.doc.height + paddingVert(display); - var atTop = y1 < snapMargin, atBottom = y2 > docBottom - snapMargin; - if (y1 < screentop) { - result.scrollTop = atTop ? 0 : y1; - } else if (y2 > screentop + screen) { - var newTop = Math.min(y1, (atBottom ? docBottom : y2) - screen); - if (newTop != screentop) result.scrollTop = newTop; - } - - var screenw = display.scroller.clientWidth - scrollerCutOff, screenleft = display.scroller.scrollLeft; - x1 += display.gutters.offsetWidth; x2 += display.gutters.offsetWidth; - var gutterw = display.gutters.offsetWidth; - var atLeft = x1 < gutterw + 10; - if (x1 < screenleft + gutterw || atLeft) { - if (atLeft) x1 = 0; - result.scrollLeft = Math.max(0, x1 - 10 - gutterw); - } else if (x2 > screenw + screenleft - 3) { - result.scrollLeft = x2 + 10 - screenw; - } - return result; - } - - function updateScrollPos(cm, left, top) { - cm.curOp.updateScrollPos = {scrollLeft: left == null ? cm.doc.scrollLeft : left, - scrollTop: top == null ? cm.doc.scrollTop : top}; - } - - function addToScrollPos(cm, left, top) { - var pos = cm.curOp.updateScrollPos || (cm.curOp.updateScrollPos = {scrollLeft: cm.doc.scrollLeft, scrollTop: cm.doc.scrollTop}); - var scroll = cm.display.scroller; - pos.scrollTop = Math.max(0, Math.min(scroll.scrollHeight - scroll.clientHeight, pos.scrollTop + top)); - pos.scrollLeft = Math.max(0, Math.min(scroll.scrollWidth - scroll.clientWidth, pos.scrollLeft + left)); - } - - // API UTILITIES - - function indentLine(cm, n, how, aggressive) { - var doc = cm.doc; - if (how == null) how = "add"; - if (how == "smart") { - if (!cm.doc.mode.indent) how = "prev"; - else var state = getStateBefore(cm, n); - } - - var tabSize = cm.options.tabSize; - var line = getLine(doc, n), curSpace = countColumn(line.text, null, tabSize); - var curSpaceString = line.text.match(/^\s*/)[0], indentation; - if (how == "smart") { - indentation = cm.doc.mode.indent(state, line.text.slice(curSpaceString.length), line.text); - if (indentation == Pass) { - if (!aggressive) return; - how = "prev"; - } - } - if (how == "prev") { - if (n > doc.first) indentation = countColumn(getLine(doc, n-1).text, null, tabSize); - else indentation = 0; - } else if (how == "add") { - indentation = curSpace + cm.options.indentUnit; - } else if (how == "subtract") { - indentation = curSpace - cm.options.indentUnit; - } else if (typeof how == "number") { - indentation = curSpace + how; - } - indentation = Math.max(0, indentation); - - var indentString = "", pos = 0; - if (cm.options.indentWithTabs) - for (var i = Math.floor(indentation / tabSize); i; --i) {pos += tabSize; indentString += "\t";} - if (pos < indentation) indentString += spaceStr(indentation - pos); - - if (indentString != curSpaceString) - replaceRange(cm.doc, indentString, Pos(n, 0), Pos(n, curSpaceString.length), "+input"); - line.stateAfter = null; - } - - function changeLine(cm, handle, op) { - var no = handle, line = handle, doc = cm.doc; - if (typeof handle == "number") line = getLine(doc, clipLine(doc, handle)); - else no = lineNo(handle); - if (no == null) return null; - if (op(line, no)) regChange(cm, no, no + 1); - else return null; - return line; - } - - function findPosH(doc, pos, dir, unit, visually) { - var line = pos.line, ch = pos.ch, origDir = dir; - var lineObj = getLine(doc, line); - var possible = true; - function findNextLine() { - var l = line + dir; - if (l < doc.first || l >= doc.first + doc.size) return (possible = false); - line = l; - return lineObj = getLine(doc, l); - } - function moveOnce(boundToLine) { - var next = (visually ? moveVisually : moveLogically)(lineObj, ch, dir, true); - if (next == null) { - if (!boundToLine && findNextLine()) { - if (visually) ch = (dir < 0 ? lineRight : lineLeft)(lineObj); - else ch = dir < 0 ? lineObj.text.length : 0; - } else return (possible = false); - } else ch = next; - return true; - } - - if (unit == "char") moveOnce(); - else if (unit == "column") moveOnce(true); - else if (unit == "word" || unit == "group") { - var sawType = null, group = unit == "group"; - for (var first = true;; first = false) { - if (dir < 0 && !moveOnce(!first)) break; - var cur = lineObj.text.charAt(ch) || "\n"; - var type = isWordChar(cur) ? "w" - : !group ? null - : /\s/.test(cur) ? null - : "p"; - if (sawType && sawType != type) { - if (dir < 0) {dir = 1; moveOnce();} - break; - } - if (type) sawType = type; - if (dir > 0 && !moveOnce(!first)) break; - } - } - var result = skipAtomic(doc, Pos(line, ch), origDir, true); - if (!possible) result.hitSide = true; - return result; - } - - function findPosV(cm, pos, dir, unit) { - var doc = cm.doc, x = pos.left, y; - if (unit == "page") { - var pageSize = Math.min(cm.display.wrapper.clientHeight, window.innerHeight || document.documentElement.clientHeight); - y = pos.top + dir * (pageSize - (dir < 0 ? 1.5 : .5) * textHeight(cm.display)); - } else if (unit == "line") { - y = dir > 0 ? pos.bottom + 3 : pos.top - 3; - } - for (;;) { - var target = coordsChar(cm, x, y); - if (!target.outside) break; - if (dir < 0 ? y <= 0 : y >= doc.height) { target.hitSide = true; break; } - y += dir * 5; - } - return target; - } - - function findWordAt(line, pos) { - var start = pos.ch, end = pos.ch; - if (line) { - if ((pos.xRel < 0 || end == line.length) && start) --start; else ++end; - var startChar = line.charAt(start); - var check = isWordChar(startChar) ? isWordChar - : /\s/.test(startChar) ? function(ch) {return /\s/.test(ch);} - : function(ch) {return !/\s/.test(ch) && !isWordChar(ch);}; - while (start > 0 && check(line.charAt(start - 1))) --start; - while (end < line.length && check(line.charAt(end))) ++end; - } - return {from: Pos(pos.line, start), to: Pos(pos.line, end)}; - } - - function selectLine(cm, line) { - extendSelection(cm.doc, Pos(line, 0), clipPos(cm.doc, Pos(line + 1, 0))); - } - - // PROTOTYPE - - // The publicly visible API. Note that operation(null, f) means - // 'wrap f in an operation, performed on its `this` parameter' - - CodeMirror.prototype = { - constructor: CodeMirror, - focus: function(){window.focus(); focusInput(this); onFocus(this); fastPoll(this);}, - - setOption: function(option, value) { - var options = this.options, old = options[option]; - if (options[option] == value && option != "mode") return; - options[option] = value; - if (optionHandlers.hasOwnProperty(option)) - operation(this, optionHandlers[option])(this, value, old); - }, - - getOption: function(option) {return this.options[option];}, - getDoc: function() {return this.doc;}, - - addKeyMap: function(map, bottom) { - this.state.keyMaps[bottom ? "push" : "unshift"](map); - }, - removeKeyMap: function(map) { - var maps = this.state.keyMaps; - for (var i = 0; i < maps.length; ++i) - if (maps[i] == map || (typeof maps[i] != "string" && maps[i].name == map)) { - maps.splice(i, 1); - return true; - } - }, - - addOverlay: operation(null, function(spec, options) { - var mode = spec.token ? spec : CodeMirror.getMode(this.options, spec); - if (mode.startState) throw new Error("Overlays may not be stateful."); - this.state.overlays.push({mode: mode, modeSpec: spec, opaque: options && options.opaque}); - this.state.modeGen++; - regChange(this); - }), - removeOverlay: operation(null, function(spec) { - var overlays = this.state.overlays; - for (var i = 0; i < overlays.length; ++i) { - var cur = overlays[i].modeSpec; - if (cur == spec || typeof spec == "string" && cur.name == spec) { - overlays.splice(i, 1); - this.state.modeGen++; - regChange(this); - return; - } - } - }), - - indentLine: operation(null, function(n, dir, aggressive) { - if (typeof dir != "string" && typeof dir != "number") { - if (dir == null) dir = this.options.smartIndent ? "smart" : "prev"; - else dir = dir ? "add" : "subtract"; - } - if (isLine(this.doc, n)) indentLine(this, n, dir, aggressive); - }), - indentSelection: operation(null, function(how) { - var sel = this.doc.sel; - if (posEq(sel.from, sel.to)) return indentLine(this, sel.from.line, how); - var e = sel.to.line - (sel.to.ch ? 0 : 1); - for (var i = sel.from.line; i <= e; ++i) indentLine(this, i, how); - }), - - // Fetch the parser token for a given character. Useful for hacks - // that want to inspect the mode state (say, for completion). - getTokenAt: function(pos, precise) { - var doc = this.doc; - pos = clipPos(doc, pos); - var state = getStateBefore(this, pos.line, precise), mode = this.doc.mode; - var line = getLine(doc, pos.line); - var stream = new StringStream(line.text, this.options.tabSize); - while (stream.pos < pos.ch && !stream.eol()) { - stream.start = stream.pos; - var style = mode.token(stream, state); - } - return {start: stream.start, - end: stream.pos, - string: stream.current(), - className: style || null, // Deprecated, use 'type' instead - type: style || null, - state: state}; - }, - - getTokenTypeAt: function(pos) { - pos = clipPos(this.doc, pos); - var styles = getLineStyles(this, getLine(this.doc, pos.line)); - var before = 0, after = (styles.length - 1) / 2, ch = pos.ch; - if (ch == 0) return styles[2]; - for (;;) { - var mid = (before + after) >> 1; - if ((mid ? styles[mid * 2 - 1] : 0) >= ch) after = mid; - else if (styles[mid * 2 + 1] < ch) before = mid + 1; - else return styles[mid * 2 + 2]; - } - }, - - getModeAt: function(pos) { - var mode = this.doc.mode; - if (!mode.innerMode) return mode; - return CodeMirror.innerMode(mode, this.getTokenAt(pos).state).mode; - }, - - getHelper: function(pos, type) { - if (!helpers.hasOwnProperty(type)) return; - var help = helpers[type], mode = this.getModeAt(pos); - return mode[type] && help[mode[type]] || - mode.helperType && help[mode.helperType] || - help[mode.name]; - }, - - getStateAfter: function(line, precise) { - var doc = this.doc; - line = clipLine(doc, line == null ? doc.first + doc.size - 1: line); - return getStateBefore(this, line + 1, precise); - }, - - cursorCoords: function(start, mode) { - var pos, sel = this.doc.sel; - if (start == null) pos = sel.head; - else if (typeof start == "object") pos = clipPos(this.doc, start); - else pos = start ? sel.from : sel.to; - return cursorCoords(this, pos, mode || "page"); - }, - - charCoords: function(pos, mode) { - return charCoords(this, clipPos(this.doc, pos), mode || "page"); - }, - - coordsChar: function(coords, mode) { - coords = fromCoordSystem(this, coords, mode || "page"); - return coordsChar(this, coords.left, coords.top); - }, - - lineAtHeight: function(height, mode) { - height = fromCoordSystem(this, {top: height, left: 0}, mode || "page").top; - return lineAtHeight(this.doc, height + this.display.viewOffset); - }, - heightAtLine: function(line, mode) { - var end = false, last = this.doc.first + this.doc.size - 1; - if (line < this.doc.first) line = this.doc.first; - else if (line > last) { line = last; end = true; } - var lineObj = getLine(this.doc, line); - return intoCoordSystem(this, getLine(this.doc, line), {top: 0, left: 0}, mode || "page").top + - (end ? lineObj.height : 0); - }, - - defaultTextHeight: function() { return textHeight(this.display); }, - defaultCharWidth: function() { return charWidth(this.display); }, - - setGutterMarker: operation(null, function(line, gutterID, value) { - return changeLine(this, line, function(line) { - var markers = line.gutterMarkers || (line.gutterMarkers = {}); - markers[gutterID] = value; - if (!value && isEmpty(markers)) line.gutterMarkers = null; - return true; - }); - }), - - clearGutter: operation(null, function(gutterID) { - var cm = this, doc = cm.doc, i = doc.first; - doc.iter(function(line) { - if (line.gutterMarkers && line.gutterMarkers[gutterID]) { - line.gutterMarkers[gutterID] = null; - regChange(cm, i, i + 1); - if (isEmpty(line.gutterMarkers)) line.gutterMarkers = null; - } - ++i; - }); - }), - - addLineClass: operation(null, function(handle, where, cls) { - return changeLine(this, handle, function(line) { - var prop = where == "text" ? "textClass" : where == "background" ? "bgClass" : "wrapClass"; - if (!line[prop]) line[prop] = cls; - else if (new RegExp("(?:^|\\s)" + cls + "(?:$|\\s)").test(line[prop])) return false; - else line[prop] += " " + cls; - return true; - }); - }), - - removeLineClass: operation(null, function(handle, where, cls) { - return changeLine(this, handle, function(line) { - var prop = where == "text" ? "textClass" : where == "background" ? "bgClass" : "wrapClass"; - var cur = line[prop]; - if (!cur) return false; - else if (cls == null) line[prop] = null; - else { - var found = cur.match(new RegExp("(?:^|\\s+)" + cls + "(?:$|\\s+)")); - if (!found) return false; - var end = found.index + found[0].length; - line[prop] = cur.slice(0, found.index) + (!found.index || end == cur.length ? "" : " ") + cur.slice(end) || null; - } - return true; - }); - }), - - addLineWidget: operation(null, function(handle, node, options) { - return addLineWidget(this, handle, node, options); - }), - - removeLineWidget: function(widget) { widget.clear(); }, - - lineInfo: function(line) { - if (typeof line == "number") { - if (!isLine(this.doc, line)) return null; - var n = line; - line = getLine(this.doc, line); - if (!line) return null; - } else { - var n = lineNo(line); - if (n == null) return null; - } - return {line: n, handle: line, text: line.text, gutterMarkers: line.gutterMarkers, - textClass: line.textClass, bgClass: line.bgClass, wrapClass: line.wrapClass, - widgets: line.widgets}; - }, - - getViewport: function() { return {from: this.display.showingFrom, to: this.display.showingTo};}, - - addWidget: function(pos, node, scroll, vert, horiz) { - var display = this.display; - pos = cursorCoords(this, clipPos(this.doc, pos)); - var top = pos.bottom, left = pos.left; - node.style.position = "absolute"; - display.sizer.appendChild(node); - if (vert == "over") { - top = pos.top; - } else if (vert == "above" || vert == "near") { - var vspace = Math.max(display.wrapper.clientHeight, this.doc.height), - hspace = Math.max(display.sizer.clientWidth, display.lineSpace.clientWidth); - // Default to positioning above (if specified and possible); otherwise default to positioning below - if ((vert == 'above' || pos.bottom + node.offsetHeight > vspace) && pos.top > node.offsetHeight) - top = pos.top - node.offsetHeight; - else if (pos.bottom + node.offsetHeight <= vspace) - top = pos.bottom; - if (left + node.offsetWidth > hspace) - left = hspace - node.offsetWidth; - } - node.style.top = top + "px"; - node.style.left = node.style.right = ""; - if (horiz == "right") { - left = display.sizer.clientWidth - node.offsetWidth; - node.style.right = "0px"; - } else { - if (horiz == "left") left = 0; - else if (horiz == "middle") left = (display.sizer.clientWidth - node.offsetWidth) / 2; - node.style.left = left + "px"; - } - if (scroll) - scrollIntoView(this, left, top, left + node.offsetWidth, top + node.offsetHeight); - }, - - triggerOnKeyDown: operation(null, onKeyDown), - - execCommand: function(cmd) {return commands[cmd](this);}, - - findPosH: function(from, amount, unit, visually) { - var dir = 1; - if (amount < 0) { dir = -1; amount = -amount; } - for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) { - cur = findPosH(this.doc, cur, dir, unit, visually); - if (cur.hitSide) break; - } - return cur; - }, - - moveH: operation(null, function(dir, unit) { - var sel = this.doc.sel, pos; - if (sel.shift || sel.extend || posEq(sel.from, sel.to)) - pos = findPosH(this.doc, sel.head, dir, unit, this.options.rtlMoveVisually); - else - pos = dir < 0 ? sel.from : sel.to; - extendSelection(this.doc, pos, pos, dir); - }), - - deleteH: operation(null, function(dir, unit) { - var sel = this.doc.sel; - if (!posEq(sel.from, sel.to)) replaceRange(this.doc, "", sel.from, sel.to, "+delete"); - else replaceRange(this.doc, "", sel.from, findPosH(this.doc, sel.head, dir, unit, false), "+delete"); - this.curOp.userSelChange = true; - }), - - findPosV: function(from, amount, unit, goalColumn) { - var dir = 1, x = goalColumn; - if (amount < 0) { dir = -1; amount = -amount; } - for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) { - var coords = cursorCoords(this, cur, "div"); - if (x == null) x = coords.left; - else coords.left = x; - cur = findPosV(this, coords, dir, unit); - if (cur.hitSide) break; - } - return cur; - }, - - moveV: operation(null, function(dir, unit) { - var sel = this.doc.sel; - var pos = cursorCoords(this, sel.head, "div"); - if (sel.goalColumn != null) pos.left = sel.goalColumn; - var target = findPosV(this, pos, dir, unit); - - if (unit == "page") addToScrollPos(this, 0, charCoords(this, target, "div").top - pos.top); - extendSelection(this.doc, target, target, dir); - sel.goalColumn = pos.left; - }), - - toggleOverwrite: function(value) { - if (value != null && value == this.state.overwrite) return; - if (this.state.overwrite = !this.state.overwrite) - this.display.cursor.className += " CodeMirror-overwrite"; - else - this.display.cursor.className = this.display.cursor.className.replace(" CodeMirror-overwrite", ""); - }, - hasFocus: function() { return this.state.focused; }, - - scrollTo: operation(null, function(x, y) { - updateScrollPos(this, x, y); - }), - getScrollInfo: function() { - var scroller = this.display.scroller, co = scrollerCutOff; - return {left: scroller.scrollLeft, top: scroller.scrollTop, - height: scroller.scrollHeight - co, width: scroller.scrollWidth - co, - clientHeight: scroller.clientHeight - co, clientWidth: scroller.clientWidth - co}; - }, - - scrollIntoView: operation(null, function(pos, margin) { - if (typeof pos == "number") pos = Pos(pos, 0); - if (!margin) margin = 0; - var coords = pos; - - if (!pos || pos.line != null) { - this.curOp.scrollToPos = pos ? clipPos(this.doc, pos) : this.doc.sel.head; - this.curOp.scrollToPosMargin = margin; - coords = cursorCoords(this, this.curOp.scrollToPos); - } - var sPos = calculateScrollPos(this, coords.left, coords.top - margin, coords.right, coords.bottom + margin); - updateScrollPos(this, sPos.scrollLeft, sPos.scrollTop); - }), - - setSize: operation(null, function(width, height) { - function interpret(val) { - return typeof val == "number" || /^\d+$/.test(String(val)) ? val + "px" : val; - } - if (width != null) this.display.wrapper.style.width = interpret(width); - if (height != null) this.display.wrapper.style.height = interpret(height); - if (this.options.lineWrapping) - this.display.measureLineCache.length = this.display.measureLineCachePos = 0; - this.curOp.forceUpdate = true; - }), - - operation: function(f){return runInOp(this, f);}, - - refresh: operation(null, function() { - var badHeight = this.display.cachedTextHeight == null; - clearCaches(this); - updateScrollPos(this, this.doc.scrollLeft, this.doc.scrollTop); - regChange(this); - if (badHeight) estimateLineHeights(this); - }), - - swapDoc: operation(null, function(doc) { - var old = this.doc; - old.cm = null; - attachDoc(this, doc); - clearCaches(this); - resetInput(this, true); - updateScrollPos(this, doc.scrollLeft, doc.scrollTop); - return old; - }), - - getInputField: function(){return this.display.input;}, - getWrapperElement: function(){return this.display.wrapper;}, - getScrollerElement: function(){return this.display.scroller;}, - getGutterElement: function(){return this.display.gutters;} - }; - eventMixin(CodeMirror); - - // OPTION DEFAULTS - - var optionHandlers = CodeMirror.optionHandlers = {}; - - // The default configuration options. - var defaults = CodeMirror.defaults = {}; - - function option(name, deflt, handle, notOnInit) { - CodeMirror.defaults[name] = deflt; - if (handle) optionHandlers[name] = - notOnInit ? function(cm, val, old) {if (old != Init) handle(cm, val, old);} : handle; - } - - var Init = CodeMirror.Init = {toString: function(){return "CodeMirror.Init";}}; - - // These two are, on init, called from the constructor because they - // have to be initialized before the editor can start at all. - option("value", "", function(cm, val) { - cm.setValue(val); - }, true); - option("mode", null, function(cm, val) { - cm.doc.modeOption = val; - loadMode(cm); - }, true); - - option("indentUnit", 2, loadMode, true); - option("indentWithTabs", false); - option("smartIndent", true); - option("tabSize", 4, function(cm) { - loadMode(cm); - clearCaches(cm); - regChange(cm); - }, true); - option("electricChars", true); - option("rtlMoveVisually", !windows); - - option("theme", "default", function(cm) { - themeChanged(cm); - guttersChanged(cm); - }, true); - option("keyMap", "default", keyMapChanged); - option("extraKeys", null); - - option("onKeyEvent", null); - option("onDragEvent", null); - - option("lineWrapping", false, wrappingChanged, true); - option("gutters", [], function(cm) { - setGuttersForLineNumbers(cm.options); - guttersChanged(cm); - }, true); - option("fixedGutter", true, function(cm, val) { - cm.display.gutters.style.left = val ? compensateForHScroll(cm.display) + "px" : "0"; - cm.refresh(); - }, true); - option("coverGutterNextToScrollbar", false, updateScrollbars, true); - option("lineNumbers", false, function(cm) { - setGuttersForLineNumbers(cm.options); - guttersChanged(cm); - }, true); - option("firstLineNumber", 1, guttersChanged, true); - option("lineNumberFormatter", function(integer) {return integer;}, guttersChanged, true); - option("showCursorWhenSelecting", false, updateSelection, true); - - option("readOnly", false, function(cm, val) { - if (val == "nocursor") {onBlur(cm); cm.display.input.blur();} - else if (!val) resetInput(cm, true); - }); - option("dragDrop", true); - - option("cursorBlinkRate", 530); - option("cursorScrollMargin", 0); - option("cursorHeight", 1); - option("workTime", 100); - option("workDelay", 100); - option("flattenSpans", true); - option("pollInterval", 100); - option("undoDepth", 40, function(cm, val){cm.doc.history.undoDepth = val;}); - option("historyEventDelay", 500); - option("viewportMargin", 10, function(cm){cm.refresh();}, true); - option("maxHighlightLength", 10000, function(cm){loadMode(cm); cm.refresh();}, true); - option("crudeMeasuringFrom", 10000); - option("moveInputWithCursor", true, function(cm, val) { - if (!val) cm.display.inputDiv.style.top = cm.display.inputDiv.style.left = 0; - }); - - option("tabindex", null, function(cm, val) { - cm.display.input.tabIndex = val || ""; - }); - option("autofocus", null); - - // MODE DEFINITION AND QUERYING - - // Known modes, by name and by MIME - var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {}; - - CodeMirror.defineMode = function(name, mode) { - if (!CodeMirror.defaults.mode && name != "null") CodeMirror.defaults.mode = name; - if (arguments.length > 2) { - mode.dependencies = []; - for (var i = 2; i < arguments.length; ++i) mode.dependencies.push(arguments[i]); - } - modes[name] = mode; - }; - - CodeMirror.defineMIME = function(mime, spec) { - mimeModes[mime] = spec; - }; - - CodeMirror.resolveMode = function(spec) { - if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) { - spec = mimeModes[spec]; - } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) { - var found = mimeModes[spec.name]; - spec = createObj(found, spec); - spec.name = found.name; - } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec)) { - return CodeMirror.resolveMode("application/xml"); - } - if (typeof spec == "string") return {name: spec}; - else return spec || {name: "null"}; - }; - - CodeMirror.getMode = function(options, spec) { - var spec = CodeMirror.resolveMode(spec); - var mfactory = modes[spec.name]; - if (!mfactory) return CodeMirror.getMode(options, "text/plain"); - var modeObj = mfactory(options, spec); - if (modeExtensions.hasOwnProperty(spec.name)) { - var exts = modeExtensions[spec.name]; - for (var prop in exts) { - if (!exts.hasOwnProperty(prop)) continue; - if (modeObj.hasOwnProperty(prop)) modeObj["_" + prop] = modeObj[prop]; - modeObj[prop] = exts[prop]; - } - } - modeObj.name = spec.name; - - return modeObj; - }; - - CodeMirror.defineMode("null", function() { - return {token: function(stream) {stream.skipToEnd();}}; - }); - CodeMirror.defineMIME("text/plain", "null"); - - var modeExtensions = CodeMirror.modeExtensions = {}; - CodeMirror.extendMode = function(mode, properties) { - var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {}); - copyObj(properties, exts); - }; - - // EXTENSIONS - - CodeMirror.defineExtension = function(name, func) { - CodeMirror.prototype[name] = func; - }; - CodeMirror.defineDocExtension = function(name, func) { - Doc.prototype[name] = func; - }; - CodeMirror.defineOption = option; - - var initHooks = []; - CodeMirror.defineInitHook = function(f) {initHooks.push(f);}; - - var helpers = CodeMirror.helpers = {}; - CodeMirror.registerHelper = function(type, name, value) { - if (!helpers.hasOwnProperty(type)) helpers[type] = CodeMirror[type] = {}; - helpers[type][name] = value; - }; - - // UTILITIES - - CodeMirror.isWordChar = isWordChar; - - // MODE STATE HANDLING - - // Utility functions for working with state. Exported because modes - // sometimes need to do this. - function copyState(mode, state) { - if (state === true) return state; - if (mode.copyState) return mode.copyState(state); - var nstate = {}; - for (var n in state) { - var val = state[n]; - if (val instanceof Array) val = val.concat([]); - nstate[n] = val; - } - return nstate; - } - CodeMirror.copyState = copyState; - - function startState(mode, a1, a2) { - return mode.startState ? mode.startState(a1, a2) : true; - } - CodeMirror.startState = startState; - - CodeMirror.innerMode = function(mode, state) { - while (mode.innerMode) { - var info = mode.innerMode(state); - if (!info || info.mode == mode) break; - state = info.state; - mode = info.mode; - } - return info || {mode: mode, state: state}; - }; - - // STANDARD COMMANDS - - var commands = CodeMirror.commands = { - selectAll: function(cm) {cm.setSelection(Pos(cm.firstLine(), 0), Pos(cm.lastLine()));}, - killLine: function(cm) { - var from = cm.getCursor(true), to = cm.getCursor(false), sel = !posEq(from, to); - if (!sel && cm.getLine(from.line).length == from.ch) - cm.replaceRange("", from, Pos(from.line + 1, 0), "+delete"); - else cm.replaceRange("", from, sel ? to : Pos(from.line), "+delete"); - }, - deleteLine: function(cm) { - var l = cm.getCursor().line; - cm.replaceRange("", Pos(l, 0), Pos(l), "+delete"); - }, - delLineLeft: function(cm) { - var cur = cm.getCursor(); - cm.replaceRange("", Pos(cur.line, 0), cur, "+delete"); - }, - undo: function(cm) {cm.undo();}, - redo: function(cm) {cm.redo();}, - goDocStart: function(cm) {cm.extendSelection(Pos(cm.firstLine(), 0));}, - goDocEnd: function(cm) {cm.extendSelection(Pos(cm.lastLine()));}, - goLineStart: function(cm) { - cm.extendSelection(lineStart(cm, cm.getCursor().line)); - }, - goLineStartSmart: function(cm) { - var cur = cm.getCursor(), start = lineStart(cm, cur.line); - var line = cm.getLineHandle(start.line); - var order = getOrder(line); - if (!order || order[0].level == 0) { - var firstNonWS = Math.max(0, line.text.search(/\S/)); - var inWS = cur.line == start.line && cur.ch <= firstNonWS && cur.ch; - cm.extendSelection(Pos(start.line, inWS ? 0 : firstNonWS)); - } else cm.extendSelection(start); - }, - goLineEnd: function(cm) { - cm.extendSelection(lineEnd(cm, cm.getCursor().line)); - }, - goLineRight: function(cm) { - var top = cm.charCoords(cm.getCursor(), "div").top + 5; - cm.extendSelection(cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div")); - }, - goLineLeft: function(cm) { - var top = cm.charCoords(cm.getCursor(), "div").top + 5; - cm.extendSelection(cm.coordsChar({left: 0, top: top}, "div")); - }, - goLineUp: function(cm) {cm.moveV(-1, "line");}, - goLineDown: function(cm) {cm.moveV(1, "line");}, - goPageUp: function(cm) {cm.moveV(-1, "page");}, - goPageDown: function(cm) {cm.moveV(1, "page");}, - goCharLeft: function(cm) {cm.moveH(-1, "char");}, - goCharRight: function(cm) {cm.moveH(1, "char");}, - goColumnLeft: function(cm) {cm.moveH(-1, "column");}, - goColumnRight: function(cm) {cm.moveH(1, "column");}, - goWordLeft: function(cm) {cm.moveH(-1, "word");}, - goGroupRight: function(cm) {cm.moveH(1, "group");}, - goGroupLeft: function(cm) {cm.moveH(-1, "group");}, - goWordRight: function(cm) {cm.moveH(1, "word");}, - delCharBefore: function(cm) {cm.deleteH(-1, "char");}, - delCharAfter: function(cm) {cm.deleteH(1, "char");}, - delWordBefore: function(cm) {cm.deleteH(-1, "word");}, - delWordAfter: function(cm) {cm.deleteH(1, "word");}, - delGroupBefore: function(cm) {cm.deleteH(-1, "group");}, - delGroupAfter: function(cm) {cm.deleteH(1, "group");}, - indentAuto: function(cm) {cm.indentSelection("smart");}, - indentMore: function(cm) {cm.indentSelection("add");}, - indentLess: function(cm) {cm.indentSelection("subtract");}, - insertTab: function(cm) {cm.replaceSelection("\t", "end", "+input");}, - defaultTab: function(cm) { - if (cm.somethingSelected()) cm.indentSelection("add"); - else cm.replaceSelection("\t", "end", "+input"); - }, - transposeChars: function(cm) { - var cur = cm.getCursor(), line = cm.getLine(cur.line); - if (cur.ch > 0 && cur.ch < line.length - 1) - cm.replaceRange(line.charAt(cur.ch) + line.charAt(cur.ch - 1), - Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1)); - }, - newlineAndIndent: function(cm) { - operation(cm, function() { - cm.replaceSelection("\n", "end", "+input"); - cm.indentLine(cm.getCursor().line, null, true); - })(); - }, - toggleOverwrite: function(cm) {cm.toggleOverwrite();} - }; - - // STANDARD KEYMAPS - - var keyMap = CodeMirror.keyMap = {}; - keyMap.basic = { - "Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown", - "End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown", - "Delete": "delCharAfter", "Backspace": "delCharBefore", "Tab": "defaultTab", "Shift-Tab": "indentAuto", - "Enter": "newlineAndIndent", "Insert": "toggleOverwrite" - }; - // Note that the save and find-related commands aren't defined by - // default. Unknown commands are simply ignored. - keyMap.pcDefault = { - "Ctrl-A": "selectAll", "Ctrl-D": "deleteLine", "Ctrl-Z": "undo", "Shift-Ctrl-Z": "redo", "Ctrl-Y": "redo", - "Ctrl-Home": "goDocStart", "Alt-Up": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Down": "goDocEnd", - "Ctrl-Left": "goGroupLeft", "Ctrl-Right": "goGroupRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd", - "Ctrl-Backspace": "delGroupBefore", "Ctrl-Delete": "delGroupAfter", "Ctrl-S": "save", "Ctrl-F": "find", - "Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll", - "Ctrl-[": "indentLess", "Ctrl-]": "indentMore", - fallthrough: "basic" - }; - keyMap.macDefault = { - "Cmd-A": "selectAll", "Cmd-D": "deleteLine", "Cmd-Z": "undo", "Shift-Cmd-Z": "redo", "Cmd-Y": "redo", - "Cmd-Up": "goDocStart", "Cmd-End": "goDocEnd", "Cmd-Down": "goDocEnd", "Alt-Left": "goGroupLeft", - "Alt-Right": "goGroupRight", "Cmd-Left": "goLineStart", "Cmd-Right": "goLineEnd", "Alt-Backspace": "delGroupBefore", - "Ctrl-Alt-Backspace": "delGroupAfter", "Alt-Delete": "delGroupAfter", "Cmd-S": "save", "Cmd-F": "find", - "Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll", - "Cmd-[": "indentLess", "Cmd-]": "indentMore", "Cmd-Backspace": "delLineLeft", - fallthrough: ["basic", "emacsy"] - }; - keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault; - keyMap.emacsy = { - "Ctrl-F": "goCharRight", "Ctrl-B": "goCharLeft", "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown", - "Alt-F": "goWordRight", "Alt-B": "goWordLeft", "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd", - "Ctrl-V": "goPageDown", "Shift-Ctrl-V": "goPageUp", "Ctrl-D": "delCharAfter", "Ctrl-H": "delCharBefore", - "Alt-D": "delWordAfter", "Alt-Backspace": "delWordBefore", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars" - }; - - // KEYMAP DISPATCH - - function getKeyMap(val) { - if (typeof val == "string") return keyMap[val]; - else return val; - } - - function lookupKey(name, maps, handle) { - function lookup(map) { - map = getKeyMap(map); - var found = map[name]; - if (found === false) return "stop"; - if (found != null && handle(found)) return true; - if (map.nofallthrough) return "stop"; - - var fallthrough = map.fallthrough; - if (fallthrough == null) return false; - if (Object.prototype.toString.call(fallthrough) != "[object Array]") - return lookup(fallthrough); - for (var i = 0, e = fallthrough.length; i < e; ++i) { - var done = lookup(fallthrough[i]); - if (done) return done; - } - return false; - } - - for (var i = 0; i < maps.length; ++i) { - var done = lookup(maps[i]); - if (done) return done != "stop"; - } - } - function isModifierKey(event) { - var name = keyNames[event.keyCode]; - return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod"; - } - function keyName(event, noShift) { - if (opera && event.keyCode == 34 && event["char"]) return false; - var name = keyNames[event.keyCode]; - if (name == null || event.altGraphKey) return false; - if (event.altKey) name = "Alt-" + name; - if (flipCtrlCmd ? event.metaKey : event.ctrlKey) name = "Ctrl-" + name; - if (flipCtrlCmd ? event.ctrlKey : event.metaKey) name = "Cmd-" + name; - if (!noShift && event.shiftKey) name = "Shift-" + name; - return name; - } - CodeMirror.lookupKey = lookupKey; - CodeMirror.isModifierKey = isModifierKey; - CodeMirror.keyName = keyName; - - // FROMTEXTAREA - - CodeMirror.fromTextArea = function(textarea, options) { - if (!options) options = {}; - options.value = textarea.value; - if (!options.tabindex && textarea.tabindex) - options.tabindex = textarea.tabindex; - if (!options.placeholder && textarea.placeholder) - options.placeholder = textarea.placeholder; - // Set autofocus to true if this textarea is focused, or if it has - // autofocus and no other element is focused. - if (options.autofocus == null) { - var hasFocus = document.body; - // doc.activeElement occasionally throws on IE - try { hasFocus = document.activeElement; } catch(e) {} - options.autofocus = hasFocus == textarea || - textarea.getAttribute("autofocus") != null && hasFocus == document.body; - } - - function save() {textarea.value = cm.getValue();} - if (textarea.form) { - on(textarea.form, "submit", save); - // Deplorable hack to make the submit method do the right thing. - if (!options.leaveSubmitMethodAlone) { - var form = textarea.form, realSubmit = form.submit; - try { - var wrappedSubmit = form.submit = function() { - save(); - form.submit = realSubmit; - form.submit(); - form.submit = wrappedSubmit; - }; - } catch(e) {} - } - } - - textarea.style.display = "none"; - var cm = CodeMirror(function(node) { - textarea.parentNode.insertBefore(node, textarea.nextSibling); - }, options); - cm.save = save; - cm.getTextArea = function() { return textarea; }; - cm.toTextArea = function() { - save(); - textarea.parentNode.removeChild(cm.getWrapperElement()); - textarea.style.display = ""; - if (textarea.form) { - off(textarea.form, "submit", save); - if (typeof textarea.form.submit == "function") - textarea.form.submit = realSubmit; - } - }; - return cm; - }; - - // STRING STREAM - - // Fed to the mode parsers, provides helper functions to make - // parsers more succinct. - - // The character stream used by a mode's parser. - function StringStream(string, tabSize) { - this.pos = this.start = 0; - this.string = string; - this.tabSize = tabSize || 8; - this.lastColumnPos = this.lastColumnValue = 0; - } - - StringStream.prototype = { - eol: function() {return this.pos >= this.string.length;}, - sol: function() {return this.pos == 0;}, - peek: function() {return this.string.charAt(this.pos) || undefined;}, - next: function() { - if (this.pos < this.string.length) - return this.string.charAt(this.pos++); - }, - eat: function(match) { - var ch = this.string.charAt(this.pos); - if (typeof match == "string") var ok = ch == match; - else var ok = ch && (match.test ? match.test(ch) : match(ch)); - if (ok) {++this.pos; return ch;} - }, - eatWhile: function(match) { - var start = this.pos; - while (this.eat(match)){} - return this.pos > start; - }, - eatSpace: function() { - var start = this.pos; - while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos; - return this.pos > start; - }, - skipToEnd: function() {this.pos = this.string.length;}, - skipTo: function(ch) { - var found = this.string.indexOf(ch, this.pos); - if (found > -1) {this.pos = found; return true;} - }, - backUp: function(n) {this.pos -= n;}, - column: function() { - if (this.lastColumnPos < this.start) { - this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue); - this.lastColumnPos = this.start; - } - return this.lastColumnValue; - }, - indentation: function() {return countColumn(this.string, null, this.tabSize);}, - match: function(pattern, consume, caseInsensitive) { - if (typeof pattern == "string") { - var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;}; - var substr = this.string.substr(this.pos, pattern.length); - if (cased(substr) == cased(pattern)) { - if (consume !== false) this.pos += pattern.length; - return true; - } - } else { - var match = this.string.slice(this.pos).match(pattern); - if (match && match.index > 0) return null; - if (match && consume !== false) this.pos += match[0].length; - return match; - } - }, - current: function(){return this.string.slice(this.start, this.pos);} - }; - CodeMirror.StringStream = StringStream; - - // TEXTMARKERS - - function TextMarker(doc, type) { - this.lines = []; - this.type = type; - this.doc = doc; - } - CodeMirror.TextMarker = TextMarker; - eventMixin(TextMarker); - - TextMarker.prototype.clear = function() { - if (this.explicitlyCleared) return; - var cm = this.doc.cm, withOp = cm && !cm.curOp; - if (withOp) startOperation(cm); - if (hasHandler(this, "clear")) { - var found = this.find(); - if (found) signalLater(this, "clear", found.from, found.to); - } - var min = null, max = null; - for (var i = 0; i < this.lines.length; ++i) { - var line = this.lines[i]; - var span = getMarkedSpanFor(line.markedSpans, this); - if (span.to != null) max = lineNo(line); - line.markedSpans = removeMarkedSpan(line.markedSpans, span); - if (span.from != null) - min = lineNo(line); - else if (this.collapsed && !lineIsHidden(this.doc, line) && cm) - updateLineHeight(line, textHeight(cm.display)); - } - if (cm && this.collapsed && !cm.options.lineWrapping) for (var i = 0; i < this.lines.length; ++i) { - var visual = visualLine(cm.doc, this.lines[i]), len = lineLength(cm.doc, visual); - if (len > cm.display.maxLineLength) { - cm.display.maxLine = visual; - cm.display.maxLineLength = len; - cm.display.maxLineChanged = true; - } - } - - if (min != null && cm) regChange(cm, min, max + 1); - this.lines.length = 0; - this.explicitlyCleared = true; - if (this.atomic && this.doc.cantEdit) { - this.doc.cantEdit = false; - if (cm) reCheckSelection(cm); - } - if (withOp) endOperation(cm); - }; - - TextMarker.prototype.find = function() { - var from, to; - for (var i = 0; i < this.lines.length; ++i) { - var line = this.lines[i]; - var span = getMarkedSpanFor(line.markedSpans, this); - if (span.from != null || span.to != null) { - var found = lineNo(line); - if (span.from != null) from = Pos(found, span.from); - if (span.to != null) to = Pos(found, span.to); - } - } - if (this.type == "bookmark") return from; - return from && {from: from, to: to}; - }; - - TextMarker.prototype.changed = function() { - var pos = this.find(), cm = this.doc.cm; - if (!pos || !cm) return; - if (this.type != "bookmark") pos = pos.from; - var line = getLine(this.doc, pos.line); - clearCachedMeasurement(cm, line); - if (pos.line >= cm.display.showingFrom && pos.line < cm.display.showingTo) { - for (var node = cm.display.lineDiv.firstChild; node; node = node.nextSibling) if (node.lineObj == line) { - if (node.offsetHeight != line.height) updateLineHeight(line, node.offsetHeight); - break; - } - runInOp(cm, function() { - cm.curOp.selectionChanged = cm.curOp.forceUpdate = cm.curOp.updateMaxLine = true; - }); - } - }; - - TextMarker.prototype.attachLine = function(line) { - if (!this.lines.length && this.doc.cm) { - var op = this.doc.cm.curOp; - if (!op.maybeHiddenMarkers || indexOf(op.maybeHiddenMarkers, this) == -1) - (op.maybeUnhiddenMarkers || (op.maybeUnhiddenMarkers = [])).push(this); - } - this.lines.push(line); - }; - TextMarker.prototype.detachLine = function(line) { - this.lines.splice(indexOf(this.lines, line), 1); - if (!this.lines.length && this.doc.cm) { - var op = this.doc.cm.curOp; - (op.maybeHiddenMarkers || (op.maybeHiddenMarkers = [])).push(this); - } - }; - - function markText(doc, from, to, options, type) { - if (options && options.shared) return markTextShared(doc, from, to, options, type); - if (doc.cm && !doc.cm.curOp) return operation(doc.cm, markText)(doc, from, to, options, type); - - var marker = new TextMarker(doc, type); - if (type == "range" && !posLess(from, to)) return marker; - if (options) copyObj(options, marker); - if (marker.replacedWith) { - marker.collapsed = true; - marker.replacedWith = elt("span", [marker.replacedWith], "CodeMirror-widget"); - if (!options.handleMouseEvents) marker.replacedWith.ignoreEvents = true; - } - if (marker.collapsed) sawCollapsedSpans = true; - - if (marker.addToHistory) - addToHistory(doc, {from: from, to: to, origin: "markText"}, - {head: doc.sel.head, anchor: doc.sel.anchor}, NaN); - - var curLine = from.line, size = 0, collapsedAtStart, collapsedAtEnd, cm = doc.cm, updateMaxLine; - doc.iter(curLine, to.line + 1, function(line) { - if (cm && marker.collapsed && !cm.options.lineWrapping && visualLine(doc, line) == cm.display.maxLine) - updateMaxLine = true; - var span = {from: null, to: null, marker: marker}; - size += line.text.length; - if (curLine == from.line) {span.from = from.ch; size -= from.ch;} - if (curLine == to.line) {span.to = to.ch; size -= line.text.length - to.ch;} - if (marker.collapsed) { - if (curLine == to.line) collapsedAtEnd = collapsedSpanAt(line, to.ch); - if (curLine == from.line) collapsedAtStart = collapsedSpanAt(line, from.ch); - else updateLineHeight(line, 0); - } - addMarkedSpan(line, span); - ++curLine; - }); - if (marker.collapsed) doc.iter(from.line, to.line + 1, function(line) { - if (lineIsHidden(doc, line)) updateLineHeight(line, 0); - }); - - if (marker.clearOnEnter) on(marker, "beforeCursorEnter", function() { marker.clear(); }); - - if (marker.readOnly) { - sawReadOnlySpans = true; - if (doc.history.done.length || doc.history.undone.length) - doc.clearHistory(); - } - if (marker.collapsed) { - if (collapsedAtStart != collapsedAtEnd) - throw new Error("Inserting collapsed marker overlapping an existing one"); - marker.size = size; - marker.atomic = true; - } - if (cm) { - if (updateMaxLine) cm.curOp.updateMaxLine = true; - if (marker.className || marker.title || marker.startStyle || marker.endStyle || marker.collapsed) - regChange(cm, from.line, to.line + 1); - if (marker.atomic) reCheckSelection(cm); - } - return marker; - } - - // SHARED TEXTMARKERS - - function SharedTextMarker(markers, primary) { - this.markers = markers; - this.primary = primary; - for (var i = 0, me = this; i < markers.length; ++i) { - markers[i].parent = this; - on(markers[i], "clear", function(){me.clear();}); - } - } - CodeMirror.SharedTextMarker = SharedTextMarker; - eventMixin(SharedTextMarker); - - SharedTextMarker.prototype.clear = function() { - if (this.explicitlyCleared) return; - this.explicitlyCleared = true; - for (var i = 0; i < this.markers.length; ++i) - this.markers[i].clear(); - signalLater(this, "clear"); - }; - SharedTextMarker.prototype.find = function() { - return this.primary.find(); - }; - - function markTextShared(doc, from, to, options, type) { - options = copyObj(options); - options.shared = false; - var markers = [markText(doc, from, to, options, type)], primary = markers[0]; - var widget = options.replacedWith; - linkedDocs(doc, function(doc) { - if (widget) options.replacedWith = widget.cloneNode(true); - markers.push(markText(doc, clipPos(doc, from), clipPos(doc, to), options, type)); - for (var i = 0; i < doc.linked.length; ++i) - if (doc.linked[i].isParent) return; - primary = lst(markers); - }); - return new SharedTextMarker(markers, primary); - } - - // TEXTMARKER SPANS - - function getMarkedSpanFor(spans, marker) { - if (spans) for (var i = 0; i < spans.length; ++i) { - var span = spans[i]; - if (span.marker == marker) return span; - } - } - function removeMarkedSpan(spans, span) { - for (var r, i = 0; i < spans.length; ++i) - if (spans[i] != span) (r || (r = [])).push(spans[i]); - return r; - } - function addMarkedSpan(line, span) { - line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span]; - span.marker.attachLine(line); - } - - function markedSpansBefore(old, startCh, isInsert) { - if (old) for (var i = 0, nw; i < old.length; ++i) { - var span = old[i], marker = span.marker; - var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh); - if (startsBefore || marker.type == "bookmark" && span.from == startCh && (!isInsert || !span.marker.insertLeft)) { - var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh); - (nw || (nw = [])).push({from: span.from, - to: endsAfter ? null : span.to, - marker: marker}); - } - } - return nw; - } - - function markedSpansAfter(old, endCh, isInsert) { - if (old) for (var i = 0, nw; i < old.length; ++i) { - var span = old[i], marker = span.marker; - var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh); - if (endsAfter || marker.type == "bookmark" && span.from == endCh && (!isInsert || span.marker.insertLeft)) { - var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh); - (nw || (nw = [])).push({from: startsBefore ? null : span.from - endCh, - to: span.to == null ? null : span.to - endCh, - marker: marker}); - } - } - return nw; - } - - function stretchSpansOverChange(doc, change) { - var oldFirst = isLine(doc, change.from.line) && getLine(doc, change.from.line).markedSpans; - var oldLast = isLine(doc, change.to.line) && getLine(doc, change.to.line).markedSpans; - if (!oldFirst && !oldLast) return null; - - var startCh = change.from.ch, endCh = change.to.ch, isInsert = posEq(change.from, change.to); - // Get the spans that 'stick out' on both sides - var first = markedSpansBefore(oldFirst, startCh, isInsert); - var last = markedSpansAfter(oldLast, endCh, isInsert); - - // Next, merge those two ends - var sameLine = change.text.length == 1, offset = lst(change.text).length + (sameLine ? startCh : 0); - if (first) { - // Fix up .to properties of first - for (var i = 0; i < first.length; ++i) { - var span = first[i]; - if (span.to == null) { - var found = getMarkedSpanFor(last, span.marker); - if (!found) span.to = startCh; - else if (sameLine) span.to = found.to == null ? null : found.to + offset; - } - } - } - if (last) { - // Fix up .from in last (or move them into first in case of sameLine) - for (var i = 0; i < last.length; ++i) { - var span = last[i]; - if (span.to != null) span.to += offset; - if (span.from == null) { - var found = getMarkedSpanFor(first, span.marker); - if (!found) { - span.from = offset; - if (sameLine) (first || (first = [])).push(span); - } - } else { - span.from += offset; - if (sameLine) (first || (first = [])).push(span); - } - } - } - if (sameLine && first) { - // Make sure we didn't create any zero-length spans - for (var i = 0; i < first.length; ++i) - if (first[i].from != null && first[i].from == first[i].to && first[i].marker.type != "bookmark") - first.splice(i--, 1); - if (!first.length) first = null; - } - - var newMarkers = [first]; - if (!sameLine) { - // Fill gap with whole-line-spans - var gap = change.text.length - 2, gapMarkers; - if (gap > 0 && first) - for (var i = 0; i < first.length; ++i) - if (first[i].to == null) - (gapMarkers || (gapMarkers = [])).push({from: null, to: null, marker: first[i].marker}); - for (var i = 0; i < gap; ++i) - newMarkers.push(gapMarkers); - newMarkers.push(last); - } - return newMarkers; - } - - function mergeOldSpans(doc, change) { - var old = getOldSpans(doc, change); - var stretched = stretchSpansOverChange(doc, change); - if (!old) return stretched; - if (!stretched) return old; - - for (var i = 0; i < old.length; ++i) { - var oldCur = old[i], stretchCur = stretched[i]; - if (oldCur && stretchCur) { - spans: for (var j = 0; j < stretchCur.length; ++j) { - var span = stretchCur[j]; - for (var k = 0; k < oldCur.length; ++k) - if (oldCur[k].marker == span.marker) continue spans; - oldCur.push(span); - } - } else if (stretchCur) { - old[i] = stretchCur; - } - } - return old; - } - - function removeReadOnlyRanges(doc, from, to) { - var markers = null; - doc.iter(from.line, to.line + 1, function(line) { - if (line.markedSpans) for (var i = 0; i < line.markedSpans.length; ++i) { - var mark = line.markedSpans[i].marker; - if (mark.readOnly && (!markers || indexOf(markers, mark) == -1)) - (markers || (markers = [])).push(mark); - } - }); - if (!markers) return null; - var parts = [{from: from, to: to}]; - for (var i = 0; i < markers.length; ++i) { - var mk = markers[i], m = mk.find(); - for (var j = 0; j < parts.length; ++j) { - var p = parts[j]; - if (posLess(p.to, m.from) || posLess(m.to, p.from)) continue; - var newParts = [j, 1]; - if (posLess(p.from, m.from) || !mk.inclusiveLeft && posEq(p.from, m.from)) - newParts.push({from: p.from, to: m.from}); - if (posLess(m.to, p.to) || !mk.inclusiveRight && posEq(p.to, m.to)) - newParts.push({from: m.to, to: p.to}); - parts.splice.apply(parts, newParts); - j += newParts.length - 1; - } - } - return parts; - } - - function collapsedSpanAt(line, ch) { - var sps = sawCollapsedSpans && line.markedSpans, found; - if (sps) for (var sp, i = 0; i < sps.length; ++i) { - sp = sps[i]; - if (!sp.marker.collapsed) continue; - if ((sp.from == null || sp.from < ch) && - (sp.to == null || sp.to > ch) && - (!found || found.width < sp.marker.width)) - found = sp.marker; - } - return found; - } - function collapsedSpanAtStart(line) { return collapsedSpanAt(line, -1); } - function collapsedSpanAtEnd(line) { return collapsedSpanAt(line, line.text.length + 1); } - - function visualLine(doc, line) { - var merged; - while (merged = collapsedSpanAtStart(line)) - line = getLine(doc, merged.find().from.line); - return line; - } - - function lineIsHidden(doc, line) { - var sps = sawCollapsedSpans && line.markedSpans; - if (sps) for (var sp, i = 0; i < sps.length; ++i) { - sp = sps[i]; - if (!sp.marker.collapsed) continue; - if (sp.from == null) return true; - if (sp.marker.replacedWith) continue; - if (sp.from == 0 && sp.marker.inclusiveLeft && lineIsHiddenInner(doc, line, sp)) - return true; - } - } - function lineIsHiddenInner(doc, line, span) { - if (span.to == null) { - var end = span.marker.find().to, endLine = getLine(doc, end.line); - return lineIsHiddenInner(doc, endLine, getMarkedSpanFor(endLine.markedSpans, span.marker)); - } - if (span.marker.inclusiveRight && span.to == line.text.length) - return true; - for (var sp, i = 0; i < line.markedSpans.length; ++i) { - sp = line.markedSpans[i]; - if (sp.marker.collapsed && !sp.marker.replacedWith && sp.from == span.to && - (sp.marker.inclusiveLeft || span.marker.inclusiveRight) && - lineIsHiddenInner(doc, line, sp)) return true; - } - } - - function detachMarkedSpans(line) { - var spans = line.markedSpans; - if (!spans) return; - for (var i = 0; i < spans.length; ++i) - spans[i].marker.detachLine(line); - line.markedSpans = null; - } - - function attachMarkedSpans(line, spans) { - if (!spans) return; - for (var i = 0; i < spans.length; ++i) - spans[i].marker.attachLine(line); - line.markedSpans = spans; - } - - // LINE WIDGETS - - var LineWidget = CodeMirror.LineWidget = function(cm, node, options) { - if (options) for (var opt in options) if (options.hasOwnProperty(opt)) - this[opt] = options[opt]; - this.cm = cm; - this.node = node; - }; - eventMixin(LineWidget); - function widgetOperation(f) { - return function() { - var withOp = !this.cm.curOp; - if (withOp) startOperation(this.cm); - try {var result = f.apply(this, arguments);} - finally {if (withOp) endOperation(this.cm);} - return result; - }; - } - LineWidget.prototype.clear = widgetOperation(function() { - var ws = this.line.widgets, no = lineNo(this.line); - if (no == null || !ws) return; - for (var i = 0; i < ws.length; ++i) if (ws[i] == this) ws.splice(i--, 1); - if (!ws.length) this.line.widgets = null; - var aboveVisible = heightAtLine(this.cm, this.line) < this.cm.doc.scrollTop; - updateLineHeight(this.line, Math.max(0, this.line.height - widgetHeight(this))); - if (aboveVisible) addToScrollPos(this.cm, 0, -this.height); - regChange(this.cm, no, no + 1); - }); - LineWidget.prototype.changed = widgetOperation(function() { - var oldH = this.height; - this.height = null; - var diff = widgetHeight(this) - oldH; - if (!diff) return; - updateLineHeight(this.line, this.line.height + diff); - var no = lineNo(this.line); - regChange(this.cm, no, no + 1); - }); - - function widgetHeight(widget) { - if (widget.height != null) return widget.height; - if (!widget.node.parentNode || widget.node.parentNode.nodeType != 1) - removeChildrenAndAdd(widget.cm.display.measure, elt("div", [widget.node], null, "position: relative")); - return widget.height = widget.node.offsetHeight; - } - - function addLineWidget(cm, handle, node, options) { - var widget = new LineWidget(cm, node, options); - if (widget.noHScroll) cm.display.alignWidgets = true; - changeLine(cm, handle, function(line) { - var widgets = line.widgets || (line.widgets = []); - if (widget.insertAt == null) widgets.push(widget); - else widgets.splice(Math.min(widgets.length - 1, Math.max(0, widget.insertAt)), 0, widget); - widget.line = line; - if (!lineIsHidden(cm.doc, line) || widget.showIfHidden) { - var aboveVisible = heightAtLine(cm, line) < cm.doc.scrollTop; - updateLineHeight(line, line.height + widgetHeight(widget)); - if (aboveVisible) addToScrollPos(cm, 0, widget.height); - } - return true; - }); - return widget; - } - - // LINE DATA STRUCTURE - - // Line objects. These hold state related to a line, including - // highlighting info (the styles array). - var Line = CodeMirror.Line = function(text, markedSpans, estimateHeight) { - this.text = text; - attachMarkedSpans(this, markedSpans); - this.height = estimateHeight ? estimateHeight(this) : 1; - }; - eventMixin(Line); - - function updateLine(line, text, markedSpans, estimateHeight) { - line.text = text; - if (line.stateAfter) line.stateAfter = null; - if (line.styles) line.styles = null; - if (line.order != null) line.order = null; - detachMarkedSpans(line); - attachMarkedSpans(line, markedSpans); - var estHeight = estimateHeight ? estimateHeight(line) : 1; - if (estHeight != line.height) updateLineHeight(line, estHeight); - } - - function cleanUpLine(line) { - line.parent = null; - detachMarkedSpans(line); - } - - // Run the given mode's parser over a line, update the styles - // array, which contains alternating fragments of text and CSS - // classes. - function runMode(cm, text, mode, state, f) { - var flattenSpans = mode.flattenSpans; - if (flattenSpans == null) flattenSpans = cm.options.flattenSpans; - var curStart = 0, curStyle = null; - var stream = new StringStream(text, cm.options.tabSize), style; - if (text == "" && mode.blankLine) mode.blankLine(state); - while (!stream.eol()) { - if (stream.pos > cm.options.maxHighlightLength) { - flattenSpans = false; - stream.pos = text.length; - style = null; - } else { - style = mode.token(stream, state); - } - if (!flattenSpans || curStyle != style) { - if (curStart < stream.start) f(stream.start, curStyle); - curStart = stream.start; curStyle = style; - } - stream.start = stream.pos; - } - while (curStart < stream.pos) { - // Webkit seems to refuse to render text nodes longer than 57444 characters - var pos = Math.min(stream.pos, curStart + 50000); - f(pos, curStyle); - curStart = pos; - } - } - - function highlightLine(cm, line, state) { - // A styles array always starts with a number identifying the - // mode/overlays that it is based on (for easy invalidation). - var st = [cm.state.modeGen]; - // Compute the base array of styles - runMode(cm, line.text, cm.doc.mode, state, function(end, style) {st.push(end, style);}); - - // Run overlays, adjust style array. - for (var o = 0; o < cm.state.overlays.length; ++o) { - var overlay = cm.state.overlays[o], i = 1, at = 0; - runMode(cm, line.text, overlay.mode, true, function(end, style) { - var start = i; - // Ensure there's a token end at the current position, and that i points at it - while (at < end) { - var i_end = st[i]; - if (i_end > end) - st.splice(i, 1, end, st[i+1], i_end); - i += 2; - at = Math.min(end, i_end); - } - if (!style) return; - if (overlay.opaque) { - st.splice(start, i - start, end, style); - i = start + 2; - } else { - for (; start < i; start += 2) { - var cur = st[start+1]; - st[start+1] = cur ? cur + " " + style : style; - } - } - }); - } - - return st; - } - - function getLineStyles(cm, line) { - if (!line.styles || line.styles[0] != cm.state.modeGen) - line.styles = highlightLine(cm, line, line.stateAfter = getStateBefore(cm, lineNo(line))); - return line.styles; - } - - // Lightweight form of highlight -- proceed over this line and - // update state, but don't save a style array. - function processLine(cm, line, state) { - var mode = cm.doc.mode; - var stream = new StringStream(line.text, cm.options.tabSize); - if (line.text == "" && mode.blankLine) mode.blankLine(state); - while (!stream.eol() && stream.pos <= cm.options.maxHighlightLength) { - mode.token(stream, state); - stream.start = stream.pos; - } - } - - var styleToClassCache = {}; - function interpretTokenStyle(style, builder) { - if (!style) return null; - for (;;) { - var lineClass = style.match(/(?:^|\s)line-(background-)?(\S+)/); - if (!lineClass) break; - style = style.slice(0, lineClass.index) + style.slice(lineClass.index + lineClass[0].length); - var prop = lineClass[1] ? "bgClass" : "textClass"; - if (builder[prop] == null) - builder[prop] = lineClass[2]; - else if (!(new RegExp("(?:^|\s)" + lineClass[2] + "(?:$|\s)")).test(builder[prop])) - builder[prop] += " " + lineClass[2]; - } - return styleToClassCache[style] || - (styleToClassCache[style] = "cm-" + style.replace(/ +/g, " cm-")); - } - - function buildLineContent(cm, realLine, measure, copyWidgets) { - var merged, line = realLine, empty = true; - while (merged = collapsedSpanAtStart(line)) - line = getLine(cm.doc, merged.find().from.line); - - var builder = {pre: elt("pre"), col: 0, pos: 0, - measure: null, measuredSomething: false, cm: cm, - copyWidgets: copyWidgets}; - - do { - if (line.text) empty = false; - builder.measure = line == realLine && measure; - builder.pos = 0; - builder.addToken = builder.measure ? buildTokenMeasure : buildToken; - if ((ie || webkit) && cm.getOption("lineWrapping")) - builder.addToken = buildTokenSplitSpaces(builder.addToken); - var next = insertLineContent(line, builder, getLineStyles(cm, line)); - if (measure && line == realLine && !builder.measuredSomething) { - measure[0] = builder.pre.appendChild(zeroWidthElement(cm.display.measure)); - builder.measuredSomething = true; - } - if (next) line = getLine(cm.doc, next.to.line); - } while (next); - - if (measure && !builder.measuredSomething && !measure[0]) - measure[0] = builder.pre.appendChild(empty ? elt("span", "\u00a0") : zeroWidthElement(cm.display.measure)); - if (!builder.pre.firstChild && !lineIsHidden(cm.doc, realLine)) - builder.pre.appendChild(document.createTextNode("\u00a0")); - - var order; - // Work around problem with the reported dimensions of single-char - // direction spans on IE (issue #1129). See also the comment in - // cursorCoords. - if (measure && ie && (order = getOrder(line))) { - var l = order.length - 1; - if (order[l].from == order[l].to) --l; - var last = order[l], prev = order[l - 1]; - if (last.from + 1 == last.to && prev && last.level < prev.level) { - var span = measure[builder.pos - 1]; - if (span) span.parentNode.insertBefore(span.measureRight = zeroWidthElement(cm.display.measure), - span.nextSibling); - } - } - - var textClass = builder.textClass ? builder.textClass + " " + (realLine.textClass || "") : realLine.textClass; - if (textClass) builder.pre.className = textClass; - - signal(cm, "renderLine", cm, realLine, builder.pre); - return builder; - } - - var tokenSpecialChars = /[\t\u0000-\u0019\u00ad\u200b\u2028\u2029\uFEFF]/g; - function buildToken(builder, text, style, startStyle, endStyle, title) { - if (!text) return; - if (!tokenSpecialChars.test(text)) { - builder.col += text.length; - var content = document.createTextNode(text); - } else { - var content = document.createDocumentFragment(), pos = 0; - while (true) { - tokenSpecialChars.lastIndex = pos; - var m = tokenSpecialChars.exec(text); - var skipped = m ? m.index - pos : text.length - pos; - if (skipped) { - content.appendChild(document.createTextNode(text.slice(pos, pos + skipped))); - builder.col += skipped; - } - if (!m) break; - pos += skipped + 1; - if (m[0] == "\t") { - var tabSize = builder.cm.options.tabSize, tabWidth = tabSize - builder.col % tabSize; - content.appendChild(elt("span", spaceStr(tabWidth), "cm-tab")); - builder.col += tabWidth; - } else { - var token = elt("span", "\u2022", "cm-invalidchar"); - token.title = "\\u" + m[0].charCodeAt(0).toString(16); - content.appendChild(token); - builder.col += 1; - } - } - } - if (style || startStyle || endStyle || builder.measure) { - var fullStyle = style || ""; - if (startStyle) fullStyle += startStyle; - if (endStyle) fullStyle += endStyle; - var token = elt("span", [content], fullStyle); - if (title) token.title = title; - return builder.pre.appendChild(token); - } - builder.pre.appendChild(content); - } - - function buildTokenMeasure(builder, text, style, startStyle, endStyle) { - var wrapping = builder.cm.options.lineWrapping; - for (var i = 0; i < text.length; ++i) { - var ch = text.charAt(i), start = i == 0; - if (ch >= "\ud800" && ch < "\udbff" && i < text.length - 1) { - ch = text.slice(i, i + 2); - ++i; - } else if (i && wrapping && spanAffectsWrapping(text, i)) { - builder.pre.appendChild(elt("wbr")); - } - var old = builder.measure[builder.pos]; - var span = builder.measure[builder.pos] = - buildToken(builder, ch, style, - start && startStyle, i == text.length - 1 && endStyle); - if (old) span.leftSide = old.leftSide || old; - // In IE single-space nodes wrap differently than spaces - // embedded in larger text nodes, except when set to - // white-space: normal (issue #1268). - if (ie && wrapping && ch == " " && i && !/\s/.test(text.charAt(i - 1)) && - i < text.length - 1 && !/\s/.test(text.charAt(i + 1))) - span.style.whiteSpace = "normal"; - builder.pos += ch.length; - } - if (text.length) builder.measuredSomething = true; - } - - function buildTokenSplitSpaces(inner) { - function split(old) { - var out = " "; - for (var i = 0; i < old.length - 2; ++i) out += i % 2 ? " " : "\u00a0"; - out += " "; - return out; - } - return function(builder, text, style, startStyle, endStyle, title) { - return inner(builder, text.replace(/ {3,}/, split), style, startStyle, endStyle, title); - }; - } - - function buildCollapsedSpan(builder, size, marker, ignoreWidget) { - var widget = !ignoreWidget && marker.replacedWith; - if (widget) { - if (builder.copyWidgets) widget = widget.cloneNode(true); - builder.pre.appendChild(widget); - if (builder.measure) { - if (size) { - builder.measure[builder.pos] = widget; - } else { - var elt = zeroWidthElement(builder.cm.display.measure); - if (marker.type == "bookmark" && !marker.insertLeft) - builder.measure[builder.pos] = builder.pre.appendChild(elt); - else if (builder.measure[builder.pos]) - return; - else - builder.measure[builder.pos] = builder.pre.insertBefore(elt, widget); - } - builder.measuredSomething = true; - } - } - builder.pos += size; - } - - // Outputs a number of spans to make up a line, taking highlighting - // and marked text into account. - function insertLineContent(line, builder, styles) { - var spans = line.markedSpans, allText = line.text, at = 0; - if (!spans) { - for (var i = 1; i < styles.length; i+=2) - builder.addToken(builder, allText.slice(at, at = styles[i]), interpretTokenStyle(styles[i+1], builder)); - return; - } - - var len = allText.length, pos = 0, i = 1, text = "", style; - var nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, title, collapsed; - for (;;) { - if (nextChange == pos) { // Update current marker set - spanStyle = spanEndStyle = spanStartStyle = title = ""; - collapsed = null; nextChange = Infinity; - var foundBookmarks = []; - for (var j = 0; j < spans.length; ++j) { - var sp = spans[j], m = sp.marker; - if (sp.from <= pos && (sp.to == null || sp.to > pos)) { - if (sp.to != null && nextChange > sp.to) { nextChange = sp.to; spanEndStyle = ""; } - if (m.className) spanStyle += " " + m.className; - if (m.startStyle && sp.from == pos) spanStartStyle += " " + m.startStyle; - if (m.endStyle && sp.to == nextChange) spanEndStyle += " " + m.endStyle; - if (m.title && !title) title = m.title; - if (m.collapsed && (!collapsed || collapsed.marker.size < m.size)) - collapsed = sp; - } else if (sp.from > pos && nextChange > sp.from) { - nextChange = sp.from; - } - if (m.type == "bookmark" && sp.from == pos && m.replacedWith) foundBookmarks.push(m); - } - if (collapsed && (collapsed.from || 0) == pos) { - buildCollapsedSpan(builder, (collapsed.to == null ? len : collapsed.to) - pos, - collapsed.marker, collapsed.from == null); - if (collapsed.to == null) return collapsed.marker.find(); - } - if (!collapsed && foundBookmarks.length) for (var j = 0; j < foundBookmarks.length; ++j) - buildCollapsedSpan(builder, 0, foundBookmarks[j]); - } - if (pos >= len) break; - - var upto = Math.min(len, nextChange); - while (true) { - if (text) { - var end = pos + text.length; - if (!collapsed) { - var tokenText = end > upto ? text.slice(0, upto - pos) : text; - builder.addToken(builder, tokenText, style ? style + spanStyle : spanStyle, - spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : "", title); - } - if (end >= upto) {text = text.slice(upto - pos); pos = upto; break;} - pos = end; - spanStartStyle = ""; - } - text = allText.slice(at, at = styles[i++]); - style = interpretTokenStyle(styles[i++], builder); - } - } - } - - // DOCUMENT DATA STRUCTURE - - function updateDoc(doc, change, markedSpans, selAfter, estimateHeight) { - function spansFor(n) {return markedSpans ? markedSpans[n] : null;} - function update(line, text, spans) { - updateLine(line, text, spans, estimateHeight); - signalLater(line, "change", line, change); - } - - var from = change.from, to = change.to, text = change.text; - var firstLine = getLine(doc, from.line), lastLine = getLine(doc, to.line); - var lastText = lst(text), lastSpans = spansFor(text.length - 1), nlines = to.line - from.line; - - // First adjust the line structure - if (from.ch == 0 && to.ch == 0 && lastText == "") { - // This is a whole-line replace. Treated specially to make - // sure line objects move the way they are supposed to. - for (var i = 0, e = text.length - 1, added = []; i < e; ++i) - added.push(new Line(text[i], spansFor(i), estimateHeight)); - update(lastLine, lastLine.text, lastSpans); - if (nlines) doc.remove(from.line, nlines); - if (added.length) doc.insert(from.line, added); - } else if (firstLine == lastLine) { - if (text.length == 1) { - update(firstLine, firstLine.text.slice(0, from.ch) + lastText + firstLine.text.slice(to.ch), lastSpans); - } else { - for (var added = [], i = 1, e = text.length - 1; i < e; ++i) - added.push(new Line(text[i], spansFor(i), estimateHeight)); - added.push(new Line(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight)); - update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0)); - doc.insert(from.line + 1, added); - } - } else if (text.length == 1) { - update(firstLine, firstLine.text.slice(0, from.ch) + text[0] + lastLine.text.slice(to.ch), spansFor(0)); - doc.remove(from.line + 1, nlines); - } else { - update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0)); - update(lastLine, lastText + lastLine.text.slice(to.ch), lastSpans); - for (var i = 1, e = text.length - 1, added = []; i < e; ++i) - added.push(new Line(text[i], spansFor(i), estimateHeight)); - if (nlines > 1) doc.remove(from.line + 1, nlines - 1); - doc.insert(from.line + 1, added); - } - - signalLater(doc, "change", doc, change); - setSelection(doc, selAfter.anchor, selAfter.head, null, true); - } - - function LeafChunk(lines) { - this.lines = lines; - this.parent = null; - for (var i = 0, e = lines.length, height = 0; i < e; ++i) { - lines[i].parent = this; - height += lines[i].height; - } - this.height = height; - } - - LeafChunk.prototype = { - chunkSize: function() { return this.lines.length; }, - removeInner: function(at, n) { - for (var i = at, e = at + n; i < e; ++i) { - var line = this.lines[i]; - this.height -= line.height; - cleanUpLine(line); - signalLater(line, "delete"); - } - this.lines.splice(at, n); - }, - collapse: function(lines) { - lines.splice.apply(lines, [lines.length, 0].concat(this.lines)); - }, - insertInner: function(at, lines, height) { - this.height += height; - this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at)); - for (var i = 0, e = lines.length; i < e; ++i) lines[i].parent = this; - }, - iterN: function(at, n, op) { - for (var e = at + n; at < e; ++at) - if (op(this.lines[at])) return true; - } - }; - - function BranchChunk(children) { - this.children = children; - var size = 0, height = 0; - for (var i = 0, e = children.length; i < e; ++i) { - var ch = children[i]; - size += ch.chunkSize(); height += ch.height; - ch.parent = this; - } - this.size = size; - this.height = height; - this.parent = null; - } - - BranchChunk.prototype = { - chunkSize: function() { return this.size; }, - removeInner: function(at, n) { - this.size -= n; - for (var i = 0; i < this.children.length; ++i) { - var child = this.children[i], sz = child.chunkSize(); - if (at < sz) { - var rm = Math.min(n, sz - at), oldHeight = child.height; - child.removeInner(at, rm); - this.height -= oldHeight - child.height; - if (sz == rm) { this.children.splice(i--, 1); child.parent = null; } - if ((n -= rm) == 0) break; - at = 0; - } else at -= sz; - } - if (this.size - n < 25) { - var lines = []; - this.collapse(lines); - this.children = [new LeafChunk(lines)]; - this.children[0].parent = this; - } - }, - collapse: function(lines) { - for (var i = 0, e = this.children.length; i < e; ++i) this.children[i].collapse(lines); - }, - insertInner: function(at, lines, height) { - this.size += lines.length; - this.height += height; - for (var i = 0, e = this.children.length; i < e; ++i) { - var child = this.children[i], sz = child.chunkSize(); - if (at <= sz) { - child.insertInner(at, lines, height); - if (child.lines && child.lines.length > 50) { - while (child.lines.length > 50) { - var spilled = child.lines.splice(child.lines.length - 25, 25); - var newleaf = new LeafChunk(spilled); - child.height -= newleaf.height; - this.children.splice(i + 1, 0, newleaf); - newleaf.parent = this; - } - this.maybeSpill(); - } - break; - } - at -= sz; - } - }, - maybeSpill: function() { - if (this.children.length <= 10) return; - var me = this; - do { - var spilled = me.children.splice(me.children.length - 5, 5); - var sibling = new BranchChunk(spilled); - if (!me.parent) { // Become the parent node - var copy = new BranchChunk(me.children); - copy.parent = me; - me.children = [copy, sibling]; - me = copy; - } else { - me.size -= sibling.size; - me.height -= sibling.height; - var myIndex = indexOf(me.parent.children, me); - me.parent.children.splice(myIndex + 1, 0, sibling); - } - sibling.parent = me.parent; - } while (me.children.length > 10); - me.parent.maybeSpill(); - }, - iterN: function(at, n, op) { - for (var i = 0, e = this.children.length; i < e; ++i) { - var child = this.children[i], sz = child.chunkSize(); - if (at < sz) { - var used = Math.min(n, sz - at); - if (child.iterN(at, used, op)) return true; - if ((n -= used) == 0) break; - at = 0; - } else at -= sz; - } - } - }; - - var nextDocId = 0; - var Doc = CodeMirror.Doc = function(text, mode, firstLine) { - if (!(this instanceof Doc)) return new Doc(text, mode, firstLine); - if (firstLine == null) firstLine = 0; - - BranchChunk.call(this, [new LeafChunk([new Line("", null)])]); - this.first = firstLine; - this.scrollTop = this.scrollLeft = 0; - this.cantEdit = false; - this.history = makeHistory(); - this.cleanGeneration = 1; - this.frontier = firstLine; - var start = Pos(firstLine, 0); - this.sel = {from: start, to: start, head: start, anchor: start, shift: false, extend: false, goalColumn: null}; - this.id = ++nextDocId; - this.modeOption = mode; - - if (typeof text == "string") text = splitLines(text); - updateDoc(this, {from: start, to: start, text: text}, null, {head: start, anchor: start}); - }; - - Doc.prototype = createObj(BranchChunk.prototype, { - constructor: Doc, - iter: function(from, to, op) { - if (op) this.iterN(from - this.first, to - from, op); - else this.iterN(this.first, this.first + this.size, from); - }, - - insert: function(at, lines) { - var height = 0; - for (var i = 0, e = lines.length; i < e; ++i) height += lines[i].height; - this.insertInner(at - this.first, lines, height); - }, - remove: function(at, n) { this.removeInner(at - this.first, n); }, - - getValue: function(lineSep) { - var lines = getLines(this, this.first, this.first + this.size); - if (lineSep === false) return lines; - return lines.join(lineSep || "\n"); - }, - setValue: function(code) { - var top = Pos(this.first, 0), last = this.first + this.size - 1; - makeChange(this, {from: top, to: Pos(last, getLine(this, last).text.length), - text: splitLines(code), origin: "setValue"}, - {head: top, anchor: top}, true); - }, - replaceRange: function(code, from, to, origin) { - from = clipPos(this, from); - to = to ? clipPos(this, to) : from; - replaceRange(this, code, from, to, origin); - }, - getRange: function(from, to, lineSep) { - var lines = getBetween(this, clipPos(this, from), clipPos(this, to)); - if (lineSep === false) return lines; - return lines.join(lineSep || "\n"); - }, - - getLine: function(line) {var l = this.getLineHandle(line); return l && l.text;}, - setLine: function(line, text) { - if (isLine(this, line)) - replaceRange(this, text, Pos(line, 0), clipPos(this, Pos(line))); - }, - removeLine: function(line) { - if (line) replaceRange(this, "", clipPos(this, Pos(line - 1)), clipPos(this, Pos(line))); - else replaceRange(this, "", Pos(0, 0), clipPos(this, Pos(1, 0))); - }, - - getLineHandle: function(line) {if (isLine(this, line)) return getLine(this, line);}, - getLineNumber: function(line) {return lineNo(line);}, - - getLineHandleVisualStart: function(line) { - if (typeof line == "number") line = getLine(this, line); - return visualLine(this, line); - }, - - lineCount: function() {return this.size;}, - firstLine: function() {return this.first;}, - lastLine: function() {return this.first + this.size - 1;}, - - clipPos: function(pos) {return clipPos(this, pos);}, - - getCursor: function(start) { - var sel = this.sel, pos; - if (start == null || start == "head") pos = sel.head; - else if (start == "anchor") pos = sel.anchor; - else if (start == "end" || start === false) pos = sel.to; - else pos = sel.from; - return copyPos(pos); - }, - somethingSelected: function() {return !posEq(this.sel.head, this.sel.anchor);}, - - setCursor: docOperation(function(line, ch, extend) { - var pos = clipPos(this, typeof line == "number" ? Pos(line, ch || 0) : line); - if (extend) extendSelection(this, pos); - else setSelection(this, pos, pos); - }), - setSelection: docOperation(function(anchor, head, bias) { - setSelection(this, clipPos(this, anchor), clipPos(this, head || anchor), bias); - }), - extendSelection: docOperation(function(from, to, bias) { - extendSelection(this, clipPos(this, from), to && clipPos(this, to), bias); - }), - - getSelection: function(lineSep) {return this.getRange(this.sel.from, this.sel.to, lineSep);}, - replaceSelection: function(code, collapse, origin) { - makeChange(this, {from: this.sel.from, to: this.sel.to, text: splitLines(code), origin: origin}, collapse || "around"); - }, - undo: docOperation(function() {makeChangeFromHistory(this, "undo");}), - redo: docOperation(function() {makeChangeFromHistory(this, "redo");}), - - setExtending: function(val) {this.sel.extend = val;}, - - historySize: function() { - var hist = this.history; - return {undo: hist.done.length, redo: hist.undone.length}; - }, - clearHistory: function() {this.history = makeHistory(this.history.maxGeneration);}, - - markClean: function() { - this.cleanGeneration = this.changeGeneration(); - }, - changeGeneration: function() { - this.history.lastOp = this.history.lastOrigin = null; - return this.history.generation; - }, - isClean: function (gen) { - return this.history.generation == (gen || this.cleanGeneration); - }, - - getHistory: function() { - return {done: copyHistoryArray(this.history.done), - undone: copyHistoryArray(this.history.undone)}; - }, - setHistory: function(histData) { - var hist = this.history = makeHistory(this.history.maxGeneration); - hist.done = histData.done.slice(0); - hist.undone = histData.undone.slice(0); - }, - - markText: function(from, to, options) { - return markText(this, clipPos(this, from), clipPos(this, to), options, "range"); - }, - setBookmark: function(pos, options) { - var realOpts = {replacedWith: options && (options.nodeType == null ? options.widget : options), - insertLeft: options && options.insertLeft}; - pos = clipPos(this, pos); - return markText(this, pos, pos, realOpts, "bookmark"); - }, - findMarksAt: function(pos) { - pos = clipPos(this, pos); - var markers = [], spans = getLine(this, pos.line).markedSpans; - if (spans) for (var i = 0; i < spans.length; ++i) { - var span = spans[i]; - if ((span.from == null || span.from <= pos.ch) && - (span.to == null || span.to >= pos.ch)) - markers.push(span.marker.parent || span.marker); - } - return markers; - }, - getAllMarks: function() { - var markers = []; - this.iter(function(line) { - var sps = line.markedSpans; - if (sps) for (var i = 0; i < sps.length; ++i) - if (sps[i].from != null) markers.push(sps[i].marker); - }); - return markers; - }, - - posFromIndex: function(off) { - var ch, lineNo = this.first; - this.iter(function(line) { - var sz = line.text.length + 1; - if (sz > off) { ch = off; return true; } - off -= sz; - ++lineNo; - }); - return clipPos(this, Pos(lineNo, ch)); - }, - indexFromPos: function (coords) { - coords = clipPos(this, coords); - var index = coords.ch; - if (coords.line < this.first || coords.ch < 0) return 0; - this.iter(this.first, coords.line, function (line) { - index += line.text.length + 1; - }); - return index; - }, - - copy: function(copyHistory) { - var doc = new Doc(getLines(this, this.first, this.first + this.size), this.modeOption, this.first); - doc.scrollTop = this.scrollTop; doc.scrollLeft = this.scrollLeft; - doc.sel = {from: this.sel.from, to: this.sel.to, head: this.sel.head, anchor: this.sel.anchor, - shift: this.sel.shift, extend: false, goalColumn: this.sel.goalColumn}; - if (copyHistory) { - doc.history.undoDepth = this.history.undoDepth; - doc.setHistory(this.getHistory()); - } - return doc; - }, - - linkedDoc: function(options) { - if (!options) options = {}; - var from = this.first, to = this.first + this.size; - if (options.from != null && options.from > from) from = options.from; - if (options.to != null && options.to < to) to = options.to; - var copy = new Doc(getLines(this, from, to), options.mode || this.modeOption, from); - if (options.sharedHist) copy.history = this.history; - (this.linked || (this.linked = [])).push({doc: copy, sharedHist: options.sharedHist}); - copy.linked = [{doc: this, isParent: true, sharedHist: options.sharedHist}]; - return copy; - }, - unlinkDoc: function(other) { - if (other instanceof CodeMirror) other = other.doc; - if (this.linked) for (var i = 0; i < this.linked.length; ++i) { - var link = this.linked[i]; - if (link.doc != other) continue; - this.linked.splice(i, 1); - other.unlinkDoc(this); - break; - } - // If the histories were shared, split them again - if (other.history == this.history) { - var splitIds = [other.id]; - linkedDocs(other, function(doc) {splitIds.push(doc.id);}, true); - other.history = makeHistory(); - other.history.done = copyHistoryArray(this.history.done, splitIds); - other.history.undone = copyHistoryArray(this.history.undone, splitIds); - } - }, - iterLinkedDocs: function(f) {linkedDocs(this, f);}, - - getMode: function() {return this.mode;}, - getEditor: function() {return this.cm;} - }); - - Doc.prototype.eachLine = Doc.prototype.iter; - - // The Doc methods that should be available on CodeMirror instances - var dontDelegate = "iter insert remove copy getEditor".split(" "); - for (var prop in Doc.prototype) if (Doc.prototype.hasOwnProperty(prop) && indexOf(dontDelegate, prop) < 0) - CodeMirror.prototype[prop] = (function(method) { - return function() {return method.apply(this.doc, arguments);}; - })(Doc.prototype[prop]); - - eventMixin(Doc); - - function linkedDocs(doc, f, sharedHistOnly) { - function propagate(doc, skip, sharedHist) { - if (doc.linked) for (var i = 0; i < doc.linked.length; ++i) { - var rel = doc.linked[i]; - if (rel.doc == skip) continue; - var shared = sharedHist && rel.sharedHist; - if (sharedHistOnly && !shared) continue; - f(rel.doc, shared); - propagate(rel.doc, doc, shared); - } - } - propagate(doc, null, true); - } - - function attachDoc(cm, doc) { - if (doc.cm) throw new Error("This document is already in use."); - cm.doc = doc; - doc.cm = cm; - estimateLineHeights(cm); - loadMode(cm); - if (!cm.options.lineWrapping) computeMaxLength(cm); - cm.options.mode = doc.modeOption; - regChange(cm); - } - - // LINE UTILITIES - - function getLine(chunk, n) { - n -= chunk.first; - while (!chunk.lines) { - for (var i = 0;; ++i) { - var child = chunk.children[i], sz = child.chunkSize(); - if (n < sz) { chunk = child; break; } - n -= sz; - } - } - return chunk.lines[n]; - } - - function getBetween(doc, start, end) { - var out = [], n = start.line; - doc.iter(start.line, end.line + 1, function(line) { - var text = line.text; - if (n == end.line) text = text.slice(0, end.ch); - if (n == start.line) text = text.slice(start.ch); - out.push(text); - ++n; - }); - return out; - } - function getLines(doc, from, to) { - var out = []; - doc.iter(from, to, function(line) { out.push(line.text); }); - return out; - } - - function updateLineHeight(line, height) { - var diff = height - line.height; - for (var n = line; n; n = n.parent) n.height += diff; - } - - function lineNo(line) { - if (line.parent == null) return null; - var cur = line.parent, no = indexOf(cur.lines, line); - for (var chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) { - for (var i = 0;; ++i) { - if (chunk.children[i] == cur) break; - no += chunk.children[i].chunkSize(); - } - } - return no + cur.first; - } - - function lineAtHeight(chunk, h) { - var n = chunk.first; - outer: do { - for (var i = 0, e = chunk.children.length; i < e; ++i) { - var child = chunk.children[i], ch = child.height; - if (h < ch) { chunk = child; continue outer; } - h -= ch; - n += child.chunkSize(); - } - return n; - } while (!chunk.lines); - for (var i = 0, e = chunk.lines.length; i < e; ++i) { - var line = chunk.lines[i], lh = line.height; - if (h < lh) break; - h -= lh; - } - return n + i; - } - - function heightAtLine(cm, lineObj) { - lineObj = visualLine(cm.doc, lineObj); - - var h = 0, chunk = lineObj.parent; - for (var i = 0; i < chunk.lines.length; ++i) { - var line = chunk.lines[i]; - if (line == lineObj) break; - else h += line.height; - } - for (var p = chunk.parent; p; chunk = p, p = chunk.parent) { - for (var i = 0; i < p.children.length; ++i) { - var cur = p.children[i]; - if (cur == chunk) break; - else h += cur.height; - } - } - return h; - } - - function getOrder(line) { - var order = line.order; - if (order == null) order = line.order = bidiOrdering(line.text); - return order; - } - - // HISTORY - - function makeHistory(startGen) { - return { - // Arrays of history events. Doing something adds an event to - // done and clears undo. Undoing moves events from done to - // undone, redoing moves them in the other direction. - done: [], undone: [], undoDepth: Infinity, - // Used to track when changes can be merged into a single undo - // event - lastTime: 0, lastOp: null, lastOrigin: null, - // Used by the isClean() method - generation: startGen || 1, maxGeneration: startGen || 1 - }; - } - - function attachLocalSpans(doc, change, from, to) { - var existing = change["spans_" + doc.id], n = 0; - doc.iter(Math.max(doc.first, from), Math.min(doc.first + doc.size, to), function(line) { - if (line.markedSpans) - (existing || (existing = change["spans_" + doc.id] = {}))[n] = line.markedSpans; - ++n; - }); - } - - function historyChangeFromChange(doc, change) { - var from = { line: change.from.line, ch: change.from.ch }; - var histChange = {from: from, to: changeEnd(change), text: getBetween(doc, change.from, change.to)}; - attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1); - linkedDocs(doc, function(doc) {attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);}, true); - return histChange; - } - - function addToHistory(doc, change, selAfter, opId) { - var hist = doc.history; - hist.undone.length = 0; - var time = +new Date, cur = lst(hist.done); - - if (cur && - (hist.lastOp == opId || - hist.lastOrigin == change.origin && change.origin && - ((change.origin.charAt(0) == "+" && doc.cm && hist.lastTime > time - doc.cm.options.historyEventDelay) || - change.origin.charAt(0) == "*"))) { - // Merge this change into the last event - var last = lst(cur.changes); - if (posEq(change.from, change.to) && posEq(change.from, last.to)) { - // Optimized case for simple insertion -- don't want to add - // new changesets for every character typed - last.to = changeEnd(change); - } else { - // Add new sub-event - cur.changes.push(historyChangeFromChange(doc, change)); - } - cur.anchorAfter = selAfter.anchor; cur.headAfter = selAfter.head; - } else { - // Can not be merged, start a new event. - cur = {changes: [historyChangeFromChange(doc, change)], - generation: hist.generation, - anchorBefore: doc.sel.anchor, headBefore: doc.sel.head, - anchorAfter: selAfter.anchor, headAfter: selAfter.head}; - hist.done.push(cur); - hist.generation = ++hist.maxGeneration; - while (hist.done.length > hist.undoDepth) - hist.done.shift(); - } - hist.lastTime = time; - hist.lastOp = opId; - hist.lastOrigin = change.origin; - } - - function removeClearedSpans(spans) { - if (!spans) return null; - for (var i = 0, out; i < spans.length; ++i) { - if (spans[i].marker.explicitlyCleared) { if (!out) out = spans.slice(0, i); } - else if (out) out.push(spans[i]); - } - return !out ? spans : out.length ? out : null; - } - - function getOldSpans(doc, change) { - var found = change["spans_" + doc.id]; - if (!found) return null; - for (var i = 0, nw = []; i < change.text.length; ++i) - nw.push(removeClearedSpans(found[i])); - return nw; - } - - // Used both to provide a JSON-safe object in .getHistory, and, when - // detaching a document, to split the history in two - function copyHistoryArray(events, newGroup) { - for (var i = 0, copy = []; i < events.length; ++i) { - var event = events[i], changes = event.changes, newChanges = []; - copy.push({changes: newChanges, anchorBefore: event.anchorBefore, headBefore: event.headBefore, - anchorAfter: event.anchorAfter, headAfter: event.headAfter}); - for (var j = 0; j < changes.length; ++j) { - var change = changes[j], m; - newChanges.push({from: change.from, to: change.to, text: change.text}); - if (newGroup) for (var prop in change) if (m = prop.match(/^spans_(\d+)$/)) { - if (indexOf(newGroup, Number(m[1])) > -1) { - lst(newChanges)[prop] = change[prop]; - delete change[prop]; - } - } - } - } - return copy; - } - - // Rebasing/resetting history to deal with externally-sourced changes - - function rebaseHistSel(pos, from, to, diff) { - if (to < pos.line) { - pos.line += diff; - } else if (from < pos.line) { - pos.line = from; - pos.ch = 0; - } - } - - // Tries to rebase an array of history events given a change in the - // document. If the change touches the same lines as the event, the - // event, and everything 'behind' it, is discarded. If the change is - // before the event, the event's positions are updated. Uses a - // copy-on-write scheme for the positions, to avoid having to - // reallocate them all on every rebase, but also avoid problems with - // shared position objects being unsafely updated. - function rebaseHistArray(array, from, to, diff) { - for (var i = 0; i < array.length; ++i) { - var sub = array[i], ok = true; - for (var j = 0; j < sub.changes.length; ++j) { - var cur = sub.changes[j]; - if (!sub.copied) { cur.from = copyPos(cur.from); cur.to = copyPos(cur.to); } - if (to < cur.from.line) { - cur.from.line += diff; - cur.to.line += diff; - } else if (from <= cur.to.line) { - ok = false; - break; - } - } - if (!sub.copied) { - sub.anchorBefore = copyPos(sub.anchorBefore); sub.headBefore = copyPos(sub.headBefore); - sub.anchorAfter = copyPos(sub.anchorAfter); sub.readAfter = copyPos(sub.headAfter); - sub.copied = true; - } - if (!ok) { - array.splice(0, i + 1); - i = 0; - } else { - rebaseHistSel(sub.anchorBefore); rebaseHistSel(sub.headBefore); - rebaseHistSel(sub.anchorAfter); rebaseHistSel(sub.headAfter); - } - } - } - - function rebaseHist(hist, change) { - var from = change.from.line, to = change.to.line, diff = change.text.length - (to - from) - 1; - rebaseHistArray(hist.done, from, to, diff); - rebaseHistArray(hist.undone, from, to, diff); - } - - // EVENT OPERATORS - - function stopMethod() {e_stop(this);} - // Ensure an event has a stop method. - function addStop(event) { - if (!event.stop) event.stop = stopMethod; - return event; - } - - function e_preventDefault(e) { - if (e.preventDefault) e.preventDefault(); - else e.returnValue = false; - } - function e_stopPropagation(e) { - if (e.stopPropagation) e.stopPropagation(); - else e.cancelBubble = true; - } - function e_defaultPrevented(e) { - return e.defaultPrevented != null ? e.defaultPrevented : e.returnValue == false; - } - function e_stop(e) {e_preventDefault(e); e_stopPropagation(e);} - CodeMirror.e_stop = e_stop; - CodeMirror.e_preventDefault = e_preventDefault; - CodeMirror.e_stopPropagation = e_stopPropagation; - - function e_target(e) {return e.target || e.srcElement;} - function e_button(e) { - var b = e.which; - if (b == null) { - if (e.button & 1) b = 1; - else if (e.button & 2) b = 3; - else if (e.button & 4) b = 2; - } - if (mac && e.ctrlKey && b == 1) b = 3; - return b; - } - - // EVENT HANDLING - - function on(emitter, type, f) { - if (emitter.addEventListener) - emitter.addEventListener(type, f, false); - else if (emitter.attachEvent) - emitter.attachEvent("on" + type, f); - else { - var map = emitter._handlers || (emitter._handlers = {}); - var arr = map[type] || (map[type] = []); - arr.push(f); - } - } - - function off(emitter, type, f) { - if (emitter.removeEventListener) - emitter.removeEventListener(type, f, false); - else if (emitter.detachEvent) - emitter.detachEvent("on" + type, f); - else { - var arr = emitter._handlers && emitter._handlers[type]; - if (!arr) return; - for (var i = 0; i < arr.length; ++i) - if (arr[i] == f) { arr.splice(i, 1); break; } - } - } - - function signal(emitter, type /*, values...*/) { - var arr = emitter._handlers && emitter._handlers[type]; - if (!arr) return; - var args = Array.prototype.slice.call(arguments, 2); - for (var i = 0; i < arr.length; ++i) arr[i].apply(null, args); - } - - var delayedCallbacks, delayedCallbackDepth = 0; - function signalLater(emitter, type /*, values...*/) { - var arr = emitter._handlers && emitter._handlers[type]; - if (!arr) return; - var args = Array.prototype.slice.call(arguments, 2); - if (!delayedCallbacks) { - ++delayedCallbackDepth; - delayedCallbacks = []; - setTimeout(fireDelayed, 0); - } - function bnd(f) {return function(){f.apply(null, args);};}; - for (var i = 0; i < arr.length; ++i) - delayedCallbacks.push(bnd(arr[i])); - } - - function signalDOMEvent(cm, e, override) { - signal(cm, override || e.type, cm, e); - return e_defaultPrevented(e) || e.codemirrorIgnore; - } - - function fireDelayed() { - --delayedCallbackDepth; - var delayed = delayedCallbacks; - delayedCallbacks = null; - for (var i = 0; i < delayed.length; ++i) delayed[i](); - } - - function hasHandler(emitter, type) { - var arr = emitter._handlers && emitter._handlers[type]; - return arr && arr.length > 0; - } - - CodeMirror.on = on; CodeMirror.off = off; CodeMirror.signal = signal; - - function eventMixin(ctor) { - ctor.prototype.on = function(type, f) {on(this, type, f);}; - ctor.prototype.off = function(type, f) {off(this, type, f);}; - } - - // MISC UTILITIES - - // Number of pixels added to scroller and sizer to hide scrollbar - var scrollerCutOff = 30; - - // Returned or thrown by various protocols to signal 'I'm not - // handling this'. - var Pass = CodeMirror.Pass = {toString: function(){return "CodeMirror.Pass";}}; - - function Delayed() {this.id = null;} - Delayed.prototype = {set: function(ms, f) {clearTimeout(this.id); this.id = setTimeout(f, ms);}}; - - // Counts the column offset in a string, taking tabs into account. - // Used mostly to find indentation. - function countColumn(string, end, tabSize, startIndex, startValue) { - if (end == null) { - end = string.search(/[^\s\u00a0]/); - if (end == -1) end = string.length; - } - for (var i = startIndex || 0, n = startValue || 0; i < end; ++i) { - if (string.charAt(i) == "\t") n += tabSize - (n % tabSize); - else ++n; - } - return n; - } - CodeMirror.countColumn = countColumn; - - var spaceStrs = [""]; - function spaceStr(n) { - while (spaceStrs.length <= n) - spaceStrs.push(lst(spaceStrs) + " "); - return spaceStrs[n]; - } - - function lst(arr) { return arr[arr.length-1]; } - - function selectInput(node) { - if (ios) { // Mobile Safari apparently has a bug where select() is broken. - node.selectionStart = 0; - node.selectionEnd = node.value.length; - } else { - // Suppress mysterious IE10 errors - try { node.select(); } - catch(_e) {} - } - } - - function indexOf(collection, elt) { - if (collection.indexOf) return collection.indexOf(elt); - for (var i = 0, e = collection.length; i < e; ++i) - if (collection[i] == elt) return i; - return -1; - } - - function createObj(base, props) { - function Obj() {} - Obj.prototype = base; - var inst = new Obj(); - if (props) copyObj(props, inst); - return inst; - } - - function copyObj(obj, target) { - if (!target) target = {}; - for (var prop in obj) if (obj.hasOwnProperty(prop)) target[prop] = obj[prop]; - return target; - } - - function emptyArray(size) { - for (var a = [], i = 0; i < size; ++i) a.push(undefined); - return a; - } - - function bind(f) { - var args = Array.prototype.slice.call(arguments, 1); - return function(){return f.apply(null, args);}; - } - - var nonASCIISingleCaseWordChar = /[\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/; - function isWordChar(ch) { - return /\w/.test(ch) || ch > "\x80" && - (ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch)); - } - - function isEmpty(obj) { - for (var n in obj) if (obj.hasOwnProperty(n) && obj[n]) return false; - return true; - } - - var isExtendingChar = /[\u0300-\u036F\u0483-\u0487\u0488-\u0489\u0591-\u05BD\u05BF\u05C1-\u05C2\u05C4-\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7-\u06E8\u06EA-\u06ED\uA66F\uA670-\uA672\uA674-\uA67D\uA69F\udc00-\udfff]/; - - // DOM UTILITIES - - function elt(tag, content, className, style) { - var e = document.createElement(tag); - if (className) e.className = className; - if (style) e.style.cssText = style; - if (typeof content == "string") setTextContent(e, content); - else if (content) for (var i = 0; i < content.length; ++i) e.appendChild(content[i]); - return e; - } - - function removeChildren(e) { - for (var count = e.childNodes.length; count > 0; --count) - e.removeChild(e.firstChild); - return e; - } - - function removeChildrenAndAdd(parent, e) { - return removeChildren(parent).appendChild(e); - } - - function setTextContent(e, str) { - if (ie_lt9) { - e.innerHTML = ""; - e.appendChild(document.createTextNode(str)); - } else e.textContent = str; - } - - function getRect(node) { - return node.getBoundingClientRect(); - } - CodeMirror.replaceGetRect = function(f) { getRect = f; }; - - // FEATURE DETECTION - - // Detect drag-and-drop - var dragAndDrop = function() { - // There is *some* kind of drag-and-drop support in IE6-8, but I - // couldn't get it to work yet. - if (ie_lt9) return false; - var div = elt('div'); - return "draggable" in div || "dragDrop" in div; - }(); - - // For a reason I have yet to figure out, some browsers disallow - // word wrapping between certain characters *only* if a new inline - // element is started between them. This makes it hard to reliably - // measure the position of things, since that requires inserting an - // extra span. This terribly fragile set of tests matches the - // character combinations that suffer from this phenomenon on the - // various browsers. - function spanAffectsWrapping() { return false; } - if (gecko) // Only for "$'" - spanAffectsWrapping = function(str, i) { - return str.charCodeAt(i - 1) == 36 && str.charCodeAt(i) == 39; - }; - else if (safari && !/Version\/([6-9]|\d\d)\b/.test(navigator.userAgent)) - spanAffectsWrapping = function(str, i) { - return /\-[^ \-?]|\?[^ !\'\"\),.\-\/:;\?\]\}]/.test(str.slice(i - 1, i + 1)); - }; - else if (webkit && /Chrome\/(?:29|[3-9]\d|\d\d\d)\./.test(navigator.userAgent)) - spanAffectsWrapping = function(str, i) { - var code = str.charCodeAt(i - 1); - return code >= 8208 && code <= 8212; - }; - else if (webkit) - spanAffectsWrapping = function(str, i) { - if (i > 1 && str.charCodeAt(i - 1) == 45) { - if (/\w/.test(str.charAt(i - 2)) && /[^\-?\.]/.test(str.charAt(i))) return true; - if (i > 2 && /[\d\.,]/.test(str.charAt(i - 2)) && /[\d\.,]/.test(str.charAt(i))) return false; - } - return /[~!#%&*)=+}\]\\|\"\.>,:;][({[<]|-[^\-?\.\u2010-\u201f\u2026]|\?[\w~`@#$%\^&*(_=+{[|><]|…[\w~`@#$%\^&*(_=+{[><]/.test(str.slice(i - 1, i + 1)); - }; - - var knownScrollbarWidth; - function scrollbarWidth(measure) { - if (knownScrollbarWidth != null) return knownScrollbarWidth; - var test = elt("div", null, null, "width: 50px; height: 50px; overflow-x: scroll"); - removeChildrenAndAdd(measure, test); - if (test.offsetWidth) - knownScrollbarWidth = test.offsetHeight - test.clientHeight; - return knownScrollbarWidth || 0; - } - - var zwspSupported; - function zeroWidthElement(measure) { - if (zwspSupported == null) { - var test = elt("span", "\u200b"); - removeChildrenAndAdd(measure, elt("span", [test, document.createTextNode("x")])); - if (measure.firstChild.offsetHeight != 0) - zwspSupported = test.offsetWidth <= 1 && test.offsetHeight > 2 && !ie_lt8; - } - if (zwspSupported) return elt("span", "\u200b"); - else return elt("span", "\u00a0", null, "display: inline-block; width: 1px; margin-right: -1px"); - } - - // See if "".split is the broken IE version, if so, provide an - // alternative way to split lines. - var splitLines = "\n\nb".split(/\n/).length != 3 ? function(string) { - var pos = 0, result = [], l = string.length; - while (pos <= l) { - var nl = string.indexOf("\n", pos); - if (nl == -1) nl = string.length; - var line = string.slice(pos, string.charAt(nl - 1) == "\r" ? nl - 1 : nl); - var rt = line.indexOf("\r"); - if (rt != -1) { - result.push(line.slice(0, rt)); - pos += rt + 1; - } else { - result.push(line); - pos = nl + 1; - } - } - return result; - } : function(string){return string.split(/\r\n?|\n/);}; - CodeMirror.splitLines = splitLines; - - var hasSelection = window.getSelection ? function(te) { - try { return te.selectionStart != te.selectionEnd; } - catch(e) { return false; } - } : function(te) { - try {var range = te.ownerDocument.selection.createRange();} - catch(e) {} - if (!range || range.parentElement() != te) return false; - return range.compareEndPoints("StartToEnd", range) != 0; - }; - - var hasCopyEvent = (function() { - var e = elt("div"); - if ("oncopy" in e) return true; - e.setAttribute("oncopy", "return;"); - return typeof e.oncopy == 'function'; - })(); - - // KEY NAMING - - var keyNames = {3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt", - 19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End", - 36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert", - 46: "Delete", 59: ";", 91: "Mod", 92: "Mod", 93: "Mod", 109: "-", 107: "=", 127: "Delete", - 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\", - 221: "]", 222: "'", 63276: "PageUp", 63277: "PageDown", 63275: "End", 63273: "Home", - 63234: "Left", 63232: "Up", 63235: "Right", 63233: "Down", 63302: "Insert", 63272: "Delete"}; - CodeMirror.keyNames = keyNames; - (function() { - // Number keys - for (var i = 0; i < 10; i++) keyNames[i + 48] = String(i); - // Alphabetic keys - for (var i = 65; i <= 90; i++) keyNames[i] = String.fromCharCode(i); - // Function keys - for (var i = 1; i <= 12; i++) keyNames[i + 111] = keyNames[i + 63235] = "F" + i; - })(); - - // BIDI HELPERS - - function iterateBidiSections(order, from, to, f) { - if (!order) return f(from, to, "ltr"); - var found = false; - for (var i = 0; i < order.length; ++i) { - var part = order[i]; - if (part.from < to && part.to > from || from == to && part.to == from) { - f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? "rtl" : "ltr"); - found = true; - } - } - if (!found) f(from, to, "ltr"); - } - - function bidiLeft(part) { return part.level % 2 ? part.to : part.from; } - function bidiRight(part) { return part.level % 2 ? part.from : part.to; } - - function lineLeft(line) { var order = getOrder(line); return order ? bidiLeft(order[0]) : 0; } - function lineRight(line) { - var order = getOrder(line); - if (!order) return line.text.length; - return bidiRight(lst(order)); - } - - function lineStart(cm, lineN) { - var line = getLine(cm.doc, lineN); - var visual = visualLine(cm.doc, line); - if (visual != line) lineN = lineNo(visual); - var order = getOrder(visual); - var ch = !order ? 0 : order[0].level % 2 ? lineRight(visual) : lineLeft(visual); - return Pos(lineN, ch); - } - function lineEnd(cm, lineN) { - var merged, line; - while (merged = collapsedSpanAtEnd(line = getLine(cm.doc, lineN))) - lineN = merged.find().to.line; - var order = getOrder(line); - var ch = !order ? line.text.length : order[0].level % 2 ? lineLeft(line) : lineRight(line); - return Pos(lineN, ch); - } - - function compareBidiLevel(order, a, b) { - var linedir = order[0].level; - if (a == linedir) return true; - if (b == linedir) return false; - return a < b; - } - var bidiOther; - function getBidiPartAt(order, pos) { - for (var i = 0, found; i < order.length; ++i) { - var cur = order[i]; - if (cur.from < pos && cur.to > pos) { bidiOther = null; return i; } - if (cur.from == pos || cur.to == pos) { - if (found == null) { - found = i; - } else if (compareBidiLevel(order, cur.level, order[found].level)) { - bidiOther = found; - return i; - } else { - bidiOther = i; - return found; - } - } - } - bidiOther = null; - return found; - } - - function moveInLine(line, pos, dir, byUnit) { - if (!byUnit) return pos + dir; - do pos += dir; - while (pos > 0 && isExtendingChar.test(line.text.charAt(pos))); - return pos; - } - - // This is somewhat involved. It is needed in order to move - // 'visually' through bi-directional text -- i.e., pressing left - // should make the cursor go left, even when in RTL text. The - // tricky part is the 'jumps', where RTL and LTR text touch each - // other. This often requires the cursor offset to move more than - // one unit, in order to visually move one unit. - function moveVisually(line, start, dir, byUnit) { - var bidi = getOrder(line); - if (!bidi) return moveLogically(line, start, dir, byUnit); - var pos = getBidiPartAt(bidi, start), part = bidi[pos]; - var target = moveInLine(line, start, part.level % 2 ? -dir : dir, byUnit); - - for (;;) { - if (target > part.from && target < part.to) return target; - if (target == part.from || target == part.to) { - if (getBidiPartAt(bidi, target) == pos) return target; - part = bidi[pos += dir]; - return (dir > 0) == part.level % 2 ? part.to : part.from; - } else { - part = bidi[pos += dir]; - if (!part) return null; - if ((dir > 0) == part.level % 2) - target = moveInLine(line, part.to, -1, byUnit); - else - target = moveInLine(line, part.from, 1, byUnit); - } - } - } - - function moveLogically(line, start, dir, byUnit) { - var target = start + dir; - if (byUnit) while (target > 0 && isExtendingChar.test(line.text.charAt(target))) target += dir; - return target < 0 || target > line.text.length ? null : target; - } - - // Bidirectional ordering algorithm - // See http://unicode.org/reports/tr9/tr9-13.html for the algorithm - // that this (partially) implements. - - // One-char codes used for character types: - // L (L): Left-to-Right - // R (R): Right-to-Left - // r (AL): Right-to-Left Arabic - // 1 (EN): European Number - // + (ES): European Number Separator - // % (ET): European Number Terminator - // n (AN): Arabic Number - // , (CS): Common Number Separator - // m (NSM): Non-Spacing Mark - // b (BN): Boundary Neutral - // s (B): Paragraph Separator - // t (S): Segment Separator - // w (WS): Whitespace - // N (ON): Other Neutrals - - // Returns null if characters are ordered as they appear - // (left-to-right), or an array of sections ({from, to, level} - // objects) in the order in which they occur visually. - var bidiOrdering = (function() { - // Character types for codepoints 0 to 0xff - var lowTypes = "bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLL"; - // Character types for codepoints 0x600 to 0x6ff - var arabicTypes = "rrrrrrrrrrrr,rNNmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmrrrrrrrnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmNmmmmrrrrrrrrrrrrrrrrrr"; - function charType(code) { - if (code <= 0xff) return lowTypes.charAt(code); - else if (0x590 <= code && code <= 0x5f4) return "R"; - else if (0x600 <= code && code <= 0x6ff) return arabicTypes.charAt(code - 0x600); - else if (0x700 <= code && code <= 0x8ac) return "r"; - else return "L"; - } - - var bidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/; - var isNeutral = /[stwN]/, isStrong = /[LRr]/, countsAsLeft = /[Lb1n]/, countsAsNum = /[1n]/; - // Browsers seem to always treat the boundaries of block elements as being L. - var outerType = "L"; - - return function(str) { - if (!bidiRE.test(str)) return false; - var len = str.length, types = []; - for (var i = 0, type; i < len; ++i) - types.push(type = charType(str.charCodeAt(i))); - - // W1. Examine each non-spacing mark (NSM) in the level run, and - // change the type of the NSM to the type of the previous - // character. If the NSM is at the start of the level run, it will - // get the type of sor. - for (var i = 0, prev = outerType; i < len; ++i) { - var type = types[i]; - if (type == "m") types[i] = prev; - else prev = type; - } - - // W2. Search backwards from each instance of a European number - // until the first strong type (R, L, AL, or sor) is found. If an - // AL is found, change the type of the European number to Arabic - // number. - // W3. Change all ALs to R. - for (var i = 0, cur = outerType; i < len; ++i) { - var type = types[i]; - if (type == "1" && cur == "r") types[i] = "n"; - else if (isStrong.test(type)) { cur = type; if (type == "r") types[i] = "R"; } - } - - // W4. A single European separator between two European numbers - // changes to a European number. A single common separator between - // two numbers of the same type changes to that type. - for (var i = 1, prev = types[0]; i < len - 1; ++i) { - var type = types[i]; - if (type == "+" && prev == "1" && types[i+1] == "1") types[i] = "1"; - else if (type == "," && prev == types[i+1] && - (prev == "1" || prev == "n")) types[i] = prev; - prev = type; - } - - // W5. A sequence of European terminators adjacent to European - // numbers changes to all European numbers. - // W6. Otherwise, separators and terminators change to Other - // Neutral. - for (var i = 0; i < len; ++i) { - var type = types[i]; - if (type == ",") types[i] = "N"; - else if (type == "%") { - for (var end = i + 1; end < len && types[end] == "%"; ++end) {} - var replace = (i && types[i-1] == "!") || (end < len - 1 && types[end] == "1") ? "1" : "N"; - for (var j = i; j < end; ++j) types[j] = replace; - i = end - 1; - } - } - - // W7. Search backwards from each instance of a European number - // until the first strong type (R, L, or sor) is found. If an L is - // found, then change the type of the European number to L. - for (var i = 0, cur = outerType; i < len; ++i) { - var type = types[i]; - if (cur == "L" && type == "1") types[i] = "L"; - else if (isStrong.test(type)) cur = type; - } - - // N1. A sequence of neutrals takes the direction of the - // surrounding strong text if the text on both sides has the same - // direction. European and Arabic numbers act as if they were R in - // terms of their influence on neutrals. Start-of-level-run (sor) - // and end-of-level-run (eor) are used at level run boundaries. - // N2. Any remaining neutrals take the embedding direction. - for (var i = 0; i < len; ++i) { - if (isNeutral.test(types[i])) { - for (var end = i + 1; end < len && isNeutral.test(types[end]); ++end) {} - var before = (i ? types[i-1] : outerType) == "L"; - var after = (end < len - 1 ? types[end] : outerType) == "L"; - var replace = before || after ? "L" : "R"; - for (var j = i; j < end; ++j) types[j] = replace; - i = end - 1; - } - } - - // Here we depart from the documented algorithm, in order to avoid - // building up an actual levels array. Since there are only three - // levels (0, 1, 2) in an implementation that doesn't take - // explicit embedding into account, we can build up the order on - // the fly, without following the level-based algorithm. - var order = [], m; - for (var i = 0; i < len;) { - if (countsAsLeft.test(types[i])) { - var start = i; - for (++i; i < len && countsAsLeft.test(types[i]); ++i) {} - order.push({from: start, to: i, level: 0}); - } else { - var pos = i, at = order.length; - for (++i; i < len && types[i] != "L"; ++i) {} - for (var j = pos; j < i;) { - if (countsAsNum.test(types[j])) { - if (pos < j) order.splice(at, 0, {from: pos, to: j, level: 1}); - var nstart = j; - for (++j; j < i && countsAsNum.test(types[j]); ++j) {} - order.splice(at, 0, {from: nstart, to: j, level: 2}); - pos = j; - } else ++j; - } - if (pos < i) order.splice(at, 0, {from: pos, to: i, level: 1}); - } - } - if (order[0].level == 1 && (m = str.match(/^\s+/))) { - order[0].from = m[0].length; - order.unshift({from: 0, to: m[0].length, level: 0}); - } - if (lst(order).level == 1 && (m = str.match(/\s+$/))) { - lst(order).to -= m[0].length; - order.push({from: len - m[0].length, to: len, level: 0}); - } - if (order[0].level != lst(order).level) - order.push({from: len, to: len, level: order[0].level}); - - return order; - }; - })(); - - // THE END - - CodeMirror.version = "3.17.0"; - - return CodeMirror; -})(); +// CodeMirror version 3.17 +// +// CodeMirror is the only global var we claim +window.CodeMirror = (function() { + "use strict"; + + // BROWSER SNIFFING + + // Crude, but necessary to handle a number of hard-to-feature-detect + // bugs and behavior differences. + var gecko = /gecko\/\d/i.test(navigator.userAgent); + var ie = /MSIE \d/.test(navigator.userAgent); + var ie_lt8 = ie && (document.documentMode == null || document.documentMode < 8); + var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9); + var webkit = /WebKit\//.test(navigator.userAgent); + var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(navigator.userAgent); + var chrome = /Chrome\//.test(navigator.userAgent); + var opera = /Opera\//.test(navigator.userAgent); + var safari = /Apple Computer/.test(navigator.vendor); + var khtml = /KHTML\//.test(navigator.userAgent); + var mac_geLion = /Mac OS X 1\d\D([7-9]|\d\d)\D/.test(navigator.userAgent); + var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(navigator.userAgent); + var phantom = /PhantomJS/.test(navigator.userAgent); + + var ios = /AppleWebKit/.test(navigator.userAgent) && /Mobile\/\w+/.test(navigator.userAgent); + // This is woefully incomplete. Suggestions for alternative methods welcome. + var mobile = ios || /Android|webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(navigator.userAgent); + var mac = ios || /Mac/.test(navigator.platform); + var windows = /win/i.test(navigator.platform); + + var opera_version = opera && navigator.userAgent.match(/Version\/(\d*\.\d*)/); + if (opera_version) opera_version = Number(opera_version[1]); + if (opera_version && opera_version >= 15) { opera = false; webkit = true; } + // Some browsers use the wrong event properties to signal cmd/ctrl on OS X + var flipCtrlCmd = mac && (qtwebkit || opera && (opera_version == null || opera_version < 12.11)); + var captureMiddleClick = gecko || (ie && !ie_lt9); + + // Optimize some code when these features are not used + var sawReadOnlySpans = false, sawCollapsedSpans = false; + + // CONSTRUCTOR + + function CodeMirror(place, options) { + if (!(this instanceof CodeMirror)) return new CodeMirror(place, options); + + this.options = options = options || {}; + // Determine effective options based on given values and defaults. + for (var opt in defaults) if (!options.hasOwnProperty(opt) && defaults.hasOwnProperty(opt)) + options[opt] = defaults[opt]; + setGuttersForLineNumbers(options); + + var docStart = typeof options.value == "string" ? 0 : options.value.first; + var display = this.display = makeDisplay(place, docStart); + display.wrapper.CodeMirror = this; + updateGutters(this); + if (options.autofocus && !mobile) focusInput(this); + + this.state = {keyMaps: [], + overlays: [], + modeGen: 0, + overwrite: false, focused: false, + suppressEdits: false, pasteIncoming: false, + draggingText: false, + highlight: new Delayed()}; + + themeChanged(this); + if (options.lineWrapping) + this.display.wrapper.className += " CodeMirror-wrap"; + + var doc = options.value; + if (typeof doc == "string") doc = new Doc(options.value, options.mode); + operation(this, attachDoc)(this, doc); + + // Override magic textarea content restore that IE sometimes does + // on our hidden textarea on reload + if (ie) setTimeout(bind(resetInput, this, true), 20); + + registerEventHandlers(this); + // IE throws unspecified error in certain cases, when + // trying to access activeElement before onload + var hasFocus; try { hasFocus = (document.activeElement == display.input); } catch(e) { } + if (hasFocus || (options.autofocus && !mobile)) setTimeout(bind(onFocus, this), 20); + else onBlur(this); + + operation(this, function() { + for (var opt in optionHandlers) + if (optionHandlers.propertyIsEnumerable(opt)) + optionHandlers[opt](this, options[opt], Init); + for (var i = 0; i < initHooks.length; ++i) initHooks[i](this); + })(); + } + + // DISPLAY CONSTRUCTOR + + function makeDisplay(place, docStart) { + var d = {}; + + var input = d.input = elt("textarea", null, null, "position: absolute; padding: 0; width: 1px; height: 1em; outline: none; font-size: 4px;"); + if (webkit) input.style.width = "1000px"; + else input.setAttribute("wrap", "off"); + // if border: 0; -- iOS fails to open keyboard (issue #1287) + if (ios) input.style.border = "1px solid black"; + input.setAttribute("autocorrect", "off"); input.setAttribute("autocapitalize", "off"); input.setAttribute("spellcheck", "false"); + + // Wraps and hides input textarea + d.inputDiv = elt("div", [input], null, "overflow: hidden; position: relative; width: 3px; height: 0px;"); + // The actual fake scrollbars. + d.scrollbarH = elt("div", [elt("div", null, null, "height: 1px")], "CodeMirror-hscrollbar"); + d.scrollbarV = elt("div", [elt("div", null, null, "width: 1px")], "CodeMirror-vscrollbar"); + d.scrollbarFiller = elt("div", null, "CodeMirror-scrollbar-filler"); + d.gutterFiller = elt("div", null, "CodeMirror-gutter-filler"); + // DIVs containing the selection and the actual code + d.lineDiv = elt("div", null, "CodeMirror-code"); + d.selectionDiv = elt("div", null, null, "position: relative; z-index: 1"); + // Blinky cursor, and element used to ensure cursor fits at the end of a line + d.cursor = elt("div", "\u00a0", "CodeMirror-cursor"); + // Secondary cursor, shown when on a 'jump' in bi-directional text + d.otherCursor = elt("div", "\u00a0", "CodeMirror-cursor CodeMirror-secondarycursor"); + // Used to measure text size + d.measure = elt("div", null, "CodeMirror-measure"); + // Wraps everything that needs to exist inside the vertically-padded coordinate system + d.lineSpace = elt("div", [d.measure, d.selectionDiv, d.lineDiv, d.cursor, d.otherCursor], + null, "position: relative; outline: none"); + // Moved around its parent to cover visible view + d.mover = elt("div", [elt("div", [d.lineSpace], "CodeMirror-lines")], null, "position: relative"); + // Set to the height of the text, causes scrolling + d.sizer = elt("div", [d.mover], "CodeMirror-sizer"); + // D is needed because behavior of elts with overflow: auto and padding is inconsistent across browsers + d.heightForcer = elt("div", null, null, "position: absolute; height: " + scrollerCutOff + "px; width: 1px;"); + // Will contain the gutters, if any + d.gutters = elt("div", null, "CodeMirror-gutters"); + d.lineGutter = null; + // Provides scrolling + d.scroller = elt("div", [d.sizer, d.heightForcer, d.gutters], "CodeMirror-scroll"); + d.scroller.setAttribute("tabIndex", "-1"); + // The element in which the editor lives. + d.wrapper = elt("div", [d.inputDiv, d.scrollbarH, d.scrollbarV, + d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror"); + // Work around IE7 z-index bug + if (ie_lt8) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0; } + if (place.appendChild) place.appendChild(d.wrapper); else place(d.wrapper); + + // Needed to hide big blue blinking cursor on Mobile Safari + if (ios) input.style.width = "0px"; + if (!webkit) d.scroller.draggable = true; + // Needed to handle Tab key in KHTML + if (khtml) { d.inputDiv.style.height = "1px"; d.inputDiv.style.position = "absolute"; } + // Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8). + else if (ie_lt8) d.scrollbarH.style.minWidth = d.scrollbarV.style.minWidth = "18px"; + + // Current visible range (may be bigger than the view window). + d.viewOffset = d.lastSizeC = 0; + d.showingFrom = d.showingTo = docStart; + + // Used to only resize the line number gutter when necessary (when + // the amount of lines crosses a boundary that makes its width change) + d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null; + // See readInput and resetInput + d.prevInput = ""; + // Set to true when a non-horizontal-scrolling widget is added. As + // an optimization, widget aligning is skipped when d is false. + d.alignWidgets = false; + // Flag that indicates whether we currently expect input to appear + // (after some event like 'keypress' or 'input') and are polling + // intensively. + d.pollingFast = false; + // Self-resetting timeout for the poller + d.poll = new Delayed(); + + d.cachedCharWidth = d.cachedTextHeight = null; + d.measureLineCache = []; + d.measureLineCachePos = 0; + + // Tracks when resetInput has punted to just putting a short + // string instead of the (large) selection. + d.inaccurateSelection = false; + + // Tracks the maximum line length so that the horizontal scrollbar + // can be kept static when scrolling. + d.maxLine = null; + d.maxLineLength = 0; + d.maxLineChanged = false; + + // Used for measuring wheel scrolling granularity + d.wheelDX = d.wheelDY = d.wheelStartX = d.wheelStartY = null; + + return d; + } + + // STATE UPDATES + + // Used to get the editor into a consistent state again when options change. + + function loadMode(cm) { + cm.doc.mode = CodeMirror.getMode(cm.options, cm.doc.modeOption); + cm.doc.iter(function(line) { + if (line.stateAfter) line.stateAfter = null; + if (line.styles) line.styles = null; + }); + cm.doc.frontier = cm.doc.first; + startWorker(cm, 100); + cm.state.modeGen++; + if (cm.curOp) regChange(cm); + } + + function wrappingChanged(cm) { + if (cm.options.lineWrapping) { + cm.display.wrapper.className += " CodeMirror-wrap"; + cm.display.sizer.style.minWidth = ""; + } else { + cm.display.wrapper.className = cm.display.wrapper.className.replace(" CodeMirror-wrap", ""); + computeMaxLength(cm); + } + estimateLineHeights(cm); + regChange(cm); + clearCaches(cm); + setTimeout(function(){updateScrollbars(cm);}, 100); + } + + function estimateHeight(cm) { + var th = textHeight(cm.display), wrapping = cm.options.lineWrapping; + var perLine = wrapping && Math.max(5, cm.display.scroller.clientWidth / charWidth(cm.display) - 3); + return function(line) { + if (lineIsHidden(cm.doc, line)) + return 0; + else if (wrapping) + return (Math.ceil(line.text.length / perLine) || 1) * th; + else + return th; + }; + } + + function estimateLineHeights(cm) { + var doc = cm.doc, est = estimateHeight(cm); + doc.iter(function(line) { + var estHeight = est(line); + if (estHeight != line.height) updateLineHeight(line, estHeight); + }); + } + + function keyMapChanged(cm) { + var map = keyMap[cm.options.keyMap], style = map.style; + cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-keymap-\S+/g, "") + + (style ? " cm-keymap-" + style : ""); + cm.state.disableInput = map.disableInput; + } + + function themeChanged(cm) { + cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-s-\S+/g, "") + + cm.options.theme.replace(/(^|\s)\s*/g, " cm-s-"); + clearCaches(cm); + } + + function guttersChanged(cm) { + updateGutters(cm); + regChange(cm); + setTimeout(function(){alignHorizontally(cm);}, 20); + } + + function updateGutters(cm) { + var gutters = cm.display.gutters, specs = cm.options.gutters; + removeChildren(gutters); + for (var i = 0; i < specs.length; ++i) { + var gutterClass = specs[i]; + var gElt = gutters.appendChild(elt("div", null, "CodeMirror-gutter " + gutterClass)); + if (gutterClass == "CodeMirror-linenumbers") { + cm.display.lineGutter = gElt; + gElt.style.width = (cm.display.lineNumWidth || 1) + "px"; + } + } + gutters.style.display = i ? "" : "none"; + } + + function lineLength(doc, line) { + if (line.height == 0) return 0; + var len = line.text.length, merged, cur = line; + while (merged = collapsedSpanAtStart(cur)) { + var found = merged.find(); + cur = getLine(doc, found.from.line); + len += found.from.ch - found.to.ch; + } + cur = line; + while (merged = collapsedSpanAtEnd(cur)) { + var found = merged.find(); + len -= cur.text.length - found.from.ch; + cur = getLine(doc, found.to.line); + len += cur.text.length - found.to.ch; + } + return len; + } + + function computeMaxLength(cm) { + var d = cm.display, doc = cm.doc; + d.maxLine = getLine(doc, doc.first); + d.maxLineLength = lineLength(doc, d.maxLine); + d.maxLineChanged = true; + doc.iter(function(line) { + var len = lineLength(doc, line); + if (len > d.maxLineLength) { + d.maxLineLength = len; + d.maxLine = line; + } + }); + } + + // Make sure the gutters options contains the element + // "CodeMirror-linenumbers" when the lineNumbers option is true. + function setGuttersForLineNumbers(options) { + var found = indexOf(options.gutters, "CodeMirror-linenumbers"); + if (found == -1 && options.lineNumbers) { + options.gutters = options.gutters.concat(["CodeMirror-linenumbers"]); + } else if (found > -1 && !options.lineNumbers) { + options.gutters = options.gutters.slice(0); + options.gutters.splice(i, 1); + } + } + + // SCROLLBARS + + // Re-synchronize the fake scrollbars with the actual size of the + // content. Optionally force a scrollTop. + function updateScrollbars(cm) { + var d = cm.display, docHeight = cm.doc.height; + var totalHeight = docHeight + paddingVert(d); + d.sizer.style.minHeight = d.heightForcer.style.top = totalHeight + "px"; + d.gutters.style.height = Math.max(totalHeight, d.scroller.clientHeight - scrollerCutOff) + "px"; + var scrollHeight = Math.max(totalHeight, d.scroller.scrollHeight); + var needsH = d.scroller.scrollWidth > (d.scroller.clientWidth + 1); + var needsV = scrollHeight > (d.scroller.clientHeight + 1); + if (needsV) { + d.scrollbarV.style.display = "block"; + d.scrollbarV.style.bottom = needsH ? scrollbarWidth(d.measure) + "px" : "0"; + d.scrollbarV.firstChild.style.height = + (scrollHeight - d.scroller.clientHeight + d.scrollbarV.clientHeight) + "px"; + } else { + d.scrollbarV.style.display = ""; + d.scrollbarV.firstChild.style.height = "0"; + } + if (needsH) { + d.scrollbarH.style.display = "block"; + d.scrollbarH.style.right = needsV ? scrollbarWidth(d.measure) + "px" : "0"; + d.scrollbarH.firstChild.style.width = + (d.scroller.scrollWidth - d.scroller.clientWidth + d.scrollbarH.clientWidth) + "px"; + } else { + d.scrollbarH.style.display = ""; + d.scrollbarH.firstChild.style.width = "0"; + } + if (needsH && needsV) { + d.scrollbarFiller.style.display = "block"; + d.scrollbarFiller.style.height = d.scrollbarFiller.style.width = scrollbarWidth(d.measure) + "px"; + } else d.scrollbarFiller.style.display = ""; + if (needsH && cm.options.coverGutterNextToScrollbar && cm.options.fixedGutter) { + d.gutterFiller.style.display = "block"; + d.gutterFiller.style.height = scrollbarWidth(d.measure) + "px"; + d.gutterFiller.style.width = d.gutters.offsetWidth + "px"; + } else d.gutterFiller.style.display = ""; + + if (mac_geLion && scrollbarWidth(d.measure) === 0) + d.scrollbarV.style.minWidth = d.scrollbarH.style.minHeight = mac_geMountainLion ? "18px" : "12px"; + } + + function visibleLines(display, doc, viewPort) { + var top = display.scroller.scrollTop, height = display.wrapper.clientHeight; + if (typeof viewPort == "number") top = viewPort; + else if (viewPort) {top = viewPort.top; height = viewPort.bottom - viewPort.top;} + top = Math.floor(top - paddingTop(display)); + var bottom = Math.ceil(top + height); + return {from: lineAtHeight(doc, top), to: lineAtHeight(doc, bottom)}; + } + + // LINE NUMBERS + + function alignHorizontally(cm) { + var display = cm.display; + if (!display.alignWidgets && (!display.gutters.firstChild || !cm.options.fixedGutter)) return; + var comp = compensateForHScroll(display) - display.scroller.scrollLeft + cm.doc.scrollLeft; + var gutterW = display.gutters.offsetWidth, l = comp + "px"; + for (var n = display.lineDiv.firstChild; n; n = n.nextSibling) if (n.alignable) { + for (var i = 0, a = n.alignable; i < a.length; ++i) a[i].style.left = l; + } + if (cm.options.fixedGutter) + display.gutters.style.left = (comp + gutterW) + "px"; + } + + function maybeUpdateLineNumberWidth(cm) { + if (!cm.options.lineNumbers) return false; + var doc = cm.doc, last = lineNumberFor(cm.options, doc.first + doc.size - 1), display = cm.display; + if (last.length != display.lineNumChars) { + var test = display.measure.appendChild(elt("div", [elt("div", last)], + "CodeMirror-linenumber CodeMirror-gutter-elt")); + var innerW = test.firstChild.offsetWidth, padding = test.offsetWidth - innerW; + display.lineGutter.style.width = ""; + display.lineNumInnerWidth = Math.max(innerW, display.lineGutter.offsetWidth - padding); + display.lineNumWidth = display.lineNumInnerWidth + padding; + display.lineNumChars = display.lineNumInnerWidth ? last.length : -1; + display.lineGutter.style.width = display.lineNumWidth + "px"; + return true; + } + return false; + } + + function lineNumberFor(options, i) { + return String(options.lineNumberFormatter(i + options.firstLineNumber)); + } + function compensateForHScroll(display) { + return getRect(display.scroller).left - getRect(display.sizer).left; + } + + // DISPLAY DRAWING + + function updateDisplay(cm, changes, viewPort, forced) { + var oldFrom = cm.display.showingFrom, oldTo = cm.display.showingTo, updated; + var visible = visibleLines(cm.display, cm.doc, viewPort); + for (var first = true;; first = false) { + var oldWidth = cm.display.scroller.clientWidth; + if (!updateDisplayInner(cm, changes, visible, forced)) break; + updated = true; + changes = []; + updateSelection(cm); + updateScrollbars(cm); + if (first && cm.options.lineWrapping && oldWidth != cm.display.scroller.clientWidth) { + forced = true; + continue; + } + forced = false; + + // Clip forced viewport to actual scrollable area + if (viewPort) + viewPort = Math.min(cm.display.scroller.scrollHeight - cm.display.scroller.clientHeight, + typeof viewPort == "number" ? viewPort : viewPort.top); + visible = visibleLines(cm.display, cm.doc, viewPort); + if (visible.from >= cm.display.showingFrom && visible.to <= cm.display.showingTo) + break; + } + + if (updated) { + signalLater(cm, "update", cm); + if (cm.display.showingFrom != oldFrom || cm.display.showingTo != oldTo) + signalLater(cm, "viewportChange", cm, cm.display.showingFrom, cm.display.showingTo); + } + return updated; + } + + // Uses a set of changes plus the current scroll position to + // determine which DOM updates have to be made, and makes the + // updates. + function updateDisplayInner(cm, changes, visible, forced) { + var display = cm.display, doc = cm.doc; + if (!display.wrapper.clientWidth) { + display.showingFrom = display.showingTo = doc.first; + display.viewOffset = 0; + return; + } + + // Bail out if the visible area is already rendered and nothing changed. + if (!forced && changes.length == 0 && + visible.from > display.showingFrom && visible.to < display.showingTo) + return; + + if (maybeUpdateLineNumberWidth(cm)) + changes = [{from: doc.first, to: doc.first + doc.size}]; + var gutterW = display.sizer.style.marginLeft = display.gutters.offsetWidth + "px"; + display.scrollbarH.style.left = cm.options.fixedGutter ? gutterW : "0"; + + // Used to determine which lines need their line numbers updated + var positionsChangedFrom = Infinity; + if (cm.options.lineNumbers) + for (var i = 0; i < changes.length; ++i) + if (changes[i].diff && changes[i].from < positionsChangedFrom) { positionsChangedFrom = changes[i].from; } + + var end = doc.first + doc.size; + var from = Math.max(visible.from - cm.options.viewportMargin, doc.first); + var to = Math.min(end, visible.to + cm.options.viewportMargin); + if (display.showingFrom < from && from - display.showingFrom < 20) from = Math.max(doc.first, display.showingFrom); + if (display.showingTo > to && display.showingTo - to < 20) to = Math.min(end, display.showingTo); + if (sawCollapsedSpans) { + from = lineNo(visualLine(doc, getLine(doc, from))); + while (to < end && lineIsHidden(doc, getLine(doc, to))) ++to; + } + + // Create a range of theoretically intact lines, and punch holes + // in that using the change info. + var intact = [{from: Math.max(display.showingFrom, doc.first), + to: Math.min(display.showingTo, end)}]; + if (intact[0].from >= intact[0].to) intact = []; + else intact = computeIntact(intact, changes); + // When merged lines are present, we might have to reduce the + // intact ranges because changes in continued fragments of the + // intact lines do require the lines to be redrawn. + if (sawCollapsedSpans) + for (var i = 0; i < intact.length; ++i) { + var range = intact[i], merged; + while (merged = collapsedSpanAtEnd(getLine(doc, range.to - 1))) { + var newTo = merged.find().from.line; + if (newTo > range.from) range.to = newTo; + else { intact.splice(i--, 1); break; } + } + } + + // Clip off the parts that won't be visible + var intactLines = 0; + for (var i = 0; i < intact.length; ++i) { + var range = intact[i]; + if (range.from < from) range.from = from; + if (range.to > to) range.to = to; + if (range.from >= range.to) intact.splice(i--, 1); + else intactLines += range.to - range.from; + } + if (!forced && intactLines == to - from && from == display.showingFrom && to == display.showingTo) { + updateViewOffset(cm); + return; + } + intact.sort(function(a, b) {return a.from - b.from;}); + + // Avoid crashing on IE's "unspecified error" when in iframes + try { + var focused = document.activeElement; + } catch(e) {} + if (intactLines < (to - from) * .7) display.lineDiv.style.display = "none"; + patchDisplay(cm, from, to, intact, positionsChangedFrom); + display.lineDiv.style.display = ""; + if (focused && document.activeElement != focused && focused.offsetHeight) focused.focus(); + + var different = from != display.showingFrom || to != display.showingTo || + display.lastSizeC != display.wrapper.clientHeight; + // This is just a bogus formula that detects when the editor is + // resized or the font size changes. + if (different) { + display.lastSizeC = display.wrapper.clientHeight; + startWorker(cm, 400); + } + display.showingFrom = from; display.showingTo = to; + + updateHeightsInViewport(cm); + updateViewOffset(cm); + + return true; + } + + function updateHeightsInViewport(cm) { + var display = cm.display; + var prevBottom = display.lineDiv.offsetTop; + for (var node = display.lineDiv.firstChild, height; node; node = node.nextSibling) if (node.lineObj) { + if (ie_lt8) { + var bot = node.offsetTop + node.offsetHeight; + height = bot - prevBottom; + prevBottom = bot; + } else { + var box = getRect(node); + height = box.bottom - box.top; + } + var diff = node.lineObj.height - height; + if (height < 2) height = textHeight(display); + if (diff > .001 || diff < -.001) { + updateLineHeight(node.lineObj, height); + var widgets = node.lineObj.widgets; + if (widgets) for (var i = 0; i < widgets.length; ++i) + widgets[i].height = widgets[i].node.offsetHeight; + } + } + } + + function updateViewOffset(cm) { + var off = cm.display.viewOffset = heightAtLine(cm, getLine(cm.doc, cm.display.showingFrom)); + // Position the mover div to align with the current virtual scroll position + cm.display.mover.style.top = off + "px"; + } + + function computeIntact(intact, changes) { + for (var i = 0, l = changes.length || 0; i < l; ++i) { + var change = changes[i], intact2 = [], diff = change.diff || 0; + for (var j = 0, l2 = intact.length; j < l2; ++j) { + var range = intact[j]; + if (change.to <= range.from && change.diff) { + intact2.push({from: range.from + diff, to: range.to + diff}); + } else if (change.to <= range.from || change.from >= range.to) { + intact2.push(range); + } else { + if (change.from > range.from) + intact2.push({from: range.from, to: change.from}); + if (change.to < range.to) + intact2.push({from: change.to + diff, to: range.to + diff}); + } + } + intact = intact2; + } + return intact; + } + + function getDimensions(cm) { + var d = cm.display, left = {}, width = {}; + for (var n = d.gutters.firstChild, i = 0; n; n = n.nextSibling, ++i) { + left[cm.options.gutters[i]] = n.offsetLeft; + width[cm.options.gutters[i]] = n.offsetWidth; + } + return {fixedPos: compensateForHScroll(d), + gutterTotalWidth: d.gutters.offsetWidth, + gutterLeft: left, + gutterWidth: width, + wrapperWidth: d.wrapper.clientWidth}; + } + + function patchDisplay(cm, from, to, intact, updateNumbersFrom) { + var dims = getDimensions(cm); + var display = cm.display, lineNumbers = cm.options.lineNumbers; + if (!intact.length && (!webkit || !cm.display.currentWheelTarget)) + removeChildren(display.lineDiv); + var container = display.lineDiv, cur = container.firstChild; + + function rm(node) { + var next = node.nextSibling; + if (webkit && mac && cm.display.currentWheelTarget == node) { + node.style.display = "none"; + node.lineObj = null; + } else { + node.parentNode.removeChild(node); + } + return next; + } + + var nextIntact = intact.shift(), lineN = from; + cm.doc.iter(from, to, function(line) { + if (nextIntact && nextIntact.to == lineN) nextIntact = intact.shift(); + if (lineIsHidden(cm.doc, line)) { + if (line.height != 0) updateLineHeight(line, 0); + if (line.widgets && cur && cur.previousSibling) for (var i = 0; i < line.widgets.length; ++i) { + var w = line.widgets[i]; + if (w.showIfHidden) { + var prev = cur.previousSibling; + if (/pre/i.test(prev.nodeName)) { + var wrap = elt("div", null, null, "position: relative"); + prev.parentNode.replaceChild(wrap, prev); + wrap.appendChild(prev); + prev = wrap; + } + var wnode = prev.appendChild(elt("div", [w.node], "CodeMirror-linewidget")); + if (!w.handleMouseEvents) wnode.ignoreEvents = true; + positionLineWidget(w, wnode, prev, dims); + } + } + } else if (nextIntact && nextIntact.from <= lineN && nextIntact.to > lineN) { + // This line is intact. Skip to the actual node. Update its + // line number if needed. + while (cur.lineObj != line) cur = rm(cur); + if (lineNumbers && updateNumbersFrom <= lineN && cur.lineNumber) + setTextContent(cur.lineNumber, lineNumberFor(cm.options, lineN)); + cur = cur.nextSibling; + } else { + // For lines with widgets, make an attempt to find and reuse + // the existing element, so that widgets aren't needlessly + // removed and re-inserted into the dom + if (line.widgets) for (var j = 0, search = cur, reuse; search && j < 20; ++j, search = search.nextSibling) + if (search.lineObj == line && /div/i.test(search.nodeName)) { reuse = search; break; } + // This line needs to be generated. + var lineNode = buildLineElement(cm, line, lineN, dims, reuse); + if (lineNode != reuse) { + container.insertBefore(lineNode, cur); + } else { + while (cur != reuse) cur = rm(cur); + cur = cur.nextSibling; + } + + lineNode.lineObj = line; + } + ++lineN; + }); + while (cur) cur = rm(cur); + } + + function buildLineElement(cm, line, lineNo, dims, reuse) { + var built = buildLineContent(cm, line), lineElement = built.pre; + var markers = line.gutterMarkers, display = cm.display, wrap; + + var bgClass = built.bgClass ? built.bgClass + " " + (line.bgClass || "") : line.bgClass; + if (!cm.options.lineNumbers && !markers && !bgClass && !line.wrapClass && !line.widgets) + return lineElement; + + // Lines with gutter elements, widgets or a background class need + // to be wrapped again, and have the extra elements added to the + // wrapper div + + if (reuse) { + reuse.alignable = null; + var isOk = true, widgetsSeen = 0, insertBefore = null; + for (var n = reuse.firstChild, next; n; n = next) { + next = n.nextSibling; + if (!/\bCodeMirror-linewidget\b/.test(n.className)) { + reuse.removeChild(n); + } else { + for (var i = 0; i < line.widgets.length; ++i) { + var widget = line.widgets[i]; + if (widget.node == n.firstChild) { + if (!widget.above && !insertBefore) insertBefore = n; + positionLineWidget(widget, n, reuse, dims); + ++widgetsSeen; + break; + } + } + if (i == line.widgets.length) { isOk = false; break; } + } + } + reuse.insertBefore(lineElement, insertBefore); + if (isOk && widgetsSeen == line.widgets.length) { + wrap = reuse; + reuse.className = line.wrapClass || ""; + } + } + if (!wrap) { + wrap = elt("div", null, line.wrapClass, "position: relative"); + wrap.appendChild(lineElement); + } + // Kludge to make sure the styled element lies behind the selection (by z-index) + if (bgClass) + wrap.insertBefore(elt("div", null, bgClass + " CodeMirror-linebackground"), wrap.firstChild); + if (cm.options.lineNumbers || markers) { + var gutterWrap = wrap.insertBefore(elt("div", null, null, "position: absolute; left: " + + (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px"), + wrap.firstChild); + if (cm.options.fixedGutter) (wrap.alignable || (wrap.alignable = [])).push(gutterWrap); + if (cm.options.lineNumbers && (!markers || !markers["CodeMirror-linenumbers"])) + wrap.lineNumber = gutterWrap.appendChild( + elt("div", lineNumberFor(cm.options, lineNo), + "CodeMirror-linenumber CodeMirror-gutter-elt", + "left: " + dims.gutterLeft["CodeMirror-linenumbers"] + "px; width: " + + display.lineNumInnerWidth + "px")); + if (markers) + for (var k = 0; k < cm.options.gutters.length; ++k) { + var id = cm.options.gutters[k], found = markers.hasOwnProperty(id) && markers[id]; + if (found) + gutterWrap.appendChild(elt("div", [found], "CodeMirror-gutter-elt", "left: " + + dims.gutterLeft[id] + "px; width: " + dims.gutterWidth[id] + "px")); + } + } + if (ie_lt8) wrap.style.zIndex = 2; + if (line.widgets && wrap != reuse) for (var i = 0, ws = line.widgets; i < ws.length; ++i) { + var widget = ws[i], node = elt("div", [widget.node], "CodeMirror-linewidget"); + if (!widget.handleMouseEvents) node.ignoreEvents = true; + positionLineWidget(widget, node, wrap, dims); + if (widget.above) + wrap.insertBefore(node, cm.options.lineNumbers && line.height != 0 ? gutterWrap : lineElement); + else + wrap.appendChild(node); + signalLater(widget, "redraw"); + } + return wrap; + } + + function positionLineWidget(widget, node, wrap, dims) { + if (widget.noHScroll) { + (wrap.alignable || (wrap.alignable = [])).push(node); + var width = dims.wrapperWidth; + node.style.left = dims.fixedPos + "px"; + if (!widget.coverGutter) { + width -= dims.gutterTotalWidth; + node.style.paddingLeft = dims.gutterTotalWidth + "px"; + } + node.style.width = width + "px"; + } + if (widget.coverGutter) { + node.style.zIndex = 5; + node.style.position = "relative"; + if (!widget.noHScroll) node.style.marginLeft = -dims.gutterTotalWidth + "px"; + } + } + + // SELECTION / CURSOR + + function updateSelection(cm) { + var display = cm.display; + var collapsed = posEq(cm.doc.sel.from, cm.doc.sel.to); + if (collapsed || cm.options.showCursorWhenSelecting) + updateSelectionCursor(cm); + else + display.cursor.style.display = display.otherCursor.style.display = "none"; + if (!collapsed) + updateSelectionRange(cm); + else + display.selectionDiv.style.display = "none"; + + // Move the hidden textarea near the cursor to prevent scrolling artifacts + if (cm.options.moveInputWithCursor) { + var headPos = cursorCoords(cm, cm.doc.sel.head, "div"); + var wrapOff = getRect(display.wrapper), lineOff = getRect(display.lineDiv); + display.inputDiv.style.top = Math.max(0, Math.min(display.wrapper.clientHeight - 10, + headPos.top + lineOff.top - wrapOff.top)) + "px"; + display.inputDiv.style.left = Math.max(0, Math.min(display.wrapper.clientWidth - 10, + headPos.left + lineOff.left - wrapOff.left)) + "px"; + } + } + + // No selection, plain cursor + function updateSelectionCursor(cm) { + var display = cm.display, pos = cursorCoords(cm, cm.doc.sel.head, "div"); + display.cursor.style.left = pos.left + "px"; + display.cursor.style.top = pos.top + "px"; + display.cursor.style.height = Math.max(0, pos.bottom - pos.top) * cm.options.cursorHeight + "px"; + display.cursor.style.display = ""; + + if (pos.other) { + display.otherCursor.style.display = ""; + display.otherCursor.style.left = pos.other.left + "px"; + display.otherCursor.style.top = pos.other.top + "px"; + display.otherCursor.style.height = (pos.other.bottom - pos.other.top) * .85 + "px"; + } else { display.otherCursor.style.display = "none"; } + } + + // Highlight selection + function updateSelectionRange(cm) { + var display = cm.display, doc = cm.doc, sel = cm.doc.sel; + var fragment = document.createDocumentFragment(); + var clientWidth = display.lineSpace.offsetWidth, pl = paddingLeft(cm.display); + + function add(left, top, width, bottom) { + if (top < 0) top = 0; + fragment.appendChild(elt("div", null, "CodeMirror-selected", "position: absolute; left: " + left + + "px; top: " + top + "px; width: " + (width == null ? clientWidth - left : width) + + "px; height: " + (bottom - top) + "px")); + } + + function drawForLine(line, fromArg, toArg) { + var lineObj = getLine(doc, line); + var lineLen = lineObj.text.length; + var start, end; + function coords(ch, bias) { + return charCoords(cm, Pos(line, ch), "div", lineObj, bias); + } + + iterateBidiSections(getOrder(lineObj), fromArg || 0, toArg == null ? lineLen : toArg, function(from, to, dir) { + var leftPos = coords(from, "left"), rightPos, left, right; + if (from == to) { + rightPos = leftPos; + left = right = leftPos.left; + } else { + rightPos = coords(to - 1, "right"); + if (dir == "rtl") { var tmp = leftPos; leftPos = rightPos; rightPos = tmp; } + left = leftPos.left; + right = rightPos.right; + } + if (fromArg == null && from == 0) left = pl; + if (rightPos.top - leftPos.top > 3) { // Different lines, draw top part + add(left, leftPos.top, null, leftPos.bottom); + left = pl; + if (leftPos.bottom < rightPos.top) add(left, leftPos.bottom, null, rightPos.top); + } + if (toArg == null && to == lineLen) right = clientWidth; + if (!start || leftPos.top < start.top || leftPos.top == start.top && leftPos.left < start.left) + start = leftPos; + if (!end || rightPos.bottom > end.bottom || rightPos.bottom == end.bottom && rightPos.right > end.right) + end = rightPos; + if (left < pl + 1) left = pl; + add(left, rightPos.top, right - left, rightPos.bottom); + }); + return {start: start, end: end}; + } + + if (sel.from.line == sel.to.line) { + drawForLine(sel.from.line, sel.from.ch, sel.to.ch); + } else { + var fromLine = getLine(doc, sel.from.line), toLine = getLine(doc, sel.to.line); + var singleVLine = visualLine(doc, fromLine) == visualLine(doc, toLine); + var leftEnd = drawForLine(sel.from.line, sel.from.ch, singleVLine ? fromLine.text.length : null).end; + var rightStart = drawForLine(sel.to.line, singleVLine ? 0 : null, sel.to.ch).start; + if (singleVLine) { + if (leftEnd.top < rightStart.top - 2) { + add(leftEnd.right, leftEnd.top, null, leftEnd.bottom); + add(pl, rightStart.top, rightStart.left, rightStart.bottom); + } else { + add(leftEnd.right, leftEnd.top, rightStart.left - leftEnd.right, leftEnd.bottom); + } + } + if (leftEnd.bottom < rightStart.top) + add(pl, leftEnd.bottom, null, rightStart.top); + } + + removeChildrenAndAdd(display.selectionDiv, fragment); + display.selectionDiv.style.display = ""; + } + + // Cursor-blinking + function restartBlink(cm) { + if (!cm.state.focused) return; + var display = cm.display; + clearInterval(display.blinker); + var on = true; + display.cursor.style.visibility = display.otherCursor.style.visibility = ""; + if (cm.options.cursorBlinkRate > 0) + display.blinker = setInterval(function() { + display.cursor.style.visibility = display.otherCursor.style.visibility = (on = !on) ? "" : "hidden"; + }, cm.options.cursorBlinkRate); + } + + // HIGHLIGHT WORKER + + function startWorker(cm, time) { + if (cm.doc.mode.startState && cm.doc.frontier < cm.display.showingTo) + cm.state.highlight.set(time, bind(highlightWorker, cm)); + } + + function highlightWorker(cm) { + var doc = cm.doc; + if (doc.frontier < doc.first) doc.frontier = doc.first; + if (doc.frontier >= cm.display.showingTo) return; + var end = +new Date + cm.options.workTime; + var state = copyState(doc.mode, getStateBefore(cm, doc.frontier)); + var changed = [], prevChange; + doc.iter(doc.frontier, Math.min(doc.first + doc.size, cm.display.showingTo + 500), function(line) { + if (doc.frontier >= cm.display.showingFrom) { // Visible + var oldStyles = line.styles; + line.styles = highlightLine(cm, line, state); + var ischange = !oldStyles || oldStyles.length != line.styles.length; + for (var i = 0; !ischange && i < oldStyles.length; ++i) ischange = oldStyles[i] != line.styles[i]; + if (ischange) { + if (prevChange && prevChange.end == doc.frontier) prevChange.end++; + else changed.push(prevChange = {start: doc.frontier, end: doc.frontier + 1}); + } + line.stateAfter = copyState(doc.mode, state); + } else { + processLine(cm, line, state); + line.stateAfter = doc.frontier % 5 == 0 ? copyState(doc.mode, state) : null; + } + ++doc.frontier; + if (+new Date > end) { + startWorker(cm, cm.options.workDelay); + return true; + } + }); + if (changed.length) + operation(cm, function() { + for (var i = 0; i < changed.length; ++i) + regChange(this, changed[i].start, changed[i].end); + })(); + } + + // Finds the line to start with when starting a parse. Tries to + // find a line with a stateAfter, so that it can start with a + // valid state. If that fails, it returns the line with the + // smallest indentation, which tends to need the least context to + // parse correctly. + function findStartLine(cm, n, precise) { + var minindent, minline, doc = cm.doc, maxScan = cm.doc.mode.innerMode ? 1000 : 100; + for (var search = n, lim = n - maxScan; search > lim; --search) { + if (search <= doc.first) return doc.first; + var line = getLine(doc, search - 1); + if (line.stateAfter && (!precise || search <= doc.frontier)) return search; + var indented = countColumn(line.text, null, cm.options.tabSize); + if (minline == null || minindent > indented) { + minline = search - 1; + minindent = indented; + } + } + return minline; + } + + function getStateBefore(cm, n, precise) { + var doc = cm.doc, display = cm.display; + if (!doc.mode.startState) return true; + var pos = findStartLine(cm, n, precise), state = pos > doc.first && getLine(doc, pos-1).stateAfter; + if (!state) state = startState(doc.mode); + else state = copyState(doc.mode, state); + doc.iter(pos, n, function(line) { + processLine(cm, line, state); + var save = pos == n - 1 || pos % 5 == 0 || pos >= display.showingFrom && pos < display.showingTo; + line.stateAfter = save ? copyState(doc.mode, state) : null; + ++pos; + }); + return state; + } + + // POSITION MEASUREMENT + + function paddingTop(display) {return display.lineSpace.offsetTop;} + function paddingVert(display) {return display.mover.offsetHeight - display.lineSpace.offsetHeight;} + function paddingLeft(display) { + var e = removeChildrenAndAdd(display.measure, elt("pre", null, null, "text-align: left")).appendChild(elt("span", "x")); + return e.offsetLeft; + } + + function measureChar(cm, line, ch, data, bias) { + var dir = -1; + data = data || measureLine(cm, line); + if (data.crude) { + var left = data.left + ch * data.width; + return {left: left, right: left + data.width, top: data.top, bottom: data.bottom}; + } + + for (var pos = ch;; pos += dir) { + var r = data[pos]; + if (r) break; + if (dir < 0 && pos == 0) dir = 1; + } + bias = pos > ch ? "left" : pos < ch ? "right" : bias; + if (bias == "left" && r.leftSide) r = r.leftSide; + else if (bias == "right" && r.rightSide) r = r.rightSide; + return {left: pos < ch ? r.right : r.left, + right: pos > ch ? r.left : r.right, + top: r.top, + bottom: r.bottom}; + } + + function findCachedMeasurement(cm, line) { + var cache = cm.display.measureLineCache; + for (var i = 0; i < cache.length; ++i) { + var memo = cache[i]; + if (memo.text == line.text && memo.markedSpans == line.markedSpans && + cm.display.scroller.clientWidth == memo.width && + memo.classes == line.textClass + "|" + line.wrapClass) + return memo; + } + } + + function clearCachedMeasurement(cm, line) { + var exists = findCachedMeasurement(cm, line); + if (exists) exists.text = exists.measure = exists.markedSpans = null; + } + + function measureLine(cm, line) { + // First look in the cache + var cached = findCachedMeasurement(cm, line); + if (cached) return cached.measure; + + // Failing that, recompute and store result in cache + var measure = measureLineInner(cm, line); + var cache = cm.display.measureLineCache; + var memo = {text: line.text, width: cm.display.scroller.clientWidth, + markedSpans: line.markedSpans, measure: measure, + classes: line.textClass + "|" + line.wrapClass}; + if (cache.length == 16) cache[++cm.display.measureLineCachePos % 16] = memo; + else cache.push(memo); + return measure; + } + + function measureLineInner(cm, line) { + if (!cm.options.lineWrapping && line.text.length >= cm.options.crudeMeasuringFrom) + return crudelyMeasureLine(cm, line); + + var display = cm.display, measure = emptyArray(line.text.length); + var pre = buildLineContent(cm, line, measure, true).pre; + + // IE does not cache element positions of inline elements between + // calls to getBoundingClientRect. This makes the loop below, + // which gathers the positions of all the characters on the line, + // do an amount of layout work quadratic to the number of + // characters. When line wrapping is off, we try to improve things + // by first subdividing the line into a bunch of inline blocks, so + // that IE can reuse most of the layout information from caches + // for those blocks. This does interfere with line wrapping, so it + // doesn't work when wrapping is on, but in that case the + // situation is slightly better, since IE does cache line-wrapping + // information and only recomputes per-line. + if (ie && !ie_lt8 && !cm.options.lineWrapping && pre.childNodes.length > 100) { + var fragment = document.createDocumentFragment(); + var chunk = 10, n = pre.childNodes.length; + for (var i = 0, chunks = Math.ceil(n / chunk); i < chunks; ++i) { + var wrap = elt("div", null, null, "display: inline-block"); + for (var j = 0; j < chunk && n; ++j) { + wrap.appendChild(pre.firstChild); + --n; + } + fragment.appendChild(wrap); + } + pre.appendChild(fragment); + } + + removeChildrenAndAdd(display.measure, pre); + + var outer = getRect(display.lineDiv); + var vranges = [], data = emptyArray(line.text.length), maxBot = pre.offsetHeight; + // Work around an IE7/8 bug where it will sometimes have randomly + // replaced our pre with a clone at this point. + if (ie_lt9 && display.measure.first != pre) + removeChildrenAndAdd(display.measure, pre); + + function measureRect(rect) { + var top = rect.top - outer.top, bot = rect.bottom - outer.top; + if (bot > maxBot) bot = maxBot; + if (top < 0) top = 0; + for (var i = vranges.length - 2; i >= 0; i -= 2) { + var rtop = vranges[i], rbot = vranges[i+1]; + if (rtop > bot || rbot < top) continue; + if (rtop <= top && rbot >= bot || + top <= rtop && bot >= rbot || + Math.min(bot, rbot) - Math.max(top, rtop) >= (bot - top) >> 1) { + vranges[i] = Math.min(top, rtop); + vranges[i+1] = Math.max(bot, rbot); + break; + } + } + if (i < 0) { i = vranges.length; vranges.push(top, bot); } + return {left: rect.left - outer.left, + right: rect.right - outer.left, + top: i, bottom: null}; + } + function finishRect(rect) { + rect.bottom = vranges[rect.top+1]; + rect.top = vranges[rect.top]; + } + + for (var i = 0, cur; i < measure.length; ++i) if (cur = measure[i]) { + var node = cur, rect = null; + // A widget might wrap, needs special care + if (/\bCodeMirror-widget\b/.test(cur.className) && cur.getClientRects) { + if (cur.firstChild.nodeType == 1) node = cur.firstChild; + var rects = node.getClientRects(); + if (rects.length > 1) { + rect = data[i] = measureRect(rects[0]); + rect.rightSide = measureRect(rects[rects.length - 1]); + } + } + if (!rect) rect = data[i] = measureRect(getRect(node)); + if (cur.measureRight) rect.right = getRect(cur.measureRight).left; + if (cur.leftSide) rect.leftSide = measureRect(getRect(cur.leftSide)); + } + removeChildren(cm.display.measure); + for (var i = 0, cur; i < data.length; ++i) if (cur = data[i]) { + finishRect(cur); + if (cur.leftSide) finishRect(cur.leftSide); + if (cur.rightSide) finishRect(cur.rightSide); + } + return data; + } + + function crudelyMeasureLine(cm, line) { + var copy = new Line(line.text.slice(0, 100), null); + if (line.textClass) copy.textClass = line.textClass; + var measure = measureLineInner(cm, copy); + var left = measureChar(cm, copy, 0, measure, "left"); + var right = measureChar(cm, copy, 99, measure, "right"); + return {crude: true, top: left.top, left: left.left, bottom: left.bottom, width: (right.right - left.left) / 100}; + } + + function measureLineWidth(cm, line) { + var hasBadSpan = false; + if (line.markedSpans) for (var i = 0; i < line.markedSpans; ++i) { + var sp = line.markedSpans[i]; + if (sp.collapsed && (sp.to == null || sp.to == line.text.length)) hasBadSpan = true; + } + var cached = !hasBadSpan && findCachedMeasurement(cm, line); + if (cached || line.text.length >= cm.options.crudeMeasuringFrom) + return measureChar(cm, line, line.text.length, cached && cached.measure, "right").right; + + var pre = buildLineContent(cm, line, null, true).pre; + var end = pre.appendChild(zeroWidthElement(cm.display.measure)); + removeChildrenAndAdd(cm.display.measure, pre); + return getRect(end).right - getRect(cm.display.lineDiv).left; + } + + function clearCaches(cm) { + cm.display.measureLineCache.length = cm.display.measureLineCachePos = 0; + cm.display.cachedCharWidth = cm.display.cachedTextHeight = null; + if (!cm.options.lineWrapping) cm.display.maxLineChanged = true; + cm.display.lineNumChars = null; + } + + function pageScrollX() { return window.pageXOffset || (document.documentElement || document.body).scrollLeft; } + function pageScrollY() { return window.pageYOffset || (document.documentElement || document.body).scrollTop; } + + // Context is one of "line", "div" (display.lineDiv), "local"/null (editor), or "page" + function intoCoordSystem(cm, lineObj, rect, context) { + if (lineObj.widgets) for (var i = 0; i < lineObj.widgets.length; ++i) if (lineObj.widgets[i].above) { + var size = widgetHeight(lineObj.widgets[i]); + rect.top += size; rect.bottom += size; + } + if (context == "line") return rect; + if (!context) context = "local"; + var yOff = heightAtLine(cm, lineObj); + if (context == "local") yOff += paddingTop(cm.display); + else yOff -= cm.display.viewOffset; + if (context == "page" || context == "window") { + var lOff = getRect(cm.display.lineSpace); + yOff += lOff.top + (context == "window" ? 0 : pageScrollY()); + var xOff = lOff.left + (context == "window" ? 0 : pageScrollX()); + rect.left += xOff; rect.right += xOff; + } + rect.top += yOff; rect.bottom += yOff; + return rect; + } + + // Context may be "window", "page", "div", or "local"/null + // Result is in "div" coords + function fromCoordSystem(cm, coords, context) { + if (context == "div") return coords; + var left = coords.left, top = coords.top; + // First move into "page" coordinate system + if (context == "page") { + left -= pageScrollX(); + top -= pageScrollY(); + } else if (context == "local" || !context) { + var localBox = getRect(cm.display.sizer); + left += localBox.left; + top += localBox.top; + } + + var lineSpaceBox = getRect(cm.display.lineSpace); + return {left: left - lineSpaceBox.left, top: top - lineSpaceBox.top}; + } + + function charCoords(cm, pos, context, lineObj, bias) { + if (!lineObj) lineObj = getLine(cm.doc, pos.line); + return intoCoordSystem(cm, lineObj, measureChar(cm, lineObj, pos.ch, null, bias), context); + } + + function cursorCoords(cm, pos, context, lineObj, measurement) { + lineObj = lineObj || getLine(cm.doc, pos.line); + if (!measurement) measurement = measureLine(cm, lineObj); + function get(ch, right) { + var m = measureChar(cm, lineObj, ch, measurement, right ? "right" : "left"); + if (right) m.left = m.right; else m.right = m.left; + return intoCoordSystem(cm, lineObj, m, context); + } + function getBidi(ch, partPos) { + var part = order[partPos], right = part.level % 2; + if (ch == bidiLeft(part) && partPos && part.level < order[partPos - 1].level) { + part = order[--partPos]; + ch = bidiRight(part) - (part.level % 2 ? 0 : 1); + right = true; + } else if (ch == bidiRight(part) && partPos < order.length - 1 && part.level < order[partPos + 1].level) { + part = order[++partPos]; + ch = bidiLeft(part) - part.level % 2; + right = false; + } + if (right && ch == part.to && ch > part.from) return get(ch - 1); + return get(ch, right); + } + var order = getOrder(lineObj), ch = pos.ch; + if (!order) return get(ch); + var partPos = getBidiPartAt(order, ch); + var val = getBidi(ch, partPos); + if (bidiOther != null) val.other = getBidi(ch, bidiOther); + return val; + } + + function PosWithInfo(line, ch, outside, xRel) { + var pos = new Pos(line, ch); + pos.xRel = xRel; + if (outside) pos.outside = true; + return pos; + } + + // Coords must be lineSpace-local + function coordsChar(cm, x, y) { + var doc = cm.doc; + y += cm.display.viewOffset; + if (y < 0) return PosWithInfo(doc.first, 0, true, -1); + var lineNo = lineAtHeight(doc, y), last = doc.first + doc.size - 1; + if (lineNo > last) + return PosWithInfo(doc.first + doc.size - 1, getLine(doc, last).text.length, true, 1); + if (x < 0) x = 0; + + for (;;) { + var lineObj = getLine(doc, lineNo); + var found = coordsCharInner(cm, lineObj, lineNo, x, y); + var merged = collapsedSpanAtEnd(lineObj); + var mergedPos = merged && merged.find(); + if (merged && (found.ch > mergedPos.from.ch || found.ch == mergedPos.from.ch && found.xRel > 0)) + lineNo = mergedPos.to.line; + else + return found; + } + } + + function coordsCharInner(cm, lineObj, lineNo, x, y) { + var innerOff = y - heightAtLine(cm, lineObj); + var wrongLine = false, adjust = 2 * cm.display.wrapper.clientWidth; + var measurement = measureLine(cm, lineObj); + + function getX(ch) { + var sp = cursorCoords(cm, Pos(lineNo, ch), "line", + lineObj, measurement); + wrongLine = true; + if (innerOff > sp.bottom) return sp.left - adjust; + else if (innerOff < sp.top) return sp.left + adjust; + else wrongLine = false; + return sp.left; + } + + var bidi = getOrder(lineObj), dist = lineObj.text.length; + var from = lineLeft(lineObj), to = lineRight(lineObj); + var fromX = getX(from), fromOutside = wrongLine, toX = getX(to), toOutside = wrongLine; + + if (x > toX) return PosWithInfo(lineNo, to, toOutside, 1); + // Do a binary search between these bounds. + for (;;) { + if (bidi ? to == from || to == moveVisually(lineObj, from, 1) : to - from <= 1) { + var ch = x < fromX || x - fromX <= toX - x ? from : to; + var xDiff = x - (ch == from ? fromX : toX); + while (isExtendingChar.test(lineObj.text.charAt(ch))) ++ch; + var pos = PosWithInfo(lineNo, ch, ch == from ? fromOutside : toOutside, + xDiff < 0 ? -1 : xDiff ? 1 : 0); + return pos; + } + var step = Math.ceil(dist / 2), middle = from + step; + if (bidi) { + middle = from; + for (var i = 0; i < step; ++i) middle = moveVisually(lineObj, middle, 1); + } + var middleX = getX(middle); + if (middleX > x) {to = middle; toX = middleX; if (toOutside = wrongLine) toX += 1000; dist = step;} + else {from = middle; fromX = middleX; fromOutside = wrongLine; dist -= step;} + } + } + + var measureText; + function textHeight(display) { + if (display.cachedTextHeight != null) return display.cachedTextHeight; + if (measureText == null) { + measureText = elt("pre"); + // Measure a bunch of lines, for browsers that compute + // fractional heights. + for (var i = 0; i < 49; ++i) { + measureText.appendChild(document.createTextNode("x")); + measureText.appendChild(elt("br")); + } + measureText.appendChild(document.createTextNode("x")); + } + removeChildrenAndAdd(display.measure, measureText); + var height = measureText.offsetHeight / 50; + if (height > 3) display.cachedTextHeight = height; + removeChildren(display.measure); + return height || 1; + } + + function charWidth(display) { + if (display.cachedCharWidth != null) return display.cachedCharWidth; + var anchor = elt("span", "x"); + var pre = elt("pre", [anchor]); + removeChildrenAndAdd(display.measure, pre); + var width = anchor.offsetWidth; + if (width > 2) display.cachedCharWidth = width; + return width || 10; + } + + // OPERATIONS + + // Operations are used to wrap changes in such a way that each + // change won't have to update the cursor and display (which would + // be awkward, slow, and error-prone), but instead updates are + // batched and then all combined and executed at once. + + var nextOpId = 0; + function startOperation(cm) { + cm.curOp = { + // An array of ranges of lines that have to be updated. See + // updateDisplay. + changes: [], + forceUpdate: false, + updateInput: null, + userSelChange: null, + textChanged: null, + selectionChanged: false, + cursorActivity: false, + updateMaxLine: false, + updateScrollPos: false, + id: ++nextOpId + }; + if (!delayedCallbackDepth++) delayedCallbacks = []; + } + + function endOperation(cm) { + var op = cm.curOp, doc = cm.doc, display = cm.display; + cm.curOp = null; + + if (op.updateMaxLine) computeMaxLength(cm); + if (display.maxLineChanged && !cm.options.lineWrapping && display.maxLine) { + var width = measureLineWidth(cm, display.maxLine); + display.sizer.style.minWidth = Math.max(0, width + 3 + scrollerCutOff) + "px"; + display.maxLineChanged = false; + var maxScrollLeft = Math.max(0, display.sizer.offsetLeft + display.sizer.offsetWidth - display.scroller.clientWidth); + if (maxScrollLeft < doc.scrollLeft && !op.updateScrollPos) + setScrollLeft(cm, Math.min(display.scroller.scrollLeft, maxScrollLeft), true); + } + var newScrollPos, updated; + if (op.updateScrollPos) { + newScrollPos = op.updateScrollPos; + } else if (op.selectionChanged && display.scroller.clientHeight) { // don't rescroll if not visible + var coords = cursorCoords(cm, doc.sel.head); + newScrollPos = calculateScrollPos(cm, coords.left, coords.top, coords.left, coords.bottom); + } + if (op.changes.length || op.forceUpdate || newScrollPos && newScrollPos.scrollTop != null) { + updated = updateDisplay(cm, op.changes, newScrollPos && newScrollPos.scrollTop, op.forceUpdate); + if (cm.display.scroller.offsetHeight) cm.doc.scrollTop = cm.display.scroller.scrollTop; + } + if (!updated && op.selectionChanged) updateSelection(cm); + if (op.updateScrollPos) { + display.scroller.scrollTop = display.scrollbarV.scrollTop = doc.scrollTop = newScrollPos.scrollTop; + display.scroller.scrollLeft = display.scrollbarH.scrollLeft = doc.scrollLeft = newScrollPos.scrollLeft; + alignHorizontally(cm); + if (op.scrollToPos) + scrollPosIntoView(cm, clipPos(cm.doc, op.scrollToPos), op.scrollToPosMargin); + } else if (newScrollPos) { + scrollCursorIntoView(cm); + } + if (op.selectionChanged) restartBlink(cm); + + if (cm.state.focused && op.updateInput) + resetInput(cm, op.userSelChange); + + var hidden = op.maybeHiddenMarkers, unhidden = op.maybeUnhiddenMarkers; + if (hidden) for (var i = 0; i < hidden.length; ++i) + if (!hidden[i].lines.length) signal(hidden[i], "hide"); + if (unhidden) for (var i = 0; i < unhidden.length; ++i) + if (unhidden[i].lines.length) signal(unhidden[i], "unhide"); + + var delayed; + if (!--delayedCallbackDepth) { + delayed = delayedCallbacks; + delayedCallbacks = null; + } + if (op.textChanged) + signal(cm, "change", cm, op.textChanged); + if (op.cursorActivity) signal(cm, "cursorActivity", cm); + if (delayed) for (var i = 0; i < delayed.length; ++i) delayed[i](); + } + + // Wraps a function in an operation. Returns the wrapped function. + function operation(cm1, f) { + return function() { + var cm = cm1 || this, withOp = !cm.curOp; + if (withOp) startOperation(cm); + try { var result = f.apply(cm, arguments); } + finally { if (withOp) endOperation(cm); } + return result; + }; + } + function docOperation(f) { + return function() { + var withOp = this.cm && !this.cm.curOp, result; + if (withOp) startOperation(this.cm); + try { result = f.apply(this, arguments); } + finally { if (withOp) endOperation(this.cm); } + return result; + }; + } + function runInOp(cm, f) { + var withOp = !cm.curOp, result; + if (withOp) startOperation(cm); + try { result = f(); } + finally { if (withOp) endOperation(cm); } + return result; + } + + function regChange(cm, from, to, lendiff) { + if (from == null) from = cm.doc.first; + if (to == null) to = cm.doc.first + cm.doc.size; + cm.curOp.changes.push({from: from, to: to, diff: lendiff}); + } + + // INPUT HANDLING + + function slowPoll(cm) { + if (cm.display.pollingFast) return; + cm.display.poll.set(cm.options.pollInterval, function() { + readInput(cm); + if (cm.state.focused) slowPoll(cm); + }); + } + + function fastPoll(cm) { + var missed = false; + cm.display.pollingFast = true; + function p() { + var changed = readInput(cm); + if (!changed && !missed) {missed = true; cm.display.poll.set(60, p);} + else {cm.display.pollingFast = false; slowPoll(cm);} + } + cm.display.poll.set(20, p); + } + + // prevInput is a hack to work with IME. If we reset the textarea + // on every change, that breaks IME. So we look for changes + // compared to the previous content instead. (Modern browsers have + // events that indicate IME taking place, but these are not widely + // supported or compatible enough yet to rely on.) + function readInput(cm) { + var input = cm.display.input, prevInput = cm.display.prevInput, doc = cm.doc, sel = doc.sel; + if (!cm.state.focused || hasSelection(input) || isReadOnly(cm) || cm.state.disableInput) return false; + if (cm.state.pasteIncoming && cm.state.fakedLastChar) { + input.value = input.value.substring(0, input.value.length - 1); + cm.state.fakedLastChar = false; + } + var text = input.value; + if (text == prevInput && posEq(sel.from, sel.to)) return false; + if (ie && !ie_lt9 && cm.display.inputHasSelection === text) { + resetInput(cm, true); + return false; + } + + var withOp = !cm.curOp; + if (withOp) startOperation(cm); + sel.shift = false; + var same = 0, l = Math.min(prevInput.length, text.length); + while (same < l && prevInput.charCodeAt(same) == text.charCodeAt(same)) ++same; + var from = sel.from, to = sel.to; + if (same < prevInput.length) + from = Pos(from.line, from.ch - (prevInput.length - same)); + else if (cm.state.overwrite && posEq(from, to) && !cm.state.pasteIncoming) + to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + (text.length - same))); + + var updateInput = cm.curOp.updateInput; + var changeEvent = {from: from, to: to, text: splitLines(text.slice(same)), + origin: cm.state.pasteIncoming ? "paste" : "+input"}; + makeChange(cm.doc, changeEvent, "end"); + cm.curOp.updateInput = updateInput; + signalLater(cm, "inputRead", cm, changeEvent); + + if (text.length > 1000 || text.indexOf("\n") > -1) input.value = cm.display.prevInput = ""; + else cm.display.prevInput = text; + if (withOp) endOperation(cm); + cm.state.pasteIncoming = false; + return true; + } + + function resetInput(cm, user) { + var minimal, selected, doc = cm.doc; + if (!posEq(doc.sel.from, doc.sel.to)) { + cm.display.prevInput = ""; + minimal = hasCopyEvent && + (doc.sel.to.line - doc.sel.from.line > 100 || (selected = cm.getSelection()).length > 1000); + var content = minimal ? "-" : selected || cm.getSelection(); + cm.display.input.value = content; + if (cm.state.focused) selectInput(cm.display.input); + if (ie && !ie_lt9) cm.display.inputHasSelection = content; + } else if (user) { + cm.display.prevInput = cm.display.input.value = ""; + if (ie && !ie_lt9) cm.display.inputHasSelection = null; + } + cm.display.inaccurateSelection = minimal; + } + + function focusInput(cm) { + if (cm.options.readOnly != "nocursor" && (!mobile || document.activeElement != cm.display.input)) + cm.display.input.focus(); + } + + function isReadOnly(cm) { + return cm.options.readOnly || cm.doc.cantEdit; + } + + // EVENT HANDLERS + + function registerEventHandlers(cm) { + var d = cm.display; + on(d.scroller, "mousedown", operation(cm, onMouseDown)); + if (ie) + on(d.scroller, "dblclick", operation(cm, function(e) { + if (signalDOMEvent(cm, e)) return; + var pos = posFromMouse(cm, e); + if (!pos || clickInGutter(cm, e) || eventInWidget(cm.display, e)) return; + e_preventDefault(e); + var word = findWordAt(getLine(cm.doc, pos.line).text, pos); + extendSelection(cm.doc, word.from, word.to); + })); + else + on(d.scroller, "dblclick", function(e) { signalDOMEvent(cm, e) || e_preventDefault(e); }); + on(d.lineSpace, "selectstart", function(e) { + if (!eventInWidget(d, e)) e_preventDefault(e); + }); + // Gecko browsers fire contextmenu *after* opening the menu, at + // which point we can't mess with it anymore. Context menu is + // handled in onMouseDown for Gecko. + if (!captureMiddleClick) on(d.scroller, "contextmenu", function(e) {onContextMenu(cm, e);}); + + on(d.scroller, "scroll", function() { + if (d.scroller.clientHeight) { + setScrollTop(cm, d.scroller.scrollTop); + setScrollLeft(cm, d.scroller.scrollLeft, true); + signal(cm, "scroll", cm); + } + }); + on(d.scrollbarV, "scroll", function() { + if (d.scroller.clientHeight) setScrollTop(cm, d.scrollbarV.scrollTop); + }); + on(d.scrollbarH, "scroll", function() { + if (d.scroller.clientHeight) setScrollLeft(cm, d.scrollbarH.scrollLeft); + }); + + on(d.scroller, "mousewheel", function(e){onScrollWheel(cm, e);}); + on(d.scroller, "DOMMouseScroll", function(e){onScrollWheel(cm, e);}); + + function reFocus() { if (cm.state.focused) setTimeout(bind(focusInput, cm), 0); } + on(d.scrollbarH, "mousedown", reFocus); + on(d.scrollbarV, "mousedown", reFocus); + // Prevent wrapper from ever scrolling + on(d.wrapper, "scroll", function() { d.wrapper.scrollTop = d.wrapper.scrollLeft = 0; }); + + var resizeTimer; + function onResize() { + if (resizeTimer == null) resizeTimer = setTimeout(function() { + resizeTimer = null; + // Might be a text scaling operation, clear size caches. + d.cachedCharWidth = d.cachedTextHeight = knownScrollbarWidth = null; + clearCaches(cm); + runInOp(cm, bind(regChange, cm)); + }, 100); + } + on(window, "resize", onResize); + // Above handler holds on to the editor and its data structures. + // Here we poll to unregister it when the editor is no longer in + // the document, so that it can be garbage-collected. + function unregister() { + for (var p = d.wrapper.parentNode; p && p != document.body; p = p.parentNode) {} + if (p) setTimeout(unregister, 5000); + else off(window, "resize", onResize); + } + setTimeout(unregister, 5000); + + on(d.input, "keyup", operation(cm, function(e) { + if (signalDOMEvent(cm, e) || cm.options.onKeyEvent && cm.options.onKeyEvent(cm, addStop(e))) return; + if (e.keyCode == 16) cm.doc.sel.shift = false; + })); + on(d.input, "input", function() { + if (ie && !ie_lt9 && cm.display.inputHasSelection) cm.display.inputHasSelection = null; + fastPoll(cm); + }); + on(d.input, "keydown", operation(cm, onKeyDown)); + on(d.input, "keypress", operation(cm, onKeyPress)); + on(d.input, "focus", bind(onFocus, cm)); + on(d.input, "blur", bind(onBlur, cm)); + + function drag_(e) { + if (signalDOMEvent(cm, e) || cm.options.onDragEvent && cm.options.onDragEvent(cm, addStop(e))) return; + e_stop(e); + } + if (cm.options.dragDrop) { + on(d.scroller, "dragstart", function(e){onDragStart(cm, e);}); + on(d.scroller, "dragenter", drag_); + on(d.scroller, "dragover", drag_); + on(d.scroller, "drop", operation(cm, onDrop)); + } + on(d.scroller, "paste", function(e) { + if (eventInWidget(d, e)) return; + focusInput(cm); + fastPoll(cm); + }); + on(d.input, "paste", function() { + // Workaround for webkit bug https://bugs.webkit.org/show_bug.cgi?id=90206 + // Add a char to the end of textarea before paste occur so that + // selection doesn't span to the end of textarea. + if (webkit && !cm.state.fakedLastChar && !(new Date - cm.state.lastMiddleDown < 200)) { + var start = d.input.selectionStart, end = d.input.selectionEnd; + d.input.value += "$"; + d.input.selectionStart = start; + d.input.selectionEnd = end; + cm.state.fakedLastChar = true; + } + cm.state.pasteIncoming = true; + fastPoll(cm); + }); + + function prepareCopy() { + if (d.inaccurateSelection) { + d.prevInput = ""; + d.inaccurateSelection = false; + d.input.value = cm.getSelection(); + selectInput(d.input); + } + } + on(d.input, "cut", prepareCopy); + on(d.input, "copy", prepareCopy); + + // Needed to handle Tab key in KHTML + if (khtml) on(d.sizer, "mouseup", function() { + if (document.activeElement == d.input) d.input.blur(); + focusInput(cm); + }); + } + + function eventInWidget(display, e) { + for (var n = e_target(e); n != display.wrapper; n = n.parentNode) { + if (!n || n.ignoreEvents || n.parentNode == display.sizer && n != display.mover) return true; + } + } + + function posFromMouse(cm, e, liberal) { + var display = cm.display; + if (!liberal) { + var target = e_target(e); + if (target == display.scrollbarH || target == display.scrollbarH.firstChild || + target == display.scrollbarV || target == display.scrollbarV.firstChild || + target == display.scrollbarFiller || target == display.gutterFiller) return null; + } + var x, y, space = getRect(display.lineSpace); + // Fails unpredictably on IE[67] when mouse is dragged around quickly. + try { x = e.clientX; y = e.clientY; } catch (e) { return null; } + return coordsChar(cm, x - space.left, y - space.top); + } + + var lastClick, lastDoubleClick; + function onMouseDown(e) { + if (signalDOMEvent(this, e)) return; + var cm = this, display = cm.display, doc = cm.doc, sel = doc.sel; + sel.shift = e.shiftKey; + + if (eventInWidget(display, e)) { + if (!webkit) { + display.scroller.draggable = false; + setTimeout(function(){display.scroller.draggable = true;}, 100); + } + return; + } + if (clickInGutter(cm, e)) return; + var start = posFromMouse(cm, e); + + switch (e_button(e)) { + case 3: + if (captureMiddleClick) onContextMenu.call(cm, cm, e); + return; + case 2: + if (webkit) cm.state.lastMiddleDown = +new Date; + if (start) extendSelection(cm.doc, start); + setTimeout(bind(focusInput, cm), 20); + e_preventDefault(e); + return; + } + // For button 1, if it was clicked inside the editor + // (posFromMouse returning non-null), we have to adjust the + // selection. + if (!start) {if (e_target(e) == display.scroller) e_preventDefault(e); return;} + + if (!cm.state.focused) onFocus(cm); + + var now = +new Date, type = "single"; + if (lastDoubleClick && lastDoubleClick.time > now - 400 && posEq(lastDoubleClick.pos, start)) { + type = "triple"; + e_preventDefault(e); + setTimeout(bind(focusInput, cm), 20); + selectLine(cm, start.line); + } else if (lastClick && lastClick.time > now - 400 && posEq(lastClick.pos, start)) { + type = "double"; + lastDoubleClick = {time: now, pos: start}; + e_preventDefault(e); + var word = findWordAt(getLine(doc, start.line).text, start); + extendSelection(cm.doc, word.from, word.to); + } else { lastClick = {time: now, pos: start}; } + + var last = start; + if (cm.options.dragDrop && dragAndDrop && !isReadOnly(cm) && !posEq(sel.from, sel.to) && + !posLess(start, sel.from) && !posLess(sel.to, start) && type == "single") { + var dragEnd = operation(cm, function(e2) { + if (webkit) display.scroller.draggable = false; + cm.state.draggingText = false; + off(document, "mouseup", dragEnd); + off(display.scroller, "drop", dragEnd); + if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) { + e_preventDefault(e2); + extendSelection(cm.doc, start); + focusInput(cm); + } + }); + // Let the drag handler handle this. + if (webkit) display.scroller.draggable = true; + cm.state.draggingText = dragEnd; + // IE's approach to draggable + if (display.scroller.dragDrop) display.scroller.dragDrop(); + on(document, "mouseup", dragEnd); + on(display.scroller, "drop", dragEnd); + return; + } + e_preventDefault(e); + if (type == "single") extendSelection(cm.doc, clipPos(doc, start)); + + var startstart = sel.from, startend = sel.to, lastPos = start; + + function doSelect(cur) { + if (posEq(lastPos, cur)) return; + lastPos = cur; + + if (type == "single") { + extendSelection(cm.doc, clipPos(doc, start), cur); + return; + } + + startstart = clipPos(doc, startstart); + startend = clipPos(doc, startend); + if (type == "double") { + var word = findWordAt(getLine(doc, cur.line).text, cur); + if (posLess(cur, startstart)) extendSelection(cm.doc, word.from, startend); + else extendSelection(cm.doc, startstart, word.to); + } else if (type == "triple") { + if (posLess(cur, startstart)) extendSelection(cm.doc, startend, clipPos(doc, Pos(cur.line, 0))); + else extendSelection(cm.doc, startstart, clipPos(doc, Pos(cur.line + 1, 0))); + } + } + + var editorSize = getRect(display.wrapper); + // Used to ensure timeout re-tries don't fire when another extend + // happened in the meantime (clearTimeout isn't reliable -- at + // least on Chrome, the timeouts still happen even when cleared, + // if the clear happens after their scheduled firing time). + var counter = 0; + + function extend(e) { + var curCount = ++counter; + var cur = posFromMouse(cm, e, true); + if (!cur) return; + if (!posEq(cur, last)) { + if (!cm.state.focused) onFocus(cm); + last = cur; + doSelect(cur); + var visible = visibleLines(display, doc); + if (cur.line >= visible.to || cur.line < visible.from) + setTimeout(operation(cm, function(){if (counter == curCount) extend(e);}), 150); + } else { + var outside = e.clientY < editorSize.top ? -20 : e.clientY > editorSize.bottom ? 20 : 0; + if (outside) setTimeout(operation(cm, function() { + if (counter != curCount) return; + display.scroller.scrollTop += outside; + extend(e); + }), 50); + } + } + + function done(e) { + counter = Infinity; + e_preventDefault(e); + focusInput(cm); + off(document, "mousemove", move); + off(document, "mouseup", up); + } + + var move = operation(cm, function(e) { + if (!ie && !e_button(e)) done(e); + else extend(e); + }); + var up = operation(cm, done); + on(document, "mousemove", move); + on(document, "mouseup", up); + } + + function gutterEvent(cm, e, type, prevent, signalfn) { + try { var mX = e.clientX, mY = e.clientY; } + catch(e) { return false; } + if (mX >= Math.floor(getRect(cm.display.gutters).right)) return false; + if (prevent) e_preventDefault(e); + + var display = cm.display; + var lineBox = getRect(display.lineDiv); + + if (mY > lineBox.bottom || !hasHandler(cm, type)) return e_defaultPrevented(e); + mY -= lineBox.top - display.viewOffset; + + for (var i = 0; i < cm.options.gutters.length; ++i) { + var g = display.gutters.childNodes[i]; + if (g && getRect(g).right >= mX) { + var line = lineAtHeight(cm.doc, mY); + var gutter = cm.options.gutters[i]; + signalfn(cm, type, cm, line, gutter, e); + return e_defaultPrevented(e); + } + } + } + + function contextMenuInGutter(cm, e) { + if (!hasHandler(cm, "gutterContextMenu")) return false; + return gutterEvent(cm, e, "gutterContextMenu", false, signal); + } + + function clickInGutter(cm, e) { + return gutterEvent(cm, e, "gutterClick", true, signalLater); + } + + // Kludge to work around strange IE behavior where it'll sometimes + // re-fire a series of drag-related events right after the drop (#1551) + var lastDrop = 0; + + function onDrop(e) { + var cm = this; + if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e) || (cm.options.onDragEvent && cm.options.onDragEvent(cm, addStop(e)))) + return; + e_preventDefault(e); + if (ie) lastDrop = +new Date; + var pos = posFromMouse(cm, e, true), files = e.dataTransfer.files; + if (!pos || isReadOnly(cm)) return; + if (files && files.length && window.FileReader && window.File) { + var n = files.length, text = Array(n), read = 0; + var loadFile = function(file, i) { + var reader = new FileReader; + reader.onload = function() { + text[i] = reader.result; + if (++read == n) { + pos = clipPos(cm.doc, pos); + makeChange(cm.doc, {from: pos, to: pos, text: splitLines(text.join("\n")), origin: "paste"}, "around"); + } + }; + reader.readAsText(file); + }; + for (var i = 0; i < n; ++i) loadFile(files[i], i); + } else { + // Don't do a replace if the drop happened inside of the selected text. + if (cm.state.draggingText && !(posLess(pos, cm.doc.sel.from) || posLess(cm.doc.sel.to, pos))) { + cm.state.draggingText(e); + // Ensure the editor is re-focused + setTimeout(bind(focusInput, cm), 20); + return; + } + try { + var text = e.dataTransfer.getData("Text"); + if (text) { + var curFrom = cm.doc.sel.from, curTo = cm.doc.sel.to; + setSelection(cm.doc, pos, pos); + if (cm.state.draggingText) replaceRange(cm.doc, "", curFrom, curTo, "paste"); + cm.replaceSelection(text, null, "paste"); + focusInput(cm); + onFocus(cm); + } + } + catch(e){} + } + } + + function onDragStart(cm, e) { + if (ie && (!cm.state.draggingText || +new Date - lastDrop < 100)) { e_stop(e); return; } + if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) return; + + var txt = cm.getSelection(); + e.dataTransfer.setData("Text", txt); + + // Use dummy image instead of default browsers image. + // Recent Safari (~6.0.2) have a tendency to segfault when this happens, so we don't do it there. + if (e.dataTransfer.setDragImage && !safari) { + var img = elt("img", null, null, "position: fixed; left: 0; top: 0;"); + img.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="; + if (opera) { + img.width = img.height = 1; + cm.display.wrapper.appendChild(img); + // Force a relayout, or Opera won't use our image for some obscure reason + img._top = img.offsetTop; + } + e.dataTransfer.setDragImage(img, 0, 0); + if (opera) img.parentNode.removeChild(img); + } + } + + function setScrollTop(cm, val) { + if (Math.abs(cm.doc.scrollTop - val) < 2) return; + cm.doc.scrollTop = val; + if (!gecko) updateDisplay(cm, [], val); + if (cm.display.scroller.scrollTop != val) cm.display.scroller.scrollTop = val; + if (cm.display.scrollbarV.scrollTop != val) cm.display.scrollbarV.scrollTop = val; + if (gecko) updateDisplay(cm, []); + startWorker(cm, 100); + } + function setScrollLeft(cm, val, isScroller) { + if (isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) return; + val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth); + cm.doc.scrollLeft = val; + alignHorizontally(cm); + if (cm.display.scroller.scrollLeft != val) cm.display.scroller.scrollLeft = val; + if (cm.display.scrollbarH.scrollLeft != val) cm.display.scrollbarH.scrollLeft = val; + } + + // Since the delta values reported on mouse wheel events are + // unstandardized between browsers and even browser versions, and + // generally horribly unpredictable, this code starts by measuring + // the scroll effect that the first few mouse wheel events have, + // and, from that, detects the way it can convert deltas to pixel + // offsets afterwards. + // + // The reason we want to know the amount a wheel event will scroll + // is that it gives us a chance to update the display before the + // actual scrolling happens, reducing flickering. + + var wheelSamples = 0, wheelPixelsPerUnit = null; + // Fill in a browser-detected starting value on browsers where we + // know one. These don't have to be accurate -- the result of them + // being wrong would just be a slight flicker on the first wheel + // scroll (if it is large enough). + if (ie) wheelPixelsPerUnit = -.53; + else if (gecko) wheelPixelsPerUnit = 15; + else if (chrome) wheelPixelsPerUnit = -.7; + else if (safari) wheelPixelsPerUnit = -1/3; + + function onScrollWheel(cm, e) { + var dx = e.wheelDeltaX, dy = e.wheelDeltaY; + if (dx == null && e.detail && e.axis == e.HORIZONTAL_AXIS) dx = e.detail; + if (dy == null && e.detail && e.axis == e.VERTICAL_AXIS) dy = e.detail; + else if (dy == null) dy = e.wheelDelta; + + var display = cm.display, scroll = display.scroller; + // Quit if there's nothing to scroll here + if (!(dx && scroll.scrollWidth > scroll.clientWidth || + dy && scroll.scrollHeight > scroll.clientHeight)) return; + + // Webkit browsers on OS X abort momentum scrolls when the target + // of the scroll event is removed from the scrollable element. + // This hack (see related code in patchDisplay) makes sure the + // element is kept around. + if (dy && mac && webkit) { + for (var cur = e.target; cur != scroll; cur = cur.parentNode) { + if (cur.lineObj) { + cm.display.currentWheelTarget = cur; + break; + } + } + } + + // On some browsers, horizontal scrolling will cause redraws to + // happen before the gutter has been realigned, causing it to + // wriggle around in a most unseemly way. When we have an + // estimated pixels/delta value, we just handle horizontal + // scrolling entirely here. It'll be slightly off from native, but + // better than glitching out. + if (dx && !gecko && !opera && wheelPixelsPerUnit != null) { + if (dy) + setScrollTop(cm, Math.max(0, Math.min(scroll.scrollTop + dy * wheelPixelsPerUnit, scroll.scrollHeight - scroll.clientHeight))); + setScrollLeft(cm, Math.max(0, Math.min(scroll.scrollLeft + dx * wheelPixelsPerUnit, scroll.scrollWidth - scroll.clientWidth))); + e_preventDefault(e); + display.wheelStartX = null; // Abort measurement, if in progress + return; + } + + if (dy && wheelPixelsPerUnit != null) { + var pixels = dy * wheelPixelsPerUnit; + var top = cm.doc.scrollTop, bot = top + display.wrapper.clientHeight; + if (pixels < 0) top = Math.max(0, top + pixels - 50); + else bot = Math.min(cm.doc.height, bot + pixels + 50); + updateDisplay(cm, [], {top: top, bottom: bot}); + } + + if (wheelSamples < 20) { + if (display.wheelStartX == null) { + display.wheelStartX = scroll.scrollLeft; display.wheelStartY = scroll.scrollTop; + display.wheelDX = dx; display.wheelDY = dy; + setTimeout(function() { + if (display.wheelStartX == null) return; + var movedX = scroll.scrollLeft - display.wheelStartX; + var movedY = scroll.scrollTop - display.wheelStartY; + var sample = (movedY && display.wheelDY && movedY / display.wheelDY) || + (movedX && display.wheelDX && movedX / display.wheelDX); + display.wheelStartX = display.wheelStartY = null; + if (!sample) return; + wheelPixelsPerUnit = (wheelPixelsPerUnit * wheelSamples + sample) / (wheelSamples + 1); + ++wheelSamples; + }, 200); + } else { + display.wheelDX += dx; display.wheelDY += dy; + } + } + } + + function doHandleBinding(cm, bound, dropShift) { + if (typeof bound == "string") { + bound = commands[bound]; + if (!bound) return false; + } + // Ensure previous input has been read, so that the handler sees a + // consistent view of the document + if (cm.display.pollingFast && readInput(cm)) cm.display.pollingFast = false; + var doc = cm.doc, prevShift = doc.sel.shift, done = false; + try { + if (isReadOnly(cm)) cm.state.suppressEdits = true; + if (dropShift) doc.sel.shift = false; + done = bound(cm) != Pass; + } finally { + doc.sel.shift = prevShift; + cm.state.suppressEdits = false; + } + return done; + } + + function allKeyMaps(cm) { + var maps = cm.state.keyMaps.slice(0); + if (cm.options.extraKeys) maps.push(cm.options.extraKeys); + maps.push(cm.options.keyMap); + return maps; + } + + var maybeTransition; + function handleKeyBinding(cm, e) { + // Handle auto keymap transitions + var startMap = getKeyMap(cm.options.keyMap), next = startMap.auto; + clearTimeout(maybeTransition); + if (next && !isModifierKey(e)) maybeTransition = setTimeout(function() { + if (getKeyMap(cm.options.keyMap) == startMap) { + cm.options.keyMap = (next.call ? next.call(null, cm) : next); + keyMapChanged(cm); + } + }, 50); + + var name = keyName(e, true), handled = false; + if (!name) return false; + var keymaps = allKeyMaps(cm); + + if (e.shiftKey) { + // First try to resolve full name (including 'Shift-'). Failing + // that, see if there is a cursor-motion command (starting with + // 'go') bound to the keyname without 'Shift-'. + handled = lookupKey("Shift-" + name, keymaps, function(b) {return doHandleBinding(cm, b, true);}) + || lookupKey(name, keymaps, function(b) { + if (typeof b == "string" ? /^go[A-Z]/.test(b) : b.motion) + return doHandleBinding(cm, b); + }); + } else { + handled = lookupKey(name, keymaps, function(b) { return doHandleBinding(cm, b); }); + } + + if (handled) { + e_preventDefault(e); + restartBlink(cm); + if (ie_lt9) { e.oldKeyCode = e.keyCode; e.keyCode = 0; } + signalLater(cm, "keyHandled", cm, name, e); + } + return handled; + } + + function handleCharBinding(cm, e, ch) { + var handled = lookupKey("'" + ch + "'", allKeyMaps(cm), + function(b) { return doHandleBinding(cm, b, true); }); + if (handled) { + e_preventDefault(e); + restartBlink(cm); + signalLater(cm, "keyHandled", cm, "'" + ch + "'", e); + } + return handled; + } + + var lastStoppedKey = null; + function onKeyDown(e) { + var cm = this; + if (!cm.state.focused) onFocus(cm); + if (signalDOMEvent(cm, e) || cm.options.onKeyEvent && cm.options.onKeyEvent(cm, addStop(e))) return; + if (ie && e.keyCode == 27) e.returnValue = false; + var code = e.keyCode; + // IE does strange things with escape. + cm.doc.sel.shift = code == 16 || e.shiftKey; + // First give onKeyEvent option a chance to handle this. + var handled = handleKeyBinding(cm, e); + if (opera) { + lastStoppedKey = handled ? code : null; + // Opera has no cut event... we try to at least catch the key combo + if (!handled && code == 88 && !hasCopyEvent && (mac ? e.metaKey : e.ctrlKey)) + cm.replaceSelection(""); + } + } + + function onKeyPress(e) { + var cm = this; + if (signalDOMEvent(cm, e) || cm.options.onKeyEvent && cm.options.onKeyEvent(cm, addStop(e))) return; + var keyCode = e.keyCode, charCode = e.charCode; + if (opera && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return;} + if (((opera && (!e.which || e.which < 10)) || khtml) && handleKeyBinding(cm, e)) return; + var ch = String.fromCharCode(charCode == null ? keyCode : charCode); + if (this.options.electricChars && this.doc.mode.electricChars && + this.options.smartIndent && !isReadOnly(this) && + this.doc.mode.electricChars.indexOf(ch) > -1) + setTimeout(operation(cm, function() {indentLine(cm, cm.doc.sel.to.line, "smart");}), 75); + if (handleCharBinding(cm, e, ch)) return; + if (ie && !ie_lt9) cm.display.inputHasSelection = null; + fastPoll(cm); + } + + function onFocus(cm) { + if (cm.options.readOnly == "nocursor") return; + if (!cm.state.focused) { + signal(cm, "focus", cm); + cm.state.focused = true; + if (cm.display.wrapper.className.search(/\bCodeMirror-focused\b/) == -1) + cm.display.wrapper.className += " CodeMirror-focused"; + if (!cm.curOp) { + resetInput(cm, true); + if (webkit) setTimeout(bind(resetInput, cm, true), 0); // Issue #1730 + } + } + slowPoll(cm); + restartBlink(cm); + } + function onBlur(cm) { + if (cm.state.focused) { + signal(cm, "blur", cm); + cm.state.focused = false; + cm.display.wrapper.className = cm.display.wrapper.className.replace(" CodeMirror-focused", ""); + } + clearInterval(cm.display.blinker); + setTimeout(function() {if (!cm.state.focused) cm.doc.sel.shift = false;}, 150); + } + + var detectingSelectAll; + function onContextMenu(cm, e) { + if (signalDOMEvent(cm, e, "contextmenu")) return; + var display = cm.display, sel = cm.doc.sel; + if (eventInWidget(display, e) || contextMenuInGutter(cm, e)) return; + + var pos = posFromMouse(cm, e), scrollPos = display.scroller.scrollTop; + if (!pos || opera) return; // Opera is difficult. + if (posEq(sel.from, sel.to) || posLess(pos, sel.from) || !posLess(pos, sel.to)) + operation(cm, setSelection)(cm.doc, pos, pos); + + var oldCSS = display.input.style.cssText; + display.inputDiv.style.position = "absolute"; + display.input.style.cssText = "position: fixed; width: 30px; height: 30px; top: " + (e.clientY - 5) + + "px; left: " + (e.clientX - 5) + "px; z-index: 1000; background: white; outline: none;" + + "border-width: 0; outline: none; overflow: hidden; opacity: .05; -ms-opacity: .05; filter: alpha(opacity=5);"; + focusInput(cm); + resetInput(cm, true); + // Adds "Select all" to context menu in FF + if (posEq(sel.from, sel.to)) display.input.value = display.prevInput = " "; + + function prepareSelectAllHack() { + if (display.input.selectionStart != null) { + var extval = display.input.value = "\u200b" + (posEq(sel.from, sel.to) ? "" : display.input.value); + display.prevInput = "\u200b"; + display.input.selectionStart = 1; display.input.selectionEnd = extval.length; + } + } + function rehide() { + display.inputDiv.style.position = "relative"; + display.input.style.cssText = oldCSS; + if (ie_lt9) display.scrollbarV.scrollTop = display.scroller.scrollTop = scrollPos; + slowPoll(cm); + + // Try to detect the user choosing select-all + if (display.input.selectionStart != null) { + if (!ie || ie_lt9) prepareSelectAllHack(); + clearTimeout(detectingSelectAll); + var i = 0, poll = function(){ + if (display.prevInput == " " && display.input.selectionStart == 0) + operation(cm, commands.selectAll)(cm); + else if (i++ < 10) detectingSelectAll = setTimeout(poll, 500); + else resetInput(cm); + }; + detectingSelectAll = setTimeout(poll, 200); + } + } + + if (ie && !ie_lt9) prepareSelectAllHack(); + if (captureMiddleClick) { + e_stop(e); + var mouseup = function() { + off(window, "mouseup", mouseup); + setTimeout(rehide, 20); + }; + on(window, "mouseup", mouseup); + } else { + setTimeout(rehide, 50); + } + } + + // UPDATING + + var changeEnd = CodeMirror.changeEnd = function(change) { + if (!change.text) return change.to; + return Pos(change.from.line + change.text.length - 1, + lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0)); + }; + + // Make sure a position will be valid after the given change. + function clipPostChange(doc, change, pos) { + if (!posLess(change.from, pos)) return clipPos(doc, pos); + var diff = (change.text.length - 1) - (change.to.line - change.from.line); + if (pos.line > change.to.line + diff) { + var preLine = pos.line - diff, lastLine = doc.first + doc.size - 1; + if (preLine > lastLine) return Pos(lastLine, getLine(doc, lastLine).text.length); + return clipToLen(pos, getLine(doc, preLine).text.length); + } + if (pos.line == change.to.line + diff) + return clipToLen(pos, lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0) + + getLine(doc, change.to.line).text.length - change.to.ch); + var inside = pos.line - change.from.line; + return clipToLen(pos, change.text[inside].length + (inside ? 0 : change.from.ch)); + } + + // Hint can be null|"end"|"start"|"around"|{anchor,head} + function computeSelAfterChange(doc, change, hint) { + if (hint && typeof hint == "object") // Assumed to be {anchor, head} object + return {anchor: clipPostChange(doc, change, hint.anchor), + head: clipPostChange(doc, change, hint.head)}; + + if (hint == "start") return {anchor: change.from, head: change.from}; + + var end = changeEnd(change); + if (hint == "around") return {anchor: change.from, head: end}; + if (hint == "end") return {anchor: end, head: end}; + + // hint is null, leave the selection alone as much as possible + var adjustPos = function(pos) { + if (posLess(pos, change.from)) return pos; + if (!posLess(change.to, pos)) return end; + + var line = pos.line + change.text.length - (change.to.line - change.from.line) - 1, ch = pos.ch; + if (pos.line == change.to.line) ch += end.ch - change.to.ch; + return Pos(line, ch); + }; + return {anchor: adjustPos(doc.sel.anchor), head: adjustPos(doc.sel.head)}; + } + + function filterChange(doc, change, update) { + var obj = { + canceled: false, + from: change.from, + to: change.to, + text: change.text, + origin: change.origin, + cancel: function() { this.canceled = true; } + }; + if (update) obj.update = function(from, to, text, origin) { + if (from) this.from = clipPos(doc, from); + if (to) this.to = clipPos(doc, to); + if (text) this.text = text; + if (origin !== undefined) this.origin = origin; + }; + signal(doc, "beforeChange", doc, obj); + if (doc.cm) signal(doc.cm, "beforeChange", doc.cm, obj); + + if (obj.canceled) return null; + return {from: obj.from, to: obj.to, text: obj.text, origin: obj.origin}; + } + + // Replace the range from from to to by the strings in replacement. + // change is a {from, to, text [, origin]} object + function makeChange(doc, change, selUpdate, ignoreReadOnly) { + if (doc.cm) { + if (!doc.cm.curOp) return operation(doc.cm, makeChange)(doc, change, selUpdate, ignoreReadOnly); + if (doc.cm.state.suppressEdits) return; + } + + if (hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange")) { + change = filterChange(doc, change, true); + if (!change) return; + } + + // Possibly split or suppress the update based on the presence + // of read-only spans in its range. + var split = sawReadOnlySpans && !ignoreReadOnly && removeReadOnlyRanges(doc, change.from, change.to); + if (split) { + for (var i = split.length - 1; i >= 1; --i) + makeChangeNoReadonly(doc, {from: split[i].from, to: split[i].to, text: [""]}); + if (split.length) + makeChangeNoReadonly(doc, {from: split[0].from, to: split[0].to, text: change.text}, selUpdate); + } else { + makeChangeNoReadonly(doc, change, selUpdate); + } + } + + function makeChangeNoReadonly(doc, change, selUpdate) { + if (change.text.length == 1 && change.text[0] == "" && posEq(change.from, change.to)) return; + var selAfter = computeSelAfterChange(doc, change, selUpdate); + addToHistory(doc, change, selAfter, doc.cm ? doc.cm.curOp.id : NaN); + + makeChangeSingleDoc(doc, change, selAfter, stretchSpansOverChange(doc, change)); + var rebased = []; + + linkedDocs(doc, function(doc, sharedHist) { + if (!sharedHist && indexOf(rebased, doc.history) == -1) { + rebaseHist(doc.history, change); + rebased.push(doc.history); + } + makeChangeSingleDoc(doc, change, null, stretchSpansOverChange(doc, change)); + }); + } + + function makeChangeFromHistory(doc, type) { + if (doc.cm && doc.cm.state.suppressEdits) return; + + var hist = doc.history; + var event = (type == "undo" ? hist.done : hist.undone).pop(); + if (!event) return; + + var anti = {changes: [], anchorBefore: event.anchorAfter, headBefore: event.headAfter, + anchorAfter: event.anchorBefore, headAfter: event.headBefore, + generation: hist.generation}; + (type == "undo" ? hist.undone : hist.done).push(anti); + hist.generation = event.generation || ++hist.maxGeneration; + + var filter = hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange"); + + for (var i = event.changes.length - 1; i >= 0; --i) { + var change = event.changes[i]; + change.origin = type; + if (filter && !filterChange(doc, change, false)) { + (type == "undo" ? hist.done : hist.undone).length = 0; + return; + } + + anti.changes.push(historyChangeFromChange(doc, change)); + + var after = i ? computeSelAfterChange(doc, change, null) + : {anchor: event.anchorBefore, head: event.headBefore}; + makeChangeSingleDoc(doc, change, after, mergeOldSpans(doc, change)); + var rebased = []; + + linkedDocs(doc, function(doc, sharedHist) { + if (!sharedHist && indexOf(rebased, doc.history) == -1) { + rebaseHist(doc.history, change); + rebased.push(doc.history); + } + makeChangeSingleDoc(doc, change, null, mergeOldSpans(doc, change)); + }); + } + } + + function shiftDoc(doc, distance) { + function shiftPos(pos) {return Pos(pos.line + distance, pos.ch);} + doc.first += distance; + if (doc.cm) regChange(doc.cm, doc.first, doc.first, distance); + doc.sel.head = shiftPos(doc.sel.head); doc.sel.anchor = shiftPos(doc.sel.anchor); + doc.sel.from = shiftPos(doc.sel.from); doc.sel.to = shiftPos(doc.sel.to); + } + + function makeChangeSingleDoc(doc, change, selAfter, spans) { + if (doc.cm && !doc.cm.curOp) + return operation(doc.cm, makeChangeSingleDoc)(doc, change, selAfter, spans); + + if (change.to.line < doc.first) { + shiftDoc(doc, change.text.length - 1 - (change.to.line - change.from.line)); + return; + } + if (change.from.line > doc.lastLine()) return; + + // Clip the change to the size of this doc + if (change.from.line < doc.first) { + var shift = change.text.length - 1 - (doc.first - change.from.line); + shiftDoc(doc, shift); + change = {from: Pos(doc.first, 0), to: Pos(change.to.line + shift, change.to.ch), + text: [lst(change.text)], origin: change.origin}; + } + var last = doc.lastLine(); + if (change.to.line > last) { + change = {from: change.from, to: Pos(last, getLine(doc, last).text.length), + text: [change.text[0]], origin: change.origin}; + } + + change.removed = getBetween(doc, change.from, change.to); + + if (!selAfter) selAfter = computeSelAfterChange(doc, change, null); + if (doc.cm) makeChangeSingleDocInEditor(doc.cm, change, spans, selAfter); + else updateDoc(doc, change, spans, selAfter); + } + + function makeChangeSingleDocInEditor(cm, change, spans, selAfter) { + var doc = cm.doc, display = cm.display, from = change.from, to = change.to; + + var recomputeMaxLength = false, checkWidthStart = from.line; + if (!cm.options.lineWrapping) { + checkWidthStart = lineNo(visualLine(doc, getLine(doc, from.line))); + doc.iter(checkWidthStart, to.line + 1, function(line) { + if (line == display.maxLine) { + recomputeMaxLength = true; + return true; + } + }); + } + + if (!posLess(doc.sel.head, change.from) && !posLess(change.to, doc.sel.head)) + cm.curOp.cursorActivity = true; + + updateDoc(doc, change, spans, selAfter, estimateHeight(cm)); + + if (!cm.options.lineWrapping) { + doc.iter(checkWidthStart, from.line + change.text.length, function(line) { + var len = lineLength(doc, line); + if (len > display.maxLineLength) { + display.maxLine = line; + display.maxLineLength = len; + display.maxLineChanged = true; + recomputeMaxLength = false; + } + }); + if (recomputeMaxLength) cm.curOp.updateMaxLine = true; + } + + // Adjust frontier, schedule worker + doc.frontier = Math.min(doc.frontier, from.line); + startWorker(cm, 400); + + var lendiff = change.text.length - (to.line - from.line) - 1; + // Remember that these lines changed, for updating the display + regChange(cm, from.line, to.line + 1, lendiff); + + if (hasHandler(cm, "change")) { + var changeObj = {from: from, to: to, + text: change.text, + removed: change.removed, + origin: change.origin}; + if (cm.curOp.textChanged) { + for (var cur = cm.curOp.textChanged; cur.next; cur = cur.next) {} + cur.next = changeObj; + } else cm.curOp.textChanged = changeObj; + } + } + + function replaceRange(doc, code, from, to, origin) { + if (!to) to = from; + if (posLess(to, from)) { var tmp = to; to = from; from = tmp; } + if (typeof code == "string") code = splitLines(code); + makeChange(doc, {from: from, to: to, text: code, origin: origin}, null); + } + + // POSITION OBJECT + + function Pos(line, ch) { + if (!(this instanceof Pos)) return new Pos(line, ch); + this.line = line; this.ch = ch; + } + CodeMirror.Pos = Pos; + + function posEq(a, b) {return a.line == b.line && a.ch == b.ch;} + function posLess(a, b) {return a.line < b.line || (a.line == b.line && a.ch < b.ch);} + function copyPos(x) {return Pos(x.line, x.ch);} + + // SELECTION + + function clipLine(doc, n) {return Math.max(doc.first, Math.min(n, doc.first + doc.size - 1));} + function clipPos(doc, pos) { + if (pos.line < doc.first) return Pos(doc.first, 0); + var last = doc.first + doc.size - 1; + if (pos.line > last) return Pos(last, getLine(doc, last).text.length); + return clipToLen(pos, getLine(doc, pos.line).text.length); + } + function clipToLen(pos, linelen) { + var ch = pos.ch; + if (ch == null || ch > linelen) return Pos(pos.line, linelen); + else if (ch < 0) return Pos(pos.line, 0); + else return pos; + } + function isLine(doc, l) {return l >= doc.first && l < doc.first + doc.size;} + + // If shift is held, this will move the selection anchor. Otherwise, + // it'll set the whole selection. + function extendSelection(doc, pos, other, bias) { + if (doc.sel.shift || doc.sel.extend) { + var anchor = doc.sel.anchor; + if (other) { + var posBefore = posLess(pos, anchor); + if (posBefore != posLess(other, anchor)) { + anchor = pos; + pos = other; + } else if (posBefore != posLess(pos, other)) { + pos = other; + } + } + setSelection(doc, anchor, pos, bias); + } else { + setSelection(doc, pos, other || pos, bias); + } + if (doc.cm) doc.cm.curOp.userSelChange = true; + } + + function filterSelectionChange(doc, anchor, head) { + var obj = {anchor: anchor, head: head}; + signal(doc, "beforeSelectionChange", doc, obj); + if (doc.cm) signal(doc.cm, "beforeSelectionChange", doc.cm, obj); + obj.anchor = clipPos(doc, obj.anchor); obj.head = clipPos(doc, obj.head); + return obj; + } + + // Update the selection. Last two args are only used by + // updateDoc, since they have to be expressed in the line + // numbers before the update. + function setSelection(doc, anchor, head, bias, checkAtomic) { + if (!checkAtomic && hasHandler(doc, "beforeSelectionChange") || doc.cm && hasHandler(doc.cm, "beforeSelectionChange")) { + var filtered = filterSelectionChange(doc, anchor, head); + head = filtered.head; + anchor = filtered.anchor; + } + + var sel = doc.sel; + sel.goalColumn = null; + if (bias == null) bias = posLess(head, sel.head) ? -1 : 1; + // Skip over atomic spans. + if (checkAtomic || !posEq(anchor, sel.anchor)) + anchor = skipAtomic(doc, anchor, bias, checkAtomic != "push"); + if (checkAtomic || !posEq(head, sel.head)) + head = skipAtomic(doc, head, bias, checkAtomic != "push"); + + if (posEq(sel.anchor, anchor) && posEq(sel.head, head)) return; + + sel.anchor = anchor; sel.head = head; + var inv = posLess(head, anchor); + sel.from = inv ? head : anchor; + sel.to = inv ? anchor : head; + + if (doc.cm) + doc.cm.curOp.updateInput = doc.cm.curOp.selectionChanged = + doc.cm.curOp.cursorActivity = true; + + signalLater(doc, "cursorActivity", doc); + } + + function reCheckSelection(cm) { + setSelection(cm.doc, cm.doc.sel.from, cm.doc.sel.to, null, "push"); + } + + function skipAtomic(doc, pos, bias, mayClear) { + var flipped = false, curPos = pos; + var dir = bias || 1; + doc.cantEdit = false; + search: for (;;) { + var line = getLine(doc, curPos.line); + if (line.markedSpans) { + for (var i = 0; i < line.markedSpans.length; ++i) { + var sp = line.markedSpans[i], m = sp.marker; + if ((sp.from == null || (m.inclusiveLeft ? sp.from <= curPos.ch : sp.from < curPos.ch)) && + (sp.to == null || (m.inclusiveRight ? sp.to >= curPos.ch : sp.to > curPos.ch))) { + if (mayClear) { + signal(m, "beforeCursorEnter"); + if (m.explicitlyCleared) { + if (!line.markedSpans) break; + else {--i; continue;} + } + } + if (!m.atomic) continue; + var newPos = m.find()[dir < 0 ? "from" : "to"]; + if (posEq(newPos, curPos)) { + newPos.ch += dir; + if (newPos.ch < 0) { + if (newPos.line > doc.first) newPos = clipPos(doc, Pos(newPos.line - 1)); + else newPos = null; + } else if (newPos.ch > line.text.length) { + if (newPos.line < doc.first + doc.size - 1) newPos = Pos(newPos.line + 1, 0); + else newPos = null; + } + if (!newPos) { + if (flipped) { + // Driven in a corner -- no valid cursor position found at all + // -- try again *with* clearing, if we didn't already + if (!mayClear) return skipAtomic(doc, pos, bias, true); + // Otherwise, turn off editing until further notice, and return the start of the doc + doc.cantEdit = true; + return Pos(doc.first, 0); + } + flipped = true; newPos = pos; dir = -dir; + } + } + curPos = newPos; + continue search; + } + } + } + return curPos; + } + } + + // SCROLLING + + function scrollCursorIntoView(cm) { + var coords = scrollPosIntoView(cm, cm.doc.sel.head, cm.options.cursorScrollMargin); + if (!cm.state.focused) return; + var display = cm.display, box = getRect(display.sizer), doScroll = null; + if (coords.top + box.top < 0) doScroll = true; + else if (coords.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) doScroll = false; + if (doScroll != null && !phantom) { + var hidden = display.cursor.style.display == "none"; + if (hidden) { + display.cursor.style.display = ""; + display.cursor.style.left = coords.left + "px"; + display.cursor.style.top = (coords.top - display.viewOffset) + "px"; + } + display.cursor.scrollIntoView(doScroll); + if (hidden) display.cursor.style.display = "none"; + } + } + + function scrollPosIntoView(cm, pos, margin) { + if (margin == null) margin = 0; + for (;;) { + var changed = false, coords = cursorCoords(cm, pos); + var scrollPos = calculateScrollPos(cm, coords.left, coords.top - margin, coords.left, coords.bottom + margin); + var startTop = cm.doc.scrollTop, startLeft = cm.doc.scrollLeft; + if (scrollPos.scrollTop != null) { + setScrollTop(cm, scrollPos.scrollTop); + if (Math.abs(cm.doc.scrollTop - startTop) > 1) changed = true; + } + if (scrollPos.scrollLeft != null) { + setScrollLeft(cm, scrollPos.scrollLeft); + if (Math.abs(cm.doc.scrollLeft - startLeft) > 1) changed = true; + } + if (!changed) return coords; + } + } + + function scrollIntoView(cm, x1, y1, x2, y2) { + var scrollPos = calculateScrollPos(cm, x1, y1, x2, y2); + if (scrollPos.scrollTop != null) setScrollTop(cm, scrollPos.scrollTop); + if (scrollPos.scrollLeft != null) setScrollLeft(cm, scrollPos.scrollLeft); + } + + function calculateScrollPos(cm, x1, y1, x2, y2) { + var display = cm.display, snapMargin = textHeight(cm.display); + if (y1 < 0) y1 = 0; + var screen = display.scroller.clientHeight - scrollerCutOff, screentop = display.scroller.scrollTop, result = {}; + var docBottom = cm.doc.height + paddingVert(display); + var atTop = y1 < snapMargin, atBottom = y2 > docBottom - snapMargin; + if (y1 < screentop) { + result.scrollTop = atTop ? 0 : y1; + } else if (y2 > screentop + screen) { + var newTop = Math.min(y1, (atBottom ? docBottom : y2) - screen); + if (newTop != screentop) result.scrollTop = newTop; + } + + var screenw = display.scroller.clientWidth - scrollerCutOff, screenleft = display.scroller.scrollLeft; + x1 += display.gutters.offsetWidth; x2 += display.gutters.offsetWidth; + var gutterw = display.gutters.offsetWidth; + var atLeft = x1 < gutterw + 10; + if (x1 < screenleft + gutterw || atLeft) { + if (atLeft) x1 = 0; + result.scrollLeft = Math.max(0, x1 - 10 - gutterw); + } else if (x2 > screenw + screenleft - 3) { + result.scrollLeft = x2 + 10 - screenw; + } + return result; + } + + function updateScrollPos(cm, left, top) { + cm.curOp.updateScrollPos = {scrollLeft: left == null ? cm.doc.scrollLeft : left, + scrollTop: top == null ? cm.doc.scrollTop : top}; + } + + function addToScrollPos(cm, left, top) { + var pos = cm.curOp.updateScrollPos || (cm.curOp.updateScrollPos = {scrollLeft: cm.doc.scrollLeft, scrollTop: cm.doc.scrollTop}); + var scroll = cm.display.scroller; + pos.scrollTop = Math.max(0, Math.min(scroll.scrollHeight - scroll.clientHeight, pos.scrollTop + top)); + pos.scrollLeft = Math.max(0, Math.min(scroll.scrollWidth - scroll.clientWidth, pos.scrollLeft + left)); + } + + // API UTILITIES + + function indentLine(cm, n, how, aggressive) { + var doc = cm.doc; + if (how == null) how = "add"; + if (how == "smart") { + if (!cm.doc.mode.indent) how = "prev"; + else var state = getStateBefore(cm, n); + } + + var tabSize = cm.options.tabSize; + var line = getLine(doc, n), curSpace = countColumn(line.text, null, tabSize); + var curSpaceString = line.text.match(/^\s*/)[0], indentation; + if (how == "smart") { + indentation = cm.doc.mode.indent(state, line.text.slice(curSpaceString.length), line.text); + if (indentation == Pass) { + if (!aggressive) return; + how = "prev"; + } + } + if (how == "prev") { + if (n > doc.first) indentation = countColumn(getLine(doc, n-1).text, null, tabSize); + else indentation = 0; + } else if (how == "add") { + indentation = curSpace + cm.options.indentUnit; + } else if (how == "subtract") { + indentation = curSpace - cm.options.indentUnit; + } else if (typeof how == "number") { + indentation = curSpace + how; + } + indentation = Math.max(0, indentation); + + var indentString = "", pos = 0; + if (cm.options.indentWithTabs) + for (var i = Math.floor(indentation / tabSize); i; --i) {pos += tabSize; indentString += "\t";} + if (pos < indentation) indentString += spaceStr(indentation - pos); + + if (indentString != curSpaceString) + replaceRange(cm.doc, indentString, Pos(n, 0), Pos(n, curSpaceString.length), "+input"); + line.stateAfter = null; + } + + function changeLine(cm, handle, op) { + var no = handle, line = handle, doc = cm.doc; + if (typeof handle == "number") line = getLine(doc, clipLine(doc, handle)); + else no = lineNo(handle); + if (no == null) return null; + if (op(line, no)) regChange(cm, no, no + 1); + else return null; + return line; + } + + function findPosH(doc, pos, dir, unit, visually) { + var line = pos.line, ch = pos.ch, origDir = dir; + var lineObj = getLine(doc, line); + var possible = true; + function findNextLine() { + var l = line + dir; + if (l < doc.first || l >= doc.first + doc.size) return (possible = false); + line = l; + return lineObj = getLine(doc, l); + } + function moveOnce(boundToLine) { + var next = (visually ? moveVisually : moveLogically)(lineObj, ch, dir, true); + if (next == null) { + if (!boundToLine && findNextLine()) { + if (visually) ch = (dir < 0 ? lineRight : lineLeft)(lineObj); + else ch = dir < 0 ? lineObj.text.length : 0; + } else return (possible = false); + } else ch = next; + return true; + } + + if (unit == "char") moveOnce(); + else if (unit == "column") moveOnce(true); + else if (unit == "word" || unit == "group") { + var sawType = null, group = unit == "group"; + for (var first = true;; first = false) { + if (dir < 0 && !moveOnce(!first)) break; + var cur = lineObj.text.charAt(ch) || "\n"; + var type = isWordChar(cur) ? "w" + : !group ? null + : /\s/.test(cur) ? null + : "p"; + if (sawType && sawType != type) { + if (dir < 0) {dir = 1; moveOnce();} + break; + } + if (type) sawType = type; + if (dir > 0 && !moveOnce(!first)) break; + } + } + var result = skipAtomic(doc, Pos(line, ch), origDir, true); + if (!possible) result.hitSide = true; + return result; + } + + function findPosV(cm, pos, dir, unit) { + var doc = cm.doc, x = pos.left, y; + if (unit == "page") { + var pageSize = Math.min(cm.display.wrapper.clientHeight, window.innerHeight || document.documentElement.clientHeight); + y = pos.top + dir * (pageSize - (dir < 0 ? 1.5 : .5) * textHeight(cm.display)); + } else if (unit == "line") { + y = dir > 0 ? pos.bottom + 3 : pos.top - 3; + } + for (;;) { + var target = coordsChar(cm, x, y); + if (!target.outside) break; + if (dir < 0 ? y <= 0 : y >= doc.height) { target.hitSide = true; break; } + y += dir * 5; + } + return target; + } + + function findWordAt(line, pos) { + var start = pos.ch, end = pos.ch; + if (line) { + if ((pos.xRel < 0 || end == line.length) && start) --start; else ++end; + var startChar = line.charAt(start); + var check = isWordChar(startChar) ? isWordChar + : /\s/.test(startChar) ? function(ch) {return /\s/.test(ch);} + : function(ch) {return !/\s/.test(ch) && !isWordChar(ch);}; + while (start > 0 && check(line.charAt(start - 1))) --start; + while (end < line.length && check(line.charAt(end))) ++end; + } + return {from: Pos(pos.line, start), to: Pos(pos.line, end)}; + } + + function selectLine(cm, line) { + extendSelection(cm.doc, Pos(line, 0), clipPos(cm.doc, Pos(line + 1, 0))); + } + + // PROTOTYPE + + // The publicly visible API. Note that operation(null, f) means + // 'wrap f in an operation, performed on its `this` parameter' + + CodeMirror.prototype = { + constructor: CodeMirror, + focus: function(){window.focus(); focusInput(this); onFocus(this); fastPoll(this);}, + + setOption: function(option, value) { + var options = this.options, old = options[option]; + if (options[option] == value && option != "mode") return; + options[option] = value; + if (optionHandlers.hasOwnProperty(option)) + operation(this, optionHandlers[option])(this, value, old); + }, + + getOption: function(option) {return this.options[option];}, + getDoc: function() {return this.doc;}, + + addKeyMap: function(map, bottom) { + this.state.keyMaps[bottom ? "push" : "unshift"](map); + }, + removeKeyMap: function(map) { + var maps = this.state.keyMaps; + for (var i = 0; i < maps.length; ++i) + if (maps[i] == map || (typeof maps[i] != "string" && maps[i].name == map)) { + maps.splice(i, 1); + return true; + } + }, + + addOverlay: operation(null, function(spec, options) { + var mode = spec.token ? spec : CodeMirror.getMode(this.options, spec); + if (mode.startState) throw new Error("Overlays may not be stateful."); + this.state.overlays.push({mode: mode, modeSpec: spec, opaque: options && options.opaque}); + this.state.modeGen++; + regChange(this); + }), + removeOverlay: operation(null, function(spec) { + var overlays = this.state.overlays; + for (var i = 0; i < overlays.length; ++i) { + var cur = overlays[i].modeSpec; + if (cur == spec || typeof spec == "string" && cur.name == spec) { + overlays.splice(i, 1); + this.state.modeGen++; + regChange(this); + return; + } + } + }), + + indentLine: operation(null, function(n, dir, aggressive) { + if (typeof dir != "string" && typeof dir != "number") { + if (dir == null) dir = this.options.smartIndent ? "smart" : "prev"; + else dir = dir ? "add" : "subtract"; + } + if (isLine(this.doc, n)) indentLine(this, n, dir, aggressive); + }), + indentSelection: operation(null, function(how) { + var sel = this.doc.sel; + if (posEq(sel.from, sel.to)) return indentLine(this, sel.from.line, how); + var e = sel.to.line - (sel.to.ch ? 0 : 1); + for (var i = sel.from.line; i <= e; ++i) indentLine(this, i, how); + }), + + // Fetch the parser token for a given character. Useful for hacks + // that want to inspect the mode state (say, for completion). + getTokenAt: function(pos, precise) { + var doc = this.doc; + pos = clipPos(doc, pos); + var state = getStateBefore(this, pos.line, precise), mode = this.doc.mode; + var line = getLine(doc, pos.line); + var stream = new StringStream(line.text, this.options.tabSize); + while (stream.pos < pos.ch && !stream.eol()) { + stream.start = stream.pos; + var style = mode.token(stream, state); + } + return {start: stream.start, + end: stream.pos, + string: stream.current(), + className: style || null, // Deprecated, use 'type' instead + type: style || null, + state: state}; + }, + + getTokenTypeAt: function(pos) { + pos = clipPos(this.doc, pos); + var styles = getLineStyles(this, getLine(this.doc, pos.line)); + var before = 0, after = (styles.length - 1) / 2, ch = pos.ch; + if (ch == 0) return styles[2]; + for (;;) { + var mid = (before + after) >> 1; + if ((mid ? styles[mid * 2 - 1] : 0) >= ch) after = mid; + else if (styles[mid * 2 + 1] < ch) before = mid + 1; + else return styles[mid * 2 + 2]; + } + }, + + getModeAt: function(pos) { + var mode = this.doc.mode; + if (!mode.innerMode) return mode; + return CodeMirror.innerMode(mode, this.getTokenAt(pos).state).mode; + }, + + getHelper: function(pos, type) { + if (!helpers.hasOwnProperty(type)) return; + var help = helpers[type], mode = this.getModeAt(pos); + return mode[type] && help[mode[type]] || + mode.helperType && help[mode.helperType] || + help[mode.name]; + }, + + getStateAfter: function(line, precise) { + var doc = this.doc; + line = clipLine(doc, line == null ? doc.first + doc.size - 1: line); + return getStateBefore(this, line + 1, precise); + }, + + cursorCoords: function(start, mode) { + var pos, sel = this.doc.sel; + if (start == null) pos = sel.head; + else if (typeof start == "object") pos = clipPos(this.doc, start); + else pos = start ? sel.from : sel.to; + return cursorCoords(this, pos, mode || "page"); + }, + + charCoords: function(pos, mode) { + return charCoords(this, clipPos(this.doc, pos), mode || "page"); + }, + + coordsChar: function(coords, mode) { + coords = fromCoordSystem(this, coords, mode || "page"); + return coordsChar(this, coords.left, coords.top); + }, + + lineAtHeight: function(height, mode) { + height = fromCoordSystem(this, {top: height, left: 0}, mode || "page").top; + return lineAtHeight(this.doc, height + this.display.viewOffset); + }, + heightAtLine: function(line, mode) { + var end = false, last = this.doc.first + this.doc.size - 1; + if (line < this.doc.first) line = this.doc.first; + else if (line > last) { line = last; end = true; } + var lineObj = getLine(this.doc, line); + return intoCoordSystem(this, getLine(this.doc, line), {top: 0, left: 0}, mode || "page").top + + (end ? lineObj.height : 0); + }, + + defaultTextHeight: function() { return textHeight(this.display); }, + defaultCharWidth: function() { return charWidth(this.display); }, + + setGutterMarker: operation(null, function(line, gutterID, value) { + return changeLine(this, line, function(line) { + var markers = line.gutterMarkers || (line.gutterMarkers = {}); + markers[gutterID] = value; + if (!value && isEmpty(markers)) line.gutterMarkers = null; + return true; + }); + }), + + clearGutter: operation(null, function(gutterID) { + var cm = this, doc = cm.doc, i = doc.first; + doc.iter(function(line) { + if (line.gutterMarkers && line.gutterMarkers[gutterID]) { + line.gutterMarkers[gutterID] = null; + regChange(cm, i, i + 1); + if (isEmpty(line.gutterMarkers)) line.gutterMarkers = null; + } + ++i; + }); + }), + + addLineClass: operation(null, function(handle, where, cls) { + return changeLine(this, handle, function(line) { + var prop = where == "text" ? "textClass" : where == "background" ? "bgClass" : "wrapClass"; + if (!line[prop]) line[prop] = cls; + else if (new RegExp("(?:^|\\s)" + cls + "(?:$|\\s)").test(line[prop])) return false; + else line[prop] += " " + cls; + return true; + }); + }), + + removeLineClass: operation(null, function(handle, where, cls) { + return changeLine(this, handle, function(line) { + var prop = where == "text" ? "textClass" : where == "background" ? "bgClass" : "wrapClass"; + var cur = line[prop]; + if (!cur) return false; + else if (cls == null) line[prop] = null; + else { + var found = cur.match(new RegExp("(?:^|\\s+)" + cls + "(?:$|\\s+)")); + if (!found) return false; + var end = found.index + found[0].length; + line[prop] = cur.slice(0, found.index) + (!found.index || end == cur.length ? "" : " ") + cur.slice(end) || null; + } + return true; + }); + }), + + addLineWidget: operation(null, function(handle, node, options) { + return addLineWidget(this, handle, node, options); + }), + + removeLineWidget: function(widget) { widget.clear(); }, + + lineInfo: function(line) { + if (typeof line == "number") { + if (!isLine(this.doc, line)) return null; + var n = line; + line = getLine(this.doc, line); + if (!line) return null; + } else { + var n = lineNo(line); + if (n == null) return null; + } + return {line: n, handle: line, text: line.text, gutterMarkers: line.gutterMarkers, + textClass: line.textClass, bgClass: line.bgClass, wrapClass: line.wrapClass, + widgets: line.widgets}; + }, + + getViewport: function() { return {from: this.display.showingFrom, to: this.display.showingTo};}, + + addWidget: function(pos, node, scroll, vert, horiz) { + var display = this.display; + pos = cursorCoords(this, clipPos(this.doc, pos)); + var top = pos.bottom, left = pos.left; + node.style.position = "absolute"; + display.sizer.appendChild(node); + if (vert == "over") { + top = pos.top; + } else if (vert == "above" || vert == "near") { + var vspace = Math.max(display.wrapper.clientHeight, this.doc.height), + hspace = Math.max(display.sizer.clientWidth, display.lineSpace.clientWidth); + // Default to positioning above (if specified and possible); otherwise default to positioning below + if ((vert == 'above' || pos.bottom + node.offsetHeight > vspace) && pos.top > node.offsetHeight) + top = pos.top - node.offsetHeight; + else if (pos.bottom + node.offsetHeight <= vspace) + top = pos.bottom; + if (left + node.offsetWidth > hspace) + left = hspace - node.offsetWidth; + } + node.style.top = top + "px"; + node.style.left = node.style.right = ""; + if (horiz == "right") { + left = display.sizer.clientWidth - node.offsetWidth; + node.style.right = "0px"; + } else { + if (horiz == "left") left = 0; + else if (horiz == "middle") left = (display.sizer.clientWidth - node.offsetWidth) / 2; + node.style.left = left + "px"; + } + if (scroll) + scrollIntoView(this, left, top, left + node.offsetWidth, top + node.offsetHeight); + }, + + triggerOnKeyDown: operation(null, onKeyDown), + + execCommand: function(cmd) {return commands[cmd](this);}, + + findPosH: function(from, amount, unit, visually) { + var dir = 1; + if (amount < 0) { dir = -1; amount = -amount; } + for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) { + cur = findPosH(this.doc, cur, dir, unit, visually); + if (cur.hitSide) break; + } + return cur; + }, + + moveH: operation(null, function(dir, unit) { + var sel = this.doc.sel, pos; + if (sel.shift || sel.extend || posEq(sel.from, sel.to)) + pos = findPosH(this.doc, sel.head, dir, unit, this.options.rtlMoveVisually); + else + pos = dir < 0 ? sel.from : sel.to; + extendSelection(this.doc, pos, pos, dir); + }), + + deleteH: operation(null, function(dir, unit) { + var sel = this.doc.sel; + if (!posEq(sel.from, sel.to)) replaceRange(this.doc, "", sel.from, sel.to, "+delete"); + else replaceRange(this.doc, "", sel.from, findPosH(this.doc, sel.head, dir, unit, false), "+delete"); + this.curOp.userSelChange = true; + }), + + findPosV: function(from, amount, unit, goalColumn) { + var dir = 1, x = goalColumn; + if (amount < 0) { dir = -1; amount = -amount; } + for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) { + var coords = cursorCoords(this, cur, "div"); + if (x == null) x = coords.left; + else coords.left = x; + cur = findPosV(this, coords, dir, unit); + if (cur.hitSide) break; + } + return cur; + }, + + moveV: operation(null, function(dir, unit) { + var sel = this.doc.sel; + var pos = cursorCoords(this, sel.head, "div"); + if (sel.goalColumn != null) pos.left = sel.goalColumn; + var target = findPosV(this, pos, dir, unit); + + if (unit == "page") addToScrollPos(this, 0, charCoords(this, target, "div").top - pos.top); + extendSelection(this.doc, target, target, dir); + sel.goalColumn = pos.left; + }), + + toggleOverwrite: function(value) { + if (value != null && value == this.state.overwrite) return; + if (this.state.overwrite = !this.state.overwrite) + this.display.cursor.className += " CodeMirror-overwrite"; + else + this.display.cursor.className = this.display.cursor.className.replace(" CodeMirror-overwrite", ""); + }, + hasFocus: function() { return this.state.focused; }, + + scrollTo: operation(null, function(x, y) { + updateScrollPos(this, x, y); + }), + getScrollInfo: function() { + var scroller = this.display.scroller, co = scrollerCutOff; + return {left: scroller.scrollLeft, top: scroller.scrollTop, + height: scroller.scrollHeight - co, width: scroller.scrollWidth - co, + clientHeight: scroller.clientHeight - co, clientWidth: scroller.clientWidth - co}; + }, + + scrollIntoView: operation(null, function(pos, margin) { + if (typeof pos == "number") pos = Pos(pos, 0); + if (!margin) margin = 0; + var coords = pos; + + if (!pos || pos.line != null) { + this.curOp.scrollToPos = pos ? clipPos(this.doc, pos) : this.doc.sel.head; + this.curOp.scrollToPosMargin = margin; + coords = cursorCoords(this, this.curOp.scrollToPos); + } + var sPos = calculateScrollPos(this, coords.left, coords.top - margin, coords.right, coords.bottom + margin); + updateScrollPos(this, sPos.scrollLeft, sPos.scrollTop); + }), + + setSize: operation(null, function(width, height) { + function interpret(val) { + return typeof val == "number" || /^\d+$/.test(String(val)) ? val + "px" : val; + } + if (width != null) this.display.wrapper.style.width = interpret(width); + if (height != null) this.display.wrapper.style.height = interpret(height); + if (this.options.lineWrapping) + this.display.measureLineCache.length = this.display.measureLineCachePos = 0; + this.curOp.forceUpdate = true; + }), + + operation: function(f){return runInOp(this, f);}, + + refresh: operation(null, function() { + var badHeight = this.display.cachedTextHeight == null; + clearCaches(this); + updateScrollPos(this, this.doc.scrollLeft, this.doc.scrollTop); + regChange(this); + if (badHeight) estimateLineHeights(this); + }), + + swapDoc: operation(null, function(doc) { + var old = this.doc; + old.cm = null; + attachDoc(this, doc); + clearCaches(this); + resetInput(this, true); + updateScrollPos(this, doc.scrollLeft, doc.scrollTop); + return old; + }), + + getInputField: function(){return this.display.input;}, + getWrapperElement: function(){return this.display.wrapper;}, + getScrollerElement: function(){return this.display.scroller;}, + getGutterElement: function(){return this.display.gutters;} + }; + eventMixin(CodeMirror); + + // OPTION DEFAULTS + + var optionHandlers = CodeMirror.optionHandlers = {}; + + // The default configuration options. + var defaults = CodeMirror.defaults = {}; + + function option(name, deflt, handle, notOnInit) { + CodeMirror.defaults[name] = deflt; + if (handle) optionHandlers[name] = + notOnInit ? function(cm, val, old) {if (old != Init) handle(cm, val, old);} : handle; + } + + var Init = CodeMirror.Init = {toString: function(){return "CodeMirror.Init";}}; + + // These two are, on init, called from the constructor because they + // have to be initialized before the editor can start at all. + option("value", "", function(cm, val) { + cm.setValue(val); + }, true); + option("mode", null, function(cm, val) { + cm.doc.modeOption = val; + loadMode(cm); + }, true); + + option("indentUnit", 2, loadMode, true); + option("indentWithTabs", false); + option("smartIndent", true); + option("tabSize", 4, function(cm) { + loadMode(cm); + clearCaches(cm); + regChange(cm); + }, true); + option("electricChars", true); + option("rtlMoveVisually", !windows); + + option("theme", "default", function(cm) { + themeChanged(cm); + guttersChanged(cm); + }, true); + option("keyMap", "default", keyMapChanged); + option("extraKeys", null); + + option("onKeyEvent", null); + option("onDragEvent", null); + + option("lineWrapping", false, wrappingChanged, true); + option("gutters", [], function(cm) { + setGuttersForLineNumbers(cm.options); + guttersChanged(cm); + }, true); + option("fixedGutter", true, function(cm, val) { + cm.display.gutters.style.left = val ? compensateForHScroll(cm.display) + "px" : "0"; + cm.refresh(); + }, true); + option("coverGutterNextToScrollbar", false, updateScrollbars, true); + option("lineNumbers", false, function(cm) { + setGuttersForLineNumbers(cm.options); + guttersChanged(cm); + }, true); + option("firstLineNumber", 1, guttersChanged, true); + option("lineNumberFormatter", function(integer) {return integer;}, guttersChanged, true); + option("showCursorWhenSelecting", false, updateSelection, true); + + option("readOnly", false, function(cm, val) { + if (val == "nocursor") {onBlur(cm); cm.display.input.blur();} + else if (!val) resetInput(cm, true); + }); + option("dragDrop", true); + + option("cursorBlinkRate", 530); + option("cursorScrollMargin", 0); + option("cursorHeight", 1); + option("workTime", 100); + option("workDelay", 100); + option("flattenSpans", true); + option("pollInterval", 100); + option("undoDepth", 40, function(cm, val){cm.doc.history.undoDepth = val;}); + option("historyEventDelay", 500); + option("viewportMargin", 10, function(cm){cm.refresh();}, true); + option("maxHighlightLength", 10000, function(cm){loadMode(cm); cm.refresh();}, true); + option("crudeMeasuringFrom", 10000); + option("moveInputWithCursor", true, function(cm, val) { + if (!val) cm.display.inputDiv.style.top = cm.display.inputDiv.style.left = 0; + }); + + option("tabindex", null, function(cm, val) { + cm.display.input.tabIndex = val || ""; + }); + option("autofocus", null); + + // MODE DEFINITION AND QUERYING + + // Known modes, by name and by MIME + var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {}; + + CodeMirror.defineMode = function(name, mode) { + if (!CodeMirror.defaults.mode && name != "null") CodeMirror.defaults.mode = name; + if (arguments.length > 2) { + mode.dependencies = []; + for (var i = 2; i < arguments.length; ++i) mode.dependencies.push(arguments[i]); + } + modes[name] = mode; + }; + + CodeMirror.defineMIME = function(mime, spec) { + mimeModes[mime] = spec; + }; + + CodeMirror.resolveMode = function(spec) { + if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) { + spec = mimeModes[spec]; + } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) { + var found = mimeModes[spec.name]; + spec = createObj(found, spec); + spec.name = found.name; + } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec)) { + return CodeMirror.resolveMode("application/xml"); + } + if (typeof spec == "string") return {name: spec}; + else return spec || {name: "null"}; + }; + + CodeMirror.getMode = function(options, spec) { + var spec = CodeMirror.resolveMode(spec); + var mfactory = modes[spec.name]; + if (!mfactory) return CodeMirror.getMode(options, "text/plain"); + var modeObj = mfactory(options, spec); + if (modeExtensions.hasOwnProperty(spec.name)) { + var exts = modeExtensions[spec.name]; + for (var prop in exts) { + if (!exts.hasOwnProperty(prop)) continue; + if (modeObj.hasOwnProperty(prop)) modeObj["_" + prop] = modeObj[prop]; + modeObj[prop] = exts[prop]; + } + } + modeObj.name = spec.name; + + return modeObj; + }; + + CodeMirror.defineMode("null", function() { + return {token: function(stream) {stream.skipToEnd();}}; + }); + CodeMirror.defineMIME("text/plain", "null"); + + var modeExtensions = CodeMirror.modeExtensions = {}; + CodeMirror.extendMode = function(mode, properties) { + var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {}); + copyObj(properties, exts); + }; + + // EXTENSIONS + + CodeMirror.defineExtension = function(name, func) { + CodeMirror.prototype[name] = func; + }; + CodeMirror.defineDocExtension = function(name, func) { + Doc.prototype[name] = func; + }; + CodeMirror.defineOption = option; + + var initHooks = []; + CodeMirror.defineInitHook = function(f) {initHooks.push(f);}; + + var helpers = CodeMirror.helpers = {}; + CodeMirror.registerHelper = function(type, name, value) { + if (!helpers.hasOwnProperty(type)) helpers[type] = CodeMirror[type] = {}; + helpers[type][name] = value; + }; + + // UTILITIES + + CodeMirror.isWordChar = isWordChar; + + // MODE STATE HANDLING + + // Utility functions for working with state. Exported because modes + // sometimes need to do this. + function copyState(mode, state) { + if (state === true) return state; + if (mode.copyState) return mode.copyState(state); + var nstate = {}; + for (var n in state) { + var val = state[n]; + if (val instanceof Array) val = val.concat([]); + nstate[n] = val; + } + return nstate; + } + CodeMirror.copyState = copyState; + + function startState(mode, a1, a2) { + return mode.startState ? mode.startState(a1, a2) : true; + } + CodeMirror.startState = startState; + + CodeMirror.innerMode = function(mode, state) { + while (mode.innerMode) { + var info = mode.innerMode(state); + if (!info || info.mode == mode) break; + state = info.state; + mode = info.mode; + } + return info || {mode: mode, state: state}; + }; + + // STANDARD COMMANDS + + var commands = CodeMirror.commands = { + selectAll: function(cm) {cm.setSelection(Pos(cm.firstLine(), 0), Pos(cm.lastLine()));}, + killLine: function(cm) { + var from = cm.getCursor(true), to = cm.getCursor(false), sel = !posEq(from, to); + if (!sel && cm.getLine(from.line).length == from.ch) + cm.replaceRange("", from, Pos(from.line + 1, 0), "+delete"); + else cm.replaceRange("", from, sel ? to : Pos(from.line), "+delete"); + }, + deleteLine: function(cm) { + var l = cm.getCursor().line; + cm.replaceRange("", Pos(l, 0), Pos(l), "+delete"); + }, + delLineLeft: function(cm) { + var cur = cm.getCursor(); + cm.replaceRange("", Pos(cur.line, 0), cur, "+delete"); + }, + undo: function(cm) {cm.undo();}, + redo: function(cm) {cm.redo();}, + goDocStart: function(cm) {cm.extendSelection(Pos(cm.firstLine(), 0));}, + goDocEnd: function(cm) {cm.extendSelection(Pos(cm.lastLine()));}, + goLineStart: function(cm) { + cm.extendSelection(lineStart(cm, cm.getCursor().line)); + }, + goLineStartSmart: function(cm) { + var cur = cm.getCursor(), start = lineStart(cm, cur.line); + var line = cm.getLineHandle(start.line); + var order = getOrder(line); + if (!order || order[0].level == 0) { + var firstNonWS = Math.max(0, line.text.search(/\S/)); + var inWS = cur.line == start.line && cur.ch <= firstNonWS && cur.ch; + cm.extendSelection(Pos(start.line, inWS ? 0 : firstNonWS)); + } else cm.extendSelection(start); + }, + goLineEnd: function(cm) { + cm.extendSelection(lineEnd(cm, cm.getCursor().line)); + }, + goLineRight: function(cm) { + var top = cm.charCoords(cm.getCursor(), "div").top + 5; + cm.extendSelection(cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div")); + }, + goLineLeft: function(cm) { + var top = cm.charCoords(cm.getCursor(), "div").top + 5; + cm.extendSelection(cm.coordsChar({left: 0, top: top}, "div")); + }, + goLineUp: function(cm) {cm.moveV(-1, "line");}, + goLineDown: function(cm) {cm.moveV(1, "line");}, + goPageUp: function(cm) {cm.moveV(-1, "page");}, + goPageDown: function(cm) {cm.moveV(1, "page");}, + goCharLeft: function(cm) {cm.moveH(-1, "char");}, + goCharRight: function(cm) {cm.moveH(1, "char");}, + goColumnLeft: function(cm) {cm.moveH(-1, "column");}, + goColumnRight: function(cm) {cm.moveH(1, "column");}, + goWordLeft: function(cm) {cm.moveH(-1, "word");}, + goGroupRight: function(cm) {cm.moveH(1, "group");}, + goGroupLeft: function(cm) {cm.moveH(-1, "group");}, + goWordRight: function(cm) {cm.moveH(1, "word");}, + delCharBefore: function(cm) {cm.deleteH(-1, "char");}, + delCharAfter: function(cm) {cm.deleteH(1, "char");}, + delWordBefore: function(cm) {cm.deleteH(-1, "word");}, + delWordAfter: function(cm) {cm.deleteH(1, "word");}, + delGroupBefore: function(cm) {cm.deleteH(-1, "group");}, + delGroupAfter: function(cm) {cm.deleteH(1, "group");}, + indentAuto: function(cm) {cm.indentSelection("smart");}, + indentMore: function(cm) {cm.indentSelection("add");}, + indentLess: function(cm) {cm.indentSelection("subtract");}, + insertTab: function(cm) {cm.replaceSelection("\t", "end", "+input");}, + defaultTab: function(cm) { + if (cm.somethingSelected()) cm.indentSelection("add"); + else cm.replaceSelection("\t", "end", "+input"); + }, + transposeChars: function(cm) { + var cur = cm.getCursor(), line = cm.getLine(cur.line); + if (cur.ch > 0 && cur.ch < line.length - 1) + cm.replaceRange(line.charAt(cur.ch) + line.charAt(cur.ch - 1), + Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1)); + }, + newlineAndIndent: function(cm) { + operation(cm, function() { + cm.replaceSelection("\n", "end", "+input"); + cm.indentLine(cm.getCursor().line, null, true); + })(); + }, + toggleOverwrite: function(cm) {cm.toggleOverwrite();} + }; + + // STANDARD KEYMAPS + + var keyMap = CodeMirror.keyMap = {}; + keyMap.basic = { + "Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown", + "End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown", + "Delete": "delCharAfter", "Backspace": "delCharBefore", "Tab": "defaultTab", "Shift-Tab": "indentAuto", + "Enter": "newlineAndIndent", "Insert": "toggleOverwrite" + }; + // Note that the save and find-related commands aren't defined by + // default. Unknown commands are simply ignored. + keyMap.pcDefault = { + "Ctrl-A": "selectAll", "Ctrl-D": "deleteLine", "Ctrl-Z": "undo", "Shift-Ctrl-Z": "redo", "Ctrl-Y": "redo", + "Ctrl-Home": "goDocStart", "Alt-Up": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Down": "goDocEnd", + "Ctrl-Left": "goGroupLeft", "Ctrl-Right": "goGroupRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd", + "Ctrl-Backspace": "delGroupBefore", "Ctrl-Delete": "delGroupAfter", "Ctrl-S": "save", "Ctrl-F": "find", + "Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll", + "Ctrl-[": "indentLess", "Ctrl-]": "indentMore", + fallthrough: "basic" + }; + keyMap.macDefault = { + "Cmd-A": "selectAll", "Cmd-D": "deleteLine", "Cmd-Z": "undo", "Shift-Cmd-Z": "redo", "Cmd-Y": "redo", + "Cmd-Up": "goDocStart", "Cmd-End": "goDocEnd", "Cmd-Down": "goDocEnd", "Alt-Left": "goGroupLeft", + "Alt-Right": "goGroupRight", "Cmd-Left": "goLineStart", "Cmd-Right": "goLineEnd", "Alt-Backspace": "delGroupBefore", + "Ctrl-Alt-Backspace": "delGroupAfter", "Alt-Delete": "delGroupAfter", "Cmd-S": "save", "Cmd-F": "find", + "Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll", + "Cmd-[": "indentLess", "Cmd-]": "indentMore", "Cmd-Backspace": "delLineLeft", + fallthrough: ["basic", "emacsy"] + }; + keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault; + keyMap.emacsy = { + "Ctrl-F": "goCharRight", "Ctrl-B": "goCharLeft", "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown", + "Alt-F": "goWordRight", "Alt-B": "goWordLeft", "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd", + "Ctrl-V": "goPageDown", "Shift-Ctrl-V": "goPageUp", "Ctrl-D": "delCharAfter", "Ctrl-H": "delCharBefore", + "Alt-D": "delWordAfter", "Alt-Backspace": "delWordBefore", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars" + }; + + // KEYMAP DISPATCH + + function getKeyMap(val) { + if (typeof val == "string") return keyMap[val]; + else return val; + } + + function lookupKey(name, maps, handle) { + function lookup(map) { + map = getKeyMap(map); + var found = map[name]; + if (found === false) return "stop"; + if (found != null && handle(found)) return true; + if (map.nofallthrough) return "stop"; + + var fallthrough = map.fallthrough; + if (fallthrough == null) return false; + if (Object.prototype.toString.call(fallthrough) != "[object Array]") + return lookup(fallthrough); + for (var i = 0, e = fallthrough.length; i < e; ++i) { + var done = lookup(fallthrough[i]); + if (done) return done; + } + return false; + } + + for (var i = 0; i < maps.length; ++i) { + var done = lookup(maps[i]); + if (done) return done != "stop"; + } + } + function isModifierKey(event) { + var name = keyNames[event.keyCode]; + return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod"; + } + function keyName(event, noShift) { + if (opera && event.keyCode == 34 && event["char"]) return false; + var name = keyNames[event.keyCode]; + if (name == null || event.altGraphKey) return false; + if (event.altKey) name = "Alt-" + name; + if (flipCtrlCmd ? event.metaKey : event.ctrlKey) name = "Ctrl-" + name; + if (flipCtrlCmd ? event.ctrlKey : event.metaKey) name = "Cmd-" + name; + if (!noShift && event.shiftKey) name = "Shift-" + name; + return name; + } + CodeMirror.lookupKey = lookupKey; + CodeMirror.isModifierKey = isModifierKey; + CodeMirror.keyName = keyName; + + // FROMTEXTAREA + + CodeMirror.fromTextArea = function(textarea, options) { + if (!options) options = {}; + options.value = textarea.value; + if (!options.tabindex && textarea.tabindex) + options.tabindex = textarea.tabindex; + if (!options.placeholder && textarea.placeholder) + options.placeholder = textarea.placeholder; + // Set autofocus to true if this textarea is focused, or if it has + // autofocus and no other element is focused. + if (options.autofocus == null) { + var hasFocus = document.body; + // doc.activeElement occasionally throws on IE + try { hasFocus = document.activeElement; } catch(e) {} + options.autofocus = hasFocus == textarea || + textarea.getAttribute("autofocus") != null && hasFocus == document.body; + } + + function save() {textarea.value = cm.getValue();} + if (textarea.form) { + on(textarea.form, "submit", save); + // Deplorable hack to make the submit method do the right thing. + if (!options.leaveSubmitMethodAlone) { + var form = textarea.form, realSubmit = form.submit; + try { + var wrappedSubmit = form.submit = function() { + save(); + form.submit = realSubmit; + form.submit(); + form.submit = wrappedSubmit; + }; + } catch(e) {} + } + } + + textarea.style.display = "none"; + var cm = CodeMirror(function(node) { + textarea.parentNode.insertBefore(node, textarea.nextSibling); + }, options); + cm.save = save; + cm.getTextArea = function() { return textarea; }; + cm.toTextArea = function() { + save(); + textarea.parentNode.removeChild(cm.getWrapperElement()); + textarea.style.display = ""; + if (textarea.form) { + off(textarea.form, "submit", save); + if (typeof textarea.form.submit == "function") + textarea.form.submit = realSubmit; + } + }; + return cm; + }; + + // STRING STREAM + + // Fed to the mode parsers, provides helper functions to make + // parsers more succinct. + + // The character stream used by a mode's parser. + function StringStream(string, tabSize) { + this.pos = this.start = 0; + this.string = string; + this.tabSize = tabSize || 8; + this.lastColumnPos = this.lastColumnValue = 0; + } + + StringStream.prototype = { + eol: function() {return this.pos >= this.string.length;}, + sol: function() {return this.pos == 0;}, + peek: function() {return this.string.charAt(this.pos) || undefined;}, + next: function() { + if (this.pos < this.string.length) + return this.string.charAt(this.pos++); + }, + eat: function(match) { + var ch = this.string.charAt(this.pos); + if (typeof match == "string") var ok = ch == match; + else var ok = ch && (match.test ? match.test(ch) : match(ch)); + if (ok) {++this.pos; return ch;} + }, + eatWhile: function(match) { + var start = this.pos; + while (this.eat(match)){} + return this.pos > start; + }, + eatSpace: function() { + var start = this.pos; + while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos; + return this.pos > start; + }, + skipToEnd: function() {this.pos = this.string.length;}, + skipTo: function(ch) { + var found = this.string.indexOf(ch, this.pos); + if (found > -1) {this.pos = found; return true;} + }, + backUp: function(n) {this.pos -= n;}, + column: function() { + if (this.lastColumnPos < this.start) { + this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue); + this.lastColumnPos = this.start; + } + return this.lastColumnValue; + }, + indentation: function() {return countColumn(this.string, null, this.tabSize);}, + match: function(pattern, consume, caseInsensitive) { + if (typeof pattern == "string") { + var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;}; + var substr = this.string.substr(this.pos, pattern.length); + if (cased(substr) == cased(pattern)) { + if (consume !== false) this.pos += pattern.length; + return true; + } + } else { + var match = this.string.slice(this.pos).match(pattern); + if (match && match.index > 0) return null; + if (match && consume !== false) this.pos += match[0].length; + return match; + } + }, + current: function(){return this.string.slice(this.start, this.pos);} + }; + CodeMirror.StringStream = StringStream; + + // TEXTMARKERS + + function TextMarker(doc, type) { + this.lines = []; + this.type = type; + this.doc = doc; + } + CodeMirror.TextMarker = TextMarker; + eventMixin(TextMarker); + + TextMarker.prototype.clear = function() { + if (this.explicitlyCleared) return; + var cm = this.doc.cm, withOp = cm && !cm.curOp; + if (withOp) startOperation(cm); + if (hasHandler(this, "clear")) { + var found = this.find(); + if (found) signalLater(this, "clear", found.from, found.to); + } + var min = null, max = null; + for (var i = 0; i < this.lines.length; ++i) { + var line = this.lines[i]; + var span = getMarkedSpanFor(line.markedSpans, this); + if (span.to != null) max = lineNo(line); + line.markedSpans = removeMarkedSpan(line.markedSpans, span); + if (span.from != null) + min = lineNo(line); + else if (this.collapsed && !lineIsHidden(this.doc, line) && cm) + updateLineHeight(line, textHeight(cm.display)); + } + if (cm && this.collapsed && !cm.options.lineWrapping) for (var i = 0; i < this.lines.length; ++i) { + var visual = visualLine(cm.doc, this.lines[i]), len = lineLength(cm.doc, visual); + if (len > cm.display.maxLineLength) { + cm.display.maxLine = visual; + cm.display.maxLineLength = len; + cm.display.maxLineChanged = true; + } + } + + if (min != null && cm) regChange(cm, min, max + 1); + this.lines.length = 0; + this.explicitlyCleared = true; + if (this.atomic && this.doc.cantEdit) { + this.doc.cantEdit = false; + if (cm) reCheckSelection(cm); + } + if (withOp) endOperation(cm); + }; + + TextMarker.prototype.find = function() { + var from, to; + for (var i = 0; i < this.lines.length; ++i) { + var line = this.lines[i]; + var span = getMarkedSpanFor(line.markedSpans, this); + if (span.from != null || span.to != null) { + var found = lineNo(line); + if (span.from != null) from = Pos(found, span.from); + if (span.to != null) to = Pos(found, span.to); + } + } + if (this.type == "bookmark") return from; + return from && {from: from, to: to}; + }; + + TextMarker.prototype.changed = function() { + var pos = this.find(), cm = this.doc.cm; + if (!pos || !cm) return; + if (this.type != "bookmark") pos = pos.from; + var line = getLine(this.doc, pos.line); + clearCachedMeasurement(cm, line); + if (pos.line >= cm.display.showingFrom && pos.line < cm.display.showingTo) { + for (var node = cm.display.lineDiv.firstChild; node; node = node.nextSibling) if (node.lineObj == line) { + if (node.offsetHeight != line.height) updateLineHeight(line, node.offsetHeight); + break; + } + runInOp(cm, function() { + cm.curOp.selectionChanged = cm.curOp.forceUpdate = cm.curOp.updateMaxLine = true; + }); + } + }; + + TextMarker.prototype.attachLine = function(line) { + if (!this.lines.length && this.doc.cm) { + var op = this.doc.cm.curOp; + if (!op.maybeHiddenMarkers || indexOf(op.maybeHiddenMarkers, this) == -1) + (op.maybeUnhiddenMarkers || (op.maybeUnhiddenMarkers = [])).push(this); + } + this.lines.push(line); + }; + TextMarker.prototype.detachLine = function(line) { + this.lines.splice(indexOf(this.lines, line), 1); + if (!this.lines.length && this.doc.cm) { + var op = this.doc.cm.curOp; + (op.maybeHiddenMarkers || (op.maybeHiddenMarkers = [])).push(this); + } + }; + + function markText(doc, from, to, options, type) { + if (options && options.shared) return markTextShared(doc, from, to, options, type); + if (doc.cm && !doc.cm.curOp) return operation(doc.cm, markText)(doc, from, to, options, type); + + var marker = new TextMarker(doc, type); + if (type == "range" && !posLess(from, to)) return marker; + if (options) copyObj(options, marker); + if (marker.replacedWith) { + marker.collapsed = true; + marker.replacedWith = elt("span", [marker.replacedWith], "CodeMirror-widget"); + if (!options.handleMouseEvents) marker.replacedWith.ignoreEvents = true; + } + if (marker.collapsed) sawCollapsedSpans = true; + + if (marker.addToHistory) + addToHistory(doc, {from: from, to: to, origin: "markText"}, + {head: doc.sel.head, anchor: doc.sel.anchor}, NaN); + + var curLine = from.line, size = 0, collapsedAtStart, collapsedAtEnd, cm = doc.cm, updateMaxLine; + doc.iter(curLine, to.line + 1, function(line) { + if (cm && marker.collapsed && !cm.options.lineWrapping && visualLine(doc, line) == cm.display.maxLine) + updateMaxLine = true; + var span = {from: null, to: null, marker: marker}; + size += line.text.length; + if (curLine == from.line) {span.from = from.ch; size -= from.ch;} + if (curLine == to.line) {span.to = to.ch; size -= line.text.length - to.ch;} + if (marker.collapsed) { + if (curLine == to.line) collapsedAtEnd = collapsedSpanAt(line, to.ch); + if (curLine == from.line) collapsedAtStart = collapsedSpanAt(line, from.ch); + else updateLineHeight(line, 0); + } + addMarkedSpan(line, span); + ++curLine; + }); + if (marker.collapsed) doc.iter(from.line, to.line + 1, function(line) { + if (lineIsHidden(doc, line)) updateLineHeight(line, 0); + }); + + if (marker.clearOnEnter) on(marker, "beforeCursorEnter", function() { marker.clear(); }); + + if (marker.readOnly) { + sawReadOnlySpans = true; + if (doc.history.done.length || doc.history.undone.length) + doc.clearHistory(); + } + if (marker.collapsed) { + if (collapsedAtStart != collapsedAtEnd) + throw new Error("Inserting collapsed marker overlapping an existing one"); + marker.size = size; + marker.atomic = true; + } + if (cm) { + if (updateMaxLine) cm.curOp.updateMaxLine = true; + if (marker.className || marker.title || marker.startStyle || marker.endStyle || marker.collapsed) + regChange(cm, from.line, to.line + 1); + if (marker.atomic) reCheckSelection(cm); + } + return marker; + } + + // SHARED TEXTMARKERS + + function SharedTextMarker(markers, primary) { + this.markers = markers; + this.primary = primary; + for (var i = 0, me = this; i < markers.length; ++i) { + markers[i].parent = this; + on(markers[i], "clear", function(){me.clear();}); + } + } + CodeMirror.SharedTextMarker = SharedTextMarker; + eventMixin(SharedTextMarker); + + SharedTextMarker.prototype.clear = function() { + if (this.explicitlyCleared) return; + this.explicitlyCleared = true; + for (var i = 0; i < this.markers.length; ++i) + this.markers[i].clear(); + signalLater(this, "clear"); + }; + SharedTextMarker.prototype.find = function() { + return this.primary.find(); + }; + + function markTextShared(doc, from, to, options, type) { + options = copyObj(options); + options.shared = false; + var markers = [markText(doc, from, to, options, type)], primary = markers[0]; + var widget = options.replacedWith; + linkedDocs(doc, function(doc) { + if (widget) options.replacedWith = widget.cloneNode(true); + markers.push(markText(doc, clipPos(doc, from), clipPos(doc, to), options, type)); + for (var i = 0; i < doc.linked.length; ++i) + if (doc.linked[i].isParent) return; + primary = lst(markers); + }); + return new SharedTextMarker(markers, primary); + } + + // TEXTMARKER SPANS + + function getMarkedSpanFor(spans, marker) { + if (spans) for (var i = 0; i < spans.length; ++i) { + var span = spans[i]; + if (span.marker == marker) return span; + } + } + function removeMarkedSpan(spans, span) { + for (var r, i = 0; i < spans.length; ++i) + if (spans[i] != span) (r || (r = [])).push(spans[i]); + return r; + } + function addMarkedSpan(line, span) { + line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span]; + span.marker.attachLine(line); + } + + function markedSpansBefore(old, startCh, isInsert) { + if (old) for (var i = 0, nw; i < old.length; ++i) { + var span = old[i], marker = span.marker; + var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh); + if (startsBefore || marker.type == "bookmark" && span.from == startCh && (!isInsert || !span.marker.insertLeft)) { + var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh); + (nw || (nw = [])).push({from: span.from, + to: endsAfter ? null : span.to, + marker: marker}); + } + } + return nw; + } + + function markedSpansAfter(old, endCh, isInsert) { + if (old) for (var i = 0, nw; i < old.length; ++i) { + var span = old[i], marker = span.marker; + var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh); + if (endsAfter || marker.type == "bookmark" && span.from == endCh && (!isInsert || span.marker.insertLeft)) { + var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh); + (nw || (nw = [])).push({from: startsBefore ? null : span.from - endCh, + to: span.to == null ? null : span.to - endCh, + marker: marker}); + } + } + return nw; + } + + function stretchSpansOverChange(doc, change) { + var oldFirst = isLine(doc, change.from.line) && getLine(doc, change.from.line).markedSpans; + var oldLast = isLine(doc, change.to.line) && getLine(doc, change.to.line).markedSpans; + if (!oldFirst && !oldLast) return null; + + var startCh = change.from.ch, endCh = change.to.ch, isInsert = posEq(change.from, change.to); + // Get the spans that 'stick out' on both sides + var first = markedSpansBefore(oldFirst, startCh, isInsert); + var last = markedSpansAfter(oldLast, endCh, isInsert); + + // Next, merge those two ends + var sameLine = change.text.length == 1, offset = lst(change.text).length + (sameLine ? startCh : 0); + if (first) { + // Fix up .to properties of first + for (var i = 0; i < first.length; ++i) { + var span = first[i]; + if (span.to == null) { + var found = getMarkedSpanFor(last, span.marker); + if (!found) span.to = startCh; + else if (sameLine) span.to = found.to == null ? null : found.to + offset; + } + } + } + if (last) { + // Fix up .from in last (or move them into first in case of sameLine) + for (var i = 0; i < last.length; ++i) { + var span = last[i]; + if (span.to != null) span.to += offset; + if (span.from == null) { + var found = getMarkedSpanFor(first, span.marker); + if (!found) { + span.from = offset; + if (sameLine) (first || (first = [])).push(span); + } + } else { + span.from += offset; + if (sameLine) (first || (first = [])).push(span); + } + } + } + if (sameLine && first) { + // Make sure we didn't create any zero-length spans + for (var i = 0; i < first.length; ++i) + if (first[i].from != null && first[i].from == first[i].to && first[i].marker.type != "bookmark") + first.splice(i--, 1); + if (!first.length) first = null; + } + + var newMarkers = [first]; + if (!sameLine) { + // Fill gap with whole-line-spans + var gap = change.text.length - 2, gapMarkers; + if (gap > 0 && first) + for (var i = 0; i < first.length; ++i) + if (first[i].to == null) + (gapMarkers || (gapMarkers = [])).push({from: null, to: null, marker: first[i].marker}); + for (var i = 0; i < gap; ++i) + newMarkers.push(gapMarkers); + newMarkers.push(last); + } + return newMarkers; + } + + function mergeOldSpans(doc, change) { + var old = getOldSpans(doc, change); + var stretched = stretchSpansOverChange(doc, change); + if (!old) return stretched; + if (!stretched) return old; + + for (var i = 0; i < old.length; ++i) { + var oldCur = old[i], stretchCur = stretched[i]; + if (oldCur && stretchCur) { + spans: for (var j = 0; j < stretchCur.length; ++j) { + var span = stretchCur[j]; + for (var k = 0; k < oldCur.length; ++k) + if (oldCur[k].marker == span.marker) continue spans; + oldCur.push(span); + } + } else if (stretchCur) { + old[i] = stretchCur; + } + } + return old; + } + + function removeReadOnlyRanges(doc, from, to) { + var markers = null; + doc.iter(from.line, to.line + 1, function(line) { + if (line.markedSpans) for (var i = 0; i < line.markedSpans.length; ++i) { + var mark = line.markedSpans[i].marker; + if (mark.readOnly && (!markers || indexOf(markers, mark) == -1)) + (markers || (markers = [])).push(mark); + } + }); + if (!markers) return null; + var parts = [{from: from, to: to}]; + for (var i = 0; i < markers.length; ++i) { + var mk = markers[i], m = mk.find(); + for (var j = 0; j < parts.length; ++j) { + var p = parts[j]; + if (posLess(p.to, m.from) || posLess(m.to, p.from)) continue; + var newParts = [j, 1]; + if (posLess(p.from, m.from) || !mk.inclusiveLeft && posEq(p.from, m.from)) + newParts.push({from: p.from, to: m.from}); + if (posLess(m.to, p.to) || !mk.inclusiveRight && posEq(p.to, m.to)) + newParts.push({from: m.to, to: p.to}); + parts.splice.apply(parts, newParts); + j += newParts.length - 1; + } + } + return parts; + } + + function collapsedSpanAt(line, ch) { + var sps = sawCollapsedSpans && line.markedSpans, found; + if (sps) for (var sp, i = 0; i < sps.length; ++i) { + sp = sps[i]; + if (!sp.marker.collapsed) continue; + if ((sp.from == null || sp.from < ch) && + (sp.to == null || sp.to > ch) && + (!found || found.width < sp.marker.width)) + found = sp.marker; + } + return found; + } + function collapsedSpanAtStart(line) { return collapsedSpanAt(line, -1); } + function collapsedSpanAtEnd(line) { return collapsedSpanAt(line, line.text.length + 1); } + + function visualLine(doc, line) { + var merged; + while (merged = collapsedSpanAtStart(line)) + line = getLine(doc, merged.find().from.line); + return line; + } + + function lineIsHidden(doc, line) { + var sps = sawCollapsedSpans && line.markedSpans; + if (sps) for (var sp, i = 0; i < sps.length; ++i) { + sp = sps[i]; + if (!sp.marker.collapsed) continue; + if (sp.from == null) return true; + if (sp.marker.replacedWith) continue; + if (sp.from == 0 && sp.marker.inclusiveLeft && lineIsHiddenInner(doc, line, sp)) + return true; + } + } + function lineIsHiddenInner(doc, line, span) { + if (span.to == null) { + var end = span.marker.find().to, endLine = getLine(doc, end.line); + return lineIsHiddenInner(doc, endLine, getMarkedSpanFor(endLine.markedSpans, span.marker)); + } + if (span.marker.inclusiveRight && span.to == line.text.length) + return true; + for (var sp, i = 0; i < line.markedSpans.length; ++i) { + sp = line.markedSpans[i]; + if (sp.marker.collapsed && !sp.marker.replacedWith && sp.from == span.to && + (sp.marker.inclusiveLeft || span.marker.inclusiveRight) && + lineIsHiddenInner(doc, line, sp)) return true; + } + } + + function detachMarkedSpans(line) { + var spans = line.markedSpans; + if (!spans) return; + for (var i = 0; i < spans.length; ++i) + spans[i].marker.detachLine(line); + line.markedSpans = null; + } + + function attachMarkedSpans(line, spans) { + if (!spans) return; + for (var i = 0; i < spans.length; ++i) + spans[i].marker.attachLine(line); + line.markedSpans = spans; + } + + // LINE WIDGETS + + var LineWidget = CodeMirror.LineWidget = function(cm, node, options) { + if (options) for (var opt in options) if (options.hasOwnProperty(opt)) + this[opt] = options[opt]; + this.cm = cm; + this.node = node; + }; + eventMixin(LineWidget); + function widgetOperation(f) { + return function() { + var withOp = !this.cm.curOp; + if (withOp) startOperation(this.cm); + try {var result = f.apply(this, arguments);} + finally {if (withOp) endOperation(this.cm);} + return result; + }; + } + LineWidget.prototype.clear = widgetOperation(function() { + var ws = this.line.widgets, no = lineNo(this.line); + if (no == null || !ws) return; + for (var i = 0; i < ws.length; ++i) if (ws[i] == this) ws.splice(i--, 1); + if (!ws.length) this.line.widgets = null; + var aboveVisible = heightAtLine(this.cm, this.line) < this.cm.doc.scrollTop; + updateLineHeight(this.line, Math.max(0, this.line.height - widgetHeight(this))); + if (aboveVisible) addToScrollPos(this.cm, 0, -this.height); + regChange(this.cm, no, no + 1); + }); + LineWidget.prototype.changed = widgetOperation(function() { + var oldH = this.height; + this.height = null; + var diff = widgetHeight(this) - oldH; + if (!diff) return; + updateLineHeight(this.line, this.line.height + diff); + var no = lineNo(this.line); + regChange(this.cm, no, no + 1); + }); + + function widgetHeight(widget) { + if (widget.height != null) return widget.height; + if (!widget.node.parentNode || widget.node.parentNode.nodeType != 1) + removeChildrenAndAdd(widget.cm.display.measure, elt("div", [widget.node], null, "position: relative")); + return widget.height = widget.node.offsetHeight; + } + + function addLineWidget(cm, handle, node, options) { + var widget = new LineWidget(cm, node, options); + if (widget.noHScroll) cm.display.alignWidgets = true; + changeLine(cm, handle, function(line) { + var widgets = line.widgets || (line.widgets = []); + if (widget.insertAt == null) widgets.push(widget); + else widgets.splice(Math.min(widgets.length - 1, Math.max(0, widget.insertAt)), 0, widget); + widget.line = line; + if (!lineIsHidden(cm.doc, line) || widget.showIfHidden) { + var aboveVisible = heightAtLine(cm, line) < cm.doc.scrollTop; + updateLineHeight(line, line.height + widgetHeight(widget)); + if (aboveVisible) addToScrollPos(cm, 0, widget.height); + } + return true; + }); + return widget; + } + + // LINE DATA STRUCTURE + + // Line objects. These hold state related to a line, including + // highlighting info (the styles array). + var Line = CodeMirror.Line = function(text, markedSpans, estimateHeight) { + this.text = text; + attachMarkedSpans(this, markedSpans); + this.height = estimateHeight ? estimateHeight(this) : 1; + }; + eventMixin(Line); + + function updateLine(line, text, markedSpans, estimateHeight) { + line.text = text; + if (line.stateAfter) line.stateAfter = null; + if (line.styles) line.styles = null; + if (line.order != null) line.order = null; + detachMarkedSpans(line); + attachMarkedSpans(line, markedSpans); + var estHeight = estimateHeight ? estimateHeight(line) : 1; + if (estHeight != line.height) updateLineHeight(line, estHeight); + } + + function cleanUpLine(line) { + line.parent = null; + detachMarkedSpans(line); + } + + // Run the given mode's parser over a line, update the styles + // array, which contains alternating fragments of text and CSS + // classes. + function runMode(cm, text, mode, state, f) { + var flattenSpans = mode.flattenSpans; + if (flattenSpans == null) flattenSpans = cm.options.flattenSpans; + var curStart = 0, curStyle = null; + var stream = new StringStream(text, cm.options.tabSize), style; + if (text == "" && mode.blankLine) mode.blankLine(state); + while (!stream.eol()) { + if (stream.pos > cm.options.maxHighlightLength) { + flattenSpans = false; + stream.pos = text.length; + style = null; + } else { + style = mode.token(stream, state); + } + if (!flattenSpans || curStyle != style) { + if (curStart < stream.start) f(stream.start, curStyle); + curStart = stream.start; curStyle = style; + } + stream.start = stream.pos; + } + while (curStart < stream.pos) { + // Webkit seems to refuse to render text nodes longer than 57444 characters + var pos = Math.min(stream.pos, curStart + 50000); + f(pos, curStyle); + curStart = pos; + } + } + + function highlightLine(cm, line, state) { + // A styles array always starts with a number identifying the + // mode/overlays that it is based on (for easy invalidation). + var st = [cm.state.modeGen]; + // Compute the base array of styles + runMode(cm, line.text, cm.doc.mode, state, function(end, style) {st.push(end, style);}); + + // Run overlays, adjust style array. + for (var o = 0; o < cm.state.overlays.length; ++o) { + var overlay = cm.state.overlays[o], i = 1, at = 0; + runMode(cm, line.text, overlay.mode, true, function(end, style) { + var start = i; + // Ensure there's a token end at the current position, and that i points at it + while (at < end) { + var i_end = st[i]; + if (i_end > end) + st.splice(i, 1, end, st[i+1], i_end); + i += 2; + at = Math.min(end, i_end); + } + if (!style) return; + if (overlay.opaque) { + st.splice(start, i - start, end, style); + i = start + 2; + } else { + for (; start < i; start += 2) { + var cur = st[start+1]; + st[start+1] = cur ? cur + " " + style : style; + } + } + }); + } + + return st; + } + + function getLineStyles(cm, line) { + if (!line.styles || line.styles[0] != cm.state.modeGen) + line.styles = highlightLine(cm, line, line.stateAfter = getStateBefore(cm, lineNo(line))); + return line.styles; + } + + // Lightweight form of highlight -- proceed over this line and + // update state, but don't save a style array. + function processLine(cm, line, state) { + var mode = cm.doc.mode; + var stream = new StringStream(line.text, cm.options.tabSize); + if (line.text == "" && mode.blankLine) mode.blankLine(state); + while (!stream.eol() && stream.pos <= cm.options.maxHighlightLength) { + mode.token(stream, state); + stream.start = stream.pos; + } + } + + var styleToClassCache = {}; + function interpretTokenStyle(style, builder) { + if (!style) return null; + for (;;) { + var lineClass = style.match(/(?:^|\s)line-(background-)?(\S+)/); + if (!lineClass) break; + style = style.slice(0, lineClass.index) + style.slice(lineClass.index + lineClass[0].length); + var prop = lineClass[1] ? "bgClass" : "textClass"; + if (builder[prop] == null) + builder[prop] = lineClass[2]; + else if (!(new RegExp("(?:^|\s)" + lineClass[2] + "(?:$|\s)")).test(builder[prop])) + builder[prop] += " " + lineClass[2]; + } + return styleToClassCache[style] || + (styleToClassCache[style] = "cm-" + style.replace(/ +/g, " cm-")); + } + + function buildLineContent(cm, realLine, measure, copyWidgets) { + var merged, line = realLine, empty = true; + while (merged = collapsedSpanAtStart(line)) + line = getLine(cm.doc, merged.find().from.line); + + var builder = {pre: elt("pre"), col: 0, pos: 0, + measure: null, measuredSomething: false, cm: cm, + copyWidgets: copyWidgets}; + + do { + if (line.text) empty = false; + builder.measure = line == realLine && measure; + builder.pos = 0; + builder.addToken = builder.measure ? buildTokenMeasure : buildToken; + if ((ie || webkit) && cm.getOption("lineWrapping")) + builder.addToken = buildTokenSplitSpaces(builder.addToken); + var next = insertLineContent(line, builder, getLineStyles(cm, line)); + if (measure && line == realLine && !builder.measuredSomething) { + measure[0] = builder.pre.appendChild(zeroWidthElement(cm.display.measure)); + builder.measuredSomething = true; + } + if (next) line = getLine(cm.doc, next.to.line); + } while (next); + + if (measure && !builder.measuredSomething && !measure[0]) + measure[0] = builder.pre.appendChild(empty ? elt("span", "\u00a0") : zeroWidthElement(cm.display.measure)); + if (!builder.pre.firstChild && !lineIsHidden(cm.doc, realLine)) + builder.pre.appendChild(document.createTextNode("\u00a0")); + + var order; + // Work around problem with the reported dimensions of single-char + // direction spans on IE (issue #1129). See also the comment in + // cursorCoords. + if (measure && ie && (order = getOrder(line))) { + var l = order.length - 1; + if (order[l].from == order[l].to) --l; + var last = order[l], prev = order[l - 1]; + if (last.from + 1 == last.to && prev && last.level < prev.level) { + var span = measure[builder.pos - 1]; + if (span) span.parentNode.insertBefore(span.measureRight = zeroWidthElement(cm.display.measure), + span.nextSibling); + } + } + + var textClass = builder.textClass ? builder.textClass + " " + (realLine.textClass || "") : realLine.textClass; + if (textClass) builder.pre.className = textClass; + + signal(cm, "renderLine", cm, realLine, builder.pre); + return builder; + } + + var tokenSpecialChars = /[\t\u0000-\u0019\u00ad\u200b\u2028\u2029\uFEFF]/g; + function buildToken(builder, text, style, startStyle, endStyle, title) { + if (!text) return; + if (!tokenSpecialChars.test(text)) { + builder.col += text.length; + var content = document.createTextNode(text); + } else { + var content = document.createDocumentFragment(), pos = 0; + while (true) { + tokenSpecialChars.lastIndex = pos; + var m = tokenSpecialChars.exec(text); + var skipped = m ? m.index - pos : text.length - pos; + if (skipped) { + content.appendChild(document.createTextNode(text.slice(pos, pos + skipped))); + builder.col += skipped; + } + if (!m) break; + pos += skipped + 1; + if (m[0] == "\t") { + var tabSize = builder.cm.options.tabSize, tabWidth = tabSize - builder.col % tabSize; + content.appendChild(elt("span", spaceStr(tabWidth), "cm-tab")); + builder.col += tabWidth; + } else { + var token = elt("span", "\u2022", "cm-invalidchar"); + token.title = "\\u" + m[0].charCodeAt(0).toString(16); + content.appendChild(token); + builder.col += 1; + } + } + } + if (style || startStyle || endStyle || builder.measure) { + var fullStyle = style || ""; + if (startStyle) fullStyle += startStyle; + if (endStyle) fullStyle += endStyle; + var token = elt("span", [content], fullStyle); + if (title) token.title = title; + return builder.pre.appendChild(token); + } + builder.pre.appendChild(content); + } + + function buildTokenMeasure(builder, text, style, startStyle, endStyle) { + var wrapping = builder.cm.options.lineWrapping; + for (var i = 0; i < text.length; ++i) { + var ch = text.charAt(i), start = i == 0; + if (ch >= "\ud800" && ch < "\udbff" && i < text.length - 1) { + ch = text.slice(i, i + 2); + ++i; + } else if (i && wrapping && spanAffectsWrapping(text, i)) { + builder.pre.appendChild(elt("wbr")); + } + var old = builder.measure[builder.pos]; + var span = builder.measure[builder.pos] = + buildToken(builder, ch, style, + start && startStyle, i == text.length - 1 && endStyle); + if (old) span.leftSide = old.leftSide || old; + // In IE single-space nodes wrap differently than spaces + // embedded in larger text nodes, except when set to + // white-space: normal (issue #1268). + if (ie && wrapping && ch == " " && i && !/\s/.test(text.charAt(i - 1)) && + i < text.length - 1 && !/\s/.test(text.charAt(i + 1))) + span.style.whiteSpace = "normal"; + builder.pos += ch.length; + } + if (text.length) builder.measuredSomething = true; + } + + function buildTokenSplitSpaces(inner) { + function split(old) { + var out = " "; + for (var i = 0; i < old.length - 2; ++i) out += i % 2 ? " " : "\u00a0"; + out += " "; + return out; + } + return function(builder, text, style, startStyle, endStyle, title) { + return inner(builder, text.replace(/ {3,}/, split), style, startStyle, endStyle, title); + }; + } + + function buildCollapsedSpan(builder, size, marker, ignoreWidget) { + var widget = !ignoreWidget && marker.replacedWith; + if (widget) { + if (builder.copyWidgets) widget = widget.cloneNode(true); + builder.pre.appendChild(widget); + if (builder.measure) { + if (size) { + builder.measure[builder.pos] = widget; + } else { + var elt = zeroWidthElement(builder.cm.display.measure); + if (marker.type == "bookmark" && !marker.insertLeft) + builder.measure[builder.pos] = builder.pre.appendChild(elt); + else if (builder.measure[builder.pos]) + return; + else + builder.measure[builder.pos] = builder.pre.insertBefore(elt, widget); + } + builder.measuredSomething = true; + } + } + builder.pos += size; + } + + // Outputs a number of spans to make up a line, taking highlighting + // and marked text into account. + function insertLineContent(line, builder, styles) { + var spans = line.markedSpans, allText = line.text, at = 0; + if (!spans) { + for (var i = 1; i < styles.length; i+=2) + builder.addToken(builder, allText.slice(at, at = styles[i]), interpretTokenStyle(styles[i+1], builder)); + return; + } + + var len = allText.length, pos = 0, i = 1, text = "", style; + var nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, title, collapsed; + for (;;) { + if (nextChange == pos) { // Update current marker set + spanStyle = spanEndStyle = spanStartStyle = title = ""; + collapsed = null; nextChange = Infinity; + var foundBookmarks = []; + for (var j = 0; j < spans.length; ++j) { + var sp = spans[j], m = sp.marker; + if (sp.from <= pos && (sp.to == null || sp.to > pos)) { + if (sp.to != null && nextChange > sp.to) { nextChange = sp.to; spanEndStyle = ""; } + if (m.className) spanStyle += " " + m.className; + if (m.startStyle && sp.from == pos) spanStartStyle += " " + m.startStyle; + if (m.endStyle && sp.to == nextChange) spanEndStyle += " " + m.endStyle; + if (m.title && !title) title = m.title; + if (m.collapsed && (!collapsed || collapsed.marker.size < m.size)) + collapsed = sp; + } else if (sp.from > pos && nextChange > sp.from) { + nextChange = sp.from; + } + if (m.type == "bookmark" && sp.from == pos && m.replacedWith) foundBookmarks.push(m); + } + if (collapsed && (collapsed.from || 0) == pos) { + buildCollapsedSpan(builder, (collapsed.to == null ? len : collapsed.to) - pos, + collapsed.marker, collapsed.from == null); + if (collapsed.to == null) return collapsed.marker.find(); + } + if (!collapsed && foundBookmarks.length) for (var j = 0; j < foundBookmarks.length; ++j) + buildCollapsedSpan(builder, 0, foundBookmarks[j]); + } + if (pos >= len) break; + + var upto = Math.min(len, nextChange); + while (true) { + if (text) { + var end = pos + text.length; + if (!collapsed) { + var tokenText = end > upto ? text.slice(0, upto - pos) : text; + builder.addToken(builder, tokenText, style ? style + spanStyle : spanStyle, + spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : "", title); + } + if (end >= upto) {text = text.slice(upto - pos); pos = upto; break;} + pos = end; + spanStartStyle = ""; + } + text = allText.slice(at, at = styles[i++]); + style = interpretTokenStyle(styles[i++], builder); + } + } + } + + // DOCUMENT DATA STRUCTURE + + function updateDoc(doc, change, markedSpans, selAfter, estimateHeight) { + function spansFor(n) {return markedSpans ? markedSpans[n] : null;} + function update(line, text, spans) { + updateLine(line, text, spans, estimateHeight); + signalLater(line, "change", line, change); + } + + var from = change.from, to = change.to, text = change.text; + var firstLine = getLine(doc, from.line), lastLine = getLine(doc, to.line); + var lastText = lst(text), lastSpans = spansFor(text.length - 1), nlines = to.line - from.line; + + // First adjust the line structure + if (from.ch == 0 && to.ch == 0 && lastText == "") { + // This is a whole-line replace. Treated specially to make + // sure line objects move the way they are supposed to. + for (var i = 0, e = text.length - 1, added = []; i < e; ++i) + added.push(new Line(text[i], spansFor(i), estimateHeight)); + update(lastLine, lastLine.text, lastSpans); + if (nlines) doc.remove(from.line, nlines); + if (added.length) doc.insert(from.line, added); + } else if (firstLine == lastLine) { + if (text.length == 1) { + update(firstLine, firstLine.text.slice(0, from.ch) + lastText + firstLine.text.slice(to.ch), lastSpans); + } else { + for (var added = [], i = 1, e = text.length - 1; i < e; ++i) + added.push(new Line(text[i], spansFor(i), estimateHeight)); + added.push(new Line(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight)); + update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0)); + doc.insert(from.line + 1, added); + } + } else if (text.length == 1) { + update(firstLine, firstLine.text.slice(0, from.ch) + text[0] + lastLine.text.slice(to.ch), spansFor(0)); + doc.remove(from.line + 1, nlines); + } else { + update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0)); + update(lastLine, lastText + lastLine.text.slice(to.ch), lastSpans); + for (var i = 1, e = text.length - 1, added = []; i < e; ++i) + added.push(new Line(text[i], spansFor(i), estimateHeight)); + if (nlines > 1) doc.remove(from.line + 1, nlines - 1); + doc.insert(from.line + 1, added); + } + + signalLater(doc, "change", doc, change); + setSelection(doc, selAfter.anchor, selAfter.head, null, true); + } + + function LeafChunk(lines) { + this.lines = lines; + this.parent = null; + for (var i = 0, e = lines.length, height = 0; i < e; ++i) { + lines[i].parent = this; + height += lines[i].height; + } + this.height = height; + } + + LeafChunk.prototype = { + chunkSize: function() { return this.lines.length; }, + removeInner: function(at, n) { + for (var i = at, e = at + n; i < e; ++i) { + var line = this.lines[i]; + this.height -= line.height; + cleanUpLine(line); + signalLater(line, "delete"); + } + this.lines.splice(at, n); + }, + collapse: function(lines) { + lines.splice.apply(lines, [lines.length, 0].concat(this.lines)); + }, + insertInner: function(at, lines, height) { + this.height += height; + this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at)); + for (var i = 0, e = lines.length; i < e; ++i) lines[i].parent = this; + }, + iterN: function(at, n, op) { + for (var e = at + n; at < e; ++at) + if (op(this.lines[at])) return true; + } + }; + + function BranchChunk(children) { + this.children = children; + var size = 0, height = 0; + for (var i = 0, e = children.length; i < e; ++i) { + var ch = children[i]; + size += ch.chunkSize(); height += ch.height; + ch.parent = this; + } + this.size = size; + this.height = height; + this.parent = null; + } + + BranchChunk.prototype = { + chunkSize: function() { return this.size; }, + removeInner: function(at, n) { + this.size -= n; + for (var i = 0; i < this.children.length; ++i) { + var child = this.children[i], sz = child.chunkSize(); + if (at < sz) { + var rm = Math.min(n, sz - at), oldHeight = child.height; + child.removeInner(at, rm); + this.height -= oldHeight - child.height; + if (sz == rm) { this.children.splice(i--, 1); child.parent = null; } + if ((n -= rm) == 0) break; + at = 0; + } else at -= sz; + } + if (this.size - n < 25) { + var lines = []; + this.collapse(lines); + this.children = [new LeafChunk(lines)]; + this.children[0].parent = this; + } + }, + collapse: function(lines) { + for (var i = 0, e = this.children.length; i < e; ++i) this.children[i].collapse(lines); + }, + insertInner: function(at, lines, height) { + this.size += lines.length; + this.height += height; + for (var i = 0, e = this.children.length; i < e; ++i) { + var child = this.children[i], sz = child.chunkSize(); + if (at <= sz) { + child.insertInner(at, lines, height); + if (child.lines && child.lines.length > 50) { + while (child.lines.length > 50) { + var spilled = child.lines.splice(child.lines.length - 25, 25); + var newleaf = new LeafChunk(spilled); + child.height -= newleaf.height; + this.children.splice(i + 1, 0, newleaf); + newleaf.parent = this; + } + this.maybeSpill(); + } + break; + } + at -= sz; + } + }, + maybeSpill: function() { + if (this.children.length <= 10) return; + var me = this; + do { + var spilled = me.children.splice(me.children.length - 5, 5); + var sibling = new BranchChunk(spilled); + if (!me.parent) { // Become the parent node + var copy = new BranchChunk(me.children); + copy.parent = me; + me.children = [copy, sibling]; + me = copy; + } else { + me.size -= sibling.size; + me.height -= sibling.height; + var myIndex = indexOf(me.parent.children, me); + me.parent.children.splice(myIndex + 1, 0, sibling); + } + sibling.parent = me.parent; + } while (me.children.length > 10); + me.parent.maybeSpill(); + }, + iterN: function(at, n, op) { + for (var i = 0, e = this.children.length; i < e; ++i) { + var child = this.children[i], sz = child.chunkSize(); + if (at < sz) { + var used = Math.min(n, sz - at); + if (child.iterN(at, used, op)) return true; + if ((n -= used) == 0) break; + at = 0; + } else at -= sz; + } + } + }; + + var nextDocId = 0; + var Doc = CodeMirror.Doc = function(text, mode, firstLine) { + if (!(this instanceof Doc)) return new Doc(text, mode, firstLine); + if (firstLine == null) firstLine = 0; + + BranchChunk.call(this, [new LeafChunk([new Line("", null)])]); + this.first = firstLine; + this.scrollTop = this.scrollLeft = 0; + this.cantEdit = false; + this.history = makeHistory(); + this.cleanGeneration = 1; + this.frontier = firstLine; + var start = Pos(firstLine, 0); + this.sel = {from: start, to: start, head: start, anchor: start, shift: false, extend: false, goalColumn: null}; + this.id = ++nextDocId; + this.modeOption = mode; + + if (typeof text == "string") text = splitLines(text); + updateDoc(this, {from: start, to: start, text: text}, null, {head: start, anchor: start}); + }; + + Doc.prototype = createObj(BranchChunk.prototype, { + constructor: Doc, + iter: function(from, to, op) { + if (op) this.iterN(from - this.first, to - from, op); + else this.iterN(this.first, this.first + this.size, from); + }, + + insert: function(at, lines) { + var height = 0; + for (var i = 0, e = lines.length; i < e; ++i) height += lines[i].height; + this.insertInner(at - this.first, lines, height); + }, + remove: function(at, n) { this.removeInner(at - this.first, n); }, + + getValue: function(lineSep) { + var lines = getLines(this, this.first, this.first + this.size); + if (lineSep === false) return lines; + return lines.join(lineSep || "\n"); + }, + setValue: function(code) { + var top = Pos(this.first, 0), last = this.first + this.size - 1; + makeChange(this, {from: top, to: Pos(last, getLine(this, last).text.length), + text: splitLines(code), origin: "setValue"}, + {head: top, anchor: top}, true); + }, + replaceRange: function(code, from, to, origin) { + from = clipPos(this, from); + to = to ? clipPos(this, to) : from; + replaceRange(this, code, from, to, origin); + }, + getRange: function(from, to, lineSep) { + var lines = getBetween(this, clipPos(this, from), clipPos(this, to)); + if (lineSep === false) return lines; + return lines.join(lineSep || "\n"); + }, + + getLine: function(line) {var l = this.getLineHandle(line); return l && l.text;}, + setLine: function(line, text) { + if (isLine(this, line)) + replaceRange(this, text, Pos(line, 0), clipPos(this, Pos(line))); + }, + removeLine: function(line) { + if (line) replaceRange(this, "", clipPos(this, Pos(line - 1)), clipPos(this, Pos(line))); + else replaceRange(this, "", Pos(0, 0), clipPos(this, Pos(1, 0))); + }, + + getLineHandle: function(line) {if (isLine(this, line)) return getLine(this, line);}, + getLineNumber: function(line) {return lineNo(line);}, + + getLineHandleVisualStart: function(line) { + if (typeof line == "number") line = getLine(this, line); + return visualLine(this, line); + }, + + lineCount: function() {return this.size;}, + firstLine: function() {return this.first;}, + lastLine: function() {return this.first + this.size - 1;}, + + clipPos: function(pos) {return clipPos(this, pos);}, + + getCursor: function(start) { + var sel = this.sel, pos; + if (start == null || start == "head") pos = sel.head; + else if (start == "anchor") pos = sel.anchor; + else if (start == "end" || start === false) pos = sel.to; + else pos = sel.from; + return copyPos(pos); + }, + somethingSelected: function() {return !posEq(this.sel.head, this.sel.anchor);}, + + setCursor: docOperation(function(line, ch, extend) { + var pos = clipPos(this, typeof line == "number" ? Pos(line, ch || 0) : line); + if (extend) extendSelection(this, pos); + else setSelection(this, pos, pos); + }), + setSelection: docOperation(function(anchor, head, bias) { + setSelection(this, clipPos(this, anchor), clipPos(this, head || anchor), bias); + }), + extendSelection: docOperation(function(from, to, bias) { + extendSelection(this, clipPos(this, from), to && clipPos(this, to), bias); + }), + + getSelection: function(lineSep) {return this.getRange(this.sel.from, this.sel.to, lineSep);}, + replaceSelection: function(code, collapse, origin) { + makeChange(this, {from: this.sel.from, to: this.sel.to, text: splitLines(code), origin: origin}, collapse || "around"); + }, + undo: docOperation(function() {makeChangeFromHistory(this, "undo");}), + redo: docOperation(function() {makeChangeFromHistory(this, "redo");}), + + setExtending: function(val) {this.sel.extend = val;}, + + historySize: function() { + var hist = this.history; + return {undo: hist.done.length, redo: hist.undone.length}; + }, + clearHistory: function() {this.history = makeHistory(this.history.maxGeneration);}, + + markClean: function() { + this.cleanGeneration = this.changeGeneration(); + }, + changeGeneration: function() { + this.history.lastOp = this.history.lastOrigin = null; + return this.history.generation; + }, + isClean: function (gen) { + return this.history.generation == (gen || this.cleanGeneration); + }, + + getHistory: function() { + return {done: copyHistoryArray(this.history.done), + undone: copyHistoryArray(this.history.undone)}; + }, + setHistory: function(histData) { + var hist = this.history = makeHistory(this.history.maxGeneration); + hist.done = histData.done.slice(0); + hist.undone = histData.undone.slice(0); + }, + + markText: function(from, to, options) { + return markText(this, clipPos(this, from), clipPos(this, to), options, "range"); + }, + setBookmark: function(pos, options) { + var realOpts = {replacedWith: options && (options.nodeType == null ? options.widget : options), + insertLeft: options && options.insertLeft}; + pos = clipPos(this, pos); + return markText(this, pos, pos, realOpts, "bookmark"); + }, + findMarksAt: function(pos) { + pos = clipPos(this, pos); + var markers = [], spans = getLine(this, pos.line).markedSpans; + if (spans) for (var i = 0; i < spans.length; ++i) { + var span = spans[i]; + if ((span.from == null || span.from <= pos.ch) && + (span.to == null || span.to >= pos.ch)) + markers.push(span.marker.parent || span.marker); + } + return markers; + }, + getAllMarks: function() { + var markers = []; + this.iter(function(line) { + var sps = line.markedSpans; + if (sps) for (var i = 0; i < sps.length; ++i) + if (sps[i].from != null) markers.push(sps[i].marker); + }); + return markers; + }, + + posFromIndex: function(off) { + var ch, lineNo = this.first; + this.iter(function(line) { + var sz = line.text.length + 1; + if (sz > off) { ch = off; return true; } + off -= sz; + ++lineNo; + }); + return clipPos(this, Pos(lineNo, ch)); + }, + indexFromPos: function (coords) { + coords = clipPos(this, coords); + var index = coords.ch; + if (coords.line < this.first || coords.ch < 0) return 0; + this.iter(this.first, coords.line, function (line) { + index += line.text.length + 1; + }); + return index; + }, + + copy: function(copyHistory) { + var doc = new Doc(getLines(this, this.first, this.first + this.size), this.modeOption, this.first); + doc.scrollTop = this.scrollTop; doc.scrollLeft = this.scrollLeft; + doc.sel = {from: this.sel.from, to: this.sel.to, head: this.sel.head, anchor: this.sel.anchor, + shift: this.sel.shift, extend: false, goalColumn: this.sel.goalColumn}; + if (copyHistory) { + doc.history.undoDepth = this.history.undoDepth; + doc.setHistory(this.getHistory()); + } + return doc; + }, + + linkedDoc: function(options) { + if (!options) options = {}; + var from = this.first, to = this.first + this.size; + if (options.from != null && options.from > from) from = options.from; + if (options.to != null && options.to < to) to = options.to; + var copy = new Doc(getLines(this, from, to), options.mode || this.modeOption, from); + if (options.sharedHist) copy.history = this.history; + (this.linked || (this.linked = [])).push({doc: copy, sharedHist: options.sharedHist}); + copy.linked = [{doc: this, isParent: true, sharedHist: options.sharedHist}]; + return copy; + }, + unlinkDoc: function(other) { + if (other instanceof CodeMirror) other = other.doc; + if (this.linked) for (var i = 0; i < this.linked.length; ++i) { + var link = this.linked[i]; + if (link.doc != other) continue; + this.linked.splice(i, 1); + other.unlinkDoc(this); + break; + } + // If the histories were shared, split them again + if (other.history == this.history) { + var splitIds = [other.id]; + linkedDocs(other, function(doc) {splitIds.push(doc.id);}, true); + other.history = makeHistory(); + other.history.done = copyHistoryArray(this.history.done, splitIds); + other.history.undone = copyHistoryArray(this.history.undone, splitIds); + } + }, + iterLinkedDocs: function(f) {linkedDocs(this, f);}, + + getMode: function() {return this.mode;}, + getEditor: function() {return this.cm;} + }); + + Doc.prototype.eachLine = Doc.prototype.iter; + + // The Doc methods that should be available on CodeMirror instances + var dontDelegate = "iter insert remove copy getEditor".split(" "); + for (var prop in Doc.prototype) if (Doc.prototype.hasOwnProperty(prop) && indexOf(dontDelegate, prop) < 0) + CodeMirror.prototype[prop] = (function(method) { + return function() {return method.apply(this.doc, arguments);}; + })(Doc.prototype[prop]); + + eventMixin(Doc); + + function linkedDocs(doc, f, sharedHistOnly) { + function propagate(doc, skip, sharedHist) { + if (doc.linked) for (var i = 0; i < doc.linked.length; ++i) { + var rel = doc.linked[i]; + if (rel.doc == skip) continue; + var shared = sharedHist && rel.sharedHist; + if (sharedHistOnly && !shared) continue; + f(rel.doc, shared); + propagate(rel.doc, doc, shared); + } + } + propagate(doc, null, true); + } + + function attachDoc(cm, doc) { + if (doc.cm) throw new Error("This document is already in use."); + cm.doc = doc; + doc.cm = cm; + estimateLineHeights(cm); + loadMode(cm); + if (!cm.options.lineWrapping) computeMaxLength(cm); + cm.options.mode = doc.modeOption; + regChange(cm); + } + + // LINE UTILITIES + + function getLine(chunk, n) { + n -= chunk.first; + while (!chunk.lines) { + for (var i = 0;; ++i) { + var child = chunk.children[i], sz = child.chunkSize(); + if (n < sz) { chunk = child; break; } + n -= sz; + } + } + return chunk.lines[n]; + } + + function getBetween(doc, start, end) { + var out = [], n = start.line; + doc.iter(start.line, end.line + 1, function(line) { + var text = line.text; + if (n == end.line) text = text.slice(0, end.ch); + if (n == start.line) text = text.slice(start.ch); + out.push(text); + ++n; + }); + return out; + } + function getLines(doc, from, to) { + var out = []; + doc.iter(from, to, function(line) { out.push(line.text); }); + return out; + } + + function updateLineHeight(line, height) { + var diff = height - line.height; + for (var n = line; n; n = n.parent) n.height += diff; + } + + function lineNo(line) { + if (line.parent == null) return null; + var cur = line.parent, no = indexOf(cur.lines, line); + for (var chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) { + for (var i = 0;; ++i) { + if (chunk.children[i] == cur) break; + no += chunk.children[i].chunkSize(); + } + } + return no + cur.first; + } + + function lineAtHeight(chunk, h) { + var n = chunk.first; + outer: do { + for (var i = 0, e = chunk.children.length; i < e; ++i) { + var child = chunk.children[i], ch = child.height; + if (h < ch) { chunk = child; continue outer; } + h -= ch; + n += child.chunkSize(); + } + return n; + } while (!chunk.lines); + for (var i = 0, e = chunk.lines.length; i < e; ++i) { + var line = chunk.lines[i], lh = line.height; + if (h < lh) break; + h -= lh; + } + return n + i; + } + + function heightAtLine(cm, lineObj) { + lineObj = visualLine(cm.doc, lineObj); + + var h = 0, chunk = lineObj.parent; + for (var i = 0; i < chunk.lines.length; ++i) { + var line = chunk.lines[i]; + if (line == lineObj) break; + else h += line.height; + } + for (var p = chunk.parent; p; chunk = p, p = chunk.parent) { + for (var i = 0; i < p.children.length; ++i) { + var cur = p.children[i]; + if (cur == chunk) break; + else h += cur.height; + } + } + return h; + } + + function getOrder(line) { + var order = line.order; + if (order == null) order = line.order = bidiOrdering(line.text); + return order; + } + + // HISTORY + + function makeHistory(startGen) { + return { + // Arrays of history events. Doing something adds an event to + // done and clears undo. Undoing moves events from done to + // undone, redoing moves them in the other direction. + done: [], undone: [], undoDepth: Infinity, + // Used to track when changes can be merged into a single undo + // event + lastTime: 0, lastOp: null, lastOrigin: null, + // Used by the isClean() method + generation: startGen || 1, maxGeneration: startGen || 1 + }; + } + + function attachLocalSpans(doc, change, from, to) { + var existing = change["spans_" + doc.id], n = 0; + doc.iter(Math.max(doc.first, from), Math.min(doc.first + doc.size, to), function(line) { + if (line.markedSpans) + (existing || (existing = change["spans_" + doc.id] = {}))[n] = line.markedSpans; + ++n; + }); + } + + function historyChangeFromChange(doc, change) { + var from = { line: change.from.line, ch: change.from.ch }; + var histChange = {from: from, to: changeEnd(change), text: getBetween(doc, change.from, change.to)}; + attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1); + linkedDocs(doc, function(doc) {attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);}, true); + return histChange; + } + + function addToHistory(doc, change, selAfter, opId) { + var hist = doc.history; + hist.undone.length = 0; + var time = +new Date, cur = lst(hist.done); + + if (cur && + (hist.lastOp == opId || + hist.lastOrigin == change.origin && change.origin && + ((change.origin.charAt(0) == "+" && doc.cm && hist.lastTime > time - doc.cm.options.historyEventDelay) || + change.origin.charAt(0) == "*"))) { + // Merge this change into the last event + var last = lst(cur.changes); + if (posEq(change.from, change.to) && posEq(change.from, last.to)) { + // Optimized case for simple insertion -- don't want to add + // new changesets for every character typed + last.to = changeEnd(change); + } else { + // Add new sub-event + cur.changes.push(historyChangeFromChange(doc, change)); + } + cur.anchorAfter = selAfter.anchor; cur.headAfter = selAfter.head; + } else { + // Can not be merged, start a new event. + cur = {changes: [historyChangeFromChange(doc, change)], + generation: hist.generation, + anchorBefore: doc.sel.anchor, headBefore: doc.sel.head, + anchorAfter: selAfter.anchor, headAfter: selAfter.head}; + hist.done.push(cur); + hist.generation = ++hist.maxGeneration; + while (hist.done.length > hist.undoDepth) + hist.done.shift(); + } + hist.lastTime = time; + hist.lastOp = opId; + hist.lastOrigin = change.origin; + } + + function removeClearedSpans(spans) { + if (!spans) return null; + for (var i = 0, out; i < spans.length; ++i) { + if (spans[i].marker.explicitlyCleared) { if (!out) out = spans.slice(0, i); } + else if (out) out.push(spans[i]); + } + return !out ? spans : out.length ? out : null; + } + + function getOldSpans(doc, change) { + var found = change["spans_" + doc.id]; + if (!found) return null; + for (var i = 0, nw = []; i < change.text.length; ++i) + nw.push(removeClearedSpans(found[i])); + return nw; + } + + // Used both to provide a JSON-safe object in .getHistory, and, when + // detaching a document, to split the history in two + function copyHistoryArray(events, newGroup) { + for (var i = 0, copy = []; i < events.length; ++i) { + var event = events[i], changes = event.changes, newChanges = []; + copy.push({changes: newChanges, anchorBefore: event.anchorBefore, headBefore: event.headBefore, + anchorAfter: event.anchorAfter, headAfter: event.headAfter}); + for (var j = 0; j < changes.length; ++j) { + var change = changes[j], m; + newChanges.push({from: change.from, to: change.to, text: change.text}); + if (newGroup) for (var prop in change) if (m = prop.match(/^spans_(\d+)$/)) { + if (indexOf(newGroup, Number(m[1])) > -1) { + lst(newChanges)[prop] = change[prop]; + delete change[prop]; + } + } + } + } + return copy; + } + + // Rebasing/resetting history to deal with externally-sourced changes + + function rebaseHistSel(pos, from, to, diff) { + if (to < pos.line) { + pos.line += diff; + } else if (from < pos.line) { + pos.line = from; + pos.ch = 0; + } + } + + // Tries to rebase an array of history events given a change in the + // document. If the change touches the same lines as the event, the + // event, and everything 'behind' it, is discarded. If the change is + // before the event, the event's positions are updated. Uses a + // copy-on-write scheme for the positions, to avoid having to + // reallocate them all on every rebase, but also avoid problems with + // shared position objects being unsafely updated. + function rebaseHistArray(array, from, to, diff) { + for (var i = 0; i < array.length; ++i) { + var sub = array[i], ok = true; + for (var j = 0; j < sub.changes.length; ++j) { + var cur = sub.changes[j]; + if (!sub.copied) { cur.from = copyPos(cur.from); cur.to = copyPos(cur.to); } + if (to < cur.from.line) { + cur.from.line += diff; + cur.to.line += diff; + } else if (from <= cur.to.line) { + ok = false; + break; + } + } + if (!sub.copied) { + sub.anchorBefore = copyPos(sub.anchorBefore); sub.headBefore = copyPos(sub.headBefore); + sub.anchorAfter = copyPos(sub.anchorAfter); sub.readAfter = copyPos(sub.headAfter); + sub.copied = true; + } + if (!ok) { + array.splice(0, i + 1); + i = 0; + } else { + rebaseHistSel(sub.anchorBefore); rebaseHistSel(sub.headBefore); + rebaseHistSel(sub.anchorAfter); rebaseHistSel(sub.headAfter); + } + } + } + + function rebaseHist(hist, change) { + var from = change.from.line, to = change.to.line, diff = change.text.length - (to - from) - 1; + rebaseHistArray(hist.done, from, to, diff); + rebaseHistArray(hist.undone, from, to, diff); + } + + // EVENT OPERATORS + + function stopMethod() {e_stop(this);} + // Ensure an event has a stop method. + function addStop(event) { + if (!event.stop) event.stop = stopMethod; + return event; + } + + function e_preventDefault(e) { + if (e.preventDefault) e.preventDefault(); + else e.returnValue = false; + } + function e_stopPropagation(e) { + if (e.stopPropagation) e.stopPropagation(); + else e.cancelBubble = true; + } + function e_defaultPrevented(e) { + return e.defaultPrevented != null ? e.defaultPrevented : e.returnValue == false; + } + function e_stop(e) {e_preventDefault(e); e_stopPropagation(e);} + CodeMirror.e_stop = e_stop; + CodeMirror.e_preventDefault = e_preventDefault; + CodeMirror.e_stopPropagation = e_stopPropagation; + + function e_target(e) {return e.target || e.srcElement;} + function e_button(e) { + var b = e.which; + if (b == null) { + if (e.button & 1) b = 1; + else if (e.button & 2) b = 3; + else if (e.button & 4) b = 2; + } + if (mac && e.ctrlKey && b == 1) b = 3; + return b; + } + + // EVENT HANDLING + + function on(emitter, type, f) { + if (emitter.addEventListener) + emitter.addEventListener(type, f, false); + else if (emitter.attachEvent) + emitter.attachEvent("on" + type, f); + else { + var map = emitter._handlers || (emitter._handlers = {}); + var arr = map[type] || (map[type] = []); + arr.push(f); + } + } + + function off(emitter, type, f) { + if (emitter.removeEventListener) + emitter.removeEventListener(type, f, false); + else if (emitter.detachEvent) + emitter.detachEvent("on" + type, f); + else { + var arr = emitter._handlers && emitter._handlers[type]; + if (!arr) return; + for (var i = 0; i < arr.length; ++i) + if (arr[i] == f) { arr.splice(i, 1); break; } + } + } + + function signal(emitter, type /*, values...*/) { + var arr = emitter._handlers && emitter._handlers[type]; + if (!arr) return; + var args = Array.prototype.slice.call(arguments, 2); + for (var i = 0; i < arr.length; ++i) arr[i].apply(null, args); + } + + var delayedCallbacks, delayedCallbackDepth = 0; + function signalLater(emitter, type /*, values...*/) { + var arr = emitter._handlers && emitter._handlers[type]; + if (!arr) return; + var args = Array.prototype.slice.call(arguments, 2); + if (!delayedCallbacks) { + ++delayedCallbackDepth; + delayedCallbacks = []; + setTimeout(fireDelayed, 0); + } + function bnd(f) {return function(){f.apply(null, args);};}; + for (var i = 0; i < arr.length; ++i) + delayedCallbacks.push(bnd(arr[i])); + } + + function signalDOMEvent(cm, e, override) { + signal(cm, override || e.type, cm, e); + return e_defaultPrevented(e) || e.codemirrorIgnore; + } + + function fireDelayed() { + --delayedCallbackDepth; + var delayed = delayedCallbacks; + delayedCallbacks = null; + for (var i = 0; i < delayed.length; ++i) delayed[i](); + } + + function hasHandler(emitter, type) { + var arr = emitter._handlers && emitter._handlers[type]; + return arr && arr.length > 0; + } + + CodeMirror.on = on; CodeMirror.off = off; CodeMirror.signal = signal; + + function eventMixin(ctor) { + ctor.prototype.on = function(type, f) {on(this, type, f);}; + ctor.prototype.off = function(type, f) {off(this, type, f);}; + } + + // MISC UTILITIES + + // Number of pixels added to scroller and sizer to hide scrollbar + var scrollerCutOff = 30; + + // Returned or thrown by various protocols to signal 'I'm not + // handling this'. + var Pass = CodeMirror.Pass = {toString: function(){return "CodeMirror.Pass";}}; + + function Delayed() {this.id = null;} + Delayed.prototype = {set: function(ms, f) {clearTimeout(this.id); this.id = setTimeout(f, ms);}}; + + // Counts the column offset in a string, taking tabs into account. + // Used mostly to find indentation. + function countColumn(string, end, tabSize, startIndex, startValue) { + if (end == null) { + end = string.search(/[^\s\u00a0]/); + if (end == -1) end = string.length; + } + for (var i = startIndex || 0, n = startValue || 0; i < end; ++i) { + if (string.charAt(i) == "\t") n += tabSize - (n % tabSize); + else ++n; + } + return n; + } + CodeMirror.countColumn = countColumn; + + var spaceStrs = [""]; + function spaceStr(n) { + while (spaceStrs.length <= n) + spaceStrs.push(lst(spaceStrs) + " "); + return spaceStrs[n]; + } + + function lst(arr) { return arr[arr.length-1]; } + + function selectInput(node) { + if (ios) { // Mobile Safari apparently has a bug where select() is broken. + node.selectionStart = 0; + node.selectionEnd = node.value.length; + } else { + // Suppress mysterious IE10 errors + try { node.select(); } + catch(_e) {} + } + } + + function indexOf(collection, elt) { + if (collection.indexOf) return collection.indexOf(elt); + for (var i = 0, e = collection.length; i < e; ++i) + if (collection[i] == elt) return i; + return -1; + } + + function createObj(base, props) { + function Obj() {} + Obj.prototype = base; + var inst = new Obj(); + if (props) copyObj(props, inst); + return inst; + } + + function copyObj(obj, target) { + if (!target) target = {}; + for (var prop in obj) if (obj.hasOwnProperty(prop)) target[prop] = obj[prop]; + return target; + } + + function emptyArray(size) { + for (var a = [], i = 0; i < size; ++i) a.push(undefined); + return a; + } + + function bind(f) { + var args = Array.prototype.slice.call(arguments, 1); + return function(){return f.apply(null, args);}; + } + + var nonASCIISingleCaseWordChar = /[\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/; + function isWordChar(ch) { + return /\w/.test(ch) || ch > "\x80" && + (ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch)); + } + + function isEmpty(obj) { + for (var n in obj) if (obj.hasOwnProperty(n) && obj[n]) return false; + return true; + } + + var isExtendingChar = /[\u0300-\u036F\u0483-\u0487\u0488-\u0489\u0591-\u05BD\u05BF\u05C1-\u05C2\u05C4-\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7-\u06E8\u06EA-\u06ED\uA66F\uA670-\uA672\uA674-\uA67D\uA69F\udc00-\udfff]/; + + // DOM UTILITIES + + function elt(tag, content, className, style) { + var e = document.createElement(tag); + if (className) e.className = className; + if (style) e.style.cssText = style; + if (typeof content == "string") setTextContent(e, content); + else if (content) for (var i = 0; i < content.length; ++i) e.appendChild(content[i]); + return e; + } + + function removeChildren(e) { + for (var count = e.childNodes.length; count > 0; --count) + e.removeChild(e.firstChild); + return e; + } + + function removeChildrenAndAdd(parent, e) { + return removeChildren(parent).appendChild(e); + } + + function setTextContent(e, str) { + if (ie_lt9) { + e.innerHTML = ""; + e.appendChild(document.createTextNode(str)); + } else e.textContent = str; + } + + function getRect(node) { + return node.getBoundingClientRect(); + } + CodeMirror.replaceGetRect = function(f) { getRect = f; }; + + // FEATURE DETECTION + + // Detect drag-and-drop + var dragAndDrop = function() { + // There is *some* kind of drag-and-drop support in IE6-8, but I + // couldn't get it to work yet. + if (ie_lt9) return false; + var div = elt('div'); + return "draggable" in div || "dragDrop" in div; + }(); + + // For a reason I have yet to figure out, some browsers disallow + // word wrapping between certain characters *only* if a new inline + // element is started between them. This makes it hard to reliably + // measure the position of things, since that requires inserting an + // extra span. This terribly fragile set of tests matches the + // character combinations that suffer from this phenomenon on the + // various browsers. + function spanAffectsWrapping() { return false; } + if (gecko) // Only for "$'" + spanAffectsWrapping = function(str, i) { + return str.charCodeAt(i - 1) == 36 && str.charCodeAt(i) == 39; + }; + else if (safari && !/Version\/([6-9]|\d\d)\b/.test(navigator.userAgent)) + spanAffectsWrapping = function(str, i) { + return /\-[^ \-?]|\?[^ !\'\"\),.\-\/:;\?\]\}]/.test(str.slice(i - 1, i + 1)); + }; + else if (webkit && /Chrome\/(?:29|[3-9]\d|\d\d\d)\./.test(navigator.userAgent)) + spanAffectsWrapping = function(str, i) { + var code = str.charCodeAt(i - 1); + return code >= 8208 && code <= 8212; + }; + else if (webkit) + spanAffectsWrapping = function(str, i) { + if (i > 1 && str.charCodeAt(i - 1) == 45) { + if (/\w/.test(str.charAt(i - 2)) && /[^\-?\.]/.test(str.charAt(i))) return true; + if (i > 2 && /[\d\.,]/.test(str.charAt(i - 2)) && /[\d\.,]/.test(str.charAt(i))) return false; + } + return /[~!#%&*)=+}\]\\|\"\.>,:;][({[<]|-[^\-?\.\u2010-\u201f\u2026]|\?[\w~`@#$%\^&*(_=+{[|><]|…[\w~`@#$%\^&*(_=+{[><]/.test(str.slice(i - 1, i + 1)); + }; + + var knownScrollbarWidth; + function scrollbarWidth(measure) { + if (knownScrollbarWidth != null) return knownScrollbarWidth; + var test = elt("div", null, null, "width: 50px; height: 50px; overflow-x: scroll"); + removeChildrenAndAdd(measure, test); + if (test.offsetWidth) + knownScrollbarWidth = test.offsetHeight - test.clientHeight; + return knownScrollbarWidth || 0; + } + + var zwspSupported; + function zeroWidthElement(measure) { + if (zwspSupported == null) { + var test = elt("span", "\u200b"); + removeChildrenAndAdd(measure, elt("span", [test, document.createTextNode("x")])); + if (measure.firstChild.offsetHeight != 0) + zwspSupported = test.offsetWidth <= 1 && test.offsetHeight > 2 && !ie_lt8; + } + if (zwspSupported) return elt("span", "\u200b"); + else return elt("span", "\u00a0", null, "display: inline-block; width: 1px; margin-right: -1px"); + } + + // See if "".split is the broken IE version, if so, provide an + // alternative way to split lines. + var splitLines = "\n\nb".split(/\n/).length != 3 ? function(string) { + var pos = 0, result = [], l = string.length; + while (pos <= l) { + var nl = string.indexOf("\n", pos); + if (nl == -1) nl = string.length; + var line = string.slice(pos, string.charAt(nl - 1) == "\r" ? nl - 1 : nl); + var rt = line.indexOf("\r"); + if (rt != -1) { + result.push(line.slice(0, rt)); + pos += rt + 1; + } else { + result.push(line); + pos = nl + 1; + } + } + return result; + } : function(string){return string.split(/\r\n?|\n/);}; + CodeMirror.splitLines = splitLines; + + var hasSelection = window.getSelection ? function(te) { + try { return te.selectionStart != te.selectionEnd; } + catch(e) { return false; } + } : function(te) { + try {var range = te.ownerDocument.selection.createRange();} + catch(e) {} + if (!range || range.parentElement() != te) return false; + return range.compareEndPoints("StartToEnd", range) != 0; + }; + + var hasCopyEvent = (function() { + var e = elt("div"); + if ("oncopy" in e) return true; + e.setAttribute("oncopy", "return;"); + return typeof e.oncopy == 'function'; + })(); + + // KEY NAMING + + var keyNames = {3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt", + 19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End", + 36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert", + 46: "Delete", 59: ";", 91: "Mod", 92: "Mod", 93: "Mod", 109: "-", 107: "=", 127: "Delete", + 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\", + 221: "]", 222: "'", 63276: "PageUp", 63277: "PageDown", 63275: "End", 63273: "Home", + 63234: "Left", 63232: "Up", 63235: "Right", 63233: "Down", 63302: "Insert", 63272: "Delete"}; + CodeMirror.keyNames = keyNames; + (function() { + // Number keys + for (var i = 0; i < 10; i++) keyNames[i + 48] = String(i); + // Alphabetic keys + for (var i = 65; i <= 90; i++) keyNames[i] = String.fromCharCode(i); + // Function keys + for (var i = 1; i <= 12; i++) keyNames[i + 111] = keyNames[i + 63235] = "F" + i; + })(); + + // BIDI HELPERS + + function iterateBidiSections(order, from, to, f) { + if (!order) return f(from, to, "ltr"); + var found = false; + for (var i = 0; i < order.length; ++i) { + var part = order[i]; + if (part.from < to && part.to > from || from == to && part.to == from) { + f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? "rtl" : "ltr"); + found = true; + } + } + if (!found) f(from, to, "ltr"); + } + + function bidiLeft(part) { return part.level % 2 ? part.to : part.from; } + function bidiRight(part) { return part.level % 2 ? part.from : part.to; } + + function lineLeft(line) { var order = getOrder(line); return order ? bidiLeft(order[0]) : 0; } + function lineRight(line) { + var order = getOrder(line); + if (!order) return line.text.length; + return bidiRight(lst(order)); + } + + function lineStart(cm, lineN) { + var line = getLine(cm.doc, lineN); + var visual = visualLine(cm.doc, line); + if (visual != line) lineN = lineNo(visual); + var order = getOrder(visual); + var ch = !order ? 0 : order[0].level % 2 ? lineRight(visual) : lineLeft(visual); + return Pos(lineN, ch); + } + function lineEnd(cm, lineN) { + var merged, line; + while (merged = collapsedSpanAtEnd(line = getLine(cm.doc, lineN))) + lineN = merged.find().to.line; + var order = getOrder(line); + var ch = !order ? line.text.length : order[0].level % 2 ? lineLeft(line) : lineRight(line); + return Pos(lineN, ch); + } + + function compareBidiLevel(order, a, b) { + var linedir = order[0].level; + if (a == linedir) return true; + if (b == linedir) return false; + return a < b; + } + var bidiOther; + function getBidiPartAt(order, pos) { + for (var i = 0, found; i < order.length; ++i) { + var cur = order[i]; + if (cur.from < pos && cur.to > pos) { bidiOther = null; return i; } + if (cur.from == pos || cur.to == pos) { + if (found == null) { + found = i; + } else if (compareBidiLevel(order, cur.level, order[found].level)) { + bidiOther = found; + return i; + } else { + bidiOther = i; + return found; + } + } + } + bidiOther = null; + return found; + } + + function moveInLine(line, pos, dir, byUnit) { + if (!byUnit) return pos + dir; + do pos += dir; + while (pos > 0 && isExtendingChar.test(line.text.charAt(pos))); + return pos; + } + + // This is somewhat involved. It is needed in order to move + // 'visually' through bi-directional text -- i.e., pressing left + // should make the cursor go left, even when in RTL text. The + // tricky part is the 'jumps', where RTL and LTR text touch each + // other. This often requires the cursor offset to move more than + // one unit, in order to visually move one unit. + function moveVisually(line, start, dir, byUnit) { + var bidi = getOrder(line); + if (!bidi) return moveLogically(line, start, dir, byUnit); + var pos = getBidiPartAt(bidi, start), part = bidi[pos]; + var target = moveInLine(line, start, part.level % 2 ? -dir : dir, byUnit); + + for (;;) { + if (target > part.from && target < part.to) return target; + if (target == part.from || target == part.to) { + if (getBidiPartAt(bidi, target) == pos) return target; + part = bidi[pos += dir]; + return (dir > 0) == part.level % 2 ? part.to : part.from; + } else { + part = bidi[pos += dir]; + if (!part) return null; + if ((dir > 0) == part.level % 2) + target = moveInLine(line, part.to, -1, byUnit); + else + target = moveInLine(line, part.from, 1, byUnit); + } + } + } + + function moveLogically(line, start, dir, byUnit) { + var target = start + dir; + if (byUnit) while (target > 0 && isExtendingChar.test(line.text.charAt(target))) target += dir; + return target < 0 || target > line.text.length ? null : target; + } + + // Bidirectional ordering algorithm + // See http://unicode.org/reports/tr9/tr9-13.html for the algorithm + // that this (partially) implements. + + // One-char codes used for character types: + // L (L): Left-to-Right + // R (R): Right-to-Left + // r (AL): Right-to-Left Arabic + // 1 (EN): European Number + // + (ES): European Number Separator + // % (ET): European Number Terminator + // n (AN): Arabic Number + // , (CS): Common Number Separator + // m (NSM): Non-Spacing Mark + // b (BN): Boundary Neutral + // s (B): Paragraph Separator + // t (S): Segment Separator + // w (WS): Whitespace + // N (ON): Other Neutrals + + // Returns null if characters are ordered as they appear + // (left-to-right), or an array of sections ({from, to, level} + // objects) in the order in which they occur visually. + var bidiOrdering = (function() { + // Character types for codepoints 0 to 0xff + var lowTypes = "bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLL"; + // Character types for codepoints 0x600 to 0x6ff + var arabicTypes = "rrrrrrrrrrrr,rNNmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmrrrrrrrnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmNmmmmrrrrrrrrrrrrrrrrrr"; + function charType(code) { + if (code <= 0xff) return lowTypes.charAt(code); + else if (0x590 <= code && code <= 0x5f4) return "R"; + else if (0x600 <= code && code <= 0x6ff) return arabicTypes.charAt(code - 0x600); + else if (0x700 <= code && code <= 0x8ac) return "r"; + else return "L"; + } + + var bidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/; + var isNeutral = /[stwN]/, isStrong = /[LRr]/, countsAsLeft = /[Lb1n]/, countsAsNum = /[1n]/; + // Browsers seem to always treat the boundaries of block elements as being L. + var outerType = "L"; + + return function(str) { + if (!bidiRE.test(str)) return false; + var len = str.length, types = []; + for (var i = 0, type; i < len; ++i) + types.push(type = charType(str.charCodeAt(i))); + + // W1. Examine each non-spacing mark (NSM) in the level run, and + // change the type of the NSM to the type of the previous + // character. If the NSM is at the start of the level run, it will + // get the type of sor. + for (var i = 0, prev = outerType; i < len; ++i) { + var type = types[i]; + if (type == "m") types[i] = prev; + else prev = type; + } + + // W2. Search backwards from each instance of a European number + // until the first strong type (R, L, AL, or sor) is found. If an + // AL is found, change the type of the European number to Arabic + // number. + // W3. Change all ALs to R. + for (var i = 0, cur = outerType; i < len; ++i) { + var type = types[i]; + if (type == "1" && cur == "r") types[i] = "n"; + else if (isStrong.test(type)) { cur = type; if (type == "r") types[i] = "R"; } + } + + // W4. A single European separator between two European numbers + // changes to a European number. A single common separator between + // two numbers of the same type changes to that type. + for (var i = 1, prev = types[0]; i < len - 1; ++i) { + var type = types[i]; + if (type == "+" && prev == "1" && types[i+1] == "1") types[i] = "1"; + else if (type == "," && prev == types[i+1] && + (prev == "1" || prev == "n")) types[i] = prev; + prev = type; + } + + // W5. A sequence of European terminators adjacent to European + // numbers changes to all European numbers. + // W6. Otherwise, separators and terminators change to Other + // Neutral. + for (var i = 0; i < len; ++i) { + var type = types[i]; + if (type == ",") types[i] = "N"; + else if (type == "%") { + for (var end = i + 1; end < len && types[end] == "%"; ++end) {} + var replace = (i && types[i-1] == "!") || (end < len - 1 && types[end] == "1") ? "1" : "N"; + for (var j = i; j < end; ++j) types[j] = replace; + i = end - 1; + } + } + + // W7. Search backwards from each instance of a European number + // until the first strong type (R, L, or sor) is found. If an L is + // found, then change the type of the European number to L. + for (var i = 0, cur = outerType; i < len; ++i) { + var type = types[i]; + if (cur == "L" && type == "1") types[i] = "L"; + else if (isStrong.test(type)) cur = type; + } + + // N1. A sequence of neutrals takes the direction of the + // surrounding strong text if the text on both sides has the same + // direction. European and Arabic numbers act as if they were R in + // terms of their influence on neutrals. Start-of-level-run (sor) + // and end-of-level-run (eor) are used at level run boundaries. + // N2. Any remaining neutrals take the embedding direction. + for (var i = 0; i < len; ++i) { + if (isNeutral.test(types[i])) { + for (var end = i + 1; end < len && isNeutral.test(types[end]); ++end) {} + var before = (i ? types[i-1] : outerType) == "L"; + var after = (end < len - 1 ? types[end] : outerType) == "L"; + var replace = before || after ? "L" : "R"; + for (var j = i; j < end; ++j) types[j] = replace; + i = end - 1; + } + } + + // Here we depart from the documented algorithm, in order to avoid + // building up an actual levels array. Since there are only three + // levels (0, 1, 2) in an implementation that doesn't take + // explicit embedding into account, we can build up the order on + // the fly, without following the level-based algorithm. + var order = [], m; + for (var i = 0; i < len;) { + if (countsAsLeft.test(types[i])) { + var start = i; + for (++i; i < len && countsAsLeft.test(types[i]); ++i) {} + order.push({from: start, to: i, level: 0}); + } else { + var pos = i, at = order.length; + for (++i; i < len && types[i] != "L"; ++i) {} + for (var j = pos; j < i;) { + if (countsAsNum.test(types[j])) { + if (pos < j) order.splice(at, 0, {from: pos, to: j, level: 1}); + var nstart = j; + for (++j; j < i && countsAsNum.test(types[j]); ++j) {} + order.splice(at, 0, {from: nstart, to: j, level: 2}); + pos = j; + } else ++j; + } + if (pos < i) order.splice(at, 0, {from: pos, to: i, level: 1}); + } + } + if (order[0].level == 1 && (m = str.match(/^\s+/))) { + order[0].from = m[0].length; + order.unshift({from: 0, to: m[0].length, level: 0}); + } + if (lst(order).level == 1 && (m = str.match(/\s+$/))) { + lst(order).to -= m[0].length; + order.push({from: len - m[0].length, to: len, level: 0}); + } + if (order[0].level != lst(order).level) + order.push({from: len, to: len, level: order[0].level}); + + return order; + }; + })(); + + // THE END + + CodeMirror.version = "3.17.0"; + + return CodeMirror; +})(); diff --git a/profile-builder/assets/lib/codemirror/mode/css/css.js b/profile-builder/assets/lib/codemirror/mode/css/css.js index 4264bc6..f2cd49f 100644 --- a/profile-builder/assets/lib/codemirror/mode/css/css.js +++ b/profile-builder/assets/lib/codemirror/mode/css/css.js @@ -1,627 +1,627 @@ -CodeMirror.defineMode("css", function(config, parserConfig) { - "use strict"; - - if (!parserConfig.propertyKeywords) parserConfig = CodeMirror.resolveMode("text/css"); - - var indentUnit = config.indentUnit, - hooks = parserConfig.hooks || {}, - atMediaTypes = parserConfig.atMediaTypes || {}, - atMediaFeatures = parserConfig.atMediaFeatures || {}, - propertyKeywords = parserConfig.propertyKeywords || {}, - colorKeywords = parserConfig.colorKeywords || {}, - valueKeywords = parserConfig.valueKeywords || {}, - allowNested = !!parserConfig.allowNested, - type = null; - - function ret(style, tp) { type = tp; return style; } - - function tokenBase(stream, state) { - var ch = stream.next(); - if (hooks[ch]) { - // result[0] is style and result[1] is type - var result = hooks[ch](stream, state); - if (result !== false) return result; - } - if (ch == "@") {stream.eatWhile(/[\w\\\-]/); return ret("def", stream.current());} - else if (ch == "=") ret(null, "compare"); - else if ((ch == "~" || ch == "|") && stream.eat("=")) return ret(null, "compare"); - else if (ch == "\"" || ch == "'") { - state.tokenize = tokenString(ch); - return state.tokenize(stream, state); - } - else if (ch == "#") { - stream.eatWhile(/[\w\\\-]/); - return ret("atom", "hash"); - } - else if (ch == "!") { - stream.match(/^\s*\w*/); - return ret("keyword", "important"); - } - else if (/\d/.test(ch) || ch == "." && stream.eat(/\d/)) { - stream.eatWhile(/[\w.%]/); - return ret("number", "unit"); - } - else if (ch === "-") { - if (/\d/.test(stream.peek())) { - stream.eatWhile(/[\w.%]/); - return ret("number", "unit"); - } else if (stream.match(/^[^-]+-/)) { - return ret("meta", "meta"); - } - } - else if (/[,+>*\/]/.test(ch)) { - return ret(null, "select-op"); - } - else if (ch == "." && stream.match(/^-?[_a-z][_a-z0-9-]*/i)) { - return ret("qualifier", "qualifier"); - } - else if (ch == ":") { - return ret("operator", ch); - } - else if (/[;{}\[\]\(\)]/.test(ch)) { - return ret(null, ch); - } - else if (ch == "u" && stream.match("rl(")) { - stream.backUp(1); - state.tokenize = tokenParenthesized; - return ret("property", "variable"); - } - else { - stream.eatWhile(/[\w\\\-]/); - return ret("property", "variable"); - } - } - - function tokenString(quote, nonInclusive) { - return function(stream, state) { - var escaped = false, ch; - while ((ch = stream.next()) != null) { - if (ch == quote && !escaped) - break; - escaped = !escaped && ch == "\\"; - } - if (!escaped) { - if (nonInclusive) stream.backUp(1); - state.tokenize = tokenBase; - } - return ret("string", "string"); - }; - } - - function tokenParenthesized(stream, state) { - stream.next(); // Must be '(' - if (!stream.match(/\s*[\"\']/, false)) - state.tokenize = tokenString(")", true); - else - state.tokenize = tokenBase; - return ret(null, "("); - } - - return { - startState: function(base) { - return {tokenize: tokenBase, - baseIndent: base || 0, - stack: [], - lastToken: null}; - }, - - token: function(stream, state) { - - // Use these terms when applicable (see http://www.xanthir.com/blog/b4E50) - // - // rule** or **ruleset: - // A selector + braces combo, or an at-rule. - // - // declaration block: - // A sequence of declarations. - // - // declaration: - // A property + colon + value combo. - // - // property value: - // The entire value of a property. - // - // component value: - // A single piece of a property value. Like the 5px in - // text-shadow: 0 0 5px blue;. Can also refer to things that are - // multiple terms, like the 1-4 terms that make up the background-size - // portion of the background shorthand. - // - // term: - // The basic unit of author-facing CSS, like a single number (5), - // dimension (5px), string ("foo"), or function. Officially defined - // by the CSS 2.1 grammar (look for the 'term' production) - // - // - // simple selector: - // A single atomic selector, like a type selector, an attr selector, a - // class selector, etc. - // - // compound selector: - // One or more simple selectors without a combinator. div.example is - // compound, div > .example is not. - // - // complex selector: - // One or more compound selectors chained with combinators. - // - // combinator: - // The parts of selectors that express relationships. There are four - // currently - the space (descendant combinator), the greater-than - // bracket (child combinator), the plus sign (next sibling combinator), - // and the tilda (following sibling combinator). - // - // sequence of selectors: - // One or more of the named type of selector chained with commas. - - state.tokenize = state.tokenize || tokenBase; - if (state.tokenize == tokenBase && stream.eatSpace()) return null; - var style = state.tokenize(stream, state); - if (style && typeof style != "string") style = ret(style[0], style[1]); - - // Changing style returned based on context - var context = state.stack[state.stack.length-1]; - if (style == "variable") { - if (type == "variable-definition") state.stack.push("propertyValue"); - return state.lastToken = "variable-2"; - } else if (style == "property") { - var word = stream.current().toLowerCase(); - if (context == "propertyValue") { - if (valueKeywords.hasOwnProperty(word)) { - style = "string-2"; - } else if (colorKeywords.hasOwnProperty(word)) { - style = "keyword"; - } else { - style = "variable-2"; - } - } else if (context == "rule") { - if (!propertyKeywords.hasOwnProperty(word)) { - style += " error"; - } - } else if (context == "block") { - // if a value is present in both property, value, or color, the order - // of preference is property -> color -> value - if (propertyKeywords.hasOwnProperty(word)) { - style = "property"; - } else if (colorKeywords.hasOwnProperty(word)) { - style = "keyword"; - } else if (valueKeywords.hasOwnProperty(word)) { - style = "string-2"; - } else { - style = "tag"; - } - } else if (!context || context == "@media{") { - style = "tag"; - } else if (context == "@media") { - if (atMediaTypes[stream.current()]) { - style = "attribute"; // Known attribute - } else if (/^(only|not)$/.test(word)) { - style = "keyword"; - } else if (word == "and") { - style = "error"; // "and" is only allowed in @mediaType - } else if (atMediaFeatures.hasOwnProperty(word)) { - style = "error"; // Known property, should be in @mediaType( - } else { - // Unknown, expecting keyword or attribute, assuming attribute - style = "attribute error"; - } - } else if (context == "@mediaType") { - if (atMediaTypes.hasOwnProperty(word)) { - style = "attribute"; - } else if (word == "and") { - style = "operator"; - } else if (/^(only|not)$/.test(word)) { - style = "error"; // Only allowed in @media - } else { - // Unknown attribute or property, but expecting property (preceded - // by "and"). Should be in parentheses - style = "error"; - } - } else if (context == "@mediaType(") { - if (propertyKeywords.hasOwnProperty(word)) { - // do nothing, remains "property" - } else if (atMediaTypes.hasOwnProperty(word)) { - style = "error"; // Known property, should be in parentheses - } else if (word == "and") { - style = "operator"; - } else if (/^(only|not)$/.test(word)) { - style = "error"; // Only allowed in @media - } else { - style += " error"; - } - } else if (context == "@import") { - style = "tag"; - } else { - style = "error"; - } - } else if (style == "atom") { - if(!context || context == "@media{" || context == "block") { - style = "builtin"; - } else if (context == "propertyValue") { - if (!/^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/.test(stream.current())) { - style += " error"; - } - } else { - style = "error"; - } - } else if (context == "@media" && type == "{") { - style = "error"; - } - - // Push/pop context stack - if (type == "{") { - if (context == "@media" || context == "@mediaType") { - state.stack[state.stack.length-1] = "@media{"; - } - else { - var newContext = allowNested ? "block" : "rule"; - state.stack.push(newContext); - } - } - else if (type == "}") { - if (context == "interpolation") style = "operator"; - state.stack.pop(); - if (context == "propertyValue") state.stack.pop(); - } - else if (type == "interpolation") state.stack.push("interpolation"); - else if (type == "@media") state.stack.push("@media"); - else if (type == "@import") state.stack.push("@import"); - else if (context == "@media" && /\b(keyword|attribute)\b/.test(style)) - state.stack[state.stack.length-1] = "@mediaType"; - else if (context == "@mediaType" && stream.current() == ",") - state.stack[state.stack.length-1] = "@media"; - else if (type == "(") { - if (context == "@media" || context == "@mediaType") { - // Make sure @mediaType is used to avoid error on { - state.stack[state.stack.length-1] = "@mediaType"; - state.stack.push("@mediaType("); - } - else state.stack.push("("); - } - else if (type == ")") { - if (context == "propertyValue") { - // In @mediaType( without closing ; after propertyValue - state.stack.pop(); - } - state.stack.pop(); - } - else if (type == ":" && state.lastToken == "property") state.stack.push("propertyValue"); - else if (context == "propertyValue" && type == ";") state.stack.pop(); - else if (context == "@import" && type == ";") state.stack.pop(); - - return state.lastToken = style; - }, - - indent: function(state, textAfter) { - var n = state.stack.length; - if (/^\}/.test(textAfter)) - n -= state.stack[n-1] == "propertyValue" ? 2 : 1; - return state.baseIndent + n * indentUnit; - }, - - electricChars: "}", - blockCommentStart: "/*", - blockCommentEnd: "*/", - fold: "brace" - }; -}); - -(function() { - function keySet(array) { - var keys = {}; - for (var i = 0; i < array.length; ++i) { - keys[array[i]] = true; - } - return keys; - } - - var atMediaTypes = keySet([ - "all", "aural", "braille", "handheld", "print", "projection", "screen", - "tty", "tv", "embossed" - ]); - - var atMediaFeatures = keySet([ - "width", "min-width", "max-width", "height", "min-height", "max-height", - "device-width", "min-device-width", "max-device-width", "device-height", - "min-device-height", "max-device-height", "aspect-ratio", - "min-aspect-ratio", "max-aspect-ratio", "device-aspect-ratio", - "min-device-aspect-ratio", "max-device-aspect-ratio", "color", "min-color", - "max-color", "color-index", "min-color-index", "max-color-index", - "monochrome", "min-monochrome", "max-monochrome", "resolution", - "min-resolution", "max-resolution", "scan", "grid" - ]); - - var propertyKeywords = keySet([ - "align-content", "align-items", "align-self", "alignment-adjust", - "alignment-baseline", "anchor-point", "animation", "animation-delay", - "animation-direction", "animation-duration", "animation-iteration-count", - "animation-name", "animation-play-state", "animation-timing-function", - "appearance", "azimuth", "backface-visibility", "background", - "background-attachment", "background-clip", "background-color", - "background-image", "background-origin", "background-position", - "background-repeat", "background-size", "baseline-shift", "binding", - "bleed", "bookmark-label", "bookmark-level", "bookmark-state", - "bookmark-target", "border", "border-bottom", "border-bottom-color", - "border-bottom-left-radius", "border-bottom-right-radius", - "border-bottom-style", "border-bottom-width", "border-collapse", - "border-color", "border-image", "border-image-outset", - "border-image-repeat", "border-image-slice", "border-image-source", - "border-image-width", "border-left", "border-left-color", - "border-left-style", "border-left-width", "border-radius", "border-right", - "border-right-color", "border-right-style", "border-right-width", - "border-spacing", "border-style", "border-top", "border-top-color", - "border-top-left-radius", "border-top-right-radius", "border-top-style", - "border-top-width", "border-width", "bottom", "box-decoration-break", - "box-shadow", "box-sizing", "break-after", "break-before", "break-inside", - "caption-side", "clear", "clip", "color", "color-profile", "column-count", - "column-fill", "column-gap", "column-rule", "column-rule-color", - "column-rule-style", "column-rule-width", "column-span", "column-width", - "columns", "content", "counter-increment", "counter-reset", "crop", "cue", - "cue-after", "cue-before", "cursor", "direction", "display", - "dominant-baseline", "drop-initial-after-adjust", - "drop-initial-after-align", "drop-initial-before-adjust", - "drop-initial-before-align", "drop-initial-size", "drop-initial-value", - "elevation", "empty-cells", "fit", "fit-position", "flex", "flex-basis", - "flex-direction", "flex-flow", "flex-grow", "flex-shrink", "flex-wrap", - "float", "float-offset", "flow-from", "flow-into", "font", "font-feature-settings", - "font-family", "font-kerning", "font-language-override", "font-size", "font-size-adjust", - "font-stretch", "font-style", "font-synthesis", "font-variant", - "font-variant-alternates", "font-variant-caps", "font-variant-east-asian", - "font-variant-ligatures", "font-variant-numeric", "font-variant-position", - "font-weight", "grid-cell", "grid-column", "grid-column-align", - "grid-column-sizing", "grid-column-span", "grid-columns", "grid-flow", - "grid-row", "grid-row-align", "grid-row-sizing", "grid-row-span", - "grid-rows", "grid-template", "hanging-punctuation", "height", "hyphens", - "icon", "image-orientation", "image-rendering", "image-resolution", - "inline-box-align", "justify-content", "left", "letter-spacing", - "line-break", "line-height", "line-stacking", "line-stacking-ruby", - "line-stacking-shift", "line-stacking-strategy", "list-style", - "list-style-image", "list-style-position", "list-style-type", "margin", - "margin-bottom", "margin-left", "margin-right", "margin-top", - "marker-offset", "marks", "marquee-direction", "marquee-loop", - "marquee-play-count", "marquee-speed", "marquee-style", "max-height", - "max-width", "min-height", "min-width", "move-to", "nav-down", "nav-index", - "nav-left", "nav-right", "nav-up", "opacity", "order", "orphans", "outline", - "outline-color", "outline-offset", "outline-style", "outline-width", - "overflow", "overflow-style", "overflow-wrap", "overflow-x", "overflow-y", - "padding", "padding-bottom", "padding-left", "padding-right", "padding-top", - "page", "page-break-after", "page-break-before", "page-break-inside", - "page-policy", "pause", "pause-after", "pause-before", "perspective", - "perspective-origin", "pitch", "pitch-range", "play-during", "position", - "presentation-level", "punctuation-trim", "quotes", "region-break-after", - "region-break-before", "region-break-inside", "region-fragment", - "rendering-intent", "resize", "rest", "rest-after", "rest-before", "richness", - "right", "rotation", "rotation-point", "ruby-align", "ruby-overhang", - "ruby-position", "ruby-span", "shape-inside", "shape-outside", "size", - "speak", "speak-as", "speak-header", - "speak-numeral", "speak-punctuation", "speech-rate", "stress", "string-set", - "tab-size", "table-layout", "target", "target-name", "target-new", - "target-position", "text-align", "text-align-last", "text-decoration", - "text-decoration-color", "text-decoration-line", "text-decoration-skip", - "text-decoration-style", "text-emphasis", "text-emphasis-color", - "text-emphasis-position", "text-emphasis-style", "text-height", - "text-indent", "text-justify", "text-outline", "text-overflow", "text-shadow", - "text-size-adjust", "text-space-collapse", "text-transform", "text-underline-position", - "text-wrap", "top", "transform", "transform-origin", "transform-style", - "transition", "transition-delay", "transition-duration", - "transition-property", "transition-timing-function", "unicode-bidi", - "vertical-align", "visibility", "voice-balance", "voice-duration", - "voice-family", "voice-pitch", "voice-range", "voice-rate", "voice-stress", - "voice-volume", "volume", "white-space", "widows", "width", "word-break", - "word-spacing", "word-wrap", "z-index", "zoom", - // SVG-specific - "clip-path", "clip-rule", "mask", "enable-background", "filter", "flood-color", - "flood-opacity", "lighting-color", "stop-color", "stop-opacity", "pointer-events", - "color-interpolation", "color-interpolation-filters", "color-profile", - "color-rendering", "fill", "fill-opacity", "fill-rule", "image-rendering", - "marker", "marker-end", "marker-mid", "marker-start", "shape-rendering", "stroke", - "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin", - "stroke-miterlimit", "stroke-opacity", "stroke-width", "text-rendering", - "baseline-shift", "dominant-baseline", "glyph-orientation-horizontal", - "glyph-orientation-vertical", "kerning", "text-anchor", "writing-mode" - ]); - - var colorKeywords = keySet([ - "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", - "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", - "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", - "cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod", - "darkgray", "darkgreen", "darkkhaki", "darkmagenta", "darkolivegreen", - "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", - "darkslateblue", "darkslategray", "darkturquoise", "darkviolet", - "deeppink", "deepskyblue", "dimgray", "dodgerblue", "firebrick", - "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", - "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", - "hotpink", "indianred", "indigo", "ivory", "khaki", "lavender", - "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", - "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightpink", - "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", - "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", - "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", - "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", - "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", - "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered", - "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", - "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", - "purple", "red", "rosybrown", "royalblue", "saddlebrown", "salmon", - "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", - "slateblue", "slategray", "snow", "springgreen", "steelblue", "tan", - "teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white", - "whitesmoke", "yellow", "yellowgreen" - ]); - - var valueKeywords = keySet([ - "above", "absolute", "activeborder", "activecaption", "afar", - "after-white-space", "ahead", "alias", "all", "all-scroll", "alternate", - "always", "amharic", "amharic-abegede", "antialiased", "appworkspace", - "arabic-indic", "armenian", "asterisks", "auto", "avoid", "avoid-column", "avoid-page", - "avoid-region", "background", "backwards", "baseline", "below", "bidi-override", "binary", - "bengali", "blink", "block", "block-axis", "bold", "bolder", "border", "border-box", - "both", "bottom", "break", "break-all", "break-word", "button", "button-bevel", - "buttonface", "buttonhighlight", "buttonshadow", "buttontext", "cambodian", - "capitalize", "caps-lock-indicator", "caption", "captiontext", "caret", - "cell", "center", "checkbox", "circle", "cjk-earthly-branch", - "cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote", - "col-resize", "collapse", "column", "compact", "condensed", "contain", "content", - "content-box", "context-menu", "continuous", "copy", "cover", "crop", - "cross", "crosshair", "currentcolor", "cursive", "dashed", "decimal", - "decimal-leading-zero", "default", "default-button", "destination-atop", - "destination-in", "destination-out", "destination-over", "devanagari", - "disc", "discard", "document", "dot-dash", "dot-dot-dash", "dotted", - "double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out", - "element", "ellipse", "ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede", - "ethiopic-abegede-am-et", "ethiopic-abegede-gez", "ethiopic-abegede-ti-er", - "ethiopic-abegede-ti-et", "ethiopic-halehame-aa-er", - "ethiopic-halehame-aa-et", "ethiopic-halehame-am-et", - "ethiopic-halehame-gez", "ethiopic-halehame-om-et", - "ethiopic-halehame-sid-et", "ethiopic-halehame-so-et", - "ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et", - "ethiopic-halehame-tig", "ew-resize", "expanded", "extra-condensed", - "extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "footnotes", - "forwards", "from", "geometricPrecision", "georgian", "graytext", "groove", - "gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hebrew", - "help", "hidden", "hide", "higher", "highlight", "highlighttext", - "hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "icon", "ignore", - "inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite", - "infobackground", "infotext", "inherit", "initial", "inline", "inline-axis", - "inline-block", "inline-table", "inset", "inside", "intrinsic", "invert", - "italic", "justify", "kannada", "katakana", "katakana-iroha", "keep-all", "khmer", - "landscape", "lao", "large", "larger", "left", "level", "lighter", - "line-through", "linear", "lines", "list-item", "listbox", "listitem", - "local", "logical", "loud", "lower", "lower-alpha", "lower-armenian", - "lower-greek", "lower-hexadecimal", "lower-latin", "lower-norwegian", - "lower-roman", "lowercase", "ltr", "malayalam", "match", - "media-controls-background", "media-current-time-display", - "media-fullscreen-button", "media-mute-button", "media-play-button", - "media-return-to-realtime-button", "media-rewind-button", - "media-seek-back-button", "media-seek-forward-button", "media-slider", - "media-sliderthumb", "media-time-remaining-display", "media-volume-slider", - "media-volume-slider-container", "media-volume-sliderthumb", "medium", - "menu", "menulist", "menulist-button", "menulist-text", - "menulist-textfield", "menutext", "message-box", "middle", "min-intrinsic", - "mix", "mongolian", "monospace", "move", "multiple", "myanmar", "n-resize", - "narrower", "ne-resize", "nesw-resize", "no-close-quote", "no-drop", - "no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap", - "ns-resize", "nw-resize", "nwse-resize", "oblique", "octal", "open-quote", - "optimizeLegibility", "optimizeSpeed", "oriya", "oromo", "outset", - "outside", "outside-shape", "overlay", "overline", "padding", "padding-box", - "painted", "page", "paused", "persian", "plus-darker", "plus-lighter", "pointer", - "polygon", "portrait", "pre", "pre-line", "pre-wrap", "preserve-3d", "progress", "push-button", - "radio", "read-only", "read-write", "read-write-plaintext-only", "rectangle", "region", - "relative", "repeat", "repeat-x", "repeat-y", "reset", "reverse", "rgb", "rgba", - "ridge", "right", "round", "row-resize", "rtl", "run-in", "running", - "s-resize", "sans-serif", "scroll", "scrollbar", "se-resize", "searchfield", - "searchfield-cancel-button", "searchfield-decoration", - "searchfield-results-button", "searchfield-results-decoration", - "semi-condensed", "semi-expanded", "separate", "serif", "show", "sidama", - "single", "skip-white-space", "slide", "slider-horizontal", - "slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow", - "small", "small-caps", "small-caption", "smaller", "solid", "somali", - "source-atop", "source-in", "source-out", "source-over", "space", "square", - "square-button", "start", "static", "status-bar", "stretch", "stroke", - "sub", "subpixel-antialiased", "super", "sw-resize", "table", - "table-caption", "table-cell", "table-column", "table-column-group", - "table-footer-group", "table-header-group", "table-row", "table-row-group", - "telugu", "text", "text-bottom", "text-top", "textarea", "textfield", "thai", - "thick", "thin", "threeddarkshadow", "threedface", "threedhighlight", - "threedlightshadow", "threedshadow", "tibetan", "tigre", "tigrinya-er", - "tigrinya-er-abegede", "tigrinya-et", "tigrinya-et-abegede", "to", "top", - "transparent", "ultra-condensed", "ultra-expanded", "underline", "up", - "upper-alpha", "upper-armenian", "upper-greek", "upper-hexadecimal", - "upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url", - "vertical", "vertical-text", "visible", "visibleFill", "visiblePainted", - "visibleStroke", "visual", "w-resize", "wait", "wave", "wider", - "window", "windowframe", "windowtext", "x-large", "x-small", "xor", - "xx-large", "xx-small" - ]); - - function tokenCComment(stream, state) { - var maybeEnd = false, ch; - while ((ch = stream.next()) != null) { - if (maybeEnd && ch == "/") { - state.tokenize = null; - break; - } - maybeEnd = (ch == "*"); - } - return ["comment", "comment"]; - } - - CodeMirror.defineMIME("text/css", { - atMediaTypes: atMediaTypes, - atMediaFeatures: atMediaFeatures, - propertyKeywords: propertyKeywords, - colorKeywords: colorKeywords, - valueKeywords: valueKeywords, - hooks: { - "<": function(stream, state) { - function tokenSGMLComment(stream, state) { - var dashes = 0, ch; - while ((ch = stream.next()) != null) { - if (dashes >= 2 && ch == ">") { - state.tokenize = null; - break; - } - dashes = (ch == "-") ? dashes + 1 : 0; - } - return ["comment", "comment"]; - } - if (stream.eat("!")) { - state.tokenize = tokenSGMLComment; - return tokenSGMLComment(stream, state); - } - }, - "/": function(stream, state) { - if (stream.eat("*")) { - state.tokenize = tokenCComment; - return tokenCComment(stream, state); - } - return false; - } - }, - name: "css" - }); - - CodeMirror.defineMIME("text/x-scss", { - atMediaTypes: atMediaTypes, - atMediaFeatures: atMediaFeatures, - propertyKeywords: propertyKeywords, - colorKeywords: colorKeywords, - valueKeywords: valueKeywords, - allowNested: true, - hooks: { - ":": function(stream) { - if (stream.match(/\s*{/)) { - return [null, "{"]; - } - return false; - }, - "$": function(stream) { - stream.match(/^[\w-]+/); - if (stream.peek() == ":") { - return ["variable", "variable-definition"]; - } - return ["variable", "variable"]; - }, - "/": function(stream, state) { - if (stream.eat("/")) { - stream.skipToEnd(); - return ["comment", "comment"]; - } else if (stream.eat("*")) { - state.tokenize = tokenCComment; - return tokenCComment(stream, state); - } else { - return ["operator", "operator"]; - } - }, - "#": function(stream) { - if (stream.eat("{")) { - return ["operator", "interpolation"]; - } else { - stream.eatWhile(/[\w\\\-]/); - return ["atom", "hash"]; - } - } - }, - name: "css" - }); -})(); +CodeMirror.defineMode("css", function(config, parserConfig) { + "use strict"; + + if (!parserConfig.propertyKeywords) parserConfig = CodeMirror.resolveMode("text/css"); + + var indentUnit = config.indentUnit, + hooks = parserConfig.hooks || {}, + atMediaTypes = parserConfig.atMediaTypes || {}, + atMediaFeatures = parserConfig.atMediaFeatures || {}, + propertyKeywords = parserConfig.propertyKeywords || {}, + colorKeywords = parserConfig.colorKeywords || {}, + valueKeywords = parserConfig.valueKeywords || {}, + allowNested = !!parserConfig.allowNested, + type = null; + + function ret(style, tp) { type = tp; return style; } + + function tokenBase(stream, state) { + var ch = stream.next(); + if (hooks[ch]) { + // result[0] is style and result[1] is type + var result = hooks[ch](stream, state); + if (result !== false) return result; + } + if (ch == "@") {stream.eatWhile(/[\w\\\-]/); return ret("def", stream.current());} + else if (ch == "=") ret(null, "compare"); + else if ((ch == "~" || ch == "|") && stream.eat("=")) return ret(null, "compare"); + else if (ch == "\"" || ch == "'") { + state.tokenize = tokenString(ch); + return state.tokenize(stream, state); + } + else if (ch == "#") { + stream.eatWhile(/[\w\\\-]/); + return ret("atom", "hash"); + } + else if (ch == "!") { + stream.match(/^\s*\w*/); + return ret("keyword", "important"); + } + else if (/\d/.test(ch) || ch == "." && stream.eat(/\d/)) { + stream.eatWhile(/[\w.%]/); + return ret("number", "unit"); + } + else if (ch === "-") { + if (/\d/.test(stream.peek())) { + stream.eatWhile(/[\w.%]/); + return ret("number", "unit"); + } else if (stream.match(/^[^-]+-/)) { + return ret("meta", "meta"); + } + } + else if (/[,+>*\/]/.test(ch)) { + return ret(null, "select-op"); + } + else if (ch == "." && stream.match(/^-?[_a-z][_a-z0-9-]*/i)) { + return ret("qualifier", "qualifier"); + } + else if (ch == ":") { + return ret("operator", ch); + } + else if (/[;{}\[\]\(\)]/.test(ch)) { + return ret(null, ch); + } + else if (ch == "u" && stream.match("rl(")) { + stream.backUp(1); + state.tokenize = tokenParenthesized; + return ret("property", "variable"); + } + else { + stream.eatWhile(/[\w\\\-]/); + return ret("property", "variable"); + } + } + + function tokenString(quote, nonInclusive) { + return function(stream, state) { + var escaped = false, ch; + while ((ch = stream.next()) != null) { + if (ch == quote && !escaped) + break; + escaped = !escaped && ch == "\\"; + } + if (!escaped) { + if (nonInclusive) stream.backUp(1); + state.tokenize = tokenBase; + } + return ret("string", "string"); + }; + } + + function tokenParenthesized(stream, state) { + stream.next(); // Must be '(' + if (!stream.match(/\s*[\"\']/, false)) + state.tokenize = tokenString(")", true); + else + state.tokenize = tokenBase; + return ret(null, "("); + } + + return { + startState: function(base) { + return {tokenize: tokenBase, + baseIndent: base || 0, + stack: [], + lastToken: null}; + }, + + token: function(stream, state) { + + // Use these terms when applicable (see http://www.xanthir.com/blog/b4E50) + // + // rule** or **ruleset: + // A selector + braces combo, or an at-rule. + // + // declaration block: + // A sequence of declarations. + // + // declaration: + // A property + colon + value combo. + // + // property value: + // The entire value of a property. + // + // component value: + // A single piece of a property value. Like the 5px in + // text-shadow: 0 0 5px blue;. Can also refer to things that are + // multiple terms, like the 1-4 terms that make up the background-size + // portion of the background shorthand. + // + // term: + // The basic unit of author-facing CSS, like a single number (5), + // dimension (5px), string ("foo"), or function. Officially defined + // by the CSS 2.1 grammar (look for the 'term' production) + // + // + // simple selector: + // A single atomic selector, like a type selector, an attr selector, a + // class selector, etc. + // + // compound selector: + // One or more simple selectors without a combinator. div.example is + // compound, div > .example is not. + // + // complex selector: + // One or more compound selectors chained with combinators. + // + // combinator: + // The parts of selectors that express relationships. There are four + // currently - the space (descendant combinator), the greater-than + // bracket (child combinator), the plus sign (next sibling combinator), + // and the tilda (following sibling combinator). + // + // sequence of selectors: + // One or more of the named type of selector chained with commas. + + state.tokenize = state.tokenize || tokenBase; + if (state.tokenize == tokenBase && stream.eatSpace()) return null; + var style = state.tokenize(stream, state); + if (style && typeof style != "string") style = ret(style[0], style[1]); + + // Changing style returned based on context + var context = state.stack[state.stack.length-1]; + if (style == "variable") { + if (type == "variable-definition") state.stack.push("propertyValue"); + return state.lastToken = "variable-2"; + } else if (style == "property") { + var word = stream.current().toLowerCase(); + if (context == "propertyValue") { + if (valueKeywords.hasOwnProperty(word)) { + style = "string-2"; + } else if (colorKeywords.hasOwnProperty(word)) { + style = "keyword"; + } else { + style = "variable-2"; + } + } else if (context == "rule") { + if (!propertyKeywords.hasOwnProperty(word)) { + style += " error"; + } + } else if (context == "block") { + // if a value is present in both property, value, or color, the order + // of preference is property -> color -> value + if (propertyKeywords.hasOwnProperty(word)) { + style = "property"; + } else if (colorKeywords.hasOwnProperty(word)) { + style = "keyword"; + } else if (valueKeywords.hasOwnProperty(word)) { + style = "string-2"; + } else { + style = "tag"; + } + } else if (!context || context == "@media{") { + style = "tag"; + } else if (context == "@media") { + if (atMediaTypes[stream.current()]) { + style = "attribute"; // Known attribute + } else if (/^(only|not)$/.test(word)) { + style = "keyword"; + } else if (word == "and") { + style = "error"; // "and" is only allowed in @mediaType + } else if (atMediaFeatures.hasOwnProperty(word)) { + style = "error"; // Known property, should be in @mediaType( + } else { + // Unknown, expecting keyword or attribute, assuming attribute + style = "attribute error"; + } + } else if (context == "@mediaType") { + if (atMediaTypes.hasOwnProperty(word)) { + style = "attribute"; + } else if (word == "and") { + style = "operator"; + } else if (/^(only|not)$/.test(word)) { + style = "error"; // Only allowed in @media + } else { + // Unknown attribute or property, but expecting property (preceded + // by "and"). Should be in parentheses + style = "error"; + } + } else if (context == "@mediaType(") { + if (propertyKeywords.hasOwnProperty(word)) { + // do nothing, remains "property" + } else if (atMediaTypes.hasOwnProperty(word)) { + style = "error"; // Known property, should be in parentheses + } else if (word == "and") { + style = "operator"; + } else if (/^(only|not)$/.test(word)) { + style = "error"; // Only allowed in @media + } else { + style += " error"; + } + } else if (context == "@import") { + style = "tag"; + } else { + style = "error"; + } + } else if (style == "atom") { + if(!context || context == "@media{" || context == "block") { + style = "builtin"; + } else if (context == "propertyValue") { + if (!/^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/.test(stream.current())) { + style += " error"; + } + } else { + style = "error"; + } + } else if (context == "@media" && type == "{") { + style = "error"; + } + + // Push/pop context stack + if (type == "{") { + if (context == "@media" || context == "@mediaType") { + state.stack[state.stack.length-1] = "@media{"; + } + else { + var newContext = allowNested ? "block" : "rule"; + state.stack.push(newContext); + } + } + else if (type == "}") { + if (context == "interpolation") style = "operator"; + state.stack.pop(); + if (context == "propertyValue") state.stack.pop(); + } + else if (type == "interpolation") state.stack.push("interpolation"); + else if (type == "@media") state.stack.push("@media"); + else if (type == "@import") state.stack.push("@import"); + else if (context == "@media" && /\b(keyword|attribute)\b/.test(style)) + state.stack[state.stack.length-1] = "@mediaType"; + else if (context == "@mediaType" && stream.current() == ",") + state.stack[state.stack.length-1] = "@media"; + else if (type == "(") { + if (context == "@media" || context == "@mediaType") { + // Make sure @mediaType is used to avoid error on { + state.stack[state.stack.length-1] = "@mediaType"; + state.stack.push("@mediaType("); + } + else state.stack.push("("); + } + else if (type == ")") { + if (context == "propertyValue") { + // In @mediaType( without closing ; after propertyValue + state.stack.pop(); + } + state.stack.pop(); + } + else if (type == ":" && state.lastToken == "property") state.stack.push("propertyValue"); + else if (context == "propertyValue" && type == ";") state.stack.pop(); + else if (context == "@import" && type == ";") state.stack.pop(); + + return state.lastToken = style; + }, + + indent: function(state, textAfter) { + var n = state.stack.length; + if (/^\}/.test(textAfter)) + n -= state.stack[n-1] == "propertyValue" ? 2 : 1; + return state.baseIndent + n * indentUnit; + }, + + electricChars: "}", + blockCommentStart: "/*", + blockCommentEnd: "*/", + fold: "brace" + }; +}); + +(function() { + function keySet(array) { + var keys = {}; + for (var i = 0; i < array.length; ++i) { + keys[array[i]] = true; + } + return keys; + } + + var atMediaTypes = keySet([ + "all", "aural", "braille", "handheld", "print", "projection", "screen", + "tty", "tv", "embossed" + ]); + + var atMediaFeatures = keySet([ + "width", "min-width", "max-width", "height", "min-height", "max-height", + "device-width", "min-device-width", "max-device-width", "device-height", + "min-device-height", "max-device-height", "aspect-ratio", + "min-aspect-ratio", "max-aspect-ratio", "device-aspect-ratio", + "min-device-aspect-ratio", "max-device-aspect-ratio", "color", "min-color", + "max-color", "color-index", "min-color-index", "max-color-index", + "monochrome", "min-monochrome", "max-monochrome", "resolution", + "min-resolution", "max-resolution", "scan", "grid" + ]); + + var propertyKeywords = keySet([ + "align-content", "align-items", "align-self", "alignment-adjust", + "alignment-baseline", "anchor-point", "animation", "animation-delay", + "animation-direction", "animation-duration", "animation-iteration-count", + "animation-name", "animation-play-state", "animation-timing-function", + "appearance", "azimuth", "backface-visibility", "background", + "background-attachment", "background-clip", "background-color", + "background-image", "background-origin", "background-position", + "background-repeat", "background-size", "baseline-shift", "binding", + "bleed", "bookmark-label", "bookmark-level", "bookmark-state", + "bookmark-target", "border", "border-bottom", "border-bottom-color", + "border-bottom-left-radius", "border-bottom-right-radius", + "border-bottom-style", "border-bottom-width", "border-collapse", + "border-color", "border-image", "border-image-outset", + "border-image-repeat", "border-image-slice", "border-image-source", + "border-image-width", "border-left", "border-left-color", + "border-left-style", "border-left-width", "border-radius", "border-right", + "border-right-color", "border-right-style", "border-right-width", + "border-spacing", "border-style", "border-top", "border-top-color", + "border-top-left-radius", "border-top-right-radius", "border-top-style", + "border-top-width", "border-width", "bottom", "box-decoration-break", + "box-shadow", "box-sizing", "break-after", "break-before", "break-inside", + "caption-side", "clear", "clip", "color", "color-profile", "column-count", + "column-fill", "column-gap", "column-rule", "column-rule-color", + "column-rule-style", "column-rule-width", "column-span", "column-width", + "columns", "content", "counter-increment", "counter-reset", "crop", "cue", + "cue-after", "cue-before", "cursor", "direction", "display", + "dominant-baseline", "drop-initial-after-adjust", + "drop-initial-after-align", "drop-initial-before-adjust", + "drop-initial-before-align", "drop-initial-size", "drop-initial-value", + "elevation", "empty-cells", "fit", "fit-position", "flex", "flex-basis", + "flex-direction", "flex-flow", "flex-grow", "flex-shrink", "flex-wrap", + "float", "float-offset", "flow-from", "flow-into", "font", "font-feature-settings", + "font-family", "font-kerning", "font-language-override", "font-size", "font-size-adjust", + "font-stretch", "font-style", "font-synthesis", "font-variant", + "font-variant-alternates", "font-variant-caps", "font-variant-east-asian", + "font-variant-ligatures", "font-variant-numeric", "font-variant-position", + "font-weight", "grid-cell", "grid-column", "grid-column-align", + "grid-column-sizing", "grid-column-span", "grid-columns", "grid-flow", + "grid-row", "grid-row-align", "grid-row-sizing", "grid-row-span", + "grid-rows", "grid-template", "hanging-punctuation", "height", "hyphens", + "icon", "image-orientation", "image-rendering", "image-resolution", + "inline-box-align", "justify-content", "left", "letter-spacing", + "line-break", "line-height", "line-stacking", "line-stacking-ruby", + "line-stacking-shift", "line-stacking-strategy", "list-style", + "list-style-image", "list-style-position", "list-style-type", "margin", + "margin-bottom", "margin-left", "margin-right", "margin-top", + "marker-offset", "marks", "marquee-direction", "marquee-loop", + "marquee-play-count", "marquee-speed", "marquee-style", "max-height", + "max-width", "min-height", "min-width", "move-to", "nav-down", "nav-index", + "nav-left", "nav-right", "nav-up", "opacity", "order", "orphans", "outline", + "outline-color", "outline-offset", "outline-style", "outline-width", + "overflow", "overflow-style", "overflow-wrap", "overflow-x", "overflow-y", + "padding", "padding-bottom", "padding-left", "padding-right", "padding-top", + "page", "page-break-after", "page-break-before", "page-break-inside", + "page-policy", "pause", "pause-after", "pause-before", "perspective", + "perspective-origin", "pitch", "pitch-range", "play-during", "position", + "presentation-level", "punctuation-trim", "quotes", "region-break-after", + "region-break-before", "region-break-inside", "region-fragment", + "rendering-intent", "resize", "rest", "rest-after", "rest-before", "richness", + "right", "rotation", "rotation-point", "ruby-align", "ruby-overhang", + "ruby-position", "ruby-span", "shape-inside", "shape-outside", "size", + "speak", "speak-as", "speak-header", + "speak-numeral", "speak-punctuation", "speech-rate", "stress", "string-set", + "tab-size", "table-layout", "target", "target-name", "target-new", + "target-position", "text-align", "text-align-last", "text-decoration", + "text-decoration-color", "text-decoration-line", "text-decoration-skip", + "text-decoration-style", "text-emphasis", "text-emphasis-color", + "text-emphasis-position", "text-emphasis-style", "text-height", + "text-indent", "text-justify", "text-outline", "text-overflow", "text-shadow", + "text-size-adjust", "text-space-collapse", "text-transform", "text-underline-position", + "text-wrap", "top", "transform", "transform-origin", "transform-style", + "transition", "transition-delay", "transition-duration", + "transition-property", "transition-timing-function", "unicode-bidi", + "vertical-align", "visibility", "voice-balance", "voice-duration", + "voice-family", "voice-pitch", "voice-range", "voice-rate", "voice-stress", + "voice-volume", "volume", "white-space", "widows", "width", "word-break", + "word-spacing", "word-wrap", "z-index", "zoom", + // SVG-specific + "clip-path", "clip-rule", "mask", "enable-background", "filter", "flood-color", + "flood-opacity", "lighting-color", "stop-color", "stop-opacity", "pointer-events", + "color-interpolation", "color-interpolation-filters", "color-profile", + "color-rendering", "fill", "fill-opacity", "fill-rule", "image-rendering", + "marker", "marker-end", "marker-mid", "marker-start", "shape-rendering", "stroke", + "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin", + "stroke-miterlimit", "stroke-opacity", "stroke-width", "text-rendering", + "baseline-shift", "dominant-baseline", "glyph-orientation-horizontal", + "glyph-orientation-vertical", "kerning", "text-anchor", "writing-mode" + ]); + + var colorKeywords = keySet([ + "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", + "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", + "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", + "cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod", + "darkgray", "darkgreen", "darkkhaki", "darkmagenta", "darkolivegreen", + "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", + "darkslateblue", "darkslategray", "darkturquoise", "darkviolet", + "deeppink", "deepskyblue", "dimgray", "dodgerblue", "firebrick", + "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", + "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", + "hotpink", "indianred", "indigo", "ivory", "khaki", "lavender", + "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", + "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightpink", + "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", + "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", + "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", + "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", + "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", + "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered", + "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", + "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", + "purple", "red", "rosybrown", "royalblue", "saddlebrown", "salmon", + "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", + "slateblue", "slategray", "snow", "springgreen", "steelblue", "tan", + "teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white", + "whitesmoke", "yellow", "yellowgreen" + ]); + + var valueKeywords = keySet([ + "above", "absolute", "activeborder", "activecaption", "afar", + "after-white-space", "ahead", "alias", "all", "all-scroll", "alternate", + "always", "amharic", "amharic-abegede", "antialiased", "appworkspace", + "arabic-indic", "armenian", "asterisks", "auto", "avoid", "avoid-column", "avoid-page", + "avoid-region", "background", "backwards", "baseline", "below", "bidi-override", "binary", + "bengali", "blink", "block", "block-axis", "bold", "bolder", "border", "border-box", + "both", "bottom", "break", "break-all", "break-word", "button", "button-bevel", + "buttonface", "buttonhighlight", "buttonshadow", "buttontext", "cambodian", + "capitalize", "caps-lock-indicator", "caption", "captiontext", "caret", + "cell", "center", "checkbox", "circle", "cjk-earthly-branch", + "cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote", + "col-resize", "collapse", "column", "compact", "condensed", "contain", "content", + "content-box", "context-menu", "continuous", "copy", "cover", "crop", + "cross", "crosshair", "currentcolor", "cursive", "dashed", "decimal", + "decimal-leading-zero", "default", "default-button", "destination-atop", + "destination-in", "destination-out", "destination-over", "devanagari", + "disc", "discard", "document", "dot-dash", "dot-dot-dash", "dotted", + "double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out", + "element", "ellipse", "ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede", + "ethiopic-abegede-am-et", "ethiopic-abegede-gez", "ethiopic-abegede-ti-er", + "ethiopic-abegede-ti-et", "ethiopic-halehame-aa-er", + "ethiopic-halehame-aa-et", "ethiopic-halehame-am-et", + "ethiopic-halehame-gez", "ethiopic-halehame-om-et", + "ethiopic-halehame-sid-et", "ethiopic-halehame-so-et", + "ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et", + "ethiopic-halehame-tig", "ew-resize", "expanded", "extra-condensed", + "extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "footnotes", + "forwards", "from", "geometricPrecision", "georgian", "graytext", "groove", + "gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hebrew", + "help", "hidden", "hide", "higher", "highlight", "highlighttext", + "hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "icon", "ignore", + "inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite", + "infobackground", "infotext", "inherit", "initial", "inline", "inline-axis", + "inline-block", "inline-table", "inset", "inside", "intrinsic", "invert", + "italic", "justify", "kannada", "katakana", "katakana-iroha", "keep-all", "khmer", + "landscape", "lao", "large", "larger", "left", "level", "lighter", + "line-through", "linear", "lines", "list-item", "listbox", "listitem", + "local", "logical", "loud", "lower", "lower-alpha", "lower-armenian", + "lower-greek", "lower-hexadecimal", "lower-latin", "lower-norwegian", + "lower-roman", "lowercase", "ltr", "malayalam", "match", + "media-controls-background", "media-current-time-display", + "media-fullscreen-button", "media-mute-button", "media-play-button", + "media-return-to-realtime-button", "media-rewind-button", + "media-seek-back-button", "media-seek-forward-button", "media-slider", + "media-sliderthumb", "media-time-remaining-display", "media-volume-slider", + "media-volume-slider-container", "media-volume-sliderthumb", "medium", + "menu", "menulist", "menulist-button", "menulist-text", + "menulist-textfield", "menutext", "message-box", "middle", "min-intrinsic", + "mix", "mongolian", "monospace", "move", "multiple", "myanmar", "n-resize", + "narrower", "ne-resize", "nesw-resize", "no-close-quote", "no-drop", + "no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap", + "ns-resize", "nw-resize", "nwse-resize", "oblique", "octal", "open-quote", + "optimizeLegibility", "optimizeSpeed", "oriya", "oromo", "outset", + "outside", "outside-shape", "overlay", "overline", "padding", "padding-box", + "painted", "page", "paused", "persian", "plus-darker", "plus-lighter", "pointer", + "polygon", "portrait", "pre", "pre-line", "pre-wrap", "preserve-3d", "progress", "push-button", + "radio", "read-only", "read-write", "read-write-plaintext-only", "rectangle", "region", + "relative", "repeat", "repeat-x", "repeat-y", "reset", "reverse", "rgb", "rgba", + "ridge", "right", "round", "row-resize", "rtl", "run-in", "running", + "s-resize", "sans-serif", "scroll", "scrollbar", "se-resize", "searchfield", + "searchfield-cancel-button", "searchfield-decoration", + "searchfield-results-button", "searchfield-results-decoration", + "semi-condensed", "semi-expanded", "separate", "serif", "show", "sidama", + "single", "skip-white-space", "slide", "slider-horizontal", + "slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow", + "small", "small-caps", "small-caption", "smaller", "solid", "somali", + "source-atop", "source-in", "source-out", "source-over", "space", "square", + "square-button", "start", "static", "status-bar", "stretch", "stroke", + "sub", "subpixel-antialiased", "super", "sw-resize", "table", + "table-caption", "table-cell", "table-column", "table-column-group", + "table-footer-group", "table-header-group", "table-row", "table-row-group", + "telugu", "text", "text-bottom", "text-top", "textarea", "textfield", "thai", + "thick", "thin", "threeddarkshadow", "threedface", "threedhighlight", + "threedlightshadow", "threedshadow", "tibetan", "tigre", "tigrinya-er", + "tigrinya-er-abegede", "tigrinya-et", "tigrinya-et-abegede", "to", "top", + "transparent", "ultra-condensed", "ultra-expanded", "underline", "up", + "upper-alpha", "upper-armenian", "upper-greek", "upper-hexadecimal", + "upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url", + "vertical", "vertical-text", "visible", "visibleFill", "visiblePainted", + "visibleStroke", "visual", "w-resize", "wait", "wave", "wider", + "window", "windowframe", "windowtext", "x-large", "x-small", "xor", + "xx-large", "xx-small" + ]); + + function tokenCComment(stream, state) { + var maybeEnd = false, ch; + while ((ch = stream.next()) != null) { + if (maybeEnd && ch == "/") { + state.tokenize = null; + break; + } + maybeEnd = (ch == "*"); + } + return ["comment", "comment"]; + } + + CodeMirror.defineMIME("text/css", { + atMediaTypes: atMediaTypes, + atMediaFeatures: atMediaFeatures, + propertyKeywords: propertyKeywords, + colorKeywords: colorKeywords, + valueKeywords: valueKeywords, + hooks: { + "<": function(stream, state) { + function tokenSGMLComment(stream, state) { + var dashes = 0, ch; + while ((ch = stream.next()) != null) { + if (dashes >= 2 && ch == ">") { + state.tokenize = null; + break; + } + dashes = (ch == "-") ? dashes + 1 : 0; + } + return ["comment", "comment"]; + } + if (stream.eat("!")) { + state.tokenize = tokenSGMLComment; + return tokenSGMLComment(stream, state); + } + }, + "/": function(stream, state) { + if (stream.eat("*")) { + state.tokenize = tokenCComment; + return tokenCComment(stream, state); + } + return false; + } + }, + name: "css" + }); + + CodeMirror.defineMIME("text/x-scss", { + atMediaTypes: atMediaTypes, + atMediaFeatures: atMediaFeatures, + propertyKeywords: propertyKeywords, + colorKeywords: colorKeywords, + valueKeywords: valueKeywords, + allowNested: true, + hooks: { + ":": function(stream) { + if (stream.match(/\s*{/)) { + return [null, "{"]; + } + return false; + }, + "$": function(stream) { + stream.match(/^[\w-]+/); + if (stream.peek() == ":") { + return ["variable", "variable-definition"]; + } + return ["variable", "variable"]; + }, + "/": function(stream, state) { + if (stream.eat("/")) { + stream.skipToEnd(); + return ["comment", "comment"]; + } else if (stream.eat("*")) { + state.tokenize = tokenCComment; + return tokenCComment(stream, state); + } else { + return ["operator", "operator"]; + } + }, + "#": function(stream) { + if (stream.eat("{")) { + return ["operator", "interpolation"]; + } else { + stream.eatWhile(/[\w\\\-]/); + return ["atom", "hash"]; + } + } + }, + name: "css" + }); +})(); diff --git a/profile-builder/assets/lib/codemirror/mode/css/index.html b/profile-builder/assets/lib/codemirror/mode/css/index.html index 1d1865e..769128e 100644 --- a/profile-builder/assets/lib/codemirror/mode/css/index.html +++ b/profile-builder/assets/lib/codemirror/mode/css/index.html @@ -1,70 +1,70 @@ - - -CodeMirror: CSS mode - - - - - - - - - -
            -

            CSS mode

            -
            - - -

            MIME types defined: text/css.

            - -

            Parsing/Highlighting Tests: normal, verbose.

            - -
            + + +CodeMirror: CSS mode + + + + + + + + + +
            +

            CSS mode

            +
            + + +

            MIME types defined: text/css.

            + +

            Parsing/Highlighting Tests: normal, verbose.

            + +
            diff --git a/profile-builder/assets/lib/codemirror/mode/css/scss.html b/profile-builder/assets/lib/codemirror/mode/css/scss.html index 72781c0..0f7d27c 100644 --- a/profile-builder/assets/lib/codemirror/mode/css/scss.html +++ b/profile-builder/assets/lib/codemirror/mode/css/scss.html @@ -1,157 +1,157 @@ - - -CodeMirror: SCSS mode - - - - - - - - - -
            -

            SCSS mode

            -
            - - -

            MIME types defined: text/scss.

            - -

            Parsing/Highlighting Tests: normal, verbose.

            - -
            + + +CodeMirror: SCSS mode + + + + + + + + + +
            +

            SCSS mode

            +
            + + +

            MIME types defined: text/scss.

            + +

            Parsing/Highlighting Tests: normal, verbose.

            + +
            diff --git a/profile-builder/assets/lib/codemirror/mode/css/scss_test.js b/profile-builder/assets/lib/codemirror/mode/css/scss_test.js index 3644f63..58f1914 100644 --- a/profile-builder/assets/lib/codemirror/mode/css/scss_test.js +++ b/profile-builder/assets/lib/codemirror/mode/css/scss_test.js @@ -1,80 +1,80 @@ -(function() { - var mode = CodeMirror.getMode({tabSize: 4}, "text/x-scss"); - function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1), "scss"); } - - MT('url_with_quotation', - "[tag foo] { [property background][operator :][string-2 url]([string test.jpg]) }"); - - MT('url_with_double_quotes', - "[tag foo] { [property background][operator :][string-2 url]([string \"test.jpg\"]) }"); - - MT('url_with_single_quotes', - "[tag foo] { [property background][operator :][string-2 url]([string \'test.jpg\']) }"); - - MT('string', - "[def @import] [string \"compass/css3\"]"); - - MT('important_keyword', - "[tag foo] { [property background][operator :][string-2 url]([string \'test.jpg\']) [keyword !important] }"); - - MT('variable', - "[variable-2 $blue][operator :][atom #333]"); - - MT('variable_as_attribute', - "[tag foo] { [property color][operator :][variable-2 $blue] }"); - - MT('numbers', - "[tag foo] { [property padding][operator :][number 10px] [number 10] [number 10em] [number 8in] }"); - - MT('number_percentage', - "[tag foo] { [property width][operator :][number 80%] }"); - - MT('selector', - "[builtin #hello][qualifier .world]{}"); - - MT('singleline_comment', - "[comment // this is a comment]"); - - MT('multiline_comment', - "[comment /*foobar*/]"); - - MT('attribute_with_hyphen', - "[tag foo] { [property font-size][operator :][number 10px] }"); - - MT('string_after_attribute', - "[tag foo] { [property content][operator :][string \"::\"] }"); - - MT('directives', - "[def @include] [qualifier .mixin]"); - - MT('basic_structure', - "[tag p] { [property background][operator :][keyword red]; }"); - - MT('nested_structure', - "[tag p] { [tag a] { [property color][operator :][keyword red]; } }"); - - MT('mixin', - "[def @mixin] [tag table-base] {}"); - - MT('number_without_semicolon', - "[tag p] {[property width][operator :][number 12]}", - "[tag a] {[property color][operator :][keyword red];}"); - - MT('atom_in_nested_block', - "[tag p] { [tag a] { [property color][operator :][atom #000]; } }"); - - MT('interpolation_in_property', - "[tag foo] { [operator #{][variable-2 $hello][operator }:][number 2]; }"); - - MT('interpolation_in_selector', - "[tag foo][operator #{][variable-2 $hello][operator }] { [property color][operator :][atom #000]; }"); - - MT('interpolation_error', - "[tag foo][operator #{][error foo][operator }] { [property color][operator :][atom #000]; }"); - - MT("divide_operator", - "[tag foo] { [property width][operator :][number 4] [operator /] [number 2] }"); - - MT('nested_structure_with_id_selector', - "[tag p] { [builtin #hello] { [property color][operator :][keyword red]; } }"); -})(); +(function() { + var mode = CodeMirror.getMode({tabSize: 4}, "text/x-scss"); + function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1), "scss"); } + + MT('url_with_quotation', + "[tag foo] { [property background][operator :][string-2 url]([string test.jpg]) }"); + + MT('url_with_double_quotes', + "[tag foo] { [property background][operator :][string-2 url]([string \"test.jpg\"]) }"); + + MT('url_with_single_quotes', + "[tag foo] { [property background][operator :][string-2 url]([string \'test.jpg\']) }"); + + MT('string', + "[def @import] [string \"compass/css3\"]"); + + MT('important_keyword', + "[tag foo] { [property background][operator :][string-2 url]([string \'test.jpg\']) [keyword !important] }"); + + MT('variable', + "[variable-2 $blue][operator :][atom #333]"); + + MT('variable_as_attribute', + "[tag foo] { [property color][operator :][variable-2 $blue] }"); + + MT('numbers', + "[tag foo] { [property padding][operator :][number 10px] [number 10] [number 10em] [number 8in] }"); + + MT('number_percentage', + "[tag foo] { [property width][operator :][number 80%] }"); + + MT('selector', + "[builtin #hello][qualifier .world]{}"); + + MT('singleline_comment', + "[comment // this is a comment]"); + + MT('multiline_comment', + "[comment /*foobar*/]"); + + MT('attribute_with_hyphen', + "[tag foo] { [property font-size][operator :][number 10px] }"); + + MT('string_after_attribute', + "[tag foo] { [property content][operator :][string \"::\"] }"); + + MT('directives', + "[def @include] [qualifier .mixin]"); + + MT('basic_structure', + "[tag p] { [property background][operator :][keyword red]; }"); + + MT('nested_structure', + "[tag p] { [tag a] { [property color][operator :][keyword red]; } }"); + + MT('mixin', + "[def @mixin] [tag table-base] {}"); + + MT('number_without_semicolon', + "[tag p] {[property width][operator :][number 12]}", + "[tag a] {[property color][operator :][keyword red];}"); + + MT('atom_in_nested_block', + "[tag p] { [tag a] { [property color][operator :][atom #000]; } }"); + + MT('interpolation_in_property', + "[tag foo] { [operator #{][variable-2 $hello][operator }:][number 2]; }"); + + MT('interpolation_in_selector', + "[tag foo][operator #{][variable-2 $hello][operator }] { [property color][operator :][atom #000]; }"); + + MT('interpolation_error', + "[tag foo][operator #{][error foo][operator }] { [property color][operator :][atom #000]; }"); + + MT("divide_operator", + "[tag foo] { [property width][operator :][number 4] [operator /] [number 2] }"); + + MT('nested_structure_with_id_selector', + "[tag p] { [builtin #hello] { [property color][operator :][keyword red]; } }"); +})(); diff --git a/profile-builder/assets/lib/codemirror/mode/css/test.js b/profile-builder/assets/lib/codemirror/mode/css/test.js index 13fc04c..76486b8 100644 --- a/profile-builder/assets/lib/codemirror/mode/css/test.js +++ b/profile-builder/assets/lib/codemirror/mode/css/test.js @@ -1,126 +1,126 @@ -(function() { - var mode = CodeMirror.getMode({tabSize: 4}, "css"); - function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); } - - // Requires at least one media query - MT("atMediaEmpty", - "[def @media] [error {] }"); - - MT("atMediaMultiple", - "[def @media] [keyword not] [attribute screen] [operator and] ([property color]), [keyword not] [attribute print] [operator and] ([property color]) { }"); - - MT("atMediaCheckStack", - "[def @media] [attribute screen] { } [tag foo] { }"); - - MT("atMediaCheckStack", - "[def @media] [attribute screen] ([property color]) { } [tag foo] { }"); - - MT("atMediaPropertyOnly", - "[def @media] ([property color]) { } [tag foo] { }"); - - MT("atMediaCheckStackInvalidAttribute", - "[def @media] [attribute&error foobarhello] { [tag foo] { } }"); - - MT("atMediaCheckStackInvalidAttribute", - "[def @media] [attribute&error foobarhello] { } [tag foo] { }"); - - // Error, because "and" is only allowed immediately preceding a media expression - MT("atMediaInvalidAttribute", - "[def @media] [attribute&error foobarhello] { }"); - - // Error, because "and" is only allowed immediately preceding a media expression - MT("atMediaInvalidAnd", - "[def @media] [error and] [attribute screen] { }"); - - // Error, because "not" is only allowed as the first item in each media query - MT("atMediaInvalidNot", - "[def @media] [attribute screen] [error not] ([error not]) { }"); - - // Error, because "only" is only allowed as the first item in each media query - MT("atMediaInvalidOnly", - "[def @media] [attribute screen] [error only] ([error only]) { }"); - - // Error, because "foobarhello" is neither a known type or property, but - // property was expected (after "and"), and it should be in parenthese. - MT("atMediaUnknownType", - "[def @media] [attribute screen] [operator and] [error foobarhello] { }"); - - // Error, because "color" is not a known type, but is a known property, and - // should be in parentheses. - MT("atMediaInvalidType", - "[def @media] [attribute screen] [operator and] [error color] { }"); - - // Error, because "print" is not a known property, but is a known type, - // and should not be in parenthese. - MT("atMediaInvalidProperty", - "[def @media] [attribute screen] [operator and] ([error print]) { }"); - - // Soft error, because "foobarhello" is not a known property or type. - MT("atMediaUnknownProperty", - "[def @media] [attribute screen] [operator and] ([property&error foobarhello]) { }"); - - // Make sure nesting works with media queries - MT("atMediaMaxWidthNested", - "[def @media] [attribute screen] [operator and] ([property max-width][operator :] [number 25px]) { [tag foo] { } }"); - - MT("tagSelector", - "[tag foo] { }"); - - MT("classSelector", - "[qualifier .foo-bar_hello] { }"); - - MT("idSelector", - "[builtin #foo] { [error #foo] }"); - - MT("tagSelectorUnclosed", - "[tag foo] { [property margin][operator :] [number 0] } [tag bar] { }"); - - MT("tagStringNoQuotes", - "[tag foo] { [property font-family][operator :] [variable-2 hello] [variable-2 world]; }"); - - MT("tagStringDouble", - "[tag foo] { [property font-family][operator :] [string \"hello world\"]; }"); - - MT("tagStringSingle", - "[tag foo] { [property font-family][operator :] [string 'hello world']; }"); - - MT("tagColorKeyword", - "[tag foo] {" + - "[property color][operator :] [keyword black];" + - "[property color][operator :] [keyword navy];" + - "[property color][operator :] [keyword yellow];" + - "}"); - - MT("tagColorHex3", - "[tag foo] { [property background][operator :] [atom #fff]; }"); - - MT("tagColorHex6", - "[tag foo] { [property background][operator :] [atom #ffffff]; }"); - - MT("tagColorHex4", - "[tag foo] { [property background][operator :] [atom&error #ffff]; }"); - - MT("tagColorHexInvalid", - "[tag foo] { [property background][operator :] [atom&error #ffg]; }"); - - MT("tagNegativeNumber", - "[tag foo] { [property margin][operator :] [number -5px]; }"); - - MT("tagPositiveNumber", - "[tag foo] { [property padding][operator :] [number 5px]; }"); - - MT("tagVendor", - "[tag foo] { [meta -foo-][property box-sizing][operator :] [meta -foo-][string-2 border-box]; }"); - - MT("tagBogusProperty", - "[tag foo] { [property&error barhelloworld][operator :] [number 0]; }"); - - MT("tagTwoProperties", - "[tag foo] { [property margin][operator :] [number 0]; [property padding][operator :] [number 0]; }"); - - MT("tagTwoPropertiesURL", - "[tag foo] { [property background][operator :] [string-2 url]([string //example.com/foo.png]); [property padding][operator :] [number 0]; }"); - - MT("commentSGML", - "[comment ]"); -})(); +(function() { + var mode = CodeMirror.getMode({tabSize: 4}, "css"); + function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); } + + // Requires at least one media query + MT("atMediaEmpty", + "[def @media] [error {] }"); + + MT("atMediaMultiple", + "[def @media] [keyword not] [attribute screen] [operator and] ([property color]), [keyword not] [attribute print] [operator and] ([property color]) { }"); + + MT("atMediaCheckStack", + "[def @media] [attribute screen] { } [tag foo] { }"); + + MT("atMediaCheckStack", + "[def @media] [attribute screen] ([property color]) { } [tag foo] { }"); + + MT("atMediaPropertyOnly", + "[def @media] ([property color]) { } [tag foo] { }"); + + MT("atMediaCheckStackInvalidAttribute", + "[def @media] [attribute&error foobarhello] { [tag foo] { } }"); + + MT("atMediaCheckStackInvalidAttribute", + "[def @media] [attribute&error foobarhello] { } [tag foo] { }"); + + // Error, because "and" is only allowed immediately preceding a media expression + MT("atMediaInvalidAttribute", + "[def @media] [attribute&error foobarhello] { }"); + + // Error, because "and" is only allowed immediately preceding a media expression + MT("atMediaInvalidAnd", + "[def @media] [error and] [attribute screen] { }"); + + // Error, because "not" is only allowed as the first item in each media query + MT("atMediaInvalidNot", + "[def @media] [attribute screen] [error not] ([error not]) { }"); + + // Error, because "only" is only allowed as the first item in each media query + MT("atMediaInvalidOnly", + "[def @media] [attribute screen] [error only] ([error only]) { }"); + + // Error, because "foobarhello" is neither a known type or property, but + // property was expected (after "and"), and it should be in parenthese. + MT("atMediaUnknownType", + "[def @media] [attribute screen] [operator and] [error foobarhello] { }"); + + // Error, because "color" is not a known type, but is a known property, and + // should be in parentheses. + MT("atMediaInvalidType", + "[def @media] [attribute screen] [operator and] [error color] { }"); + + // Error, because "print" is not a known property, but is a known type, + // and should not be in parenthese. + MT("atMediaInvalidProperty", + "[def @media] [attribute screen] [operator and] ([error print]) { }"); + + // Soft error, because "foobarhello" is not a known property or type. + MT("atMediaUnknownProperty", + "[def @media] [attribute screen] [operator and] ([property&error foobarhello]) { }"); + + // Make sure nesting works with media queries + MT("atMediaMaxWidthNested", + "[def @media] [attribute screen] [operator and] ([property max-width][operator :] [number 25px]) { [tag foo] { } }"); + + MT("tagSelector", + "[tag foo] { }"); + + MT("classSelector", + "[qualifier .foo-bar_hello] { }"); + + MT("idSelector", + "[builtin #foo] { [error #foo] }"); + + MT("tagSelectorUnclosed", + "[tag foo] { [property margin][operator :] [number 0] } [tag bar] { }"); + + MT("tagStringNoQuotes", + "[tag foo] { [property font-family][operator :] [variable-2 hello] [variable-2 world]; }"); + + MT("tagStringDouble", + "[tag foo] { [property font-family][operator :] [string \"hello world\"]; }"); + + MT("tagStringSingle", + "[tag foo] { [property font-family][operator :] [string 'hello world']; }"); + + MT("tagColorKeyword", + "[tag foo] {" + + "[property color][operator :] [keyword black];" + + "[property color][operator :] [keyword navy];" + + "[property color][operator :] [keyword yellow];" + + "}"); + + MT("tagColorHex3", + "[tag foo] { [property background][operator :] [atom #fff]; }"); + + MT("tagColorHex6", + "[tag foo] { [property background][operator :] [atom #ffffff]; }"); + + MT("tagColorHex4", + "[tag foo] { [property background][operator :] [atom&error #ffff]; }"); + + MT("tagColorHexInvalid", + "[tag foo] { [property background][operator :] [atom&error #ffg]; }"); + + MT("tagNegativeNumber", + "[tag foo] { [property margin][operator :] [number -5px]; }"); + + MT("tagPositiveNumber", + "[tag foo] { [property padding][operator :] [number 5px]; }"); + + MT("tagVendor", + "[tag foo] { [meta -foo-][property box-sizing][operator :] [meta -foo-][string-2 border-box]; }"); + + MT("tagBogusProperty", + "[tag foo] { [property&error barhelloworld][operator :] [number 0]; }"); + + MT("tagTwoProperties", + "[tag foo] { [property margin][operator :] [number 0]; [property padding][operator :] [number 0]; }"); + + MT("tagTwoPropertiesURL", + "[tag foo] { [property background][operator :] [string-2 url]([string //example.com/foo.png]); [property padding][operator :] [number 0]; }"); + + MT("commentSGML", + "[comment ]"); +})(); diff --git a/profile-builder/assets/lib/codemirror/mode/htmlembedded/htmlembedded.js b/profile-builder/assets/lib/codemirror/mode/htmlembedded/htmlembedded.js index ff6dfd2..967ece0 100644 --- a/profile-builder/assets/lib/codemirror/mode/htmlembedded/htmlembedded.js +++ b/profile-builder/assets/lib/codemirror/mode/htmlembedded/htmlembedded.js @@ -1,73 +1,73 @@ -CodeMirror.defineMode("htmlembedded", function(config, parserConfig) { - - //config settings - var scriptStartRegex = parserConfig.scriptStartRegex || /^<%/i, - scriptEndRegex = parserConfig.scriptEndRegex || /^%>/i; - - //inner modes - var scriptingMode, htmlMixedMode; - - //tokenizer when in html mode - function htmlDispatch(stream, state) { - if (stream.match(scriptStartRegex, false)) { - state.token=scriptingDispatch; - return scriptingMode.token(stream, state.scriptState); - } - else - return htmlMixedMode.token(stream, state.htmlState); - } - - //tokenizer when in scripting mode - function scriptingDispatch(stream, state) { - if (stream.match(scriptEndRegex, false)) { - state.token=htmlDispatch; - return htmlMixedMode.token(stream, state.htmlState); - } - else - return scriptingMode.token(stream, state.scriptState); - } - - - return { - startState: function() { - scriptingMode = scriptingMode || CodeMirror.getMode(config, parserConfig.scriptingModeSpec); - htmlMixedMode = htmlMixedMode || CodeMirror.getMode(config, "htmlmixed"); - return { - token : parserConfig.startOpen ? scriptingDispatch : htmlDispatch, - htmlState : CodeMirror.startState(htmlMixedMode), - scriptState : CodeMirror.startState(scriptingMode) - }; - }, - - token: function(stream, state) { - return state.token(stream, state); - }, - - indent: function(state, textAfter) { - if (state.token == htmlDispatch) - return htmlMixedMode.indent(state.htmlState, textAfter); - else if (scriptingMode.indent) - return scriptingMode.indent(state.scriptState, textAfter); - }, - - copyState: function(state) { - return { - token : state.token, - htmlState : CodeMirror.copyState(htmlMixedMode, state.htmlState), - scriptState : CodeMirror.copyState(scriptingMode, state.scriptState) - }; - }, - - electricChars: "/{}:", - - innerMode: function(state) { - if (state.token == scriptingDispatch) return {state: state.scriptState, mode: scriptingMode}; - else return {state: state.htmlState, mode: htmlMixedMode}; - } - }; -}, "htmlmixed"); - -CodeMirror.defineMIME("application/x-ejs", { name: "htmlembedded", scriptingModeSpec:"javascript"}); -CodeMirror.defineMIME("application/x-aspx", { name: "htmlembedded", scriptingModeSpec:"text/x-csharp"}); -CodeMirror.defineMIME("application/x-jsp", { name: "htmlembedded", scriptingModeSpec:"text/x-java"}); -CodeMirror.defineMIME("application/x-erb", { name: "htmlembedded", scriptingModeSpec:"ruby"}); +CodeMirror.defineMode("htmlembedded", function(config, parserConfig) { + + //config settings + var scriptStartRegex = parserConfig.scriptStartRegex || /^<%/i, + scriptEndRegex = parserConfig.scriptEndRegex || /^%>/i; + + //inner modes + var scriptingMode, htmlMixedMode; + + //tokenizer when in html mode + function htmlDispatch(stream, state) { + if (stream.match(scriptStartRegex, false)) { + state.token=scriptingDispatch; + return scriptingMode.token(stream, state.scriptState); + } + else + return htmlMixedMode.token(stream, state.htmlState); + } + + //tokenizer when in scripting mode + function scriptingDispatch(stream, state) { + if (stream.match(scriptEndRegex, false)) { + state.token=htmlDispatch; + return htmlMixedMode.token(stream, state.htmlState); + } + else + return scriptingMode.token(stream, state.scriptState); + } + + + return { + startState: function() { + scriptingMode = scriptingMode || CodeMirror.getMode(config, parserConfig.scriptingModeSpec); + htmlMixedMode = htmlMixedMode || CodeMirror.getMode(config, "htmlmixed"); + return { + token : parserConfig.startOpen ? scriptingDispatch : htmlDispatch, + htmlState : CodeMirror.startState(htmlMixedMode), + scriptState : CodeMirror.startState(scriptingMode) + }; + }, + + token: function(stream, state) { + return state.token(stream, state); + }, + + indent: function(state, textAfter) { + if (state.token == htmlDispatch) + return htmlMixedMode.indent(state.htmlState, textAfter); + else if (scriptingMode.indent) + return scriptingMode.indent(state.scriptState, textAfter); + }, + + copyState: function(state) { + return { + token : state.token, + htmlState : CodeMirror.copyState(htmlMixedMode, state.htmlState), + scriptState : CodeMirror.copyState(scriptingMode, state.scriptState) + }; + }, + + electricChars: "/{}:", + + innerMode: function(state) { + if (state.token == scriptingDispatch) return {state: state.scriptState, mode: scriptingMode}; + else return {state: state.htmlState, mode: htmlMixedMode}; + } + }; +}, "htmlmixed"); + +CodeMirror.defineMIME("application/x-ejs", { name: "htmlembedded", scriptingModeSpec:"javascript"}); +CodeMirror.defineMIME("application/x-aspx", { name: "htmlembedded", scriptingModeSpec:"text/x-csharp"}); +CodeMirror.defineMIME("application/x-jsp", { name: "htmlembedded", scriptingModeSpec:"text/x-java"}); +CodeMirror.defineMIME("application/x-erb", { name: "htmlembedded", scriptingModeSpec:"ruby"}); diff --git a/profile-builder/assets/lib/codemirror/mode/htmlembedded/index.html b/profile-builder/assets/lib/codemirror/mode/htmlembedded/index.html index 4ab90f7..002fcae 100644 --- a/profile-builder/assets/lib/codemirror/mode/htmlembedded/index.html +++ b/profile-builder/assets/lib/codemirror/mode/htmlembedded/index.html @@ -1,60 +1,60 @@ - - -CodeMirror: Html Embedded Scripts mode - - - - - - - - - - - - - -
            -

            Html Embedded Scripts mode

            -
            - - - -

            Mode for html embedded scripts like JSP and ASP.NET. Depends on HtmlMixed which in turn depends on - JavaScript, CSS and XML.
            Other dependancies include those of the scriping language chosen.

            - -

            MIME types defined: application/x-aspx (ASP.NET), - application/x-ejs (Embedded Javascript), application/x-jsp (JavaServer Pages)

            -
            + + +CodeMirror: Html Embedded Scripts mode + + + + + + + + + + + + + +
            +

            Html Embedded Scripts mode

            +
            + + + +

            Mode for html embedded scripts like JSP and ASP.NET. Depends on HtmlMixed which in turn depends on + JavaScript, CSS and XML.
            Other dependancies include those of the scriping language chosen.

            + +

            MIME types defined: application/x-aspx (ASP.NET), + application/x-ejs (Embedded Javascript), application/x-jsp (JavaServer Pages)

            +
            diff --git a/profile-builder/assets/lib/codemirror/mode/htmlmixed/htmlmixed.js b/profile-builder/assets/lib/codemirror/mode/htmlmixed/htmlmixed.js index ec0c21d..f458532 100644 --- a/profile-builder/assets/lib/codemirror/mode/htmlmixed/htmlmixed.js +++ b/profile-builder/assets/lib/codemirror/mode/htmlmixed/htmlmixed.js @@ -1,104 +1,104 @@ -CodeMirror.defineMode("htmlmixed", function(config, parserConfig) { - var htmlMode = CodeMirror.getMode(config, {name: "xml", htmlMode: true}); - var cssMode = CodeMirror.getMode(config, "css"); - - var scriptTypes = [], scriptTypesConf = parserConfig && parserConfig.scriptTypes; - scriptTypes.push({matches: /^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^$/i, - mode: CodeMirror.getMode(config, "javascript")}); - if (scriptTypesConf) for (var i = 0; i < scriptTypesConf.length; ++i) { - var conf = scriptTypesConf[i]; - scriptTypes.push({matches: conf.matches, mode: conf.mode && CodeMirror.getMode(config, conf.mode)}); - } - scriptTypes.push({matches: /./, - mode: CodeMirror.getMode(config, "text/plain")}); - - function html(stream, state) { - var tagName = state.htmlState.tagName; - var style = htmlMode.token(stream, state.htmlState); - if (tagName == "script" && /\btag\b/.test(style) && stream.current() == ">") { - // Script block: mode to change to depends on type attribute - var scriptType = stream.string.slice(Math.max(0, stream.pos - 100), stream.pos).match(/\btype\s*=\s*("[^"]+"|'[^']+'|\S+)[^<]*$/i); - scriptType = scriptType ? scriptType[1] : ""; - if (scriptType && /[\"\']/.test(scriptType.charAt(0))) scriptType = scriptType.slice(1, scriptType.length - 1); - for (var i = 0; i < scriptTypes.length; ++i) { - var tp = scriptTypes[i]; - if (typeof tp.matches == "string" ? scriptType == tp.matches : tp.matches.test(scriptType)) { - if (tp.mode) { - state.token = script; - state.localMode = tp.mode; - state.localState = tp.mode.startState && tp.mode.startState(htmlMode.indent(state.htmlState, "")); - } - break; - } - } - } else if (tagName == "style" && /\btag\b/.test(style) && stream.current() == ">") { - state.token = css; - state.localMode = cssMode; - state.localState = cssMode.startState(htmlMode.indent(state.htmlState, "")); - } - return style; - } - function maybeBackup(stream, pat, style) { - var cur = stream.current(); - var close = cur.search(pat), m; - if (close > -1) stream.backUp(cur.length - close); - else if (m = cur.match(/<\/?$/)) { - stream.backUp(cur.length); - if (!stream.match(pat, false)) stream.match(cur[0]); - } - return style; - } - function script(stream, state) { - if (stream.match(/^<\/\s*script\s*>/i, false)) { - state.token = html; - state.localState = state.localMode = null; - return html(stream, state); - } - return maybeBackup(stream, /<\/\s*script\s*>/, - state.localMode.token(stream, state.localState)); - } - function css(stream, state) { - if (stream.match(/^<\/\s*style\s*>/i, false)) { - state.token = html; - state.localState = state.localMode = null; - return html(stream, state); - } - return maybeBackup(stream, /<\/\s*style\s*>/, - cssMode.token(stream, state.localState)); - } - - return { - startState: function() { - var state = htmlMode.startState(); - return {token: html, localMode: null, localState: null, htmlState: state}; - }, - - copyState: function(state) { - if (state.localState) - var local = CodeMirror.copyState(state.localMode, state.localState); - return {token: state.token, localMode: state.localMode, localState: local, - htmlState: CodeMirror.copyState(htmlMode, state.htmlState)}; - }, - - token: function(stream, state) { - return state.token(stream, state); - }, - - indent: function(state, textAfter) { - if (!state.localMode || /^\s*<\//.test(textAfter)) - return htmlMode.indent(state.htmlState, textAfter); - else if (state.localMode.indent) - return state.localMode.indent(state.localState, textAfter); - else - return CodeMirror.Pass; - }, - - electricChars: "/{}:", - - innerMode: function(state) { - return {state: state.localState || state.htmlState, mode: state.localMode || htmlMode}; - } - }; -}, "xml", "javascript", "css"); - -CodeMirror.defineMIME("text/html", "htmlmixed"); +CodeMirror.defineMode("htmlmixed", function(config, parserConfig) { + var htmlMode = CodeMirror.getMode(config, {name: "xml", htmlMode: true}); + var cssMode = CodeMirror.getMode(config, "css"); + + var scriptTypes = [], scriptTypesConf = parserConfig && parserConfig.scriptTypes; + scriptTypes.push({matches: /^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^$/i, + mode: CodeMirror.getMode(config, "javascript")}); + if (scriptTypesConf) for (var i = 0; i < scriptTypesConf.length; ++i) { + var conf = scriptTypesConf[i]; + scriptTypes.push({matches: conf.matches, mode: conf.mode && CodeMirror.getMode(config, conf.mode)}); + } + scriptTypes.push({matches: /./, + mode: CodeMirror.getMode(config, "text/plain")}); + + function html(stream, state) { + var tagName = state.htmlState.tagName; + var style = htmlMode.token(stream, state.htmlState); + if (tagName == "script" && /\btag\b/.test(style) && stream.current() == ">") { + // Script block: mode to change to depends on type attribute + var scriptType = stream.string.slice(Math.max(0, stream.pos - 100), stream.pos).match(/\btype\s*=\s*("[^"]+"|'[^']+'|\S+)[^<]*$/i); + scriptType = scriptType ? scriptType[1] : ""; + if (scriptType && /[\"\']/.test(scriptType.charAt(0))) scriptType = scriptType.slice(1, scriptType.length - 1); + for (var i = 0; i < scriptTypes.length; ++i) { + var tp = scriptTypes[i]; + if (typeof tp.matches == "string" ? scriptType == tp.matches : tp.matches.test(scriptType)) { + if (tp.mode) { + state.token = script; + state.localMode = tp.mode; + state.localState = tp.mode.startState && tp.mode.startState(htmlMode.indent(state.htmlState, "")); + } + break; + } + } + } else if (tagName == "style" && /\btag\b/.test(style) && stream.current() == ">") { + state.token = css; + state.localMode = cssMode; + state.localState = cssMode.startState(htmlMode.indent(state.htmlState, "")); + } + return style; + } + function maybeBackup(stream, pat, style) { + var cur = stream.current(); + var close = cur.search(pat), m; + if (close > -1) stream.backUp(cur.length - close); + else if (m = cur.match(/<\/?$/)) { + stream.backUp(cur.length); + if (!stream.match(pat, false)) stream.match(cur[0]); + } + return style; + } + function script(stream, state) { + if (stream.match(/^<\/\s*script\s*>/i, false)) { + state.token = html; + state.localState = state.localMode = null; + return html(stream, state); + } + return maybeBackup(stream, /<\/\s*script\s*>/, + state.localMode.token(stream, state.localState)); + } + function css(stream, state) { + if (stream.match(/^<\/\s*style\s*>/i, false)) { + state.token = html; + state.localState = state.localMode = null; + return html(stream, state); + } + return maybeBackup(stream, /<\/\s*style\s*>/, + cssMode.token(stream, state.localState)); + } + + return { + startState: function() { + var state = htmlMode.startState(); + return {token: html, localMode: null, localState: null, htmlState: state}; + }, + + copyState: function(state) { + if (state.localState) + var local = CodeMirror.copyState(state.localMode, state.localState); + return {token: state.token, localMode: state.localMode, localState: local, + htmlState: CodeMirror.copyState(htmlMode, state.htmlState)}; + }, + + token: function(stream, state) { + return state.token(stream, state); + }, + + indent: function(state, textAfter) { + if (!state.localMode || /^\s*<\//.test(textAfter)) + return htmlMode.indent(state.htmlState, textAfter); + else if (state.localMode.indent) + return state.localMode.indent(state.localState, textAfter); + else + return CodeMirror.Pass; + }, + + electricChars: "/{}:", + + innerMode: function(state) { + return {state: state.localState || state.htmlState, mode: state.localMode || htmlMode}; + } + }; +}, "xml", "javascript", "css"); + +CodeMirror.defineMIME("text/html", "htmlmixed"); diff --git a/profile-builder/assets/lib/codemirror/mode/htmlmixed/index.html b/profile-builder/assets/lib/codemirror/mode/htmlmixed/index.html index b461743..90c6856 100644 --- a/profile-builder/assets/lib/codemirror/mode/htmlmixed/index.html +++ b/profile-builder/assets/lib/codemirror/mode/htmlmixed/index.html @@ -1,85 +1,85 @@ - - -CodeMirror: HTML mixed mode - - - - - - - - - - - - - -
            -

            HTML mixed mode

            -
            - - -

            The HTML mixed mode depends on the XML, JavaScript, and CSS modes.

            - -

            It takes an optional mode configuration - option, scriptTypes, which can be used to add custom - behavior for specific <script type="..."> tags. If - given, it should hold an array of {matches, mode} - objects, where matches is a string or regexp that - matches the script type, and mode is - either null, for script types that should stay in - HTML mode, or a mode - spec corresponding to the mode that should be used for the - script.

            - -

            MIME types defined: text/html - (redefined, only takes effect if you load this parser after the - XML parser).

            - -
            + + +CodeMirror: HTML mixed mode + + + + + + + + + + + + + +
            +

            HTML mixed mode

            +
            + + +

            The HTML mixed mode depends on the XML, JavaScript, and CSS modes.

            + +

            It takes an optional mode configuration + option, scriptTypes, which can be used to add custom + behavior for specific <script type="..."> tags. If + given, it should hold an array of {matches, mode} + objects, where matches is a string or regexp that + matches the script type, and mode is + either null, for script types that should stay in + HTML mode, or a mode + spec corresponding to the mode that should be used for the + script.

            + +

            MIME types defined: text/html + (redefined, only takes effect if you load this parser after the + XML parser).

            + +
            diff --git a/profile-builder/assets/lib/codemirror/mode/http/http.js b/profile-builder/assets/lib/codemirror/mode/http/http.js index 5a51636..28c10d1 100644 --- a/profile-builder/assets/lib/codemirror/mode/http/http.js +++ b/profile-builder/assets/lib/codemirror/mode/http/http.js @@ -1,98 +1,98 @@ -CodeMirror.defineMode("http", function() { - function failFirstLine(stream, state) { - stream.skipToEnd(); - state.cur = header; - return "error"; - } - - function start(stream, state) { - if (stream.match(/^HTTP\/\d\.\d/)) { - state.cur = responseStatusCode; - return "keyword"; - } else if (stream.match(/^[A-Z]+/) && /[ \t]/.test(stream.peek())) { - state.cur = requestPath; - return "keyword"; - } else { - return failFirstLine(stream, state); - } - } - - function responseStatusCode(stream, state) { - var code = stream.match(/^\d+/); - if (!code) return failFirstLine(stream, state); - - state.cur = responseStatusText; - var status = Number(code[0]); - if (status >= 100 && status < 200) { - return "positive informational"; - } else if (status >= 200 && status < 300) { - return "positive success"; - } else if (status >= 300 && status < 400) { - return "positive redirect"; - } else if (status >= 400 && status < 500) { - return "negative client-error"; - } else if (status >= 500 && status < 600) { - return "negative server-error"; - } else { - return "error"; - } - } - - function responseStatusText(stream, state) { - stream.skipToEnd(); - state.cur = header; - return null; - } - - function requestPath(stream, state) { - stream.eatWhile(/\S/); - state.cur = requestProtocol; - return "string-2"; - } - - function requestProtocol(stream, state) { - if (stream.match(/^HTTP\/\d\.\d$/)) { - state.cur = header; - return "keyword"; - } else { - return failFirstLine(stream, state); - } - } - - function header(stream) { - if (stream.sol() && !stream.eat(/[ \t]/)) { - if (stream.match(/^.*?:/)) { - return "atom"; - } else { - stream.skipToEnd(); - return "error"; - } - } else { - stream.skipToEnd(); - return "string"; - } - } - - function body(stream) { - stream.skipToEnd(); - return null; - } - - return { - token: function(stream, state) { - var cur = state.cur; - if (cur != header && cur != body && stream.eatSpace()) return null; - return cur(stream, state); - }, - - blankLine: function(state) { - state.cur = body; - }, - - startState: function() { - return {cur: start}; - } - }; -}); - -CodeMirror.defineMIME("message/http", "http"); +CodeMirror.defineMode("http", function() { + function failFirstLine(stream, state) { + stream.skipToEnd(); + state.cur = header; + return "error"; + } + + function start(stream, state) { + if (stream.match(/^HTTP\/\d\.\d/)) { + state.cur = responseStatusCode; + return "keyword"; + } else if (stream.match(/^[A-Z]+/) && /[ \t]/.test(stream.peek())) { + state.cur = requestPath; + return "keyword"; + } else { + return failFirstLine(stream, state); + } + } + + function responseStatusCode(stream, state) { + var code = stream.match(/^\d+/); + if (!code) return failFirstLine(stream, state); + + state.cur = responseStatusText; + var status = Number(code[0]); + if (status >= 100 && status < 200) { + return "positive informational"; + } else if (status >= 200 && status < 300) { + return "positive success"; + } else if (status >= 300 && status < 400) { + return "positive redirect"; + } else if (status >= 400 && status < 500) { + return "negative client-error"; + } else if (status >= 500 && status < 600) { + return "negative server-error"; + } else { + return "error"; + } + } + + function responseStatusText(stream, state) { + stream.skipToEnd(); + state.cur = header; + return null; + } + + function requestPath(stream, state) { + stream.eatWhile(/\S/); + state.cur = requestProtocol; + return "string-2"; + } + + function requestProtocol(stream, state) { + if (stream.match(/^HTTP\/\d\.\d$/)) { + state.cur = header; + return "keyword"; + } else { + return failFirstLine(stream, state); + } + } + + function header(stream) { + if (stream.sol() && !stream.eat(/[ \t]/)) { + if (stream.match(/^.*?:/)) { + return "atom"; + } else { + stream.skipToEnd(); + return "error"; + } + } else { + stream.skipToEnd(); + return "string"; + } + } + + function body(stream) { + stream.skipToEnd(); + return null; + } + + return { + token: function(stream, state) { + var cur = state.cur; + if (cur != header && cur != body && stream.eatSpace()) return null; + return cur(stream, state); + }, + + blankLine: function(state) { + state.cur = body; + }, + + startState: function() { + return {cur: start}; + } + }; +}); + +CodeMirror.defineMIME("message/http", "http"); diff --git a/profile-builder/assets/lib/codemirror/mode/http/index.html b/profile-builder/assets/lib/codemirror/mode/http/index.html index 705085e..c2c7f55 100644 --- a/profile-builder/assets/lib/codemirror/mode/http/index.html +++ b/profile-builder/assets/lib/codemirror/mode/http/index.html @@ -1,45 +1,45 @@ - - -CodeMirror: HTTP mode - - - - - - - - - -
            -

            HTTP mode

            - - -
            - - - -

            MIME types defined: message/http.

            -
            + + +CodeMirror: HTTP mode + + + + + + + + + +
            +

            HTTP mode

            + + +
            + + + +

            MIME types defined: message/http.

            +
            diff --git a/profile-builder/assets/lib/codemirror/mode/index.html b/profile-builder/assets/lib/codemirror/mode/index.html index 063e69b..5b714d9 100644 --- a/profile-builder/assets/lib/codemirror/mode/index.html +++ b/profile-builder/assets/lib/codemirror/mode/index.html @@ -1,110 +1,110 @@ - - -CodeMirror: Language Modes - - - - - -
            - -

            Language modes

            - -

            This is a list of every mode in the distribution. Each mode lives -in a subdirectory of the mode/ directory, and typically -defines a single JavaScript file that implements the mode. Loading -such file will make the language available to CodeMirror, through -the mode -option.

            - - - -
            + + +CodeMirror: Language Modes + + + + + +
            + +

            Language modes

            + +

            This is a list of every mode in the distribution. Each mode lives +in a subdirectory of the mode/ directory, and typically +defines a single JavaScript file that implements the mode. Loading +such file will make the language available to CodeMirror, through +the mode +option.

            + + + +
            diff --git a/profile-builder/assets/lib/codemirror/mode/javascript/index.html b/profile-builder/assets/lib/codemirror/mode/javascript/index.html index 45d70ff..89d2bc1 100644 --- a/profile-builder/assets/lib/codemirror/mode/javascript/index.html +++ b/profile-builder/assets/lib/codemirror/mode/javascript/index.html @@ -1,107 +1,107 @@ - - -CodeMirror: JavaScript mode - - - - - - - - - - - - -
            -

            JavaScript mode

            - - -
            - - - -

            - JavaScript mode supports a two configuration - options: -

              -
            • json which will set the mode to expect JSON - data rather than a JavaScript program.
            • -
            • typescript which will activate additional - syntax highlighting and some other things for TypeScript code - (demo).
            • -
            • statementIndent which (given a number) will - determine the amount of indentation to use for statements - continued on a new line.
            • -
            -

            - -

            MIME types defined: text/javascript, application/json, text/typescript, application/typescript.

            -
            + + +CodeMirror: JavaScript mode + + + + + + + + + + + + +
            +

            JavaScript mode

            + + +
            + + + +

            + JavaScript mode supports a two configuration + options: +

              +
            • json which will set the mode to expect JSON + data rather than a JavaScript program.
            • +
            • typescript which will activate additional + syntax highlighting and some other things for TypeScript code + (demo).
            • +
            • statementIndent which (given a number) will + determine the amount of indentation to use for statements + continued on a new line.
            • +
            +

            + +

            MIME types defined: text/javascript, application/json, text/typescript, application/typescript.

            +
            diff --git a/profile-builder/assets/lib/codemirror/mode/javascript/javascript.js b/profile-builder/assets/lib/codemirror/mode/javascript/javascript.js index e8ace32..e0d1050 100644 --- a/profile-builder/assets/lib/codemirror/mode/javascript/javascript.js +++ b/profile-builder/assets/lib/codemirror/mode/javascript/javascript.js @@ -1,480 +1,480 @@ -// TODO actually recognize syntax of TypeScript constructs - -CodeMirror.defineMode("javascript", function(config, parserConfig) { - var indentUnit = config.indentUnit; - var statementIndent = parserConfig.statementIndent; - var jsonMode = parserConfig.json; - var isTS = parserConfig.typescript; - - // Tokenizer - - var keywords = function(){ - function kw(type) {return {type: type, style: "keyword"};} - var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c"); - var operator = kw("operator"), atom = {type: "atom", style: "atom"}; - - var jsKeywords = { - "if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B, - "return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C, - "var": kw("var"), "const": kw("var"), "let": kw("var"), - "function": kw("function"), "catch": kw("catch"), - "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"), - "in": operator, "typeof": operator, "instanceof": operator, - "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom, - "this": kw("this") - }; - - // Extend the 'normal' keywords with the TypeScript language extensions - if (isTS) { - var type = {type: "variable", style: "variable-3"}; - var tsKeywords = { - // object-like things - "interface": kw("interface"), - "class": kw("class"), - "extends": kw("extends"), - "constructor": kw("constructor"), - - // scope modifiers - "public": kw("public"), - "private": kw("private"), - "protected": kw("protected"), - "static": kw("static"), - - "super": kw("super"), - - // types - "string": type, "number": type, "bool": type, "any": type - }; - - for (var attr in tsKeywords) { - jsKeywords[attr] = tsKeywords[attr]; - } - } - - return jsKeywords; - }(); - - var isOperatorChar = /[+\-*&%=<>!?|~^]/; - - function chain(stream, state, f) { - state.tokenize = f; - return f(stream, state); - } - - function nextUntilUnescaped(stream, end) { - var escaped = false, next; - while ((next = stream.next()) != null) { - if (next == end && !escaped) - return false; - escaped = !escaped && next == "\\"; - } - return escaped; - } - - // Used as scratch variables to communicate multiple values without - // consing up tons of objects. - var type, content; - function ret(tp, style, cont) { - type = tp; content = cont; - return style; - } - function jsTokenBase(stream, state) { - var ch = stream.next(); - if (ch == '"' || ch == "'") - return chain(stream, state, jsTokenString(ch)); - else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) - return ret("number", "number"); - else if (/[\[\]{}\(\),;\:\.]/.test(ch)) - return ret(ch); - else if (ch == "0" && stream.eat(/x/i)) { - stream.eatWhile(/[\da-f]/i); - return ret("number", "number"); - } - else if (/\d/.test(ch)) { - stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/); - return ret("number", "number"); - } - else if (ch == "/") { - if (stream.eat("*")) { - return chain(stream, state, jsTokenComment); - } - else if (stream.eat("/")) { - stream.skipToEnd(); - return ret("comment", "comment"); - } - else if (state.lastType == "operator" || state.lastType == "keyword c" || - /^[\[{}\(,;:]$/.test(state.lastType)) { - nextUntilUnescaped(stream, "/"); - stream.eatWhile(/[gimy]/); // 'y' is "sticky" option in Mozilla - return ret("regexp", "string-2"); - } - else { - stream.eatWhile(isOperatorChar); - return ret("operator", null, stream.current()); - } - } - else if (ch == "#") { - stream.skipToEnd(); - return ret("error", "error"); - } - else if (isOperatorChar.test(ch)) { - stream.eatWhile(isOperatorChar); - return ret("operator", null, stream.current()); - } - else { - stream.eatWhile(/[\w\$_]/); - var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word]; - return (known && state.lastType != ".") ? ret(known.type, known.style, word) : - ret("variable", "variable", word); - } - } - - function jsTokenString(quote) { - return function(stream, state) { - if (!nextUntilUnescaped(stream, quote)) - state.tokenize = jsTokenBase; - return ret("string", "string"); - }; - } - - function jsTokenComment(stream, state) { - var maybeEnd = false, ch; - while (ch = stream.next()) { - if (ch == "/" && maybeEnd) { - state.tokenize = jsTokenBase; - break; - } - maybeEnd = (ch == "*"); - } - return ret("comment", "comment"); - } - - // Parser - - var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true, "this": true}; - - function JSLexical(indented, column, type, align, prev, info) { - this.indented = indented; - this.column = column; - this.type = type; - this.prev = prev; - this.info = info; - if (align != null) this.align = align; - } - - function inScope(state, varname) { - for (var v = state.localVars; v; v = v.next) - if (v.name == varname) return true; - } - - function parseJS(state, style, type, content, stream) { - var cc = state.cc; - // Communicate our context to the combinators. - // (Less wasteful than consing up a hundred closures on every call.) - cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc; - - if (!state.lexical.hasOwnProperty("align")) - state.lexical.align = true; - - while(true) { - var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement; - if (combinator(type, content)) { - while(cc.length && cc[cc.length - 1].lex) - cc.pop()(); - if (cx.marked) return cx.marked; - if (type == "variable" && inScope(state, content)) return "variable-2"; - return style; - } - } - } - - // Combinator utils - - var cx = {state: null, column: null, marked: null, cc: null}; - function pass() { - for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]); - } - function cont() { - pass.apply(null, arguments); - return true; - } - function register(varname) { - function inList(list) { - for (var v = list; v; v = v.next) - if (v.name == varname) return true; - return false; - } - var state = cx.state; - if (state.context) { - cx.marked = "def"; - if (inList(state.localVars)) return; - state.localVars = {name: varname, next: state.localVars}; - } else { - if (inList(state.globalVars)) return; - state.globalVars = {name: varname, next: state.globalVars}; - } - } - - // Combinators - - var defaultVars = {name: "this", next: {name: "arguments"}}; - function pushcontext() { - cx.state.context = {prev: cx.state.context, vars: cx.state.localVars}; - cx.state.localVars = defaultVars; - } - function popcontext() { - cx.state.localVars = cx.state.context.vars; - cx.state.context = cx.state.context.prev; - } - function pushlex(type, info) { - var result = function() { - var state = cx.state, indent = state.indented; - if (state.lexical.type == "stat") indent = state.lexical.indented; - state.lexical = new JSLexical(indent, cx.stream.column(), type, null, state.lexical, info); - }; - result.lex = true; - return result; - } - function poplex() { - var state = cx.state; - if (state.lexical.prev) { - if (state.lexical.type == ")") - state.indented = state.lexical.indented; - state.lexical = state.lexical.prev; - } - } - poplex.lex = true; - - function expect(wanted) { - return function(type) { - if (type == wanted) return cont(); - else if (wanted == ";") return pass(); - else return cont(arguments.callee); - }; - } - - function statement(type) { - if (type == "var") return cont(pushlex("vardef"), vardef1, expect(";"), poplex); - if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex); - if (type == "keyword b") return cont(pushlex("form"), statement, poplex); - if (type == "{") return cont(pushlex("}"), block, poplex); - if (type == ";") return cont(); - if (type == "if") return cont(pushlex("form"), expression, statement, poplex, maybeelse); - if (type == "function") return cont(functiondef); - if (type == "for") return cont(pushlex("form"), expect("("), pushlex(")"), forspec1, expect(")"), - poplex, statement, poplex); - if (type == "variable") return cont(pushlex("stat"), maybelabel); - if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"), - block, poplex, poplex); - if (type == "case") return cont(expression, expect(":")); - if (type == "default") return cont(expect(":")); - if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"), - statement, poplex, popcontext); - return pass(pushlex("stat"), expression, expect(";"), poplex); - } - function expression(type) { - return expressionInner(type, false); - } - function expressionNoComma(type) { - return expressionInner(type, true); - } - function expressionInner(type, noComma) { - var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma; - if (atomicTypes.hasOwnProperty(type)) return cont(maybeop); - if (type == "function") return cont(functiondef); - if (type == "keyword c") return cont(noComma ? maybeexpressionNoComma : maybeexpression); - if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeop); - if (type == "operator") return cont(noComma ? expressionNoComma : expression); - if (type == "[") return cont(pushlex("]"), commasep(expressionNoComma, "]"), poplex, maybeop); - if (type == "{") return cont(pushlex("}"), commasep(objprop, "}"), poplex, maybeop); - return cont(); - } - function maybeexpression(type) { - if (type.match(/[;\}\)\],]/)) return pass(); - return pass(expression); - } - function maybeexpressionNoComma(type) { - if (type.match(/[;\}\)\],]/)) return pass(); - return pass(expressionNoComma); - } - - function maybeoperatorComma(type, value) { - if (type == ",") return cont(expression); - return maybeoperatorNoComma(type, value, false); - } - function maybeoperatorNoComma(type, value, noComma) { - var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma; - var expr = noComma == false ? expression : expressionNoComma; - if (type == "operator") { - if (/\+\+|--/.test(value)) return cont(me); - if (value == "?") return cont(expression, expect(":"), expr); - return cont(expr); - } - if (type == ";") return; - if (type == "(") return cont(pushlex(")", "call"), commasep(expressionNoComma, ")"), poplex, me); - if (type == ".") return cont(property, me); - if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me); - } - function maybelabel(type) { - if (type == ":") return cont(poplex, statement); - return pass(maybeoperatorComma, expect(";"), poplex); - } - function property(type) { - if (type == "variable") {cx.marked = "property"; return cont();} - } - function objprop(type, value) { - if (type == "variable") { - cx.marked = "property"; - if (value == "get" || value == "set") return cont(getterSetter); - } else if (type == "number" || type == "string") { - cx.marked = type + " property"; - } - if (atomicTypes.hasOwnProperty(type)) return cont(expect(":"), expressionNoComma); - } - function getterSetter(type) { - if (type == ":") return cont(expression); - if (type != "variable") return cont(expect(":"), expression); - cx.marked = "property"; - return cont(functiondef); - } - function commasep(what, end) { - function proceed(type) { - if (type == ",") { - var lex = cx.state.lexical; - if (lex.info == "call") lex.pos = (lex.pos || 0) + 1; - return cont(what, proceed); - } - if (type == end) return cont(); - return cont(expect(end)); - } - return function(type) { - if (type == end) return cont(); - else return pass(what, proceed); - }; - } - function block(type) { - if (type == "}") return cont(); - return pass(statement, block); - } - function maybetype(type) { - if (type == ":") return cont(typedef); - return pass(); - } - function typedef(type) { - if (type == "variable"){cx.marked = "variable-3"; return cont();} - return pass(); - } - function vardef1(type, value) { - if (type == "variable") { - register(value); - return isTS ? cont(maybetype, vardef2) : cont(vardef2); - } - return pass(); - } - function vardef2(type, value) { - if (value == "=") return cont(expressionNoComma, vardef2); - if (type == ",") return cont(vardef1); - } - function maybeelse(type, value) { - if (type == "keyword b" && value == "else") return cont(pushlex("form"), statement, poplex); - } - function forspec1(type) { - if (type == "var") return cont(vardef1, expect(";"), forspec2); - if (type == ";") return cont(forspec2); - if (type == "variable") return cont(formaybein); - return pass(expression, expect(";"), forspec2); - } - function formaybein(_type, value) { - if (value == "in") return cont(expression); - return cont(maybeoperatorComma, forspec2); - } - function forspec2(type, value) { - if (type == ";") return cont(forspec3); - if (value == "in") return cont(expression); - return pass(expression, expect(";"), forspec3); - } - function forspec3(type) { - if (type != ")") cont(expression); - } - function functiondef(type, value) { - if (type == "variable") {register(value); return cont(functiondef);} - if (type == "(") return cont(pushlex(")"), pushcontext, commasep(funarg, ")"), poplex, statement, popcontext); - } - function funarg(type, value) { - if (type == "variable") {register(value); return isTS ? cont(maybetype) : cont();} - } - - // Interface - - return { - startState: function(basecolumn) { - return { - tokenize: jsTokenBase, - lastType: null, - cc: [], - lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false), - localVars: parserConfig.localVars, - globalVars: parserConfig.globalVars, - context: parserConfig.localVars && {vars: parserConfig.localVars}, - indented: 0 - }; - }, - - token: function(stream, state) { - if (stream.sol()) { - if (!state.lexical.hasOwnProperty("align")) - state.lexical.align = false; - state.indented = stream.indentation(); - } - if (state.tokenize != jsTokenComment && stream.eatSpace()) return null; - var style = state.tokenize(stream, state); - if (type == "comment") return style; - state.lastType = type == "operator" && (content == "++" || content == "--") ? "incdec" : type; - return parseJS(state, style, type, content, stream); - }, - - indent: function(state, textAfter) { - if (state.tokenize == jsTokenComment) return CodeMirror.Pass; - if (state.tokenize != jsTokenBase) return 0; - var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical; - // Kludge to prevent 'maybelse' from blocking lexical scope pops - for (var i = state.cc.length - 1; i >= 0; --i) { - var c = state.cc[i]; - if (c == poplex) lexical = lexical.prev; - else if (c != maybeelse || /^else\b/.test(textAfter)) break; - } - if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev; - if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat") - lexical = lexical.prev; - var type = lexical.type, closing = firstChar == type; - - if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? 4 : 0); - else if (type == "form" && firstChar == "{") return lexical.indented; - else if (type == "form") return lexical.indented + indentUnit; - else if (type == "stat") - return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? statementIndent || indentUnit : 0); - else if (lexical.info == "switch" && !closing && parserConfig.doubleIndentSwitch != false) - return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit); - else if (lexical.align) return lexical.column + (closing ? 0 : 1); - else return lexical.indented + (closing ? 0 : indentUnit); - }, - - electricChars: ":{}", - blockCommentStart: jsonMode ? null : "/*", - blockCommentEnd: jsonMode ? null : "*/", - lineComment: jsonMode ? null : "//", - fold: "brace", - - helperType: jsonMode ? "json" : "javascript", - jsonMode: jsonMode - }; -}); - -CodeMirror.defineMIME("text/javascript", "javascript"); -CodeMirror.defineMIME("text/ecmascript", "javascript"); -CodeMirror.defineMIME("application/javascript", "javascript"); -CodeMirror.defineMIME("application/ecmascript", "javascript"); -CodeMirror.defineMIME("application/json", {name: "javascript", json: true}); -CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true}); -CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true }); -CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true }); +// TODO actually recognize syntax of TypeScript constructs + +CodeMirror.defineMode("javascript", function(config, parserConfig) { + var indentUnit = config.indentUnit; + var statementIndent = parserConfig.statementIndent; + var jsonMode = parserConfig.json; + var isTS = parserConfig.typescript; + + // Tokenizer + + var keywords = function(){ + function kw(type) {return {type: type, style: "keyword"};} + var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c"); + var operator = kw("operator"), atom = {type: "atom", style: "atom"}; + + var jsKeywords = { + "if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B, + "return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C, + "var": kw("var"), "const": kw("var"), "let": kw("var"), + "function": kw("function"), "catch": kw("catch"), + "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"), + "in": operator, "typeof": operator, "instanceof": operator, + "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom, + "this": kw("this") + }; + + // Extend the 'normal' keywords with the TypeScript language extensions + if (isTS) { + var type = {type: "variable", style: "variable-3"}; + var tsKeywords = { + // object-like things + "interface": kw("interface"), + "class": kw("class"), + "extends": kw("extends"), + "constructor": kw("constructor"), + + // scope modifiers + "public": kw("public"), + "private": kw("private"), + "protected": kw("protected"), + "static": kw("static"), + + "super": kw("super"), + + // types + "string": type, "number": type, "bool": type, "any": type + }; + + for (var attr in tsKeywords) { + jsKeywords[attr] = tsKeywords[attr]; + } + } + + return jsKeywords; + }(); + + var isOperatorChar = /[+\-*&%=<>!?|~^]/; + + function chain(stream, state, f) { + state.tokenize = f; + return f(stream, state); + } + + function nextUntilUnescaped(stream, end) { + var escaped = false, next; + while ((next = stream.next()) != null) { + if (next == end && !escaped) + return false; + escaped = !escaped && next == "\\"; + } + return escaped; + } + + // Used as scratch variables to communicate multiple values without + // consing up tons of objects. + var type, content; + function ret(tp, style, cont) { + type = tp; content = cont; + return style; + } + function jsTokenBase(stream, state) { + var ch = stream.next(); + if (ch == '"' || ch == "'") + return chain(stream, state, jsTokenString(ch)); + else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) + return ret("number", "number"); + else if (/[\[\]{}\(\),;\:\.]/.test(ch)) + return ret(ch); + else if (ch == "0" && stream.eat(/x/i)) { + stream.eatWhile(/[\da-f]/i); + return ret("number", "number"); + } + else if (/\d/.test(ch)) { + stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/); + return ret("number", "number"); + } + else if (ch == "/") { + if (stream.eat("*")) { + return chain(stream, state, jsTokenComment); + } + else if (stream.eat("/")) { + stream.skipToEnd(); + return ret("comment", "comment"); + } + else if (state.lastType == "operator" || state.lastType == "keyword c" || + /^[\[{}\(,;:]$/.test(state.lastType)) { + nextUntilUnescaped(stream, "/"); + stream.eatWhile(/[gimy]/); // 'y' is "sticky" option in Mozilla + return ret("regexp", "string-2"); + } + else { + stream.eatWhile(isOperatorChar); + return ret("operator", null, stream.current()); + } + } + else if (ch == "#") { + stream.skipToEnd(); + return ret("error", "error"); + } + else if (isOperatorChar.test(ch)) { + stream.eatWhile(isOperatorChar); + return ret("operator", null, stream.current()); + } + else { + stream.eatWhile(/[\w\$_]/); + var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word]; + return (known && state.lastType != ".") ? ret(known.type, known.style, word) : + ret("variable", "variable", word); + } + } + + function jsTokenString(quote) { + return function(stream, state) { + if (!nextUntilUnescaped(stream, quote)) + state.tokenize = jsTokenBase; + return ret("string", "string"); + }; + } + + function jsTokenComment(stream, state) { + var maybeEnd = false, ch; + while (ch = stream.next()) { + if (ch == "/" && maybeEnd) { + state.tokenize = jsTokenBase; + break; + } + maybeEnd = (ch == "*"); + } + return ret("comment", "comment"); + } + + // Parser + + var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true, "this": true}; + + function JSLexical(indented, column, type, align, prev, info) { + this.indented = indented; + this.column = column; + this.type = type; + this.prev = prev; + this.info = info; + if (align != null) this.align = align; + } + + function inScope(state, varname) { + for (var v = state.localVars; v; v = v.next) + if (v.name == varname) return true; + } + + function parseJS(state, style, type, content, stream) { + var cc = state.cc; + // Communicate our context to the combinators. + // (Less wasteful than consing up a hundred closures on every call.) + cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc; + + if (!state.lexical.hasOwnProperty("align")) + state.lexical.align = true; + + while(true) { + var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement; + if (combinator(type, content)) { + while(cc.length && cc[cc.length - 1].lex) + cc.pop()(); + if (cx.marked) return cx.marked; + if (type == "variable" && inScope(state, content)) return "variable-2"; + return style; + } + } + } + + // Combinator utils + + var cx = {state: null, column: null, marked: null, cc: null}; + function pass() { + for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]); + } + function cont() { + pass.apply(null, arguments); + return true; + } + function register(varname) { + function inList(list) { + for (var v = list; v; v = v.next) + if (v.name == varname) return true; + return false; + } + var state = cx.state; + if (state.context) { + cx.marked = "def"; + if (inList(state.localVars)) return; + state.localVars = {name: varname, next: state.localVars}; + } else { + if (inList(state.globalVars)) return; + state.globalVars = {name: varname, next: state.globalVars}; + } + } + + // Combinators + + var defaultVars = {name: "this", next: {name: "arguments"}}; + function pushcontext() { + cx.state.context = {prev: cx.state.context, vars: cx.state.localVars}; + cx.state.localVars = defaultVars; + } + function popcontext() { + cx.state.localVars = cx.state.context.vars; + cx.state.context = cx.state.context.prev; + } + function pushlex(type, info) { + var result = function() { + var state = cx.state, indent = state.indented; + if (state.lexical.type == "stat") indent = state.lexical.indented; + state.lexical = new JSLexical(indent, cx.stream.column(), type, null, state.lexical, info); + }; + result.lex = true; + return result; + } + function poplex() { + var state = cx.state; + if (state.lexical.prev) { + if (state.lexical.type == ")") + state.indented = state.lexical.indented; + state.lexical = state.lexical.prev; + } + } + poplex.lex = true; + + function expect(wanted) { + return function(type) { + if (type == wanted) return cont(); + else if (wanted == ";") return pass(); + else return cont(arguments.callee); + }; + } + + function statement(type) { + if (type == "var") return cont(pushlex("vardef"), vardef1, expect(";"), poplex); + if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex); + if (type == "keyword b") return cont(pushlex("form"), statement, poplex); + if (type == "{") return cont(pushlex("}"), block, poplex); + if (type == ";") return cont(); + if (type == "if") return cont(pushlex("form"), expression, statement, poplex, maybeelse); + if (type == "function") return cont(functiondef); + if (type == "for") return cont(pushlex("form"), expect("("), pushlex(")"), forspec1, expect(")"), + poplex, statement, poplex); + if (type == "variable") return cont(pushlex("stat"), maybelabel); + if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"), + block, poplex, poplex); + if (type == "case") return cont(expression, expect(":")); + if (type == "default") return cont(expect(":")); + if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"), + statement, poplex, popcontext); + return pass(pushlex("stat"), expression, expect(";"), poplex); + } + function expression(type) { + return expressionInner(type, false); + } + function expressionNoComma(type) { + return expressionInner(type, true); + } + function expressionInner(type, noComma) { + var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma; + if (atomicTypes.hasOwnProperty(type)) return cont(maybeop); + if (type == "function") return cont(functiondef); + if (type == "keyword c") return cont(noComma ? maybeexpressionNoComma : maybeexpression); + if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeop); + if (type == "operator") return cont(noComma ? expressionNoComma : expression); + if (type == "[") return cont(pushlex("]"), commasep(expressionNoComma, "]"), poplex, maybeop); + if (type == "{") return cont(pushlex("}"), commasep(objprop, "}"), poplex, maybeop); + return cont(); + } + function maybeexpression(type) { + if (type.match(/[;\}\)\],]/)) return pass(); + return pass(expression); + } + function maybeexpressionNoComma(type) { + if (type.match(/[;\}\)\],]/)) return pass(); + return pass(expressionNoComma); + } + + function maybeoperatorComma(type, value) { + if (type == ",") return cont(expression); + return maybeoperatorNoComma(type, value, false); + } + function maybeoperatorNoComma(type, value, noComma) { + var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma; + var expr = noComma == false ? expression : expressionNoComma; + if (type == "operator") { + if (/\+\+|--/.test(value)) return cont(me); + if (value == "?") return cont(expression, expect(":"), expr); + return cont(expr); + } + if (type == ";") return; + if (type == "(") return cont(pushlex(")", "call"), commasep(expressionNoComma, ")"), poplex, me); + if (type == ".") return cont(property, me); + if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me); + } + function maybelabel(type) { + if (type == ":") return cont(poplex, statement); + return pass(maybeoperatorComma, expect(";"), poplex); + } + function property(type) { + if (type == "variable") {cx.marked = "property"; return cont();} + } + function objprop(type, value) { + if (type == "variable") { + cx.marked = "property"; + if (value == "get" || value == "set") return cont(getterSetter); + } else if (type == "number" || type == "string") { + cx.marked = type + " property"; + } + if (atomicTypes.hasOwnProperty(type)) return cont(expect(":"), expressionNoComma); + } + function getterSetter(type) { + if (type == ":") return cont(expression); + if (type != "variable") return cont(expect(":"), expression); + cx.marked = "property"; + return cont(functiondef); + } + function commasep(what, end) { + function proceed(type) { + if (type == ",") { + var lex = cx.state.lexical; + if (lex.info == "call") lex.pos = (lex.pos || 0) + 1; + return cont(what, proceed); + } + if (type == end) return cont(); + return cont(expect(end)); + } + return function(type) { + if (type == end) return cont(); + else return pass(what, proceed); + }; + } + function block(type) { + if (type == "}") return cont(); + return pass(statement, block); + } + function maybetype(type) { + if (type == ":") return cont(typedef); + return pass(); + } + function typedef(type) { + if (type == "variable"){cx.marked = "variable-3"; return cont();} + return pass(); + } + function vardef1(type, value) { + if (type == "variable") { + register(value); + return isTS ? cont(maybetype, vardef2) : cont(vardef2); + } + return pass(); + } + function vardef2(type, value) { + if (value == "=") return cont(expressionNoComma, vardef2); + if (type == ",") return cont(vardef1); + } + function maybeelse(type, value) { + if (type == "keyword b" && value == "else") return cont(pushlex("form"), statement, poplex); + } + function forspec1(type) { + if (type == "var") return cont(vardef1, expect(";"), forspec2); + if (type == ";") return cont(forspec2); + if (type == "variable") return cont(formaybein); + return pass(expression, expect(";"), forspec2); + } + function formaybein(_type, value) { + if (value == "in") return cont(expression); + return cont(maybeoperatorComma, forspec2); + } + function forspec2(type, value) { + if (type == ";") return cont(forspec3); + if (value == "in") return cont(expression); + return pass(expression, expect(";"), forspec3); + } + function forspec3(type) { + if (type != ")") cont(expression); + } + function functiondef(type, value) { + if (type == "variable") {register(value); return cont(functiondef);} + if (type == "(") return cont(pushlex(")"), pushcontext, commasep(funarg, ")"), poplex, statement, popcontext); + } + function funarg(type, value) { + if (type == "variable") {register(value); return isTS ? cont(maybetype) : cont();} + } + + // Interface + + return { + startState: function(basecolumn) { + return { + tokenize: jsTokenBase, + lastType: null, + cc: [], + lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false), + localVars: parserConfig.localVars, + globalVars: parserConfig.globalVars, + context: parserConfig.localVars && {vars: parserConfig.localVars}, + indented: 0 + }; + }, + + token: function(stream, state) { + if (stream.sol()) { + if (!state.lexical.hasOwnProperty("align")) + state.lexical.align = false; + state.indented = stream.indentation(); + } + if (state.tokenize != jsTokenComment && stream.eatSpace()) return null; + var style = state.tokenize(stream, state); + if (type == "comment") return style; + state.lastType = type == "operator" && (content == "++" || content == "--") ? "incdec" : type; + return parseJS(state, style, type, content, stream); + }, + + indent: function(state, textAfter) { + if (state.tokenize == jsTokenComment) return CodeMirror.Pass; + if (state.tokenize != jsTokenBase) return 0; + var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical; + // Kludge to prevent 'maybelse' from blocking lexical scope pops + for (var i = state.cc.length - 1; i >= 0; --i) { + var c = state.cc[i]; + if (c == poplex) lexical = lexical.prev; + else if (c != maybeelse || /^else\b/.test(textAfter)) break; + } + if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev; + if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat") + lexical = lexical.prev; + var type = lexical.type, closing = firstChar == type; + + if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? 4 : 0); + else if (type == "form" && firstChar == "{") return lexical.indented; + else if (type == "form") return lexical.indented + indentUnit; + else if (type == "stat") + return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? statementIndent || indentUnit : 0); + else if (lexical.info == "switch" && !closing && parserConfig.doubleIndentSwitch != false) + return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit); + else if (lexical.align) return lexical.column + (closing ? 0 : 1); + else return lexical.indented + (closing ? 0 : indentUnit); + }, + + electricChars: ":{}", + blockCommentStart: jsonMode ? null : "/*", + blockCommentEnd: jsonMode ? null : "*/", + lineComment: jsonMode ? null : "//", + fold: "brace", + + helperType: jsonMode ? "json" : "javascript", + jsonMode: jsonMode + }; +}); + +CodeMirror.defineMIME("text/javascript", "javascript"); +CodeMirror.defineMIME("text/ecmascript", "javascript"); +CodeMirror.defineMIME("application/javascript", "javascript"); +CodeMirror.defineMIME("application/ecmascript", "javascript"); +CodeMirror.defineMIME("application/json", {name: "javascript", json: true}); +CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true}); +CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true }); +CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true }); diff --git a/profile-builder/assets/lib/codemirror/mode/javascript/test.js b/profile-builder/assets/lib/codemirror/mode/javascript/test.js index a2af527..d6654b2 100644 --- a/profile-builder/assets/lib/codemirror/mode/javascript/test.js +++ b/profile-builder/assets/lib/codemirror/mode/javascript/test.js @@ -1,10 +1,10 @@ -(function() { - var mode = CodeMirror.getMode({indentUnit: 2}, "javascript"); - function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); } - - MT("locals", - "[keyword function] [variable foo]([def a], [def b]) { [keyword var] [def c] = [number 10]; [keyword return] [variable-2 a] + [variable-2 c] + [variable d]; }"); - - MT("comma-and-binop", - "[keyword function](){ [keyword var] [def x] = [number 1] + [number 2], [def y]; }"); -})(); +(function() { + var mode = CodeMirror.getMode({indentUnit: 2}, "javascript"); + function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); } + + MT("locals", + "[keyword function] [variable foo]([def a], [def b]) { [keyword var] [def c] = [number 10]; [keyword return] [variable-2 a] + [variable-2 c] + [variable d]; }"); + + MT("comma-and-binop", + "[keyword function](){ [keyword var] [def x] = [number 1] + [number 2], [def y]; }"); +})(); diff --git a/profile-builder/assets/lib/codemirror/mode/javascript/typescript.html b/profile-builder/assets/lib/codemirror/mode/javascript/typescript.html index 9cc5f49..2ccae2a 100644 --- a/profile-builder/assets/lib/codemirror/mode/javascript/typescript.html +++ b/profile-builder/assets/lib/codemirror/mode/javascript/typescript.html @@ -1,61 +1,61 @@ - - -CodeMirror: TypeScript mode - - - - - - - - - -
            -

            TypeScript mode

            - - -
            - - - -

            This is a specialization of the JavaScript mode.

            -
            + + +CodeMirror: TypeScript mode + + + + + + + + + +
            +

            TypeScript mode

            + + +
            + + + +

            This is a specialization of the JavaScript mode.

            +
            diff --git a/profile-builder/assets/lib/codemirror/mode/meta.js b/profile-builder/assets/lib/codemirror/mode/meta.js index ce51c8a..931d664 100644 --- a/profile-builder/assets/lib/codemirror/mode/meta.js +++ b/profile-builder/assets/lib/codemirror/mode/meta.js @@ -1,87 +1,87 @@ -CodeMirror.modeInfo = [ - {name: 'APL', mime: 'text/apl', mode: 'apl'}, - {name: 'Asterisk', mime: 'text/x-asterisk', mode: 'asterisk'}, - {name: 'C', mime: 'text/x-csrc', mode: 'clike'}, - {name: 'C++', mime: 'text/x-c++src', mode: 'clike'}, - {name: 'Cobol', mime: 'text/x-cobol', mode: 'cobol'}, - {name: 'Java', mime: 'text/x-java', mode: 'clike'}, - {name: 'C#', mime: 'text/x-csharp', mode: 'clike'}, - {name: 'Scala', mime: 'text/x-scala', mode: 'clike'}, - {name: 'Clojure', mime: 'text/x-clojure', mode: 'clojure'}, - {name: 'CoffeeScript', mime: 'text/x-coffeescript', mode: 'coffeescript'}, - {name: 'Common Lisp', mime: 'text/x-common-lisp', mode: 'commonlisp'}, - {name: 'CSS', mime: 'text/css', mode: 'css'}, - {name: 'D', mime: 'text/x-d', mode: 'd'}, - {name: 'diff', mime: 'text/x-diff', mode: 'diff'}, - {name: 'DTD', mime: 'application/xml-dtd', mode: 'dtd'}, - {name: 'ECL', mime: 'text/x-ecl', mode: 'ecl'}, - {name: 'Erlang', mime: 'text/x-erlang', mode: 'erlang'}, - {name: 'Fortran', mime: 'text/x-fortran', mode: 'fortran'}, - {name: 'Gas', mime: 'text/x-gas', mode: 'gas'}, - {name: 'GitHub Flavored Markdown', mime: 'text/x-gfm', mode: 'gfm'}, - {name: 'GO', mime: 'text/x-go', mode: 'go'}, - {name: 'Groovy', mime: 'text/x-groovy', mode: 'groovy'}, - {name: 'HAML', mime: 'text/x-haml', mode: 'haml'}, - {name: 'Haskell', mime: 'text/x-haskell', mode: 'haskell'}, - {name: 'Haxe', mime: 'text/x-haxe', mode: 'haxe'}, - {name: 'ASP.NET', mime: 'application/x-aspx', mode: 'htmlembedded'}, - {name: 'Embedded Javascript', mime: 'application/x-ejs', mode: 'htmlembedded'}, - {name: 'JavaServer Pages', mime: 'application/x-jsp', mode: 'htmlembedded'}, - {name: 'HTML', mime: 'text/html', mode: 'htmlmixed'}, - {name: 'HTTP', mime: 'message/http', mode: 'http'}, - {name: 'Jade', mime: 'text/x-jade', mode: 'jade'}, - {name: 'JavaScript', mime: 'text/javascript', mode: 'javascript'}, - {name: 'JSON', mime: 'application/x-json', mode: 'javascript'}, - {name: 'JSON', mime: 'application/json', mode: 'javascript'}, - {name: 'TypeScript', mime: 'application/typescript', mode: 'javascript'}, - {name: 'Jinja2', mime: 'jinja2', mode: 'jinja2'}, - {name: 'LESS', mime: 'text/x-less', mode: 'less'}, - {name: 'LiveScript', mime: 'text/x-livescript', mode: 'livescript'}, - {name: 'Lua', mime: 'text/x-lua', mode: 'lua'}, - {name: 'Markdown (GitHub-flavour)', mime: 'text/x-markdown', mode: 'markdown'}, - {name: 'mIRC', mime: 'text/mirc', mode: 'mirc'}, - {name: 'Nginx', mime: 'text/x-nginx-conf', mode: 'nginx'}, - {name: 'NTriples', mime: 'text/n-triples', mode: 'ntriples'}, - {name: 'OCaml', mime: 'text/x-ocaml', mode: 'ocaml'}, - {name: 'Octave', mime: 'text/x-octave', mode: 'octave'}, - {name: 'Pascal', mime: 'text/x-pascal', mode: 'pascal'}, - {name: 'Perl', mime: 'text/x-perl', mode: 'perl'}, - {name: 'PHP', mime: 'text/x-php', mode: 'php'}, - {name: 'PHP(HTML)', mime: 'application/x-httpd-php', mode: 'php'}, - {name: 'Pig', mime: 'text/x-pig', mode: 'pig'}, - {name: 'Plain Text', mime: 'text/plain', mode: 'null'}, - {name: 'Properties files', mime: 'text/x-properties', mode: 'properties'}, - {name: 'Python', mime: 'text/x-python', mode: 'python'}, - {name: 'Cython', mime: 'text/x-cython', mode: 'python'}, - {name: 'R', mime: 'text/x-rsrc', mode: 'r'}, - {name: 'reStructuredText', mime: 'text/x-rst', mode: 'rst'}, - {name: 'Ruby', mime: 'text/x-ruby', mode: 'ruby'}, - {name: 'Rust', mime: 'text/x-rustsrc', mode: 'rust'}, - {name: 'Sass', mime: 'text/x-sass', mode: 'sass'}, - {name: 'Scheme', mime: 'text/x-scheme', mode: 'scheme'}, - {name: 'SCSS', mime: 'text/x-scss', mode: 'css'}, - {name: 'Shell', mime: 'text/x-sh', mode: 'shell'}, - {name: 'Sieve', mime: 'application/sieve', mode: 'sieve'}, - {name: 'Smalltalk', mime: 'text/x-stsrc', mode: 'smalltalk'}, - {name: 'Smarty', mime: 'text/x-smarty', mode: 'smarty'}, - {name: 'SmartyMixed', mime: 'text/x-smarty', mode: 'smartymixed'}, - {name: 'SPARQL', mime: 'application/x-sparql-query', mode: 'sparql'}, - {name: 'SQL', mime: 'text/x-sql', mode: 'sql'}, - {name: 'MariaDB', mime: 'text/x-mariadb', mode: 'sql'}, - {name: 'sTeX', mime: 'text/x-stex', mode: 'stex'}, - {name: 'LaTeX', mime: 'text/x-latex', mode: 'stex'}, - {name: 'Tcl', mime: 'text/x-tcl', mode: 'tcl'}, - {name: 'TiddlyWiki ', mime: 'text/x-tiddlywiki', mode: 'tiddlywiki'}, - {name: 'Tiki wiki', mime: 'text/tiki', mode: 'tiki'}, - {name: 'TOML', mime: 'text/x-toml', mode: 'toml'}, - {name: 'Turtle', mime: 'text/turtle', mode: 'turtle'}, - {name: 'VB.NET', mime: 'text/x-vb', mode: 'vb'}, - {name: 'VBScript', mime: 'text/vbscript', mode: 'vbscript'}, - {name: 'Velocity', mime: 'text/velocity', mode: 'velocity'}, - {name: 'Verilog', mime: 'text/x-verilog', mode: 'verilog'}, - {name: 'XML', mime: 'application/xml', mode: 'xml'}, - {name: 'HTML', mime: 'text/html', mode: 'xml'}, - {name: 'XQuery', mime: 'application/xquery', mode: 'xquery'}, - {name: 'YAML', mime: 'text/x-yaml', mode: 'yaml'}, - {name: 'Z80', mime: 'text/x-z80', mode: 'z80'} -]; +CodeMirror.modeInfo = [ + {name: 'APL', mime: 'text/apl', mode: 'apl'}, + {name: 'Asterisk', mime: 'text/x-asterisk', mode: 'asterisk'}, + {name: 'C', mime: 'text/x-csrc', mode: 'clike'}, + {name: 'C++', mime: 'text/x-c++src', mode: 'clike'}, + {name: 'Cobol', mime: 'text/x-cobol', mode: 'cobol'}, + {name: 'Java', mime: 'text/x-java', mode: 'clike'}, + {name: 'C#', mime: 'text/x-csharp', mode: 'clike'}, + {name: 'Scala', mime: 'text/x-scala', mode: 'clike'}, + {name: 'Clojure', mime: 'text/x-clojure', mode: 'clojure'}, + {name: 'CoffeeScript', mime: 'text/x-coffeescript', mode: 'coffeescript'}, + {name: 'Common Lisp', mime: 'text/x-common-lisp', mode: 'commonlisp'}, + {name: 'CSS', mime: 'text/css', mode: 'css'}, + {name: 'D', mime: 'text/x-d', mode: 'd'}, + {name: 'diff', mime: 'text/x-diff', mode: 'diff'}, + {name: 'DTD', mime: 'application/xml-dtd', mode: 'dtd'}, + {name: 'ECL', mime: 'text/x-ecl', mode: 'ecl'}, + {name: 'Erlang', mime: 'text/x-erlang', mode: 'erlang'}, + {name: 'Fortran', mime: 'text/x-fortran', mode: 'fortran'}, + {name: 'Gas', mime: 'text/x-gas', mode: 'gas'}, + {name: 'GitHub Flavored Markdown', mime: 'text/x-gfm', mode: 'gfm'}, + {name: 'GO', mime: 'text/x-go', mode: 'go'}, + {name: 'Groovy', mime: 'text/x-groovy', mode: 'groovy'}, + {name: 'HAML', mime: 'text/x-haml', mode: 'haml'}, + {name: 'Haskell', mime: 'text/x-haskell', mode: 'haskell'}, + {name: 'Haxe', mime: 'text/x-haxe', mode: 'haxe'}, + {name: 'ASP.NET', mime: 'application/x-aspx', mode: 'htmlembedded'}, + {name: 'Embedded Javascript', mime: 'application/x-ejs', mode: 'htmlembedded'}, + {name: 'JavaServer Pages', mime: 'application/x-jsp', mode: 'htmlembedded'}, + {name: 'HTML', mime: 'text/html', mode: 'htmlmixed'}, + {name: 'HTTP', mime: 'message/http', mode: 'http'}, + {name: 'Jade', mime: 'text/x-jade', mode: 'jade'}, + {name: 'JavaScript', mime: 'text/javascript', mode: 'javascript'}, + {name: 'JSON', mime: 'application/x-json', mode: 'javascript'}, + {name: 'JSON', mime: 'application/json', mode: 'javascript'}, + {name: 'TypeScript', mime: 'application/typescript', mode: 'javascript'}, + {name: 'Jinja2', mime: 'jinja2', mode: 'jinja2'}, + {name: 'LESS', mime: 'text/x-less', mode: 'less'}, + {name: 'LiveScript', mime: 'text/x-livescript', mode: 'livescript'}, + {name: 'Lua', mime: 'text/x-lua', mode: 'lua'}, + {name: 'Markdown (GitHub-flavour)', mime: 'text/x-markdown', mode: 'markdown'}, + {name: 'mIRC', mime: 'text/mirc', mode: 'mirc'}, + {name: 'Nginx', mime: 'text/x-nginx-conf', mode: 'nginx'}, + {name: 'NTriples', mime: 'text/n-triples', mode: 'ntriples'}, + {name: 'OCaml', mime: 'text/x-ocaml', mode: 'ocaml'}, + {name: 'Octave', mime: 'text/x-octave', mode: 'octave'}, + {name: 'Pascal', mime: 'text/x-pascal', mode: 'pascal'}, + {name: 'Perl', mime: 'text/x-perl', mode: 'perl'}, + {name: 'PHP', mime: 'text/x-php', mode: 'php'}, + {name: 'PHP(HTML)', mime: 'application/x-httpd-php', mode: 'php'}, + {name: 'Pig', mime: 'text/x-pig', mode: 'pig'}, + {name: 'Plain Text', mime: 'text/plain', mode: 'null'}, + {name: 'Properties files', mime: 'text/x-properties', mode: 'properties'}, + {name: 'Python', mime: 'text/x-python', mode: 'python'}, + {name: 'Cython', mime: 'text/x-cython', mode: 'python'}, + {name: 'R', mime: 'text/x-rsrc', mode: 'r'}, + {name: 'reStructuredText', mime: 'text/x-rst', mode: 'rst'}, + {name: 'Ruby', mime: 'text/x-ruby', mode: 'ruby'}, + {name: 'Rust', mime: 'text/x-rustsrc', mode: 'rust'}, + {name: 'Sass', mime: 'text/x-sass', mode: 'sass'}, + {name: 'Scheme', mime: 'text/x-scheme', mode: 'scheme'}, + {name: 'SCSS', mime: 'text/x-scss', mode: 'css'}, + {name: 'Shell', mime: 'text/x-sh', mode: 'shell'}, + {name: 'Sieve', mime: 'application/sieve', mode: 'sieve'}, + {name: 'Smalltalk', mime: 'text/x-stsrc', mode: 'smalltalk'}, + {name: 'Smarty', mime: 'text/x-smarty', mode: 'smarty'}, + {name: 'SmartyMixed', mime: 'text/x-smarty', mode: 'smartymixed'}, + {name: 'SPARQL', mime: 'application/x-sparql-query', mode: 'sparql'}, + {name: 'SQL', mime: 'text/x-sql', mode: 'sql'}, + {name: 'MariaDB', mime: 'text/x-mariadb', mode: 'sql'}, + {name: 'sTeX', mime: 'text/x-stex', mode: 'stex'}, + {name: 'LaTeX', mime: 'text/x-latex', mode: 'stex'}, + {name: 'Tcl', mime: 'text/x-tcl', mode: 'tcl'}, + {name: 'TiddlyWiki ', mime: 'text/x-tiddlywiki', mode: 'tiddlywiki'}, + {name: 'Tiki wiki', mime: 'text/tiki', mode: 'tiki'}, + {name: 'TOML', mime: 'text/x-toml', mode: 'toml'}, + {name: 'Turtle', mime: 'text/turtle', mode: 'turtle'}, + {name: 'VB.NET', mime: 'text/x-vb', mode: 'vb'}, + {name: 'VBScript', mime: 'text/vbscript', mode: 'vbscript'}, + {name: 'Velocity', mime: 'text/velocity', mode: 'velocity'}, + {name: 'Verilog', mime: 'text/x-verilog', mode: 'verilog'}, + {name: 'XML', mime: 'application/xml', mode: 'xml'}, + {name: 'HTML', mime: 'text/html', mode: 'xml'}, + {name: 'XQuery', mime: 'application/xquery', mode: 'xquery'}, + {name: 'YAML', mime: 'text/x-yaml', mode: 'yaml'}, + {name: 'Z80', mime: 'text/x-z80', mode: 'z80'} +]; diff --git a/profile-builder/assets/lib/codemirror/mode/php/index.html b/profile-builder/assets/lib/codemirror/mode/php/index.html index aaf51c0..d467a31 100644 --- a/profile-builder/assets/lib/codemirror/mode/php/index.html +++ b/profile-builder/assets/lib/codemirror/mode/php/index.html @@ -1,62 +1,62 @@ - - -CodeMirror: PHP mode - - - - - - - - - - - - - - - -
            -

            PHP mode

            -
            - - - -

            Simple HTML/PHP mode based on - the C-like mode. Depends on XML, - JavaScript, CSS, HTMLMixed, and C-like modes.

            - -

            MIME types defined: application/x-httpd-php (HTML with PHP code), text/x-php (plain, non-wrapped PHP code).

            -
            + + +CodeMirror: PHP mode + + + + + + + + + + + + + + + +
            +

            PHP mode

            +
            + + + +

            Simple HTML/PHP mode based on + the C-like mode. Depends on XML, + JavaScript, CSS, HTMLMixed, and C-like modes.

            + +

            MIME types defined: application/x-httpd-php (HTML with PHP code), text/x-php (plain, non-wrapped PHP code).

            +
            diff --git a/profile-builder/assets/lib/codemirror/mode/php/php.js b/profile-builder/assets/lib/codemirror/mode/php/php.js index fa0db5b..6094103 100644 --- a/profile-builder/assets/lib/codemirror/mode/php/php.js +++ b/profile-builder/assets/lib/codemirror/mode/php/php.js @@ -1,132 +1,132 @@ -(function() { - function keywords(str) { - var obj = {}, words = str.split(" "); - for (var i = 0; i < words.length; ++i) obj[words[i]] = true; - return obj; - } - function heredoc(delim) { - return function(stream, state) { - if (stream.match(delim)) state.tokenize = null; - else stream.skipToEnd(); - return "string"; - }; - } - var phpConfig = { - name: "clike", - keywords: keywords("abstract and array as break case catch class clone const continue declare default " + - "do else elseif enddeclare endfor endforeach endif endswitch endwhile extends final " + - "for foreach function global goto if implements interface instanceof namespace " + - "new or private protected public static switch throw trait try use var while xor " + - "die echo empty exit eval include include_once isset list require require_once return " + - "print unset __halt_compiler self static parent"), - blockKeywords: keywords("catch do else elseif for foreach if switch try while"), - atoms: keywords("true false null TRUE FALSE NULL __CLASS__ __DIR__ __FILE__ __LINE__ __METHOD__ __FUNCTION__ __NAMESPACE__"), - builtin: keywords("func_num_args func_get_arg func_get_args strlen strcmp strncmp strcasecmp strncasecmp each error_reporting define defined trigger_error user_error set_error_handler restore_error_handler get_declared_classes get_loaded_extensions extension_loaded get_extension_funcs debug_backtrace constant bin2hex sleep usleep time mktime gmmktime strftime gmstrftime strtotime date gmdate getdate localtime checkdate flush wordwrap htmlspecialchars htmlentities html_entity_decode md5 md5_file crc32 getimagesize image_type_to_mime_type phpinfo phpversion phpcredits strnatcmp strnatcasecmp substr_count strspn strcspn strtok strtoupper strtolower strpos strrpos strrev hebrev hebrevc nl2br basename dirname pathinfo stripslashes stripcslashes strstr stristr strrchr str_shuffle str_word_count strcoll substr substr_replace quotemeta ucfirst ucwords strtr addslashes addcslashes rtrim str_replace str_repeat count_chars chunk_split trim ltrim strip_tags similar_text explode implode setlocale localeconv parse_str str_pad chop strchr sprintf printf vprintf vsprintf sscanf fscanf parse_url urlencode urldecode rawurlencode rawurldecode readlink linkinfo link unlink exec system escapeshellcmd escapeshellarg passthru shell_exec proc_open proc_close rand srand getrandmax mt_rand mt_srand mt_getrandmax base64_decode base64_encode abs ceil floor round is_finite is_nan is_infinite bindec hexdec octdec decbin decoct dechex base_convert number_format fmod ip2long long2ip getenv putenv getopt microtime gettimeofday getrusage uniqid quoted_printable_decode set_time_limit get_cfg_var magic_quotes_runtime set_magic_quotes_runtime get_magic_quotes_gpc get_magic_quotes_runtime import_request_variables error_log serialize unserialize memory_get_usage var_dump var_export debug_zval_dump print_r highlight_file show_source highlight_string ini_get ini_get_all ini_set ini_alter ini_restore get_include_path set_include_path restore_include_path setcookie header headers_sent connection_aborted connection_status ignore_user_abort parse_ini_file is_uploaded_file move_uploaded_file intval floatval doubleval strval gettype settype is_null is_resource is_bool is_long is_float is_int is_integer is_double is_real is_numeric is_string is_array is_object is_scalar ereg ereg_replace eregi eregi_replace split spliti join sql_regcase dl pclose popen readfile rewind rmdir umask fclose feof fgetc fgets fgetss fread fopen fpassthru ftruncate fstat fseek ftell fflush fwrite fputs mkdir rename copy tempnam tmpfile file file_get_contents stream_select stream_context_create stream_context_set_params stream_context_set_option stream_context_get_options stream_filter_prepend stream_filter_append fgetcsv flock get_meta_tags stream_set_write_buffer set_file_buffer set_socket_blocking stream_set_blocking socket_set_blocking stream_get_meta_data stream_register_wrapper stream_wrapper_register stream_set_timeout socket_set_timeout socket_get_status realpath fnmatch fsockopen pfsockopen pack unpack get_browser crypt opendir closedir chdir getcwd rewinddir readdir dir glob fileatime filectime filegroup fileinode filemtime fileowner fileperms filesize filetype file_exists is_writable is_writeable is_readable is_executable is_file is_dir is_link stat lstat chown touch clearstatcache mail ob_start ob_flush ob_clean ob_end_flush ob_end_clean ob_get_flush ob_get_clean ob_get_length ob_get_level ob_get_status ob_get_contents ob_implicit_flush ob_list_handlers ksort krsort natsort natcasesort asort arsort sort rsort usort uasort uksort shuffle array_walk count end prev next reset current key min max in_array array_search extract compact array_fill range array_multisort array_push array_pop array_shift array_unshift array_splice array_slice array_merge array_merge_recursive array_keys array_values array_count_values array_reverse array_reduce array_pad array_flip array_change_key_case array_rand array_unique array_intersect array_intersect_assoc array_diff array_diff_assoc array_sum array_filter array_map array_chunk array_key_exists pos sizeof key_exists assert assert_options version_compare ftok str_rot13 aggregate session_name session_module_name session_save_path session_id session_regenerate_id session_decode session_register session_unregister session_is_registered session_encode session_start session_destroy session_unset session_set_save_handler session_cache_limiter session_cache_expire session_set_cookie_params session_get_cookie_params session_write_close preg_match preg_match_all preg_replace preg_replace_callback preg_split preg_quote preg_grep overload ctype_alnum ctype_alpha ctype_cntrl ctype_digit ctype_lower ctype_graph ctype_print ctype_punct ctype_space ctype_upper ctype_xdigit virtual apache_request_headers apache_note apache_lookup_uri apache_child_terminate apache_setenv apache_response_headers apache_get_version getallheaders mysql_connect mysql_pconnect mysql_close mysql_select_db mysql_create_db mysql_drop_db mysql_query mysql_unbuffered_query mysql_db_query mysql_list_dbs mysql_list_tables mysql_list_fields mysql_list_processes mysql_error mysql_errno mysql_affected_rows mysql_insert_id mysql_result mysql_num_rows mysql_num_fields mysql_fetch_row mysql_fetch_array mysql_fetch_assoc mysql_fetch_object mysql_data_seek mysql_fetch_lengths mysql_fetch_field mysql_field_seek mysql_free_result mysql_field_name mysql_field_table mysql_field_len mysql_field_type mysql_field_flags mysql_escape_string mysql_real_escape_string mysql_stat mysql_thread_id mysql_client_encoding mysql_get_client_info mysql_get_host_info mysql_get_proto_info mysql_get_server_info mysql_info mysql mysql_fieldname mysql_fieldtable mysql_fieldlen mysql_fieldtype mysql_fieldflags mysql_selectdb mysql_createdb mysql_dropdb mysql_freeresult mysql_numfields mysql_numrows mysql_listdbs mysql_listtables mysql_listfields mysql_db_name mysql_dbname mysql_tablename mysql_table_name pg_connect pg_pconnect pg_close pg_connection_status pg_connection_busy pg_connection_reset pg_host pg_dbname pg_port pg_tty pg_options pg_ping pg_query pg_send_query pg_cancel_query pg_fetch_result pg_fetch_row pg_fetch_assoc pg_fetch_array pg_fetch_object pg_fetch_all pg_affected_rows pg_get_result pg_result_seek pg_result_status pg_free_result pg_last_oid pg_num_rows pg_num_fields pg_field_name pg_field_num pg_field_size pg_field_type pg_field_prtlen pg_field_is_null pg_get_notify pg_get_pid pg_result_error pg_last_error pg_last_notice pg_put_line pg_end_copy pg_copy_to pg_copy_from pg_trace pg_untrace pg_lo_create pg_lo_unlink pg_lo_open pg_lo_close pg_lo_read pg_lo_write pg_lo_read_all pg_lo_import pg_lo_export pg_lo_seek pg_lo_tell pg_escape_string pg_escape_bytea pg_unescape_bytea pg_client_encoding pg_set_client_encoding pg_meta_data pg_convert pg_insert pg_update pg_delete pg_select pg_exec pg_getlastoid pg_cmdtuples pg_errormessage pg_numrows pg_numfields pg_fieldname pg_fieldsize pg_fieldtype pg_fieldnum pg_fieldprtlen pg_fieldisnull pg_freeresult pg_result pg_loreadall pg_locreate pg_lounlink pg_loopen pg_loclose pg_loread pg_lowrite pg_loimport pg_loexport echo print global static exit array empty eval isset unset die include require include_once require_once"), - multiLineStrings: true, - hooks: { - "$": function(stream) { - stream.eatWhile(/[\w\$_]/); - return "variable-2"; - }, - "<": function(stream, state) { - if (stream.match(/<", false)) stream.next(); - return "comment"; - }, - "/": function(stream) { - if (stream.eat("/")) { - while (!stream.eol() && !stream.match("?>", false)) stream.next(); - return "comment"; - } - return false; - } - } - }; - - CodeMirror.defineMode("php", function(config, parserConfig) { - var htmlMode = CodeMirror.getMode(config, "text/html"); - var phpMode = CodeMirror.getMode(config, phpConfig); - - function dispatch(stream, state) { - var isPHP = state.curMode == phpMode; - if (stream.sol() && state.pending != '"') state.pending = null; - if (!isPHP) { - if (stream.match(/^<\?\w*/)) { - state.curMode = phpMode; - state.curState = state.php; - return "meta"; - } - if (state.pending == '"') { - while (!stream.eol() && stream.next() != '"') {} - var style = "string"; - } else if (state.pending && stream.pos < state.pending.end) { - stream.pos = state.pending.end; - var style = state.pending.style; - } else { - var style = htmlMode.token(stream, state.curState); - } - state.pending = null; - var cur = stream.current(), openPHP = cur.search(/<\?/); - if (openPHP != -1) { - if (style == "string" && /\"$/.test(cur) && !/\?>/.test(cur)) state.pending = '"'; - else state.pending = {end: stream.pos, style: style}; - stream.backUp(cur.length - openPHP); - } - return style; - } else if (isPHP && state.php.tokenize == null && stream.match("?>")) { - state.curMode = htmlMode; - state.curState = state.html; - return "meta"; - } else { - return phpMode.token(stream, state.curState); - } - } - - return { - startState: function() { - var html = CodeMirror.startState(htmlMode), php = CodeMirror.startState(phpMode); - return {html: html, - php: php, - curMode: parserConfig.startOpen ? phpMode : htmlMode, - curState: parserConfig.startOpen ? php : html, - pending: null}; - }, - - copyState: function(state) { - var html = state.html, htmlNew = CodeMirror.copyState(htmlMode, html), - php = state.php, phpNew = CodeMirror.copyState(phpMode, php), cur; - if (state.curMode == htmlMode) cur = htmlNew; - else cur = phpNew; - return {html: htmlNew, php: phpNew, curMode: state.curMode, curState: cur, - pending: state.pending}; - }, - - token: dispatch, - - indent: function(state, textAfter) { - if ((state.curMode != phpMode && /^\s*<\//.test(textAfter)) || - (state.curMode == phpMode && /^\?>/.test(textAfter))) - return htmlMode.indent(state.html, textAfter); - return state.curMode.indent(state.curState, textAfter); - }, - - electricChars: "/{}:", - blockCommentStart: "/*", - blockCommentEnd: "*/", - lineComment: "//", - - innerMode: function(state) { return {state: state.curState, mode: state.curMode}; } - }; - }, "htmlmixed", "clike"); - - CodeMirror.defineMIME("application/x-httpd-php", "php"); - CodeMirror.defineMIME("application/x-httpd-php-open", {name: "php", startOpen: true}); - CodeMirror.defineMIME("text/x-php", phpConfig); -})(); +(function() { + function keywords(str) { + var obj = {}, words = str.split(" "); + for (var i = 0; i < words.length; ++i) obj[words[i]] = true; + return obj; + } + function heredoc(delim) { + return function(stream, state) { + if (stream.match(delim)) state.tokenize = null; + else stream.skipToEnd(); + return "string"; + }; + } + var phpConfig = { + name: "clike", + keywords: keywords("abstract and array as break case catch class clone const continue declare default " + + "do else elseif enddeclare endfor endforeach endif endswitch endwhile extends final " + + "for foreach function global goto if implements interface instanceof namespace " + + "new or private protected public static switch throw trait try use var while xor " + + "die echo empty exit eval include include_once isset list require require_once return " + + "print unset __halt_compiler self static parent"), + blockKeywords: keywords("catch do else elseif for foreach if switch try while"), + atoms: keywords("true false null TRUE FALSE NULL __CLASS__ __DIR__ __FILE__ __LINE__ __METHOD__ __FUNCTION__ __NAMESPACE__"), + builtin: keywords("func_num_args func_get_arg func_get_args strlen strcmp strncmp strcasecmp strncasecmp each error_reporting define defined trigger_error user_error set_error_handler restore_error_handler get_declared_classes get_loaded_extensions extension_loaded get_extension_funcs debug_backtrace constant bin2hex sleep usleep time mktime gmmktime strftime gmstrftime strtotime date gmdate getdate localtime checkdate flush wordwrap htmlspecialchars htmlentities html_entity_decode md5 md5_file crc32 getimagesize image_type_to_mime_type phpinfo phpversion phpcredits strnatcmp strnatcasecmp substr_count strspn strcspn strtok strtoupper strtolower strpos strrpos strrev hebrev hebrevc nl2br basename dirname pathinfo stripslashes stripcslashes strstr stristr strrchr str_shuffle str_word_count strcoll substr substr_replace quotemeta ucfirst ucwords strtr addslashes addcslashes rtrim str_replace str_repeat count_chars chunk_split trim ltrim strip_tags similar_text explode implode setlocale localeconv parse_str str_pad chop strchr sprintf printf vprintf vsprintf sscanf fscanf parse_url urlencode urldecode rawurlencode rawurldecode readlink linkinfo link unlink exec system escapeshellcmd escapeshellarg passthru shell_exec proc_open proc_close rand srand getrandmax mt_rand mt_srand mt_getrandmax base64_decode base64_encode abs ceil floor round is_finite is_nan is_infinite bindec hexdec octdec decbin decoct dechex base_convert number_format fmod ip2long long2ip getenv putenv getopt microtime gettimeofday getrusage uniqid quoted_printable_decode set_time_limit get_cfg_var magic_quotes_runtime set_magic_quotes_runtime get_magic_quotes_gpc get_magic_quotes_runtime import_request_variables error_log serialize unserialize memory_get_usage var_dump var_export debug_zval_dump print_r highlight_file show_source highlight_string ini_get ini_get_all ini_set ini_alter ini_restore get_include_path set_include_path restore_include_path setcookie header headers_sent connection_aborted connection_status ignore_user_abort parse_ini_file is_uploaded_file move_uploaded_file intval floatval doubleval strval gettype settype is_null is_resource is_bool is_long is_float is_int is_integer is_double is_real is_numeric is_string is_array is_object is_scalar ereg ereg_replace eregi eregi_replace split spliti join sql_regcase dl pclose popen readfile rewind rmdir umask fclose feof fgetc fgets fgetss fread fopen fpassthru ftruncate fstat fseek ftell fflush fwrite fputs mkdir rename copy tempnam tmpfile file file_get_contents stream_select stream_context_create stream_context_set_params stream_context_set_option stream_context_get_options stream_filter_prepend stream_filter_append fgetcsv flock get_meta_tags stream_set_write_buffer set_file_buffer set_socket_blocking stream_set_blocking socket_set_blocking stream_get_meta_data stream_register_wrapper stream_wrapper_register stream_set_timeout socket_set_timeout socket_get_status realpath fnmatch fsockopen pfsockopen pack unpack get_browser crypt opendir closedir chdir getcwd rewinddir readdir dir glob fileatime filectime filegroup fileinode filemtime fileowner fileperms filesize filetype file_exists is_writable is_writeable is_readable is_executable is_file is_dir is_link stat lstat chown touch clearstatcache mail ob_start ob_flush ob_clean ob_end_flush ob_end_clean ob_get_flush ob_get_clean ob_get_length ob_get_level ob_get_status ob_get_contents ob_implicit_flush ob_list_handlers ksort krsort natsort natcasesort asort arsort sort rsort usort uasort uksort shuffle array_walk count end prev next reset current key min max in_array array_search extract compact array_fill range array_multisort array_push array_pop array_shift array_unshift array_splice array_slice array_merge array_merge_recursive array_keys array_values array_count_values array_reverse array_reduce array_pad array_flip array_change_key_case array_rand array_unique array_intersect array_intersect_assoc array_diff array_diff_assoc array_sum array_filter array_map array_chunk array_key_exists pos sizeof key_exists assert assert_options version_compare ftok str_rot13 aggregate session_name session_module_name session_save_path session_id session_regenerate_id session_decode session_register session_unregister session_is_registered session_encode session_start session_destroy session_unset session_set_save_handler session_cache_limiter session_cache_expire session_set_cookie_params session_get_cookie_params session_write_close preg_match preg_match_all preg_replace preg_replace_callback preg_split preg_quote preg_grep overload ctype_alnum ctype_alpha ctype_cntrl ctype_digit ctype_lower ctype_graph ctype_print ctype_punct ctype_space ctype_upper ctype_xdigit virtual apache_request_headers apache_note apache_lookup_uri apache_child_terminate apache_setenv apache_response_headers apache_get_version getallheaders mysql_connect mysql_pconnect mysql_close mysql_select_db mysql_create_db mysql_drop_db mysql_query mysql_unbuffered_query mysql_db_query mysql_list_dbs mysql_list_tables mysql_list_fields mysql_list_processes mysql_error mysql_errno mysql_affected_rows mysql_insert_id mysql_result mysql_num_rows mysql_num_fields mysql_fetch_row mysql_fetch_array mysql_fetch_assoc mysql_fetch_object mysql_data_seek mysql_fetch_lengths mysql_fetch_field mysql_field_seek mysql_free_result mysql_field_name mysql_field_table mysql_field_len mysql_field_type mysql_field_flags mysql_escape_string mysql_real_escape_string mysql_stat mysql_thread_id mysql_client_encoding mysql_get_client_info mysql_get_host_info mysql_get_proto_info mysql_get_server_info mysql_info mysql mysql_fieldname mysql_fieldtable mysql_fieldlen mysql_fieldtype mysql_fieldflags mysql_selectdb mysql_createdb mysql_dropdb mysql_freeresult mysql_numfields mysql_numrows mysql_listdbs mysql_listtables mysql_listfields mysql_db_name mysql_dbname mysql_tablename mysql_table_name pg_connect pg_pconnect pg_close pg_connection_status pg_connection_busy pg_connection_reset pg_host pg_dbname pg_port pg_tty pg_options pg_ping pg_query pg_send_query pg_cancel_query pg_fetch_result pg_fetch_row pg_fetch_assoc pg_fetch_array pg_fetch_object pg_fetch_all pg_affected_rows pg_get_result pg_result_seek pg_result_status pg_free_result pg_last_oid pg_num_rows pg_num_fields pg_field_name pg_field_num pg_field_size pg_field_type pg_field_prtlen pg_field_is_null pg_get_notify pg_get_pid pg_result_error pg_last_error pg_last_notice pg_put_line pg_end_copy pg_copy_to pg_copy_from pg_trace pg_untrace pg_lo_create pg_lo_unlink pg_lo_open pg_lo_close pg_lo_read pg_lo_write pg_lo_read_all pg_lo_import pg_lo_export pg_lo_seek pg_lo_tell pg_escape_string pg_escape_bytea pg_unescape_bytea pg_client_encoding pg_set_client_encoding pg_meta_data pg_convert pg_insert pg_update pg_delete pg_select pg_exec pg_getlastoid pg_cmdtuples pg_errormessage pg_numrows pg_numfields pg_fieldname pg_fieldsize pg_fieldtype pg_fieldnum pg_fieldprtlen pg_fieldisnull pg_freeresult pg_result pg_loreadall pg_locreate pg_lounlink pg_loopen pg_loclose pg_loread pg_lowrite pg_loimport pg_loexport echo print global static exit array empty eval isset unset die include require include_once require_once"), + multiLineStrings: true, + hooks: { + "$": function(stream) { + stream.eatWhile(/[\w\$_]/); + return "variable-2"; + }, + "<": function(stream, state) { + if (stream.match(/<", false)) stream.next(); + return "comment"; + }, + "/": function(stream) { + if (stream.eat("/")) { + while (!stream.eol() && !stream.match("?>", false)) stream.next(); + return "comment"; + } + return false; + } + } + }; + + CodeMirror.defineMode("php", function(config, parserConfig) { + var htmlMode = CodeMirror.getMode(config, "text/html"); + var phpMode = CodeMirror.getMode(config, phpConfig); + + function dispatch(stream, state) { + var isPHP = state.curMode == phpMode; + if (stream.sol() && state.pending != '"') state.pending = null; + if (!isPHP) { + if (stream.match(/^<\?\w*/)) { + state.curMode = phpMode; + state.curState = state.php; + return "meta"; + } + if (state.pending == '"') { + while (!stream.eol() && stream.next() != '"') {} + var style = "string"; + } else if (state.pending && stream.pos < state.pending.end) { + stream.pos = state.pending.end; + var style = state.pending.style; + } else { + var style = htmlMode.token(stream, state.curState); + } + state.pending = null; + var cur = stream.current(), openPHP = cur.search(/<\?/); + if (openPHP != -1) { + if (style == "string" && /\"$/.test(cur) && !/\?>/.test(cur)) state.pending = '"'; + else state.pending = {end: stream.pos, style: style}; + stream.backUp(cur.length - openPHP); + } + return style; + } else if (isPHP && state.php.tokenize == null && stream.match("?>")) { + state.curMode = htmlMode; + state.curState = state.html; + return "meta"; + } else { + return phpMode.token(stream, state.curState); + } + } + + return { + startState: function() { + var html = CodeMirror.startState(htmlMode), php = CodeMirror.startState(phpMode); + return {html: html, + php: php, + curMode: parserConfig.startOpen ? phpMode : htmlMode, + curState: parserConfig.startOpen ? php : html, + pending: null}; + }, + + copyState: function(state) { + var html = state.html, htmlNew = CodeMirror.copyState(htmlMode, html), + php = state.php, phpNew = CodeMirror.copyState(phpMode, php), cur; + if (state.curMode == htmlMode) cur = htmlNew; + else cur = phpNew; + return {html: htmlNew, php: phpNew, curMode: state.curMode, curState: cur, + pending: state.pending}; + }, + + token: dispatch, + + indent: function(state, textAfter) { + if ((state.curMode != phpMode && /^\s*<\//.test(textAfter)) || + (state.curMode == phpMode && /^\?>/.test(textAfter))) + return htmlMode.indent(state.html, textAfter); + return state.curMode.indent(state.curState, textAfter); + }, + + electricChars: "/{}:", + blockCommentStart: "/*", + blockCommentEnd: "*/", + lineComment: "//", + + innerMode: function(state) { return {state: state.curState, mode: state.curMode}; } + }; + }, "htmlmixed", "clike"); + + CodeMirror.defineMIME("application/x-httpd-php", "php"); + CodeMirror.defineMIME("application/x-httpd-php-open", {name: "php", startOpen: true}); + CodeMirror.defineMIME("text/x-php", phpConfig); +})(); diff --git a/profile-builder/assets/lib/codemirror/mode/xml/index.html b/profile-builder/assets/lib/codemirror/mode/xml/index.html index 873099a..8be9edb 100644 --- a/profile-builder/assets/lib/codemirror/mode/xml/index.html +++ b/profile-builder/assets/lib/codemirror/mode/xml/index.html @@ -1,57 +1,57 @@ - - -CodeMirror: XML mode - - - - - - - - - -
            -

            XML mode

            -
            - -

            The XML mode supports two configuration parameters:

            -
            -
            htmlMode (boolean)
            -
            This switches the mode to parse HTML instead of XML. This - means attributes do not have to be quoted, and some elements - (such as br) do not require a closing tag.
            -
            alignCDATA (boolean)
            -
            Setting this to true will force the opening tag of CDATA - blocks to not be indented.
            -
            - -

            MIME types defined: application/xml, text/html.

            -
            + + +CodeMirror: XML mode + + + + + + + + + +
            +

            XML mode

            +
            + +

            The XML mode supports two configuration parameters:

            +
            +
            htmlMode (boolean)
            +
            This switches the mode to parse HTML instead of XML. This + means attributes do not have to be quoted, and some elements + (such as br) do not require a closing tag.
            +
            alignCDATA (boolean)
            +
            Setting this to true will force the opening tag of CDATA + blocks to not be indented.
            +
            + +

            MIME types defined: application/xml, text/html.

            +
            diff --git a/profile-builder/assets/lib/codemirror/mode/xml/xml.js b/profile-builder/assets/lib/codemirror/mode/xml/xml.js index 53285c8..80137c2 100644 --- a/profile-builder/assets/lib/codemirror/mode/xml/xml.js +++ b/profile-builder/assets/lib/codemirror/mode/xml/xml.js @@ -1,341 +1,341 @@ -CodeMirror.defineMode("xml", function(config, parserConfig) { - var indentUnit = config.indentUnit; - var multilineTagIndentFactor = parserConfig.multilineTagIndentFactor || 1; - var multilineTagIndentPastTag = parserConfig.multilineTagIndentPastTag || true; - - var Kludges = parserConfig.htmlMode ? { - autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true, - 'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true, - 'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true, - 'track': true, 'wbr': true}, - implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true, 'p': true, - 'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot': true, - 'th': true, 'tr': true}, - contextGrabbers: { - 'dd': {'dd': true, 'dt': true}, - 'dt': {'dd': true, 'dt': true}, - 'li': {'li': true}, - 'option': {'option': true, 'optgroup': true}, - 'optgroup': {'optgroup': true}, - 'p': {'address': true, 'article': true, 'aside': true, 'blockquote': true, 'dir': true, - 'div': true, 'dl': true, 'fieldset': true, 'footer': true, 'form': true, - 'h1': true, 'h2': true, 'h3': true, 'h4': true, 'h5': true, 'h6': true, - 'header': true, 'hgroup': true, 'hr': true, 'menu': true, 'nav': true, 'ol': true, - 'p': true, 'pre': true, 'section': true, 'table': true, 'ul': true}, - 'rp': {'rp': true, 'rt': true}, - 'rt': {'rp': true, 'rt': true}, - 'tbody': {'tbody': true, 'tfoot': true}, - 'td': {'td': true, 'th': true}, - 'tfoot': {'tbody': true}, - 'th': {'td': true, 'th': true}, - 'thead': {'tbody': true, 'tfoot': true}, - 'tr': {'tr': true} - }, - doNotIndent: {"pre": true}, - allowUnquoted: true, - allowMissing: true - } : { - autoSelfClosers: {}, - implicitlyClosed: {}, - contextGrabbers: {}, - doNotIndent: {}, - allowUnquoted: false, - allowMissing: false - }; - var alignCDATA = parserConfig.alignCDATA; - - // Return variables for tokenizers - var tagName, type; - - function inText(stream, state) { - function chain(parser) { - state.tokenize = parser; - return parser(stream, state); - } - - var ch = stream.next(); - if (ch == "<") { - if (stream.eat("!")) { - if (stream.eat("[")) { - if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>")); - else return null; - } else if (stream.match("--")) { - return chain(inBlock("comment", "-->")); - } else if (stream.match("DOCTYPE", true, true)) { - stream.eatWhile(/[\w\._\-]/); - return chain(doctype(1)); - } else { - return null; - } - } else if (stream.eat("?")) { - stream.eatWhile(/[\w\._\-]/); - state.tokenize = inBlock("meta", "?>"); - return "meta"; - } else { - var isClose = stream.eat("/"); - tagName = ""; - var c; - while ((c = stream.eat(/[^\s\u00a0=<>\"\'\/?]/))) tagName += c; - if (!tagName) return "error"; - type = isClose ? "closeTag" : "openTag"; - state.tokenize = inTag; - return "tag"; - } - } else if (ch == "&") { - var ok; - if (stream.eat("#")) { - if (stream.eat("x")) { - ok = stream.eatWhile(/[a-fA-F\d]/) && stream.eat(";"); - } else { - ok = stream.eatWhile(/[\d]/) && stream.eat(";"); - } - } else { - ok = stream.eatWhile(/[\w\.\-:]/) && stream.eat(";"); - } - return ok ? "atom" : "error"; - } else { - stream.eatWhile(/[^&<]/); - return null; - } - } - - function inTag(stream, state) { - var ch = stream.next(); - if (ch == ">" || (ch == "/" && stream.eat(">"))) { - state.tokenize = inText; - type = ch == ">" ? "endTag" : "selfcloseTag"; - return "tag"; - } else if (ch == "=") { - type = "equals"; - return null; - } else if (ch == "<") { - return "error"; - } else if (/[\'\"]/.test(ch)) { - state.tokenize = inAttribute(ch); - state.stringStartCol = stream.column(); - return state.tokenize(stream, state); - } else { - stream.eatWhile(/[^\s\u00a0=<>\"\']/); - return "word"; - } - } - - function inAttribute(quote) { - var closure = function(stream, state) { - while (!stream.eol()) { - if (stream.next() == quote) { - state.tokenize = inTag; - break; - } - } - return "string"; - }; - closure.isInAttribute = true; - return closure; - } - - function inBlock(style, terminator) { - return function(stream, state) { - while (!stream.eol()) { - if (stream.match(terminator)) { - state.tokenize = inText; - break; - } - stream.next(); - } - return style; - }; - } - function doctype(depth) { - return function(stream, state) { - var ch; - while ((ch = stream.next()) != null) { - if (ch == "<") { - state.tokenize = doctype(depth + 1); - return state.tokenize(stream, state); - } else if (ch == ">") { - if (depth == 1) { - state.tokenize = inText; - break; - } else { - state.tokenize = doctype(depth - 1); - return state.tokenize(stream, state); - } - } - } - return "meta"; - }; - } - - var curState, curStream, setStyle; - function pass() { - for (var i = arguments.length - 1; i >= 0; i--) curState.cc.push(arguments[i]); - } - function cont() { - pass.apply(null, arguments); - return true; - } - - function pushContext(tagName, startOfLine) { - var noIndent = Kludges.doNotIndent.hasOwnProperty(tagName) || (curState.context && curState.context.noIndent); - curState.context = { - prev: curState.context, - tagName: tagName, - indent: curState.indented, - startOfLine: startOfLine, - noIndent: noIndent - }; - } - function popContext() { - if (curState.context) curState.context = curState.context.prev; - } - - function element(type) { - if (type == "openTag") { - curState.tagName = tagName; - curState.tagStart = curStream.column(); - return cont(attributes, endtag(curState.startOfLine)); - } else if (type == "closeTag") { - var err = false; - if (curState.context) { - if (curState.context.tagName != tagName) { - if (Kludges.implicitlyClosed.hasOwnProperty(curState.context.tagName.toLowerCase())) { - popContext(); - } - err = !curState.context || curState.context.tagName != tagName; - } - } else { - err = true; - } - if (err) setStyle = "error"; - return cont(endclosetag(err)); - } - return cont(); - } - function endtag(startOfLine) { - return function(type) { - var tagName = curState.tagName; - curState.tagName = curState.tagStart = null; - if (type == "selfcloseTag" || - (type == "endTag" && Kludges.autoSelfClosers.hasOwnProperty(tagName.toLowerCase()))) { - maybePopContext(tagName.toLowerCase()); - return cont(); - } - if (type == "endTag") { - maybePopContext(tagName.toLowerCase()); - pushContext(tagName, startOfLine); - return cont(); - } - return cont(); - }; - } - function endclosetag(err) { - return function(type) { - if (err) setStyle = "error"; - if (type == "endTag") { popContext(); return cont(); } - setStyle = "error"; - return cont(arguments.callee); - }; - } - function maybePopContext(nextTagName) { - var parentTagName; - while (true) { - if (!curState.context) { - return; - } - parentTagName = curState.context.tagName.toLowerCase(); - if (!Kludges.contextGrabbers.hasOwnProperty(parentTagName) || - !Kludges.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) { - return; - } - popContext(); - } - } - - function attributes(type) { - if (type == "word") {setStyle = "attribute"; return cont(attribute, attributes);} - if (type == "endTag" || type == "selfcloseTag") return pass(); - setStyle = "error"; - return cont(attributes); - } - function attribute(type) { - if (type == "equals") return cont(attvalue, attributes); - if (!Kludges.allowMissing) setStyle = "error"; - else if (type == "word") {setStyle = "attribute"; return cont(attribute, attributes);} - return (type == "endTag" || type == "selfcloseTag") ? pass() : cont(); - } - function attvalue(type) { - if (type == "string") return cont(attvaluemaybe); - if (type == "word" && Kludges.allowUnquoted) {setStyle = "string"; return cont();} - setStyle = "error"; - return (type == "endTag" || type == "selfCloseTag") ? pass() : cont(); - } - function attvaluemaybe(type) { - if (type == "string") return cont(attvaluemaybe); - else return pass(); - } - - return { - startState: function() { - return {tokenize: inText, cc: [], indented: 0, startOfLine: true, tagName: null, tagStart: null, context: null}; - }, - - token: function(stream, state) { - if (!state.tagName && stream.sol()) { - state.startOfLine = true; - state.indented = stream.indentation(); - } - if (stream.eatSpace()) return null; - - setStyle = type = tagName = null; - var style = state.tokenize(stream, state); - state.type = type; - if ((style || type) && style != "comment") { - curState = state; curStream = stream; - while (true) { - var comb = state.cc.pop() || element; - if (comb(type || style)) break; - } - } - state.startOfLine = false; - return setStyle || style; - }, - - indent: function(state, textAfter, fullLine) { - var context = state.context; - // Indent multi-line strings (e.g. css). - if (state.tokenize.isInAttribute) { - return state.stringStartCol + 1; - } - if ((state.tokenize != inTag && state.tokenize != inText) || - context && context.noIndent) - return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0; - // Indent the starts of attribute names. - if (state.tagName) { - if (multilineTagIndentPastTag) - return state.tagStart + state.tagName.length + 2; - else - return state.tagStart + indentUnit * multilineTagIndentFactor; - } - if (alignCDATA && /", - - configuration: parserConfig.htmlMode ? "html" : "xml", - helperType: parserConfig.htmlMode ? "html" : "xml" - }; -}); - -CodeMirror.defineMIME("text/xml", "xml"); -CodeMirror.defineMIME("application/xml", "xml"); -if (!CodeMirror.mimeModes.hasOwnProperty("text/html")) - CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true}); +CodeMirror.defineMode("xml", function(config, parserConfig) { + var indentUnit = config.indentUnit; + var multilineTagIndentFactor = parserConfig.multilineTagIndentFactor || 1; + var multilineTagIndentPastTag = parserConfig.multilineTagIndentPastTag || true; + + var Kludges = parserConfig.htmlMode ? { + autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true, + 'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true, + 'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true, + 'track': true, 'wbr': true}, + implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true, 'p': true, + 'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot': true, + 'th': true, 'tr': true}, + contextGrabbers: { + 'dd': {'dd': true, 'dt': true}, + 'dt': {'dd': true, 'dt': true}, + 'li': {'li': true}, + 'option': {'option': true, 'optgroup': true}, + 'optgroup': {'optgroup': true}, + 'p': {'address': true, 'article': true, 'aside': true, 'blockquote': true, 'dir': true, + 'div': true, 'dl': true, 'fieldset': true, 'footer': true, 'form': true, + 'h1': true, 'h2': true, 'h3': true, 'h4': true, 'h5': true, 'h6': true, + 'header': true, 'hgroup': true, 'hr': true, 'menu': true, 'nav': true, 'ol': true, + 'p': true, 'pre': true, 'section': true, 'table': true, 'ul': true}, + 'rp': {'rp': true, 'rt': true}, + 'rt': {'rp': true, 'rt': true}, + 'tbody': {'tbody': true, 'tfoot': true}, + 'td': {'td': true, 'th': true}, + 'tfoot': {'tbody': true}, + 'th': {'td': true, 'th': true}, + 'thead': {'tbody': true, 'tfoot': true}, + 'tr': {'tr': true} + }, + doNotIndent: {"pre": true}, + allowUnquoted: true, + allowMissing: true + } : { + autoSelfClosers: {}, + implicitlyClosed: {}, + contextGrabbers: {}, + doNotIndent: {}, + allowUnquoted: false, + allowMissing: false + }; + var alignCDATA = parserConfig.alignCDATA; + + // Return variables for tokenizers + var tagName, type; + + function inText(stream, state) { + function chain(parser) { + state.tokenize = parser; + return parser(stream, state); + } + + var ch = stream.next(); + if (ch == "<") { + if (stream.eat("!")) { + if (stream.eat("[")) { + if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>")); + else return null; + } else if (stream.match("--")) { + return chain(inBlock("comment", "-->")); + } else if (stream.match("DOCTYPE", true, true)) { + stream.eatWhile(/[\w\._\-]/); + return chain(doctype(1)); + } else { + return null; + } + } else if (stream.eat("?")) { + stream.eatWhile(/[\w\._\-]/); + state.tokenize = inBlock("meta", "?>"); + return "meta"; + } else { + var isClose = stream.eat("/"); + tagName = ""; + var c; + while ((c = stream.eat(/[^\s\u00a0=<>\"\'\/?]/))) tagName += c; + if (!tagName) return "error"; + type = isClose ? "closeTag" : "openTag"; + state.tokenize = inTag; + return "tag"; + } + } else if (ch == "&") { + var ok; + if (stream.eat("#")) { + if (stream.eat("x")) { + ok = stream.eatWhile(/[a-fA-F\d]/) && stream.eat(";"); + } else { + ok = stream.eatWhile(/[\d]/) && stream.eat(";"); + } + } else { + ok = stream.eatWhile(/[\w\.\-:]/) && stream.eat(";"); + } + return ok ? "atom" : "error"; + } else { + stream.eatWhile(/[^&<]/); + return null; + } + } + + function inTag(stream, state) { + var ch = stream.next(); + if (ch == ">" || (ch == "/" && stream.eat(">"))) { + state.tokenize = inText; + type = ch == ">" ? "endTag" : "selfcloseTag"; + return "tag"; + } else if (ch == "=") { + type = "equals"; + return null; + } else if (ch == "<") { + return "error"; + } else if (/[\'\"]/.test(ch)) { + state.tokenize = inAttribute(ch); + state.stringStartCol = stream.column(); + return state.tokenize(stream, state); + } else { + stream.eatWhile(/[^\s\u00a0=<>\"\']/); + return "word"; + } + } + + function inAttribute(quote) { + var closure = function(stream, state) { + while (!stream.eol()) { + if (stream.next() == quote) { + state.tokenize = inTag; + break; + } + } + return "string"; + }; + closure.isInAttribute = true; + return closure; + } + + function inBlock(style, terminator) { + return function(stream, state) { + while (!stream.eol()) { + if (stream.match(terminator)) { + state.tokenize = inText; + break; + } + stream.next(); + } + return style; + }; + } + function doctype(depth) { + return function(stream, state) { + var ch; + while ((ch = stream.next()) != null) { + if (ch == "<") { + state.tokenize = doctype(depth + 1); + return state.tokenize(stream, state); + } else if (ch == ">") { + if (depth == 1) { + state.tokenize = inText; + break; + } else { + state.tokenize = doctype(depth - 1); + return state.tokenize(stream, state); + } + } + } + return "meta"; + }; + } + + var curState, curStream, setStyle; + function pass() { + for (var i = arguments.length - 1; i >= 0; i--) curState.cc.push(arguments[i]); + } + function cont() { + pass.apply(null, arguments); + return true; + } + + function pushContext(tagName, startOfLine) { + var noIndent = Kludges.doNotIndent.hasOwnProperty(tagName) || (curState.context && curState.context.noIndent); + curState.context = { + prev: curState.context, + tagName: tagName, + indent: curState.indented, + startOfLine: startOfLine, + noIndent: noIndent + }; + } + function popContext() { + if (curState.context) curState.context = curState.context.prev; + } + + function element(type) { + if (type == "openTag") { + curState.tagName = tagName; + curState.tagStart = curStream.column(); + return cont(attributes, endtag(curState.startOfLine)); + } else if (type == "closeTag") { + var err = false; + if (curState.context) { + if (curState.context.tagName != tagName) { + if (Kludges.implicitlyClosed.hasOwnProperty(curState.context.tagName.toLowerCase())) { + popContext(); + } + err = !curState.context || curState.context.tagName != tagName; + } + } else { + err = true; + } + if (err) setStyle = "error"; + return cont(endclosetag(err)); + } + return cont(); + } + function endtag(startOfLine) { + return function(type) { + var tagName = curState.tagName; + curState.tagName = curState.tagStart = null; + if (type == "selfcloseTag" || + (type == "endTag" && Kludges.autoSelfClosers.hasOwnProperty(tagName.toLowerCase()))) { + maybePopContext(tagName.toLowerCase()); + return cont(); + } + if (type == "endTag") { + maybePopContext(tagName.toLowerCase()); + pushContext(tagName, startOfLine); + return cont(); + } + return cont(); + }; + } + function endclosetag(err) { + return function(type) { + if (err) setStyle = "error"; + if (type == "endTag") { popContext(); return cont(); } + setStyle = "error"; + return cont(arguments.callee); + }; + } + function maybePopContext(nextTagName) { + var parentTagName; + while (true) { + if (!curState.context) { + return; + } + parentTagName = curState.context.tagName.toLowerCase(); + if (!Kludges.contextGrabbers.hasOwnProperty(parentTagName) || + !Kludges.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) { + return; + } + popContext(); + } + } + + function attributes(type) { + if (type == "word") {setStyle = "attribute"; return cont(attribute, attributes);} + if (type == "endTag" || type == "selfcloseTag") return pass(); + setStyle = "error"; + return cont(attributes); + } + function attribute(type) { + if (type == "equals") return cont(attvalue, attributes); + if (!Kludges.allowMissing) setStyle = "error"; + else if (type == "word") {setStyle = "attribute"; return cont(attribute, attributes);} + return (type == "endTag" || type == "selfcloseTag") ? pass() : cont(); + } + function attvalue(type) { + if (type == "string") return cont(attvaluemaybe); + if (type == "word" && Kludges.allowUnquoted) {setStyle = "string"; return cont();} + setStyle = "error"; + return (type == "endTag" || type == "selfCloseTag") ? pass() : cont(); + } + function attvaluemaybe(type) { + if (type == "string") return cont(attvaluemaybe); + else return pass(); + } + + return { + startState: function() { + return {tokenize: inText, cc: [], indented: 0, startOfLine: true, tagName: null, tagStart: null, context: null}; + }, + + token: function(stream, state) { + if (!state.tagName && stream.sol()) { + state.startOfLine = true; + state.indented = stream.indentation(); + } + if (stream.eatSpace()) return null; + + setStyle = type = tagName = null; + var style = state.tokenize(stream, state); + state.type = type; + if ((style || type) && style != "comment") { + curState = state; curStream = stream; + while (true) { + var comb = state.cc.pop() || element; + if (comb(type || style)) break; + } + } + state.startOfLine = false; + return setStyle || style; + }, + + indent: function(state, textAfter, fullLine) { + var context = state.context; + // Indent multi-line strings (e.g. css). + if (state.tokenize.isInAttribute) { + return state.stringStartCol + 1; + } + if ((state.tokenize != inTag && state.tokenize != inText) || + context && context.noIndent) + return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0; + // Indent the starts of attribute names. + if (state.tagName) { + if (multilineTagIndentPastTag) + return state.tagStart + state.tagName.length + 2; + else + return state.tagStart + indentUnit * multilineTagIndentFactor; + } + if (alignCDATA && /", + + configuration: parserConfig.htmlMode ? "html" : "xml", + helperType: parserConfig.htmlMode ? "html" : "xml" + }; +}); + +CodeMirror.defineMIME("text/xml", "xml"); +CodeMirror.defineMIME("application/xml", "xml"); +if (!CodeMirror.mimeModes.hasOwnProperty("text/html")) + CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true}); diff --git a/profile-builder/assets/lib/wck-api/assets/country/country-select.php b/profile-builder/assets/lib/wck-api/assets/country/country-select.php index 17ea83c..3649a80 100644 --- a/profile-builder/assets/lib/wck-api/assets/country/country-select.php +++ b/profile-builder/assets/lib/wck-api/assets/country/country-select.php @@ -1,201 +1,201 @@ - \ No newline at end of file diff --git a/profile-builder/assets/lib/wck-api/assets/datepicker/datepicker.css b/profile-builder/assets/lib/wck-api/assets/datepicker/datepicker.css index f94aae7..b270398 100644 --- a/profile-builder/assets/lib/wck-api/assets/datepicker/datepicker.css +++ b/profile-builder/assets/lib/wck-api/assets/datepicker/datepicker.css @@ -1,649 +1,649 @@ -/*! jQuery UI - v1.10.3 - 2013-09-23 -* http://jqueryui.com -* Includes: jquery.ui.core.css, jquery.ui.datepicker.css, jquery.ui.theme.css -* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana%2CArial%2Csans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=highlight_soft&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=flat&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=glass&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=glass&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=glass&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=glass&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px -* Copyright 2013 jQuery Foundation and other contributors; Licensed MIT */ - -/* Layout helpers -----------------------------------*/ -.ui-helper-hidden { - display: none; -} -.ui-helper-hidden-accessible { - border: 0; - clip: rect(0 0 0 0); - height: 1px; - margin: -1px; - overflow: hidden; - padding: 0; - position: absolute; - width: 1px; -} -.ui-helper-reset { - margin: 0; - padding: 0; - border: 0; - outline: 0; - line-height: 1.3; - text-decoration: none; - font-size: 100%; - list-style: none; -} -.ui-helper-clearfix:before, -.ui-helper-clearfix:after { - content: ""; - display: table; - border-collapse: collapse; -} -.ui-helper-clearfix:after { - clear: both; -} -.ui-helper-clearfix { - min-height: 0; /* support: IE7 */ -} -.ui-helper-zfix { - width: 100%; - height: 100%; - top: 0; - left: 0; - position: absolute; - opacity: 0; - filter:Alpha(Opacity=0); -} - -.ui-front { - z-index: 100; -} - - -/* Interaction Cues -----------------------------------*/ -.ui-state-disabled { - cursor: default !important; -} - - -/* Icons -----------------------------------*/ - -/* states and images */ -.ui-icon { - display: block; - text-indent: -99999px; - overflow: hidden; - background-repeat: no-repeat; -} - - -/* Misc visuals -----------------------------------*/ - -/* Overlays */ -.ui-widget-overlay { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; -} -.ui-datepicker { - width: 17em; - padding: .2em .2em 0; - display: none; -} -.ui-datepicker .ui-datepicker-header { - position: relative; - padding: .2em 0; -} -.ui-datepicker .ui-datepicker-prev, -.ui-datepicker .ui-datepicker-next { - position: absolute; - top: 2px; - width: 1.8em; - height: 1.8em; -} -.ui-datepicker .ui-datepicker-prev-hover, -.ui-datepicker .ui-datepicker-next-hover { - top: 1px; -} -.ui-datepicker .ui-datepicker-prev { - left: 2px; -} -.ui-datepicker .ui-datepicker-next { - right: 2px; -} -.ui-datepicker .ui-datepicker-prev-hover { - left: 1px; -} -.ui-datepicker .ui-datepicker-next-hover { - right: 1px; -} -.ui-datepicker .ui-datepicker-prev span, -.ui-datepicker .ui-datepicker-next span { - display: block; - position: absolute; - left: 50%; - margin-left: -8px; - top: 50%; - margin-top: -8px; -} -.ui-datepicker .ui-datepicker-title { - margin: 0 2.3em; - line-height: 1.8em; - text-align: center; -} -.ui-datepicker .ui-datepicker-title select { - font-size: 1em; - margin: 1px 0; -} -.ui-datepicker select.ui-datepicker-month-year { - width: 100%; -} -.ui-datepicker select.ui-datepicker-month, -.ui-datepicker select.ui-datepicker-year { - width: 49%; -} -.ui-datepicker table { - width: 100%; - font-size: .9em; - border-collapse: collapse; - margin: 0 0 .4em; -} -.ui-datepicker th { - padding: .7em .3em; - text-align: center; - font-weight: bold; - border: 0; -} -.ui-datepicker td { - border: 0; - padding: 1px; -} -.ui-datepicker td span, -.ui-datepicker td a { - display: block; - padding: .2em; - text-align: right; - text-decoration: none; -} -.ui-datepicker .ui-datepicker-buttonpane { - background-image: none; - margin: .7em 0 0 0; - padding: 0 .2em; - border-left: 0; - border-right: 0; - border-bottom: 0; -} -.ui-datepicker .ui-datepicker-buttonpane button { - float: right; - margin: .5em .2em .4em; - cursor: pointer; - padding: .2em .6em .3em .6em; - width: auto; - overflow: visible; -} -.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { - float: left; -} - -/* with multiple calendars */ -.ui-datepicker.ui-datepicker-multi { - width: auto; -} -.ui-datepicker-multi .ui-datepicker-group { - float: left; -} -.ui-datepicker-multi .ui-datepicker-group table { - width: 95%; - margin: 0 auto .4em; -} -.ui-datepicker-multi-2 .ui-datepicker-group { - width: 50%; -} -.ui-datepicker-multi-3 .ui-datepicker-group { - width: 33.3%; -} -.ui-datepicker-multi-4 .ui-datepicker-group { - width: 25%; -} -.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header, -.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { - border-left-width: 0; -} -.ui-datepicker-multi .ui-datepicker-buttonpane { - clear: left; -} -.ui-datepicker-row-break { - clear: both; - width: 100%; - font-size: 0; -} - -/* RTL support */ -.ui-datepicker-rtl { - direction: rtl; -} -.ui-datepicker-rtl .ui-datepicker-prev { - right: 2px; - left: auto; -} -.ui-datepicker-rtl .ui-datepicker-next { - left: 2px; - right: auto; -} -.ui-datepicker-rtl .ui-datepicker-prev:hover { - right: 1px; - left: auto; -} -.ui-datepicker-rtl .ui-datepicker-next:hover { - left: 1px; - right: auto; -} -.ui-datepicker-rtl .ui-datepicker-buttonpane { - clear: right; -} -.ui-datepicker-rtl .ui-datepicker-buttonpane button { - float: left; -} -.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current, -.ui-datepicker-rtl .ui-datepicker-group { - float: right; -} -.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header, -.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { - border-right-width: 0; - border-left-width: 1px; -} - -/* Component containers -----------------------------------*/ -#ui-datepicker-div.ui-widget { - font-family: Verdana,Arial,sans-serif; - font-size: 1.1em; -} -#ui-datepicker-div.ui-widget .ui-widget { - font-size: 1em; -} -#ui-datepicker-div.ui-widget input, -#ui-datepicker-div.ui-widget select, -#ui-datepicker-div.ui-widget textarea, -#ui-datepicker-div.ui-widget button { - font-family: Verdana,Arial,sans-serif; - font-size: 1em; -} -#ui-datepicker-div.ui-widget-content { - border: 1px solid #aaaaaa; - background: #ffffff url(images/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x; - color: #222222; -} -#ui-datepicker-div.ui-widget-content a { - color: #222222; -} -#ui-datepicker-div .ui-widget-header { - border: 1px solid #aaaaaa; - background: #cccccc url(images/ui-bg_highlight-soft_75_cccccc_1x100.png) 50% 50% repeat-x; - color: #222222; - font-weight: bold; -} -#ui-datepicker-div .ui-widget-header a { - color: #222222; -} - -/* Interaction states -----------------------------------*/ -#ui-datepicker-div .ui-state-default, -#ui-datepicker-div.ui-widget-content .ui-state-default, -#ui-datepicker-div .ui-widget-header .ui-state-default { - border: 1px solid #d3d3d3; - background: #e6e6e6 url(images/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% repeat-x; - font-weight: normal; - color: #555555; -} -#ui-datepicker-div .ui-state-default a, -#ui-datepicker-div .ui-state-default a:link, -#ui-datepicker-div .ui-state-default a:visited { - color: #555555; - text-decoration: none; -} -#ui-datepicker-div .ui-state-hover, -#ui-datepicker-div.ui-widget-content .ui-state-hover, -#ui-datepicker-div .ui-widget-header .ui-state-hover, -#ui-datepicker-div .ui-state-focus, -#ui-datepicker-div.ui-widget-content .ui-state-focus, -#ui-datepicker-div .ui-widget-header .ui-state-focus { - border: 1px solid #999999; - background: #dadada url(images/ui-bg_glass_75_dadada_1x400.png) 50% 50% repeat-x; - font-weight: normal; - color: #212121; -} -#ui-datepicker-div .ui-state-hover a, -#ui-datepicker-div .ui-state-hover a:hover, -#ui-datepicker-div .ui-state-hover a:link, -#ui-datepicker-div .ui-state-hover a:visited { - color: #212121; - text-decoration: none; -} -#ui-datepicker-div .ui-state-active, -#ui-datepicker-div.ui-widget-content .ui-state-active, -#ui-datepicker-div .ui-widget-header .ui-state-active { - border: 1px solid #aaaaaa; - background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; - font-weight: normal; - color: #212121; -} -#ui-datepicker-div .ui-state-active a, -#ui-datepicker-div .ui-state-active a:link, -#ui-datepicker-div .ui-state-active a:visited { - color: #212121; - text-decoration: none; -} - -/* Interaction Cues -----------------------------------*/ -#ui-datepicker-div .ui-state-highlight, -#ui-datepicker-div.ui-widget-content .ui-state-highlight, -#ui-datepicker-div .ui-widget-header .ui-state-highlight { - border: 1px solid #fcefa1; - background: #fbf9ee url(images/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x; - color: #363636; -} -#ui-datepicker-div .ui-state-highlight a, -#ui-datepicker-div.ui-widget-content .ui-state-highlight a, -#ui-datepicker-div .ui-widget-header .ui-state-highlight a { - color: #363636; -} -#ui-datepicker-div .ui-state-error, -#ui-datepicker-div.ui-widget-content .ui-state-error, -#ui-datepicker-div .ui-widget-header .ui-state-error { - border: 1px solid #cd0a0a; - background: #fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; - color: #cd0a0a; -} -#ui-datepicker-div .ui-state-error a, -#ui-datepicker-div.ui-widget-content .ui-state-error a, -#ui-datepicker-div .ui-widget-header .ui-state-error a { - color: #cd0a0a; -} -#ui-datepicker-div .ui-state-error-text, -#ui-datepicker-div.ui-widget-content .ui-state-error-text, -#ui-datepicker-div .ui-widget-header .ui-state-error-text { - color: #cd0a0a; -} -#ui-datepicker-div .ui-priority-primary, -#ui-datepicker-div.ui-widget-content .ui-priority-primary, -#ui-datepicker-div .ui-widget-header .ui-priority-primary { - font-weight: bold; -} -#ui-datepicker-div .ui-priority-secondary, -#ui-datepicker-div.ui-widget-content .ui-priority-secondary, -#ui-datepicker-div .ui-widget-header .ui-priority-secondary { - opacity: .7; - filter:Alpha(Opacity=70); - font-weight: normal; -} -#ui-datepicker-div .ui-state-disabled, -#ui-datepicker-div.ui-widget-content .ui-state-disabled, -#ui-datepicker-div .ui-widget-header .ui-state-disabled { - opacity: .35; - filter:Alpha(Opacity=35); - background-image: none; -} -#ui-datepicker-div .ui-state-disabled .ui-icon { - filter:Alpha(Opacity=35); /* For IE8 - See #6059 */ -} - -/* Icons -----------------------------------*/ - -/* states and images */ -#ui-datepicker-div .ui-icon { - width: 16px; - height: 16px; -} -#ui-datepicker-div .ui-icon, -#ui-datepicker-div.ui-widget-content .ui-icon { - background-image: url(images/ui-icons_222222_256x240.png); -} -#ui-datepicker-div .ui-widget-header .ui-icon { - background-image: url(images/ui-icons_222222_256x240.png); -} -#ui-datepicker-div .ui-state-default .ui-icon { - background-image: url(images/ui-icons_888888_256x240.png); -} -#ui-datepicker-div .ui-state-hover .ui-icon, -#ui-datepicker-div .ui-state-focus .ui-icon { - background-image: url(images/ui-icons_454545_256x240.png); -} -#ui-datepicker-div .ui-state-active .ui-icon { - background-image: url(images/ui-icons_454545_256x240.png); -} -#ui-datepicker-div .ui-state-highlight .ui-icon { - background-image: url(images/ui-icons_2e83ff_256x240.png); -} -#ui-datepicker-div .ui-state-error .ui-icon, -#ui-datepicker-div .ui-state-error-text .ui-icon { - background-image: url(images/ui-icons_cd0a0a_256x240.png); -} - -/* positioning */ -#ui-datepicker-div .ui-icon-blank { background-position: 16px 16px; } -#ui-datepicker-div .ui-icon-carat-1-n { background-position: 0 0; } -#ui-datepicker-div .ui-icon-carat-1-ne { background-position: -16px 0; } -#ui-datepicker-div .ui-icon-carat-1-e { background-position: -32px 0; } -#ui-datepicker-div .ui-icon-carat-1-se { background-position: -48px 0; } -#ui-datepicker-div .ui-icon-carat-1-s { background-position: -64px 0; } -#ui-datepicker-div .ui-icon-carat-1-sw { background-position: -80px 0; } -#ui-datepicker-div .ui-icon-carat-1-w { background-position: -96px 0; } -#ui-datepicker-div .ui-icon-carat-1-nw { background-position: -112px 0; } -#ui-datepicker-div .ui-icon-carat-2-n-s { background-position: -128px 0; } -#ui-datepicker-div .ui-icon-carat-2-e-w { background-position: -144px 0; } -#ui-datepicker-div .ui-icon-triangle-1-n { background-position: 0 -16px; } -#ui-datepicker-div .ui-icon-triangle-1-ne { background-position: -16px -16px; } -#ui-datepicker-div .ui-icon-triangle-1-e { background-position: -32px -16px; } -#ui-datepicker-div .ui-icon-triangle-1-se { background-position: -48px -16px; } -#ui-datepicker-div .ui-icon-triangle-1-s { background-position: -64px -16px; } -#ui-datepicker-div .ui-icon-triangle-1-sw { background-position: -80px -16px; } -#ui-datepicker-div .ui-icon-triangle-1-w { background-position: -96px -16px; } -#ui-datepicker-div .ui-icon-triangle-1-nw { background-position: -112px -16px; } -#ui-datepicker-div .ui-icon-triangle-2-n-s { background-position: -128px -16px; } -#ui-datepicker-div .ui-icon-triangle-2-e-w { background-position: -144px -16px; } -#ui-datepicker-div .ui-icon-arrow-1-n { background-position: 0 -32px; } -#ui-datepicker-div .ui-icon-arrow-1-ne { background-position: -16px -32px; } -#ui-datepicker-div .ui-icon-arrow-1-e { background-position: -32px -32px; } -#ui-datepicker-div .ui-icon-arrow-1-se { background-position: -48px -32px; } -#ui-datepicker-div .ui-icon-arrow-1-s { background-position: -64px -32px; } -#ui-datepicker-div .ui-icon-arrow-1-sw { background-position: -80px -32px; } -#ui-datepicker-div .ui-icon-arrow-1-w { background-position: -96px -32px; } -#ui-datepicker-div .ui-icon-arrow-1-nw { background-position: -112px -32px; } -#ui-datepicker-div .ui-icon-arrow-2-n-s { background-position: -128px -32px; } -#ui-datepicker-div .ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } -#ui-datepicker-div .ui-icon-arrow-2-e-w { background-position: -160px -32px; } -#ui-datepicker-div .ui-icon-arrow-2-se-nw { background-position: -176px -32px; } -#ui-datepicker-div .ui-icon-arrowstop-1-n { background-position: -192px -32px; } -#ui-datepicker-div .ui-icon-arrowstop-1-e { background-position: -208px -32px; } -#ui-datepicker-div .ui-icon-arrowstop-1-s { background-position: -224px -32px; } -#ui-datepicker-div .ui-icon-arrowstop-1-w { background-position: -240px -32px; } -#ui-datepicker-div .ui-icon-arrowthick-1-n { background-position: 0 -48px; } -#ui-datepicker-div .ui-icon-arrowthick-1-ne { background-position: -16px -48px; } -#ui-datepicker-div .ui-icon-arrowthick-1-e { background-position: -32px -48px; } -#ui-datepicker-div .ui-icon-arrowthick-1-se { background-position: -48px -48px; } -#ui-datepicker-div .ui-icon-arrowthick-1-s { background-position: -64px -48px; } -#ui-datepicker-div .ui-icon-arrowthick-1-sw { background-position: -80px -48px; } -#ui-datepicker-div .ui-icon-arrowthick-1-w { background-position: -96px -48px; } -#ui-datepicker-div .ui-icon-arrowthick-1-nw { background-position: -112px -48px; } -#ui-datepicker-div .ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } -#ui-datepicker-div .ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } -#ui-datepicker-div .ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } -#ui-datepicker-div .ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } -#ui-datepicker-div .ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } -#ui-datepicker-div .ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } -#ui-datepicker-div .ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } -#ui-datepicker-div .ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } -#ui-datepicker-div .ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } -#ui-datepicker-div .ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } -#ui-datepicker-div .ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } -#ui-datepicker-div .ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } -#ui-datepicker-div .ui-icon-arrowreturn-1-w { background-position: -64px -64px; } -#ui-datepicker-div .ui-icon-arrowreturn-1-n { background-position: -80px -64px; } -#ui-datepicker-div .ui-icon-arrowreturn-1-e { background-position: -96px -64px; } -#ui-datepicker-div .ui-icon-arrowreturn-1-s { background-position: -112px -64px; } -#ui-datepicker-div .ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } -#ui-datepicker-div .ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } -#ui-datepicker-div .ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } -#ui-datepicker-div .ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } -#ui-datepicker-div .ui-icon-arrow-4 { background-position: 0 -80px; } -#ui-datepicker-div .ui-icon-arrow-4-diag { background-position: -16px -80px; } -#ui-datepicker-div .ui-icon-extlink { background-position: -32px -80px; } -#ui-datepicker-div .ui-icon-newwin { background-position: -48px -80px; } -#ui-datepicker-div .ui-icon-refresh { background-position: -64px -80px; } -#ui-datepicker-div .ui-icon-shuffle { background-position: -80px -80px; } -#ui-datepicker-div .ui-icon-transfer-e-w { background-position: -96px -80px; } -#ui-datepicker-div .ui-icon-transferthick-e-w { background-position: -112px -80px; } -#ui-datepicker-div .ui-icon-folder-collapsed { background-position: 0 -96px; } -#ui-datepicker-div .ui-icon-folder-open { background-position: -16px -96px; } -#ui-datepicker-div .ui-icon-document { background-position: -32px -96px; } -#ui-datepicker-div .ui-icon-document-b { background-position: -48px -96px; } -#ui-datepicker-div .ui-icon-note { background-position: -64px -96px; } -#ui-datepicker-div .ui-icon-mail-closed { background-position: -80px -96px; } -#ui-datepicker-div .ui-icon-mail-open { background-position: -96px -96px; } -#ui-datepicker-div .ui-icon-suitcase { background-position: -112px -96px; } -#ui-datepicker-div .ui-icon-comment { background-position: -128px -96px; } -#ui-datepicker-div .ui-icon-person { background-position: -144px -96px; } -#ui-datepicker-div .ui-icon-print { background-position: -160px -96px; } -#ui-datepicker-div .ui-icon-trash { background-position: -176px -96px; } -#ui-datepicker-div .ui-icon-locked { background-position: -192px -96px; } -#ui-datepicker-div .ui-icon-unlocked { background-position: -208px -96px; } -#ui-datepicker-div .ui-icon-bookmark { background-position: -224px -96px; } -#ui-datepicker-div .ui-icon-tag { background-position: -240px -96px; } -#ui-datepicker-div .ui-icon-home { background-position: 0 -112px; } -#ui-datepicker-div .ui-icon-flag { background-position: -16px -112px; } -#ui-datepicker-div .ui-icon-calendar { background-position: -32px -112px; } -#ui-datepicker-div .ui-icon-cart { background-position: -48px -112px; } -#ui-datepicker-div .ui-icon-pencil { background-position: -64px -112px; } -#ui-datepicker-div .ui-icon-clock { background-position: -80px -112px; } -#ui-datepicker-div .ui-icon-disk { background-position: -96px -112px; } -#ui-datepicker-div .ui-icon-calculator { background-position: -112px -112px; } -#ui-datepicker-div .ui-icon-zoomin { background-position: -128px -112px; } -#ui-datepicker-div .ui-icon-zoomout { background-position: -144px -112px; } -#ui-datepicker-div .ui-icon-search { background-position: -160px -112px; } -#ui-datepicker-div .ui-icon-wrench { background-position: -176px -112px; } -#ui-datepicker-div .ui-icon-gear { background-position: -192px -112px; } -#ui-datepicker-div .ui-icon-heart { background-position: -208px -112px; } -#ui-datepicker-div .ui-icon-star { background-position: -224px -112px; } -#ui-datepicker-div .ui-icon-link { background-position: -240px -112px; } -#ui-datepicker-div .ui-icon-cancel { background-position: 0 -128px; } -#ui-datepicker-div .ui-icon-plus { background-position: -16px -128px; } -#ui-datepicker-div .ui-icon-plusthick { background-position: -32px -128px; } -#ui-datepicker-div .ui-icon-minus { background-position: -48px -128px; } -#ui-datepicker-div .ui-icon-minusthick { background-position: -64px -128px; } -#ui-datepicker-div .ui-icon-close { background-position: -80px -128px; } -#ui-datepicker-div .ui-icon-closethick { background-position: -96px -128px; } -#ui-datepicker-div .ui-icon-key { background-position: -112px -128px; } -#ui-datepicker-div .ui-icon-lightbulb { background-position: -128px -128px; } -#ui-datepicker-div .ui-icon-scissors { background-position: -144px -128px; } -#ui-datepicker-div .ui-icon-clipboard { background-position: -160px -128px; } -#ui-datepicker-div .ui-icon-copy { background-position: -176px -128px; } -#ui-datepicker-div .ui-icon-contact { background-position: -192px -128px; } -#ui-datepicker-div .ui-icon-image { background-position: -208px -128px; } -#ui-datepicker-div .ui-icon-video { background-position: -224px -128px; } -#ui-datepicker-div .ui-icon-script { background-position: -240px -128px; } -#ui-datepicker-div .ui-icon-alert { background-position: 0 -144px; } -#ui-datepicker-div .ui-icon-info { background-position: -16px -144px; } -#ui-datepicker-div .ui-icon-notice { background-position: -32px -144px; } -#ui-datepicker-div .ui-icon-help { background-position: -48px -144px; } -#ui-datepicker-div .ui-icon-check { background-position: -64px -144px; } -#ui-datepicker-div .ui-icon-bullet { background-position: -80px -144px; } -#ui-datepicker-div .ui-icon-radio-on { background-position: -96px -144px; } -#ui-datepicker-div .ui-icon-radio-off { background-position: -112px -144px; } -#ui-datepicker-div .ui-icon-pin-w { background-position: -128px -144px; } -#ui-datepicker-div .ui-icon-pin-s { background-position: -144px -144px; } -#ui-datepicker-div .ui-icon-play { background-position: 0 -160px; } -#ui-datepicker-div .ui-icon-pause { background-position: -16px -160px; } -#ui-datepicker-div .ui-icon-seek-next { background-position: -32px -160px; } -#ui-datepicker-div .ui-icon-seek-prev { background-position: -48px -160px; } -#ui-datepicker-div .ui-icon-seek-end { background-position: -64px -160px; } -#ui-datepicker-div .ui-icon-seek-start { background-position: -80px -160px; } -/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ -#ui-datepicker-div .ui-icon-seek-first { background-position: -80px -160px; } -#ui-datepicker-div .ui-icon-stop { background-position: -96px -160px; } -#ui-datepicker-div .ui-icon-eject { background-position: -112px -160px; } -#ui-datepicker-div .ui-icon-volume-off { background-position: -128px -160px; } -#ui-datepicker-div .ui-icon-volume-on { background-position: -144px -160px; } -#ui-datepicker-div .ui-icon-power { background-position: 0 -176px; } -#ui-datepicker-div .ui-icon-signal-diag { background-position: -16px -176px; } -#ui-datepicker-div .ui-icon-signal { background-position: -32px -176px; } -#ui-datepicker-div .ui-icon-battery-0 { background-position: -48px -176px; } -#ui-datepicker-div .ui-icon-battery-1 { background-position: -64px -176px; } -#ui-datepicker-div .ui-icon-battery-2 { background-position: -80px -176px; } -#ui-datepicker-div .ui-icon-battery-3 { background-position: -96px -176px; } -#ui-datepicker-div .ui-icon-circle-plus { background-position: 0 -192px; } -#ui-datepicker-div .ui-icon-circle-minus { background-position: -16px -192px; } -#ui-datepicker-div .ui-icon-circle-close { background-position: -32px -192px; } -#ui-datepicker-div .ui-icon-circle-triangle-e { background-position: -48px -192px; } -#ui-datepicker-div .ui-icon-circle-triangle-s { background-position: -64px -192px; } -#ui-datepicker-div .ui-icon-circle-triangle-w { background-position: -80px -192px; } -#ui-datepicker-div .ui-icon-circle-triangle-n { background-position: -96px -192px; } -#ui-datepicker-div .ui-icon-circle-arrow-e { background-position: -112px -192px; } -#ui-datepicker-div .ui-icon-circle-arrow-s { background-position: -128px -192px; } -#ui-datepicker-div .ui-icon-circle-arrow-w { background-position: -144px -192px; } -#ui-datepicker-div .ui-icon-circle-arrow-n { background-position: -160px -192px; } -#ui-datepicker-div .ui-icon-circle-zoomin { background-position: -176px -192px; } -#ui-datepicker-div .ui-icon-circle-zoomout { background-position: -192px -192px; } -#ui-datepicker-div .ui-icon-circle-check { background-position: -208px -192px; } -#ui-datepicker-div .ui-icon-circlesmall-plus { background-position: 0 -208px; } -#ui-datepicker-div .ui-icon-circlesmall-minus { background-position: -16px -208px; } -#ui-datepicker-div .ui-icon-circlesmall-close { background-position: -32px -208px; } -#ui-datepicker-div .ui-icon-squaresmall-plus { background-position: -48px -208px; } -#ui-datepicker-div .ui-icon-squaresmall-minus { background-position: -64px -208px; } -#ui-datepicker-div .ui-icon-squaresmall-close { background-position: -80px -208px; } -#ui-datepicker-div .ui-icon-grip-dotted-vertical { background-position: 0 -224px; } -#ui-datepicker-div .ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } -#ui-datepicker-div .ui-icon-grip-solid-vertical { background-position: -32px -224px; } -#ui-datepicker-div .ui-icon-grip-solid-horizontal { background-position: -48px -224px; } -#ui-datepicker-div .ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } -#ui-datepicker-div .ui-icon-grip-diagonal-se { background-position: -80px -224px; } - - -/* Misc visuals -----------------------------------*/ - -/* Corner radius */ -#ui-datepicker-div .ui-corner-all, -#ui-datepicker-div .ui-corner-top, -#ui-datepicker-div .ui-corner-left, -#ui-datepicker-div .ui-corner-tl { - border-top-left-radius: 4px; -} -#ui-datepicker-div .ui-corner-all, -#ui-datepicker-div .ui-corner-top, -#ui-datepicker-div .ui-corner-right, -#ui-datepicker-div .ui-corner-tr { - border-top-right-radius: 4px; -} -#ui-datepicker-div .ui-corner-all, -#ui-datepicker-div .ui-corner-bottom, -#ui-datepicker-div .ui-corner-left, -#ui-datepicker-div .ui-corner-bl { - border-bottom-left-radius: 4px; -} -#ui-datepicker-div .ui-corner-all, -#ui-datepicker-div .ui-corner-bottom, -#ui-datepicker-div .ui-corner-right, -#ui-datepicker-div .ui-corner-br { - border-bottom-right-radius: 4px; -} - -/* Overlays */ -#ui-datepicker-div .ui-widget-overlay { - background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; - opacity: .3; - filter: Alpha(Opacity=30); -} -#ui-datepicker-div .ui-widget-shadow { - margin: -8px 0 0 -8px; - padding: 8px; - background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; - opacity: .3; - filter: Alpha(Opacity=30); - border-radius: 8px; -} +/*! jQuery UI - v1.10.3 - 2013-09-23 +* http://jqueryui.com +* Includes: jquery.ui.core.css, jquery.ui.datepicker.css, jquery.ui.theme.css +* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana%2CArial%2Csans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=highlight_soft&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=flat&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=glass&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=glass&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=glass&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=glass&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px +* Copyright 2013 jQuery Foundation and other contributors; Licensed MIT */ + +/* Layout helpers +----------------------------------*/ +.ui-helper-hidden { + display: none; +} +.ui-helper-hidden-accessible { + border: 0; + clip: rect(0 0 0 0); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; +} +.ui-helper-reset { + margin: 0; + padding: 0; + border: 0; + outline: 0; + line-height: 1.3; + text-decoration: none; + font-size: 100%; + list-style: none; +} +.ui-helper-clearfix:before, +.ui-helper-clearfix:after { + content: ""; + display: table; + border-collapse: collapse; +} +.ui-helper-clearfix:after { + clear: both; +} +.ui-helper-clearfix { + min-height: 0; /* support: IE7 */ +} +.ui-helper-zfix { + width: 100%; + height: 100%; + top: 0; + left: 0; + position: absolute; + opacity: 0; + filter:Alpha(Opacity=0); +} + +.ui-front { + z-index: 100; +} + + +/* Interaction Cues +----------------------------------*/ +.ui-state-disabled { + cursor: default !important; +} + + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { + display: block; + text-indent: -99999px; + overflow: hidden; + background-repeat: no-repeat; +} + + +/* Misc visuals +----------------------------------*/ + +/* Overlays */ +.ui-widget-overlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; +} +.ui-datepicker { + width: 17em; + padding: .2em .2em 0; + display: none; +} +.ui-datepicker .ui-datepicker-header { + position: relative; + padding: .2em 0; +} +.ui-datepicker .ui-datepicker-prev, +.ui-datepicker .ui-datepicker-next { + position: absolute; + top: 2px; + width: 1.8em; + height: 1.8em; +} +.ui-datepicker .ui-datepicker-prev-hover, +.ui-datepicker .ui-datepicker-next-hover { + top: 1px; +} +.ui-datepicker .ui-datepicker-prev { + left: 2px; +} +.ui-datepicker .ui-datepicker-next { + right: 2px; +} +.ui-datepicker .ui-datepicker-prev-hover { + left: 1px; +} +.ui-datepicker .ui-datepicker-next-hover { + right: 1px; +} +.ui-datepicker .ui-datepicker-prev span, +.ui-datepicker .ui-datepicker-next span { + display: block; + position: absolute; + left: 50%; + margin-left: -8px; + top: 50%; + margin-top: -8px; +} +.ui-datepicker .ui-datepicker-title { + margin: 0 2.3em; + line-height: 1.8em; + text-align: center; +} +.ui-datepicker .ui-datepicker-title select { + font-size: 1em; + margin: 1px 0; +} +.ui-datepicker select.ui-datepicker-month-year { + width: 100%; +} +.ui-datepicker select.ui-datepicker-month, +.ui-datepicker select.ui-datepicker-year { + width: 49%; +} +.ui-datepicker table { + width: 100%; + font-size: .9em; + border-collapse: collapse; + margin: 0 0 .4em; +} +.ui-datepicker th { + padding: .7em .3em; + text-align: center; + font-weight: bold; + border: 0; +} +.ui-datepicker td { + border: 0; + padding: 1px; +} +.ui-datepicker td span, +.ui-datepicker td a { + display: block; + padding: .2em; + text-align: right; + text-decoration: none; +} +.ui-datepicker .ui-datepicker-buttonpane { + background-image: none; + margin: .7em 0 0 0; + padding: 0 .2em; + border-left: 0; + border-right: 0; + border-bottom: 0; +} +.ui-datepicker .ui-datepicker-buttonpane button { + float: right; + margin: .5em .2em .4em; + cursor: pointer; + padding: .2em .6em .3em .6em; + width: auto; + overflow: visible; +} +.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { + float: left; +} + +/* with multiple calendars */ +.ui-datepicker.ui-datepicker-multi { + width: auto; +} +.ui-datepicker-multi .ui-datepicker-group { + float: left; +} +.ui-datepicker-multi .ui-datepicker-group table { + width: 95%; + margin: 0 auto .4em; +} +.ui-datepicker-multi-2 .ui-datepicker-group { + width: 50%; +} +.ui-datepicker-multi-3 .ui-datepicker-group { + width: 33.3%; +} +.ui-datepicker-multi-4 .ui-datepicker-group { + width: 25%; +} +.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header, +.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { + border-left-width: 0; +} +.ui-datepicker-multi .ui-datepicker-buttonpane { + clear: left; +} +.ui-datepicker-row-break { + clear: both; + width: 100%; + font-size: 0; +} + +/* RTL support */ +.ui-datepicker-rtl { + direction: rtl; +} +.ui-datepicker-rtl .ui-datepicker-prev { + right: 2px; + left: auto; +} +.ui-datepicker-rtl .ui-datepicker-next { + left: 2px; + right: auto; +} +.ui-datepicker-rtl .ui-datepicker-prev:hover { + right: 1px; + left: auto; +} +.ui-datepicker-rtl .ui-datepicker-next:hover { + left: 1px; + right: auto; +} +.ui-datepicker-rtl .ui-datepicker-buttonpane { + clear: right; +} +.ui-datepicker-rtl .ui-datepicker-buttonpane button { + float: left; +} +.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current, +.ui-datepicker-rtl .ui-datepicker-group { + float: right; +} +.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header, +.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { + border-right-width: 0; + border-left-width: 1px; +} + +/* Component containers +----------------------------------*/ +#ui-datepicker-div.ui-widget { + font-family: Verdana,Arial,sans-serif; + font-size: 1.1em; +} +#ui-datepicker-div.ui-widget .ui-widget { + font-size: 1em; +} +#ui-datepicker-div.ui-widget input, +#ui-datepicker-div.ui-widget select, +#ui-datepicker-div.ui-widget textarea, +#ui-datepicker-div.ui-widget button { + font-family: Verdana,Arial,sans-serif; + font-size: 1em; +} +#ui-datepicker-div.ui-widget-content { + border: 1px solid #aaaaaa; + background: #ffffff url(images/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x; + color: #222222; +} +#ui-datepicker-div.ui-widget-content a { + color: #222222; +} +#ui-datepicker-div .ui-widget-header { + border: 1px solid #aaaaaa; + background: #cccccc url(images/ui-bg_highlight-soft_75_cccccc_1x100.png) 50% 50% repeat-x; + color: #222222; + font-weight: bold; +} +#ui-datepicker-div .ui-widget-header a { + color: #222222; +} + +/* Interaction states +----------------------------------*/ +#ui-datepicker-div .ui-state-default, +#ui-datepicker-div.ui-widget-content .ui-state-default, +#ui-datepicker-div .ui-widget-header .ui-state-default { + border: 1px solid #d3d3d3; + background: #e6e6e6 url(images/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% repeat-x; + font-weight: normal; + color: #555555; +} +#ui-datepicker-div .ui-state-default a, +#ui-datepicker-div .ui-state-default a:link, +#ui-datepicker-div .ui-state-default a:visited { + color: #555555; + text-decoration: none; +} +#ui-datepicker-div .ui-state-hover, +#ui-datepicker-div.ui-widget-content .ui-state-hover, +#ui-datepicker-div .ui-widget-header .ui-state-hover, +#ui-datepicker-div .ui-state-focus, +#ui-datepicker-div.ui-widget-content .ui-state-focus, +#ui-datepicker-div .ui-widget-header .ui-state-focus { + border: 1px solid #999999; + background: #dadada url(images/ui-bg_glass_75_dadada_1x400.png) 50% 50% repeat-x; + font-weight: normal; + color: #212121; +} +#ui-datepicker-div .ui-state-hover a, +#ui-datepicker-div .ui-state-hover a:hover, +#ui-datepicker-div .ui-state-hover a:link, +#ui-datepicker-div .ui-state-hover a:visited { + color: #212121; + text-decoration: none; +} +#ui-datepicker-div .ui-state-active, +#ui-datepicker-div.ui-widget-content .ui-state-active, +#ui-datepicker-div .ui-widget-header .ui-state-active { + border: 1px solid #aaaaaa; + background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; + font-weight: normal; + color: #212121; +} +#ui-datepicker-div .ui-state-active a, +#ui-datepicker-div .ui-state-active a:link, +#ui-datepicker-div .ui-state-active a:visited { + color: #212121; + text-decoration: none; +} + +/* Interaction Cues +----------------------------------*/ +#ui-datepicker-div .ui-state-highlight, +#ui-datepicker-div.ui-widget-content .ui-state-highlight, +#ui-datepicker-div .ui-widget-header .ui-state-highlight { + border: 1px solid #fcefa1; + background: #fbf9ee url(images/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x; + color: #363636; +} +#ui-datepicker-div .ui-state-highlight a, +#ui-datepicker-div.ui-widget-content .ui-state-highlight a, +#ui-datepicker-div .ui-widget-header .ui-state-highlight a { + color: #363636; +} +#ui-datepicker-div .ui-state-error, +#ui-datepicker-div.ui-widget-content .ui-state-error, +#ui-datepicker-div .ui-widget-header .ui-state-error { + border: 1px solid #cd0a0a; + background: #fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; + color: #cd0a0a; +} +#ui-datepicker-div .ui-state-error a, +#ui-datepicker-div.ui-widget-content .ui-state-error a, +#ui-datepicker-div .ui-widget-header .ui-state-error a { + color: #cd0a0a; +} +#ui-datepicker-div .ui-state-error-text, +#ui-datepicker-div.ui-widget-content .ui-state-error-text, +#ui-datepicker-div .ui-widget-header .ui-state-error-text { + color: #cd0a0a; +} +#ui-datepicker-div .ui-priority-primary, +#ui-datepicker-div.ui-widget-content .ui-priority-primary, +#ui-datepicker-div .ui-widget-header .ui-priority-primary { + font-weight: bold; +} +#ui-datepicker-div .ui-priority-secondary, +#ui-datepicker-div.ui-widget-content .ui-priority-secondary, +#ui-datepicker-div .ui-widget-header .ui-priority-secondary { + opacity: .7; + filter:Alpha(Opacity=70); + font-weight: normal; +} +#ui-datepicker-div .ui-state-disabled, +#ui-datepicker-div.ui-widget-content .ui-state-disabled, +#ui-datepicker-div .ui-widget-header .ui-state-disabled { + opacity: .35; + filter:Alpha(Opacity=35); + background-image: none; +} +#ui-datepicker-div .ui-state-disabled .ui-icon { + filter:Alpha(Opacity=35); /* For IE8 - See #6059 */ +} + +/* Icons +----------------------------------*/ + +/* states and images */ +#ui-datepicker-div .ui-icon { + width: 16px; + height: 16px; +} +#ui-datepicker-div .ui-icon, +#ui-datepicker-div.ui-widget-content .ui-icon { + background-image: url(images/ui-icons_222222_256x240.png); +} +#ui-datepicker-div .ui-widget-header .ui-icon { + background-image: url(images/ui-icons_222222_256x240.png); +} +#ui-datepicker-div .ui-state-default .ui-icon { + background-image: url(images/ui-icons_888888_256x240.png); +} +#ui-datepicker-div .ui-state-hover .ui-icon, +#ui-datepicker-div .ui-state-focus .ui-icon { + background-image: url(images/ui-icons_454545_256x240.png); +} +#ui-datepicker-div .ui-state-active .ui-icon { + background-image: url(images/ui-icons_454545_256x240.png); +} +#ui-datepicker-div .ui-state-highlight .ui-icon { + background-image: url(images/ui-icons_2e83ff_256x240.png); +} +#ui-datepicker-div .ui-state-error .ui-icon, +#ui-datepicker-div .ui-state-error-text .ui-icon { + background-image: url(images/ui-icons_cd0a0a_256x240.png); +} + +/* positioning */ +#ui-datepicker-div .ui-icon-blank { background-position: 16px 16px; } +#ui-datepicker-div .ui-icon-carat-1-n { background-position: 0 0; } +#ui-datepicker-div .ui-icon-carat-1-ne { background-position: -16px 0; } +#ui-datepicker-div .ui-icon-carat-1-e { background-position: -32px 0; } +#ui-datepicker-div .ui-icon-carat-1-se { background-position: -48px 0; } +#ui-datepicker-div .ui-icon-carat-1-s { background-position: -64px 0; } +#ui-datepicker-div .ui-icon-carat-1-sw { background-position: -80px 0; } +#ui-datepicker-div .ui-icon-carat-1-w { background-position: -96px 0; } +#ui-datepicker-div .ui-icon-carat-1-nw { background-position: -112px 0; } +#ui-datepicker-div .ui-icon-carat-2-n-s { background-position: -128px 0; } +#ui-datepicker-div .ui-icon-carat-2-e-w { background-position: -144px 0; } +#ui-datepicker-div .ui-icon-triangle-1-n { background-position: 0 -16px; } +#ui-datepicker-div .ui-icon-triangle-1-ne { background-position: -16px -16px; } +#ui-datepicker-div .ui-icon-triangle-1-e { background-position: -32px -16px; } +#ui-datepicker-div .ui-icon-triangle-1-se { background-position: -48px -16px; } +#ui-datepicker-div .ui-icon-triangle-1-s { background-position: -64px -16px; } +#ui-datepicker-div .ui-icon-triangle-1-sw { background-position: -80px -16px; } +#ui-datepicker-div .ui-icon-triangle-1-w { background-position: -96px -16px; } +#ui-datepicker-div .ui-icon-triangle-1-nw { background-position: -112px -16px; } +#ui-datepicker-div .ui-icon-triangle-2-n-s { background-position: -128px -16px; } +#ui-datepicker-div .ui-icon-triangle-2-e-w { background-position: -144px -16px; } +#ui-datepicker-div .ui-icon-arrow-1-n { background-position: 0 -32px; } +#ui-datepicker-div .ui-icon-arrow-1-ne { background-position: -16px -32px; } +#ui-datepicker-div .ui-icon-arrow-1-e { background-position: -32px -32px; } +#ui-datepicker-div .ui-icon-arrow-1-se { background-position: -48px -32px; } +#ui-datepicker-div .ui-icon-arrow-1-s { background-position: -64px -32px; } +#ui-datepicker-div .ui-icon-arrow-1-sw { background-position: -80px -32px; } +#ui-datepicker-div .ui-icon-arrow-1-w { background-position: -96px -32px; } +#ui-datepicker-div .ui-icon-arrow-1-nw { background-position: -112px -32px; } +#ui-datepicker-div .ui-icon-arrow-2-n-s { background-position: -128px -32px; } +#ui-datepicker-div .ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } +#ui-datepicker-div .ui-icon-arrow-2-e-w { background-position: -160px -32px; } +#ui-datepicker-div .ui-icon-arrow-2-se-nw { background-position: -176px -32px; } +#ui-datepicker-div .ui-icon-arrowstop-1-n { background-position: -192px -32px; } +#ui-datepicker-div .ui-icon-arrowstop-1-e { background-position: -208px -32px; } +#ui-datepicker-div .ui-icon-arrowstop-1-s { background-position: -224px -32px; } +#ui-datepicker-div .ui-icon-arrowstop-1-w { background-position: -240px -32px; } +#ui-datepicker-div .ui-icon-arrowthick-1-n { background-position: 0 -48px; } +#ui-datepicker-div .ui-icon-arrowthick-1-ne { background-position: -16px -48px; } +#ui-datepicker-div .ui-icon-arrowthick-1-e { background-position: -32px -48px; } +#ui-datepicker-div .ui-icon-arrowthick-1-se { background-position: -48px -48px; } +#ui-datepicker-div .ui-icon-arrowthick-1-s { background-position: -64px -48px; } +#ui-datepicker-div .ui-icon-arrowthick-1-sw { background-position: -80px -48px; } +#ui-datepicker-div .ui-icon-arrowthick-1-w { background-position: -96px -48px; } +#ui-datepicker-div .ui-icon-arrowthick-1-nw { background-position: -112px -48px; } +#ui-datepicker-div .ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } +#ui-datepicker-div .ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } +#ui-datepicker-div .ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } +#ui-datepicker-div .ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } +#ui-datepicker-div .ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } +#ui-datepicker-div .ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } +#ui-datepicker-div .ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } +#ui-datepicker-div .ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } +#ui-datepicker-div .ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } +#ui-datepicker-div .ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } +#ui-datepicker-div .ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } +#ui-datepicker-div .ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } +#ui-datepicker-div .ui-icon-arrowreturn-1-w { background-position: -64px -64px; } +#ui-datepicker-div .ui-icon-arrowreturn-1-n { background-position: -80px -64px; } +#ui-datepicker-div .ui-icon-arrowreturn-1-e { background-position: -96px -64px; } +#ui-datepicker-div .ui-icon-arrowreturn-1-s { background-position: -112px -64px; } +#ui-datepicker-div .ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } +#ui-datepicker-div .ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } +#ui-datepicker-div .ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } +#ui-datepicker-div .ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } +#ui-datepicker-div .ui-icon-arrow-4 { background-position: 0 -80px; } +#ui-datepicker-div .ui-icon-arrow-4-diag { background-position: -16px -80px; } +#ui-datepicker-div .ui-icon-extlink { background-position: -32px -80px; } +#ui-datepicker-div .ui-icon-newwin { background-position: -48px -80px; } +#ui-datepicker-div .ui-icon-refresh { background-position: -64px -80px; } +#ui-datepicker-div .ui-icon-shuffle { background-position: -80px -80px; } +#ui-datepicker-div .ui-icon-transfer-e-w { background-position: -96px -80px; } +#ui-datepicker-div .ui-icon-transferthick-e-w { background-position: -112px -80px; } +#ui-datepicker-div .ui-icon-folder-collapsed { background-position: 0 -96px; } +#ui-datepicker-div .ui-icon-folder-open { background-position: -16px -96px; } +#ui-datepicker-div .ui-icon-document { background-position: -32px -96px; } +#ui-datepicker-div .ui-icon-document-b { background-position: -48px -96px; } +#ui-datepicker-div .ui-icon-note { background-position: -64px -96px; } +#ui-datepicker-div .ui-icon-mail-closed { background-position: -80px -96px; } +#ui-datepicker-div .ui-icon-mail-open { background-position: -96px -96px; } +#ui-datepicker-div .ui-icon-suitcase { background-position: -112px -96px; } +#ui-datepicker-div .ui-icon-comment { background-position: -128px -96px; } +#ui-datepicker-div .ui-icon-person { background-position: -144px -96px; } +#ui-datepicker-div .ui-icon-print { background-position: -160px -96px; } +#ui-datepicker-div .ui-icon-trash { background-position: -176px -96px; } +#ui-datepicker-div .ui-icon-locked { background-position: -192px -96px; } +#ui-datepicker-div .ui-icon-unlocked { background-position: -208px -96px; } +#ui-datepicker-div .ui-icon-bookmark { background-position: -224px -96px; } +#ui-datepicker-div .ui-icon-tag { background-position: -240px -96px; } +#ui-datepicker-div .ui-icon-home { background-position: 0 -112px; } +#ui-datepicker-div .ui-icon-flag { background-position: -16px -112px; } +#ui-datepicker-div .ui-icon-calendar { background-position: -32px -112px; } +#ui-datepicker-div .ui-icon-cart { background-position: -48px -112px; } +#ui-datepicker-div .ui-icon-pencil { background-position: -64px -112px; } +#ui-datepicker-div .ui-icon-clock { background-position: -80px -112px; } +#ui-datepicker-div .ui-icon-disk { background-position: -96px -112px; } +#ui-datepicker-div .ui-icon-calculator { background-position: -112px -112px; } +#ui-datepicker-div .ui-icon-zoomin { background-position: -128px -112px; } +#ui-datepicker-div .ui-icon-zoomout { background-position: -144px -112px; } +#ui-datepicker-div .ui-icon-search { background-position: -160px -112px; } +#ui-datepicker-div .ui-icon-wrench { background-position: -176px -112px; } +#ui-datepicker-div .ui-icon-gear { background-position: -192px -112px; } +#ui-datepicker-div .ui-icon-heart { background-position: -208px -112px; } +#ui-datepicker-div .ui-icon-star { background-position: -224px -112px; } +#ui-datepicker-div .ui-icon-link { background-position: -240px -112px; } +#ui-datepicker-div .ui-icon-cancel { background-position: 0 -128px; } +#ui-datepicker-div .ui-icon-plus { background-position: -16px -128px; } +#ui-datepicker-div .ui-icon-plusthick { background-position: -32px -128px; } +#ui-datepicker-div .ui-icon-minus { background-position: -48px -128px; } +#ui-datepicker-div .ui-icon-minusthick { background-position: -64px -128px; } +#ui-datepicker-div .ui-icon-close { background-position: -80px -128px; } +#ui-datepicker-div .ui-icon-closethick { background-position: -96px -128px; } +#ui-datepicker-div .ui-icon-key { background-position: -112px -128px; } +#ui-datepicker-div .ui-icon-lightbulb { background-position: -128px -128px; } +#ui-datepicker-div .ui-icon-scissors { background-position: -144px -128px; } +#ui-datepicker-div .ui-icon-clipboard { background-position: -160px -128px; } +#ui-datepicker-div .ui-icon-copy { background-position: -176px -128px; } +#ui-datepicker-div .ui-icon-contact { background-position: -192px -128px; } +#ui-datepicker-div .ui-icon-image { background-position: -208px -128px; } +#ui-datepicker-div .ui-icon-video { background-position: -224px -128px; } +#ui-datepicker-div .ui-icon-script { background-position: -240px -128px; } +#ui-datepicker-div .ui-icon-alert { background-position: 0 -144px; } +#ui-datepicker-div .ui-icon-info { background-position: -16px -144px; } +#ui-datepicker-div .ui-icon-notice { background-position: -32px -144px; } +#ui-datepicker-div .ui-icon-help { background-position: -48px -144px; } +#ui-datepicker-div .ui-icon-check { background-position: -64px -144px; } +#ui-datepicker-div .ui-icon-bullet { background-position: -80px -144px; } +#ui-datepicker-div .ui-icon-radio-on { background-position: -96px -144px; } +#ui-datepicker-div .ui-icon-radio-off { background-position: -112px -144px; } +#ui-datepicker-div .ui-icon-pin-w { background-position: -128px -144px; } +#ui-datepicker-div .ui-icon-pin-s { background-position: -144px -144px; } +#ui-datepicker-div .ui-icon-play { background-position: 0 -160px; } +#ui-datepicker-div .ui-icon-pause { background-position: -16px -160px; } +#ui-datepicker-div .ui-icon-seek-next { background-position: -32px -160px; } +#ui-datepicker-div .ui-icon-seek-prev { background-position: -48px -160px; } +#ui-datepicker-div .ui-icon-seek-end { background-position: -64px -160px; } +#ui-datepicker-div .ui-icon-seek-start { background-position: -80px -160px; } +/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ +#ui-datepicker-div .ui-icon-seek-first { background-position: -80px -160px; } +#ui-datepicker-div .ui-icon-stop { background-position: -96px -160px; } +#ui-datepicker-div .ui-icon-eject { background-position: -112px -160px; } +#ui-datepicker-div .ui-icon-volume-off { background-position: -128px -160px; } +#ui-datepicker-div .ui-icon-volume-on { background-position: -144px -160px; } +#ui-datepicker-div .ui-icon-power { background-position: 0 -176px; } +#ui-datepicker-div .ui-icon-signal-diag { background-position: -16px -176px; } +#ui-datepicker-div .ui-icon-signal { background-position: -32px -176px; } +#ui-datepicker-div .ui-icon-battery-0 { background-position: -48px -176px; } +#ui-datepicker-div .ui-icon-battery-1 { background-position: -64px -176px; } +#ui-datepicker-div .ui-icon-battery-2 { background-position: -80px -176px; } +#ui-datepicker-div .ui-icon-battery-3 { background-position: -96px -176px; } +#ui-datepicker-div .ui-icon-circle-plus { background-position: 0 -192px; } +#ui-datepicker-div .ui-icon-circle-minus { background-position: -16px -192px; } +#ui-datepicker-div .ui-icon-circle-close { background-position: -32px -192px; } +#ui-datepicker-div .ui-icon-circle-triangle-e { background-position: -48px -192px; } +#ui-datepicker-div .ui-icon-circle-triangle-s { background-position: -64px -192px; } +#ui-datepicker-div .ui-icon-circle-triangle-w { background-position: -80px -192px; } +#ui-datepicker-div .ui-icon-circle-triangle-n { background-position: -96px -192px; } +#ui-datepicker-div .ui-icon-circle-arrow-e { background-position: -112px -192px; } +#ui-datepicker-div .ui-icon-circle-arrow-s { background-position: -128px -192px; } +#ui-datepicker-div .ui-icon-circle-arrow-w { background-position: -144px -192px; } +#ui-datepicker-div .ui-icon-circle-arrow-n { background-position: -160px -192px; } +#ui-datepicker-div .ui-icon-circle-zoomin { background-position: -176px -192px; } +#ui-datepicker-div .ui-icon-circle-zoomout { background-position: -192px -192px; } +#ui-datepicker-div .ui-icon-circle-check { background-position: -208px -192px; } +#ui-datepicker-div .ui-icon-circlesmall-plus { background-position: 0 -208px; } +#ui-datepicker-div .ui-icon-circlesmall-minus { background-position: -16px -208px; } +#ui-datepicker-div .ui-icon-circlesmall-close { background-position: -32px -208px; } +#ui-datepicker-div .ui-icon-squaresmall-plus { background-position: -48px -208px; } +#ui-datepicker-div .ui-icon-squaresmall-minus { background-position: -64px -208px; } +#ui-datepicker-div .ui-icon-squaresmall-close { background-position: -80px -208px; } +#ui-datepicker-div .ui-icon-grip-dotted-vertical { background-position: 0 -224px; } +#ui-datepicker-div .ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } +#ui-datepicker-div .ui-icon-grip-solid-vertical { background-position: -32px -224px; } +#ui-datepicker-div .ui-icon-grip-solid-horizontal { background-position: -48px -224px; } +#ui-datepicker-div .ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } +#ui-datepicker-div .ui-icon-grip-diagonal-se { background-position: -80px -224px; } + + +/* Misc visuals +----------------------------------*/ + +/* Corner radius */ +#ui-datepicker-div .ui-corner-all, +#ui-datepicker-div .ui-corner-top, +#ui-datepicker-div .ui-corner-left, +#ui-datepicker-div .ui-corner-tl { + border-top-left-radius: 4px; +} +#ui-datepicker-div .ui-corner-all, +#ui-datepicker-div .ui-corner-top, +#ui-datepicker-div .ui-corner-right, +#ui-datepicker-div .ui-corner-tr { + border-top-right-radius: 4px; +} +#ui-datepicker-div .ui-corner-all, +#ui-datepicker-div .ui-corner-bottom, +#ui-datepicker-div .ui-corner-left, +#ui-datepicker-div .ui-corner-bl { + border-bottom-left-radius: 4px; +} +#ui-datepicker-div .ui-corner-all, +#ui-datepicker-div .ui-corner-bottom, +#ui-datepicker-div .ui-corner-right, +#ui-datepicker-div .ui-corner-br { + border-bottom-right-radius: 4px; +} + +/* Overlays */ +#ui-datepicker-div .ui-widget-overlay { + background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; + opacity: .3; + filter: Alpha(Opacity=30); +} +#ui-datepicker-div .ui-widget-shadow { + margin: -8px 0 0 -8px; + padding: 8px; + background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; + opacity: .3; + filter: Alpha(Opacity=30); + border-radius: 8px; +} diff --git a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/license.txt b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/license.txt index 1837b0a..60d6d4c 100644 --- a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/license.txt +++ b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/license.txt @@ -1,504 +1,504 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 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. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -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 and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, 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 library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete 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 distribute a copy of this License along with the -Library. - - 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 Library or any portion -of it, thus forming a work based on the Library, 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) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -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 Library, 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 Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you 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. - - If distribution of 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 satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be 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. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library 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. - - 9. 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 Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -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 with -this License. - - 11. 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 Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library 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 Library. - -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. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library 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. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser 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 Library -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 Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -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 - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "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 -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. 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 LIBRARY 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 -LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), 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 Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. 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 library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; 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. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! - - + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 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. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +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 and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, 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 library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete 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 distribute a copy of this License along with the +Library. + + 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 Library or any portion +of it, thus forming a work based on the Library, 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) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +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 Library, 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 Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you 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. + + If distribution of 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 satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be 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. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library 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. + + 9. 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 Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +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 with +this License. + + 11. 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 Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library 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 Library. + +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. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library 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. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser 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 Library +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 Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +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 + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "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 +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. 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 LIBRARY 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 +LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), 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 Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. 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 library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; 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. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/directionality/editor_plugin_src.js b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/directionality/editor_plugin_src.js index 205d02c..4444959 100644 --- a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/directionality/editor_plugin_src.js +++ b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/directionality/editor_plugin_src.js @@ -1,82 +1,82 @@ -/** - * editor_plugin_src.js - * - * Copyright 2009, Moxiecode Systems AB - * Released under LGPL License. - * - * License: http://tinymce.moxiecode.com/license - * Contributing: http://tinymce.moxiecode.com/contributing - */ - -(function() { - tinymce.create('tinymce.plugins.Directionality', { - init : function(ed, url) { - var t = this; - - t.editor = ed; - - ed.addCommand('mceDirectionLTR', function() { - var e = ed.dom.getParent(ed.selection.getNode(), ed.dom.isBlock); - - if (e) { - if (ed.dom.getAttrib(e, "dir") != "ltr") - ed.dom.setAttrib(e, "dir", "ltr"); - else - ed.dom.setAttrib(e, "dir", ""); - } - - ed.nodeChanged(); - }); - - ed.addCommand('mceDirectionRTL', function() { - var e = ed.dom.getParent(ed.selection.getNode(), ed.dom.isBlock); - - if (e) { - if (ed.dom.getAttrib(e, "dir") != "rtl") - ed.dom.setAttrib(e, "dir", "rtl"); - else - ed.dom.setAttrib(e, "dir", ""); - } - - ed.nodeChanged(); - }); - - ed.addButton('ltr', {title : 'directionality.ltr_desc', cmd : 'mceDirectionLTR'}); - ed.addButton('rtl', {title : 'directionality.rtl_desc', cmd : 'mceDirectionRTL'}); - - ed.onNodeChange.add(t._nodeChange, t); - }, - - getInfo : function() { - return { - longname : 'Directionality', - author : 'Moxiecode Systems AB', - authorurl : 'http://tinymce.moxiecode.com', - infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/directionality', - version : tinymce.majorVersion + "." + tinymce.minorVersion - }; - }, - - // Private methods - - _nodeChange : function(ed, cm, n) { - var dom = ed.dom, dir; - - n = dom.getParent(n, dom.isBlock); - if (!n) { - cm.setDisabled('ltr', 1); - cm.setDisabled('rtl', 1); - return; - } - - dir = dom.getAttrib(n, 'dir'); - cm.setActive('ltr', dir == "ltr"); - cm.setDisabled('ltr', 0); - cm.setActive('rtl', dir == "rtl"); - cm.setDisabled('rtl', 0); - } - }); - - // Register plugin - tinymce.PluginManager.add('directionality', tinymce.plugins.Directionality); +/** + * editor_plugin_src.js + * + * Copyright 2009, Moxiecode Systems AB + * Released under LGPL License. + * + * License: http://tinymce.moxiecode.com/license + * Contributing: http://tinymce.moxiecode.com/contributing + */ + +(function() { + tinymce.create('tinymce.plugins.Directionality', { + init : function(ed, url) { + var t = this; + + t.editor = ed; + + ed.addCommand('mceDirectionLTR', function() { + var e = ed.dom.getParent(ed.selection.getNode(), ed.dom.isBlock); + + if (e) { + if (ed.dom.getAttrib(e, "dir") != "ltr") + ed.dom.setAttrib(e, "dir", "ltr"); + else + ed.dom.setAttrib(e, "dir", ""); + } + + ed.nodeChanged(); + }); + + ed.addCommand('mceDirectionRTL', function() { + var e = ed.dom.getParent(ed.selection.getNode(), ed.dom.isBlock); + + if (e) { + if (ed.dom.getAttrib(e, "dir") != "rtl") + ed.dom.setAttrib(e, "dir", "rtl"); + else + ed.dom.setAttrib(e, "dir", ""); + } + + ed.nodeChanged(); + }); + + ed.addButton('ltr', {title : 'directionality.ltr_desc', cmd : 'mceDirectionLTR'}); + ed.addButton('rtl', {title : 'directionality.rtl_desc', cmd : 'mceDirectionRTL'}); + + ed.onNodeChange.add(t._nodeChange, t); + }, + + getInfo : function() { + return { + longname : 'Directionality', + author : 'Moxiecode Systems AB', + authorurl : 'http://tinymce.moxiecode.com', + infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/directionality', + version : tinymce.majorVersion + "." + tinymce.minorVersion + }; + }, + + // Private methods + + _nodeChange : function(ed, cm, n) { + var dom = ed.dom, dir; + + n = dom.getParent(n, dom.isBlock); + if (!n) { + cm.setDisabled('ltr', 1); + cm.setDisabled('rtl', 1); + return; + } + + dir = dom.getAttrib(n, 'dir'); + cm.setActive('ltr', dir == "ltr"); + cm.setDisabled('ltr', 0); + cm.setActive('rtl', dir == "rtl"); + cm.setDisabled('rtl', 0); + } + }); + + // Register plugin + tinymce.PluginManager.add('directionality', tinymce.plugins.Directionality); })(); \ No newline at end of file diff --git a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/fullscreen/editor_plugin_src.js b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/fullscreen/editor_plugin_src.js index d211c7b..6622f92 100644 --- a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/fullscreen/editor_plugin_src.js +++ b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/fullscreen/editor_plugin_src.js @@ -1,159 +1,159 @@ -/** - * editor_plugin_src.js - * - * Copyright 2009, Moxiecode Systems AB - * Released under LGPL License. - * - * License: http://tinymce.moxiecode.com/license - * Contributing: http://tinymce.moxiecode.com/contributing - */ - -(function() { - var DOM = tinymce.DOM; - - tinymce.create('tinymce.plugins.FullScreenPlugin', { - init : function(ed, url) { - var t = this, s = {}, vp, posCss; - - t.editor = ed; - - // Register commands - ed.addCommand('mceFullScreen', function() { - var win, de = DOM.doc.documentElement; - - if (ed.getParam('fullscreen_is_enabled')) { - if (ed.getParam('fullscreen_new_window')) - closeFullscreen(); // Call to close in new window - else { - DOM.win.setTimeout(function() { - tinymce.dom.Event.remove(DOM.win, 'resize', t.resizeFunc); - tinyMCE.get(ed.getParam('fullscreen_editor_id')).setContent(ed.getContent()); - tinyMCE.remove(ed); - DOM.remove('mce_fullscreen_container'); - de.style.overflow = ed.getParam('fullscreen_html_overflow'); - DOM.setStyle(DOM.doc.body, 'overflow', ed.getParam('fullscreen_overflow')); - DOM.win.scrollTo(ed.getParam('fullscreen_scrollx'), ed.getParam('fullscreen_scrolly')); - tinyMCE.settings = tinyMCE.oldSettings; // Restore old settings - }, 10); - } - - return; - } - - if (ed.getParam('fullscreen_new_window')) { - win = DOM.win.open(url + "/fullscreen.htm", "mceFullScreenPopup", "fullscreen=yes,menubar=no,toolbar=no,scrollbars=no,resizable=yes,left=0,top=0,width=" + screen.availWidth + ",height=" + screen.availHeight); - try { - win.resizeTo(screen.availWidth, screen.availHeight); - } catch (e) { - // Ignore - } - } else { - tinyMCE.oldSettings = tinyMCE.settings; // Store old settings - s.fullscreen_overflow = DOM.getStyle(DOM.doc.body, 'overflow', 1) || 'auto'; - s.fullscreen_html_overflow = DOM.getStyle(de, 'overflow', 1); - vp = DOM.getViewPort(); - s.fullscreen_scrollx = vp.x; - s.fullscreen_scrolly = vp.y; - - // Fixes an Opera bug where the scrollbars doesn't reappear - if (tinymce.isOpera && s.fullscreen_overflow == 'visible') - s.fullscreen_overflow = 'auto'; - - // Fixes an IE bug where horizontal scrollbars would appear - if (tinymce.isIE && s.fullscreen_overflow == 'scroll') - s.fullscreen_overflow = 'auto'; - - // Fixes an IE bug where the scrollbars doesn't reappear - if (tinymce.isIE && (s.fullscreen_html_overflow == 'visible' || s.fullscreen_html_overflow == 'scroll')) - s.fullscreen_html_overflow = 'auto'; - - if (s.fullscreen_overflow == '0px') - s.fullscreen_overflow = ''; - - DOM.setStyle(DOM.doc.body, 'overflow', 'hidden'); - de.style.overflow = 'hidden'; //Fix for IE6/7 - vp = DOM.getViewPort(); - DOM.win.scrollTo(0, 0); - - if (tinymce.isIE) - vp.h -= 1; - - // Use fixed position if it exists - if (tinymce.isIE6 || document.compatMode == 'BackCompat') - posCss = 'absolute;top:' + vp.y; - else - posCss = 'fixed;top:0'; - - n = DOM.add(DOM.doc.body, 'div', { - id : 'mce_fullscreen_container', - style : 'position:' + posCss + ';left:0;width:' + vp.w + 'px;height:' + vp.h + 'px;z-index:200000;'}); - DOM.add(n, 'div', {id : 'mce_fullscreen'}); - - tinymce.each(ed.settings, function(v, n) { - s[n] = v; - }); - - s.id = 'mce_fullscreen'; - s.width = n.clientWidth; - s.height = n.clientHeight - 15; - s.fullscreen_is_enabled = true; - s.fullscreen_editor_id = ed.id; - s.theme_advanced_resizing = false; - s.save_onsavecallback = function() { - ed.setContent(tinyMCE.get(s.id).getContent()); - ed.execCommand('mceSave'); - }; - - tinymce.each(ed.getParam('fullscreen_settings'), function(v, k) { - s[k] = v; - }); - - if (s.theme_advanced_toolbar_location === 'external') - s.theme_advanced_toolbar_location = 'top'; - - t.fullscreenEditor = new tinymce.Editor('mce_fullscreen', s); - t.fullscreenEditor.onInit.add(function() { - t.fullscreenEditor.setContent(ed.getContent()); - t.fullscreenEditor.focus(); - }); - - t.fullscreenEditor.render(); - - t.fullscreenElement = new tinymce.dom.Element('mce_fullscreen_container'); - t.fullscreenElement.update(); - //document.body.overflow = 'hidden'; - - t.resizeFunc = tinymce.dom.Event.add(DOM.win, 'resize', function() { - var vp = tinymce.DOM.getViewPort(), fed = t.fullscreenEditor, outerSize, innerSize; - - // Get outer/inner size to get a delta size that can be used to calc the new iframe size - outerSize = fed.dom.getSize(fed.getContainer().firstChild); - innerSize = fed.dom.getSize(fed.getContainer().getElementsByTagName('iframe')[0]); - - fed.theme.resizeTo(vp.w - outerSize.w + innerSize.w, vp.h - outerSize.h + innerSize.h); - }); - } - }); - - // Register buttons - ed.addButton('fullscreen', {title : 'fullscreen.desc', cmd : 'mceFullScreen'}); - - ed.onNodeChange.add(function(ed, cm) { - cm.setActive('fullscreen', ed.getParam('fullscreen_is_enabled')); - }); - }, - - getInfo : function() { - return { - longname : 'Fullscreen', - author : 'Moxiecode Systems AB', - authorurl : 'http://tinymce.moxiecode.com', - infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/fullscreen', - version : tinymce.majorVersion + "." + tinymce.minorVersion - }; - } - }); - - // Register plugin - tinymce.PluginManager.add('fullscreen', tinymce.plugins.FullScreenPlugin); +/** + * editor_plugin_src.js + * + * Copyright 2009, Moxiecode Systems AB + * Released under LGPL License. + * + * License: http://tinymce.moxiecode.com/license + * Contributing: http://tinymce.moxiecode.com/contributing + */ + +(function() { + var DOM = tinymce.DOM; + + tinymce.create('tinymce.plugins.FullScreenPlugin', { + init : function(ed, url) { + var t = this, s = {}, vp, posCss; + + t.editor = ed; + + // Register commands + ed.addCommand('mceFullScreen', function() { + var win, de = DOM.doc.documentElement; + + if (ed.getParam('fullscreen_is_enabled')) { + if (ed.getParam('fullscreen_new_window')) + closeFullscreen(); // Call to close in new window + else { + DOM.win.setTimeout(function() { + tinymce.dom.Event.remove(DOM.win, 'resize', t.resizeFunc); + tinyMCE.get(ed.getParam('fullscreen_editor_id')).setContent(ed.getContent()); + tinyMCE.remove(ed); + DOM.remove('mce_fullscreen_container'); + de.style.overflow = ed.getParam('fullscreen_html_overflow'); + DOM.setStyle(DOM.doc.body, 'overflow', ed.getParam('fullscreen_overflow')); + DOM.win.scrollTo(ed.getParam('fullscreen_scrollx'), ed.getParam('fullscreen_scrolly')); + tinyMCE.settings = tinyMCE.oldSettings; // Restore old settings + }, 10); + } + + return; + } + + if (ed.getParam('fullscreen_new_window')) { + win = DOM.win.open(url + "/fullscreen.htm", "mceFullScreenPopup", "fullscreen=yes,menubar=no,toolbar=no,scrollbars=no,resizable=yes,left=0,top=0,width=" + screen.availWidth + ",height=" + screen.availHeight); + try { + win.resizeTo(screen.availWidth, screen.availHeight); + } catch (e) { + // Ignore + } + } else { + tinyMCE.oldSettings = tinyMCE.settings; // Store old settings + s.fullscreen_overflow = DOM.getStyle(DOM.doc.body, 'overflow', 1) || 'auto'; + s.fullscreen_html_overflow = DOM.getStyle(de, 'overflow', 1); + vp = DOM.getViewPort(); + s.fullscreen_scrollx = vp.x; + s.fullscreen_scrolly = vp.y; + + // Fixes an Opera bug where the scrollbars doesn't reappear + if (tinymce.isOpera && s.fullscreen_overflow == 'visible') + s.fullscreen_overflow = 'auto'; + + // Fixes an IE bug where horizontal scrollbars would appear + if (tinymce.isIE && s.fullscreen_overflow == 'scroll') + s.fullscreen_overflow = 'auto'; + + // Fixes an IE bug where the scrollbars doesn't reappear + if (tinymce.isIE && (s.fullscreen_html_overflow == 'visible' || s.fullscreen_html_overflow == 'scroll')) + s.fullscreen_html_overflow = 'auto'; + + if (s.fullscreen_overflow == '0px') + s.fullscreen_overflow = ''; + + DOM.setStyle(DOM.doc.body, 'overflow', 'hidden'); + de.style.overflow = 'hidden'; //Fix for IE6/7 + vp = DOM.getViewPort(); + DOM.win.scrollTo(0, 0); + + if (tinymce.isIE) + vp.h -= 1; + + // Use fixed position if it exists + if (tinymce.isIE6 || document.compatMode == 'BackCompat') + posCss = 'absolute;top:' + vp.y; + else + posCss = 'fixed;top:0'; + + n = DOM.add(DOM.doc.body, 'div', { + id : 'mce_fullscreen_container', + style : 'position:' + posCss + ';left:0;width:' + vp.w + 'px;height:' + vp.h + 'px;z-index:200000;'}); + DOM.add(n, 'div', {id : 'mce_fullscreen'}); + + tinymce.each(ed.settings, function(v, n) { + s[n] = v; + }); + + s.id = 'mce_fullscreen'; + s.width = n.clientWidth; + s.height = n.clientHeight - 15; + s.fullscreen_is_enabled = true; + s.fullscreen_editor_id = ed.id; + s.theme_advanced_resizing = false; + s.save_onsavecallback = function() { + ed.setContent(tinyMCE.get(s.id).getContent()); + ed.execCommand('mceSave'); + }; + + tinymce.each(ed.getParam('fullscreen_settings'), function(v, k) { + s[k] = v; + }); + + if (s.theme_advanced_toolbar_location === 'external') + s.theme_advanced_toolbar_location = 'top'; + + t.fullscreenEditor = new tinymce.Editor('mce_fullscreen', s); + t.fullscreenEditor.onInit.add(function() { + t.fullscreenEditor.setContent(ed.getContent()); + t.fullscreenEditor.focus(); + }); + + t.fullscreenEditor.render(); + + t.fullscreenElement = new tinymce.dom.Element('mce_fullscreen_container'); + t.fullscreenElement.update(); + //document.body.overflow = 'hidden'; + + t.resizeFunc = tinymce.dom.Event.add(DOM.win, 'resize', function() { + var vp = tinymce.DOM.getViewPort(), fed = t.fullscreenEditor, outerSize, innerSize; + + // Get outer/inner size to get a delta size that can be used to calc the new iframe size + outerSize = fed.dom.getSize(fed.getContainer().firstChild); + innerSize = fed.dom.getSize(fed.getContainer().getElementsByTagName('iframe')[0]); + + fed.theme.resizeTo(vp.w - outerSize.w + innerSize.w, vp.h - outerSize.h + innerSize.h); + }); + } + }); + + // Register buttons + ed.addButton('fullscreen', {title : 'fullscreen.desc', cmd : 'mceFullScreen'}); + + ed.onNodeChange.add(function(ed, cm) { + cm.setActive('fullscreen', ed.getParam('fullscreen_is_enabled')); + }); + }, + + getInfo : function() { + return { + longname : 'Fullscreen', + author : 'Moxiecode Systems AB', + authorurl : 'http://tinymce.moxiecode.com', + infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/fullscreen', + version : tinymce.majorVersion + "." + tinymce.minorVersion + }; + } + }); + + // Register plugin + tinymce.PluginManager.add('fullscreen', tinymce.plugins.FullScreenPlugin); })(); \ No newline at end of file diff --git a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/fullscreen/fullscreen.htm b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/fullscreen/fullscreen.htm index 496a2f6..ffe528e 100644 --- a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/fullscreen/fullscreen.htm +++ b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/fullscreen/fullscreen.htm @@ -1,110 +1,110 @@ - - - - - - - - - -
            - -
            - - - - - + + + + + + + + + +
            + +
            + + + + + diff --git a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/inlinepopups/editor_plugin_src.js b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/inlinepopups/editor_plugin_src.js index 2a6f3ad..67123ca 100644 --- a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/inlinepopups/editor_plugin_src.js +++ b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/inlinepopups/editor_plugin_src.js @@ -1,699 +1,699 @@ -/** - * editor_plugin_src.js - * - * Copyright 2009, Moxiecode Systems AB - * Released under LGPL License. - * - * License: http://tinymce.moxiecode.com/license - * Contributing: http://tinymce.moxiecode.com/contributing - */ - -(function() { - var DOM = tinymce.DOM, Element = tinymce.dom.Element, Event = tinymce.dom.Event, each = tinymce.each, is = tinymce.is; - - tinymce.create('tinymce.plugins.InlinePopups', { - init : function(ed, url) { - // Replace window manager - ed.onBeforeRenderUI.add(function() { - ed.windowManager = new tinymce.InlineWindowManager(ed); - DOM.loadCSS(url + '/skins/' + (ed.settings.inlinepopups_skin || 'clearlooks2') + "/window.css"); - }); - }, - - getInfo : function() { - return { - longname : 'InlinePopups', - author : 'Moxiecode Systems AB', - authorurl : 'http://tinymce.moxiecode.com', - infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/inlinepopups', - version : tinymce.majorVersion + "." + tinymce.minorVersion - }; - } - }); - - tinymce.create('tinymce.InlineWindowManager:tinymce.WindowManager', { - InlineWindowManager : function(ed) { - var t = this; - - t.parent(ed); - t.zIndex = 300000; - t.count = 0; - t.windows = {}; - }, - - open : function(f, p) { - var t = this, id, opt = '', ed = t.editor, dw = 0, dh = 0, vp, po, mdf, clf, we, w, u, parentWindow; - - f = f || {}; - p = p || {}; - - // Run native windows - if (!f.inline) - return t.parent(f, p); - - parentWindow = t._frontWindow(); - if (parentWindow && DOM.get(parentWindow.id + '_ifr')) { - parentWindow.focussedElement = DOM.get(parentWindow.id + '_ifr').contentWindow.document.activeElement; - } - - // Only store selection if the type is a normal window - if (!f.type) - t.bookmark = ed.selection.getBookmark(1); - - id = DOM.uniqueId(); - vp = DOM.getViewPort(); - f.width = parseInt(f.width || 320); - f.height = parseInt(f.height || 240) + (tinymce.isIE ? 8 : 0); - f.min_width = parseInt(f.min_width || 150); - f.min_height = parseInt(f.min_height || 100); - f.max_width = parseInt(f.max_width || 2000); - f.max_height = parseInt(f.max_height || 2000); - f.left = f.left || Math.round(Math.max(vp.x, vp.x + (vp.w / 2.0) - (f.width / 2.0))); - f.top = f.top || Math.round(Math.max(vp.y, vp.y + (vp.h / 2.0) - (f.height / 2.0))); - f.movable = f.resizable = true; - p.mce_width = f.width; - p.mce_height = f.height; - p.mce_inline = true; - p.mce_window_id = id; - p.mce_auto_focus = f.auto_focus; - - // Transpose -// po = DOM.getPos(ed.getContainer()); -// f.left -= po.x; -// f.top -= po.y; - - t.features = f; - t.params = p; - t.onOpen.dispatch(t, f, p); - - if (f.type) { - opt += ' mceModal'; - - if (f.type) - opt += ' mce' + f.type.substring(0, 1).toUpperCase() + f.type.substring(1); - - f.resizable = false; - } - - if (f.statusbar) - opt += ' mceStatusbar'; - - if (f.resizable) - opt += ' mceResizable'; - - if (f.minimizable) - opt += ' mceMinimizable'; - - if (f.maximizable) - opt += ' mceMaximizable'; - - if (f.movable) - opt += ' mceMovable'; - - // Create DOM objects - t._addAll(DOM.doc.body, - ['div', {id : id, role : 'dialog', 'aria-labelledby': f.type ? id + '_content' : id + '_title', 'class' : (ed.settings.inlinepopups_skin || 'clearlooks2') + (tinymce.isIE && window.getSelection ? ' ie9' : ''), style : 'width:100px;height:100px'}, - ['div', {id : id + '_wrapper', 'class' : 'mceWrapper' + opt}, - ['div', {id : id + '_top', 'class' : 'mceTop'}, - ['div', {'class' : 'mceLeft'}], - ['div', {'class' : 'mceCenter'}], - ['div', {'class' : 'mceRight'}], - ['span', {id : id + '_title'}, f.title || ''] - ], - - ['div', {id : id + '_middle', 'class' : 'mceMiddle'}, - ['div', {id : id + '_left', 'class' : 'mceLeft', tabindex : '0'}], - ['span', {id : id + '_content'}], - ['div', {id : id + '_right', 'class' : 'mceRight', tabindex : '0'}] - ], - - ['div', {id : id + '_bottom', 'class' : 'mceBottom'}, - ['div', {'class' : 'mceLeft'}], - ['div', {'class' : 'mceCenter'}], - ['div', {'class' : 'mceRight'}], - ['span', {id : id + '_status'}, 'Content'] - ], - - ['a', {'class' : 'mceMove', tabindex : '-1', href : 'javascript:;'}], - ['a', {'class' : 'mceMin', tabindex : '-1', href : 'javascript:;', onmousedown : 'return false;'}], - ['a', {'class' : 'mceMax', tabindex : '-1', href : 'javascript:;', onmousedown : 'return false;'}], - ['a', {'class' : 'mceMed', tabindex : '-1', href : 'javascript:;', onmousedown : 'return false;'}], - ['a', {'class' : 'mceClose', tabindex : '-1', href : 'javascript:;', onmousedown : 'return false;'}], - ['a', {id : id + '_resize_n', 'class' : 'mceResize mceResizeN', tabindex : '-1', href : 'javascript:;'}], - ['a', {id : id + '_resize_s', 'class' : 'mceResize mceResizeS', tabindex : '-1', href : 'javascript:;'}], - ['a', {id : id + '_resize_w', 'class' : 'mceResize mceResizeW', tabindex : '-1', href : 'javascript:;'}], - ['a', {id : id + '_resize_e', 'class' : 'mceResize mceResizeE', tabindex : '-1', href : 'javascript:;'}], - ['a', {id : id + '_resize_nw', 'class' : 'mceResize mceResizeNW', tabindex : '-1', href : 'javascript:;'}], - ['a', {id : id + '_resize_ne', 'class' : 'mceResize mceResizeNE', tabindex : '-1', href : 'javascript:;'}], - ['a', {id : id + '_resize_sw', 'class' : 'mceResize mceResizeSW', tabindex : '-1', href : 'javascript:;'}], - ['a', {id : id + '_resize_se', 'class' : 'mceResize mceResizeSE', tabindex : '-1', href : 'javascript:;'}] - ] - ] - ); - - DOM.setStyles(id, {top : -10000, left : -10000}); - - // Fix gecko rendering bug, where the editors iframe messed with window contents - if (tinymce.isGecko) - DOM.setStyle(id, 'overflow', 'auto'); - - // Measure borders - if (!f.type) { - dw += DOM.get(id + '_left').clientWidth; - dw += DOM.get(id + '_right').clientWidth; - dh += DOM.get(id + '_top').clientHeight; - dh += DOM.get(id + '_bottom').clientHeight; - } - - // Resize window - DOM.setStyles(id, {top : f.top, left : f.left, width : f.width + dw, height : f.height + dh}); - - u = f.url || f.file; - if (u) { - if (tinymce.relaxedDomain) - u += (u.indexOf('?') == -1 ? '?' : '&') + 'mce_rdomain=' + tinymce.relaxedDomain; - - u = tinymce._addVer(u); - } - - if (!f.type) { - DOM.add(id + '_content', 'iframe', {id : id + '_ifr', src : 'javascript:""', frameBorder : 0, style : 'border:0;width:10px;height:10px'}); - DOM.setStyles(id + '_ifr', {width : f.width, height : f.height}); - DOM.setAttrib(id + '_ifr', 'src', u); - } else { - DOM.add(id + '_wrapper', 'a', {id : id + '_ok', 'class' : 'mceButton mceOk', href : 'javascript:;', onmousedown : 'return false;'}, 'Ok'); - - if (f.type == 'confirm') - DOM.add(id + '_wrapper', 'a', {'class' : 'mceButton mceCancel', href : 'javascript:;', onmousedown : 'return false;'}, 'Cancel'); - - DOM.add(id + '_middle', 'div', {'class' : 'mceIcon'}); - DOM.setHTML(id + '_content', f.content.replace('\n', '
            ')); - - Event.add(id, 'keyup', function(evt) { - var VK_ESCAPE = 27; - if (evt.keyCode === VK_ESCAPE) { - f.button_func(false); - return Event.cancel(evt); - } - }); - - Event.add(id, 'keydown', function(evt) { - var cancelButton, VK_TAB = 9; - if (evt.keyCode === VK_TAB) { - cancelButton = DOM.select('a.mceCancel', id + '_wrapper')[0]; - if (cancelButton && cancelButton !== evt.target) { - cancelButton.focus(); - } else { - DOM.get(id + '_ok').focus(); - } - return Event.cancel(evt); - } - }); - } - - // Register events - mdf = Event.add(id, 'mousedown', function(e) { - var n = e.target, w, vp; - - w = t.windows[id]; - t.focus(id); - - if (n.nodeName == 'A' || n.nodeName == 'a') { - if (n.className == 'mceClose') { - t.close(null, id); - return Event.cancel(e); - } else if (n.className == 'mceMax') { - w.oldPos = w.element.getXY(); - w.oldSize = w.element.getSize(); - - vp = DOM.getViewPort(); - - // Reduce viewport size to avoid scrollbars - vp.w -= 2; - vp.h -= 2; - - w.element.moveTo(vp.x, vp.y); - w.element.resizeTo(vp.w, vp.h); - DOM.setStyles(id + '_ifr', {width : vp.w - w.deltaWidth, height : vp.h - w.deltaHeight}); - DOM.addClass(id + '_wrapper', 'mceMaximized'); - } else if (n.className == 'mceMed') { - // Reset to old size - w.element.moveTo(w.oldPos.x, w.oldPos.y); - w.element.resizeTo(w.oldSize.w, w.oldSize.h); - w.iframeElement.resizeTo(w.oldSize.w - w.deltaWidth, w.oldSize.h - w.deltaHeight); - - DOM.removeClass(id + '_wrapper', 'mceMaximized'); - } else if (n.className == 'mceMove') - return t._startDrag(id, e, n.className); - else if (DOM.hasClass(n, 'mceResize')) - return t._startDrag(id, e, n.className.substring(13)); - } - }); - - clf = Event.add(id, 'click', function(e) { - var n = e.target; - - t.focus(id); - - if (n.nodeName == 'A' || n.nodeName == 'a') { - switch (n.className) { - case 'mceClose': - t.close(null, id); - return Event.cancel(e); - - case 'mceButton mceOk': - case 'mceButton mceCancel': - f.button_func(n.className == 'mceButton mceOk'); - return Event.cancel(e); - } - } - }); - - // Make sure the tab order loops within the dialog. - Event.add([id + '_left', id + '_right'], 'focus', function(evt) { - var iframe = DOM.get(id + '_ifr'); - if (iframe) { - var body = iframe.contentWindow.document.body; - var focusable = DOM.select(':input:enabled,*[tabindex=0]', body); - if (evt.target.id === (id + '_left')) { - focusable[focusable.length - 1].focus(); - } else { - focusable[0].focus(); - } - } else { - DOM.get(id + '_ok').focus(); - } - }); - - // Add window - w = t.windows[id] = { - id : id, - mousedown_func : mdf, - click_func : clf, - element : new Element(id, {blocker : 1, container : ed.getContainer()}), - iframeElement : new Element(id + '_ifr'), - features : f, - deltaWidth : dw, - deltaHeight : dh - }; - - w.iframeElement.on('focus', function() { - t.focus(id); - }); - - // Setup blocker - if (t.count == 0 && t.editor.getParam('dialog_type', 'modal') == 'modal') { - DOM.add(DOM.doc.body, 'div', { - id : 'mceModalBlocker', - 'class' : (t.editor.settings.inlinepopups_skin || 'clearlooks2') + '_modalBlocker', - style : {zIndex : t.zIndex - 1} - }); - - DOM.show('mceModalBlocker'); // Reduces flicker in IE - DOM.setAttrib(DOM.doc.body, 'aria-hidden', 'true'); - } else - DOM.setStyle('mceModalBlocker', 'z-index', t.zIndex - 1); - - if (tinymce.isIE6 || /Firefox\/2\./.test(navigator.userAgent) || (tinymce.isIE && !DOM.boxModel)) - DOM.setStyles('mceModalBlocker', {position : 'absolute', left : vp.x, top : vp.y, width : vp.w - 2, height : vp.h - 2}); - - DOM.setAttrib(id, 'aria-hidden', 'false'); - t.focus(id); - t._fixIELayout(id, 1); - - // Focus ok button - if (DOM.get(id + '_ok')) - DOM.get(id + '_ok').focus(); - t.count++; - - return w; - }, - - focus : function(id) { - var t = this, w; - - if (w = t.windows[id]) { - w.zIndex = this.zIndex++; - w.element.setStyle('zIndex', w.zIndex); - w.element.update(); - - id = id + '_wrapper'; - DOM.removeClass(t.lastId, 'mceFocus'); - DOM.addClass(id, 'mceFocus'); - t.lastId = id; - - if (w.focussedElement) { - w.focussedElement.focus(); - } else if (DOM.get(id + '_ok')) { - DOM.get(w.id + '_ok').focus(); - } else if (DOM.get(w.id + '_ifr')) { - DOM.get(w.id + '_ifr').focus(); - } - } - }, - - _addAll : function(te, ne) { - var i, n, t = this, dom = tinymce.DOM; - - if (is(ne, 'string')) - te.appendChild(dom.doc.createTextNode(ne)); - else if (ne.length) { - te = te.appendChild(dom.create(ne[0], ne[1])); - - for (i=2; i ix) { - fw = w; - ix = w.zIndex; - } - }); - return fw; - }, - - setTitle : function(w, ti) { - var e; - - w = this._findId(w); - - if (e = DOM.get(w + '_title')) - e.innerHTML = DOM.encode(ti); - }, - - alert : function(txt, cb, s) { - var t = this, w; - - w = t.open({ - title : t, - type : 'alert', - button_func : function(s) { - if (cb) - cb.call(s || t, s); - - t.close(null, w.id); - }, - content : DOM.encode(t.editor.getLang(txt, txt)), - inline : 1, - width : 400, - height : 130 - }); - }, - - confirm : function(txt, cb, s) { - var t = this, w; - - w = t.open({ - title : t, - type : 'confirm', - button_func : function(s) { - if (cb) - cb.call(s || t, s); - - t.close(null, w.id); - }, - content : DOM.encode(t.editor.getLang(txt, txt)), - inline : 1, - width : 400, - height : 130 - }); - }, - - // Internal functions - - _findId : function(w) { - var t = this; - - if (typeof(w) == 'string') - return w; - - each(t.windows, function(wo) { - var ifr = DOM.get(wo.id + '_ifr'); - - if (ifr && w == ifr.contentWindow) { - w = wo.id; - return false; - } - }); - - return w; - }, - - _fixIELayout : function(id, s) { - var w, img; - - if (!tinymce.isIE6) - return; - - // Fixes the bug where hover flickers and does odd things in IE6 - each(['n','s','w','e','nw','ne','sw','se'], function(v) { - var e = DOM.get(id + '_resize_' + v); - - DOM.setStyles(e, { - width : s ? e.clientWidth : '', - height : s ? e.clientHeight : '', - cursor : DOM.getStyle(e, 'cursor', 1) - }); - - DOM.setStyle(id + "_bottom", 'bottom', '-1px'); - - e = 0; - }); - - // Fixes graphics glitch - if (w = this.windows[id]) { - // Fixes rendering bug after resize - w.element.hide(); - w.element.show(); - - // Forced a repaint of the window - //DOM.get(id).style.filter = ''; - - // IE has a bug where images used in CSS won't get loaded - // sometimes when the cache in the browser is disabled - // This fix tries to solve it by loading the images using the image object - each(DOM.select('div,a', id), function(e, i) { - if (e.currentStyle.backgroundImage != 'none') { - img = new Image(); - img.src = e.currentStyle.backgroundImage.replace(/url\(\"(.+)\"\)/, '$1'); - } - }); - - DOM.get(id).style.filter = ''; - } - } - }); - - // Register plugin - tinymce.PluginManager.add('inlinepopups', tinymce.plugins.InlinePopups); -})(); - +/** + * editor_plugin_src.js + * + * Copyright 2009, Moxiecode Systems AB + * Released under LGPL License. + * + * License: http://tinymce.moxiecode.com/license + * Contributing: http://tinymce.moxiecode.com/contributing + */ + +(function() { + var DOM = tinymce.DOM, Element = tinymce.dom.Element, Event = tinymce.dom.Event, each = tinymce.each, is = tinymce.is; + + tinymce.create('tinymce.plugins.InlinePopups', { + init : function(ed, url) { + // Replace window manager + ed.onBeforeRenderUI.add(function() { + ed.windowManager = new tinymce.InlineWindowManager(ed); + DOM.loadCSS(url + '/skins/' + (ed.settings.inlinepopups_skin || 'clearlooks2') + "/window.css"); + }); + }, + + getInfo : function() { + return { + longname : 'InlinePopups', + author : 'Moxiecode Systems AB', + authorurl : 'http://tinymce.moxiecode.com', + infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/inlinepopups', + version : tinymce.majorVersion + "." + tinymce.minorVersion + }; + } + }); + + tinymce.create('tinymce.InlineWindowManager:tinymce.WindowManager', { + InlineWindowManager : function(ed) { + var t = this; + + t.parent(ed); + t.zIndex = 300000; + t.count = 0; + t.windows = {}; + }, + + open : function(f, p) { + var t = this, id, opt = '', ed = t.editor, dw = 0, dh = 0, vp, po, mdf, clf, we, w, u, parentWindow; + + f = f || {}; + p = p || {}; + + // Run native windows + if (!f.inline) + return t.parent(f, p); + + parentWindow = t._frontWindow(); + if (parentWindow && DOM.get(parentWindow.id + '_ifr')) { + parentWindow.focussedElement = DOM.get(parentWindow.id + '_ifr').contentWindow.document.activeElement; + } + + // Only store selection if the type is a normal window + if (!f.type) + t.bookmark = ed.selection.getBookmark(1); + + id = DOM.uniqueId(); + vp = DOM.getViewPort(); + f.width = parseInt(f.width || 320); + f.height = parseInt(f.height || 240) + (tinymce.isIE ? 8 : 0); + f.min_width = parseInt(f.min_width || 150); + f.min_height = parseInt(f.min_height || 100); + f.max_width = parseInt(f.max_width || 2000); + f.max_height = parseInt(f.max_height || 2000); + f.left = f.left || Math.round(Math.max(vp.x, vp.x + (vp.w / 2.0) - (f.width / 2.0))); + f.top = f.top || Math.round(Math.max(vp.y, vp.y + (vp.h / 2.0) - (f.height / 2.0))); + f.movable = f.resizable = true; + p.mce_width = f.width; + p.mce_height = f.height; + p.mce_inline = true; + p.mce_window_id = id; + p.mce_auto_focus = f.auto_focus; + + // Transpose +// po = DOM.getPos(ed.getContainer()); +// f.left -= po.x; +// f.top -= po.y; + + t.features = f; + t.params = p; + t.onOpen.dispatch(t, f, p); + + if (f.type) { + opt += ' mceModal'; + + if (f.type) + opt += ' mce' + f.type.substring(0, 1).toUpperCase() + f.type.substring(1); + + f.resizable = false; + } + + if (f.statusbar) + opt += ' mceStatusbar'; + + if (f.resizable) + opt += ' mceResizable'; + + if (f.minimizable) + opt += ' mceMinimizable'; + + if (f.maximizable) + opt += ' mceMaximizable'; + + if (f.movable) + opt += ' mceMovable'; + + // Create DOM objects + t._addAll(DOM.doc.body, + ['div', {id : id, role : 'dialog', 'aria-labelledby': f.type ? id + '_content' : id + '_title', 'class' : (ed.settings.inlinepopups_skin || 'clearlooks2') + (tinymce.isIE && window.getSelection ? ' ie9' : ''), style : 'width:100px;height:100px'}, + ['div', {id : id + '_wrapper', 'class' : 'mceWrapper' + opt}, + ['div', {id : id + '_top', 'class' : 'mceTop'}, + ['div', {'class' : 'mceLeft'}], + ['div', {'class' : 'mceCenter'}], + ['div', {'class' : 'mceRight'}], + ['span', {id : id + '_title'}, f.title || ''] + ], + + ['div', {id : id + '_middle', 'class' : 'mceMiddle'}, + ['div', {id : id + '_left', 'class' : 'mceLeft', tabindex : '0'}], + ['span', {id : id + '_content'}], + ['div', {id : id + '_right', 'class' : 'mceRight', tabindex : '0'}] + ], + + ['div', {id : id + '_bottom', 'class' : 'mceBottom'}, + ['div', {'class' : 'mceLeft'}], + ['div', {'class' : 'mceCenter'}], + ['div', {'class' : 'mceRight'}], + ['span', {id : id + '_status'}, 'Content'] + ], + + ['a', {'class' : 'mceMove', tabindex : '-1', href : 'javascript:;'}], + ['a', {'class' : 'mceMin', tabindex : '-1', href : 'javascript:;', onmousedown : 'return false;'}], + ['a', {'class' : 'mceMax', tabindex : '-1', href : 'javascript:;', onmousedown : 'return false;'}], + ['a', {'class' : 'mceMed', tabindex : '-1', href : 'javascript:;', onmousedown : 'return false;'}], + ['a', {'class' : 'mceClose', tabindex : '-1', href : 'javascript:;', onmousedown : 'return false;'}], + ['a', {id : id + '_resize_n', 'class' : 'mceResize mceResizeN', tabindex : '-1', href : 'javascript:;'}], + ['a', {id : id + '_resize_s', 'class' : 'mceResize mceResizeS', tabindex : '-1', href : 'javascript:;'}], + ['a', {id : id + '_resize_w', 'class' : 'mceResize mceResizeW', tabindex : '-1', href : 'javascript:;'}], + ['a', {id : id + '_resize_e', 'class' : 'mceResize mceResizeE', tabindex : '-1', href : 'javascript:;'}], + ['a', {id : id + '_resize_nw', 'class' : 'mceResize mceResizeNW', tabindex : '-1', href : 'javascript:;'}], + ['a', {id : id + '_resize_ne', 'class' : 'mceResize mceResizeNE', tabindex : '-1', href : 'javascript:;'}], + ['a', {id : id + '_resize_sw', 'class' : 'mceResize mceResizeSW', tabindex : '-1', href : 'javascript:;'}], + ['a', {id : id + '_resize_se', 'class' : 'mceResize mceResizeSE', tabindex : '-1', href : 'javascript:;'}] + ] + ] + ); + + DOM.setStyles(id, {top : -10000, left : -10000}); + + // Fix gecko rendering bug, where the editors iframe messed with window contents + if (tinymce.isGecko) + DOM.setStyle(id, 'overflow', 'auto'); + + // Measure borders + if (!f.type) { + dw += DOM.get(id + '_left').clientWidth; + dw += DOM.get(id + '_right').clientWidth; + dh += DOM.get(id + '_top').clientHeight; + dh += DOM.get(id + '_bottom').clientHeight; + } + + // Resize window + DOM.setStyles(id, {top : f.top, left : f.left, width : f.width + dw, height : f.height + dh}); + + u = f.url || f.file; + if (u) { + if (tinymce.relaxedDomain) + u += (u.indexOf('?') == -1 ? '?' : '&') + 'mce_rdomain=' + tinymce.relaxedDomain; + + u = tinymce._addVer(u); + } + + if (!f.type) { + DOM.add(id + '_content', 'iframe', {id : id + '_ifr', src : 'javascript:""', frameBorder : 0, style : 'border:0;width:10px;height:10px'}); + DOM.setStyles(id + '_ifr', {width : f.width, height : f.height}); + DOM.setAttrib(id + '_ifr', 'src', u); + } else { + DOM.add(id + '_wrapper', 'a', {id : id + '_ok', 'class' : 'mceButton mceOk', href : 'javascript:;', onmousedown : 'return false;'}, 'Ok'); + + if (f.type == 'confirm') + DOM.add(id + '_wrapper', 'a', {'class' : 'mceButton mceCancel', href : 'javascript:;', onmousedown : 'return false;'}, 'Cancel'); + + DOM.add(id + '_middle', 'div', {'class' : 'mceIcon'}); + DOM.setHTML(id + '_content', f.content.replace('\n', '
            ')); + + Event.add(id, 'keyup', function(evt) { + var VK_ESCAPE = 27; + if (evt.keyCode === VK_ESCAPE) { + f.button_func(false); + return Event.cancel(evt); + } + }); + + Event.add(id, 'keydown', function(evt) { + var cancelButton, VK_TAB = 9; + if (evt.keyCode === VK_TAB) { + cancelButton = DOM.select('a.mceCancel', id + '_wrapper')[0]; + if (cancelButton && cancelButton !== evt.target) { + cancelButton.focus(); + } else { + DOM.get(id + '_ok').focus(); + } + return Event.cancel(evt); + } + }); + } + + // Register events + mdf = Event.add(id, 'mousedown', function(e) { + var n = e.target, w, vp; + + w = t.windows[id]; + t.focus(id); + + if (n.nodeName == 'A' || n.nodeName == 'a') { + if (n.className == 'mceClose') { + t.close(null, id); + return Event.cancel(e); + } else if (n.className == 'mceMax') { + w.oldPos = w.element.getXY(); + w.oldSize = w.element.getSize(); + + vp = DOM.getViewPort(); + + // Reduce viewport size to avoid scrollbars + vp.w -= 2; + vp.h -= 2; + + w.element.moveTo(vp.x, vp.y); + w.element.resizeTo(vp.w, vp.h); + DOM.setStyles(id + '_ifr', {width : vp.w - w.deltaWidth, height : vp.h - w.deltaHeight}); + DOM.addClass(id + '_wrapper', 'mceMaximized'); + } else if (n.className == 'mceMed') { + // Reset to old size + w.element.moveTo(w.oldPos.x, w.oldPos.y); + w.element.resizeTo(w.oldSize.w, w.oldSize.h); + w.iframeElement.resizeTo(w.oldSize.w - w.deltaWidth, w.oldSize.h - w.deltaHeight); + + DOM.removeClass(id + '_wrapper', 'mceMaximized'); + } else if (n.className == 'mceMove') + return t._startDrag(id, e, n.className); + else if (DOM.hasClass(n, 'mceResize')) + return t._startDrag(id, e, n.className.substring(13)); + } + }); + + clf = Event.add(id, 'click', function(e) { + var n = e.target; + + t.focus(id); + + if (n.nodeName == 'A' || n.nodeName == 'a') { + switch (n.className) { + case 'mceClose': + t.close(null, id); + return Event.cancel(e); + + case 'mceButton mceOk': + case 'mceButton mceCancel': + f.button_func(n.className == 'mceButton mceOk'); + return Event.cancel(e); + } + } + }); + + // Make sure the tab order loops within the dialog. + Event.add([id + '_left', id + '_right'], 'focus', function(evt) { + var iframe = DOM.get(id + '_ifr'); + if (iframe) { + var body = iframe.contentWindow.document.body; + var focusable = DOM.select(':input:enabled,*[tabindex=0]', body); + if (evt.target.id === (id + '_left')) { + focusable[focusable.length - 1].focus(); + } else { + focusable[0].focus(); + } + } else { + DOM.get(id + '_ok').focus(); + } + }); + + // Add window + w = t.windows[id] = { + id : id, + mousedown_func : mdf, + click_func : clf, + element : new Element(id, {blocker : 1, container : ed.getContainer()}), + iframeElement : new Element(id + '_ifr'), + features : f, + deltaWidth : dw, + deltaHeight : dh + }; + + w.iframeElement.on('focus', function() { + t.focus(id); + }); + + // Setup blocker + if (t.count == 0 && t.editor.getParam('dialog_type', 'modal') == 'modal') { + DOM.add(DOM.doc.body, 'div', { + id : 'mceModalBlocker', + 'class' : (t.editor.settings.inlinepopups_skin || 'clearlooks2') + '_modalBlocker', + style : {zIndex : t.zIndex - 1} + }); + + DOM.show('mceModalBlocker'); // Reduces flicker in IE + DOM.setAttrib(DOM.doc.body, 'aria-hidden', 'true'); + } else + DOM.setStyle('mceModalBlocker', 'z-index', t.zIndex - 1); + + if (tinymce.isIE6 || /Firefox\/2\./.test(navigator.userAgent) || (tinymce.isIE && !DOM.boxModel)) + DOM.setStyles('mceModalBlocker', {position : 'absolute', left : vp.x, top : vp.y, width : vp.w - 2, height : vp.h - 2}); + + DOM.setAttrib(id, 'aria-hidden', 'false'); + t.focus(id); + t._fixIELayout(id, 1); + + // Focus ok button + if (DOM.get(id + '_ok')) + DOM.get(id + '_ok').focus(); + t.count++; + + return w; + }, + + focus : function(id) { + var t = this, w; + + if (w = t.windows[id]) { + w.zIndex = this.zIndex++; + w.element.setStyle('zIndex', w.zIndex); + w.element.update(); + + id = id + '_wrapper'; + DOM.removeClass(t.lastId, 'mceFocus'); + DOM.addClass(id, 'mceFocus'); + t.lastId = id; + + if (w.focussedElement) { + w.focussedElement.focus(); + } else if (DOM.get(id + '_ok')) { + DOM.get(w.id + '_ok').focus(); + } else if (DOM.get(w.id + '_ifr')) { + DOM.get(w.id + '_ifr').focus(); + } + } + }, + + _addAll : function(te, ne) { + var i, n, t = this, dom = tinymce.DOM; + + if (is(ne, 'string')) + te.appendChild(dom.doc.createTextNode(ne)); + else if (ne.length) { + te = te.appendChild(dom.create(ne[0], ne[1])); + + for (i=2; i ix) { + fw = w; + ix = w.zIndex; + } + }); + return fw; + }, + + setTitle : function(w, ti) { + var e; + + w = this._findId(w); + + if (e = DOM.get(w + '_title')) + e.innerHTML = DOM.encode(ti); + }, + + alert : function(txt, cb, s) { + var t = this, w; + + w = t.open({ + title : t, + type : 'alert', + button_func : function(s) { + if (cb) + cb.call(s || t, s); + + t.close(null, w.id); + }, + content : DOM.encode(t.editor.getLang(txt, txt)), + inline : 1, + width : 400, + height : 130 + }); + }, + + confirm : function(txt, cb, s) { + var t = this, w; + + w = t.open({ + title : t, + type : 'confirm', + button_func : function(s) { + if (cb) + cb.call(s || t, s); + + t.close(null, w.id); + }, + content : DOM.encode(t.editor.getLang(txt, txt)), + inline : 1, + width : 400, + height : 130 + }); + }, + + // Internal functions + + _findId : function(w) { + var t = this; + + if (typeof(w) == 'string') + return w; + + each(t.windows, function(wo) { + var ifr = DOM.get(wo.id + '_ifr'); + + if (ifr && w == ifr.contentWindow) { + w = wo.id; + return false; + } + }); + + return w; + }, + + _fixIELayout : function(id, s) { + var w, img; + + if (!tinymce.isIE6) + return; + + // Fixes the bug where hover flickers and does odd things in IE6 + each(['n','s','w','e','nw','ne','sw','se'], function(v) { + var e = DOM.get(id + '_resize_' + v); + + DOM.setStyles(e, { + width : s ? e.clientWidth : '', + height : s ? e.clientHeight : '', + cursor : DOM.getStyle(e, 'cursor', 1) + }); + + DOM.setStyle(id + "_bottom", 'bottom', '-1px'); + + e = 0; + }); + + // Fixes graphics glitch + if (w = this.windows[id]) { + // Fixes rendering bug after resize + w.element.hide(); + w.element.show(); + + // Forced a repaint of the window + //DOM.get(id).style.filter = ''; + + // IE has a bug where images used in CSS won't get loaded + // sometimes when the cache in the browser is disabled + // This fix tries to solve it by loading the images using the image object + each(DOM.select('div,a', id), function(e, i) { + if (e.currentStyle.backgroundImage != 'none') { + img = new Image(); + img.src = e.currentStyle.backgroundImage.replace(/url\(\"(.+)\"\)/, '$1'); + } + }); + + DOM.get(id).style.filter = ''; + } + } + }); + + // Register plugin + tinymce.PluginManager.add('inlinepopups', tinymce.plugins.InlinePopups); +})(); + diff --git a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/inlinepopups/skins/clearlooks2/window.css b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/inlinepopups/skins/clearlooks2/window.css index a50d4fc..74416fc 100644 --- a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/inlinepopups/skins/clearlooks2/window.css +++ b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/inlinepopups/skins/clearlooks2/window.css @@ -1,90 +1,90 @@ -/* Clearlooks 2 */ - -/* Reset */ -.clearlooks2, .clearlooks2 div, .clearlooks2 span, .clearlooks2 a {vertical-align:baseline; text-align:left; position:absolute; border:0; padding:0; margin:0; background:transparent; font-family:Arial,Verdana; font-size:11px; color:#000; text-decoration:none; font-weight:normal; width:auto; height:auto; overflow:hidden; display:block} - -/* General */ -.clearlooks2 {position:absolute; direction:ltr} -.clearlooks2 .mceWrapper {position:static} -.mceEventBlocker {position:fixed; left:0; top:0; background:url(img/horizontal.gif) no-repeat 0 -75px; width:100%; height:100%} -.clearlooks2 .mcePlaceHolder {border:1px solid #000; background:#888; top:0; left:0; opacity:0.5; -ms-filter:'alpha(opacity=50)'; filter:alpha(opacity=50)} -.clearlooks2_modalBlocker {position:fixed; left:0; top:0; width:100%; height:100%; background:#FFF; opacity:0.6; -ms-filter:'alpha(opacity=60)'; filter:alpha(opacity=60); display:none} - -/* Top */ -.clearlooks2 .mceTop, .clearlooks2 .mceTop div {top:0; width:100%; height:23px} -.clearlooks2 .mceTop .mceLeft {width:6px; background:url(img/corners.gif)} -.clearlooks2 .mceTop .mceCenter {right:6px; width:100%; height:23px; background:url(img/horizontal.gif) 12px 0; clip:rect(auto auto auto 12px)} -.clearlooks2 .mceTop .mceRight {right:0; width:6px; height:23px; background:url(img/corners.gif) -12px 0} -.clearlooks2 .mceTop span {width:100%; text-align:center; vertical-align:middle; line-height:23px; font-weight:bold} -.clearlooks2 .mceFocus .mceTop .mceLeft {background:url(img/corners.gif) -6px 0} -.clearlooks2 .mceFocus .mceTop .mceCenter {background:url(img/horizontal.gif) 0 -23px} -.clearlooks2 .mceFocus .mceTop .mceRight {background:url(img/corners.gif) -18px 0} -.clearlooks2 .mceFocus .mceTop span {color:#FFF} - -/* Middle */ -.clearlooks2 .mceMiddle, .clearlooks2 .mceMiddle div {top:0} -.clearlooks2 .mceMiddle {width:100%; height:100%; clip:rect(23px auto auto auto)} -.clearlooks2 .mceMiddle .mceLeft {left:0; width:5px; height:100%; background:url(img/vertical.gif) -5px 0} -.clearlooks2 .mceMiddle span {top:23px; left:5px; width:100%; height:100%; background:#FFF} -.clearlooks2 .mceMiddle .mceRight {right:0; width:5px; height:100%; background:url(img/vertical.gif)} - -/* Bottom */ -.clearlooks2 .mceBottom, .clearlooks2 .mceBottom div {height:6px} -.clearlooks2 .mceBottom {left:0; bottom:0; width:100%} -.clearlooks2 .mceBottom div {top:0} -.clearlooks2 .mceBottom .mceLeft {left:0; width:5px; background:url(img/corners.gif) -34px -6px} -.clearlooks2 .mceBottom .mceCenter {left:5px; width:100%; background:url(img/horizontal.gif) 0 -46px} -.clearlooks2 .mceBottom .mceRight {right:0; width:5px; background: url(img/corners.gif) -34px 0} -.clearlooks2 .mceBottom span {display:none} -.clearlooks2 .mceStatusbar .mceBottom, .clearlooks2 .mceStatusbar .mceBottom div {height:23px} -.clearlooks2 .mceStatusbar .mceBottom .mceLeft {background:url(img/corners.gif) -29px 0} -.clearlooks2 .mceStatusbar .mceBottom .mceCenter {background:url(img/horizontal.gif) 0 -52px} -.clearlooks2 .mceStatusbar .mceBottom .mceRight {background:url(img/corners.gif) -24px 0} -.clearlooks2 .mceStatusbar .mceBottom span {display:block; left:7px; font-family:Arial, Verdana; font-size:11px; line-height:23px} - -/* Actions */ -.clearlooks2 a {width:29px; height:16px; top:3px;} -.clearlooks2 .mceClose {right:6px; background:url(img/buttons.gif) -87px 0} -.clearlooks2 .mceMin {display:none; right:68px; background:url(img/buttons.gif) 0 0} -.clearlooks2 .mceMed {display:none; right:37px; background:url(img/buttons.gif) -29px 0} -.clearlooks2 .mceMax {display:none; right:37px; background:url(img/buttons.gif) -58px 0} -.clearlooks2 .mceMove {display:none;width:100%;cursor:move;background:url(img/corners.gif) no-repeat -100px -100px} -.clearlooks2 .mceMovable .mceMove {display:block} -.clearlooks2 .mceFocus .mceClose {right:6px; background:url(img/buttons.gif) -87px -16px} -.clearlooks2 .mceFocus .mceMin {right:68px; background:url(img/buttons.gif) 0 -16px} -.clearlooks2 .mceFocus .mceMed {right:37px; background:url(img/buttons.gif) -29px -16px} -.clearlooks2 .mceFocus .mceMax {right:37px; background:url(img/buttons.gif) -58px -16px} -.clearlooks2 .mceFocus .mceClose:hover {right:6px; background:url(img/buttons.gif) -87px -32px} -.clearlooks2 .mceFocus .mceClose:hover {right:6px; background:url(img/buttons.gif) -87px -32px} -.clearlooks2 .mceFocus .mceMin:hover {right:68px; background:url(img/buttons.gif) 0 -32px} -.clearlooks2 .mceFocus .mceMed:hover {right:37px; background:url(img/buttons.gif) -29px -32px} -.clearlooks2 .mceFocus .mceMax:hover {right:37px; background:url(img/buttons.gif) -58px -32px} - -/* Resize */ -.clearlooks2 .mceResize {top:auto; left:auto; display:none; width:5px; height:5px; background:url(img/horizontal.gif) no-repeat 0 -75px} -.clearlooks2 .mceResizable .mceResize {display:block} -.clearlooks2 .mceResizable .mceMin, .clearlooks2 .mceMax {display:none} -.clearlooks2 .mceMinimizable .mceMin {display:block} -.clearlooks2 .mceMaximizable .mceMax {display:block} -.clearlooks2 .mceMaximized .mceMed {display:block} -.clearlooks2 .mceMaximized .mceMax {display:none} -.clearlooks2 a.mceResizeN {top:0; left:0; width:100%; cursor:n-resize} -.clearlooks2 a.mceResizeNW {top:0; left:0; cursor:nw-resize} -.clearlooks2 a.mceResizeNE {top:0; right:0; cursor:ne-resize} -.clearlooks2 a.mceResizeW {top:0; left:0; height:100%; cursor:w-resize;} -.clearlooks2 a.mceResizeE {top:0; right:0; height:100%; cursor:e-resize} -.clearlooks2 a.mceResizeS {bottom:0; left:0; width:100%; cursor:s-resize} -.clearlooks2 a.mceResizeSW {bottom:0; left:0; cursor:sw-resize} -.clearlooks2 a.mceResizeSE {bottom:0; right:0; cursor:se-resize} - -/* Alert/Confirm */ -.clearlooks2 .mceButton {font-weight:bold; bottom:10px; width:80px; height:30px; background:url(img/button.gif); line-height:30px; vertical-align:middle; text-align:center; outline:0} -.clearlooks2 .mceMiddle .mceIcon {left:15px; top:35px; width:32px; height:32px} -.clearlooks2 .mceAlert .mceMiddle span, .clearlooks2 .mceConfirm .mceMiddle span {background:transparent;left:60px; top:35px; width:320px; height:50px; font-weight:bold; overflow:auto; white-space:normal} -.clearlooks2 a:hover {font-weight:bold;} -.clearlooks2 .mceAlert .mceMiddle, .clearlooks2 .mceConfirm .mceMiddle {background:#D6D7D5} -.clearlooks2 .mceAlert .mceOk {left:50%; top:auto; margin-left: -40px} -.clearlooks2 .mceAlert .mceIcon {background:url(img/alert.gif)} -.clearlooks2 .mceConfirm .mceOk {left:50%; top:auto; margin-left: -90px} -.clearlooks2 .mceConfirm .mceCancel {left:50%; top:auto} -.clearlooks2 .mceConfirm .mceIcon {background:url(img/confirm.gif)} +/* Clearlooks 2 */ + +/* Reset */ +.clearlooks2, .clearlooks2 div, .clearlooks2 span, .clearlooks2 a {vertical-align:baseline; text-align:left; position:absolute; border:0; padding:0; margin:0; background:transparent; font-family:Arial,Verdana; font-size:11px; color:#000; text-decoration:none; font-weight:normal; width:auto; height:auto; overflow:hidden; display:block} + +/* General */ +.clearlooks2 {position:absolute; direction:ltr} +.clearlooks2 .mceWrapper {position:static} +.mceEventBlocker {position:fixed; left:0; top:0; background:url(img/horizontal.gif) no-repeat 0 -75px; width:100%; height:100%} +.clearlooks2 .mcePlaceHolder {border:1px solid #000; background:#888; top:0; left:0; opacity:0.5; -ms-filter:'alpha(opacity=50)'; filter:alpha(opacity=50)} +.clearlooks2_modalBlocker {position:fixed; left:0; top:0; width:100%; height:100%; background:#FFF; opacity:0.6; -ms-filter:'alpha(opacity=60)'; filter:alpha(opacity=60); display:none} + +/* Top */ +.clearlooks2 .mceTop, .clearlooks2 .mceTop div {top:0; width:100%; height:23px} +.clearlooks2 .mceTop .mceLeft {width:6px; background:url(img/corners.gif)} +.clearlooks2 .mceTop .mceCenter {right:6px; width:100%; height:23px; background:url(img/horizontal.gif) 12px 0; clip:rect(auto auto auto 12px)} +.clearlooks2 .mceTop .mceRight {right:0; width:6px; height:23px; background:url(img/corners.gif) -12px 0} +.clearlooks2 .mceTop span {width:100%; text-align:center; vertical-align:middle; line-height:23px; font-weight:bold} +.clearlooks2 .mceFocus .mceTop .mceLeft {background:url(img/corners.gif) -6px 0} +.clearlooks2 .mceFocus .mceTop .mceCenter {background:url(img/horizontal.gif) 0 -23px} +.clearlooks2 .mceFocus .mceTop .mceRight {background:url(img/corners.gif) -18px 0} +.clearlooks2 .mceFocus .mceTop span {color:#FFF} + +/* Middle */ +.clearlooks2 .mceMiddle, .clearlooks2 .mceMiddle div {top:0} +.clearlooks2 .mceMiddle {width:100%; height:100%; clip:rect(23px auto auto auto)} +.clearlooks2 .mceMiddle .mceLeft {left:0; width:5px; height:100%; background:url(img/vertical.gif) -5px 0} +.clearlooks2 .mceMiddle span {top:23px; left:5px; width:100%; height:100%; background:#FFF} +.clearlooks2 .mceMiddle .mceRight {right:0; width:5px; height:100%; background:url(img/vertical.gif)} + +/* Bottom */ +.clearlooks2 .mceBottom, .clearlooks2 .mceBottom div {height:6px} +.clearlooks2 .mceBottom {left:0; bottom:0; width:100%} +.clearlooks2 .mceBottom div {top:0} +.clearlooks2 .mceBottom .mceLeft {left:0; width:5px; background:url(img/corners.gif) -34px -6px} +.clearlooks2 .mceBottom .mceCenter {left:5px; width:100%; background:url(img/horizontal.gif) 0 -46px} +.clearlooks2 .mceBottom .mceRight {right:0; width:5px; background: url(img/corners.gif) -34px 0} +.clearlooks2 .mceBottom span {display:none} +.clearlooks2 .mceStatusbar .mceBottom, .clearlooks2 .mceStatusbar .mceBottom div {height:23px} +.clearlooks2 .mceStatusbar .mceBottom .mceLeft {background:url(img/corners.gif) -29px 0} +.clearlooks2 .mceStatusbar .mceBottom .mceCenter {background:url(img/horizontal.gif) 0 -52px} +.clearlooks2 .mceStatusbar .mceBottom .mceRight {background:url(img/corners.gif) -24px 0} +.clearlooks2 .mceStatusbar .mceBottom span {display:block; left:7px; font-family:Arial, Verdana; font-size:11px; line-height:23px} + +/* Actions */ +.clearlooks2 a {width:29px; height:16px; top:3px;} +.clearlooks2 .mceClose {right:6px; background:url(img/buttons.gif) -87px 0} +.clearlooks2 .mceMin {display:none; right:68px; background:url(img/buttons.gif) 0 0} +.clearlooks2 .mceMed {display:none; right:37px; background:url(img/buttons.gif) -29px 0} +.clearlooks2 .mceMax {display:none; right:37px; background:url(img/buttons.gif) -58px 0} +.clearlooks2 .mceMove {display:none;width:100%;cursor:move;background:url(img/corners.gif) no-repeat -100px -100px} +.clearlooks2 .mceMovable .mceMove {display:block} +.clearlooks2 .mceFocus .mceClose {right:6px; background:url(img/buttons.gif) -87px -16px} +.clearlooks2 .mceFocus .mceMin {right:68px; background:url(img/buttons.gif) 0 -16px} +.clearlooks2 .mceFocus .mceMed {right:37px; background:url(img/buttons.gif) -29px -16px} +.clearlooks2 .mceFocus .mceMax {right:37px; background:url(img/buttons.gif) -58px -16px} +.clearlooks2 .mceFocus .mceClose:hover {right:6px; background:url(img/buttons.gif) -87px -32px} +.clearlooks2 .mceFocus .mceClose:hover {right:6px; background:url(img/buttons.gif) -87px -32px} +.clearlooks2 .mceFocus .mceMin:hover {right:68px; background:url(img/buttons.gif) 0 -32px} +.clearlooks2 .mceFocus .mceMed:hover {right:37px; background:url(img/buttons.gif) -29px -32px} +.clearlooks2 .mceFocus .mceMax:hover {right:37px; background:url(img/buttons.gif) -58px -32px} + +/* Resize */ +.clearlooks2 .mceResize {top:auto; left:auto; display:none; width:5px; height:5px; background:url(img/horizontal.gif) no-repeat 0 -75px} +.clearlooks2 .mceResizable .mceResize {display:block} +.clearlooks2 .mceResizable .mceMin, .clearlooks2 .mceMax {display:none} +.clearlooks2 .mceMinimizable .mceMin {display:block} +.clearlooks2 .mceMaximizable .mceMax {display:block} +.clearlooks2 .mceMaximized .mceMed {display:block} +.clearlooks2 .mceMaximized .mceMax {display:none} +.clearlooks2 a.mceResizeN {top:0; left:0; width:100%; cursor:n-resize} +.clearlooks2 a.mceResizeNW {top:0; left:0; cursor:nw-resize} +.clearlooks2 a.mceResizeNE {top:0; right:0; cursor:ne-resize} +.clearlooks2 a.mceResizeW {top:0; left:0; height:100%; cursor:w-resize;} +.clearlooks2 a.mceResizeE {top:0; right:0; height:100%; cursor:e-resize} +.clearlooks2 a.mceResizeS {bottom:0; left:0; width:100%; cursor:s-resize} +.clearlooks2 a.mceResizeSW {bottom:0; left:0; cursor:sw-resize} +.clearlooks2 a.mceResizeSE {bottom:0; right:0; cursor:se-resize} + +/* Alert/Confirm */ +.clearlooks2 .mceButton {font-weight:bold; bottom:10px; width:80px; height:30px; background:url(img/button.gif); line-height:30px; vertical-align:middle; text-align:center; outline:0} +.clearlooks2 .mceMiddle .mceIcon {left:15px; top:35px; width:32px; height:32px} +.clearlooks2 .mceAlert .mceMiddle span, .clearlooks2 .mceConfirm .mceMiddle span {background:transparent;left:60px; top:35px; width:320px; height:50px; font-weight:bold; overflow:auto; white-space:normal} +.clearlooks2 a:hover {font-weight:bold;} +.clearlooks2 .mceAlert .mceMiddle, .clearlooks2 .mceConfirm .mceMiddle {background:#D6D7D5} +.clearlooks2 .mceAlert .mceOk {left:50%; top:auto; margin-left: -40px} +.clearlooks2 .mceAlert .mceIcon {background:url(img/alert.gif)} +.clearlooks2 .mceConfirm .mceOk {left:50%; top:auto; margin-left: -90px} +.clearlooks2 .mceConfirm .mceCancel {left:50%; top:auto} +.clearlooks2 .mceConfirm .mceIcon {background:url(img/confirm.gif)} diff --git a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/inlinepopups/template.htm b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/inlinepopups/template.htm index c98fe41..f9ec642 100644 --- a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/inlinepopups/template.htm +++ b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/inlinepopups/template.htm @@ -1,387 +1,387 @@ - - - -Template for dialogs - - - - -
            -
            -
            -
            -
            -
            -
            - Blured -
            - -
            -
            - Content -
            -
            - -
            -
            -
            -
            - Statusbar text. -
            - - - - - - - - - - - - - - -
            -
            - -
            -
            -
            -
            -
            -
            - Focused -
            - -
            -
            - Content -
            -
            - -
            -
            -
            -
            - Statusbar text. -
            - - - - - - - - - - - - - - -
            -
            - -
            -
            -
            -
            -
            -
            - Statusbar -
            - -
            -
            - Content -
            -
            - -
            -
            -
            -
            - Statusbar text. -
            - - - - - - - - - - - - - - -
            -
            - -
            -
            -
            -
            -
            -
            - Statusbar, Resizable -
            - -
            -
            - Content -
            -
            - -
            -
            -
            -
            - Statusbar text. -
            - - - - - - - - - - - - - - -
            -
            - -
            -
            -
            -
            -
            -
            - Resizable, Maximizable -
            - -
            -
            - Content -
            -
            - -
            -
            -
            -
            - Statusbar text. -
            - - - - - - - - - - - - - - -
            -
            - -
            -
            -
            -
            -
            -
            - Blurred, Maximizable, Statusbar, Resizable -
            - -
            -
            - Content -
            -
            - -
            -
            -
            -
            - Statusbar text. -
            - - - - - - - - - - - - - - -
            -
            - -
            -
            -
            -
            -
            -
            - Maximized, Maximizable, Minimizable -
            - -
            -
            - Content -
            -
            - -
            -
            -
            -
            - Statusbar text. -
            - - - - - - - - - - - - - - -
            -
            - -
            -
            -
            -
            -
            -
            - Blured -
            - -
            -
            - Content -
            -
            - -
            -
            -
            -
            - Statusbar text. -
            - - - - - - - - - - - - - - -
            -
            - -
            -
            -
            -
            -
            -
            - Alert -
            - -
            -
            - - This is a very long error message. This is a very long error message. - This is a very long error message. This is a very long error message. - This is a very long error message. This is a very long error message. - This is a very long error message. This is a very long error message. - This is a very long error message. This is a very long error message. - This is a very long error message. This is a very long error message. - -
            -
            -
            - -
            -
            -
            -
            -
            - - - Ok - -
            -
            - -
            -
            -
            -
            -
            -
            - Confirm -
            - -
            -
            - - This is a very long error message. This is a very long error message. - This is a very long error message. This is a very long error message. - This is a very long error message. This is a very long error message. - This is a very long error message. This is a very long error message. - This is a very long error message. This is a very long error message. - This is a very long error message. This is a very long error message. - -
            -
            -
            - -
            -
            -
            -
            -
            - - - Ok - Cancel - -
            -
            -
            - - - + + + +Template for dialogs + + + + +
            +
            +
            +
            +
            +
            +
            + Blured +
            + +
            +
            + Content +
            +
            + +
            +
            +
            +
            + Statusbar text. +
            + + + + + + + + + + + + + + +
            +
            + +
            +
            +
            +
            +
            +
            + Focused +
            + +
            +
            + Content +
            +
            + +
            +
            +
            +
            + Statusbar text. +
            + + + + + + + + + + + + + + +
            +
            + +
            +
            +
            +
            +
            +
            + Statusbar +
            + +
            +
            + Content +
            +
            + +
            +
            +
            +
            + Statusbar text. +
            + + + + + + + + + + + + + + +
            +
            + +
            +
            +
            +
            +
            +
            + Statusbar, Resizable +
            + +
            +
            + Content +
            +
            + +
            +
            +
            +
            + Statusbar text. +
            + + + + + + + + + + + + + + +
            +
            + +
            +
            +
            +
            +
            +
            + Resizable, Maximizable +
            + +
            +
            + Content +
            +
            + +
            +
            +
            +
            + Statusbar text. +
            + + + + + + + + + + + + + + +
            +
            + +
            +
            +
            +
            +
            +
            + Blurred, Maximizable, Statusbar, Resizable +
            + +
            +
            + Content +
            +
            + +
            +
            +
            +
            + Statusbar text. +
            + + + + + + + + + + + + + + +
            +
            + +
            +
            +
            +
            +
            +
            + Maximized, Maximizable, Minimizable +
            + +
            +
            + Content +
            +
            + +
            +
            +
            +
            + Statusbar text. +
            + + + + + + + + + + + + + + +
            +
            + +
            +
            +
            +
            +
            +
            + Blured +
            + +
            +
            + Content +
            +
            + +
            +
            +
            +
            + Statusbar text. +
            + + + + + + + + + + + + + + +
            +
            + +
            +
            +
            +
            +
            +
            + Alert +
            + +
            +
            + + This is a very long error message. This is a very long error message. + This is a very long error message. This is a very long error message. + This is a very long error message. This is a very long error message. + This is a very long error message. This is a very long error message. + This is a very long error message. This is a very long error message. + This is a very long error message. This is a very long error message. + +
            +
            +
            + +
            +
            +
            +
            +
            + + + Ok + +
            +
            + +
            +
            +
            +
            +
            +
            + Confirm +
            + +
            +
            + + This is a very long error message. This is a very long error message. + This is a very long error message. This is a very long error message. + This is a very long error message. This is a very long error message. + This is a very long error message. This is a very long error message. + This is a very long error message. This is a very long error message. + This is a very long error message. This is a very long error message. + +
            +
            +
            + +
            +
            +
            +
            +
            + + + Ok + Cancel + +
            +
            +
            + + + diff --git a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/media/css/media.css b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/media/css/media.css index fd04898..0c45c7f 100644 --- a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/media/css/media.css +++ b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/media/css/media.css @@ -1,17 +1,17 @@ -#id, #name, #hspace, #vspace, #class_name, #align { width: 100px } -#hspace, #vspace { width: 50px } -#flash_quality, #flash_align, #flash_scale, #flash_salign, #flash_wmode { width: 100px } -#flash_base, #flash_flashvars, #html5_altsource1, #html5_altsource2, #html5_poster { width: 240px } -#width, #height { width: 40px } -#src, #media_type { width: 250px } -#class { width: 120px } -#prev { margin: 0; border: 1px solid black; width: 380px; height: 260px; overflow: auto } -.panel_wrapper div.current { height: 420px; overflow: auto } -#flash_options, #shockwave_options, #qt_options, #wmp_options, #rmp_options { display: none } -.mceAddSelectValue { background-color: #DDDDDD } -#qt_starttime, #qt_endtime, #qt_fov, #qt_href, #qt_moveid, #qt_moviename, #qt_node, #qt_pan, #qt_qtsrc, #qt_qtsrcchokespeed, #qt_target, #qt_tilt, #qt_urlsubstituten, #qt_volume { width: 70px } -#wmp_balance, #wmp_baseurl, #wmp_captioningid, #wmp_currentmarker, #wmp_currentposition, #wmp_defaultframe, #wmp_playcount, #wmp_rate, #wmp_uimode, #wmp_volume { width: 70px } -#rmp_console, #rmp_numloop, #rmp_controls, #rmp_scriptcallbacks { width: 70px } -#shockwave_swvolume, #shockwave_swframe, #shockwave_swurl, #shockwave_swstretchvalign, #shockwave_swstretchhalign, #shockwave_swstretchstyle { width: 90px } -#qt_qtsrc { width: 200px } -iframe {border: 1px solid gray} +#id, #name, #hspace, #vspace, #class_name, #align { width: 100px } +#hspace, #vspace { width: 50px } +#flash_quality, #flash_align, #flash_scale, #flash_salign, #flash_wmode { width: 100px } +#flash_base, #flash_flashvars, #html5_altsource1, #html5_altsource2, #html5_poster { width: 240px } +#width, #height { width: 40px } +#src, #media_type { width: 250px } +#class { width: 120px } +#prev { margin: 0; border: 1px solid black; width: 380px; height: 260px; overflow: auto } +.panel_wrapper div.current { height: 420px; overflow: auto } +#flash_options, #shockwave_options, #qt_options, #wmp_options, #rmp_options { display: none } +.mceAddSelectValue { background-color: #DDDDDD } +#qt_starttime, #qt_endtime, #qt_fov, #qt_href, #qt_moveid, #qt_moviename, #qt_node, #qt_pan, #qt_qtsrc, #qt_qtsrcchokespeed, #qt_target, #qt_tilt, #qt_urlsubstituten, #qt_volume { width: 70px } +#wmp_balance, #wmp_baseurl, #wmp_captioningid, #wmp_currentmarker, #wmp_currentposition, #wmp_defaultframe, #wmp_playcount, #wmp_rate, #wmp_uimode, #wmp_volume { width: 70px } +#rmp_console, #rmp_numloop, #rmp_controls, #rmp_scriptcallbacks { width: 70px } +#shockwave_swvolume, #shockwave_swframe, #shockwave_swurl, #shockwave_swstretchvalign, #shockwave_swstretchhalign, #shockwave_swstretchstyle { width: 90px } +#qt_qtsrc { width: 200px } +iframe {border: 1px solid gray} diff --git a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/media/editor_plugin_src.js b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/media/editor_plugin_src.js index b5bc5aa..aee9236 100644 --- a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/media/editor_plugin_src.js +++ b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/media/editor_plugin_src.js @@ -1,898 +1,898 @@ -/** - * editor_plugin_src.js - * - * Copyright 2009, Moxiecode Systems AB - * Released under LGPL License. - * - * License: http://tinymce.moxiecode.com/license - * Contributing: http://tinymce.moxiecode.com/contributing - */ - -(function() { - var rootAttributes = tinymce.explode('id,name,width,height,style,align,class,hspace,vspace,bgcolor,type'), excludedAttrs = tinymce.makeMap(rootAttributes.join(',')), Node = tinymce.html.Node, - mediaTypes, scriptRegExp, JSON = tinymce.util.JSON, mimeTypes; - - // Media types supported by this plugin - mediaTypes = [ - // Type, clsid:s, mime types, codebase - ["Flash", "d27cdb6e-ae6d-11cf-96b8-444553540000", "application/x-shockwave-flash", "http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"], - ["ShockWave", "166b1bca-3f9c-11cf-8075-444553540000", "application/x-director", "http://download.macromedia.com/pub/shockwave/cabs/director/sw.cab#version=8,5,1,0"], - ["WindowsMedia", "6bf52a52-394a-11d3-b153-00c04f79faa6,22d6f312-b0f6-11d0-94ab-0080c74c7e95,05589fa1-c356-11ce-bf01-00aa0055595a", "application/x-mplayer2", "http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=5,1,52,701"], - ["QuickTime", "02bf25d5-8c17-4b23-bc80-d3488abddc6b", "video/quicktime", "http://www.apple.com/qtactivex/qtplugin.cab#version=6,0,2,0"], - ["RealMedia", "cfcdaa03-8be4-11cf-b84b-0020afbbccfa", "audio/x-pn-realaudio-plugin", "http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"], - ["Java", "8ad9c840-044e-11d1-b3e9-00805f499d93", "application/x-java-applet", "http://java.sun.com/products/plugin/autodl/jinstall-1_5_0-windows-i586.cab#Version=1,5,0,0"], - ["Silverlight", "dfeaf541-f3e1-4c24-acac-99c30715084a", "application/x-silverlight-2"], - ["Iframe"], - ["Video"], - ["EmbeddedAudio"], - ["Audio"] - ]; - - function normalizeSize(size) { - return typeof(size) == "string" ? size.replace(/[^0-9%]/g, '') : size; - } - - function toArray(obj) { - var undef, out, i; - - if (obj && !obj.splice) { - out = []; - - for (i = 0; true; i++) { - if (obj[i]) - out[i] = obj[i]; - else - break; - } - - return out; - } - - return obj; - }; - - tinymce.create('tinymce.plugins.MediaPlugin', { - init : function(ed, url) { - var self = this, lookup = {}, i, y, item, name; - - function isMediaImg(node) { - return node && node.nodeName === 'IMG' && ed.dom.hasClass(node, 'mceItemMedia'); - }; - - self.editor = ed; - self.url = url; - - // Parse media types into a lookup table - scriptRegExp = ''; - for (i = 0; i < mediaTypes.length; i++) { - name = mediaTypes[i][0]; - - item = { - name : name, - clsids : tinymce.explode(mediaTypes[i][1] || ''), - mimes : tinymce.explode(mediaTypes[i][2] || ''), - codebase : mediaTypes[i][3] - }; - - for (y = 0; y < item.clsids.length; y++) - lookup['clsid:' + item.clsids[y]] = item; - - for (y = 0; y < item.mimes.length; y++) - lookup[item.mimes[y]] = item; - - lookup['mceItem' + name] = item; - lookup[name.toLowerCase()] = item; - - scriptRegExp += (scriptRegExp ? '|' : '') + name; - } - - // Handle the media_types setting - tinymce.each(ed.getParam("media_types", - "video=mp4,m4v,ogv,webm;" + - "silverlight=xap;" + - "flash=swf,flv;" + - "shockwave=dcr;" + - "quicktime=mov,qt,mpg,mpeg;" + - "shockwave=dcr;" + - "windowsmedia=avi,wmv,wm,asf,asx,wmx,wvx;" + - "realmedia=rm,ra,ram;" + - "java=jar;" + - "audio=mp3,ogg" - ).split(';'), function(item) { - var i, extensions, type; - - item = item.split(/=/); - extensions = tinymce.explode(item[1].toLowerCase()); - for (i = 0; i < extensions.length; i++) { - type = lookup[item[0].toLowerCase()]; - - if (type) - lookup[extensions[i]] = type; - } - }); - - scriptRegExp = new RegExp('write(' + scriptRegExp + ')\\(([^)]+)\\)'); - self.lookup = lookup; - - ed.onPreInit.add(function() { - // Allow video elements - ed.schema.addValidElements('object[id|style|width|height|classid|codebase|*],param[name|value],embed[id|style|width|height|type|src|*],video[*],audio[*],source[*]'); - - // Convert video elements to image placeholder - ed.parser.addNodeFilter('object,embed,video,audio,script,iframe', function(nodes) { - var i = nodes.length; - - while (i--) - self.objectToImg(nodes[i]); - }); - - // Convert image placeholders to video elements - ed.serializer.addNodeFilter('img', function(nodes, name, args) { - var i = nodes.length, node; - - while (i--) { - node = nodes[i]; - if ((node.attr('class') || '').indexOf('mceItemMedia') !== -1) - self.imgToObject(node, args); - } - }); - }); - - ed.onInit.add(function() { - // Display "media" instead of "img" in element path - if (ed.theme && ed.theme.onResolveName) { - ed.theme.onResolveName.add(function(theme, path_object) { - if (path_object.name === 'img' && ed.dom.hasClass(path_object.node, 'mceItemMedia')) - path_object.name = 'media'; - }); - } - - // Add contect menu if it's loaded - if (ed && ed.plugins.contextmenu) { - ed.plugins.contextmenu.onContextMenu.add(function(plugin, menu, element) { - if (element.nodeName === 'IMG' && element.className.indexOf('mceItemMedia') !== -1) - menu.add({title : 'media.edit', icon : 'media', cmd : 'mceMedia'}); - }); - } - }); - - // Register commands - ed.addCommand('mceMedia', function() { - var data, img; - - img = ed.selection.getNode(); - if (isMediaImg(img)) { - data = ed.dom.getAttrib(img, 'data-mce-json'); - if (data) { - data = JSON.parse(data); - - // Add some extra properties to the data object - tinymce.each(rootAttributes, function(name) { - var value = ed.dom.getAttrib(img, name); - - if (value) - data[name] = value; - }); - - data.type = self.getType(img.className).name.toLowerCase(); - } - } - - if (!data) { - data = { - type : 'flash', - video: {sources:[]}, - params: {} - }; - } - - ed.windowManager.open({ - file : url + '/media.htm', - width : 430 + parseInt(ed.getLang('media.delta_width', 0)), - height : 500 + parseInt(ed.getLang('media.delta_height', 0)), - inline : 1 - }, { - plugin_url : url, - data : data - }); - }); - - // Register buttons - ed.addButton('media', {title : 'media.desc', cmd : 'mceMedia'}); - - // Update media selection status - ed.onNodeChange.add(function(ed, cm, node) { - cm.setActive('media', isMediaImg(node)); - }); - }, - - convertUrl : function(url, force_absolute) { - var self = this, editor = self.editor, settings = editor.settings, - urlConverter = settings.url_converter, - urlConverterScope = settings.url_converter_scope || self; - - if (!url) - return url; - - if (force_absolute) - return editor.documentBaseURI.toAbsolute(url); - - return urlConverter.call(urlConverterScope, url, 'src', 'object'); - }, - - getInfo : function() { - return { - longname : 'Media', - author : 'Moxiecode Systems AB', - authorurl : 'http://tinymce.moxiecode.com', - infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/media', - version : tinymce.majorVersion + "." + tinymce.minorVersion - }; - }, - - /** - * Converts the JSON data object to an img node. - */ - dataToImg : function(data, force_absolute) { - var self = this, editor = self.editor, baseUri = editor.documentBaseURI, sources, attrs, img, i; - - data.params.src = self.convertUrl(data.params.src, force_absolute); - - attrs = data.video.attrs; - if (attrs) - attrs.src = self.convertUrl(attrs.src, force_absolute); - - if (attrs) - attrs.poster = self.convertUrl(attrs.poster, force_absolute); - - sources = toArray(data.video.sources); - if (sources) { - for (i = 0; i < sources.length; i++) - sources[i].src = self.convertUrl(sources[i].src, force_absolute); - } - - img = self.editor.dom.create('img', { - id : data.id, - style : data.style, - align : data.align, - hspace : data.hspace, - vspace : data.vspace, - src : self.editor.theme.url + '/img/trans.gif', - 'class' : 'mceItemMedia mceItem' + self.getType(data.type).name, - 'data-mce-json' : JSON.serialize(data, "'") - }); - - img.width = data.width = normalizeSize(data.width || (data.type == 'audio' ? "300" : "320")); - img.height = data.height = normalizeSize(data.height || (data.type == 'audio' ? "32" : "240")); - - return img; - }, - - /** - * Converts the JSON data object to a HTML string. - */ - dataToHtml : function(data, force_absolute) { - return this.editor.serializer.serialize(this.dataToImg(data, force_absolute), {forced_root_block : '', force_absolute : force_absolute}); - }, - - /** - * Converts the JSON data object to a HTML string. - */ - htmlToData : function(html) { - var fragment, img, data; - - data = { - type : 'flash', - video: {sources:[]}, - params: {} - }; - - fragment = this.editor.parser.parse(html); - img = fragment.getAll('img')[0]; - - if (img) { - data = JSON.parse(img.attr('data-mce-json')); - data.type = this.getType(img.attr('class')).name.toLowerCase(); - - // Add some extra properties to the data object - tinymce.each(rootAttributes, function(name) { - var value = img.attr(name); - - if (value) - data[name] = value; - }); - } - - return data; - }, - - /** - * Get type item by extension, class, clsid or mime type. - * - * @method getType - * @param {String} value Value to get type item by. - * @return {Object} Type item object or undefined. - */ - getType : function(value) { - var i, values, typeItem; - - // Find type by checking the classes - values = tinymce.explode(value, ' '); - for (i = 0; i < values.length; i++) { - typeItem = this.lookup[values[i]]; - - if (typeItem) - return typeItem; - } - }, - - /** - * Converts a tinymce.html.Node image element to video/object/embed. - */ - imgToObject : function(node, args) { - var self = this, editor = self.editor, video, object, embed, iframe, name, value, data, - source, sources, params, param, typeItem, i, item, mp4Source, replacement, - posterSrc, style, audio; - - // Adds the flash player - function addPlayer(video_src, poster_src) { - var baseUri, flashVars, flashVarsOutput, params, flashPlayer; - - flashPlayer = editor.getParam('flash_video_player_url', self.convertUrl(self.url + '/moxieplayer.swf')); - if (flashPlayer) { - baseUri = editor.documentBaseURI; - data.params.src = flashPlayer; - - // Convert the movie url to absolute urls - if (editor.getParam('flash_video_player_absvideourl', true)) { - video_src = baseUri.toAbsolute(video_src || '', true); - poster_src = baseUri.toAbsolute(poster_src || '', true); - } - - // Generate flash vars - flashVarsOutput = ''; - flashVars = editor.getParam('flash_video_player_flashvars', {url : '$url', poster : '$poster'}); - tinymce.each(flashVars, function(value, name) { - // Replace $url and $poster variables in flashvars value - value = value.replace(/\$url/, video_src || ''); - value = value.replace(/\$poster/, poster_src || ''); - - if (value.length > 0) - flashVarsOutput += (flashVarsOutput ? '&' : '') + name + '=' + escape(value); - }); - - if (flashVarsOutput.length) - data.params.flashvars = flashVarsOutput; - - params = editor.getParam('flash_video_player_params', { - allowfullscreen: true, - allowscriptaccess: true - }); - - tinymce.each(params, function(value, name) { - data.params[name] = "" + value; - }); - } - }; - - data = node.attr('data-mce-json'); - if (!data) - return; - - data = JSON.parse(data); - typeItem = this.getType(node.attr('class')); - - style = node.attr('data-mce-style') - if (!style) { - style = node.attr('style'); - - if (style) - style = editor.dom.serializeStyle(editor.dom.parseStyle(style, 'img')); - } - - // Use node width/height to override the data width/height when the placeholder is resized - data.width = node.attr('width') || data.width; - data.height = node.attr('height') || data.height; - - // Handle iframe - if (typeItem.name === 'Iframe') { - replacement = new Node('iframe', 1); - - tinymce.each(rootAttributes, function(name) { - var value = node.attr(name); - - if (name == 'class' && value) - value = value.replace(/mceItem.+ ?/g, ''); - - if (value && value.length > 0) - replacement.attr(name, value); - }); - - for (name in data.params) - replacement.attr(name, data.params[name]); - - replacement.attr({ - style: style, - src: data.params.src - }); - - node.replace(replacement); - - return; - } - - // Handle scripts - if (this.editor.settings.media_use_script) { - replacement = new Node('script', 1).attr('type', 'text/javascript'); - - value = new Node('#text', 3); - value.value = 'write' + typeItem.name + '(' + JSON.serialize(tinymce.extend(data.params, { - width: node.attr('width'), - height: node.attr('height') - })) + ');'; - - replacement.append(value); - node.replace(replacement); - - return; - } - - // Add HTML5 video element - if (typeItem.name === 'Video' && data.video.sources[0]) { - // Create new object element - video = new Node('video', 1).attr(tinymce.extend({ - id : node.attr('id'), - width: normalizeSize(node.attr('width')), - height: normalizeSize(node.attr('height')), - style : style - }, data.video.attrs)); - - // Get poster source and use that for flash fallback - if (data.video.attrs) - posterSrc = data.video.attrs.poster; - - sources = data.video.sources = toArray(data.video.sources); - for (i = 0; i < sources.length; i++) { - if (/\.mp4$/.test(sources[i].src)) - mp4Source = sources[i].src; - } - - if (!sources[0].type) { - video.attr('src', sources[0].src); - sources.splice(0, 1); - } - - for (i = 0; i < sources.length; i++) { - source = new Node('source', 1).attr(sources[i]); - source.shortEnded = true; - video.append(source); - } - - // Create flash fallback for video if we have a mp4 source - if (mp4Source) { - addPlayer(mp4Source, posterSrc); - typeItem = self.getType('flash'); - } else - data.params.src = ''; - } - - // Add HTML5 audio element - if (typeItem.name === 'Audio' && data.video.sources[0]) { - // Create new object element - audio = new Node('audio', 1).attr(tinymce.extend({ - id : node.attr('id'), - width: normalizeSize(node.attr('width')), - height: normalizeSize(node.attr('height')), - style : style - }, data.video.attrs)); - - // Get poster source and use that for flash fallback - if (data.video.attrs) - posterSrc = data.video.attrs.poster; - - sources = data.video.sources = toArray(data.video.sources); - if (!sources[0].type) { - audio.attr('src', sources[0].src); - sources.splice(0, 1); - } - - for (i = 0; i < sources.length; i++) { - source = new Node('source', 1).attr(sources[i]); - source.shortEnded = true; - audio.append(source); - } - - data.params.src = ''; - } - - if (typeItem.name === 'EmbeddedAudio') { - embed = new Node('embed', 1); - embed.shortEnded = true; - embed.attr({ - id: node.attr('id'), - width: normalizeSize(node.attr('width')), - height: normalizeSize(node.attr('height')), - style : style, - type: node.attr('type') - }); - - for (name in data.params) - embed.attr(name, data.params[name]); - - tinymce.each(rootAttributes, function(name) { - if (data[name] && name != 'type') - embed.attr(name, data[name]); - }); - - data.params.src = ''; - } - - // Do we have a params src then we can generate object - if (data.params.src) { - // Is flv movie add player for it - if (/\.flv$/i.test(data.params.src)) - addPlayer(data.params.src, ''); - - if (args && args.force_absolute) - data.params.src = editor.documentBaseURI.toAbsolute(data.params.src); - - // Create new object element - object = new Node('object', 1).attr({ - id : node.attr('id'), - width: normalizeSize(node.attr('width')), - height: normalizeSize(node.attr('height')), - style : style - }); - - tinymce.each(rootAttributes, function(name) { - var value = data[name]; - - if (name == 'class' && value) - value = value.replace(/mceItem.+ ?/g, ''); - - if (value && name != 'type') - object.attr(name, value); - }); - - // Add params - for (name in data.params) { - param = new Node('param', 1); - param.shortEnded = true; - value = data.params[name]; - - // Windows media needs to use url instead of src for the media URL - if (name === 'src' && typeItem.name === 'WindowsMedia') - name = 'url'; - - param.attr({name: name, value: value}); - object.append(param); - } - - // Setup add type and classid if strict is disabled - if (this.editor.getParam('media_strict', true)) { - object.attr({ - data: data.params.src, - type: typeItem.mimes[0] - }); - } else { - object.attr({ - classid: "clsid:" + typeItem.clsids[0], - codebase: typeItem.codebase - }); - - embed = new Node('embed', 1); - embed.shortEnded = true; - embed.attr({ - id: node.attr('id'), - width: normalizeSize(node.attr('width')), - height: normalizeSize(node.attr('height')), - style : style, - type: typeItem.mimes[0] - }); - - for (name in data.params) - embed.attr(name, data.params[name]); - - tinymce.each(rootAttributes, function(name) { - if (data[name] && name != 'type') - embed.attr(name, data[name]); - }); - - object.append(embed); - } - - // Insert raw HTML - if (data.object_html) { - value = new Node('#text', 3); - value.raw = true; - value.value = data.object_html; - object.append(value); - } - - // Append object to video element if it exists - if (video) - video.append(object); - } - - if (video) { - // Insert raw HTML - if (data.video_html) { - value = new Node('#text', 3); - value.raw = true; - value.value = data.video_html; - video.append(value); - } - } - - if (audio) { - // Insert raw HTML - if (data.video_html) { - value = new Node('#text', 3); - value.raw = true; - value.value = data.video_html; - audio.append(value); - } - } - - var n = video || audio || object || embed; - if (n) - node.replace(n); - else - node.remove(); - }, - - /** - * Converts a tinymce.html.Node video/object/embed to an img element. - * - * The video/object/embed will be converted into an image placeholder with a JSON data attribute like this: - * - * - * The JSON structure will be like this: - * {'params':{'flashvars':'something','quality':'high','src':'someurl'}, 'video':{'sources':[{src: 'someurl', type: 'video/mp4'}]}} - */ - objectToImg : function(node) { - var object, embed, video, iframe, img, name, id, width, height, style, i, html, - param, params, source, sources, data, type, lookup = this.lookup, - matches, attrs, urlConverter = this.editor.settings.url_converter, - urlConverterScope = this.editor.settings.url_converter_scope, - hspace, vspace, align, bgcolor; - - function getInnerHTML(node) { - return new tinymce.html.Serializer({ - inner: true, - validate: false - }).serialize(node); - }; - - function lookupAttribute(o, attr) { - return lookup[(o.attr(attr) || '').toLowerCase()]; - } - - function lookupExtension(src) { - var ext = src.replace(/^.*\.([^.]+)$/, '$1'); - return lookup[ext.toLowerCase() || '']; - } - - // If node isn't in document - if (!node.parent) - return; - - // Handle media scripts - if (node.name === 'script') { - if (node.firstChild) - matches = scriptRegExp.exec(node.firstChild.value); - - if (!matches) - return; - - type = matches[1]; - data = {video : {}, params : JSON.parse(matches[2])}; - width = data.params.width; - height = data.params.height; - } - - // Setup data objects - data = data || { - video : {}, - params : {} - }; - - // Setup new image object - img = new Node('img', 1); - img.attr({ - src : this.editor.theme.url + '/img/trans.gif' - }); - - // Video element - name = node.name; - if (name === 'video' || name == 'audio') { - video = node; - object = node.getAll('object')[0]; - embed = node.getAll('embed')[0]; - width = video.attr('width'); - height = video.attr('height'); - id = video.attr('id'); - data.video = {attrs : {}, sources : []}; - - // Get all video attributes - attrs = data.video.attrs; - for (name in video.attributes.map) - attrs[name] = video.attributes.map[name]; - - source = node.attr('src'); - if (source) - data.video.sources.push({src : urlConverter.call(urlConverterScope, source, 'src', node.name)}); - - // Get all sources - sources = video.getAll("source"); - for (i = 0; i < sources.length; i++) { - source = sources[i].remove(); - - data.video.sources.push({ - src: urlConverter.call(urlConverterScope, source.attr('src'), 'src', 'source'), - type: source.attr('type'), - media: source.attr('media') - }); - } - - // Convert the poster URL - if (attrs.poster) - attrs.poster = urlConverter.call(urlConverterScope, attrs.poster, 'poster', node.name); - } - - // Object element - if (node.name === 'object') { - object = node; - embed = node.getAll('embed')[0]; - } - - // Embed element - if (node.name === 'embed') - embed = node; - - // Iframe element - if (node.name === 'iframe') { - iframe = node; - type = 'Iframe'; - } - - if (object) { - // Get width/height - width = width || object.attr('width'); - height = height || object.attr('height'); - style = style || object.attr('style'); - id = id || object.attr('id'); - hspace = hspace || object.attr('hspace'); - vspace = vspace || object.attr('vspace'); - align = align || object.attr('align'); - bgcolor = bgcolor || object.attr('bgcolor'); - data.name = object.attr('name'); - - // Get all object params - params = object.getAll("param"); - for (i = 0; i < params.length; i++) { - param = params[i]; - name = param.remove().attr('name'); - - if (!excludedAttrs[name]) - data.params[name] = param.attr('value'); - } - - data.params.src = data.params.src || object.attr('data'); - } - - if (embed) { - // Get width/height - width = width || embed.attr('width'); - height = height || embed.attr('height'); - style = style || embed.attr('style'); - id = id || embed.attr('id'); - hspace = hspace || embed.attr('hspace'); - vspace = vspace || embed.attr('vspace'); - align = align || embed.attr('align'); - bgcolor = bgcolor || embed.attr('bgcolor'); - - // Get all embed attributes - for (name in embed.attributes.map) { - if (!excludedAttrs[name] && !data.params[name]) - data.params[name] = embed.attributes.map[name]; - } - } - - if (iframe) { - // Get width/height - width = normalizeSize(iframe.attr('width')); - height = normalizeSize(iframe.attr('height')); - style = style || iframe.attr('style'); - id = iframe.attr('id'); - hspace = iframe.attr('hspace'); - vspace = iframe.attr('vspace'); - align = iframe.attr('align'); - bgcolor = iframe.attr('bgcolor'); - - tinymce.each(rootAttributes, function(name) { - img.attr(name, iframe.attr(name)); - }); - - // Get all iframe attributes - for (name in iframe.attributes.map) { - if (!excludedAttrs[name] && !data.params[name]) - data.params[name] = iframe.attributes.map[name]; - } - } - - // Use src not movie - if (data.params.movie) { - data.params.src = data.params.src || data.params.movie; - delete data.params.movie; - } - - // Convert the URL to relative/absolute depending on configuration - if (data.params.src) - data.params.src = urlConverter.call(urlConverterScope, data.params.src, 'src', 'object'); - - if (video) { - if (node.name === 'video') - type = lookup.video.name; - else if (node.name === 'audio') - type = lookup.audio.name; - } - - if (object && !type) - type = (lookupAttribute(object, 'clsid') || lookupAttribute(object, 'classid') || lookupAttribute(object, 'type') || {}).name; - - if (embed && !type) - type = (lookupAttribute(embed, 'type') || lookupExtension(data.params.src) || {}).name; - - // for embedded audio we preserve the original specified type - if (embed && type == 'EmbeddedAudio') { - data.params.type = embed.attr('type'); - } - - // Replace the video/object/embed element with a placeholder image containing the data - node.replace(img); - - // Remove embed - if (embed) - embed.remove(); - - // Serialize the inner HTML of the object element - if (object) { - html = getInnerHTML(object.remove()); - - if (html) - data.object_html = html; - } - - // Serialize the inner HTML of the video element - if (video) { - html = getInnerHTML(video.remove()); - - if (html) - data.video_html = html; - } - - data.hspace = hspace; - data.vspace = vspace; - data.align = align; - data.bgcolor = bgcolor; - - // Set width/height of placeholder - img.attr({ - id : id, - 'class' : 'mceItemMedia mceItem' + (type || 'Flash'), - style : style, - width : width || (node.name == 'audio' ? "300" : "320"), - height : height || (node.name == 'audio' ? "32" : "240"), - hspace : hspace, - vspace : vspace, - align : align, - bgcolor : bgcolor, - "data-mce-json" : JSON.serialize(data, "'") - }); - } - }); - - // Register plugin - tinymce.PluginManager.add('media', tinymce.plugins.MediaPlugin); -})(); +/** + * editor_plugin_src.js + * + * Copyright 2009, Moxiecode Systems AB + * Released under LGPL License. + * + * License: http://tinymce.moxiecode.com/license + * Contributing: http://tinymce.moxiecode.com/contributing + */ + +(function() { + var rootAttributes = tinymce.explode('id,name,width,height,style,align,class,hspace,vspace,bgcolor,type'), excludedAttrs = tinymce.makeMap(rootAttributes.join(',')), Node = tinymce.html.Node, + mediaTypes, scriptRegExp, JSON = tinymce.util.JSON, mimeTypes; + + // Media types supported by this plugin + mediaTypes = [ + // Type, clsid:s, mime types, codebase + ["Flash", "d27cdb6e-ae6d-11cf-96b8-444553540000", "application/x-shockwave-flash", "http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"], + ["ShockWave", "166b1bca-3f9c-11cf-8075-444553540000", "application/x-director", "http://download.macromedia.com/pub/shockwave/cabs/director/sw.cab#version=8,5,1,0"], + ["WindowsMedia", "6bf52a52-394a-11d3-b153-00c04f79faa6,22d6f312-b0f6-11d0-94ab-0080c74c7e95,05589fa1-c356-11ce-bf01-00aa0055595a", "application/x-mplayer2", "http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=5,1,52,701"], + ["QuickTime", "02bf25d5-8c17-4b23-bc80-d3488abddc6b", "video/quicktime", "http://www.apple.com/qtactivex/qtplugin.cab#version=6,0,2,0"], + ["RealMedia", "cfcdaa03-8be4-11cf-b84b-0020afbbccfa", "audio/x-pn-realaudio-plugin", "http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"], + ["Java", "8ad9c840-044e-11d1-b3e9-00805f499d93", "application/x-java-applet", "http://java.sun.com/products/plugin/autodl/jinstall-1_5_0-windows-i586.cab#Version=1,5,0,0"], + ["Silverlight", "dfeaf541-f3e1-4c24-acac-99c30715084a", "application/x-silverlight-2"], + ["Iframe"], + ["Video"], + ["EmbeddedAudio"], + ["Audio"] + ]; + + function normalizeSize(size) { + return typeof(size) == "string" ? size.replace(/[^0-9%]/g, '') : size; + } + + function toArray(obj) { + var undef, out, i; + + if (obj && !obj.splice) { + out = []; + + for (i = 0; true; i++) { + if (obj[i]) + out[i] = obj[i]; + else + break; + } + + return out; + } + + return obj; + }; + + tinymce.create('tinymce.plugins.MediaPlugin', { + init : function(ed, url) { + var self = this, lookup = {}, i, y, item, name; + + function isMediaImg(node) { + return node && node.nodeName === 'IMG' && ed.dom.hasClass(node, 'mceItemMedia'); + }; + + self.editor = ed; + self.url = url; + + // Parse media types into a lookup table + scriptRegExp = ''; + for (i = 0; i < mediaTypes.length; i++) { + name = mediaTypes[i][0]; + + item = { + name : name, + clsids : tinymce.explode(mediaTypes[i][1] || ''), + mimes : tinymce.explode(mediaTypes[i][2] || ''), + codebase : mediaTypes[i][3] + }; + + for (y = 0; y < item.clsids.length; y++) + lookup['clsid:' + item.clsids[y]] = item; + + for (y = 0; y < item.mimes.length; y++) + lookup[item.mimes[y]] = item; + + lookup['mceItem' + name] = item; + lookup[name.toLowerCase()] = item; + + scriptRegExp += (scriptRegExp ? '|' : '') + name; + } + + // Handle the media_types setting + tinymce.each(ed.getParam("media_types", + "video=mp4,m4v,ogv,webm;" + + "silverlight=xap;" + + "flash=swf,flv;" + + "shockwave=dcr;" + + "quicktime=mov,qt,mpg,mpeg;" + + "shockwave=dcr;" + + "windowsmedia=avi,wmv,wm,asf,asx,wmx,wvx;" + + "realmedia=rm,ra,ram;" + + "java=jar;" + + "audio=mp3,ogg" + ).split(';'), function(item) { + var i, extensions, type; + + item = item.split(/=/); + extensions = tinymce.explode(item[1].toLowerCase()); + for (i = 0; i < extensions.length; i++) { + type = lookup[item[0].toLowerCase()]; + + if (type) + lookup[extensions[i]] = type; + } + }); + + scriptRegExp = new RegExp('write(' + scriptRegExp + ')\\(([^)]+)\\)'); + self.lookup = lookup; + + ed.onPreInit.add(function() { + // Allow video elements + ed.schema.addValidElements('object[id|style|width|height|classid|codebase|*],param[name|value],embed[id|style|width|height|type|src|*],video[*],audio[*],source[*]'); + + // Convert video elements to image placeholder + ed.parser.addNodeFilter('object,embed,video,audio,script,iframe', function(nodes) { + var i = nodes.length; + + while (i--) + self.objectToImg(nodes[i]); + }); + + // Convert image placeholders to video elements + ed.serializer.addNodeFilter('img', function(nodes, name, args) { + var i = nodes.length, node; + + while (i--) { + node = nodes[i]; + if ((node.attr('class') || '').indexOf('mceItemMedia') !== -1) + self.imgToObject(node, args); + } + }); + }); + + ed.onInit.add(function() { + // Display "media" instead of "img" in element path + if (ed.theme && ed.theme.onResolveName) { + ed.theme.onResolveName.add(function(theme, path_object) { + if (path_object.name === 'img' && ed.dom.hasClass(path_object.node, 'mceItemMedia')) + path_object.name = 'media'; + }); + } + + // Add contect menu if it's loaded + if (ed && ed.plugins.contextmenu) { + ed.plugins.contextmenu.onContextMenu.add(function(plugin, menu, element) { + if (element.nodeName === 'IMG' && element.className.indexOf('mceItemMedia') !== -1) + menu.add({title : 'media.edit', icon : 'media', cmd : 'mceMedia'}); + }); + } + }); + + // Register commands + ed.addCommand('mceMedia', function() { + var data, img; + + img = ed.selection.getNode(); + if (isMediaImg(img)) { + data = ed.dom.getAttrib(img, 'data-mce-json'); + if (data) { + data = JSON.parse(data); + + // Add some extra properties to the data object + tinymce.each(rootAttributes, function(name) { + var value = ed.dom.getAttrib(img, name); + + if (value) + data[name] = value; + }); + + data.type = self.getType(img.className).name.toLowerCase(); + } + } + + if (!data) { + data = { + type : 'flash', + video: {sources:[]}, + params: {} + }; + } + + ed.windowManager.open({ + file : url + '/media.htm', + width : 430 + parseInt(ed.getLang('media.delta_width', 0)), + height : 500 + parseInt(ed.getLang('media.delta_height', 0)), + inline : 1 + }, { + plugin_url : url, + data : data + }); + }); + + // Register buttons + ed.addButton('media', {title : 'media.desc', cmd : 'mceMedia'}); + + // Update media selection status + ed.onNodeChange.add(function(ed, cm, node) { + cm.setActive('media', isMediaImg(node)); + }); + }, + + convertUrl : function(url, force_absolute) { + var self = this, editor = self.editor, settings = editor.settings, + urlConverter = settings.url_converter, + urlConverterScope = settings.url_converter_scope || self; + + if (!url) + return url; + + if (force_absolute) + return editor.documentBaseURI.toAbsolute(url); + + return urlConverter.call(urlConverterScope, url, 'src', 'object'); + }, + + getInfo : function() { + return { + longname : 'Media', + author : 'Moxiecode Systems AB', + authorurl : 'http://tinymce.moxiecode.com', + infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/media', + version : tinymce.majorVersion + "." + tinymce.minorVersion + }; + }, + + /** + * Converts the JSON data object to an img node. + */ + dataToImg : function(data, force_absolute) { + var self = this, editor = self.editor, baseUri = editor.documentBaseURI, sources, attrs, img, i; + + data.params.src = self.convertUrl(data.params.src, force_absolute); + + attrs = data.video.attrs; + if (attrs) + attrs.src = self.convertUrl(attrs.src, force_absolute); + + if (attrs) + attrs.poster = self.convertUrl(attrs.poster, force_absolute); + + sources = toArray(data.video.sources); + if (sources) { + for (i = 0; i < sources.length; i++) + sources[i].src = self.convertUrl(sources[i].src, force_absolute); + } + + img = self.editor.dom.create('img', { + id : data.id, + style : data.style, + align : data.align, + hspace : data.hspace, + vspace : data.vspace, + src : self.editor.theme.url + '/img/trans.gif', + 'class' : 'mceItemMedia mceItem' + self.getType(data.type).name, + 'data-mce-json' : JSON.serialize(data, "'") + }); + + img.width = data.width = normalizeSize(data.width || (data.type == 'audio' ? "300" : "320")); + img.height = data.height = normalizeSize(data.height || (data.type == 'audio' ? "32" : "240")); + + return img; + }, + + /** + * Converts the JSON data object to a HTML string. + */ + dataToHtml : function(data, force_absolute) { + return this.editor.serializer.serialize(this.dataToImg(data, force_absolute), {forced_root_block : '', force_absolute : force_absolute}); + }, + + /** + * Converts the JSON data object to a HTML string. + */ + htmlToData : function(html) { + var fragment, img, data; + + data = { + type : 'flash', + video: {sources:[]}, + params: {} + }; + + fragment = this.editor.parser.parse(html); + img = fragment.getAll('img')[0]; + + if (img) { + data = JSON.parse(img.attr('data-mce-json')); + data.type = this.getType(img.attr('class')).name.toLowerCase(); + + // Add some extra properties to the data object + tinymce.each(rootAttributes, function(name) { + var value = img.attr(name); + + if (value) + data[name] = value; + }); + } + + return data; + }, + + /** + * Get type item by extension, class, clsid or mime type. + * + * @method getType + * @param {String} value Value to get type item by. + * @return {Object} Type item object or undefined. + */ + getType : function(value) { + var i, values, typeItem; + + // Find type by checking the classes + values = tinymce.explode(value, ' '); + for (i = 0; i < values.length; i++) { + typeItem = this.lookup[values[i]]; + + if (typeItem) + return typeItem; + } + }, + + /** + * Converts a tinymce.html.Node image element to video/object/embed. + */ + imgToObject : function(node, args) { + var self = this, editor = self.editor, video, object, embed, iframe, name, value, data, + source, sources, params, param, typeItem, i, item, mp4Source, replacement, + posterSrc, style, audio; + + // Adds the flash player + function addPlayer(video_src, poster_src) { + var baseUri, flashVars, flashVarsOutput, params, flashPlayer; + + flashPlayer = editor.getParam('flash_video_player_url', self.convertUrl(self.url + '/moxieplayer.swf')); + if (flashPlayer) { + baseUri = editor.documentBaseURI; + data.params.src = flashPlayer; + + // Convert the movie url to absolute urls + if (editor.getParam('flash_video_player_absvideourl', true)) { + video_src = baseUri.toAbsolute(video_src || '', true); + poster_src = baseUri.toAbsolute(poster_src || '', true); + } + + // Generate flash vars + flashVarsOutput = ''; + flashVars = editor.getParam('flash_video_player_flashvars', {url : '$url', poster : '$poster'}); + tinymce.each(flashVars, function(value, name) { + // Replace $url and $poster variables in flashvars value + value = value.replace(/\$url/, video_src || ''); + value = value.replace(/\$poster/, poster_src || ''); + + if (value.length > 0) + flashVarsOutput += (flashVarsOutput ? '&' : '') + name + '=' + escape(value); + }); + + if (flashVarsOutput.length) + data.params.flashvars = flashVarsOutput; + + params = editor.getParam('flash_video_player_params', { + allowfullscreen: true, + allowscriptaccess: true + }); + + tinymce.each(params, function(value, name) { + data.params[name] = "" + value; + }); + } + }; + + data = node.attr('data-mce-json'); + if (!data) + return; + + data = JSON.parse(data); + typeItem = this.getType(node.attr('class')); + + style = node.attr('data-mce-style') + if (!style) { + style = node.attr('style'); + + if (style) + style = editor.dom.serializeStyle(editor.dom.parseStyle(style, 'img')); + } + + // Use node width/height to override the data width/height when the placeholder is resized + data.width = node.attr('width') || data.width; + data.height = node.attr('height') || data.height; + + // Handle iframe + if (typeItem.name === 'Iframe') { + replacement = new Node('iframe', 1); + + tinymce.each(rootAttributes, function(name) { + var value = node.attr(name); + + if (name == 'class' && value) + value = value.replace(/mceItem.+ ?/g, ''); + + if (value && value.length > 0) + replacement.attr(name, value); + }); + + for (name in data.params) + replacement.attr(name, data.params[name]); + + replacement.attr({ + style: style, + src: data.params.src + }); + + node.replace(replacement); + + return; + } + + // Handle scripts + if (this.editor.settings.media_use_script) { + replacement = new Node('script', 1).attr('type', 'text/javascript'); + + value = new Node('#text', 3); + value.value = 'write' + typeItem.name + '(' + JSON.serialize(tinymce.extend(data.params, { + width: node.attr('width'), + height: node.attr('height') + })) + ');'; + + replacement.append(value); + node.replace(replacement); + + return; + } + + // Add HTML5 video element + if (typeItem.name === 'Video' && data.video.sources[0]) { + // Create new object element + video = new Node('video', 1).attr(tinymce.extend({ + id : node.attr('id'), + width: normalizeSize(node.attr('width')), + height: normalizeSize(node.attr('height')), + style : style + }, data.video.attrs)); + + // Get poster source and use that for flash fallback + if (data.video.attrs) + posterSrc = data.video.attrs.poster; + + sources = data.video.sources = toArray(data.video.sources); + for (i = 0; i < sources.length; i++) { + if (/\.mp4$/.test(sources[i].src)) + mp4Source = sources[i].src; + } + + if (!sources[0].type) { + video.attr('src', sources[0].src); + sources.splice(0, 1); + } + + for (i = 0; i < sources.length; i++) { + source = new Node('source', 1).attr(sources[i]); + source.shortEnded = true; + video.append(source); + } + + // Create flash fallback for video if we have a mp4 source + if (mp4Source) { + addPlayer(mp4Source, posterSrc); + typeItem = self.getType('flash'); + } else + data.params.src = ''; + } + + // Add HTML5 audio element + if (typeItem.name === 'Audio' && data.video.sources[0]) { + // Create new object element + audio = new Node('audio', 1).attr(tinymce.extend({ + id : node.attr('id'), + width: normalizeSize(node.attr('width')), + height: normalizeSize(node.attr('height')), + style : style + }, data.video.attrs)); + + // Get poster source and use that for flash fallback + if (data.video.attrs) + posterSrc = data.video.attrs.poster; + + sources = data.video.sources = toArray(data.video.sources); + if (!sources[0].type) { + audio.attr('src', sources[0].src); + sources.splice(0, 1); + } + + for (i = 0; i < sources.length; i++) { + source = new Node('source', 1).attr(sources[i]); + source.shortEnded = true; + audio.append(source); + } + + data.params.src = ''; + } + + if (typeItem.name === 'EmbeddedAudio') { + embed = new Node('embed', 1); + embed.shortEnded = true; + embed.attr({ + id: node.attr('id'), + width: normalizeSize(node.attr('width')), + height: normalizeSize(node.attr('height')), + style : style, + type: node.attr('type') + }); + + for (name in data.params) + embed.attr(name, data.params[name]); + + tinymce.each(rootAttributes, function(name) { + if (data[name] && name != 'type') + embed.attr(name, data[name]); + }); + + data.params.src = ''; + } + + // Do we have a params src then we can generate object + if (data.params.src) { + // Is flv movie add player for it + if (/\.flv$/i.test(data.params.src)) + addPlayer(data.params.src, ''); + + if (args && args.force_absolute) + data.params.src = editor.documentBaseURI.toAbsolute(data.params.src); + + // Create new object element + object = new Node('object', 1).attr({ + id : node.attr('id'), + width: normalizeSize(node.attr('width')), + height: normalizeSize(node.attr('height')), + style : style + }); + + tinymce.each(rootAttributes, function(name) { + var value = data[name]; + + if (name == 'class' && value) + value = value.replace(/mceItem.+ ?/g, ''); + + if (value && name != 'type') + object.attr(name, value); + }); + + // Add params + for (name in data.params) { + param = new Node('param', 1); + param.shortEnded = true; + value = data.params[name]; + + // Windows media needs to use url instead of src for the media URL + if (name === 'src' && typeItem.name === 'WindowsMedia') + name = 'url'; + + param.attr({name: name, value: value}); + object.append(param); + } + + // Setup add type and classid if strict is disabled + if (this.editor.getParam('media_strict', true)) { + object.attr({ + data: data.params.src, + type: typeItem.mimes[0] + }); + } else { + object.attr({ + classid: "clsid:" + typeItem.clsids[0], + codebase: typeItem.codebase + }); + + embed = new Node('embed', 1); + embed.shortEnded = true; + embed.attr({ + id: node.attr('id'), + width: normalizeSize(node.attr('width')), + height: normalizeSize(node.attr('height')), + style : style, + type: typeItem.mimes[0] + }); + + for (name in data.params) + embed.attr(name, data.params[name]); + + tinymce.each(rootAttributes, function(name) { + if (data[name] && name != 'type') + embed.attr(name, data[name]); + }); + + object.append(embed); + } + + // Insert raw HTML + if (data.object_html) { + value = new Node('#text', 3); + value.raw = true; + value.value = data.object_html; + object.append(value); + } + + // Append object to video element if it exists + if (video) + video.append(object); + } + + if (video) { + // Insert raw HTML + if (data.video_html) { + value = new Node('#text', 3); + value.raw = true; + value.value = data.video_html; + video.append(value); + } + } + + if (audio) { + // Insert raw HTML + if (data.video_html) { + value = new Node('#text', 3); + value.raw = true; + value.value = data.video_html; + audio.append(value); + } + } + + var n = video || audio || object || embed; + if (n) + node.replace(n); + else + node.remove(); + }, + + /** + * Converts a tinymce.html.Node video/object/embed to an img element. + * + * The video/object/embed will be converted into an image placeholder with a JSON data attribute like this: + * + * + * The JSON structure will be like this: + * {'params':{'flashvars':'something','quality':'high','src':'someurl'}, 'video':{'sources':[{src: 'someurl', type: 'video/mp4'}]}} + */ + objectToImg : function(node) { + var object, embed, video, iframe, img, name, id, width, height, style, i, html, + param, params, source, sources, data, type, lookup = this.lookup, + matches, attrs, urlConverter = this.editor.settings.url_converter, + urlConverterScope = this.editor.settings.url_converter_scope, + hspace, vspace, align, bgcolor; + + function getInnerHTML(node) { + return new tinymce.html.Serializer({ + inner: true, + validate: false + }).serialize(node); + }; + + function lookupAttribute(o, attr) { + return lookup[(o.attr(attr) || '').toLowerCase()]; + } + + function lookupExtension(src) { + var ext = src.replace(/^.*\.([^.]+)$/, '$1'); + return lookup[ext.toLowerCase() || '']; + } + + // If node isn't in document + if (!node.parent) + return; + + // Handle media scripts + if (node.name === 'script') { + if (node.firstChild) + matches = scriptRegExp.exec(node.firstChild.value); + + if (!matches) + return; + + type = matches[1]; + data = {video : {}, params : JSON.parse(matches[2])}; + width = data.params.width; + height = data.params.height; + } + + // Setup data objects + data = data || { + video : {}, + params : {} + }; + + // Setup new image object + img = new Node('img', 1); + img.attr({ + src : this.editor.theme.url + '/img/trans.gif' + }); + + // Video element + name = node.name; + if (name === 'video' || name == 'audio') { + video = node; + object = node.getAll('object')[0]; + embed = node.getAll('embed')[0]; + width = video.attr('width'); + height = video.attr('height'); + id = video.attr('id'); + data.video = {attrs : {}, sources : []}; + + // Get all video attributes + attrs = data.video.attrs; + for (name in video.attributes.map) + attrs[name] = video.attributes.map[name]; + + source = node.attr('src'); + if (source) + data.video.sources.push({src : urlConverter.call(urlConverterScope, source, 'src', node.name)}); + + // Get all sources + sources = video.getAll("source"); + for (i = 0; i < sources.length; i++) { + source = sources[i].remove(); + + data.video.sources.push({ + src: urlConverter.call(urlConverterScope, source.attr('src'), 'src', 'source'), + type: source.attr('type'), + media: source.attr('media') + }); + } + + // Convert the poster URL + if (attrs.poster) + attrs.poster = urlConverter.call(urlConverterScope, attrs.poster, 'poster', node.name); + } + + // Object element + if (node.name === 'object') { + object = node; + embed = node.getAll('embed')[0]; + } + + // Embed element + if (node.name === 'embed') + embed = node; + + // Iframe element + if (node.name === 'iframe') { + iframe = node; + type = 'Iframe'; + } + + if (object) { + // Get width/height + width = width || object.attr('width'); + height = height || object.attr('height'); + style = style || object.attr('style'); + id = id || object.attr('id'); + hspace = hspace || object.attr('hspace'); + vspace = vspace || object.attr('vspace'); + align = align || object.attr('align'); + bgcolor = bgcolor || object.attr('bgcolor'); + data.name = object.attr('name'); + + // Get all object params + params = object.getAll("param"); + for (i = 0; i < params.length; i++) { + param = params[i]; + name = param.remove().attr('name'); + + if (!excludedAttrs[name]) + data.params[name] = param.attr('value'); + } + + data.params.src = data.params.src || object.attr('data'); + } + + if (embed) { + // Get width/height + width = width || embed.attr('width'); + height = height || embed.attr('height'); + style = style || embed.attr('style'); + id = id || embed.attr('id'); + hspace = hspace || embed.attr('hspace'); + vspace = vspace || embed.attr('vspace'); + align = align || embed.attr('align'); + bgcolor = bgcolor || embed.attr('bgcolor'); + + // Get all embed attributes + for (name in embed.attributes.map) { + if (!excludedAttrs[name] && !data.params[name]) + data.params[name] = embed.attributes.map[name]; + } + } + + if (iframe) { + // Get width/height + width = normalizeSize(iframe.attr('width')); + height = normalizeSize(iframe.attr('height')); + style = style || iframe.attr('style'); + id = iframe.attr('id'); + hspace = iframe.attr('hspace'); + vspace = iframe.attr('vspace'); + align = iframe.attr('align'); + bgcolor = iframe.attr('bgcolor'); + + tinymce.each(rootAttributes, function(name) { + img.attr(name, iframe.attr(name)); + }); + + // Get all iframe attributes + for (name in iframe.attributes.map) { + if (!excludedAttrs[name] && !data.params[name]) + data.params[name] = iframe.attributes.map[name]; + } + } + + // Use src not movie + if (data.params.movie) { + data.params.src = data.params.src || data.params.movie; + delete data.params.movie; + } + + // Convert the URL to relative/absolute depending on configuration + if (data.params.src) + data.params.src = urlConverter.call(urlConverterScope, data.params.src, 'src', 'object'); + + if (video) { + if (node.name === 'video') + type = lookup.video.name; + else if (node.name === 'audio') + type = lookup.audio.name; + } + + if (object && !type) + type = (lookupAttribute(object, 'clsid') || lookupAttribute(object, 'classid') || lookupAttribute(object, 'type') || {}).name; + + if (embed && !type) + type = (lookupAttribute(embed, 'type') || lookupExtension(data.params.src) || {}).name; + + // for embedded audio we preserve the original specified type + if (embed && type == 'EmbeddedAudio') { + data.params.type = embed.attr('type'); + } + + // Replace the video/object/embed element with a placeholder image containing the data + node.replace(img); + + // Remove embed + if (embed) + embed.remove(); + + // Serialize the inner HTML of the object element + if (object) { + html = getInnerHTML(object.remove()); + + if (html) + data.object_html = html; + } + + // Serialize the inner HTML of the video element + if (video) { + html = getInnerHTML(video.remove()); + + if (html) + data.video_html = html; + } + + data.hspace = hspace; + data.vspace = vspace; + data.align = align; + data.bgcolor = bgcolor; + + // Set width/height of placeholder + img.attr({ + id : id, + 'class' : 'mceItemMedia mceItem' + (type || 'Flash'), + style : style, + width : width || (node.name == 'audio' ? "300" : "320"), + height : height || (node.name == 'audio' ? "32" : "240"), + hspace : hspace, + vspace : vspace, + align : align, + bgcolor : bgcolor, + "data-mce-json" : JSON.serialize(data, "'") + }); + } + }); + + // Register plugin + tinymce.PluginManager.add('media', tinymce.plugins.MediaPlugin); +})(); diff --git a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/media/js/embed.js b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/media/js/embed.js index 6fe25de..f8dc810 100644 --- a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/media/js/embed.js +++ b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/media/js/embed.js @@ -1,73 +1,73 @@ -/** - * This script contains embed functions for common plugins. This scripts are complety free to use for any purpose. - */ - -function writeFlash(p) { - writeEmbed( - 'D27CDB6E-AE6D-11cf-96B8-444553540000', - 'http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0', - 'application/x-shockwave-flash', - p - ); -} - -function writeShockWave(p) { - writeEmbed( - '166B1BCA-3F9C-11CF-8075-444553540000', - 'http://download.macromedia.com/pub/shockwave/cabs/director/sw.cab#version=8,5,1,0', - 'application/x-director', - p - ); -} - -function writeQuickTime(p) { - writeEmbed( - '02BF25D5-8C17-4B23-BC80-D3488ABDDC6B', - 'http://www.apple.com/qtactivex/qtplugin.cab#version=6,0,2,0', - 'video/quicktime', - p - ); -} - -function writeRealMedia(p) { - writeEmbed( - 'CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA', - 'http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0', - 'audio/x-pn-realaudio-plugin', - p - ); -} - -function writeWindowsMedia(p) { - p.url = p.src; - writeEmbed( - '6BF52A52-394A-11D3-B153-00C04F79FAA6', - 'http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=5,1,52,701', - 'application/x-mplayer2', - p - ); -} - -function writeEmbed(cls, cb, mt, p) { - var h = '', n; - - h += ''; - - h += ''; + + h += ''); - - function get(id) { - return document.getElementById(id); - } - - function clone(obj) { - var i, len, copy, attr; - - if (null == obj || "object" != typeof obj) - return obj; - - // Handle Array - if ('length' in obj) { - copy = []; - - for (i = 0, len = obj.length; i < len; ++i) { - copy[i] = clone(obj[i]); - } - - return copy; - } - - // Handle Object - copy = {}; - for (attr in obj) { - if (obj.hasOwnProperty(attr)) - copy[attr] = clone(obj[attr]); - } - - return copy; - } - - function getVal(id) { - var elm = get(id); - - if (elm.nodeName == "SELECT") - return elm.options[elm.selectedIndex].value; - - if (elm.type == "checkbox") - return elm.checked; - - return elm.value; - } - - function setVal(id, value, name) { - if (typeof(value) != 'undefined' && value != null) { - var elm = get(id); - - if (elm.nodeName == "SELECT") - selectByValue(document.forms[0], id, value); - else if (elm.type == "checkbox") { - if (typeof(value) == 'string') { - value = value.toLowerCase(); - value = (!name && value === 'true') || (name && value === name.toLowerCase()); - } - elm.checked = !!value; - } else - elm.value = value; - } - } - - window.Media = { - init : function() { - var html, editor, self = this; - - self.editor = editor = tinyMCEPopup.editor; - - // Setup file browsers and color pickers - get('filebrowsercontainer').innerHTML = getBrowserHTML('filebrowser','src','media','media'); - get('qtsrcfilebrowsercontainer').innerHTML = getBrowserHTML('qtsrcfilebrowser','quicktime_qtsrc','media','media'); - get('bgcolor_pickcontainer').innerHTML = getColorPickerHTML('bgcolor_pick','bgcolor'); - get('video_altsource1_filebrowser').innerHTML = getBrowserHTML('video_filebrowser_altsource1','video_altsource1','media','media'); - get('video_altsource2_filebrowser').innerHTML = getBrowserHTML('video_filebrowser_altsource2','video_altsource2','media','media'); - get('audio_altsource1_filebrowser').innerHTML = getBrowserHTML('audio_filebrowser_altsource1','audio_altsource1','media','media'); - get('audio_altsource2_filebrowser').innerHTML = getBrowserHTML('audio_filebrowser_altsource2','audio_altsource2','media','media'); - get('video_poster_filebrowser').innerHTML = getBrowserHTML('filebrowser_poster','video_poster','media','image'); - - html = self.getMediaListHTML('medialist', 'src', 'media', 'media'); - if (html == "") - get("linklistrow").style.display = 'none'; - else - get("linklistcontainer").innerHTML = html; - - if (isVisible('filebrowser')) - get('src').style.width = '230px'; - - if (isVisible('video_filebrowser_altsource1')) - get('video_altsource1').style.width = '220px'; - - if (isVisible('video_filebrowser_altsource2')) - get('video_altsource2').style.width = '220px'; - - if (isVisible('audio_filebrowser_altsource1')) - get('audio_altsource1').style.width = '220px'; - - if (isVisible('audio_filebrowser_altsource2')) - get('audio_altsource2').style.width = '220px'; - - if (isVisible('filebrowser_poster')) - get('video_poster').style.width = '220px'; - - editor.dom.setOuterHTML(get('media_type'), self.getMediaTypeHTML(editor)); - - self.setDefaultDialogSettings(editor); - self.data = clone(tinyMCEPopup.getWindowArg('data')); - self.dataToForm(); - self.preview(); - - updateColor('bgcolor_pick', 'bgcolor'); - }, - - insert : function() { - var editor = tinyMCEPopup.editor; - - this.formToData(); - editor.execCommand('mceRepaint'); - tinyMCEPopup.restoreSelection(); - editor.selection.setNode(editor.plugins.media.dataToImg(this.data)); - tinyMCEPopup.close(); - }, - - preview : function() { - get('prev').innerHTML = this.editor.plugins.media.dataToHtml(this.data, true); - }, - - moveStates : function(to_form, field) { - var data = this.data, editor = this.editor, - mediaPlugin = editor.plugins.media, ext, src, typeInfo, defaultStates, src; - - defaultStates = { - // QuickTime - quicktime_autoplay : true, - quicktime_controller : true, - - // Flash - flash_play : true, - flash_loop : true, - flash_menu : true, - - // WindowsMedia - windowsmedia_autostart : true, - windowsmedia_enablecontextmenu : true, - windowsmedia_invokeurls : true, - - // RealMedia - realmedia_autogotourl : true, - realmedia_imagestatus : true - }; - - function parseQueryParams(str) { - var out = {}; - - if (str) { - tinymce.each(str.split('&'), function(item) { - var parts = item.split('='); - - out[unescape(parts[0])] = unescape(parts[1]); - }); - } - - return out; - }; - - function setOptions(type, names) { - var i, name, formItemName, value, list; - - if (type == data.type || type == 'global') { - names = tinymce.explode(names); - for (i = 0; i < names.length; i++) { - name = names[i]; - formItemName = type == 'global' ? name : type + '_' + name; - - if (type == 'global') - list = data; - else if (type == 'video' || type == 'audio') { - list = data.video.attrs; - - if (!list && !to_form) - data.video.attrs = list = {}; - } else - list = data.params; - - if (list) { - if (to_form) { - setVal(formItemName, list[name], type == 'video' || type == 'audio' ? name : ''); - } else { - delete list[name]; - - value = getVal(formItemName); - if ((type == 'video' || type == 'audio') && value === true) - value = name; - - if (defaultStates[formItemName]) { - if (value !== defaultStates[formItemName]) { - value = "" + value; - list[name] = value; - } - } else if (value) { - value = "" + value; - list[name] = value; - } - } - } - } - } - } - - if (!to_form) { - data.type = get('media_type').options[get('media_type').selectedIndex].value; - data.width = getVal('width'); - data.height = getVal('height'); - - // Switch type based on extension - src = getVal('src'); - if (field == 'src') { - ext = src.replace(/^.*\.([^.]+)$/, '$1'); - if (typeInfo = mediaPlugin.getType(ext)) - data.type = typeInfo.name.toLowerCase(); - - setVal('media_type', data.type); - } - - if (data.type == "video" || data.type == "audio") { - if (!data.video.sources) - data.video.sources = []; - - data.video.sources[0] = {src: getVal('src')}; - } - } - - // Hide all fieldsets and show the one active - get('video_options').style.display = 'none'; - get('audio_options').style.display = 'none'; - get('flash_options').style.display = 'none'; - get('quicktime_options').style.display = 'none'; - get('shockwave_options').style.display = 'none'; - get('windowsmedia_options').style.display = 'none'; - get('realmedia_options').style.display = 'none'; - get('embeddedaudio_options').style.display = 'none'; - - if (get(data.type + '_options')) - get(data.type + '_options').style.display = 'block'; - - setVal('media_type', data.type); - - setOptions('flash', 'play,loop,menu,swliveconnect,quality,scale,salign,wmode,base,flashvars'); - setOptions('quicktime', 'loop,autoplay,cache,controller,correction,enablejavascript,kioskmode,autohref,playeveryframe,targetcache,scale,starttime,endtime,target,qtsrcchokespeed,volume,qtsrc'); - setOptions('shockwave', 'sound,progress,autostart,swliveconnect,swvolume,swstretchstyle,swstretchhalign,swstretchvalign'); - setOptions('windowsmedia', 'autostart,enabled,enablecontextmenu,fullscreen,invokeurls,mute,stretchtofit,windowlessvideo,balance,baseurl,captioningid,currentmarker,currentposition,defaultframe,playcount,rate,uimode,volume'); - setOptions('realmedia', 'autostart,loop,autogotourl,center,imagestatus,maintainaspect,nojava,prefetch,shuffle,console,controls,numloop,scriptcallbacks'); - setOptions('video', 'poster,autoplay,loop,muted,preload,controls'); - setOptions('audio', 'autoplay,loop,preload,controls'); - setOptions('embeddedaudio', 'autoplay,loop,controls'); - setOptions('global', 'id,name,vspace,hspace,bgcolor,align,width,height'); - - if (to_form) { - if (data.type == 'video') { - if (data.video.sources[0]) - setVal('src', data.video.sources[0].src); - - src = data.video.sources[1]; - if (src) - setVal('video_altsource1', src.src); - - src = data.video.sources[2]; - if (src) - setVal('video_altsource2', src.src); - } else if (data.type == 'audio') { - if (data.video.sources[0]) - setVal('src', data.video.sources[0].src); - - src = data.video.sources[1]; - if (src) - setVal('audio_altsource1', src.src); - - src = data.video.sources[2]; - if (src) - setVal('audio_altsource2', src.src); - } else { - // Check flash vars - if (data.type == 'flash') { - tinymce.each(editor.getParam('flash_video_player_flashvars', {url : '$url', poster : '$poster'}), function(value, name) { - if (value == '$url') - data.params.src = parseQueryParams(data.params.flashvars)[name] || data.params.src || ''; - }); - } - - setVal('src', data.params.src); - } - } else { - src = getVal("src"); - - // YouTube *NEW* - if (src.match(/youtu.be\/[a-z1-9.-_]+/)) { - data.width = 425; - data.height = 350; - data.params.frameborder = '0'; - data.type = 'iframe'; - src = 'http://www.youtube.com/embed/' + src.match(/youtu.be\/([a-z1-9.-_]+)/)[1]; - setVal('src', src); - setVal('media_type', data.type); - } - - // YouTube - if (src.match(/youtube.com(.+)v=([^&]+)/)) { - data.width = 425; - data.height = 350; - data.params.frameborder = '0'; - data.type = 'iframe'; - src = 'http://www.youtube.com/embed/' + src.match(/v=([^&]+)/)[1]; - setVal('src', src); - setVal('media_type', data.type); - } - - // Google video - if (src.match(/video.google.com(.+)docid=([^&]+)/)) { - data.width = 425; - data.height = 326; - data.type = 'flash'; - src = 'http://video.google.com/googleplayer.swf?docId=' + src.match(/docid=([^&]+)/)[1] + '&hl=en'; - setVal('src', src); - setVal('media_type', data.type); - } - - if (data.type == 'video') { - if (!data.video.sources) - data.video.sources = []; - - data.video.sources[0] = {src : src}; - - src = getVal("video_altsource1"); - if (src) - data.video.sources[1] = {src : src}; - - src = getVal("video_altsource2"); - if (src) - data.video.sources[2] = {src : src}; - } else if (data.type == 'audio') { - if (!data.video.sources) - data.video.sources = []; - - data.video.sources[0] = {src : src}; - - src = getVal("audio_altsource1"); - if (src) - data.video.sources[1] = {src : src}; - - src = getVal("audio_altsource2"); - if (src) - data.video.sources[2] = {src : src}; - } else - data.params.src = src; - - // Set default size - setVal('width', data.width || (data.type == 'audio' ? 300 : 320)); - setVal('height', data.height || (data.type == 'audio' ? 32 : 240)); - } - }, - - dataToForm : function() { - this.moveStates(true); - }, - - formToData : function(field) { - if (field == "width" || field == "height") - this.changeSize(field); - - if (field == 'source') { - this.moveStates(false, field); - setVal('source', this.editor.plugins.media.dataToHtml(this.data)); - this.panel = 'source'; - } else { - if (this.panel == 'source') { - this.data = clone(this.editor.plugins.media.htmlToData(getVal('source'))); - this.dataToForm(); - this.panel = ''; - } - - this.moveStates(false, field); - this.preview(); - } - }, - - beforeResize : function() { - this.width = parseInt(getVal('width') || (this.data.type == 'audio' ? "300" : "320"), 10); - this.height = parseInt(getVal('height') || (this.data.type == 'audio' ? "32" : "240"), 10); - }, - - changeSize : function(type) { - var width, height, scale, size; - - if (get('constrain').checked) { - width = parseInt(getVal('width') || (this.data.type == 'audio' ? "300" : "320"), 10); - height = parseInt(getVal('height') || (this.data.type == 'audio' ? "32" : "240"), 10); - - if (type == 'width') { - this.height = Math.round((width / this.width) * height); - setVal('height', this.height); - } else { - this.width = Math.round((height / this.height) * width); - setVal('width', this.width); - } - } - }, - - getMediaListHTML : function() { - if (typeof(tinyMCEMediaList) != "undefined" && tinyMCEMediaList.length > 0) { - var html = ""; - - html += ''; - - return html; - } - - return ""; - }, - - getMediaTypeHTML : function(editor) { - function option(media_type, element) { - if (!editor.schema.getElementRule(element || media_type)) { - return ''; - } - - return '' - } - - var html = ""; - - html += ''; - return html; - }, - - setDefaultDialogSettings : function(editor) { - var defaultDialogSettings = editor.getParam("media_dialog_defaults", {}); - tinymce.each(defaultDialogSettings, function(v, k) { - setVal(k, v); - }); - } - }; - - tinyMCEPopup.requireLangPack(); - tinyMCEPopup.onInit.add(function() { - Media.init(); - }); -})(); +(function() { + var url; + + if (url = tinyMCEPopup.getParam("media_external_list_url")) + document.write(''); + + function get(id) { + return document.getElementById(id); + } + + function clone(obj) { + var i, len, copy, attr; + + if (null == obj || "object" != typeof obj) + return obj; + + // Handle Array + if ('length' in obj) { + copy = []; + + for (i = 0, len = obj.length; i < len; ++i) { + copy[i] = clone(obj[i]); + } + + return copy; + } + + // Handle Object + copy = {}; + for (attr in obj) { + if (obj.hasOwnProperty(attr)) + copy[attr] = clone(obj[attr]); + } + + return copy; + } + + function getVal(id) { + var elm = get(id); + + if (elm.nodeName == "SELECT") + return elm.options[elm.selectedIndex].value; + + if (elm.type == "checkbox") + return elm.checked; + + return elm.value; + } + + function setVal(id, value, name) { + if (typeof(value) != 'undefined' && value != null) { + var elm = get(id); + + if (elm.nodeName == "SELECT") + selectByValue(document.forms[0], id, value); + else if (elm.type == "checkbox") { + if (typeof(value) == 'string') { + value = value.toLowerCase(); + value = (!name && value === 'true') || (name && value === name.toLowerCase()); + } + elm.checked = !!value; + } else + elm.value = value; + } + } + + window.Media = { + init : function() { + var html, editor, self = this; + + self.editor = editor = tinyMCEPopup.editor; + + // Setup file browsers and color pickers + get('filebrowsercontainer').innerHTML = getBrowserHTML('filebrowser','src','media','media'); + get('qtsrcfilebrowsercontainer').innerHTML = getBrowserHTML('qtsrcfilebrowser','quicktime_qtsrc','media','media'); + get('bgcolor_pickcontainer').innerHTML = getColorPickerHTML('bgcolor_pick','bgcolor'); + get('video_altsource1_filebrowser').innerHTML = getBrowserHTML('video_filebrowser_altsource1','video_altsource1','media','media'); + get('video_altsource2_filebrowser').innerHTML = getBrowserHTML('video_filebrowser_altsource2','video_altsource2','media','media'); + get('audio_altsource1_filebrowser').innerHTML = getBrowserHTML('audio_filebrowser_altsource1','audio_altsource1','media','media'); + get('audio_altsource2_filebrowser').innerHTML = getBrowserHTML('audio_filebrowser_altsource2','audio_altsource2','media','media'); + get('video_poster_filebrowser').innerHTML = getBrowserHTML('filebrowser_poster','video_poster','media','image'); + + html = self.getMediaListHTML('medialist', 'src', 'media', 'media'); + if (html == "") + get("linklistrow").style.display = 'none'; + else + get("linklistcontainer").innerHTML = html; + + if (isVisible('filebrowser')) + get('src').style.width = '230px'; + + if (isVisible('video_filebrowser_altsource1')) + get('video_altsource1').style.width = '220px'; + + if (isVisible('video_filebrowser_altsource2')) + get('video_altsource2').style.width = '220px'; + + if (isVisible('audio_filebrowser_altsource1')) + get('audio_altsource1').style.width = '220px'; + + if (isVisible('audio_filebrowser_altsource2')) + get('audio_altsource2').style.width = '220px'; + + if (isVisible('filebrowser_poster')) + get('video_poster').style.width = '220px'; + + editor.dom.setOuterHTML(get('media_type'), self.getMediaTypeHTML(editor)); + + self.setDefaultDialogSettings(editor); + self.data = clone(tinyMCEPopup.getWindowArg('data')); + self.dataToForm(); + self.preview(); + + updateColor('bgcolor_pick', 'bgcolor'); + }, + + insert : function() { + var editor = tinyMCEPopup.editor; + + this.formToData(); + editor.execCommand('mceRepaint'); + tinyMCEPopup.restoreSelection(); + editor.selection.setNode(editor.plugins.media.dataToImg(this.data)); + tinyMCEPopup.close(); + }, + + preview : function() { + get('prev').innerHTML = this.editor.plugins.media.dataToHtml(this.data, true); + }, + + moveStates : function(to_form, field) { + var data = this.data, editor = this.editor, + mediaPlugin = editor.plugins.media, ext, src, typeInfo, defaultStates, src; + + defaultStates = { + // QuickTime + quicktime_autoplay : true, + quicktime_controller : true, + + // Flash + flash_play : true, + flash_loop : true, + flash_menu : true, + + // WindowsMedia + windowsmedia_autostart : true, + windowsmedia_enablecontextmenu : true, + windowsmedia_invokeurls : true, + + // RealMedia + realmedia_autogotourl : true, + realmedia_imagestatus : true + }; + + function parseQueryParams(str) { + var out = {}; + + if (str) { + tinymce.each(str.split('&'), function(item) { + var parts = item.split('='); + + out[unescape(parts[0])] = unescape(parts[1]); + }); + } + + return out; + }; + + function setOptions(type, names) { + var i, name, formItemName, value, list; + + if (type == data.type || type == 'global') { + names = tinymce.explode(names); + for (i = 0; i < names.length; i++) { + name = names[i]; + formItemName = type == 'global' ? name : type + '_' + name; + + if (type == 'global') + list = data; + else if (type == 'video' || type == 'audio') { + list = data.video.attrs; + + if (!list && !to_form) + data.video.attrs = list = {}; + } else + list = data.params; + + if (list) { + if (to_form) { + setVal(formItemName, list[name], type == 'video' || type == 'audio' ? name : ''); + } else { + delete list[name]; + + value = getVal(formItemName); + if ((type == 'video' || type == 'audio') && value === true) + value = name; + + if (defaultStates[formItemName]) { + if (value !== defaultStates[formItemName]) { + value = "" + value; + list[name] = value; + } + } else if (value) { + value = "" + value; + list[name] = value; + } + } + } + } + } + } + + if (!to_form) { + data.type = get('media_type').options[get('media_type').selectedIndex].value; + data.width = getVal('width'); + data.height = getVal('height'); + + // Switch type based on extension + src = getVal('src'); + if (field == 'src') { + ext = src.replace(/^.*\.([^.]+)$/, '$1'); + if (typeInfo = mediaPlugin.getType(ext)) + data.type = typeInfo.name.toLowerCase(); + + setVal('media_type', data.type); + } + + if (data.type == "video" || data.type == "audio") { + if (!data.video.sources) + data.video.sources = []; + + data.video.sources[0] = {src: getVal('src')}; + } + } + + // Hide all fieldsets and show the one active + get('video_options').style.display = 'none'; + get('audio_options').style.display = 'none'; + get('flash_options').style.display = 'none'; + get('quicktime_options').style.display = 'none'; + get('shockwave_options').style.display = 'none'; + get('windowsmedia_options').style.display = 'none'; + get('realmedia_options').style.display = 'none'; + get('embeddedaudio_options').style.display = 'none'; + + if (get(data.type + '_options')) + get(data.type + '_options').style.display = 'block'; + + setVal('media_type', data.type); + + setOptions('flash', 'play,loop,menu,swliveconnect,quality,scale,salign,wmode,base,flashvars'); + setOptions('quicktime', 'loop,autoplay,cache,controller,correction,enablejavascript,kioskmode,autohref,playeveryframe,targetcache,scale,starttime,endtime,target,qtsrcchokespeed,volume,qtsrc'); + setOptions('shockwave', 'sound,progress,autostart,swliveconnect,swvolume,swstretchstyle,swstretchhalign,swstretchvalign'); + setOptions('windowsmedia', 'autostart,enabled,enablecontextmenu,fullscreen,invokeurls,mute,stretchtofit,windowlessvideo,balance,baseurl,captioningid,currentmarker,currentposition,defaultframe,playcount,rate,uimode,volume'); + setOptions('realmedia', 'autostart,loop,autogotourl,center,imagestatus,maintainaspect,nojava,prefetch,shuffle,console,controls,numloop,scriptcallbacks'); + setOptions('video', 'poster,autoplay,loop,muted,preload,controls'); + setOptions('audio', 'autoplay,loop,preload,controls'); + setOptions('embeddedaudio', 'autoplay,loop,controls'); + setOptions('global', 'id,name,vspace,hspace,bgcolor,align,width,height'); + + if (to_form) { + if (data.type == 'video') { + if (data.video.sources[0]) + setVal('src', data.video.sources[0].src); + + src = data.video.sources[1]; + if (src) + setVal('video_altsource1', src.src); + + src = data.video.sources[2]; + if (src) + setVal('video_altsource2', src.src); + } else if (data.type == 'audio') { + if (data.video.sources[0]) + setVal('src', data.video.sources[0].src); + + src = data.video.sources[1]; + if (src) + setVal('audio_altsource1', src.src); + + src = data.video.sources[2]; + if (src) + setVal('audio_altsource2', src.src); + } else { + // Check flash vars + if (data.type == 'flash') { + tinymce.each(editor.getParam('flash_video_player_flashvars', {url : '$url', poster : '$poster'}), function(value, name) { + if (value == '$url') + data.params.src = parseQueryParams(data.params.flashvars)[name] || data.params.src || ''; + }); + } + + setVal('src', data.params.src); + } + } else { + src = getVal("src"); + + // YouTube *NEW* + if (src.match(/youtu.be\/[a-z1-9.-_]+/)) { + data.width = 425; + data.height = 350; + data.params.frameborder = '0'; + data.type = 'iframe'; + src = 'http://www.youtube.com/embed/' + src.match(/youtu.be\/([a-z1-9.-_]+)/)[1]; + setVal('src', src); + setVal('media_type', data.type); + } + + // YouTube + if (src.match(/youtube.com(.+)v=([^&]+)/)) { + data.width = 425; + data.height = 350; + data.params.frameborder = '0'; + data.type = 'iframe'; + src = 'http://www.youtube.com/embed/' + src.match(/v=([^&]+)/)[1]; + setVal('src', src); + setVal('media_type', data.type); + } + + // Google video + if (src.match(/video.google.com(.+)docid=([^&]+)/)) { + data.width = 425; + data.height = 326; + data.type = 'flash'; + src = 'http://video.google.com/googleplayer.swf?docId=' + src.match(/docid=([^&]+)/)[1] + '&hl=en'; + setVal('src', src); + setVal('media_type', data.type); + } + + if (data.type == 'video') { + if (!data.video.sources) + data.video.sources = []; + + data.video.sources[0] = {src : src}; + + src = getVal("video_altsource1"); + if (src) + data.video.sources[1] = {src : src}; + + src = getVal("video_altsource2"); + if (src) + data.video.sources[2] = {src : src}; + } else if (data.type == 'audio') { + if (!data.video.sources) + data.video.sources = []; + + data.video.sources[0] = {src : src}; + + src = getVal("audio_altsource1"); + if (src) + data.video.sources[1] = {src : src}; + + src = getVal("audio_altsource2"); + if (src) + data.video.sources[2] = {src : src}; + } else + data.params.src = src; + + // Set default size + setVal('width', data.width || (data.type == 'audio' ? 300 : 320)); + setVal('height', data.height || (data.type == 'audio' ? 32 : 240)); + } + }, + + dataToForm : function() { + this.moveStates(true); + }, + + formToData : function(field) { + if (field == "width" || field == "height") + this.changeSize(field); + + if (field == 'source') { + this.moveStates(false, field); + setVal('source', this.editor.plugins.media.dataToHtml(this.data)); + this.panel = 'source'; + } else { + if (this.panel == 'source') { + this.data = clone(this.editor.plugins.media.htmlToData(getVal('source'))); + this.dataToForm(); + this.panel = ''; + } + + this.moveStates(false, field); + this.preview(); + } + }, + + beforeResize : function() { + this.width = parseInt(getVal('width') || (this.data.type == 'audio' ? "300" : "320"), 10); + this.height = parseInt(getVal('height') || (this.data.type == 'audio' ? "32" : "240"), 10); + }, + + changeSize : function(type) { + var width, height, scale, size; + + if (get('constrain').checked) { + width = parseInt(getVal('width') || (this.data.type == 'audio' ? "300" : "320"), 10); + height = parseInt(getVal('height') || (this.data.type == 'audio' ? "32" : "240"), 10); + + if (type == 'width') { + this.height = Math.round((width / this.width) * height); + setVal('height', this.height); + } else { + this.width = Math.round((height / this.height) * width); + setVal('width', this.width); + } + } + }, + + getMediaListHTML : function() { + if (typeof(tinyMCEMediaList) != "undefined" && tinyMCEMediaList.length > 0) { + var html = ""; + + html += ''; + + return html; + } + + return ""; + }, + + getMediaTypeHTML : function(editor) { + function option(media_type, element) { + if (!editor.schema.getElementRule(element || media_type)) { + return ''; + } + + return '' + } + + var html = ""; + + html += ''; + return html; + }, + + setDefaultDialogSettings : function(editor) { + var defaultDialogSettings = editor.getParam("media_dialog_defaults", {}); + tinymce.each(defaultDialogSettings, function(v, k) { + setVal(k, v); + }); + } + }; + + tinyMCEPopup.requireLangPack(); + tinyMCEPopup.onInit.add(function() { + Media.init(); + }); +})(); diff --git a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/media/langs/en_dlg.js b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/media/langs/en_dlg.js index ecef3a8..6f98f07 100644 --- a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/media/langs/en_dlg.js +++ b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/media/langs/en_dlg.js @@ -1 +1 @@ -tinyMCE.addI18n('en.media_dlg',{list:"List",file:"File/URL",advanced:"Advanced",general:"General",title:"Insert/Edit Embedded Media","align_top_left":"Top Left","align_center":"Center","align_left":"Left","align_bottom":"Bottom","align_right":"Right","align_top":"Top","qt_stream_warn":"Streamed RTSP resources should be added to the QT Source field under the Advanced tab.\nYou should also add a non-streamed version to the Source field.",qtsrc:"QT Source",progress:"Progress",sound:"Sound",swstretchvalign:"Stretch V-Align",swstretchhalign:"Stretch H-Align",swstretchstyle:"Stretch Style",scriptcallbacks:"Script Callbacks","align_top_right":"Top Right",uimode:"UI Mode",rate:"Rate",playcount:"Play Count",defaultframe:"Default Frame",currentposition:"Current Position",currentmarker:"Current Marker",captioningid:"Captioning ID",baseurl:"Base URL",balance:"Balance",windowlessvideo:"Windowless Video",stretchtofit:"Stretch to Fit",mute:"Mute",invokeurls:"Invoke URLs",fullscreen:"Full Screen",enabled:"Enabled",autostart:"Auto Start",volume:"Volume",target:"Target",qtsrcchokespeed:"Choke Speed",href:"HREF",endtime:"End Time",starttime:"Start Time",enablejavascript:"Enable JavaScript",correction:"No Correction",targetcache:"Target Cache",playeveryframe:"Play Every Frame",kioskmode:"Kiosk Mode",controller:"Controller",menu:"Show Menu",loop:"Loop",play:"Auto Play",hspace:"H-Space",vspace:"V-Space","class_name":"Class",name:"Name",id:"ID",type:"Type",size:"Dimensions",preview:"Preview","constrain_proportions":"Constrain Proportions",controls:"Controls",numloop:"Num Loops",console:"Console",cache:"Cache",autohref:"Auto HREF",liveconnect:"SWLiveConnect",flashvars:"Flash Vars",base:"Base",bgcolor:"Background",wmode:"WMode",salign:"SAlign",align:"Align",scale:"Scale",quality:"Quality",shuffle:"Shuffle",prefetch:"Prefetch",nojava:"No Java",maintainaspect:"Maintain Aspect",imagestatus:"Image Status",center:"Center",autogotourl:"Auto Goto URL","shockwave_options":"Shockwave Options","rmp_options":"Real Media Player Options","wmp_options":"Windows Media Player Options","qt_options":"QuickTime Options","flash_options":"Flash Options",hidden:"Hidden","align_bottom_left":"Bottom Left","align_bottom_right":"Bottom Right","html5_video_options":"HTML5 Video Options",altsource1:"Alternative source 1",altsource2:"Alternative source 2",preload:"Preload",poster:"Poster",source:"Source","html5_audio_options":"Audio Options","preload_none":"Don\'t Preload","preload_metadata":"Preload video metadata","preload_auto":"Let user\'s browser decide", "embedded_audio_options":"Embedded Audio Options", video:"HTML5 Video", audio:"HTML5 Audio", flash:"Flash", quicktime:"QuickTime", shockwave:"Shockwave", windowsmedia:"Windows Media", realmedia:"Real Media", iframe:"Iframe", embeddedaudio:"Embedded Audio" }); +tinyMCE.addI18n('en.media_dlg',{list:"List",file:"File/URL",advanced:"Advanced",general:"General",title:"Insert/Edit Embedded Media","align_top_left":"Top Left","align_center":"Center","align_left":"Left","align_bottom":"Bottom","align_right":"Right","align_top":"Top","qt_stream_warn":"Streamed RTSP resources should be added to the QT Source field under the Advanced tab.\nYou should also add a non-streamed version to the Source field.",qtsrc:"QT Source",progress:"Progress",sound:"Sound",swstretchvalign:"Stretch V-Align",swstretchhalign:"Stretch H-Align",swstretchstyle:"Stretch Style",scriptcallbacks:"Script Callbacks","align_top_right":"Top Right",uimode:"UI Mode",rate:"Rate",playcount:"Play Count",defaultframe:"Default Frame",currentposition:"Current Position",currentmarker:"Current Marker",captioningid:"Captioning ID",baseurl:"Base URL",balance:"Balance",windowlessvideo:"Windowless Video",stretchtofit:"Stretch to Fit",mute:"Mute",invokeurls:"Invoke URLs",fullscreen:"Full Screen",enabled:"Enabled",autostart:"Auto Start",volume:"Volume",target:"Target",qtsrcchokespeed:"Choke Speed",href:"HREF",endtime:"End Time",starttime:"Start Time",enablejavascript:"Enable JavaScript",correction:"No Correction",targetcache:"Target Cache",playeveryframe:"Play Every Frame",kioskmode:"Kiosk Mode",controller:"Controller",menu:"Show Menu",loop:"Loop",play:"Auto Play",hspace:"H-Space",vspace:"V-Space","class_name":"Class",name:"Name",id:"ID",type:"Type",size:"Dimensions",preview:"Preview","constrain_proportions":"Constrain Proportions",controls:"Controls",numloop:"Num Loops",console:"Console",cache:"Cache",autohref:"Auto HREF",liveconnect:"SWLiveConnect",flashvars:"Flash Vars",base:"Base",bgcolor:"Background",wmode:"WMode",salign:"SAlign",align:"Align",scale:"Scale",quality:"Quality",shuffle:"Shuffle",prefetch:"Prefetch",nojava:"No Java",maintainaspect:"Maintain Aspect",imagestatus:"Image Status",center:"Center",autogotourl:"Auto Goto URL","shockwave_options":"Shockwave Options","rmp_options":"Real Media Player Options","wmp_options":"Windows Media Player Options","qt_options":"QuickTime Options","flash_options":"Flash Options",hidden:"Hidden","align_bottom_left":"Bottom Left","align_bottom_right":"Bottom Right","html5_video_options":"HTML5 Video Options",altsource1:"Alternative source 1",altsource2:"Alternative source 2",preload:"Preload",poster:"Poster",source:"Source","html5_audio_options":"Audio Options","preload_none":"Don\'t Preload","preload_metadata":"Preload video metadata","preload_auto":"Let user\'s browser decide", "embedded_audio_options":"Embedded Audio Options", video:"HTML5 Video", audio:"HTML5 Audio", flash:"Flash", quicktime:"QuickTime", shockwave:"Shockwave", windowsmedia:"Windows Media", realmedia:"Real Media", iframe:"Iframe", embeddedaudio:"Embedded Audio" }); diff --git a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/media/media.htm b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/media/media.htm index 50efe91..957d83a 100644 --- a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/media/media.htm +++ b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/media/media.htm @@ -1,922 +1,922 @@ - - - - {#media_dlg.title} - - - - - - - - - -
            - - -
            -
            -
            - {#media_dlg.general} - - - - - - - - - - - - - - - - - - -
            - -
            - - - - - -
             
            -
            - - - - - - -
            x   
            -
            -
            - -
            - {#media_dlg.preview} - -
            -
            - -
            -
            - {#media_dlg.advanced} - - - - - - - - - - - - - - - - - - - - - - - -
            - - - - - - - -
             
            -
            -
            - -
            - {#media_dlg.html5_video_options} - - - - - - - - - - - - - - - - - - - - - -
            - - - - - -
             
            -
            - - - - - -
             
            -
            - - - - - -
             
            -
            - -
            - - - - - - - - - - - -
            - - - - - -
            -
            - - - - - -
            -
            - - - - - -
            -
            - - - - - -
            -
            -
            - -
            - {#media_dlg.embedded_audio_options} - - - - - - - - - -
            - - - - - -
            -
            - - - - - -
            -
            - - - - - -
            -
            -
            - -
            - {#media_dlg.html5_audio_options} - - - - - - - - - - - - - - - - -
            - - - - - -
             
            -
            - - - - - -
             
            -
            - -
            - - - - - - - - - -
            - - - - - -
            -
            - - - - - -
            -
            - - - - - -
            -
            -
            - -
            - {#media_dlg.flash_options} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
            - - - -
            - - - -
            - - - - - -
            -
            - - - - - -
            -
            - - - - - -
            -
            - - - - - -
            -
            - - - - - - - - - - - -
            -
            - -
            - {#media_dlg.qt_options} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
            - - - - - -
            -
            - - - - - -
            -
            - - - - - -
            -
            - - - - - -
            -
            - - - - - -
            -
            - - - - - -
            -
            - - - - - -
            -
            - - - - - -
            -
            - - - - - -
            -
            - - - - - -
            -
            -  
            - - - - - -
             
            -
            -
            - -
            - {#media_dlg.wmp_options} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
            - - - - - -
            -
            - - - - - -
            -
            - - - - - -
            -
            - - - - - -
            -
            - - - - - -
            -
            - - - - - -
            -
            - - - - - -
            -
            - - - - - -
            -
            -
            - -
            - {#media_dlg.rmp_options} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
            - - - - - -
            -
            - - - - - -
            -
            - - - - - -
            -
            - - - - - -
            -
            - - - - - -
            -
            - - - - - -
            -
            - - - - - -
            -
            - - - - - -
            -
            - - - - - -
            -
            -   -
            -
            - -
            - {#media_dlg.shockwave_options} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
            - -
            - - - -
            - - - - - -
            -
            - - - - - -
            -
            - - - - - -
            -
            - - - - - -
            -
            -
            -
            - -
            -
            - {#media_dlg.source} - -
            -
            -
            - -
            - - -
            -
            - - + + + + {#media_dlg.title} + + + + + + + + + +
            + + +
            +
            +
            + {#media_dlg.general} + + + + + + + + + + + + + + + + + + +
            + +
            + + + + + +
             
            +
            + + + + + + +
            x   
            +
            +
            + +
            + {#media_dlg.preview} + +
            +
            + +
            +
            + {#media_dlg.advanced} + + + + + + + + + + + + + + + + + + + + + + + +
            + + + + + + + +
             
            +
            +
            + +
            + {#media_dlg.html5_video_options} + + + + + + + + + + + + + + + + + + + + + +
            + + + + + +
             
            +
            + + + + + +
             
            +
            + + + + + +
             
            +
            + +
            + + + + + + + + + + + +
            + + + + + +
            +
            + + + + + +
            +
            + + + + + +
            +
            + + + + + +
            +
            +
            + +
            + {#media_dlg.embedded_audio_options} + + + + + + + + + +
            + + + + + +
            +
            + + + + + +
            +
            + + + + + +
            +
            +
            + +
            + {#media_dlg.html5_audio_options} + + + + + + + + + + + + + + + + +
            + + + + + +
             
            +
            + + + + + +
             
            +
            + +
            + + + + + + + + + +
            + + + + + +
            +
            + + + + + +
            +
            + + + + + +
            +
            +
            + +
            + {#media_dlg.flash_options} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + +
            + + + +
            + + + + + +
            +
            + + + + + +
            +
            + + + + + +
            +
            + + + + + +
            +
            + + + + + + + + + + + +
            +
            + +
            + {#media_dlg.qt_options} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + + + +
            +
            + + + + + +
            +
            + + + + + +
            +
            + + + + + +
            +
            + + + + + +
            +
            + + + + + +
            +
            + + + + + +
            +
            + + + + + +
            +
            + + + + + +
            +
            + + + + + +
            +
            +  
            + + + + + +
             
            +
            +
            + +
            + {#media_dlg.wmp_options} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + + + +
            +
            + + + + + +
            +
            + + + + + +
            +
            + + + + + +
            +
            + + + + + +
            +
            + + + + + +
            +
            + + + + + +
            +
            + + + + + +
            +
            +
            + +
            + {#media_dlg.rmp_options} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + + + +
            +
            + + + + + +
            +
            + + + + + +
            +
            + + + + + +
            +
            + + + + + +
            +
            + + + + + +
            +
            + + + + + +
            +
            + + + + + +
            +
            + + + + + +
            +
            +   +
            +
            + +
            + {#media_dlg.shockwave_options} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + +
            + + + +
            + + + + + +
            +
            + + + + + +
            +
            + + + + + +
            +
            + + + + + +
            +
            +
            +
            + +
            +
            + {#media_dlg.source} + +
            +
            +
            + +
            + + +
            +
            + + diff --git a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/paste/editor_plugin_src.js b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/paste/editor_plugin_src.js index 4fbb544..9f1c354 100644 --- a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/paste/editor_plugin_src.js +++ b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/paste/editor_plugin_src.js @@ -1,871 +1,871 @@ -/** - * editor_plugin_src.js - * - * Copyright 2009, Moxiecode Systems AB - * Released under LGPL License. - * - * License: http://tinymce.moxiecode.com/license - * Contributing: http://tinymce.moxiecode.com/contributing - */ - -(function() { - var each = tinymce.each, - defs = { - paste_auto_cleanup_on_paste : true, - paste_enable_default_filters : true, - paste_block_drop : false, - paste_retain_style_properties : "none", - paste_strip_class_attributes : "mso", - paste_remove_spans : false, - paste_remove_styles : false, - paste_remove_styles_if_webkit : true, - paste_convert_middot_lists : true, - paste_convert_headers_to_strong : false, - paste_dialog_width : "450", - paste_dialog_height : "400", - paste_text_use_dialog : false, - paste_text_sticky : false, - paste_text_sticky_default : false, - paste_text_notifyalways : false, - paste_text_linebreaktype : "combined", - paste_text_replacements : [ - [/\u2026/g, "..."], - [/[\x93\x94\u201c\u201d]/g, '"'], - [/[\x60\x91\x92\u2018\u2019]/g, "'"] - ] - }; - - function getParam(ed, name) { - return ed.getParam(name, defs[name]); - } - - tinymce.create('tinymce.plugins.PastePlugin', { - init : function(ed, url) { - var t = this; - - t.editor = ed; - t.url = url; - - // Setup plugin events - t.onPreProcess = new tinymce.util.Dispatcher(t); - t.onPostProcess = new tinymce.util.Dispatcher(t); - - // Register default handlers - t.onPreProcess.add(t._preProcess); - t.onPostProcess.add(t._postProcess); - - // Register optional preprocess handler - t.onPreProcess.add(function(pl, o) { - ed.execCallback('paste_preprocess', pl, o); - }); - - // Register optional postprocess - t.onPostProcess.add(function(pl, o) { - ed.execCallback('paste_postprocess', pl, o); - }); - - ed.onKeyDown.addToTop(function(ed, e) { - // Block ctrl+v from adding an undo level since the default logic in tinymce.Editor will add that - if (((tinymce.isMac ? e.metaKey : e.ctrlKey) && e.keyCode == 86) || (e.shiftKey && e.keyCode == 45)) - return false; // Stop other listeners - }); - - // Initialize plain text flag - ed.pasteAsPlainText = getParam(ed, 'paste_text_sticky_default'); - - // This function executes the process handlers and inserts the contents - // force_rich overrides plain text mode set by user, important for pasting with execCommand - function process(o, force_rich) { - var dom = ed.dom, rng; - - // Execute pre process handlers - t.onPreProcess.dispatch(t, o); - - // Create DOM structure - o.node = dom.create('div', 0, o.content); - - // If pasting inside the same element and the contents is only one block - // remove the block and keep the text since Firefox will copy parts of pre and h1-h6 as a pre element - if (tinymce.isGecko) { - rng = ed.selection.getRng(true); - if (rng.startContainer == rng.endContainer && rng.startContainer.nodeType == 3) { - // Is only one block node and it doesn't contain word stuff - if (o.node.childNodes.length === 1 && /^(p|h[1-6]|pre)$/i.test(o.node.firstChild.nodeName) && o.content.indexOf('__MCE_ITEM__') === -1) - dom.remove(o.node.firstChild, true); - } - } - - // Execute post process handlers - t.onPostProcess.dispatch(t, o); - - // Serialize content - o.content = ed.serializer.serialize(o.node, {getInner : 1, forced_root_block : ''}); - - // Plain text option active? - if ((!force_rich) && (ed.pasteAsPlainText)) { - t._insertPlainText(o.content); - - if (!getParam(ed, "paste_text_sticky")) { - ed.pasteAsPlainText = false; - ed.controlManager.setActive("pastetext", false); - } - } else { - t._insert(o.content); - } - } - - // Add command for external usage - ed.addCommand('mceInsertClipboardContent', function(u, o) { - process(o, true); - }); - - if (!getParam(ed, "paste_text_use_dialog")) { - ed.addCommand('mcePasteText', function(u, v) { - var cookie = tinymce.util.Cookie; - - ed.pasteAsPlainText = !ed.pasteAsPlainText; - ed.controlManager.setActive('pastetext', ed.pasteAsPlainText); - - if ((ed.pasteAsPlainText) && (!cookie.get("tinymcePasteText"))) { - if (getParam(ed, "paste_text_sticky")) { - ed.windowManager.alert(ed.translate('paste.plaintext_mode_sticky')); - } else { - ed.windowManager.alert(ed.translate('paste.plaintext_mode')); - } - - if (!getParam(ed, "paste_text_notifyalways")) { - cookie.set("tinymcePasteText", "1", new Date(new Date().getFullYear() + 1, 12, 31)) - } - } - }); - } - - ed.addButton('pastetext', {title: 'paste.paste_text_desc', cmd: 'mcePasteText'}); - ed.addButton('selectall', {title: 'paste.selectall_desc', cmd: 'selectall'}); - - // This function grabs the contents from the clipboard by adding a - // hidden div and placing the caret inside it and after the browser paste - // is done it grabs that contents and processes that - function grabContent(e) { - var n, or, rng, oldRng, sel = ed.selection, dom = ed.dom, body = ed.getBody(), posY, textContent; - - // Check if browser supports direct plaintext access - if (e.clipboardData || dom.doc.dataTransfer) { - textContent = (e.clipboardData || dom.doc.dataTransfer).getData('Text'); - - if (ed.pasteAsPlainText) { - e.preventDefault(); - process({content : dom.encode(textContent).replace(/\r?\n/g, '
            ')}); - return; - } - } - - if (dom.get('_mcePaste')) - return; - - // Create container to paste into - n = dom.add(body, 'div', {id : '_mcePaste', 'class' : 'mcePaste', 'data-mce-bogus' : '1'}, '\uFEFF\uFEFF'); - - // If contentEditable mode we need to find out the position of the closest element - if (body != ed.getDoc().body) - posY = dom.getPos(ed.selection.getStart(), body).y; - else - posY = body.scrollTop + dom.getViewPort(ed.getWin()).y; - - // Styles needs to be applied after the element is added to the document since WebKit will otherwise remove all styles - // If also needs to be in view on IE or the paste would fail - dom.setStyles(n, { - position : 'absolute', - left : tinymce.isGecko ? -40 : 0, // Need to move it out of site on Gecko since it will othewise display a ghost resize rect for the div - top : posY - 25, - width : 1, - height : 1, - overflow : 'hidden' - }); - - if (tinymce.isIE) { - // Store away the old range - oldRng = sel.getRng(); - - // Select the container - rng = dom.doc.body.createTextRange(); - rng.moveToElementText(n); - rng.execCommand('Paste'); - - // Remove container - dom.remove(n); - - // Check if the contents was changed, if it wasn't then clipboard extraction failed probably due - // to IE security settings so we pass the junk though better than nothing right - if (n.innerHTML === '\uFEFF\uFEFF') { - ed.execCommand('mcePasteWord'); - e.preventDefault(); - return; - } - - // Restore the old range and clear the contents before pasting - sel.setRng(oldRng); - sel.setContent(''); - - // For some odd reason we need to detach the the mceInsertContent call from the paste event - // It's like IE has a reference to the parent element that you paste in and the selection gets messed up - // when it tries to restore the selection - setTimeout(function() { - // Process contents - process({content : n.innerHTML}); - }, 0); - - // Block the real paste event - return tinymce.dom.Event.cancel(e); - } else { - function block(e) { - e.preventDefault(); - }; - - // Block mousedown and click to prevent selection change - dom.bind(ed.getDoc(), 'mousedown', block); - dom.bind(ed.getDoc(), 'keydown', block); - - or = ed.selection.getRng(); - - // Move select contents inside DIV - n = n.firstChild; - rng = ed.getDoc().createRange(); - rng.setStart(n, 0); - rng.setEnd(n, 2); - sel.setRng(rng); - - // Wait a while and grab the pasted contents - window.setTimeout(function() { - var h = '', nl; - - // Paste divs duplicated in paste divs seems to happen when you paste plain text so lets first look for that broken behavior in WebKit - if (!dom.select('div.mcePaste > div.mcePaste').length) { - nl = dom.select('div.mcePaste'); - - // WebKit will split the div into multiple ones so this will loop through then all and join them to get the whole HTML string - each(nl, function(n) { - var child = n.firstChild; - - // WebKit inserts a DIV container with lots of odd styles - if (child && child.nodeName == 'DIV' && child.style.marginTop && child.style.backgroundColor) { - dom.remove(child, 1); - } - - // Remove apply style spans - each(dom.select('span.Apple-style-span', n), function(n) { - dom.remove(n, 1); - }); - - // Remove bogus br elements - each(dom.select('br[data-mce-bogus]', n), function(n) { - dom.remove(n); - }); - - // WebKit will make a copy of the DIV for each line of plain text pasted and insert them into the DIV - if (n.parentNode.className != 'mcePaste') - h += n.innerHTML; - }); - } else { - // Found WebKit weirdness so force the content into paragraphs this seems to happen when you paste plain text from Nodepad etc - // So this logic will replace double enter with paragraphs and single enter with br so it kind of looks the same - h = '

            ' + dom.encode(textContent).replace(/\r?\n\r?\n/g, '

            ').replace(/\r?\n/g, '
            ') + '

            '; - } - - // Remove the nodes - each(dom.select('div.mcePaste'), function(n) { - dom.remove(n); - }); - - // Restore the old selection - if (or) - sel.setRng(or); - - process({content : h}); - - // Unblock events ones we got the contents - dom.unbind(ed.getDoc(), 'mousedown', block); - dom.unbind(ed.getDoc(), 'keydown', block); - }, 0); - } - } - - // Check if we should use the new auto process method - if (getParam(ed, "paste_auto_cleanup_on_paste")) { - // Is it's Opera or older FF use key handler - if (tinymce.isOpera || /Firefox\/2/.test(navigator.userAgent)) { - ed.onKeyDown.addToTop(function(ed, e) { - if (((tinymce.isMac ? e.metaKey : e.ctrlKey) && e.keyCode == 86) || (e.shiftKey && e.keyCode == 45)) - grabContent(e); - }); - } else { - // Grab contents on paste event on Gecko and WebKit - ed.onPaste.addToTop(function(ed, e) { - return grabContent(e); - }); - } - } - - ed.onInit.add(function() { - ed.controlManager.setActive("pastetext", ed.pasteAsPlainText); - - // Block all drag/drop events - if (getParam(ed, "paste_block_drop")) { - ed.dom.bind(ed.getBody(), ['dragend', 'dragover', 'draggesture', 'dragdrop', 'drop', 'drag'], function(e) { - e.preventDefault(); - e.stopPropagation(); - - return false; - }); - } - }); - - // Add legacy support - t._legacySupport(); - }, - - getInfo : function() { - return { - longname : 'Paste text/word', - author : 'Moxiecode Systems AB', - authorurl : 'http://tinymce.moxiecode.com', - infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/paste', - version : tinymce.majorVersion + "." + tinymce.minorVersion - }; - }, - - _preProcess : function(pl, o) { - var ed = this.editor, - h = o.content, - grep = tinymce.grep, - explode = tinymce.explode, - trim = tinymce.trim, - len, stripClass; - - //console.log('Before preprocess:' + o.content); - - function process(items) { - each(items, function(v) { - // Remove or replace - if (v.constructor == RegExp) - h = h.replace(v, ''); - else - h = h.replace(v[0], v[1]); - }); - } - - if (ed.settings.paste_enable_default_filters == false) { - return; - } - - // IE9 adds BRs before/after block elements when contents is pasted from word or for example another browser - if (tinymce.isIE && document.documentMode >= 9 && /<(h[1-6r]|p|div|address|pre|form|table|tbody|thead|tfoot|th|tr|td|li|ol|ul|caption|blockquote|center|dl|dt|dd|dir|fieldset)/.test(o.content)) { - // IE9 adds BRs before/after block elements when contents is pasted from word or for example another browser - process([[/(?:
             [\s\r\n]+|
            )*(<\/?(h[1-6r]|p|div|address|pre|form|table|tbody|thead|tfoot|th|tr|td|li|ol|ul|caption|blockquote|center|dl|dt|dd|dir|fieldset)[^>]*>)(?:
             [\s\r\n]+|
            )*/g, '$1']]); - - // IE9 also adds an extra BR element for each soft-linefeed and it also adds a BR for each word wrap break - process([ - [/

            /g, '

            '], // Replace multiple BR elements with uppercase BR to keep them intact - [/
            /g, ' '], // Replace single br elements with space since they are word wrap BR:s - [/

            /g, '
            '] // Replace back the double brs but into a single BR - ]); - } - - // Detect Word content and process it more aggressive - if (/class="?Mso|style="[^"]*\bmso-|w:WordDocument/i.test(h) || o.wordContent) { - o.wordContent = true; // Mark the pasted contents as word specific content - //console.log('Word contents detected.'); - - // Process away some basic content - process([ - /^\s*( )+/gi, //   entities at the start of contents - /( |]*>)+\s*$/gi //   entities at the end of contents - ]); - - if (getParam(ed, "paste_convert_headers_to_strong")) { - h = h.replace(/

            ]*class="?MsoHeading"?[^>]*>(.*?)<\/p>/gi, "

            $1

            "); - } - - if (getParam(ed, "paste_convert_middot_lists")) { - process([ - [//gi, '$&__MCE_ITEM__'], // Convert supportLists to a list item marker - [/(]+(?:mso-list:|:\s*symbol)[^>]+>)/gi, '$1__MCE_ITEM__'], // Convert mso-list and symbol spans to item markers - [/(]+(?:MsoListParagraph)[^>]+>)/gi, '$1__MCE_ITEM__'] // Convert mso-list and symbol paragraphs to item markers (FF) - ]); - } - - process([ - // Word comments like conditional comments etc - //gi, - - // Remove comments, scripts (e.g., msoShowComment), XML tag, VML content, MS Office namespaced tags, and a few other tags - /<(!|script[^>]*>.*?<\/script(?=[>\s])|\/?(\?xml(:\w+)?|img|meta|link|style|\w:\w+)(?=[\s\/>]))[^>]*>/gi, - - // Convert into for line-though - [/<(\/?)s>/gi, "<$1strike>"], - - // Replace nsbp entites to char since it's easier to handle - [/ /gi, "\u00a0"] - ]); - - // Remove bad attributes, with or without quotes, ensuring that attribute text is really inside a tag. - // If JavaScript had a RegExp look-behind, we could have integrated this with the last process() array and got rid of the loop. But alas, it does not, so we cannot. - do { - len = h.length; - h = h.replace(/(<[a-z][^>]*\s)(?:id|name|language|type|on\w+|\w+:\w+)=(?:"[^"]*"|\w+)\s?/gi, "$1"); - } while (len != h.length); - - // Remove all spans if no styles is to be retained - if (getParam(ed, "paste_retain_style_properties").replace(/^none$/i, "").length == 0) { - h = h.replace(/<\/?span[^>]*>/gi, ""); - } else { - // We're keeping styles, so at least clean them up. - // CSS Reference: http://msdn.microsoft.com/en-us/library/aa155477.aspx - - process([ - // Convert ___ to string of alternating breaking/non-breaking spaces of same length - [/([\s\u00a0]*)<\/span>/gi, - function(str, spaces) { - return (spaces.length > 0)? spaces.replace(/./, " ").slice(Math.floor(spaces.length/2)).split("").join("\u00a0") : ""; - } - ], - - // Examine all styles: delete junk, transform some, and keep the rest - [/(<[a-z][^>]*)\sstyle="([^"]*)"/gi, - function(str, tag, style) { - var n = [], - i = 0, - s = explode(trim(style).replace(/"/gi, "'"), ";"); - - // Examine each style definition within the tag's style attribute - each(s, function(v) { - var name, value, - parts = explode(v, ":"); - - function ensureUnits(v) { - return v + ((v !== "0") && (/\d$/.test(v)))? "px" : ""; - } - - if (parts.length == 2) { - name = parts[0].toLowerCase(); - value = parts[1].toLowerCase(); - - // Translate certain MS Office styles into their CSS equivalents - switch (name) { - case "mso-padding-alt": - case "mso-padding-top-alt": - case "mso-padding-right-alt": - case "mso-padding-bottom-alt": - case "mso-padding-left-alt": - case "mso-margin-alt": - case "mso-margin-top-alt": - case "mso-margin-right-alt": - case "mso-margin-bottom-alt": - case "mso-margin-left-alt": - case "mso-table-layout-alt": - case "mso-height": - case "mso-width": - case "mso-vertical-align-alt": - n[i++] = name.replace(/^mso-|-alt$/g, "") + ":" + ensureUnits(value); - return; - - case "horiz-align": - n[i++] = "text-align:" + value; - return; - - case "vert-align": - n[i++] = "vertical-align:" + value; - return; - - case "font-color": - case "mso-foreground": - n[i++] = "color:" + value; - return; - - case "mso-background": - case "mso-highlight": - n[i++] = "background:" + value; - return; - - case "mso-default-height": - n[i++] = "min-height:" + ensureUnits(value); - return; - - case "mso-default-width": - n[i++] = "min-width:" + ensureUnits(value); - return; - - case "mso-padding-between-alt": - n[i++] = "border-collapse:separate;border-spacing:" + ensureUnits(value); - return; - - case "text-line-through": - if ((value == "single") || (value == "double")) { - n[i++] = "text-decoration:line-through"; - } - return; - - case "mso-zero-height": - if (value == "yes") { - n[i++] = "display:none"; - } - return; - } - - // Eliminate all MS Office style definitions that have no CSS equivalent by examining the first characters in the name - if (/^(mso|column|font-emph|lang|layout|line-break|list-image|nav|panose|punct|row|ruby|sep|size|src|tab-|table-border|text-(?!align|decor|indent|trans)|top-bar|version|vnd|word-break)/.test(name)) { - return; - } - - // If it reached this point, it must be a valid CSS style - n[i++] = name + ":" + parts[1]; // Lower-case name, but keep value case - } - }); - - // If style attribute contained any valid styles the re-write it; otherwise delete style attribute. - if (i > 0) { - return tag + ' style="' + n.join(';') + '"'; - } else { - return tag; - } - } - ] - ]); - } - } - - // Replace headers with - if (getParam(ed, "paste_convert_headers_to_strong")) { - process([ - [/]*>/gi, "

            "], - [/<\/h[1-6][^>]*>/gi, "

            "] - ]); - } - - process([ - // Copy paste from Java like Open Office will produce this junk on FF - [/Version:[\d.]+\nStartHTML:\d+\nEndHTML:\d+\nStartFragment:\d+\nEndFragment:\d+/gi, ''] - ]); - - // Class attribute options are: leave all as-is ("none"), remove all ("all"), or remove only those starting with mso ("mso"). - // Note:- paste_strip_class_attributes: "none", verify_css_classes: true is also a good variation. - stripClass = getParam(ed, "paste_strip_class_attributes"); - - if (stripClass !== "none") { - function removeClasses(match, g1) { - if (stripClass === "all") - return ''; - - var cls = grep(explode(g1.replace(/^(["'])(.*)\1$/, "$2"), " "), - function(v) { - return (/^(?!mso)/i.test(v)); - } - ); - - return cls.length ? ' class="' + cls.join(" ") + '"' : ''; - }; - - h = h.replace(/ class="([^"]+)"/gi, removeClasses); - h = h.replace(/ class=([\-\w]+)/gi, removeClasses); - } - - // Remove spans option - if (getParam(ed, "paste_remove_spans")) { - h = h.replace(/<\/?span[^>]*>/gi, ""); - } - - //console.log('After preprocess:' + h); - - o.content = h; - }, - - /** - * Various post process items. - */ - _postProcess : function(pl, o) { - var t = this, ed = t.editor, dom = ed.dom, styleProps; - - if (ed.settings.paste_enable_default_filters == false) { - return; - } - - if (o.wordContent) { - // Remove named anchors or TOC links - each(dom.select('a', o.node), function(a) { - if (!a.href || a.href.indexOf('#_Toc') != -1) - dom.remove(a, 1); - }); - - if (getParam(ed, "paste_convert_middot_lists")) { - t._convertLists(pl, o); - } - - // Process styles - styleProps = getParam(ed, "paste_retain_style_properties"); // retained properties - - // Process only if a string was specified and not equal to "all" or "*" - if ((tinymce.is(styleProps, "string")) && (styleProps !== "all") && (styleProps !== "*")) { - styleProps = tinymce.explode(styleProps.replace(/^none$/i, "")); - - // Retains some style properties - each(dom.select('*', o.node), function(el) { - var newStyle = {}, npc = 0, i, sp, sv; - - // Store a subset of the existing styles - if (styleProps) { - for (i = 0; i < styleProps.length; i++) { - sp = styleProps[i]; - sv = dom.getStyle(el, sp); - - if (sv) { - newStyle[sp] = sv; - npc++; - } - } - } - - // Remove all of the existing styles - dom.setAttrib(el, 'style', ''); - - if (styleProps && npc > 0) - dom.setStyles(el, newStyle); // Add back the stored subset of styles - else // Remove empty span tags that do not have class attributes - if (el.nodeName == 'SPAN' && !el.className) - dom.remove(el, true); - }); - } - } - - // Remove all style information or only specifically on WebKit to avoid the style bug on that browser - if (getParam(ed, "paste_remove_styles") || (getParam(ed, "paste_remove_styles_if_webkit") && tinymce.isWebKit)) { - each(dom.select('*[style]', o.node), function(el) { - el.removeAttribute('style'); - el.removeAttribute('data-mce-style'); - }); - } else { - if (tinymce.isWebKit) { - // We need to compress the styles on WebKit since if you paste it will become - // Removing the mce_style that contains the real value will force the Serializer engine to compress the styles - each(dom.select('*', o.node), function(el) { - el.removeAttribute('data-mce-style'); - }); - } - } - }, - - /** - * Converts the most common bullet and number formats in Office into a real semantic UL/LI list. - */ - _convertLists : function(pl, o) { - var dom = pl.editor.dom, listElm, li, lastMargin = -1, margin, levels = [], lastType, html; - - // Convert middot lists into real semantic lists - each(dom.select('p', o.node), function(p) { - var sib, val = '', type, html, idx, parents; - - // Get text node value at beginning of paragraph - for (sib = p.firstChild; sib && sib.nodeType == 3; sib = sib.nextSibling) - val += sib.nodeValue; - - val = p.innerHTML.replace(/<\/?\w+[^>]*>/gi, '').replace(/ /g, '\u00a0'); - - // Detect unordered lists look for bullets - if (/^(__MCE_ITEM__)+[\u2022\u00b7\u00a7\u00d8o\u25CF]\s*\u00a0*/.test(val)) - type = 'ul'; - - // Detect ordered lists 1., a. or ixv. - if (/^__MCE_ITEM__\s*\w+\.\s*\u00a0+/.test(val)) - type = 'ol'; - - // Check if node value matches the list pattern: o   - if (type) { - margin = parseFloat(p.style.marginLeft || 0); - - if (margin > lastMargin) - levels.push(margin); - - if (!listElm || type != lastType) { - listElm = dom.create(type); - dom.insertAfter(listElm, p); - } else { - // Nested list element - if (margin > lastMargin) { - listElm = li.appendChild(dom.create(type)); - } else if (margin < lastMargin) { - // Find parent level based on margin value - idx = tinymce.inArray(levels, margin); - parents = dom.getParents(listElm.parentNode, type); - listElm = parents[parents.length - 1 - idx] || listElm; - } - } - - // Remove middot or number spans if they exists - each(dom.select('span', p), function(span) { - var html = span.innerHTML.replace(/<\/?\w+[^>]*>/gi, ''); - - // Remove span with the middot or the number - if (type == 'ul' && /^__MCE_ITEM__[\u2022\u00b7\u00a7\u00d8o\u25CF]/.test(html)) - dom.remove(span); - else if (/^__MCE_ITEM__[\s\S]*\w+\.( |\u00a0)*\s*/.test(html)) - dom.remove(span); - }); - - html = p.innerHTML; - - // Remove middot/list items - if (type == 'ul') - html = p.innerHTML.replace(/__MCE_ITEM__/g, '').replace(/^[\u2022\u00b7\u00a7\u00d8o\u25CF]\s*( |\u00a0)+\s*/, ''); - else - html = p.innerHTML.replace(/__MCE_ITEM__/g, '').replace(/^\s*\w+\.( |\u00a0)+\s*/, ''); - - // Create li and add paragraph data into the new li - li = listElm.appendChild(dom.create('li', 0, html)); - dom.remove(p); - - lastMargin = margin; - lastType = type; - } else - listElm = lastMargin = 0; // End list element - }); - - // Remove any left over makers - html = o.node.innerHTML; - if (html.indexOf('__MCE_ITEM__') != -1) - o.node.innerHTML = html.replace(/__MCE_ITEM__/g, ''); - }, - - /** - * Inserts the specified contents at the caret position. - */ - _insert : function(h, skip_undo) { - var ed = this.editor, r = ed.selection.getRng(); - - // First delete the contents seems to work better on WebKit when the selection spans multiple list items or multiple table cells. - if (!ed.selection.isCollapsed() && r.startContainer != r.endContainer) - ed.getDoc().execCommand('Delete', false, null); - - ed.execCommand('mceInsertContent', false, h, {skip_undo : skip_undo}); - }, - - /** - * Instead of the old plain text method which tried to re-create a paste operation, the - * new approach adds a plain text mode toggle switch that changes the behavior of paste. - * This function is passed the same input that the regular paste plugin produces. - * It performs additional scrubbing and produces (and inserts) the plain text. - * This approach leverages all of the great existing functionality in the paste - * plugin, and requires minimal changes to add the new functionality. - * Speednet - June 2009 - */ - _insertPlainText : function(content) { - var ed = this.editor, - linebr = getParam(ed, "paste_text_linebreaktype"), - rl = getParam(ed, "paste_text_replacements"), - is = tinymce.is; - - function process(items) { - each(items, function(v) { - if (v.constructor == RegExp) - content = content.replace(v, ""); - else - content = content.replace(v[0], v[1]); - }); - }; - - if ((typeof(content) === "string") && (content.length > 0)) { - // If HTML content with line-breaking tags, then remove all cr/lf chars because only tags will break a line - if (/<(?:p|br|h[1-6]|ul|ol|dl|table|t[rdh]|div|blockquote|fieldset|pre|address|center)[^>]*>/i.test(content)) { - process([ - /[\n\r]+/g - ]); - } else { - // Otherwise just get rid of carriage returns (only need linefeeds) - process([ - /\r+/g - ]); - } - - process([ - [/<\/(?:p|h[1-6]|ul|ol|dl|table|div|blockquote|fieldset|pre|address|center)>/gi, "\n\n"], // Block tags get a blank line after them - [/]*>|<\/tr>/gi, "\n"], // Single linebreak for
            tags and table rows - [/<\/t[dh]>\s*]*>/gi, "\t"], // Table cells get tabs betweem them - /<[a-z!\/?][^>]*>/gi, // Delete all remaining tags - [/ /gi, " "], // Convert non-break spaces to regular spaces (remember, *plain text*) - [/(?:(?!\n)\s)*(\n+)(?:(?!\n)\s)*/gi, "$1"],// Cool little RegExp deletes whitespace around linebreak chars. - [/\n{3,}/g, "\n\n"] // Max. 2 consecutive linebreaks - ]); - - content = ed.dom.decode(tinymce.html.Entities.encodeRaw(content)); - - // Perform default or custom replacements - if (is(rl, "array")) { - process(rl); - } else if (is(rl, "string")) { - process(new RegExp(rl, "gi")); - } - - // Treat paragraphs as specified in the config - if (linebr == "none") { - // Convert all line breaks to space - process([ - [/\n+/g, " "] - ]); - } else if (linebr == "br") { - // Convert all line breaks to
            - process([ - [/\n/g, "
            "] - ]); - } else if (linebr == "p") { - // Convert all line breaks to

            ...

            - process([ - [/\n+/g, "

            "], - [/^(.*<\/p>)(

            )$/, '

            $1'] - ]); - } else { - // defaults to "combined" - // Convert single line breaks to
            and double line breaks to

            ...

            - process([ - [/\n\n/g, "

            "], - [/^(.*<\/p>)(

            )$/, '

            $1'], - [/\n/g, "
            "] - ]); - } - - ed.execCommand('mceInsertContent', false, content); - } - }, - - /** - * This method will open the old style paste dialogs. Some users might want the old behavior but still use the new cleanup engine. - */ - _legacySupport : function() { - var t = this, ed = t.editor; - - // Register command(s) for backwards compatibility - ed.addCommand("mcePasteWord", function() { - ed.windowManager.open({ - file: t.url + "/pasteword.htm", - width: parseInt(getParam(ed, "paste_dialog_width")), - height: parseInt(getParam(ed, "paste_dialog_height")), - inline: 1 - }); - }); - - if (getParam(ed, "paste_text_use_dialog")) { - ed.addCommand("mcePasteText", function() { - ed.windowManager.open({ - file : t.url + "/pastetext.htm", - width: parseInt(getParam(ed, "paste_dialog_width")), - height: parseInt(getParam(ed, "paste_dialog_height")), - inline : 1 - }); - }); - } - - // Register button for backwards compatibility - ed.addButton("pasteword", {title : "paste.paste_word_desc", cmd : "mcePasteWord"}); - } - }); - - // Register plugin - tinymce.PluginManager.add("paste", tinymce.plugins.PastePlugin); -})(); +/** + * editor_plugin_src.js + * + * Copyright 2009, Moxiecode Systems AB + * Released under LGPL License. + * + * License: http://tinymce.moxiecode.com/license + * Contributing: http://tinymce.moxiecode.com/contributing + */ + +(function() { + var each = tinymce.each, + defs = { + paste_auto_cleanup_on_paste : true, + paste_enable_default_filters : true, + paste_block_drop : false, + paste_retain_style_properties : "none", + paste_strip_class_attributes : "mso", + paste_remove_spans : false, + paste_remove_styles : false, + paste_remove_styles_if_webkit : true, + paste_convert_middot_lists : true, + paste_convert_headers_to_strong : false, + paste_dialog_width : "450", + paste_dialog_height : "400", + paste_text_use_dialog : false, + paste_text_sticky : false, + paste_text_sticky_default : false, + paste_text_notifyalways : false, + paste_text_linebreaktype : "combined", + paste_text_replacements : [ + [/\u2026/g, "..."], + [/[\x93\x94\u201c\u201d]/g, '"'], + [/[\x60\x91\x92\u2018\u2019]/g, "'"] + ] + }; + + function getParam(ed, name) { + return ed.getParam(name, defs[name]); + } + + tinymce.create('tinymce.plugins.PastePlugin', { + init : function(ed, url) { + var t = this; + + t.editor = ed; + t.url = url; + + // Setup plugin events + t.onPreProcess = new tinymce.util.Dispatcher(t); + t.onPostProcess = new tinymce.util.Dispatcher(t); + + // Register default handlers + t.onPreProcess.add(t._preProcess); + t.onPostProcess.add(t._postProcess); + + // Register optional preprocess handler + t.onPreProcess.add(function(pl, o) { + ed.execCallback('paste_preprocess', pl, o); + }); + + // Register optional postprocess + t.onPostProcess.add(function(pl, o) { + ed.execCallback('paste_postprocess', pl, o); + }); + + ed.onKeyDown.addToTop(function(ed, e) { + // Block ctrl+v from adding an undo level since the default logic in tinymce.Editor will add that + if (((tinymce.isMac ? e.metaKey : e.ctrlKey) && e.keyCode == 86) || (e.shiftKey && e.keyCode == 45)) + return false; // Stop other listeners + }); + + // Initialize plain text flag + ed.pasteAsPlainText = getParam(ed, 'paste_text_sticky_default'); + + // This function executes the process handlers and inserts the contents + // force_rich overrides plain text mode set by user, important for pasting with execCommand + function process(o, force_rich) { + var dom = ed.dom, rng; + + // Execute pre process handlers + t.onPreProcess.dispatch(t, o); + + // Create DOM structure + o.node = dom.create('div', 0, o.content); + + // If pasting inside the same element and the contents is only one block + // remove the block and keep the text since Firefox will copy parts of pre and h1-h6 as a pre element + if (tinymce.isGecko) { + rng = ed.selection.getRng(true); + if (rng.startContainer == rng.endContainer && rng.startContainer.nodeType == 3) { + // Is only one block node and it doesn't contain word stuff + if (o.node.childNodes.length === 1 && /^(p|h[1-6]|pre)$/i.test(o.node.firstChild.nodeName) && o.content.indexOf('__MCE_ITEM__') === -1) + dom.remove(o.node.firstChild, true); + } + } + + // Execute post process handlers + t.onPostProcess.dispatch(t, o); + + // Serialize content + o.content = ed.serializer.serialize(o.node, {getInner : 1, forced_root_block : ''}); + + // Plain text option active? + if ((!force_rich) && (ed.pasteAsPlainText)) { + t._insertPlainText(o.content); + + if (!getParam(ed, "paste_text_sticky")) { + ed.pasteAsPlainText = false; + ed.controlManager.setActive("pastetext", false); + } + } else { + t._insert(o.content); + } + } + + // Add command for external usage + ed.addCommand('mceInsertClipboardContent', function(u, o) { + process(o, true); + }); + + if (!getParam(ed, "paste_text_use_dialog")) { + ed.addCommand('mcePasteText', function(u, v) { + var cookie = tinymce.util.Cookie; + + ed.pasteAsPlainText = !ed.pasteAsPlainText; + ed.controlManager.setActive('pastetext', ed.pasteAsPlainText); + + if ((ed.pasteAsPlainText) && (!cookie.get("tinymcePasteText"))) { + if (getParam(ed, "paste_text_sticky")) { + ed.windowManager.alert(ed.translate('paste.plaintext_mode_sticky')); + } else { + ed.windowManager.alert(ed.translate('paste.plaintext_mode')); + } + + if (!getParam(ed, "paste_text_notifyalways")) { + cookie.set("tinymcePasteText", "1", new Date(new Date().getFullYear() + 1, 12, 31)) + } + } + }); + } + + ed.addButton('pastetext', {title: 'paste.paste_text_desc', cmd: 'mcePasteText'}); + ed.addButton('selectall', {title: 'paste.selectall_desc', cmd: 'selectall'}); + + // This function grabs the contents from the clipboard by adding a + // hidden div and placing the caret inside it and after the browser paste + // is done it grabs that contents and processes that + function grabContent(e) { + var n, or, rng, oldRng, sel = ed.selection, dom = ed.dom, body = ed.getBody(), posY, textContent; + + // Check if browser supports direct plaintext access + if (e.clipboardData || dom.doc.dataTransfer) { + textContent = (e.clipboardData || dom.doc.dataTransfer).getData('Text'); + + if (ed.pasteAsPlainText) { + e.preventDefault(); + process({content : dom.encode(textContent).replace(/\r?\n/g, '
            ')}); + return; + } + } + + if (dom.get('_mcePaste')) + return; + + // Create container to paste into + n = dom.add(body, 'div', {id : '_mcePaste', 'class' : 'mcePaste', 'data-mce-bogus' : '1'}, '\uFEFF\uFEFF'); + + // If contentEditable mode we need to find out the position of the closest element + if (body != ed.getDoc().body) + posY = dom.getPos(ed.selection.getStart(), body).y; + else + posY = body.scrollTop + dom.getViewPort(ed.getWin()).y; + + // Styles needs to be applied after the element is added to the document since WebKit will otherwise remove all styles + // If also needs to be in view on IE or the paste would fail + dom.setStyles(n, { + position : 'absolute', + left : tinymce.isGecko ? -40 : 0, // Need to move it out of site on Gecko since it will othewise display a ghost resize rect for the div + top : posY - 25, + width : 1, + height : 1, + overflow : 'hidden' + }); + + if (tinymce.isIE) { + // Store away the old range + oldRng = sel.getRng(); + + // Select the container + rng = dom.doc.body.createTextRange(); + rng.moveToElementText(n); + rng.execCommand('Paste'); + + // Remove container + dom.remove(n); + + // Check if the contents was changed, if it wasn't then clipboard extraction failed probably due + // to IE security settings so we pass the junk though better than nothing right + if (n.innerHTML === '\uFEFF\uFEFF') { + ed.execCommand('mcePasteWord'); + e.preventDefault(); + return; + } + + // Restore the old range and clear the contents before pasting + sel.setRng(oldRng); + sel.setContent(''); + + // For some odd reason we need to detach the the mceInsertContent call from the paste event + // It's like IE has a reference to the parent element that you paste in and the selection gets messed up + // when it tries to restore the selection + setTimeout(function() { + // Process contents + process({content : n.innerHTML}); + }, 0); + + // Block the real paste event + return tinymce.dom.Event.cancel(e); + } else { + function block(e) { + e.preventDefault(); + }; + + // Block mousedown and click to prevent selection change + dom.bind(ed.getDoc(), 'mousedown', block); + dom.bind(ed.getDoc(), 'keydown', block); + + or = ed.selection.getRng(); + + // Move select contents inside DIV + n = n.firstChild; + rng = ed.getDoc().createRange(); + rng.setStart(n, 0); + rng.setEnd(n, 2); + sel.setRng(rng); + + // Wait a while and grab the pasted contents + window.setTimeout(function() { + var h = '', nl; + + // Paste divs duplicated in paste divs seems to happen when you paste plain text so lets first look for that broken behavior in WebKit + if (!dom.select('div.mcePaste > div.mcePaste').length) { + nl = dom.select('div.mcePaste'); + + // WebKit will split the div into multiple ones so this will loop through then all and join them to get the whole HTML string + each(nl, function(n) { + var child = n.firstChild; + + // WebKit inserts a DIV container with lots of odd styles + if (child && child.nodeName == 'DIV' && child.style.marginTop && child.style.backgroundColor) { + dom.remove(child, 1); + } + + // Remove apply style spans + each(dom.select('span.Apple-style-span', n), function(n) { + dom.remove(n, 1); + }); + + // Remove bogus br elements + each(dom.select('br[data-mce-bogus]', n), function(n) { + dom.remove(n); + }); + + // WebKit will make a copy of the DIV for each line of plain text pasted and insert them into the DIV + if (n.parentNode.className != 'mcePaste') + h += n.innerHTML; + }); + } else { + // Found WebKit weirdness so force the content into paragraphs this seems to happen when you paste plain text from Nodepad etc + // So this logic will replace double enter with paragraphs and single enter with br so it kind of looks the same + h = '

            ' + dom.encode(textContent).replace(/\r?\n\r?\n/g, '

            ').replace(/\r?\n/g, '
            ') + '

            '; + } + + // Remove the nodes + each(dom.select('div.mcePaste'), function(n) { + dom.remove(n); + }); + + // Restore the old selection + if (or) + sel.setRng(or); + + process({content : h}); + + // Unblock events ones we got the contents + dom.unbind(ed.getDoc(), 'mousedown', block); + dom.unbind(ed.getDoc(), 'keydown', block); + }, 0); + } + } + + // Check if we should use the new auto process method + if (getParam(ed, "paste_auto_cleanup_on_paste")) { + // Is it's Opera or older FF use key handler + if (tinymce.isOpera || /Firefox\/2/.test(navigator.userAgent)) { + ed.onKeyDown.addToTop(function(ed, e) { + if (((tinymce.isMac ? e.metaKey : e.ctrlKey) && e.keyCode == 86) || (e.shiftKey && e.keyCode == 45)) + grabContent(e); + }); + } else { + // Grab contents on paste event on Gecko and WebKit + ed.onPaste.addToTop(function(ed, e) { + return grabContent(e); + }); + } + } + + ed.onInit.add(function() { + ed.controlManager.setActive("pastetext", ed.pasteAsPlainText); + + // Block all drag/drop events + if (getParam(ed, "paste_block_drop")) { + ed.dom.bind(ed.getBody(), ['dragend', 'dragover', 'draggesture', 'dragdrop', 'drop', 'drag'], function(e) { + e.preventDefault(); + e.stopPropagation(); + + return false; + }); + } + }); + + // Add legacy support + t._legacySupport(); + }, + + getInfo : function() { + return { + longname : 'Paste text/word', + author : 'Moxiecode Systems AB', + authorurl : 'http://tinymce.moxiecode.com', + infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/paste', + version : tinymce.majorVersion + "." + tinymce.minorVersion + }; + }, + + _preProcess : function(pl, o) { + var ed = this.editor, + h = o.content, + grep = tinymce.grep, + explode = tinymce.explode, + trim = tinymce.trim, + len, stripClass; + + //console.log('Before preprocess:' + o.content); + + function process(items) { + each(items, function(v) { + // Remove or replace + if (v.constructor == RegExp) + h = h.replace(v, ''); + else + h = h.replace(v[0], v[1]); + }); + } + + if (ed.settings.paste_enable_default_filters == false) { + return; + } + + // IE9 adds BRs before/after block elements when contents is pasted from word or for example another browser + if (tinymce.isIE && document.documentMode >= 9 && /<(h[1-6r]|p|div|address|pre|form|table|tbody|thead|tfoot|th|tr|td|li|ol|ul|caption|blockquote|center|dl|dt|dd|dir|fieldset)/.test(o.content)) { + // IE9 adds BRs before/after block elements when contents is pasted from word or for example another browser + process([[/(?:
             [\s\r\n]+|
            )*(<\/?(h[1-6r]|p|div|address|pre|form|table|tbody|thead|tfoot|th|tr|td|li|ol|ul|caption|blockquote|center|dl|dt|dd|dir|fieldset)[^>]*>)(?:
             [\s\r\n]+|
            )*/g, '$1']]); + + // IE9 also adds an extra BR element for each soft-linefeed and it also adds a BR for each word wrap break + process([ + [/

            /g, '

            '], // Replace multiple BR elements with uppercase BR to keep them intact + [/
            /g, ' '], // Replace single br elements with space since they are word wrap BR:s + [/

            /g, '
            '] // Replace back the double brs but into a single BR + ]); + } + + // Detect Word content and process it more aggressive + if (/class="?Mso|style="[^"]*\bmso-|w:WordDocument/i.test(h) || o.wordContent) { + o.wordContent = true; // Mark the pasted contents as word specific content + //console.log('Word contents detected.'); + + // Process away some basic content + process([ + /^\s*( )+/gi, //   entities at the start of contents + /( |]*>)+\s*$/gi //   entities at the end of contents + ]); + + if (getParam(ed, "paste_convert_headers_to_strong")) { + h = h.replace(/

            ]*class="?MsoHeading"?[^>]*>(.*?)<\/p>/gi, "

            $1

            "); + } + + if (getParam(ed, "paste_convert_middot_lists")) { + process([ + [//gi, '$&__MCE_ITEM__'], // Convert supportLists to a list item marker + [/(]+(?:mso-list:|:\s*symbol)[^>]+>)/gi, '$1__MCE_ITEM__'], // Convert mso-list and symbol spans to item markers + [/(]+(?:MsoListParagraph)[^>]+>)/gi, '$1__MCE_ITEM__'] // Convert mso-list and symbol paragraphs to item markers (FF) + ]); + } + + process([ + // Word comments like conditional comments etc + //gi, + + // Remove comments, scripts (e.g., msoShowComment), XML tag, VML content, MS Office namespaced tags, and a few other tags + /<(!|script[^>]*>.*?<\/script(?=[>\s])|\/?(\?xml(:\w+)?|img|meta|link|style|\w:\w+)(?=[\s\/>]))[^>]*>/gi, + + // Convert into for line-though + [/<(\/?)s>/gi, "<$1strike>"], + + // Replace nsbp entites to char since it's easier to handle + [/ /gi, "\u00a0"] + ]); + + // Remove bad attributes, with or without quotes, ensuring that attribute text is really inside a tag. + // If JavaScript had a RegExp look-behind, we could have integrated this with the last process() array and got rid of the loop. But alas, it does not, so we cannot. + do { + len = h.length; + h = h.replace(/(<[a-z][^>]*\s)(?:id|name|language|type|on\w+|\w+:\w+)=(?:"[^"]*"|\w+)\s?/gi, "$1"); + } while (len != h.length); + + // Remove all spans if no styles is to be retained + if (getParam(ed, "paste_retain_style_properties").replace(/^none$/i, "").length == 0) { + h = h.replace(/<\/?span[^>]*>/gi, ""); + } else { + // We're keeping styles, so at least clean them up. + // CSS Reference: http://msdn.microsoft.com/en-us/library/aa155477.aspx + + process([ + // Convert ___ to string of alternating breaking/non-breaking spaces of same length + [/([\s\u00a0]*)<\/span>/gi, + function(str, spaces) { + return (spaces.length > 0)? spaces.replace(/./, " ").slice(Math.floor(spaces.length/2)).split("").join("\u00a0") : ""; + } + ], + + // Examine all styles: delete junk, transform some, and keep the rest + [/(<[a-z][^>]*)\sstyle="([^"]*)"/gi, + function(str, tag, style) { + var n = [], + i = 0, + s = explode(trim(style).replace(/"/gi, "'"), ";"); + + // Examine each style definition within the tag's style attribute + each(s, function(v) { + var name, value, + parts = explode(v, ":"); + + function ensureUnits(v) { + return v + ((v !== "0") && (/\d$/.test(v)))? "px" : ""; + } + + if (parts.length == 2) { + name = parts[0].toLowerCase(); + value = parts[1].toLowerCase(); + + // Translate certain MS Office styles into their CSS equivalents + switch (name) { + case "mso-padding-alt": + case "mso-padding-top-alt": + case "mso-padding-right-alt": + case "mso-padding-bottom-alt": + case "mso-padding-left-alt": + case "mso-margin-alt": + case "mso-margin-top-alt": + case "mso-margin-right-alt": + case "mso-margin-bottom-alt": + case "mso-margin-left-alt": + case "mso-table-layout-alt": + case "mso-height": + case "mso-width": + case "mso-vertical-align-alt": + n[i++] = name.replace(/^mso-|-alt$/g, "") + ":" + ensureUnits(value); + return; + + case "horiz-align": + n[i++] = "text-align:" + value; + return; + + case "vert-align": + n[i++] = "vertical-align:" + value; + return; + + case "font-color": + case "mso-foreground": + n[i++] = "color:" + value; + return; + + case "mso-background": + case "mso-highlight": + n[i++] = "background:" + value; + return; + + case "mso-default-height": + n[i++] = "min-height:" + ensureUnits(value); + return; + + case "mso-default-width": + n[i++] = "min-width:" + ensureUnits(value); + return; + + case "mso-padding-between-alt": + n[i++] = "border-collapse:separate;border-spacing:" + ensureUnits(value); + return; + + case "text-line-through": + if ((value == "single") || (value == "double")) { + n[i++] = "text-decoration:line-through"; + } + return; + + case "mso-zero-height": + if (value == "yes") { + n[i++] = "display:none"; + } + return; + } + + // Eliminate all MS Office style definitions that have no CSS equivalent by examining the first characters in the name + if (/^(mso|column|font-emph|lang|layout|line-break|list-image|nav|panose|punct|row|ruby|sep|size|src|tab-|table-border|text-(?!align|decor|indent|trans)|top-bar|version|vnd|word-break)/.test(name)) { + return; + } + + // If it reached this point, it must be a valid CSS style + n[i++] = name + ":" + parts[1]; // Lower-case name, but keep value case + } + }); + + // If style attribute contained any valid styles the re-write it; otherwise delete style attribute. + if (i > 0) { + return tag + ' style="' + n.join(';') + '"'; + } else { + return tag; + } + } + ] + ]); + } + } + + // Replace headers with + if (getParam(ed, "paste_convert_headers_to_strong")) { + process([ + [/]*>/gi, "

            "], + [/<\/h[1-6][^>]*>/gi, "

            "] + ]); + } + + process([ + // Copy paste from Java like Open Office will produce this junk on FF + [/Version:[\d.]+\nStartHTML:\d+\nEndHTML:\d+\nStartFragment:\d+\nEndFragment:\d+/gi, ''] + ]); + + // Class attribute options are: leave all as-is ("none"), remove all ("all"), or remove only those starting with mso ("mso"). + // Note:- paste_strip_class_attributes: "none", verify_css_classes: true is also a good variation. + stripClass = getParam(ed, "paste_strip_class_attributes"); + + if (stripClass !== "none") { + function removeClasses(match, g1) { + if (stripClass === "all") + return ''; + + var cls = grep(explode(g1.replace(/^(["'])(.*)\1$/, "$2"), " "), + function(v) { + return (/^(?!mso)/i.test(v)); + } + ); + + return cls.length ? ' class="' + cls.join(" ") + '"' : ''; + }; + + h = h.replace(/ class="([^"]+)"/gi, removeClasses); + h = h.replace(/ class=([\-\w]+)/gi, removeClasses); + } + + // Remove spans option + if (getParam(ed, "paste_remove_spans")) { + h = h.replace(/<\/?span[^>]*>/gi, ""); + } + + //console.log('After preprocess:' + h); + + o.content = h; + }, + + /** + * Various post process items. + */ + _postProcess : function(pl, o) { + var t = this, ed = t.editor, dom = ed.dom, styleProps; + + if (ed.settings.paste_enable_default_filters == false) { + return; + } + + if (o.wordContent) { + // Remove named anchors or TOC links + each(dom.select('a', o.node), function(a) { + if (!a.href || a.href.indexOf('#_Toc') != -1) + dom.remove(a, 1); + }); + + if (getParam(ed, "paste_convert_middot_lists")) { + t._convertLists(pl, o); + } + + // Process styles + styleProps = getParam(ed, "paste_retain_style_properties"); // retained properties + + // Process only if a string was specified and not equal to "all" or "*" + if ((tinymce.is(styleProps, "string")) && (styleProps !== "all") && (styleProps !== "*")) { + styleProps = tinymce.explode(styleProps.replace(/^none$/i, "")); + + // Retains some style properties + each(dom.select('*', o.node), function(el) { + var newStyle = {}, npc = 0, i, sp, sv; + + // Store a subset of the existing styles + if (styleProps) { + for (i = 0; i < styleProps.length; i++) { + sp = styleProps[i]; + sv = dom.getStyle(el, sp); + + if (sv) { + newStyle[sp] = sv; + npc++; + } + } + } + + // Remove all of the existing styles + dom.setAttrib(el, 'style', ''); + + if (styleProps && npc > 0) + dom.setStyles(el, newStyle); // Add back the stored subset of styles + else // Remove empty span tags that do not have class attributes + if (el.nodeName == 'SPAN' && !el.className) + dom.remove(el, true); + }); + } + } + + // Remove all style information or only specifically on WebKit to avoid the style bug on that browser + if (getParam(ed, "paste_remove_styles") || (getParam(ed, "paste_remove_styles_if_webkit") && tinymce.isWebKit)) { + each(dom.select('*[style]', o.node), function(el) { + el.removeAttribute('style'); + el.removeAttribute('data-mce-style'); + }); + } else { + if (tinymce.isWebKit) { + // We need to compress the styles on WebKit since if you paste it will become + // Removing the mce_style that contains the real value will force the Serializer engine to compress the styles + each(dom.select('*', o.node), function(el) { + el.removeAttribute('data-mce-style'); + }); + } + } + }, + + /** + * Converts the most common bullet and number formats in Office into a real semantic UL/LI list. + */ + _convertLists : function(pl, o) { + var dom = pl.editor.dom, listElm, li, lastMargin = -1, margin, levels = [], lastType, html; + + // Convert middot lists into real semantic lists + each(dom.select('p', o.node), function(p) { + var sib, val = '', type, html, idx, parents; + + // Get text node value at beginning of paragraph + for (sib = p.firstChild; sib && sib.nodeType == 3; sib = sib.nextSibling) + val += sib.nodeValue; + + val = p.innerHTML.replace(/<\/?\w+[^>]*>/gi, '').replace(/ /g, '\u00a0'); + + // Detect unordered lists look for bullets + if (/^(__MCE_ITEM__)+[\u2022\u00b7\u00a7\u00d8o\u25CF]\s*\u00a0*/.test(val)) + type = 'ul'; + + // Detect ordered lists 1., a. or ixv. + if (/^__MCE_ITEM__\s*\w+\.\s*\u00a0+/.test(val)) + type = 'ol'; + + // Check if node value matches the list pattern: o   + if (type) { + margin = parseFloat(p.style.marginLeft || 0); + + if (margin > lastMargin) + levels.push(margin); + + if (!listElm || type != lastType) { + listElm = dom.create(type); + dom.insertAfter(listElm, p); + } else { + // Nested list element + if (margin > lastMargin) { + listElm = li.appendChild(dom.create(type)); + } else if (margin < lastMargin) { + // Find parent level based on margin value + idx = tinymce.inArray(levels, margin); + parents = dom.getParents(listElm.parentNode, type); + listElm = parents[parents.length - 1 - idx] || listElm; + } + } + + // Remove middot or number spans if they exists + each(dom.select('span', p), function(span) { + var html = span.innerHTML.replace(/<\/?\w+[^>]*>/gi, ''); + + // Remove span with the middot or the number + if (type == 'ul' && /^__MCE_ITEM__[\u2022\u00b7\u00a7\u00d8o\u25CF]/.test(html)) + dom.remove(span); + else if (/^__MCE_ITEM__[\s\S]*\w+\.( |\u00a0)*\s*/.test(html)) + dom.remove(span); + }); + + html = p.innerHTML; + + // Remove middot/list items + if (type == 'ul') + html = p.innerHTML.replace(/__MCE_ITEM__/g, '').replace(/^[\u2022\u00b7\u00a7\u00d8o\u25CF]\s*( |\u00a0)+\s*/, ''); + else + html = p.innerHTML.replace(/__MCE_ITEM__/g, '').replace(/^\s*\w+\.( |\u00a0)+\s*/, ''); + + // Create li and add paragraph data into the new li + li = listElm.appendChild(dom.create('li', 0, html)); + dom.remove(p); + + lastMargin = margin; + lastType = type; + } else + listElm = lastMargin = 0; // End list element + }); + + // Remove any left over makers + html = o.node.innerHTML; + if (html.indexOf('__MCE_ITEM__') != -1) + o.node.innerHTML = html.replace(/__MCE_ITEM__/g, ''); + }, + + /** + * Inserts the specified contents at the caret position. + */ + _insert : function(h, skip_undo) { + var ed = this.editor, r = ed.selection.getRng(); + + // First delete the contents seems to work better on WebKit when the selection spans multiple list items or multiple table cells. + if (!ed.selection.isCollapsed() && r.startContainer != r.endContainer) + ed.getDoc().execCommand('Delete', false, null); + + ed.execCommand('mceInsertContent', false, h, {skip_undo : skip_undo}); + }, + + /** + * Instead of the old plain text method which tried to re-create a paste operation, the + * new approach adds a plain text mode toggle switch that changes the behavior of paste. + * This function is passed the same input that the regular paste plugin produces. + * It performs additional scrubbing and produces (and inserts) the plain text. + * This approach leverages all of the great existing functionality in the paste + * plugin, and requires minimal changes to add the new functionality. + * Speednet - June 2009 + */ + _insertPlainText : function(content) { + var ed = this.editor, + linebr = getParam(ed, "paste_text_linebreaktype"), + rl = getParam(ed, "paste_text_replacements"), + is = tinymce.is; + + function process(items) { + each(items, function(v) { + if (v.constructor == RegExp) + content = content.replace(v, ""); + else + content = content.replace(v[0], v[1]); + }); + }; + + if ((typeof(content) === "string") && (content.length > 0)) { + // If HTML content with line-breaking tags, then remove all cr/lf chars because only tags will break a line + if (/<(?:p|br|h[1-6]|ul|ol|dl|table|t[rdh]|div|blockquote|fieldset|pre|address|center)[^>]*>/i.test(content)) { + process([ + /[\n\r]+/g + ]); + } else { + // Otherwise just get rid of carriage returns (only need linefeeds) + process([ + /\r+/g + ]); + } + + process([ + [/<\/(?:p|h[1-6]|ul|ol|dl|table|div|blockquote|fieldset|pre|address|center)>/gi, "\n\n"], // Block tags get a blank line after them + [/]*>|<\/tr>/gi, "\n"], // Single linebreak for
            tags and table rows + [/<\/t[dh]>\s*]*>/gi, "\t"], // Table cells get tabs betweem them + /<[a-z!\/?][^>]*>/gi, // Delete all remaining tags + [/ /gi, " "], // Convert non-break spaces to regular spaces (remember, *plain text*) + [/(?:(?!\n)\s)*(\n+)(?:(?!\n)\s)*/gi, "$1"],// Cool little RegExp deletes whitespace around linebreak chars. + [/\n{3,}/g, "\n\n"] // Max. 2 consecutive linebreaks + ]); + + content = ed.dom.decode(tinymce.html.Entities.encodeRaw(content)); + + // Perform default or custom replacements + if (is(rl, "array")) { + process(rl); + } else if (is(rl, "string")) { + process(new RegExp(rl, "gi")); + } + + // Treat paragraphs as specified in the config + if (linebr == "none") { + // Convert all line breaks to space + process([ + [/\n+/g, " "] + ]); + } else if (linebr == "br") { + // Convert all line breaks to
            + process([ + [/\n/g, "
            "] + ]); + } else if (linebr == "p") { + // Convert all line breaks to

            ...

            + process([ + [/\n+/g, "

            "], + [/^(.*<\/p>)(

            )$/, '

            $1'] + ]); + } else { + // defaults to "combined" + // Convert single line breaks to
            and double line breaks to

            ...

            + process([ + [/\n\n/g, "

            "], + [/^(.*<\/p>)(

            )$/, '

            $1'], + [/\n/g, "
            "] + ]); + } + + ed.execCommand('mceInsertContent', false, content); + } + }, + + /** + * This method will open the old style paste dialogs. Some users might want the old behavior but still use the new cleanup engine. + */ + _legacySupport : function() { + var t = this, ed = t.editor; + + // Register command(s) for backwards compatibility + ed.addCommand("mcePasteWord", function() { + ed.windowManager.open({ + file: t.url + "/pasteword.htm", + width: parseInt(getParam(ed, "paste_dialog_width")), + height: parseInt(getParam(ed, "paste_dialog_height")), + inline: 1 + }); + }); + + if (getParam(ed, "paste_text_use_dialog")) { + ed.addCommand("mcePasteText", function() { + ed.windowManager.open({ + file : t.url + "/pastetext.htm", + width: parseInt(getParam(ed, "paste_dialog_width")), + height: parseInt(getParam(ed, "paste_dialog_height")), + inline : 1 + }); + }); + } + + // Register button for backwards compatibility + ed.addButton("pasteword", {title : "paste.paste_word_desc", cmd : "mcePasteWord"}); + } + }); + + // Register plugin + tinymce.PluginManager.add("paste", tinymce.plugins.PastePlugin); +})(); diff --git a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/paste/js/pastetext.js b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/paste/js/pastetext.js index 81b1d6a..c524f9e 100644 --- a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/paste/js/pastetext.js +++ b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/paste/js/pastetext.js @@ -1,36 +1,36 @@ -tinyMCEPopup.requireLangPack(); - -var PasteTextDialog = { - init : function() { - this.resize(); - }, - - insert : function() { - var h = tinyMCEPopup.dom.encode(document.getElementById('content').value), lines; - - // Convert linebreaks into paragraphs - if (document.getElementById('linebreaks').checked) { - lines = h.split(/\r?\n/); - if (lines.length > 1) { - h = ''; - tinymce.each(lines, function(row) { - h += '

            ' + row + '

            '; - }); - } - } - - tinyMCEPopup.editor.execCommand('mceInsertClipboardContent', false, {content : h}); - tinyMCEPopup.close(); - }, - - resize : function() { - var vp = tinyMCEPopup.dom.getViewPort(window), el; - - el = document.getElementById('content'); - - el.style.width = (vp.w - 20) + 'px'; - el.style.height = (vp.h - 90) + 'px'; - } -}; - -tinyMCEPopup.onInit.add(PasteTextDialog.init, PasteTextDialog); +tinyMCEPopup.requireLangPack(); + +var PasteTextDialog = { + init : function() { + this.resize(); + }, + + insert : function() { + var h = tinyMCEPopup.dom.encode(document.getElementById('content').value), lines; + + // Convert linebreaks into paragraphs + if (document.getElementById('linebreaks').checked) { + lines = h.split(/\r?\n/); + if (lines.length > 1) { + h = ''; + tinymce.each(lines, function(row) { + h += '

            ' + row + '

            '; + }); + } + } + + tinyMCEPopup.editor.execCommand('mceInsertClipboardContent', false, {content : h}); + tinyMCEPopup.close(); + }, + + resize : function() { + var vp = tinyMCEPopup.dom.getViewPort(window), el; + + el = document.getElementById('content'); + + el.style.width = (vp.w - 20) + 'px'; + el.style.height = (vp.h - 90) + 'px'; + } +}; + +tinyMCEPopup.onInit.add(PasteTextDialog.init, PasteTextDialog); diff --git a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/paste/js/pasteword.js b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/paste/js/pasteword.js index 959bf39..a52731c 100644 --- a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/paste/js/pasteword.js +++ b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/paste/js/pasteword.js @@ -1,51 +1,51 @@ -tinyMCEPopup.requireLangPack(); - -var PasteWordDialog = { - init : function() { - var ed = tinyMCEPopup.editor, el = document.getElementById('iframecontainer'), ifr, doc, css, cssHTML = ''; - - // Create iframe - el.innerHTML = ''; - ifr = document.getElementById('iframe'); - doc = ifr.contentWindow.document; - - // Force absolute CSS urls - css = [ed.baseURI.toAbsolute("themes/" + ed.settings.theme + "/skins/" + ed.settings.skin + "/content.css")]; - css = css.concat(tinymce.explode(ed.settings.content_css) || []); - tinymce.each(css, function(u) { - cssHTML += ''; - }); - - // Write content into iframe - doc.open(); - doc.write('' + cssHTML + ''); - doc.close(); - - doc.designMode = 'on'; - this.resize(); - - window.setTimeout(function() { - ifr.contentWindow.focus(); - }, 10); - }, - - insert : function() { - var h = document.getElementById('iframe').contentWindow.document.body.innerHTML; - - tinyMCEPopup.editor.execCommand('mceInsertClipboardContent', false, {content : h, wordContent : true}); - tinyMCEPopup.close(); - }, - - resize : function() { - var vp = tinyMCEPopup.dom.getViewPort(window), el; - - el = document.getElementById('iframe'); - - if (el) { - el.style.width = (vp.w - 20) + 'px'; - el.style.height = (vp.h - 90) + 'px'; - } - } -}; - -tinyMCEPopup.onInit.add(PasteWordDialog.init, PasteWordDialog); +tinyMCEPopup.requireLangPack(); + +var PasteWordDialog = { + init : function() { + var ed = tinyMCEPopup.editor, el = document.getElementById('iframecontainer'), ifr, doc, css, cssHTML = ''; + + // Create iframe + el.innerHTML = ''; + ifr = document.getElementById('iframe'); + doc = ifr.contentWindow.document; + + // Force absolute CSS urls + css = [ed.baseURI.toAbsolute("themes/" + ed.settings.theme + "/skins/" + ed.settings.skin + "/content.css")]; + css = css.concat(tinymce.explode(ed.settings.content_css) || []); + tinymce.each(css, function(u) { + cssHTML += ''; + }); + + // Write content into iframe + doc.open(); + doc.write('' + cssHTML + ''); + doc.close(); + + doc.designMode = 'on'; + this.resize(); + + window.setTimeout(function() { + ifr.contentWindow.focus(); + }, 10); + }, + + insert : function() { + var h = document.getElementById('iframe').contentWindow.document.body.innerHTML; + + tinyMCEPopup.editor.execCommand('mceInsertClipboardContent', false, {content : h, wordContent : true}); + tinyMCEPopup.close(); + }, + + resize : function() { + var vp = tinyMCEPopup.dom.getViewPort(window), el; + + el = document.getElementById('iframe'); + + if (el) { + el.style.width = (vp.w - 20) + 'px'; + el.style.height = (vp.h - 90) + 'px'; + } + } +}; + +tinyMCEPopup.onInit.add(PasteWordDialog.init, PasteWordDialog); diff --git a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/paste/pastetext.htm b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/paste/pastetext.htm index 8ccfbb9..b655945 100644 --- a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/paste/pastetext.htm +++ b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/paste/pastetext.htm @@ -1,27 +1,27 @@ - - - {#paste.paste_text_desc} - - - - -
            -
            {#paste.paste_text_desc}
            - -
            - -
            - -
            - -
            {#paste_dlg.text_title}
            - - - -
            - - -
            -
            - + + + {#paste.paste_text_desc} + + + + +
            +
            {#paste.paste_text_desc}
            + +
            + +
            + +
            + +
            {#paste_dlg.text_title}
            + + + +
            + + +
            +
            + \ No newline at end of file diff --git a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/paste/pasteword.htm b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/paste/pasteword.htm index 7731f39..0f6bb41 100644 --- a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/paste/pasteword.htm +++ b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/paste/pasteword.htm @@ -1,21 +1,21 @@ - - - {#paste.paste_word_desc} - - - - -
            -
            {#paste.paste_word_desc}
            - -
            {#paste_dlg.word_title}
            - -
            - -
            - - -
            -
            - - + + + {#paste.paste_word_desc} + + + + +
            +
            {#paste.paste_word_desc}
            + +
            {#paste_dlg.word_title}
            + +
            + +
            + + +
            +
            + + diff --git a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/spellchecker/css/content.css b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/spellchecker/css/content.css index 656ce1e..24efa02 100644 --- a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/spellchecker/css/content.css +++ b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/spellchecker/css/content.css @@ -1 +1 @@ -.mceItemHiddenSpellWord {background:url(../img/wline.gif) repeat-x bottom left; cursor:default;} +.mceItemHiddenSpellWord {background:url(../img/wline.gif) repeat-x bottom left; cursor:default;} diff --git a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/spellchecker/editor_plugin_src.js b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/spellchecker/editor_plugin_src.js index 925d2f2..86fdfce 100644 --- a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/spellchecker/editor_plugin_src.js +++ b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/spellchecker/editor_plugin_src.js @@ -1,436 +1,436 @@ -/** - * editor_plugin_src.js - * - * Copyright 2009, Moxiecode Systems AB - * Released under LGPL License. - * - * License: http://tinymce.moxiecode.com/license - * Contributing: http://tinymce.moxiecode.com/contributing - */ - -(function() { - var JSONRequest = tinymce.util.JSONRequest, each = tinymce.each, DOM = tinymce.DOM; - - tinymce.create('tinymce.plugins.SpellcheckerPlugin', { - getInfo : function() { - return { - longname : 'Spellchecker', - author : 'Moxiecode Systems AB', - authorurl : 'http://tinymce.moxiecode.com', - infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/spellchecker', - version : tinymce.majorVersion + "." + tinymce.minorVersion - }; - }, - - init : function(ed, url) { - var t = this, cm; - - t.url = url; - t.editor = ed; - t.rpcUrl = ed.getParam("spellchecker_rpc_url", "{backend}"); - - if (t.rpcUrl == '{backend}') { - // Sniff if the browser supports native spellchecking (Don't know of a better way) - if (tinymce.isIE) - return; - - t.hasSupport = true; - - // Disable the context menu when spellchecking is active - ed.onContextMenu.addToTop(function(ed, e) { - if (t.active) - return false; - }); - } - - // Register commands - ed.addCommand('mceSpellCheck', function() { - if (t.rpcUrl == '{backend}') { - // Enable/disable native spellchecker - t.editor.getBody().spellcheck = t.active = !t.active; - return; - } - - if (!t.active) { - ed.setProgressState(1); - t._sendRPC('checkWords', [t.selectedLang, t._getWords()], function(r) { - if (r.length > 0) { - t.active = 1; - t._markWords(r); - ed.setProgressState(0); - ed.nodeChanged(); - } else { - ed.setProgressState(0); - - if (ed.getParam('spellchecker_report_no_misspellings', true)) - ed.windowManager.alert('spellchecker.no_mpell'); - } - }); - } else - t._done(); - }); - - if (ed.settings.content_css !== false) - ed.contentCSS.push(url + '/css/content.css'); - - ed.onClick.add(t._showMenu, t); - ed.onContextMenu.add(t._showMenu, t); - ed.onBeforeGetContent.add(function() { - if (t.active) - t._removeWords(); - }); - - ed.onNodeChange.add(function(ed, cm) { - cm.setActive('spellchecker', t.active); - }); - - ed.onSetContent.add(function() { - t._done(); - }); - - ed.onBeforeGetContent.add(function() { - t._done(); - }); - - ed.onBeforeExecCommand.add(function(ed, cmd) { - if (cmd == 'mceFullScreen') - t._done(); - }); - - // Find selected language - t.languages = {}; - each(ed.getParam('spellchecker_languages', '+English=en,Danish=da,Dutch=nl,Finnish=fi,French=fr,German=de,Italian=it,Polish=pl,Portuguese=pt,Spanish=es,Swedish=sv', 'hash'), function(v, k) { - if (k.indexOf('+') === 0) { - k = k.substring(1); - t.selectedLang = v; - } - - t.languages[k] = v; - }); - }, - - createControl : function(n, cm) { - var t = this, c, ed = t.editor; - - if (n == 'spellchecker') { - // Use basic button if we use the native spellchecker - if (t.rpcUrl == '{backend}') { - // Create simple toggle button if we have native support - if (t.hasSupport) - c = cm.createButton(n, {title : 'spellchecker.desc', cmd : 'mceSpellCheck', scope : t}); - - return c; - } - - c = cm.createSplitButton(n, {title : 'spellchecker.desc', cmd : 'mceSpellCheck', scope : t}); - - c.onRenderMenu.add(function(c, m) { - m.add({title : 'spellchecker.langs', 'class' : 'mceMenuItemTitle'}).setDisabled(1); - each(t.languages, function(v, k) { - var o = {icon : 1}, mi; - - o.onclick = function() { - if (v == t.selectedLang) { - return; - } - mi.setSelected(1); - t.selectedItem.setSelected(0); - t.selectedItem = mi; - t.selectedLang = v; - }; - - o.title = k; - mi = m.add(o); - mi.setSelected(v == t.selectedLang); - - if (v == t.selectedLang) - t.selectedItem = mi; - }) - }); - - return c; - } - }, - - // Internal functions - - _walk : function(n, f) { - var d = this.editor.getDoc(), w; - - if (d.createTreeWalker) { - w = d.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, false); - - while ((n = w.nextNode()) != null) - f.call(this, n); - } else - tinymce.walk(n, f, 'childNodes'); - }, - - _getSeparators : function() { - var re = '', i, str = this.editor.getParam('spellchecker_word_separator_chars', '\\s!"#$%&()*+,-./:;<=>?@[\]^_{|}\u201d\u201c'); - - // Build word separator regexp - for (i=0; i elements content is broken after spellchecking. - // Bug #1408: Preceding whitespace characters are removed - // @TODO: I'm not sure that both are still issues on IE9. - if (tinymce.isIE) { - // Enclose mispelled words with temporal tag - v = v.replace(rx, '$1$2'); - // Loop over the content finding mispelled words - while ((pos = v.indexOf('')) != -1) { - // Add text node for the content before the word - txt = v.substring(0, pos); - if (txt.length) { - node = doc.createTextNode(dom.decode(txt)); - elem.appendChild(node); - } - v = v.substring(pos+10); - pos = v.indexOf(''); - txt = v.substring(0, pos); - v = v.substring(pos+11); - // Add span element for the word - elem.appendChild(dom.create('span', {'class' : 'mceItemHiddenSpellWord'}, txt)); - } - // Add text node for the rest of the content - if (v.length) { - node = doc.createTextNode(dom.decode(v)); - elem.appendChild(node); - } - } else { - // Other browsers preserve whitespace characters on innerHTML usage - elem.innerHTML = v.replace(rx, '$1$2'); - } - - // Finally, replace the node with the container - dom.replace(elem, n); - } - }); - - se.setRng(r); - }, - - _showMenu : function(ed, e) { - var t = this, ed = t.editor, m = t._menu, p1, dom = ed.dom, vp = dom.getViewPort(ed.getWin()), wordSpan = e.target; - - e = 0; // Fixes IE memory leak - - if (!m) { - m = ed.controlManager.createDropMenu('spellcheckermenu', {'class' : 'mceNoIcons'}); - t._menu = m; - } - - if (dom.hasClass(wordSpan, 'mceItemHiddenSpellWord')) { - m.removeAll(); - m.add({title : 'spellchecker.wait', 'class' : 'mceMenuItemTitle'}).setDisabled(1); - - t._sendRPC('getSuggestions', [t.selectedLang, dom.decode(wordSpan.innerHTML)], function(r) { - var ignoreRpc; - - m.removeAll(); - - if (r.length > 0) { - m.add({title : 'spellchecker.sug', 'class' : 'mceMenuItemTitle'}).setDisabled(1); - each(r, function(v) { - m.add({title : v, onclick : function() { - dom.replace(ed.getDoc().createTextNode(v), wordSpan); - t._checkDone(); - }}); - }); - - m.addSeparator(); - } else - m.add({title : 'spellchecker.no_sug', 'class' : 'mceMenuItemTitle'}).setDisabled(1); - - if (ed.getParam('show_ignore_words', true)) { - ignoreRpc = t.editor.getParam("spellchecker_enable_ignore_rpc", ''); - m.add({ - title : 'spellchecker.ignore_word', - onclick : function() { - var word = wordSpan.innerHTML; - - dom.remove(wordSpan, 1); - t._checkDone(); - - // tell the server if we need to - if (ignoreRpc) { - ed.setProgressState(1); - t._sendRPC('ignoreWord', [t.selectedLang, word], function(r) { - ed.setProgressState(0); - }); - } - } - }); - - m.add({ - title : 'spellchecker.ignore_words', - onclick : function() { - var word = wordSpan.innerHTML; - - t._removeWords(dom.decode(word)); - t._checkDone(); - - // tell the server if we need to - if (ignoreRpc) { - ed.setProgressState(1); - t._sendRPC('ignoreWords', [t.selectedLang, word], function(r) { - ed.setProgressState(0); - }); - } - } - }); - } - - if (t.editor.getParam("spellchecker_enable_learn_rpc")) { - m.add({ - title : 'spellchecker.learn_word', - onclick : function() { - var word = wordSpan.innerHTML; - - dom.remove(wordSpan, 1); - t._checkDone(); - - ed.setProgressState(1); - t._sendRPC('learnWord', [t.selectedLang, word], function(r) { - ed.setProgressState(0); - }); - } - }); - } - - m.update(); - }); - - p1 = DOM.getPos(ed.getContentAreaContainer()); - m.settings.offset_x = p1.x; - m.settings.offset_y = p1.y; - - ed.selection.select(wordSpan); - p1 = dom.getPos(wordSpan); - m.showMenu(p1.x, p1.y + wordSpan.offsetHeight - vp.y); - - return tinymce.dom.Event.cancel(e); - } else - m.hideMenu(); - }, - - _checkDone : function() { - var t = this, ed = t.editor, dom = ed.dom, o; - - each(dom.select('span'), function(n) { - if (n && dom.hasClass(n, 'mceItemHiddenSpellWord')) { - o = true; - return false; - } - }); - - if (!o) - t._done(); - }, - - _done : function() { - var t = this, la = t.active; - - if (t.active) { - t.active = 0; - t._removeWords(); - - if (t._menu) - t._menu.hideMenu(); - - if (la) - t.editor.nodeChanged(); - } - }, - - _sendRPC : function(m, p, cb) { - var t = this; - - JSONRequest.sendRPC({ - url : t.rpcUrl, - method : m, - params : p, - success : cb, - error : function(e, x) { - t.editor.setProgressState(0); - t.editor.windowManager.alert(e.errstr || ('Error response: ' + x.responseText)); - } - }); - } - }); - - // Register plugin - tinymce.PluginManager.add('spellchecker', tinymce.plugins.SpellcheckerPlugin); -})(); +/** + * editor_plugin_src.js + * + * Copyright 2009, Moxiecode Systems AB + * Released under LGPL License. + * + * License: http://tinymce.moxiecode.com/license + * Contributing: http://tinymce.moxiecode.com/contributing + */ + +(function() { + var JSONRequest = tinymce.util.JSONRequest, each = tinymce.each, DOM = tinymce.DOM; + + tinymce.create('tinymce.plugins.SpellcheckerPlugin', { + getInfo : function() { + return { + longname : 'Spellchecker', + author : 'Moxiecode Systems AB', + authorurl : 'http://tinymce.moxiecode.com', + infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/spellchecker', + version : tinymce.majorVersion + "." + tinymce.minorVersion + }; + }, + + init : function(ed, url) { + var t = this, cm; + + t.url = url; + t.editor = ed; + t.rpcUrl = ed.getParam("spellchecker_rpc_url", "{backend}"); + + if (t.rpcUrl == '{backend}') { + // Sniff if the browser supports native spellchecking (Don't know of a better way) + if (tinymce.isIE) + return; + + t.hasSupport = true; + + // Disable the context menu when spellchecking is active + ed.onContextMenu.addToTop(function(ed, e) { + if (t.active) + return false; + }); + } + + // Register commands + ed.addCommand('mceSpellCheck', function() { + if (t.rpcUrl == '{backend}') { + // Enable/disable native spellchecker + t.editor.getBody().spellcheck = t.active = !t.active; + return; + } + + if (!t.active) { + ed.setProgressState(1); + t._sendRPC('checkWords', [t.selectedLang, t._getWords()], function(r) { + if (r.length > 0) { + t.active = 1; + t._markWords(r); + ed.setProgressState(0); + ed.nodeChanged(); + } else { + ed.setProgressState(0); + + if (ed.getParam('spellchecker_report_no_misspellings', true)) + ed.windowManager.alert('spellchecker.no_mpell'); + } + }); + } else + t._done(); + }); + + if (ed.settings.content_css !== false) + ed.contentCSS.push(url + '/css/content.css'); + + ed.onClick.add(t._showMenu, t); + ed.onContextMenu.add(t._showMenu, t); + ed.onBeforeGetContent.add(function() { + if (t.active) + t._removeWords(); + }); + + ed.onNodeChange.add(function(ed, cm) { + cm.setActive('spellchecker', t.active); + }); + + ed.onSetContent.add(function() { + t._done(); + }); + + ed.onBeforeGetContent.add(function() { + t._done(); + }); + + ed.onBeforeExecCommand.add(function(ed, cmd) { + if (cmd == 'mceFullScreen') + t._done(); + }); + + // Find selected language + t.languages = {}; + each(ed.getParam('spellchecker_languages', '+English=en,Danish=da,Dutch=nl,Finnish=fi,French=fr,German=de,Italian=it,Polish=pl,Portuguese=pt,Spanish=es,Swedish=sv', 'hash'), function(v, k) { + if (k.indexOf('+') === 0) { + k = k.substring(1); + t.selectedLang = v; + } + + t.languages[k] = v; + }); + }, + + createControl : function(n, cm) { + var t = this, c, ed = t.editor; + + if (n == 'spellchecker') { + // Use basic button if we use the native spellchecker + if (t.rpcUrl == '{backend}') { + // Create simple toggle button if we have native support + if (t.hasSupport) + c = cm.createButton(n, {title : 'spellchecker.desc', cmd : 'mceSpellCheck', scope : t}); + + return c; + } + + c = cm.createSplitButton(n, {title : 'spellchecker.desc', cmd : 'mceSpellCheck', scope : t}); + + c.onRenderMenu.add(function(c, m) { + m.add({title : 'spellchecker.langs', 'class' : 'mceMenuItemTitle'}).setDisabled(1); + each(t.languages, function(v, k) { + var o = {icon : 1}, mi; + + o.onclick = function() { + if (v == t.selectedLang) { + return; + } + mi.setSelected(1); + t.selectedItem.setSelected(0); + t.selectedItem = mi; + t.selectedLang = v; + }; + + o.title = k; + mi = m.add(o); + mi.setSelected(v == t.selectedLang); + + if (v == t.selectedLang) + t.selectedItem = mi; + }) + }); + + return c; + } + }, + + // Internal functions + + _walk : function(n, f) { + var d = this.editor.getDoc(), w; + + if (d.createTreeWalker) { + w = d.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, false); + + while ((n = w.nextNode()) != null) + f.call(this, n); + } else + tinymce.walk(n, f, 'childNodes'); + }, + + _getSeparators : function() { + var re = '', i, str = this.editor.getParam('spellchecker_word_separator_chars', '\\s!"#$%&()*+,-./:;<=>?@[\]^_{|}\u201d\u201c'); + + // Build word separator regexp + for (i=0; i elements content is broken after spellchecking. + // Bug #1408: Preceding whitespace characters are removed + // @TODO: I'm not sure that both are still issues on IE9. + if (tinymce.isIE) { + // Enclose mispelled words with temporal tag + v = v.replace(rx, '$1$2'); + // Loop over the content finding mispelled words + while ((pos = v.indexOf('')) != -1) { + // Add text node for the content before the word + txt = v.substring(0, pos); + if (txt.length) { + node = doc.createTextNode(dom.decode(txt)); + elem.appendChild(node); + } + v = v.substring(pos+10); + pos = v.indexOf(''); + txt = v.substring(0, pos); + v = v.substring(pos+11); + // Add span element for the word + elem.appendChild(dom.create('span', {'class' : 'mceItemHiddenSpellWord'}, txt)); + } + // Add text node for the rest of the content + if (v.length) { + node = doc.createTextNode(dom.decode(v)); + elem.appendChild(node); + } + } else { + // Other browsers preserve whitespace characters on innerHTML usage + elem.innerHTML = v.replace(rx, '$1$2'); + } + + // Finally, replace the node with the container + dom.replace(elem, n); + } + }); + + se.setRng(r); + }, + + _showMenu : function(ed, e) { + var t = this, ed = t.editor, m = t._menu, p1, dom = ed.dom, vp = dom.getViewPort(ed.getWin()), wordSpan = e.target; + + e = 0; // Fixes IE memory leak + + if (!m) { + m = ed.controlManager.createDropMenu('spellcheckermenu', {'class' : 'mceNoIcons'}); + t._menu = m; + } + + if (dom.hasClass(wordSpan, 'mceItemHiddenSpellWord')) { + m.removeAll(); + m.add({title : 'spellchecker.wait', 'class' : 'mceMenuItemTitle'}).setDisabled(1); + + t._sendRPC('getSuggestions', [t.selectedLang, dom.decode(wordSpan.innerHTML)], function(r) { + var ignoreRpc; + + m.removeAll(); + + if (r.length > 0) { + m.add({title : 'spellchecker.sug', 'class' : 'mceMenuItemTitle'}).setDisabled(1); + each(r, function(v) { + m.add({title : v, onclick : function() { + dom.replace(ed.getDoc().createTextNode(v), wordSpan); + t._checkDone(); + }}); + }); + + m.addSeparator(); + } else + m.add({title : 'spellchecker.no_sug', 'class' : 'mceMenuItemTitle'}).setDisabled(1); + + if (ed.getParam('show_ignore_words', true)) { + ignoreRpc = t.editor.getParam("spellchecker_enable_ignore_rpc", ''); + m.add({ + title : 'spellchecker.ignore_word', + onclick : function() { + var word = wordSpan.innerHTML; + + dom.remove(wordSpan, 1); + t._checkDone(); + + // tell the server if we need to + if (ignoreRpc) { + ed.setProgressState(1); + t._sendRPC('ignoreWord', [t.selectedLang, word], function(r) { + ed.setProgressState(0); + }); + } + } + }); + + m.add({ + title : 'spellchecker.ignore_words', + onclick : function() { + var word = wordSpan.innerHTML; + + t._removeWords(dom.decode(word)); + t._checkDone(); + + // tell the server if we need to + if (ignoreRpc) { + ed.setProgressState(1); + t._sendRPC('ignoreWords', [t.selectedLang, word], function(r) { + ed.setProgressState(0); + }); + } + } + }); + } + + if (t.editor.getParam("spellchecker_enable_learn_rpc")) { + m.add({ + title : 'spellchecker.learn_word', + onclick : function() { + var word = wordSpan.innerHTML; + + dom.remove(wordSpan, 1); + t._checkDone(); + + ed.setProgressState(1); + t._sendRPC('learnWord', [t.selectedLang, word], function(r) { + ed.setProgressState(0); + }); + } + }); + } + + m.update(); + }); + + p1 = DOM.getPos(ed.getContentAreaContainer()); + m.settings.offset_x = p1.x; + m.settings.offset_y = p1.y; + + ed.selection.select(wordSpan); + p1 = dom.getPos(wordSpan); + m.showMenu(p1.x, p1.y + wordSpan.offsetHeight - vp.y); + + return tinymce.dom.Event.cancel(e); + } else + m.hideMenu(); + }, + + _checkDone : function() { + var t = this, ed = t.editor, dom = ed.dom, o; + + each(dom.select('span'), function(n) { + if (n && dom.hasClass(n, 'mceItemHiddenSpellWord')) { + o = true; + return false; + } + }); + + if (!o) + t._done(); + }, + + _done : function() { + var t = this, la = t.active; + + if (t.active) { + t.active = 0; + t._removeWords(); + + if (t._menu) + t._menu.hideMenu(); + + if (la) + t.editor.nodeChanged(); + } + }, + + _sendRPC : function(m, p, cb) { + var t = this; + + JSONRequest.sendRPC({ + url : t.rpcUrl, + method : m, + params : p, + success : cb, + error : function(e, x) { + t.editor.setProgressState(0); + t.editor.windowManager.alert(e.errstr || ('Error response: ' + x.responseText)); + } + }); + } + }); + + // Register plugin + tinymce.PluginManager.add('spellchecker', tinymce.plugins.SpellcheckerPlugin); +})(); diff --git a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/tabfocus/editor_plugin_src.js b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/tabfocus/editor_plugin_src.js index 94f4532..f9df7de 100644 --- a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/tabfocus/editor_plugin_src.js +++ b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/tabfocus/editor_plugin_src.js @@ -1,122 +1,122 @@ -/** - * editor_plugin_src.js - * - * Copyright 2009, Moxiecode Systems AB - * Released under LGPL License. - * - * License: http://tinymce.moxiecode.com/license - * Contributing: http://tinymce.moxiecode.com/contributing - */ - -(function() { - var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each, explode = tinymce.explode; - - tinymce.create('tinymce.plugins.TabFocusPlugin', { - init : function(ed, url) { - function tabCancel(ed, e) { - if (e.keyCode === 9) - return Event.cancel(e); - } - - function tabHandler(ed, e) { - var x, i, f, el, v; - - function find(d) { - el = DOM.select(':input:enabled,*[tabindex]:not(iframe)'); - - function canSelectRecursive(e) { - return e.nodeName==="BODY" || (e.type != 'hidden' && - !(e.style.display == "none") && - !(e.style.visibility == "hidden") && canSelectRecursive(e.parentNode)); - } - function canSelectInOldIe(el) { - return el.attributes["tabIndex"].specified || el.nodeName == "INPUT" || el.nodeName == "TEXTAREA"; - } - function isOldIe() { - return tinymce.isIE6 || tinymce.isIE7; - } - function canSelect(el) { - return ((!isOldIe() || canSelectInOldIe(el))) && el.getAttribute("tabindex") != '-1' && canSelectRecursive(el); - } - - each(el, function(e, i) { - if (e.id == ed.id) { - x = i; - return false; - } - }); - if (d > 0) { - for (i = x + 1; i < el.length; i++) { - if (canSelect(el[i])) - return el[i]; - } - } else { - for (i = x - 1; i >= 0; i--) { - if (canSelect(el[i])) - return el[i]; - } - } - - return null; - } - - if (e.keyCode === 9) { - v = explode(ed.getParam('tab_focus', ed.getParam('tabfocus_elements', ':prev,:next'))); - - if (v.length == 1) { - v[1] = v[0]; - v[0] = ':prev'; - } - - // Find element to focus - if (e.shiftKey) { - if (v[0] == ':prev') - el = find(-1); - else - el = DOM.get(v[0]); - } else { - if (v[1] == ':next') - el = find(1); - else - el = DOM.get(v[1]); - } - - if (el) { - if (el.id && (ed = tinymce.get(el.id || el.name))) - ed.focus(); - else - window.setTimeout(function() { - if (!tinymce.isWebKit) - window.focus(); - el.focus(); - }, 10); - - return Event.cancel(e); - } - } - } - - ed.onKeyUp.add(tabCancel); - - if (tinymce.isGecko) { - ed.onKeyPress.add(tabHandler); - ed.onKeyDown.add(tabCancel); - } else - ed.onKeyDown.add(tabHandler); - - }, - - getInfo : function() { - return { - longname : 'Tabfocus', - author : 'Moxiecode Systems AB', - authorurl : 'http://tinymce.moxiecode.com', - infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/tabfocus', - version : tinymce.majorVersion + "." + tinymce.minorVersion - }; - } - }); - - // Register plugin - tinymce.PluginManager.add('tabfocus', tinymce.plugins.TabFocusPlugin); -})(); +/** + * editor_plugin_src.js + * + * Copyright 2009, Moxiecode Systems AB + * Released under LGPL License. + * + * License: http://tinymce.moxiecode.com/license + * Contributing: http://tinymce.moxiecode.com/contributing + */ + +(function() { + var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each, explode = tinymce.explode; + + tinymce.create('tinymce.plugins.TabFocusPlugin', { + init : function(ed, url) { + function tabCancel(ed, e) { + if (e.keyCode === 9) + return Event.cancel(e); + } + + function tabHandler(ed, e) { + var x, i, f, el, v; + + function find(d) { + el = DOM.select(':input:enabled,*[tabindex]:not(iframe)'); + + function canSelectRecursive(e) { + return e.nodeName==="BODY" || (e.type != 'hidden' && + !(e.style.display == "none") && + !(e.style.visibility == "hidden") && canSelectRecursive(e.parentNode)); + } + function canSelectInOldIe(el) { + return el.attributes["tabIndex"].specified || el.nodeName == "INPUT" || el.nodeName == "TEXTAREA"; + } + function isOldIe() { + return tinymce.isIE6 || tinymce.isIE7; + } + function canSelect(el) { + return ((!isOldIe() || canSelectInOldIe(el))) && el.getAttribute("tabindex") != '-1' && canSelectRecursive(el); + } + + each(el, function(e, i) { + if (e.id == ed.id) { + x = i; + return false; + } + }); + if (d > 0) { + for (i = x + 1; i < el.length; i++) { + if (canSelect(el[i])) + return el[i]; + } + } else { + for (i = x - 1; i >= 0; i--) { + if (canSelect(el[i])) + return el[i]; + } + } + + return null; + } + + if (e.keyCode === 9) { + v = explode(ed.getParam('tab_focus', ed.getParam('tabfocus_elements', ':prev,:next'))); + + if (v.length == 1) { + v[1] = v[0]; + v[0] = ':prev'; + } + + // Find element to focus + if (e.shiftKey) { + if (v[0] == ':prev') + el = find(-1); + else + el = DOM.get(v[0]); + } else { + if (v[1] == ':next') + el = find(1); + else + el = DOM.get(v[1]); + } + + if (el) { + if (el.id && (ed = tinymce.get(el.id || el.name))) + ed.focus(); + else + window.setTimeout(function() { + if (!tinymce.isWebKit) + window.focus(); + el.focus(); + }, 10); + + return Event.cancel(e); + } + } + } + + ed.onKeyUp.add(tabCancel); + + if (tinymce.isGecko) { + ed.onKeyPress.add(tabHandler); + ed.onKeyDown.add(tabCancel); + } else + ed.onKeyDown.add(tabHandler); + + }, + + getInfo : function() { + return { + longname : 'Tabfocus', + author : 'Moxiecode Systems AB', + authorurl : 'http://tinymce.moxiecode.com', + infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/tabfocus', + version : tinymce.majorVersion + "." + tinymce.minorVersion + }; + } + }); + + // Register plugin + tinymce.PluginManager.add('tabfocus', tinymce.plugins.TabFocusPlugin); +})(); diff --git a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/wordcount/editor_plugin_src.js b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/wordcount/editor_plugin_src.js index 3fb8fff..34b2655 100644 --- a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/wordcount/editor_plugin_src.js +++ b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/plugins/wordcount/editor_plugin_src.js @@ -1,122 +1,122 @@ -/** - * editor_plugin_src.js - * - * Copyright 2009, Moxiecode Systems AB - * Released under LGPL License. - * - * License: http://tinymce.moxiecode.com/license - * Contributing: http://tinymce.moxiecode.com/contributing - */ - -(function() { - tinymce.create('tinymce.plugins.WordCount', { - block : 0, - id : null, - countre : null, - cleanre : null, - - init : function(ed, url) { - var t = this, last = 0, VK = tinymce.VK; - - t.countre = ed.getParam('wordcount_countregex', /[\w\u2019\'-]+/g); // u2019 == ’ - t.cleanre = ed.getParam('wordcount_cleanregex', /[0-9.(),;:!?%#$?\'\"_+=\\\/-]*/g); - t.update_rate = ed.getParam('wordcount_update_rate', 2000); - t.update_on_delete = ed.getParam('wordcount_update_on_delete', false); - t.id = ed.id + '-word-count'; - - ed.onPostRender.add(function(ed, cm) { - var row, id; - - // Add it to the specified id or the theme advanced path - id = ed.getParam('wordcount_target_id'); - if (!id) { - row = tinymce.DOM.get(ed.id + '_path_row'); - - if (row) - tinymce.DOM.add(row.parentNode, 'div', {'style': 'float: right'}, ed.getLang('wordcount.words', 'Words: ') + '0'); - } else { - tinymce.DOM.add(id, 'span', {}, '0'); - } - }); - - ed.onInit.add(function(ed) { - ed.selection.onSetContent.add(function() { - t._count(ed); - }); - - t._count(ed); - }); - - ed.onSetContent.add(function(ed) { - t._count(ed); - }); - - function checkKeys(key) { - return key !== last && (key === VK.ENTER || last === VK.SPACEBAR || checkDelOrBksp(last)); - } - - function checkDelOrBksp(key) { - return key === VK.DELETE || key === VK.BACKSPACE; - } - - ed.onKeyUp.add(function(ed, e) { - if (checkKeys(e.keyCode) || t.update_on_delete && checkDelOrBksp(e.keyCode)) { - t._count(ed); - } - - last = e.keyCode; - }); - }, - - _getCount : function(ed) { - var tc = 0; - var tx = ed.getContent({ format: 'raw' }); - - if (tx) { - tx = tx.replace(/\.\.\./g, ' '); // convert ellipses to spaces - tx = tx.replace(/<.[^<>]*?>/g, ' ').replace(/ | /gi, ' '); // remove html tags and space chars - - // deal with html entities - tx = tx.replace(/(\w+)(&.+?;)+(\w+)/, "$1$3").replace(/&.+?;/g, ' '); - tx = tx.replace(this.cleanre, ''); // remove numbers and punctuation - - var wordArray = tx.match(this.countre); - if (wordArray) { - tc = wordArray.length; - } - } - - return tc; - }, - - _count : function(ed) { - var t = this; - - // Keep multiple calls from happening at the same time - if (t.block) - return; - - t.block = 1; - - setTimeout(function() { - if (!ed.destroyed) { - var tc = t._getCount(ed); - tinymce.DOM.setHTML(t.id, tc.toString()); - setTimeout(function() {t.block = 0;}, t.update_rate); - } - }, 1); - }, - - getInfo: function() { - return { - longname : 'Word Count plugin', - author : 'Moxiecode Systems AB', - authorurl : 'http://tinymce.moxiecode.com', - infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/wordcount', - version : tinymce.majorVersion + "." + tinymce.minorVersion - }; - } - }); - - tinymce.PluginManager.add('wordcount', tinymce.plugins.WordCount); -})(); +/** + * editor_plugin_src.js + * + * Copyright 2009, Moxiecode Systems AB + * Released under LGPL License. + * + * License: http://tinymce.moxiecode.com/license + * Contributing: http://tinymce.moxiecode.com/contributing + */ + +(function() { + tinymce.create('tinymce.plugins.WordCount', { + block : 0, + id : null, + countre : null, + cleanre : null, + + init : function(ed, url) { + var t = this, last = 0, VK = tinymce.VK; + + t.countre = ed.getParam('wordcount_countregex', /[\w\u2019\'-]+/g); // u2019 == ’ + t.cleanre = ed.getParam('wordcount_cleanregex', /[0-9.(),;:!?%#$?\'\"_+=\\\/-]*/g); + t.update_rate = ed.getParam('wordcount_update_rate', 2000); + t.update_on_delete = ed.getParam('wordcount_update_on_delete', false); + t.id = ed.id + '-word-count'; + + ed.onPostRender.add(function(ed, cm) { + var row, id; + + // Add it to the specified id or the theme advanced path + id = ed.getParam('wordcount_target_id'); + if (!id) { + row = tinymce.DOM.get(ed.id + '_path_row'); + + if (row) + tinymce.DOM.add(row.parentNode, 'div', {'style': 'float: right'}, ed.getLang('wordcount.words', 'Words: ') + '0'); + } else { + tinymce.DOM.add(id, 'span', {}, '0'); + } + }); + + ed.onInit.add(function(ed) { + ed.selection.onSetContent.add(function() { + t._count(ed); + }); + + t._count(ed); + }); + + ed.onSetContent.add(function(ed) { + t._count(ed); + }); + + function checkKeys(key) { + return key !== last && (key === VK.ENTER || last === VK.SPACEBAR || checkDelOrBksp(last)); + } + + function checkDelOrBksp(key) { + return key === VK.DELETE || key === VK.BACKSPACE; + } + + ed.onKeyUp.add(function(ed, e) { + if (checkKeys(e.keyCode) || t.update_on_delete && checkDelOrBksp(e.keyCode)) { + t._count(ed); + } + + last = e.keyCode; + }); + }, + + _getCount : function(ed) { + var tc = 0; + var tx = ed.getContent({ format: 'raw' }); + + if (tx) { + tx = tx.replace(/\.\.\./g, ' '); // convert ellipses to spaces + tx = tx.replace(/<.[^<>]*?>/g, ' ').replace(/ | /gi, ' '); // remove html tags and space chars + + // deal with html entities + tx = tx.replace(/(\w+)(&.+?;)+(\w+)/, "$1$3").replace(/&.+?;/g, ' '); + tx = tx.replace(this.cleanre, ''); // remove numbers and punctuation + + var wordArray = tx.match(this.countre); + if (wordArray) { + tc = wordArray.length; + } + } + + return tc; + }, + + _count : function(ed) { + var t = this; + + // Keep multiple calls from happening at the same time + if (t.block) + return; + + t.block = 1; + + setTimeout(function() { + if (!ed.destroyed) { + var tc = t._getCount(ed); + tinymce.DOM.setHTML(t.id, tc.toString()); + setTimeout(function() {t.block = 0;}, t.update_rate); + } + }, 1); + }, + + getInfo: function() { + return { + longname : 'Word Count plugin', + author : 'Moxiecode Systems AB', + authorurl : 'http://tinymce.moxiecode.com', + infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/wordcount', + version : tinymce.majorVersion + "." + tinymce.minorVersion + }; + } + }); + + tinymce.PluginManager.add('wordcount', tinymce.plugins.WordCount); +})(); diff --git a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/about.htm b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/about.htm index fe36603..7a97cb7 100644 --- a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/about.htm +++ b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/about.htm @@ -1,52 +1,52 @@ - - - - {#advanced_dlg.about_title} - - - - - - - -
            -
            -

            {#advanced_dlg.about_title}

            -

            Version: ()

            -

            TinyMCE is a platform independent web based Javascript HTML WYSIWYG editor control released as Open Source under LGPL - by Moxiecode Systems AB. It has the ability to convert HTML TEXTAREA fields or other HTML elements to editor instances.

            -

            Copyright © 2003-2008, Moxiecode Systems AB, All rights reserved.

            -

            For more information about this software visit the TinyMCE website.

            - -
            - Got Moxie? -
            -
            - -
            -
            -

            {#advanced_dlg.about_loaded}

            - -
            -
            - -

             

            -
            -
            - -
            -
            -
            -
            - -
            - -
            - - + + + + {#advanced_dlg.about_title} + + + + + + + +
            +
            +

            {#advanced_dlg.about_title}

            +

            Version: ()

            +

            TinyMCE is a platform independent web based Javascript HTML WYSIWYG editor control released as Open Source under LGPL + by Moxiecode Systems AB. It has the ability to convert HTML TEXTAREA fields or other HTML elements to editor instances.

            +

            Copyright © 2003-2008, Moxiecode Systems AB, All rights reserved.

            +

            For more information about this software visit the TinyMCE website.

            + +
            + Got Moxie? +
            +
            + +
            +
            +

            {#advanced_dlg.about_loaded}

            + +
            +
            + +

             

            +
            +
            + +
            +
            +
            +
            + +
            + +
            + + diff --git a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/anchor.htm b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/anchor.htm index dc53312..75c93b7 100644 --- a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/anchor.htm +++ b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/anchor.htm @@ -1,26 +1,26 @@ - - - - {#advanced_dlg.anchor_title} - - - - -
            - - - - - - - - -
            {#advanced_dlg.anchor_title}
            - -
            - - -
            -
            - - + + + + {#advanced_dlg.anchor_title} + + + + +
            + + + + + + + + +
            {#advanced_dlg.anchor_title}
            + +
            + + +
            +
            + + diff --git a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/charmap.htm b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/charmap.htm index 12acfe1..d4b6bdf 100644 --- a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/charmap.htm +++ b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/charmap.htm @@ -1,55 +1,55 @@ - - - - {#advanced_dlg.charmap_title} - - - - - - - - - - - - - - - - - - - -
            - - - - - - - - - -
             
             
            -
            - - - - - - - - - - - - - - - - -
             
             
             
            -
            {#advanced_dlg.charmap_usage}
            - - + + + + {#advanced_dlg.charmap_title} + + + + + + + + + + + + + + + + + + + +
            + + + + + + + + + +
             
             
            +
            + + + + + + + + + + + + + + + + +
             
             
             
            +
            {#advanced_dlg.charmap_usage}
            + + diff --git a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/color_picker.htm b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/color_picker.htm index 66633d0..b625531 100644 --- a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/color_picker.htm +++ b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/color_picker.htm @@ -1,70 +1,70 @@ - - - - {#advanced_dlg.colorpicker_title} - - - - - - -
            - - -
            -
            -
            - {#advanced_dlg.colorpicker_picker_title} -
            - - -
            - -
            - -
            -
            -
            -
            - -
            -
            - {#advanced_dlg.colorpicker_palette_title} -
            - -
            - -
            -
            -
            - -
            -
            - {#advanced_dlg.colorpicker_named_title} -
            - -
            - -
            - -
            - {#advanced_dlg.colorpicker_name} -
            -
            -
            -
            - -
            - - -
            -
            -
            - - + + + + {#advanced_dlg.colorpicker_title} + + + + + + +
            + + +
            +
            +
            + {#advanced_dlg.colorpicker_picker_title} +
            + + +
            + +
            + +
            +
            +
            +
            + +
            +
            + {#advanced_dlg.colorpicker_palette_title} +
            + +
            + +
            +
            +
            + +
            +
            + {#advanced_dlg.colorpicker_named_title} +
            + +
            + +
            + +
            + {#advanced_dlg.colorpicker_name} +
            +
            +
            +
            + +
            + + +
            +
            +
            + + diff --git a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/editor_template_src.js b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/editor_template_src.js index 5fb19b1..28ba982 100644 --- a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/editor_template_src.js +++ b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/editor_template_src.js @@ -1,1487 +1,1487 @@ -/** - * editor_template_src.js - * - * Copyright 2009, Moxiecode Systems AB - * Released under LGPL License. - * - * License: http://tinymce.moxiecode.com/license - * Contributing: http://tinymce.moxiecode.com/contributing - */ - -(function(tinymce) { - var DOM = tinymce.DOM, Event = tinymce.dom.Event, extend = tinymce.extend, each = tinymce.each, Cookie = tinymce.util.Cookie, lastExtID, explode = tinymce.explode; - - // Generates a preview for a format - function getPreviewCss(ed, fmt) { - var previewElm, dom = ed.dom, previewCss = '', parentFontSize, previewStylesName; - - previewStyles = ed.settings.preview_styles; - - // No preview forced - if (previewStyles === false) - return ''; - - // Default preview - if (!previewStyles) - previewStyles = 'font-family font-size font-weight text-decoration text-transform color background-color'; - - // Removes any variables since these can't be previewed - function removeVars(val) { - return val.replace(/%(\w+)/g, ''); - }; - - // Create block/inline element to use for preview - name = fmt.block || fmt.inline || 'span'; - previewElm = dom.create(name); - - // Add format styles to preview element - each(fmt.styles, function(value, name) { - value = removeVars(value); - - if (value) - dom.setStyle(previewElm, name, value); - }); - - // Add attributes to preview element - each(fmt.attributes, function(value, name) { - value = removeVars(value); - - if (value) - dom.setAttrib(previewElm, name, value); - }); - - // Add classes to preview element - each(fmt.classes, function(value) { - value = removeVars(value); - - if (!dom.hasClass(previewElm, value)) - dom.addClass(previewElm, value); - }); - - // Add the previewElm outside the visual area - dom.setStyles(previewElm, {position: 'absolute', left: -0xFFFF}); - ed.getBody().appendChild(previewElm); - - // Get parent container font size so we can compute px values out of em/% for older IE:s - parentFontSize = dom.getStyle(ed.getBody(), 'fontSize', true); - parentFontSize = /px$/.test(parentFontSize) ? parseInt(parentFontSize, 10) : 0; - - each(previewStyles.split(' '), function(name) { - var value = dom.getStyle(previewElm, name, true); - - // If background is transparent then check if the body has a background color we can use - if (name == 'background-color' && /transparent|rgba\s*\([^)]+,\s*0\)/.test(value)) { - value = dom.getStyle(ed.getBody(), name, true); - - // Ignore white since it's the default color, not the nicest fix - if (dom.toHex(value).toLowerCase() == '#ffffff') { - return; - } - } - - // Old IE won't calculate the font size so we need to do that manually - if (name == 'font-size') { - if (/em|%$/.test(value)) { - if (parentFontSize === 0) { - return; - } - - // Convert font size from em/% to px - value = parseFloat(value, 10) / (/%$/.test(value) ? 100 : 1); - value = (value * parentFontSize) + 'px'; - } - } - - previewCss += name + ':' + value + ';'; - }); - - dom.remove(previewElm); - - return previewCss; - }; - - // Tell it to load theme specific language pack(s) - tinymce.ThemeManager.requireLangPack('advanced'); - - tinymce.create('tinymce.themes.AdvancedTheme', { - sizes : [8, 10, 12, 14, 18, 24, 36], - - // Control name lookup, format: title, command - controls : { - bold : ['bold_desc', 'Bold'], - italic : ['italic_desc', 'Italic'], - underline : ['underline_desc', 'Underline'], - strikethrough : ['striketrough_desc', 'Strikethrough'], - justifyleft : ['justifyleft_desc', 'JustifyLeft'], - justifycenter : ['justifycenter_desc', 'JustifyCenter'], - justifyright : ['justifyright_desc', 'JustifyRight'], - justifyfull : ['justifyfull_desc', 'JustifyFull'], - bullist : ['bullist_desc', 'InsertUnorderedList'], - numlist : ['numlist_desc', 'InsertOrderedList'], - outdent : ['outdent_desc', 'Outdent'], - indent : ['indent_desc', 'Indent'], - cut : ['cut_desc', 'Cut'], - copy : ['copy_desc', 'Copy'], - paste : ['paste_desc', 'Paste'], - undo : ['undo_desc', 'Undo'], - redo : ['redo_desc', 'Redo'], - link : ['link_desc', 'mceLink'], - unlink : ['unlink_desc', 'unlink'], - image : ['image_desc', 'mceImage'], - cleanup : ['cleanup_desc', 'mceCleanup'], - help : ['help_desc', 'mceHelp'], - code : ['code_desc', 'mceCodeEditor'], - hr : ['hr_desc', 'InsertHorizontalRule'], - removeformat : ['removeformat_desc', 'RemoveFormat'], - sub : ['sub_desc', 'subscript'], - sup : ['sup_desc', 'superscript'], - forecolor : ['forecolor_desc', 'ForeColor'], - forecolorpicker : ['forecolor_desc', 'mceForeColor'], - backcolor : ['backcolor_desc', 'HiliteColor'], - backcolorpicker : ['backcolor_desc', 'mceBackColor'], - charmap : ['charmap_desc', 'mceCharMap'], - visualaid : ['visualaid_desc', 'mceToggleVisualAid'], - anchor : ['anchor_desc', 'mceInsertAnchor'], - newdocument : ['newdocument_desc', 'mceNewDocument'], - blockquote : ['blockquote_desc', 'mceBlockQuote'] - }, - - stateControls : ['bold', 'italic', 'underline', 'strikethrough', 'bullist', 'numlist', 'justifyleft', 'justifycenter', 'justifyright', 'justifyfull', 'sub', 'sup', 'blockquote'], - - init : function(ed, url) { - var t = this, s, v, o; - - t.editor = ed; - t.url = url; - t.onResolveName = new tinymce.util.Dispatcher(this); - s = ed.settings; - - ed.forcedHighContrastMode = ed.settings.detect_highcontrast && t._isHighContrast(); - ed.settings.skin = ed.forcedHighContrastMode ? 'highcontrast' : ed.settings.skin; - - // Setup default buttons - if (!s.theme_advanced_buttons1) { - s = extend({ - theme_advanced_buttons1 : "bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,styleselect,formatselect", - theme_advanced_buttons2 : "bullist,numlist,|,outdent,indent,|,undo,redo,|,link,unlink,anchor,image,cleanup,help,code", - theme_advanced_buttons3 : "hr,removeformat,visualaid,|,sub,sup,|,charmap" - }, s); - } - - // Default settings - t.settings = s = extend({ - theme_advanced_path : true, - theme_advanced_toolbar_location : 'top', - theme_advanced_blockformats : "p,address,pre,h1,h2,h3,h4,h5,h6", - theme_advanced_toolbar_align : "left", - theme_advanced_statusbar_location : "bottom", - theme_advanced_fonts : "Andale Mono=andale mono,times;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;Comic Sans MS=comic sans ms,sans-serif;Courier New=courier new,courier;Georgia=georgia,palatino;Helvetica=helvetica;Impact=impact,chicago;Symbol=symbol;Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,monaco;Times New Roman=times new roman,times;Trebuchet MS=trebuchet ms,geneva;Verdana=verdana,geneva;Webdings=webdings;Wingdings=wingdings,zapf dingbats", - theme_advanced_more_colors : 1, - theme_advanced_row_height : 23, - theme_advanced_resize_horizontal : 1, - theme_advanced_resizing_use_cookie : 1, - theme_advanced_font_sizes : "1,2,3,4,5,6,7", - theme_advanced_font_selector : "span", - theme_advanced_show_current_color: 0, - readonly : ed.settings.readonly - }, s); - - // Setup default font_size_style_values - if (!s.font_size_style_values) - s.font_size_style_values = "8pt,10pt,12pt,14pt,18pt,24pt,36pt"; - - if (tinymce.is(s.theme_advanced_font_sizes, 'string')) { - s.font_size_style_values = tinymce.explode(s.font_size_style_values); - s.font_size_classes = tinymce.explode(s.font_size_classes || ''); - - // Parse string value - o = {}; - ed.settings.theme_advanced_font_sizes = s.theme_advanced_font_sizes; - each(ed.getParam('theme_advanced_font_sizes', '', 'hash'), function(v, k) { - var cl; - - if (k == v && v >= 1 && v <= 7) { - k = v + ' (' + t.sizes[v - 1] + 'pt)'; - cl = s.font_size_classes[v - 1]; - v = s.font_size_style_values[v - 1] || (t.sizes[v - 1] + 'pt'); - } - - if (/^\s*\./.test(v)) - cl = v.replace(/\./g, ''); - - o[k] = cl ? {'class' : cl} : {fontSize : v}; - }); - - s.theme_advanced_font_sizes = o; - } - - if ((v = s.theme_advanced_path_location) && v != 'none') - s.theme_advanced_statusbar_location = s.theme_advanced_path_location; - - if (s.theme_advanced_statusbar_location == 'none') - s.theme_advanced_statusbar_location = 0; - - if (ed.settings.content_css !== false) - ed.contentCSS.push(ed.baseURI.toAbsolute(url + "/skins/" + ed.settings.skin + "/content.css")); - - // Init editor - ed.onInit.add(function() { - if (!ed.settings.readonly) { - ed.onNodeChange.add(t._nodeChanged, t); - ed.onKeyUp.add(t._updateUndoStatus, t); - ed.onMouseUp.add(t._updateUndoStatus, t); - ed.dom.bind(ed.dom.getRoot(), 'dragend', function() { - t._updateUndoStatus(ed); - }); - } - }); - - ed.onSetProgressState.add(function(ed, b, ti) { - var co, id = ed.id, tb; - - if (b) { - t.progressTimer = setTimeout(function() { - co = ed.getContainer(); - co = co.insertBefore(DOM.create('DIV', {style : 'position:relative'}), co.firstChild); - tb = DOM.get(ed.id + '_tbl'); - - DOM.add(co, 'div', {id : id + '_blocker', 'class' : 'mceBlocker', style : {width : tb.clientWidth + 2, height : tb.clientHeight + 2}}); - DOM.add(co, 'div', {id : id + '_progress', 'class' : 'mceProgress', style : {left : tb.clientWidth / 2, top : tb.clientHeight / 2}}); - }, ti || 0); - } else { - DOM.remove(id + '_blocker'); - DOM.remove(id + '_progress'); - clearTimeout(t.progressTimer); - } - }); - - DOM.loadCSS(s.editor_css ? ed.documentBaseURI.toAbsolute(s.editor_css) : url + "/skins/" + ed.settings.skin + "/ui.css"); - - if (s.skin_variant) - DOM.loadCSS(url + "/skins/" + ed.settings.skin + "/ui_" + s.skin_variant + ".css"); - }, - - _isHighContrast : function() { - var actualColor, div = DOM.add(DOM.getRoot(), 'div', {'style': 'background-color: rgb(171,239,86);'}); - - actualColor = (DOM.getStyle(div, 'background-color', true) + '').toLowerCase().replace(/ /g, ''); - DOM.remove(div); - - return actualColor != 'rgb(171,239,86)' && actualColor != '#abef56'; - }, - - createControl : function(n, cf) { - var cd, c; - - if (c = cf.createControl(n)) - return c; - - switch (n) { - case "styleselect": - return this._createStyleSelect(); - - case "formatselect": - return this._createBlockFormats(); - - case "fontselect": - return this._createFontSelect(); - - case "fontsizeselect": - return this._createFontSizeSelect(); - - case "forecolor": - return this._createForeColorMenu(); - - case "backcolor": - return this._createBackColorMenu(); - } - - if ((cd = this.controls[n])) - return cf.createButton(n, {title : "advanced." + cd[0], cmd : cd[1], ui : cd[2], value : cd[3]}); - }, - - execCommand : function(cmd, ui, val) { - var f = this['_' + cmd]; - - if (f) { - f.call(this, ui, val); - return true; - } - - return false; - }, - - _importClasses : function(e) { - var ed = this.editor, ctrl = ed.controlManager.get('styleselect'); - - if (ctrl.getLength() == 0) { - each(ed.dom.getClasses(), function(o, idx) { - var name = 'style_' + idx, fmt; - - fmt = { - inline : 'span', - attributes : {'class' : o['class']}, - selector : '*' - }; - - ed.formatter.register(name, fmt); - - ctrl.add(o['class'], name, { - style: function() { - return getPreviewCss(ed, fmt); - } - }); - }); - } - }, - - _createStyleSelect : function(n) { - var t = this, ed = t.editor, ctrlMan = ed.controlManager, ctrl; - - // Setup style select box - ctrl = ctrlMan.createListBox('styleselect', { - title : 'advanced.style_select', - onselect : function(name) { - var matches, formatNames = [], removedFormat; - - each(ctrl.items, function(item) { - formatNames.push(item.value); - }); - - ed.focus(); - ed.undoManager.add(); - - // Toggle off the current format(s) - matches = ed.formatter.matchAll(formatNames); - tinymce.each(matches, function(match) { - if (!name || match == name) { - if (match) - ed.formatter.remove(match); - - removedFormat = true; - } - }); - - if (!removedFormat) - ed.formatter.apply(name); - - ed.undoManager.add(); - ed.nodeChanged(); - - return false; // No auto select - } - }); - - // Handle specified format - ed.onPreInit.add(function() { - var counter = 0, formats = ed.getParam('style_formats'); - - if (formats) { - each(formats, function(fmt) { - var name, keys = 0; - - each(fmt, function() {keys++;}); - - if (keys > 1) { - name = fmt.name = fmt.name || 'style_' + (counter++); - ed.formatter.register(name, fmt); - ctrl.add(fmt.title, name, { - style: function() { - return getPreviewCss(ed, fmt); - } - }); - } else - ctrl.add(fmt.title); - }); - } else { - each(ed.getParam('theme_advanced_styles', '', 'hash'), function(val, key) { - var name, fmt; - - if (val) { - name = 'style_' + (counter++); - fmt = { - inline : 'span', - classes : val, - selector : '*' - }; - - ed.formatter.register(name, fmt); - ctrl.add(t.editor.translate(key), name, { - style: function() { - return getPreviewCss(ed, fmt); - } - }); - } - }); - } - }); - - // Auto import classes if the ctrl box is empty - if (ctrl.getLength() == 0) { - ctrl.onPostRender.add(function(ed, n) { - if (!ctrl.NativeListBox) { - Event.add(n.id + '_text', 'focus', t._importClasses, t); - Event.add(n.id + '_text', 'mousedown', t._importClasses, t); - Event.add(n.id + '_open', 'focus', t._importClasses, t); - Event.add(n.id + '_open', 'mousedown', t._importClasses, t); - } else - Event.add(n.id, 'focus', t._importClasses, t); - }); - } - - return ctrl; - }, - - _createFontSelect : function() { - var c, t = this, ed = t.editor; - - c = ed.controlManager.createListBox('fontselect', { - title : 'advanced.fontdefault', - onselect : function(v) { - var cur = c.items[c.selectedIndex]; - - if (!v && cur) { - ed.execCommand('FontName', false, cur.value); - return; - } - - ed.execCommand('FontName', false, v); - - // Fake selection, execCommand will fire a nodeChange and update the selection - c.select(function(sv) { - return v == sv; - }); - - if (cur && cur.value == v) { - c.select(null); - } - - return false; // No auto select - } - }); - - if (c) { - each(ed.getParam('theme_advanced_fonts', t.settings.theme_advanced_fonts, 'hash'), function(v, k) { - c.add(ed.translate(k), v, {style : v.indexOf('dings') == -1 ? 'font-family:' + v : ''}); - }); - } - - return c; - }, - - _createFontSizeSelect : function() { - var t = this, ed = t.editor, c, i = 0, cl = []; - - c = ed.controlManager.createListBox('fontsizeselect', {title : 'advanced.font_size', onselect : function(v) { - var cur = c.items[c.selectedIndex]; - - if (!v && cur) { - cur = cur.value; - - if (cur['class']) { - ed.formatter.toggle('fontsize_class', {value : cur['class']}); - ed.undoManager.add(); - ed.nodeChanged(); - } else { - ed.execCommand('FontSize', false, cur.fontSize); - } - - return; - } - - if (v['class']) { - ed.focus(); - ed.undoManager.add(); - ed.formatter.toggle('fontsize_class', {value : v['class']}); - ed.undoManager.add(); - ed.nodeChanged(); - } else - ed.execCommand('FontSize', false, v.fontSize); - - // Fake selection, execCommand will fire a nodeChange and update the selection - c.select(function(sv) { - return v == sv; - }); - - if (cur && (cur.value.fontSize == v.fontSize || cur.value['class'] && cur.value['class'] == v['class'])) { - c.select(null); - } - - return false; // No auto select - }}); - - if (c) { - each(t.settings.theme_advanced_font_sizes, function(v, k) { - var fz = v.fontSize; - - if (fz >= 1 && fz <= 7) - fz = t.sizes[parseInt(fz) - 1] + 'pt'; - - c.add(k, v, {'style' : 'font-size:' + fz, 'class' : 'mceFontSize' + (i++) + (' ' + (v['class'] || ''))}); - }); - } - - return c; - }, - - _createBlockFormats : function() { - var c, fmts = { - p : 'advanced.paragraph', - address : 'advanced.address', - pre : 'advanced.pre', - h1 : 'advanced.h1', - h2 : 'advanced.h2', - h3 : 'advanced.h3', - h4 : 'advanced.h4', - h5 : 'advanced.h5', - h6 : 'advanced.h6', - div : 'advanced.div', - blockquote : 'advanced.blockquote', - code : 'advanced.code', - dt : 'advanced.dt', - dd : 'advanced.dd', - samp : 'advanced.samp' - }, t = this; - - c = t.editor.controlManager.createListBox('formatselect', {title : 'advanced.block', onselect : function(v) { - t.editor.execCommand('FormatBlock', false, v); - return false; - }}); - - if (c) { - each(t.editor.getParam('theme_advanced_blockformats', t.settings.theme_advanced_blockformats, 'hash'), function(v, k) { - c.add(t.editor.translate(k != v ? k : fmts[v]), v, {'class' : 'mce_formatPreview mce_' + v, style: function() { - return getPreviewCss(t.editor, {block: v}); - }}); - }); - } - - return c; - }, - - _createForeColorMenu : function() { - var c, t = this, s = t.settings, o = {}, v; - - if (s.theme_advanced_more_colors) { - o.more_colors_func = function() { - t._mceColorPicker(0, { - color : c.value, - func : function(co) { - c.setColor(co); - } - }); - }; - } - - if (v = s.theme_advanced_text_colors) - o.colors = v; - - if (s.theme_advanced_default_foreground_color) - o.default_color = s.theme_advanced_default_foreground_color; - - o.title = 'advanced.forecolor_desc'; - o.cmd = 'ForeColor'; - o.scope = this; - - c = t.editor.controlManager.createColorSplitButton('forecolor', o); - - return c; - }, - - _createBackColorMenu : function() { - var c, t = this, s = t.settings, o = {}, v; - - if (s.theme_advanced_more_colors) { - o.more_colors_func = function() { - t._mceColorPicker(0, { - color : c.value, - func : function(co) { - c.setColor(co); - } - }); - }; - } - - if (v = s.theme_advanced_background_colors) - o.colors = v; - - if (s.theme_advanced_default_background_color) - o.default_color = s.theme_advanced_default_background_color; - - o.title = 'advanced.backcolor_desc'; - o.cmd = 'HiliteColor'; - o.scope = this; - - c = t.editor.controlManager.createColorSplitButton('backcolor', o); - - return c; - }, - - renderUI : function(o) { - var n, ic, tb, t = this, ed = t.editor, s = t.settings, sc, p, nl; - - if (ed.settings) { - ed.settings.aria_label = s.aria_label + ed.getLang('advanced.help_shortcut'); - } - - // TODO: ACC Should have an aria-describedby attribute which is user-configurable to describe what this field is actually for. - // Maybe actually inherit it from the original textara? - n = p = DOM.create('span', {role : 'application', 'aria-labelledby' : ed.id + '_voice', id : ed.id + '_parent', 'class' : 'mceEditor ' + ed.settings.skin + 'Skin' + (s.skin_variant ? ' ' + ed.settings.skin + 'Skin' + t._ufirst(s.skin_variant) : '') + (ed.settings.directionality == "rtl" ? ' mceRtl' : '')}); - DOM.add(n, 'span', {'class': 'mceVoiceLabel', 'style': 'display:none;', id: ed.id + '_voice'}, s.aria_label); - - if (!DOM.boxModel) - n = DOM.add(n, 'div', {'class' : 'mceOldBoxModel'}); - - n = sc = DOM.add(n, 'table', {role : "presentation", id : ed.id + '_tbl', 'class' : 'mceLayout', cellSpacing : 0, cellPadding : 0}); - n = tb = DOM.add(n, 'tbody'); - - switch ((s.theme_advanced_layout_manager || '').toLowerCase()) { - case "rowlayout": - ic = t._rowLayout(s, tb, o); - break; - - case "customlayout": - ic = ed.execCallback("theme_advanced_custom_layout", s, tb, o, p); - break; - - default: - ic = t._simpleLayout(s, tb, o, p); - } - - n = o.targetNode; - - // Add classes to first and last TRs - nl = sc.rows; - DOM.addClass(nl[0], 'mceFirst'); - DOM.addClass(nl[nl.length - 1], 'mceLast'); - - // Add classes to first and last TDs - each(DOM.select('tr', tb), function(n) { - DOM.addClass(n.firstChild, 'mceFirst'); - DOM.addClass(n.childNodes[n.childNodes.length - 1], 'mceLast'); - }); - - if (DOM.get(s.theme_advanced_toolbar_container)) - DOM.get(s.theme_advanced_toolbar_container).appendChild(p); - else - DOM.insertAfter(p, n); - - Event.add(ed.id + '_path_row', 'click', function(e) { - e = e.target; - - if (e.nodeName == 'A') { - t._sel(e.className.replace(/^.*mcePath_([0-9]+).*$/, '$1')); - return false; - } - }); -/* - if (DOM.get(ed.id + '_path_row')) { - Event.add(ed.id + '_tbl', 'mouseover', function(e) { - var re; - - e = e.target; - - if (e.nodeName == 'SPAN' && DOM.hasClass(e.parentNode, 'mceButton')) { - re = DOM.get(ed.id + '_path_row'); - t.lastPath = re.innerHTML; - DOM.setHTML(re, e.parentNode.title); - } - }); - - Event.add(ed.id + '_tbl', 'mouseout', function(e) { - if (t.lastPath) { - DOM.setHTML(ed.id + '_path_row', t.lastPath); - t.lastPath = 0; - } - }); - } -*/ - - if (!ed.getParam('accessibility_focus')) - Event.add(DOM.add(p, 'a', {href : '#'}, ''), 'focus', function() {tinyMCE.get(ed.id).focus();}); - - if (s.theme_advanced_toolbar_location == 'external') - o.deltaHeight = 0; - - t.deltaHeight = o.deltaHeight; - o.targetNode = null; - - ed.onKeyDown.add(function(ed, evt) { - var DOM_VK_F10 = 121, DOM_VK_F11 = 122; - - if (evt.altKey) { - if (evt.keyCode === DOM_VK_F10) { - // Make sure focus is given to toolbar in Safari. - // We can't do this in IE as it prevents giving focus to toolbar when editor is in a frame - if (tinymce.isWebKit) { - window.focus(); - } - t.toolbarGroup.focus(); - return Event.cancel(evt); - } else if (evt.keyCode === DOM_VK_F11) { - DOM.get(ed.id + '_path_row').focus(); - return Event.cancel(evt); - } - } - }); - - // alt+0 is the UK recommended shortcut for accessing the list of access controls. - ed.addShortcut('alt+0', '', 'mceShortcuts', t); - - return { - iframeContainer : ic, - editorContainer : ed.id + '_parent', - sizeContainer : sc, - deltaHeight : o.deltaHeight - }; - }, - - getInfo : function() { - return { - longname : 'Advanced theme', - author : 'Moxiecode Systems AB', - authorurl : 'http://tinymce.moxiecode.com', - version : tinymce.majorVersion + "." + tinymce.minorVersion - } - }, - - resizeBy : function(dw, dh) { - var e = DOM.get(this.editor.id + '_ifr'); - - this.resizeTo(e.clientWidth + dw, e.clientHeight + dh); - }, - - resizeTo : function(w, h, store) { - var ed = this.editor, s = this.settings, e = DOM.get(ed.id + '_tbl'), ifr = DOM.get(ed.id + '_ifr'); - - // Boundery fix box - w = Math.max(s.theme_advanced_resizing_min_width || 100, w); - h = Math.max(s.theme_advanced_resizing_min_height || 100, h); - w = Math.min(s.theme_advanced_resizing_max_width || 0xFFFF, w); - h = Math.min(s.theme_advanced_resizing_max_height || 0xFFFF, h); - - // Resize iframe and container - DOM.setStyle(e, 'height', ''); - DOM.setStyle(ifr, 'height', h); - - if (s.theme_advanced_resize_horizontal) { - DOM.setStyle(e, 'width', ''); - DOM.setStyle(ifr, 'width', w); - - // Make sure that the size is never smaller than the over all ui - if (w < e.clientWidth) { - w = e.clientWidth; - DOM.setStyle(ifr, 'width', e.clientWidth); - } - } - - // Store away the size - if (store && s.theme_advanced_resizing_use_cookie) { - Cookie.setHash("TinyMCE_" + ed.id + "_size", { - cw : w, - ch : h - }); - } - }, - - destroy : function() { - var id = this.editor.id; - - Event.clear(id + '_resize'); - Event.clear(id + '_path_row'); - Event.clear(id + '_external_close'); - }, - - // Internal functions - - _simpleLayout : function(s, tb, o, p) { - var t = this, ed = t.editor, lo = s.theme_advanced_toolbar_location, sl = s.theme_advanced_statusbar_location, n, ic, etb, c; - - if (s.readonly) { - n = DOM.add(tb, 'tr'); - n = ic = DOM.add(n, 'td', {'class' : 'mceIframeContainer'}); - return ic; - } - - // Create toolbar container at top - if (lo == 'top') - t._addToolbars(tb, o); - - // Create external toolbar - if (lo == 'external') { - n = c = DOM.create('div', {style : 'position:relative'}); - n = DOM.add(n, 'div', {id : ed.id + '_external', 'class' : 'mceExternalToolbar'}); - DOM.add(n, 'a', {id : ed.id + '_external_close', href : 'javascript:;', 'class' : 'mceExternalClose'}); - n = DOM.add(n, 'table', {id : ed.id + '_tblext', cellSpacing : 0, cellPadding : 0}); - etb = DOM.add(n, 'tbody'); - - if (p.firstChild.className == 'mceOldBoxModel') - p.firstChild.appendChild(c); - else - p.insertBefore(c, p.firstChild); - - t._addToolbars(etb, o); - - ed.onMouseUp.add(function() { - var e = DOM.get(ed.id + '_external'); - DOM.show(e); - - DOM.hide(lastExtID); - - var f = Event.add(ed.id + '_external_close', 'click', function() { - DOM.hide(ed.id + '_external'); - Event.remove(ed.id + '_external_close', 'click', f); - }); - - DOM.show(e); - DOM.setStyle(e, 'top', 0 - DOM.getRect(ed.id + '_tblext').h - 1); - - // Fixes IE rendering bug - DOM.hide(e); - DOM.show(e); - e.style.filter = ''; - - lastExtID = ed.id + '_external'; - - e = null; - }); - } - - if (sl == 'top') - t._addStatusBar(tb, o); - - // Create iframe container - if (!s.theme_advanced_toolbar_container) { - n = DOM.add(tb, 'tr'); - n = ic = DOM.add(n, 'td', {'class' : 'mceIframeContainer'}); - } - - // Create toolbar container at bottom - if (lo == 'bottom') - t._addToolbars(tb, o); - - if (sl == 'bottom') - t._addStatusBar(tb, o); - - return ic; - }, - - _rowLayout : function(s, tb, o) { - var t = this, ed = t.editor, dc, da, cf = ed.controlManager, n, ic, to, a; - - dc = s.theme_advanced_containers_default_class || ''; - da = s.theme_advanced_containers_default_align || 'center'; - - each(explode(s.theme_advanced_containers || ''), function(c, i) { - var v = s['theme_advanced_container_' + c] || ''; - - switch (c.toLowerCase()) { - case 'mceeditor': - n = DOM.add(tb, 'tr'); - n = ic = DOM.add(n, 'td', {'class' : 'mceIframeContainer'}); - break; - - case 'mceelementpath': - t._addStatusBar(tb, o); - break; - - default: - a = (s['theme_advanced_container_' + c + '_align'] || da).toLowerCase(); - a = 'mce' + t._ufirst(a); - - n = DOM.add(DOM.add(tb, 'tr'), 'td', { - 'class' : 'mceToolbar ' + (s['theme_advanced_container_' + c + '_class'] || dc) + ' ' + a || da - }); - - to = cf.createToolbar("toolbar" + i); - t._addControls(v, to); - DOM.setHTML(n, to.renderHTML()); - o.deltaHeight -= s.theme_advanced_row_height; - } - }); - - return ic; - }, - - _addControls : function(v, tb) { - var t = this, s = t.settings, di, cf = t.editor.controlManager; - - if (s.theme_advanced_disable && !t._disabled) { - di = {}; - - each(explode(s.theme_advanced_disable), function(v) { - di[v] = 1; - }); - - t._disabled = di; - } else - di = t._disabled; - - each(explode(v), function(n) { - var c; - - if (di && di[n]) - return; - - // Compatiblity with 2.x - if (n == 'tablecontrols') { - each(["table","|","row_props","cell_props","|","row_before","row_after","delete_row","|","col_before","col_after","delete_col","|","split_cells","merge_cells"], function(n) { - n = t.createControl(n, cf); - - if (n) - tb.add(n); - }); - - return; - } - - c = t.createControl(n, cf); - - if (c) - tb.add(c); - }); - }, - - _addToolbars : function(c, o) { - var t = this, i, tb, ed = t.editor, s = t.settings, v, cf = ed.controlManager, di, n, h = [], a, toolbarGroup, toolbarsExist = false; - - toolbarGroup = cf.createToolbarGroup('toolbargroup', { - 'name': ed.getLang('advanced.toolbar'), - 'tab_focus_toolbar':ed.getParam('theme_advanced_tab_focus_toolbar') - }); - - t.toolbarGroup = toolbarGroup; - - a = s.theme_advanced_toolbar_align.toLowerCase(); - a = 'mce' + t._ufirst(a); - - n = DOM.add(DOM.add(c, 'tr', {role: 'presentation'}), 'td', {'class' : 'mceToolbar ' + a, "role":"presentation"}); - - // Create toolbar and add the controls - for (i=1; (v = s['theme_advanced_buttons' + i]); i++) { - toolbarsExist = true; - tb = cf.createToolbar("toolbar" + i, {'class' : 'mceToolbarRow' + i}); - - if (s['theme_advanced_buttons' + i + '_add']) - v += ',' + s['theme_advanced_buttons' + i + '_add']; - - if (s['theme_advanced_buttons' + i + '_add_before']) - v = s['theme_advanced_buttons' + i + '_add_before'] + ',' + v; - - t._addControls(v, tb); - toolbarGroup.add(tb); - - o.deltaHeight -= s.theme_advanced_row_height; - } - // Handle case when there are no toolbar buttons and ensure editor height is adjusted accordingly - if (!toolbarsExist) - o.deltaHeight -= s.theme_advanced_row_height; - h.push(toolbarGroup.renderHTML()); - h.push(DOM.createHTML('a', {href : '#', accesskey : 'z', title : ed.getLang("advanced.toolbar_focus"), onfocus : 'tinyMCE.getInstanceById(\'' + ed.id + '\').focus();'}, '')); - DOM.setHTML(n, h.join('')); - }, - - _addStatusBar : function(tb, o) { - var n, t = this, ed = t.editor, s = t.settings, r, mf, me, td; - - n = DOM.add(tb, 'tr'); - n = td = DOM.add(n, 'td', {'class' : 'mceStatusbar'}); - n = DOM.add(n, 'div', {id : ed.id + '_path_row', 'role': 'group', 'aria-labelledby': ed.id + '_path_voice'}); - if (s.theme_advanced_path) { - DOM.add(n, 'span', {id: ed.id + '_path_voice'}, ed.translate('advanced.path')); - DOM.add(n, 'span', {}, ': '); - } else { - DOM.add(n, 'span', {}, ' '); - } - - - if (s.theme_advanced_resizing) { - DOM.add(td, 'a', {id : ed.id + '_resize', href : 'javascript:;', onclick : "return false;", 'class' : 'mceResize', tabIndex:"-1"}); - - if (s.theme_advanced_resizing_use_cookie) { - ed.onPostRender.add(function() { - var o = Cookie.getHash("TinyMCE_" + ed.id + "_size"), c = DOM.get(ed.id + '_tbl'); - - if (!o) - return; - - t.resizeTo(o.cw, o.ch); - }); - } - - ed.onPostRender.add(function() { - Event.add(ed.id + '_resize', 'click', function(e) { - e.preventDefault(); - }); - - Event.add(ed.id + '_resize', 'mousedown', function(e) { - var mouseMoveHandler1, mouseMoveHandler2, - mouseUpHandler1, mouseUpHandler2, - startX, startY, startWidth, startHeight, width, height, ifrElm; - - function resizeOnMove(e) { - e.preventDefault(); - - width = startWidth + (e.screenX - startX); - height = startHeight + (e.screenY - startY); - - t.resizeTo(width, height); - }; - - function endResize(e) { - // Stop listening - Event.remove(DOM.doc, 'mousemove', mouseMoveHandler1); - Event.remove(ed.getDoc(), 'mousemove', mouseMoveHandler2); - Event.remove(DOM.doc, 'mouseup', mouseUpHandler1); - Event.remove(ed.getDoc(), 'mouseup', mouseUpHandler2); - - width = startWidth + (e.screenX - startX); - height = startHeight + (e.screenY - startY); - t.resizeTo(width, height, true); - }; - - e.preventDefault(); - - // Get the current rect size - startX = e.screenX; - startY = e.screenY; - ifrElm = DOM.get(t.editor.id + '_ifr'); - startWidth = width = ifrElm.clientWidth; - startHeight = height = ifrElm.clientHeight; - - // Register envent handlers - mouseMoveHandler1 = Event.add(DOM.doc, 'mousemove', resizeOnMove); - mouseMoveHandler2 = Event.add(ed.getDoc(), 'mousemove', resizeOnMove); - mouseUpHandler1 = Event.add(DOM.doc, 'mouseup', endResize); - mouseUpHandler2 = Event.add(ed.getDoc(), 'mouseup', endResize); - }); - }); - } - - o.deltaHeight -= 21; - n = tb = null; - }, - - _updateUndoStatus : function(ed) { - var cm = ed.controlManager, um = ed.undoManager; - - cm.setDisabled('undo', !um.hasUndo() && !um.typing); - cm.setDisabled('redo', !um.hasRedo()); - }, - - _nodeChanged : function(ed, cm, n, co, ob) { - var t = this, p, de = 0, v, c, s = t.settings, cl, fz, fn, fc, bc, formatNames, matches; - - tinymce.each(t.stateControls, function(c) { - cm.setActive(c, ed.queryCommandState(t.controls[c][1])); - }); - - function getParent(name) { - var i, parents = ob.parents, func = name; - - if (typeof(name) == 'string') { - func = function(node) { - return node.nodeName == name; - }; - } - - for (i = 0; i < parents.length; i++) { - if (func(parents[i])) - return parents[i]; - } - }; - - cm.setActive('visualaid', ed.hasVisual); - t._updateUndoStatus(ed); - cm.setDisabled('outdent', !ed.queryCommandState('Outdent')); - - p = getParent('A'); - if (c = cm.get('link')) { - c.setDisabled((!p && co) || (p && !p.href)); - c.setActive(!!p && (!p.name && !p.id)); - } - - if (c = cm.get('unlink')) { - c.setDisabled(!p && co); - c.setActive(!!p && !p.name && !p.id); - } - - if (c = cm.get('anchor')) { - c.setActive(!co && !!p && (p.name || (p.id && !p.href))); - } - - p = getParent('IMG'); - if (c = cm.get('image')) - c.setActive(!co && !!p && n.className.indexOf('mceItem') == -1); - - if (c = cm.get('styleselect')) { - t._importClasses(); - - formatNames = []; - each(c.items, function(item) { - formatNames.push(item.value); - }); - - matches = ed.formatter.matchAll(formatNames); - c.select(matches[0]); - tinymce.each(matches, function(match, index) { - if (index > 0) { - c.mark(match); - } - }); - } - - if (c = cm.get('formatselect')) { - p = getParent(ed.dom.isBlock); - - if (p) - c.select(p.nodeName.toLowerCase()); - } - - // Find out current fontSize, fontFamily and fontClass - getParent(function(n) { - if (n.nodeName === 'SPAN') { - if (!cl && n.className) - cl = n.className; - } - - if (ed.dom.is(n, s.theme_advanced_font_selector)) { - if (!fz && n.style.fontSize) - fz = n.style.fontSize; - - if (!fn && n.style.fontFamily) - fn = n.style.fontFamily.replace(/[\"\']+/g, '').replace(/^([^,]+).*/, '$1').toLowerCase(); - - if (!fc && n.style.color) - fc = n.style.color; - - if (!bc && n.style.backgroundColor) - bc = n.style.backgroundColor; - } - - return false; - }); - - if (c = cm.get('fontselect')) { - c.select(function(v) { - return v.replace(/^([^,]+).*/, '$1').toLowerCase() == fn; - }); - } - - // Select font size - if (c = cm.get('fontsizeselect')) { - // Use computed style - if (s.theme_advanced_runtime_fontsize && !fz && !cl) - fz = ed.dom.getStyle(n, 'fontSize', true); - - c.select(function(v) { - if (v.fontSize && v.fontSize === fz) - return true; - - if (v['class'] && v['class'] === cl) - return true; - }); - } - - if (s.theme_advanced_show_current_color) { - function updateColor(controlId, color) { - if (c = cm.get(controlId)) { - if (!color) - color = c.settings.default_color; - if (color !== c.value) { - c.displayColor(color); - } - } - } - updateColor('forecolor', fc); - updateColor('backcolor', bc); - } - - if (s.theme_advanced_show_current_color) { - function updateColor(controlId, color) { - if (c = cm.get(controlId)) { - if (!color) - color = c.settings.default_color; - if (color !== c.value) { - c.displayColor(color); - } - } - }; - - updateColor('forecolor', fc); - updateColor('backcolor', bc); - } - - if (s.theme_advanced_path && s.theme_advanced_statusbar_location) { - p = DOM.get(ed.id + '_path') || DOM.add(ed.id + '_path_row', 'span', {id : ed.id + '_path'}); - - if (t.statusKeyboardNavigation) { - t.statusKeyboardNavigation.destroy(); - t.statusKeyboardNavigation = null; - } - - DOM.setHTML(p, ''); - - getParent(function(n) { - var na = n.nodeName.toLowerCase(), u, pi, ti = ''; - - // Ignore non element and bogus/hidden elements - if (n.nodeType != 1 || na === 'br' || n.getAttribute('data-mce-bogus') || DOM.hasClass(n, 'mceItemHidden') || DOM.hasClass(n, 'mceItemRemoved')) - return; - - // Handle prefix - if (tinymce.isIE && n.scopeName !== 'HTML' && n.scopeName) - na = n.scopeName + ':' + na; - - // Remove internal prefix - na = na.replace(/mce\:/g, ''); - - // Handle node name - switch (na) { - case 'b': - na = 'strong'; - break; - - case 'i': - na = 'em'; - break; - - case 'img': - if (v = DOM.getAttrib(n, 'src')) - ti += 'src: ' + v + ' '; - - break; - - case 'a': - if (v = DOM.getAttrib(n, 'name')) { - ti += 'name: ' + v + ' '; - na += '#' + v; - } - - if (v = DOM.getAttrib(n, 'href')) - ti += 'href: ' + v + ' '; - - break; - - case 'font': - if (v = DOM.getAttrib(n, 'face')) - ti += 'font: ' + v + ' '; - - if (v = DOM.getAttrib(n, 'size')) - ti += 'size: ' + v + ' '; - - if (v = DOM.getAttrib(n, 'color')) - ti += 'color: ' + v + ' '; - - break; - - case 'span': - if (v = DOM.getAttrib(n, 'style')) - ti += 'style: ' + v + ' '; - - break; - } - - if (v = DOM.getAttrib(n, 'id')) - ti += 'id: ' + v + ' '; - - if (v = n.className) { - v = v.replace(/\b\s*(webkit|mce|Apple-)\w+\s*\b/g, '') - - if (v) { - ti += 'class: ' + v + ' '; - - if (ed.dom.isBlock(n) || na == 'img' || na == 'span') - na += '.' + v; - } - } - - na = na.replace(/(html:)/g, ''); - na = {name : na, node : n, title : ti}; - t.onResolveName.dispatch(t, na); - ti = na.title; - na = na.name; - - //u = "javascript:tinymce.EditorManager.get('" + ed.id + "').theme._sel('" + (de++) + "');"; - pi = DOM.create('a', {'href' : "javascript:;", role: 'button', onmousedown : "return false;", title : ti, 'class' : 'mcePath_' + (de++)}, na); - - if (p.hasChildNodes()) { - p.insertBefore(DOM.create('span', {'aria-hidden': 'true'}, '\u00a0\u00bb '), p.firstChild); - p.insertBefore(pi, p.firstChild); - } else - p.appendChild(pi); - }, ed.getBody()); - - if (DOM.select('a', p).length > 0) { - t.statusKeyboardNavigation = new tinymce.ui.KeyboardNavigation({ - root: ed.id + "_path_row", - items: DOM.select('a', p), - excludeFromTabOrder: true, - onCancel: function() { - ed.focus(); - } - }, DOM); - } - } - }, - - // Commands gets called by execCommand - - _sel : function(v) { - this.editor.execCommand('mceSelectNodeDepth', false, v); - }, - - _mceInsertAnchor : function(ui, v) { - var ed = this.editor; - - ed.windowManager.open({ - url : this.url + '/anchor.htm', - width : 320 + parseInt(ed.getLang('advanced.anchor_delta_width', 0)), - height : 90 + parseInt(ed.getLang('advanced.anchor_delta_height', 0)), - inline : true - }, { - theme_url : this.url - }); - }, - - _mceCharMap : function() { - var ed = this.editor; - - ed.windowManager.open({ - url : this.url + '/charmap.htm', - width : 550 + parseInt(ed.getLang('advanced.charmap_delta_width', 0)), - height : 265 + parseInt(ed.getLang('advanced.charmap_delta_height', 0)), - inline : true - }, { - theme_url : this.url - }); - }, - - _mceHelp : function() { - var ed = this.editor; - - ed.windowManager.open({ - url : this.url + '/about.htm', - width : 480, - height : 380, - inline : true - }, { - theme_url : this.url - }); - }, - - _mceShortcuts : function() { - var ed = this.editor; - ed.windowManager.open({ - url: this.url + '/shortcuts.htm', - width: 480, - height: 380, - inline: true - }, { - theme_url: this.url - }); - }, - - _mceColorPicker : function(u, v) { - var ed = this.editor; - - v = v || {}; - - ed.windowManager.open({ - url : this.url + '/color_picker.htm', - width : 375 + parseInt(ed.getLang('advanced.colorpicker_delta_width', 0)), - height : 250 + parseInt(ed.getLang('advanced.colorpicker_delta_height', 0)), - close_previous : false, - inline : true - }, { - input_color : v.color, - func : v.func, - theme_url : this.url - }); - }, - - _mceCodeEditor : function(ui, val) { - var ed = this.editor; - - ed.windowManager.open({ - url : this.url + '/source_editor.htm', - width : parseInt(ed.getParam("theme_advanced_source_editor_width", 720)), - height : parseInt(ed.getParam("theme_advanced_source_editor_height", 580)), - inline : true, - resizable : true, - maximizable : true - }, { - theme_url : this.url - }); - }, - - _mceImage : function(ui, val) { - var ed = this.editor; - - // Internal image object like a flash placeholder - if (ed.dom.getAttrib(ed.selection.getNode(), 'class', '').indexOf('mceItem') != -1) - return; - - ed.windowManager.open({ - url : this.url + '/image.htm', - width : 355 + parseInt(ed.getLang('advanced.image_delta_width', 0)), - height : 275 + parseInt(ed.getLang('advanced.image_delta_height', 0)), - inline : true - }, { - theme_url : this.url - }); - }, - - _mceLink : function(ui, val) { - var ed = this.editor; - - ed.windowManager.open({ - url : this.url + '/link.htm', - width : 310 + parseInt(ed.getLang('advanced.link_delta_width', 0)), - height : 200 + parseInt(ed.getLang('advanced.link_delta_height', 0)), - inline : true - }, { - theme_url : this.url - }); - }, - - _mceNewDocument : function() { - var ed = this.editor; - - ed.windowManager.confirm('advanced.newdocument', function(s) { - if (s) - ed.execCommand('mceSetContent', false, ''); - }); - }, - - _mceForeColor : function() { - var t = this; - - this._mceColorPicker(0, { - color: t.fgColor, - func : function(co) { - t.fgColor = co; - t.editor.execCommand('ForeColor', false, co); - } - }); - }, - - _mceBackColor : function() { - var t = this; - - this._mceColorPicker(0, { - color: t.bgColor, - func : function(co) { - t.bgColor = co; - t.editor.execCommand('HiliteColor', false, co); - } - }); - }, - - _ufirst : function(s) { - return s.substring(0, 1).toUpperCase() + s.substring(1); - } - }); - - tinymce.ThemeManager.add('advanced', tinymce.themes.AdvancedTheme); -}(tinymce)); +/** + * editor_template_src.js + * + * Copyright 2009, Moxiecode Systems AB + * Released under LGPL License. + * + * License: http://tinymce.moxiecode.com/license + * Contributing: http://tinymce.moxiecode.com/contributing + */ + +(function(tinymce) { + var DOM = tinymce.DOM, Event = tinymce.dom.Event, extend = tinymce.extend, each = tinymce.each, Cookie = tinymce.util.Cookie, lastExtID, explode = tinymce.explode; + + // Generates a preview for a format + function getPreviewCss(ed, fmt) { + var previewElm, dom = ed.dom, previewCss = '', parentFontSize, previewStylesName; + + previewStyles = ed.settings.preview_styles; + + // No preview forced + if (previewStyles === false) + return ''; + + // Default preview + if (!previewStyles) + previewStyles = 'font-family font-size font-weight text-decoration text-transform color background-color'; + + // Removes any variables since these can't be previewed + function removeVars(val) { + return val.replace(/%(\w+)/g, ''); + }; + + // Create block/inline element to use for preview + name = fmt.block || fmt.inline || 'span'; + previewElm = dom.create(name); + + // Add format styles to preview element + each(fmt.styles, function(value, name) { + value = removeVars(value); + + if (value) + dom.setStyle(previewElm, name, value); + }); + + // Add attributes to preview element + each(fmt.attributes, function(value, name) { + value = removeVars(value); + + if (value) + dom.setAttrib(previewElm, name, value); + }); + + // Add classes to preview element + each(fmt.classes, function(value) { + value = removeVars(value); + + if (!dom.hasClass(previewElm, value)) + dom.addClass(previewElm, value); + }); + + // Add the previewElm outside the visual area + dom.setStyles(previewElm, {position: 'absolute', left: -0xFFFF}); + ed.getBody().appendChild(previewElm); + + // Get parent container font size so we can compute px values out of em/% for older IE:s + parentFontSize = dom.getStyle(ed.getBody(), 'fontSize', true); + parentFontSize = /px$/.test(parentFontSize) ? parseInt(parentFontSize, 10) : 0; + + each(previewStyles.split(' '), function(name) { + var value = dom.getStyle(previewElm, name, true); + + // If background is transparent then check if the body has a background color we can use + if (name == 'background-color' && /transparent|rgba\s*\([^)]+,\s*0\)/.test(value)) { + value = dom.getStyle(ed.getBody(), name, true); + + // Ignore white since it's the default color, not the nicest fix + if (dom.toHex(value).toLowerCase() == '#ffffff') { + return; + } + } + + // Old IE won't calculate the font size so we need to do that manually + if (name == 'font-size') { + if (/em|%$/.test(value)) { + if (parentFontSize === 0) { + return; + } + + // Convert font size from em/% to px + value = parseFloat(value, 10) / (/%$/.test(value) ? 100 : 1); + value = (value * parentFontSize) + 'px'; + } + } + + previewCss += name + ':' + value + ';'; + }); + + dom.remove(previewElm); + + return previewCss; + }; + + // Tell it to load theme specific language pack(s) + tinymce.ThemeManager.requireLangPack('advanced'); + + tinymce.create('tinymce.themes.AdvancedTheme', { + sizes : [8, 10, 12, 14, 18, 24, 36], + + // Control name lookup, format: title, command + controls : { + bold : ['bold_desc', 'Bold'], + italic : ['italic_desc', 'Italic'], + underline : ['underline_desc', 'Underline'], + strikethrough : ['striketrough_desc', 'Strikethrough'], + justifyleft : ['justifyleft_desc', 'JustifyLeft'], + justifycenter : ['justifycenter_desc', 'JustifyCenter'], + justifyright : ['justifyright_desc', 'JustifyRight'], + justifyfull : ['justifyfull_desc', 'JustifyFull'], + bullist : ['bullist_desc', 'InsertUnorderedList'], + numlist : ['numlist_desc', 'InsertOrderedList'], + outdent : ['outdent_desc', 'Outdent'], + indent : ['indent_desc', 'Indent'], + cut : ['cut_desc', 'Cut'], + copy : ['copy_desc', 'Copy'], + paste : ['paste_desc', 'Paste'], + undo : ['undo_desc', 'Undo'], + redo : ['redo_desc', 'Redo'], + link : ['link_desc', 'mceLink'], + unlink : ['unlink_desc', 'unlink'], + image : ['image_desc', 'mceImage'], + cleanup : ['cleanup_desc', 'mceCleanup'], + help : ['help_desc', 'mceHelp'], + code : ['code_desc', 'mceCodeEditor'], + hr : ['hr_desc', 'InsertHorizontalRule'], + removeformat : ['removeformat_desc', 'RemoveFormat'], + sub : ['sub_desc', 'subscript'], + sup : ['sup_desc', 'superscript'], + forecolor : ['forecolor_desc', 'ForeColor'], + forecolorpicker : ['forecolor_desc', 'mceForeColor'], + backcolor : ['backcolor_desc', 'HiliteColor'], + backcolorpicker : ['backcolor_desc', 'mceBackColor'], + charmap : ['charmap_desc', 'mceCharMap'], + visualaid : ['visualaid_desc', 'mceToggleVisualAid'], + anchor : ['anchor_desc', 'mceInsertAnchor'], + newdocument : ['newdocument_desc', 'mceNewDocument'], + blockquote : ['blockquote_desc', 'mceBlockQuote'] + }, + + stateControls : ['bold', 'italic', 'underline', 'strikethrough', 'bullist', 'numlist', 'justifyleft', 'justifycenter', 'justifyright', 'justifyfull', 'sub', 'sup', 'blockquote'], + + init : function(ed, url) { + var t = this, s, v, o; + + t.editor = ed; + t.url = url; + t.onResolveName = new tinymce.util.Dispatcher(this); + s = ed.settings; + + ed.forcedHighContrastMode = ed.settings.detect_highcontrast && t._isHighContrast(); + ed.settings.skin = ed.forcedHighContrastMode ? 'highcontrast' : ed.settings.skin; + + // Setup default buttons + if (!s.theme_advanced_buttons1) { + s = extend({ + theme_advanced_buttons1 : "bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,styleselect,formatselect", + theme_advanced_buttons2 : "bullist,numlist,|,outdent,indent,|,undo,redo,|,link,unlink,anchor,image,cleanup,help,code", + theme_advanced_buttons3 : "hr,removeformat,visualaid,|,sub,sup,|,charmap" + }, s); + } + + // Default settings + t.settings = s = extend({ + theme_advanced_path : true, + theme_advanced_toolbar_location : 'top', + theme_advanced_blockformats : "p,address,pre,h1,h2,h3,h4,h5,h6", + theme_advanced_toolbar_align : "left", + theme_advanced_statusbar_location : "bottom", + theme_advanced_fonts : "Andale Mono=andale mono,times;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;Comic Sans MS=comic sans ms,sans-serif;Courier New=courier new,courier;Georgia=georgia,palatino;Helvetica=helvetica;Impact=impact,chicago;Symbol=symbol;Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,monaco;Times New Roman=times new roman,times;Trebuchet MS=trebuchet ms,geneva;Verdana=verdana,geneva;Webdings=webdings;Wingdings=wingdings,zapf dingbats", + theme_advanced_more_colors : 1, + theme_advanced_row_height : 23, + theme_advanced_resize_horizontal : 1, + theme_advanced_resizing_use_cookie : 1, + theme_advanced_font_sizes : "1,2,3,4,5,6,7", + theme_advanced_font_selector : "span", + theme_advanced_show_current_color: 0, + readonly : ed.settings.readonly + }, s); + + // Setup default font_size_style_values + if (!s.font_size_style_values) + s.font_size_style_values = "8pt,10pt,12pt,14pt,18pt,24pt,36pt"; + + if (tinymce.is(s.theme_advanced_font_sizes, 'string')) { + s.font_size_style_values = tinymce.explode(s.font_size_style_values); + s.font_size_classes = tinymce.explode(s.font_size_classes || ''); + + // Parse string value + o = {}; + ed.settings.theme_advanced_font_sizes = s.theme_advanced_font_sizes; + each(ed.getParam('theme_advanced_font_sizes', '', 'hash'), function(v, k) { + var cl; + + if (k == v && v >= 1 && v <= 7) { + k = v + ' (' + t.sizes[v - 1] + 'pt)'; + cl = s.font_size_classes[v - 1]; + v = s.font_size_style_values[v - 1] || (t.sizes[v - 1] + 'pt'); + } + + if (/^\s*\./.test(v)) + cl = v.replace(/\./g, ''); + + o[k] = cl ? {'class' : cl} : {fontSize : v}; + }); + + s.theme_advanced_font_sizes = o; + } + + if ((v = s.theme_advanced_path_location) && v != 'none') + s.theme_advanced_statusbar_location = s.theme_advanced_path_location; + + if (s.theme_advanced_statusbar_location == 'none') + s.theme_advanced_statusbar_location = 0; + + if (ed.settings.content_css !== false) + ed.contentCSS.push(ed.baseURI.toAbsolute(url + "/skins/" + ed.settings.skin + "/content.css")); + + // Init editor + ed.onInit.add(function() { + if (!ed.settings.readonly) { + ed.onNodeChange.add(t._nodeChanged, t); + ed.onKeyUp.add(t._updateUndoStatus, t); + ed.onMouseUp.add(t._updateUndoStatus, t); + ed.dom.bind(ed.dom.getRoot(), 'dragend', function() { + t._updateUndoStatus(ed); + }); + } + }); + + ed.onSetProgressState.add(function(ed, b, ti) { + var co, id = ed.id, tb; + + if (b) { + t.progressTimer = setTimeout(function() { + co = ed.getContainer(); + co = co.insertBefore(DOM.create('DIV', {style : 'position:relative'}), co.firstChild); + tb = DOM.get(ed.id + '_tbl'); + + DOM.add(co, 'div', {id : id + '_blocker', 'class' : 'mceBlocker', style : {width : tb.clientWidth + 2, height : tb.clientHeight + 2}}); + DOM.add(co, 'div', {id : id + '_progress', 'class' : 'mceProgress', style : {left : tb.clientWidth / 2, top : tb.clientHeight / 2}}); + }, ti || 0); + } else { + DOM.remove(id + '_blocker'); + DOM.remove(id + '_progress'); + clearTimeout(t.progressTimer); + } + }); + + DOM.loadCSS(s.editor_css ? ed.documentBaseURI.toAbsolute(s.editor_css) : url + "/skins/" + ed.settings.skin + "/ui.css"); + + if (s.skin_variant) + DOM.loadCSS(url + "/skins/" + ed.settings.skin + "/ui_" + s.skin_variant + ".css"); + }, + + _isHighContrast : function() { + var actualColor, div = DOM.add(DOM.getRoot(), 'div', {'style': 'background-color: rgb(171,239,86);'}); + + actualColor = (DOM.getStyle(div, 'background-color', true) + '').toLowerCase().replace(/ /g, ''); + DOM.remove(div); + + return actualColor != 'rgb(171,239,86)' && actualColor != '#abef56'; + }, + + createControl : function(n, cf) { + var cd, c; + + if (c = cf.createControl(n)) + return c; + + switch (n) { + case "styleselect": + return this._createStyleSelect(); + + case "formatselect": + return this._createBlockFormats(); + + case "fontselect": + return this._createFontSelect(); + + case "fontsizeselect": + return this._createFontSizeSelect(); + + case "forecolor": + return this._createForeColorMenu(); + + case "backcolor": + return this._createBackColorMenu(); + } + + if ((cd = this.controls[n])) + return cf.createButton(n, {title : "advanced." + cd[0], cmd : cd[1], ui : cd[2], value : cd[3]}); + }, + + execCommand : function(cmd, ui, val) { + var f = this['_' + cmd]; + + if (f) { + f.call(this, ui, val); + return true; + } + + return false; + }, + + _importClasses : function(e) { + var ed = this.editor, ctrl = ed.controlManager.get('styleselect'); + + if (ctrl.getLength() == 0) { + each(ed.dom.getClasses(), function(o, idx) { + var name = 'style_' + idx, fmt; + + fmt = { + inline : 'span', + attributes : {'class' : o['class']}, + selector : '*' + }; + + ed.formatter.register(name, fmt); + + ctrl.add(o['class'], name, { + style: function() { + return getPreviewCss(ed, fmt); + } + }); + }); + } + }, + + _createStyleSelect : function(n) { + var t = this, ed = t.editor, ctrlMan = ed.controlManager, ctrl; + + // Setup style select box + ctrl = ctrlMan.createListBox('styleselect', { + title : 'advanced.style_select', + onselect : function(name) { + var matches, formatNames = [], removedFormat; + + each(ctrl.items, function(item) { + formatNames.push(item.value); + }); + + ed.focus(); + ed.undoManager.add(); + + // Toggle off the current format(s) + matches = ed.formatter.matchAll(formatNames); + tinymce.each(matches, function(match) { + if (!name || match == name) { + if (match) + ed.formatter.remove(match); + + removedFormat = true; + } + }); + + if (!removedFormat) + ed.formatter.apply(name); + + ed.undoManager.add(); + ed.nodeChanged(); + + return false; // No auto select + } + }); + + // Handle specified format + ed.onPreInit.add(function() { + var counter = 0, formats = ed.getParam('style_formats'); + + if (formats) { + each(formats, function(fmt) { + var name, keys = 0; + + each(fmt, function() {keys++;}); + + if (keys > 1) { + name = fmt.name = fmt.name || 'style_' + (counter++); + ed.formatter.register(name, fmt); + ctrl.add(fmt.title, name, { + style: function() { + return getPreviewCss(ed, fmt); + } + }); + } else + ctrl.add(fmt.title); + }); + } else { + each(ed.getParam('theme_advanced_styles', '', 'hash'), function(val, key) { + var name, fmt; + + if (val) { + name = 'style_' + (counter++); + fmt = { + inline : 'span', + classes : val, + selector : '*' + }; + + ed.formatter.register(name, fmt); + ctrl.add(t.editor.translate(key), name, { + style: function() { + return getPreviewCss(ed, fmt); + } + }); + } + }); + } + }); + + // Auto import classes if the ctrl box is empty + if (ctrl.getLength() == 0) { + ctrl.onPostRender.add(function(ed, n) { + if (!ctrl.NativeListBox) { + Event.add(n.id + '_text', 'focus', t._importClasses, t); + Event.add(n.id + '_text', 'mousedown', t._importClasses, t); + Event.add(n.id + '_open', 'focus', t._importClasses, t); + Event.add(n.id + '_open', 'mousedown', t._importClasses, t); + } else + Event.add(n.id, 'focus', t._importClasses, t); + }); + } + + return ctrl; + }, + + _createFontSelect : function() { + var c, t = this, ed = t.editor; + + c = ed.controlManager.createListBox('fontselect', { + title : 'advanced.fontdefault', + onselect : function(v) { + var cur = c.items[c.selectedIndex]; + + if (!v && cur) { + ed.execCommand('FontName', false, cur.value); + return; + } + + ed.execCommand('FontName', false, v); + + // Fake selection, execCommand will fire a nodeChange and update the selection + c.select(function(sv) { + return v == sv; + }); + + if (cur && cur.value == v) { + c.select(null); + } + + return false; // No auto select + } + }); + + if (c) { + each(ed.getParam('theme_advanced_fonts', t.settings.theme_advanced_fonts, 'hash'), function(v, k) { + c.add(ed.translate(k), v, {style : v.indexOf('dings') == -1 ? 'font-family:' + v : ''}); + }); + } + + return c; + }, + + _createFontSizeSelect : function() { + var t = this, ed = t.editor, c, i = 0, cl = []; + + c = ed.controlManager.createListBox('fontsizeselect', {title : 'advanced.font_size', onselect : function(v) { + var cur = c.items[c.selectedIndex]; + + if (!v && cur) { + cur = cur.value; + + if (cur['class']) { + ed.formatter.toggle('fontsize_class', {value : cur['class']}); + ed.undoManager.add(); + ed.nodeChanged(); + } else { + ed.execCommand('FontSize', false, cur.fontSize); + } + + return; + } + + if (v['class']) { + ed.focus(); + ed.undoManager.add(); + ed.formatter.toggle('fontsize_class', {value : v['class']}); + ed.undoManager.add(); + ed.nodeChanged(); + } else + ed.execCommand('FontSize', false, v.fontSize); + + // Fake selection, execCommand will fire a nodeChange and update the selection + c.select(function(sv) { + return v == sv; + }); + + if (cur && (cur.value.fontSize == v.fontSize || cur.value['class'] && cur.value['class'] == v['class'])) { + c.select(null); + } + + return false; // No auto select + }}); + + if (c) { + each(t.settings.theme_advanced_font_sizes, function(v, k) { + var fz = v.fontSize; + + if (fz >= 1 && fz <= 7) + fz = t.sizes[parseInt(fz) - 1] + 'pt'; + + c.add(k, v, {'style' : 'font-size:' + fz, 'class' : 'mceFontSize' + (i++) + (' ' + (v['class'] || ''))}); + }); + } + + return c; + }, + + _createBlockFormats : function() { + var c, fmts = { + p : 'advanced.paragraph', + address : 'advanced.address', + pre : 'advanced.pre', + h1 : 'advanced.h1', + h2 : 'advanced.h2', + h3 : 'advanced.h3', + h4 : 'advanced.h4', + h5 : 'advanced.h5', + h6 : 'advanced.h6', + div : 'advanced.div', + blockquote : 'advanced.blockquote', + code : 'advanced.code', + dt : 'advanced.dt', + dd : 'advanced.dd', + samp : 'advanced.samp' + }, t = this; + + c = t.editor.controlManager.createListBox('formatselect', {title : 'advanced.block', onselect : function(v) { + t.editor.execCommand('FormatBlock', false, v); + return false; + }}); + + if (c) { + each(t.editor.getParam('theme_advanced_blockformats', t.settings.theme_advanced_blockformats, 'hash'), function(v, k) { + c.add(t.editor.translate(k != v ? k : fmts[v]), v, {'class' : 'mce_formatPreview mce_' + v, style: function() { + return getPreviewCss(t.editor, {block: v}); + }}); + }); + } + + return c; + }, + + _createForeColorMenu : function() { + var c, t = this, s = t.settings, o = {}, v; + + if (s.theme_advanced_more_colors) { + o.more_colors_func = function() { + t._mceColorPicker(0, { + color : c.value, + func : function(co) { + c.setColor(co); + } + }); + }; + } + + if (v = s.theme_advanced_text_colors) + o.colors = v; + + if (s.theme_advanced_default_foreground_color) + o.default_color = s.theme_advanced_default_foreground_color; + + o.title = 'advanced.forecolor_desc'; + o.cmd = 'ForeColor'; + o.scope = this; + + c = t.editor.controlManager.createColorSplitButton('forecolor', o); + + return c; + }, + + _createBackColorMenu : function() { + var c, t = this, s = t.settings, o = {}, v; + + if (s.theme_advanced_more_colors) { + o.more_colors_func = function() { + t._mceColorPicker(0, { + color : c.value, + func : function(co) { + c.setColor(co); + } + }); + }; + } + + if (v = s.theme_advanced_background_colors) + o.colors = v; + + if (s.theme_advanced_default_background_color) + o.default_color = s.theme_advanced_default_background_color; + + o.title = 'advanced.backcolor_desc'; + o.cmd = 'HiliteColor'; + o.scope = this; + + c = t.editor.controlManager.createColorSplitButton('backcolor', o); + + return c; + }, + + renderUI : function(o) { + var n, ic, tb, t = this, ed = t.editor, s = t.settings, sc, p, nl; + + if (ed.settings) { + ed.settings.aria_label = s.aria_label + ed.getLang('advanced.help_shortcut'); + } + + // TODO: ACC Should have an aria-describedby attribute which is user-configurable to describe what this field is actually for. + // Maybe actually inherit it from the original textara? + n = p = DOM.create('span', {role : 'application', 'aria-labelledby' : ed.id + '_voice', id : ed.id + '_parent', 'class' : 'mceEditor ' + ed.settings.skin + 'Skin' + (s.skin_variant ? ' ' + ed.settings.skin + 'Skin' + t._ufirst(s.skin_variant) : '') + (ed.settings.directionality == "rtl" ? ' mceRtl' : '')}); + DOM.add(n, 'span', {'class': 'mceVoiceLabel', 'style': 'display:none;', id: ed.id + '_voice'}, s.aria_label); + + if (!DOM.boxModel) + n = DOM.add(n, 'div', {'class' : 'mceOldBoxModel'}); + + n = sc = DOM.add(n, 'table', {role : "presentation", id : ed.id + '_tbl', 'class' : 'mceLayout', cellSpacing : 0, cellPadding : 0}); + n = tb = DOM.add(n, 'tbody'); + + switch ((s.theme_advanced_layout_manager || '').toLowerCase()) { + case "rowlayout": + ic = t._rowLayout(s, tb, o); + break; + + case "customlayout": + ic = ed.execCallback("theme_advanced_custom_layout", s, tb, o, p); + break; + + default: + ic = t._simpleLayout(s, tb, o, p); + } + + n = o.targetNode; + + // Add classes to first and last TRs + nl = sc.rows; + DOM.addClass(nl[0], 'mceFirst'); + DOM.addClass(nl[nl.length - 1], 'mceLast'); + + // Add classes to first and last TDs + each(DOM.select('tr', tb), function(n) { + DOM.addClass(n.firstChild, 'mceFirst'); + DOM.addClass(n.childNodes[n.childNodes.length - 1], 'mceLast'); + }); + + if (DOM.get(s.theme_advanced_toolbar_container)) + DOM.get(s.theme_advanced_toolbar_container).appendChild(p); + else + DOM.insertAfter(p, n); + + Event.add(ed.id + '_path_row', 'click', function(e) { + e = e.target; + + if (e.nodeName == 'A') { + t._sel(e.className.replace(/^.*mcePath_([0-9]+).*$/, '$1')); + return false; + } + }); +/* + if (DOM.get(ed.id + '_path_row')) { + Event.add(ed.id + '_tbl', 'mouseover', function(e) { + var re; + + e = e.target; + + if (e.nodeName == 'SPAN' && DOM.hasClass(e.parentNode, 'mceButton')) { + re = DOM.get(ed.id + '_path_row'); + t.lastPath = re.innerHTML; + DOM.setHTML(re, e.parentNode.title); + } + }); + + Event.add(ed.id + '_tbl', 'mouseout', function(e) { + if (t.lastPath) { + DOM.setHTML(ed.id + '_path_row', t.lastPath); + t.lastPath = 0; + } + }); + } +*/ + + if (!ed.getParam('accessibility_focus')) + Event.add(DOM.add(p, 'a', {href : '#'}, ''), 'focus', function() {tinyMCE.get(ed.id).focus();}); + + if (s.theme_advanced_toolbar_location == 'external') + o.deltaHeight = 0; + + t.deltaHeight = o.deltaHeight; + o.targetNode = null; + + ed.onKeyDown.add(function(ed, evt) { + var DOM_VK_F10 = 121, DOM_VK_F11 = 122; + + if (evt.altKey) { + if (evt.keyCode === DOM_VK_F10) { + // Make sure focus is given to toolbar in Safari. + // We can't do this in IE as it prevents giving focus to toolbar when editor is in a frame + if (tinymce.isWebKit) { + window.focus(); + } + t.toolbarGroup.focus(); + return Event.cancel(evt); + } else if (evt.keyCode === DOM_VK_F11) { + DOM.get(ed.id + '_path_row').focus(); + return Event.cancel(evt); + } + } + }); + + // alt+0 is the UK recommended shortcut for accessing the list of access controls. + ed.addShortcut('alt+0', '', 'mceShortcuts', t); + + return { + iframeContainer : ic, + editorContainer : ed.id + '_parent', + sizeContainer : sc, + deltaHeight : o.deltaHeight + }; + }, + + getInfo : function() { + return { + longname : 'Advanced theme', + author : 'Moxiecode Systems AB', + authorurl : 'http://tinymce.moxiecode.com', + version : tinymce.majorVersion + "." + tinymce.minorVersion + } + }, + + resizeBy : function(dw, dh) { + var e = DOM.get(this.editor.id + '_ifr'); + + this.resizeTo(e.clientWidth + dw, e.clientHeight + dh); + }, + + resizeTo : function(w, h, store) { + var ed = this.editor, s = this.settings, e = DOM.get(ed.id + '_tbl'), ifr = DOM.get(ed.id + '_ifr'); + + // Boundery fix box + w = Math.max(s.theme_advanced_resizing_min_width || 100, w); + h = Math.max(s.theme_advanced_resizing_min_height || 100, h); + w = Math.min(s.theme_advanced_resizing_max_width || 0xFFFF, w); + h = Math.min(s.theme_advanced_resizing_max_height || 0xFFFF, h); + + // Resize iframe and container + DOM.setStyle(e, 'height', ''); + DOM.setStyle(ifr, 'height', h); + + if (s.theme_advanced_resize_horizontal) { + DOM.setStyle(e, 'width', ''); + DOM.setStyle(ifr, 'width', w); + + // Make sure that the size is never smaller than the over all ui + if (w < e.clientWidth) { + w = e.clientWidth; + DOM.setStyle(ifr, 'width', e.clientWidth); + } + } + + // Store away the size + if (store && s.theme_advanced_resizing_use_cookie) { + Cookie.setHash("TinyMCE_" + ed.id + "_size", { + cw : w, + ch : h + }); + } + }, + + destroy : function() { + var id = this.editor.id; + + Event.clear(id + '_resize'); + Event.clear(id + '_path_row'); + Event.clear(id + '_external_close'); + }, + + // Internal functions + + _simpleLayout : function(s, tb, o, p) { + var t = this, ed = t.editor, lo = s.theme_advanced_toolbar_location, sl = s.theme_advanced_statusbar_location, n, ic, etb, c; + + if (s.readonly) { + n = DOM.add(tb, 'tr'); + n = ic = DOM.add(n, 'td', {'class' : 'mceIframeContainer'}); + return ic; + } + + // Create toolbar container at top + if (lo == 'top') + t._addToolbars(tb, o); + + // Create external toolbar + if (lo == 'external') { + n = c = DOM.create('div', {style : 'position:relative'}); + n = DOM.add(n, 'div', {id : ed.id + '_external', 'class' : 'mceExternalToolbar'}); + DOM.add(n, 'a', {id : ed.id + '_external_close', href : 'javascript:;', 'class' : 'mceExternalClose'}); + n = DOM.add(n, 'table', {id : ed.id + '_tblext', cellSpacing : 0, cellPadding : 0}); + etb = DOM.add(n, 'tbody'); + + if (p.firstChild.className == 'mceOldBoxModel') + p.firstChild.appendChild(c); + else + p.insertBefore(c, p.firstChild); + + t._addToolbars(etb, o); + + ed.onMouseUp.add(function() { + var e = DOM.get(ed.id + '_external'); + DOM.show(e); + + DOM.hide(lastExtID); + + var f = Event.add(ed.id + '_external_close', 'click', function() { + DOM.hide(ed.id + '_external'); + Event.remove(ed.id + '_external_close', 'click', f); + }); + + DOM.show(e); + DOM.setStyle(e, 'top', 0 - DOM.getRect(ed.id + '_tblext').h - 1); + + // Fixes IE rendering bug + DOM.hide(e); + DOM.show(e); + e.style.filter = ''; + + lastExtID = ed.id + '_external'; + + e = null; + }); + } + + if (sl == 'top') + t._addStatusBar(tb, o); + + // Create iframe container + if (!s.theme_advanced_toolbar_container) { + n = DOM.add(tb, 'tr'); + n = ic = DOM.add(n, 'td', {'class' : 'mceIframeContainer'}); + } + + // Create toolbar container at bottom + if (lo == 'bottom') + t._addToolbars(tb, o); + + if (sl == 'bottom') + t._addStatusBar(tb, o); + + return ic; + }, + + _rowLayout : function(s, tb, o) { + var t = this, ed = t.editor, dc, da, cf = ed.controlManager, n, ic, to, a; + + dc = s.theme_advanced_containers_default_class || ''; + da = s.theme_advanced_containers_default_align || 'center'; + + each(explode(s.theme_advanced_containers || ''), function(c, i) { + var v = s['theme_advanced_container_' + c] || ''; + + switch (c.toLowerCase()) { + case 'mceeditor': + n = DOM.add(tb, 'tr'); + n = ic = DOM.add(n, 'td', {'class' : 'mceIframeContainer'}); + break; + + case 'mceelementpath': + t._addStatusBar(tb, o); + break; + + default: + a = (s['theme_advanced_container_' + c + '_align'] || da).toLowerCase(); + a = 'mce' + t._ufirst(a); + + n = DOM.add(DOM.add(tb, 'tr'), 'td', { + 'class' : 'mceToolbar ' + (s['theme_advanced_container_' + c + '_class'] || dc) + ' ' + a || da + }); + + to = cf.createToolbar("toolbar" + i); + t._addControls(v, to); + DOM.setHTML(n, to.renderHTML()); + o.deltaHeight -= s.theme_advanced_row_height; + } + }); + + return ic; + }, + + _addControls : function(v, tb) { + var t = this, s = t.settings, di, cf = t.editor.controlManager; + + if (s.theme_advanced_disable && !t._disabled) { + di = {}; + + each(explode(s.theme_advanced_disable), function(v) { + di[v] = 1; + }); + + t._disabled = di; + } else + di = t._disabled; + + each(explode(v), function(n) { + var c; + + if (di && di[n]) + return; + + // Compatiblity with 2.x + if (n == 'tablecontrols') { + each(["table","|","row_props","cell_props","|","row_before","row_after","delete_row","|","col_before","col_after","delete_col","|","split_cells","merge_cells"], function(n) { + n = t.createControl(n, cf); + + if (n) + tb.add(n); + }); + + return; + } + + c = t.createControl(n, cf); + + if (c) + tb.add(c); + }); + }, + + _addToolbars : function(c, o) { + var t = this, i, tb, ed = t.editor, s = t.settings, v, cf = ed.controlManager, di, n, h = [], a, toolbarGroup, toolbarsExist = false; + + toolbarGroup = cf.createToolbarGroup('toolbargroup', { + 'name': ed.getLang('advanced.toolbar'), + 'tab_focus_toolbar':ed.getParam('theme_advanced_tab_focus_toolbar') + }); + + t.toolbarGroup = toolbarGroup; + + a = s.theme_advanced_toolbar_align.toLowerCase(); + a = 'mce' + t._ufirst(a); + + n = DOM.add(DOM.add(c, 'tr', {role: 'presentation'}), 'td', {'class' : 'mceToolbar ' + a, "role":"presentation"}); + + // Create toolbar and add the controls + for (i=1; (v = s['theme_advanced_buttons' + i]); i++) { + toolbarsExist = true; + tb = cf.createToolbar("toolbar" + i, {'class' : 'mceToolbarRow' + i}); + + if (s['theme_advanced_buttons' + i + '_add']) + v += ',' + s['theme_advanced_buttons' + i + '_add']; + + if (s['theme_advanced_buttons' + i + '_add_before']) + v = s['theme_advanced_buttons' + i + '_add_before'] + ',' + v; + + t._addControls(v, tb); + toolbarGroup.add(tb); + + o.deltaHeight -= s.theme_advanced_row_height; + } + // Handle case when there are no toolbar buttons and ensure editor height is adjusted accordingly + if (!toolbarsExist) + o.deltaHeight -= s.theme_advanced_row_height; + h.push(toolbarGroup.renderHTML()); + h.push(DOM.createHTML('a', {href : '#', accesskey : 'z', title : ed.getLang("advanced.toolbar_focus"), onfocus : 'tinyMCE.getInstanceById(\'' + ed.id + '\').focus();'}, '')); + DOM.setHTML(n, h.join('')); + }, + + _addStatusBar : function(tb, o) { + var n, t = this, ed = t.editor, s = t.settings, r, mf, me, td; + + n = DOM.add(tb, 'tr'); + n = td = DOM.add(n, 'td', {'class' : 'mceStatusbar'}); + n = DOM.add(n, 'div', {id : ed.id + '_path_row', 'role': 'group', 'aria-labelledby': ed.id + '_path_voice'}); + if (s.theme_advanced_path) { + DOM.add(n, 'span', {id: ed.id + '_path_voice'}, ed.translate('advanced.path')); + DOM.add(n, 'span', {}, ': '); + } else { + DOM.add(n, 'span', {}, ' '); + } + + + if (s.theme_advanced_resizing) { + DOM.add(td, 'a', {id : ed.id + '_resize', href : 'javascript:;', onclick : "return false;", 'class' : 'mceResize', tabIndex:"-1"}); + + if (s.theme_advanced_resizing_use_cookie) { + ed.onPostRender.add(function() { + var o = Cookie.getHash("TinyMCE_" + ed.id + "_size"), c = DOM.get(ed.id + '_tbl'); + + if (!o) + return; + + t.resizeTo(o.cw, o.ch); + }); + } + + ed.onPostRender.add(function() { + Event.add(ed.id + '_resize', 'click', function(e) { + e.preventDefault(); + }); + + Event.add(ed.id + '_resize', 'mousedown', function(e) { + var mouseMoveHandler1, mouseMoveHandler2, + mouseUpHandler1, mouseUpHandler2, + startX, startY, startWidth, startHeight, width, height, ifrElm; + + function resizeOnMove(e) { + e.preventDefault(); + + width = startWidth + (e.screenX - startX); + height = startHeight + (e.screenY - startY); + + t.resizeTo(width, height); + }; + + function endResize(e) { + // Stop listening + Event.remove(DOM.doc, 'mousemove', mouseMoveHandler1); + Event.remove(ed.getDoc(), 'mousemove', mouseMoveHandler2); + Event.remove(DOM.doc, 'mouseup', mouseUpHandler1); + Event.remove(ed.getDoc(), 'mouseup', mouseUpHandler2); + + width = startWidth + (e.screenX - startX); + height = startHeight + (e.screenY - startY); + t.resizeTo(width, height, true); + }; + + e.preventDefault(); + + // Get the current rect size + startX = e.screenX; + startY = e.screenY; + ifrElm = DOM.get(t.editor.id + '_ifr'); + startWidth = width = ifrElm.clientWidth; + startHeight = height = ifrElm.clientHeight; + + // Register envent handlers + mouseMoveHandler1 = Event.add(DOM.doc, 'mousemove', resizeOnMove); + mouseMoveHandler2 = Event.add(ed.getDoc(), 'mousemove', resizeOnMove); + mouseUpHandler1 = Event.add(DOM.doc, 'mouseup', endResize); + mouseUpHandler2 = Event.add(ed.getDoc(), 'mouseup', endResize); + }); + }); + } + + o.deltaHeight -= 21; + n = tb = null; + }, + + _updateUndoStatus : function(ed) { + var cm = ed.controlManager, um = ed.undoManager; + + cm.setDisabled('undo', !um.hasUndo() && !um.typing); + cm.setDisabled('redo', !um.hasRedo()); + }, + + _nodeChanged : function(ed, cm, n, co, ob) { + var t = this, p, de = 0, v, c, s = t.settings, cl, fz, fn, fc, bc, formatNames, matches; + + tinymce.each(t.stateControls, function(c) { + cm.setActive(c, ed.queryCommandState(t.controls[c][1])); + }); + + function getParent(name) { + var i, parents = ob.parents, func = name; + + if (typeof(name) == 'string') { + func = function(node) { + return node.nodeName == name; + }; + } + + for (i = 0; i < parents.length; i++) { + if (func(parents[i])) + return parents[i]; + } + }; + + cm.setActive('visualaid', ed.hasVisual); + t._updateUndoStatus(ed); + cm.setDisabled('outdent', !ed.queryCommandState('Outdent')); + + p = getParent('A'); + if (c = cm.get('link')) { + c.setDisabled((!p && co) || (p && !p.href)); + c.setActive(!!p && (!p.name && !p.id)); + } + + if (c = cm.get('unlink')) { + c.setDisabled(!p && co); + c.setActive(!!p && !p.name && !p.id); + } + + if (c = cm.get('anchor')) { + c.setActive(!co && !!p && (p.name || (p.id && !p.href))); + } + + p = getParent('IMG'); + if (c = cm.get('image')) + c.setActive(!co && !!p && n.className.indexOf('mceItem') == -1); + + if (c = cm.get('styleselect')) { + t._importClasses(); + + formatNames = []; + each(c.items, function(item) { + formatNames.push(item.value); + }); + + matches = ed.formatter.matchAll(formatNames); + c.select(matches[0]); + tinymce.each(matches, function(match, index) { + if (index > 0) { + c.mark(match); + } + }); + } + + if (c = cm.get('formatselect')) { + p = getParent(ed.dom.isBlock); + + if (p) + c.select(p.nodeName.toLowerCase()); + } + + // Find out current fontSize, fontFamily and fontClass + getParent(function(n) { + if (n.nodeName === 'SPAN') { + if (!cl && n.className) + cl = n.className; + } + + if (ed.dom.is(n, s.theme_advanced_font_selector)) { + if (!fz && n.style.fontSize) + fz = n.style.fontSize; + + if (!fn && n.style.fontFamily) + fn = n.style.fontFamily.replace(/[\"\']+/g, '').replace(/^([^,]+).*/, '$1').toLowerCase(); + + if (!fc && n.style.color) + fc = n.style.color; + + if (!bc && n.style.backgroundColor) + bc = n.style.backgroundColor; + } + + return false; + }); + + if (c = cm.get('fontselect')) { + c.select(function(v) { + return v.replace(/^([^,]+).*/, '$1').toLowerCase() == fn; + }); + } + + // Select font size + if (c = cm.get('fontsizeselect')) { + // Use computed style + if (s.theme_advanced_runtime_fontsize && !fz && !cl) + fz = ed.dom.getStyle(n, 'fontSize', true); + + c.select(function(v) { + if (v.fontSize && v.fontSize === fz) + return true; + + if (v['class'] && v['class'] === cl) + return true; + }); + } + + if (s.theme_advanced_show_current_color) { + function updateColor(controlId, color) { + if (c = cm.get(controlId)) { + if (!color) + color = c.settings.default_color; + if (color !== c.value) { + c.displayColor(color); + } + } + } + updateColor('forecolor', fc); + updateColor('backcolor', bc); + } + + if (s.theme_advanced_show_current_color) { + function updateColor(controlId, color) { + if (c = cm.get(controlId)) { + if (!color) + color = c.settings.default_color; + if (color !== c.value) { + c.displayColor(color); + } + } + }; + + updateColor('forecolor', fc); + updateColor('backcolor', bc); + } + + if (s.theme_advanced_path && s.theme_advanced_statusbar_location) { + p = DOM.get(ed.id + '_path') || DOM.add(ed.id + '_path_row', 'span', {id : ed.id + '_path'}); + + if (t.statusKeyboardNavigation) { + t.statusKeyboardNavigation.destroy(); + t.statusKeyboardNavigation = null; + } + + DOM.setHTML(p, ''); + + getParent(function(n) { + var na = n.nodeName.toLowerCase(), u, pi, ti = ''; + + // Ignore non element and bogus/hidden elements + if (n.nodeType != 1 || na === 'br' || n.getAttribute('data-mce-bogus') || DOM.hasClass(n, 'mceItemHidden') || DOM.hasClass(n, 'mceItemRemoved')) + return; + + // Handle prefix + if (tinymce.isIE && n.scopeName !== 'HTML' && n.scopeName) + na = n.scopeName + ':' + na; + + // Remove internal prefix + na = na.replace(/mce\:/g, ''); + + // Handle node name + switch (na) { + case 'b': + na = 'strong'; + break; + + case 'i': + na = 'em'; + break; + + case 'img': + if (v = DOM.getAttrib(n, 'src')) + ti += 'src: ' + v + ' '; + + break; + + case 'a': + if (v = DOM.getAttrib(n, 'name')) { + ti += 'name: ' + v + ' '; + na += '#' + v; + } + + if (v = DOM.getAttrib(n, 'href')) + ti += 'href: ' + v + ' '; + + break; + + case 'font': + if (v = DOM.getAttrib(n, 'face')) + ti += 'font: ' + v + ' '; + + if (v = DOM.getAttrib(n, 'size')) + ti += 'size: ' + v + ' '; + + if (v = DOM.getAttrib(n, 'color')) + ti += 'color: ' + v + ' '; + + break; + + case 'span': + if (v = DOM.getAttrib(n, 'style')) + ti += 'style: ' + v + ' '; + + break; + } + + if (v = DOM.getAttrib(n, 'id')) + ti += 'id: ' + v + ' '; + + if (v = n.className) { + v = v.replace(/\b\s*(webkit|mce|Apple-)\w+\s*\b/g, '') + + if (v) { + ti += 'class: ' + v + ' '; + + if (ed.dom.isBlock(n) || na == 'img' || na == 'span') + na += '.' + v; + } + } + + na = na.replace(/(html:)/g, ''); + na = {name : na, node : n, title : ti}; + t.onResolveName.dispatch(t, na); + ti = na.title; + na = na.name; + + //u = "javascript:tinymce.EditorManager.get('" + ed.id + "').theme._sel('" + (de++) + "');"; + pi = DOM.create('a', {'href' : "javascript:;", role: 'button', onmousedown : "return false;", title : ti, 'class' : 'mcePath_' + (de++)}, na); + + if (p.hasChildNodes()) { + p.insertBefore(DOM.create('span', {'aria-hidden': 'true'}, '\u00a0\u00bb '), p.firstChild); + p.insertBefore(pi, p.firstChild); + } else + p.appendChild(pi); + }, ed.getBody()); + + if (DOM.select('a', p).length > 0) { + t.statusKeyboardNavigation = new tinymce.ui.KeyboardNavigation({ + root: ed.id + "_path_row", + items: DOM.select('a', p), + excludeFromTabOrder: true, + onCancel: function() { + ed.focus(); + } + }, DOM); + } + } + }, + + // Commands gets called by execCommand + + _sel : function(v) { + this.editor.execCommand('mceSelectNodeDepth', false, v); + }, + + _mceInsertAnchor : function(ui, v) { + var ed = this.editor; + + ed.windowManager.open({ + url : this.url + '/anchor.htm', + width : 320 + parseInt(ed.getLang('advanced.anchor_delta_width', 0)), + height : 90 + parseInt(ed.getLang('advanced.anchor_delta_height', 0)), + inline : true + }, { + theme_url : this.url + }); + }, + + _mceCharMap : function() { + var ed = this.editor; + + ed.windowManager.open({ + url : this.url + '/charmap.htm', + width : 550 + parseInt(ed.getLang('advanced.charmap_delta_width', 0)), + height : 265 + parseInt(ed.getLang('advanced.charmap_delta_height', 0)), + inline : true + }, { + theme_url : this.url + }); + }, + + _mceHelp : function() { + var ed = this.editor; + + ed.windowManager.open({ + url : this.url + '/about.htm', + width : 480, + height : 380, + inline : true + }, { + theme_url : this.url + }); + }, + + _mceShortcuts : function() { + var ed = this.editor; + ed.windowManager.open({ + url: this.url + '/shortcuts.htm', + width: 480, + height: 380, + inline: true + }, { + theme_url: this.url + }); + }, + + _mceColorPicker : function(u, v) { + var ed = this.editor; + + v = v || {}; + + ed.windowManager.open({ + url : this.url + '/color_picker.htm', + width : 375 + parseInt(ed.getLang('advanced.colorpicker_delta_width', 0)), + height : 250 + parseInt(ed.getLang('advanced.colorpicker_delta_height', 0)), + close_previous : false, + inline : true + }, { + input_color : v.color, + func : v.func, + theme_url : this.url + }); + }, + + _mceCodeEditor : function(ui, val) { + var ed = this.editor; + + ed.windowManager.open({ + url : this.url + '/source_editor.htm', + width : parseInt(ed.getParam("theme_advanced_source_editor_width", 720)), + height : parseInt(ed.getParam("theme_advanced_source_editor_height", 580)), + inline : true, + resizable : true, + maximizable : true + }, { + theme_url : this.url + }); + }, + + _mceImage : function(ui, val) { + var ed = this.editor; + + // Internal image object like a flash placeholder + if (ed.dom.getAttrib(ed.selection.getNode(), 'class', '').indexOf('mceItem') != -1) + return; + + ed.windowManager.open({ + url : this.url + '/image.htm', + width : 355 + parseInt(ed.getLang('advanced.image_delta_width', 0)), + height : 275 + parseInt(ed.getLang('advanced.image_delta_height', 0)), + inline : true + }, { + theme_url : this.url + }); + }, + + _mceLink : function(ui, val) { + var ed = this.editor; + + ed.windowManager.open({ + url : this.url + '/link.htm', + width : 310 + parseInt(ed.getLang('advanced.link_delta_width', 0)), + height : 200 + parseInt(ed.getLang('advanced.link_delta_height', 0)), + inline : true + }, { + theme_url : this.url + }); + }, + + _mceNewDocument : function() { + var ed = this.editor; + + ed.windowManager.confirm('advanced.newdocument', function(s) { + if (s) + ed.execCommand('mceSetContent', false, ''); + }); + }, + + _mceForeColor : function() { + var t = this; + + this._mceColorPicker(0, { + color: t.fgColor, + func : function(co) { + t.fgColor = co; + t.editor.execCommand('ForeColor', false, co); + } + }); + }, + + _mceBackColor : function() { + var t = this; + + this._mceColorPicker(0, { + color: t.bgColor, + func : function(co) { + t.bgColor = co; + t.editor.execCommand('HiliteColor', false, co); + } + }); + }, + + _ufirst : function(s) { + return s.substring(0, 1).toUpperCase() + s.substring(1); + } + }); + + tinymce.ThemeManager.add('advanced', tinymce.themes.AdvancedTheme); +}(tinymce)); diff --git a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/image.htm b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/image.htm index 884890f..b8ba729 100644 --- a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/image.htm +++ b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/image.htm @@ -1,80 +1,80 @@ - - - - {#advanced_dlg.image_title} - - - - - - -
            - - -
            -
            - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
            - - - - -
             
            - x -
            -
            -
            - -
            - - -
            -
            - - + + + + {#advanced_dlg.image_title} + + + + + + +
            + + +
            +
            + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + + +
             
            + x +
            +
            +
            + +
            + + +
            +
            + + diff --git a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/js/about.js b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/js/about.js index daf4909..5b35845 100644 --- a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/js/about.js +++ b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/js/about.js @@ -1,73 +1,73 @@ -tinyMCEPopup.requireLangPack(); - -function init() { - var ed, tcont; - - tinyMCEPopup.resizeToInnerSize(); - ed = tinyMCEPopup.editor; - - // Give FF some time - window.setTimeout(insertHelpIFrame, 10); - - tcont = document.getElementById('plugintablecontainer'); - document.getElementById('plugins_tab').style.display = 'none'; - - var html = ""; - html += ''; - html += ''; - html += ''; - html += ''; - html += ''; - html += ''; - html += ''; - html += ''; - html += ''; - - tinymce.each(ed.plugins, function(p, n) { - var info; - - if (!p.getInfo) - return; - - html += ''; - - info = p.getInfo(); - - if (info.infourl != null && info.infourl != '') - html += ''; - else - html += ''; - - if (info.authorurl != null && info.authorurl != '') - html += ''; - else - html += ''; - - html += ''; - html += ''; - - document.getElementById('plugins_tab').style.display = ''; - - }); - - html += ''; - html += '
            ' + ed.getLang('advanced_dlg.about_plugin') + '' + ed.getLang('advanced_dlg.about_author') + '' + ed.getLang('advanced_dlg.about_version') + '
            ' + info.longname + '' + info.longname + '' + info.author + '' + info.author + '' + info.version + '
            '; - - tcont.innerHTML = html; - - tinyMCEPopup.dom.get('version').innerHTML = tinymce.majorVersion + "." + tinymce.minorVersion; - tinyMCEPopup.dom.get('date').innerHTML = tinymce.releaseDate; -} - -function insertHelpIFrame() { - var html; - - if (tinyMCEPopup.getParam('docs_url')) { - html = ''; - document.getElementById('iframecontainer').innerHTML = html; - document.getElementById('help_tab').style.display = 'block'; - document.getElementById('help_tab').setAttribute("aria-hidden", "false"); - } -} - -tinyMCEPopup.onInit.add(init); +tinyMCEPopup.requireLangPack(); + +function init() { + var ed, tcont; + + tinyMCEPopup.resizeToInnerSize(); + ed = tinyMCEPopup.editor; + + // Give FF some time + window.setTimeout(insertHelpIFrame, 10); + + tcont = document.getElementById('plugintablecontainer'); + document.getElementById('plugins_tab').style.display = 'none'; + + var html = ""; + html += ''; + html += ''; + html += ''; + html += ''; + html += ''; + html += ''; + html += ''; + html += ''; + html += ''; + + tinymce.each(ed.plugins, function(p, n) { + var info; + + if (!p.getInfo) + return; + + html += ''; + + info = p.getInfo(); + + if (info.infourl != null && info.infourl != '') + html += ''; + else + html += ''; + + if (info.authorurl != null && info.authorurl != '') + html += ''; + else + html += ''; + + html += ''; + html += ''; + + document.getElementById('plugins_tab').style.display = ''; + + }); + + html += ''; + html += '
            ' + ed.getLang('advanced_dlg.about_plugin') + '' + ed.getLang('advanced_dlg.about_author') + '' + ed.getLang('advanced_dlg.about_version') + '
            ' + info.longname + '' + info.longname + '' + info.author + '' + info.author + '' + info.version + '
            '; + + tcont.innerHTML = html; + + tinyMCEPopup.dom.get('version').innerHTML = tinymce.majorVersion + "." + tinymce.minorVersion; + tinyMCEPopup.dom.get('date').innerHTML = tinymce.releaseDate; +} + +function insertHelpIFrame() { + var html; + + if (tinyMCEPopup.getParam('docs_url')) { + html = ''; + document.getElementById('iframecontainer').innerHTML = html; + document.getElementById('help_tab').style.display = 'block'; + document.getElementById('help_tab').setAttribute("aria-hidden", "false"); + } +} + +tinyMCEPopup.onInit.add(init); diff --git a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/js/anchor.js b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/js/anchor.js index a3a0186..2909a3a 100644 --- a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/js/anchor.js +++ b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/js/anchor.js @@ -1,56 +1,56 @@ -tinyMCEPopup.requireLangPack(); - -var AnchorDialog = { - init : function(ed) { - var action, elm, f = document.forms[0]; - - this.editor = ed; - elm = ed.dom.getParent(ed.selection.getNode(), 'A'); - v = ed.dom.getAttrib(elm, 'name') || ed.dom.getAttrib(elm, 'id'); - - if (v) { - this.action = 'update'; - f.anchorName.value = v; - } - - f.insert.value = ed.getLang(elm ? 'update' : 'insert'); - }, - - update : function() { - var ed = this.editor, elm, name = document.forms[0].anchorName.value, attribName; - - if (!name || !/^[a-z][a-z0-9\-\_:\.]*$/i.test(name)) { - tinyMCEPopup.alert('advanced_dlg.anchor_invalid'); - return; - } - - tinyMCEPopup.restoreSelection(); - - if (this.action != 'update') - ed.selection.collapse(1); - - var aRule = ed.schema.getElementRule('a'); - if (!aRule || aRule.attributes.name) { - attribName = 'name'; - } else { - attribName = 'id'; - } - - elm = ed.dom.getParent(ed.selection.getNode(), 'A'); - if (elm) { - elm.setAttribute(attribName, name); - elm[attribName] = name; - ed.undoManager.add(); - } else { - // create with zero-sized nbsp so that in Webkit where anchor is on last line by itself caret cannot be placed after it - var attrs = {'class' : 'mceItemAnchor'}; - attrs[attribName] = name; - ed.execCommand('mceInsertContent', 0, ed.dom.createHTML('a', attrs, '\uFEFF')); - ed.nodeChanged(); - } - - tinyMCEPopup.close(); - } -}; - -tinyMCEPopup.onInit.add(AnchorDialog.init, AnchorDialog); +tinyMCEPopup.requireLangPack(); + +var AnchorDialog = { + init : function(ed) { + var action, elm, f = document.forms[0]; + + this.editor = ed; + elm = ed.dom.getParent(ed.selection.getNode(), 'A'); + v = ed.dom.getAttrib(elm, 'name') || ed.dom.getAttrib(elm, 'id'); + + if (v) { + this.action = 'update'; + f.anchorName.value = v; + } + + f.insert.value = ed.getLang(elm ? 'update' : 'insert'); + }, + + update : function() { + var ed = this.editor, elm, name = document.forms[0].anchorName.value, attribName; + + if (!name || !/^[a-z][a-z0-9\-\_:\.]*$/i.test(name)) { + tinyMCEPopup.alert('advanced_dlg.anchor_invalid'); + return; + } + + tinyMCEPopup.restoreSelection(); + + if (this.action != 'update') + ed.selection.collapse(1); + + var aRule = ed.schema.getElementRule('a'); + if (!aRule || aRule.attributes.name) { + attribName = 'name'; + } else { + attribName = 'id'; + } + + elm = ed.dom.getParent(ed.selection.getNode(), 'A'); + if (elm) { + elm.setAttribute(attribName, name); + elm[attribName] = name; + ed.undoManager.add(); + } else { + // create with zero-sized nbsp so that in Webkit where anchor is on last line by itself caret cannot be placed after it + var attrs = {'class' : 'mceItemAnchor'}; + attrs[attribName] = name; + ed.execCommand('mceInsertContent', 0, ed.dom.createHTML('a', attrs, '\uFEFF')); + ed.nodeChanged(); + } + + tinyMCEPopup.close(); + } +}; + +tinyMCEPopup.onInit.add(AnchorDialog.init, AnchorDialog); diff --git a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/js/charmap.js b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/js/charmap.js index cbb4172..bb18695 100644 --- a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/js/charmap.js +++ b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/js/charmap.js @@ -1,363 +1,363 @@ -/** - * charmap.js - * - * Copyright 2009, Moxiecode Systems AB - * Released under LGPL License. - * - * License: http://tinymce.moxiecode.com/license - * Contributing: http://tinymce.moxiecode.com/contributing - */ - -tinyMCEPopup.requireLangPack(); - -var charmap = [ - [' ', ' ', true, 'no-break space'], - ['&', '&', true, 'ampersand'], - ['"', '"', true, 'quotation mark'], -// finance - ['¢', '¢', true, 'cent sign'], - ['€', '€', true, 'euro sign'], - ['£', '£', true, 'pound sign'], - ['¥', '¥', true, 'yen sign'], -// signs - ['©', '©', true, 'copyright sign'], - ['®', '®', true, 'registered sign'], - ['™', '™', true, 'trade mark sign'], - ['‰', '‰', true, 'per mille sign'], - ['µ', 'µ', true, 'micro sign'], - ['·', '·', true, 'middle dot'], - ['•', '•', true, 'bullet'], - ['…', '…', true, 'three dot leader'], - ['′', '′', true, 'minutes / feet'], - ['″', '″', true, 'seconds / inches'], - ['§', '§', true, 'section sign'], - ['¶', '¶', true, 'paragraph sign'], - ['ß', 'ß', true, 'sharp s / ess-zed'], -// quotations - ['‹', '‹', true, 'single left-pointing angle quotation mark'], - ['›', '›', true, 'single right-pointing angle quotation mark'], - ['«', '«', true, 'left pointing guillemet'], - ['»', '»', true, 'right pointing guillemet'], - ['‘', '‘', true, 'left single quotation mark'], - ['’', '’', true, 'right single quotation mark'], - ['“', '“', true, 'left double quotation mark'], - ['”', '”', true, 'right double quotation mark'], - ['‚', '‚', true, 'single low-9 quotation mark'], - ['„', '„', true, 'double low-9 quotation mark'], - ['<', '<', true, 'less-than sign'], - ['>', '>', true, 'greater-than sign'], - ['≤', '≤', true, 'less-than or equal to'], - ['≥', '≥', true, 'greater-than or equal to'], - ['–', '–', true, 'en dash'], - ['—', '—', true, 'em dash'], - ['¯', '¯', true, 'macron'], - ['‾', '‾', true, 'overline'], - ['¤', '¤', true, 'currency sign'], - ['¦', '¦', true, 'broken bar'], - ['¨', '¨', true, 'diaeresis'], - ['¡', '¡', true, 'inverted exclamation mark'], - ['¿', '¿', true, 'turned question mark'], - ['ˆ', 'ˆ', true, 'circumflex accent'], - ['˜', '˜', true, 'small tilde'], - ['°', '°', true, 'degree sign'], - ['−', '−', true, 'minus sign'], - ['±', '±', true, 'plus-minus sign'], - ['÷', '÷', true, 'division sign'], - ['⁄', '⁄', true, 'fraction slash'], - ['×', '×', true, 'multiplication sign'], - ['¹', '¹', true, 'superscript one'], - ['²', '²', true, 'superscript two'], - ['³', '³', true, 'superscript three'], - ['¼', '¼', true, 'fraction one quarter'], - ['½', '½', true, 'fraction one half'], - ['¾', '¾', true, 'fraction three quarters'], -// math / logical - ['ƒ', 'ƒ', true, 'function / florin'], - ['∫', '∫', true, 'integral'], - ['∑', '∑', true, 'n-ary sumation'], - ['∞', '∞', true, 'infinity'], - ['√', '√', true, 'square root'], - ['∼', '∼', false,'similar to'], - ['≅', '≅', false,'approximately equal to'], - ['≈', '≈', true, 'almost equal to'], - ['≠', '≠', true, 'not equal to'], - ['≡', '≡', true, 'identical to'], - ['∈', '∈', false,'element of'], - ['∉', '∉', false,'not an element of'], - ['∋', '∋', false,'contains as member'], - ['∏', '∏', true, 'n-ary product'], - ['∧', '∧', false,'logical and'], - ['∨', '∨', false,'logical or'], - ['¬', '¬', true, 'not sign'], - ['∩', '∩', true, 'intersection'], - ['∪', '∪', false,'union'], - ['∂', '∂', true, 'partial differential'], - ['∀', '∀', false,'for all'], - ['∃', '∃', false,'there exists'], - ['∅', '∅', false,'diameter'], - ['∇', '∇', false,'backward difference'], - ['∗', '∗', false,'asterisk operator'], - ['∝', '∝', false,'proportional to'], - ['∠', '∠', false,'angle'], -// undefined - ['´', '´', true, 'acute accent'], - ['¸', '¸', true, 'cedilla'], - ['ª', 'ª', true, 'feminine ordinal indicator'], - ['º', 'º', true, 'masculine ordinal indicator'], - ['†', '†', true, 'dagger'], - ['‡', '‡', true, 'double dagger'], -// alphabetical special chars - ['À', 'À', true, 'A - grave'], - ['Á', 'Á', true, 'A - acute'], - ['Â', 'Â', true, 'A - circumflex'], - ['Ã', 'Ã', true, 'A - tilde'], - ['Ä', 'Ä', true, 'A - diaeresis'], - ['Å', 'Å', true, 'A - ring above'], - ['Æ', 'Æ', true, 'ligature AE'], - ['Ç', 'Ç', true, 'C - cedilla'], - ['È', 'È', true, 'E - grave'], - ['É', 'É', true, 'E - acute'], - ['Ê', 'Ê', true, 'E - circumflex'], - ['Ë', 'Ë', true, 'E - diaeresis'], - ['Ì', 'Ì', true, 'I - grave'], - ['Í', 'Í', true, 'I - acute'], - ['Î', 'Î', true, 'I - circumflex'], - ['Ï', 'Ï', true, 'I - diaeresis'], - ['Ð', 'Ð', true, 'ETH'], - ['Ñ', 'Ñ', true, 'N - tilde'], - ['Ò', 'Ò', true, 'O - grave'], - ['Ó', 'Ó', true, 'O - acute'], - ['Ô', 'Ô', true, 'O - circumflex'], - ['Õ', 'Õ', true, 'O - tilde'], - ['Ö', 'Ö', true, 'O - diaeresis'], - ['Ø', 'Ø', true, 'O - slash'], - ['Œ', 'Œ', true, 'ligature OE'], - ['Š', 'Š', true, 'S - caron'], - ['Ù', 'Ù', true, 'U - grave'], - ['Ú', 'Ú', true, 'U - acute'], - ['Û', 'Û', true, 'U - circumflex'], - ['Ü', 'Ü', true, 'U - diaeresis'], - ['Ý', 'Ý', true, 'Y - acute'], - ['Ÿ', 'Ÿ', true, 'Y - diaeresis'], - ['Þ', 'Þ', true, 'THORN'], - ['à', 'à', true, 'a - grave'], - ['á', 'á', true, 'a - acute'], - ['â', 'â', true, 'a - circumflex'], - ['ã', 'ã', true, 'a - tilde'], - ['ä', 'ä', true, 'a - diaeresis'], - ['å', 'å', true, 'a - ring above'], - ['æ', 'æ', true, 'ligature ae'], - ['ç', 'ç', true, 'c - cedilla'], - ['è', 'è', true, 'e - grave'], - ['é', 'é', true, 'e - acute'], - ['ê', 'ê', true, 'e - circumflex'], - ['ë', 'ë', true, 'e - diaeresis'], - ['ì', 'ì', true, 'i - grave'], - ['í', 'í', true, 'i - acute'], - ['î', 'î', true, 'i - circumflex'], - ['ï', 'ï', true, 'i - diaeresis'], - ['ð', 'ð', true, 'eth'], - ['ñ', 'ñ', true, 'n - tilde'], - ['ò', 'ò', true, 'o - grave'], - ['ó', 'ó', true, 'o - acute'], - ['ô', 'ô', true, 'o - circumflex'], - ['õ', 'õ', true, 'o - tilde'], - ['ö', 'ö', true, 'o - diaeresis'], - ['ø', 'ø', true, 'o slash'], - ['œ', 'œ', true, 'ligature oe'], - ['š', 'š', true, 's - caron'], - ['ù', 'ù', true, 'u - grave'], - ['ú', 'ú', true, 'u - acute'], - ['û', 'û', true, 'u - circumflex'], - ['ü', 'ü', true, 'u - diaeresis'], - ['ý', 'ý', true, 'y - acute'], - ['þ', 'þ', true, 'thorn'], - ['ÿ', 'ÿ', true, 'y - diaeresis'], - ['Α', 'Α', true, 'Alpha'], - ['Β', 'Β', true, 'Beta'], - ['Γ', 'Γ', true, 'Gamma'], - ['Δ', 'Δ', true, 'Delta'], - ['Ε', 'Ε', true, 'Epsilon'], - ['Ζ', 'Ζ', true, 'Zeta'], - ['Η', 'Η', true, 'Eta'], - ['Θ', 'Θ', true, 'Theta'], - ['Ι', 'Ι', true, 'Iota'], - ['Κ', 'Κ', true, 'Kappa'], - ['Λ', 'Λ', true, 'Lambda'], - ['Μ', 'Μ', true, 'Mu'], - ['Ν', 'Ν', true, 'Nu'], - ['Ξ', 'Ξ', true, 'Xi'], - ['Ο', 'Ο', true, 'Omicron'], - ['Π', 'Π', true, 'Pi'], - ['Ρ', 'Ρ', true, 'Rho'], - ['Σ', 'Σ', true, 'Sigma'], - ['Τ', 'Τ', true, 'Tau'], - ['Υ', 'Υ', true, 'Upsilon'], - ['Φ', 'Φ', true, 'Phi'], - ['Χ', 'Χ', true, 'Chi'], - ['Ψ', 'Ψ', true, 'Psi'], - ['Ω', 'Ω', true, 'Omega'], - ['α', 'α', true, 'alpha'], - ['β', 'β', true, 'beta'], - ['γ', 'γ', true, 'gamma'], - ['δ', 'δ', true, 'delta'], - ['ε', 'ε', true, 'epsilon'], - ['ζ', 'ζ', true, 'zeta'], - ['η', 'η', true, 'eta'], - ['θ', 'θ', true, 'theta'], - ['ι', 'ι', true, 'iota'], - ['κ', 'κ', true, 'kappa'], - ['λ', 'λ', true, 'lambda'], - ['μ', 'μ', true, 'mu'], - ['ν', 'ν', true, 'nu'], - ['ξ', 'ξ', true, 'xi'], - ['ο', 'ο', true, 'omicron'], - ['π', 'π', true, 'pi'], - ['ρ', 'ρ', true, 'rho'], - ['ς', 'ς', true, 'final sigma'], - ['σ', 'σ', true, 'sigma'], - ['τ', 'τ', true, 'tau'], - ['υ', 'υ', true, 'upsilon'], - ['φ', 'φ', true, 'phi'], - ['χ', 'χ', true, 'chi'], - ['ψ', 'ψ', true, 'psi'], - ['ω', 'ω', true, 'omega'], -// symbols - ['ℵ', 'ℵ', false,'alef symbol'], - ['ϖ', 'ϖ', false,'pi symbol'], - ['ℜ', 'ℜ', false,'real part symbol'], - ['ϑ','ϑ', false,'theta symbol'], - ['ϒ', 'ϒ', false,'upsilon - hook symbol'], - ['℘', '℘', false,'Weierstrass p'], - ['ℑ', 'ℑ', false,'imaginary part'], -// arrows - ['←', '←', true, 'leftwards arrow'], - ['↑', '↑', true, 'upwards arrow'], - ['→', '→', true, 'rightwards arrow'], - ['↓', '↓', true, 'downwards arrow'], - ['↔', '↔', true, 'left right arrow'], - ['↵', '↵', false,'carriage return'], - ['⇐', '⇐', false,'leftwards double arrow'], - ['⇑', '⇑', false,'upwards double arrow'], - ['⇒', '⇒', false,'rightwards double arrow'], - ['⇓', '⇓', false,'downwards double arrow'], - ['⇔', '⇔', false,'left right double arrow'], - ['∴', '∴', false,'therefore'], - ['⊂', '⊂', false,'subset of'], - ['⊃', '⊃', false,'superset of'], - ['⊄', '⊄', false,'not a subset of'], - ['⊆', '⊆', false,'subset of or equal to'], - ['⊇', '⊇', false,'superset of or equal to'], - ['⊕', '⊕', false,'circled plus'], - ['⊗', '⊗', false,'circled times'], - ['⊥', '⊥', false,'perpendicular'], - ['⋅', '⋅', false,'dot operator'], - ['⌈', '⌈', false,'left ceiling'], - ['⌉', '⌉', false,'right ceiling'], - ['⌊', '⌊', false,'left floor'], - ['⌋', '⌋', false,'right floor'], - ['⟨', '〈', false,'left-pointing angle bracket'], - ['⟩', '〉', false,'right-pointing angle bracket'], - ['◊', '◊', true, 'lozenge'], - ['♠', '♠', true, 'black spade suit'], - ['♣', '♣', true, 'black club suit'], - ['♥', '♥', true, 'black heart suit'], - ['♦', '♦', true, 'black diamond suit'], - [' ', ' ', false,'en space'], - [' ', ' ', false,'em space'], - [' ', ' ', false,'thin space'], - ['‌', '‌', false,'zero width non-joiner'], - ['‍', '‍', false,'zero width joiner'], - ['‎', '‎', false,'left-to-right mark'], - ['‏', '‏', false,'right-to-left mark'], - ['­', '­', false,'soft hyphen'] -]; - -tinyMCEPopup.onInit.add(function() { - tinyMCEPopup.dom.setHTML('charmapView', renderCharMapHTML()); - addKeyboardNavigation(); -}); - -function addKeyboardNavigation(){ - var tableElm, cells, settings; - - cells = tinyMCEPopup.dom.select("a.charmaplink", "charmapgroup"); - - settings ={ - root: "charmapgroup", - items: cells - }; - cells[0].tabindex=0; - tinyMCEPopup.dom.addClass(cells[0], "mceFocus"); - if (tinymce.isGecko) { - cells[0].focus(); - } else { - setTimeout(function(){ - cells[0].focus(); - }, 100); - } - tinyMCEPopup.editor.windowManager.createInstance('tinymce.ui.KeyboardNavigation', settings, tinyMCEPopup.dom); -} - -function renderCharMapHTML() { - var charsPerRow = 20, tdWidth=20, tdHeight=20, i; - var html = '
            '+ - ''; - var cols=-1; - - for (i=0; i' - + '' - + charmap[i][1] - + ''; - if ((cols+1) % charsPerRow == 0) - html += ''; - } - } - - if (cols % charsPerRow > 0) { - var padd = charsPerRow - (cols % charsPerRow); - for (var i=0; i '; - } - - html += '
            '; - html = html.replace(/<\/tr>/g, ''); - - return html; -} - -function insertChar(chr) { - tinyMCEPopup.execCommand('mceInsertContent', false, '&#' + chr + ';'); - - // Refocus in window - if (tinyMCEPopup.isWindow) - window.focus(); - - tinyMCEPopup.editor.focus(); - tinyMCEPopup.close(); -} - -function previewChar(codeA, codeB, codeN) { - var elmA = document.getElementById('codeA'); - var elmB = document.getElementById('codeB'); - var elmV = document.getElementById('codeV'); - var elmN = document.getElementById('codeN'); - - if (codeA=='#160;') { - elmV.innerHTML = '__'; - } else { - elmV.innerHTML = '&' + codeA; - } - - elmB.innerHTML = '&' + codeA; - elmA.innerHTML = '&' + codeB; - elmN.innerHTML = codeN; -} +/** + * charmap.js + * + * Copyright 2009, Moxiecode Systems AB + * Released under LGPL License. + * + * License: http://tinymce.moxiecode.com/license + * Contributing: http://tinymce.moxiecode.com/contributing + */ + +tinyMCEPopup.requireLangPack(); + +var charmap = [ + [' ', ' ', true, 'no-break space'], + ['&', '&', true, 'ampersand'], + ['"', '"', true, 'quotation mark'], +// finance + ['¢', '¢', true, 'cent sign'], + ['€', '€', true, 'euro sign'], + ['£', '£', true, 'pound sign'], + ['¥', '¥', true, 'yen sign'], +// signs + ['©', '©', true, 'copyright sign'], + ['®', '®', true, 'registered sign'], + ['™', '™', true, 'trade mark sign'], + ['‰', '‰', true, 'per mille sign'], + ['µ', 'µ', true, 'micro sign'], + ['·', '·', true, 'middle dot'], + ['•', '•', true, 'bullet'], + ['…', '…', true, 'three dot leader'], + ['′', '′', true, 'minutes / feet'], + ['″', '″', true, 'seconds / inches'], + ['§', '§', true, 'section sign'], + ['¶', '¶', true, 'paragraph sign'], + ['ß', 'ß', true, 'sharp s / ess-zed'], +// quotations + ['‹', '‹', true, 'single left-pointing angle quotation mark'], + ['›', '›', true, 'single right-pointing angle quotation mark'], + ['«', '«', true, 'left pointing guillemet'], + ['»', '»', true, 'right pointing guillemet'], + ['‘', '‘', true, 'left single quotation mark'], + ['’', '’', true, 'right single quotation mark'], + ['“', '“', true, 'left double quotation mark'], + ['”', '”', true, 'right double quotation mark'], + ['‚', '‚', true, 'single low-9 quotation mark'], + ['„', '„', true, 'double low-9 quotation mark'], + ['<', '<', true, 'less-than sign'], + ['>', '>', true, 'greater-than sign'], + ['≤', '≤', true, 'less-than or equal to'], + ['≥', '≥', true, 'greater-than or equal to'], + ['–', '–', true, 'en dash'], + ['—', '—', true, 'em dash'], + ['¯', '¯', true, 'macron'], + ['‾', '‾', true, 'overline'], + ['¤', '¤', true, 'currency sign'], + ['¦', '¦', true, 'broken bar'], + ['¨', '¨', true, 'diaeresis'], + ['¡', '¡', true, 'inverted exclamation mark'], + ['¿', '¿', true, 'turned question mark'], + ['ˆ', 'ˆ', true, 'circumflex accent'], + ['˜', '˜', true, 'small tilde'], + ['°', '°', true, 'degree sign'], + ['−', '−', true, 'minus sign'], + ['±', '±', true, 'plus-minus sign'], + ['÷', '÷', true, 'division sign'], + ['⁄', '⁄', true, 'fraction slash'], + ['×', '×', true, 'multiplication sign'], + ['¹', '¹', true, 'superscript one'], + ['²', '²', true, 'superscript two'], + ['³', '³', true, 'superscript three'], + ['¼', '¼', true, 'fraction one quarter'], + ['½', '½', true, 'fraction one half'], + ['¾', '¾', true, 'fraction three quarters'], +// math / logical + ['ƒ', 'ƒ', true, 'function / florin'], + ['∫', '∫', true, 'integral'], + ['∑', '∑', true, 'n-ary sumation'], + ['∞', '∞', true, 'infinity'], + ['√', '√', true, 'square root'], + ['∼', '∼', false,'similar to'], + ['≅', '≅', false,'approximately equal to'], + ['≈', '≈', true, 'almost equal to'], + ['≠', '≠', true, 'not equal to'], + ['≡', '≡', true, 'identical to'], + ['∈', '∈', false,'element of'], + ['∉', '∉', false,'not an element of'], + ['∋', '∋', false,'contains as member'], + ['∏', '∏', true, 'n-ary product'], + ['∧', '∧', false,'logical and'], + ['∨', '∨', false,'logical or'], + ['¬', '¬', true, 'not sign'], + ['∩', '∩', true, 'intersection'], + ['∪', '∪', false,'union'], + ['∂', '∂', true, 'partial differential'], + ['∀', '∀', false,'for all'], + ['∃', '∃', false,'there exists'], + ['∅', '∅', false,'diameter'], + ['∇', '∇', false,'backward difference'], + ['∗', '∗', false,'asterisk operator'], + ['∝', '∝', false,'proportional to'], + ['∠', '∠', false,'angle'], +// undefined + ['´', '´', true, 'acute accent'], + ['¸', '¸', true, 'cedilla'], + ['ª', 'ª', true, 'feminine ordinal indicator'], + ['º', 'º', true, 'masculine ordinal indicator'], + ['†', '†', true, 'dagger'], + ['‡', '‡', true, 'double dagger'], +// alphabetical special chars + ['À', 'À', true, 'A - grave'], + ['Á', 'Á', true, 'A - acute'], + ['Â', 'Â', true, 'A - circumflex'], + ['Ã', 'Ã', true, 'A - tilde'], + ['Ä', 'Ä', true, 'A - diaeresis'], + ['Å', 'Å', true, 'A - ring above'], + ['Æ', 'Æ', true, 'ligature AE'], + ['Ç', 'Ç', true, 'C - cedilla'], + ['È', 'È', true, 'E - grave'], + ['É', 'É', true, 'E - acute'], + ['Ê', 'Ê', true, 'E - circumflex'], + ['Ë', 'Ë', true, 'E - diaeresis'], + ['Ì', 'Ì', true, 'I - grave'], + ['Í', 'Í', true, 'I - acute'], + ['Î', 'Î', true, 'I - circumflex'], + ['Ï', 'Ï', true, 'I - diaeresis'], + ['Ð', 'Ð', true, 'ETH'], + ['Ñ', 'Ñ', true, 'N - tilde'], + ['Ò', 'Ò', true, 'O - grave'], + ['Ó', 'Ó', true, 'O - acute'], + ['Ô', 'Ô', true, 'O - circumflex'], + ['Õ', 'Õ', true, 'O - tilde'], + ['Ö', 'Ö', true, 'O - diaeresis'], + ['Ø', 'Ø', true, 'O - slash'], + ['Œ', 'Œ', true, 'ligature OE'], + ['Š', 'Š', true, 'S - caron'], + ['Ù', 'Ù', true, 'U - grave'], + ['Ú', 'Ú', true, 'U - acute'], + ['Û', 'Û', true, 'U - circumflex'], + ['Ü', 'Ü', true, 'U - diaeresis'], + ['Ý', 'Ý', true, 'Y - acute'], + ['Ÿ', 'Ÿ', true, 'Y - diaeresis'], + ['Þ', 'Þ', true, 'THORN'], + ['à', 'à', true, 'a - grave'], + ['á', 'á', true, 'a - acute'], + ['â', 'â', true, 'a - circumflex'], + ['ã', 'ã', true, 'a - tilde'], + ['ä', 'ä', true, 'a - diaeresis'], + ['å', 'å', true, 'a - ring above'], + ['æ', 'æ', true, 'ligature ae'], + ['ç', 'ç', true, 'c - cedilla'], + ['è', 'è', true, 'e - grave'], + ['é', 'é', true, 'e - acute'], + ['ê', 'ê', true, 'e - circumflex'], + ['ë', 'ë', true, 'e - diaeresis'], + ['ì', 'ì', true, 'i - grave'], + ['í', 'í', true, 'i - acute'], + ['î', 'î', true, 'i - circumflex'], + ['ï', 'ï', true, 'i - diaeresis'], + ['ð', 'ð', true, 'eth'], + ['ñ', 'ñ', true, 'n - tilde'], + ['ò', 'ò', true, 'o - grave'], + ['ó', 'ó', true, 'o - acute'], + ['ô', 'ô', true, 'o - circumflex'], + ['õ', 'õ', true, 'o - tilde'], + ['ö', 'ö', true, 'o - diaeresis'], + ['ø', 'ø', true, 'o slash'], + ['œ', 'œ', true, 'ligature oe'], + ['š', 'š', true, 's - caron'], + ['ù', 'ù', true, 'u - grave'], + ['ú', 'ú', true, 'u - acute'], + ['û', 'û', true, 'u - circumflex'], + ['ü', 'ü', true, 'u - diaeresis'], + ['ý', 'ý', true, 'y - acute'], + ['þ', 'þ', true, 'thorn'], + ['ÿ', 'ÿ', true, 'y - diaeresis'], + ['Α', 'Α', true, 'Alpha'], + ['Β', 'Β', true, 'Beta'], + ['Γ', 'Γ', true, 'Gamma'], + ['Δ', 'Δ', true, 'Delta'], + ['Ε', 'Ε', true, 'Epsilon'], + ['Ζ', 'Ζ', true, 'Zeta'], + ['Η', 'Η', true, 'Eta'], + ['Θ', 'Θ', true, 'Theta'], + ['Ι', 'Ι', true, 'Iota'], + ['Κ', 'Κ', true, 'Kappa'], + ['Λ', 'Λ', true, 'Lambda'], + ['Μ', 'Μ', true, 'Mu'], + ['Ν', 'Ν', true, 'Nu'], + ['Ξ', 'Ξ', true, 'Xi'], + ['Ο', 'Ο', true, 'Omicron'], + ['Π', 'Π', true, 'Pi'], + ['Ρ', 'Ρ', true, 'Rho'], + ['Σ', 'Σ', true, 'Sigma'], + ['Τ', 'Τ', true, 'Tau'], + ['Υ', 'Υ', true, 'Upsilon'], + ['Φ', 'Φ', true, 'Phi'], + ['Χ', 'Χ', true, 'Chi'], + ['Ψ', 'Ψ', true, 'Psi'], + ['Ω', 'Ω', true, 'Omega'], + ['α', 'α', true, 'alpha'], + ['β', 'β', true, 'beta'], + ['γ', 'γ', true, 'gamma'], + ['δ', 'δ', true, 'delta'], + ['ε', 'ε', true, 'epsilon'], + ['ζ', 'ζ', true, 'zeta'], + ['η', 'η', true, 'eta'], + ['θ', 'θ', true, 'theta'], + ['ι', 'ι', true, 'iota'], + ['κ', 'κ', true, 'kappa'], + ['λ', 'λ', true, 'lambda'], + ['μ', 'μ', true, 'mu'], + ['ν', 'ν', true, 'nu'], + ['ξ', 'ξ', true, 'xi'], + ['ο', 'ο', true, 'omicron'], + ['π', 'π', true, 'pi'], + ['ρ', 'ρ', true, 'rho'], + ['ς', 'ς', true, 'final sigma'], + ['σ', 'σ', true, 'sigma'], + ['τ', 'τ', true, 'tau'], + ['υ', 'υ', true, 'upsilon'], + ['φ', 'φ', true, 'phi'], + ['χ', 'χ', true, 'chi'], + ['ψ', 'ψ', true, 'psi'], + ['ω', 'ω', true, 'omega'], +// symbols + ['ℵ', 'ℵ', false,'alef symbol'], + ['ϖ', 'ϖ', false,'pi symbol'], + ['ℜ', 'ℜ', false,'real part symbol'], + ['ϑ','ϑ', false,'theta symbol'], + ['ϒ', 'ϒ', false,'upsilon - hook symbol'], + ['℘', '℘', false,'Weierstrass p'], + ['ℑ', 'ℑ', false,'imaginary part'], +// arrows + ['←', '←', true, 'leftwards arrow'], + ['↑', '↑', true, 'upwards arrow'], + ['→', '→', true, 'rightwards arrow'], + ['↓', '↓', true, 'downwards arrow'], + ['↔', '↔', true, 'left right arrow'], + ['↵', '↵', false,'carriage return'], + ['⇐', '⇐', false,'leftwards double arrow'], + ['⇑', '⇑', false,'upwards double arrow'], + ['⇒', '⇒', false,'rightwards double arrow'], + ['⇓', '⇓', false,'downwards double arrow'], + ['⇔', '⇔', false,'left right double arrow'], + ['∴', '∴', false,'therefore'], + ['⊂', '⊂', false,'subset of'], + ['⊃', '⊃', false,'superset of'], + ['⊄', '⊄', false,'not a subset of'], + ['⊆', '⊆', false,'subset of or equal to'], + ['⊇', '⊇', false,'superset of or equal to'], + ['⊕', '⊕', false,'circled plus'], + ['⊗', '⊗', false,'circled times'], + ['⊥', '⊥', false,'perpendicular'], + ['⋅', '⋅', false,'dot operator'], + ['⌈', '⌈', false,'left ceiling'], + ['⌉', '⌉', false,'right ceiling'], + ['⌊', '⌊', false,'left floor'], + ['⌋', '⌋', false,'right floor'], + ['⟨', '〈', false,'left-pointing angle bracket'], + ['⟩', '〉', false,'right-pointing angle bracket'], + ['◊', '◊', true, 'lozenge'], + ['♠', '♠', true, 'black spade suit'], + ['♣', '♣', true, 'black club suit'], + ['♥', '♥', true, 'black heart suit'], + ['♦', '♦', true, 'black diamond suit'], + [' ', ' ', false,'en space'], + [' ', ' ', false,'em space'], + [' ', ' ', false,'thin space'], + ['‌', '‌', false,'zero width non-joiner'], + ['‍', '‍', false,'zero width joiner'], + ['‎', '‎', false,'left-to-right mark'], + ['‏', '‏', false,'right-to-left mark'], + ['­', '­', false,'soft hyphen'] +]; + +tinyMCEPopup.onInit.add(function() { + tinyMCEPopup.dom.setHTML('charmapView', renderCharMapHTML()); + addKeyboardNavigation(); +}); + +function addKeyboardNavigation(){ + var tableElm, cells, settings; + + cells = tinyMCEPopup.dom.select("a.charmaplink", "charmapgroup"); + + settings ={ + root: "charmapgroup", + items: cells + }; + cells[0].tabindex=0; + tinyMCEPopup.dom.addClass(cells[0], "mceFocus"); + if (tinymce.isGecko) { + cells[0].focus(); + } else { + setTimeout(function(){ + cells[0].focus(); + }, 100); + } + tinyMCEPopup.editor.windowManager.createInstance('tinymce.ui.KeyboardNavigation', settings, tinyMCEPopup.dom); +} + +function renderCharMapHTML() { + var charsPerRow = 20, tdWidth=20, tdHeight=20, i; + var html = '
            '+ + ''; + var cols=-1; + + for (i=0; i' + + '' + + charmap[i][1] + + ''; + if ((cols+1) % charsPerRow == 0) + html += ''; + } + } + + if (cols % charsPerRow > 0) { + var padd = charsPerRow - (cols % charsPerRow); + for (var i=0; i '; + } + + html += '
            '; + html = html.replace(/<\/tr>/g, ''); + + return html; +} + +function insertChar(chr) { + tinyMCEPopup.execCommand('mceInsertContent', false, '&#' + chr + ';'); + + // Refocus in window + if (tinyMCEPopup.isWindow) + window.focus(); + + tinyMCEPopup.editor.focus(); + tinyMCEPopup.close(); +} + +function previewChar(codeA, codeB, codeN) { + var elmA = document.getElementById('codeA'); + var elmB = document.getElementById('codeB'); + var elmV = document.getElementById('codeV'); + var elmN = document.getElementById('codeN'); + + if (codeA=='#160;') { + elmV.innerHTML = '__'; + } else { + elmV.innerHTML = '&' + codeA; + } + + elmB.innerHTML = '&' + codeA; + elmA.innerHTML = '&' + codeB; + elmN.innerHTML = codeN; +} diff --git a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/js/color_picker.js b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/js/color_picker.js index cc891c1..4ae53ab 100644 --- a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/js/color_picker.js +++ b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/js/color_picker.js @@ -1,345 +1,345 @@ -tinyMCEPopup.requireLangPack(); - -var detail = 50, strhex = "0123456789abcdef", i, isMouseDown = false, isMouseOver = false; - -var colors = [ - "#000000","#000033","#000066","#000099","#0000cc","#0000ff","#330000","#330033", - "#330066","#330099","#3300cc","#3300ff","#660000","#660033","#660066","#660099", - "#6600cc","#6600ff","#990000","#990033","#990066","#990099","#9900cc","#9900ff", - "#cc0000","#cc0033","#cc0066","#cc0099","#cc00cc","#cc00ff","#ff0000","#ff0033", - "#ff0066","#ff0099","#ff00cc","#ff00ff","#003300","#003333","#003366","#003399", - "#0033cc","#0033ff","#333300","#333333","#333366","#333399","#3333cc","#3333ff", - "#663300","#663333","#663366","#663399","#6633cc","#6633ff","#993300","#993333", - "#993366","#993399","#9933cc","#9933ff","#cc3300","#cc3333","#cc3366","#cc3399", - "#cc33cc","#cc33ff","#ff3300","#ff3333","#ff3366","#ff3399","#ff33cc","#ff33ff", - "#006600","#006633","#006666","#006699","#0066cc","#0066ff","#336600","#336633", - "#336666","#336699","#3366cc","#3366ff","#666600","#666633","#666666","#666699", - "#6666cc","#6666ff","#996600","#996633","#996666","#996699","#9966cc","#9966ff", - "#cc6600","#cc6633","#cc6666","#cc6699","#cc66cc","#cc66ff","#ff6600","#ff6633", - "#ff6666","#ff6699","#ff66cc","#ff66ff","#009900","#009933","#009966","#009999", - "#0099cc","#0099ff","#339900","#339933","#339966","#339999","#3399cc","#3399ff", - "#669900","#669933","#669966","#669999","#6699cc","#6699ff","#999900","#999933", - "#999966","#999999","#9999cc","#9999ff","#cc9900","#cc9933","#cc9966","#cc9999", - "#cc99cc","#cc99ff","#ff9900","#ff9933","#ff9966","#ff9999","#ff99cc","#ff99ff", - "#00cc00","#00cc33","#00cc66","#00cc99","#00cccc","#00ccff","#33cc00","#33cc33", - "#33cc66","#33cc99","#33cccc","#33ccff","#66cc00","#66cc33","#66cc66","#66cc99", - "#66cccc","#66ccff","#99cc00","#99cc33","#99cc66","#99cc99","#99cccc","#99ccff", - "#cccc00","#cccc33","#cccc66","#cccc99","#cccccc","#ccccff","#ffcc00","#ffcc33", - "#ffcc66","#ffcc99","#ffcccc","#ffccff","#00ff00","#00ff33","#00ff66","#00ff99", - "#00ffcc","#00ffff","#33ff00","#33ff33","#33ff66","#33ff99","#33ffcc","#33ffff", - "#66ff00","#66ff33","#66ff66","#66ff99","#66ffcc","#66ffff","#99ff00","#99ff33", - "#99ff66","#99ff99","#99ffcc","#99ffff","#ccff00","#ccff33","#ccff66","#ccff99", - "#ccffcc","#ccffff","#ffff00","#ffff33","#ffff66","#ffff99","#ffffcc","#ffffff" -]; - -var named = { - '#F0F8FF':'Alice Blue','#FAEBD7':'Antique White','#00FFFF':'Aqua','#7FFFD4':'Aquamarine','#F0FFFF':'Azure','#F5F5DC':'Beige', - '#FFE4C4':'Bisque','#000000':'Black','#FFEBCD':'Blanched Almond','#0000FF':'Blue','#8A2BE2':'Blue Violet','#A52A2A':'Brown', - '#DEB887':'Burly Wood','#5F9EA0':'Cadet Blue','#7FFF00':'Chartreuse','#D2691E':'Chocolate','#FF7F50':'Coral','#6495ED':'Cornflower Blue', - '#FFF8DC':'Cornsilk','#DC143C':'Crimson','#00FFFF':'Cyan','#00008B':'Dark Blue','#008B8B':'Dark Cyan','#B8860B':'Dark Golden Rod', - '#A9A9A9':'Dark Gray','#A9A9A9':'Dark Grey','#006400':'Dark Green','#BDB76B':'Dark Khaki','#8B008B':'Dark Magenta','#556B2F':'Dark Olive Green', - '#FF8C00':'Darkorange','#9932CC':'Dark Orchid','#8B0000':'Dark Red','#E9967A':'Dark Salmon','#8FBC8F':'Dark Sea Green','#483D8B':'Dark Slate Blue', - '#2F4F4F':'Dark Slate Gray','#2F4F4F':'Dark Slate Grey','#00CED1':'Dark Turquoise','#9400D3':'Dark Violet','#FF1493':'Deep Pink','#00BFFF':'Deep Sky Blue', - '#696969':'Dim Gray','#696969':'Dim Grey','#1E90FF':'Dodger Blue','#B22222':'Fire Brick','#FFFAF0':'Floral White','#228B22':'Forest Green', - '#FF00FF':'Fuchsia','#DCDCDC':'Gainsboro','#F8F8FF':'Ghost White','#FFD700':'Gold','#DAA520':'Golden Rod','#808080':'Gray','#808080':'Grey', - '#008000':'Green','#ADFF2F':'Green Yellow','#F0FFF0':'Honey Dew','#FF69B4':'Hot Pink','#CD5C5C':'Indian Red','#4B0082':'Indigo','#FFFFF0':'Ivory', - '#F0E68C':'Khaki','#E6E6FA':'Lavender','#FFF0F5':'Lavender Blush','#7CFC00':'Lawn Green','#FFFACD':'Lemon Chiffon','#ADD8E6':'Light Blue', - '#F08080':'Light Coral','#E0FFFF':'Light Cyan','#FAFAD2':'Light Golden Rod Yellow','#D3D3D3':'Light Gray','#D3D3D3':'Light Grey','#90EE90':'Light Green', - '#FFB6C1':'Light Pink','#FFA07A':'Light Salmon','#20B2AA':'Light Sea Green','#87CEFA':'Light Sky Blue','#778899':'Light Slate Gray','#778899':'Light Slate Grey', - '#B0C4DE':'Light Steel Blue','#FFFFE0':'Light Yellow','#00FF00':'Lime','#32CD32':'Lime Green','#FAF0E6':'Linen','#FF00FF':'Magenta','#800000':'Maroon', - '#66CDAA':'Medium Aqua Marine','#0000CD':'Medium Blue','#BA55D3':'Medium Orchid','#9370D8':'Medium Purple','#3CB371':'Medium Sea Green','#7B68EE':'Medium Slate Blue', - '#00FA9A':'Medium Spring Green','#48D1CC':'Medium Turquoise','#C71585':'Medium Violet Red','#191970':'Midnight Blue','#F5FFFA':'Mint Cream','#FFE4E1':'Misty Rose','#FFE4B5':'Moccasin', - '#FFDEAD':'Navajo White','#000080':'Navy','#FDF5E6':'Old Lace','#808000':'Olive','#6B8E23':'Olive Drab','#FFA500':'Orange','#FF4500':'Orange Red','#DA70D6':'Orchid', - '#EEE8AA':'Pale Golden Rod','#98FB98':'Pale Green','#AFEEEE':'Pale Turquoise','#D87093':'Pale Violet Red','#FFEFD5':'Papaya Whip','#FFDAB9':'Peach Puff', - '#CD853F':'Peru','#FFC0CB':'Pink','#DDA0DD':'Plum','#B0E0E6':'Powder Blue','#800080':'Purple','#FF0000':'Red','#BC8F8F':'Rosy Brown','#4169E1':'Royal Blue', - '#8B4513':'Saddle Brown','#FA8072':'Salmon','#F4A460':'Sandy Brown','#2E8B57':'Sea Green','#FFF5EE':'Sea Shell','#A0522D':'Sienna','#C0C0C0':'Silver', - '#87CEEB':'Sky Blue','#6A5ACD':'Slate Blue','#708090':'Slate Gray','#708090':'Slate Grey','#FFFAFA':'Snow','#00FF7F':'Spring Green', - '#4682B4':'Steel Blue','#D2B48C':'Tan','#008080':'Teal','#D8BFD8':'Thistle','#FF6347':'Tomato','#40E0D0':'Turquoise','#EE82EE':'Violet', - '#F5DEB3':'Wheat','#FFFFFF':'White','#F5F5F5':'White Smoke','#FFFF00':'Yellow','#9ACD32':'Yellow Green' -}; - -var namedLookup = {}; - -function init() { - var inputColor = convertRGBToHex(tinyMCEPopup.getWindowArg('input_color')), key, value; - - tinyMCEPopup.resizeToInnerSize(); - - generatePicker(); - generateWebColors(); - generateNamedColors(); - - if (inputColor) { - changeFinalColor(inputColor); - - col = convertHexToRGB(inputColor); - - if (col) - updateLight(col.r, col.g, col.b); - } - - for (key in named) { - value = named[key]; - namedLookup[value.replace(/\s+/, '').toLowerCase()] = key.replace(/#/, '').toLowerCase(); - } -} - -function toHexColor(color) { - var matches, red, green, blue, toInt = parseInt; - - function hex(value) { - value = parseInt(value).toString(16); - - return value.length > 1 ? value : '0' + value; // Padd with leading zero - }; - - color = tinymce.trim(color); - color = color.replace(/^[#]/, '').toLowerCase(); // remove leading '#' - color = namedLookup[color] || color; - - matches = /^rgb\((\d{1,3}),(\d{1,3}),(\d{1,3})\)$/.exec(color); - - if (matches) { - red = toInt(matches[1]); - green = toInt(matches[2]); - blue = toInt(matches[3]); - } else { - matches = /^([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/.exec(color); - - if (matches) { - red = toInt(matches[1], 16); - green = toInt(matches[2], 16); - blue = toInt(matches[3], 16); - } else { - matches = /^([0-9a-f])([0-9a-f])([0-9a-f])$/.exec(color); - - if (matches) { - red = toInt(matches[1] + matches[1], 16); - green = toInt(matches[2] + matches[2], 16); - blue = toInt(matches[3] + matches[3], 16); - } else { - return ''; - } - } - } - - return '#' + hex(red) + hex(green) + hex(blue); -} - -function insertAction() { - var color = document.getElementById("color").value, f = tinyMCEPopup.getWindowArg('func'); - - var hexColor = toHexColor(color); - - if (hexColor === '') { - var text = tinyMCEPopup.editor.getLang('advanced_dlg.invalid_color_value'); - tinyMCEPopup.alert(text + ': ' + color); - } - else { - tinyMCEPopup.restoreSelection(); - - if (f) - f(hexColor); - - tinyMCEPopup.close(); - } -} - -function showColor(color, name) { - if (name) - document.getElementById("colorname").innerHTML = name; - - document.getElementById("preview").style.backgroundColor = color; - document.getElementById("color").value = color.toUpperCase(); -} - -function convertRGBToHex(col) { - var re = new RegExp("rgb\\s*\\(\\s*([0-9]+).*,\\s*([0-9]+).*,\\s*([0-9]+).*\\)", "gi"); - - if (!col) - return col; - - var rgb = col.replace(re, "$1,$2,$3").split(','); - if (rgb.length == 3) { - r = parseInt(rgb[0]).toString(16); - g = parseInt(rgb[1]).toString(16); - b = parseInt(rgb[2]).toString(16); - - r = r.length == 1 ? '0' + r : r; - g = g.length == 1 ? '0' + g : g; - b = b.length == 1 ? '0' + b : b; - - return "#" + r + g + b; - } - - return col; -} - -function convertHexToRGB(col) { - if (col.indexOf('#') != -1) { - col = col.replace(new RegExp('[^0-9A-F]', 'gi'), ''); - - r = parseInt(col.substring(0, 2), 16); - g = parseInt(col.substring(2, 4), 16); - b = parseInt(col.substring(4, 6), 16); - - return {r : r, g : g, b : b}; - } - - return null; -} - -function generatePicker() { - var el = document.getElementById('light'), h = '', i; - - for (i = 0; i < detail; i++){ - h += '
            '; - } - - el.innerHTML = h; -} - -function generateWebColors() { - var el = document.getElementById('webcolors'), h = '', i; - - if (el.className == 'generated') - return; - - // TODO: VoiceOver doesn't seem to support legend as a label referenced by labelledby. - h += '
            ' - + ''; - - for (i=0; i' - + ''; - if (tinyMCEPopup.editor.forcedHighContrastMode) { - h += ''; - } - h += ''; - h += ''; - if ((i+1) % 18 == 0) - h += ''; - } - - h += '
            '; - - el.innerHTML = h; - el.className = 'generated'; - - paintCanvas(el); - enableKeyboardNavigation(el.firstChild); -} - -function paintCanvas(el) { - tinyMCEPopup.getWin().tinymce.each(tinyMCEPopup.dom.select('canvas.mceColorSwatch', el), function(canvas) { - var context; - if (canvas.getContext && (context = canvas.getContext("2d"))) { - context.fillStyle = canvas.getAttribute('data-color'); - context.fillRect(0, 0, 10, 10); - } - }); -} -function generateNamedColors() { - var el = document.getElementById('namedcolors'), h = '', n, v, i = 0; - - if (el.className == 'generated') - return; - - for (n in named) { - v = named[n]; - h += ''; - if (tinyMCEPopup.editor.forcedHighContrastMode) { - h += ''; - } - h += ''; - h += ''; - i++; - } - - el.innerHTML = h; - el.className = 'generated'; - - paintCanvas(el); - enableKeyboardNavigation(el); -} - -function enableKeyboardNavigation(el) { - tinyMCEPopup.editor.windowManager.createInstance('tinymce.ui.KeyboardNavigation', { - root: el, - items: tinyMCEPopup.dom.select('a', el) - }, tinyMCEPopup.dom); -} - -function dechex(n) { - return strhex.charAt(Math.floor(n / 16)) + strhex.charAt(n % 16); -} - -function computeColor(e) { - var x, y, partWidth, partDetail, imHeight, r, g, b, coef, i, finalCoef, finalR, finalG, finalB, pos = tinyMCEPopup.dom.getPos(e.target); - - x = e.offsetX ? e.offsetX : (e.target ? e.clientX - pos.x : 0); - y = e.offsetY ? e.offsetY : (e.target ? e.clientY - pos.y : 0); - - partWidth = document.getElementById('colors').width / 6; - partDetail = detail / 2; - imHeight = document.getElementById('colors').height; - - r = (x >= 0)*(x < partWidth)*255 + (x >= partWidth)*(x < 2*partWidth)*(2*255 - x * 255 / partWidth) + (x >= 4*partWidth)*(x < 5*partWidth)*(-4*255 + x * 255 / partWidth) + (x >= 5*partWidth)*(x < 6*partWidth)*255; - g = (x >= 0)*(x < partWidth)*(x * 255 / partWidth) + (x >= partWidth)*(x < 3*partWidth)*255 + (x >= 3*partWidth)*(x < 4*partWidth)*(4*255 - x * 255 / partWidth); - b = (x >= 2*partWidth)*(x < 3*partWidth)*(-2*255 + x * 255 / partWidth) + (x >= 3*partWidth)*(x < 5*partWidth)*255 + (x >= 5*partWidth)*(x < 6*partWidth)*(6*255 - x * 255 / partWidth); - - coef = (imHeight - y) / imHeight; - r = 128 + (r - 128) * coef; - g = 128 + (g - 128) * coef; - b = 128 + (b - 128) * coef; - - changeFinalColor('#' + dechex(r) + dechex(g) + dechex(b)); - updateLight(r, g, b); -} - -function updateLight(r, g, b) { - var i, partDetail = detail / 2, finalCoef, finalR, finalG, finalB, color; - - for (i=0; i=0) && (i 1 ? value : '0' + value; // Padd with leading zero + }; + + color = tinymce.trim(color); + color = color.replace(/^[#]/, '').toLowerCase(); // remove leading '#' + color = namedLookup[color] || color; + + matches = /^rgb\((\d{1,3}),(\d{1,3}),(\d{1,3})\)$/.exec(color); + + if (matches) { + red = toInt(matches[1]); + green = toInt(matches[2]); + blue = toInt(matches[3]); + } else { + matches = /^([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/.exec(color); + + if (matches) { + red = toInt(matches[1], 16); + green = toInt(matches[2], 16); + blue = toInt(matches[3], 16); + } else { + matches = /^([0-9a-f])([0-9a-f])([0-9a-f])$/.exec(color); + + if (matches) { + red = toInt(matches[1] + matches[1], 16); + green = toInt(matches[2] + matches[2], 16); + blue = toInt(matches[3] + matches[3], 16); + } else { + return ''; + } + } + } + + return '#' + hex(red) + hex(green) + hex(blue); +} + +function insertAction() { + var color = document.getElementById("color").value, f = tinyMCEPopup.getWindowArg('func'); + + var hexColor = toHexColor(color); + + if (hexColor === '') { + var text = tinyMCEPopup.editor.getLang('advanced_dlg.invalid_color_value'); + tinyMCEPopup.alert(text + ': ' + color); + } + else { + tinyMCEPopup.restoreSelection(); + + if (f) + f(hexColor); + + tinyMCEPopup.close(); + } +} + +function showColor(color, name) { + if (name) + document.getElementById("colorname").innerHTML = name; + + document.getElementById("preview").style.backgroundColor = color; + document.getElementById("color").value = color.toUpperCase(); +} + +function convertRGBToHex(col) { + var re = new RegExp("rgb\\s*\\(\\s*([0-9]+).*,\\s*([0-9]+).*,\\s*([0-9]+).*\\)", "gi"); + + if (!col) + return col; + + var rgb = col.replace(re, "$1,$2,$3").split(','); + if (rgb.length == 3) { + r = parseInt(rgb[0]).toString(16); + g = parseInt(rgb[1]).toString(16); + b = parseInt(rgb[2]).toString(16); + + r = r.length == 1 ? '0' + r : r; + g = g.length == 1 ? '0' + g : g; + b = b.length == 1 ? '0' + b : b; + + return "#" + r + g + b; + } + + return col; +} + +function convertHexToRGB(col) { + if (col.indexOf('#') != -1) { + col = col.replace(new RegExp('[^0-9A-F]', 'gi'), ''); + + r = parseInt(col.substring(0, 2), 16); + g = parseInt(col.substring(2, 4), 16); + b = parseInt(col.substring(4, 6), 16); + + return {r : r, g : g, b : b}; + } + + return null; +} + +function generatePicker() { + var el = document.getElementById('light'), h = '', i; + + for (i = 0; i < detail; i++){ + h += '
            '; + } + + el.innerHTML = h; +} + +function generateWebColors() { + var el = document.getElementById('webcolors'), h = '', i; + + if (el.className == 'generated') + return; + + // TODO: VoiceOver doesn't seem to support legend as a label referenced by labelledby. + h += '
            ' + + ''; + + for (i=0; i' + + ''; + if (tinyMCEPopup.editor.forcedHighContrastMode) { + h += ''; + } + h += ''; + h += ''; + if ((i+1) % 18 == 0) + h += ''; + } + + h += '
            '; + + el.innerHTML = h; + el.className = 'generated'; + + paintCanvas(el); + enableKeyboardNavigation(el.firstChild); +} + +function paintCanvas(el) { + tinyMCEPopup.getWin().tinymce.each(tinyMCEPopup.dom.select('canvas.mceColorSwatch', el), function(canvas) { + var context; + if (canvas.getContext && (context = canvas.getContext("2d"))) { + context.fillStyle = canvas.getAttribute('data-color'); + context.fillRect(0, 0, 10, 10); + } + }); +} +function generateNamedColors() { + var el = document.getElementById('namedcolors'), h = '', n, v, i = 0; + + if (el.className == 'generated') + return; + + for (n in named) { + v = named[n]; + h += ''; + if (tinyMCEPopup.editor.forcedHighContrastMode) { + h += ''; + } + h += ''; + h += ''; + i++; + } + + el.innerHTML = h; + el.className = 'generated'; + + paintCanvas(el); + enableKeyboardNavigation(el); +} + +function enableKeyboardNavigation(el) { + tinyMCEPopup.editor.windowManager.createInstance('tinymce.ui.KeyboardNavigation', { + root: el, + items: tinyMCEPopup.dom.select('a', el) + }, tinyMCEPopup.dom); +} + +function dechex(n) { + return strhex.charAt(Math.floor(n / 16)) + strhex.charAt(n % 16); +} + +function computeColor(e) { + var x, y, partWidth, partDetail, imHeight, r, g, b, coef, i, finalCoef, finalR, finalG, finalB, pos = tinyMCEPopup.dom.getPos(e.target); + + x = e.offsetX ? e.offsetX : (e.target ? e.clientX - pos.x : 0); + y = e.offsetY ? e.offsetY : (e.target ? e.clientY - pos.y : 0); + + partWidth = document.getElementById('colors').width / 6; + partDetail = detail / 2; + imHeight = document.getElementById('colors').height; + + r = (x >= 0)*(x < partWidth)*255 + (x >= partWidth)*(x < 2*partWidth)*(2*255 - x * 255 / partWidth) + (x >= 4*partWidth)*(x < 5*partWidth)*(-4*255 + x * 255 / partWidth) + (x >= 5*partWidth)*(x < 6*partWidth)*255; + g = (x >= 0)*(x < partWidth)*(x * 255 / partWidth) + (x >= partWidth)*(x < 3*partWidth)*255 + (x >= 3*partWidth)*(x < 4*partWidth)*(4*255 - x * 255 / partWidth); + b = (x >= 2*partWidth)*(x < 3*partWidth)*(-2*255 + x * 255 / partWidth) + (x >= 3*partWidth)*(x < 5*partWidth)*255 + (x >= 5*partWidth)*(x < 6*partWidth)*(6*255 - x * 255 / partWidth); + + coef = (imHeight - y) / imHeight; + r = 128 + (r - 128) * coef; + g = 128 + (g - 128) * coef; + b = 128 + (b - 128) * coef; + + changeFinalColor('#' + dechex(r) + dechex(g) + dechex(b)); + updateLight(r, g, b); +} + +function updateLight(r, g, b) { + var i, partDetail = detail / 2, finalCoef, finalR, finalG, finalB, color; + + for (i=0; i=0) && (i'); - }, - - init : function() { - var f = document.forms[0], ed = tinyMCEPopup.editor; - - // Setup browse button - document.getElementById('srcbrowsercontainer').innerHTML = getBrowserHTML('srcbrowser','src','image','theme_advanced_image'); - if (isVisible('srcbrowser')) - document.getElementById('src').style.width = '180px'; - - e = ed.selection.getNode(); - - this.fillFileList('image_list', tinyMCEPopup.getParam('external_image_list', 'tinyMCEImageList')); - - if (e.nodeName == 'IMG') { - f.src.value = ed.dom.getAttrib(e, 'src'); - f.alt.value = ed.dom.getAttrib(e, 'alt'); - f.border.value = this.getAttrib(e, 'border'); - f.vspace.value = this.getAttrib(e, 'vspace'); - f.hspace.value = this.getAttrib(e, 'hspace'); - f.width.value = ed.dom.getAttrib(e, 'width'); - f.height.value = ed.dom.getAttrib(e, 'height'); - f.insert.value = ed.getLang('update'); - this.styleVal = ed.dom.getAttrib(e, 'style'); - selectByValue(f, 'image_list', f.src.value); - selectByValue(f, 'align', this.getAttrib(e, 'align')); - this.updateStyle(); - } - }, - - fillFileList : function(id, l) { - var dom = tinyMCEPopup.dom, lst = dom.get(id), v, cl; - - l = typeof(l) === 'function' ? l() : window[l]; - - if (l && l.length > 0) { - lst.options[lst.options.length] = new Option('', ''); - - tinymce.each(l, function(o) { - lst.options[lst.options.length] = new Option(o[0], o[1]); - }); - } else - dom.remove(dom.getParent(id, 'tr')); - }, - - update : function() { - var f = document.forms[0], nl = f.elements, ed = tinyMCEPopup.editor, args = {}, el; - - tinyMCEPopup.restoreSelection(); - - if (f.src.value === '') { - if (ed.selection.getNode().nodeName == 'IMG') { - ed.dom.remove(ed.selection.getNode()); - ed.execCommand('mceRepaint'); - } - - tinyMCEPopup.close(); - return; - } - - if (!ed.settings.inline_styles) { - args = tinymce.extend(args, { - vspace : nl.vspace.value, - hspace : nl.hspace.value, - border : nl.border.value, - align : getSelectValue(f, 'align') - }); - } else - args.style = this.styleVal; - - tinymce.extend(args, { - src : f.src.value.replace(/ /g, '%20'), - alt : f.alt.value, - width : f.width.value, - height : f.height.value - }); - - el = ed.selection.getNode(); - - if (el && el.nodeName == 'IMG') { - ed.dom.setAttribs(el, args); - tinyMCEPopup.editor.execCommand('mceRepaint'); - tinyMCEPopup.editor.focus(); - } else { - tinymce.each(args, function(value, name) { - if (value === "") { - delete args[name]; - } - }); - - ed.execCommand('mceInsertContent', false, tinyMCEPopup.editor.dom.createHTML('img', args), {skip_undo : 1}); - ed.undoManager.add(); - } - - tinyMCEPopup.close(); - }, - - updateStyle : function() { - var dom = tinyMCEPopup.dom, st = {}, v, f = document.forms[0]; - - if (tinyMCEPopup.editor.settings.inline_styles) { - tinymce.each(tinyMCEPopup.dom.parseStyle(this.styleVal), function(value, key) { - st[key] = value; - }); - - // Handle align - v = getSelectValue(f, 'align'); - if (v) { - if (v == 'left' || v == 'right') { - st['float'] = v; - delete st['vertical-align']; - } else { - st['vertical-align'] = v; - delete st['float']; - } - } else { - delete st['float']; - delete st['vertical-align']; - } - - // Handle border - v = f.border.value; - if (v || v == '0') { - if (v == '0') - st['border'] = '0'; - else - st['border'] = v + 'px solid black'; - } else - delete st['border']; - - // Handle hspace - v = f.hspace.value; - if (v) { - delete st['margin']; - st['margin-left'] = v + 'px'; - st['margin-right'] = v + 'px'; - } else { - delete st['margin-left']; - delete st['margin-right']; - } - - // Handle vspace - v = f.vspace.value; - if (v) { - delete st['margin']; - st['margin-top'] = v + 'px'; - st['margin-bottom'] = v + 'px'; - } else { - delete st['margin-top']; - delete st['margin-bottom']; - } - - // Merge - st = tinyMCEPopup.dom.parseStyle(dom.serializeStyle(st), 'img'); - this.styleVal = dom.serializeStyle(st, 'img'); - } - }, - - getAttrib : function(e, at) { - var ed = tinyMCEPopup.editor, dom = ed.dom, v, v2; - - if (ed.settings.inline_styles) { - switch (at) { - case 'align': - if (v = dom.getStyle(e, 'float')) - return v; - - if (v = dom.getStyle(e, 'vertical-align')) - return v; - - break; - - case 'hspace': - v = dom.getStyle(e, 'margin-left') - v2 = dom.getStyle(e, 'margin-right'); - if (v && v == v2) - return parseInt(v.replace(/[^0-9]/g, '')); - - break; - - case 'vspace': - v = dom.getStyle(e, 'margin-top') - v2 = dom.getStyle(e, 'margin-bottom'); - if (v && v == v2) - return parseInt(v.replace(/[^0-9]/g, '')); - - break; - - case 'border': - v = 0; - - tinymce.each(['top', 'right', 'bottom', 'left'], function(sv) { - sv = dom.getStyle(e, 'border-' + sv + '-width'); - - // False or not the same as prev - if (!sv || (sv != v && v !== 0)) { - v = 0; - return false; - } - - if (sv) - v = sv; - }); - - if (v) - return parseInt(v.replace(/[^0-9]/g, '')); - - break; - } - } - - if (v = dom.getAttrib(e, at)) - return v; - - return ''; - }, - - resetImageData : function() { - var f = document.forms[0]; - - f.width.value = f.height.value = ""; - }, - - updateImageData : function() { - var f = document.forms[0], t = ImageDialog; - - if (f.width.value == "") - f.width.value = t.preloadImg.width; - - if (f.height.value == "") - f.height.value = t.preloadImg.height; - }, - - getImageData : function() { - var f = document.forms[0]; - - this.preloadImg = new Image(); - this.preloadImg.onload = this.updateImageData; - this.preloadImg.onerror = this.resetImageData; - this.preloadImg.src = tinyMCEPopup.editor.documentBaseURI.toAbsolute(f.src.value); - } -}; - -ImageDialog.preInit(); -tinyMCEPopup.onInit.add(ImageDialog.init, ImageDialog); +var ImageDialog = { + preInit : function() { + var url; + + tinyMCEPopup.requireLangPack(); + + if (url = tinyMCEPopup.getParam("external_image_list_url")) + document.write(''); + }, + + init : function() { + var f = document.forms[0], ed = tinyMCEPopup.editor; + + // Setup browse button + document.getElementById('srcbrowsercontainer').innerHTML = getBrowserHTML('srcbrowser','src','image','theme_advanced_image'); + if (isVisible('srcbrowser')) + document.getElementById('src').style.width = '180px'; + + e = ed.selection.getNode(); + + this.fillFileList('image_list', tinyMCEPopup.getParam('external_image_list', 'tinyMCEImageList')); + + if (e.nodeName == 'IMG') { + f.src.value = ed.dom.getAttrib(e, 'src'); + f.alt.value = ed.dom.getAttrib(e, 'alt'); + f.border.value = this.getAttrib(e, 'border'); + f.vspace.value = this.getAttrib(e, 'vspace'); + f.hspace.value = this.getAttrib(e, 'hspace'); + f.width.value = ed.dom.getAttrib(e, 'width'); + f.height.value = ed.dom.getAttrib(e, 'height'); + f.insert.value = ed.getLang('update'); + this.styleVal = ed.dom.getAttrib(e, 'style'); + selectByValue(f, 'image_list', f.src.value); + selectByValue(f, 'align', this.getAttrib(e, 'align')); + this.updateStyle(); + } + }, + + fillFileList : function(id, l) { + var dom = tinyMCEPopup.dom, lst = dom.get(id), v, cl; + + l = typeof(l) === 'function' ? l() : window[l]; + + if (l && l.length > 0) { + lst.options[lst.options.length] = new Option('', ''); + + tinymce.each(l, function(o) { + lst.options[lst.options.length] = new Option(o[0], o[1]); + }); + } else + dom.remove(dom.getParent(id, 'tr')); + }, + + update : function() { + var f = document.forms[0], nl = f.elements, ed = tinyMCEPopup.editor, args = {}, el; + + tinyMCEPopup.restoreSelection(); + + if (f.src.value === '') { + if (ed.selection.getNode().nodeName == 'IMG') { + ed.dom.remove(ed.selection.getNode()); + ed.execCommand('mceRepaint'); + } + + tinyMCEPopup.close(); + return; + } + + if (!ed.settings.inline_styles) { + args = tinymce.extend(args, { + vspace : nl.vspace.value, + hspace : nl.hspace.value, + border : nl.border.value, + align : getSelectValue(f, 'align') + }); + } else + args.style = this.styleVal; + + tinymce.extend(args, { + src : f.src.value.replace(/ /g, '%20'), + alt : f.alt.value, + width : f.width.value, + height : f.height.value + }); + + el = ed.selection.getNode(); + + if (el && el.nodeName == 'IMG') { + ed.dom.setAttribs(el, args); + tinyMCEPopup.editor.execCommand('mceRepaint'); + tinyMCEPopup.editor.focus(); + } else { + tinymce.each(args, function(value, name) { + if (value === "") { + delete args[name]; + } + }); + + ed.execCommand('mceInsertContent', false, tinyMCEPopup.editor.dom.createHTML('img', args), {skip_undo : 1}); + ed.undoManager.add(); + } + + tinyMCEPopup.close(); + }, + + updateStyle : function() { + var dom = tinyMCEPopup.dom, st = {}, v, f = document.forms[0]; + + if (tinyMCEPopup.editor.settings.inline_styles) { + tinymce.each(tinyMCEPopup.dom.parseStyle(this.styleVal), function(value, key) { + st[key] = value; + }); + + // Handle align + v = getSelectValue(f, 'align'); + if (v) { + if (v == 'left' || v == 'right') { + st['float'] = v; + delete st['vertical-align']; + } else { + st['vertical-align'] = v; + delete st['float']; + } + } else { + delete st['float']; + delete st['vertical-align']; + } + + // Handle border + v = f.border.value; + if (v || v == '0') { + if (v == '0') + st['border'] = '0'; + else + st['border'] = v + 'px solid black'; + } else + delete st['border']; + + // Handle hspace + v = f.hspace.value; + if (v) { + delete st['margin']; + st['margin-left'] = v + 'px'; + st['margin-right'] = v + 'px'; + } else { + delete st['margin-left']; + delete st['margin-right']; + } + + // Handle vspace + v = f.vspace.value; + if (v) { + delete st['margin']; + st['margin-top'] = v + 'px'; + st['margin-bottom'] = v + 'px'; + } else { + delete st['margin-top']; + delete st['margin-bottom']; + } + + // Merge + st = tinyMCEPopup.dom.parseStyle(dom.serializeStyle(st), 'img'); + this.styleVal = dom.serializeStyle(st, 'img'); + } + }, + + getAttrib : function(e, at) { + var ed = tinyMCEPopup.editor, dom = ed.dom, v, v2; + + if (ed.settings.inline_styles) { + switch (at) { + case 'align': + if (v = dom.getStyle(e, 'float')) + return v; + + if (v = dom.getStyle(e, 'vertical-align')) + return v; + + break; + + case 'hspace': + v = dom.getStyle(e, 'margin-left') + v2 = dom.getStyle(e, 'margin-right'); + if (v && v == v2) + return parseInt(v.replace(/[^0-9]/g, '')); + + break; + + case 'vspace': + v = dom.getStyle(e, 'margin-top') + v2 = dom.getStyle(e, 'margin-bottom'); + if (v && v == v2) + return parseInt(v.replace(/[^0-9]/g, '')); + + break; + + case 'border': + v = 0; + + tinymce.each(['top', 'right', 'bottom', 'left'], function(sv) { + sv = dom.getStyle(e, 'border-' + sv + '-width'); + + // False or not the same as prev + if (!sv || (sv != v && v !== 0)) { + v = 0; + return false; + } + + if (sv) + v = sv; + }); + + if (v) + return parseInt(v.replace(/[^0-9]/g, '')); + + break; + } + } + + if (v = dom.getAttrib(e, at)) + return v; + + return ''; + }, + + resetImageData : function() { + var f = document.forms[0]; + + f.width.value = f.height.value = ""; + }, + + updateImageData : function() { + var f = document.forms[0], t = ImageDialog; + + if (f.width.value == "") + f.width.value = t.preloadImg.width; + + if (f.height.value == "") + f.height.value = t.preloadImg.height; + }, + + getImageData : function() { + var f = document.forms[0]; + + this.preloadImg = new Image(); + this.preloadImg.onload = this.updateImageData; + this.preloadImg.onerror = this.resetImageData; + this.preloadImg.src = tinyMCEPopup.editor.documentBaseURI.toAbsolute(f.src.value); + } +}; + +ImageDialog.preInit(); +tinyMCEPopup.onInit.add(ImageDialog.init, ImageDialog); diff --git a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/js/link.js b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/js/link.js index b08b2ba..8c1d73c 100644 --- a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/js/link.js +++ b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/js/link.js @@ -1,159 +1,159 @@ -tinyMCEPopup.requireLangPack(); - -var LinkDialog = { - preInit : function() { - var url; - - if (url = tinyMCEPopup.getParam("external_link_list_url")) - document.write(''); - }, - - init : function() { - var f = document.forms[0], ed = tinyMCEPopup.editor; - - // Setup browse button - document.getElementById('hrefbrowsercontainer').innerHTML = getBrowserHTML('hrefbrowser', 'href', 'file', 'theme_advanced_link'); - if (isVisible('hrefbrowser')) - document.getElementById('href').style.width = '180px'; - - this.fillClassList('class_list'); - this.fillFileList('link_list', 'tinyMCELinkList'); - this.fillTargetList('target_list'); - - if (e = ed.dom.getParent(ed.selection.getNode(), 'A')) { - f.href.value = ed.dom.getAttrib(e, 'href'); - f.linktitle.value = ed.dom.getAttrib(e, 'title'); - f.insert.value = ed.getLang('update'); - selectByValue(f, 'link_list', f.href.value); - selectByValue(f, 'target_list', ed.dom.getAttrib(e, 'target')); - selectByValue(f, 'class_list', ed.dom.getAttrib(e, 'class')); - } - }, - - update : function() { - var f = document.forms[0], ed = tinyMCEPopup.editor, e, b, href = f.href.value.replace(/ /g, '%20'); - - tinyMCEPopup.restoreSelection(); - e = ed.dom.getParent(ed.selection.getNode(), 'A'); - - // Remove element if there is no href - if (!f.href.value) { - if (e) { - b = ed.selection.getBookmark(); - ed.dom.remove(e, 1); - ed.selection.moveToBookmark(b); - tinyMCEPopup.execCommand("mceEndUndoLevel"); - tinyMCEPopup.close(); - return; - } - } - - // Create new anchor elements - if (e == null) { - ed.getDoc().execCommand("unlink", false, null); - tinyMCEPopup.execCommand("mceInsertLink", false, "#mce_temp_url#", {skip_undo : 1}); - - tinymce.each(ed.dom.select("a"), function(n) { - if (ed.dom.getAttrib(n, 'href') == '#mce_temp_url#') { - e = n; - - ed.dom.setAttribs(e, { - href : href, - title : f.linktitle.value, - target : f.target_list ? getSelectValue(f, "target_list") : null, - 'class' : f.class_list ? getSelectValue(f, "class_list") : null - }); - } - }); - } else { - ed.dom.setAttribs(e, { - href : href, - title : f.linktitle.value - }); - - if (f.target_list) { - ed.dom.setAttrib(e, 'target', getSelectValue(f, "target_list")); - } - - if (f.class_list) { - ed.dom.setAttrib(e, 'class', getSelectValue(f, "class_list")); - } - } - - // Don't move caret if selection was image - if (e.childNodes.length != 1 || e.firstChild.nodeName != 'IMG') { - ed.focus(); - ed.selection.select(e); - ed.selection.collapse(0); - tinyMCEPopup.storeSelection(); - } - - tinyMCEPopup.execCommand("mceEndUndoLevel"); - tinyMCEPopup.close(); - }, - - checkPrefix : function(n) { - if (n.value && Validator.isEmail(n) && !/^\s*mailto:/i.test(n.value) && confirm(tinyMCEPopup.getLang('advanced_dlg.link_is_email'))) - n.value = 'mailto:' + n.value; - - if (/^\s*www\./i.test(n.value) && confirm(tinyMCEPopup.getLang('advanced_dlg.link_is_external'))) - n.value = 'http://' + n.value; - }, - - fillFileList : function(id, l) { - var dom = tinyMCEPopup.dom, lst = dom.get(id), v, cl; - - l = window[l]; - - if (l && l.length > 0) { - lst.options[lst.options.length] = new Option('', ''); - - tinymce.each(l, function(o) { - lst.options[lst.options.length] = new Option(o[0], o[1]); - }); - } else - dom.remove(dom.getParent(id, 'tr')); - }, - - fillClassList : function(id) { - var dom = tinyMCEPopup.dom, lst = dom.get(id), v, cl; - - if (v = tinyMCEPopup.getParam('theme_advanced_styles')) { - cl = []; - - tinymce.each(v.split(';'), function(v) { - var p = v.split('='); - - cl.push({'title' : p[0], 'class' : p[1]}); - }); - } else - cl = tinyMCEPopup.editor.dom.getClasses(); - - if (cl.length > 0) { - lst.options[lst.options.length] = new Option(tinyMCEPopup.getLang('not_set'), ''); - - tinymce.each(cl, function(o) { - lst.options[lst.options.length] = new Option(o.title || o['class'], o['class']); - }); - } else - dom.remove(dom.getParent(id, 'tr')); - }, - - fillTargetList : function(id) { - var dom = tinyMCEPopup.dom, lst = dom.get(id), v; - - lst.options[lst.options.length] = new Option(tinyMCEPopup.getLang('not_set'), ''); - lst.options[lst.options.length] = new Option(tinyMCEPopup.getLang('advanced_dlg.link_target_same'), '_self'); - lst.options[lst.options.length] = new Option(tinyMCEPopup.getLang('advanced_dlg.link_target_blank'), '_blank'); - - if (v = tinyMCEPopup.getParam('theme_advanced_link_targets')) { - tinymce.each(v.split(','), function(v) { - v = v.split('='); - lst.options[lst.options.length] = new Option(v[0], v[1]); - }); - } - } -}; - -LinkDialog.preInit(); -tinyMCEPopup.onInit.add(LinkDialog.init, LinkDialog); +tinyMCEPopup.requireLangPack(); + +var LinkDialog = { + preInit : function() { + var url; + + if (url = tinyMCEPopup.getParam("external_link_list_url")) + document.write(''); + }, + + init : function() { + var f = document.forms[0], ed = tinyMCEPopup.editor; + + // Setup browse button + document.getElementById('hrefbrowsercontainer').innerHTML = getBrowserHTML('hrefbrowser', 'href', 'file', 'theme_advanced_link'); + if (isVisible('hrefbrowser')) + document.getElementById('href').style.width = '180px'; + + this.fillClassList('class_list'); + this.fillFileList('link_list', 'tinyMCELinkList'); + this.fillTargetList('target_list'); + + if (e = ed.dom.getParent(ed.selection.getNode(), 'A')) { + f.href.value = ed.dom.getAttrib(e, 'href'); + f.linktitle.value = ed.dom.getAttrib(e, 'title'); + f.insert.value = ed.getLang('update'); + selectByValue(f, 'link_list', f.href.value); + selectByValue(f, 'target_list', ed.dom.getAttrib(e, 'target')); + selectByValue(f, 'class_list', ed.dom.getAttrib(e, 'class')); + } + }, + + update : function() { + var f = document.forms[0], ed = tinyMCEPopup.editor, e, b, href = f.href.value.replace(/ /g, '%20'); + + tinyMCEPopup.restoreSelection(); + e = ed.dom.getParent(ed.selection.getNode(), 'A'); + + // Remove element if there is no href + if (!f.href.value) { + if (e) { + b = ed.selection.getBookmark(); + ed.dom.remove(e, 1); + ed.selection.moveToBookmark(b); + tinyMCEPopup.execCommand("mceEndUndoLevel"); + tinyMCEPopup.close(); + return; + } + } + + // Create new anchor elements + if (e == null) { + ed.getDoc().execCommand("unlink", false, null); + tinyMCEPopup.execCommand("mceInsertLink", false, "#mce_temp_url#", {skip_undo : 1}); + + tinymce.each(ed.dom.select("a"), function(n) { + if (ed.dom.getAttrib(n, 'href') == '#mce_temp_url#') { + e = n; + + ed.dom.setAttribs(e, { + href : href, + title : f.linktitle.value, + target : f.target_list ? getSelectValue(f, "target_list") : null, + 'class' : f.class_list ? getSelectValue(f, "class_list") : null + }); + } + }); + } else { + ed.dom.setAttribs(e, { + href : href, + title : f.linktitle.value + }); + + if (f.target_list) { + ed.dom.setAttrib(e, 'target', getSelectValue(f, "target_list")); + } + + if (f.class_list) { + ed.dom.setAttrib(e, 'class', getSelectValue(f, "class_list")); + } + } + + // Don't move caret if selection was image + if (e.childNodes.length != 1 || e.firstChild.nodeName != 'IMG') { + ed.focus(); + ed.selection.select(e); + ed.selection.collapse(0); + tinyMCEPopup.storeSelection(); + } + + tinyMCEPopup.execCommand("mceEndUndoLevel"); + tinyMCEPopup.close(); + }, + + checkPrefix : function(n) { + if (n.value && Validator.isEmail(n) && !/^\s*mailto:/i.test(n.value) && confirm(tinyMCEPopup.getLang('advanced_dlg.link_is_email'))) + n.value = 'mailto:' + n.value; + + if (/^\s*www\./i.test(n.value) && confirm(tinyMCEPopup.getLang('advanced_dlg.link_is_external'))) + n.value = 'http://' + n.value; + }, + + fillFileList : function(id, l) { + var dom = tinyMCEPopup.dom, lst = dom.get(id), v, cl; + + l = window[l]; + + if (l && l.length > 0) { + lst.options[lst.options.length] = new Option('', ''); + + tinymce.each(l, function(o) { + lst.options[lst.options.length] = new Option(o[0], o[1]); + }); + } else + dom.remove(dom.getParent(id, 'tr')); + }, + + fillClassList : function(id) { + var dom = tinyMCEPopup.dom, lst = dom.get(id), v, cl; + + if (v = tinyMCEPopup.getParam('theme_advanced_styles')) { + cl = []; + + tinymce.each(v.split(';'), function(v) { + var p = v.split('='); + + cl.push({'title' : p[0], 'class' : p[1]}); + }); + } else + cl = tinyMCEPopup.editor.dom.getClasses(); + + if (cl.length > 0) { + lst.options[lst.options.length] = new Option(tinyMCEPopup.getLang('not_set'), ''); + + tinymce.each(cl, function(o) { + lst.options[lst.options.length] = new Option(o.title || o['class'], o['class']); + }); + } else + dom.remove(dom.getParent(id, 'tr')); + }, + + fillTargetList : function(id) { + var dom = tinyMCEPopup.dom, lst = dom.get(id), v; + + lst.options[lst.options.length] = new Option(tinyMCEPopup.getLang('not_set'), ''); + lst.options[lst.options.length] = new Option(tinyMCEPopup.getLang('advanced_dlg.link_target_same'), '_self'); + lst.options[lst.options.length] = new Option(tinyMCEPopup.getLang('advanced_dlg.link_target_blank'), '_blank'); + + if (v = tinyMCEPopup.getParam('theme_advanced_link_targets')) { + tinymce.each(v.split(','), function(v) { + v = v.split('='); + lst.options[lst.options.length] = new Option(v[0], v[1]); + }); + } + } +}; + +LinkDialog.preInit(); +tinyMCEPopup.onInit.add(LinkDialog.init, LinkDialog); diff --git a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/js/source_editor.js b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/js/source_editor.js index d417937..dd5e366 100644 --- a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/js/source_editor.js +++ b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/js/source_editor.js @@ -1,78 +1,78 @@ -tinyMCEPopup.requireLangPack(); -tinyMCEPopup.onInit.add(onLoadInit); - -function saveContent() { - tinyMCEPopup.editor.setContent(document.getElementById('htmlSource').value, {source_view : true}); - tinyMCEPopup.close(); -} - -function onLoadInit() { - tinyMCEPopup.resizeToInnerSize(); - - // Remove Gecko spellchecking - if (tinymce.isGecko) - document.body.spellcheck = tinyMCEPopup.editor.getParam("gecko_spellcheck"); - - document.getElementById('htmlSource').value = tinyMCEPopup.editor.getContent({source_view : true}); - - if (tinyMCEPopup.editor.getParam("theme_advanced_source_editor_wrap", true)) { - turnWrapOn(); - document.getElementById('wraped').checked = true; - } - - resizeInputs(); -} - -function setWrap(val) { - var v, n, s = document.getElementById('htmlSource'); - - s.wrap = val; - - if (!tinymce.isIE) { - v = s.value; - n = s.cloneNode(false); - n.setAttribute("wrap", val); - s.parentNode.replaceChild(n, s); - n.value = v; - } -} - -function setWhiteSpaceCss(value) { - var el = document.getElementById('htmlSource'); - tinymce.DOM.setStyle(el, 'white-space', value); -} - -function turnWrapOff() { - if (tinymce.isWebKit) { - setWhiteSpaceCss('pre'); - } else { - setWrap('off'); - } -} - -function turnWrapOn() { - if (tinymce.isWebKit) { - setWhiteSpaceCss('pre-wrap'); - } else { - setWrap('soft'); - } -} - -function toggleWordWrap(elm) { - if (elm.checked) { - turnWrapOn(); - } else { - turnWrapOff(); - } -} - -function resizeInputs() { - var vp = tinyMCEPopup.dom.getViewPort(window), el; - - el = document.getElementById('htmlSource'); - - if (el) { - el.style.width = (vp.w - 20) + 'px'; - el.style.height = (vp.h - 65) + 'px'; - } -} +tinyMCEPopup.requireLangPack(); +tinyMCEPopup.onInit.add(onLoadInit); + +function saveContent() { + tinyMCEPopup.editor.setContent(document.getElementById('htmlSource').value, {source_view : true}); + tinyMCEPopup.close(); +} + +function onLoadInit() { + tinyMCEPopup.resizeToInnerSize(); + + // Remove Gecko spellchecking + if (tinymce.isGecko) + document.body.spellcheck = tinyMCEPopup.editor.getParam("gecko_spellcheck"); + + document.getElementById('htmlSource').value = tinyMCEPopup.editor.getContent({source_view : true}); + + if (tinyMCEPopup.editor.getParam("theme_advanced_source_editor_wrap", true)) { + turnWrapOn(); + document.getElementById('wraped').checked = true; + } + + resizeInputs(); +} + +function setWrap(val) { + var v, n, s = document.getElementById('htmlSource'); + + s.wrap = val; + + if (!tinymce.isIE) { + v = s.value; + n = s.cloneNode(false); + n.setAttribute("wrap", val); + s.parentNode.replaceChild(n, s); + n.value = v; + } +} + +function setWhiteSpaceCss(value) { + var el = document.getElementById('htmlSource'); + tinymce.DOM.setStyle(el, 'white-space', value); +} + +function turnWrapOff() { + if (tinymce.isWebKit) { + setWhiteSpaceCss('pre'); + } else { + setWrap('off'); + } +} + +function turnWrapOn() { + if (tinymce.isWebKit) { + setWhiteSpaceCss('pre-wrap'); + } else { + setWrap('soft'); + } +} + +function toggleWordWrap(elm) { + if (elm.checked) { + turnWrapOn(); + } else { + turnWrapOff(); + } +} + +function resizeInputs() { + var vp = tinyMCEPopup.dom.getViewPort(window), el; + + el = document.getElementById('htmlSource'); + + if (el) { + el.style.width = (vp.w - 20) + 'px'; + el.style.height = (vp.h - 65) + 'px'; + } +} diff --git a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/langs/en_dlg.js b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/langs/en_dlg.js index 50cd87e..b4bd922 100644 --- a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/langs/en_dlg.js +++ b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/langs/en_dlg.js @@ -1 +1 @@ -tinyMCE.addI18n('en.advanced_dlg', {"link_list":"Link List","link_is_external":"The URL you entered seems to be an external link. Do you want to add the required http:// prefix?","link_is_email":"The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?","link_titlefield":"Title","link_target_blank":"Open Link in a New Window","link_target_same":"Open Link in the Same Window","link_target":"Target","link_url":"Link URL","link_title":"Insert/Edit Link","image_align_right":"Right","image_align_left":"Left","image_align_textbottom":"Text Bottom","image_align_texttop":"Text Top","image_align_bottom":"Bottom","image_align_middle":"Middle","image_align_top":"Top","image_align_baseline":"Baseline","image_align":"Alignment","image_hspace":"Horizontal Space","image_vspace":"Vertical Space","image_dimensions":"Dimensions","image_alt":"Image Description","image_list":"Image List","image_border":"Border","image_src":"Image URL","image_title":"Insert/Edit Image","charmap_title":"Select Special Character", "charmap_usage":"Use left and right arrows to navigate.","colorpicker_name":"Name:","colorpicker_color":"Color:","colorpicker_named_title":"Named Colors","colorpicker_named_tab":"Named","colorpicker_palette_title":"Palette Colors","colorpicker_palette_tab":"Palette","colorpicker_picker_title":"Color Picker","colorpicker_picker_tab":"Picker","colorpicker_title":"Select a Color","code_wordwrap":"Word Wrap","code_title":"HTML Source Editor","anchor_name":"Anchor Name","anchor_title":"Insert/Edit Anchor","about_loaded":"Loaded Plugins","about_version":"Version","about_author":"Author","about_plugin":"Plugin","about_plugins":"Plugins","about_license":"License","about_help":"Help","about_general":"About","about_title":"About TinyMCE","anchor_invalid":"Please specify a valid anchor name.","accessibility_help":"Accessibility Help","accessibility_usage_title":"General Usage","invalid_color_value":"Invalid color value","":""}); +tinyMCE.addI18n('en.advanced_dlg', {"link_list":"Link List","link_is_external":"The URL you entered seems to be an external link. Do you want to add the required http:// prefix?","link_is_email":"The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?","link_titlefield":"Title","link_target_blank":"Open Link in a New Window","link_target_same":"Open Link in the Same Window","link_target":"Target","link_url":"Link URL","link_title":"Insert/Edit Link","image_align_right":"Right","image_align_left":"Left","image_align_textbottom":"Text Bottom","image_align_texttop":"Text Top","image_align_bottom":"Bottom","image_align_middle":"Middle","image_align_top":"Top","image_align_baseline":"Baseline","image_align":"Alignment","image_hspace":"Horizontal Space","image_vspace":"Vertical Space","image_dimensions":"Dimensions","image_alt":"Image Description","image_list":"Image List","image_border":"Border","image_src":"Image URL","image_title":"Insert/Edit Image","charmap_title":"Select Special Character", "charmap_usage":"Use left and right arrows to navigate.","colorpicker_name":"Name:","colorpicker_color":"Color:","colorpicker_named_title":"Named Colors","colorpicker_named_tab":"Named","colorpicker_palette_title":"Palette Colors","colorpicker_palette_tab":"Palette","colorpicker_picker_title":"Color Picker","colorpicker_picker_tab":"Picker","colorpicker_title":"Select a Color","code_wordwrap":"Word Wrap","code_title":"HTML Source Editor","anchor_name":"Anchor Name","anchor_title":"Insert/Edit Anchor","about_loaded":"Loaded Plugins","about_version":"Version","about_author":"Author","about_plugin":"Plugin","about_plugins":"Plugins","about_license":"License","about_help":"Help","about_general":"About","about_title":"About TinyMCE","anchor_invalid":"Please specify a valid anchor name.","accessibility_help":"Accessibility Help","accessibility_usage_title":"General Usage","invalid_color_value":"Invalid color value","":""}); diff --git a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/link.htm b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/link.htm index 4a2459f..5d9dea9 100644 --- a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/link.htm +++ b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/link.htm @@ -1,57 +1,57 @@ - - - - {#advanced_dlg.link_title} - - - - - - - -
            - - -
            -
            - - - - - - - - - - - - - - - - - - - - - -
            - - - - -
             
            -
            -
            - -
            - - -
            -
            - - + + + + {#advanced_dlg.link_title} + + + + + + + +
            + + +
            +
            + + + + + + + + + + + + + + + + + + + + + +
            + + + + +
             
            +
            +
            + +
            + + +
            +
            + + diff --git a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/shortcuts.htm b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/shortcuts.htm index 436091f..20ec2f5 100644 --- a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/shortcuts.htm +++ b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/shortcuts.htm @@ -1,47 +1,47 @@ - - - - {#advanced_dlg.accessibility_help} - - - - -

            {#advanced_dlg.accessibility_usage_title}

            -

            Toolbars

            -

            Press ALT-F10 to move focus to the toolbars. Navigate through the buttons using the arrow keys. - Press enter to activate a button and return focus to the editor. - Press escape to return focus to the editor without performing any actions.

            - -

            Status Bar

            -

            To access the editor status bar, press ALT-F11. Use the left and right arrow keys to navigate between elements in the path. - Press enter or space to select an element. Press escape to return focus to the editor without changing the selection.

            - -

            Context Menu

            -

            Press shift-F10 to activate the context menu. Use the up and down arrow keys to move between menu items. To open sub-menus press the right arrow key. - To close submenus press the left arrow key. Press escape to close the context menu.

            - -

            Keyboard Shortcuts

            - - - - - - - - - - - - - - - - - - - - - -
            KeystrokeFunction
            Control-BBold
            Control-IItalic
            Control-ZUndo
            Control-YRedo
            - - + + + + {#advanced_dlg.accessibility_help} + + + + +

            {#advanced_dlg.accessibility_usage_title}

            +

            Toolbars

            +

            Press ALT-F10 to move focus to the toolbars. Navigate through the buttons using the arrow keys. + Press enter to activate a button and return focus to the editor. + Press escape to return focus to the editor without performing any actions.

            + +

            Status Bar

            +

            To access the editor status bar, press ALT-F11. Use the left and right arrow keys to navigate between elements in the path. + Press enter or space to select an element. Press escape to return focus to the editor without changing the selection.

            + +

            Context Menu

            +

            Press shift-F10 to activate the context menu. Use the up and down arrow keys to move between menu items. To open sub-menus press the right arrow key. + To close submenus press the left arrow key. Press escape to close the context menu.

            + +

            Keyboard Shortcuts

            + + + + + + + + + + + + + + + + + + + + + +
            KeystrokeFunction
            Control-BBold
            Control-IItalic
            Control-ZUndo
            Control-YRedo
            + + diff --git a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/skins/default/content.css b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/skins/default/content.css index 4d63ca9..2fd94a1 100644 --- a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/skins/default/content.css +++ b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/skins/default/content.css @@ -1,50 +1,50 @@ -body, td, pre {color:#000; font-family:Verdana, Arial, Helvetica, sans-serif; font-size:10px; margin:8px;} -body {background:#FFF;} -body.mceForceColors {background:#FFF; color:#000;} -body.mceBrowserDefaults {background:transparent; color:inherit; font-size:inherit; font-family:inherit;} -h1 {font-size: 2em} -h2 {font-size: 1.5em} -h3 {font-size: 1.17em} -h4 {font-size: 1em} -h5 {font-size: .83em} -h6 {font-size: .75em} -.mceItemTable, .mceItemTable td, .mceItemTable th, .mceItemTable caption, .mceItemVisualAid {border: 1px dashed #BBB;} -a.mceItemAnchor {display:inline-block; -webkit-user-select:all; -webkit-user-modify:read-only; -moz-user-select:all; -moz-user-modify:read-only; width:11px !important; height:11px !important; background:url(img/items.gif) no-repeat center center} -span.mceItemNbsp {background: #DDD} -td.mceSelected, th.mceSelected {background-color:#3399ff !important} -img {border:0;} -table, img, hr, .mceItemAnchor {cursor:default} -table td, table th {cursor:text} -ins {border-bottom:1px solid green; text-decoration: none; color:green} -del {color:red; text-decoration:line-through} -cite {border-bottom:1px dashed blue} -acronym {border-bottom:1px dotted #CCC; cursor:help} -abbr {border-bottom:1px dashed #CCC; cursor:help} - -/* IE */ -* html body { -scrollbar-3dlight-color:#F0F0EE; -scrollbar-arrow-color:#676662; -scrollbar-base-color:#F0F0EE; -scrollbar-darkshadow-color:#DDD; -scrollbar-face-color:#E0E0DD; -scrollbar-highlight-color:#F0F0EE; -scrollbar-shadow-color:#F0F0EE; -scrollbar-track-color:#F5F5F5; -} - -img:-moz-broken {-moz-force-broken-image-icon:1; width:24px; height:24px} -font[face=mceinline] {font-family:inherit !important} -*[contentEditable]:focus {outline:0} - -.mceItemMedia {border:1px dotted #cc0000; background-position:center; background-repeat:no-repeat; background-color:#ffffcc} -.mceItemShockWave {background-image:url(../../img/shockwave.gif)} -.mceItemFlash {background-image:url(../../img/flash.gif)} -.mceItemQuickTime {background-image:url(../../img/quicktime.gif)} -.mceItemWindowsMedia {background-image:url(../../img/windowsmedia.gif)} -.mceItemRealMedia {background-image:url(../../img/realmedia.gif)} -.mceItemVideo {background-image:url(../../img/video.gif)} -.mceItemAudio {background-image:url(../../img/video.gif)} -.mceItemEmbeddedAudio {background-image:url(../../img/video.gif)} -.mceItemIframe {background-image:url(../../img/iframe.gif)} -.mcePageBreak {display:block;border:0;width:100%;height:12px;border-top:1px dotted #ccc;margin-top:15px;background:#fff url(../../img/pagebreak.gif) no-repeat center top;} +body, td, pre {color:#000; font-family:Verdana, Arial, Helvetica, sans-serif; font-size:10px; margin:8px;} +body {background:#FFF;} +body.mceForceColors {background:#FFF; color:#000;} +body.mceBrowserDefaults {background:transparent; color:inherit; font-size:inherit; font-family:inherit;} +h1 {font-size: 2em} +h2 {font-size: 1.5em} +h3 {font-size: 1.17em} +h4 {font-size: 1em} +h5 {font-size: .83em} +h6 {font-size: .75em} +.mceItemTable, .mceItemTable td, .mceItemTable th, .mceItemTable caption, .mceItemVisualAid {border: 1px dashed #BBB;} +a.mceItemAnchor {display:inline-block; -webkit-user-select:all; -webkit-user-modify:read-only; -moz-user-select:all; -moz-user-modify:read-only; width:11px !important; height:11px !important; background:url(img/items.gif) no-repeat center center} +span.mceItemNbsp {background: #DDD} +td.mceSelected, th.mceSelected {background-color:#3399ff !important} +img {border:0;} +table, img, hr, .mceItemAnchor {cursor:default} +table td, table th {cursor:text} +ins {border-bottom:1px solid green; text-decoration: none; color:green} +del {color:red; text-decoration:line-through} +cite {border-bottom:1px dashed blue} +acronym {border-bottom:1px dotted #CCC; cursor:help} +abbr {border-bottom:1px dashed #CCC; cursor:help} + +/* IE */ +* html body { +scrollbar-3dlight-color:#F0F0EE; +scrollbar-arrow-color:#676662; +scrollbar-base-color:#F0F0EE; +scrollbar-darkshadow-color:#DDD; +scrollbar-face-color:#E0E0DD; +scrollbar-highlight-color:#F0F0EE; +scrollbar-shadow-color:#F0F0EE; +scrollbar-track-color:#F5F5F5; +} + +img:-moz-broken {-moz-force-broken-image-icon:1; width:24px; height:24px} +font[face=mceinline] {font-family:inherit !important} +*[contentEditable]:focus {outline:0} + +.mceItemMedia {border:1px dotted #cc0000; background-position:center; background-repeat:no-repeat; background-color:#ffffcc} +.mceItemShockWave {background-image:url(../../img/shockwave.gif)} +.mceItemFlash {background-image:url(../../img/flash.gif)} +.mceItemQuickTime {background-image:url(../../img/quicktime.gif)} +.mceItemWindowsMedia {background-image:url(../../img/windowsmedia.gif)} +.mceItemRealMedia {background-image:url(../../img/realmedia.gif)} +.mceItemVideo {background-image:url(../../img/video.gif)} +.mceItemAudio {background-image:url(../../img/video.gif)} +.mceItemEmbeddedAudio {background-image:url(../../img/video.gif)} +.mceItemIframe {background-image:url(../../img/iframe.gif)} +.mcePageBreak {display:block;border:0;width:100%;height:12px;border-top:1px dotted #ccc;margin-top:15px;background:#fff url(../../img/pagebreak.gif) no-repeat center top;} diff --git a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/skins/default/dialog.css b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/skins/default/dialog.css index 8950ba3..879786f 100644 --- a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/skins/default/dialog.css +++ b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/skins/default/dialog.css @@ -1,118 +1,118 @@ -/* Generic */ -body { -font-family:Verdana, Arial, Helvetica, sans-serif; font-size:11px; -scrollbar-3dlight-color:#F0F0EE; -scrollbar-arrow-color:#676662; -scrollbar-base-color:#F0F0EE; -scrollbar-darkshadow-color:#DDDDDD; -scrollbar-face-color:#E0E0DD; -scrollbar-highlight-color:#F0F0EE; -scrollbar-shadow-color:#F0F0EE; -scrollbar-track-color:#F5F5F5; -background:#F0F0EE; -padding:0; -margin:8px 8px 0 8px; -} - -html {background:#F0F0EE;} -td {font-family:Verdana, Arial, Helvetica, sans-serif; font-size:10px;} -textarea {resize:none;outline:none;} -a:link, a:visited {color:black;} -a:hover {color:#2B6FB6;} -.nowrap {white-space: nowrap} - -/* Forms */ -fieldset {margin:0; padding:4px; border:1px solid #919B9C; font-family:Verdana, Arial; font-size:10px;} -legend {color:#2B6FB6; font-weight:bold;} -label.msg {display:none;} -label.invalid {color:#EE0000; display:inline;} -input.invalid {border:1px solid #EE0000;} -input {background:#FFF; border:1px solid #CCC;} -input, select, textarea {font-family:Verdana, Arial, Helvetica, sans-serif; font-size:10px;} -input, select, textarea {border:1px solid #808080;} -input.radio {border:1px none #000000; background:transparent; vertical-align:middle;} -input.checkbox {border:1px none #000000; background:transparent; vertical-align:middle;} -.input_noborder {border:0;} - -/* Buttons */ -#insert, #cancel, input.button, .updateButton { -border:0; margin:0; padding:0; -font-weight:bold; -width:94px; height:26px; -background:url(img/buttons.png) 0 -26px; -cursor:pointer; -padding-bottom:2px; -float:left; -} - -#insert {background:url(img/buttons.png) 0 -52px} -#cancel {background:url(img/buttons.png) 0 0; float:right} - -/* Browse */ -a.pickcolor, a.browse {text-decoration:none} -a.browse span {display:block; width:20px; height:18px; background:url(../../img/icons.gif) -860px 0; border:1px solid #FFF; margin-left:1px;} -.mceOldBoxModel a.browse span {width:22px; height:20px;} -a.browse:hover span {border:1px solid #0A246A; background-color:#B2BBD0;} -a.browse span.disabled {border:1px solid white; opacity:0.3; -ms-filter:'alpha(opacity=30)'; filter:alpha(opacity=30)} -a.browse:hover span.disabled {border:1px solid white; background-color:transparent;} -a.pickcolor span {display:block; width:20px; height:16px; background:url(../../img/icons.gif) -840px 0; margin-left:2px;} -.mceOldBoxModel a.pickcolor span {width:21px; height:17px;} -a.pickcolor:hover span {background-color:#B2BBD0;} -a.pickcolor:hover span.disabled {} - -/* Charmap */ -table.charmap {border:1px solid #AAA; text-align:center} -td.charmap, #charmap a {width:18px; height:18px; color:#000; border:1px solid #AAA; text-align:center; font-size:12px; vertical-align:middle; line-height: 18px;} -#charmap a {display:block; color:#000; text-decoration:none; border:0} -#charmap a:hover {background:#CCC;color:#2B6FB6} -#charmap #codeN {font-size:10px; font-family:Arial,Helvetica,sans-serif; text-align:center} -#charmap #codeV {font-size:40px; height:80px; border:1px solid #AAA; text-align:center} - -/* Source */ -.wordWrapCode {vertical-align:middle; border:1px none #000000; background:transparent;} -.mceActionPanel {margin-top:5px;} - -/* Tabs classes */ -.tabs {width:100%; height:18px; line-height:normal; background:url(img/tabs.gif) repeat-x 0 -72px;} -.tabs ul {margin:0; padding:0; list-style:none;} -.tabs li {float:left; background:url(img/tabs.gif) no-repeat 0 0; margin:0 2px 0 0; padding:0 0 0 10px; line-height:17px; height:18px; display:block;} -.tabs li.current {background:url(img/tabs.gif) no-repeat 0 -18px; margin-right:2px;} -.tabs span {float:left; display:block; background:url(img/tabs.gif) no-repeat right -36px; padding:0px 10px 0 0;} -.tabs .current span {background:url(img/tabs.gif) no-repeat right -54px;} -.tabs a {text-decoration:none; font-family:Verdana, Arial; font-size:10px;} -.tabs a:link, .tabs a:visited, .tabs a:hover {color:black;} - -/* Panels */ -.panel_wrapper div.panel {display:none;} -.panel_wrapper div.current {display:block; width:100%; height:300px; overflow:visible;} -.panel_wrapper {border:1px solid #919B9C; border-top:0px; padding:10px; padding-top:5px; clear:both; background:white;} - -/* Columns */ -.column {float:left;} -.properties {width:100%;} -.properties .column1 {} -.properties .column2 {text-align:left;} - -/* Titles */ -h1, h2, h3, h4 {color:#2B6FB6; margin:0; padding:0; padding-top:5px;} -h3 {font-size:14px;} -.title {font-size:12px; font-weight:bold; color:#2B6FB6;} - -/* Dialog specific */ -#link .panel_wrapper, #link div.current {height:125px;} -#image .panel_wrapper, #image div.current {height:200px;} -#plugintable thead {font-weight:bold; background:#DDD;} -#plugintable, #about #plugintable td {border:1px solid #919B9C;} -#plugintable {width:96%; margin-top:10px;} -#pluginscontainer {height:290px; overflow:auto;} -#colorpicker #preview {display:inline-block; padding-left:40px; height:14px; border:1px solid black; margin-left:5px; margin-right: 5px} -#colorpicker #previewblock {position: relative; top: -3px; padding-left:5px; padding-top: 0px; display:inline} -#colorpicker #preview_wrapper { text-align:center; padding-top:4px; white-space: nowrap} -#colorpicker #colors {float:left; border:1px solid gray; cursor:crosshair;} -#colorpicker #light {border:1px solid gray; margin-left:5px; float:left;width:15px; height:150px; cursor:crosshair;} -#colorpicker #light div {overflow:hidden;} -#colorpicker .panel_wrapper div.current {height:175px;} -#colorpicker #namedcolors {width:150px;} -#colorpicker #namedcolors a {display:block; float:left; width:10px; height:10px; margin:1px 1px 0 0; overflow:hidden;} -#colorpicker #colornamecontainer {margin-top:5px;} -#colorpicker #picker_panel fieldset {margin:auto;width:325px;} +/* Generic */ +body { +font-family:Verdana, Arial, Helvetica, sans-serif; font-size:11px; +scrollbar-3dlight-color:#F0F0EE; +scrollbar-arrow-color:#676662; +scrollbar-base-color:#F0F0EE; +scrollbar-darkshadow-color:#DDDDDD; +scrollbar-face-color:#E0E0DD; +scrollbar-highlight-color:#F0F0EE; +scrollbar-shadow-color:#F0F0EE; +scrollbar-track-color:#F5F5F5; +background:#F0F0EE; +padding:0; +margin:8px 8px 0 8px; +} + +html {background:#F0F0EE;} +td {font-family:Verdana, Arial, Helvetica, sans-serif; font-size:10px;} +textarea {resize:none;outline:none;} +a:link, a:visited {color:black;} +a:hover {color:#2B6FB6;} +.nowrap {white-space: nowrap} + +/* Forms */ +fieldset {margin:0; padding:4px; border:1px solid #919B9C; font-family:Verdana, Arial; font-size:10px;} +legend {color:#2B6FB6; font-weight:bold;} +label.msg {display:none;} +label.invalid {color:#EE0000; display:inline;} +input.invalid {border:1px solid #EE0000;} +input {background:#FFF; border:1px solid #CCC;} +input, select, textarea {font-family:Verdana, Arial, Helvetica, sans-serif; font-size:10px;} +input, select, textarea {border:1px solid #808080;} +input.radio {border:1px none #000000; background:transparent; vertical-align:middle;} +input.checkbox {border:1px none #000000; background:transparent; vertical-align:middle;} +.input_noborder {border:0;} + +/* Buttons */ +#insert, #cancel, input.button, .updateButton { +border:0; margin:0; padding:0; +font-weight:bold; +width:94px; height:26px; +background:url(img/buttons.png) 0 -26px; +cursor:pointer; +padding-bottom:2px; +float:left; +} + +#insert {background:url(img/buttons.png) 0 -52px} +#cancel {background:url(img/buttons.png) 0 0; float:right} + +/* Browse */ +a.pickcolor, a.browse {text-decoration:none} +a.browse span {display:block; width:20px; height:18px; background:url(../../img/icons.gif) -860px 0; border:1px solid #FFF; margin-left:1px;} +.mceOldBoxModel a.browse span {width:22px; height:20px;} +a.browse:hover span {border:1px solid #0A246A; background-color:#B2BBD0;} +a.browse span.disabled {border:1px solid white; opacity:0.3; -ms-filter:'alpha(opacity=30)'; filter:alpha(opacity=30)} +a.browse:hover span.disabled {border:1px solid white; background-color:transparent;} +a.pickcolor span {display:block; width:20px; height:16px; background:url(../../img/icons.gif) -840px 0; margin-left:2px;} +.mceOldBoxModel a.pickcolor span {width:21px; height:17px;} +a.pickcolor:hover span {background-color:#B2BBD0;} +a.pickcolor:hover span.disabled {} + +/* Charmap */ +table.charmap {border:1px solid #AAA; text-align:center} +td.charmap, #charmap a {width:18px; height:18px; color:#000; border:1px solid #AAA; text-align:center; font-size:12px; vertical-align:middle; line-height: 18px;} +#charmap a {display:block; color:#000; text-decoration:none; border:0} +#charmap a:hover {background:#CCC;color:#2B6FB6} +#charmap #codeN {font-size:10px; font-family:Arial,Helvetica,sans-serif; text-align:center} +#charmap #codeV {font-size:40px; height:80px; border:1px solid #AAA; text-align:center} + +/* Source */ +.wordWrapCode {vertical-align:middle; border:1px none #000000; background:transparent;} +.mceActionPanel {margin-top:5px;} + +/* Tabs classes */ +.tabs {width:100%; height:18px; line-height:normal; background:url(img/tabs.gif) repeat-x 0 -72px;} +.tabs ul {margin:0; padding:0; list-style:none;} +.tabs li {float:left; background:url(img/tabs.gif) no-repeat 0 0; margin:0 2px 0 0; padding:0 0 0 10px; line-height:17px; height:18px; display:block;} +.tabs li.current {background:url(img/tabs.gif) no-repeat 0 -18px; margin-right:2px;} +.tabs span {float:left; display:block; background:url(img/tabs.gif) no-repeat right -36px; padding:0px 10px 0 0;} +.tabs .current span {background:url(img/tabs.gif) no-repeat right -54px;} +.tabs a {text-decoration:none; font-family:Verdana, Arial; font-size:10px;} +.tabs a:link, .tabs a:visited, .tabs a:hover {color:black;} + +/* Panels */ +.panel_wrapper div.panel {display:none;} +.panel_wrapper div.current {display:block; width:100%; height:300px; overflow:visible;} +.panel_wrapper {border:1px solid #919B9C; border-top:0px; padding:10px; padding-top:5px; clear:both; background:white;} + +/* Columns */ +.column {float:left;} +.properties {width:100%;} +.properties .column1 {} +.properties .column2 {text-align:left;} + +/* Titles */ +h1, h2, h3, h4 {color:#2B6FB6; margin:0; padding:0; padding-top:5px;} +h3 {font-size:14px;} +.title {font-size:12px; font-weight:bold; color:#2B6FB6;} + +/* Dialog specific */ +#link .panel_wrapper, #link div.current {height:125px;} +#image .panel_wrapper, #image div.current {height:200px;} +#plugintable thead {font-weight:bold; background:#DDD;} +#plugintable, #about #plugintable td {border:1px solid #919B9C;} +#plugintable {width:96%; margin-top:10px;} +#pluginscontainer {height:290px; overflow:auto;} +#colorpicker #preview {display:inline-block; padding-left:40px; height:14px; border:1px solid black; margin-left:5px; margin-right: 5px} +#colorpicker #previewblock {position: relative; top: -3px; padding-left:5px; padding-top: 0px; display:inline} +#colorpicker #preview_wrapper { text-align:center; padding-top:4px; white-space: nowrap} +#colorpicker #colors {float:left; border:1px solid gray; cursor:crosshair;} +#colorpicker #light {border:1px solid gray; margin-left:5px; float:left;width:15px; height:150px; cursor:crosshair;} +#colorpicker #light div {overflow:hidden;} +#colorpicker .panel_wrapper div.current {height:175px;} +#colorpicker #namedcolors {width:150px;} +#colorpicker #namedcolors a {display:block; float:left; width:10px; height:10px; margin:1px 1px 0 0; overflow:hidden;} +#colorpicker #colornamecontainer {margin-top:5px;} +#colorpicker #picker_panel fieldset {margin:auto;width:325px;} diff --git a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/skins/default/ui.css b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/skins/default/ui.css index 2e8c658..77083f3 100644 --- a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/skins/default/ui.css +++ b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/skins/default/ui.css @@ -1,219 +1,219 @@ -/* Reset */ -.defaultSkin table, .defaultSkin tbody, .defaultSkin a, .defaultSkin img, .defaultSkin tr, .defaultSkin div, .defaultSkin td, .defaultSkin iframe, .defaultSkin span, .defaultSkin *, .defaultSkin .mceText {border:0; margin:0; padding:0; background:transparent; white-space:nowrap; text-decoration:none; font-weight:normal; cursor:default; color:#000; vertical-align:baseline; width:auto; border-collapse:separate; text-align:left} -.defaultSkin a:hover, .defaultSkin a:link, .defaultSkin a:visited, .defaultSkin a:active {text-decoration:none; font-weight:normal; cursor:default; color:#000} -.defaultSkin table td {vertical-align:middle} - -/* Containers */ -.defaultSkin table {direction:ltr;background:transparent} -.defaultSkin iframe {display:block;} -.defaultSkin .mceToolbar {height:26px} -.defaultSkin .mceLeft {text-align:left} -.defaultSkin .mceRight {text-align:right} - -/* External */ -.defaultSkin .mceExternalToolbar {position:absolute; border:1px solid #CCC; border-bottom:0; display:none;} -.defaultSkin .mceExternalToolbar td.mceToolbar {padding-right:13px;} -.defaultSkin .mceExternalClose {position:absolute; top:3px; right:3px; width:7px; height:7px; background:url(../../img/icons.gif) -820px 0} - -/* Layout */ -.defaultSkin table.mceLayout {border:0; border-left:1px solid #CCC; border-right:1px solid #CCC} -.defaultSkin table.mceLayout tr.mceFirst td {border-top:1px solid #CCC} -.defaultSkin table.mceLayout tr.mceLast td {border-bottom:1px solid #CCC} -.defaultSkin table.mceToolbar, .defaultSkin tr.mceFirst .mceToolbar tr td, .defaultSkin tr.mceLast .mceToolbar tr td {border:0; margin:0; padding:0;} -.defaultSkin td.mceToolbar {background:#F0F0EE; padding-top:1px; vertical-align:top} -.defaultSkin .mceIframeContainer {border-top:1px solid #CCC; border-bottom:1px solid #CCC} -.defaultSkin .mceStatusbar {background:#F0F0EE; font-family:'MS Sans Serif',sans-serif,Verdana,Arial; font-size:9pt; line-height:16px; overflow:visible; color:#000; display:block; height:20px} -.defaultSkin .mceStatusbar div {float:left; margin:2px} -.defaultSkin .mceStatusbar a.mceResize {display:block; float:right; background:url(../../img/icons.gif) -800px 0; width:20px; height:20px; cursor:se-resize; outline:0} -.defaultSkin .mceStatusbar a:hover {text-decoration:underline} -.defaultSkin table.mceToolbar {margin-left:3px} -.defaultSkin span.mceIcon, .defaultSkin img.mceIcon {display:block; width:20px; height:20px} -.defaultSkin .mceIcon {background:url(../../img/icons.gif) no-repeat 20px 20px} -.defaultSkin td.mceCenter {text-align:center;} -.defaultSkin td.mceCenter table {margin:0 auto; text-align:left;} -.defaultSkin td.mceRight table {margin:0 0 0 auto;} - -/* Button */ -.defaultSkin .mceButton {display:block; border:1px solid #F0F0EE; width:20px; height:20px; margin-right:1px} -.defaultSkin a.mceButtonEnabled:hover {border:1px solid #0A246A; background-color:#B2BBD0} -.defaultSkin a.mceButtonActive, .defaultSkin a.mceButtonSelected {border:1px solid #0A246A; background-color:#C2CBE0} -.defaultSkin .mceButtonDisabled .mceIcon {opacity:0.3; -ms-filter:'alpha(opacity=30)'; filter:alpha(opacity=30)} -.defaultSkin .mceButtonLabeled {width:auto} -.defaultSkin .mceButtonLabeled span.mceIcon {float:left} -.defaultSkin span.mceButtonLabel {display:block; font-size:10px; padding:4px 6px 0 22px; font-family:Tahoma,Verdana,Arial,Helvetica} -.defaultSkin .mceButtonDisabled .mceButtonLabel {color:#888} - -/* Separator */ -.defaultSkin .mceSeparator {display:block; background:url(../../img/icons.gif) -180px 0; width:2px; height:20px; margin:2px 2px 0 4px} - -/* ListBox */ -.defaultSkin .mceListBox, .defaultSkin .mceListBox a {display:block} -.defaultSkin .mceListBox .mceText {padding-left:4px; width:70px; text-align:left; border:1px solid #CCC; border-right:0; background:#FFF; font-family:Tahoma,Verdana,Arial,Helvetica; font-size:11px; height:20px; line-height:20px; overflow:hidden} -.defaultSkin .mceListBox .mceOpen {width:9px; height:20px; background:url(../../img/icons.gif) -741px 0; margin-right:2px; border:1px solid #CCC;} -.defaultSkin table.mceListBoxEnabled:hover .mceText, .defaultSkin .mceListBoxHover .mceText, .defaultSkin .mceListBoxSelected .mceText {border:1px solid #A2ABC0; border-right:0; background:#FFF} -.defaultSkin table.mceListBoxEnabled:hover .mceOpen, .defaultSkin .mceListBoxHover .mceOpen, .defaultSkin .mceListBoxSelected .mceOpen {background-color:#FFF; border:1px solid #A2ABC0} -.defaultSkin .mceListBoxDisabled a.mceText {color:gray; background-color:transparent;} -.defaultSkin .mceListBoxMenu {overflow:auto; overflow-x:hidden} -.defaultSkin .mceOldBoxModel .mceListBox .mceText {height:22px} -.defaultSkin .mceOldBoxModel .mceListBox .mceOpen {width:11px; height:22px;} -.defaultSkin select.mceNativeListBox {font-family:'MS Sans Serif',sans-serif,Verdana,Arial; font-size:7pt; background:#F0F0EE; border:1px solid gray; margin-right:2px;} - -/* SplitButton */ -.defaultSkin .mceSplitButton {width:32px; height:20px; direction:ltr} -.defaultSkin .mceSplitButton a, .defaultSkin .mceSplitButton span {height:20px; display:block} -.defaultSkin .mceSplitButton a.mceAction {width:20px; border:1px solid #F0F0EE; border-right:0;} -.defaultSkin .mceSplitButton span.mceAction {width:20px; background-image:url(../../img/icons.gif);} -.defaultSkin .mceSplitButton a.mceOpen {width:9px; background:url(../../img/icons.gif) -741px 0; border:1px solid #F0F0EE;} -.defaultSkin .mceSplitButton span.mceOpen {display:none} -.defaultSkin table.mceSplitButtonEnabled:hover a.mceAction, .defaultSkin .mceSplitButtonHover a.mceAction, .defaultSkin .mceSplitButtonSelected a.mceAction {border:1px solid #0A246A; border-right:0; background-color:#B2BBD0} -.defaultSkin table.mceSplitButtonEnabled:hover a.mceOpen, .defaultSkin .mceSplitButtonHover a.mceOpen, .defaultSkin .mceSplitButtonSelected a.mceOpen {background-color:#B2BBD0; border:1px solid #0A246A;} -.defaultSkin .mceSplitButtonDisabled .mceAction, .defaultSkin .mceSplitButtonDisabled a.mceOpen {opacity:0.3; -ms-filter:'alpha(opacity=30)'; filter:alpha(opacity=30)} -.defaultSkin .mceSplitButtonActive a.mceAction {border:1px solid #0A246A; background-color:#C2CBE0} -.defaultSkin .mceSplitButtonActive a.mceOpen {border-left:0;} - -/* ColorSplitButton */ -.defaultSkin div.mceColorSplitMenu table {background:#FFF; border:1px solid gray} -.defaultSkin .mceColorSplitMenu td {padding:2px} -.defaultSkin .mceColorSplitMenu a {display:block; width:9px; height:9px; overflow:hidden; border:1px solid #808080} -.defaultSkin .mceColorSplitMenu td.mceMoreColors {padding:1px 3px 1px 1px} -.defaultSkin .mceColorSplitMenu a.mceMoreColors {width:100%; height:auto; text-align:center; font-family:Tahoma,Verdana,Arial,Helvetica; font-size:11px; line-height:20px; border:1px solid #FFF} -.defaultSkin .mceColorSplitMenu a.mceMoreColors:hover {border:1px solid #0A246A; background-color:#B6BDD2} -.defaultSkin a.mceMoreColors:hover {border:1px solid #0A246A} -.defaultSkin .mceColorPreview {margin-left:2px; width:16px; height:4px; overflow:hidden; background:#9a9b9a} -.defaultSkin .mce_forecolor span.mceAction, .defaultSkin .mce_backcolor span.mceAction {overflow:hidden; height:16px} - -/* Menu */ -.defaultSkin .mceMenu {position:absolute; left:0; top:0; z-index:1000; border:1px solid #D4D0C8; direction:ltr} -.defaultSkin .mceNoIcons span.mceIcon {width:0;} -.defaultSkin .mceNoIcons a .mceText {padding-left:10px} -.defaultSkin .mceMenu table {background:#FFF} -.defaultSkin .mceMenu a, .defaultSkin .mceMenu span, .defaultSkin .mceMenu {display:block} -.defaultSkin .mceMenu td {height:20px} -.defaultSkin .mceMenu a {position:relative;padding:3px 0 4px 0} -.defaultSkin .mceMenu .mceText {position:relative; display:block; font-family:Tahoma,Verdana,Arial,Helvetica; color:#000; cursor:default; margin:0; padding:0 25px 0 25px; display:block} -.defaultSkin .mceMenu span.mceText, .defaultSkin .mceMenu .mcePreview {font-size:11px} -.defaultSkin .mceMenu pre.mceText {font-family:Monospace} -.defaultSkin .mceMenu .mceIcon {position:absolute; top:0; left:0; width:22px;} -.defaultSkin .mceMenu .mceMenuItemEnabled a:hover, .defaultSkin .mceMenu .mceMenuItemActive {background-color:#dbecf3} -.defaultSkin td.mceMenuItemSeparator {background:#DDD; height:1px} -.defaultSkin .mceMenuItemTitle a {border:0; background:#EEE; border-bottom:1px solid #DDD} -.defaultSkin .mceMenuItemTitle span.mceText {color:#000; font-weight:bold; padding-left:4px} -.defaultSkin .mceMenuItemDisabled .mceText {color:#888} -.defaultSkin .mceMenuItemSelected .mceIcon {background:url(img/menu_check.gif)} -.defaultSkin .mceNoIcons .mceMenuItemSelected a {background:url(img/menu_arrow.gif) no-repeat -6px center} -.defaultSkin .mceMenu span.mceMenuLine {display:none} -.defaultSkin .mceMenuItemSub a {background:url(img/menu_arrow.gif) no-repeat top right;} -.defaultSkin .mceMenuItem td, .defaultSkin .mceMenuItem th {line-height: normal} - -/* Progress,Resize */ -.defaultSkin .mceBlocker {position:absolute; left:0; top:0; z-index:1000; opacity:0.5; -ms-filter:'alpha(opacity=50)'; filter:alpha(opacity=50); background:#FFF} -.defaultSkin .mceProgress {position:absolute; left:0; top:0; z-index:1001; background:url(img/progress.gif) no-repeat; width:32px; height:32px; margin:-16px 0 0 -16px} - -/* Rtl */ -.mceRtl .mceListBox .mceText {text-align: right; padding: 0 4px 0 0} -.mceRtl .mceMenuItem .mceText {text-align: right} - -/* Formats */ -.defaultSkin .mce_formatPreview a {font-size:10px} -.defaultSkin .mce_p span.mceText {} -.defaultSkin .mce_address span.mceText {font-style:italic} -.defaultSkin .mce_pre span.mceText {font-family:monospace} -.defaultSkin .mce_h1 span.mceText {font-weight:bolder; font-size: 2em} -.defaultSkin .mce_h2 span.mceText {font-weight:bolder; font-size: 1.5em} -.defaultSkin .mce_h3 span.mceText {font-weight:bolder; font-size: 1.17em} -.defaultSkin .mce_h4 span.mceText {font-weight:bolder; font-size: 1em} -.defaultSkin .mce_h5 span.mceText {font-weight:bolder; font-size: .83em} -.defaultSkin .mce_h6 span.mceText {font-weight:bolder; font-size: .75em} - -/* Theme */ -.defaultSkin span.mce_bold {background-position:0 0} -.defaultSkin span.mce_italic {background-position:-60px 0} -.defaultSkin span.mce_underline {background-position:-140px 0} -.defaultSkin span.mce_strikethrough {background-position:-120px 0} -.defaultSkin span.mce_undo {background-position:-160px 0} -.defaultSkin span.mce_redo {background-position:-100px 0} -.defaultSkin span.mce_cleanup {background-position:-40px 0} -.defaultSkin span.mce_bullist {background-position:-20px 0} -.defaultSkin span.mce_numlist {background-position:-80px 0} -.defaultSkin span.mce_justifyleft {background-position:-460px 0} -.defaultSkin span.mce_justifyright {background-position:-480px 0} -.defaultSkin span.mce_justifycenter {background-position:-420px 0} -.defaultSkin span.mce_justifyfull {background-position:-440px 0} -.defaultSkin span.mce_anchor {background-position:-200px 0} -.defaultSkin span.mce_indent {background-position:-400px 0} -.defaultSkin span.mce_outdent {background-position:-540px 0} -.defaultSkin span.mce_link {background-position:-500px 0} -.defaultSkin span.mce_unlink {background-position:-640px 0} -.defaultSkin span.mce_sub {background-position:-600px 0} -.defaultSkin span.mce_sup {background-position:-620px 0} -.defaultSkin span.mce_removeformat {background-position:-580px 0} -.defaultSkin span.mce_newdocument {background-position:-520px 0} -.defaultSkin span.mce_image {background-position:-380px 0} -.defaultSkin span.mce_help {background-position:-340px 0} -.defaultSkin span.mce_code {background-position:-260px 0} -.defaultSkin span.mce_hr {background-position:-360px 0} -.defaultSkin span.mce_visualaid {background-position:-660px 0} -.defaultSkin span.mce_charmap {background-position:-240px 0} -.defaultSkin span.mce_paste {background-position:-560px 0} -.defaultSkin span.mce_copy {background-position:-700px 0} -.defaultSkin span.mce_cut {background-position:-680px 0} -.defaultSkin span.mce_blockquote {background-position:-220px 0} -.defaultSkin .mce_forecolor span.mceAction {background-position:-720px 0} -.defaultSkin .mce_backcolor span.mceAction {background-position:-760px 0} -.defaultSkin span.mce_forecolorpicker {background-position:-720px 0} -.defaultSkin span.mce_backcolorpicker {background-position:-760px 0} - -/* Plugins */ -.defaultSkin span.mce_advhr {background-position:-0px -20px} -.defaultSkin span.mce_ltr {background-position:-20px -20px} -.defaultSkin span.mce_rtl {background-position:-40px -20px} -.defaultSkin span.mce_emotions {background-position:-60px -20px} -.defaultSkin span.mce_fullpage {background-position:-80px -20px} -.defaultSkin span.mce_fullscreen {background-position:-100px -20px} -.defaultSkin span.mce_iespell {background-position:-120px -20px} -.defaultSkin span.mce_insertdate {background-position:-140px -20px} -.defaultSkin span.mce_inserttime {background-position:-160px -20px} -.defaultSkin span.mce_absolute {background-position:-180px -20px} -.defaultSkin span.mce_backward {background-position:-200px -20px} -.defaultSkin span.mce_forward {background-position:-220px -20px} -.defaultSkin span.mce_insert_layer {background-position:-240px -20px} -.defaultSkin span.mce_insertlayer {background-position:-260px -20px} -.defaultSkin span.mce_movebackward {background-position:-280px -20px} -.defaultSkin span.mce_moveforward {background-position:-300px -20px} -.defaultSkin span.mce_media {background-position:-320px -20px} -.defaultSkin span.mce_nonbreaking {background-position:-340px -20px} -.defaultSkin span.mce_pastetext {background-position:-360px -20px} -.defaultSkin span.mce_pasteword {background-position:-380px -20px} -.defaultSkin span.mce_selectall {background-position:-400px -20px} -.defaultSkin span.mce_preview {background-position:-420px -20px} -.defaultSkin span.mce_print {background-position:-440px -20px} -.defaultSkin span.mce_cancel {background-position:-460px -20px} -.defaultSkin span.mce_save {background-position:-480px -20px} -.defaultSkin span.mce_replace {background-position:-500px -20px} -.defaultSkin span.mce_search {background-position:-520px -20px} -.defaultSkin span.mce_styleprops {background-position:-560px -20px} -.defaultSkin span.mce_table {background-position:-580px -20px} -.defaultSkin span.mce_cell_props {background-position:-600px -20px} -.defaultSkin span.mce_delete_table {background-position:-620px -20px} -.defaultSkin span.mce_delete_col {background-position:-640px -20px} -.defaultSkin span.mce_delete_row {background-position:-660px -20px} -.defaultSkin span.mce_col_after {background-position:-680px -20px} -.defaultSkin span.mce_col_before {background-position:-700px -20px} -.defaultSkin span.mce_row_after {background-position:-720px -20px} -.defaultSkin span.mce_row_before {background-position:-740px -20px} -.defaultSkin span.mce_merge_cells {background-position:-760px -20px} -.defaultSkin span.mce_table_props {background-position:-980px -20px} -.defaultSkin span.mce_row_props {background-position:-780px -20px} -.defaultSkin span.mce_split_cells {background-position:-800px -20px} -.defaultSkin span.mce_template {background-position:-820px -20px} -.defaultSkin span.mce_visualchars {background-position:-840px -20px} -.defaultSkin span.mce_abbr {background-position:-860px -20px} -.defaultSkin span.mce_acronym {background-position:-880px -20px} -.defaultSkin span.mce_attribs {background-position:-900px -20px} -.defaultSkin span.mce_cite {background-position:-920px -20px} -.defaultSkin span.mce_del {background-position:-940px -20px} -.defaultSkin span.mce_ins {background-position:-960px -20px} -.defaultSkin span.mce_pagebreak {background-position:0 -40px} -.defaultSkin span.mce_restoredraft {background-position:-20px -40px} -.defaultSkin span.mce_spellchecker {background-position:-540px -20px} -.defaultSkin span.mce_visualblocks {background-position: -40px -40px} +/* Reset */ +.defaultSkin table, .defaultSkin tbody, .defaultSkin a, .defaultSkin img, .defaultSkin tr, .defaultSkin div, .defaultSkin td, .defaultSkin iframe, .defaultSkin span, .defaultSkin *, .defaultSkin .mceText {border:0; margin:0; padding:0; background:transparent; white-space:nowrap; text-decoration:none; font-weight:normal; cursor:default; color:#000; vertical-align:baseline; width:auto; border-collapse:separate; text-align:left} +.defaultSkin a:hover, .defaultSkin a:link, .defaultSkin a:visited, .defaultSkin a:active {text-decoration:none; font-weight:normal; cursor:default; color:#000} +.defaultSkin table td {vertical-align:middle} + +/* Containers */ +.defaultSkin table {direction:ltr;background:transparent} +.defaultSkin iframe {display:block;} +.defaultSkin .mceToolbar {height:26px} +.defaultSkin .mceLeft {text-align:left} +.defaultSkin .mceRight {text-align:right} + +/* External */ +.defaultSkin .mceExternalToolbar {position:absolute; border:1px solid #CCC; border-bottom:0; display:none;} +.defaultSkin .mceExternalToolbar td.mceToolbar {padding-right:13px;} +.defaultSkin .mceExternalClose {position:absolute; top:3px; right:3px; width:7px; height:7px; background:url(../../img/icons.gif) -820px 0} + +/* Layout */ +.defaultSkin table.mceLayout {border:0; border-left:1px solid #CCC; border-right:1px solid #CCC} +.defaultSkin table.mceLayout tr.mceFirst td {border-top:1px solid #CCC} +.defaultSkin table.mceLayout tr.mceLast td {border-bottom:1px solid #CCC} +.defaultSkin table.mceToolbar, .defaultSkin tr.mceFirst .mceToolbar tr td, .defaultSkin tr.mceLast .mceToolbar tr td {border:0; margin:0; padding:0;} +.defaultSkin td.mceToolbar {background:#F0F0EE; padding-top:1px; vertical-align:top} +.defaultSkin .mceIframeContainer {border-top:1px solid #CCC; border-bottom:1px solid #CCC} +.defaultSkin .mceStatusbar {background:#F0F0EE; font-family:'MS Sans Serif',sans-serif,Verdana,Arial; font-size:9pt; line-height:16px; overflow:visible; color:#000; display:block; height:20px} +.defaultSkin .mceStatusbar div {float:left; margin:2px} +.defaultSkin .mceStatusbar a.mceResize {display:block; float:right; background:url(../../img/icons.gif) -800px 0; width:20px; height:20px; cursor:se-resize; outline:0} +.defaultSkin .mceStatusbar a:hover {text-decoration:underline} +.defaultSkin table.mceToolbar {margin-left:3px} +.defaultSkin span.mceIcon, .defaultSkin img.mceIcon {display:block; width:20px; height:20px} +.defaultSkin .mceIcon {background:url(../../img/icons.gif) no-repeat 20px 20px} +.defaultSkin td.mceCenter {text-align:center;} +.defaultSkin td.mceCenter table {margin:0 auto; text-align:left;} +.defaultSkin td.mceRight table {margin:0 0 0 auto;} + +/* Button */ +.defaultSkin .mceButton {display:block; border:1px solid #F0F0EE; width:20px; height:20px; margin-right:1px} +.defaultSkin a.mceButtonEnabled:hover {border:1px solid #0A246A; background-color:#B2BBD0} +.defaultSkin a.mceButtonActive, .defaultSkin a.mceButtonSelected {border:1px solid #0A246A; background-color:#C2CBE0} +.defaultSkin .mceButtonDisabled .mceIcon {opacity:0.3; -ms-filter:'alpha(opacity=30)'; filter:alpha(opacity=30)} +.defaultSkin .mceButtonLabeled {width:auto} +.defaultSkin .mceButtonLabeled span.mceIcon {float:left} +.defaultSkin span.mceButtonLabel {display:block; font-size:10px; padding:4px 6px 0 22px; font-family:Tahoma,Verdana,Arial,Helvetica} +.defaultSkin .mceButtonDisabled .mceButtonLabel {color:#888} + +/* Separator */ +.defaultSkin .mceSeparator {display:block; background:url(../../img/icons.gif) -180px 0; width:2px; height:20px; margin:2px 2px 0 4px} + +/* ListBox */ +.defaultSkin .mceListBox, .defaultSkin .mceListBox a {display:block} +.defaultSkin .mceListBox .mceText {padding-left:4px; width:70px; text-align:left; border:1px solid #CCC; border-right:0; background:#FFF; font-family:Tahoma,Verdana,Arial,Helvetica; font-size:11px; height:20px; line-height:20px; overflow:hidden} +.defaultSkin .mceListBox .mceOpen {width:9px; height:20px; background:url(../../img/icons.gif) -741px 0; margin-right:2px; border:1px solid #CCC;} +.defaultSkin table.mceListBoxEnabled:hover .mceText, .defaultSkin .mceListBoxHover .mceText, .defaultSkin .mceListBoxSelected .mceText {border:1px solid #A2ABC0; border-right:0; background:#FFF} +.defaultSkin table.mceListBoxEnabled:hover .mceOpen, .defaultSkin .mceListBoxHover .mceOpen, .defaultSkin .mceListBoxSelected .mceOpen {background-color:#FFF; border:1px solid #A2ABC0} +.defaultSkin .mceListBoxDisabled a.mceText {color:gray; background-color:transparent;} +.defaultSkin .mceListBoxMenu {overflow:auto; overflow-x:hidden} +.defaultSkin .mceOldBoxModel .mceListBox .mceText {height:22px} +.defaultSkin .mceOldBoxModel .mceListBox .mceOpen {width:11px; height:22px;} +.defaultSkin select.mceNativeListBox {font-family:'MS Sans Serif',sans-serif,Verdana,Arial; font-size:7pt; background:#F0F0EE; border:1px solid gray; margin-right:2px;} + +/* SplitButton */ +.defaultSkin .mceSplitButton {width:32px; height:20px; direction:ltr} +.defaultSkin .mceSplitButton a, .defaultSkin .mceSplitButton span {height:20px; display:block} +.defaultSkin .mceSplitButton a.mceAction {width:20px; border:1px solid #F0F0EE; border-right:0;} +.defaultSkin .mceSplitButton span.mceAction {width:20px; background-image:url(../../img/icons.gif);} +.defaultSkin .mceSplitButton a.mceOpen {width:9px; background:url(../../img/icons.gif) -741px 0; border:1px solid #F0F0EE;} +.defaultSkin .mceSplitButton span.mceOpen {display:none} +.defaultSkin table.mceSplitButtonEnabled:hover a.mceAction, .defaultSkin .mceSplitButtonHover a.mceAction, .defaultSkin .mceSplitButtonSelected a.mceAction {border:1px solid #0A246A; border-right:0; background-color:#B2BBD0} +.defaultSkin table.mceSplitButtonEnabled:hover a.mceOpen, .defaultSkin .mceSplitButtonHover a.mceOpen, .defaultSkin .mceSplitButtonSelected a.mceOpen {background-color:#B2BBD0; border:1px solid #0A246A;} +.defaultSkin .mceSplitButtonDisabled .mceAction, .defaultSkin .mceSplitButtonDisabled a.mceOpen {opacity:0.3; -ms-filter:'alpha(opacity=30)'; filter:alpha(opacity=30)} +.defaultSkin .mceSplitButtonActive a.mceAction {border:1px solid #0A246A; background-color:#C2CBE0} +.defaultSkin .mceSplitButtonActive a.mceOpen {border-left:0;} + +/* ColorSplitButton */ +.defaultSkin div.mceColorSplitMenu table {background:#FFF; border:1px solid gray} +.defaultSkin .mceColorSplitMenu td {padding:2px} +.defaultSkin .mceColorSplitMenu a {display:block; width:9px; height:9px; overflow:hidden; border:1px solid #808080} +.defaultSkin .mceColorSplitMenu td.mceMoreColors {padding:1px 3px 1px 1px} +.defaultSkin .mceColorSplitMenu a.mceMoreColors {width:100%; height:auto; text-align:center; font-family:Tahoma,Verdana,Arial,Helvetica; font-size:11px; line-height:20px; border:1px solid #FFF} +.defaultSkin .mceColorSplitMenu a.mceMoreColors:hover {border:1px solid #0A246A; background-color:#B6BDD2} +.defaultSkin a.mceMoreColors:hover {border:1px solid #0A246A} +.defaultSkin .mceColorPreview {margin-left:2px; width:16px; height:4px; overflow:hidden; background:#9a9b9a} +.defaultSkin .mce_forecolor span.mceAction, .defaultSkin .mce_backcolor span.mceAction {overflow:hidden; height:16px} + +/* Menu */ +.defaultSkin .mceMenu {position:absolute; left:0; top:0; z-index:1000; border:1px solid #D4D0C8; direction:ltr} +.defaultSkin .mceNoIcons span.mceIcon {width:0;} +.defaultSkin .mceNoIcons a .mceText {padding-left:10px} +.defaultSkin .mceMenu table {background:#FFF} +.defaultSkin .mceMenu a, .defaultSkin .mceMenu span, .defaultSkin .mceMenu {display:block} +.defaultSkin .mceMenu td {height:20px} +.defaultSkin .mceMenu a {position:relative;padding:3px 0 4px 0} +.defaultSkin .mceMenu .mceText {position:relative; display:block; font-family:Tahoma,Verdana,Arial,Helvetica; color:#000; cursor:default; margin:0; padding:0 25px 0 25px; display:block} +.defaultSkin .mceMenu span.mceText, .defaultSkin .mceMenu .mcePreview {font-size:11px} +.defaultSkin .mceMenu pre.mceText {font-family:Monospace} +.defaultSkin .mceMenu .mceIcon {position:absolute; top:0; left:0; width:22px;} +.defaultSkin .mceMenu .mceMenuItemEnabled a:hover, .defaultSkin .mceMenu .mceMenuItemActive {background-color:#dbecf3} +.defaultSkin td.mceMenuItemSeparator {background:#DDD; height:1px} +.defaultSkin .mceMenuItemTitle a {border:0; background:#EEE; border-bottom:1px solid #DDD} +.defaultSkin .mceMenuItemTitle span.mceText {color:#000; font-weight:bold; padding-left:4px} +.defaultSkin .mceMenuItemDisabled .mceText {color:#888} +.defaultSkin .mceMenuItemSelected .mceIcon {background:url(img/menu_check.gif)} +.defaultSkin .mceNoIcons .mceMenuItemSelected a {background:url(img/menu_arrow.gif) no-repeat -6px center} +.defaultSkin .mceMenu span.mceMenuLine {display:none} +.defaultSkin .mceMenuItemSub a {background:url(img/menu_arrow.gif) no-repeat top right;} +.defaultSkin .mceMenuItem td, .defaultSkin .mceMenuItem th {line-height: normal} + +/* Progress,Resize */ +.defaultSkin .mceBlocker {position:absolute; left:0; top:0; z-index:1000; opacity:0.5; -ms-filter:'alpha(opacity=50)'; filter:alpha(opacity=50); background:#FFF} +.defaultSkin .mceProgress {position:absolute; left:0; top:0; z-index:1001; background:url(img/progress.gif) no-repeat; width:32px; height:32px; margin:-16px 0 0 -16px} + +/* Rtl */ +.mceRtl .mceListBox .mceText {text-align: right; padding: 0 4px 0 0} +.mceRtl .mceMenuItem .mceText {text-align: right} + +/* Formats */ +.defaultSkin .mce_formatPreview a {font-size:10px} +.defaultSkin .mce_p span.mceText {} +.defaultSkin .mce_address span.mceText {font-style:italic} +.defaultSkin .mce_pre span.mceText {font-family:monospace} +.defaultSkin .mce_h1 span.mceText {font-weight:bolder; font-size: 2em} +.defaultSkin .mce_h2 span.mceText {font-weight:bolder; font-size: 1.5em} +.defaultSkin .mce_h3 span.mceText {font-weight:bolder; font-size: 1.17em} +.defaultSkin .mce_h4 span.mceText {font-weight:bolder; font-size: 1em} +.defaultSkin .mce_h5 span.mceText {font-weight:bolder; font-size: .83em} +.defaultSkin .mce_h6 span.mceText {font-weight:bolder; font-size: .75em} + +/* Theme */ +.defaultSkin span.mce_bold {background-position:0 0} +.defaultSkin span.mce_italic {background-position:-60px 0} +.defaultSkin span.mce_underline {background-position:-140px 0} +.defaultSkin span.mce_strikethrough {background-position:-120px 0} +.defaultSkin span.mce_undo {background-position:-160px 0} +.defaultSkin span.mce_redo {background-position:-100px 0} +.defaultSkin span.mce_cleanup {background-position:-40px 0} +.defaultSkin span.mce_bullist {background-position:-20px 0} +.defaultSkin span.mce_numlist {background-position:-80px 0} +.defaultSkin span.mce_justifyleft {background-position:-460px 0} +.defaultSkin span.mce_justifyright {background-position:-480px 0} +.defaultSkin span.mce_justifycenter {background-position:-420px 0} +.defaultSkin span.mce_justifyfull {background-position:-440px 0} +.defaultSkin span.mce_anchor {background-position:-200px 0} +.defaultSkin span.mce_indent {background-position:-400px 0} +.defaultSkin span.mce_outdent {background-position:-540px 0} +.defaultSkin span.mce_link {background-position:-500px 0} +.defaultSkin span.mce_unlink {background-position:-640px 0} +.defaultSkin span.mce_sub {background-position:-600px 0} +.defaultSkin span.mce_sup {background-position:-620px 0} +.defaultSkin span.mce_removeformat {background-position:-580px 0} +.defaultSkin span.mce_newdocument {background-position:-520px 0} +.defaultSkin span.mce_image {background-position:-380px 0} +.defaultSkin span.mce_help {background-position:-340px 0} +.defaultSkin span.mce_code {background-position:-260px 0} +.defaultSkin span.mce_hr {background-position:-360px 0} +.defaultSkin span.mce_visualaid {background-position:-660px 0} +.defaultSkin span.mce_charmap {background-position:-240px 0} +.defaultSkin span.mce_paste {background-position:-560px 0} +.defaultSkin span.mce_copy {background-position:-700px 0} +.defaultSkin span.mce_cut {background-position:-680px 0} +.defaultSkin span.mce_blockquote {background-position:-220px 0} +.defaultSkin .mce_forecolor span.mceAction {background-position:-720px 0} +.defaultSkin .mce_backcolor span.mceAction {background-position:-760px 0} +.defaultSkin span.mce_forecolorpicker {background-position:-720px 0} +.defaultSkin span.mce_backcolorpicker {background-position:-760px 0} + +/* Plugins */ +.defaultSkin span.mce_advhr {background-position:-0px -20px} +.defaultSkin span.mce_ltr {background-position:-20px -20px} +.defaultSkin span.mce_rtl {background-position:-40px -20px} +.defaultSkin span.mce_emotions {background-position:-60px -20px} +.defaultSkin span.mce_fullpage {background-position:-80px -20px} +.defaultSkin span.mce_fullscreen {background-position:-100px -20px} +.defaultSkin span.mce_iespell {background-position:-120px -20px} +.defaultSkin span.mce_insertdate {background-position:-140px -20px} +.defaultSkin span.mce_inserttime {background-position:-160px -20px} +.defaultSkin span.mce_absolute {background-position:-180px -20px} +.defaultSkin span.mce_backward {background-position:-200px -20px} +.defaultSkin span.mce_forward {background-position:-220px -20px} +.defaultSkin span.mce_insert_layer {background-position:-240px -20px} +.defaultSkin span.mce_insertlayer {background-position:-260px -20px} +.defaultSkin span.mce_movebackward {background-position:-280px -20px} +.defaultSkin span.mce_moveforward {background-position:-300px -20px} +.defaultSkin span.mce_media {background-position:-320px -20px} +.defaultSkin span.mce_nonbreaking {background-position:-340px -20px} +.defaultSkin span.mce_pastetext {background-position:-360px -20px} +.defaultSkin span.mce_pasteword {background-position:-380px -20px} +.defaultSkin span.mce_selectall {background-position:-400px -20px} +.defaultSkin span.mce_preview {background-position:-420px -20px} +.defaultSkin span.mce_print {background-position:-440px -20px} +.defaultSkin span.mce_cancel {background-position:-460px -20px} +.defaultSkin span.mce_save {background-position:-480px -20px} +.defaultSkin span.mce_replace {background-position:-500px -20px} +.defaultSkin span.mce_search {background-position:-520px -20px} +.defaultSkin span.mce_styleprops {background-position:-560px -20px} +.defaultSkin span.mce_table {background-position:-580px -20px} +.defaultSkin span.mce_cell_props {background-position:-600px -20px} +.defaultSkin span.mce_delete_table {background-position:-620px -20px} +.defaultSkin span.mce_delete_col {background-position:-640px -20px} +.defaultSkin span.mce_delete_row {background-position:-660px -20px} +.defaultSkin span.mce_col_after {background-position:-680px -20px} +.defaultSkin span.mce_col_before {background-position:-700px -20px} +.defaultSkin span.mce_row_after {background-position:-720px -20px} +.defaultSkin span.mce_row_before {background-position:-740px -20px} +.defaultSkin span.mce_merge_cells {background-position:-760px -20px} +.defaultSkin span.mce_table_props {background-position:-980px -20px} +.defaultSkin span.mce_row_props {background-position:-780px -20px} +.defaultSkin span.mce_split_cells {background-position:-800px -20px} +.defaultSkin span.mce_template {background-position:-820px -20px} +.defaultSkin span.mce_visualchars {background-position:-840px -20px} +.defaultSkin span.mce_abbr {background-position:-860px -20px} +.defaultSkin span.mce_acronym {background-position:-880px -20px} +.defaultSkin span.mce_attribs {background-position:-900px -20px} +.defaultSkin span.mce_cite {background-position:-920px -20px} +.defaultSkin span.mce_del {background-position:-940px -20px} +.defaultSkin span.mce_ins {background-position:-960px -20px} +.defaultSkin span.mce_pagebreak {background-position:0 -40px} +.defaultSkin span.mce_restoredraft {background-position:-20px -40px} +.defaultSkin span.mce_spellchecker {background-position:-540px -20px} +.defaultSkin span.mce_visualblocks {background-position: -40px -40px} diff --git a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/skins/wp_theme/content.css b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/skins/wp_theme/content.css index 23fef64..0a0cf91 100644 --- a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/skins/wp_theme/content.css +++ b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/skins/wp_theme/content.css @@ -1,144 +1,144 @@ - -body.mceForceColors {background:#FFF; color:#000;} -body.mceBrowserDefaults {background:transparent; color:inherit; font-size:inherit; font-family:inherit;} -td {color:#000; font-family:Verdana, Arial, Helvetica, sans-serif; font-size:10px; margin:8px;} -h1 {font-size: 2em} -h2 {font-size: 1.5em} -h3 {font-size: 1.17em} -h4 {font-size: 1em} -h5 {font-size: .83em} -h6 {font-size: .75em} -.mceItemTable, .mceItemTable td, .mceItemTable th, .mceItemTable caption, .mceItemVisualAid {border: 1px dashed #BBB;} -a.mceItemAnchor {display:inline-block; -webkit-user-select:all; -webkit-user-modify:read-only; -moz-user-select:all; -moz-user-modify:read-only; width:11px !important; height:11px !important; background:url(../default/img/items.gif) no-repeat center center} -span.mceItemNbsp {background: #DDD} -td.mceSelected, th.mceSelected {background-color:#3399ff !important} -img {border:0;} -table, img, hr, .mceItemAnchor {cursor:default} -table td, table th {cursor:text} -ins {border-bottom:1px solid green; text-decoration: none; color:green} -del {color:red; text-decoration:line-through} -cite {border-bottom:1px dashed blue} -acronym {border-bottom:1px dotted #CCC; cursor:help} -abbr {border-bottom:1px dashed #CCC; cursor:help} - -img:-moz-broken {-moz-force-broken-image-icon:1; width:24px; height:24px} -font[face=mceinline] {font-family:inherit !important} -*[contentEditable]:focus {outline:0} - -.mceItemMedia {border:1px dotted #cc0000; background-position:center; background-repeat:no-repeat; background-color:#ffffcc} -.mceItemShockWave {background-image:url(../../img/shockwave.gif)} -.mceItemFlash {background-image:url(../../img/flash.gif)} -.mceItemQuickTime {background-image:url(../../img/quicktime.gif)} -.mceItemWindowsMedia {background-image:url(../../img/windowsmedia.gif)} -.mceItemRealMedia {background-image:url(../../img/realmedia.gif)} -.mceItemVideo {background-image:url(../../img/video.gif)} -.mceItemAudio {background-image:url(../../img/video.gif)} -.mceItemIframe {background-image:url(../../img/iframe.gif)} -.mcePageBreak {display:block;border:0;width:100%;height:12px;border-top:1px dotted #ccc;margin-top:15px;background:#fff url(../../img/pagebreak.gif) no-repeat center top;} - -/* WordPress styles */ -body { - font-family: Georgia, "Times New Roman", "Bitstream Charter", Times, serif; - font-size: 13px; - line-height: 19px; - color: #333; - margin: 10px; - min-height: 100%; -} - -br[data-mce-bogus] { - line-height: 1em; - margin-top: -1em; -} - -br[data-mce-bogus]:only-child { - line-height: inherit; - margin-top: inherit; -} - -.aligncenter, -dl.aligncenter { - display: block; - margin-left: auto; - margin-right: auto; -} - -.alignleft { - float: left; -} - -.alignright { - float: right; -} - -.wp-caption { - border: 1px solid #ddd; - text-align: center; - background-color: #f3f3f3; - padding-top: 4px; - margin: 10px 0; - -webkit-border-radius: 3px; - border-radius: 3px; -} - -.mceIEcenter { - text-align: center; -} - -.wp-caption img { - margin: 0; - padding: 0; - border: 0 none; - -webkit-user-drag: none; -} - -.wp-caption-dd { - font-size: 11px; - line-height: 17px; - padding: 0 4px 5px; - margin: 0; -} - -pre { - font: 12px/18px Consolas, Monaco, monospace; -} - -td { - color: #000; - font-size: 11px; - margin: 8px; -} - -/* Styles for the WordPress plugins */ -img.mceWPnextpage, -img.mceWPmore { - border: 0; - border-top: 1px dotted #cccccc; - display: block; - width: 95%; - height: 12px; - margin: 15px auto 0; -} - -img.mceWPmore { - background: transparent url("img/more_bug.gif") no-repeat right top; -} - -img.mceWPnextpage { - background: transparent url("img/page_bug.gif") no-repeat right top; -} - -img.wpGallery { - border: 1px dashed #888; - background: #f2f8ff url("img/gallery.png") no-repeat scroll center center; - width: 99%; - height: 250px; -} - -img.wp-oembed { - border: 1px dashed #888; - background: #f7f5f2 url("img/embedded.png") no-repeat scroll center center; - width: 300px; - height: 250px; -} - + +body.mceForceColors {background:#FFF; color:#000;} +body.mceBrowserDefaults {background:transparent; color:inherit; font-size:inherit; font-family:inherit;} +td {color:#000; font-family:Verdana, Arial, Helvetica, sans-serif; font-size:10px; margin:8px;} +h1 {font-size: 2em} +h2 {font-size: 1.5em} +h3 {font-size: 1.17em} +h4 {font-size: 1em} +h5 {font-size: .83em} +h6 {font-size: .75em} +.mceItemTable, .mceItemTable td, .mceItemTable th, .mceItemTable caption, .mceItemVisualAid {border: 1px dashed #BBB;} +a.mceItemAnchor {display:inline-block; -webkit-user-select:all; -webkit-user-modify:read-only; -moz-user-select:all; -moz-user-modify:read-only; width:11px !important; height:11px !important; background:url(../default/img/items.gif) no-repeat center center} +span.mceItemNbsp {background: #DDD} +td.mceSelected, th.mceSelected {background-color:#3399ff !important} +img {border:0;} +table, img, hr, .mceItemAnchor {cursor:default} +table td, table th {cursor:text} +ins {border-bottom:1px solid green; text-decoration: none; color:green} +del {color:red; text-decoration:line-through} +cite {border-bottom:1px dashed blue} +acronym {border-bottom:1px dotted #CCC; cursor:help} +abbr {border-bottom:1px dashed #CCC; cursor:help} + +img:-moz-broken {-moz-force-broken-image-icon:1; width:24px; height:24px} +font[face=mceinline] {font-family:inherit !important} +*[contentEditable]:focus {outline:0} + +.mceItemMedia {border:1px dotted #cc0000; background-position:center; background-repeat:no-repeat; background-color:#ffffcc} +.mceItemShockWave {background-image:url(../../img/shockwave.gif)} +.mceItemFlash {background-image:url(../../img/flash.gif)} +.mceItemQuickTime {background-image:url(../../img/quicktime.gif)} +.mceItemWindowsMedia {background-image:url(../../img/windowsmedia.gif)} +.mceItemRealMedia {background-image:url(../../img/realmedia.gif)} +.mceItemVideo {background-image:url(../../img/video.gif)} +.mceItemAudio {background-image:url(../../img/video.gif)} +.mceItemIframe {background-image:url(../../img/iframe.gif)} +.mcePageBreak {display:block;border:0;width:100%;height:12px;border-top:1px dotted #ccc;margin-top:15px;background:#fff url(../../img/pagebreak.gif) no-repeat center top;} + +/* WordPress styles */ +body { + font-family: Georgia, "Times New Roman", "Bitstream Charter", Times, serif; + font-size: 13px; + line-height: 19px; + color: #333; + margin: 10px; + min-height: 100%; +} + +br[data-mce-bogus] { + line-height: 1em; + margin-top: -1em; +} + +br[data-mce-bogus]:only-child { + line-height: inherit; + margin-top: inherit; +} + +.aligncenter, +dl.aligncenter { + display: block; + margin-left: auto; + margin-right: auto; +} + +.alignleft { + float: left; +} + +.alignright { + float: right; +} + +.wp-caption { + border: 1px solid #ddd; + text-align: center; + background-color: #f3f3f3; + padding-top: 4px; + margin: 10px 0; + -webkit-border-radius: 3px; + border-radius: 3px; +} + +.mceIEcenter { + text-align: center; +} + +.wp-caption img { + margin: 0; + padding: 0; + border: 0 none; + -webkit-user-drag: none; +} + +.wp-caption-dd { + font-size: 11px; + line-height: 17px; + padding: 0 4px 5px; + margin: 0; +} + +pre { + font: 12px/18px Consolas, Monaco, monospace; +} + +td { + color: #000; + font-size: 11px; + margin: 8px; +} + +/* Styles for the WordPress plugins */ +img.mceWPnextpage, +img.mceWPmore { + border: 0; + border-top: 1px dotted #cccccc; + display: block; + width: 95%; + height: 12px; + margin: 15px auto 0; +} + +img.mceWPmore { + background: transparent url("img/more_bug.gif") no-repeat right top; +} + +img.mceWPnextpage { + background: transparent url("img/page_bug.gif") no-repeat right top; +} + +img.wpGallery { + border: 1px dashed #888; + background: #f2f8ff url("img/gallery.png") no-repeat scroll center center; + width: 99%; + height: 250px; +} + +img.wp-oembed { + border: 1px dashed #888; + background: #f7f5f2 url("img/embedded.png") no-repeat scroll center center; + width: 300px; + height: 250px; +} + diff --git a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/skins/wp_theme/dialog.css b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/skins/wp_theme/dialog.css index fe48d85..7b77e68 100644 --- a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/skins/wp_theme/dialog.css +++ b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/skins/wp_theme/dialog.css @@ -1,121 +1,121 @@ -/* Generic */ -body { -font-family:Verdana, Arial, Helvetica, sans-serif; font-size:11px; -background:#f1f1f1; -padding:0; -margin:8px 8px 0 8px; -} - -html {background:#f1f1f1;} -td {font-family:Verdana, Arial, Helvetica, sans-serif; font-size:10px;} -textarea {resize:none;outline:none;} -a:link, a:visited {color:black;} -a:hover {color:#2B6FB6;} -.nowrap {white-space: nowrap} - -/* Forms */ -fieldset {margin:0; padding:4px; border:1px solid #dfdfdf; font-family:Verdana, Arial; font-size:10px;} -legend {color:#2B6FB6; font-weight:bold;} -label.msg {display:none;} -label.invalid {color:#EE0000; display:inline;} -input.invalid {border:1px solid #EE0000;} -input {background:#FFF; border:1px solid #dfdfdf;} -input, select, textarea {font-family:Verdana, Arial, Helvetica, sans-serif; font-size:10px;} -input, select, textarea {border:1px solid #dfdfdf;} -input.radio {border:1px none #000000; background:transparent; vertical-align:middle;} -input.checkbox {border:1px none #000000; background:transparent; vertical-align:middle;} -.input_noborder {border:0;} - -/* Buttons */ -#insert, #cancel, #apply, .mceActionPanel .button, input.mceButton, .updateButton { - border: 1px solid #bbb; - margin:0; - padding:0 0 1px; - font-weight:bold; - font-size: 11px; - width:94px; - height:24px; - color:#000; - cursor:pointer; - -webkit-border-radius: 3px; - border-radius: 3px; - background-color: #eee; /* Fallback */ - background-image: -ms-linear-gradient(bottom, #ddd, #fff); /* IE10 */ - background-image: -moz-linear-gradient(bottom, #ddd, #fff); /* Firefox */ - background-image: -o-linear-gradient(bottom, #ddd, #fff); /* Opera */ - background-image: -webkit-gradient(linear, left bottom, left top, from(#ddd), to(#fff)); /* old Webkit */ - background-image: -webkit-linear-gradient(bottom, #ddd, #fff); /* new Webkit */ - background-image: linear-gradient(bottom, #ddd, #fff); /* proposed W3C Markup */ -} -#insert:hover, #cancel:hover, input.mceButton:hover, .updateButton:hover, -#insert:focus, #cancel:focus, input.mceButton:focus, .updateButton:focus { - border: 1px solid #555; -} - -/* Browse */ -a.browse span {display:block; width:20px; height:18px; background:url(../../img/icons.gif) -860px 0; border:1px solid #FFF; margin-left:1px;} -.mceOldBoxModel a.browse span {width:22px; height:20px;} -a.browse:hover span {border:1px solid #0A246A; background-color:#B2BBD0;} -a.browse span.disabled {border:1px solid white; -moz-opacity:0.3; opacity:0.3; filter:progid:DXImageTransform.Microsoft.Alpha(opacity=30);} -a.browse:hover span.disabled {border:1px solid white; background-color:transparent;} -a.pickcolor span {display:block; width:20px; height:16px; background:url(../../img/icons.gif) -840px 0; margin-left:2px;} -.mceOldBoxModel a.pickcolor span {width:21px; height:17px;} -a.pickcolor:hover span {background-color:#B2BBD0;} -a.pickcolor, a.browse {text-decoration:none} - -/* Charmap */ -table.charmap {border:1px solid #AAA; text-align:center} -td.charmap, #charmap a {width:18px; height:18px; color:#000; border:1px solid #AAA; text-align:center; font-size:12px; vertical-align:middle; line-height: 18px;} -#charmap a {display:block; color:#000; text-decoration:none; border:0} -#charmap a:hover {background:#CCC;color:#2B6FB6} -#charmap #codeN {font-size:10px; font-family:Arial,Helvetica,sans-serif; text-align:center} -#charmap #codeV {font-size:40px; height:80px; border:1px solid #AAA; text-align:center} -#charmap #charmapView {background-color:#fff;} - -/* Source */ -.wordWrapCode {vertical-align:middle; border:1px none #000000; background:transparent;} -.mceActionPanel {margin-top:5px;} - -/* Tabs classes */ -.tabs {width:100%; height:18px; line-height:normal; background:url(img/tabs.gif) repeat-x 0 -72px;} -.tabs ul {margin:0; padding:0; list-style:none;} -.tabs li {float:left; background:url(img/tabs.gif) no-repeat 0 0; margin:0 2px 0 0; padding:0 0 0 10px; line-height:17px; height:18px; display:block;} -.tabs li.current {background:url(img/tabs.gif) no-repeat 0 -18px; margin-right:2px;} -.tabs span {float:left; display:block; background:url(img/tabs.gif) no-repeat right -36px; padding:0px 10px 0 0;} -.tabs .current span {background:url(img/tabs.gif) no-repeat right -54px;} -.tabs a {text-decoration:none; font-family:Verdana, Arial; font-size:10px;} -.tabs a:link, .tabs a:visited, .tabs a:hover {color:black;} - -/* Panels */ -.panel_wrapper div.panel {display:none;} -.panel_wrapper div.current {display:block; width:100%; height:300px; overflow:visible;} -.panel_wrapper {border:1px solid #919B9C; border-top:0px; padding:10px; padding-top:5px; clear:both; background:white;} - -/* Columns */ -.column {float:left;} -.properties {width:100%;} -.properties .column1 {} -.properties .column2 {text-align:left;} - -/* Titles */ -h1, h2, h3, h4 {color:#2B6FB6; margin:0; padding:0; padding-top:5px;} -h3 {font-size:14px;} -.title {font-size:12px; font-weight:bold; color:#2B6FB6;} - -/* Dialog specific */ -#link .panel_wrapper, #link div.current {height:125px;} -#image .panel_wrapper, #image div.current {height:200px;} -#plugintable thead {font-weight:bold; background:#DDD;} -#plugintable, #about #plugintable td {border:1px solid #919B9C;} -#plugintable {width:96%; margin-top:10px;} -#pluginscontainer {height:290px; overflow:auto;} -#colorpicker #preview {float:right; width:50px; height:14px;line-height:1px; border:1px solid black; margin-left:5px;} -#colorpicker #colors {float:left; border:1px solid gray; cursor:crosshair;} -#colorpicker #light {border:1px solid gray; margin-left:5px; float:left;width:15px; height:150px; cursor:crosshair;} -#colorpicker #light div {overflow:hidden;} -#colorpicker #previewblock {float:right; padding-left:10px; height:20px;} -#colorpicker .panel_wrapper div.current {height:175px;} -#colorpicker #namedcolors {width:150px;} -#colorpicker #namedcolors a {display:block; float:left; width:10px; height:10px; margin:1px 1px 0 0; overflow:hidden;} -#colorpicker #colornamecontainer {margin-top:5px;} -#colorpicker #picker_panel fieldset {margin:auto;width:325px;} +/* Generic */ +body { +font-family:Verdana, Arial, Helvetica, sans-serif; font-size:11px; +background:#f1f1f1; +padding:0; +margin:8px 8px 0 8px; +} + +html {background:#f1f1f1;} +td {font-family:Verdana, Arial, Helvetica, sans-serif; font-size:10px;} +textarea {resize:none;outline:none;} +a:link, a:visited {color:black;} +a:hover {color:#2B6FB6;} +.nowrap {white-space: nowrap} + +/* Forms */ +fieldset {margin:0; padding:4px; border:1px solid #dfdfdf; font-family:Verdana, Arial; font-size:10px;} +legend {color:#2B6FB6; font-weight:bold;} +label.msg {display:none;} +label.invalid {color:#EE0000; display:inline;} +input.invalid {border:1px solid #EE0000;} +input {background:#FFF; border:1px solid #dfdfdf;} +input, select, textarea {font-family:Verdana, Arial, Helvetica, sans-serif; font-size:10px;} +input, select, textarea {border:1px solid #dfdfdf;} +input.radio {border:1px none #000000; background:transparent; vertical-align:middle;} +input.checkbox {border:1px none #000000; background:transparent; vertical-align:middle;} +.input_noborder {border:0;} + +/* Buttons */ +#insert, #cancel, #apply, .mceActionPanel .button, input.mceButton, .updateButton { + border: 1px solid #bbb; + margin:0; + padding:0 0 1px; + font-weight:bold; + font-size: 11px; + width:94px; + height:24px; + color:#000; + cursor:pointer; + -webkit-border-radius: 3px; + border-radius: 3px; + background-color: #eee; /* Fallback */ + background-image: -ms-linear-gradient(bottom, #ddd, #fff); /* IE10 */ + background-image: -moz-linear-gradient(bottom, #ddd, #fff); /* Firefox */ + background-image: -o-linear-gradient(bottom, #ddd, #fff); /* Opera */ + background-image: -webkit-gradient(linear, left bottom, left top, from(#ddd), to(#fff)); /* old Webkit */ + background-image: -webkit-linear-gradient(bottom, #ddd, #fff); /* new Webkit */ + background-image: linear-gradient(bottom, #ddd, #fff); /* proposed W3C Markup */ +} +#insert:hover, #cancel:hover, input.mceButton:hover, .updateButton:hover, +#insert:focus, #cancel:focus, input.mceButton:focus, .updateButton:focus { + border: 1px solid #555; +} + +/* Browse */ +a.browse span {display:block; width:20px; height:18px; background:url(../../img/icons.gif) -860px 0; border:1px solid #FFF; margin-left:1px;} +.mceOldBoxModel a.browse span {width:22px; height:20px;} +a.browse:hover span {border:1px solid #0A246A; background-color:#B2BBD0;} +a.browse span.disabled {border:1px solid white; -moz-opacity:0.3; opacity:0.3; filter:progid:DXImageTransform.Microsoft.Alpha(opacity=30);} +a.browse:hover span.disabled {border:1px solid white; background-color:transparent;} +a.pickcolor span {display:block; width:20px; height:16px; background:url(../../img/icons.gif) -840px 0; margin-left:2px;} +.mceOldBoxModel a.pickcolor span {width:21px; height:17px;} +a.pickcolor:hover span {background-color:#B2BBD0;} +a.pickcolor, a.browse {text-decoration:none} + +/* Charmap */ +table.charmap {border:1px solid #AAA; text-align:center} +td.charmap, #charmap a {width:18px; height:18px; color:#000; border:1px solid #AAA; text-align:center; font-size:12px; vertical-align:middle; line-height: 18px;} +#charmap a {display:block; color:#000; text-decoration:none; border:0} +#charmap a:hover {background:#CCC;color:#2B6FB6} +#charmap #codeN {font-size:10px; font-family:Arial,Helvetica,sans-serif; text-align:center} +#charmap #codeV {font-size:40px; height:80px; border:1px solid #AAA; text-align:center} +#charmap #charmapView {background-color:#fff;} + +/* Source */ +.wordWrapCode {vertical-align:middle; border:1px none #000000; background:transparent;} +.mceActionPanel {margin-top:5px;} + +/* Tabs classes */ +.tabs {width:100%; height:18px; line-height:normal; background:url(img/tabs.gif) repeat-x 0 -72px;} +.tabs ul {margin:0; padding:0; list-style:none;} +.tabs li {float:left; background:url(img/tabs.gif) no-repeat 0 0; margin:0 2px 0 0; padding:0 0 0 10px; line-height:17px; height:18px; display:block;} +.tabs li.current {background:url(img/tabs.gif) no-repeat 0 -18px; margin-right:2px;} +.tabs span {float:left; display:block; background:url(img/tabs.gif) no-repeat right -36px; padding:0px 10px 0 0;} +.tabs .current span {background:url(img/tabs.gif) no-repeat right -54px;} +.tabs a {text-decoration:none; font-family:Verdana, Arial; font-size:10px;} +.tabs a:link, .tabs a:visited, .tabs a:hover {color:black;} + +/* Panels */ +.panel_wrapper div.panel {display:none;} +.panel_wrapper div.current {display:block; width:100%; height:300px; overflow:visible;} +.panel_wrapper {border:1px solid #919B9C; border-top:0px; padding:10px; padding-top:5px; clear:both; background:white;} + +/* Columns */ +.column {float:left;} +.properties {width:100%;} +.properties .column1 {} +.properties .column2 {text-align:left;} + +/* Titles */ +h1, h2, h3, h4 {color:#2B6FB6; margin:0; padding:0; padding-top:5px;} +h3 {font-size:14px;} +.title {font-size:12px; font-weight:bold; color:#2B6FB6;} + +/* Dialog specific */ +#link .panel_wrapper, #link div.current {height:125px;} +#image .panel_wrapper, #image div.current {height:200px;} +#plugintable thead {font-weight:bold; background:#DDD;} +#plugintable, #about #plugintable td {border:1px solid #919B9C;} +#plugintable {width:96%; margin-top:10px;} +#pluginscontainer {height:290px; overflow:auto;} +#colorpicker #preview {float:right; width:50px; height:14px;line-height:1px; border:1px solid black; margin-left:5px;} +#colorpicker #colors {float:left; border:1px solid gray; cursor:crosshair;} +#colorpicker #light {border:1px solid gray; margin-left:5px; float:left;width:15px; height:150px; cursor:crosshair;} +#colorpicker #light div {overflow:hidden;} +#colorpicker #previewblock {float:right; padding-left:10px; height:20px;} +#colorpicker .panel_wrapper div.current {height:175px;} +#colorpicker #namedcolors {width:150px;} +#colorpicker #namedcolors a {display:block; float:left; width:10px; height:10px; margin:1px 1px 0 0; overflow:hidden;} +#colorpicker #colornamecontainer {margin-top:5px;} +#colorpicker #picker_panel fieldset {margin:auto;width:325px;} diff --git a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/skins/wp_theme/ui.css b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/skins/wp_theme/ui.css index 759d64a..ecddec9 100644 --- a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/skins/wp_theme/ui.css +++ b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/skins/wp_theme/ui.css @@ -1 +1 @@ -.wp_themeSkin table,.wp_themeSkin tbody,.wp_themeSkin a,.wp_themeSkin img,.wp_themeSkin tr,.wp_themeSkin div,.wp_themeSkin td,.wp_themeSkin iframe,.wp_themeSkin span,.wp_themeSkin *,.wp_themeSkin .mceText{border:0;margin:0;padding:0;white-space:nowrap;text-decoration:none;font-weight:normal;cursor:default;vertical-align:baseline;width:auto;border-collapse:separate}.wp_themeSkin a:hover,.wp_themeSkin a:link,.wp_themeSkin a:visited,.wp_themeSkin a:active{text-decoration:none;font-weight:normal;cursor:default}.wp_themeSkin table td{vertical-align:middle}.wp_themeSkin *,.wp_themeSkin a:hover,.wp_themeSkin a:link,.wp_themeSkin a:visited,.wp_themeSkin a:active{color:#000}.wp_themeSkin iframe{display:block}.wp_themeSkin #mce_fullscreen_ifr{background-color:#fff}.wp_themeSkin .mceToolbar{padding:1px}.wp_themeSkin .mceExternalToolbar{position:absolute;border-bottom:0;display:none}.wp_themeSkin .mceExternalToolbar td.mceToolbar{padding-right:13px}.wp_themeSkin .mceExternalClose{position:absolute;top:3px;right:3px;width:7px;height:7px;background:url("../../img/icons.gif") -820px 0}.wp_themeSkin table.mceToolbar,.wp_themeSkin tr.mceFirst .mceToolbar tr td,.wp_themeSkin tr.mceLast .mceToolbar tr td{border:0;margin:0;padding:0}.wp_themeSkin table.mceLayout{border-color: #CCCCCC #CCCCCC #DFDFDF;border-style: solid;border-top-left-radius: 3px; border-top-right-radius: 3px; border-width: 1px;}.wp_themeSkin .mceStatusbar{display:block;font-family:Arial,"Bitstream Vera Sans",Helvetica,Verdana,sans-serif;font-size:12px;line-height:16px;padding:0 0 0 8px;overflow:visible;height:20px;border-top:1px solid #dfdfdf;color:#000;background-color:#f5f5f5}.rtl .wp_themeSkin .mceStatusbar{padding:0 8px 0 0}.wp_themeSkin .mceStatusbar *{color:#555}.wp_themeSkin .mceStatusbar div{float:left;padding:2px}.rtl .wp_themeSkin .mceStatusbar div{float:right}.wp_themeSkin .mceStatusbar a.mceResize{display:block;float:right;background:url("../../img/icons.gif") -800px 0;width:20px;height:20px;cursor:se-resize}.rtl .wp_themeSkin .mceStatusbar a.mceResize{float:left}.wp_themeSkin .mceStatusbar a:hover{text-decoration:underline}.wp_themeSkin table.mceToolbar{margin:0 6px 2px}.wp_themeSkin #content_toolbar1{margin-top:2px}.wp_themeSkin .mceToolbar .mceToolbarEndListBox span{display:none}.wp_themeSkin span.mceIcon,.wp_themeSkin img.mceIcon{display:block;width:20px;height:20px}.wp_themeSkin .mceIcon{background:url("../../img/icons.gif") no-repeat 20px 20px}.wp_themeSkin .mceButton{display:block;width:20px;height:20px;cursor:default;padding:1px 2px;margin:1px;-webkit-border-radius:2px;border-radius:2px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.15),inset 0 0 2px 1px #fff;-moz-box-shadow:0 1px 0 rgba(0,0,0,0.15),inset 0 0 2px 1px #fff;box-shadow:0 1px 0 rgba(0,0,0,0.15),inset 0 0 2px 1px #fff}.wp_themeSkin a.mceButtonEnabled:hover{background-image:inherit 0 -10px}.wp_themeSkin .mceOldBoxModel a.mceButton span,.wp_themeSkin .mceOldBoxModel a.mceButton img{margin:0 0 0 1px}.wp_themeSkin a.mceButton:active,.wp_themeSkin a.mceButtonActive,.wp_themeSkin a.mceButtonActive:hover,.wp_themeSkin a.mceButtonSelected{-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.15),inset 0 0 2px 1px #fff;-moz-box-shadow:0 1px 0 rgba(0,0,0,0.15),inset 0 0 2px 1px #fff;box-shadow:0 1px 0 rgba(0,0,0,0.15),inset 0 0 2px 1px #fff}.wp_themeSkin .mceButtonDisabled .mceIcon{opacity:.5;filter:alpha(opacity=50)}.wp_themeSkin .mceSeparator{height:24px;width:1px;display:block;background:transparent;overflow:hidden;margin:0 2px}.wp_themeSkin .mceListBox,.wp_themeSkin .mceListBox a{display:block}.wp_themeSkin .mceListBox .mceText{padding:1px 2px 1px 5px;text-align:left;text-decoration:none;width:70px;-webkit-border-bottom-left-radius:2px;-webkit-border-top-left-radius:2px;border-bottom-left-radius:2px;border-top-left-radius:2px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.15),inset 0 0 2px 1px #fff;-moz-box-shadow:0 1px 0 rgba(0,0,0,0.15),inset 0 0 2px 1px #fff;box-shadow:0 1px 0 rgba(0,0,0,0.15),inset 0 0 2px 1px #fff;font-family:Arial,"Bitstream Vera Sans",Helvetica,Verdana,sans-serif;font-size:12px;height:20px;line-height:20px;overflow:hidden}.wp_themeSkin .mceListBox{margin:1px;direction:ltr}.wp_themeSkin .mceListBox .mceOpen{width:14px;height:20px;border-collapse:separate;padding:1px;-webkit-border-bottom-left-radius:0;-webkit-border-top-left-radius:0;border-bottom-left-radius:0;border-top-left-radius:0;-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.15),inset 0 0 2px 1px #fff;-moz-box-shadow:0 1px 0 rgba(0,0,0,0.15),inset 0 0 2px 1px #fff;box-shadow:0 1px 0 rgba(0,0,0,0.15),inset 0 0 2px 1px #fff}.wp_themeSkin .mceListBox .mceOpen span{display:block;width:14px;height:20px;background-image:url("./img/down_arrow.gif");background-position:2px 1px;background-repeat:no-repeat}.wp_themeSkin table.mceListBoxEnabled:hover .mceText,.wp_themeSkin .mceListBoxHover .mceText,.wp_themeSkin .mceListBoxSelected .mceText,.wp_themeSkin table.mceListBoxEnabled:hover .mceOpen,.wp_themeSkin .mceListBoxHover .mceOpen,.wp_themeSkin .mceListBoxSelected .mceOpen{background-image:none}.wp_themeSkin .mceListBoxDisabled .mceText{color:gray}.wp_themeSkin .mceListBoxMenu{overflow:auto;overflow-x:hidden}.wp_themeSkin .mceOldBoxModel .mceListBox .mceText{height:22px}.wp_themeSkin select.mceListBox{font-family:Arial,"Bitstream Vera Sans",Helvetica,Verdana,sans-serif;font-size:12px;border-color:#b2b2b2;background-color:#fff}.wp_themeSkin .mceSplitButton a,.wp_themeSkin .mceSplitButton span{display:block;height:20px}.wp_themeSkin .mceSplitButton{display:block;margin:1px;direction:ltr}.wp_themeSkin table.mceSplitButton td{padding:2px;-webkit-border-radius:2px;border-radius:2px}.wp_themeSkin table.mceSplitButton td a{-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.15),inset 0 0 2px 1px #fff;-moz-box-shadow:0 1px 0 rgba(0,0,0,0.15),inset 0 0 2px 1px #fff;box-shadow:0 1px 0 rgba(0,0,0,0.15),inset 0 0 2px 1px #fff}.wp_themeSkin table.mceSplitButton:hover td{background-image:inherit 0 -10px}.wp_themeSkin .mceSplitButton a.mceAction{height:20px;width:20px;padding:1px 2px}.wp_themeSkin .mceSplitButton span.mceAction{background-image:url("../../img/icons.gif");background-repeat:no-repeat;background-color:transparent;width:20px}.wp_themeSkin .mceSplitButton a.mceOpen{width:10px;height:20px;background-image:url("./img/down_arrow.gif");background-position:1px 2px;background-repeat:no-repeat;padding:1px;border-left:0 none!important}.wp_themeSkin .mceSplitButton span.mceOpen{display:none}.wp_themeSkin .mceSplitButtonDisabled .mceAction{opacity:.3;filter:alpha(opacity=30)}.wp_themeSkin .mceListBox a.mceText,.wp_themeSkin .mceSplitButton a.mceAction{-webkit-border-bottom-left-radius:2px;-webkit-border-top-left-radius:2px;border-bottom-left-radius:2px;border-top-left-radius:2px}.wp_themeSkin .mceSplitButton a.mceOpen,.wp_themeSkin .mceListBox a.mceOpen{-webkit-border-bottom-right-radius:2px;-webkit-border-top-right-radius:2px;border-bottom-right-radius:2px;border-top-right-radius:2px}.wp_themeSkin span.mce_undo,.wp_themeSkin span.mce_redo,.wp_themeSkin span.mce_bullist,.wp_themeSkin span.mce_numlist,.wp_themeSkin span.mce_blockquote,.wp_themeSkin span.mce_charmap,.wp_themeSkin span.mce_bold,.wp_themeSkin span.mce_italic,.wp_themeSkin span.mce_underline,.wp_themeSkin span.mce_justifyleft,.wp_themeSkin span.mce_justifyright,.wp_themeSkin span.mce_justifycenter,.wp_themeSkin span.mce_justifyfull,.wp_themeSkin span.mce_indent,.wp_themeSkin span.mce_outdent,.wp_themeSkin span.mce_link,.wp_themeSkin span.mce_unlink,.wp_themeSkin span.mce_help,.wp_themeSkin span.mce_removeformat,.wp_themeSkin span.mce_fullscreen,.wp_themeSkin span.mce_wp_fullscreen,.wp_themeSkin span.mce_media,.wp_themeSkin span.mce_pastetext,.wp_themeSkin span.mce_pasteword,.wp_themeSkin span.mce_wp_help,.wp_themeSkin span.mce_wp_adv,.wp_themeSkin span.mce_wp_more,.wp_themeSkin span.mce_strikethrough,.wp_themeSkin span.mce_spellchecker,.wp_themeSkin span.mce_forecolor,.wp_themeSkin .mce_forecolorpicker,.wp_themeSkin .mceSplitButton .mce_spellchecker span.mce_spellchecker,.wp_themeSkin .mceSplitButton .mce_forecolor span.mce_forecolor,.wp_themeSkin .mceSplitButton span.mce_numlist,.wp_themeSkin .mceSplitButton span.mce_bullist{background-image:url(./img/wpicons.png)}.wp_themeSkin div.mceColorSplitMenu table{background-color:#ebebeb;border-color:#b2b2b2}.wp_themeSkin .mceColorSplitMenu td{padding:2px}.wp_themeSkin .mceColorSplitMenu a{display:block;width:9px;height:9px;overflow:hidden;border-color:#b2b2b2}.wp_themeSkin .mceColorSplitMenu td.mceMoreColors{padding:1px 3px 1px 1px}.wp_themeSkin .mceColorSplitMenu a.mceMoreColors{width:100%;height:auto;text-align:center;font-family:Tahoma,Verdana,Arial,Helvetica;font-size:11px;line-height:20px;border-color:#fff}.wp_themeSkin .mceColorPreview{margin:-5px 0 0 2px;width:16px;height:4px;overflow:hidden}.wp_themeSkin .mceMenu{position:absolute;left:0;top:0;z-index:1000;border-color:#ddd}.wp_themeSkin .mceNoIcons span.mceIcon{width:0}.wp_themeSkin .mceNoIcons a .mceText{padding-left:10px}.wp_themeSkin .mceMenu table{background-color:#ebeaeb}.wp_themeSkin .mceMenu a,.wp_themeSkin .mceMenu span,.wp_themeSkin .mceMenu{display:block}.wp_themeSkin .mceMenu td{height:20px;overflow:hidden}.wp_themeSkin .mceMenu a{position:relative;padding:3px 0 4px 0;text-decoration:none!important}.wp_themeSkin .mceMenu .mceText{position:relative;display:block;font-family:Tahoma,Verdana,Arial,Helvetica;cursor:default;margin:0;padding:0 25px;color:#000}.wp_themeSkin .mceMenu span.mceText,.wp_themeSkin .mceMenu .mcePreview{font-size:12px}.wp_themeSkin .mceMenu pre.mceText{font-family:Monospace}.wp_themeSkin .mceMenu .mceIcon{position:absolute;top:0;left:0;width:22px}.wp_themeSkin .mceMenu .mceMenuItemEnabled a:hover,.wp_themeSkin .mceMenu .mceMenuItemActive{background-color:#f5f5f5}.wp_themeSkin td.mceMenuItemSeparator{height:1px;background-color:#aaa}.wp_themeSkin .mceMenuItemTitle a{border-top:0;border-right:0;border-left:0;border-bottom:1px solid #aaa;text-decoration:none!important;background-color:#ccc}.wp_themeSkin .mceMenuItemTitle span.mceText{font-weight:bold;padding-left:4px;color:#000}.wp_themeSkin .mceMenuItemSelected .mceIcon{background:url("../js/tinymce/themes/advanced/skins/default/img/menu_check.gif");color:#888}.wp_themeSkin .mceNoIcons .mceMenuItemSelected a{background:url("../js/tinymce/themes/advanced/skins/default/img/menu_arrow.gif") no-repeat -6px center}.wp_themeSkin .mceMenu span.mceMenuLine{display:none}.wp_themeSkin .mceMenuItemSub a{background:url("../js/tinymce/themes/advanced/skins/default/img/menu_arrow.gif") no-repeat top right}.wp_themeSkin .mceBlocker{position:absolute;left:0;top:0;z-index:1000;opacity:.5;filter:alpha(opacity=50);background:#FFF}.wp_themeSkin .mceProgress{position:absolute;left:0;top:0;z-index:1001;background:url("../js/tinymce/themes/advanced/skins/default/img/progress.gif") no-repeat;width:32px;height:32px;margin:-16px 0 0 -16px}.wp_themeSkin .mcePlaceHolder{border:1px dotted gray}.wp_themeSkin .mce_address span.mceText{font-style:italic}.wp_themeSkin .mce_pre span.mceText{font-family:monospace}.wp_themeSkin .mce_h1 span.mceText{font-weight:bolder;font-size:17px}.wp_themeSkin .mce_h2 span.mceText{font-weight:bolder;font-size:16px}.wp_themeSkin .mce_h3 span.mceText{font-weight:bolder;font-size:15px}.wp_themeSkin .mce_h4 span.mceText{font-weight:bolder;font-size:14px}.wp_themeSkin .mce_h5 span.mceText{font-weight:bolder;font-size:13px}.wp_themeSkin .mce_h6 span.mceText{font-weight:bolder;font-size:12px}.wp_themeSkin span.mce_undo{background-position:-500px -20px}.wp_themeSkin .mceButtonEnabled:hover span.mce_undo,.wp_themeSkin .mceButtonActive span.mce_undo{background-position:-500px 0}.wp_themeSkin span.mce_redo{background-position:-480px -20px}.wp_themeSkin .mceButtonEnabled:hover span.mce_redo,.wp_themeSkin .mceButtonActive span.mce_redo{background-position:-480px 0}.wp_themeSkin span.mce_bullist{background-position:-40px -20px}.wp_themeSkin .mceButtonEnabled:hover span.mce_bullist,.wp_themeSkin .mceButtonActive span.mce_bullist,.wp_themeSkin .mceSplitButton:hover span.mce_bullist{background-position:-40px 0}.wp_themeSkin span.mce_numlist{background-position:-61px -20px}.wp_themeSkin .mceButtonEnabled:hover span.mce_numlist,.wp_themeSkin .mceButtonActive span.mce_numlist,.wp_themeSkin .mceSplitButton:hover span.mce_numlist{background-position:-61px 0}.wp_themeSkin span.mce_blockquote{background-position:-80px -20px}.wp_themeSkin .mceButtonEnabled:hover span.mce_blockquote,.wp_themeSkin .mceButtonActive span.mce_blockquote{background-position:-80px 0}.wp_themeSkin span.mce_charmap{background-position:-420px -20px}.wp_themeSkin .mceButtonEnabled:hover span.mce_charmap,.wp_themeSkin .mceButtonActive span.mce_charmap{background-position:-420px 0}.wp_themeSkin span.mce_bold{background-position:-1px -20px}.wp_themeSkin .mceButtonEnabled:hover span.mce_bold,.wp_themeSkin .mceButtonActive span.mce_bold{background-position:-1px 0}.wp_themeSkin span.mce_italic{background-position:-21px -20px}.wp_themeSkin .mceButtonEnabled:hover span.mce_italic,.wp_themeSkin .mceButtonActive span.mce_italic{background-position:-21px 0}.wp_themeSkin span.mce_underline{background-position:-280px -19px}.wp_themeSkin .mceButtonEnabled:hover span.mce_underline,.wp_themeSkin .mceButtonActive span.mce_underline{background-position:-280px 1px}.wp_themeSkin span.mce_justifyleft{background-position:-100px -19px}.wp_themeSkin .mceButtonEnabled:hover span.mce_justifyleft,.wp_themeSkin .mceButtonActive span.mce_justifyleft{background-position:-100px 1px}.wp_themeSkin span.mce_justifyright{background-position:-141px -19px}.wp_themeSkin .mceButtonEnabled:hover span.mce_justifyright,.wp_themeSkin .mceButtonActive span.mce_justifyright{background-position:-141px 1px}.wp_themeSkin span.mce_justifycenter{background-position:-120px -19px}.wp_themeSkin .mceButtonEnabled:hover span.mce_justifycenter,.wp_themeSkin .mceButtonActive span.mce_justifycenter{background-position:-120px 1px}.wp_themeSkin span.mce_justifyfull{background-position:-300px -19px}.wp_themeSkin .mceButtonEnabled:hover span.mce_justifyfull,.wp_themeSkin .mceButtonActive span.mce_justifyfull{background-position:-300px 1px}.wp_themeSkin span.mce_indent{background-position:-461px -19px}.wp_themeSkin .mceButtonEnabled:hover span.mce_indent,.wp_themeSkin .mceButtonActive span.mce_indent{background-position:-461px 1px}.wp_themeSkin span.mce_outdent{background-position:-440px -19px}.wp_themeSkin .mceButtonEnabled:hover span.mce_outdent,.wp_themeSkin .mceButtonActive span.mce_outdent{background-position:-440px 1px}.wp_themeSkin span.mce_link{background-position:-161px -20px}.wp_themeSkin .mceButtonEnabled:hover span.mce_link,.wp_themeSkin .mceButtonActive span.mce_link{background-position:-161px 0}.wp_themeSkin span.mce_unlink{background-position:-180px -20px}.wp_themeSkin .mceButtonEnabled:hover span.mce_unlink,.wp_themeSkin .mceButtonActive span.mce_unlink{background-position:-180px 0}.wp_themeSkin span.mce_help{background-position:-521px -20px}.wp_themeSkin .mceButtonEnabled:hover span.mce_help,.wp_themeSkin .mceButtonActive span.mce_help{background-position:-521px 0}.wp_themeSkin span.mce_removeformat{background-position:-381px -20px}.wp_themeSkin .mceButtonEnabled:hover span.mce_removeformat,.wp_themeSkin .mceButtonActive span.mce_removeformat{background-position:-381px 0}.wp_themeSkin span.mce_strikethrough{background-position:-540px -18px}.wp_themeSkin .mceButtonEnabled:hover span.mce_strikethrough,.wp_themeSkin .mceButtonActive span.mce_strikethrough{background-position:-540px 0}.wp_themeSkin .mceSplitButton .mce_forecolor span.mce_forecolor{background-position:-321px -22px}.wp_themeSkin .mceSplitButtonEnabled:hover span.mce_forecolor,.wp_themeSkin .mceSplitButtonActive span.mce_forecolor{background-position:-321px -2px}.wp_themeSkin .mce_forecolorpicker{background-position:-320px -20px}.wp_themeSkin span.mce_fullscreen{background-position:-240px -20px}.wp_themeSkin .mceButtonEnabled:hover span.mce_fullscreen,.wp_themeSkin .mceButtonActive span.mce_fullscreen{background-position:-240px 0}.wp_themeSkin span.mce_wp_fullscreen{background-position:-240px -20px}.wp_themeSkin .mceButtonEnabled:hover span.mce_wp_fullscreen,.wp_themeSkin .mceButtonActive span.mce_wp_fullscreen{background-position:-240px 0}.wp_themeSkin span.mce_media{background-position:-401px -20px}.wp_themeSkin .mceButtonEnabled:hover span.mce_media,.wp_themeSkin .mceButtonActive span.mce_media{background-position:-401px 0}.wp_themeSkin span.mce_pastetext{background-position:-340px -20px}.wp_themeSkin .mceButtonEnabled:hover span.mce_pastetext,.wp_themeSkin .mceButtonActive span.mce_pastetext{background-position:-340px 0}.wp_themeSkin span.mce_pasteword{background-position:-360px -20px}.wp_themeSkin .mceButtonEnabled:hover span.mce_pasteword,.wp_themeSkin .mceButtonActive span.mce_pasteword{background-position:-360px 0}.wp_themeSkin span.mce_spellchecker{background-position:-220px -19px}.wp_themeSkin .mceButtonEnabled:hover span.mce_spellchecker,.wp_themeSkin .mceSplitButtonEnabled:hover span.mce_spellchecker,.wp_themeSkin .mceButtonActive span.mce_spellchecker,.wp_themeSkin .mceSplitButtonActive span.mce_spellchecker{background-position:-220px 1px}.wp_themeSkin span.mce_wp_help{background-position:-521px -20px}.wp_themeSkin .mceButtonEnabled:hover span.mce_wp_help,.wp_themeSkin .mceButtonActive span.mce_wp_help{background-position:-521px 0}.wp_themeSkin span.mce_wp_adv{background-position:-260px -20px}.wp_themeSkin .mceButtonEnabled:hover span.mce_wp_adv,.wp_themeSkin .mceButtonActive span.mce_wp_adv{background-position:-260px 0}.wp_themeSkin span.mce_wp_more{background-position:-201px -20px}.wp_themeSkin .mceButtonEnabled:hover span.mce_wp_more,.wp_themeSkin .mceButtonActive span.mce_wp_more{background-position:-201px 0}.wp_themeSkin span.mce_cleanup{background-position:-380px -20px}.wp_themeSkin span.mce_anchor{background-position:-200px 0}.wp_themeSkin span.mce_sub{background-position:-600px 0}.wp_themeSkin span.mce_sup{background-position:-620px 0}.wp_themeSkin span.mce_newdocument{background-position:-520px 0}.wp_themeSkin span.mce_image{background-position:-380px 0}.wp_themeSkin span.mce_code{background-position:-260px 0}.wp_themeSkin span.mce_hr{background-position:-360px 0}.wp_themeSkin span.mce_visualaid{background-position:-660px 0}.wp_themeSkin span.mce_paste{background-position:-560px 0}.wp_themeSkin span.mce_copy{background-position:-700px 0}.wp_themeSkin span.mce_cut{background-position:-680px 0}.wp_themeSkin .mce_backcolor span.mceAction{background-position:-760px 0}.wp_themeSkin .mce_backcolorpicker{background-position:-760px 0}.wp_themeSkin span.mce_advhr{background-position:-0px -20px}.wp_themeSkin span.mce_ltr{background-position:-20px -20px}.wp_themeSkin span.mce_rtl{background-position:-40px -20px}.wp_themeSkin span.mce_emotions{background-position:-60px -20px}.wp_themeSkin span.mce_fullpage{background-position:-80px -20px}.wp_themeSkin span.mce_iespell{background-position:-120px -20px}.wp_themeSkin span.mce_insertdate{background-position:-140px -20px}.wp_themeSkin span.mce_inserttime{background-position:-160px -20px}.wp_themeSkin span.mce_absolute{background-position:-180px -20px}.wp_themeSkin span.mce_backward{background-position:-200px -20px}.wp_themeSkin span.mce_forward{background-position:-220px -20px}.wp_themeSkin span.mce_insert_layer{background-position:-240px -20px}.wp_themeSkin span.mce_insertlayer{background-position:-260px -20px}.wp_themeSkin span.mce_movebackward{background-position:-280px -20px}.wp_themeSkin span.mce_moveforward{background-position:-300px -20px}.wp_themeSkin span.mce_nonbreaking{background-position:-340px -20px}.wp_themeSkin span.mce_selectall{background-position:-400px -20px}.wp_themeSkin span.mce_preview{background-position:-420px -20px}.wp_themeSkin span.mce_print{background-position:-440px -20px}.wp_themeSkin span.mce_cancel{background-position:-460px -20px}.wp_themeSkin span.mce_save{background-position:-480px -20px}.wp_themeSkin span.mce_replace{background-position:-500px -20px}.wp_themeSkin span.mce_search{background-position:-520px -20px}.wp_themeSkin span.mce_styleprops{background-position:-560px -20px}.wp_themeSkin span.mce_table{background-position:-580px -20px}.wp_themeSkin span.mce_cell_props{background-position:-600px -20px}.wp_themeSkin span.mce_delete_table{background-position:-620px -20px}.wp_themeSkin span.mce_delete_col{background-position:-640px -20px}.wp_themeSkin span.mce_delete_row{background-position:-660px -20px}.wp_themeSkin span.mce_col_after{background-position:-680px -20px}.wp_themeSkin span.mce_col_before{background-position:-700px -20px}.wp_themeSkin span.mce_row_after{background-position:-720px -20px}.wp_themeSkin span.mce_row_before{background-position:-740px -20px}.wp_themeSkin span.mce_merge_cells{background-position:-760px -20px}.wp_themeSkin span.mce_table_props{background-position:-980px -20px}.wp_themeSkin span.mce_row_props{background-position:-780px -20px}.wp_themeSkin span.mce_split_cells{background-position:-800px -20px}.wp_themeSkin span.mce_template{background-position:-820px -20px}.wp_themeSkin span.mce_visualchars{background-position:-840px -20px}.wp_themeSkin span.mce_abbr{background-position:-860px -20px}.wp_themeSkin span.mce_acronym{background-position:-880px -20px}.wp_themeSkin span.mce_attribs{background-position:-900px -20px}.wp_themeSkin span.mce_cite{background-position:-920px -20px}.wp_themeSkin span.mce_del{background-position:-940px -20px}.wp_themeSkin span.mce_ins{background-position:-960px -20px}.wp_themeSkin span.mce_pagebreak{background-position:0 -40px}.wp_themeSkin .mceExternalToolbar,.wp_themeSkin .mceButton,.wp_themeSkin a.mceButtonEnabled:hover,.wp_themeSkin a.mceButtonActive,.wp_themeSkin a.mceButtonSelected,.wp_themeSkin .mceListBox .mceText,.wp_themeSkin .mceListBox .mceOpen,.wp_themeSkin table.mceListBoxEnabled:hover .mceText,.wp_themeSkin .mceListBoxHover .mceText,.wp_themeSkin .mceListBoxSelected .mceText,.wp_themeSkin table.mceListBoxEnabled:hover .mceOpen,.wp_themeSkin .mceListBoxHover .mceOpen,.wp_themeSkin .mceListBoxSelected .mceOpen,.wp_themeSkin select.mceListBox,.wp_themeSkin .mceSplitButton a.mceAction,.wp_themeSkin .mceSplitButton a.mceOpen,.wp_themeSkin .mceSplitButton a.mceOpen:hover,.wp_themeSkin .mceSplitButtonSelected a.mceOpen,.wp_themeSkin table.mceSplitButtonEnabled:hover a.mceAction,.wp_themeSkin .mceSplitButton a.mceAction:hover,.wp_themeSkin div.mceColorSplitMenu table,.wp_themeSkin .mceColorSplitMenu a,.wp_themeSkin .mceColorSplitMenu a.mceMoreColors,.wp_themeSkin .mceColorSplitMenu a.mceMoreColors:hover,.wp_themeSkin a.mceMoreColors:hover,.wp_themeSkin .mceMenu{border-style:solid;border-width:1px}.wp_themeSkin iframe{background:transparent}.wp_themeSkin .mceButton,.wp_themeSkin .mceListBox .mceText,.wp_themeSkin .mceListBox .mceOpen{border-color:#ccc;background-color:#eee;background-image:-ms-linear-gradient(bottom,#ddd,#fff);background-image:-moz-linear-gradient(bottom,#ddd,#fff);background-image:-o-linear-gradient(bottom,#ddd,#fff);background-image:-webkit-gradient(linear,left bottom,left top,from(#ddd),to(#fff));background-image:-webkit-linear-gradient(bottom,#ddd,#fff);background-image:linear-gradient(bottom,#ddd,#fff)}.wp_themeSkin a.mceButtonEnabled:hover{border-color:#a0a0a0;background:#ddd;background-image:-ms-linear-gradient(bottom,#ccc,#fff);background-image:-moz-linear-gradient(bottom,#ccc,#fff);background-image:-o-linear-gradient(bottom,#ccc,#fff);background-image:-webkit-gradient(linear,left bottom,left top,from(#ccc),to(#fff));background-image:-webkit-linear-gradient(bottom,#ccc,#fff);background-image:linear-gradient(bottom,#ccc,#fff)}.wp_themeSkin a.mceButton:active,.wp_themeSkin a.mceButtonEnabled:active,.wp_themeSkin a.mceButtonSelected:active,.wp_themeSkin a.mceButtonActive,.wp_themeSkin a.mceButtonActive:active,.wp_themeSkin a.mceButtonActive:hover{background-color:#ddd;background-image:-ms-linear-gradient(bottom,#eee,#bbb);background-image:-moz-linear-gradient(bottom,#eee,#bbb);background-image:-o-linear-gradient(bottom,#eee,#bbb);background-image:-webkit-gradient(linear,left bottom,left top,from(#eee),to(#bbb));background-image:-webkit-linear-gradient(bottom,#eee,#bbb);background-image:linear-gradient(bottom,#eee,#bbb);border-color:#909090}.wp_themeSkin .mceButtonDisabled{border-color:#ccc!important}.wp_themeSkin .mceListBox .mceOpen{border-left:0!important}.wp_themeSkin table.mceListBoxEnabled:hover .mceOpen,.wp_themeSkin .mceListBoxHover .mceOpen,.wp_themeSkin .mceListBoxHover:active .mceOpen,.wp_themeSkin .mceListBoxSelected .mceOpen,.wp_themeSkin .mceListBoxSelected .mceText,.wp_themeSkin table.mceListBoxEnabled:active .mceText{background:#ccc;border-color:#999}.wp_themeSkin table.mceListBoxEnabled:hover .mceText,.wp_themeSkin .mceListBoxHover .mceText,.wp_themeSkin table.mceListBoxEnabled:hover .mceOpen,.wp_themeSkin .mceListBoxHover .mceOpen{border-color:#909090;background-color:#eee;background-image:-ms-linear-gradient(bottom,#ccc,#fff);background-image:-moz-linear-gradient(bottom,#ccc,#fff);background-image:-o-linear-gradient(bottom,#ccc,#fff);background-image:-webkit-gradient(linear,left bottom,left top,from(#ccc),to(#fff));background-image:-webkit-linear-gradient(bottom,#ccc,#fff);background-image:linear-gradient(bottom,#ccc,#fff)}.wp_themeSkin .mceSplitButton a.mceAction,.wp_themeSkin .mceSplitButton a.mceOpen{border-color:#ccc}.wp_themeSkin .mceSplitButton a.mceOpen:hover,.wp_themeSkin .mceSplitButtonSelected a.mceOpen,.wp_themeSkin table.mceSplitButtonEnabled:hover a.mceAction,.wp_themeSkin .mceSplitButton a.mceAction:hover{border-color:#909090}.wp_themeSkin table.mceSplitButton td{background-color:#eee;background-image:-ms-linear-gradient(bottom,#ddd,#fff);background-image:-moz-linear-gradient(bottom,#ddd,#fff);background-image:-o-linear-gradient(bottom,#ddd,#fff);background-image:-webkit-gradient(linear,left bottom,left top,from(#ddd),to(#fff));background-image:-webkit-linear-gradient(bottom,#ddd,#fff);background-image:linear-gradient(bottom,#ddd,#fff)}.wp_themeSkin table.mceSplitButton:hover td{background-image:-ms-linear-gradient(bottom,#ccc,#fff);background-image:-moz-linear-gradient(bottom,#ccc,#fff);background-image:-o-linear-gradient(bottom,#ccc,#fff);background-image:-webkit-gradient(linear,left bottom,left top,from(#ccc),to(#fff));background-image:-webkit-linear-gradient(bottom,#ccc,#fff);background-image:linear-gradient(bottom,#ccc,#fff)}.wp_themeSkin .mceSplitButtonActive{background-color:#b2b2b2}.wp_themeSkin .mceColorSplitMenu a.mceMoreColors:hover{border-color:#0a246a;background-color:#b6bdd2}.wp_themeSkin a.mceMoreColors:hover{border-color:#0a246a}.wp_themeSkin .mceMenuItemDisabled .mceText{color:#888}#mceModalBlocker{background:#000}.wp-editor-area{font-family:Consolas,Monaco,monospace;padding:10px;line-height:150%;border:0 none;outline:0;resize:vertical;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.wp-editor-tools{height:30px;padding:0 10px}.wp-editor-container{border-width:1px;border-style:solid;-webkit-border-top-right-radius:3px;-webkit-border-top-left-radius:3px;border-top-right-radius:3px;border-top-left-radius:3px;border-color:#ccc #ccc #dfdfdf}.wp-editor-container textarea.wp-editor-area{width:99.9%}.quicktags-toolbar,.wp_themeSkin tr.mceFirst td.mceToolbar{border-bottom:1px solid #ccc;background-color:#e9e9e9;background-image:-ms-linear-gradient(bottom,#ddd,#e9e9e9);background-image:-moz-linear-gradient(bottom,#ddd,#e9e9e9);background-image:-o-linear-gradient(bottom,#ddd,#e9e9e9);background-image:-webkit-linear-gradient(bottom,#ddd,#e9e9e9);background-image:linear-gradient(bottom,#ddd,#e9e9e9)}.wp-switch-editor{height:18px;font:13px/18px Arial,Helvetica,sans-serif normal;margin:5px 5px 0 0;padding:4px 5px 2px;float:right;cursor:pointer;border-width:1px;border-style:solid;-webkit-border-top-right-radius:3px;-webkit-border-top-left-radius:3px;border-top-right-radius:3px;border-top-left-radius:3px;background-color:#f1f1f1;border-color:#dfdfdf #dfdfdf #ccc;color:#999}html[dir="rtl"] .wp-switch-editor{float:left}.wp-switch-editor:hover{text-decoration:none!important}.js .tmce-active .wp-editor-area{color:white}.tmce-active .quicktags-toolbar{display:none}.tmce-active .switch-tmce,.html-active .switch-html{border-color:#ccc #ccc #e9e9e9;background-color:#e9e9e9;color:#333}.wp-media-buttons{line-height:1;padding:9px 0 0}.wp-media-buttons a{text-decoration:none;color:#333;font-size:12px;vertical-align:bottom}.wp-media-buttons img{padding:0 4px;vertical-align:middle}.quicktags-toolbar{border-bottom-style:solid;border-bottom-width:1px;-webkit-border-top-right-radius:3px;-webkit-border-top-left-radius:3px;border-top-right-radius:3px;border-top-left-radius:3px;padding:2px 8px 0;min-height:29px}.quicktags-toolbar>div{padding:2px 4px 0}.quicktags-toolbar input{margin:2px 1px 4px;line-height:18px;display:inline-block;min-width:26px;padding:2px 4px;font:12px/18px Arial,Helvetica,sans-serif normal;color:#464646;border:1px solid #c3c3c3;-webkit-border-radius:3px;border-radius:3px;background-color:#eee;background-image:-ms-linear-gradient(bottom,#e3e3e3,#fff);background-image:-moz-linear-gradient(bottom,#e3e3e3,#fff);background-image:-o-linear-gradient(bottom,#e3e3e3,#fff);background-image:-webkit-linear-gradient(bottom,#e3e3e3,#fff);background-image:linear-gradient(bottom,#e3e3e3,#fff)}.quicktags-toolbar input:hover{border-color:#aaa;background:#ddd}.quicktags-toolbar input[value="link"]{text-decoration:underline}.quicktags-toolbar input[value="del"]{text-decoration:line-through}.quicktags-toolbar input[value="i"]{font-style:italic}.quicktags-toolbar input[value="b"]{font-weight:bold}#wp_editbtns,#wp_gallerybtns{padding:2px;position:absolute;display:none;z-index:999998}#wp_editimgbtn,#wp_delimgbtn,#wp_editgallery,#wp_delgallery{border-color:#999;background-color:#eee;margin:2px;padding:2px;border-width:1px;border-style:solid;-webkit-border-radius:3px;border-radius:3px}#wp_editimgbtn:hover,#wp_delimgbtn:hover,#wp_editgallery:hover,#wp_delgallery:hover{border-color:#555;background-color:#ccc}#wp-link{background-color:#f5f5f5;line-height:1.4em;font-size:12px}#wp-link ol,#wp-link ul{list-style:none;margin:0;padding:0}#wp-link input[type="text"]{-webkit-box-sizing:border-box}#wp-link input[type="text"],#wp-link textarea{border-width:1px;border-style:solid;-webkit-border-radius:4px;border-radius:4px;font-size:12px;margin:1px;padding:3px}#wp-link #link-options{padding:10px 0 14px;border-bottom:1px solid #dfdfdf;margin:0 6px 14px}#wp-link p.howto{margin:3px}#wp-link #internal-toggle{display:inline-block;cursor:pointer;padding-left:18px}#wp-link .toggle-arrow{background:transparent url('../images/toggle-arrow.png') top left no-repeat;height:23px;line-height:23px}#wp-link .toggle-arrow-active{background-position:center left}#wp-link label input[type="text"]{width:360px;margin-top:5px}#wp-link label span{display:inline-block;width:80px;text-align:right;padding-right:5px}#wp-link .link-search-wrapper{margin:5px 6px 9px;display:block;overflow:hidden}#wp-link .link-search-wrapper span{float:left;margin-top:6px}#wp-link .link-search-wrapper input[type="text"]{float:left;width:220px}#wp-link .link-search-wrapper img.waiting{margin:8px 1px 0 4px;float:left;display:none}#wp-link .link-target{width:auto;padding:3px 0 0;margin:0 0 0 87px;font-size:11px}#wp-link .query-results{border:1px #dfdfdf solid;margin:0 5px 5px;background:#fff;height:185px;overflow:auto;position:relative}#wp-link li,#wp-link .query-notice{clear:both;margin-bottom:0;border-bottom:1px solid #f1f1f1;color:#333;padding:4px 6px;cursor:pointer;position:relative}#wp-link li:hover{background:#eaf2fa;color:#151515}#wp-link li.unselectable{border-bottom:1px solid #dfdfdf}#wp-link li.unselectable:hover{background:#fff;cursor:auto;color:#333}#wp-link li.selected{background:#ddd;color:#333}#wp-link li.selected .item-title{font-weight:bold}#wp-link .item-title{display:inline-block;width:80%}#wp-link .item-info{text-transform:uppercase;color:#666;font-size:11px;position:absolute;right:5px;top:4px;bottom:0}#wp-link #search-results{display:none}#wp-link #search-panel{float:left;width:100%}#wp-link .river-waiting{display:none;padding:10px 0}#wp-link .river-waiting img.waiting{margin:0 auto;display:block}#wp-link .submitbox{padding:5px 10px;font-size:11px;overflow:auto;height:29px}#wp-link-cancel{line-height:25px;float:left}#wp-link-update{line-height:23px;float:right}.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{position:absolute;left:-99999999px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:after{content:".";display:block;height:0;clear:both;visibility:hidden}.ui-helper-clearfix{display:inline-block}/*\*/* html .ui-helper-clearfix{height:1%}.ui-helper-clearfix{display:block}/**/.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-state-disabled{cursor:default!important}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-overlay{position:absolute;top:0;left:0;width:100%;height:100%}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:.1px;z-index:99999;display:block}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px}.wp-dialog{position:absolute;width:300px;overflow:hidden}.wp-dialog .ui-dialog-titlebar{position:relative}.wp-dialog .ui-dialog-titlebar-close span{display:block;margin:1px}.wp-dialog .ui-dialog-content{position:relative;border:0;padding:0;background:0;overflow:auto;zoom:1}.wp-dialog .ui-dialog-buttonpane{text-align:left;border-width:1px 0 0 0;background-image:none;margin:.5em 0 0 0;padding:.3em 1em .5em .4em}.wp-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:right}.wp-dialog .ui-dialog-buttonpane button{margin:.5em .4em .5em 0;cursor:pointer}.wp-dialog .ui-resizable-se{width:14px;height:14px;right:3px;bottom:3px}.ui-draggable .ui-dialog-titlebar{cursor:move}.wp-dialog{border:1px solid #999;-moz-box-shadow:0 0 16px rgba(0,0,0,0.3);-webkit-box-shadow:0 0 16px rgba(0,0,0,0.3);box-shadow:0 0 16px rgba(0,0,0,0.3)}.wp-dialog .ui-dialog-title{display:block;text-align:center;padding:1px 0 2px}.wp-dialog .ui-dialog-titlebar{padding:0 1em;background-color:#444;font-weight:bold;font-size:11px;line-height:18px;color:#e5e5e5}.wp-dialog{background-color:#fff;-webkit-border-top-left-radius:4px;-webkit-border-top-right-radius:4px;border-top-left-radius:4px;border-top-right-radius:4px}.wp-dialog .ui-dialog-titlebar{-webkit-border-top-left-radius:3px;-webkit-border-top-right-radius:3px;border-top-left-radius:3px;border-top-right-radius:3px}.wp-dialog .ui-dialog-titlebar-close{position:absolute;width:29px;height:16px;top:2px;right:6px;background:url('../js/tinymce/plugins/inlinepopups/skins/clearlooks2/img/buttons.gif') no-repeat -87px -16px;padding:0}.wp-dialog .ui-dialog-titlebar-close:hover,.wp-dialog .ui-dialog-titlebar-close:focus{background-position:-87px -32px}.ui-widget-overlay{background-color:#000;opacity:.6;filter:alpha(opacity=60)}.rtl #wp-link #internal-toggle{padding-right:18px;padding-left:0}.rtl #wp-link label span{text-align:left;padding-left:5px;padding-right:0}.rtl #wp-link .link-search-wrapper span{float:right}.rtl #wp-link .link-search-wrapper input[type="text"]{float:right}.rtl #wp-link .link-search-wrapper img.waiting{margin:8px 4px 0 1px;float:right}.rtl #wp-link .link-target{margin:0 87px 0 0}.rtl #wp-link .item-info{left:5px;right:auto;top:4px;bottom:0}.rtl #wp-link #search-panel{float:right}.rtl #wp-link-cancel{float:right}.rtl #wp-link-update{float:left}.rtl #wp-link .toggle-arrow{background-position:top right}.rtl #wp-link .toggle-arrow-active{background-position:center right}.rtl .wp_themeSkin .mceListBox .mceText{text-align:right}.rtl .wp_themeSkin .mceNoIcons a .mceText{padding-right:10px;padding-left:25px}.rtl .mceListBoxMenu.mceNoIcons{margin-left:-14px}.clearlooks2 .mceFocus .mceTop .mceLeft{background:#444;border-left:1px solid #999;border-top:1px solid #999;-webkit-border-top-left-radius:3px;border-top-left-radius:3px}.clearlooks2 .mceFocus .mceTop .mceRight{background:#444;border-right:1px solid #999;border-top:1px solid #999;-webkit-border-top-right-radius:3px;border-top-right-radius:3px}.clearlooks2 .mceMiddle .mceLeft{background:#f1f1f1;border-left:1px solid #999}.clearlooks2 .mceMiddle .mceRight{background:#f1f1f1;border-right:1px solid #999}.clearlooks2 .mceBottom{background:#f1f1f1;border-bottom:1px solid #999}.clearlooks2 .mceBottom .mceLeft{background:#f1f1f1;border-bottom:1px solid #999;border-left:1px solid #999}.clearlooks2 .mceBottom .mceCenter{background:#f1f1f1;border-bottom:1px solid #999}.clearlooks2 .mceBottom .mceRight{background:#f1f1f1;border-bottom:1px solid #999;border-right:1px solid #999}.clearlooks2 .mceFocus .mceTop span{color:#e5e5e5}.fullscreen-overlay{z-index:149999;display:none;position:fixed;top:0;bottom:0;left:0;right:0;filter:inherit}.fullscreen-active .fullscreen-overlay,.fullscreen-active #wp-fullscreen-body{display:block}.fullscreen-fader{z-index:200000}.fullscreen-active .fullscreen-fader{display:none}#wp-fullscreen-body{width:100%;z-index:150005;display:none;position:absolute;top:0;left:0;font-size:12px}#wp-fullscreen-wrap{margin:0 auto 50px;position:relative;padding-top:60px}#wp-fullscreen-title{font-size:1.7em;line-height:100%;outline:medium none;padding:6px 7px;width:100%;margin-bottom:30px}#wp-fullscreen-container{padding:4px 10px 50px}#wp-fullscreen-title,#wp-fullscreen-container{-webkit-border-radius:0;border-radius:0;border:1px dashed transparent;background:transparent;-moz-transition-property:border-color;-moz-transition-duration:.6s;-webkit-transition-property:border-color;-webkit-transition-duration:.6s;-o-transition-property:border-color;-o-transition-duration:.6s;transition-property:border-color;transition-duration:.6s}#wp_mce_fullscreen{width:100%;min-height:300px;border:0;background:transparent;font-family:Consolas,Monaco,monospace;line-height:1.6em;padding:0;overflow-y:hidden;outline:0;resize:none}#wp-fullscreen-tagline{color:#bbb;font-size:18px;float:right;padding-top:5px}#fullscreen-topbar{position:fixed;top:0;left:0;z-index:150050;border-bottom-style:solid;border-bottom-width:1px;min-width:800px;width:100%;height:40px}#wp-fullscreen-toolbar{padding:6px 10px 0;clear:both;max-width:1100px;min-width:820px;margin:0 auto}#wp-fullscreen-mode-bar,#wp-fullscreen-button-bar,#wp-fullscreen-close,#wp-fullscreen-count{float:left}#wp-fullscreen-save{float:right;padding:2px 2px 0 5px}#wp-fullscreen-count,#wp-fullscreen-close{padding-top:5px}#wp-fullscreen-central-toolbar{margin:auto;padding:0}#wp-fullscreen-buttons>div{float:left}#wp-fullscreen-mode-bar{padding:1px 14px 0 0}#wp-fullscreen-modes a{display:block;font-size:11px;text-decoration:none;float:left;margin:1px 0 0 0;padding:2px 6px 2px;border-width:1px 1px 1px 0;border-style:solid;border-color:#bbb;color:#777;text-shadow:0 1px 0 #fff;background-color:#f4f4f4;background-image:-moz-linear-gradient(bottom,#e4e4e4,#f9f9f9);background-image:-webkit-gradient(linear,left bottom,left top,from(#e4e4e4),to(#f9f9f9))}#wp-fullscreen-modes a:hover,.wp-html-mode #wp-fullscreen-modes a:last-child,.wp-tmce-mode #wp-fullscreen-modes a:first-child{color:#333;border-color:#999;background-color:#eee;background-image:-moz-linear-gradient(bottom,#f9f9f9,#e0e0e0);background-image:-webkit-gradient(linear,left bottom,left top,from(#f9f9f9),to(#e0e0e0))}#wp-fullscreen-modes a:first-child{border-width:1px;-webkit-border-top-left-radius:3px;-webkit-border-bottom-left-radius:3px;border-top-left-radius:3px;border-bottom-left-radius:3px}#wp-fullscreen-modes a:last-child{-webkit-border-top-right-radius:3px;-webkit-border-bottom-right-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px}#wp-fullscreen-buttons .active a{background:inherit}#wp-fullscreen-buttons .hidden{display:none}#wp-fullscreen-buttons .disabled{opacity:.5}.wp-html-mode #wp-fullscreen-buttons div{display:none}.wp-html-mode #wp-fullscreen-buttons div.wp-fullscreen-both{display:block}#fullscreen-topbar.fullscreen-make-sticky{display:block!important}#wp-fullscreen-save img{vertical-align:middle}#wp-fullscreen-save img,#wp-fullscreen-save span{padding-right:4px;display:none}#wp-fullscreen-buttons .mce_image .mce_image{background-image:url('../../wp-admin/images/media-button.png?ver=20120201');background-position:3px 3px}.fullscreen-active #TB_overlay{z-index:150100}.fullscreen-active #TB_window{z-index:150102}#wp_mce_fullscreen_ifr{background:transparent}#wp_mce_fullscreen_parent #wp_mce_fullscreen_tbl tr.mceFirst{display:none}#wp-fullscreen-container .wp_themeSkin table td{vertical-align:top}.fullscreen-overlay{background:#fff}.wp-fullscreen-focus #wp-fullscreen-title,.wp-fullscreen-focus #wp-fullscreen-container{border-color:#ccc}#fullscreen-topbar{border-bottom-color:#dfdfdf;background-color:#f1f1f1;background-image:-ms-linear-gradient(top,#f9f9f9,#ececec);background-image:-moz-linear-gradient(top,#f9f9f9,#ececec);background-image:-o-linear-gradient(top,#f9f9f9,#ececec);background-image:-webkit-gradient(linear,left top,left bottom,from(#f9f9f9),to(#ececec));background-image:-webkit-linear-gradient(top,#f9f9f9,#ececec);background-image:linear-gradient(top,#f9f9f9,#ececec)}.fade-1000,.fade-600,.fade-400,.fade-300{opacity:0;-moz-transition-property:opacity;-webkit-transition-property:opacity;-o-transition-property:opacity;transition-property:opacity}.fade-1000{-moz-transition-duration:1s;-webkit-transition-duration:1s;-o-transition-duration:1s;transition-duration:1s}.fade-600{-moz-transition-duration:.6s;-webkit-transition-duration:.6s;-o-transition-duration:.6s;transition-duration:.6s}.fade-400{-moz-transition-duration:.4s;-webkit-transition-duration:.4s;-o-transition-duration:.4s;transition-duration:.4s}.fade-300{-moz-transition-duration:.3s;-webkit-transition-duration:.3s;-o-transition-duration:.3s;transition-duration:.3s}.fade-trigger{opacity:1}.rtl #wp-fullscreen-tagline{float:left}.rtl #fullscreen-topbar{left:auto;right:0}.rtl #wp-fullscreen-mode-bar,.rtl #wp-fullscreen-button-bar,.rtl #wp-fullscreen-close,.rtl #wp-fullscreen-count{float:right}.rtl #wp-fullscreen-save{float:left}.rtl #wp-fullscreen-save{padding:2px 5px 0 2px}.rtl #wp-fullscreen-buttons>div{float:right}.rtl #wp-fullscreen-mode-bar{padding:1px 0 0 14px}.rtl #wp-fullscreen-modes a{float:right;border-width:1px 0 1px 1px}.rtl #wp-fullscreen-modes a:first-child{-webkit-border-top-left-radius:0;-webkit-border-top-right-radius:3px;-webkit-border-bottom-left-radius:0;-webkit-border-bottom-right-radius:3px;border-width:1px;border-top-left-radius:0;border-top-right-radius:3px;border-bottom-right-left:0;border-bottom-right-radius:3px}.rtl #wp-fullscreen-modes a:last-child{-webkit-border-top-right-radius:0;-webkit-border-top-left-radius:3px;-webkit-border-bottom-right-radius:0;-webkit-border-bottom-left-radius:3px;border-top-right-radius:0;border-top-left-radius:3px;border-bottom-right-radius:0;border-bottom-left-radius:3px}.rtl #wp-fullscreen-save img,.rtl #wp-fullscreen-save span{padding-right:0;padding-left:4px} +.wp_themeSkin table,.wp_themeSkin tbody,.wp_themeSkin a,.wp_themeSkin img,.wp_themeSkin tr,.wp_themeSkin div,.wp_themeSkin td,.wp_themeSkin iframe,.wp_themeSkin span,.wp_themeSkin *,.wp_themeSkin .mceText{border:0;margin:0;padding:0;white-space:nowrap;text-decoration:none;font-weight:normal;cursor:default;vertical-align:baseline;width:auto;border-collapse:separate}.wp_themeSkin a:hover,.wp_themeSkin a:link,.wp_themeSkin a:visited,.wp_themeSkin a:active{text-decoration:none;font-weight:normal;cursor:default}.wp_themeSkin table td{vertical-align:middle}.wp_themeSkin *,.wp_themeSkin a:hover,.wp_themeSkin a:link,.wp_themeSkin a:visited,.wp_themeSkin a:active{color:#000}.wp_themeSkin iframe{display:block}.wp_themeSkin #mce_fullscreen_ifr{background-color:#fff}.wp_themeSkin .mceToolbar{padding:1px}.wp_themeSkin .mceExternalToolbar{position:absolute;border-bottom:0;display:none}.wp_themeSkin .mceExternalToolbar td.mceToolbar{padding-right:13px}.wp_themeSkin .mceExternalClose{position:absolute;top:3px;right:3px;width:7px;height:7px;background:url("../../img/icons.gif") -820px 0}.wp_themeSkin table.mceToolbar,.wp_themeSkin tr.mceFirst .mceToolbar tr td,.wp_themeSkin tr.mceLast .mceToolbar tr td{border:0;margin:0;padding:0}.wp_themeSkin table.mceLayout{border-color: #CCCCCC #CCCCCC #DFDFDF;border-style: solid;border-top-left-radius: 3px; border-top-right-radius: 3px; border-width: 1px;}.wp_themeSkin .mceStatusbar{display:block;font-family:Arial,"Bitstream Vera Sans",Helvetica,Verdana,sans-serif;font-size:12px;line-height:16px;padding:0 0 0 8px;overflow:visible;height:20px;border-top:1px solid #dfdfdf;color:#000;background-color:#f5f5f5}.rtl .wp_themeSkin .mceStatusbar{padding:0 8px 0 0}.wp_themeSkin .mceStatusbar *{color:#555}.wp_themeSkin .mceStatusbar div{float:left;padding:2px}.rtl .wp_themeSkin .mceStatusbar div{float:right}.wp_themeSkin .mceStatusbar a.mceResize{display:block;float:right;background:url("../../img/icons.gif") -800px 0;width:20px;height:20px;cursor:se-resize}.rtl .wp_themeSkin .mceStatusbar a.mceResize{float:left}.wp_themeSkin .mceStatusbar a:hover{text-decoration:underline}.wp_themeSkin table.mceToolbar{margin:0 6px 2px}.wp_themeSkin #content_toolbar1{margin-top:2px}.wp_themeSkin .mceToolbar .mceToolbarEndListBox span{display:none}.wp_themeSkin span.mceIcon,.wp_themeSkin img.mceIcon{display:block;width:20px;height:20px}.wp_themeSkin .mceIcon{background:url("../../img/icons.gif") no-repeat 20px 20px}.wp_themeSkin .mceButton{display:block;width:20px;height:20px;cursor:default;padding:1px 2px;margin:1px;-webkit-border-radius:2px;border-radius:2px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.15),inset 0 0 2px 1px #fff;-moz-box-shadow:0 1px 0 rgba(0,0,0,0.15),inset 0 0 2px 1px #fff;box-shadow:0 1px 0 rgba(0,0,0,0.15),inset 0 0 2px 1px #fff}.wp_themeSkin a.mceButtonEnabled:hover{background-image:inherit 0 -10px}.wp_themeSkin .mceOldBoxModel a.mceButton span,.wp_themeSkin .mceOldBoxModel a.mceButton img{margin:0 0 0 1px}.wp_themeSkin a.mceButton:active,.wp_themeSkin a.mceButtonActive,.wp_themeSkin a.mceButtonActive:hover,.wp_themeSkin a.mceButtonSelected{-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.15),inset 0 0 2px 1px #fff;-moz-box-shadow:0 1px 0 rgba(0,0,0,0.15),inset 0 0 2px 1px #fff;box-shadow:0 1px 0 rgba(0,0,0,0.15),inset 0 0 2px 1px #fff}.wp_themeSkin .mceButtonDisabled .mceIcon{opacity:.5;filter:alpha(opacity=50)}.wp_themeSkin .mceSeparator{height:24px;width:1px;display:block;background:transparent;overflow:hidden;margin:0 2px}.wp_themeSkin .mceListBox,.wp_themeSkin .mceListBox a{display:block}.wp_themeSkin .mceListBox .mceText{padding:1px 2px 1px 5px;text-align:left;text-decoration:none;width:70px;-webkit-border-bottom-left-radius:2px;-webkit-border-top-left-radius:2px;border-bottom-left-radius:2px;border-top-left-radius:2px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.15),inset 0 0 2px 1px #fff;-moz-box-shadow:0 1px 0 rgba(0,0,0,0.15),inset 0 0 2px 1px #fff;box-shadow:0 1px 0 rgba(0,0,0,0.15),inset 0 0 2px 1px #fff;font-family:Arial,"Bitstream Vera Sans",Helvetica,Verdana,sans-serif;font-size:12px;height:20px;line-height:20px;overflow:hidden}.wp_themeSkin .mceListBox{margin:1px;direction:ltr}.wp_themeSkin .mceListBox .mceOpen{width:14px;height:20px;border-collapse:separate;padding:1px;-webkit-border-bottom-left-radius:0;-webkit-border-top-left-radius:0;border-bottom-left-radius:0;border-top-left-radius:0;-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.15),inset 0 0 2px 1px #fff;-moz-box-shadow:0 1px 0 rgba(0,0,0,0.15),inset 0 0 2px 1px #fff;box-shadow:0 1px 0 rgba(0,0,0,0.15),inset 0 0 2px 1px #fff}.wp_themeSkin .mceListBox .mceOpen span{display:block;width:14px;height:20px;background-image:url("./img/down_arrow.gif");background-position:2px 1px;background-repeat:no-repeat}.wp_themeSkin table.mceListBoxEnabled:hover .mceText,.wp_themeSkin .mceListBoxHover .mceText,.wp_themeSkin .mceListBoxSelected .mceText,.wp_themeSkin table.mceListBoxEnabled:hover .mceOpen,.wp_themeSkin .mceListBoxHover .mceOpen,.wp_themeSkin .mceListBoxSelected .mceOpen{background-image:none}.wp_themeSkin .mceListBoxDisabled .mceText{color:gray}.wp_themeSkin .mceListBoxMenu{overflow:auto;overflow-x:hidden}.wp_themeSkin .mceOldBoxModel .mceListBox .mceText{height:22px}.wp_themeSkin select.mceListBox{font-family:Arial,"Bitstream Vera Sans",Helvetica,Verdana,sans-serif;font-size:12px;border-color:#b2b2b2;background-color:#fff}.wp_themeSkin .mceSplitButton a,.wp_themeSkin .mceSplitButton span{display:block;height:20px}.wp_themeSkin .mceSplitButton{display:block;margin:1px;direction:ltr}.wp_themeSkin table.mceSplitButton td{padding:2px;-webkit-border-radius:2px;border-radius:2px}.wp_themeSkin table.mceSplitButton td a{-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.15),inset 0 0 2px 1px #fff;-moz-box-shadow:0 1px 0 rgba(0,0,0,0.15),inset 0 0 2px 1px #fff;box-shadow:0 1px 0 rgba(0,0,0,0.15),inset 0 0 2px 1px #fff}.wp_themeSkin table.mceSplitButton:hover td{background-image:inherit 0 -10px}.wp_themeSkin .mceSplitButton a.mceAction{height:20px;width:20px;padding:1px 2px}.wp_themeSkin .mceSplitButton span.mceAction{background-image:url("../../img/icons.gif");background-repeat:no-repeat;background-color:transparent;width:20px}.wp_themeSkin .mceSplitButton a.mceOpen{width:10px;height:20px;background-image:url("./img/down_arrow.gif");background-position:1px 2px;background-repeat:no-repeat;padding:1px;border-left:0 none!important}.wp_themeSkin .mceSplitButton span.mceOpen{display:none}.wp_themeSkin .mceSplitButtonDisabled .mceAction{opacity:.3;filter:alpha(opacity=30)}.wp_themeSkin .mceListBox a.mceText,.wp_themeSkin .mceSplitButton a.mceAction{-webkit-border-bottom-left-radius:2px;-webkit-border-top-left-radius:2px;border-bottom-left-radius:2px;border-top-left-radius:2px}.wp_themeSkin .mceSplitButton a.mceOpen,.wp_themeSkin .mceListBox a.mceOpen{-webkit-border-bottom-right-radius:2px;-webkit-border-top-right-radius:2px;border-bottom-right-radius:2px;border-top-right-radius:2px}.wp_themeSkin span.mce_undo,.wp_themeSkin span.mce_redo,.wp_themeSkin span.mce_bullist,.wp_themeSkin span.mce_numlist,.wp_themeSkin span.mce_blockquote,.wp_themeSkin span.mce_charmap,.wp_themeSkin span.mce_bold,.wp_themeSkin span.mce_italic,.wp_themeSkin span.mce_underline,.wp_themeSkin span.mce_justifyleft,.wp_themeSkin span.mce_justifyright,.wp_themeSkin span.mce_justifycenter,.wp_themeSkin span.mce_justifyfull,.wp_themeSkin span.mce_indent,.wp_themeSkin span.mce_outdent,.wp_themeSkin span.mce_link,.wp_themeSkin span.mce_unlink,.wp_themeSkin span.mce_help,.wp_themeSkin span.mce_removeformat,.wp_themeSkin span.mce_fullscreen,.wp_themeSkin span.mce_wp_fullscreen,.wp_themeSkin span.mce_media,.wp_themeSkin span.mce_pastetext,.wp_themeSkin span.mce_pasteword,.wp_themeSkin span.mce_wp_help,.wp_themeSkin span.mce_wp_adv,.wp_themeSkin span.mce_wp_more,.wp_themeSkin span.mce_strikethrough,.wp_themeSkin span.mce_spellchecker,.wp_themeSkin span.mce_forecolor,.wp_themeSkin .mce_forecolorpicker,.wp_themeSkin .mceSplitButton .mce_spellchecker span.mce_spellchecker,.wp_themeSkin .mceSplitButton .mce_forecolor span.mce_forecolor,.wp_themeSkin .mceSplitButton span.mce_numlist,.wp_themeSkin .mceSplitButton span.mce_bullist{background-image:url(./img/wpicons.png)}.wp_themeSkin div.mceColorSplitMenu table{background-color:#ebebeb;border-color:#b2b2b2}.wp_themeSkin .mceColorSplitMenu td{padding:2px}.wp_themeSkin .mceColorSplitMenu a{display:block;width:9px;height:9px;overflow:hidden;border-color:#b2b2b2}.wp_themeSkin .mceColorSplitMenu td.mceMoreColors{padding:1px 3px 1px 1px}.wp_themeSkin .mceColorSplitMenu a.mceMoreColors{width:100%;height:auto;text-align:center;font-family:Tahoma,Verdana,Arial,Helvetica;font-size:11px;line-height:20px;border-color:#fff}.wp_themeSkin .mceColorPreview{margin:-5px 0 0 2px;width:16px;height:4px;overflow:hidden}.wp_themeSkin .mceMenu{position:absolute;left:0;top:0;z-index:1000;border-color:#ddd}.wp_themeSkin .mceNoIcons span.mceIcon{width:0}.wp_themeSkin .mceNoIcons a .mceText{padding-left:10px}.wp_themeSkin .mceMenu table{background-color:#ebeaeb}.wp_themeSkin .mceMenu a,.wp_themeSkin .mceMenu span,.wp_themeSkin .mceMenu{display:block}.wp_themeSkin .mceMenu td{height:20px;overflow:hidden}.wp_themeSkin .mceMenu a{position:relative;padding:3px 0 4px 0;text-decoration:none!important}.wp_themeSkin .mceMenu .mceText{position:relative;display:block;font-family:Tahoma,Verdana,Arial,Helvetica;cursor:default;margin:0;padding:0 25px;color:#000}.wp_themeSkin .mceMenu span.mceText,.wp_themeSkin .mceMenu .mcePreview{font-size:12px}.wp_themeSkin .mceMenu pre.mceText{font-family:Monospace}.wp_themeSkin .mceMenu .mceIcon{position:absolute;top:0;left:0;width:22px}.wp_themeSkin .mceMenu .mceMenuItemEnabled a:hover,.wp_themeSkin .mceMenu .mceMenuItemActive{background-color:#f5f5f5}.wp_themeSkin td.mceMenuItemSeparator{height:1px;background-color:#aaa}.wp_themeSkin .mceMenuItemTitle a{border-top:0;border-right:0;border-left:0;border-bottom:1px solid #aaa;text-decoration:none!important;background-color:#ccc}.wp_themeSkin .mceMenuItemTitle span.mceText{font-weight:bold;padding-left:4px;color:#000}.wp_themeSkin .mceMenuItemSelected .mceIcon{background:url("../js/tinymce/themes/advanced/skins/default/img/menu_check.gif");color:#888}.wp_themeSkin .mceNoIcons .mceMenuItemSelected a{background:url("../js/tinymce/themes/advanced/skins/default/img/menu_arrow.gif") no-repeat -6px center}.wp_themeSkin .mceMenu span.mceMenuLine{display:none}.wp_themeSkin .mceMenuItemSub a{background:url("../js/tinymce/themes/advanced/skins/default/img/menu_arrow.gif") no-repeat top right}.wp_themeSkin .mceBlocker{position:absolute;left:0;top:0;z-index:1000;opacity:.5;filter:alpha(opacity=50);background:#FFF}.wp_themeSkin .mceProgress{position:absolute;left:0;top:0;z-index:1001;background:url("../js/tinymce/themes/advanced/skins/default/img/progress.gif") no-repeat;width:32px;height:32px;margin:-16px 0 0 -16px}.wp_themeSkin .mcePlaceHolder{border:1px dotted gray}.wp_themeSkin .mce_address span.mceText{font-style:italic}.wp_themeSkin .mce_pre span.mceText{font-family:monospace}.wp_themeSkin .mce_h1 span.mceText{font-weight:bolder;font-size:17px}.wp_themeSkin .mce_h2 span.mceText{font-weight:bolder;font-size:16px}.wp_themeSkin .mce_h3 span.mceText{font-weight:bolder;font-size:15px}.wp_themeSkin .mce_h4 span.mceText{font-weight:bolder;font-size:14px}.wp_themeSkin .mce_h5 span.mceText{font-weight:bolder;font-size:13px}.wp_themeSkin .mce_h6 span.mceText{font-weight:bolder;font-size:12px}.wp_themeSkin span.mce_undo{background-position:-500px -20px}.wp_themeSkin .mceButtonEnabled:hover span.mce_undo,.wp_themeSkin .mceButtonActive span.mce_undo{background-position:-500px 0}.wp_themeSkin span.mce_redo{background-position:-480px -20px}.wp_themeSkin .mceButtonEnabled:hover span.mce_redo,.wp_themeSkin .mceButtonActive span.mce_redo{background-position:-480px 0}.wp_themeSkin span.mce_bullist{background-position:-40px -20px}.wp_themeSkin .mceButtonEnabled:hover span.mce_bullist,.wp_themeSkin .mceButtonActive span.mce_bullist,.wp_themeSkin .mceSplitButton:hover span.mce_bullist{background-position:-40px 0}.wp_themeSkin span.mce_numlist{background-position:-61px -20px}.wp_themeSkin .mceButtonEnabled:hover span.mce_numlist,.wp_themeSkin .mceButtonActive span.mce_numlist,.wp_themeSkin .mceSplitButton:hover span.mce_numlist{background-position:-61px 0}.wp_themeSkin span.mce_blockquote{background-position:-80px -20px}.wp_themeSkin .mceButtonEnabled:hover span.mce_blockquote,.wp_themeSkin .mceButtonActive span.mce_blockquote{background-position:-80px 0}.wp_themeSkin span.mce_charmap{background-position:-420px -20px}.wp_themeSkin .mceButtonEnabled:hover span.mce_charmap,.wp_themeSkin .mceButtonActive span.mce_charmap{background-position:-420px 0}.wp_themeSkin span.mce_bold{background-position:-1px -20px}.wp_themeSkin .mceButtonEnabled:hover span.mce_bold,.wp_themeSkin .mceButtonActive span.mce_bold{background-position:-1px 0}.wp_themeSkin span.mce_italic{background-position:-21px -20px}.wp_themeSkin .mceButtonEnabled:hover span.mce_italic,.wp_themeSkin .mceButtonActive span.mce_italic{background-position:-21px 0}.wp_themeSkin span.mce_underline{background-position:-280px -19px}.wp_themeSkin .mceButtonEnabled:hover span.mce_underline,.wp_themeSkin .mceButtonActive span.mce_underline{background-position:-280px 1px}.wp_themeSkin span.mce_justifyleft{background-position:-100px -19px}.wp_themeSkin .mceButtonEnabled:hover span.mce_justifyleft,.wp_themeSkin .mceButtonActive span.mce_justifyleft{background-position:-100px 1px}.wp_themeSkin span.mce_justifyright{background-position:-141px -19px}.wp_themeSkin .mceButtonEnabled:hover span.mce_justifyright,.wp_themeSkin .mceButtonActive span.mce_justifyright{background-position:-141px 1px}.wp_themeSkin span.mce_justifycenter{background-position:-120px -19px}.wp_themeSkin .mceButtonEnabled:hover span.mce_justifycenter,.wp_themeSkin .mceButtonActive span.mce_justifycenter{background-position:-120px 1px}.wp_themeSkin span.mce_justifyfull{background-position:-300px -19px}.wp_themeSkin .mceButtonEnabled:hover span.mce_justifyfull,.wp_themeSkin .mceButtonActive span.mce_justifyfull{background-position:-300px 1px}.wp_themeSkin span.mce_indent{background-position:-461px -19px}.wp_themeSkin .mceButtonEnabled:hover span.mce_indent,.wp_themeSkin .mceButtonActive span.mce_indent{background-position:-461px 1px}.wp_themeSkin span.mce_outdent{background-position:-440px -19px}.wp_themeSkin .mceButtonEnabled:hover span.mce_outdent,.wp_themeSkin .mceButtonActive span.mce_outdent{background-position:-440px 1px}.wp_themeSkin span.mce_link{background-position:-161px -20px}.wp_themeSkin .mceButtonEnabled:hover span.mce_link,.wp_themeSkin .mceButtonActive span.mce_link{background-position:-161px 0}.wp_themeSkin span.mce_unlink{background-position:-180px -20px}.wp_themeSkin .mceButtonEnabled:hover span.mce_unlink,.wp_themeSkin .mceButtonActive span.mce_unlink{background-position:-180px 0}.wp_themeSkin span.mce_help{background-position:-521px -20px}.wp_themeSkin .mceButtonEnabled:hover span.mce_help,.wp_themeSkin .mceButtonActive span.mce_help{background-position:-521px 0}.wp_themeSkin span.mce_removeformat{background-position:-381px -20px}.wp_themeSkin .mceButtonEnabled:hover span.mce_removeformat,.wp_themeSkin .mceButtonActive span.mce_removeformat{background-position:-381px 0}.wp_themeSkin span.mce_strikethrough{background-position:-540px -18px}.wp_themeSkin .mceButtonEnabled:hover span.mce_strikethrough,.wp_themeSkin .mceButtonActive span.mce_strikethrough{background-position:-540px 0}.wp_themeSkin .mceSplitButton .mce_forecolor span.mce_forecolor{background-position:-321px -22px}.wp_themeSkin .mceSplitButtonEnabled:hover span.mce_forecolor,.wp_themeSkin .mceSplitButtonActive span.mce_forecolor{background-position:-321px -2px}.wp_themeSkin .mce_forecolorpicker{background-position:-320px -20px}.wp_themeSkin span.mce_fullscreen{background-position:-240px -20px}.wp_themeSkin .mceButtonEnabled:hover span.mce_fullscreen,.wp_themeSkin .mceButtonActive span.mce_fullscreen{background-position:-240px 0}.wp_themeSkin span.mce_wp_fullscreen{background-position:-240px -20px}.wp_themeSkin .mceButtonEnabled:hover span.mce_wp_fullscreen,.wp_themeSkin .mceButtonActive span.mce_wp_fullscreen{background-position:-240px 0}.wp_themeSkin span.mce_media{background-position:-401px -20px}.wp_themeSkin .mceButtonEnabled:hover span.mce_media,.wp_themeSkin .mceButtonActive span.mce_media{background-position:-401px 0}.wp_themeSkin span.mce_pastetext{background-position:-340px -20px}.wp_themeSkin .mceButtonEnabled:hover span.mce_pastetext,.wp_themeSkin .mceButtonActive span.mce_pastetext{background-position:-340px 0}.wp_themeSkin span.mce_pasteword{background-position:-360px -20px}.wp_themeSkin .mceButtonEnabled:hover span.mce_pasteword,.wp_themeSkin .mceButtonActive span.mce_pasteword{background-position:-360px 0}.wp_themeSkin span.mce_spellchecker{background-position:-220px -19px}.wp_themeSkin .mceButtonEnabled:hover span.mce_spellchecker,.wp_themeSkin .mceSplitButtonEnabled:hover span.mce_spellchecker,.wp_themeSkin .mceButtonActive span.mce_spellchecker,.wp_themeSkin .mceSplitButtonActive span.mce_spellchecker{background-position:-220px 1px}.wp_themeSkin span.mce_wp_help{background-position:-521px -20px}.wp_themeSkin .mceButtonEnabled:hover span.mce_wp_help,.wp_themeSkin .mceButtonActive span.mce_wp_help{background-position:-521px 0}.wp_themeSkin span.mce_wp_adv{background-position:-260px -20px}.wp_themeSkin .mceButtonEnabled:hover span.mce_wp_adv,.wp_themeSkin .mceButtonActive span.mce_wp_adv{background-position:-260px 0}.wp_themeSkin span.mce_wp_more{background-position:-201px -20px}.wp_themeSkin .mceButtonEnabled:hover span.mce_wp_more,.wp_themeSkin .mceButtonActive span.mce_wp_more{background-position:-201px 0}.wp_themeSkin span.mce_cleanup{background-position:-380px -20px}.wp_themeSkin span.mce_anchor{background-position:-200px 0}.wp_themeSkin span.mce_sub{background-position:-600px 0}.wp_themeSkin span.mce_sup{background-position:-620px 0}.wp_themeSkin span.mce_newdocument{background-position:-520px 0}.wp_themeSkin span.mce_image{background-position:-380px 0}.wp_themeSkin span.mce_code{background-position:-260px 0}.wp_themeSkin span.mce_hr{background-position:-360px 0}.wp_themeSkin span.mce_visualaid{background-position:-660px 0}.wp_themeSkin span.mce_paste{background-position:-560px 0}.wp_themeSkin span.mce_copy{background-position:-700px 0}.wp_themeSkin span.mce_cut{background-position:-680px 0}.wp_themeSkin .mce_backcolor span.mceAction{background-position:-760px 0}.wp_themeSkin .mce_backcolorpicker{background-position:-760px 0}.wp_themeSkin span.mce_advhr{background-position:-0px -20px}.wp_themeSkin span.mce_ltr{background-position:-20px -20px}.wp_themeSkin span.mce_rtl{background-position:-40px -20px}.wp_themeSkin span.mce_emotions{background-position:-60px -20px}.wp_themeSkin span.mce_fullpage{background-position:-80px -20px}.wp_themeSkin span.mce_iespell{background-position:-120px -20px}.wp_themeSkin span.mce_insertdate{background-position:-140px -20px}.wp_themeSkin span.mce_inserttime{background-position:-160px -20px}.wp_themeSkin span.mce_absolute{background-position:-180px -20px}.wp_themeSkin span.mce_backward{background-position:-200px -20px}.wp_themeSkin span.mce_forward{background-position:-220px -20px}.wp_themeSkin span.mce_insert_layer{background-position:-240px -20px}.wp_themeSkin span.mce_insertlayer{background-position:-260px -20px}.wp_themeSkin span.mce_movebackward{background-position:-280px -20px}.wp_themeSkin span.mce_moveforward{background-position:-300px -20px}.wp_themeSkin span.mce_nonbreaking{background-position:-340px -20px}.wp_themeSkin span.mce_selectall{background-position:-400px -20px}.wp_themeSkin span.mce_preview{background-position:-420px -20px}.wp_themeSkin span.mce_print{background-position:-440px -20px}.wp_themeSkin span.mce_cancel{background-position:-460px -20px}.wp_themeSkin span.mce_save{background-position:-480px -20px}.wp_themeSkin span.mce_replace{background-position:-500px -20px}.wp_themeSkin span.mce_search{background-position:-520px -20px}.wp_themeSkin span.mce_styleprops{background-position:-560px -20px}.wp_themeSkin span.mce_table{background-position:-580px -20px}.wp_themeSkin span.mce_cell_props{background-position:-600px -20px}.wp_themeSkin span.mce_delete_table{background-position:-620px -20px}.wp_themeSkin span.mce_delete_col{background-position:-640px -20px}.wp_themeSkin span.mce_delete_row{background-position:-660px -20px}.wp_themeSkin span.mce_col_after{background-position:-680px -20px}.wp_themeSkin span.mce_col_before{background-position:-700px -20px}.wp_themeSkin span.mce_row_after{background-position:-720px -20px}.wp_themeSkin span.mce_row_before{background-position:-740px -20px}.wp_themeSkin span.mce_merge_cells{background-position:-760px -20px}.wp_themeSkin span.mce_table_props{background-position:-980px -20px}.wp_themeSkin span.mce_row_props{background-position:-780px -20px}.wp_themeSkin span.mce_split_cells{background-position:-800px -20px}.wp_themeSkin span.mce_template{background-position:-820px -20px}.wp_themeSkin span.mce_visualchars{background-position:-840px -20px}.wp_themeSkin span.mce_abbr{background-position:-860px -20px}.wp_themeSkin span.mce_acronym{background-position:-880px -20px}.wp_themeSkin span.mce_attribs{background-position:-900px -20px}.wp_themeSkin span.mce_cite{background-position:-920px -20px}.wp_themeSkin span.mce_del{background-position:-940px -20px}.wp_themeSkin span.mce_ins{background-position:-960px -20px}.wp_themeSkin span.mce_pagebreak{background-position:0 -40px}.wp_themeSkin .mceExternalToolbar,.wp_themeSkin .mceButton,.wp_themeSkin a.mceButtonEnabled:hover,.wp_themeSkin a.mceButtonActive,.wp_themeSkin a.mceButtonSelected,.wp_themeSkin .mceListBox .mceText,.wp_themeSkin .mceListBox .mceOpen,.wp_themeSkin table.mceListBoxEnabled:hover .mceText,.wp_themeSkin .mceListBoxHover .mceText,.wp_themeSkin .mceListBoxSelected .mceText,.wp_themeSkin table.mceListBoxEnabled:hover .mceOpen,.wp_themeSkin .mceListBoxHover .mceOpen,.wp_themeSkin .mceListBoxSelected .mceOpen,.wp_themeSkin select.mceListBox,.wp_themeSkin .mceSplitButton a.mceAction,.wp_themeSkin .mceSplitButton a.mceOpen,.wp_themeSkin .mceSplitButton a.mceOpen:hover,.wp_themeSkin .mceSplitButtonSelected a.mceOpen,.wp_themeSkin table.mceSplitButtonEnabled:hover a.mceAction,.wp_themeSkin .mceSplitButton a.mceAction:hover,.wp_themeSkin div.mceColorSplitMenu table,.wp_themeSkin .mceColorSplitMenu a,.wp_themeSkin .mceColorSplitMenu a.mceMoreColors,.wp_themeSkin .mceColorSplitMenu a.mceMoreColors:hover,.wp_themeSkin a.mceMoreColors:hover,.wp_themeSkin .mceMenu{border-style:solid;border-width:1px}.wp_themeSkin iframe{background:transparent}.wp_themeSkin .mceButton,.wp_themeSkin .mceListBox .mceText,.wp_themeSkin .mceListBox .mceOpen{border-color:#ccc;background-color:#eee;background-image:-ms-linear-gradient(bottom,#ddd,#fff);background-image:-moz-linear-gradient(bottom,#ddd,#fff);background-image:-o-linear-gradient(bottom,#ddd,#fff);background-image:-webkit-gradient(linear,left bottom,left top,from(#ddd),to(#fff));background-image:-webkit-linear-gradient(bottom,#ddd,#fff);background-image:linear-gradient(bottom,#ddd,#fff)}.wp_themeSkin a.mceButtonEnabled:hover{border-color:#a0a0a0;background:#ddd;background-image:-ms-linear-gradient(bottom,#ccc,#fff);background-image:-moz-linear-gradient(bottom,#ccc,#fff);background-image:-o-linear-gradient(bottom,#ccc,#fff);background-image:-webkit-gradient(linear,left bottom,left top,from(#ccc),to(#fff));background-image:-webkit-linear-gradient(bottom,#ccc,#fff);background-image:linear-gradient(bottom,#ccc,#fff)}.wp_themeSkin a.mceButton:active,.wp_themeSkin a.mceButtonEnabled:active,.wp_themeSkin a.mceButtonSelected:active,.wp_themeSkin a.mceButtonActive,.wp_themeSkin a.mceButtonActive:active,.wp_themeSkin a.mceButtonActive:hover{background-color:#ddd;background-image:-ms-linear-gradient(bottom,#eee,#bbb);background-image:-moz-linear-gradient(bottom,#eee,#bbb);background-image:-o-linear-gradient(bottom,#eee,#bbb);background-image:-webkit-gradient(linear,left bottom,left top,from(#eee),to(#bbb));background-image:-webkit-linear-gradient(bottom,#eee,#bbb);background-image:linear-gradient(bottom,#eee,#bbb);border-color:#909090}.wp_themeSkin .mceButtonDisabled{border-color:#ccc!important}.wp_themeSkin .mceListBox .mceOpen{border-left:0!important}.wp_themeSkin table.mceListBoxEnabled:hover .mceOpen,.wp_themeSkin .mceListBoxHover .mceOpen,.wp_themeSkin .mceListBoxHover:active .mceOpen,.wp_themeSkin .mceListBoxSelected .mceOpen,.wp_themeSkin .mceListBoxSelected .mceText,.wp_themeSkin table.mceListBoxEnabled:active .mceText{background:#ccc;border-color:#999}.wp_themeSkin table.mceListBoxEnabled:hover .mceText,.wp_themeSkin .mceListBoxHover .mceText,.wp_themeSkin table.mceListBoxEnabled:hover .mceOpen,.wp_themeSkin .mceListBoxHover .mceOpen{border-color:#909090;background-color:#eee;background-image:-ms-linear-gradient(bottom,#ccc,#fff);background-image:-moz-linear-gradient(bottom,#ccc,#fff);background-image:-o-linear-gradient(bottom,#ccc,#fff);background-image:-webkit-gradient(linear,left bottom,left top,from(#ccc),to(#fff));background-image:-webkit-linear-gradient(bottom,#ccc,#fff);background-image:linear-gradient(bottom,#ccc,#fff)}.wp_themeSkin .mceSplitButton a.mceAction,.wp_themeSkin .mceSplitButton a.mceOpen{border-color:#ccc}.wp_themeSkin .mceSplitButton a.mceOpen:hover,.wp_themeSkin .mceSplitButtonSelected a.mceOpen,.wp_themeSkin table.mceSplitButtonEnabled:hover a.mceAction,.wp_themeSkin .mceSplitButton a.mceAction:hover{border-color:#909090}.wp_themeSkin table.mceSplitButton td{background-color:#eee;background-image:-ms-linear-gradient(bottom,#ddd,#fff);background-image:-moz-linear-gradient(bottom,#ddd,#fff);background-image:-o-linear-gradient(bottom,#ddd,#fff);background-image:-webkit-gradient(linear,left bottom,left top,from(#ddd),to(#fff));background-image:-webkit-linear-gradient(bottom,#ddd,#fff);background-image:linear-gradient(bottom,#ddd,#fff)}.wp_themeSkin table.mceSplitButton:hover td{background-image:-ms-linear-gradient(bottom,#ccc,#fff);background-image:-moz-linear-gradient(bottom,#ccc,#fff);background-image:-o-linear-gradient(bottom,#ccc,#fff);background-image:-webkit-gradient(linear,left bottom,left top,from(#ccc),to(#fff));background-image:-webkit-linear-gradient(bottom,#ccc,#fff);background-image:linear-gradient(bottom,#ccc,#fff)}.wp_themeSkin .mceSplitButtonActive{background-color:#b2b2b2}.wp_themeSkin .mceColorSplitMenu a.mceMoreColors:hover{border-color:#0a246a;background-color:#b6bdd2}.wp_themeSkin a.mceMoreColors:hover{border-color:#0a246a}.wp_themeSkin .mceMenuItemDisabled .mceText{color:#888}#mceModalBlocker{background:#000}.wp-editor-area{font-family:Consolas,Monaco,monospace;padding:10px;line-height:150%;border:0 none;outline:0;resize:vertical;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.wp-editor-tools{height:30px;padding:0 10px}.wp-editor-container{border-width:1px;border-style:solid;-webkit-border-top-right-radius:3px;-webkit-border-top-left-radius:3px;border-top-right-radius:3px;border-top-left-radius:3px;border-color:#ccc #ccc #dfdfdf}.wp-editor-container textarea.wp-editor-area{width:99.9%}.quicktags-toolbar,.wp_themeSkin tr.mceFirst td.mceToolbar{border-bottom:1px solid #ccc;background-color:#e9e9e9;background-image:-ms-linear-gradient(bottom,#ddd,#e9e9e9);background-image:-moz-linear-gradient(bottom,#ddd,#e9e9e9);background-image:-o-linear-gradient(bottom,#ddd,#e9e9e9);background-image:-webkit-linear-gradient(bottom,#ddd,#e9e9e9);background-image:linear-gradient(bottom,#ddd,#e9e9e9)}.wp-switch-editor{height:18px;font:13px/18px Arial,Helvetica,sans-serif normal;margin:5px 5px 0 0;padding:4px 5px 2px;float:right;cursor:pointer;border-width:1px;border-style:solid;-webkit-border-top-right-radius:3px;-webkit-border-top-left-radius:3px;border-top-right-radius:3px;border-top-left-radius:3px;background-color:#f1f1f1;border-color:#dfdfdf #dfdfdf #ccc;color:#999}html[dir="rtl"] .wp-switch-editor{float:left}.wp-switch-editor:hover{text-decoration:none!important}.js .tmce-active .wp-editor-area{color:white}.tmce-active .quicktags-toolbar{display:none}.tmce-active .switch-tmce,.html-active .switch-html{border-color:#ccc #ccc #e9e9e9;background-color:#e9e9e9;color:#333}.wp-media-buttons{line-height:1;padding:9px 0 0}.wp-media-buttons a{text-decoration:none;color:#333;font-size:12px;vertical-align:bottom}.wp-media-buttons img{padding:0 4px;vertical-align:middle}.quicktags-toolbar{border-bottom-style:solid;border-bottom-width:1px;-webkit-border-top-right-radius:3px;-webkit-border-top-left-radius:3px;border-top-right-radius:3px;border-top-left-radius:3px;padding:2px 8px 0;min-height:29px}.quicktags-toolbar>div{padding:2px 4px 0}.quicktags-toolbar input{margin:2px 1px 4px;line-height:18px;display:inline-block;min-width:26px;padding:2px 4px;font:12px/18px Arial,Helvetica,sans-serif normal;color:#464646;border:1px solid #c3c3c3;-webkit-border-radius:3px;border-radius:3px;background-color:#eee;background-image:-ms-linear-gradient(bottom,#e3e3e3,#fff);background-image:-moz-linear-gradient(bottom,#e3e3e3,#fff);background-image:-o-linear-gradient(bottom,#e3e3e3,#fff);background-image:-webkit-linear-gradient(bottom,#e3e3e3,#fff);background-image:linear-gradient(bottom,#e3e3e3,#fff)}.quicktags-toolbar input:hover{border-color:#aaa;background:#ddd}.quicktags-toolbar input[value="link"]{text-decoration:underline}.quicktags-toolbar input[value="del"]{text-decoration:line-through}.quicktags-toolbar input[value="i"]{font-style:italic}.quicktags-toolbar input[value="b"]{font-weight:bold}#wp_editbtns,#wp_gallerybtns{padding:2px;position:absolute;display:none;z-index:999998}#wp_editimgbtn,#wp_delimgbtn,#wp_editgallery,#wp_delgallery{border-color:#999;background-color:#eee;margin:2px;padding:2px;border-width:1px;border-style:solid;-webkit-border-radius:3px;border-radius:3px}#wp_editimgbtn:hover,#wp_delimgbtn:hover,#wp_editgallery:hover,#wp_delgallery:hover{border-color:#555;background-color:#ccc}#wp-link{background-color:#f5f5f5;line-height:1.4em;font-size:12px}#wp-link ol,#wp-link ul{list-style:none;margin:0;padding:0}#wp-link input[type="text"]{-webkit-box-sizing:border-box}#wp-link input[type="text"],#wp-link textarea{border-width:1px;border-style:solid;-webkit-border-radius:4px;border-radius:4px;font-size:12px;margin:1px;padding:3px}#wp-link #link-options{padding:10px 0 14px;border-bottom:1px solid #dfdfdf;margin:0 6px 14px}#wp-link p.howto{margin:3px}#wp-link #internal-toggle{display:inline-block;cursor:pointer;padding-left:18px}#wp-link .toggle-arrow{background:transparent url('../images/toggle-arrow.png') top left no-repeat;height:23px;line-height:23px}#wp-link .toggle-arrow-active{background-position:center left}#wp-link label input[type="text"]{width:360px;margin-top:5px}#wp-link label span{display:inline-block;width:80px;text-align:right;padding-right:5px}#wp-link .link-search-wrapper{margin:5px 6px 9px;display:block;overflow:hidden}#wp-link .link-search-wrapper span{float:left;margin-top:6px}#wp-link .link-search-wrapper input[type="text"]{float:left;width:220px}#wp-link .link-search-wrapper img.waiting{margin:8px 1px 0 4px;float:left;display:none}#wp-link .link-target{width:auto;padding:3px 0 0;margin:0 0 0 87px;font-size:11px}#wp-link .query-results{border:1px #dfdfdf solid;margin:0 5px 5px;background:#fff;height:185px;overflow:auto;position:relative}#wp-link li,#wp-link .query-notice{clear:both;margin-bottom:0;border-bottom:1px solid #f1f1f1;color:#333;padding:4px 6px;cursor:pointer;position:relative}#wp-link li:hover{background:#eaf2fa;color:#151515}#wp-link li.unselectable{border-bottom:1px solid #dfdfdf}#wp-link li.unselectable:hover{background:#fff;cursor:auto;color:#333}#wp-link li.selected{background:#ddd;color:#333}#wp-link li.selected .item-title{font-weight:bold}#wp-link .item-title{display:inline-block;width:80%}#wp-link .item-info{text-transform:uppercase;color:#666;font-size:11px;position:absolute;right:5px;top:4px;bottom:0}#wp-link #search-results{display:none}#wp-link #search-panel{float:left;width:100%}#wp-link .river-waiting{display:none;padding:10px 0}#wp-link .river-waiting img.waiting{margin:0 auto;display:block}#wp-link .submitbox{padding:5px 10px;font-size:11px;overflow:auto;height:29px}#wp-link-cancel{line-height:25px;float:left}#wp-link-update{line-height:23px;float:right}.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{position:absolute;left:-99999999px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:after{content:".";display:block;height:0;clear:both;visibility:hidden}.ui-helper-clearfix{display:inline-block}/*\*/* html .ui-helper-clearfix{height:1%}.ui-helper-clearfix{display:block}/**/.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-state-disabled{cursor:default!important}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-overlay{position:absolute;top:0;left:0;width:100%;height:100%}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:.1px;z-index:99999;display:block}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px}.wp-dialog{position:absolute;width:300px;overflow:hidden}.wp-dialog .ui-dialog-titlebar{position:relative}.wp-dialog .ui-dialog-titlebar-close span{display:block;margin:1px}.wp-dialog .ui-dialog-content{position:relative;border:0;padding:0;background:0;overflow:auto;zoom:1}.wp-dialog .ui-dialog-buttonpane{text-align:left;border-width:1px 0 0 0;background-image:none;margin:.5em 0 0 0;padding:.3em 1em .5em .4em}.wp-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:right}.wp-dialog .ui-dialog-buttonpane button{margin:.5em .4em .5em 0;cursor:pointer}.wp-dialog .ui-resizable-se{width:14px;height:14px;right:3px;bottom:3px}.ui-draggable .ui-dialog-titlebar{cursor:move}.wp-dialog{border:1px solid #999;-moz-box-shadow:0 0 16px rgba(0,0,0,0.3);-webkit-box-shadow:0 0 16px rgba(0,0,0,0.3);box-shadow:0 0 16px rgba(0,0,0,0.3)}.wp-dialog .ui-dialog-title{display:block;text-align:center;padding:1px 0 2px}.wp-dialog .ui-dialog-titlebar{padding:0 1em;background-color:#444;font-weight:bold;font-size:11px;line-height:18px;color:#e5e5e5}.wp-dialog{background-color:#fff;-webkit-border-top-left-radius:4px;-webkit-border-top-right-radius:4px;border-top-left-radius:4px;border-top-right-radius:4px}.wp-dialog .ui-dialog-titlebar{-webkit-border-top-left-radius:3px;-webkit-border-top-right-radius:3px;border-top-left-radius:3px;border-top-right-radius:3px}.wp-dialog .ui-dialog-titlebar-close{position:absolute;width:29px;height:16px;top:2px;right:6px;background:url('../js/tinymce/plugins/inlinepopups/skins/clearlooks2/img/buttons.gif') no-repeat -87px -16px;padding:0}.wp-dialog .ui-dialog-titlebar-close:hover,.wp-dialog .ui-dialog-titlebar-close:focus{background-position:-87px -32px}.ui-widget-overlay{background-color:#000;opacity:.6;filter:alpha(opacity=60)}.rtl #wp-link #internal-toggle{padding-right:18px;padding-left:0}.rtl #wp-link label span{text-align:left;padding-left:5px;padding-right:0}.rtl #wp-link .link-search-wrapper span{float:right}.rtl #wp-link .link-search-wrapper input[type="text"]{float:right}.rtl #wp-link .link-search-wrapper img.waiting{margin:8px 4px 0 1px;float:right}.rtl #wp-link .link-target{margin:0 87px 0 0}.rtl #wp-link .item-info{left:5px;right:auto;top:4px;bottom:0}.rtl #wp-link #search-panel{float:right}.rtl #wp-link-cancel{float:right}.rtl #wp-link-update{float:left}.rtl #wp-link .toggle-arrow{background-position:top right}.rtl #wp-link .toggle-arrow-active{background-position:center right}.rtl .wp_themeSkin .mceListBox .mceText{text-align:right}.rtl .wp_themeSkin .mceNoIcons a .mceText{padding-right:10px;padding-left:25px}.rtl .mceListBoxMenu.mceNoIcons{margin-left:-14px}.clearlooks2 .mceFocus .mceTop .mceLeft{background:#444;border-left:1px solid #999;border-top:1px solid #999;-webkit-border-top-left-radius:3px;border-top-left-radius:3px}.clearlooks2 .mceFocus .mceTop .mceRight{background:#444;border-right:1px solid #999;border-top:1px solid #999;-webkit-border-top-right-radius:3px;border-top-right-radius:3px}.clearlooks2 .mceMiddle .mceLeft{background:#f1f1f1;border-left:1px solid #999}.clearlooks2 .mceMiddle .mceRight{background:#f1f1f1;border-right:1px solid #999}.clearlooks2 .mceBottom{background:#f1f1f1;border-bottom:1px solid #999}.clearlooks2 .mceBottom .mceLeft{background:#f1f1f1;border-bottom:1px solid #999;border-left:1px solid #999}.clearlooks2 .mceBottom .mceCenter{background:#f1f1f1;border-bottom:1px solid #999}.clearlooks2 .mceBottom .mceRight{background:#f1f1f1;border-bottom:1px solid #999;border-right:1px solid #999}.clearlooks2 .mceFocus .mceTop span{color:#e5e5e5}.fullscreen-overlay{z-index:149999;display:none;position:fixed;top:0;bottom:0;left:0;right:0;filter:inherit}.fullscreen-active .fullscreen-overlay,.fullscreen-active #wp-fullscreen-body{display:block}.fullscreen-fader{z-index:200000}.fullscreen-active .fullscreen-fader{display:none}#wp-fullscreen-body{width:100%;z-index:150005;display:none;position:absolute;top:0;left:0;font-size:12px}#wp-fullscreen-wrap{margin:0 auto 50px;position:relative;padding-top:60px}#wp-fullscreen-title{font-size:1.7em;line-height:100%;outline:medium none;padding:6px 7px;width:100%;margin-bottom:30px}#wp-fullscreen-container{padding:4px 10px 50px}#wp-fullscreen-title,#wp-fullscreen-container{-webkit-border-radius:0;border-radius:0;border:1px dashed transparent;background:transparent;-moz-transition-property:border-color;-moz-transition-duration:.6s;-webkit-transition-property:border-color;-webkit-transition-duration:.6s;-o-transition-property:border-color;-o-transition-duration:.6s;transition-property:border-color;transition-duration:.6s}#wp_mce_fullscreen{width:100%;min-height:300px;border:0;background:transparent;font-family:Consolas,Monaco,monospace;line-height:1.6em;padding:0;overflow-y:hidden;outline:0;resize:none}#wp-fullscreen-tagline{color:#bbb;font-size:18px;float:right;padding-top:5px}#fullscreen-topbar{position:fixed;top:0;left:0;z-index:150050;border-bottom-style:solid;border-bottom-width:1px;min-width:800px;width:100%;height:40px}#wp-fullscreen-toolbar{padding:6px 10px 0;clear:both;max-width:1100px;min-width:820px;margin:0 auto}#wp-fullscreen-mode-bar,#wp-fullscreen-button-bar,#wp-fullscreen-close,#wp-fullscreen-count{float:left}#wp-fullscreen-save{float:right;padding:2px 2px 0 5px}#wp-fullscreen-count,#wp-fullscreen-close{padding-top:5px}#wp-fullscreen-central-toolbar{margin:auto;padding:0}#wp-fullscreen-buttons>div{float:left}#wp-fullscreen-mode-bar{padding:1px 14px 0 0}#wp-fullscreen-modes a{display:block;font-size:11px;text-decoration:none;float:left;margin:1px 0 0 0;padding:2px 6px 2px;border-width:1px 1px 1px 0;border-style:solid;border-color:#bbb;color:#777;text-shadow:0 1px 0 #fff;background-color:#f4f4f4;background-image:-moz-linear-gradient(bottom,#e4e4e4,#f9f9f9);background-image:-webkit-gradient(linear,left bottom,left top,from(#e4e4e4),to(#f9f9f9))}#wp-fullscreen-modes a:hover,.wp-html-mode #wp-fullscreen-modes a:last-child,.wp-tmce-mode #wp-fullscreen-modes a:first-child{color:#333;border-color:#999;background-color:#eee;background-image:-moz-linear-gradient(bottom,#f9f9f9,#e0e0e0);background-image:-webkit-gradient(linear,left bottom,left top,from(#f9f9f9),to(#e0e0e0))}#wp-fullscreen-modes a:first-child{border-width:1px;-webkit-border-top-left-radius:3px;-webkit-border-bottom-left-radius:3px;border-top-left-radius:3px;border-bottom-left-radius:3px}#wp-fullscreen-modes a:last-child{-webkit-border-top-right-radius:3px;-webkit-border-bottom-right-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px}#wp-fullscreen-buttons .active a{background:inherit}#wp-fullscreen-buttons .hidden{display:none}#wp-fullscreen-buttons .disabled{opacity:.5}.wp-html-mode #wp-fullscreen-buttons div{display:none}.wp-html-mode #wp-fullscreen-buttons div.wp-fullscreen-both{display:block}#fullscreen-topbar.fullscreen-make-sticky{display:block!important}#wp-fullscreen-save img{vertical-align:middle}#wp-fullscreen-save img,#wp-fullscreen-save span{padding-right:4px;display:none}#wp-fullscreen-buttons .mce_image .mce_image{background-image:url('../../wp-admin/images/media-button.png?ver=20120201');background-position:3px 3px}.fullscreen-active #TB_overlay{z-index:150100}.fullscreen-active #TB_window{z-index:150102}#wp_mce_fullscreen_ifr{background:transparent}#wp_mce_fullscreen_parent #wp_mce_fullscreen_tbl tr.mceFirst{display:none}#wp-fullscreen-container .wp_themeSkin table td{vertical-align:top}.fullscreen-overlay{background:#fff}.wp-fullscreen-focus #wp-fullscreen-title,.wp-fullscreen-focus #wp-fullscreen-container{border-color:#ccc}#fullscreen-topbar{border-bottom-color:#dfdfdf;background-color:#f1f1f1;background-image:-ms-linear-gradient(top,#f9f9f9,#ececec);background-image:-moz-linear-gradient(top,#f9f9f9,#ececec);background-image:-o-linear-gradient(top,#f9f9f9,#ececec);background-image:-webkit-gradient(linear,left top,left bottom,from(#f9f9f9),to(#ececec));background-image:-webkit-linear-gradient(top,#f9f9f9,#ececec);background-image:linear-gradient(top,#f9f9f9,#ececec)}.fade-1000,.fade-600,.fade-400,.fade-300{opacity:0;-moz-transition-property:opacity;-webkit-transition-property:opacity;-o-transition-property:opacity;transition-property:opacity}.fade-1000{-moz-transition-duration:1s;-webkit-transition-duration:1s;-o-transition-duration:1s;transition-duration:1s}.fade-600{-moz-transition-duration:.6s;-webkit-transition-duration:.6s;-o-transition-duration:.6s;transition-duration:.6s}.fade-400{-moz-transition-duration:.4s;-webkit-transition-duration:.4s;-o-transition-duration:.4s;transition-duration:.4s}.fade-300{-moz-transition-duration:.3s;-webkit-transition-duration:.3s;-o-transition-duration:.3s;transition-duration:.3s}.fade-trigger{opacity:1}.rtl #wp-fullscreen-tagline{float:left}.rtl #fullscreen-topbar{left:auto;right:0}.rtl #wp-fullscreen-mode-bar,.rtl #wp-fullscreen-button-bar,.rtl #wp-fullscreen-close,.rtl #wp-fullscreen-count{float:right}.rtl #wp-fullscreen-save{float:left}.rtl #wp-fullscreen-save{padding:2px 5px 0 2px}.rtl #wp-fullscreen-buttons>div{float:right}.rtl #wp-fullscreen-mode-bar{padding:1px 0 0 14px}.rtl #wp-fullscreen-modes a{float:right;border-width:1px 0 1px 1px}.rtl #wp-fullscreen-modes a:first-child{-webkit-border-top-left-radius:0;-webkit-border-top-right-radius:3px;-webkit-border-bottom-left-radius:0;-webkit-border-bottom-right-radius:3px;border-width:1px;border-top-left-radius:0;border-top-right-radius:3px;border-bottom-right-left:0;border-bottom-right-radius:3px}.rtl #wp-fullscreen-modes a:last-child{-webkit-border-top-right-radius:0;-webkit-border-top-left-radius:3px;-webkit-border-bottom-right-radius:0;-webkit-border-bottom-left-radius:3px;border-top-right-radius:0;border-top-left-radius:3px;border-bottom-right-radius:0;border-bottom-left-radius:3px}.rtl #wp-fullscreen-save img,.rtl #wp-fullscreen-save span{padding-right:0;padding-left:4px} diff --git a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/source_editor.htm b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/source_editor.htm index 2861e05..dd973fc 100644 --- a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/source_editor.htm +++ b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/themes/advanced/source_editor.htm @@ -1,25 +1,25 @@ - - - {#advanced_dlg.code_title} - - - - -
            -
            - -
            - -
            - -
            - - - -
            - - -
            -
            - - + + + {#advanced_dlg.code_title} + + + + +
            +
            + +
            + +
            + +
            + + + +
            + + +
            +
            + + diff --git a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/tiny_mce_popup.js b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/tiny_mce_popup.js index bb8e58c..f2d3ef9 100644 --- a/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/tiny_mce_popup.js +++ b/profile-builder/assets/lib/wck-api/assets/js/tiny_mce/tiny_mce_popup.js @@ -1,5 +1,5 @@ - -// Uncomment and change this document.domain value if you are loading the script cross subdomains -// document.domain = 'moxiecode.com'; - + +// Uncomment and change this document.domain value if you are loading the script cross subdomains +// document.domain = 'moxiecode.com'; + var tinymce=null,tinyMCEPopup,tinyMCE;tinyMCEPopup={init:function(){var b=this,a,c;a=b.getWin();tinymce=a.tinymce;tinyMCE=a.tinyMCE;b.editor=tinymce.EditorManager.activeEditor;b.params=b.editor.windowManager.params;b.features=b.editor.windowManager.features;b.dom=b.editor.windowManager.createInstance("tinymce.dom.DOMUtils",document,{ownEvents:true,proxy:tinyMCEPopup._eventProxy});b.dom.bind(window,"ready",b._onDOMLoaded,b);if(b.features.popup_css!==false){b.dom.loadCSS(b.features.popup_css||b.editor.settings.popup_css)}b.listeners=[];b.onInit={add:function(e,d){b.listeners.push({func:e,scope:d})}};b.isWindow=!b.getWindowArg("mce_inline");b.id=b.getWindowArg("mce_window_id");b.editor.windowManager.onOpen.dispatch(b.editor.windowManager,window)},getWin:function(){return(!window.frameElement&&window.dialogArguments)||opener||parent||top},getWindowArg:function(c,b){var a=this.params[c];return tinymce.is(a)?a:b},getParam:function(b,a){return this.editor.getParam(b,a)},getLang:function(b,a){return this.editor.getLang(b,a)},execCommand:function(d,c,e,b){b=b||{};b.skip_focus=1;this.restoreSelection();return this.editor.execCommand(d,c,e,b)},resizeToInnerSize:function(){var a=this;setTimeout(function(){var b=a.dom.getViewPort(window);a.editor.windowManager.resizeBy(a.getWindowArg("mce_width")-b.w,a.getWindowArg("mce_height")-b.h,a.id||window)},10)},executeOnLoad:function(s){this.onInit.add(function(){eval(s)})},storeSelection:function(){this.editor.windowManager.bookmark=tinyMCEPopup.editor.selection.getBookmark(1)},restoreSelection:function(){var a=tinyMCEPopup;if(!a.isWindow&&tinymce.isIE){a.editor.selection.moveToBookmark(a.editor.windowManager.bookmark)}},requireLangPack:function(){var b=this,a=b.getWindowArg("plugin_url")||b.getWindowArg("theme_url");if(a&&b.editor.settings.language&&b.features.translate_i18n!==false&&b.editor.settings.language_load!==false){a+="/langs/"+b.editor.settings.language+"_dlg.js";if(!tinymce.ScriptLoader.isDone(a)){document.write(''; +'; +$element .= ''; ?> \ No newline at end of file diff --git a/profile-builder/assets/lib/wck-api/fields/nested repeater.php b/profile-builder/assets/lib/wck-api/fields/nested repeater.php index 275123f..319393e 100644 --- a/profile-builder/assets/lib/wck-api/fields/nested repeater.php +++ b/profile-builder/assets/lib/wck-api/fields/nested repeater.php @@ -1,9 +1,9 @@ - \ No newline at end of file diff --git a/profile-builder/assets/lib/wck-api/fields/radio.php b/profile-builder/assets/lib/wck-api/fields/radio.php index c2e4bfd..ee9bb06 100644 --- a/profile-builder/assets/lib/wck-api/fields/radio.php +++ b/profile-builder/assets/lib/wck-api/fields/radio.php @@ -1,45 +1,45 @@ -'; - foreach( $details['options'] as $option ){ - $found = false; - - $values = explode( ', ', $value ); - if( strpos( $option, '%' ) === false ){ - $label = $option; - $value_attr = $option; - if ( in_array( $option, $values ) ) - $found = true; - } - else{ - $option_parts = explode( '%', $option ); - if( !empty( $option_parts ) ){ - if( empty( $option_parts[0] ) && count( $option_parts ) == 3 ){ - $label = $option_parts[1]; - $value_attr = $option_parts[2]; - if ( in_array( $option_parts[2], $values ) ) - $found = true; - } - } - } - - $element .= '
            '; - } - $element .= ''; -} +'; + foreach( $details['options'] as $option ){ + $found = false; + + $values = explode( ', ', $value ); + if( strpos( $option, '%' ) === false ){ + $label = $option; + $value_attr = $option; + if ( in_array( $option, $values ) ) + $found = true; + } + else{ + $option_parts = explode( '%', $option ); + if( !empty( $option_parts ) ){ + if( empty( $option_parts[0] ) && count( $option_parts ) == 3 ){ + $label = $option_parts[1]; + $value_attr = $option_parts[2]; + if ( in_array( $option_parts[2], $values ) ) + $found = true; + } + } + } + + $element .= '
            '; + } + $element .= ''; +} ?> \ No newline at end of file diff --git a/profile-builder/assets/lib/wck-api/fields/select.php b/profile-builder/assets/lib/wck-api/fields/select.php index 0e6c8d8..5b70984 100644 --- a/profile-builder/assets/lib/wck-api/fields/select.php +++ b/profile-builder/assets/lib/wck-api/fields/select.php @@ -1,51 +1,51 @@ -'; - -if( !empty( $details['default-option'] ) && $details['default-option'] ) - $element .= ''; - -$field_name = Wordpress_Creation_Kit_PB::wck_generate_slug( $details['title'], $details ); - -$options = ''; -if( !empty( $details['options'] ) ){ - $i = 0; - foreach( $details['options'] as $option ){ - - if( strpos( $option, '%' ) === false ){ - $label = $option; - if( !empty( $details['values'] ) ) - $value_attr = $details['values'][$i]; - else - $value_attr = $option; - } - else{ - $option_parts = explode( '%', $option ); - if( !empty( $option_parts ) ){ - if( empty( $option_parts[0] ) && count( $option_parts ) == 3 ){ - $label = $option_parts[1]; - if( !empty( $details['values'] ) ) - $value_attr = $details['values'][$i]; - else - $value_attr = $option_parts[2]; - } - } - } - - $optionOutput = ''; - $options .= apply_filters( "wck_select_{$meta}_{$field_name}_option_{$i}", $optionOutput, $i); - - $i++; - } -} -$element .= apply_filters( "wck_select_{$meta}_{$field_name}_options", $options ); -$element .= ''; +'; + +if( !empty( $details['default-option'] ) && $details['default-option'] ) + $element .= ''; + +$field_name = Wordpress_Creation_Kit_PB::wck_generate_slug( $details['title'], $details ); + +$options = ''; +if( !empty( $details['options'] ) ){ + $i = 0; + foreach( $details['options'] as $option ){ + + if( strpos( $option, '%' ) === false ){ + $label = $option; + if( !empty( $details['values'] ) ) + $value_attr = $details['values'][$i]; + else + $value_attr = $option; + } + else{ + $option_parts = explode( '%', $option ); + if( !empty( $option_parts ) ){ + if( empty( $option_parts[0] ) && count( $option_parts ) == 3 ){ + $label = $option_parts[1]; + if( !empty( $details['values'] ) ) + $value_attr = $details['values'][$i]; + else + $value_attr = $option_parts[2]; + } + } + } + + $optionOutput = ''; + $options .= apply_filters( "wck_select_{$meta}_{$field_name}_option_{$i}", $optionOutput, $i); + + $i++; + } +} +$element .= apply_filters( "wck_select_{$meta}_{$field_name}_options", $options ); +$element .= ''; ?> \ No newline at end of file diff --git a/profile-builder/assets/lib/wck-api/fields/text.php b/profile-builder/assets/lib/wck-api/fields/text.php index 57043e4..e1e3693 100644 --- a/profile-builder/assets/lib/wck-api/fields/text.php +++ b/profile-builder/assets/lib/wck-api/fields/text.php @@ -1,16 +1,16 @@ -'; +'; ?> \ No newline at end of file diff --git a/profile-builder/assets/lib/wck-api/fields/textarea.php b/profile-builder/assets/lib/wck-api/fields/textarea.php index 2cc7daa..73a9554 100644 --- a/profile-builder/assets/lib/wck-api/fields/textarea.php +++ b/profile-builder/assets/lib/wck-api/fields/textarea.php @@ -1,12 +1,12 @@ -'. esc_html( $value ) .''; +'. esc_html( $value ) .''; ?> \ No newline at end of file diff --git a/profile-builder/assets/lib/wck-api/fields/upload.js b/profile-builder/assets/lib/wck-api/fields/upload.js index ecb1e06..64fd609 100644 --- a/profile-builder/assets/lib/wck-api/fields/upload.js +++ b/profile-builder/assets/lib/wck-api/fields/upload.js @@ -1,131 +1,131 @@ -jQuery(document).ready(function(){ - - if( typeof wp != "undefined" ){ - - // Uploading files - var wp_media_post_id = wp.media.model.settings.post.id; // Store the old id - - - jQuery(document).on( 'click', '.wck_upload_button', function( event ){ - event.preventDefault(); - - var set_to_post_id = jQuery( this ).data( 'post_id' ); // Set this - - - var file_frame; - var uploadInputId = jQuery( this ).data( 'upload_input' ); - var uploadInFront = jQuery( this ).data( 'upload_in_backend' ); - var attachToPost = jQuery( this ).data( 'attach_to_post' ); - var uploadButton = jQuery( this ); - - /* remove set_to_post_id value if we do not want to attach to post */ - if( attachToPost != true ){ - set_to_post_id = ''; - } - - /* set default tab to upload file */ - wp.media.controller.Library.prototype.defaults.contentUserSetting = false; - if( uploadInFront != true ) - wp.media.controller.Library.prototype.defaults.router = false; - wp.media.controller.Library.prototype.defaults.searchable = true; - wp.media.controller.Library.prototype.defaults.sortable = false; - - // If the media frame already exists, reopen it. - if ( file_frame ) { - // Set the post ID to what we want - file_frame.uploader.uploader.param( 'post_id', set_to_post_id ); - // Open frame - file_frame.open(); - return; - } else { - // Set the wp.media post id so the uploader grabs the ID we want when initialised - wp.media.model.settings.post.id = set_to_post_id; - } - - // Create the media frame. - file_frame = wp.media.frames.file_frame = wp.media({ - title: jQuery( this ).data( 'uploader_title' ), - button: { - text: jQuery( this ).data( 'uploader_button_text' ), - }, - multiple: jQuery( this ).data( 'multiple_upload' ) // Set to true to allow multiple files to be selected - }); - - /* restrict allowed file types if we have to */ - allowedTypes = jQuery( this ).data( 'allowed_types' ); - if( allowedTypes != undefined ) - file_frame.uploader.options.uploader['params']['allowed_type'] = allowedTypes; - - // When an image is selected, run a callback. - file_frame.on( 'select', function() { - // We set multiple to false so only get one image from the uploader - attachments = file_frame.state().get('selection').toJSON(); - var attids = []; - - for( var i=0;i < attachments.length; i++ ){ - // Do something with attachment.id and/or attachment.url here - attids.push( attachments[i].id ); - result = '
            '; - if( attachments[i].sizes != undefined ){ - if( attachments[i].sizes.thumbnail != undefined ) - thumb = attachments[i].sizes.thumbnail; - else - thumb = attachments[i].sizes.full; - thumbnailUrl = thumb.url; - } - else{ - thumbnailUrl = attachments[i].icon; - } - result += '
            '; - result += '

            '+attachments[i].filename+''+attachments[i].mime +'Remove

            '; - - /* if multiple upload false remove previous upload details */ - if( uploadButton.data( 'multiple_upload' ) == false ){ - jQuery( '.upload-field-details', uploadButton.parent() ).remove(); - } - - uploadButton.before( result ); - - } - /* turn into comma separated string */ - attids = attids.join(','); - jQuery( 'input[id="'+uploadInputId+'"]', uploadButton.parent() ).val( attids ); - - // Restore the main post ID - wp.media.model.settings.post.id = wp_media_post_id; - }); - - // Finally, open the modal - file_frame.open(); - // remove tabs from the top ( this is done higher in the code when setting router to false ) - //jQuery('.media-frame-router').remove(); - - if( jQuery( this ).data( 'uploader_logged_in' ) == undefined ){ - jQuery('.media-frame-title').append(''); - } - }); - - // Restore the main ID when the add media button is pressed - jQuery('a.add_media').on('click', function() { - wp.media.model.settings.post.id = wp_media_post_id; - }); - - jQuery(document).on('click', '.wck-remove-upload', function(e){ - /* update hidden input */ - removedAttachement = jQuery(this).parent().parent('.upload-field-details').data('attachment_id'); - upload_input = jQuery(this).parent().parent().parent().children('input[type="hidden"]'); - uploadAttachemnts = upload_input.val(); - uploadAttachemntsArray = uploadAttachemnts.split( ',' ); - newuploadAttachments = []; - for( var i=0;i < uploadAttachemntsArray.length; i++ ){ - if( uploadAttachemntsArray[i] != removedAttachement ) - newuploadAttachments.push(uploadAttachemntsArray[i]); - } - newuploadAttachments = newuploadAttachments.join(','); - upload_input.val(newuploadAttachments); - - /* remove the attachment details */ - jQuery(this).parent().parent('.upload-field-details').remove(); - }); - } +jQuery(document).ready(function(){ + + if( typeof wp != "undefined" ){ + + // Uploading files + var wp_media_post_id = wp.media.model.settings.post.id; // Store the old id + + + jQuery(document).on( 'click', '.wck_upload_button', function( event ){ + event.preventDefault(); + + var set_to_post_id = jQuery( this ).data( 'post_id' ); // Set this + + + var file_frame; + var uploadInputId = jQuery( this ).data( 'upload_input' ); + var uploadInFront = jQuery( this ).data( 'upload_in_backend' ); + var attachToPost = jQuery( this ).data( 'attach_to_post' ); + var uploadButton = jQuery( this ); + + /* remove set_to_post_id value if we do not want to attach to post */ + if( attachToPost != true ){ + set_to_post_id = ''; + } + + /* set default tab to upload file */ + wp.media.controller.Library.prototype.defaults.contentUserSetting = false; + if( uploadInFront != true ) + wp.media.controller.Library.prototype.defaults.router = false; + wp.media.controller.Library.prototype.defaults.searchable = true; + wp.media.controller.Library.prototype.defaults.sortable = false; + + // If the media frame already exists, reopen it. + if ( file_frame ) { + // Set the post ID to what we want + file_frame.uploader.uploader.param( 'post_id', set_to_post_id ); + // Open frame + file_frame.open(); + return; + } else { + // Set the wp.media post id so the uploader grabs the ID we want when initialised + wp.media.model.settings.post.id = set_to_post_id; + } + + // Create the media frame. + file_frame = wp.media.frames.file_frame = wp.media({ + title: jQuery( this ).data( 'uploader_title' ), + button: { + text: jQuery( this ).data( 'uploader_button_text' ), + }, + multiple: jQuery( this ).data( 'multiple_upload' ) // Set to true to allow multiple files to be selected + }); + + /* restrict allowed file types if we have to */ + allowedTypes = jQuery( this ).data( 'allowed_types' ); + if( allowedTypes != undefined ) + file_frame.uploader.options.uploader['params']['allowed_type'] = allowedTypes; + + // When an image is selected, run a callback. + file_frame.on( 'select', function() { + // We set multiple to false so only get one image from the uploader + attachments = file_frame.state().get('selection').toJSON(); + var attids = []; + + for( var i=0;i < attachments.length; i++ ){ + // Do something with attachment.id and/or attachment.url here + attids.push( attachments[i].id ); + result = '
            '; + if( attachments[i].sizes != undefined ){ + if( attachments[i].sizes.thumbnail != undefined ) + thumb = attachments[i].sizes.thumbnail; + else + thumb = attachments[i].sizes.full; + thumbnailUrl = thumb.url; + } + else{ + thumbnailUrl = attachments[i].icon; + } + result += '
            '; + result += '

            '+attachments[i].filename+''+attachments[i].mime +'Remove

            '; + + /* if multiple upload false remove previous upload details */ + if( uploadButton.data( 'multiple_upload' ) == false ){ + jQuery( '.upload-field-details', uploadButton.parent() ).remove(); + } + + uploadButton.before( result ); + + } + /* turn into comma separated string */ + attids = attids.join(','); + jQuery( 'input[id="'+uploadInputId+'"]', uploadButton.parent() ).val( attids ); + + // Restore the main post ID + wp.media.model.settings.post.id = wp_media_post_id; + }); + + // Finally, open the modal + file_frame.open(); + // remove tabs from the top ( this is done higher in the code when setting router to false ) + //jQuery('.media-frame-router').remove(); + + if( jQuery( this ).data( 'uploader_logged_in' ) == undefined ){ + jQuery('.media-frame-title').append(''); + } + }); + + // Restore the main ID when the add media button is pressed + jQuery('a.add_media').on('click', function() { + wp.media.model.settings.post.id = wp_media_post_id; + }); + + jQuery(document).on('click', '.wck-remove-upload', function(e){ + /* update hidden input */ + removedAttachement = jQuery(this).parent().parent('.upload-field-details').data('attachment_id'); + upload_input = jQuery(this).parent().parent().parent().children('input[type="hidden"]'); + uploadAttachemnts = upload_input.val(); + uploadAttachemntsArray = uploadAttachemnts.split( ',' ); + newuploadAttachments = []; + for( var i=0;i < uploadAttachemntsArray.length; i++ ){ + if( uploadAttachemntsArray[i] != removedAttachement ) + newuploadAttachments.push(uploadAttachemntsArray[i]); + } + newuploadAttachments = newuploadAttachments.join(','); + upload_input.val(newuploadAttachments); + + /* remove the attachment details */ + jQuery(this).parent().parent('.upload-field-details').remove(); + }); + } }); \ No newline at end of file diff --git a/profile-builder/assets/lib/wck-api/fields/upload.php b/profile-builder/assets/lib/wck-api/fields/upload.php index 4a71e83..126f85e 100644 --- a/profile-builder/assets/lib/wck-api/fields/upload.php +++ b/profile-builder/assets/lib/wck-api/fields/upload.php @@ -1,76 +1,76 @@ -'; - -/* container for the image preview (or file ico) and name and file type */ -if( !empty ( $value ) ){ - /* it can hold multiple attachments separated by comma */ - $values = explode( ',', $value ); - foreach( $values as $value ){ - $file_src = wp_get_attachment_url($value); - $thumbnail = wp_get_attachment_image( $value, array( 80, 80 ), true ); - $file_name = get_the_title( $value ); - $file_type = get_post_mime_type( $value ); - $attachment_url = admin_url( "post.php?post={$value}&action=edit" ); - - $element.= '
            '; - $element.= '
            '; - $element.= "" . $thumbnail . ""; - $element.= '
            '; - - $element.= '

            '; - $element.= $file_name; - $element.= ''; - $element.= $file_type; - $element.= ''; - if( !empty ( $value ) ) - $element.= ''.__( 'Remove', 'core' ).''; - $element.= '

            '; - } -} - -$element.= ''; +'; + +/* container for the image preview (or file ico) and name and file type */ +if( !empty ( $value ) ){ + /* it can hold multiple attachments separated by comma */ + $values = explode( ',', $value ); + foreach( $values as $value ){ + $file_src = wp_get_attachment_url($value); + $thumbnail = wp_get_attachment_image( $value, array( 80, 80 ), true ); + $file_name = get_the_title( $value ); + $file_type = get_post_mime_type( $value ); + $attachment_url = admin_url( "post.php?post={$value}&action=edit" ); + + $element.= '
            '; + $element.= ''; + + $element.= '

            '; + $element.= $file_name; + $element.= ''; + $element.= $file_type; + $element.= ''; + if( !empty ( $value ) ) + $element.= ''.__( 'Remove', 'core' ).''; + $element.= '

            '; + } +} + +$element.= ''; ?> \ No newline at end of file diff --git a/profile-builder/assets/lib/wck-api/fields/user select.php b/profile-builder/assets/lib/wck-api/fields/user select.php index b15e931..f9019a6 100644 --- a/profile-builder/assets/lib/wck-api/fields/user select.php +++ b/profile-builder/assets/lib/wck-api/fields/user select.php @@ -1,21 +1,21 @@ - 'display_name' ) ); -$user_query = new WP_User_Query($args); -if( !empty( $user_query->results ) ){ - $element .= ''; -} + 'display_name' ) ); +$user_query = new WP_User_Query($args); +if( !empty( $user_query->results ) ){ + $element .= ''; +} ?> \ No newline at end of file diff --git a/profile-builder/assets/lib/wck-api/fields/wysiwyg editor.php b/profile-builder/assets/lib/wck-api/fields/wysiwyg editor.php index b838453..ec521e8 100644 --- a/profile-builder/assets/lib/wck-api/fields/wysiwyg editor.php +++ b/profile-builder/assets/lib/wck-api/fields/wysiwyg editor.php @@ -1,10 +1,10 @@ -'. esc_html( $value ) .''; -$element .= ''; +'. esc_html( $value ) .''; +$element .= ''; ?> \ No newline at end of file diff --git a/profile-builder/assets/lib/wck-api/readme.txt b/profile-builder/assets/lib/wck-api/readme.txt index e3e4e07..e20ee9b 100644 --- a/profile-builder/assets/lib/wck-api/readme.txt +++ b/profile-builder/assets/lib/wck-api/readme.txt @@ -1,135 +1,135 @@ -Usage Example 1 - - 'text', 'title' => 'Title', 'description' => 'Description for this input' ), - array( 'type' => 'textarea', 'title' => 'Description' ), - array( 'type' => 'upload', 'title' => 'Image', 'description' => 'Upload a image' ), - array( 'type' => 'select', 'title' => 'Select This', 'options' => array( 'Option 1', 'Option 2', 'Option 3' ) ), - - array( 'type' => 'checkbox', 'title' => 'Check This', 'options' => array( 'Option 1', 'Option 2', 'Option 3' ) ), - - array( 'type' => 'radio', 'title' => 'Radio This', 'options' => array( 'Radio 1', 'Radio 2', 'Radio 3' ) ), - ); - - $args = array( - 'metabox_id' => 'rm_slider_content', - 'metabox_title' => 'Slideshow Class', - 'post_type' => 'slideshows', - 'meta_name' => 'rmscontent', - 'meta_array' => $fint - ); - - new Wordpress_Creation_Kit_PB( $args ); - - ?> - -For Frontend use like this: - -ID, 'rmscontent', true ); ?> - - - - -Default Parameters - - '', - 'metabox_title' => 'Meta Box', - 'post_type' => 'post', - 'meta_name' => '', - 'meta_array' => array(), - 'page_template' => '', - 'post_id' => '', - 'single' => false, - 'unserialize_fields' => false, - 'sortable' => true, - 'context' => 'post_meta' - ) -?> - -Parameters - -$metabox_id - (string) (required) HTML 'id' attribute of the edit screen section - - Default: None - -$metabox_title - (string) (required) Title of the edit screen section, visible to user - - Default: 'Meta Box' - -$post_type - (string) (required) The type of Write screen on which to show the edit screen section ('post', 'page', 'link', or 'custom_post_type' where custom_post_type is the custom post type slug) - - Default: 'post' - -$meta_name - (string) (required) The name of the meta key used to query for data - - Default: None - -$meta_array - (array) (required) The array of fields used to create the form. See example above. Must be array( array() ). Type and Title are required. - - Default: None - -$page_template - (string) (optional) The name of the page template on wich you want the meta box to appear. If this is set than $post_type can be omitted. - - Default: None - -$post_id - (string) (optional) The id of the post you want the meta box to appear. If this is set than $post_type can be omitted. - - Default: None - -$single - (boolean) (optional) Set this to true if you don't want a repeater box and you will be able to enter just one value. - - Default: false - -$unserialize_fields - (boolean) (optional) Set this to true if you want to enable wpml compatibility - -$sortable - (boolean) (optional) Wheater or not the fields in a repeater box are sortable. - - Default: true - -$context - (string) (optional) WCK API can add data as meta or as option depending on the context. Using 'post_meta' will add data as post meta and using 'option' will add data as option - - Default: 'post_meta' - -Parameters for meta_array - -'title' (string) Title of the field. -'type' (string) The field type. Possible values: 'text', 'textarea', 'select', 'checkbox', 'radio', 'upload'. -'description' (string) The description of the field. -'required' (boolean) true if the field is required. -'default' (string) If you want the string to have a default value enter it here. For Checkboxes if there are multiple - values separate them with a ",". -'default-option' (boolean) true if you want Select to have a default option. -'options' (array) Options for field types "select", "checkbox" and "radio". - - -How to add into a plugin: - -1. Copy the foldder "wordpress-creation-kit-api" into the plugin dir -2. Change the class name "Wordpress_Creation_Kit_PB" if multiple plugins use wordpress-creation-kit-api on the same site. -3. Include "wordpress-creation-kit.php" into the plugin file - - /* include Custom Fields Creator API */ - require_once('wordpress-creation-kit/wordpress-creation-kit.php'); - -4. Use the API as in Exampe 1, in your plugin file or functions or whatever fits the situation. - - -WPML Compatibility - -When unserialize_fields is true on a meta box, besides saving the contents of the box in one serialized custom field, we create automatically a custom field for every field in every entry. We do this because WPML can't handle serialized custom fields and also we will get good control on what actions we want to perform (don't translate, copy, translate ) on each of the fields. - +Usage Example 1 + + 'text', 'title' => 'Title', 'description' => 'Description for this input' ), + array( 'type' => 'textarea', 'title' => 'Description' ), + array( 'type' => 'upload', 'title' => 'Image', 'description' => 'Upload a image' ), + array( 'type' => 'select', 'title' => 'Select This', 'options' => array( 'Option 1', 'Option 2', 'Option 3' ) ), + + array( 'type' => 'checkbox', 'title' => 'Check This', 'options' => array( 'Option 1', 'Option 2', 'Option 3' ) ), + + array( 'type' => 'radio', 'title' => 'Radio This', 'options' => array( 'Radio 1', 'Radio 2', 'Radio 3' ) ), + ); + + $args = array( + 'metabox_id' => 'rm_slider_content', + 'metabox_title' => 'Slideshow Class', + 'post_type' => 'slideshows', + 'meta_name' => 'rmscontent', + 'meta_array' => $fint + ); + + new Wordpress_Creation_Kit_PB( $args ); + + ?> + +For Frontend use like this: + +ID, 'rmscontent', true ); ?> + + + + +Default Parameters + + '', + 'metabox_title' => 'Meta Box', + 'post_type' => 'post', + 'meta_name' => '', + 'meta_array' => array(), + 'page_template' => '', + 'post_id' => '', + 'single' => false, + 'unserialize_fields' => false, + 'sortable' => true, + 'context' => 'post_meta' + ) +?> + +Parameters + +$metabox_id + (string) (required) HTML 'id' attribute of the edit screen section + + Default: None + +$metabox_title + (string) (required) Title of the edit screen section, visible to user + + Default: 'Meta Box' + +$post_type + (string) (required) The type of Write screen on which to show the edit screen section ('post', 'page', 'link', or 'custom_post_type' where custom_post_type is the custom post type slug) + + Default: 'post' + +$meta_name + (string) (required) The name of the meta key used to query for data + + Default: None + +$meta_array + (array) (required) The array of fields used to create the form. See example above. Must be array( array() ). Type and Title are required. + + Default: None + +$page_template + (string) (optional) The name of the page template on wich you want the meta box to appear. If this is set than $post_type can be omitted. + + Default: None + +$post_id + (string) (optional) The id of the post you want the meta box to appear. If this is set than $post_type can be omitted. + + Default: None + +$single + (boolean) (optional) Set this to true if you don't want a repeater box and you will be able to enter just one value. + + Default: false + +$unserialize_fields + (boolean) (optional) Set this to true if you want to enable wpml compatibility + +$sortable + (boolean) (optional) Wheater or not the fields in a repeater box are sortable. + + Default: true + +$context + (string) (optional) WCK API can add data as meta or as option depending on the context. Using 'post_meta' will add data as post meta and using 'option' will add data as option + + Default: 'post_meta' + +Parameters for meta_array + +'title' (string) Title of the field. +'type' (string) The field type. Possible values: 'text', 'textarea', 'select', 'checkbox', 'radio', 'upload'. +'description' (string) The description of the field. +'required' (boolean) true if the field is required. +'default' (string) If you want the string to have a default value enter it here. For Checkboxes if there are multiple + values separate them with a ",". +'default-option' (boolean) true if you want Select to have a default option. +'options' (array) Options for field types "select", "checkbox" and "radio". + + +How to add into a plugin: + +1. Copy the foldder "wordpress-creation-kit-api" into the plugin dir +2. Change the class name "Wordpress_Creation_Kit_PB" if multiple plugins use wordpress-creation-kit-api on the same site. +3. Include "wordpress-creation-kit.php" into the plugin file + + /* include Custom Fields Creator API */ + require_once('wordpress-creation-kit/wordpress-creation-kit.php'); + +4. Use the API as in Exampe 1, in your plugin file or functions or whatever fits the situation. + + +WPML Compatibility + +When unserialize_fields is true on a meta box, besides saving the contents of the box in one serialized custom field, we create automatically a custom field for every field in every entry. We do this because WPML can't handle serialized custom fields and also we will get good control on what actions we want to perform (don't translate, copy, translate ) on each of the fields. + After the fields are translated with Icanlcalize and we have the translated post in our system, we can go on the translated post and press the "Syncronize WCK Translation" button which will create the serialized array from the individual custom fields. \ No newline at end of file diff --git a/profile-builder/assets/lib/wck-api/wordpress-creation-kit.css b/profile-builder/assets/lib/wck-api/wordpress-creation-kit.css index 6352ac1..ccec05c 100644 --- a/profile-builder/assets/lib/wck-api/wordpress-creation-kit.css +++ b/profile-builder/assets/lib/wck-api/wordpress-creation-kit.css @@ -1,273 +1,273 @@ -.wck-post-box{ - visibility:hidden; - height:0; -} - -.mb-list-entry-fields li{ - margin-bottom:15px; - clear:both; - overflow:hidden; -} - -.mb-right-column{ - overflow:hidden; -} - -.field-label{ - max-width:200px; - float:left; - min-height:30px; - font-weight:bold; - padding-right:10px; -} - -.field-label.error{ - color:#ff0000; -} - -.field-label .required{ - color:#ff0000; - padding:0 2px; -} - -.mb-table-container strong{ - max-width:200px; -} - -.mb-right-column label{ - padding:0 6px 0 0; -} - -.mb-right-column input[type="checkbox"], .mb-right-column input[type="radio"]{ - margin-right:3px; -} - -#mb-ajax-loading{ - position:absolute; - top:0; - left:0; - width:100%; - height:100%; - background:url(images/ajax-loader.gif) center center no-repeat; z-index:999; -} - -.mb-table-container pre{ - display:inline-block; - vertical-align:top; - margin:0; - white-space: -moz-pre-wrap; - white-space: -pre-wrap; - white-space: -o-pre-wrap; - white-space: pre-wrap; - word-wrap: break-word; -} - - -.wck-edit, .wck-delete, .wck-number{ - width:50px; - text-align:center !important; -} - -td.wck-number{ - cursor:move; -} - -.wck-content > ul{ - margin:0; -} - -.not-sortable td.wck-number{ - cursor:auto; -} - -.wck-edit .button-secondary{ - padding:0 15px; -} - -.mbdelete, .wck-remove-upload{ - color:#BC0B0B; - cursor:pointer; -} - -.mbdelete:hover, .wck-remove-upload:hover{ - color:#FF0000; -} - -.mb-list-entry-fields{ - list-style:none; -} - -.mb-table-container tr:nth-child(2n+1) { - background-color:#FCFCFC; -} - -.mb-table-container tr:last-child td { - border-bottom: 0 none; -} - -.mb-table-container tr td { - background: none repeat scroll 0 0 transparent; - border-bottom: 1px solid #EDEDED; - border-right: 1px solid #EDEDED; - padding: 8px; - position: relative; -} - -.mb-table-container tr td:last-child { - border-right: 0 none; -} - -.mb-table-container thead > tr > th { - border-right: 1px solid #E1E1E1; -} - -.mb-table-container tr > th:last-child { - border-right: 0 none; -} - -.mb-textarea{ - width:60%; - max-width:600px; - height:130px; -} -.mb-text-input{ - width:40%; - max-width:400px; -} - -.mb-select{ - min-width:150px; -} - -/* upload field */ -.upload-field-details{ - display:inline-block; - vertical-align:middle; - min-height:24px; - padding:2px 0; -} - -.upload-field-details p{ - margin:2px 0 0; -} - -.upload-field-details img{ - margin:0 5px; - box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3); -} - -.upload-field-details > *{ - float:left; -} - -.upload-field-details span{ - display:block; -} - -.upload-field-details .file-name{ - font-weight:bold; - color:#21759B; -} - - -/* Settings page. */ -.side .form-table th { - width: 20%; - font-weight: bold; - text-align: left; - padding-left: 0; -} - -.wck-post-body{ - clear: left; - float: left; - margin-right: -2000px; - width: 100%; -} - -.metabox-holder .column-1 { - margin-right:300px; -} -.metabox-holder .column-2 { - float: right; - width: 280px; - clear:right; - position:relative; -} -.metabox-holder .column-3 { - clear: both; - margin-right:300px; -} - -/* wysiwyg */ -.mb-right-column .wp_themeSkin table.mceLayout{ - border-color: #CCCCCC #CCCCCC #DFDFDF; - border-style: solid; - border-top-left-radius: 3px; - border-top-right-radius: 3px; - border-width: 1px; - background-color:#fff; -} - -/* nested repeater */ -.mb-table-container .wck-nested{ - background:#F5F5F5; - border:1px solid #DFDFDF; - box-shadow: 0 1px 0 #FFFFFF; -} - -.mb-table-container .wck-nested > div{ - padding:10px; -} - -.mb-table-container li[data-type="nested-repeater"]{ - display:none; -} - -.wck_page_cptc-page #contextual-help-link-wrap, .wck_page_ctc-page #contextual-help-link-wrap, .wck_page_cfc-page #contextual-help-link-wrap, .wck_page_fep-page #contextual-help-link-wrap, .wck_page_opc-page #contextual-help-link-wrap{ - background: rgb(248,79,79); /* Old browsers */ - background: -moz-linear-gradient(top, rgba(248,79,79,1) 0%, rgba(210,11,11,1) 100%); /* FF3.6+ */ - background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(248,79,79,1)), color-stop(100%,rgba(210,11,11,1))); /* Chrome,Safari4+ */ - background: -webkit-linear-gradient(top, rgba(248,79,79,1) 0%,rgba(210,11,11,1) 100%); /* Chrome10+,Safari5.1+ */ - background: -o-linear-gradient(top, rgba(248,79,79,1) 0%,rgba(210,11,11,1) 100%); /* Opera 11.10+ */ - background: -ms-linear-gradient(top, rgba(248,79,79,1) 0%,rgba(210,11,11,1) 100%); /* IE10+ */ - background: linear-gradient(to bottom, rgba(248,79,79,1) 0%,rgba(210,11,11,1) 100%); /* W3C */ - filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f84f4f', endColorstr='#d20b0b',GradientType=0 ); /* IE6-9 */ -} - -.wck_page_cptc-page #contextual-help-link-wrap #contextual-help-link, .wck_page_ctc-page #contextual-help-link-wrap #contextual-help-link, .wck_page_cfc-page #contextual-help-link-wrap #contextual-help-link, .wck_page_fep-page #contextual-help-link-wrap #contextual-help-link, .wck_page_opc-page #contextual-help-link-wrap #contextual-help-link{ - padding-left:55px; - color: #FFFFFF; - text-shadow: 0 1px 0 rgba(0, 0, 0, 0.7); -} - -.wck_page_cptc-page #contextual-help-link-wrap #contextual-help-link:before, .wck_page_ctc-page #contextual-help-link-wrap #contextual-help-link:before, .wck_page_cfc-page #contextual-help-link-wrap #contextual-help-link:before, .wck_page_fep-page #contextual-help-link-wrap #contextual-help-link:before, .wck_page_opc-page #contextual-help-link-wrap #contextual-help-link:before{ - content:"WCK"; - width:15px; - height:20px; - background:url( ../images/wck-icon-dark.png ) no-repeat 0 0; - position:absolute; - top:4px; - left:4px; - line-height: 16px; - padding-left: 18px; -} - -/*-------------------------------------------------------------- -Media Queries ---------------------------------------------------------------*/ -@media screen and ( max-width: 878px ) { - .wck-post-body{ - float:none; - margin-right: 0; - } - - .metabox-holder .column-2{ - float:none; - width:100%; - } - - .metabox-holder .column-1{ - margin-right:0; - } +.wck-post-box{ + visibility:hidden; + height:0; +} + +.mb-list-entry-fields li{ + margin-bottom:15px; + clear:both; + overflow:hidden; +} + +.mb-right-column{ + overflow:hidden; +} + +.field-label{ + max-width:200px; + float:left; + min-height:30px; + font-weight:bold; + padding-right:10px; +} + +.field-label.error{ + color:#ff0000; +} + +.field-label .required{ + color:#ff0000; + padding:0 2px; +} + +.mb-table-container strong{ + max-width:200px; +} + +.mb-right-column label{ + padding:0 6px 0 0; +} + +.mb-right-column input[type="checkbox"], .mb-right-column input[type="radio"]{ + margin-right:3px; +} + +#mb-ajax-loading{ + position:absolute; + top:0; + left:0; + width:100%; + height:100%; + background:url(images/ajax-loader.gif) center center no-repeat; z-index:999; +} + +.mb-table-container pre{ + display:inline-block; + vertical-align:top; + margin:0; + white-space: -moz-pre-wrap; + white-space: -pre-wrap; + white-space: -o-pre-wrap; + white-space: pre-wrap; + word-wrap: break-word; +} + + +.wck-edit, .wck-delete, .wck-number{ + width:50px; + text-align:center !important; +} + +td.wck-number{ + cursor:move; +} + +.wck-content > ul{ + margin:0; +} + +.not-sortable td.wck-number{ + cursor:auto; +} + +.wck-edit .button-secondary{ + padding:0 15px; +} + +.mbdelete, .wck-remove-upload{ + color:#BC0B0B; + cursor:pointer; +} + +.mbdelete:hover, .wck-remove-upload:hover{ + color:#FF0000; +} + +.mb-list-entry-fields{ + list-style:none; +} + +.mb-table-container tr:nth-child(2n+1) { + background-color:#FCFCFC; +} + +.mb-table-container tr:last-child td { + border-bottom: 0 none; +} + +.mb-table-container tr td { + background: none repeat scroll 0 0 transparent; + border-bottom: 1px solid #EDEDED; + border-right: 1px solid #EDEDED; + padding: 8px; + position: relative; +} + +.mb-table-container tr td:last-child { + border-right: 0 none; +} + +.mb-table-container thead > tr > th { + border-right: 1px solid #E1E1E1; +} + +.mb-table-container tr > th:last-child { + border-right: 0 none; +} + +.mb-textarea{ + width:60%; + max-width:600px; + height:130px; +} +.mb-text-input{ + width:40%; + max-width:400px; +} + +.mb-select{ + min-width:150px; +} + +/* upload field */ +.upload-field-details{ + display:inline-block; + vertical-align:middle; + min-height:24px; + padding:2px 0; +} + +.upload-field-details p{ + margin:2px 0 0; +} + +.upload-field-details img{ + margin:0 5px; + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3); +} + +.upload-field-details > *{ + float:left; +} + +.upload-field-details span{ + display:block; +} + +.upload-field-details .file-name{ + font-weight:bold; + color:#21759B; +} + + +/* Settings page. */ +.side .form-table th { + width: 20%; + font-weight: bold; + text-align: left; + padding-left: 0; +} + +.wck-post-body{ + clear: left; + float: left; + margin-right: -2000px; + width: 100%; +} + +.metabox-holder .column-1 { + margin-right:300px; +} +.metabox-holder .column-2 { + float: right; + width: 280px; + clear:right; + position:relative; +} +.metabox-holder .column-3 { + clear: both; + margin-right:300px; +} + +/* wysiwyg */ +.mb-right-column .wp_themeSkin table.mceLayout{ + border-color: #CCCCCC #CCCCCC #DFDFDF; + border-style: solid; + border-top-left-radius: 3px; + border-top-right-radius: 3px; + border-width: 1px; + background-color:#fff; +} + +/* nested repeater */ +.mb-table-container .wck-nested{ + background:#F5F5F5; + border:1px solid #DFDFDF; + box-shadow: 0 1px 0 #FFFFFF; +} + +.mb-table-container .wck-nested > div{ + padding:10px; +} + +.mb-table-container li[data-type="nested-repeater"]{ + display:none; +} + +.wck_page_cptc-page #contextual-help-link-wrap, .wck_page_ctc-page #contextual-help-link-wrap, .wck_page_cfc-page #contextual-help-link-wrap, .wck_page_fep-page #contextual-help-link-wrap, .wck_page_opc-page #contextual-help-link-wrap{ + background: rgb(248,79,79); /* Old browsers */ + background: -moz-linear-gradient(top, rgba(248,79,79,1) 0%, rgba(210,11,11,1) 100%); /* FF3.6+ */ + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(248,79,79,1)), color-stop(100%,rgba(210,11,11,1))); /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(top, rgba(248,79,79,1) 0%,rgba(210,11,11,1) 100%); /* Chrome10+,Safari5.1+ */ + background: -o-linear-gradient(top, rgba(248,79,79,1) 0%,rgba(210,11,11,1) 100%); /* Opera 11.10+ */ + background: -ms-linear-gradient(top, rgba(248,79,79,1) 0%,rgba(210,11,11,1) 100%); /* IE10+ */ + background: linear-gradient(to bottom, rgba(248,79,79,1) 0%,rgba(210,11,11,1) 100%); /* W3C */ + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f84f4f', endColorstr='#d20b0b',GradientType=0 ); /* IE6-9 */ +} + +.wck_page_cptc-page #contextual-help-link-wrap #contextual-help-link, .wck_page_ctc-page #contextual-help-link-wrap #contextual-help-link, .wck_page_cfc-page #contextual-help-link-wrap #contextual-help-link, .wck_page_fep-page #contextual-help-link-wrap #contextual-help-link, .wck_page_opc-page #contextual-help-link-wrap #contextual-help-link{ + padding-left:55px; + color: #FFFFFF; + text-shadow: 0 1px 0 rgba(0, 0, 0, 0.7); +} + +.wck_page_cptc-page #contextual-help-link-wrap #contextual-help-link:before, .wck_page_ctc-page #contextual-help-link-wrap #contextual-help-link:before, .wck_page_cfc-page #contextual-help-link-wrap #contextual-help-link:before, .wck_page_fep-page #contextual-help-link-wrap #contextual-help-link:before, .wck_page_opc-page #contextual-help-link-wrap #contextual-help-link:before{ + content:"WCK"; + width:15px; + height:20px; + background:url( ../images/wck-icon-dark.png ) no-repeat 0 0; + position:absolute; + top:4px; + left:4px; + line-height: 16px; + padding-left: 18px; +} + +/*-------------------------------------------------------------- +Media Queries +--------------------------------------------------------------*/ +@media screen and ( max-width: 878px ) { + .wck-post-body{ + float:none; + margin-right: 0; + } + + .metabox-holder .column-2{ + float:none; + width:100%; + } + + .metabox-holder .column-1{ + margin-right:0; + } } \ No newline at end of file diff --git a/profile-builder/assets/lib/wck-api/wordpress-creation-kit.js b/profile-builder/assets/lib/wck-api/wordpress-creation-kit.js index f7abf57..83ce9ee 100644 --- a/profile-builder/assets/lib/wck-api/wordpress-creation-kit.js +++ b/profile-builder/assets/lib/wck-api/wordpress-creation-kit.js @@ -1,404 +1,404 @@ -/* Add width to elements at startup */ -jQuery(function(){ - jQuery('.mb-table-container tbody td').css('width', function(){ return jQuery(this).width() }); -}); - -/* Add width to labels if the post box is closed at load */ -jQuery(function(){ - - /* Callback version */ - /* postboxes.pbshow = function(box){ - jQuery('strong, .field-label', jQuery('#'+box)).css( 'width', 'auto' ); - } */ - - jQuery( '.wck-post-box .hndle' ).click( function(){ - jQuery('strong, .field-label', jQuery(this).parent() ).css( 'width', 'auto' ); - }) - -}); - - - - -/* add reccord to the meta */ -function addMeta(value, id, nonce){ - - /* if tinyMCE then trigger save. save puts the content in the hidden textarea */ - if( typeof tinyMCE !== 'undefined' ) - tinyMCE.triggerSave(); - - jQuery('#'+value).parent().css({'opacity':'0.4', 'position':'relative'}).append('
            '); - /*object to hold the values */ - var values = {}; - - jQuery('#'+value+' .mb-field').each(function(){ - - var key = jQuery(this).attr('name'); - - if(jQuery(this).attr('type') == 'checkbox' || jQuery(this).attr('type') == 'radio' ) { - - if( typeof values[key.toString()] === "undefined" ) - values[key.toString()] = ''; - - if(jQuery(this).is(':checked')){ - if( values[key.toString()] == '' ) - values[key.toString()] += jQuery(this).val().toString(); - else - values[key.toString()] += ', ' + jQuery(this).val().toString(); - } - } - - else - values[key.toString()] = jQuery(this).val().toString(); - }); - - meta = value; - - if( value.indexOf("-wcknested-") != -1 ){ - metaDetails = value.split("-wcknested-"); - meta = metaDetails[0]; - } - - jQuery.post( wppbWckAjaxurl , { action:"wck_add_meta"+meta, meta:value, id:id, values:values, _ajax_nonce:nonce}, function(response) { - - jQuery( '#'+value+' .field-label').removeClass('error'); - - if( response.error ){ - jQuery('#'+value).parent().css('opacity','1'); - jQuery('#mb-ajax-loading').remove(); - - jQuery.each( response.errorfields, function (index, field) { - jQuery( '#'+value+' .field-label[for="' + field + '"]' ).addClass('error'); - }); - - alert( response.error ); - } - else{ - /* refresh the list */ - jQuery.post( wppbWckAjaxurl , { action:"wck_refresh_list"+meta, meta:value, id:id}, function(response) { - - jQuery('#container_'+value).replaceWith(response); - - jQuery('.mb-table-container tbody td').css('width', function(){ return jQuery(this).width() }); - - if( !jQuery( '#'+value ).hasClass('single') ) - mb_sortable_elements(); - - /* restore the add form to the original values */ - if( !jQuery( '#'+value ).hasClass('single') ){ - jQuery.post( wppbWckAjaxurl , { action:"wck_add_form"+meta, meta:value, id:id }, function(response) { - jQuery( '#'+value ).replaceWith( response ); - }); - } - - /* jQuery('#'+value+' .mb-field').each(function(){ - if(jQuery(this).attr('type') == 'checkbox' || jQuery(this).attr('type') == 'radio' ) - jQuery(this).removeAttr( 'checked' ); - else - jQuery(this).val(''); - }); - - jQuery('#'+value+' .upload-field-details').each(function(){ - jQuery(this).html('

            '); - }); */ - - jQuery('#'+value).parent().css('opacity','1'); - - jQuery('body').trigger('wck-added-element'); - - jQuery('#mb-ajax-loading').remove(); - }); - } - }); - -} - -/* remove reccord from the meta */ -function removeMeta(value, id, element_id, nonce){ - - var response = confirm( "Delete this item ?" ); - - if( response == true ){ - - meta = value; - - if( value.indexOf("-wcknested-") != -1 ){ - metaDetails = value.split("-wcknested-"); - meta = metaDetails[0]; - } - - jQuery('#'+value).parent().css({'opacity':'0.4', 'position':'relative'}).append('
            '); - jQuery.post( wppbWckAjaxurl , { action:"wck_remove_meta"+meta, meta:value, id:id, element_id:element_id, _ajax_nonce:nonce}, function(response) { - - /* If single add the form */ - if( jQuery( '#container_'+value ).hasClass('single') ){ - jQuery.post( wppbWckAjaxurl , { action:"wck_add_form"+meta, meta:value, id:id }, function(response) { - jQuery( '#container_'+value ).before( response ); - jQuery( '#'+value ).addClass('single'); - }); - } - - /* refresh the list */ - jQuery.post( wppbWckAjaxurl , { action:"wck_refresh_list"+meta, meta:value, id:id}, function(response) { - jQuery('#container_'+value).replaceWith(response); - - jQuery('.mb-table-container tbody td').css('width', function(){ return jQuery(this).width() }); - - mb_sortable_elements(); - jQuery('#'+value).parent().css('opacity','1'); - jQuery('#mb-ajax-loading').remove(); - }); - - }); - } -} - -/* swap two reccords */ -/*function swapMetaMb(value, id, element_id, swap_with){ - jQuery('#'+value).parent().css({'opacity':'0.4', 'position':'relative'}).append('
            '); - jQuery.post( wppbWckAjaxurl , { action:"swap_meta_mb", meta:value, id:id, element_id:element_id, swap_with:swap_with}, function(response) { - - jQuery.post( wppbWckAjaxurl , { action:"refresh_list", meta:value, id:id}, function(response) { - jQuery('#container_'+value).replaceWith(response); jQuery('#'+value).parent().css('opacity','1'); jQuery('#mb-ajax-loading').remove(); - }); - - }); -} -*/ - -/* reorder elements through drag and drop */ -function mb_sortable_elements() { - jQuery( ".mb-table-container tbody" ).not( jQuery( ".mb-table-container.single tbody, .mb-table-container.not-sortable tbody" ) ).sortable({ - update: function(event, ui){ - - var value = jQuery(this).parent().siblings('.wck-add-form').attr('id'); - var id = jQuery(this).parent().attr('post'); - - var result = jQuery(this).sortable('toArray'); - - var values = {}; - for(var i in result) - { - values[i] = result[i].replace('element_',''); - } - - jQuery('#'+value).parent().css({'opacity':'0.4', 'position':'relative'}).append('
            '); - - meta = value; - - if( value.indexOf("-wcknested-") != -1 ){ - metaDetails = value.split("-wcknested-"); - meta = metaDetails[0]; - } - - - jQuery.post( wppbWckAjaxurl , { action:"wck_reorder_meta"+meta, meta:value, id:id, values:values}, function(response) { - jQuery.post( wppbWckAjaxurl , { action:"wck_refresh_list"+meta, meta:value, id:id}, function(response) { - jQuery('#container_'+value).replaceWith(response); - - jQuery('.mb-table-container tbody td').css('width', function(){ return jQuery(this).width() }); - - mb_sortable_elements(); - jQuery('#'+value).parent().css('opacity','1'); - jQuery('#mb-ajax-loading').remove(); - }); - - }); - }, - items: "> tr" - }); - /*I don't know if this is necessary. Remove when I have more time for tests */ - jQuery( "#sortable:not(select)" ).disableSelection(); - - - jQuery('.mb-table-container ul').mousedown( function(e){ - e.stopPropagation(); - }); -} -jQuery(mb_sortable_elements); - - - -/* show the update form */ -function showUpdateFormMeta(value, id, element_id, nonce){ - if( jQuery( '#update_container_' + value + '_' + element_id ).length == 0 ){ - jQuery('#container_'+value).parent().css({'opacity':'0.4', 'position':'relative'}).append('
            '); - - if( jQuery( '#container_' + value + " tbody" ).hasClass('ui-sortable') ) - jQuery( '#container_' + value + " tbody" ).sortable("disable"); - - - meta = value; - - if( value.indexOf("-wcknested-") != -1 ){ - metaDetails = value.split("-wcknested-"); - meta = metaDetails[0]; - } - - - jQuery.post( wppbWckAjaxurl , { action:"wck_show_update"+meta, meta:value, id:id, element_id:element_id, _ajax_nonce:nonce}, function(response) { - //jQuery('#container_'+value+' #element_'+element_id).append(response); - jQuery(response).insertAfter('#container_'+value+' > tbody > #element_'+element_id); - - jQuery('#container_'+value).parent().css('opacity','1'); - jQuery('#mb-ajax-loading').remove(); - wckGoToByScroll('update_container_' + value + '_' + element_id); - }); - } -} - -/* remove the update form */ -function removeUpdateForm( id ){ - jQuery('html, body').animate({ - scrollTop: jQuery( '#'+id).prev().offset().top - 40 }, 700); - - jQuery( '#'+id).prev().animate({ - backgroundColor: '#FFFF9C' - }, 700); - jQuery( '#'+id).prev().animate({ - backgroundColor: 'none' - }, 700); - - if( jQuery( '#'+id).parent('tbody').hasClass('ui-sortable') ) - jQuery( '#'+id).parent('tbody').sortable("enable"); - - jQuery( '#'+id ).remove(); -} - -/* update reccord */ -function updateMeta(value, id, element_id, nonce){ - - /* if tinyMCE then trigger save. save puts the content in the hidden textarea */ - if( typeof tinyMCE !== 'undefined' ) - tinyMCE.triggerSave(); - - jQuery('#container_'+value).parent().css({'opacity':'0.4', 'position':'relative'}).append('
            '); - var values = {}; - jQuery('#update_container_'+value+'_'+element_id+' .mb-field').each(function(){ - var key = jQuery(this).attr('name'); - - if(jQuery(this).attr('type') == 'checkbox' || jQuery(this).attr('type') == 'radio' ) { - - if( typeof values[key.toString()] === "undefined" ) - values[key.toString()] = ''; - - if(jQuery(this).is(':checked')){ - if( values[key.toString()] == '' ) - values[key.toString()] += jQuery(this).val().toString(); - else - values[key.toString()] += ', ' + jQuery(this).val().toString(); - } - } - - else - values[key.toString()] = jQuery(this).val().toString(); - - }); - - - meta = value; - - if( value.indexOf("-wcknested-") != -1 ){ - metaDetails = value.split("-wcknested-"); - meta = metaDetails[0]; - } - - - jQuery.post( wppbWckAjaxurl , { action:"wck_update_meta"+meta, meta:value, id:id, element_id:element_id, values:values, _ajax_nonce:nonce}, function(response) { - - jQuery( '#update_container_'+value+'_'+element_id + ' .field-label').removeClass('error'); - - if( response.error ){ - jQuery('#container_'+value).parent().css('opacity','1'); - jQuery('#mb-ajax-loading').remove(); - - jQuery.each( response.errorfields, function (index, field) { - jQuery( '#update_container_'+value+'_'+element_id + ' .field-label[for="' + field + '"]' ).addClass('error'); - }); - - alert( response.error ); - } - else{ - jQuery('html, body').animate({ - scrollTop: jQuery('#container_'+value+' #element_' + element_id).offset().top - 40 }, 700); - - jQuery('#container_'+value+' #element_' + element_id).animate({ - backgroundColor: '#FFFF9C' - }, 700); - jQuery('#container_'+value+' #element_' + element_id).animate({ - backgroundColor: 'none' - }, 700); - - jQuery('#update_container_'+value+'_'+element_id).remove(); - - /* refresh the list */ - jQuery.post( wppbWckAjaxurl , { action:"wck_refresh_entry"+meta, meta:value, id:id, element_id:element_id}, function(response) { - jQuery('#container_'+value+' #element_'+element_id).replaceWith(response); - - jQuery('.mb-table-container tbody td').css('width', function(){ return jQuery(this).width() }); - - if( jQuery( '#container_' + value + " tbody" ).hasClass('ui-sortable') && jQuery( '#container_' + value + " tbody .wck_update_container" ).length == 0 ) - jQuery( '#container_' + value + " tbody" ).sortable("enable"); - - jQuery('#container_'+value).parent().css('opacity','1'); - jQuery('#mb-ajax-loading').remove(); - }); - } - }); -} - -/* function syncs the translation */ -function wckSyncTranslation(id){ - jQuery.post( wppbWckAjaxurl , { action:"wck_sync_translation", id:id}, function(response) { - if( response == 'syncsuccess' ) - window.location.reload(); - }); -} - -function wckGoToByScroll(id){ - jQuery('html,body').animate({scrollTop: jQuery("#"+id).offset().top - 28},'slow'); -} - -/* Remove uploaded file */ -jQuery(function(){ - jQuery(document).on('click', '.wck-remove-upload', function(e){ - jQuery(this).parent().parent().parent().children('.mb-field').val(""); - jQuery(this).parent().parent('.upload-field-details').html('

            '); - }); -}); - -/* Set width for listing "label" equal to the widest */ -jQuery( function(){ - jQuery('.wck-post-box').css( {visibility: 'visible', height: 'auto'} ); -}); - -function wck_set_to_widest( element, parent ){ - if( element == '.field-label' ){ - if( jQuery( "#" + parent + ' ' + element ).length != 0 ){ - var widest = null; - jQuery( "#" + parent + ' ' + element ).each(function() { - if (widest == null) - widest = jQuery(this); - else - if ( jQuery(this).width() > widest.width() ) - widest = jQuery(this); - }); - - jQuery( "#" + parent ).append(""); - } - } - else if( element == 'strong' ){ - if( jQuery( "#container_" + parent + " #element_0 " + element ).length != 0 ){ - var widest = null; - jQuery( "#container_" + parent + " #element_0 " + element ).each(function() { - if (widest == null) - widest = jQuery(this); - else - if ( jQuery(this).width() > widest.width() ) - widest = jQuery(this); - }); - - jQuery( "#container_" + parent ).append(""); - } - } +/* Add width to elements at startup */ +jQuery(function(){ + jQuery('.mb-table-container tbody td').css('width', function(){ return jQuery(this).width() }); +}); + +/* Add width to labels if the post box is closed at load */ +jQuery(function(){ + + /* Callback version */ + /* postboxes.pbshow = function(box){ + jQuery('strong, .field-label', jQuery('#'+box)).css( 'width', 'auto' ); + } */ + + jQuery( '.wck-post-box .hndle' ).click( function(){ + jQuery('strong, .field-label', jQuery(this).parent() ).css( 'width', 'auto' ); + }) + +}); + + + + +/* add reccord to the meta */ +function addMeta(value, id, nonce){ + + /* if tinyMCE then trigger save. save puts the content in the hidden textarea */ + if( typeof tinyMCE !== 'undefined' ) + tinyMCE.triggerSave(); + + jQuery('#'+value).parent().css({'opacity':'0.4', 'position':'relative'}).append('
            '); + /*object to hold the values */ + var values = {}; + + jQuery('#'+value+' .mb-field').each(function(){ + + var key = jQuery(this).attr('name'); + + if(jQuery(this).attr('type') == 'checkbox' || jQuery(this).attr('type') == 'radio' ) { + + if( typeof values[key.toString()] === "undefined" ) + values[key.toString()] = ''; + + if(jQuery(this).is(':checked')){ + if( values[key.toString()] == '' ) + values[key.toString()] += jQuery(this).val().toString(); + else + values[key.toString()] += ', ' + jQuery(this).val().toString(); + } + } + + else + values[key.toString()] = jQuery(this).val().toString(); + }); + + meta = value; + + if( value.indexOf("-wcknested-") != -1 ){ + metaDetails = value.split("-wcknested-"); + meta = metaDetails[0]; + } + + jQuery.post( wppbWckAjaxurl , { action:"wck_add_meta"+meta, meta:value, id:id, values:values, _ajax_nonce:nonce}, function(response) { + + jQuery( '#'+value+' .field-label').removeClass('error'); + + if( response.error ){ + jQuery('#'+value).parent().css('opacity','1'); + jQuery('#mb-ajax-loading').remove(); + + jQuery.each( response.errorfields, function (index, field) { + jQuery( '#'+value+' .field-label[for="' + field + '"]' ).addClass('error'); + }); + + alert( response.error ); + } + else{ + /* refresh the list */ + jQuery.post( wppbWckAjaxurl , { action:"wck_refresh_list"+meta, meta:value, id:id}, function(response) { + + jQuery('#container_'+value).replaceWith(response); + + jQuery('.mb-table-container tbody td').css('width', function(){ return jQuery(this).width() }); + + if( !jQuery( '#'+value ).hasClass('single') ) + mb_sortable_elements(); + + /* restore the add form to the original values */ + if( !jQuery( '#'+value ).hasClass('single') ){ + jQuery.post( wppbWckAjaxurl , { action:"wck_add_form"+meta, meta:value, id:id }, function(response) { + jQuery( '#'+value ).replaceWith( response ); + }); + } + + /* jQuery('#'+value+' .mb-field').each(function(){ + if(jQuery(this).attr('type') == 'checkbox' || jQuery(this).attr('type') == 'radio' ) + jQuery(this).removeAttr( 'checked' ); + else + jQuery(this).val(''); + }); + + jQuery('#'+value+' .upload-field-details').each(function(){ + jQuery(this).html('

            '); + }); */ + + jQuery('#'+value).parent().css('opacity','1'); + + jQuery('body').trigger('wck-added-element'); + + jQuery('#mb-ajax-loading').remove(); + }); + } + }); + +} + +/* remove reccord from the meta */ +function removeMeta(value, id, element_id, nonce){ + + var response = confirm( "Delete this item ?" ); + + if( response == true ){ + + meta = value; + + if( value.indexOf("-wcknested-") != -1 ){ + metaDetails = value.split("-wcknested-"); + meta = metaDetails[0]; + } + + jQuery('#'+value).parent().css({'opacity':'0.4', 'position':'relative'}).append('
            '); + jQuery.post( wppbWckAjaxurl , { action:"wck_remove_meta"+meta, meta:value, id:id, element_id:element_id, _ajax_nonce:nonce}, function(response) { + + /* If single add the form */ + if( jQuery( '#container_'+value ).hasClass('single') ){ + jQuery.post( wppbWckAjaxurl , { action:"wck_add_form"+meta, meta:value, id:id }, function(response) { + jQuery( '#container_'+value ).before( response ); + jQuery( '#'+value ).addClass('single'); + }); + } + + /* refresh the list */ + jQuery.post( wppbWckAjaxurl , { action:"wck_refresh_list"+meta, meta:value, id:id}, function(response) { + jQuery('#container_'+value).replaceWith(response); + + jQuery('.mb-table-container tbody td').css('width', function(){ return jQuery(this).width() }); + + mb_sortable_elements(); + jQuery('#'+value).parent().css('opacity','1'); + jQuery('#mb-ajax-loading').remove(); + }); + + }); + } +} + +/* swap two reccords */ +/*function swapMetaMb(value, id, element_id, swap_with){ + jQuery('#'+value).parent().css({'opacity':'0.4', 'position':'relative'}).append('
            '); + jQuery.post( wppbWckAjaxurl , { action:"swap_meta_mb", meta:value, id:id, element_id:element_id, swap_with:swap_with}, function(response) { + + jQuery.post( wppbWckAjaxurl , { action:"refresh_list", meta:value, id:id}, function(response) { + jQuery('#container_'+value).replaceWith(response); jQuery('#'+value).parent().css('opacity','1'); jQuery('#mb-ajax-loading').remove(); + }); + + }); +} +*/ + +/* reorder elements through drag and drop */ +function mb_sortable_elements() { + jQuery( ".mb-table-container tbody" ).not( jQuery( ".mb-table-container.single tbody, .mb-table-container.not-sortable tbody" ) ).sortable({ + update: function(event, ui){ + + var value = jQuery(this).parent().siblings('.wck-add-form').attr('id'); + var id = jQuery(this).parent().attr('post'); + + var result = jQuery(this).sortable('toArray'); + + var values = {}; + for(var i in result) + { + values[i] = result[i].replace('element_',''); + } + + jQuery('#'+value).parent().css({'opacity':'0.4', 'position':'relative'}).append('
            '); + + meta = value; + + if( value.indexOf("-wcknested-") != -1 ){ + metaDetails = value.split("-wcknested-"); + meta = metaDetails[0]; + } + + + jQuery.post( wppbWckAjaxurl , { action:"wck_reorder_meta"+meta, meta:value, id:id, values:values}, function(response) { + jQuery.post( wppbWckAjaxurl , { action:"wck_refresh_list"+meta, meta:value, id:id}, function(response) { + jQuery('#container_'+value).replaceWith(response); + + jQuery('.mb-table-container tbody td').css('width', function(){ return jQuery(this).width() }); + + mb_sortable_elements(); + jQuery('#'+value).parent().css('opacity','1'); + jQuery('#mb-ajax-loading').remove(); + }); + + }); + }, + items: "> tr" + }); + /*I don't know if this is necessary. Remove when I have more time for tests */ + jQuery( "#sortable:not(select)" ).disableSelection(); + + + jQuery('.mb-table-container ul').mousedown( function(e){ + e.stopPropagation(); + }); +} +jQuery(mb_sortable_elements); + + + +/* show the update form */ +function showUpdateFormMeta(value, id, element_id, nonce){ + if( jQuery( '#update_container_' + value + '_' + element_id ).length == 0 ){ + jQuery('#container_'+value).parent().css({'opacity':'0.4', 'position':'relative'}).append('
            '); + + if( jQuery( '#container_' + value + " tbody" ).hasClass('ui-sortable') ) + jQuery( '#container_' + value + " tbody" ).sortable("disable"); + + + meta = value; + + if( value.indexOf("-wcknested-") != -1 ){ + metaDetails = value.split("-wcknested-"); + meta = metaDetails[0]; + } + + + jQuery.post( wppbWckAjaxurl , { action:"wck_show_update"+meta, meta:value, id:id, element_id:element_id, _ajax_nonce:nonce}, function(response) { + //jQuery('#container_'+value+' #element_'+element_id).append(response); + jQuery(response).insertAfter('#container_'+value+' > tbody > #element_'+element_id); + + jQuery('#container_'+value).parent().css('opacity','1'); + jQuery('#mb-ajax-loading').remove(); + wckGoToByScroll('update_container_' + value + '_' + element_id); + }); + } +} + +/* remove the update form */ +function removeUpdateForm( id ){ + jQuery('html, body').animate({ + scrollTop: jQuery( '#'+id).prev().offset().top - 40 }, 700); + + jQuery( '#'+id).prev().animate({ + backgroundColor: '#FFFF9C' + }, 700); + jQuery( '#'+id).prev().animate({ + backgroundColor: 'none' + }, 700); + + if( jQuery( '#'+id).parent('tbody').hasClass('ui-sortable') ) + jQuery( '#'+id).parent('tbody').sortable("enable"); + + jQuery( '#'+id ).remove(); +} + +/* update reccord */ +function updateMeta(value, id, element_id, nonce){ + + /* if tinyMCE then trigger save. save puts the content in the hidden textarea */ + if( typeof tinyMCE !== 'undefined' ) + tinyMCE.triggerSave(); + + jQuery('#container_'+value).parent().css({'opacity':'0.4', 'position':'relative'}).append('
            '); + var values = {}; + jQuery('#update_container_'+value+'_'+element_id+' .mb-field').each(function(){ + var key = jQuery(this).attr('name'); + + if(jQuery(this).attr('type') == 'checkbox' || jQuery(this).attr('type') == 'radio' ) { + + if( typeof values[key.toString()] === "undefined" ) + values[key.toString()] = ''; + + if(jQuery(this).is(':checked')){ + if( values[key.toString()] == '' ) + values[key.toString()] += jQuery(this).val().toString(); + else + values[key.toString()] += ', ' + jQuery(this).val().toString(); + } + } + + else + values[key.toString()] = jQuery(this).val().toString(); + + }); + + + meta = value; + + if( value.indexOf("-wcknested-") != -1 ){ + metaDetails = value.split("-wcknested-"); + meta = metaDetails[0]; + } + + + jQuery.post( wppbWckAjaxurl , { action:"wck_update_meta"+meta, meta:value, id:id, element_id:element_id, values:values, _ajax_nonce:nonce}, function(response) { + + jQuery( '#update_container_'+value+'_'+element_id + ' .field-label').removeClass('error'); + + if( response.error ){ + jQuery('#container_'+value).parent().css('opacity','1'); + jQuery('#mb-ajax-loading').remove(); + + jQuery.each( response.errorfields, function (index, field) { + jQuery( '#update_container_'+value+'_'+element_id + ' .field-label[for="' + field + '"]' ).addClass('error'); + }); + + alert( response.error ); + } + else{ + jQuery('html, body').animate({ + scrollTop: jQuery('#container_'+value+' #element_' + element_id).offset().top - 40 }, 700); + + jQuery('#container_'+value+' #element_' + element_id).animate({ + backgroundColor: '#FFFF9C' + }, 700); + jQuery('#container_'+value+' #element_' + element_id).animate({ + backgroundColor: 'none' + }, 700); + + jQuery('#update_container_'+value+'_'+element_id).remove(); + + /* refresh the list */ + jQuery.post( wppbWckAjaxurl , { action:"wck_refresh_entry"+meta, meta:value, id:id, element_id:element_id}, function(response) { + jQuery('#container_'+value+' #element_'+element_id).replaceWith(response); + + jQuery('.mb-table-container tbody td').css('width', function(){ return jQuery(this).width() }); + + if( jQuery( '#container_' + value + " tbody" ).hasClass('ui-sortable') && jQuery( '#container_' + value + " tbody .wck_update_container" ).length == 0 ) + jQuery( '#container_' + value + " tbody" ).sortable("enable"); + + jQuery('#container_'+value).parent().css('opacity','1'); + jQuery('#mb-ajax-loading').remove(); + }); + } + }); +} + +/* function syncs the translation */ +function wckSyncTranslation(id){ + jQuery.post( wppbWckAjaxurl , { action:"wck_sync_translation", id:id}, function(response) { + if( response == 'syncsuccess' ) + window.location.reload(); + }); +} + +function wckGoToByScroll(id){ + jQuery('html,body').animate({scrollTop: jQuery("#"+id).offset().top - 28},'slow'); +} + +/* Remove uploaded file */ +jQuery(function(){ + jQuery(document).on('click', '.wck-remove-upload', function(e){ + jQuery(this).parent().parent().parent().children('.mb-field').val(""); + jQuery(this).parent().parent('.upload-field-details').html('

            '); + }); +}); + +/* Set width for listing "label" equal to the widest */ +jQuery( function(){ + jQuery('.wck-post-box').css( {visibility: 'visible', height: 'auto'} ); +}); + +function wck_set_to_widest( element, parent ){ + if( element == '.field-label' ){ + if( jQuery( "#" + parent + ' ' + element ).length != 0 ){ + var widest = null; + jQuery( "#" + parent + ' ' + element ).each(function() { + if (widest == null) + widest = jQuery(this); + else + if ( jQuery(this).width() > widest.width() ) + widest = jQuery(this); + }); + + jQuery( "#" + parent ).append(""); + } + } + else if( element == 'strong' ){ + if( jQuery( "#container_" + parent + " #element_0 " + element ).length != 0 ){ + var widest = null; + jQuery( "#container_" + parent + " #element_0 " + element ).each(function() { + if (widest == null) + widest = jQuery(this); + else + if ( jQuery(this).width() > widest.width() ) + widest = jQuery(this); + }); + + jQuery( "#container_" + parent ).append(""); + } + } } \ No newline at end of file diff --git a/profile-builder/assets/lib/wck-api/wordpress-creation-kit.php b/profile-builder/assets/lib/wck-api/wordpress-creation-kit.php index 66eda86..4df5802 100644 --- a/profile-builder/assets/lib/wck-api/wordpress-creation-kit.php +++ b/profile-builder/assets/lib/wck-api/wordpress-creation-kit.php @@ -1,1467 +1,1467 @@ - 'text', 'title' => 'Title', 'description' => 'Description for this input' ), - array( 'type' => 'textarea', 'title' => 'Description' ), - array( 'type' => 'upload', 'title' => 'Image', 'description' => 'Upload a image' ), - array( 'type' => 'select', 'title' => 'Select This', 'options' => array( 'Option 1', 'Option 2', 'Option 3' ) ), - array( 'type' => 'checkbox', 'title' => 'Check This', 'options' => array( 'Option 1', 'Option 2', 'Option 3' ) ), - array( 'type' => 'radio', 'title' => 'Radio This', 'options' => array( 'Radio 1', 'Radio 2', 'Radio 3' ) ), - ); - -$args = array( - 'metabox_id' => 'rm_slider_content', - 'metabox_title' => 'Slideshow Class', - 'post_type' => 'slideshows', - 'meta_name' => 'rmscontent', - 'meta_array' => $fint -); - -new Wordpress_Creation_Kit_PB( $args ); - - -On the frontend: - -$meta = get_post_meta( $post->ID, 'rmscontent', true ); - -*/ - -class Wordpress_Creation_Kit_PB{ - - private $defaults = array( - 'metabox_id' => '', - 'metabox_title' => 'Meta Box', - 'post_type' => 'post', - 'meta_name' => '', - 'meta_array' => array(), - 'page_template' => '', - 'post_id' => '', - 'single' => false, - 'unserialize_fields' => false, - 'sortable' => true, - 'context' => 'post_meta', - 'mb_context' => 'normal' - ); - private $args; - - - /* Constructor method for the class. */ - function __construct( $args ) { - - /* Global that will hold all the arguments for all the custom boxes */ - global $wck_objects; - - /* Merge the input arguments and the defaults. */ - $this->args = wp_parse_args( $args, $this->defaults ); - - /* Add the settings for this box to the global object */ - $wck_objects[$this->args['metabox_id']] = $this->args; - - /*print scripts*/ - add_action('admin_enqueue_scripts', array( &$this, 'wck_print_scripts' )); - /* add our own ajaxurl because we are going to use the wck script also in frontend and we want to avoid any conflicts */ - add_action( 'admin_head', array( &$this, 'wck_print_ajax_url' ) ); - - // Set up the AJAX hooks - add_action("wp_ajax_wck_add_meta".$this->args['meta_name'], array( &$this, 'wck_add_meta') ); - add_action("wp_ajax_wck_update_meta".$this->args['meta_name'], array( &$this, 'wck_update_meta') ); - add_action("wp_ajax_wck_show_update".$this->args['meta_name'], array( &$this, 'wck_show_update_form') ); - add_action("wp_ajax_wck_refresh_list".$this->args['meta_name'], array( &$this, 'wck_refresh_list') ); - add_action("wp_ajax_wck_refresh_entry".$this->args['meta_name'], array( &$this, 'wck_refresh_entry') ); - add_action("wp_ajax_wck_add_form".$this->args['meta_name'], array( &$this, 'wck_add_form') ); - add_action("wp_ajax_wck_remove_meta".$this->args['meta_name'], array( &$this, 'wck_remove_meta') ); - add_action("wp_ajax_wck_reorder_meta".$this->args['meta_name'], array( &$this, 'wck_reorder_meta') ); - - add_action('add_meta_boxes', array( &$this, 'wck_add_metabox') ); - - /* For single forms we save them the old fashion way */ - if( $this->args['single'] ){ - add_action('save_post', array($this, 'wck_save_single_metabox'), 10, 2); - /* wp_insert_post executes after save_post so at this point if we have the error global we can redirect the page - and add the error message and error fields urlencoded as $_GET */ - add_action('wp_insert_post', array($this, 'wck_single_metabox_redirect_if_errors'), 10, 2); - /* if we have any $_GET errors alert them with js so we have consistency */ - add_action('admin_print_footer_scripts', array($this, 'wck_single_metabox_errors_display') ); - } - - } - - - //add metabox using wordpress api - - function wck_add_metabox() { - - global $pb_wck_pages_hooknames; - - if( $this->args['context'] == 'post_meta' ){ - if( $this->args['post_id'] == '' && $this->args['page_template'] == '' ){ - add_meta_box($this->args['metabox_id'], $this->args['metabox_title'], array( &$this, 'wck_content' ), $this->args['post_type'], $this->args['mb_context'], 'high', array( 'meta_name' => $this->args['meta_name'], 'meta_array' => $this->args['meta_array']) ); - /* add class to meta box */ - add_filter( "postbox_classes_".$this->args['post_type']."_".$this->args['metabox_id'], array( &$this, 'wck_add_metabox_classes' ) ); - } - else{ - if( !empty( $_GET['post'] ) ) - $post_id = filter_var( $_GET['post'], FILTER_SANITIZE_NUMBER_INT ); - else if( !empty( $_POST['post_ID'] ) ) - $post_id = filter_var( $_POST['post_ID'], FILTER_SANITIZE_NUMBER_INT ); - else - $post_id = ''; - - - if( $this->args['post_id'] != '' && $this->args['page_template'] != '' ){ - $template_file = get_post_meta($post_id,'_wp_page_template',TRUE); - if( $this->args['post_id'] == $post_id && $template_file == $this->args['page_template'] ) - add_meta_box($this->args['metabox_id'], $this->args['metabox_title'], array( &$this, 'wck_content' ), 'page', $this->args['mb_context'], 'high', array( 'meta_name' => $this->args['meta_name'], 'meta_array' => $this->args['meta_array'] ) ); - - /* add class to meta box */ - add_filter( "postbox_classes_page_".$this->args['metabox_id'], array( &$this, 'wck_add_metabox_classes' ) ); - } - else{ - - if( $this->args['post_id'] != '' ){ - if( $this->args['post_id'] == $post_id ){ - $post_type = get_post_type( $post_id ); - add_meta_box($this->args['metabox_id'], $this->args['metabox_title'], array( &$this, 'wck_content' ), $post_type, $this->args['mb_context'], 'high', array( 'meta_name' => $this->args['meta_name'], 'meta_array' => $this->args['meta_array'] ) ); - /* add class to meta box */ - add_filter( "postbox_classes_".$post_type."_".$this->args['metabox_id'], array( &$this, 'wck_add_metabox_classes' ) ); - } - } - - if( $this->args['page_template'] != '' ){ - $template_file = get_post_meta($post_id,'_wp_page_template',TRUE); - if ( $template_file == $this->args['page_template'] ){ - add_meta_box($this->args['metabox_id'], $this->args['metabox_title'], array( &$this, 'wck_content' ), 'page', $this->args['mb_context'], 'high', array( 'meta_name' => $this->args['meta_name'], 'meta_array' => $this->args['meta_array']) ); - /* add class to meta box */ - add_filter( "postbox_classes_page_".$this->args['metabox_id'], array( &$this, 'wck_add_metabox_classes' ) ); - } - } - - } - - } - } - else if( $this->args['context'] == 'option' ){ - if( !empty( $pb_wck_pages_hooknames[$this->args['post_type']] ) ) { - add_meta_box($this->args['metabox_id'], $this->args['metabox_title'], array(&$this, 'wck_content'), $pb_wck_pages_hooknames[$this->args['post_type']], $this->args['mb_context'], 'high', array('meta_name' => $this->args['meta_name'], 'meta_array' => $this->args['meta_array'])); - /* add class to meta box */ - add_filter("postbox_classes_" . $pb_wck_pages_hooknames[$this->args['post_type']] . "_" . $this->args['metabox_id'], array(&$this, 'wck_add_metabox_classes')); - } - } - } - - /* Function used to add classes to the wck meta boxes */ - function wck_add_metabox_classes( $classes ){ - array_push($classes,'wck-post-box'); - return $classes; - } - - function wck_content($post, $metabox){ - if( !empty( $post->ID ) ) - $post_id = $post->ID; - else - $post_id = ''; - - //output the add form - self::create_add_form($metabox['args']['meta_array'], $metabox['args']['meta_name'], $post); - - //output the entries only for repeater fields - if( !$this->args['single'] ) - echo self::wck_output_meta_content($metabox['args']['meta_name'], $post_id, $metabox['args']['meta_array']); - } - - /** - * The function used to create a form element - * - * @since 1.0.0 - * - * @param string $meta Meta name. - * @param array $details Contains the details for the field. - * @param string $value Contains input value; - * @param string $context Context where the function is used. Depending on it some actions are preformed.; - * @param int $post_id The post ID; - * @return string $element input element html string. - */ - - function wck_output_form_field( $meta, $details, $value = '', $context = '', $post_id = '' ){ - $element = ''; - - if( $context == 'edit_form' ){ - $edit_class = '.mb-table-container '; - $var_prefix = 'edit'; - } - else if( $context == 'fep' ){ - /* id prefix for frontend posting */ - $frontend_prefix = 'fep-'; - } - else{ - if( isset( $details['default'] ) && !( $this->args['single'] == true && !is_null( $value ) ) ) { - $value = apply_filters("wck_default_value_{$meta}_" . Wordpress_Creation_Kit_PB::wck_generate_slug( $details['title'], $details ), $details['default']); - } - } - - /* for single post meta metaboxes we need a prefix in the name attr of the input because in the case we have multiple single metaboxes on the same - post we need to prevent the fields from having the same name attr */ - if( $this->args['context'] == 'post_meta' && $this->args['single'] && $context != 'fep' ) - $single_prefix = $this->args['meta_name'].'_'; - else - $single_prefix = ''; - - $element .= ''; - - $element .= '
            '; - - /* - include actual field type - possible field types: text, textarea, select, checkbox, radio, upload, wysiwyg editor, datepicker, country select, user select, cpt select - */ - - if( function_exists( 'wck_nr_get_repeater_boxes' ) ){ - $cfc_titles = wck_nr_get_repeater_boxes(); - if( in_array( $details['type'], $cfc_titles ) ){ - $details['type'] = 'nested repeater'; - } - } - - - if( file_exists( dirname( __FILE__ ).'/fields/'.$details['type'].'.php' ) ){ - require( dirname( __FILE__ ).'/fields/'.$details['type'].'.php' ); - } - - // Add a filter that allows us to add support for custom field types, not just the ones defined in fields (wck api) - $element .= apply_filters('wck_output_form_field_customtype_' . $details['type'], '', $value, $details, $single_prefix); - - if( !empty( $details['description'] ) ){ - $element .= '

            '. $details['description'].'

            '; - } - - $element .= '
            '; - - $element = apply_filters( "wck_output_form_field_{$meta}_" . Wordpress_Creation_Kit_PB::wck_generate_slug( $details['title'], $details ), $element ); - - return $element; - - } - - - /** - * The function used to create the form for adding records - * - * @since 1.0.0 - * - * @param array $fields Contains the desired inputs in the repeater field. Must be like: array('Key:type'). - * Key is used for the name attribute of the field, label of the field and as the meta_key. - * Supported types: input, textarea, upload - * @param string $meta It is used in update_post_meta($id, $meta, $results);. Use '_' prefix if you don't want - * the meta to apear in custom fields box. - * @param object $post Post object - */ - function create_add_form($fields, $meta, $post, $context = '' ){ - $nonce = wp_create_nonce( 'wck-add-meta' ); - if( !empty( $post->ID ) ) - $post_id = $post->ID; - else - $post_id = ''; - - /* for single forms we need the values that are stored in the meta */ - if( $this->args['single'] == true ) { - if ($this->args['context'] == 'post_meta') - $results = get_post_meta($post_id, $meta, true); - else if ($this->args['context'] == 'option') - $results = get_option( apply_filters( 'wck_option_meta' , $meta )); - - /* Filter primary used for CFC/OPC fields in order to show/hide fields based on type */ - $wck_update_container_css_class = apply_filters("wck_add_form_class_{$meta}", '', $meta, $results ); - } - ?> -
            - - args['context'] == 'post_meta' ) - $results = get_post_meta($id, $meta, true); - else if ( $this->args['context'] == 'option' ) - $results = get_option( apply_filters( 'wck_option_meta' , $meta ) ); - - /* Filter primary used for CFC/OPC fields in order to show/hide fields based on type */ - $wck_update_container_css_class = " class='wck_update_container update_container_$meta'"; - $wck_update_container_css_class = apply_filters("wck_update_container_class_{$meta}", $wck_update_container_css_class, $meta, $results, $element_id ); - - $form = ''; - $form .= ''; - if($results != null){ - $i = 0; - $form .= '
              '; - - if( !empty( $fields ) ){ - foreach( $fields as $field ){ - $details = $field; - if( isset( $results[$element_id][Wordpress_Creation_Kit_PB::wck_generate_slug( $details['title'], $details )] ) ) - $value = $results[$element_id][Wordpress_Creation_Kit_PB::wck_generate_slug( $details['title'], $details )]; - else - $value = ''; - - $form = apply_filters( "wck_before_update_form_{$meta}_element_{$i}", $form, $element_id, $value ); - - $form .= '
            • '; - - $form .= self::wck_output_form_field( $meta, $details, $value, 'edit_form', $id ); - - $form .= '
            • '; - - $form = apply_filters( "wck_after_update_form_{$meta}_element_{$i}", $form, $element_id, $value ); - - $i++; - } - } - $form .= '
            • '; - $form .= ''. __( apply_filters( 'wck_save_changes_button', 'Save Changes', $meta ), 'profile-builder' ) .''; - $form .= ''. __( apply_filters( 'wck_cancel_button', 'Cancel', $meta ), 'profile-builder' ) .''; - $form .= '
            • '; - - $form .= '
            '; - } - $form .= ''; - - return $form; - } - - - /** - * The function used to output the content of a meta - * - * @since 1.0.0 - * - * @param string $meta It is used in get_post_meta($id, $meta, $results);. Use '_' prefix if you don't want - * the meta to apear in custom fields box. - * @param int $id Post id - */ - function wck_output_meta_content($meta, $id, $fields, $box_args = '' ){ - /* in fep $this->args is empty so we need it as a parameter */ - if( !empty( $box_args ) ) - $this->args = wp_parse_args( $box_args, $this->defaults ); - - - if( $this->args['context'] == 'post_meta' || $this->args['context'] == '' ) - $results = get_post_meta($id, $meta, true); - else if ( $this->args['context'] == 'option' ) - $results = get_option( apply_filters( 'wck_option_meta' , $meta ) ); - - $list = ''; - $list .= ''; - - - if( !empty( $results ) ){ - $list .= apply_filters( 'wck_metabox_content_header_'.$meta , '' ); - $i=0; - foreach ($results as $result){ - - $list .= self::wck_output_entry_content( $meta, $id, $fields, $results, $i ); - - $i++; - } - } - $list .= apply_filters( 'wck_metabox_content_footer_'.$meta , '', $id ); - $list .= '
            #'. __( 'Content', 'profile-builder' ) .''. __( 'Edit', 'wck' ) .''. __( 'Delete', 'wck' ) .'
            '; - - $list = apply_filters('wck_metabox_content_'.$meta, $list, $id); - return $list; - } - - function wck_output_entry_content( $meta, $id, $fields, $results, $element_id ){ - $edit_nonce = wp_create_nonce( 'wck-edit-entry' ); - $delete_nonce = wp_create_nonce( 'wck-delete-entry' ); - $entry_nr = $element_id +1; - - $wck_element_class = ''; - $wck_element_class = apply_filters( "wck_element_class_{$meta}", $wck_element_class, $meta, $results, $element_id ); - - $list = ''; - $list .= ''; - $list .= apply_filters( 'wck_add_content_before_columns', '', $list, $meta ); - $list .= ''. $entry_nr .''; - $list .= '
              ' . "\r\n"; - - $j = 0; - - if( !empty( $fields ) ){ - foreach( $fields as $field ){ - $details = $field; - - if( !empty( $results[$element_id][Wordpress_Creation_Kit_PB::wck_generate_slug( $details['title'], $details )] ) ) - $value = $results[$element_id][Wordpress_Creation_Kit_PB::wck_generate_slug( $details['title'], $details )]; - else - $value =''; - - /* filter display value */ - $value = apply_filters( "wck_displayed_value_{$meta}_element_{$j}", $value ); - - /* display it differently based on field type*/ - if( $details['type'] == 'upload' ){ - $display_value = self::wck_get_entry_field_upload($value); - } elseif ( $details['type'] == 'user select' ) { - $display_value = self::wck_get_entry_field_user_select( $value ) . ''; - } elseif ( $details['type'] == 'cpt select' ){ - $display_value = self::wck_get_entry_field_cpt_select( $value ) . ''; - } elseif ( $details['type'] == 'checkbox' && is_array( $value ) ){ - $display_value = implode( ', ', $value ); - } elseif ( $details['type'] == 'select' ){ - $display_value = '
              ' . __(self::wck_get_entry_field_select( $value, $details ), 'profilebuilder') . '
              '; - } else { - $display_value = '
              '.htmlspecialchars( $value ) . '
              '; - } - - $display_value = apply_filters( "wck_pre_displayed_value_{$meta}_element_{$field['slug']}", $display_value ); - - $list = apply_filters( "wck_before_listed_{$meta}_element_{$j}", $list, $element_id, $value ); - /*check for nested repeater type and set it acordingly */ - if( strpos( $details['type'], 'CFC-') === 0 ) - $details['type'] = 'nested-repeater'; - - $list .= '
            • '.$details['title'].': '.$display_value.'
            • ' . "\r\n"; - - $list = apply_filters( "wck_after_listed_{$meta}_element_{$j}", $list, $element_id, $value ); - - $j++; - - /* In CFC/OPC we need the field title. Find it out and output it if found */ - if ($meta == 'wck_cfc_fields') { - if( !empty( $results[$element_id][Wordpress_Creation_Kit_PB::wck_generate_slug( $details['title'], $details )] ) ){ - $field_title = $results[$element_id][Wordpress_Creation_Kit_PB::wck_generate_slug( $details['title'], $details )]; - if ($field_title == "Field Type") - $cfc_field_type = $value; - } - } - } - } - $list .= '
            '; - - $list = apply_filters( 'wck_after_content_element', $list, $meta, $id, $results, $element_id ); - /* check if we have nested repeaters */ - if( function_exists( 'wck_nr_check_for_nested_repeaters' ) ){ - if( wck_nr_check_for_nested_repeaters( $fields ) === true ){ - $list .= wck_nr_handle_repeaters( $meta, $id, $fields, $results, $element_id ); - } - } - - if( $element_id === 0 ){ - $list .= ""; - } - - $list .= ''; - $list .= ''. apply_filters( 'wck_edit_button', __('Edit','wck'), $meta ) .''; - $list .= ''. apply_filters( 'wck_delete_button', __( 'Delete', 'wck' ), $meta) .''; - $list .= apply_filters( 'wck_add_content_after_columns', '', $list, $meta ); - - $list .= " \r\n"; - - return $list; - } - - /* function to generate the output for the select field */ - function wck_get_entry_field_select( $value, $field_details ){ - if ( (!is_array( $field_details ) && !isset( $field_details['options']) ) || empty( $value )){ - return $value; - } - foreach( $field_details['options'] as $option ){ - if ( strpos( $option, $value ) !== false ){ - if( strpos( $option, '%' ) === false ){ - return $value; - } else { - $option_parts = explode( '%', $option ); - if( !empty( $option_parts ) ){ - if( empty( $option_parts[0] ) && count( $option_parts ) == 3 ){ - $label = $option_parts[1]; - return $label; - } - } - } - } - } - } - - /* function to generate output for upload field */ - function wck_get_entry_field_upload($id){ - if( !empty ( $id ) && is_numeric( $id ) ){ - $file_src = wp_get_attachment_url($id); - $thumbnail = wp_get_attachment_image( $id, array( 80, 60 ), true ); - $file_name = get_the_title( $id ); - - if ( preg_match( '/^.*?\.(\w+)$/', get_attached_file( $id ), $matches ) ) - $file_type = esc_html( strtoupper( $matches[1] ) ); - else - $file_type = strtoupper( str_replace( 'image/', '', get_post_mime_type( $id ) ) ); - - return $display_value = '
            '. $thumbnail .'

            '. $file_name .''. $file_type . '

            '; - } else { - return ''; - } - } - - /* function to generate output for user select */ - function wck_get_entry_field_user_select($id){ - if( !empty ( $id ) && is_numeric( $id ) ){ - $user = get_user_by( 'id', $id ); - if ( $user ) - return '
            '.htmlspecialchars( $user->display_name );
            -			else
            -				return 'Error - User ID not found in database';
            -				
            -		} else {
            -			return '';
            -		}
            -	}
            -	
            -	/* function to generate output for cpt select */
            -	function wck_get_entry_field_cpt_select($id){
            -		if( !empty ( $id ) && is_numeric( $id ) ){				
            -			$post = get_post( $id );	 
            -			
            -			if ( $post != null ){
            -				if ( $post->post_title == '' )
            -					$post->post_title = 'No title. ID: ' . $id;
            -					
            -				return '
            '.htmlspecialchars( $post->post_title );	
            -			}
            -			else
            -				return 'Error - Post ID not found in database';
            -				
            -		} else {
            -			return '';
            -		}
            -	}	
            -	
            -	/* enque the js/css */
            -	function wck_print_scripts($hook){
            -		global $pb_wck_pages_hooknames;
            -		
            -		if( $this->args['context'] == 'post_meta' ) {		
            -			if( 'post.php' == $hook || 'post-new.php' == $hook){
            -				
            -				/* only add on profile builder custom post types */
            -				if( !empty( $_GET['post'] ) )
            -					$post_id = filter_var( $_GET['post'], FILTER_SANITIZE_NUMBER_INT );
            -				else if( !empty( $_POST['post_ID'] ) )
            -					$post_id = filter_var( $_POST['post_ID'], FILTER_SANITIZE_NUMBER_INT );
            -				else 
            -					$post_id = '';
            -				if( !empty( $post_id ) ){
            -					$current_post_type = get_post_type( $post_id );					
            -					if( strpos( $current_post_type, 'wppb-' ) === false )					
            -						return '';
            -				}			
            -				
            -				self::wck_enqueue();				
            -			}
            -		}
            -		elseif( $this->args['context'] == 'option' ){
            -			if( $pb_wck_pages_hooknames[$this->args['post_type']] == $hook ){				
            -				self::wck_enqueue( 'options' );		
            -			}
            -		}
            -	}
            -	
            -	/* our own ajaxurl */
            -	function wck_print_ajax_url(){
            -		echo '';
            -	}
            -	
            -	
            -	/* Helper function for enqueueing scripts and styles */
            -	private static function wck_enqueue( $context = '' ){
            -	
            -		wp_enqueue_script( 'jquery-ui-draggable' );
            -		wp_enqueue_script( 'jquery-ui-droppable' );
            -		wp_enqueue_script( 'jquery-ui-sortable' );
            -		
            -		if( $context == 'options' ){
            -			wp_enqueue_script( 'thickbox' );
            -			wp_enqueue_style( 'thickbox' );
            -		}
            -		
            -		wp_enqueue_script('wordpress-creation-kit', plugins_url('/wordpress-creation-kit.js', __FILE__), array('jquery', 'jquery-ui-draggable', 'jquery-ui-droppable', 'jquery-ui-sortable' ) );
            -		wp_register_style('wordpress-creation-kit-css', plugins_url('/wordpress-creation-kit.css', __FILE__));
            -		wp_enqueue_style('wordpress-creation-kit-css');
            -
            -		// wysiwyg		
            -//		wp_register_script( 'wck-tinymce', plugins_url( '/assets/js/tiny_mce/tiny_mce.js', __FILE__ ), array(), '1.0', true );
            -//		wp_enqueue_script( 'wck-tinymce' );
            -//		wp_register_script( 'wck-tinymce-init', plugins_url( '/assets/js/tiny_mce/wck_tiny_mce_init.js', __FILE__ ), array(), '1.0', true );
            -//		wp_enqueue_script( 'wck-tinymce-init' );
            -		
            -		//datepicker
            -		wp_enqueue_script('jquery-ui-datepicker');		
            -		wp_enqueue_style( 'jquery-style', plugins_url( '/assets/datepicker/datepicker.css', __FILE__ ) );
            -
            -
            -        /* media upload */
            -        wp_enqueue_media();
            -        wp_enqueue_script('wck-upload-field', plugins_url('/fields/upload.js', __FILE__), array('jquery') );
            -
            -	}	
            -
            -	/* Helper function for required fields */
            -	function wck_test_required( $meta_array, $meta, $values, $id ){
            -        $fields = apply_filters( 'wck_before_test_required', $meta_array, $meta, $values, $id );
            -		$required_fields = array();
            -		$required_fields_with_errors = array();
            -		$required_message = '';
            -		
            -		$errors = '';
            -		
            -		if( !empty( $fields ) ){
            -			foreach( $fields as $field ){
            -				if( !empty( $field['required'] ) && $field['required'] )
            -					$required_fields[Wordpress_Creation_Kit_PB::wck_generate_slug( $field['title'], $field )] = $field['title'];
            -			}
            -		}
            -		
            -		if( !empty( $values ) ){
            -			foreach( $values as $key => $value ){
            -				if( array_key_exists( $key, $required_fields ) && apply_filters( "wck_required_test_{$meta}_{$key}", empty( $value ), $value, $id ) ){
            -					$required_message .= apply_filters( "wck_required_message_{$meta}_{$key}", __( "Please enter a value for the required field ", "wck" ) . "$required_fields[$key] \n", $value );
            -					$required_fields_with_errors[] = $key;
            -				}
            -			}
            -		}
            -		
            -		$required_message .= apply_filters( "wck_extra_message", "", $fields, $required_fields, $meta, $values, $id );
            -		$required_fields_with_errors = apply_filters( "wck_required_fields_with_errors", $required_fields_with_errors, $fields, $required_fields, $meta, $value, $id );
            -
            -		if( $required_message != '' ){			
            -			$errors = array( 'error' => $required_message, 'errorfields' => $required_fields_with_errors );			
            -		}
            -		
            -		return $errors;
            -	}
            -
            -	/* Checks to see wether the current user can modify data */
            -	function wck_verify_user_capabilities( $context, $meta = '', $id = 0 ) {
            -
            -		$return = true;
            -
            -		// Meta is an option
            -		if( $context == 'option' && !current_user_can( 'manage_options' ) )
            -			$return = false;
            -
            -		// Meta is post related
            -		if( $context == 'post_meta' && is_user_logged_in() ) {
            -			
            -			// Current user must be able to edit posts
            -			if( !current_user_can( 'edit_posts' ) )
            -				$return = false;
            -
            -			// If the user can't edit others posts the current post must be his/hers
            -			elseif( !current_user_can( 'edit_others_posts' ) ) {
            -
            -				$current_post = get_post( $id );
            -				$current_user = wp_get_current_user();
            -
            -				if( $current_user->ID != $current_post->post_author )
            -					$return = false;
            -
            -			}
            -
            -		}
            -
            -		// Return
            -		if( $return )
            -			return $return;
            -		else
            -			return array( 'error' => __( 'You are not allowed to do this.', 'wck' ), 'errorfields' => '' );
            -
            -	}
            -	
            -
            -	/* ajax add a reccord to the meta */
            -	function wck_add_meta(){
            -		check_ajax_referer( "wck-add-meta" );
            -		if( !empty( $_POST['meta'] ) )
            -			$meta = sanitize_text_field( $_POST['meta'] );
            -		else
            -			$meta = '';
            -		if( !empty( $_POST['id'] ) )
            -			$id = absint($_POST['id']);
            -		else 
            -			$id = '';
            -		if( !empty( $_POST['values'] ) && is_array( $_POST['values'] ) )
            -			$values = array_map( 'wppb_sanitize_value', $_POST['values'] );
            -		else
            -			$values = array();
            -
            -		// Security checks
            -		if( true !== ( $error = self::wck_verify_user_capabilities( $this->args['context'], $meta, $id ) ) ) {
            -			header( 'Content-type: application/json' );
            -			die( json_encode( $error ) );
            -		}
            -
            -		$values = apply_filters( "wck_add_meta_filter_values_{$meta}", $values );
            -
            -		/* check required fields */
            -		$errors = self::wck_test_required( $this->args['meta_array'], $meta, $values, $id );		
            -		if( $errors != '' ){
            -			header( 'Content-type: application/json' );
            -			die( json_encode( $errors ) );
            -		}
            -			
            -		
            -		if( $this->args['context'] == 'post_meta' )
            -			$results = get_post_meta($id, $meta, true);
            -		else if ( $this->args['context'] == 'option' )
            -			$results = get_option( apply_filters( 'wck_option_meta' , $meta, $values ) );
            -
            -		/* we need an array here */
            -		if( empty( $results ) && !is_array( $results ) )
            -			$results = array();
            -
            -        /* for single metaboxes owerwrite entries each time so we have a maximum of one */
            -        if( $this->args['single'] )
            -            $results = array( $values );
            -        else
            -            $results[] = $values;
            -		
            -		do_action( 'wck_before_add_meta', $meta, $id, $values );
            -		
            -		if( $this->args['context'] == 'post_meta' )
            -			update_post_meta($id, $meta, $results);
            -		else if ( $this->args['context'] == 'option' )
            -			update_option( apply_filters( 'wck_option_meta' , $meta, $results ), wp_unslash( $results ) );
            -		
            -		/* if unserialize_fields is true add for each entry separate post meta for every element of the form  */
            -		if( $this->args['unserialize_fields'] && $this->args['context'] == 'post_meta' ){
            -			
            -			$meta_suffix = count( $results );
            -			if( !empty( $values ) ){ 
            -				foreach( $values as $name => $value ){
            -					update_post_meta($id, $meta.'_'.$name.'_'.$meta_suffix, $value);
            -				}
            -			}
            -		}
            -		
            -		exit;
            -	}
            -
            -	/* ajax update a reccord in the meta */
            -	function wck_update_meta(){
            -		check_ajax_referer( "wck-update-entry" );
            -		if( !empty( $_POST['meta'] ) )
            -			$meta = sanitize_text_field( $_POST['meta'] );
            -		else 
            -			$meta = '';
            -		if( !empty( $_POST['id'] ) )
            -			$id = absint($_POST['id']);
            -		else 
            -			$id = '';
            -		if( isset( $_POST['element_id'] ) )
            -			$element_id = absint( $_POST['element_id'] );
            -		else 
            -			$element_id = 0;
            -		if( !empty( $_POST['values'] ) && is_array( $_POST['values']) )
            -			$values = array_map( 'wppb_sanitize_value', $_POST['values'] );
            -		else
            -			$values = array();
            -		
            -		// Security checks
            -		if( true !== ( $error = self::wck_verify_user_capabilities( $this->args['context'], $meta, $id ) ) ) {
            -			header( 'Content-type: application/json' );
            -			die( json_encode( $error ) );
            -		}
            -		
            -		$values = apply_filters( "wck_update_meta_filter_values_{$meta}", $values, $element_id );
            -		
            -		/* check required fields */
            -		$errors = self::wck_test_required( $this->args['meta_array'], $meta, $values, $id );
            -		if( $errors != '' ){
            -			header( 'Content-type: application/json' );
            -			die( json_encode( $errors ) );
            -		}
            -		
            -		if( $this->args['context'] == 'post_meta' )
            -			$results = get_post_meta($id, $meta, true);
            -		else if ( $this->args['context'] == 'option' )
            -			$results = get_option( apply_filters( 'wck_option_meta' , $meta, $values, $element_id ) );
            -		
            -		$results[$element_id] = $values;
            -		
            -		do_action( 'wck_before_update_meta', $meta, $id, $values, $element_id );
            -
            -		if( $this->args['context'] == 'post_meta' )
            -			update_post_meta($id, $meta, $results);
            -		else if ( $this->args['context'] == 'option' )
            -			update_option( apply_filters( 'wck_option_meta' , $meta, $results, $element_id ), wp_unslash( $results ) );
            -		
            -		/* if unserialize_fields is true update the coresponding post metas for every element of the form  */
            -		if( $this->args['unserialize_fields'] && $this->args['context'] == 'post_meta' ){
            -			
            -			$meta_suffix = $element_id + 1;	
            -			if( !empty( $values ) ){
            -				foreach( $values as $name => $value ){
            -					update_post_meta($id, $meta.'_'.$name.'_'.$meta_suffix, $value);				
            -				}
            -			}
            -		}
            -		
            -		exit;
            -	}
            -
            -	/* ajax to refresh the meta content */
            -	function wck_refresh_list(){
            -		if( isset( $_POST['meta'] ) )
            -			$meta = sanitize_text_field( $_POST['meta'] );
            -		else 
            -			$meta = '';
            -		if( isset( $_POST['id'] ) )
            -			$id = absint($_POST['id']);
            -		else 
            -			$id = '';
            -		echo self::wck_output_meta_content($meta, $id, $this->args['meta_array']);
            -		
            -		do_action( "wck_refresh_list_{$meta}", $id );
            -		
            -		exit;
            -	}
            -	
            -	/* ajax to refresh an entry content */
            -	function wck_refresh_entry(){
            -		if( isset( $_POST['meta'] ) )
            -			$meta = sanitize_text_field( $_POST['meta'] );
            -		else 
            -			$meta = '';
            -		if( isset( $_POST['id'] ) )
            -			$id = absint( $_POST['id'] );
            -		else
            -			$id = '';
            -		if( isset( $_POST['element_id'] ) )
            -			$element_id = absint( $_POST['element_id'] );
            -		else
            -			$element_id = '';
            -		
            -		if( $this->args['context'] == 'post_meta' )
            -			$results = get_post_meta($id, $meta, true);
            -		else if ( $this->args['context'] == 'option' )
            -			$results = get_option( apply_filters( 'wck_option_meta' , $meta, $element_id ) );
            -		
            -		echo self::wck_output_entry_content( $meta, $id, $this->args['meta_array'], $results, $element_id );
            -		
            -		do_action( "wck_refresh_entry_{$meta}", $id );
            -		
            -		exit;
            -	}
            -	
            -	/* ajax to add the form for single */
            -	function wck_add_form(){
            -		if( !empty( $_POST['meta'] ) )
            -			$meta = sanitize_text_field( $_POST['meta'] );
            -		else
            -			$meta = '';
            -		if( !empty( $_POST['id'] ) )
            -			$id = absint( $_POST['id'] );
            -		else
            -			$id = '';
            -		$post = get_post($id);
            -		self::create_add_form($this->args['meta_array'], $meta, $post );
            -		do_action( "wck_ajax_add_form_{$meta}", $id );
            -		
            -		exit;
            -	}
            -	
            -
            -	/* ajax to show the update form */
            -	function wck_show_update_form(){
            -		check_ajax_referer( "wck-edit-entry" );		
            -		$meta = sanitize_text_field( $_POST['meta'] );
            -		$id = absint($_POST['id']);
            -		$element_id = absint( $_POST['element_id'] );
            -
            -        do_action( "wck_before_adding_form_{$meta}", $id, $element_id );
            -
            -		echo self::mb_update_form($this->args['meta_array'], $meta, $id, $element_id);
            -		
            -		do_action( "wck_after_adding_form", $meta, $id, $element_id );
            -        do_action( "wck_after_adding_form_{$meta}", $id, $element_id );
            -
            -		exit;
            -	}
            -
            -	/* ajax to remove a reccord from the meta */
            -	function wck_remove_meta(){
            -		check_ajax_referer( "wck-delete-entry" );
            -		if( !empty( $_POST['meta'] ) )
            -			$meta = sanitize_text_field( $_POST['meta'] );
            -		else 
            -			$meta = '';
            -		if( !empty( $_POST['id'] ) )
            -			$id = absint( $_POST['id'] );
            -		else 
            -			$id = '';
            -		if( isset( $_POST['element_id'] ) )
            -			$element_id = absint( $_POST['element_id'] );
            -		else 
            -			$element_id = '';
            -
            -		// Security checks
            -		if( true !== ( $error = self::wck_verify_user_capabilities( $this->args['context'], $meta, $id ) ) ) {
            -			header( 'Content-type: application/json' );
            -			die( json_encode( $error ) );
            -		}
            -		
            -		if( $this->args['context'] == 'post_meta' )
            -			$results = get_post_meta($id, $meta, true);
            -		else if ( $this->args['context'] == 'option' )
            -			$results = get_option( apply_filters( 'wck_option_meta' , $meta, $element_id ) );
            -		
            -		$old_results = $results;
            -		unset($results[$element_id]);
            -		/* reset the keys for the array */
            -		$results = array_values($results);
            -		
            -		do_action( 'wck_before_remove_meta', $meta, $id, $element_id );
            -		
            -		if( $this->args['context'] == 'post_meta' )
            -			update_post_meta($id, $meta, $results);
            -		else if ( $this->args['context'] == 'option' )
            -			update_option( apply_filters( 'wck_option_meta' , $meta, $results, $element_id ), wp_unslash( $results ) );
            -		
            -		
            -		
            -		/* TODO: optimize so that it updates from the deleted element forward */
            -		/* if unserialize_fields is true delete the coresponding post metas */
            -		if( $this->args['unserialize_fields'] && $this->args['context'] == 'post_meta' ){			
            -			
            -			$meta_suffix = 1;			
            -
            -			if( !empty( $results ) ){
            -				foreach( $results as $result ){
            -					foreach ( $result as $name => $value){
            -						update_post_meta($id, $meta.'_'.$name.'_'.$meta_suffix, $value);
            -					}
            -					$meta_suffix++;			
            -				}
            -			}
            -			
            -			if( count( $results ) == 0 )
            -				$results = $old_results;
            -			
            -			if( !empty( $results ) ){
            -				foreach( $results as $result ){				
            -					foreach ( $result as $name => $value){
            -						delete_post_meta( $id, $meta.'_'.$name.'_'.$meta_suffix );					
            -					}
            -					break;
            -				}
            -			}
            -		}
            -
            -		exit;
            -	}
            -
            -
            -	/* ajax to reorder records */
            -	function wck_reorder_meta(){
            -		if( !empty( $_POST['meta'] ) )
            -			$meta = sanitize_text_field( $_POST['meta'] );
            -		else 
            -			$meta = '';
            -		if( !empty( $_POST['id'] ) )
            -			$id = absint($_POST['id']);
            -		else 
            -			$id = '';
            -		if( !empty( $_POST['values'] ) && is_array( $_POST['values'] ) )
            -			$elements_id = array_map( 'absint', $_POST['values'] );
            -		else 
            -			$elements_id = array();
            -
            -		// Security checks
            -		if( true !== ( $error = self::wck_verify_user_capabilities( $this->args['context'], $meta, $id ) ) ) {
            -			header( 'Content-type: application/json' );
            -			die( json_encode( $error ) );
            -		}
            -		
            -		do_action( 'wck_before_reorder_meta', $meta, $id, $elements_id );
            -		
            -		if( $this->args['context'] == 'post_meta' )
            -			$results = get_post_meta($id, $meta, true);
            -		else if ( $this->args['context'] == 'option' )
            -			$results = get_option( apply_filters( 'wck_option_meta' , $meta ) );
            -		
            -		$new_results = array();
            -		if( !empty( $elements_id ) ){
            -			foreach($elements_id as $element_id){
            -				$new_results[] = $results[$element_id];
            -			}
            -		}
            -		
            -		$results = $new_results;
            -		
            -		if( $this->args['context'] == 'post_meta' )
            -			update_post_meta($id, $meta, $results);
            -		else if ( $this->args['context'] == 'option' )
            -			update_option( apply_filters( 'wck_option_meta' , $meta, $results, $element_id ), wp_unslash( $results ) );
            -		
            -		
            -		/* if unserialize_fields is true reorder all the coresponding post metas  */
            -		if( $this->args['unserialize_fields'] && $this->args['context'] == 'post_meta' ){			
            -			
            -			$meta_suffix = 1;
            -			if( !empty( $new_results ) ){
            -				foreach( $new_results as $result ){				
            -					foreach ( $result as $name => $value){					
            -						update_post_meta($id, $meta.'_'.$name.'_'.$meta_suffix, $value);					
            -					}
            -					$meta_suffix++;
            -				}
            -			}
            -			
            -		}		
            -		
            -		exit;
            -	}
            -
            -    /**
            -     * Function that saves the entries for single forms on posts(no options). It is hooke on the 'save_post' hook
            -     * It is executed on each WCK object instance so we need to restrict it on only the ones that are present for that post
            -     */
            -    function wck_save_single_metabox( $post_id, $post ){
            -        if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
            -            return $post_id;
            -
            -        // Check the user's permissions.
            -        if ( isset( $_POST['post_type'] ) && 'page' == $_POST['post_type'] ) {
            -            if ( ! current_user_can( 'edit_page', $post_id ) ) {
            -                return $post_id;
            -            }
            -        } else {
            -            if ( ! current_user_can( 'edit_post', $post_id ) ) {
            -                return $post_id;
            -            }
            -        }
            -
            -        /* only go through for metaboxes defined for this post type */
            -        if( get_post_type( $post_id ) != $this->args['post_type'] )
            -            return $post_id;
            -
            -        if( !empty( $_POST ) ){
            -            /* for single metaboxes we save a hidden input that contains the meta_name attr as a key so we need to search for it */
            -            foreach( $_POST as $request_key => $request_value ){
            -                if( strpos( $request_key, '_wckmetaname_' ) !== false && strpos( $request_key, '#wck' ) !== false ){
            -                    /* found it so now retrieve the meta_name from the key formatted _wckmetaname_actuaname#wck */
            -                    $request_key = str_replace( '_wckmetaname_', '', $request_key );
            -                    $meta_name = sanitize_text_field( str_replace( '#wck', '', $request_key ) );
            -                    /* we have it so go through only on the WCK object instance that has this meta_name */
            -                    if( $this->args['meta_name'] == $meta_name ){
            -
            -                        /* get the meta values from the $_POST and store them in an array */
            -                        $meta_values = array();
            -                        if( !empty( $this->args['meta_array'] ) ){
            -                            foreach ($this->args['meta_array'] as $meta_field){
            -                                /* in the $_POST the names for the fields are prefixed with the meta_name for the single metaboxes in case there are multiple metaboxes that contain fields wit hthe same name */
            -                                $single_field_name = $this->args['meta_name'] .'_'. Wordpress_Creation_Kit_PB::wck_generate_slug( $meta_field['title'],$meta_field );
            -                                if (isset($_POST[$single_field_name])) {
            -                                    /* checkbox needs to be stored as string not array */
            -                                    if( $meta_field['type'] == 'checkbox' )
            -                                        $_POST[$single_field_name] = implode( ', ', $_POST[$single_field_name] );
            -
            -                                    $meta_values[Wordpress_Creation_Kit_PB::wck_generate_slug( $meta_field['title'], $meta_field )] = wppb_sanitize_value( $_POST[$single_field_name] );
            -                                }
            -                                else
            -                                    $meta_values[Wordpress_Creation_Kit_PB::wck_generate_slug( $meta_field['title'], $meta_field )] = '';
            -                            }
            -                        }
            -
            -                        /* test if we have errors for the required fields */
            -                        $errors = self::wck_test_required( $this->args['meta_array'], $meta_name, $meta_values, $post_id );
            -                        if( !empty( $errors ) ){
            -                            /* if we have errors then add them in the global. We do this so we get all errors from all single metaboxes that might be on that page */
            -                            global $wck_single_forms_errors;
            -                            if( !empty( $errors['errorfields'] ) ){
            -                                foreach( $errors['errorfields'] as $key => $field_name ){
            -                                    $errors['errorfields'][$key] = $this->args['meta_name']. '_' .$field_name;
            -                                }
            -                            }
            -                            $wck_single_forms_errors[] = $errors;
            -                        }
            -                        else {
            -                            /* no errors so we can save */
            -                            update_post_meta($post_id, $meta_name, array($meta_values));
            -                            /* handle unserialized fields */
            -                            if ($this->args['unserialize_fields']) {
            -                                if (!empty($this->args['meta_array'])) {
            -                                    foreach ($this->args['meta_array'] as $meta_field) {
            -                                        update_post_meta($post_id, $meta_name . '_' . Wordpress_Creation_Kit_PB::wck_generate_slug( $meta_field['title'], $meta_field ) . '_1', $_POST[$this->args['meta_name'] . '_' . Wordpress_Creation_Kit_PB::wck_generate_slug( $meta_field['title'], $meta_field )]);
            -                                    }
            -                                }
            -                            }
            -                        }
            -                        break;
            -                    }
            -                }
            -            }
            -        }
            -    }
            -
            -    /**
            -     * Function that checks if we have any errors in the required fields from the single metaboxes. It is executed on 'wp_insert_post' hook
            -     * that comes after 'save_post' so we should have the global errors by now. If we have errors perform a redirect and add the error messages and error fields
            -     * in the url
            -     */
            -    function wck_single_metabox_redirect_if_errors( $post_id, $post ){
            -        global $wck_single_forms_errors;
            -        if( !empty( $wck_single_forms_errors ) ) {
            -            $error_messages = '';
            -            $error_fields = '';
            -            foreach( $wck_single_forms_errors as $wck_single_forms_error ){
            -                $error_messages .= $wck_single_forms_error['error'];
            -                $error_fields .= implode( ',', $wck_single_forms_error['errorfields'] ).',';
            -            }
            -            wp_safe_redirect( add_query_arg( array( 'wckerrormessages' => base64_encode( urlencode( $error_messages ) ), 'wckerrorfields' => base64_encode( urlencode( $error_fields ) ) ), $_SERVER["HTTP_REFERER"] ) );
            -            exit;
            -        }
            -    }
            -
            -    /** Function that displays the error messages, if we have any, as js alerts and marks the fields with red
            -     */
            -    function wck_single_metabox_errors_display(){
            -        /* only execute for the WCK objects defined for the current post type */
            -        global $post;
            -        if( get_post_type( $post ) != $this->args['post_type'] )
            -            return;
            -
            -        /* and only do it once */
            -        global $allready_saved;
            -        if( isset( $allready_saved ) && $allready_saved == true )
            -            return;
            -        $allready_saved = true;
            -
            -        /* mark the fields */
            -        if( isset( $_GET['wckerrorfields'] ) && !empty( $_GET['wckerrorfields'] ) ){
            -            echo '';
            -        }
            -
            -        /* alert the error messages */
            -        if( isset( $_GET['wckerrormessages'] ) ){
            -            echo '';
            -        }
            -    }
            -
            -	
            -	/**
            -	 * The function used to generate slugs in WCK
            -	 *
            -	 * @since 1.1.1
            -	 *	 
            -	 * @param string $string The input string from which we generate the slug	 
            -	 * @return string $slug The henerated slug
            -	 */
            -	static function wck_generate_slug( $string, $details = array() ){
            -        if( !empty( $details['slug'] ) )
            -            $slug = $details['slug'];
            -        else
            -		    $slug = rawurldecode( sanitize_title_with_dashes( remove_accents( $string ) ) );
            -		return $slug;
            -	}
            -
            -	static function wck_strip_script_tags(){
            -
            -	}
            -}
            -
            -
            -/*
            -Helper class that creates admin menu pages ( both top level menu pages and submenu pages )
            -Default Usage: 
            -
            -$args = array(
            -			'page_type' => 'menu_page',
            -			'page_title' => '',
            -			'menu_title' => '',
            -			'capability' => '',
            -			'menu_slug' => '',
            -			'icon_url' => '',
            -			'position' => '',
            -			'parent_slug' => ''			
            -		);
            -
            -'page_type'		(string) (required) The type of page you want to add. Possible values: 'menu_page', 'submenu_page'
            -'page_title' 	(string) (required) The text to be displayed in the title tags and header of 
            -				the page when the menu is selected
            -'menu_title'	(string) (required) The on-screen name text for the menu
            -'capability'	(string) (required) The capability required for this menu to be displayed to
            -				the user.
            -'menu_slug'	    (string) (required) The slug name to refer to this menu by (should be unique 
            -				for this menu).
            -'icon_url'	    (string) (optional for 'page_type' => 'menu_page') The url to the icon to be used for this menu. 
            -				This parameter is optional. Icons should be fairly small, around 16 x 16 pixels 
            -				for best results.
            -'position'	    (integer) (optional for 'page_type' => 'menu_page') The position in the menu order this menu 
            -				should appear. 
            -				By default, if this parameter is omitted, the menu will appear at the bottom 
            -				of the menu structure. The higher the number, the lower its position in the menu. 
            -				WARNING: if 2 menu items use the same position attribute, one of the items may be 
            -				overwritten so that only one item displays!
            -'parent_slug' 	(string) (required for 'page_type' => 'submenu_page' ) The slug name for the parent menu 
            -				(or the file name of a standard WordPress admin page) For examples see http://codex.wordpress.org/Function_Reference/add_submenu_page $parent_slug parameter
            -'priority'	    (int) (optional) How important your function is. Alter this to make your function 
            -				be called before or after other functions. The default is 10, so (for example) setting it to 5 would make it run earlier and setting it to 12 would make it run later. 				
            -
            -public $hookname ( for required for 'page_type' => 'menu_page' ) string used internally to 
            -				 track menu page callbacks for outputting the page inside the global $menu array
            -				 ( for required for 'page_type' => 'submenu_page' ) The resulting page's hook_suffix,
            -				 or false if the user does not have the capability required.  				
            -*/
            -
            -class WCK_Page_Creator_PB{
            -
            -	private $defaults = array(
            -							'page_type' => 'menu_page',
            -							'page_title' => '',
            -							'menu_title' => '',
            -							'capability' => '',
            -							'menu_slug' => '',
            -							'icon_url' => '',
            -							'position' => '',
            -							'parent_slug' => '',
            -							'priority' => 10,
            -							'network_page' => false
            -						);
            -	private $args;
            -	public $hookname;
            -	
            -	
            -	/* Constructor method for the class. */
            -	function __construct( $args ) {
            -
            -		/* Global that will hold all the arguments for all the menu pages */
            -		global $wck_pages;		
            -		
            -		/* Merge the input arguments and the defaults. */
            -		$this->args = wp_parse_args( $args, $this->defaults );
            -		
            -		/* Add the settings for this page to the global object */
            -		$wck_pages[$this->args['page_title']] = $this->args;
            -		
            -		if( !$this->args['network_page'] ){		
            -			/* Hook the page function to 'admin_menu'. */
            -			add_action( 'admin_menu', array( &$this, 'wck_page_init' ), $this->args['priority'] );
            -		}
            -		else{
            -			/* Hook the page function to 'admin_menu'. */
            -			add_action( 'network_admin_menu', array( &$this, 'wck_page_init' ), $this->args['priority'] );
            -		}				
            -	}
            -	
            -	/**
            -	 * Function that creates the admin page
            -	 */
            -	function wck_page_init(){			
            -		global $pb_wck_pages_hooknames;
            -
            -        /* don't add the page at all if the user doesn't meet the capabilities */
            -        if( !empty( $this->args['capability'] ) ){
            -            if( !current_user_can( $this->args['capability'] ) )
            -                return;
            -        }
            -		
            -		/* Create the page using either add_menu_page or add_submenu_page functions depending on the 'page_type' parameter. */
            -		if( $this->args['page_type'] == 'menu_page' ){
            -			$this->hookname = add_menu_page( $this->args['page_title'], $this->args['menu_title'], $this->args['capability'], $this->args['menu_slug'], array( &$this, 'wck_page_template' ), $this->args['icon_url'], $this->args['position'] );
            -
            -			$pb_wck_pages_hooknames[$this->args['menu_slug']] = $this->hookname;
            -		}
            -		else if( $this->args['page_type'] == 'submenu_page' ){
            -			$this->hookname = add_submenu_page( $this->args['parent_slug'], $this->args['page_title'], $this->args['menu_title'], $this->args['capability'], $this->args['menu_slug'], array( &$this, 'wck_page_template' ) );
            -
            -			$pb_wck_pages_hooknames[$this->args['menu_slug']] = $this->hookname;
            -		}
            -
            -		do_action( 'WCK_Page_Creator_PB_after_init', $this->hookname );
            -		
            -		/* Create a hook for adding meta boxes. */
            -		add_action( "load-{$this->hookname}", array( &$this, 'wck_settings_page_add_meta_boxes' ) );
            -		/* Load the JavaScript needed for the screen. */
            -		add_action( 'admin_enqueue_scripts', array( &$this, 'wck_page_enqueue_scripts' ) );
            -		add_action( "admin_head-{$this->hookname}", array( &$this, 'wck_page_load_scripts' ) );
            -	}
            -	
            -	/**
            -	 * Do action 'add_meta_boxes'. This hook isn't executed by default on a admin page so we have to add it.
            -	 */
            -	function wck_settings_page_add_meta_boxes() {
            -        global $post;
            -		do_action( 'add_meta_boxes', $this->hookname, $post );
            -	}
            -	
            -	/**
            -	 * Loads the JavaScript files required for managing the meta boxes on the theme settings
            -	 * page, which allows users to arrange the boxes to their liking.
            -	 *
            -	 * @global string $bareskin_settings_page. The global setting page (returned by add_theme_page in function
            -	 * bareskin_settings_page_init ).
            -	 * @since 1.0.0
            -	 * @param string $hook The current page being viewed.
            -	 */
            -	function wck_page_enqueue_scripts( $hook ) {		
            -		if ( $hook == $this->hookname ) {
            -			wp_enqueue_script( 'common' );
            -			wp_enqueue_script( 'wp-lists' );
            -			wp_enqueue_script( 'postbox' );
            -		}
            -	}
            -	
            -	/**
            -	 * Loads the JavaScript required for toggling the meta boxes on the theme settings page.
            -	 *
            -	 * @global string $bareskin_settings_page. The global setting page (returned by add_theme_page in function
            -	 * bareskin_settings_page_init ).
            -	 * @since 1.0.0
            -	 */
            -	function wck_page_load_scripts() {		
            -		?>
            -				
            -		
            - - args['page_icon'] ) ): ?> -
            -
            -
            - - -

            args['page_title'] ?>

            - -
            - - - - - hookname ); ?> - -
            -
            -
            - hookname ); ?> - hookname, 'normal', null ); ?> - hookname ); ?> -
            -
            - hookname ); ?> - hookname, 'advanced', null ); ?> - hookname ); ?> -
            -
            -
            hookname, 'side', null ); ?>
            - -
            - - hookname ); ?> - -
            - -
            - 'text', 'title' => 'Title', 'description' => 'Description for this input' ), + array( 'type' => 'textarea', 'title' => 'Description' ), + array( 'type' => 'upload', 'title' => 'Image', 'description' => 'Upload a image' ), + array( 'type' => 'select', 'title' => 'Select This', 'options' => array( 'Option 1', 'Option 2', 'Option 3' ) ), + array( 'type' => 'checkbox', 'title' => 'Check This', 'options' => array( 'Option 1', 'Option 2', 'Option 3' ) ), + array( 'type' => 'radio', 'title' => 'Radio This', 'options' => array( 'Radio 1', 'Radio 2', 'Radio 3' ) ), + ); + +$args = array( + 'metabox_id' => 'rm_slider_content', + 'metabox_title' => 'Slideshow Class', + 'post_type' => 'slideshows', + 'meta_name' => 'rmscontent', + 'meta_array' => $fint +); + +new Wordpress_Creation_Kit_PB( $args ); + + +On the frontend: + +$meta = get_post_meta( $post->ID, 'rmscontent', true ); + +*/ + +class Wordpress_Creation_Kit_PB{ + + private $defaults = array( + 'metabox_id' => '', + 'metabox_title' => 'Meta Box', + 'post_type' => 'post', + 'meta_name' => '', + 'meta_array' => array(), + 'page_template' => '', + 'post_id' => '', + 'single' => false, + 'unserialize_fields' => false, + 'sortable' => true, + 'context' => 'post_meta', + 'mb_context' => 'normal' + ); + private $args; + + + /* Constructor method for the class. */ + function __construct( $args ) { + + /* Global that will hold all the arguments for all the custom boxes */ + global $wck_objects; + + /* Merge the input arguments and the defaults. */ + $this->args = wp_parse_args( $args, $this->defaults ); + + /* Add the settings for this box to the global object */ + $wck_objects[$this->args['metabox_id']] = $this->args; + + /*print scripts*/ + add_action('admin_enqueue_scripts', array( &$this, 'wck_print_scripts' )); + /* add our own ajaxurl because we are going to use the wck script also in frontend and we want to avoid any conflicts */ + add_action( 'admin_head', array( &$this, 'wck_print_ajax_url' ) ); + + // Set up the AJAX hooks + add_action("wp_ajax_wck_add_meta".$this->args['meta_name'], array( &$this, 'wck_add_meta') ); + add_action("wp_ajax_wck_update_meta".$this->args['meta_name'], array( &$this, 'wck_update_meta') ); + add_action("wp_ajax_wck_show_update".$this->args['meta_name'], array( &$this, 'wck_show_update_form') ); + add_action("wp_ajax_wck_refresh_list".$this->args['meta_name'], array( &$this, 'wck_refresh_list') ); + add_action("wp_ajax_wck_refresh_entry".$this->args['meta_name'], array( &$this, 'wck_refresh_entry') ); + add_action("wp_ajax_wck_add_form".$this->args['meta_name'], array( &$this, 'wck_add_form') ); + add_action("wp_ajax_wck_remove_meta".$this->args['meta_name'], array( &$this, 'wck_remove_meta') ); + add_action("wp_ajax_wck_reorder_meta".$this->args['meta_name'], array( &$this, 'wck_reorder_meta') ); + + add_action('add_meta_boxes', array( &$this, 'wck_add_metabox') ); + + /* For single forms we save them the old fashion way */ + if( $this->args['single'] ){ + add_action('save_post', array($this, 'wck_save_single_metabox'), 10, 2); + /* wp_insert_post executes after save_post so at this point if we have the error global we can redirect the page + and add the error message and error fields urlencoded as $_GET */ + add_action('wp_insert_post', array($this, 'wck_single_metabox_redirect_if_errors'), 10, 2); + /* if we have any $_GET errors alert them with js so we have consistency */ + add_action('admin_print_footer_scripts', array($this, 'wck_single_metabox_errors_display') ); + } + + } + + + //add metabox using wordpress api + + function wck_add_metabox() { + + global $pb_wck_pages_hooknames; + + if( $this->args['context'] == 'post_meta' ){ + if( $this->args['post_id'] == '' && $this->args['page_template'] == '' ){ + add_meta_box($this->args['metabox_id'], $this->args['metabox_title'], array( &$this, 'wck_content' ), $this->args['post_type'], $this->args['mb_context'], 'high', array( 'meta_name' => $this->args['meta_name'], 'meta_array' => $this->args['meta_array']) ); + /* add class to meta box */ + add_filter( "postbox_classes_".$this->args['post_type']."_".$this->args['metabox_id'], array( &$this, 'wck_add_metabox_classes' ) ); + } + else{ + if( !empty( $_GET['post'] ) ) + $post_id = filter_var( $_GET['post'], FILTER_SANITIZE_NUMBER_INT ); + else if( !empty( $_POST['post_ID'] ) ) + $post_id = filter_var( $_POST['post_ID'], FILTER_SANITIZE_NUMBER_INT ); + else + $post_id = ''; + + + if( $this->args['post_id'] != '' && $this->args['page_template'] != '' ){ + $template_file = get_post_meta($post_id,'_wp_page_template',TRUE); + if( $this->args['post_id'] == $post_id && $template_file == $this->args['page_template'] ) + add_meta_box($this->args['metabox_id'], $this->args['metabox_title'], array( &$this, 'wck_content' ), 'page', $this->args['mb_context'], 'high', array( 'meta_name' => $this->args['meta_name'], 'meta_array' => $this->args['meta_array'] ) ); + + /* add class to meta box */ + add_filter( "postbox_classes_page_".$this->args['metabox_id'], array( &$this, 'wck_add_metabox_classes' ) ); + } + else{ + + if( $this->args['post_id'] != '' ){ + if( $this->args['post_id'] == $post_id ){ + $post_type = get_post_type( $post_id ); + add_meta_box($this->args['metabox_id'], $this->args['metabox_title'], array( &$this, 'wck_content' ), $post_type, $this->args['mb_context'], 'high', array( 'meta_name' => $this->args['meta_name'], 'meta_array' => $this->args['meta_array'] ) ); + /* add class to meta box */ + add_filter( "postbox_classes_".$post_type."_".$this->args['metabox_id'], array( &$this, 'wck_add_metabox_classes' ) ); + } + } + + if( $this->args['page_template'] != '' ){ + $template_file = get_post_meta($post_id,'_wp_page_template',TRUE); + if ( $template_file == $this->args['page_template'] ){ + add_meta_box($this->args['metabox_id'], $this->args['metabox_title'], array( &$this, 'wck_content' ), 'page', $this->args['mb_context'], 'high', array( 'meta_name' => $this->args['meta_name'], 'meta_array' => $this->args['meta_array']) ); + /* add class to meta box */ + add_filter( "postbox_classes_page_".$this->args['metabox_id'], array( &$this, 'wck_add_metabox_classes' ) ); + } + } + + } + + } + } + else if( $this->args['context'] == 'option' ){ + if( !empty( $pb_wck_pages_hooknames[$this->args['post_type']] ) ) { + add_meta_box($this->args['metabox_id'], $this->args['metabox_title'], array(&$this, 'wck_content'), $pb_wck_pages_hooknames[$this->args['post_type']], $this->args['mb_context'], 'high', array('meta_name' => $this->args['meta_name'], 'meta_array' => $this->args['meta_array'])); + /* add class to meta box */ + add_filter("postbox_classes_" . $pb_wck_pages_hooknames[$this->args['post_type']] . "_" . $this->args['metabox_id'], array(&$this, 'wck_add_metabox_classes')); + } + } + } + + /* Function used to add classes to the wck meta boxes */ + function wck_add_metabox_classes( $classes ){ + array_push($classes,'wck-post-box'); + return $classes; + } + + function wck_content($post, $metabox){ + if( !empty( $post->ID ) ) + $post_id = $post->ID; + else + $post_id = ''; + + //output the add form + self::create_add_form($metabox['args']['meta_array'], $metabox['args']['meta_name'], $post); + + //output the entries only for repeater fields + if( !$this->args['single'] ) + echo self::wck_output_meta_content($metabox['args']['meta_name'], $post_id, $metabox['args']['meta_array']); + } + + /** + * The function used to create a form element + * + * @since 1.0.0 + * + * @param string $meta Meta name. + * @param array $details Contains the details for the field. + * @param string $value Contains input value; + * @param string $context Context where the function is used. Depending on it some actions are preformed.; + * @param int $post_id The post ID; + * @return string $element input element html string. + */ + + function wck_output_form_field( $meta, $details, $value = '', $context = '', $post_id = '' ){ + $element = ''; + + if( $context == 'edit_form' ){ + $edit_class = '.mb-table-container '; + $var_prefix = 'edit'; + } + else if( $context == 'fep' ){ + /* id prefix for frontend posting */ + $frontend_prefix = 'fep-'; + } + else{ + if( isset( $details['default'] ) && !( $this->args['single'] == true && !is_null( $value ) ) ) { + $value = apply_filters("wck_default_value_{$meta}_" . Wordpress_Creation_Kit_PB::wck_generate_slug( $details['title'], $details ), $details['default']); + } + } + + /* for single post meta metaboxes we need a prefix in the name attr of the input because in the case we have multiple single metaboxes on the same + post we need to prevent the fields from having the same name attr */ + if( $this->args['context'] == 'post_meta' && $this->args['single'] && $context != 'fep' ) + $single_prefix = $this->args['meta_name'].'_'; + else + $single_prefix = ''; + + $element .= ''; + + $element .= '
            '; + + /* + include actual field type + possible field types: text, textarea, select, checkbox, radio, upload, wysiwyg editor, datepicker, country select, user select, cpt select + */ + + if( function_exists( 'wck_nr_get_repeater_boxes' ) ){ + $cfc_titles = wck_nr_get_repeater_boxes(); + if( in_array( $details['type'], $cfc_titles ) ){ + $details['type'] = 'nested repeater'; + } + } + + + if( file_exists( dirname( __FILE__ ).'/fields/'.$details['type'].'.php' ) ){ + require( dirname( __FILE__ ).'/fields/'.$details['type'].'.php' ); + } + + // Add a filter that allows us to add support for custom field types, not just the ones defined in fields (wck api) + $element .= apply_filters('wck_output_form_field_customtype_' . $details['type'], '', $value, $details, $single_prefix); + + if( !empty( $details['description'] ) ){ + $element .= '

            '. $details['description'].'

            '; + } + + $element .= '
            '; + + $element = apply_filters( "wck_output_form_field_{$meta}_" . Wordpress_Creation_Kit_PB::wck_generate_slug( $details['title'], $details ), $element ); + + return $element; + + } + + + /** + * The function used to create the form for adding records + * + * @since 1.0.0 + * + * @param array $fields Contains the desired inputs in the repeater field. Must be like: array('Key:type'). + * Key is used for the name attribute of the field, label of the field and as the meta_key. + * Supported types: input, textarea, upload + * @param string $meta It is used in update_post_meta($id, $meta, $results);. Use '_' prefix if you don't want + * the meta to apear in custom fields box. + * @param object $post Post object + */ + function create_add_form($fields, $meta, $post, $context = '' ){ + $nonce = wp_create_nonce( 'wck-add-meta' ); + if( !empty( $post->ID ) ) + $post_id = $post->ID; + else + $post_id = ''; + + /* for single forms we need the values that are stored in the meta */ + if( $this->args['single'] == true ) { + if ($this->args['context'] == 'post_meta') + $results = get_post_meta($post_id, $meta, true); + else if ($this->args['context'] == 'option') + $results = get_option( apply_filters( 'wck_option_meta' , $meta )); + + /* Filter primary used for CFC/OPC fields in order to show/hide fields based on type */ + $wck_update_container_css_class = apply_filters("wck_add_form_class_{$meta}", '', $meta, $results ); + } + ?> +
            + +
            + + args['context'] == 'post_meta' ) + $results = get_post_meta($id, $meta, true); + else if ( $this->args['context'] == 'option' ) + $results = get_option( apply_filters( 'wck_option_meta' , $meta ) ); + + /* Filter primary used for CFC/OPC fields in order to show/hide fields based on type */ + $wck_update_container_css_class = " class='wck_update_container update_container_$meta'"; + $wck_update_container_css_class = apply_filters("wck_update_container_class_{$meta}", $wck_update_container_css_class, $meta, $results, $element_id ); + + $form = ''; + $form .= ''; + if($results != null){ + $i = 0; + $form .= '
              '; + + if( !empty( $fields ) ){ + foreach( $fields as $field ){ + $details = $field; + if( isset( $results[$element_id][Wordpress_Creation_Kit_PB::wck_generate_slug( $details['title'], $details )] ) ) + $value = $results[$element_id][Wordpress_Creation_Kit_PB::wck_generate_slug( $details['title'], $details )]; + else + $value = ''; + + $form = apply_filters( "wck_before_update_form_{$meta}_element_{$i}", $form, $element_id, $value ); + + $form .= '
            • '; + + $form .= self::wck_output_form_field( $meta, $details, $value, 'edit_form', $id ); + + $form .= '
            • '; + + $form = apply_filters( "wck_after_update_form_{$meta}_element_{$i}", $form, $element_id, $value ); + + $i++; + } + } + $form .= '
            • '; + $form .= ''. __( apply_filters( 'wck_save_changes_button', 'Save Changes', $meta ), 'profile-builder' ) .''; + $form .= ''. __( apply_filters( 'wck_cancel_button', 'Cancel', $meta ), 'profile-builder' ) .''; + $form .= '
            • '; + + $form .= '
            '; + } + $form .= ''; + + return $form; + } + + + /** + * The function used to output the content of a meta + * + * @since 1.0.0 + * + * @param string $meta It is used in get_post_meta($id, $meta, $results);. Use '_' prefix if you don't want + * the meta to apear in custom fields box. + * @param int $id Post id + */ + function wck_output_meta_content($meta, $id, $fields, $box_args = '' ){ + /* in fep $this->args is empty so we need it as a parameter */ + if( !empty( $box_args ) ) + $this->args = wp_parse_args( $box_args, $this->defaults ); + + + if( $this->args['context'] == 'post_meta' || $this->args['context'] == '' ) + $results = get_post_meta($id, $meta, true); + else if ( $this->args['context'] == 'option' ) + $results = get_option( apply_filters( 'wck_option_meta' , $meta ) ); + + $list = ''; + $list .= ''; + + + if( !empty( $results ) ){ + $list .= apply_filters( 'wck_metabox_content_header_'.$meta , '' ); + $i=0; + foreach ($results as $result){ + + $list .= self::wck_output_entry_content( $meta, $id, $fields, $results, $i ); + + $i++; + } + } + $list .= apply_filters( 'wck_metabox_content_footer_'.$meta , '', $id ); + $list .= '
            #'. __( 'Content', 'profile-builder' ) .''. __( 'Edit', 'wck' ) .''. __( 'Delete', 'wck' ) .'
            '; + + $list = apply_filters('wck_metabox_content_'.$meta, $list, $id); + return $list; + } + + function wck_output_entry_content( $meta, $id, $fields, $results, $element_id ){ + $edit_nonce = wp_create_nonce( 'wck-edit-entry' ); + $delete_nonce = wp_create_nonce( 'wck-delete-entry' ); + $entry_nr = $element_id +1; + + $wck_element_class = ''; + $wck_element_class = apply_filters( "wck_element_class_{$meta}", $wck_element_class, $meta, $results, $element_id ); + + $list = ''; + $list .= ''; + $list .= apply_filters( 'wck_add_content_before_columns', '', $list, $meta ); + $list .= ''. $entry_nr .''; + $list .= '
              ' . "\r\n"; + + $j = 0; + + if( !empty( $fields ) ){ + foreach( $fields as $field ){ + $details = $field; + + if( !empty( $results[$element_id][Wordpress_Creation_Kit_PB::wck_generate_slug( $details['title'], $details )] ) ) + $value = $results[$element_id][Wordpress_Creation_Kit_PB::wck_generate_slug( $details['title'], $details )]; + else + $value =''; + + /* filter display value */ + $value = apply_filters( "wck_displayed_value_{$meta}_element_{$j}", $value ); + + /* display it differently based on field type*/ + if( $details['type'] == 'upload' ){ + $display_value = self::wck_get_entry_field_upload($value); + } elseif ( $details['type'] == 'user select' ) { + $display_value = self::wck_get_entry_field_user_select( $value ) . '
            '; + } elseif ( $details['type'] == 'cpt select' ){ + $display_value = self::wck_get_entry_field_cpt_select( $value ) . '
            '; + } elseif ( $details['type'] == 'checkbox' && is_array( $value ) ){ + $display_value = implode( ', ', $value ); + } elseif ( $details['type'] == 'select' ){ + $display_value = '
            ' . __(self::wck_get_entry_field_select( $value, $details ), 'profilebuilder') . '
            '; + } else { + $display_value = '
            '.htmlspecialchars( $value ) . '
            '; + } + + $display_value = apply_filters( "wck_pre_displayed_value_{$meta}_element_{$field['slug']}", $display_value ); + + $list = apply_filters( "wck_before_listed_{$meta}_element_{$j}", $list, $element_id, $value ); + /*check for nested repeater type and set it acordingly */ + if( strpos( $details['type'], 'CFC-') === 0 ) + $details['type'] = 'nested-repeater'; + + $list .= '
          • '.$details['title'].': '.$display_value.'
          • ' . "\r\n"; + + $list = apply_filters( "wck_after_listed_{$meta}_element_{$j}", $list, $element_id, $value ); + + $j++; + + /* In CFC/OPC we need the field title. Find it out and output it if found */ + if ($meta == 'wck_cfc_fields') { + if( !empty( $results[$element_id][Wordpress_Creation_Kit_PB::wck_generate_slug( $details['title'], $details )] ) ){ + $field_title = $results[$element_id][Wordpress_Creation_Kit_PB::wck_generate_slug( $details['title'], $details )]; + if ($field_title == "Field Type") + $cfc_field_type = $value; + } + } + } + } + $list .= ''; + + $list = apply_filters( 'wck_after_content_element', $list, $meta, $id, $results, $element_id ); + /* check if we have nested repeaters */ + if( function_exists( 'wck_nr_check_for_nested_repeaters' ) ){ + if( wck_nr_check_for_nested_repeaters( $fields ) === true ){ + $list .= wck_nr_handle_repeaters( $meta, $id, $fields, $results, $element_id ); + } + } + + if( $element_id === 0 ){ + $list .= ""; + } + + $list .= ''; + $list .= ''. apply_filters( 'wck_edit_button', __('Edit','wck'), $meta ) .''; + $list .= ''. apply_filters( 'wck_delete_button', __( 'Delete', 'wck' ), $meta) .''; + $list .= apply_filters( 'wck_add_content_after_columns', '', $list, $meta ); + + $list .= " \r\n"; + + return $list; + } + + /* function to generate the output for the select field */ + function wck_get_entry_field_select( $value, $field_details ){ + if ( (!is_array( $field_details ) && !isset( $field_details['options']) ) || empty( $value )){ + return $value; + } + foreach( $field_details['options'] as $option ){ + if ( strpos( $option, $value ) !== false ){ + if( strpos( $option, '%' ) === false ){ + return $value; + } else { + $option_parts = explode( '%', $option ); + if( !empty( $option_parts ) ){ + if( empty( $option_parts[0] ) && count( $option_parts ) == 3 ){ + $label = $option_parts[1]; + return $label; + } + } + } + } + } + } + + /* function to generate output for upload field */ + function wck_get_entry_field_upload($id){ + if( !empty ( $id ) && is_numeric( $id ) ){ + $file_src = wp_get_attachment_url($id); + $thumbnail = wp_get_attachment_image( $id, array( 80, 60 ), true ); + $file_name = get_the_title( $id ); + + if ( preg_match( '/^.*?\.(\w+)$/', get_attached_file( $id ), $matches ) ) + $file_type = esc_html( strtoupper( $matches[1] ) ); + else + $file_type = strtoupper( str_replace( 'image/', '', get_post_mime_type( $id ) ) ); + + return $display_value = '
            '. $thumbnail .'

            '. $file_name .''. $file_type . '

            '; + } else { + return ''; + } + } + + /* function to generate output for user select */ + function wck_get_entry_field_user_select($id){ + if( !empty ( $id ) && is_numeric( $id ) ){ + $user = get_user_by( 'id', $id ); + if ( $user ) + return '
            '.htmlspecialchars( $user->display_name );
            +			else
            +				return 'Error - User ID not found in database';
            +				
            +		} else {
            +			return '';
            +		}
            +	}
            +	
            +	/* function to generate output for cpt select */
            +	function wck_get_entry_field_cpt_select($id){
            +		if( !empty ( $id ) && is_numeric( $id ) ){				
            +			$post = get_post( $id );	 
            +			
            +			if ( $post != null ){
            +				if ( $post->post_title == '' )
            +					$post->post_title = 'No title. ID: ' . $id;
            +					
            +				return '
            '.htmlspecialchars( $post->post_title );	
            +			}
            +			else
            +				return 'Error - Post ID not found in database';
            +				
            +		} else {
            +			return '';
            +		}
            +	}	
            +	
            +	/* enque the js/css */
            +	function wck_print_scripts($hook){
            +		global $pb_wck_pages_hooknames;
            +		
            +		if( $this->args['context'] == 'post_meta' ) {		
            +			if( 'post.php' == $hook || 'post-new.php' == $hook){
            +				
            +				/* only add on profile builder custom post types */
            +				if( !empty( $_GET['post'] ) )
            +					$post_id = filter_var( $_GET['post'], FILTER_SANITIZE_NUMBER_INT );
            +				else if( !empty( $_POST['post_ID'] ) )
            +					$post_id = filter_var( $_POST['post_ID'], FILTER_SANITIZE_NUMBER_INT );
            +				else 
            +					$post_id = '';
            +				if( !empty( $post_id ) ){
            +					$current_post_type = get_post_type( $post_id );					
            +					if( strpos( $current_post_type, 'wppb-' ) === false )					
            +						return '';
            +				}			
            +				
            +				self::wck_enqueue();				
            +			}
            +		}
            +		elseif( $this->args['context'] == 'option' ){
            +			if( $pb_wck_pages_hooknames[$this->args['post_type']] == $hook ){				
            +				self::wck_enqueue( 'options' );		
            +			}
            +		}
            +	}
            +	
            +	/* our own ajaxurl */
            +	function wck_print_ajax_url(){
            +		echo '';
            +	}
            +	
            +	
            +	/* Helper function for enqueueing scripts and styles */
            +	private static function wck_enqueue( $context = '' ){
            +	
            +		wp_enqueue_script( 'jquery-ui-draggable' );
            +		wp_enqueue_script( 'jquery-ui-droppable' );
            +		wp_enqueue_script( 'jquery-ui-sortable' );
            +		
            +		if( $context == 'options' ){
            +			wp_enqueue_script( 'thickbox' );
            +			wp_enqueue_style( 'thickbox' );
            +		}
            +		
            +		wp_enqueue_script('wordpress-creation-kit', plugins_url('/wordpress-creation-kit.js', __FILE__), array('jquery', 'jquery-ui-draggable', 'jquery-ui-droppable', 'jquery-ui-sortable' ) );
            +		wp_register_style('wordpress-creation-kit-css', plugins_url('/wordpress-creation-kit.css', __FILE__));
            +		wp_enqueue_style('wordpress-creation-kit-css');
            +
            +		// wysiwyg		
            +//		wp_register_script( 'wck-tinymce', plugins_url( '/assets/js/tiny_mce/tiny_mce.js', __FILE__ ), array(), '1.0', true );
            +//		wp_enqueue_script( 'wck-tinymce' );
            +//		wp_register_script( 'wck-tinymce-init', plugins_url( '/assets/js/tiny_mce/wck_tiny_mce_init.js', __FILE__ ), array(), '1.0', true );
            +//		wp_enqueue_script( 'wck-tinymce-init' );
            +		
            +		//datepicker
            +		wp_enqueue_script('jquery-ui-datepicker');		
            +		wp_enqueue_style( 'jquery-style', plugins_url( '/assets/datepicker/datepicker.css', __FILE__ ) );
            +
            +
            +        /* media upload */
            +        wp_enqueue_media();
            +        wp_enqueue_script('wck-upload-field', plugins_url('/fields/upload.js', __FILE__), array('jquery') );
            +
            +	}	
            +
            +	/* Helper function for required fields */
            +	function wck_test_required( $meta_array, $meta, $values, $id ){
            +        $fields = apply_filters( 'wck_before_test_required', $meta_array, $meta, $values, $id );
            +		$required_fields = array();
            +		$required_fields_with_errors = array();
            +		$required_message = '';
            +		
            +		$errors = '';
            +		
            +		if( !empty( $fields ) ){
            +			foreach( $fields as $field ){
            +				if( !empty( $field['required'] ) && $field['required'] )
            +					$required_fields[Wordpress_Creation_Kit_PB::wck_generate_slug( $field['title'], $field )] = $field['title'];
            +			}
            +		}
            +		
            +		if( !empty( $values ) ){
            +			foreach( $values as $key => $value ){
            +				if( array_key_exists( $key, $required_fields ) && apply_filters( "wck_required_test_{$meta}_{$key}", empty( $value ), $value, $id ) ){
            +					$required_message .= apply_filters( "wck_required_message_{$meta}_{$key}", __( "Please enter a value for the required field ", "wck" ) . "$required_fields[$key] \n", $value );
            +					$required_fields_with_errors[] = $key;
            +				}
            +			}
            +		}
            +		
            +		$required_message .= apply_filters( "wck_extra_message", "", $fields, $required_fields, $meta, $values, $id );
            +		$required_fields_with_errors = apply_filters( "wck_required_fields_with_errors", $required_fields_with_errors, $fields, $required_fields, $meta, $value, $id );
            +
            +		if( $required_message != '' ){			
            +			$errors = array( 'error' => $required_message, 'errorfields' => $required_fields_with_errors );			
            +		}
            +		
            +		return $errors;
            +	}
            +
            +	/* Checks to see wether the current user can modify data */
            +	function wck_verify_user_capabilities( $context, $meta = '', $id = 0 ) {
            +
            +		$return = true;
            +
            +		// Meta is an option
            +		if( $context == 'option' && !current_user_can( 'manage_options' ) )
            +			$return = false;
            +
            +		// Meta is post related
            +		if( $context == 'post_meta' && is_user_logged_in() ) {
            +			
            +			// Current user must be able to edit posts
            +			if( !current_user_can( 'edit_posts' ) )
            +				$return = false;
            +
            +			// If the user can't edit others posts the current post must be his/hers
            +			elseif( !current_user_can( 'edit_others_posts' ) ) {
            +
            +				$current_post = get_post( $id );
            +				$current_user = wp_get_current_user();
            +
            +				if( $current_user->ID != $current_post->post_author )
            +					$return = false;
            +
            +			}
            +
            +		}
            +
            +		// Return
            +		if( $return )
            +			return $return;
            +		else
            +			return array( 'error' => __( 'You are not allowed to do this.', 'wck' ), 'errorfields' => '' );
            +
            +	}
            +	
            +
            +	/* ajax add a reccord to the meta */
            +	function wck_add_meta(){
            +		check_ajax_referer( "wck-add-meta" );
            +		if( !empty( $_POST['meta'] ) )
            +			$meta = sanitize_text_field( $_POST['meta'] );
            +		else
            +			$meta = '';
            +		if( !empty( $_POST['id'] ) )
            +			$id = absint($_POST['id']);
            +		else 
            +			$id = '';
            +		if( !empty( $_POST['values'] ) && is_array( $_POST['values'] ) )
            +			$values = array_map( 'wppb_sanitize_value', $_POST['values'] );
            +		else
            +			$values = array();
            +
            +		// Security checks
            +		if( true !== ( $error = self::wck_verify_user_capabilities( $this->args['context'], $meta, $id ) ) ) {
            +			header( 'Content-type: application/json' );
            +			die( json_encode( $error ) );
            +		}
            +
            +		$values = apply_filters( "wck_add_meta_filter_values_{$meta}", $values );
            +
            +		/* check required fields */
            +		$errors = self::wck_test_required( $this->args['meta_array'], $meta, $values, $id );		
            +		if( $errors != '' ){
            +			header( 'Content-type: application/json' );
            +			die( json_encode( $errors ) );
            +		}
            +			
            +		
            +		if( $this->args['context'] == 'post_meta' )
            +			$results = get_post_meta($id, $meta, true);
            +		else if ( $this->args['context'] == 'option' )
            +			$results = get_option( apply_filters( 'wck_option_meta' , $meta, $values ) );
            +
            +		/* we need an array here */
            +		if( empty( $results ) && !is_array( $results ) )
            +			$results = array();
            +
            +        /* for single metaboxes owerwrite entries each time so we have a maximum of one */
            +        if( $this->args['single'] )
            +            $results = array( $values );
            +        else
            +            $results[] = $values;
            +		
            +		do_action( 'wck_before_add_meta', $meta, $id, $values );
            +		
            +		if( $this->args['context'] == 'post_meta' )
            +			update_post_meta($id, $meta, $results);
            +		else if ( $this->args['context'] == 'option' )
            +			update_option( apply_filters( 'wck_option_meta' , $meta, $results ), wp_unslash( $results ) );
            +		
            +		/* if unserialize_fields is true add for each entry separate post meta for every element of the form  */
            +		if( $this->args['unserialize_fields'] && $this->args['context'] == 'post_meta' ){
            +			
            +			$meta_suffix = count( $results );
            +			if( !empty( $values ) ){ 
            +				foreach( $values as $name => $value ){
            +					update_post_meta($id, $meta.'_'.$name.'_'.$meta_suffix, $value);
            +				}
            +			}
            +		}
            +		
            +		exit;
            +	}
            +
            +	/* ajax update a reccord in the meta */
            +	function wck_update_meta(){
            +		check_ajax_referer( "wck-update-entry" );
            +		if( !empty( $_POST['meta'] ) )
            +			$meta = sanitize_text_field( $_POST['meta'] );
            +		else 
            +			$meta = '';
            +		if( !empty( $_POST['id'] ) )
            +			$id = absint($_POST['id']);
            +		else 
            +			$id = '';
            +		if( isset( $_POST['element_id'] ) )
            +			$element_id = absint( $_POST['element_id'] );
            +		else 
            +			$element_id = 0;
            +		if( !empty( $_POST['values'] ) && is_array( $_POST['values']) )
            +			$values = array_map( 'wppb_sanitize_value', $_POST['values'] );
            +		else
            +			$values = array();
            +		
            +		// Security checks
            +		if( true !== ( $error = self::wck_verify_user_capabilities( $this->args['context'], $meta, $id ) ) ) {
            +			header( 'Content-type: application/json' );
            +			die( json_encode( $error ) );
            +		}
            +		
            +		$values = apply_filters( "wck_update_meta_filter_values_{$meta}", $values, $element_id );
            +		
            +		/* check required fields */
            +		$errors = self::wck_test_required( $this->args['meta_array'], $meta, $values, $id );
            +		if( $errors != '' ){
            +			header( 'Content-type: application/json' );
            +			die( json_encode( $errors ) );
            +		}
            +		
            +		if( $this->args['context'] == 'post_meta' )
            +			$results = get_post_meta($id, $meta, true);
            +		else if ( $this->args['context'] == 'option' )
            +			$results = get_option( apply_filters( 'wck_option_meta' , $meta, $values, $element_id ) );
            +		
            +		$results[$element_id] = $values;
            +		
            +		do_action( 'wck_before_update_meta', $meta, $id, $values, $element_id );
            +
            +		if( $this->args['context'] == 'post_meta' )
            +			update_post_meta($id, $meta, $results);
            +		else if ( $this->args['context'] == 'option' )
            +			update_option( apply_filters( 'wck_option_meta' , $meta, $results, $element_id ), wp_unslash( $results ) );
            +		
            +		/* if unserialize_fields is true update the coresponding post metas for every element of the form  */
            +		if( $this->args['unserialize_fields'] && $this->args['context'] == 'post_meta' ){
            +			
            +			$meta_suffix = $element_id + 1;	
            +			if( !empty( $values ) ){
            +				foreach( $values as $name => $value ){
            +					update_post_meta($id, $meta.'_'.$name.'_'.$meta_suffix, $value);				
            +				}
            +			}
            +		}
            +		
            +		exit;
            +	}
            +
            +	/* ajax to refresh the meta content */
            +	function wck_refresh_list(){
            +		if( isset( $_POST['meta'] ) )
            +			$meta = sanitize_text_field( $_POST['meta'] );
            +		else 
            +			$meta = '';
            +		if( isset( $_POST['id'] ) )
            +			$id = absint($_POST['id']);
            +		else 
            +			$id = '';
            +		echo self::wck_output_meta_content($meta, $id, $this->args['meta_array']);
            +		
            +		do_action( "wck_refresh_list_{$meta}", $id );
            +		
            +		exit;
            +	}
            +	
            +	/* ajax to refresh an entry content */
            +	function wck_refresh_entry(){
            +		if( isset( $_POST['meta'] ) )
            +			$meta = sanitize_text_field( $_POST['meta'] );
            +		else 
            +			$meta = '';
            +		if( isset( $_POST['id'] ) )
            +			$id = absint( $_POST['id'] );
            +		else
            +			$id = '';
            +		if( isset( $_POST['element_id'] ) )
            +			$element_id = absint( $_POST['element_id'] );
            +		else
            +			$element_id = '';
            +		
            +		if( $this->args['context'] == 'post_meta' )
            +			$results = get_post_meta($id, $meta, true);
            +		else if ( $this->args['context'] == 'option' )
            +			$results = get_option( apply_filters( 'wck_option_meta' , $meta, $element_id ) );
            +		
            +		echo self::wck_output_entry_content( $meta, $id, $this->args['meta_array'], $results, $element_id );
            +		
            +		do_action( "wck_refresh_entry_{$meta}", $id );
            +		
            +		exit;
            +	}
            +	
            +	/* ajax to add the form for single */
            +	function wck_add_form(){
            +		if( !empty( $_POST['meta'] ) )
            +			$meta = sanitize_text_field( $_POST['meta'] );
            +		else
            +			$meta = '';
            +		if( !empty( $_POST['id'] ) )
            +			$id = absint( $_POST['id'] );
            +		else
            +			$id = '';
            +		$post = get_post($id);
            +		self::create_add_form($this->args['meta_array'], $meta, $post );
            +		do_action( "wck_ajax_add_form_{$meta}", $id );
            +		
            +		exit;
            +	}
            +	
            +
            +	/* ajax to show the update form */
            +	function wck_show_update_form(){
            +		check_ajax_referer( "wck-edit-entry" );		
            +		$meta = sanitize_text_field( $_POST['meta'] );
            +		$id = absint($_POST['id']);
            +		$element_id = absint( $_POST['element_id'] );
            +
            +        do_action( "wck_before_adding_form_{$meta}", $id, $element_id );
            +
            +		echo self::mb_update_form($this->args['meta_array'], $meta, $id, $element_id);
            +		
            +		do_action( "wck_after_adding_form", $meta, $id, $element_id );
            +        do_action( "wck_after_adding_form_{$meta}", $id, $element_id );
            +
            +		exit;
            +	}
            +
            +	/* ajax to remove a reccord from the meta */
            +	function wck_remove_meta(){
            +		check_ajax_referer( "wck-delete-entry" );
            +		if( !empty( $_POST['meta'] ) )
            +			$meta = sanitize_text_field( $_POST['meta'] );
            +		else 
            +			$meta = '';
            +		if( !empty( $_POST['id'] ) )
            +			$id = absint( $_POST['id'] );
            +		else 
            +			$id = '';
            +		if( isset( $_POST['element_id'] ) )
            +			$element_id = absint( $_POST['element_id'] );
            +		else 
            +			$element_id = '';
            +
            +		// Security checks
            +		if( true !== ( $error = self::wck_verify_user_capabilities( $this->args['context'], $meta, $id ) ) ) {
            +			header( 'Content-type: application/json' );
            +			die( json_encode( $error ) );
            +		}
            +		
            +		if( $this->args['context'] == 'post_meta' )
            +			$results = get_post_meta($id, $meta, true);
            +		else if ( $this->args['context'] == 'option' )
            +			$results = get_option( apply_filters( 'wck_option_meta' , $meta, $element_id ) );
            +		
            +		$old_results = $results;
            +		unset($results[$element_id]);
            +		/* reset the keys for the array */
            +		$results = array_values($results);
            +		
            +		do_action( 'wck_before_remove_meta', $meta, $id, $element_id );
            +		
            +		if( $this->args['context'] == 'post_meta' )
            +			update_post_meta($id, $meta, $results);
            +		else if ( $this->args['context'] == 'option' )
            +			update_option( apply_filters( 'wck_option_meta' , $meta, $results, $element_id ), wp_unslash( $results ) );
            +		
            +		
            +		
            +		/* TODO: optimize so that it updates from the deleted element forward */
            +		/* if unserialize_fields is true delete the coresponding post metas */
            +		if( $this->args['unserialize_fields'] && $this->args['context'] == 'post_meta' ){			
            +			
            +			$meta_suffix = 1;			
            +
            +			if( !empty( $results ) ){
            +				foreach( $results as $result ){
            +					foreach ( $result as $name => $value){
            +						update_post_meta($id, $meta.'_'.$name.'_'.$meta_suffix, $value);
            +					}
            +					$meta_suffix++;			
            +				}
            +			}
            +			
            +			if( count( $results ) == 0 )
            +				$results = $old_results;
            +			
            +			if( !empty( $results ) ){
            +				foreach( $results as $result ){				
            +					foreach ( $result as $name => $value){
            +						delete_post_meta( $id, $meta.'_'.$name.'_'.$meta_suffix );					
            +					}
            +					break;
            +				}
            +			}
            +		}
            +
            +		exit;
            +	}
            +
            +
            +	/* ajax to reorder records */
            +	function wck_reorder_meta(){
            +		if( !empty( $_POST['meta'] ) )
            +			$meta = sanitize_text_field( $_POST['meta'] );
            +		else 
            +			$meta = '';
            +		if( !empty( $_POST['id'] ) )
            +			$id = absint($_POST['id']);
            +		else 
            +			$id = '';
            +		if( !empty( $_POST['values'] ) && is_array( $_POST['values'] ) )
            +			$elements_id = array_map( 'absint', $_POST['values'] );
            +		else 
            +			$elements_id = array();
            +
            +		// Security checks
            +		if( true !== ( $error = self::wck_verify_user_capabilities( $this->args['context'], $meta, $id ) ) ) {
            +			header( 'Content-type: application/json' );
            +			die( json_encode( $error ) );
            +		}
            +		
            +		do_action( 'wck_before_reorder_meta', $meta, $id, $elements_id );
            +		
            +		if( $this->args['context'] == 'post_meta' )
            +			$results = get_post_meta($id, $meta, true);
            +		else if ( $this->args['context'] == 'option' )
            +			$results = get_option( apply_filters( 'wck_option_meta' , $meta ) );
            +		
            +		$new_results = array();
            +		if( !empty( $elements_id ) ){
            +			foreach($elements_id as $element_id){
            +				$new_results[] = $results[$element_id];
            +			}
            +		}
            +		
            +		$results = $new_results;
            +		
            +		if( $this->args['context'] == 'post_meta' )
            +			update_post_meta($id, $meta, $results);
            +		else if ( $this->args['context'] == 'option' )
            +			update_option( apply_filters( 'wck_option_meta' , $meta, $results, $element_id ), wp_unslash( $results ) );
            +		
            +		
            +		/* if unserialize_fields is true reorder all the coresponding post metas  */
            +		if( $this->args['unserialize_fields'] && $this->args['context'] == 'post_meta' ){			
            +			
            +			$meta_suffix = 1;
            +			if( !empty( $new_results ) ){
            +				foreach( $new_results as $result ){				
            +					foreach ( $result as $name => $value){					
            +						update_post_meta($id, $meta.'_'.$name.'_'.$meta_suffix, $value);					
            +					}
            +					$meta_suffix++;
            +				}
            +			}
            +			
            +		}		
            +		
            +		exit;
            +	}
            +
            +    /**
            +     * Function that saves the entries for single forms on posts(no options). It is hooke on the 'save_post' hook
            +     * It is executed on each WCK object instance so we need to restrict it on only the ones that are present for that post
            +     */
            +    function wck_save_single_metabox( $post_id, $post ){
            +        if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
            +            return $post_id;
            +
            +        // Check the user's permissions.
            +        if ( isset( $_POST['post_type'] ) && 'page' == $_POST['post_type'] ) {
            +            if ( ! current_user_can( 'edit_page', $post_id ) ) {
            +                return $post_id;
            +            }
            +        } else {
            +            if ( ! current_user_can( 'edit_post', $post_id ) ) {
            +                return $post_id;
            +            }
            +        }
            +
            +        /* only go through for metaboxes defined for this post type */
            +        if( get_post_type( $post_id ) != $this->args['post_type'] )
            +            return $post_id;
            +
            +        if( !empty( $_POST ) ){
            +            /* for single metaboxes we save a hidden input that contains the meta_name attr as a key so we need to search for it */
            +            foreach( $_POST as $request_key => $request_value ){
            +                if( strpos( $request_key, '_wckmetaname_' ) !== false && strpos( $request_key, '#wck' ) !== false ){
            +                    /* found it so now retrieve the meta_name from the key formatted _wckmetaname_actuaname#wck */
            +                    $request_key = str_replace( '_wckmetaname_', '', $request_key );
            +                    $meta_name = sanitize_text_field( str_replace( '#wck', '', $request_key ) );
            +                    /* we have it so go through only on the WCK object instance that has this meta_name */
            +                    if( $this->args['meta_name'] == $meta_name ){
            +
            +                        /* get the meta values from the $_POST and store them in an array */
            +                        $meta_values = array();
            +                        if( !empty( $this->args['meta_array'] ) ){
            +                            foreach ($this->args['meta_array'] as $meta_field){
            +                                /* in the $_POST the names for the fields are prefixed with the meta_name for the single metaboxes in case there are multiple metaboxes that contain fields wit hthe same name */
            +                                $single_field_name = $this->args['meta_name'] .'_'. Wordpress_Creation_Kit_PB::wck_generate_slug( $meta_field['title'],$meta_field );
            +                                if (isset($_POST[$single_field_name])) {
            +                                    /* checkbox needs to be stored as string not array */
            +                                    if( $meta_field['type'] == 'checkbox' )
            +                                        $_POST[$single_field_name] = implode( ', ', $_POST[$single_field_name] );
            +
            +                                    $meta_values[Wordpress_Creation_Kit_PB::wck_generate_slug( $meta_field['title'], $meta_field )] = wppb_sanitize_value( $_POST[$single_field_name] );
            +                                }
            +                                else
            +                                    $meta_values[Wordpress_Creation_Kit_PB::wck_generate_slug( $meta_field['title'], $meta_field )] = '';
            +                            }
            +                        }
            +
            +                        /* test if we have errors for the required fields */
            +                        $errors = self::wck_test_required( $this->args['meta_array'], $meta_name, $meta_values, $post_id );
            +                        if( !empty( $errors ) ){
            +                            /* if we have errors then add them in the global. We do this so we get all errors from all single metaboxes that might be on that page */
            +                            global $wck_single_forms_errors;
            +                            if( !empty( $errors['errorfields'] ) ){
            +                                foreach( $errors['errorfields'] as $key => $field_name ){
            +                                    $errors['errorfields'][$key] = $this->args['meta_name']. '_' .$field_name;
            +                                }
            +                            }
            +                            $wck_single_forms_errors[] = $errors;
            +                        }
            +                        else {
            +                            /* no errors so we can save */
            +                            update_post_meta($post_id, $meta_name, array($meta_values));
            +                            /* handle unserialized fields */
            +                            if ($this->args['unserialize_fields']) {
            +                                if (!empty($this->args['meta_array'])) {
            +                                    foreach ($this->args['meta_array'] as $meta_field) {
            +                                        update_post_meta($post_id, $meta_name . '_' . Wordpress_Creation_Kit_PB::wck_generate_slug( $meta_field['title'], $meta_field ) . '_1', $_POST[$this->args['meta_name'] . '_' . Wordpress_Creation_Kit_PB::wck_generate_slug( $meta_field['title'], $meta_field )]);
            +                                    }
            +                                }
            +                            }
            +                        }
            +                        break;
            +                    }
            +                }
            +            }
            +        }
            +    }
            +
            +    /**
            +     * Function that checks if we have any errors in the required fields from the single metaboxes. It is executed on 'wp_insert_post' hook
            +     * that comes after 'save_post' so we should have the global errors by now. If we have errors perform a redirect and add the error messages and error fields
            +     * in the url
            +     */
            +    function wck_single_metabox_redirect_if_errors( $post_id, $post ){
            +        global $wck_single_forms_errors;
            +        if( !empty( $wck_single_forms_errors ) ) {
            +            $error_messages = '';
            +            $error_fields = '';
            +            foreach( $wck_single_forms_errors as $wck_single_forms_error ){
            +                $error_messages .= $wck_single_forms_error['error'];
            +                $error_fields .= implode( ',', $wck_single_forms_error['errorfields'] ).',';
            +            }
            +            wp_safe_redirect( add_query_arg( array( 'wckerrormessages' => base64_encode( urlencode( $error_messages ) ), 'wckerrorfields' => base64_encode( urlencode( $error_fields ) ) ), $_SERVER["HTTP_REFERER"] ) );
            +            exit;
            +        }
            +    }
            +
            +    /** Function that displays the error messages, if we have any, as js alerts and marks the fields with red
            +     */
            +    function wck_single_metabox_errors_display(){
            +        /* only execute for the WCK objects defined for the current post type */
            +        global $post;
            +        if( get_post_type( $post ) != $this->args['post_type'] )
            +            return;
            +
            +        /* and only do it once */
            +        global $allready_saved;
            +        if( isset( $allready_saved ) && $allready_saved == true )
            +            return;
            +        $allready_saved = true;
            +
            +        /* mark the fields */
            +        if( isset( $_GET['wckerrorfields'] ) && !empty( $_GET['wckerrorfields'] ) ){
            +            echo '';
            +        }
            +
            +        /* alert the error messages */
            +        if( isset( $_GET['wckerrormessages'] ) ){
            +            echo '';
            +        }
            +    }
            +
            +	
            +	/**
            +	 * The function used to generate slugs in WCK
            +	 *
            +	 * @since 1.1.1
            +	 *	 
            +	 * @param string $string The input string from which we generate the slug	 
            +	 * @return string $slug The henerated slug
            +	 */
            +	static function wck_generate_slug( $string, $details = array() ){
            +        if( !empty( $details['slug'] ) )
            +            $slug = $details['slug'];
            +        else
            +		    $slug = rawurldecode( sanitize_title_with_dashes( remove_accents( $string ) ) );
            +		return $slug;
            +	}
            +
            +	static function wck_strip_script_tags(){
            +
            +	}
            +}
            +
            +
            +/*
            +Helper class that creates admin menu pages ( both top level menu pages and submenu pages )
            +Default Usage: 
            +
            +$args = array(
            +			'page_type' => 'menu_page',
            +			'page_title' => '',
            +			'menu_title' => '',
            +			'capability' => '',
            +			'menu_slug' => '',
            +			'icon_url' => '',
            +			'position' => '',
            +			'parent_slug' => ''			
            +		);
            +
            +'page_type'		(string) (required) The type of page you want to add. Possible values: 'menu_page', 'submenu_page'
            +'page_title' 	(string) (required) The text to be displayed in the title tags and header of 
            +				the page when the menu is selected
            +'menu_title'	(string) (required) The on-screen name text for the menu
            +'capability'	(string) (required) The capability required for this menu to be displayed to
            +				the user.
            +'menu_slug'	    (string) (required) The slug name to refer to this menu by (should be unique 
            +				for this menu).
            +'icon_url'	    (string) (optional for 'page_type' => 'menu_page') The url to the icon to be used for this menu. 
            +				This parameter is optional. Icons should be fairly small, around 16 x 16 pixels 
            +				for best results.
            +'position'	    (integer) (optional for 'page_type' => 'menu_page') The position in the menu order this menu 
            +				should appear. 
            +				By default, if this parameter is omitted, the menu will appear at the bottom 
            +				of the menu structure. The higher the number, the lower its position in the menu. 
            +				WARNING: if 2 menu items use the same position attribute, one of the items may be 
            +				overwritten so that only one item displays!
            +'parent_slug' 	(string) (required for 'page_type' => 'submenu_page' ) The slug name for the parent menu 
            +				(or the file name of a standard WordPress admin page) For examples see http://codex.wordpress.org/Function_Reference/add_submenu_page $parent_slug parameter
            +'priority'	    (int) (optional) How important your function is. Alter this to make your function 
            +				be called before or after other functions. The default is 10, so (for example) setting it to 5 would make it run earlier and setting it to 12 would make it run later. 				
            +
            +public $hookname ( for required for 'page_type' => 'menu_page' ) string used internally to 
            +				 track menu page callbacks for outputting the page inside the global $menu array
            +				 ( for required for 'page_type' => 'submenu_page' ) The resulting page's hook_suffix,
            +				 or false if the user does not have the capability required.  				
            +*/
            +
            +class WCK_Page_Creator_PB{
            +
            +	private $defaults = array(
            +							'page_type' => 'menu_page',
            +							'page_title' => '',
            +							'menu_title' => '',
            +							'capability' => '',
            +							'menu_slug' => '',
            +							'icon_url' => '',
            +							'position' => '',
            +							'parent_slug' => '',
            +							'priority' => 10,
            +							'network_page' => false
            +						);
            +	private $args;
            +	public $hookname;
            +	
            +	
            +	/* Constructor method for the class. */
            +	function __construct( $args ) {
            +
            +		/* Global that will hold all the arguments for all the menu pages */
            +		global $wck_pages;		
            +		
            +		/* Merge the input arguments and the defaults. */
            +		$this->args = wp_parse_args( $args, $this->defaults );
            +		
            +		/* Add the settings for this page to the global object */
            +		$wck_pages[$this->args['page_title']] = $this->args;
            +		
            +		if( !$this->args['network_page'] ){		
            +			/* Hook the page function to 'admin_menu'. */
            +			add_action( 'admin_menu', array( &$this, 'wck_page_init' ), $this->args['priority'] );
            +		}
            +		else{
            +			/* Hook the page function to 'admin_menu'. */
            +			add_action( 'network_admin_menu', array( &$this, 'wck_page_init' ), $this->args['priority'] );
            +		}				
            +	}
            +	
            +	/**
            +	 * Function that creates the admin page
            +	 */
            +	function wck_page_init(){			
            +		global $pb_wck_pages_hooknames;
            +
            +        /* don't add the page at all if the user doesn't meet the capabilities */
            +        if( !empty( $this->args['capability'] ) ){
            +            if( !current_user_can( $this->args['capability'] ) )
            +                return;
            +        }
            +		
            +		/* Create the page using either add_menu_page or add_submenu_page functions depending on the 'page_type' parameter. */
            +		if( $this->args['page_type'] == 'menu_page' ){
            +			$this->hookname = add_menu_page( $this->args['page_title'], $this->args['menu_title'], $this->args['capability'], $this->args['menu_slug'], array( &$this, 'wck_page_template' ), $this->args['icon_url'], $this->args['position'] );
            +
            +			$pb_wck_pages_hooknames[$this->args['menu_slug']] = $this->hookname;
            +		}
            +		else if( $this->args['page_type'] == 'submenu_page' ){
            +			$this->hookname = add_submenu_page( $this->args['parent_slug'], $this->args['page_title'], $this->args['menu_title'], $this->args['capability'], $this->args['menu_slug'], array( &$this, 'wck_page_template' ) );
            +
            +			$pb_wck_pages_hooknames[$this->args['menu_slug']] = $this->hookname;
            +		}
            +
            +		do_action( 'WCK_Page_Creator_PB_after_init', $this->hookname );
            +		
            +		/* Create a hook for adding meta boxes. */
            +		add_action( "load-{$this->hookname}", array( &$this, 'wck_settings_page_add_meta_boxes' ) );
            +		/* Load the JavaScript needed for the screen. */
            +		add_action( 'admin_enqueue_scripts', array( &$this, 'wck_page_enqueue_scripts' ) );
            +		add_action( "admin_head-{$this->hookname}", array( &$this, 'wck_page_load_scripts' ) );
            +	}
            +	
            +	/**
            +	 * Do action 'add_meta_boxes'. This hook isn't executed by default on a admin page so we have to add it.
            +	 */
            +	function wck_settings_page_add_meta_boxes() {
            +        global $post;
            +		do_action( 'add_meta_boxes', $this->hookname, $post );
            +	}
            +	
            +	/**
            +	 * Loads the JavaScript files required for managing the meta boxes on the theme settings
            +	 * page, which allows users to arrange the boxes to their liking.
            +	 *
            +	 * @global string $bareskin_settings_page. The global setting page (returned by add_theme_page in function
            +	 * bareskin_settings_page_init ).
            +	 * @since 1.0.0
            +	 * @param string $hook The current page being viewed.
            +	 */
            +	function wck_page_enqueue_scripts( $hook ) {		
            +		if ( $hook == $this->hookname ) {
            +			wp_enqueue_script( 'common' );
            +			wp_enqueue_script( 'wp-lists' );
            +			wp_enqueue_script( 'postbox' );
            +		}
            +	}
            +	
            +	/**
            +	 * Loads the JavaScript required for toggling the meta boxes on the theme settings page.
            +	 *
            +	 * @global string $bareskin_settings_page. The global setting page (returned by add_theme_page in function
            +	 * bareskin_settings_page_init ).
            +	 * @since 1.0.0
            +	 */
            +	function wck_page_load_scripts() {		
            +		?>
            +				
            +		
            + + args['page_icon'] ) ): ?> +
            +
            +
            + + +

            args['page_title'] ?>

            + +
            + + + + + hookname ); ?> + +
            +
            +
            + hookname ); ?> + hookname, 'normal', null ); ?> + hookname ); ?> +
            +
            + hookname ); ?> + hookname, 'advanced', null ); ?> + hookname ); ?> +
            +
            +
            hookname, 'side', null ); ?>
            + +
            + + hookname ); ?> + +
            + +
            + \ No newline at end of file diff --git a/profile-builder/assets/misc/fallback-page.php b/profile-builder/assets/misc/fallback-page.php index 6719d70..c21f1c1 100644 --- a/profile-builder/assets/misc/fallback-page.php +++ b/profile-builder/assets/misc/fallback-page.php @@ -1,29 +1,29 @@ - - - - - - - <?php echo htmlspecialchars( $site_name, ENT_QUOTES ); ?> - - - -

            - - '. htmlspecialchars( strip_tags( $message ) ). '

            '; ?> - - here to return to the main site'; ?> - + + + + + + + <?php echo htmlspecialchars( $site_name, ENT_QUOTES ); ?> + + + +

            + + '. htmlspecialchars( strip_tags( $message ) ). '

            '; ?> + + here to return to the main site'; ?> + \ No newline at end of file diff --git a/profile-builder/assets/misc/plugin-compatibilities.php b/profile-builder/assets/misc/plugin-compatibilities.php index 38117e9..c2a4770 100644 --- a/profile-builder/assets/misc/plugin-compatibilities.php +++ b/profile-builder/assets/misc/plugin-compatibilities.php @@ -1,303 +1,314 @@ -' . cptch_display_captcha_custom() . '' . $output; - } - elseif( !empty( $cptch_options['forms']['wp_register']['enable'] ) && $cptch_options['forms']['wp_register']['enable'] ) - $output = '
          • ' . cptch_display_captcha_custom() . '
          • ' . $output; - } - - - return $output; - } - - add_filter( 'wppb_after_form_fields', 'wppb_captcha_add_form_form_builder', 10, 2 ); - } - - - /* - * Function that displays the Captcha error on register form - * - */ - if( function_exists('cptch_register_check') ) { - - function wppb_captcha_register_form_display_error() { - - $cptch_options = get_option('cptch_options'); - - if ( isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'register' && ( ( !empty( $cptch_options['cptch_register_form'] ) && 1 == $cptch_options['cptch_register_form'] ) || ( !empty( $cptch_options['forms']['wp_register']['enable'] ) && $cptch_options['forms']['wp_register']['enable'] ) ) ) { - - $result = cptch_register_check(new WP_Error()); - - if ($result->get_error_message('captcha_error')) - echo '

            ' . $result->get_error_message('captcha_error') . '

            '; - - } - - } - - add_action('wppb_before_register_fields', 'wppb_captcha_register_form_display_error' ); - } - - /* - * Function that validates captcha value on register form - * - */ - if( function_exists('cptch_register_check') ) { - - function wppb_captcha_register_form_check_value($output_field_errors) { - - $cptch_options = get_option('cptch_options'); - - if ( isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'register' && ( ( !empty( $cptch_options['cptch_register_form'] ) && 1 == $cptch_options['cptch_register_form'] ) || ( !empty( $cptch_options['forms']['wp_register']['enable'] ) && $cptch_options['forms']['wp_register']['enable'] ) ) ) { - - $result = cptch_register_check(new WP_Error() ); - - if ($result->get_error_message('captcha_error')) - $output_field_errors[] = $result->get_error_message('captcha_error'); - } - - - return $output_field_errors; - } - - add_filter('wppb_output_field_errors_filter', 'wppb_captcha_register_form_check_value'); - } - - - /* - * Function that ads the Captcha HTML to PB custom recover password form - * - */ - if ( function_exists('cptch_display_captcha_custom') ) { - - function wppb_captcha_add_form_recover_password($output, $username_email = '') { - - $cptch_options = get_option('cptch_options'); - - if (!empty( $cptch_options['cptch_lost_password_form'] ) && 1 == $cptch_options['cptch_lost_password_form']) { - $output = str_replace('', '
          • ' . cptch_display_captcha_custom() . '
          • ' . '', $output); - } - elseif( !empty( $cptch_options['forms']['wp_lost_password']['enable'] ) && $cptch_options['forms']['wp_lost_password']['enable'] ){ - $output = str_replace('', '
          • ' . cptch_display_captcha_custom() . '
          • ' . '', $output); - } - - - return $output; - } - - add_filter('wppb_recover_password_generate_password_input', 'wppb_captcha_add_form_recover_password', 10, 2); - } - - /* - * Function that changes the messageNo from the Recover Password form - * - */ - if( function_exists('cptch_register_check') ) { - - function wppb_captcha_recover_password_message_no($messageNo) { - - $cptch_options = get_option('cptch_options'); - - if (isset($_REQUEST['action']) && $_REQUEST['action'] == 'recover_password' && ( ( !empty( $cptch_options['cptch_lost_password_form'] ) && 1 == $cptch_options['cptch_lost_password_form'] ) || ( !empty( $cptch_options['forms']['wp_lost_password']['enable'] ) && $cptch_options['forms']['wp_lost_password']['enable'] ) ) ) { - - $result = cptch_register_check(new WP_Error()); - - if ($result->get_error_message('captcha_error') || $result->get_error_message('captcha_error')) - $messageNo = ''; - - } - - return $messageNo; - } - - add_filter('wppb_recover_password_message_no', 'wppb_captcha_recover_password_message_no'); - } - - /* - * Function that adds the captcha error message on Recover Password form - * - */ - if( function_exists('cptch_register_check') ) { - - function wppb_captcha_recover_password_displayed_message1($message) { - - $cptch_options = get_option('cptch_options'); - - if (isset($_REQUEST['action']) && $_REQUEST['action'] == 'recover_password' && ( ( !empty( $cptch_options['cptch_lost_password_form'] ) && 1 == $cptch_options['cptch_lost_password_form'] ) || ( !empty( $cptch_options['forms']['wp_lost_password']['enable'] ) && $cptch_options['forms']['wp_lost_password']['enable'] ) ) ) { - - $result = cptch_register_check(new WP_Error()); - $error_message = ''; - - if ($result->get_error_message('captcha_error')) - $error_message = $result->get_error_message('captcha_error'); - - if( empty($error_message) ) - return $message; - - if ( ($message == '

            wppb_captcha_error

            ') || ($message == '

            wppb_recaptcha_error

            ') ) - $message = '

            ' . $error_message . '

            '; - else - $message = $message . '

            ' . $error_message . '

            '; - - } - - return $message; - } - - add_filter('wppb_recover_password_displayed_message1', 'wppb_captcha_recover_password_displayed_message1'); - } - - - /* - * Function that changes the default success message to wppb_captcha_error if the captcha - * doesn't validate so that we can change the message displayed with the - * wppb_recover_password_displayed_message1 filter - * - */ - if( function_exists('cptch_register_check') ) { - - function wppb_captcha_recover_password_sent_message_1($message) { - - $cptch_options = get_option('cptch_options'); - - if (isset($_REQUEST['action']) && $_REQUEST['action'] == 'recover_password' && ( ( !empty( $cptch_options['cptch_lost_password_form'] ) && 1 == $cptch_options['cptch_lost_password_form'] ) || ( !empty( $cptch_options['forms']['wp_lost_password']['enable'] ) && $cptch_options['forms']['wp_lost_password']['enable'] ) ) ) { - - $result = cptch_register_check( new WP_Error() ); - - if ($result->get_error_message('captcha_error') ) - $message = 'wppb_captcha_error'; - - } - - return $message; - } - - add_filter('wppb_recover_password_sent_message1', 'wppb_captcha_recover_password_sent_message_1'); - } - - - - /**************************************************** - * Plugin Name: Easy Digital Downloads - * Plugin URI: https://wordpress.org/plugins/easy-digital-downloads/ - ****************************************************/ - - /* Function that checks if a user is approved before loggin in, when admin approval is on */ - function wppb_check_edd_login_form( $auth_cookie, $expire, $expiration, $user_id, $scheme ) { - $wppb_generalSettings = get_option('wppb_general_settings', 'not_found'); - - if( $wppb_generalSettings != 'not_found' ) { - if( ! empty( $wppb_generalSettings['adminApproval'] ) && ( $wppb_generalSettings['adminApproval'] == 'yes' ) ) { - if( isset( $_REQUEST['edd_login_nonce'] ) ) { - if( wp_get_object_terms( $user_id, 'user_status' ) ) { - if( isset( $_REQUEST['edd_redirect'] ) ) { - wp_redirect( esc_url_raw( $_REQUEST['edd_redirect'] ) ); - edd_set_error( 'user_unapproved', __('Your account has to be confirmed by an administrator before you can log in.', 'profile-builder') ); - edd_get_errors(); - edd_die(); - } - } - } - } - } - } - add_action( 'set_auth_cookie', 'wppb_check_edd_login_form', 10, 5 ); - add_action( 'set_logged_in_cookie', 'wppb_check_edd_login_form', 10, 5 ); - - - /**************************************************** - * Plugin Name: Page Builder by SiteOrigin && Yoast SEO - * Plugin URI: https://wordpress.org/plugins/siteorigin-panels/ && https://wordpress.org/plugins/wordpress-seo/ - * When both plugins are activated SEO generates description tags that execute shortcodes because of the filter on "the_content" added by Page Builder when generating the excerpt - ****************************************************/ - if( function_exists( 'siteorigin_panels_filter_content' ) ){ - add_action( 'wpseo_head', 'wppb_remove_siteorigin_panels_content_filter', 8 ); - function wppb_remove_siteorigin_panels_content_filter() - { - global $post; - if( !empty( $post->post_content ) ) { - if (has_shortcode($post->post_content, 'wppb-register') || has_shortcode($post->post_content, 'wppb-edit-profile') || has_shortcode($post->post_content, 'wppb-login') || has_shortcode($post->post_content, 'wppb-list-users')) - remove_filter('the_content', 'siteorigin_panels_filter_content'); - } - } - - add_filter( 'wpseo_head', 'wppb_add_back_siteorigin_panels_content_filter', 50 ); - function wppb_add_back_siteorigin_panels_content_filter() - { - global $post; - if( !empty( $post->post_content ) ) { - if (has_shortcode($post->post_content, 'wppb-register') || has_shortcode($post->post_content, 'wppb-edit-profile') || has_shortcode($post->post_content, 'wppb-login') || has_shortcode($post->post_content, 'wppb-list-users')) - add_filter('the_content', 'siteorigin_panels_filter_content'); - } - } - } - - /**************************************************** - * Plugin Name: WPML - * Compatibility with wp_login_form() that wasn't getting the language code in the site url - ****************************************************/ - add_filter( 'site_url', 'wppb_wpml_login_form_compatibility', 10, 4 ); - function wppb_wpml_login_form_compatibility( $url, $path, $scheme, $blog_id ){ - global $wppb_login_shortcode; - if( defined( 'ICL_LANGUAGE_CODE' ) && $wppb_login_shortcode ){ - if( $path == 'wp-login.php' ) { - if( !empty( $_GET['lang'] ) ) - return add_query_arg('lang', ICL_LANGUAGE_CODE, $url); - else{ - if( function_exists('curl_version') ) { - /* let's see if the directory structure exists for wp-login.php */ - $headers = wp_remote_head( trailingslashit( get_home_url() ) . $path, array( 'timeout' => 2 ) ); - if (!is_wp_error($headers)) { - if ($headers['response']['code'] == 200) { - return trailingslashit( get_home_url() ) . $path; - } - } - } - return add_query_arg('lang', ICL_LANGUAGE_CODE, $url); - } - } - } - return $url; - } \ No newline at end of file +' . cptch_display_captcha_custom() . '' . $output; + } + elseif( !empty( $cptch_options['forms']['wp_register']['enable'] ) && $cptch_options['forms']['wp_register']['enable'] ) + $output = '
          • ' . cptch_display_captcha_custom() . '
          • ' . $output; + } + + + return $output; + } + + add_filter( 'wppb_after_form_fields', 'wppb_captcha_add_form_form_builder', 10, 2 ); + } + + + /* + * Function that displays the Captcha error on register form + * + */ + if( function_exists('cptch_register_check') ) { + + function wppb_captcha_register_form_display_error() { + + $cptch_options = get_option('cptch_options'); + + if ( isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'register' && ( ( !empty( $cptch_options['cptch_register_form'] ) && 1 == $cptch_options['cptch_register_form'] ) || ( !empty( $cptch_options['forms']['wp_register']['enable'] ) && $cptch_options['forms']['wp_register']['enable'] ) ) ) { + + $result = cptch_register_check(new WP_Error()); + + if ($result->get_error_message('captcha_error')) + echo '

            ' . $result->get_error_message('captcha_error') . '

            '; + + } + + } + + add_action('wppb_before_register_fields', 'wppb_captcha_register_form_display_error' ); + } + + /* + * Function that validates captcha value on register form + * + */ + if( function_exists('cptch_register_check') ) { + + function wppb_captcha_register_form_check_value($output_field_errors) { + + $cptch_options = get_option('cptch_options'); + + if ( isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'register' && ( ( !empty( $cptch_options['cptch_register_form'] ) && 1 == $cptch_options['cptch_register_form'] ) || ( !empty( $cptch_options['forms']['wp_register']['enable'] ) && $cptch_options['forms']['wp_register']['enable'] ) ) ) { + + $result = cptch_register_check(new WP_Error() ); + + if ($result->get_error_message('captcha_error')) + $output_field_errors[] = $result->get_error_message('captcha_error'); + } + + + return $output_field_errors; + } + + add_filter('wppb_output_field_errors_filter', 'wppb_captcha_register_form_check_value'); + } + + + /* + * Function that ads the Captcha HTML to PB custom recover password form + * + */ + if ( function_exists('cptch_display_captcha_custom') ) { + + function wppb_captcha_add_form_recover_password($output, $username_email = '') { + + $cptch_options = get_option('cptch_options'); + + if (!empty( $cptch_options['cptch_lost_password_form'] ) && 1 == $cptch_options['cptch_lost_password_form']) { + $output = str_replace('', '
          • ' . cptch_display_captcha_custom() . '
          • ' . '', $output); + } + elseif( !empty( $cptch_options['forms']['wp_lost_password']['enable'] ) && $cptch_options['forms']['wp_lost_password']['enable'] ){ + $output = str_replace('', '
          • ' . cptch_display_captcha_custom() . '
          • ' . '', $output); + } + + + return $output; + } + + add_filter('wppb_recover_password_generate_password_input', 'wppb_captcha_add_form_recover_password', 10, 2); + } + + /* + * Function that changes the messageNo from the Recover Password form + * + */ + if( function_exists('cptch_register_check') ) { + + function wppb_captcha_recover_password_message_no($messageNo) { + + $cptch_options = get_option('cptch_options'); + + if (isset($_REQUEST['action']) && $_REQUEST['action'] == 'recover_password' && ( ( !empty( $cptch_options['cptch_lost_password_form'] ) && 1 == $cptch_options['cptch_lost_password_form'] ) || ( !empty( $cptch_options['forms']['wp_lost_password']['enable'] ) && $cptch_options['forms']['wp_lost_password']['enable'] ) ) ) { + + $result = cptch_register_check(new WP_Error()); + + if ($result->get_error_message('captcha_error') || $result->get_error_message('captcha_error')) + $messageNo = ''; + + } + + return $messageNo; + } + + add_filter('wppb_recover_password_message_no', 'wppb_captcha_recover_password_message_no'); + } + + /* + * Function that adds the captcha error message on Recover Password form + * + */ + if( function_exists('cptch_register_check') ) { + + function wppb_captcha_recover_password_displayed_message1($message) { + + $cptch_options = get_option('cptch_options'); + + if (isset($_REQUEST['action']) && $_REQUEST['action'] == 'recover_password' && ( ( !empty( $cptch_options['cptch_lost_password_form'] ) && 1 == $cptch_options['cptch_lost_password_form'] ) || ( !empty( $cptch_options['forms']['wp_lost_password']['enable'] ) && $cptch_options['forms']['wp_lost_password']['enable'] ) ) ) { + + $result = cptch_register_check(new WP_Error()); + $error_message = ''; + + if ($result->get_error_message('captcha_error')) + $error_message = $result->get_error_message('captcha_error'); + + if( empty($error_message) ) + return $message; + + if ( ($message == '

            wppb_captcha_error

            ') || ($message == '

            wppb_recaptcha_error

            ') ) + $message = '

            ' . $error_message . '

            '; + else + $message = $message . '

            ' . $error_message . '

            '; + + } + + return $message; + } + + add_filter('wppb_recover_password_displayed_message1', 'wppb_captcha_recover_password_displayed_message1'); + } + + + /* + * Function that changes the default success message to wppb_captcha_error if the captcha + * doesn't validate so that we can change the message displayed with the + * wppb_recover_password_displayed_message1 filter + * + */ + if( function_exists('cptch_register_check') ) { + + function wppb_captcha_recover_password_sent_message_1($message) { + + $cptch_options = get_option('cptch_options'); + + if (isset($_REQUEST['action']) && $_REQUEST['action'] == 'recover_password' && ( ( !empty( $cptch_options['cptch_lost_password_form'] ) && 1 == $cptch_options['cptch_lost_password_form'] ) || ( !empty( $cptch_options['forms']['wp_lost_password']['enable'] ) && $cptch_options['forms']['wp_lost_password']['enable'] ) ) ) { + + $result = cptch_register_check( new WP_Error() ); + + if ($result->get_error_message('captcha_error') ) + $message = 'wppb_captcha_error'; + + } + + return $message; + } + + add_filter('wppb_recover_password_sent_message1', 'wppb_captcha_recover_password_sent_message_1'); + } + + + + /**************************************************** + * Plugin Name: Easy Digital Downloads + * Plugin URI: https://wordpress.org/plugins/easy-digital-downloads/ + ****************************************************/ + + /* Function that checks if a user is approved before loggin in, when admin approval is on */ + function wppb_check_edd_login_form( $auth_cookie, $expire, $expiration, $user_id, $scheme ) { + $wppb_generalSettings = get_option('wppb_general_settings', 'not_found'); + + if( $wppb_generalSettings != 'not_found' ) { + if( ! empty( $wppb_generalSettings['adminApproval'] ) && ( $wppb_generalSettings['adminApproval'] == 'yes' ) ) { + if( isset( $_REQUEST['edd_login_nonce'] ) ) { + if( wp_get_object_terms( $user_id, 'user_status' ) ) { + if( isset( $_REQUEST['edd_redirect'] ) ) { + wp_redirect( esc_url_raw( $_REQUEST['edd_redirect'] ) ); + edd_set_error( 'user_unapproved', __('Your account has to be confirmed by an administrator before you can log in.', 'profile-builder') ); + edd_get_errors(); + edd_die(); + } + } + } + } + } + } + add_action( 'set_auth_cookie', 'wppb_check_edd_login_form', 10, 5 ); + add_action( 'set_logged_in_cookie', 'wppb_check_edd_login_form', 10, 5 ); + + + /**************************************************** + * Plugin Name: Page Builder by SiteOrigin && Yoast SEO + * Plugin URI: https://wordpress.org/plugins/siteorigin-panels/ && https://wordpress.org/plugins/wordpress-seo/ + * When both plugins are activated SEO generates description tags that execute shortcodes because of the filter on "the_content" added by Page Builder when generating the excerpt + ****************************************************/ + if( function_exists( 'siteorigin_panels_filter_content' ) ){ + add_action( 'wpseo_head', 'wppb_remove_siteorigin_panels_content_filter', 8 ); + function wppb_remove_siteorigin_panels_content_filter() + { + global $post; + if( !empty( $post->post_content ) ) { + if (has_shortcode($post->post_content, 'wppb-register') || has_shortcode($post->post_content, 'wppb-edit-profile') || has_shortcode($post->post_content, 'wppb-login') || has_shortcode($post->post_content, 'wppb-list-users')) + remove_filter('the_content', 'siteorigin_panels_filter_content'); + } + } + + add_filter( 'wpseo_head', 'wppb_add_back_siteorigin_panels_content_filter', 50 ); + function wppb_add_back_siteorigin_panels_content_filter() + { + global $post; + if( !empty( $post->post_content ) ) { + if (has_shortcode($post->post_content, 'wppb-register') || has_shortcode($post->post_content, 'wppb-edit-profile') || has_shortcode($post->post_content, 'wppb-login') || has_shortcode($post->post_content, 'wppb-list-users')) + add_filter('the_content', 'siteorigin_panels_filter_content'); + } + } + } + + /**************************************************** + * Plugin Name: WPML + * Compatibility with wp_login_form() that wasn't getting the language code in the site url + ****************************************************/ + add_filter( 'site_url', 'wppb_wpml_login_form_compatibility', 10, 4 ); + function wppb_wpml_login_form_compatibility( $url, $path, $scheme, $blog_id ){ + global $wppb_login_shortcode; + if( defined( 'ICL_LANGUAGE_CODE' ) && $wppb_login_shortcode ){ + if( $path == 'wp-login.php' ) { + if( !empty( $_GET['lang'] ) ) + return add_query_arg('lang', ICL_LANGUAGE_CODE, $url); + else{ + if( function_exists('curl_version') ) { + /* let's see if the directory structure exists for wp-login.php */ + $headers = wp_remote_head( trailingslashit( get_home_url() ) . $path, array( 'timeout' => 2 ) ); + if (!is_wp_error($headers)) { + if ($headers['response']['code'] == 200) { + return trailingslashit( get_home_url() ) . $path; + } + } + } + return add_query_arg('lang', ICL_LANGUAGE_CODE, $url); + } + } + } + return $url; + } + + /**************************************************** + * Plugin Name: ACF + * Compatibility with Role Editor where ACF includes it's own select 2 and a bit differently then the standard hooks + ****************************************************/ + add_action( 'admin_enqueue_scripts', 'wppb_acf_and_user_role_select_2_compatibility' ); + function wppb_acf_and_user_role_select_2_compatibility(){ + $post_type = get_post_type(); + if( !empty( $post_type ) && $post_type == 'wppb-roles-editor' ) + remove_all_actions('acf/input/admin_enqueue_scripts'); + } diff --git a/profile-builder/features/class-list-table.php b/profile-builder/features/class-list-table.php index 45cf319..1de03d3 100644 --- a/profile-builder/features/class-list-table.php +++ b/profile-builder/features/class-list-table.php @@ -1,968 +1,968 @@ - '', - 'singular' => '', - 'ajax' => false, - 'screen' => null, - ) ); - - $this->screen = convert_to_screen( $args['screen'] ); - - add_filter( "manage_{$this->screen->id}_columns", array( $this, 'get_columns' ), 0 ); - - if ( !$args['plural'] ) - $args['plural'] = $this->screen->base; - - $args['plural'] = sanitize_key( $args['plural'] ); - $args['singular'] = sanitize_key( $args['singular'] ); - - $this->_args = $args; - - if ( $args['ajax'] ) { - // wp_enqueue_script( 'list-table' ); - add_action( 'admin_footer', array( $this, '_js_vars' ) ); - } - } - - /** - * Checks the current user's permissions - * @uses wp_die() - * - * @since 3.1.0 - * @access public - * @abstract - */ - function ajax_user_can() { - die( 'function WP_List_Table::ajax_user_can() must be over-ridden in a sub-class.' ); - } - - /** - * Prepares the list of items for displaying. - * @uses WP_List_Table::set_pagination_args() - * - * @since 3.1.0 - * @access public - * @abstract - */ - function prepare_items() { - die( 'function WP_List_Table::prepare_items() must be over-ridden in a sub-class.' ); - } - - /** - * An internal method that sets all the necessary pagination arguments - * - * @param array $args An associative array with information about the pagination - * @access protected - */ - function set_pagination_args( $args ) { - $args = wp_parse_args( $args, array( - 'total_items' => 0, - 'total_pages' => 0, - 'per_page' => 0, - ) ); - - if ( !$args['total_pages'] && $args['per_page'] > 0 ) - $args['total_pages'] = ceil( $args['total_items'] / $args['per_page'] ); - - // redirect if page number is invalid and headers are not already sent - if ( ! headers_sent() && ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX ) && $args['total_pages'] > 0 && $this->get_pagenum() > $args['total_pages'] ) { - wp_safe_redirect( add_query_arg( 'paged', $args['total_pages'] ) ); - exit; - } - - $this->_pagination_args = $args; - } - - /** - * Access the pagination args - * - * @since 3.1.0 - * @access public - * - * @param string $key - * @return array - */ - function get_pagination_arg( $key ) { - if ( 'page' == $key ) - return $this->get_pagenum(); - - if ( isset( $this->_pagination_args[$key] ) ) - return $this->_pagination_args[$key]; - } - - /** - * Whether the table has items to display or not - * - * @since 3.1.0 - * @access public - * - * @return bool - */ - function has_items() { - return !empty( $this->items ); - } - - /** - * Message to be displayed when there are no items - * - * @since 3.1.0 - * @access public - */ - function no_items() { - _e( 'No items found.' ); - } - - /** - * Display the search box. - * - * @since 3.1.0 - * @access public - * - * @param string $text The search button text - * @param string $input_id The search input id - */ - function search_box( $text, $input_id ) { - if ( empty( $_REQUEST['s'] ) && !$this->has_items() ) - return; - - $input_id = $input_id . '-search-input'; - - if ( ! empty( $_REQUEST['orderby'] ) ) - echo ''; - if ( ! empty( $_REQUEST['order'] ) ) - echo ''; - if ( ! empty( $_REQUEST['post_mime_type'] ) ) - echo ''; - if ( ! empty( $_REQUEST['detached'] ) ) - echo ''; -?> - - link ) with the list - * of views available on this table. - * - * @since 3.1.0 - * @access protected - * - * @return array - */ - function get_views() { - return array(); - } - - /** - * Display the list of views available on this table. - * - * @since 3.1.0 - * @access public - */ - function views() { - $views = $this->get_views(); - /** - * Filter the list of available list table views. - * - * The dynamic portion of the hook name, $this->screen->id, refers - * to the ID of the current screen, usually a string. - * - * @since 3.5.0 - * - * @param array $views An array of available list table views. - */ - $views = apply_filters( "views_{$this->screen->id}", $views ); - - if ( empty( $views ) ) - return; - - echo "
              \n"; - foreach ( $views as $class => $view ) { - $views[ $class ] = "\t
            • $view"; - } - echo implode( " |
            • \n", $views ) . "\n"; - echo "
            "; - } - - /** - * Get an associative array ( option_name => option_title ) with the list - * of bulk actions available on this table. - * - * @since 3.1.0 - * @access protected - * - * @return array - */ - function get_bulk_actions() { - return array(); - } - - /** - * Display the bulk actions dropdown. - * - * @since 3.1.0 - * @access public - */ - function bulk_actions() { - if ( is_null( $this->_actions ) ) { - $no_new_actions = $this->_actions = $this->get_bulk_actions(); - /** - * Filter the list table Bulk Actions drop-down. - * - * The dynamic portion of the hook name, $this->screen->id, refers - * to the ID of the current screen, usually a string. - * - * This filter can currently only be used to remove bulk actions. - * - * @since 3.5.0 - * - * @param array $actions An array of the available bulk actions. - */ - $this->_actions = apply_filters( "bulk_actions-{$this->screen->id}", $this->_actions ); - $this->_actions = array_intersect_assoc( $this->_actions, $no_new_actions ); - $two = ''; - } else { - $two = '2'; - } - - if ( empty( $this->_actions ) ) - return; - - echo "\n"; - - submit_button( __( 'Apply' ), 'action', false, false, array( 'id' => "doaction$two" ) ); - echo "\n"; - } - - /** - * Get the current action selected from the bulk actions dropdown. - * - * @since 3.1.0 - * @access public - * - * @return string|bool The action name or False if no action was selected - */ - function current_action() { - if ( isset( $_REQUEST['action'] ) && -1 != $_REQUEST['action'] ) - return sanitize_text_field( $_REQUEST['action'] ); - - if ( isset( $_REQUEST['action2'] ) && -1 != $_REQUEST['action2'] ) - return sanitize_text_field( $_REQUEST['action2'] ); - - return false; - } - - /** - * Generate row actions div - * - * @since 3.1.0 - * @access protected - * - * @param array $actions The list of actions - * @param bool $always_visible Whether the actions should be always visible - * @return string - */ - function row_actions( $actions, $always_visible = false ) { - $action_count = count( $actions ); - $i = 0; - - if ( !$action_count ) - return ''; - - $out = '
            '; - foreach ( $actions as $action => $link ) { - ++$i; - ( $i == $action_count ) ? $sep = '' : $sep = ' | '; - $out .= "$link$sep"; - } - $out .= '
            '; - - return $out; - } - - /** - * Display a monthly dropdown for filtering items - * - * @since 3.1.0 - * @access protected - */ - function months_dropdown( $post_type ) { - global $wpdb, $wp_locale; - - $months = $wpdb->get_results( $wpdb->prepare( " - SELECT DISTINCT YEAR( post_date ) AS year, MONTH( post_date ) AS month - FROM $wpdb->posts - WHERE post_type = %s - ORDER BY post_date DESC - ", $post_type ) ); - - /** - * Filter the 'Months' drop-down results. - * - * @since 3.7.0 - * - * @param object $months The months drop-down query results. - * @param string $post_type The post type. - */ - $months = apply_filters( 'months_dropdown_results', $months, $post_type ); - - $month_count = count( $months ); - - if ( !$month_count || ( 1 == $month_count && 0 == $months[0]->month ) ) - return; - - $m = isset( $_GET['m'] ) ? (int) $_GET['m'] : 0; -?> - - __( 'List View' ), - 'excerpt' => __( 'Excerpt View' ) - ); - -?> - -
            - $title ) { - $class = ( $current_mode == $mode ) ? 'class="current"' : ''; - echo "$title\n"; - } - ?> -
            -'; - - echo "" . number_format_i18n( get_comments_number() ) . ""; - - if ( $pending_comments ) - echo '
            '; - } - - /** - * Get the current page number - * - * @since 3.1.0 - * @access protected - * - * @return int - */ - function get_pagenum() { - $pagenum = isset( $_REQUEST['paged'] ) ? absint( $_REQUEST['paged'] ) : 0; - - if( isset( $this->_pagination_args['total_pages'] ) && $pagenum > $this->_pagination_args['total_pages'] ) - $pagenum = $this->_pagination_args['total_pages']; - - return max( 1, $pagenum ); - } - - /** - * Get number of items to display on a single page - * - * @since 3.1.0 - * @access protected - * - * @return int - */ - function get_items_per_page( $option, $default = 20 ) { - $per_page = (int) get_user_option( $option ); - if ( empty( $per_page ) || $per_page < 1 ) - $per_page = $default; - - /** - * Filter the number of items to be displayed on each page of the list table. - * - * The dynamic hook name, $option, refers to the per page option depending - * on the type of list table in use. Possible values may include: - * 'edit_comments_per_page', 'sites_network_per_page', 'site_themes_network_per_page', - * 'themes_netework_per_page', 'users_network_per_page', 'edit_{$post_type}', etc. - * - * @since 2.9.0 - * - * @param int $per_page Number of items to be displayed. Default 20. - */ - return (int) apply_filters( $option, $per_page ); - } - - /** - * Display the pagination. - * - * @since 3.1.0 - * @access protected - */ - function pagination( $which ) { - if ( empty( $this->_pagination_args ) ) - return; - - extract( $this->_pagination_args, EXTR_SKIP ); - - $output = '' . sprintf( _n( '1 item', '%s items', $total_items ), number_format_i18n( $total_items ) ) . ''; - - $current = $this->get_pagenum(); - - $current_url = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ); - - $current_url = remove_query_arg( array( 'hotkeys_highlight_last', 'hotkeys_highlight_first' ), $current_url ); - - $page_links = array(); - - $disable_first = $disable_last = ''; - if ( $current == 1 ) - $disable_first = ' disabled'; - if ( $current == $total_pages ) - $disable_last = ' disabled'; - - $page_links[] = sprintf( "%s", - 'first-page' . $disable_first, - esc_attr__( 'Go to the first page' ), - esc_url( remove_query_arg( 'paged', $current_url ) ), - '«' - ); - - $page_links[] = sprintf( "%s", - 'prev-page' . $disable_first, - esc_attr__( 'Go to the previous page' ), - esc_url( add_query_arg( 'paged', max( 1, $current-1 ), $current_url ) ), - '‹' - ); - - if ( 'bottom' == $which ) - $html_current_page = $current; - else - $html_current_page = sprintf( "", - esc_attr__( 'Current page' ), - $current, - strlen( $total_pages ) - ); - - $html_total_pages = sprintf( "%s", number_format_i18n( $total_pages ) ); - $page_links[] = '' . sprintf( _x( '%1$s of %2$s', 'paging' ), $html_current_page, $html_total_pages ) . ''; - - $page_links[] = sprintf( "%s", - 'next-page' . $disable_last, - esc_attr__( 'Go to the next page' ), - esc_url( add_query_arg( 'paged', min( $total_pages, $current+1 ), $current_url ) ), - '›' - ); - - $page_links[] = sprintf( "%s", - 'last-page' . $disable_last, - esc_attr__( 'Go to the last page' ), - esc_url( add_query_arg( 'paged', $total_pages, $current_url ) ), - '»' - ); - - $pagination_links_class = 'pagination-links'; - if ( ! empty( $infinite_scroll ) ) - $pagination_links_class = ' hide-if-js'; - $output .= "\n" . join( "\n", $page_links ) . ''; - - if ( $total_pages ) - $page_class = $total_pages < 2 ? ' one-page' : ''; - else - $page_class = ' no-pages'; - - $this->_pagination = "
            $output
            "; - - echo $this->_pagination; - } - - /** - * Get a list of columns. The format is: - * 'internal-name' => 'Title' - * - * @since 3.1.0 - * @access protected - * @abstract - * - * @return array - */ - function get_columns() { - die( 'function WP_List_Table::get_columns() must be over-ridden in a sub-class.' ); - } - - /** - * Get a list of sortable columns. The format is: - * 'internal-name' => 'orderby' - * or - * 'internal-name' => array( 'orderby', true ) - * - * The second format will make the initial sorting order be descending - * - * @since 3.1.0 - * @access protected - * - * @return array - */ - function get_sortable_columns() { - return array(); - } - - /** - * Get a list of all, hidden and sortable columns, with filter applied - * - * @since 3.1.0 - * @access protected - * - * @return array - */ - function get_column_info() { - if ( isset( $this->_column_headers ) ) - return $this->_column_headers; - - $columns = get_column_headers( $this->screen ); - $hidden = get_hidden_columns( $this->screen ); - - $sortable_columns = $this->get_sortable_columns(); - /** - * Filter the list table sortable columns for a specific screen. - * - * The dynamic portion of the hook name, $this->screen->id, refers - * to the ID of the current screen, usually a string. - * - * @since 3.5.0 - * - * @param array $sortable_columns An array of sortable columns. - */ - $_sortable = apply_filters( "manage_{$this->screen->id}_sortable_columns", $sortable_columns ); - - $sortable = array(); - foreach ( $_sortable as $id => $data ) { - if ( empty( $data ) ) - continue; - - $data = (array) $data; - if ( !isset( $data[1] ) ) - $data[1] = false; - - $sortable[$id] = $data; - } - - $this->_column_headers = array( $columns, $hidden, $sortable ); - - return $this->_column_headers; - } - - /** - * Return number of visible columns - * - * @since 3.1.0 - * @access public - * - * @return int - */ - function get_column_count() { - list ( $columns, $hidden ) = $this->get_column_info(); - $hidden = array_intersect( array_keys( $columns ), array_filter( $hidden ) ); - return count( $columns ) - count( $hidden ); - } - - /** - * Print column headers, accounting for hidden and sortable columns. - * - * @since 3.1.0 - * @access protected - * - * @param bool $with_id Whether to set the id attribute or not - */ - function print_column_headers( $with_id = true ) { - list( $columns, $hidden, $sortable ) = $this->get_column_info(); - - $current_url = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ); - $current_url = remove_query_arg( 'paged', $current_url ); - - if ( isset( $_GET['orderby'] ) ) - $current_orderby = $_GET['orderby']; - else - $current_orderby = ''; - - if ( isset( $_GET['order'] ) && 'desc' == $_GET['order'] ) - $current_order = 'desc'; - else - $current_order = 'asc'; - - if ( ! empty( $columns['cb'] ) ) { - static $cb_counter = 1; - $columns['cb'] = '' - . ''; - $cb_counter++; - } - - foreach ( $columns as $column_key => $column_display_name ) { - $class = array( 'manage-column', "column-$column_key" ); - - $style = ''; - if ( in_array( $column_key, $hidden ) ) - $style = 'display:none;'; - - if ( 'cb' == $column_key ) { - $class[] = 'check-column'; - $style .= ' padding: 10px 0 10px 3px;'; - } elseif ( in_array( $column_key, array( 'posts', 'comments', 'links' ) ) ) - $class[] = 'num'; - - $style = ' style="' . $style . '"'; - - if ( isset( $sortable[$column_key] ) ) { - list( $orderby, $desc_first ) = $sortable[$column_key]; - - if ( $current_orderby == $orderby ) { - $order = 'asc' == $current_order ? 'desc' : 'asc'; - $class[] = 'sorted'; - $class[] = $current_order; - } else { - $order = $desc_first ? 'desc' : 'asc'; - $class[] = 'sortable'; - $class[] = $desc_first ? 'asc' : 'desc'; - } - - $column_display_name = '' . $column_display_name . ''; - } - - $id = $with_id ? "id='$column_key'" : ''; - - if ( !empty( $class ) ) - $class = "class='" . join( ' ', $class ) . "'"; - - echo "$column_display_name"; - } - } - - /** - * Display the table - * - * @since 3.1.0 - * @access public - */ - function display() { - extract( $this->_args ); - - $this->display_tablenav( 'top' ); - -?> - - - - print_column_headers(); ?> - - - - - - print_column_headers( false ); ?> - - - - > - display_rows_or_placeholder(); ?> - -
            -display_tablenav( 'bottom' ); - } - - /** - * Get a list of CSS classes for the tag - * - * @since 3.1.0 - * @access protected - * - * @return array - */ - function get_table_classes() { - return array( 'widefat', 'fixed', $this->_args['plural'] ); - } - - /** - * Generate the table navigation above or below the table - * - * @since 3.1.0 - * @access protected - */ - function display_tablenav( $which ) { - if ( 'top' == $which ) - wp_nonce_field( 'bulk-' . $this->_args['plural'] ); -?> -
            - -
            - bulk_actions(); ?> -
            -extra_tablenav( $which ); - $this->pagination( $which ); -?> - -
            -
            - part of the table - * - * @since 3.1.0 - * @access protected - */ - function display_rows_or_placeholder() { - if ( $this->has_items() ) { - $this->display_rows(); - } else { - list( $columns, $hidden ) = $this->get_column_info(); - echo ''; - } - } - - /** - * Generate the table rows - * - * @since 3.1.0 - * @access protected - */ - function display_rows() { - foreach ( $this->items as $item ) - $this->single_row( $item ); - } - - /** - * Generates content for a single row of the table - * - * @since 3.1.0 - * @access protected - * - * @param object $item The current item - */ - function single_row( $item ) { - static $row_class = ''; - $row_class = ( $row_class == '' ? ' class="alternate"' : '' ); - - echo ''; - $this->single_row_columns( $item ); - echo ''; - } - - /** - * Generates the columns for a single row of the table - * - * @since 3.1.0 - * @access protected - * - * @param object $item The current item - */ - function single_row_columns( $item ) { - list( $columns, $hidden ) = $this->get_column_info(); - - foreach ( $columns as $column_name => $column_display_name ) { - $class = "class='$column_name column-$column_name'"; - - $style = ''; - if ( in_array( $column_name, $hidden ) ) - $style = ' style="display:none;"'; - - $attributes = "$class$style"; - - if ( 'cb' == $column_name ) { - echo ''; - } - elseif ( method_exists( $this, 'column_' . $column_name ) ) { - echo ""; - } - else { - echo ""; - } - } - } - - /** - * Handle an incoming ajax request (called from admin-ajax.php) - * - * @since 3.1.0 - * @access public - */ - function ajax_response() { - $this->prepare_items(); - - extract( $this->_args ); - extract( $this->_pagination_args, EXTR_SKIP ); - - ob_start(); - if ( ! empty( $_REQUEST['no_placeholder'] ) ) - $this->display_rows(); - else - $this->display_rows_or_placeholder(); - - $rows = ob_get_clean(); - - $response = array( 'rows' => $rows ); - - if ( isset( $total_items ) ) - $response['total_items_i18n'] = sprintf( _n( '1 item', '%s items', $total_items ), number_format_i18n( $total_items ) ); - - if ( isset( $total_pages ) ) { - $response['total_pages'] = $total_pages; - $response['total_pages_i18n'] = number_format_i18n( $total_pages ); - } - - die( json_encode( $response ) ); - } - - /** - * Send required variables to JavaScript land - * - * @access private - */ - function _js_vars() { - $args = array( - 'class' => get_class( $this ), - 'screen' => array( - 'id' => $this->screen->id, - 'base' => $this->screen->base, - ) - ); - - printf( "\n", json_encode( $args ) ); - } + '', + 'singular' => '', + 'ajax' => false, + 'screen' => null, + ) ); + + $this->screen = convert_to_screen( $args['screen'] ); + + add_filter( "manage_{$this->screen->id}_columns", array( $this, 'get_columns' ), 0 ); + + if ( !$args['plural'] ) + $args['plural'] = $this->screen->base; + + $args['plural'] = sanitize_key( $args['plural'] ); + $args['singular'] = sanitize_key( $args['singular'] ); + + $this->_args = $args; + + if ( $args['ajax'] ) { + // wp_enqueue_script( 'list-table' ); + add_action( 'admin_footer', array( $this, '_js_vars' ) ); + } + } + + /** + * Checks the current user's permissions + * @uses wp_die() + * + * @since 3.1.0 + * @access public + * @abstract + */ + function ajax_user_can() { + die( 'function WP_List_Table::ajax_user_can() must be over-ridden in a sub-class.' ); + } + + /** + * Prepares the list of items for displaying. + * @uses WP_List_Table::set_pagination_args() + * + * @since 3.1.0 + * @access public + * @abstract + */ + function prepare_items() { + die( 'function WP_List_Table::prepare_items() must be over-ridden in a sub-class.' ); + } + + /** + * An internal method that sets all the necessary pagination arguments + * + * @param array $args An associative array with information about the pagination + * @access protected + */ + function set_pagination_args( $args ) { + $args = wp_parse_args( $args, array( + 'total_items' => 0, + 'total_pages' => 0, + 'per_page' => 0, + ) ); + + if ( !$args['total_pages'] && $args['per_page'] > 0 ) + $args['total_pages'] = ceil( $args['total_items'] / $args['per_page'] ); + + // redirect if page number is invalid and headers are not already sent + if ( ! headers_sent() && ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX ) && $args['total_pages'] > 0 && $this->get_pagenum() > $args['total_pages'] ) { + wp_safe_redirect( add_query_arg( 'paged', $args['total_pages'] ) ); + exit; + } + + $this->_pagination_args = $args; + } + + /** + * Access the pagination args + * + * @since 3.1.0 + * @access public + * + * @param string $key + * @return array + */ + function get_pagination_arg( $key ) { + if ( 'page' == $key ) + return $this->get_pagenum(); + + if ( isset( $this->_pagination_args[$key] ) ) + return $this->_pagination_args[$key]; + } + + /** + * Whether the table has items to display or not + * + * @since 3.1.0 + * @access public + * + * @return bool + */ + function has_items() { + return !empty( $this->items ); + } + + /** + * Message to be displayed when there are no items + * + * @since 3.1.0 + * @access public + */ + function no_items() { + _e( 'No items found.' ); + } + + /** + * Display the search box. + * + * @since 3.1.0 + * @access public + * + * @param string $text The search button text + * @param string $input_id The search input id + */ + function search_box( $text, $input_id ) { + if ( empty( $_REQUEST['s'] ) && !$this->has_items() ) + return; + + $input_id = $input_id . '-search-input'; + + if ( ! empty( $_REQUEST['orderby'] ) ) + echo ''; + if ( ! empty( $_REQUEST['order'] ) ) + echo ''; + if ( ! empty( $_REQUEST['post_mime_type'] ) ) + echo ''; + if ( ! empty( $_REQUEST['detached'] ) ) + echo ''; +?> + + link ) with the list + * of views available on this table. + * + * @since 3.1.0 + * @access protected + * + * @return array + */ + function get_views() { + return array(); + } + + /** + * Display the list of views available on this table. + * + * @since 3.1.0 + * @access public + */ + function views() { + $views = $this->get_views(); + /** + * Filter the list of available list table views. + * + * The dynamic portion of the hook name, $this->screen->id, refers + * to the ID of the current screen, usually a string. + * + * @since 3.5.0 + * + * @param array $views An array of available list table views. + */ + $views = apply_filters( "views_{$this->screen->id}", $views ); + + if ( empty( $views ) ) + return; + + echo "
              \n"; + foreach ( $views as $class => $view ) { + $views[ $class ] = "\t
            • $view"; + } + echo implode( " |
            • \n", $views ) . "\n"; + echo "
            "; + } + + /** + * Get an associative array ( option_name => option_title ) with the list + * of bulk actions available on this table. + * + * @since 3.1.0 + * @access protected + * + * @return array + */ + function get_bulk_actions() { + return array(); + } + + /** + * Display the bulk actions dropdown. + * + * @since 3.1.0 + * @access public + */ + function bulk_actions() { + if ( is_null( $this->_actions ) ) { + $no_new_actions = $this->_actions = $this->get_bulk_actions(); + /** + * Filter the list table Bulk Actions drop-down. + * + * The dynamic portion of the hook name, $this->screen->id, refers + * to the ID of the current screen, usually a string. + * + * This filter can currently only be used to remove bulk actions. + * + * @since 3.5.0 + * + * @param array $actions An array of the available bulk actions. + */ + $this->_actions = apply_filters( "bulk_actions-{$this->screen->id}", $this->_actions ); + $this->_actions = array_intersect_assoc( $this->_actions, $no_new_actions ); + $two = ''; + } else { + $two = '2'; + } + + if ( empty( $this->_actions ) ) + return; + + echo "\n"; + + submit_button( __( 'Apply' ), 'action', false, false, array( 'id' => "doaction$two" ) ); + echo "\n"; + } + + /** + * Get the current action selected from the bulk actions dropdown. + * + * @since 3.1.0 + * @access public + * + * @return string|bool The action name or False if no action was selected + */ + function current_action() { + if ( isset( $_REQUEST['action'] ) && -1 != $_REQUEST['action'] ) + return sanitize_text_field( $_REQUEST['action'] ); + + if ( isset( $_REQUEST['action2'] ) && -1 != $_REQUEST['action2'] ) + return sanitize_text_field( $_REQUEST['action2'] ); + + return false; + } + + /** + * Generate row actions div + * + * @since 3.1.0 + * @access protected + * + * @param array $actions The list of actions + * @param bool $always_visible Whether the actions should be always visible + * @return string + */ + function row_actions( $actions, $always_visible = false ) { + $action_count = count( $actions ); + $i = 0; + + if ( !$action_count ) + return ''; + + $out = '
            '; + foreach ( $actions as $action => $link ) { + ++$i; + ( $i == $action_count ) ? $sep = '' : $sep = ' | '; + $out .= "$link$sep"; + } + $out .= '
            '; + + return $out; + } + + /** + * Display a monthly dropdown for filtering items + * + * @since 3.1.0 + * @access protected + */ + function months_dropdown( $post_type ) { + global $wpdb, $wp_locale; + + $months = $wpdb->get_results( $wpdb->prepare( " + SELECT DISTINCT YEAR( post_date ) AS year, MONTH( post_date ) AS month + FROM $wpdb->posts + WHERE post_type = %s + ORDER BY post_date DESC + ", $post_type ) ); + + /** + * Filter the 'Months' drop-down results. + * + * @since 3.7.0 + * + * @param object $months The months drop-down query results. + * @param string $post_type The post type. + */ + $months = apply_filters( 'months_dropdown_results', $months, $post_type ); + + $month_count = count( $months ); + + if ( !$month_count || ( 1 == $month_count && 0 == $months[0]->month ) ) + return; + + $m = isset( $_GET['m'] ) ? (int) $_GET['m'] : 0; +?> + + __( 'List View' ), + 'excerpt' => __( 'Excerpt View' ) + ); + +?> + +
            + $title ) { + $class = ( $current_mode == $mode ) ? 'class="current"' : ''; + echo "$title\n"; + } + ?> +
            +'; + + echo "" . number_format_i18n( get_comments_number() ) . ""; + + if ( $pending_comments ) + echo ''; + } + + /** + * Get the current page number + * + * @since 3.1.0 + * @access protected + * + * @return int + */ + function get_pagenum() { + $pagenum = isset( $_REQUEST['paged'] ) ? absint( $_REQUEST['paged'] ) : 0; + + if( isset( $this->_pagination_args['total_pages'] ) && $pagenum > $this->_pagination_args['total_pages'] ) + $pagenum = $this->_pagination_args['total_pages']; + + return max( 1, $pagenum ); + } + + /** + * Get number of items to display on a single page + * + * @since 3.1.0 + * @access protected + * + * @return int + */ + function get_items_per_page( $option, $default = 20 ) { + $per_page = (int) get_user_option( $option ); + if ( empty( $per_page ) || $per_page < 1 ) + $per_page = $default; + + /** + * Filter the number of items to be displayed on each page of the list table. + * + * The dynamic hook name, $option, refers to the per page option depending + * on the type of list table in use. Possible values may include: + * 'edit_comments_per_page', 'sites_network_per_page', 'site_themes_network_per_page', + * 'themes_netework_per_page', 'users_network_per_page', 'edit_{$post_type}', etc. + * + * @since 2.9.0 + * + * @param int $per_page Number of items to be displayed. Default 20. + */ + return (int) apply_filters( $option, $per_page ); + } + + /** + * Display the pagination. + * + * @since 3.1.0 + * @access protected + */ + function pagination( $which ) { + if ( empty( $this->_pagination_args ) ) + return; + + extract( $this->_pagination_args, EXTR_SKIP ); + + $output = '' . sprintf( _n( '1 item', '%s items', $total_items ), number_format_i18n( $total_items ) ) . ''; + + $current = $this->get_pagenum(); + + $current_url = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ); + + $current_url = remove_query_arg( array( 'hotkeys_highlight_last', 'hotkeys_highlight_first' ), $current_url ); + + $page_links = array(); + + $disable_first = $disable_last = ''; + if ( $current == 1 ) + $disable_first = ' disabled'; + if ( $current == $total_pages ) + $disable_last = ' disabled'; + + $page_links[] = sprintf( "%s", + 'first-page' . $disable_first, + esc_attr__( 'Go to the first page' ), + esc_url( remove_query_arg( 'paged', $current_url ) ), + '«' + ); + + $page_links[] = sprintf( "%s", + 'prev-page' . $disable_first, + esc_attr__( 'Go to the previous page' ), + esc_url( add_query_arg( 'paged', max( 1, $current-1 ), $current_url ) ), + '‹' + ); + + if ( 'bottom' == $which ) + $html_current_page = $current; + else + $html_current_page = sprintf( "", + esc_attr__( 'Current page' ), + $current, + strlen( $total_pages ) + ); + + $html_total_pages = sprintf( "%s", number_format_i18n( $total_pages ) ); + $page_links[] = '' . sprintf( _x( '%1$s of %2$s', 'paging' ), $html_current_page, $html_total_pages ) . ''; + + $page_links[] = sprintf( "%s", + 'next-page' . $disable_last, + esc_attr__( 'Go to the next page' ), + esc_url( add_query_arg( 'paged', min( $total_pages, $current+1 ), $current_url ) ), + '›' + ); + + $page_links[] = sprintf( "%s", + 'last-page' . $disable_last, + esc_attr__( 'Go to the last page' ), + esc_url( add_query_arg( 'paged', $total_pages, $current_url ) ), + '»' + ); + + $pagination_links_class = 'pagination-links'; + if ( ! empty( $infinite_scroll ) ) + $pagination_links_class = ' hide-if-js'; + $output .= "\n" . join( "\n", $page_links ) . ''; + + if ( $total_pages ) + $page_class = $total_pages < 2 ? ' one-page' : ''; + else + $page_class = ' no-pages'; + + $this->_pagination = "
            $output
            "; + + echo $this->_pagination; + } + + /** + * Get a list of columns. The format is: + * 'internal-name' => 'Title' + * + * @since 3.1.0 + * @access protected + * @abstract + * + * @return array + */ + function get_columns() { + die( 'function WP_List_Table::get_columns() must be over-ridden in a sub-class.' ); + } + + /** + * Get a list of sortable columns. The format is: + * 'internal-name' => 'orderby' + * or + * 'internal-name' => array( 'orderby', true ) + * + * The second format will make the initial sorting order be descending + * + * @since 3.1.0 + * @access protected + * + * @return array + */ + function get_sortable_columns() { + return array(); + } + + /** + * Get a list of all, hidden and sortable columns, with filter applied + * + * @since 3.1.0 + * @access protected + * + * @return array + */ + function get_column_info() { + if ( isset( $this->_column_headers ) ) + return $this->_column_headers; + + $columns = get_column_headers( $this->screen ); + $hidden = get_hidden_columns( $this->screen ); + + $sortable_columns = $this->get_sortable_columns(); + /** + * Filter the list table sortable columns for a specific screen. + * + * The dynamic portion of the hook name, $this->screen->id, refers + * to the ID of the current screen, usually a string. + * + * @since 3.5.0 + * + * @param array $sortable_columns An array of sortable columns. + */ + $_sortable = apply_filters( "manage_{$this->screen->id}_sortable_columns", $sortable_columns ); + + $sortable = array(); + foreach ( $_sortable as $id => $data ) { + if ( empty( $data ) ) + continue; + + $data = (array) $data; + if ( !isset( $data[1] ) ) + $data[1] = false; + + $sortable[$id] = $data; + } + + $this->_column_headers = array( $columns, $hidden, $sortable ); + + return $this->_column_headers; + } + + /** + * Return number of visible columns + * + * @since 3.1.0 + * @access public + * + * @return int + */ + function get_column_count() { + list ( $columns, $hidden ) = $this->get_column_info(); + $hidden = array_intersect( array_keys( $columns ), array_filter( $hidden ) ); + return count( $columns ) - count( $hidden ); + } + + /** + * Print column headers, accounting for hidden and sortable columns. + * + * @since 3.1.0 + * @access protected + * + * @param bool $with_id Whether to set the id attribute or not + */ + function print_column_headers( $with_id = true ) { + list( $columns, $hidden, $sortable ) = $this->get_column_info(); + + $current_url = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ); + $current_url = remove_query_arg( 'paged', $current_url ); + + if ( isset( $_GET['orderby'] ) ) + $current_orderby = $_GET['orderby']; + else + $current_orderby = ''; + + if ( isset( $_GET['order'] ) && 'desc' == $_GET['order'] ) + $current_order = 'desc'; + else + $current_order = 'asc'; + + if ( ! empty( $columns['cb'] ) ) { + static $cb_counter = 1; + $columns['cb'] = '' + . ''; + $cb_counter++; + } + + foreach ( $columns as $column_key => $column_display_name ) { + $class = array( 'manage-column', "column-$column_key" ); + + $style = ''; + if ( in_array( $column_key, $hidden ) ) + $style = 'display:none;'; + + if ( 'cb' == $column_key ) { + $class[] = 'check-column'; + $style .= ' padding: 10px 0 10px 3px;'; + } elseif ( in_array( $column_key, array( 'posts', 'comments', 'links' ) ) ) + $class[] = 'num'; + + $style = ' style="' . $style . '"'; + + if ( isset( $sortable[$column_key] ) ) { + list( $orderby, $desc_first ) = $sortable[$column_key]; + + if ( $current_orderby == $orderby ) { + $order = 'asc' == $current_order ? 'desc' : 'asc'; + $class[] = 'sorted'; + $class[] = $current_order; + } else { + $order = $desc_first ? 'desc' : 'asc'; + $class[] = 'sortable'; + $class[] = $desc_first ? 'asc' : 'desc'; + } + + $column_display_name = '' . $column_display_name . ''; + } + + $id = $with_id ? "id='$column_key'" : ''; + + if ( !empty( $class ) ) + $class = "class='" . join( ' ', $class ) . "'"; + + echo ""; + } + } + + /** + * Display the table + * + * @since 3.1.0 + * @access public + */ + function display() { + extract( $this->_args ); + + $this->display_tablenav( 'top' ); + +?> +
            '; - $this->no_items(); - echo '
            '; - echo $this->column_cb( $item ); - echo '"; - echo call_user_func( array( $this, 'column_' . $column_name ), $item ); - echo ""; - echo $this->column_default( $item, $column_name ); - echo "$column_display_name
            + + + print_column_headers(); ?> + + + + + + print_column_headers( false ); ?> + + + + > + display_rows_or_placeholder(); ?> + +
            +display_tablenav( 'bottom' ); + } + + /** + * Get a list of CSS classes for the tag + * + * @since 3.1.0 + * @access protected + * + * @return array + */ + function get_table_classes() { + return array( 'widefat', 'fixed', $this->_args['plural'] ); + } + + /** + * Generate the table navigation above or below the table + * + * @since 3.1.0 + * @access protected + */ + function display_tablenav( $which ) { + if ( 'top' == $which ) + wp_nonce_field( 'bulk-' . $this->_args['plural'] ); +?> +
            + +
            + bulk_actions(); ?> +
            +extra_tablenav( $which ); + $this->pagination( $which ); +?> + +
            +
            + part of the table + * + * @since 3.1.0 + * @access protected + */ + function display_rows_or_placeholder() { + if ( $this->has_items() ) { + $this->display_rows(); + } else { + list( $columns, $hidden ) = $this->get_column_info(); + echo ''; + } + } + + /** + * Generate the table rows + * + * @since 3.1.0 + * @access protected + */ + function display_rows() { + foreach ( $this->items as $item ) + $this->single_row( $item ); + } + + /** + * Generates content for a single row of the table + * + * @since 3.1.0 + * @access protected + * + * @param object $item The current item + */ + function single_row( $item ) { + static $row_class = ''; + $row_class = ( $row_class == '' ? ' class="alternate"' : '' ); + + echo ''; + $this->single_row_columns( $item ); + echo ''; + } + + /** + * Generates the columns for a single row of the table + * + * @since 3.1.0 + * @access protected + * + * @param object $item The current item + */ + function single_row_columns( $item ) { + list( $columns, $hidden ) = $this->get_column_info(); + + foreach ( $columns as $column_name => $column_display_name ) { + $class = "class='$column_name column-$column_name'"; + + $style = ''; + if ( in_array( $column_name, $hidden ) ) + $style = ' style="display:none;"'; + + $attributes = "$class$style"; + + if ( 'cb' == $column_name ) { + echo ''; + } + elseif ( method_exists( $this, 'column_' . $column_name ) ) { + echo ""; + } + else { + echo ""; + } + } + } + + /** + * Handle an incoming ajax request (called from admin-ajax.php) + * + * @since 3.1.0 + * @access public + */ + function ajax_response() { + $this->prepare_items(); + + extract( $this->_args ); + extract( $this->_pagination_args, EXTR_SKIP ); + + ob_start(); + if ( ! empty( $_REQUEST['no_placeholder'] ) ) + $this->display_rows(); + else + $this->display_rows_or_placeholder(); + + $rows = ob_get_clean(); + + $response = array( 'rows' => $rows ); + + if ( isset( $total_items ) ) + $response['total_items_i18n'] = sprintf( _n( '1 item', '%s items', $total_items ), number_format_i18n( $total_items ) ); + + if ( isset( $total_pages ) ) { + $response['total_pages'] = $total_pages; + $response['total_pages_i18n'] = number_format_i18n( $total_pages ); + } + + die( json_encode( $response ) ); + } + + /** + * Send required variables to JavaScript land + * + * @access private + */ + function _js_vars() { + $args = array( + 'class' => get_class( $this ), + 'screen' => array( + 'id' => $this->screen->id, + 'base' => $this->screen->base, + ) + ); + + printf( "\n", json_encode( $args ) ); + } } \ No newline at end of file diff --git a/profile-builder/features/email-confirmation/class-email-confirmation.php b/profile-builder/features/email-confirmation/class-email-confirmation.php index 9ff47e5..5b7eca0 100644 --- a/profile-builder/features/email-confirmation/class-email-confirmation.php +++ b/profile-builder/features/email-confirmation/class-email-confirmation.php @@ -1,468 +1,468 @@ -prepare_items() to handle any data manipulation, then - * finally call $yourInstance->display() to render the table to the page. - * - */ -class wpp_list_unfonfirmed_email_table extends PB_WP_List_Table { - - /** ************************************************************************ - * REQUIRED. Set up a constructor that references the parent constructor. We - * use the parent reference to set some default configs. - ***************************************************************************/ - function __construct(){ - global $status, $page; - global $wpdb; - - //Set parent defaults - parent::__construct( array( - 'singular' => 'user', //singular name of the listed records - 'plural' => 'users', //plural name of the listed records - 'ajax' => false //does this table support ajax? - ) ); - - } - - - /** ************************************************************************ - * Recommended. This method is called when the parent class can't find a method - * specifically build for a given column. Generally, it's recommended to include - * one method for each column you want to render, keeping your package class - * neat and organized. For example, if the class needs to process a column - * named 'username', it would first see if a method named $this->column_title() - * exists - if it does, that method will be used. If it doesn't, this one will - * be used. Generally, you should try to use custom column methods as much as - * possible. - * - * Since we have defined a column_title() method later on, this method doesn't - * need to concern itself with any column with a name of 'username'. Instead, it - * needs to handle everything else. - * - * For more detailed insight into how columns are handled, take a look at - * PB_WP_List_Table::single_row_columns() - * - * @param array $item A singular item (one full row's worth of data) - * @param array $column_name The name/slug of the column to be processed - * @return string Text or HTML to be placed inside the column '; -} -add_filter('wck_metabox_content_header_wppb_ul_page_settings', 'wppb_change_metabox_content_header', 1); -add_filter('wck_metabox_content_header_wppb_rf_page_settings', 'wppb_change_metabox_content_header', 1); -add_filter('wck_metabox_content_header_wppb_epf_page_settings', 'wppb_change_metabox_content_header', 1); - - -/* Add a notice if people are not able to register via Profile Builder; Membership -> "Anyone can register" checkbox is not checked under WordPress admin UI -> Settings -> General tab */ -/* -if ( (get_option('users_can_register') == false) && (!class_exists('PMS_Add_General_Notices')) ) { - if( is_multisite() ) { - new WPPB_Add_General_Notices('wppb_anyone_can_register', - sprintf(__('To allow users to register for your website via Profile Builder, you first must enable user registration. Go to %1$sNetwork Settings%2$s, and under Registration Settings make sure to check “User accounts may be registered”. %3$sDismiss%4$s', 'profile-builder'), "", "", "", ""), - 'update-nag'); - }else{ - new WPPB_Add_General_Notices('wppb_anyone_can_register', - sprintf(__('To allow users to register for your website via Profile Builder, you first must enable user registration. Go to %1$sSettings -> General%2$s tab, and under Membership make sure to check “Anyone can register”. %3$sDismiss%4$s', 'profile-builder'), "", "", "", ""), - 'update-nag'); - } -} -*/ -/*Filter default WordPress notices ("Post published. Post updated."), add post type name for User Listing, Registration Forms and Edit Profile Forms*/ -function wppb_change_default_post_updated_messages($messages){ - global $post; - $post_type = get_post_type($post->ID); - $object = get_post_type_object($post_type); - - if ( ($post_type == 'wppb-rf-cpt')||($post_type == 'wppb-epf-cpt')||($post_type == 'wppb-ul-cpt') ){ - $messages['post'][1] = $object->labels->name . ' updated.'; - $messages['post'][6] = $object->labels->name . ' published.'; - } - return $messages; -} -add_filter('post_updated_messages','wppb_change_default_post_updated_messages', 2); - - -/* for meta-names with spaces in them PHP converts the space to underline in the $_POST */ -function wppb_handle_meta_name( $meta_name ){ - $meta_name = str_replace( ' ', '_', $meta_name ); - $meta_name = str_replace( '.', '_', $meta_name ); - return $meta_name; -} - - -// change User Registered date and time according to timezone selected in WordPress settings -function wppb_get_date_by_timezone() { - $wppb_wp_timezone = get_option( 'timezone_string' ); - - if( ! empty( $wppb_wp_timezone ) ) { - date_default_timezone_set( $wppb_wp_timezone ); - $wppb_get_date = date( "Y-m-d G:i:s" ); - } else { - $wppb_wp_gmt_offset = get_option( 'gmt_offset' ); - $wppb_gmt_offset = $wppb_wp_gmt_offset * 60 * 60; - $wppb_get_date = gmdate( "Y-m-d G:i:s", time() + $wppb_gmt_offset ); - } - - return $wppb_get_date; -} - -/** - * Add HTML tag 'required' to fields - * - * Add HTML tag 'required' for each field if the field is required. For browsers that don't support this HTML tag, we will still have the fallback. - * Field type 'Checkbox' is explicitly excluded because there is no HTML support to check if at least one option is selected. - * Other fields excluded are Avatar, Upload, Heading, ReCaptcha, WYSIWYG, Map. - * - * @since - * - * @param string $extra_attributes Extra attributes attached to the field HTML tag. - * @param array $field Field description. - * @return string $extra_attributes - */ -function wppb_add_html_tag_required_to_fields( $extra_attributes, $field, $form_location ) { - if ( $field['field'] != "Checkbox" && isset( $field['required'] ) && $field['required'] == 'Yes' ){ - if( !( ( $field['field'] == "Default - Password" || $field['field'] == "Default - Repeat Password" ) && $form_location == 'edit_profile' ) ) - $extra_attributes .= ' required '; - } - return $extra_attributes; -} -add_filter( 'wppb_extra_attribute', 'wppb_add_html_tag_required_to_fields', 10, 3 ); - -/** - * Add HTML tag 'required' to WooCommerce fields - * - * Add HTML tag 'required' for each WooCommerce field if the field is required. For browsers that don't support this HTML tag, we will still have the fallback. - * Does not work on 'State / County' field, if it becomes required later depending on the Country Value - * - * @since - * - * @param string $extra_attributes Extra attributes attached to the field HTML tag. - * @param array $field Field description. - * @return string $extra_attributes - */ -function wppb_add_html_tag_required_to_woo_fields( $extra_attributes, $field ) { - if ( isset( $field['required'] ) && $field['required'] == 'Yes' ){ - $extra_attributes .= ' required '; - } - return $extra_attributes; -} -add_filter( 'wppb_woo_extra_attribute', 'wppb_add_html_tag_required_to_woo_fields', 10, 2 ); - - -/** - * Add jQuery script to remove required attribute for hidden fields - * - * If a field is hidden dynamically via conditional fields or WooSync 'Ship to a different address' checkbox, then the required field needs to be removed. - * If a field is made visible again, add the required field back again. - * - * @since - * - * @param string $extra_attributes Extra attributes attached to the field HTML tag. - * @param array $field Field description. - * @return string $extra_attributes - */ -function wppb_manage_required_attribute() { - global $wppb_shortcode_on_front; - if ($wppb_shortcode_on_front) { - ?> - - errors['blogname']) && empty($blog_details['errors']->errors['blog_title'])) { - $blog_path = $blog_details['domain'] . $blog_details['path']; - $message .= __( '

            Also, you will be able to visit your site at ', 'profile-builder' ) . '' . $blog_path . '.'; - } - } - return $message; -} -add_filter( 'wppb_signup_user_notification_email_content', 'wpbb_specify_blog_details_on_signup_email', 5, 8 ); - -function wpbb_specify_blog_details_on_registration_email( $user_message_content, $email, $password, $user_message_subject, $context ){ - - if ( is_multisite() ) { - $user = get_user_by( 'email', $email ); - $blog_path = wppb_get_blog_url_of_user_id( $user->ID ); - if ( ! empty ( $blog_path ) ) { - $user_message_content .= __( '

            You can visit your site at ', 'profile-builder' ) . '' . $blog_path . '.'; - } - } - return $user_message_content; - -} -add_filter( 'wppb_register_user_email_message_without_admin_approval', 'wpbb_specify_blog_details_on_registration_email', 5, 5 ); -add_filter( 'wppb_register_user_email_message_with_admin_approval', 'wpbb_specify_blog_details_on_registration_email', 5, 5 ); - - -function wppb_get_blog_url_of_user_id( $user_id, $ignore_privacy = true ){ - $blog_id = get_user_meta( $user_id, 'primary_blog', true ); - if ( is_multisite() && !empty( $blog_id ) ){ - $blog_details = get_blog_details( $blog_id ); - if ( $ignore_privacy || $blog_details->public ) { - return $blog_details->domain . $blog_details->path; - } - } - return ''; -} - -function wppb_can_users_signup_blog(){ - if ( ! is_multisite() ) - return false; - global $wpdb; - $current_site = get_current_site(); - $sitemeta_options_query = $wpdb->prepare( "SELECT meta_value FROM {$wpdb->sitemeta} WHERE meta_key = 'registration' AND site_id = %d", $current_site->id ); - $network_options_meta = $wpdb->get_results( $sitemeta_options_query ); - - if ( $network_options_meta[0]->meta_value == 'all' ){ - return true; - } - return false; -} - -/** - * Function that handle redirect URL - * - * @param string $redirect_priority - it can be normal or top priority - * @param string $redirect_type - type of the redirect - * @param null|string $redirect_url - redirect URL if already set - * @param null|string|object $user - username, user email or user data - * @param null|string $user_role - user role - * - * @return null|string $redirect_url - */ -function wppb_get_redirect_url( $redirect_priority = 'normal', $redirect_type, $redirect_url = NULL, $user = NULL, $user_role = NULL ) { - if( PROFILE_BUILDER == 'Profile Builder Pro' ) { - $wppb_module_settings = get_option( 'wppb_module_settings' ); - - if( isset( $wppb_module_settings['wppb_customRedirect'] ) && $wppb_module_settings['wppb_customRedirect'] == 'show' && $redirect_priority != 'top' && function_exists( 'wppb_custom_redirect_url' ) ) { - $redirect_url = wppb_custom_redirect_url( $redirect_type, $redirect_url, $user, $user_role ); - } - } - - if( ! empty( $redirect_url ) ) { - $redirect_url = ( wppb_check_missing_http( $redirect_url ) ? 'http://'. $redirect_url : $redirect_url ); - } - - return $redirect_url; -} - -/** - * Function that builds the redirect - * - * @param string $redirect_url - redirect URL - * @param int $redirect_delay - redirect delay in seconds - * @param null|string $redirect_type - the type of the redirect - * @param null|array $form_args - form args if set - * - * @return string $redirect_message - */ -function wppb_build_redirect( $redirect_url, $redirect_delay, $redirect_type = NULL, $form_args = NULL ) { - if( isset( $redirect_type ) ) { - $redirect_url = apply_filters( 'wppb_'. $redirect_type .'_redirect', $redirect_url ); - } - - $redirect_message = ''; - - if( ! empty( $redirect_url ) ) { - $redirect_url = ( wppb_check_missing_http( $redirect_url ) ? 'http://'. $redirect_url : $redirect_url ); - - if( $redirect_delay == 0 ) { - $redirect_message = ''; - } else { - $redirect_url_href = apply_filters( 'wppb_redirect_url', ''. __( 'here', 'profile-builder' ) .'', $redirect_url, $redirect_type, $form_args ); - $redirect_message = apply_filters( 'wppb_redirect_message_before_returning', '

            '. sprintf( wp_slash( __( 'You will soon be redirected automatically. If you see this page for more than %1$d seconds, please click %2$s.%3$s', 'profile-builder' ) ), $redirect_delay, $redirect_url_href, '' ) .'

            ', $redirect_url, $redirect_delay, $redirect_url_href, $redirect_type, $form_args ); - } - } - - return $redirect_message; -} - -/** - * Function that strips the script tags from an input - * @param $string - * @return mixed - */ -function wppb_sanitize_value( $string ){ - return preg_replace( '/]*>(.*?)<\/script>/is', '', $string ); -} +ID) + foreach ($current_user->roles as $role_key) { + if (empty($GLOBALS['wp_roles']->roles[$role_key])) + continue; + $role = $GLOBALS['wp_roles']->roles[$role_key]; + if (isset($adminSettingsPresent[$role['name']])) { + if ($adminSettingsPresent[$role['name']] == 'show') + $show = true; + if ($adminSettingsPresent[$role['name']] == 'hide' && $show === null) + $show = false; + } + } + return $show === null ? $content : $show; +} + + +if(!function_exists('wppb_curpageurl')){ + function wppb_curpageurl() { + $pageURL = 'http'; + + if ((isset($_SERVER["HTTPS"])) && ($_SERVER["HTTPS"] == "on")) + $pageURL .= "s"; + + $pageURL .= "://"; + + if( strpos( $_SERVER["HTTP_HOST"], $_SERVER["SERVER_NAME"] ) !== false ){ + $pageURL .=$_SERVER["HTTP_HOST"].$_SERVER["REQUEST_URI"]; + } + else { + if ($_SERVER["SERVER_PORT"] != "80") + $pageURL .= $_SERVER["SERVER_NAME"] . ":" . $_SERVER["SERVER_PORT"] . $_SERVER["REQUEST_URI"]; + else + $pageURL .= $_SERVER["SERVER_NAME"] . $_SERVER["REQUEST_URI"]; + } + + if ( function_exists('apply_filters') ) $pageURL = apply_filters('wppb_curpageurl', $pageURL); + + return $pageURL; + } +} + + +if ( is_admin() ){ + + // register the settings for the menu only display sidebar menu for a user with a certain capability, in this case only the "admin" + add_action( 'admin_init', 'wppb_register_settings' ); + + // display the same extra profile fields in the admin panel also + if ( file_exists ( WPPB_PLUGIN_DIR.'/front-end/extra-fields/extra-fields.php' ) ){ + require_once( WPPB_PLUGIN_DIR.'/front-end/extra-fields/extra-fields.php' ); + + add_action( 'show_user_profile', 'display_profile_extra_fields_in_admin', 10 ); + add_action( 'edit_user_profile', 'display_profile_extra_fields_in_admin', 10 ); + global $pagenow; + if( $pagenow != 'user-new.php' ) + add_action( 'user_profile_update_errors', 'wppb_validate_backend_fields', 10, 3 ); + add_action( 'personal_options_update', 'save_profile_extra_fields_in_admin', 10 ); + add_action( 'edit_user_profile_update', 'save_profile_extra_fields_in_admin', 10 ); + } + +}else if ( !is_admin() ){ + // include the stylesheet + add_action( 'wp_print_styles', 'wppb_add_plugin_stylesheet' ); + + // include the menu file for the profile informations + include_once( WPPB_PLUGIN_DIR.'/front-end/edit-profile.php' ); + include_once( WPPB_PLUGIN_DIR.'/front-end/class-formbuilder.php' ); + add_shortcode( 'wppb-edit-profile', 'wppb_front_end_profile_info' ); + + // include the menu file for the login screen + include_once( WPPB_PLUGIN_DIR.'/front-end/login.php' ); + add_shortcode( 'wppb-login', 'wppb_front_end_login' ); + + // include the menu file for the logout screen + include_once( WPPB_PLUGIN_DIR.'/front-end/logout.php' ); + add_shortcode( 'wppb-logout', 'wppb_front_end_logout' ); + + // include the menu file for the register screen + include_once( WPPB_PLUGIN_DIR.'/front-end/register.php' ); + add_shortcode( 'wppb-register', 'wppb_front_end_register_handler' ); + + // include the menu file for the recover password screen + include_once( WPPB_PLUGIN_DIR.'/front-end/recover.php' ); + add_shortcode( 'wppb-recover-password', 'wppb_front_end_password_recovery' ); + + // set the front-end admin bar to show/hide + add_filter( 'show_admin_bar' , 'wppb_show_admin_bar'); + + // Shortcodes used for the widget area + add_filter( 'widget_text', 'do_shortcode', 11 ); +} + + +/** + * Function that overwrites the default wp_mail function and sends out emails + * + * @since v.2.0 + * + * @param string $to + * @param string $subject + * @param string $message + * @param string $message_from + * + */ +function wppb_mail( $to, $subject, $message, $message_from = null, $context = null ) { + $to = apply_filters( 'wppb_send_email_to', $to ); + $send_email = apply_filters( 'wppb_send_email', true, $to, $subject, $message, $context ); + + $message = apply_filters( 'wppb_email_message', $message, $context ); + + do_action( 'wppb_before_sending_email', $to, $subject, $message, $send_email, $context ); + + if ( $send_email ) { + //we add this filter to enable html encoding + add_filter( 'wp_mail_content_type', create_function( '', 'return "text/html"; ' ) ); + + $sent = wp_mail( $to , html_entity_decode( htmlspecialchars_decode( $subject, ENT_QUOTES ), ENT_QUOTES ), $message ); + + do_action( 'wppb_after_sending_email', $sent, $to, $subject, $message, $send_email, $context ); + + return $sent; + } + + return ''; +} + +function wppb_activate_account_check(){ + if ( ( isset( $_GET['activation_key'] ) ) && ( trim( $_GET['activation_key'] ) != '' ) ){ + global $post; + $activation_key = sanitize_text_field( $_GET['activation_key'] ); + + $wppb_generalSettings = get_option( 'wppb_general_settings' ); + $activation_landing_page_id = ( ( isset( $wppb_generalSettings['activationLandingPage'] ) && ( trim( $wppb_generalSettings['activationLandingPage'] ) != '' ) ) ? $wppb_generalSettings['activationLandingPage'] : 'not_set' ); + + if ( $activation_landing_page_id != 'not_set' ){ + //an activation page was selected, but we still need to check if the current page doesn't already have the registration shortcode + if ( strpos( $post->post_content, '[wppb-register' ) === false ) + add_filter( 'the_content', 'wppb_add_activation_message' ); + + }elseif ( strpos( $post->post_content, '[wppb-register' ) === false ){ + //no activation page was selected, and the sent link pointed to the home url + wp_redirect( apply_filters( 'wppb_activatate_account_redirect_url', WPPB_PLUGIN_URL.'assets/misc/fallback-page.php?activation_key='.urlencode( $activation_key ).'&site_name='.urlencode( get_bloginfo( 'name' ) ).'&site_url='.urlencode( get_bloginfo( 'url' ) ).'&message='.urlencode( $activation_message = wppb_activate_signup( $activation_key ) ), $activation_key, $activation_message ) ); + exit; + } + } +} +add_action( 'template_redirect', 'wppb_activate_account_check' ); + + +function wppb_add_activation_message( $content ){ + + return wppb_activate_signup( sanitize_text_field( $_GET['activation_key'] ) ) . $content; +} + + +// Create a new, top-level page +$args = array( + 'page_title' => 'Profile Builder', + 'menu_title' => 'Profile Builder', + 'capability' => 'manage_options', + 'menu_slug' => 'profile-builder', + 'page_type' => 'menu_page', + 'position' => '70,69', + 'priority' => 1, + 'icon_url' => WPPB_PLUGIN_URL . 'assets/images/pb-menu-icon.png' + ); +new WCK_Page_Creator_PB( $args ); + +/** + * Remove the automatically created submenu page + * + * @since v.2.0 + * + * @return void + */ +function wppb_remove_main_menu_page(){ + remove_submenu_page( 'profile-builder', 'profile-builder' ); +} +add_action( 'admin_menu', 'wppb_remove_main_menu_page', 11 ); + +/** + * Add scripts to the back-end CPT's to remove the slug from the edit page + * + * @since v.2.0 + * + * @return void + */ +function wppb_print_cpt_script( $hook ){ + wp_enqueue_script( 'jquery-ui-dialog' ); + wp_enqueue_style( 'wp-jquery-ui-dialog' ); + + if ( $hook == 'profile-builder_page_manage-fields' ){ + wp_enqueue_script( 'wppb-manage-fields-live-change', WPPB_PLUGIN_URL . 'assets/js/jquery-manage-fields-live-change.js', array(), PROFILE_BUILDER_VERSION, true ); + } + + if (( $hook == 'profile-builder_page_manage-fields' ) || + ( $hook == 'profile-builder_page_profile-builder-basic-info' ) || + ( $hook == 'profile-builder_page_profile-builder-modules' ) || + ( $hook == 'profile-builder_page_profile-builder-general-settings' ) || + ( $hook == 'profile-builder_page_profile-builder-admin-bar-settings' ) || + ( $hook == 'profile-builder_page_profile-builder-register' ) || + ( $hook == 'profile-builder_page_profile-builder-wppb_userListing' ) || + ( $hook == 'profile-builder_page_custom-redirects' ) || + ( $hook == 'profile-builder_page_profile-builder-wppb_emailCustomizer' ) || + ( $hook == 'profile-builder_page_profile-builder-wppb_emailCustomizerAdmin' ) || + ( $hook == 'profile-builder_page_profile-builder-add-ons' ) || + ( $hook == 'profile-builder_page_profile-builder-woocommerce-sync' ) || + ( $hook == 'profile-builder_page_profile-builder-bbpress') || + ( $hook == 'admin_page_profile-builder-pms-promo') ) { + wp_enqueue_style( 'wppb-back-end-style', WPPB_PLUGIN_URL . 'assets/css/style-back-end.css', false, PROFILE_BUILDER_VERSION ); + } + + if ( $hook == 'profile-builder_page_profile-builder-general-settings' ) + wp_enqueue_script( 'wppb-manage-fields-live-change', WPPB_PLUGIN_URL . 'assets/js/jquery-email-confirmation.js', array(), PROFILE_BUILDER_VERSION, true ); + + if( ($hook == 'profile-builder_page_profile-builder-add-ons' ) || + ($hook == 'admin_page_profile-builder-pms-promo' ) ) { + wp_enqueue_script('wppb-add-ons', WPPB_PLUGIN_URL . 'assets/js/jquery-pb-add-ons.js', array(), PROFILE_BUILDER_VERSION, true); + wp_enqueue_style( 'thickbox' ); + wp_enqueue_script( 'thickbox' ); + } + + if ( isset( $_GET['post_type'] ) || isset( $_GET['post'] ) ){ + if ( isset( $_GET['post_type'] ) ) + $post_type = sanitize_text_field( $_GET['post_type'] ); + + elseif ( isset( $_GET['post'] ) ) + $post_type = get_post_type( absint( $_GET['post'] ) ); + + if ( ( 'wppb-epf-cpt' == $post_type ) || ( 'wppb-rf-cpt' == $post_type ) || ( 'wppb-ul-cpt' == $post_type ) ){ + wp_enqueue_style( 'wppb-back-end-style', WPPB_PLUGIN_URL . 'assets/css/style-back-end.css', false, PROFILE_BUILDER_VERSION ); + wp_enqueue_script( 'wppb-epf-rf', WPPB_PLUGIN_URL . 'assets/js/jquery-epf-rf.js', array(), PROFILE_BUILDER_VERSION, true ); + } + } + if ( file_exists ( WPPB_PLUGIN_DIR.'/update/update-checker.php' ) ) { + wp_enqueue_script( 'wppb-sitewide', WPPB_PLUGIN_URL . 'assets/js/jquery-pb-sitewide.js', array(), PROFILE_BUILDER_VERSION, true ); + } + wp_enqueue_style( 'wppb-serial-notice-css', WPPB_PLUGIN_URL . 'assets/css/serial-notice.css', false, PROFILE_BUILDER_VERSION ); +} +add_action( 'admin_enqueue_scripts', 'wppb_print_cpt_script' ); + + +//the function used to overwrite the avatar across the wp installation +function wppb_changeDefaultAvatar( $avatar, $id_or_email, $size, $default, $alt ){ + /* Get user info. */ + if(is_object($id_or_email)){ + $my_user_id = $id_or_email->user_id; + + }elseif(is_numeric($id_or_email)){ + $my_user_id = $id_or_email; + + }elseif(!is_integer($id_or_email)){ + $user_info = get_user_by( 'email', $id_or_email ); + $my_user_id = ( is_object( $user_info ) ? $user_info->ID : '' ); + }else + $my_user_id = $id_or_email; + + $wppb_manage_fields = get_option( 'wppb_manage_fields', 'not_found' ); + if ( $wppb_manage_fields != 'not_found' ){ + foreach( $wppb_manage_fields as $value ){ + if ( $value['field'] == 'Avatar'){ + $avatar_field = $value; + } + } + } + + /* for multisite if we don't have an avatar try to get it from the main blog */ + if( is_multisite() && empty( $avatar_field ) ){ + switch_to_blog(1); + $wppb_switched_blog = true; + $wppb_manage_fields = get_option( 'wppb_manage_fields', 'not_found' ); + if ( $wppb_manage_fields != 'not_found' ){ + foreach( $wppb_manage_fields as $value ){ + if ( $value['field'] == 'Avatar'){ + $avatar_field = $value; + } + } + } + } + + if ( !empty( $avatar_field ) ){ + + $customUserAvatar = get_user_meta( $my_user_id, $avatar_field['meta-name'], true ); + if( !empty( $customUserAvatar ) ){ + if( is_numeric( $customUserAvatar ) ){ + $img_attr = wp_get_attachment_image_src( $customUserAvatar, 'wppb-avatar-size-'.$size ); + if( $img_attr[3] === false ){ + $img_attr = wp_get_attachment_image_src( $customUserAvatar, 'thumbnail' ); + $avatar = "{$alt}"; + } + else + $avatar = "{$alt}"; + } + else { + $customUserAvatar = get_user_meta($my_user_id, 'resized_avatar_' . $avatar_field['id'], true); + $customUserAvatarRelativePath = get_user_meta($my_user_id, 'resized_avatar_' . $avatar_field['id'] . '_relative_path', true); + + if ((($customUserAvatar != '') || ($customUserAvatar != null)) && file_exists($customUserAvatarRelativePath)) { + $avatar = "{$alt}"; + } + } + } + + } + + /* if we switched the blog restore it */ + if( is_multisite() && !empty( $wppb_switched_blog ) && $wppb_switched_blog ) + restore_current_blog(); + + return $avatar; +} +add_filter( 'get_avatar', 'wppb_changeDefaultAvatar', 21, 5 ); + + +//the function used to resize the avatar image; the new function uses a user ID as parameter to make pages load faster +function wppb_resize_avatar( $userID, $userlisting_size = null, $userlisting_crop = null ){ + // include the admin image API + require_once( ABSPATH . '/wp-admin/includes/image.php' ); + + // retrieve first a list of all the current custom fields + $wppb_manage_fields = get_option( 'wppb_manage_fields', 'not_found' ); + if ( $wppb_manage_fields != 'not_found' ){ + foreach( $wppb_manage_fields as $value ){ + if ( $value['field'] == 'Avatar'){ + $avatar_field = $value; + } + } + } + + /* for multisite if we don't have an avatar try to get it from the main blog */ + if( is_multisite() && empty( $avatar_field ) ){ + switch_to_blog(1); + $wppb_switched_blog = true; + $wppb_manage_fields = get_option( 'wppb_manage_fields', 'not_found' ); + if ( $wppb_manage_fields != 'not_found' ){ + foreach( $wppb_manage_fields as $value ){ + if ( $value['field'] == 'Avatar'){ + $avatar_field = $value; + } + } + } + } + + + if ( !empty( $avatar_field ) ){ + + // retrieve width and height of the image + $width = $height = ''; + + //this checks if it only has 1 component + if ( is_numeric( $avatar_field['avatar-size'] ) ){ + $width = $height = $avatar_field['avatar-size']; + + }else{ + //this checks if the entered value has 2 components + $sentValue = explode( ',', $avatar_field['avatar-size'] ); + $width = $sentValue[0]; + $height = $sentValue[1]; + } + + $width = ( !empty( $userlisting_size ) ? $userlisting_size : $width ); + $height = ( !empty( $userlisting_size ) ? $userlisting_size : $height ); + + if( !strpos( get_user_meta( $userID, 'resized_avatar_'.$avatar_field['id'], true ), $width . 'x' . $height ) ) { + // retrieve the original image (in original size) + $avatar_directory_path = get_user_meta( $userID, 'avatar_directory_path_'.$avatar_field['id'], true ); + + $image = wp_get_image_editor( $avatar_directory_path ); + if ( !is_wp_error( $image ) ) { + do_action( 'wppb_before_avatar_resizing', $image, $userID, $avatar_field['meta-name'], $avatar_field['avatar-size'] ); + + $crop = apply_filters( 'wppb_avatar_crop_resize', ( !empty( $userlisting_crop ) ? $userlisting_crop : false ) ); + + $resize = $image->resize( $width, $height, $crop ); + + if ($resize !== FALSE) { + do_action( 'wppb_avatar_resizing', $image, $resize ); + + $fileType = apply_filters( 'wppb_resized_file_extension', 'png' ); + + $wp_upload_array = wp_upload_dir(); // Array of key => value pairs + + //create file(name); both with directory and url + $fileName_dir = $image->generate_filename( NULL, $wp_upload_array['basedir'].'/profile_builder/avatars/', $fileType ); + + if ( PHP_OS == "WIN32" || PHP_OS == "WINNT" ) + $fileName_dir = str_replace( '\\', '/', $fileName_dir ); + + $fileName_url = str_replace( str_replace( '\\', '/', $wp_upload_array['basedir'] ), $wp_upload_array['baseurl'], $fileName_dir ); + + //save the newly created (resized) avatar on the disc + $saved_image = $image->save( $fileName_dir ); + + if ( !is_wp_error( $saved_image ) ) { + /* the image save sometimes doesn't save with the desired extension so we need to see with what extension it saved it with and + if it differs replace the extension in the path and url that we save as meta */ + $validate_saved_image = wp_check_filetype_and_ext( $saved_image['path'], $saved_image['path'] ); + $ext = substr( $fileName_dir,strrpos( $fileName_dir, '.', -1 ), strlen($fileName_dir) ); + if( !empty( $validate_saved_image['ext'] ) && $validate_saved_image['ext'] != $ext ){ + $fileName_url = str_replace( $ext, '.'.$validate_saved_image['ext'], $fileName_url ); + $fileName_dir = str_replace( $ext, '.'.$validate_saved_image['ext'], $fileName_dir ); + } + + update_user_meta( $userID, 'resized_avatar_'.$avatar_field['id'], $fileName_url ); + update_user_meta( $userID, 'resized_avatar_'.$avatar_field['id'].'_relative_path', $fileName_dir ); + + do_action( 'wppb_after_avatar_resizing', $image, $fileName_dir, $fileName_url ); + } + } + } + } + } + + /* if we switched the blog restore it */ + if( is_multisite() && !empty( $wppb_switched_blog ) && $wppb_switched_blog ) + restore_current_blog(); + +} + + +if ( is_admin() ){ + // add a hook to delete the user from the _signups table if either the email confirmation is activated, or it is a wpmu installation + function wppb_delete_user_from_signups_table($user_id) { + global $wpdb; + + $userLogin = $wpdb->get_var( $wpdb->prepare( "SELECT user_login, user_email FROM " . $wpdb->users . " WHERE ID = %d LIMIT 1", $user_id ) ); + if ( is_multisite() ) + $delete = $wpdb->delete( $wpdb->signups, array( 'user_login' => $userLogin ) ); + else + $delete = $wpdb->delete( $wpdb->prefix.'signups', array( 'user_login' => $userLogin ) ); + } + + $wppb_generalSettings = get_option( 'wppb_general_settings' ); + if ( !empty( $wppb_generalSettings['emailConfirmation'] ) && ( $wppb_generalSettings['emailConfirmation'] == 'yes' ) ) { + if( is_multisite() ) + add_action( 'wpmu_delete_user', 'wppb_delete_user_from_signups_table' ); + else + add_action('delete_user', 'wppb_delete_user_from_signups_table'); + } +} + + + +// This function offers compatibility with the all in one event calendar plugin +function wppb_aioec_compatibility(){ + + wp_deregister_script( 'jquery.tools-form'); +} +add_action('admin_print_styles-users_page_ProfileBuilderOptionsAndSettings', 'wppb_aioec_compatibility'); + + +function wppb_user_meta_exists( $id, $meta_name ){ + global $wpdb; + + return $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->usermeta WHERE user_id = %d AND meta_key = %s", $id, $meta_name ) ); +} + + +// function to check if there is a need to add the http:// prefix +function wppb_check_missing_http( $redirectLink ) { + return preg_match( '#^(?:[a-z\d]+(?:-+[a-z\d]+)*\.)+[a-z]+(?::\d+)?(?:/|$)#i', $redirectLink ); +} + + + +//function to output the password strength checker on frontend forms +function wppb_password_strength_checker_html(){ + $wppb_generalSettings = get_option( 'wppb_general_settings' ); + if( !empty( $wppb_generalSettings['minimum_password_strength'] ) ){ + $password_strength = ''.__('Strength indicator', 'profile-builder' ).' + '; + return $password_strength; + } + return ''; +} + +//function to check password length check +function wppb_check_password_length( $password ){ + $wppb_generalSettings = get_option( 'wppb_general_settings' ); + if( !empty( $wppb_generalSettings['minimum_password_length'] ) ){ + if( strlen( $password ) < $wppb_generalSettings['minimum_password_length'] ){ + return true; + } + else + return false; + } + return false; +} + +//function to check password strength +function wppb_check_password_strength(){ + $wppb_generalSettings = get_option( 'wppb_general_settings' ); + if( isset( $_POST['wppb_password_strength'] ) && !empty( $wppb_generalSettings['minimum_password_strength'] ) ){ + $wppb_password_strength = sanitize_text_field( $_POST['wppb_password_strength'] ); + $password_strength_array = array( 'short' => 0, 'bad' => 1, 'good' => 2, 'strong' => 3 ); + $password_strength_text = array( 'short' => __( 'Very Weak', 'profile-builder' ), 'bad' => __( 'Weak', 'profile-builder' ), 'good' => __( 'Medium', 'profile-builder' ), 'strong' => __( 'Strong', 'profile-builder' ) ); + if( $password_strength_array[$wppb_password_strength] < $password_strength_array[$wppb_generalSettings['minimum_password_strength']] ){ + return $password_strength_text[$wppb_generalSettings['minimum_password_strength']]; + } + else + return false; + } + return false; +} + +/* function to output password length requirements text */ +function wppb_password_length_text(){ + $wppb_generalSettings = get_option( 'wppb_general_settings' ); + if( !empty( $wppb_generalSettings['minimum_password_length'] ) ){ + return sprintf(__('Minimum length of %d characters', 'profile-builder'), $wppb_generalSettings['minimum_password_length']); + } + return ''; +} + +/** + * Include password strength check scripts on frontend where we have shortoces present + */ +add_action( 'wp_footer', 'wppb_enqueue_password_strength_check' ); +function wppb_enqueue_password_strength_check() { + global $wppb_shortcode_on_front; + if( $wppb_shortcode_on_front ){ + $wppb_generalSettings = get_option( 'wppb_general_settings' ); + if( !empty( $wppb_generalSettings['minimum_password_strength'] ) ){ + wp_enqueue_script( 'password-strength-meter' ); + } + } +} +add_action( 'wp_footer', 'wppb_password_strength_check', 102 ); +function wppb_password_strength_check(){ + global $wppb_shortcode_on_front; + if( $wppb_shortcode_on_front ){ + $wppb_generalSettings = get_option( 'wppb_general_settings' ); + if( !empty( $wppb_generalSettings['minimum_password_strength'] ) ){ + ?> + + $field) { + if ( (!empty($id)) && ($field['id'] == $id) ) + return $field; + if ( (!empty($meta)) && ($field['meta-name'] == $meta) ) + return $field; + } + + } + + return ''; +} + + +/* Function for displaying reCAPTCHA error on Login and Recover Password forms */ +function wppb_recaptcha_field_error($field_title='') { + $recaptcha_error = apply_filters('wppb_recaptcha_error' , __('Please enter a (valid) reCAPTCHA value','profile-builder') , $field_title); + + return $recaptcha_error; + +} +/* Function for displaying phone field error */ +function wppb_phone_field_error( $field_title = '' ) { + $phone_error = apply_filters( 'wppb_phone_error' , __( 'Incorrect phone number', 'profile-builder' ) , $field_title ); + + return $phone_error; +} + +/* Create a wrapper function for get_query_var */ +function wppb_get_query_var( $varname ){ + return apply_filters( 'wppb_get_query_var_'.$varname, get_query_var( $varname ) ); +} + +/* Filter the "Save Changes" button text, to make it translatable */ +function wppb_change_save_changes_button($value){ + $value = __('Save Changes','profile-builder'); + return $value; +} +add_filter( 'wck_save_changes_button', 'wppb_change_save_changes_button', 10, 2); + +/* Filter the "Cancel" button text, to make it translatable */ +function wppb_change_cancel_button($value){ + $value = __('Cancel','profile-builder'); + return $value; +} +add_filter( 'wck_cancel_button', 'wppb_change_cancel_button', 10, 2); + +/* ilter the "Delete" button text, to make it translatable */ +function wppb_change_delete_button($value){ + $value = __('Delete','profile-builder'); + return $value; +} +add_filter( 'wck_delete_button', 'wppb_change_delete_button', 10, 2); + +/*Filter the "Edit" button text, to make it translatable*/ +function wppb_change_edit_button($value){ + $value = __('Edit','profile-builder'); + return $value; +} +add_filter( 'wck_edit_button', 'wppb_change_edit_button', 10, 2); + +/*Filter the User Listing, Register Forms and Edit Profile forms metabox header content, to make it translatable*/ +function wppb_change_metabox_content_header(){ + return ''; +} +add_filter('wck_metabox_content_header_wppb_ul_page_settings', 'wppb_change_metabox_content_header', 1); +add_filter('wck_metabox_content_header_wppb_rf_page_settings', 'wppb_change_metabox_content_header', 1); +add_filter('wck_metabox_content_header_wppb_epf_page_settings', 'wppb_change_metabox_content_header', 1); + + +/* Add a notice if people are not able to register via Profile Builder; Membership -> "Anyone can register" checkbox is not checked under WordPress admin UI -> Settings -> General tab */ +if ( (get_option('users_can_register') == false) && (!class_exists('PMS_Add_General_Notices')) ) { + if( is_multisite() ) { + new WPPB_Add_General_Notices('wppb_anyone_can_register', + sprintf(__('Aby zezwolić użytkownikom na logowanie na Twojej stronie poprzez Profile Builder, musisz najpierw zezwolić na rejestrację użytkowników. Idź do %1$sUstawień Sieciowych%2$s, oraz upewnij się, że pole "Możliwość rejestracji kont użytowników" jest zaznaczone. %3$sAnuluj%4$s', 'profile-builder'), "", "", "", ""),//To allow users to register for your website via Profile Builder, you first must enable user registration. Go to %1$sNetwork Settings%2$s, and under Registration Settings make sure to check “User accounts may be registered”. %3$sDismiss%4$s + 'update-nag'); + }else{ + new WPPB_Add_General_Notices('wppb_anyone_can_register', + sprintf(__('Aby zezwolić użytkownikom na rejestrację na Twojej stronie poprzez Profile Builder, musisz najpierw umożliwić rejestrację użytkowników. Idź do zakładki %1$sUstawienia -> Ogólne%2$s oraz upewnij się, że w sekcji Członkostwo pole “Każdy może się zarejestrować” jest zaznaczone. %3$sOdrzuć%4$s', 'profile-builder'), "", "", "", ""),//To allow users to register for your website via Profile Builder, you first must enable user registration. Go to %1$sSettings -> General%2$s tab, and under Membership make sure to check “Anyone can register”. %3$sDismiss%4$s + 'update-nag'); + } +} + +/*Filter default WordPress notices ("Post published. Post updated."), add post type name for User Listing, Registration Forms and Edit Profile Forms*/ +function wppb_change_default_post_updated_messages($messages){ + global $post; + $post_type = get_post_type($post->ID); + $object = get_post_type_object($post_type); + + if ( ($post_type == 'wppb-rf-cpt')||($post_type == 'wppb-epf-cpt')||($post_type == 'wppb-ul-cpt') ){ + $messages['post'][1] = $object->labels->name . ' updated.'; + $messages['post'][6] = $object->labels->name . ' published.'; + } + return $messages; +} +add_filter('post_updated_messages','wppb_change_default_post_updated_messages', 2); + + +/* for meta-names with spaces in them PHP converts the space to underline in the $_POST */ +function wppb_handle_meta_name( $meta_name ){ + $meta_name = str_replace( ' ', '_', $meta_name ); + $meta_name = str_replace( '.', '_', $meta_name ); + return $meta_name; +} + + +// change User Registered date and time according to timezone selected in WordPress settings +function wppb_get_date_by_timezone() { + $wppb_wp_timezone = get_option( 'timezone_string' ); + + if( ! empty( $wppb_wp_timezone ) ) { + date_default_timezone_set( $wppb_wp_timezone ); + $wppb_get_date = date( "Y-m-d G:i:s" ); + } else { + $wppb_wp_gmt_offset = get_option( 'gmt_offset' ); + $wppb_gmt_offset = $wppb_wp_gmt_offset * 60 * 60; + $wppb_get_date = gmdate( "Y-m-d G:i:s", time() + $wppb_gmt_offset ); + } + + return $wppb_get_date; +} + +/** + * Add HTML tag 'required' to fields + * + * Add HTML tag 'required' for each field if the field is required. For browsers that don't support this HTML tag, we will still have the fallback. + * Field type 'Checkbox' is explicitly excluded because there is no HTML support to check if at least one option is selected. + * Other fields excluded are Avatar, Upload, Heading, ReCaptcha, WYSIWYG, Map. + * + * @since + * + * @param string $extra_attributes Extra attributes attached to the field HTML tag. + * @param array $field Field description. + * @return string $extra_attributes + */ +function wppb_add_html_tag_required_to_fields( $extra_attributes, $field, $form_location ) { + if ( $field['field'] != "Checkbox" && isset( $field['required'] ) && $field['required'] == 'Yes' ){ + if( !( ( $field['field'] == "Default - Password" || $field['field'] == "Default - Repeat Password" ) && $form_location == 'edit_profile' ) ) + $extra_attributes .= ' required '; + } + return $extra_attributes; +} +add_filter( 'wppb_extra_attribute', 'wppb_add_html_tag_required_to_fields', 10, 3 ); + +/** + * Add HTML tag 'required' to WooCommerce fields + * + * Add HTML tag 'required' for each WooCommerce field if the field is required. For browsers that don't support this HTML tag, we will still have the fallback. + * Does not work on 'State / County' field, if it becomes required later depending on the Country Value + * + * @since + * + * @param string $extra_attributes Extra attributes attached to the field HTML tag. + * @param array $field Field description. + * @return string $extra_attributes + */ +function wppb_add_html_tag_required_to_woo_fields( $extra_attributes, $field ) { + if ( isset( $field['required'] ) && $field['required'] == 'Yes' ){ + $extra_attributes .= ' required '; + } + return $extra_attributes; +} +add_filter( 'wppb_woo_extra_attribute', 'wppb_add_html_tag_required_to_woo_fields', 10, 2 ); + + +/** + * Add jQuery script to remove required attribute for hidden fields + * + * If a field is hidden dynamically via conditional fields or WooSync 'Ship to a different address' checkbox, then the required field needs to be removed. + * If a field is made visible again, add the required field back again. + * + * @since + * + * @param string $extra_attributes Extra attributes attached to the field HTML tag. + * @param array $field Field description. + * @return string $extra_attributes + */ +function wppb_manage_required_attribute() { + global $wppb_shortcode_on_front; + if ($wppb_shortcode_on_front) { + ?> + + errors['blogname']) && empty($blog_details['errors']->errors['blog_title'])) { + $blog_path = $blog_details['domain'] . $blog_details['path']; + $message .= __( '

            Also, you will be able to visit your site at ', 'profile-builder' ) . '' . $blog_path . '.'; + } + } + return $message; +} +add_filter( 'wppb_signup_user_notification_email_content', 'wpbb_specify_blog_details_on_signup_email', 5, 8 ); + +function wpbb_specify_blog_details_on_registration_email( $user_message_content, $email, $password, $user_message_subject, $context ){ + + if ( is_multisite() ) { + $user = get_user_by( 'email', $email ); + $blog_path = wppb_get_blog_url_of_user_id( $user->ID ); + if ( ! empty ( $blog_path ) ) { + $user_message_content .= __( '

            You can visit your site at ', 'profile-builder' ) . '' . $blog_path . '.'; + } + } + return $user_message_content; + +} +add_filter( 'wppb_register_user_email_message_without_admin_approval', 'wpbb_specify_blog_details_on_registration_email', 5, 5 ); +add_filter( 'wppb_register_user_email_message_with_admin_approval', 'wpbb_specify_blog_details_on_registration_email', 5, 5 ); + + +function wppb_get_blog_url_of_user_id( $user_id, $ignore_privacy = true ){ + $blog_id = get_user_meta( $user_id, 'primary_blog', true ); + if ( is_multisite() && !empty( $blog_id ) ){ + $blog_details = get_blog_details( $blog_id ); + if ( $ignore_privacy || $blog_details->public ) { + return $blog_details->domain . $blog_details->path; + } + } + return ''; +} + +function wppb_can_users_signup_blog(){ + if ( ! is_multisite() ) + return false; + global $wpdb; + $current_site = get_current_site(); + $sitemeta_options_query = $wpdb->prepare( "SELECT meta_value FROM {$wpdb->sitemeta} WHERE meta_key = 'registration' AND site_id = %d", $current_site->id ); + $network_options_meta = $wpdb->get_results( $sitemeta_options_query ); + + if ( $network_options_meta[0]->meta_value == 'all' ){ + return true; + } + return false; +} + +/** + * Function that handle redirect URL + * + * @param string $redirect_priority - it can be normal or top priority + * @param string $redirect_type - type of the redirect + * @param null|string $redirect_url - redirect URL if already set + * @param null|string|object $user - username, user email or user data + * @param null|string $user_role - user role + * + * @return null|string $redirect_url + */ +function wppb_get_redirect_url( $redirect_priority = 'normal', $redirect_type, $redirect_url = NULL, $user = NULL, $user_role = NULL ) { + if( PROFILE_BUILDER == 'Profile Builder Pro' ) { + $wppb_module_settings = get_option( 'wppb_module_settings' ); + + if( isset( $wppb_module_settings['wppb_customRedirect'] ) && $wppb_module_settings['wppb_customRedirect'] == 'show' && $redirect_priority != 'top' && function_exists( 'wppb_custom_redirect_url' ) ) { + $redirect_url = wppb_custom_redirect_url( $redirect_type, $redirect_url, $user, $user_role ); + } + } + + if( ! empty( $redirect_url ) ) { + $redirect_url = ( wppb_check_missing_http( $redirect_url ) ? 'http://'. $redirect_url : $redirect_url ); + } + + return $redirect_url; +} + +/** + * Function that builds the redirect + * + * @param string $redirect_url - redirect URL + * @param int $redirect_delay - redirect delay in seconds + * @param null|string $redirect_type - the type of the redirect + * @param null|array $form_args - form args if set + * + * @return string $redirect_message + */ +function wppb_build_redirect( $redirect_url, $redirect_delay, $redirect_type = NULL, $form_args = NULL ) { + if( isset( $redirect_type ) ) { + $redirect_url = apply_filters( 'wppb_'. $redirect_type .'_redirect', $redirect_url ); + } + + $redirect_message = ''; + + if( ! empty( $redirect_url ) ) { + $redirect_url = ( wppb_check_missing_http( $redirect_url ) ? 'http://'. $redirect_url : $redirect_url ); + + if( $redirect_delay == 0 ) { + $redirect_message = ''; + } else { + $redirect_url_href = apply_filters( 'wppb_redirect_url', ''. __( 'here', 'profile-builder' ) .'', $redirect_url, $redirect_type, $form_args ); + $redirect_message = apply_filters( 'wppb_redirect_message_before_returning', '

            '. sprintf( wp_slash( __( 'You will soon be redirected automatically. If you see this page for more than %1$d seconds, please click %2$s.%3$s', 'profile-builder' ) ), $redirect_delay, $redirect_url_href, '' ) .'

            ', $redirect_url, $redirect_delay, $redirect_url_href, $redirect_type, $form_args ); + } + } + + return $redirect_message; +} + +/** + * Function that strips the script tags from an input + * @param $string + * @return mixed + */ +function wppb_sanitize_value( $string ){ + return preg_replace( '/]*>(.*?)<\/script>/is', '', $string ); +} diff --git a/profile-builder/features/login-widget/login-widget.php b/profile-builder/features/login-widget/login-widget.php index c278910..c79a340 100644 --- a/profile-builder/features/login-widget/login-widget.php +++ b/profile-builder/features/login-widget/login-widget.php @@ -1,97 +1,97 @@ - 'login', 'description' => __( 'This login widget lets you add a login form in the sidebar.', 'profile-builder' ) ); - $control_ops = array( 'width' => 300, 'height' => 350, 'id_base' => 'wppb-login-widget' ); - - do_action( 'wppb_login_widget_settings', $widget_ops, $control_ops); - - parent::__construct( 'wppb-login-widget', __('Profile Builder Login Widget', 'profile-builder'), $widget_ops, $control_ops ); - - } - - function widget( $args, $instance ) { - extract( $args ); - - $title = apply_filters( 'wppb_login_widget_title', ( isset( $instance['title'] ) ? $instance['title'] : '' ) ); - $redirect = ( isset( $instance['redirect'] ) ? trim( $instance['redirect'] ) : '' ); - $register = ( isset( $instance['register'] ) ? trim( $instance['register'] ) : '' ); - $lostpass = ( isset( $instance['lostpass'] ) ? trim( $instance['lostpass'] ) : '' ); - - echo $before_widget; - - if ( ! empty( $title ) ) - echo $before_title . $title . $after_title; - - echo do_shortcode('[wppb-login display="false" register_url="'.$register.'" lostpassword_url="'.$lostpass.'" redirect="'.$redirect.'"]'); - - do_action( 'wppb_login_widget_display', $args, $instance); - - echo $after_widget; - } - - /** - * Update the widget settings. - */ - function update( $new_instance, $old_instance ) { - $instance = $old_instance; - - $instance['title'] = strip_tags( $new_instance['title'] ); - $instance['redirect'] = strip_tags( $new_instance['redirect'] ); - $instance['register'] = strip_tags( $new_instance['register'] ); - $instance['lostpass'] = strip_tags( $new_instance['lostpass'] ); - - do_action( 'wppb_login_widget_update_action', $new_instance, $old_instance); - - return $instance; - - } - - - function form( $instance ) { - - $defaults = array( 'title' => __('Login', 'profile-builder'), 'redirect' => '', 'register' => '', 'lostpass' => '' ); - $instance = wp_parse_args( (array) $instance, $defaults ); ?> - -

            - - -

            - -

            - - -

            - -

            - - -

            - -

            - - -

            - - jQuery('html, body').animate({scrollTop: jQuery('#wppb_login').offset().top }) " . $content; -} -//add_filter('wppb_login_wp_error_message', 'wppb_scroll_down_to_widget'); - -function wppb_require_jquery(){ - wp_enqueue_script( 'jquery' ); -} + 'login', 'description' => __( 'This login widget lets you add a login form in the sidebar.', 'profile-builder' ) ); + $control_ops = array( 'width' => 300, 'height' => 350, 'id_base' => 'wppb-login-widget' ); + + do_action( 'wppb_login_widget_settings', $widget_ops, $control_ops); + + parent::__construct( 'wppb-login-widget', __('Profile Builder Login Widget', 'profile-builder'), $widget_ops, $control_ops ); + + } + + function widget( $args, $instance ) { + extract( $args ); + + $title = apply_filters( 'wppb_login_widget_title', ( isset( $instance['title'] ) ? $instance['title'] : '' ) ); + $redirect = ( isset( $instance['redirect'] ) ? trim( $instance['redirect'] ) : '' ); + $register = ( isset( $instance['register'] ) ? trim( $instance['register'] ) : '' ); + $lostpass = ( isset( $instance['lostpass'] ) ? trim( $instance['lostpass'] ) : '' ); + + echo $before_widget; + + if ( ! empty( $title ) ) + echo $before_title . $title . $after_title; + + echo do_shortcode('[wppb-login display="false" register_url="'.$register.'" lostpassword_url="'.$lostpass.'" redirect="'.$redirect.'"]'); + + do_action( 'wppb_login_widget_display', $args, $instance); + + echo $after_widget; + } + + /** + * Update the widget settings. + */ + function update( $new_instance, $old_instance ) { + $instance = $old_instance; + + $instance['title'] = strip_tags( $new_instance['title'] ); + $instance['redirect'] = strip_tags( $new_instance['redirect'] ); + $instance['register'] = strip_tags( $new_instance['register'] ); + $instance['lostpass'] = strip_tags( $new_instance['lostpass'] ); + + do_action( 'wppb_login_widget_update_action', $new_instance, $old_instance); + + return $instance; + + } + + + function form( $instance ) { + + $defaults = array( 'title' => __('Login', 'profile-builder'), 'redirect' => '', 'register' => '', 'lostpass' => '' ); + $instance = wp_parse_args( (array) $instance, $defaults ); ?> + +

            + + +

            + +

            + + +

            + +

            + + +

            + +

            + + +

            + + jQuery('html, body').animate({scrollTop: jQuery('#wppb_login').offset().top }) " . $content; +} +//add_filter('wppb_login_wp_error_message', 'wppb_scroll_down_to_widget'); + +function wppb_require_jquery(){ + wp_enqueue_script( 'jquery' ); +} //add_action( 'wp_enqueue_scripts', 'wppb_require_jquery' ); \ No newline at end of file diff --git a/profile-builder/features/roles-editor/assets/css/roles-editor.css b/profile-builder/features/roles-editor/assets/css/roles-editor.css index 2fc741b..9afd418 100644 --- a/profile-builder/features/roles-editor/assets/css/roles-editor.css +++ b/profile-builder/features/roles-editor/assets/css/roles-editor.css @@ -1,480 +1,480 @@ -@font-face { - font-family: 'wppb_re_font'; - src: url('../font/wppb_re_font.eot?45804157'); - src: url('../font/wppb_re_font.eot?45804157#iefix') format('embedded-opentype'), - url('../font/wppb_re_font.woff2?45804157') format('woff2'), - url('../font/wppb_re_font.woff?45804157') format('woff'), - url('../font/wppb_re_font.ttf?45804157') format('truetype'), - url('../font/wppb_re_font.svg?45804157#wppb_re_font') format('svg'); - font-weight: normal; - font-style: normal; -} -/* Chrome hack: SVG is rendered more smooth in Windozze. 100% magic, uncomment if you need it. */ -/* Note, that will break hinting! In other OS-es font will be not as sharp as it could be */ -/* -@media screen and (-webkit-min-device-pixel-ratio:0) { - @font-face { - font-family: 'wppb_re_font'; - src: url('../font/wppb_re_font.svg?45804157#wppb_re_font') format('svg'); - } -} -*/ - -[class^="icon-wppb-re-"]:before, [class*=" icon-wppb-re-"]:before { - font-family: "wppb_re_font"; - font-style: normal; - font-weight: normal; - speak: none; - - display: inline-block; - text-decoration: inherit; - width: 1em; - margin-right: .2em; - text-align: center; - /* opacity: .8; */ - - /* For safety - reset parent styles, that can break glyph codes*/ - font-variant: normal; - text-transform: none; - - /* fix buttons height, for twitter bootstrap */ - line-height: 1em; - - /* Animation center compensation - margins should be symmetric */ - /* remove if not needed */ - margin-left: .2em; - - /* you can be more comfortable with increased icons size */ - /* font-size: 120%; */ - - /* Font smoothing. That was taken from TWBS */ - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - - /* Uncomment for 3D effect */ - /* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */ -} - -.icon-wppb-re-users:before { content: '\e801'; } /* '' */ -.icon-wppb-re-slug:before { content: '\e802'; } /* '' */ -.icon-wppb-re-caps:before { content: '\e803'; } /* '' */ -.icon-wppb-re-spinner:before { content: '\e838'; } /* '' */ - -.post-type-wppb-roles-editor .table-role-info { - font-size: 13px; -} - -.post-type-wppb-roles-editor #post-query-submit { - display: none; -} - -.post-type-wppb-roles-editor .column-role { - width: 25%; -} - -.post-type-wppb-roles-editor .column-capabilities { - width: 15%; - text-align: center; -} - -.post-type-wppb-roles-editor .column-users { - width: 10%; - text-align: center; -} - -.post-type-wppb-roles-editor .wppb-delete-capability-disabled, -.post-type-wppb-roles-editor .row-actions span.delete_notify { - color: #a00; - cursor: not-allowed; -} - -.post-type-wppb-roles-editor .misc-pub-section .icon-wppb-re-users, -.post-type-wppb-roles-editor .misc-pub-section .icon-wppb-re-slug, -.post-type-wppb-roles-editor .misc-pub-section .icon-wppb-re-caps { - font-size: 20px; -} - -.post-type-wppb-roles-editor #wppb-role-edit-add-caps { - height: 100px; -} - -.post-type-wppb-roles-editor #wppb_edit_role_capabilities .select2 .select2-container { - padding: 0 5px 5px 0 !important; -} - -.post-type-wppb-roles-editor #wppb_edit_role_capabilities a.button-primary { - vertical-align: top; - margin: 1px 0 0 10px; - height: 32px; - line-height: 30px; -} - -.post-type-wppb-roles-editor #wppb_edit_role_capabilities #wppb-add-new-cap-link { - margin: 10px 5px; -} - -.post-type-wppb-roles-editor #wppb_edit_role_capabilities #wppb-add-new-cap-link a:link, -.post-type-wppb-roles-editor #wppb_edit_role_capabilities #wppb-add-new-cap-link a:hover, -.post-type-wppb-roles-editor #wppb_edit_role_capabilities #wppb-add-new-cap-link a:visited, -.post-type-wppb-roles-editor #wppb_edit_role_capabilities #wppb-add-new-cap-link a:active { - text-decoration: none; - box-shadow: none; -} - -.post-type-wppb-roles-editor #wppb_edit_role_capabilities .wppb-add-new-cap-input { - display: none; - vertical-align: middle; - width: 40%; - line-height: 20px; - padding-bottom: 10px; - border: 1px solid #AAAAAA; - border-radius: 4px; - outline: none; - box-shadow: none; - font-size: 13px; - margin: 0; -} - -.post-type-wppb-roles-editor #wppb_edit_role_capabilities .wppb-add-new-cap-input:focus { - border: 1px solid #000; - outline: none; - box-shadow: none; -} - -.post-type-wppb-roles-editor #wppb-duplicate-capability-error, -.post-type-wppb-roles-editor #wppb-hidden-capability-error, -.post-type-wppb-roles-editor #wppb-add-capability-error { - border-left: 3px solid #a00; - display: none; - color: #a00; - font-size: 14px; - margin-left: 6px; - padding: 5px 10px; - line-height: 35px; - vertical-align: top; -} - -.post-type-wppb-roles-editor #wppb-capabilities-tabs { - float: left; - width: 11%; - min-width: 150px; - padding: 20px 0 0 5px; - margin: 0; -} - -.post-type-wppb-roles-editor #wppb-capabilities-tabs .wppb-role-editor-tab-title { - margin: 5px 0.5% 5px 0.5%; - /*padding: 10px 0 10px 10px;*/ - background-color: #f7f7f7; -} - -.post-type-wppb-roles-editor #wppb-capabilities-tabs .wppb-role-editor-tab-title i { - margin-right: 10px; - line-height: 25px; -} - -.post-type-wppb-roles-editor #wppb-capabilities-tabs .wppb-role-editor-tab-title a { - text-decoration: none; - color: inherit; - display: block; - padding: 10px 0 10px 10px; - height: 24px; - line-height: 24px; -} - -.post-type-wppb-roles-editor #wppb-capabilities-tabs .wppb-role-editor-tab-title a:active, -.post-type-wppb-roles-editor #wppb-capabilities-tabs .wppb-role-editor-tab-title a:focus, -.post-type-wppb-roles-editor #wppb-capabilities-tabs .wppb-role-editor-tab-title a:hover { - text-decoration: none; - color: #a00; - box-shadow: none; -} - -.post-type-wppb-roles-editor #wppb-capabilities-tabs .wppb-role-editor-tab-title.wppb-role-editor-tab-active { - color: #a00; - font-weight: bold; -} - -.post-type-wppb-roles-editor #wppb-role-edit-table { - padding: 20px 5px 0 5px; - float: right; - width: 84%; -} - -.post-type-wppb-roles-editor .wppb-re-spinner-container { - margin: 5px 3px 0 2px; - padding: 11px 0; - width: 100%; -} - -.post-type-wppb-roles-editor .wppb-re-spinner-container i.icon-wppb-re-spinner { - font-size: 35px; - margin-left: 45%; -} - -.post-type-wppb-roles-editor #wppb-role-edit-table .wppb-role-edit-table-entry { - width: 32.3%; - float: left; - margin: 5px 3px 0 2px; - padding: 6px 0; - background-color: #f7f7f7; - display: block; - height: 32px; -} - -.post-type-wppb-roles-editor #wppb-role-edit-table .wppb-role-edit-table-entry.wppb-new-capability-highlight { - background-color: #e6e6e6; -} - -.post-type-wppb-roles-editor #wppb-role-edit-table .wppb-role-edit-table-entry .wppb-capability { - padding: 0 10px; - width: 70%; - overflow-wrap: break-word; - word-wrap: break-word; - -ms-word-break: break-all; - word-break: break-all; - word-break: break-word; - -ms-hyphens: auto; - -moz-hyphens: auto; - -webkit-hyphens: auto; - hyphens: auto; - display: inline-block; -} - -.post-type-wppb-roles-editor #wppb-role-edit-table .wppb-role-edit-table-entry .wppb-capability.wppb-new-capability { - color: #0085ba; -} - -.post-type-wppb-roles-editor #wppb-role-edit-table .wppb-role-edit-table-entry .wppb-delete-capability { - float: right; - padding-right: 5px; - display: inline-block; - width: 15%; -} - -.post-type-wppb-roles-editor #wppb-role-edit-table .wppb-role-edit-table-entry .wppb-delete-capability a:link { - text-decoration: none; - color: #a00; -} - -.post-type-wppb-roles-editor #wppb-role-edit-table .wppb-role-edit-table-entry .wppb-delete-capability a:active, -.post-type-wppb-roles-editor #wppb-role-edit-table .wppb-role-edit-table-entry .wppb-delete-capability a:hover, -.post-type-wppb-roles-editor #wppb-role-edit-table .wppb-role-edit-table-entry .wppb-delete-capability a:visited { - text-decoration: none; - color: #FF0000; -} - -.post-type-wppb-roles-editor #wppb-role-edit-table .wppb-role-edit-table-entry.wppb-role-edit-no-cap { - background-color: inherit; -} - -.post-type-wppb-roles-editor #wppb-role-edit-table .wppb-role-edit-table-entry.wppb-role-edit-no-cap span { - color: #a00; -} - -.post-type-wppb-roles-editor #wppb-role-edit-table #wppb-role-edit-caps-clear, -.post-type-wppb-roles-editor #wppb-role-edit-caps-div #wppb-role-edit-divs-clear { - width: 100%; - clear: both; -} - -.post-type-wppb-roles-editor .misc-pub-section #wppb-role-slug { - width: 59%; - margin-left: 5px; - text-transform: lowercase; -} - -.post-type-wppb-roles-editor .misc-pub-section.misc-pub-section-users, -.post-type-wppb-roles-editor .misc-pub-section.misc-pub-section-capabilities, -.post-type-wppb-roles-editor .misc-pub-section.misc-pub-section-edit-slug { - padding-top: 10px; - margin: 5px 0; -} - -.post-type-wppb-roles-editor .misc-pub-section.misc-pub-section-users span, -.post-type-wppb-roles-editor .misc-pub-section.misc-pub-section-capabilities span, -.post-type-wppb-roles-editor .misc-pub-section.misc-pub-section-edit-slug span { - font-size: 14px; - bottom: 1px; - position: relative; -} - -.post-type-wppb-roles-editor .wppb-re-cap-perm-delete { - color: #a00; - font-size: 13px; - float: right; - position: relative; - z-index: 1; -} - -.post-type-wppb-roles-editor .wppb-re-cap-perm-delete:active, -.post-type-wppb-roles-editor .wppb-re-cap-perm-delete:focus, -.post-type-wppb-roles-editor .wppb-re-cap-perm-delete:hover { - color: #000000; - cursor: pointer; -} - -@media screen and ( max-width: 1600px ) { - .post-type-wppb-roles-editor #wppb-role-edit-table .wppb-role-edit-table-entry { - width: 49%; - } - - .post-type-wppb-roles-editor #wppb-role-edit-table { - width: 80%; - } -} - -@media screen and ( max-width: 1400px ) { - .post-type-wppb-roles-editor #wppb-role-edit-table { - width: 76%; - } -} - -@media screen and ( max-width: 1350px ) { - .post-type-wppb-roles-editor #wppb-role-edit-table .wppb-role-edit-table-entry { - width: 100%; - } -} - -@media screen and ( max-width: 1250px ) { - .post-type-wppb-roles-editor #wppb-role-edit-table { - width: 72%; - } -} - -@media screen and ( max-width: 1150px ) { - .post-type-wppb-roles-editor #wppb-role-edit-table { - width: 68%; - } -} - -@media screen and ( max-width: 1100px ) { - .post-type-wppb-roles-editor #wppb-role-edit-table { - width: 62%; - } -} - -@media screen and ( max-width: 850px ) { - .post-type-wppb-roles-editor #wppb-role-edit-table { - width: 70%; - } -} - -@media screen and ( max-width: 782px ) { - .post-type-wppb-roles-editor .column-role input.wppb-role-slug-input { - height: 25px; - } - - .post-type-wppb-roles-editor .column-capabilities, - .post-type-wppb-roles-editor .column-users { - text-align: inherit; - } -} - -@media screen and ( max-width: 650px ) { - .post-type-wppb-roles-editor #wppb-role-edit-table { - width: 100%; - } - - .post-type-wppb-roles-editor #wppb-capabilities-tabs { - width: 100%; - padding: 20px 0 0 0; - } - - .post-type-wppb-roles-editor #wppb-capabilities-tabs .wppb-role-editor-tab-title { - padding: 0 25px 0 5px; - margin: 2px 0; - display: inline-block; - min-width: 40%; - } -} - -@media screen and ( max-width: 450px ) { - .post-type-wppb-roles-editor #wppb-capabilities-tabs .wppb-role-editor-tab-title { - min-width: 91%; - } -} - -.post-type-wppb-roles-editor .wppb-re-spin { - -moz-animation: wppb_re_spin 2s infinite linear; - -o-animation: wppb_re_spin 2s infinite linear; - -webkit-animation: wppb_re_spin 2s infinite linear; - animation: wppb_re_spin 2s infinite linear; - display: inline-block; -} -@-moz-keyframes wppb_re_spin { - 0% { - -moz-transform: rotate(0deg); - -o-transform: rotate(0deg); - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } - - 100% { - -moz-transform: rotate(359deg); - -o-transform: rotate(359deg); - -webkit-transform: rotate(359deg); - transform: rotate(359deg); - } -} -@-webkit-keyframes wppb_re_spin { - 0% { - -moz-transform: rotate(0deg); - -o-transform: rotate(0deg); - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } - - 100% { - -moz-transform: rotate(359deg); - -o-transform: rotate(359deg); - -webkit-transform: rotate(359deg); - transform: rotate(359deg); - } -} -@-o-keyframes wppb_re_spin { - 0% { - -moz-transform: rotate(0deg); - -o-transform: rotate(0deg); - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } - - 100% { - -moz-transform: rotate(359deg); - -o-transform: rotate(359deg); - -webkit-transform: rotate(359deg); - transform: rotate(359deg); - } -} -@-ms-keyframes wppb_re_spin { - 0% { - -moz-transform: rotate(0deg); - -o-transform: rotate(0deg); - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } - - 100% { - -moz-transform: rotate(359deg); - -o-transform: rotate(359deg); - -webkit-transform: rotate(359deg); - transform: rotate(359deg); - } -} -@keyframes wppb_re_spin { - 0% { - -moz-transform: rotate(0deg); - -o-transform: rotate(0deg); - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } - - 100% { - -moz-transform: rotate(359deg); - -o-transform: rotate(359deg); - -webkit-transform: rotate(359deg); - transform: rotate(359deg); - } -} - +@font-face { + font-family: 'wppb_re_font'; + src: url('../font/wppb_re_font.eot?45804157'); + src: url('../font/wppb_re_font.eot?45804157#iefix') format('embedded-opentype'), + url('../font/wppb_re_font.woff2?45804157') format('woff2'), + url('../font/wppb_re_font.woff?45804157') format('woff'), + url('../font/wppb_re_font.ttf?45804157') format('truetype'), + url('../font/wppb_re_font.svg?45804157#wppb_re_font') format('svg'); + font-weight: normal; + font-style: normal; +} +/* Chrome hack: SVG is rendered more smooth in Windozze. 100% magic, uncomment if you need it. */ +/* Note, that will break hinting! In other OS-es font will be not as sharp as it could be */ +/* +@media screen and (-webkit-min-device-pixel-ratio:0) { + @font-face { + font-family: 'wppb_re_font'; + src: url('../font/wppb_re_font.svg?45804157#wppb_re_font') format('svg'); + } +} +*/ + +[class^="icon-wppb-re-"]:before, [class*=" icon-wppb-re-"]:before { + font-family: "wppb_re_font"; + font-style: normal; + font-weight: normal; + speak: none; + + display: inline-block; + text-decoration: inherit; + width: 1em; + margin-right: .2em; + text-align: center; + /* opacity: .8; */ + + /* For safety - reset parent styles, that can break glyph codes*/ + font-variant: normal; + text-transform: none; + + /* fix buttons height, for twitter bootstrap */ + line-height: 1em; + + /* Animation center compensation - margins should be symmetric */ + /* remove if not needed */ + margin-left: .2em; + + /* you can be more comfortable with increased icons size */ + /* font-size: 120%; */ + + /* Font smoothing. That was taken from TWBS */ + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + + /* Uncomment for 3D effect */ + /* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */ +} + +.icon-wppb-re-users:before { content: '\e801'; } /* '' */ +.icon-wppb-re-slug:before { content: '\e802'; } /* '' */ +.icon-wppb-re-caps:before { content: '\e803'; } /* '' */ +.icon-wppb-re-spinner:before { content: '\e838'; } /* '' */ + +.post-type-wppb-roles-editor .table-role-info { + font-size: 13px; +} + +.post-type-wppb-roles-editor #post-query-submit { + display: none; +} + +.post-type-wppb-roles-editor .column-role { + width: 25%; +} + +.post-type-wppb-roles-editor .column-capabilities { + width: 15%; + text-align: center; +} + +.post-type-wppb-roles-editor .column-users { + width: 10%; + text-align: center; +} + +.post-type-wppb-roles-editor .wppb-delete-capability-disabled, +.post-type-wppb-roles-editor .row-actions span.delete_notify { + color: #a00; + cursor: not-allowed; +} + +.post-type-wppb-roles-editor .misc-pub-section .icon-wppb-re-users, +.post-type-wppb-roles-editor .misc-pub-section .icon-wppb-re-slug, +.post-type-wppb-roles-editor .misc-pub-section .icon-wppb-re-caps { + font-size: 20px; +} + +.post-type-wppb-roles-editor #wppb-role-edit-add-caps { + height: 100px; +} + +.post-type-wppb-roles-editor #wppb_edit_role_capabilities .select2 .select2-container { + padding: 0 5px 5px 0 !important; +} + +.post-type-wppb-roles-editor #wppb_edit_role_capabilities a.button-primary { + vertical-align: top; + margin: 1px 0 0 10px; + height: 32px; + line-height: 30px; +} + +.post-type-wppb-roles-editor #wppb_edit_role_capabilities #wppb-add-new-cap-link { + margin: 10px 5px; +} + +.post-type-wppb-roles-editor #wppb_edit_role_capabilities #wppb-add-new-cap-link a:link, +.post-type-wppb-roles-editor #wppb_edit_role_capabilities #wppb-add-new-cap-link a:hover, +.post-type-wppb-roles-editor #wppb_edit_role_capabilities #wppb-add-new-cap-link a:visited, +.post-type-wppb-roles-editor #wppb_edit_role_capabilities #wppb-add-new-cap-link a:active { + text-decoration: none; + box-shadow: none; +} + +.post-type-wppb-roles-editor #wppb_edit_role_capabilities .wppb-add-new-cap-input { + display: none; + vertical-align: middle; + width: 40%; + line-height: 20px; + padding-bottom: 10px; + border: 1px solid #AAAAAA; + border-radius: 4px; + outline: none; + box-shadow: none; + font-size: 13px; + margin: 0; +} + +.post-type-wppb-roles-editor #wppb_edit_role_capabilities .wppb-add-new-cap-input:focus { + border: 1px solid #000; + outline: none; + box-shadow: none; +} + +.post-type-wppb-roles-editor #wppb-duplicate-capability-error, +.post-type-wppb-roles-editor #wppb-hidden-capability-error, +.post-type-wppb-roles-editor #wppb-add-capability-error { + border-left: 3px solid #a00; + display: none; + color: #a00; + font-size: 14px; + margin-left: 6px; + padding: 5px 10px; + line-height: 35px; + vertical-align: top; +} + +.post-type-wppb-roles-editor #wppb-capabilities-tabs { + float: left; + width: 11%; + min-width: 150px; + padding: 20px 0 0 5px; + margin: 0; +} + +.post-type-wppb-roles-editor #wppb-capabilities-tabs .wppb-role-editor-tab-title { + margin: 5px 0.5% 5px 0.5%; + /*padding: 10px 0 10px 10px;*/ + background-color: #f7f7f7; +} + +.post-type-wppb-roles-editor #wppb-capabilities-tabs .wppb-role-editor-tab-title i { + margin-right: 10px; + line-height: 25px; +} + +.post-type-wppb-roles-editor #wppb-capabilities-tabs .wppb-role-editor-tab-title a { + text-decoration: none; + color: inherit; + display: block; + padding: 10px 0 10px 10px; + height: 24px; + line-height: 24px; +} + +.post-type-wppb-roles-editor #wppb-capabilities-tabs .wppb-role-editor-tab-title a:active, +.post-type-wppb-roles-editor #wppb-capabilities-tabs .wppb-role-editor-tab-title a:focus, +.post-type-wppb-roles-editor #wppb-capabilities-tabs .wppb-role-editor-tab-title a:hover { + text-decoration: none; + color: #a00; + box-shadow: none; +} + +.post-type-wppb-roles-editor #wppb-capabilities-tabs .wppb-role-editor-tab-title.wppb-role-editor-tab-active { + color: #a00; + font-weight: bold; +} + +.post-type-wppb-roles-editor #wppb-role-edit-table { + padding: 20px 5px 0 5px; + float: right; + width: 84%; +} + +.post-type-wppb-roles-editor .wppb-re-spinner-container { + margin: 5px 3px 0 2px; + padding: 11px 0; + width: 100%; +} + +.post-type-wppb-roles-editor .wppb-re-spinner-container i.icon-wppb-re-spinner { + font-size: 35px; + margin-left: 45%; +} + +.post-type-wppb-roles-editor #wppb-role-edit-table .wppb-role-edit-table-entry { + width: 32.3%; + float: left; + margin: 5px 3px 0 2px; + padding: 6px 0; + background-color: #f7f7f7; + display: block; + height: 32px; +} + +.post-type-wppb-roles-editor #wppb-role-edit-table .wppb-role-edit-table-entry.wppb-new-capability-highlight { + background-color: #e6e6e6; +} + +.post-type-wppb-roles-editor #wppb-role-edit-table .wppb-role-edit-table-entry .wppb-capability { + padding: 0 10px; + width: 70%; + overflow-wrap: break-word; + word-wrap: break-word; + -ms-word-break: break-all; + word-break: break-all; + word-break: break-word; + -ms-hyphens: auto; + -moz-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; + display: inline-block; +} + +.post-type-wppb-roles-editor #wppb-role-edit-table .wppb-role-edit-table-entry .wppb-capability.wppb-new-capability { + color: #0085ba; +} + +.post-type-wppb-roles-editor #wppb-role-edit-table .wppb-role-edit-table-entry .wppb-delete-capability { + float: right; + padding-right: 5px; + display: inline-block; + width: 15%; +} + +.post-type-wppb-roles-editor #wppb-role-edit-table .wppb-role-edit-table-entry .wppb-delete-capability a:link { + text-decoration: none; + color: #a00; +} + +.post-type-wppb-roles-editor #wppb-role-edit-table .wppb-role-edit-table-entry .wppb-delete-capability a:active, +.post-type-wppb-roles-editor #wppb-role-edit-table .wppb-role-edit-table-entry .wppb-delete-capability a:hover, +.post-type-wppb-roles-editor #wppb-role-edit-table .wppb-role-edit-table-entry .wppb-delete-capability a:visited { + text-decoration: none; + color: #FF0000; +} + +.post-type-wppb-roles-editor #wppb-role-edit-table .wppb-role-edit-table-entry.wppb-role-edit-no-cap { + background-color: inherit; +} + +.post-type-wppb-roles-editor #wppb-role-edit-table .wppb-role-edit-table-entry.wppb-role-edit-no-cap span { + color: #a00; +} + +.post-type-wppb-roles-editor #wppb-role-edit-table #wppb-role-edit-caps-clear, +.post-type-wppb-roles-editor #wppb-role-edit-caps-div #wppb-role-edit-divs-clear { + width: 100%; + clear: both; +} + +.post-type-wppb-roles-editor .misc-pub-section #wppb-role-slug { + width: 59%; + margin-left: 5px; + text-transform: lowercase; +} + +.post-type-wppb-roles-editor .misc-pub-section.misc-pub-section-users, +.post-type-wppb-roles-editor .misc-pub-section.misc-pub-section-capabilities, +.post-type-wppb-roles-editor .misc-pub-section.misc-pub-section-edit-slug { + padding-top: 10px; + margin: 5px 0; +} + +.post-type-wppb-roles-editor .misc-pub-section.misc-pub-section-users span, +.post-type-wppb-roles-editor .misc-pub-section.misc-pub-section-capabilities span, +.post-type-wppb-roles-editor .misc-pub-section.misc-pub-section-edit-slug span { + font-size: 14px; + bottom: 1px; + position: relative; +} + +.post-type-wppb-roles-editor .wppb-re-cap-perm-delete { + color: #a00; + font-size: 13px; + float: right; + position: relative; + z-index: 1; +} + +.post-type-wppb-roles-editor .wppb-re-cap-perm-delete:active, +.post-type-wppb-roles-editor .wppb-re-cap-perm-delete:focus, +.post-type-wppb-roles-editor .wppb-re-cap-perm-delete:hover { + color: #000000; + cursor: pointer; +} + +@media screen and ( max-width: 1600px ) { + .post-type-wppb-roles-editor #wppb-role-edit-table .wppb-role-edit-table-entry { + width: 49%; + } + + .post-type-wppb-roles-editor #wppb-role-edit-table { + width: 80%; + } +} + +@media screen and ( max-width: 1400px ) { + .post-type-wppb-roles-editor #wppb-role-edit-table { + width: 76%; + } +} + +@media screen and ( max-width: 1350px ) { + .post-type-wppb-roles-editor #wppb-role-edit-table .wppb-role-edit-table-entry { + width: 100%; + } +} + +@media screen and ( max-width: 1250px ) { + .post-type-wppb-roles-editor #wppb-role-edit-table { + width: 72%; + } +} + +@media screen and ( max-width: 1150px ) { + .post-type-wppb-roles-editor #wppb-role-edit-table { + width: 68%; + } +} + +@media screen and ( max-width: 1100px ) { + .post-type-wppb-roles-editor #wppb-role-edit-table { + width: 62%; + } +} + +@media screen and ( max-width: 850px ) { + .post-type-wppb-roles-editor #wppb-role-edit-table { + width: 70%; + } +} + +@media screen and ( max-width: 782px ) { + .post-type-wppb-roles-editor .column-role input.wppb-role-slug-input { + height: 25px; + } + + .post-type-wppb-roles-editor .column-capabilities, + .post-type-wppb-roles-editor .column-users { + text-align: inherit; + } +} + +@media screen and ( max-width: 650px ) { + .post-type-wppb-roles-editor #wppb-role-edit-table { + width: 100%; + } + + .post-type-wppb-roles-editor #wppb-capabilities-tabs { + width: 100%; + padding: 20px 0 0 0; + } + + .post-type-wppb-roles-editor #wppb-capabilities-tabs .wppb-role-editor-tab-title { + padding: 0 25px 0 5px; + margin: 2px 0; + display: inline-block; + min-width: 40%; + } +} + +@media screen and ( max-width: 450px ) { + .post-type-wppb-roles-editor #wppb-capabilities-tabs .wppb-role-editor-tab-title { + min-width: 91%; + } +} + +.post-type-wppb-roles-editor .wppb-re-spin { + -moz-animation: wppb_re_spin 2s infinite linear; + -o-animation: wppb_re_spin 2s infinite linear; + -webkit-animation: wppb_re_spin 2s infinite linear; + animation: wppb_re_spin 2s infinite linear; + display: inline-block; +} +@-moz-keyframes wppb_re_spin { + 0% { + -moz-transform: rotate(0deg); + -o-transform: rotate(0deg); + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + + 100% { + -moz-transform: rotate(359deg); + -o-transform: rotate(359deg); + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@-webkit-keyframes wppb_re_spin { + 0% { + -moz-transform: rotate(0deg); + -o-transform: rotate(0deg); + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + + 100% { + -moz-transform: rotate(359deg); + -o-transform: rotate(359deg); + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@-o-keyframes wppb_re_spin { + 0% { + -moz-transform: rotate(0deg); + -o-transform: rotate(0deg); + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + + 100% { + -moz-transform: rotate(359deg); + -o-transform: rotate(359deg); + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@-ms-keyframes wppb_re_spin { + 0% { + -moz-transform: rotate(0deg); + -o-transform: rotate(0deg); + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + + 100% { + -moz-transform: rotate(359deg); + -o-transform: rotate(359deg); + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@keyframes wppb_re_spin { + 0% { + -moz-transform: rotate(0deg); + -o-transform: rotate(0deg); + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + + 100% { + -moz-transform: rotate(359deg); + -o-transform: rotate(359deg); + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} + diff --git a/profile-builder/features/roles-editor/assets/font/wppb_re_font.svg b/profile-builder/features/roles-editor/assets/font/wppb_re_font.svg index abdba83..e304901 100644 --- a/profile-builder/features/roles-editor/assets/font/wppb_re_font.svg +++ b/profile-builder/features/roles-editor/assets/font/wppb_re_font.svg @@ -1,18 +1,18 @@ - - - -Copyright (C) 2017 by original authors @ fontello.com - - - - - - - - - - - - - + + + +Copyright (C) 2017 by original authors @ fontello.com + + + + + + + + + + + + + \ No newline at end of file diff --git a/profile-builder/features/roles-editor/assets/js/roles-editor.js b/profile-builder/features/roles-editor/assets/js/roles-editor.js index 1aa355f..27621d6 100644 --- a/profile-builder/features/roles-editor/assets/js/roles-editor.js +++ b/profile-builder/features/roles-editor/assets/js/roles-editor.js @@ -1,510 +1,510 @@ -var wppb_re_capabilities_group = []; -var wppb_re_new_capabilities = {}; -var wppb_re_current_role_capabilities = jQuery.extend( {}, wppb_roles_editor_data.current_role_capabilities ); -var wppb_re_unsaved_capabilities = {}; -var wppb_re_capabilities_to_delete = {}; - -jQuery( document ).ready( function() { - // Disable Enter key - jQuery( window ).keydown( function( e ) { - if( e.keyCode == 13 ) { - event.preventDefault(); - return false; - } - } ); - - // Disable the role title field when editing a role - if( wppb_roles_editor_data.current_screen_action != 'add' ) { - jQuery( '.post-type-wppb-roles-editor input#title' ).attr( 'disabled', 'disabled' ); - } - - var table_roles = jQuery( '.post-type-wppb-roles-editor .wp-list-table.posts tr .row-actions' ); - if( jQuery( table_roles ).find( '.default_role' ) ) { - jQuery( ' — ' + wppb_roles_editor_data.default_role_text + '' ).insertAfter( jQuery( table_roles ).find( '.default_role' ).parent().parent().find( 'strong .row-title' ) ); - } - if( jQuery( table_roles ).find( '.delete_notify.your_role' ) ) { - jQuery( ' — ' + wppb_roles_editor_data.your_role_text + '' ).insertAfter( jQuery( table_roles ).find( '.delete_notify.your_role' ).parent().parent().find( 'strong .row-title' ) ); - } - - // Dynamically change value of the Role Slug field - jQuery( '.post-type-wppb-roles-editor #titlewrap' ).find( '#title' ).change( function() { - if( ! jQuery( '.post-type-wppb-roles-editor #wppb-role-slug' ).val() ) { - jQuery( '.post-type-wppb-roles-editor #wppb-role-slug' ).val( jQuery( this ).val().toLowerCase() ); - } - } ); - - // Create an object with grouped capabilities for the Add Capability select2 - var counter = 1; - jQuery.each( wppb_roles_editor_data.capabilities, function( key, value ) { - var capabilities_single_group = {}; - if( key != 'post_types' ) { - capabilities_single_group = wppb_re_create_capabilities_group( key, value, counter ); - wppb_re_capabilities_group.push( capabilities_single_group ); - counter++; - } else if( key == 'post_types' ) { - jQuery.each( value, function( key, value ) { - capabilities_single_group = wppb_re_create_capabilities_group( key, value, counter ); - wppb_re_capabilities_group.push( capabilities_single_group ); - counter++; - } ); - } - } ); - - // Display the current role capabilities (on single role page) - wppb_re_display_capabilities( 'all' ); - - // Check for already added capabilities and disable them before select2 initialization - wppb_re_disable_select_capabilities( wppb_re_capabilities_group, wppb_roles_editor_data.current_role_capabilities, 'add' ); - - if( wppb_re_getParameterByName( 'wppb_re_clone' ) ) { - var data = { - 'action' : 'get_role_capabilities', - 'security' : jQuery( '.post-type-wppb-roles-editor #wppb-re-ajax-nonce' ).val(), - 'role' : wppb_re_getParameterByName( 'wppb_re_clone' ) - }; - - jQuery( '.post-type-wppb-roles-editor .wppb-role-edit-no-cap' ).remove(); - - jQuery.post( wppb_roles_editor_data.ajaxUrl, data, function( response ) { - if( response != 'no_caps' ) { - jQuery( '.post-type-wppb-roles-editor .wppb-re-spinner-container' ).hide(); - wppb_re_current_role_capabilities = jQuery.extend( wppb_re_current_role_capabilities, JSON.parse( response ) ); - wppb_re_display_capabilities( 'all' ); - wppb_re_disable_select_capabilities( wppb_re_capabilities_group, wppb_re_current_role_capabilities, 'add' ); - } else { - jQuery( '.wppb-re-spinner-container' ).hide(); - wppb_re_no_capabilities_found(); - } - } ); - } - - // Delete a capability - jQuery( '.post-type-wppb-roles-editor #wppb-role-edit-table' ).on( 'click', 'a.wppb-delete-capability-link', function() { - if( ( wppb_roles_editor_data.current_user_role && jQuery.inArray( jQuery( this ).closest( 'span.wppb-delete-capability' ).siblings( 'span.wppb-capability' ).text(), wppb_roles_editor_data.admin_capabilities ) === -1 ) || ! wppb_roles_editor_data.current_user_role ) { - jQuery( this ).closest( 'div.wppb-role-edit-table-entry' ).remove(); - - var deleted_capability = {}; - deleted_capability[jQuery( this ).closest( 'span.wppb-delete-capability' ).siblings( 'span.wppb-capability' ).text()] = jQuery( this ).closest( 'span.wppb-delete-capability' ).siblings( 'span.wppb-capability' ).text(); - wppb_re_capabilities_to_delete[jQuery( this ).closest( 'span.wppb-delete-capability' ).siblings( 'span.wppb-capability' ).text()] = jQuery( this ).closest( 'span.wppb-delete-capability' ).siblings( 'span.wppb-capability' ).text(); - - delete wppb_re_current_role_capabilities[jQuery( this ).closest( 'span.wppb-delete-capability' ).siblings( 'span.wppb-capability' ).text()]; - delete wppb_re_new_capabilities[jQuery( this ).closest( 'span.wppb-delete-capability' ).siblings( 'span.wppb-capability' ).text()]; - - if( jQuery( '.wppb-add-new-cap-input' ).is( ':visible' ) ) { - wppb_re_change_select_to_input(); - } - - wppb_re_disable_select_capabilities( wppb_re_capabilities_group, deleted_capability, 'delete' ); - - if( jQuery( '.wppb-role-edit-table-entry' ).length < 1 ) { - wppb_re_no_capabilities_found(); - } - - wppb_re_number_of_capabilities(); - } - } ); - - // Change between select2 with all existing capabilities and input to add a new capability - jQuery( '.post-type-wppb-roles-editor a.wppb-add-new-cap-link' ).click( function() { - wppb_re_change_select_to_input(); - } ); - - jQuery( '.post-type-wppb-roles-editor .wppb-role-editor-tab' ).click( function() { - wppb_re_tabs_handler( jQuery( this ) ); - } ); - - wppb_re_form_submit(); - - wppb_re_number_of_capabilities(); - - // Display number of users for current role - if( wppb_roles_editor_data.current_role_users_count !== null ) { - jQuery( '.post-type-wppb-roles-editor .misc-pub-section.misc-pub-section-users span' ).find( 'strong' ).text( wppb_roles_editor_data.current_role_users_count ); - } - - // Check if role has a title or return an error if not - jQuery( 'body' ).on( 'submit.edit-post', '#post', function() { - if( jQuery( '.post-type-wppb-roles-editor #title' ).val().replace( / /g, '' ).length === 0 ) { - window.alert( wppb_roles_editor_data.role_name_required_error_text ); - jQuery( '.post-type-wppb-roles-editor #major-publishing-actions .spinner' ).hide(); - jQuery( '.post-type-wppb-roles-editor #major-publishing-actions' ).find( ':button, :submit, a.submitdelete, #post-preview' ).removeClass( 'disabled' ); - jQuery( '.post-type-wppb-roles-editor #title' ).focus(); - - wppb_re_form_submit(); - - return false; - } else { - jQuery( '.post-type-wppb-roles-editor #major-publishing-actions .spinner' ).show(); - } - } ); -} ); - -function wppb_re_form_submit() { - jQuery( '.post-type-wppb-roles-editor #publishing-action #publish' ).unbind( 'click' ).one( 'click', function( e ) { - e.preventDefault(); - jQuery( this ).addClass( 'disabled' ); - jQuery( this ).siblings( '.spinner' ).addClass( 'is-active' ); - wppb_re_update_role_capabilities(); - } ); -} - -function wppb_re_no_capabilities_found() { - jQuery( '.post-type-wppb-roles-editor #wppb-role-edit-table' ).find( '#wppb-role-edit-caps-clear' ).after( - '
            ' + - '' + wppb_roles_editor_data.no_capabilities_found_text + '' + - '
            ' - ); -} - -function wppb_re_number_of_capabilities() { - var count = 0; - var i; - - for( i in wppb_re_current_role_capabilities ) { - if( wppb_re_current_role_capabilities.hasOwnProperty( i ) ) { - count++; - } - } - - jQuery( '.post-type-wppb-roles-editor .misc-pub-section.misc-pub-section-capabilities span' ).find( 'strong' ).text( count ); -} - -function wppb_re_tabs_handler( tab ) { - wppb_re_display_capabilities( jQuery( tab ).data( 'wppb-re-tab' ) ); - - jQuery( '.post-type-wppb-roles-editor .wppb-role-editor-tab-title.wppb-role-editor-tab-active' ).removeClass( 'wppb-role-editor-tab-active' ); - jQuery( tab ).closest( '.wppb-role-editor-tab-title' ).addClass( 'wppb-role-editor-tab-active' ); -} - -function wppb_re_disable_select_capabilities( wppb_re_capabilities_group, capabilities, action ) { - if( capabilities != null ) { - jQuery.each( wppb_re_capabilities_group, function( key, value ) { - jQuery.each( value['children'], function( key, value ) { - if( value['text'] in capabilities ) { - if( action == 'add' ) { - value['disabled'] = true; - } else if( action == 'delete' ) { - value['disabled'] = false; - } - } - } ); - } ); - } - - wppb_re_initialize_select2( wppb_re_capabilities_group ); -} - -function wppb_re_initialize_select2( wppb_re_capabilities_group ) { - var capabilities_select = jQuery( '.wppb-capabilities-select' ); - - capabilities_select.empty(); - capabilities_select.select2( { - placeholder: wppb_roles_editor_data.select2_placeholder_text, - allowClear: true, - data: wppb_re_capabilities_group, - templateResult: function( data ) { - if( data.id == null || jQuery.inArray( data.text, wppb_roles_editor_data.capabilities['custom']['capabilities'] ) === -1 ) { - return data.text; - } - - var option = jQuery( '' ); - var delete_cap = jQuery( '' + wppb_roles_editor_data.delete_permanently_text + '' ); - - delete_cap.on( 'mouseup', function( event ) { - event.stopPropagation(); - } ); - - delete_cap.on( 'click', function( event ) { - if( confirm( wppb_roles_editor_data.capability_text + ': ' + jQuery( this ).siblings( 'span' ).text() + '\n\n' + wppb_roles_editor_data.capability_perm_delete_text ) ) { - wppb_re_delete_capability_permanently( jQuery( this ).siblings( 'span' ).text() ); - } - } ); - - option.text( data.text ); - option = option.add( delete_cap ); - - return option; - } - } ); -} - -function wppb_re_delete_capability_permanently( capability ) { - var data = { - 'action' : 'delete_capability_permanently', - 'security' : jQuery( '.post-type-wppb-roles-editor #wppb-re-ajax-nonce' ).val(), - 'capability' : capability - }; - - jQuery( '.post-type-wppb-roles-editor .wppb-role-edit-table-entry' ).remove(); - jQuery( '.post-type-wppb-roles-editor .wppb-re-spinner-container' ).show(); - - jQuery.post( wppb_roles_editor_data.ajaxUrl, data, function( response ) { - window.location.reload(); - } ); -} - -function wppb_re_create_capabilities_group( key, value, counter ) { - var capabilities_single_group_caps = {}; - var capabilities_single_group_caps_array = []; - - jQuery.each( value['capabilities'], function( key, value ) { - capabilities_single_group_caps = { - id: value + '_' + counter, - text: value - }; - - capabilities_single_group_caps_array.push( capabilities_single_group_caps ); - } ); - - return { - category: key, - text: value['label'], - children: capabilities_single_group_caps_array - }; -} - -function wppb_re_display_capabilities( action ) { - jQuery( '.post-type-wppb-roles-editor .wppb-re-spinner-container' ).hide(); - jQuery( '.post-type-wppb-roles-editor .wppb-role-edit-table-entry' ).remove(); - - var capabilities; - if( action == 'all' ) { - capabilities = wppb_re_current_role_capabilities; - } else { - capabilities = wppb_re_capabilities_group; - } - - jQuery.each( capabilities, function( key, value ) { - var table = jQuery( '#wppb-role-edit-table' ); - - if( action == 'all' ) { - wppb_re_display_capability( key ); - } else { - if( value['category'] == action ) { - jQuery.each( value['children'], function( key, value ) { - if( wppb_re_current_role_capabilities != null && value['text'] in wppb_re_current_role_capabilities ) { - wppb_re_display_capability( value['text'] ); - } - } ); - } - - if( value['category'] == action && action == 'custom' ) { - if( ! jQuery.isEmptyObject( wppb_re_new_capabilities ) ) { - jQuery.each( wppb_re_new_capabilities, function( key, value ) { - if( ! ( value in wppb_roles_editor_data.all_capabilities ) ) { - var new_capability_check = 0; - jQuery.each( wppb_roles_editor_data.capabilities, function( key2, value2 ) { - if( value2['label'] && value2['label'] != 'Custom' && jQuery.inArray( value, value2['capabilities'] ) !== -1 ) { - new_capability_check++; - } - } ); - - if( new_capability_check == 0 ) { - wppb_re_display_capability( value ); - } - } - } ); - } - } - } - } ); - - if( jQuery( '.post-type-wppb-roles-editor .wppb-role-edit-table-entry' ).length ) { - jQuery( '.post-type-wppb-roles-editor .wppb-role-edit-no-cap' ).remove(); - } else { - wppb_re_no_capabilities_found(); - } -} - -function wppb_re_display_capability( capability ) { - var title = ''; - var wppb_capability_class = 'wppb-capability'; - if( ! wppb_roles_editor_data.current_role_capabilities || ( wppb_roles_editor_data.current_role_capabilities && ! ( capability in wppb_roles_editor_data.current_role_capabilities ) ) ) { - wppb_capability_class = wppb_capability_class + ' wppb-new-capability'; - title = 'title = "' + wppb_roles_editor_data.new_cap_update_title_text + '"'; - } else if( wppb_re_getParameterByName( 'wppb_re_clone' ) && ! wppb_roles_editor_data.current_role_capabilities ) { - wppb_capability_class = wppb_capability_class + ' wppb-new-capability'; - title = 'title = "' + wppb_roles_editor_data.new_cap_publish_title_text + '"'; - } - - var delete_link = 'Delete'; - if( wppb_roles_editor_data.current_user_role && jQuery.inArray( capability, wppb_roles_editor_data.admin_capabilities ) !== -1 ) { - delete_link = '' + wppb_roles_editor_data.delete_text + ''; - } - - jQuery( '.post-type-wppb-roles-editor #wppb-role-edit-table' ).find( '#wppb-role-edit-caps-clear' ).after( - '
            ' + - '' + capability + '' + - '' + delete_link + '' + - '
            ' - ); -} - -function wppb_re_add_capability() { - var capabilities_select = jQuery( '.post-type-wppb-roles-editor .wppb-capabilities-select' ); - var new_capability_input = jQuery( '.post-type-wppb-roles-editor .wppb-add-new-cap-input' ); - var table = jQuery( '.post-type-wppb-roles-editor #wppb-role-edit-table' ); - var capabilities = {}; - var no_duplicates = {}; - - if( jQuery( '.post-type-wppb-roles-editor .select2.select2-container' ).is( ':visible' ) && jQuery( capabilities_select ).val() != null ) { - jQuery( capabilities_select ).find( 'option:selected' ).each( function() { - if( ! no_duplicates[jQuery( this ).text()] ) { - if( ! jQuery( '.post-type-wppb-roles-editor .wppb-role-editor-tab.wppb-role-editor-all' ).closest( 'li.wppb-role-editor-tab-title' ).hasClass( 'wppb-role-editor-tab-active' ) ) { - wppb_re_tabs_handler( jQuery( '.post-type-wppb-roles-editor .wppb-role-editor-tab.wppb-role-editor-all' ) ); - } - - var title = ''; - var wppb_capability_class = 'wppb-capability'; - if( ! wppb_roles_editor_data.current_role_capabilities || ( wppb_roles_editor_data.current_role_capabilities && ! ( jQuery( this ).text() in wppb_roles_editor_data.current_role_capabilities ) ) ) { - wppb_capability_class = wppb_capability_class + ' wppb-new-capability'; - wppb_re_unsaved_capabilities[jQuery( this ).text()] = jQuery( this ).text(); - title = 'title = "' + wppb_roles_editor_data.new_cap_update_title_text + '"'; - } else if( wppb_re_getParameterByName( 'wppb_re_clone' ) && ! wppb_roles_editor_data.current_role_capabilities ) { - wppb_capability_class = wppb_capability_class + ' wppb-new-capability'; - title = 'title = "' + wppb_roles_editor_data.new_cap_publish_title_text + '"'; - } - - jQuery( '.post-type-wppb-roles-editor .wppb-role-edit-no-cap' ).remove(); - - jQuery( table ).find( '#wppb-role-edit-caps-clear' ).after( - '
            ' + - '' + jQuery( this ).text() + '' + - '' + wppb_roles_editor_data.delete_text + '' + - '
            ' ); - - capabilities[jQuery( this ).text()] = jQuery( this ).text(); - no_duplicates[jQuery( this ).text()] = jQuery( this ).text(); - - delete wppb_re_capabilities_to_delete[jQuery( this ).text()]; - } - } ); - - wppb_re_new_capability( capabilities ); - - wppb_re_disable_select_capabilities( wppb_re_capabilities_group, capabilities, 'add' ); - - jQuery( capabilities_select ).val( null ).trigger( 'change' ); - - wppb_re_number_of_capabilities(); - - setTimeout( function() { - jQuery( '.post-type-wppb-roles-editor .wppb-role-edit-table-entry' ).removeClass( 'wppb-new-capability-highlight' ); - }, 500 ); - } else if( jQuery( new_capability_input ).is( ':visible' ) && jQuery( new_capability_input ).val().length != 0 ) { - var new_capability_value = jQuery( new_capability_input ).val(); - new_capability_value = new_capability_value.trim().replace( /<.*?>/g, '' ).replace( /\s/g, '_' ).replace( /[^a-zA-Z0-9_]/g, '' ); - - if( new_capability_value && ( ! wppb_roles_editor_data.hidden_capabilities || ! ( new_capability_value in wppb_roles_editor_data.hidden_capabilities ) ) ) { - if( ! ( new_capability_value in wppb_re_current_role_capabilities ) && ! ( new_capability_value in wppb_re_new_capabilities ) ) { - wppb_re_tabs_handler( jQuery( '.post-type-wppb-roles-editor .wppb-role-editor-tab.wppb-role-editor-all' ) ); - - var title = ''; - var wppb_capability_class = 'wppb-capability'; - if( ! wppb_roles_editor_data.current_role_capabilities || ( wppb_roles_editor_data.current_role_capabilities && ! ( new_capability_value in wppb_roles_editor_data.current_role_capabilities ) ) ) { - wppb_capability_class = wppb_capability_class + ' wppb-new-capability'; - wppb_re_unsaved_capabilities[new_capability_value] = new_capability_value; - title = 'title = "' + wppb_roles_editor_data.new_cap_update_title_text + '"'; - } else if( wppb_re_getParameterByName( 'wppb_re_clone' ) && ! wppb_roles_editor_data.current_role_capabilities ) { - wppb_capability_class = wppb_capability_class + ' wppb-new-capability'; - title = 'title = "' + wppb_roles_editor_data.new_cap_publish_title_text + '"'; - } - - jQuery( '.post-type-wppb-roles-editor .wppb-role-edit-no-cap' ).remove(); - - jQuery( table ).find( '#wppb-role-edit-caps-clear' ).after( - '
            ' + - '' + new_capability_value + '' + - '' + wppb_roles_editor_data.delete_text + '' + - '
            ' ); - - capabilities[new_capability_value] = new_capability_value; - delete wppb_re_capabilities_to_delete[new_capability_value]; - - wppb_re_change_select_to_input(); - - wppb_re_new_capability( capabilities ); - - wppb_re_disable_select_capabilities( wppb_re_capabilities_group, capabilities, 'add' ); - - jQuery( new_capability_input ).val( '' ); - - wppb_re_number_of_capabilities(); - - setTimeout( function() { - jQuery( '.post-type-wppb-roles-editor .wppb-role-edit-table-entry' ).removeClass( 'wppb-new-capability-highlight' ); - }, 500 ); - } else { - jQuery( new_capability_input ).val( '' ); - - jQuery( '.post-type-wppb-roles-editor #wppb-duplicate-capability-error' ).show().delay( 3000 ).fadeOut(); - } - } else if( wppb_roles_editor_data.hidden_capabilities && new_capability_value in wppb_roles_editor_data.hidden_capabilities ) { - jQuery( '.post-type-wppb-roles-editor #wppb-hidden-capability-error' ).show().delay( 3000 ).fadeOut(); - } else { - jQuery( '.post-type-wppb-roles-editor #wppb-add-capability-error' ).show().delay( 3000 ).fadeOut(); - } - } else { - jQuery( '.post-type-wppb-roles-editor #wppb-add-capability-error' ).show().delay( 3000 ).fadeOut(); - } -} - -function wppb_re_new_capability( capabilities ) { - jQuery.each( capabilities, function( key, value ) { - if( ! ( value in wppb_roles_editor_data.all_capabilities ) || ! ( value in wppb_re_current_role_capabilities ) ) { - wppb_re_new_capabilities[value] = value; - } - } ); - - jQuery.extend( wppb_re_current_role_capabilities, wppb_re_new_capabilities ); -} - -function wppb_re_update_role_capabilities() { - jQuery( '.post-type-wppb-roles-editor #wppb-role-slug-hidden' ).val( jQuery( '#wppb-role-slug' ).val() ); - - var data = { - 'action' : 'update_role_capabilities', - 'security' : jQuery( '.post-type-wppb-roles-editor #wppb-re-ajax-nonce' ).val(), - 'role_display_name' : jQuery( '.post-type-wppb-roles-editor #titlediv' ).find( '#title' ).val(), - 'role' : jQuery( '.post-type-wppb-roles-editor #wppb-role-slug' ).val(), - 'new_capabilities' : wppb_re_unsaved_capabilities, - 'all_capabilities' : wppb_re_current_role_capabilities, - 'capabilities_to_delete' : wppb_re_capabilities_to_delete - }; - - jQuery.post( wppb_roles_editor_data.ajaxUrl, data, function( response ) { - jQuery( '.post-type-wppb-roles-editor #publishing-action #publish' ).removeClass( 'disabled' ).trigger( 'click' ); - } ); -} - -function wppb_re_change_select_to_input() { - if( jQuery( '.post-type-wppb-roles-editor .select2.select2-container' ).is( ':visible' ) ) { - jQuery( '.post-type-wppb-roles-editor .select2.select2-container' ).hide(); - jQuery( '.post-type-wppb-roles-editor .wppb-add-new-cap-input' ).show(); - jQuery( '.post-type-wppb-roles-editor a.wppb-add-new-cap-link' ).text( wppb_roles_editor_data.cancel_text ); - } else { - jQuery( '.post-type-wppb-roles-editor .select2.select2-container' ).show(); - jQuery( '.post-type-wppb-roles-editor .wppb-add-new-cap-input' ).hide(); - jQuery( '.post-type-wppb-roles-editor a.wppb-add-new-cap-link' ).text( wppb_roles_editor_data.add_new_capability_text ); - } -} - -function wppb_re_getParameterByName( name, url ) { - if( ! url ) { - url = window.location.href; - } - - name = name.replace( /[\[\]]/g, "\\$&" ); - - var regex = new RegExp( "[?&]" + name + "(=([^&#]*)|&|#|$)" ), results = regex.exec( url ); - - if( ! results ) { - return null; - } - - if( ! results[2] ) { - return ''; - } - - return decodeURIComponent( results[2].replace( /\+/g, " " ) ); -} +var wppb_re_capabilities_group = []; +var wppb_re_new_capabilities = {}; +var wppb_re_current_role_capabilities = jQuery.extend( {}, wppb_roles_editor_data.current_role_capabilities ); +var wppb_re_unsaved_capabilities = {}; +var wppb_re_capabilities_to_delete = {}; + +jQuery( document ).ready( function() { + // Disable Enter key + jQuery( window ).keydown( function( e ) { + if( e.keyCode == 13 ) { + event.preventDefault(); + return false; + } + } ); + + // Disable the role title field when editing a role + if( wppb_roles_editor_data.current_screen_action != 'add' ) { + jQuery( '.post-type-wppb-roles-editor input#title' ).attr( 'disabled', 'disabled' ); + } + + var table_roles = jQuery( '.post-type-wppb-roles-editor .wp-list-table.posts tr .row-actions' ); + if( jQuery( table_roles ).find( '.default_role' ) ) { + jQuery( ' — ' + wppb_roles_editor_data.default_role_text + '' ).insertAfter( jQuery( table_roles ).find( '.default_role' ).parent().parent().find( 'strong .row-title' ) ); + } + if( jQuery( table_roles ).find( '.delete_notify.your_role' ) ) { + jQuery( ' — ' + wppb_roles_editor_data.your_role_text + '' ).insertAfter( jQuery( table_roles ).find( '.delete_notify.your_role' ).parent().parent().find( 'strong .row-title' ) ); + } + + // Dynamically change value of the Role Slug field + jQuery( '.post-type-wppb-roles-editor #titlewrap' ).find( '#title' ).change( function() { + if( ! jQuery( '.post-type-wppb-roles-editor #wppb-role-slug' ).val() ) { + jQuery( '.post-type-wppb-roles-editor #wppb-role-slug' ).val( jQuery( this ).val().toLowerCase() ); + } + } ); + + // Create an object with grouped capabilities for the Add Capability select2 + var counter = 1; + jQuery.each( wppb_roles_editor_data.capabilities, function( key, value ) { + var capabilities_single_group = {}; + if( key != 'post_types' ) { + capabilities_single_group = wppb_re_create_capabilities_group( key, value, counter ); + wppb_re_capabilities_group.push( capabilities_single_group ); + counter++; + } else if( key == 'post_types' ) { + jQuery.each( value, function( key, value ) { + capabilities_single_group = wppb_re_create_capabilities_group( key, value, counter ); + wppb_re_capabilities_group.push( capabilities_single_group ); + counter++; + } ); + } + } ); + + // Display the current role capabilities (on single role page) + wppb_re_display_capabilities( 'all' ); + + // Check for already added capabilities and disable them before select2 initialization + wppb_re_disable_select_capabilities( wppb_re_capabilities_group, wppb_roles_editor_data.current_role_capabilities, 'add' ); + + if( wppb_re_getParameterByName( 'wppb_re_clone' ) ) { + var data = { + 'action' : 'get_role_capabilities', + 'security' : jQuery( '.post-type-wppb-roles-editor #wppb-re-ajax-nonce' ).val(), + 'role' : wppb_re_getParameterByName( 'wppb_re_clone' ) + }; + + jQuery( '.post-type-wppb-roles-editor .wppb-role-edit-no-cap' ).remove(); + + jQuery.post( wppb_roles_editor_data.ajaxUrl, data, function( response ) { + if( response != 'no_caps' ) { + jQuery( '.post-type-wppb-roles-editor .wppb-re-spinner-container' ).hide(); + wppb_re_current_role_capabilities = jQuery.extend( wppb_re_current_role_capabilities, JSON.parse( response ) ); + wppb_re_display_capabilities( 'all' ); + wppb_re_disable_select_capabilities( wppb_re_capabilities_group, wppb_re_current_role_capabilities, 'add' ); + } else { + jQuery( '.wppb-re-spinner-container' ).hide(); + wppb_re_no_capabilities_found(); + } + } ); + } + + // Delete a capability + jQuery( '.post-type-wppb-roles-editor #wppb-role-edit-table' ).on( 'click', 'a.wppb-delete-capability-link', function() { + if( ( wppb_roles_editor_data.current_user_role && jQuery.inArray( jQuery( this ).closest( 'span.wppb-delete-capability' ).siblings( 'span.wppb-capability' ).text(), wppb_roles_editor_data.admin_capabilities ) === -1 ) || ! wppb_roles_editor_data.current_user_role ) { + jQuery( this ).closest( 'div.wppb-role-edit-table-entry' ).remove(); + + var deleted_capability = {}; + deleted_capability[jQuery( this ).closest( 'span.wppb-delete-capability' ).siblings( 'span.wppb-capability' ).text()] = jQuery( this ).closest( 'span.wppb-delete-capability' ).siblings( 'span.wppb-capability' ).text(); + wppb_re_capabilities_to_delete[jQuery( this ).closest( 'span.wppb-delete-capability' ).siblings( 'span.wppb-capability' ).text()] = jQuery( this ).closest( 'span.wppb-delete-capability' ).siblings( 'span.wppb-capability' ).text(); + + delete wppb_re_current_role_capabilities[jQuery( this ).closest( 'span.wppb-delete-capability' ).siblings( 'span.wppb-capability' ).text()]; + delete wppb_re_new_capabilities[jQuery( this ).closest( 'span.wppb-delete-capability' ).siblings( 'span.wppb-capability' ).text()]; + + if( jQuery( '.wppb-add-new-cap-input' ).is( ':visible' ) ) { + wppb_re_change_select_to_input(); + } + + wppb_re_disable_select_capabilities( wppb_re_capabilities_group, deleted_capability, 'delete' ); + + if( jQuery( '.wppb-role-edit-table-entry' ).length < 1 ) { + wppb_re_no_capabilities_found(); + } + + wppb_re_number_of_capabilities(); + } + } ); + + // Change between select2 with all existing capabilities and input to add a new capability + jQuery( '.post-type-wppb-roles-editor a.wppb-add-new-cap-link' ).click( function() { + wppb_re_change_select_to_input(); + } ); + + jQuery( '.post-type-wppb-roles-editor .wppb-role-editor-tab' ).click( function() { + wppb_re_tabs_handler( jQuery( this ) ); + } ); + + wppb_re_form_submit(); + + wppb_re_number_of_capabilities(); + + // Display number of users for current role + if( wppb_roles_editor_data.current_role_users_count !== null ) { + jQuery( '.post-type-wppb-roles-editor .misc-pub-section.misc-pub-section-users span' ).find( 'strong' ).text( wppb_roles_editor_data.current_role_users_count ); + } + + // Check if role has a title or return an error if not + jQuery( 'body' ).on( 'submit.edit-post', '#post', function() { + if( jQuery( '.post-type-wppb-roles-editor #title' ).val().replace( / /g, '' ).length === 0 ) { + window.alert( wppb_roles_editor_data.role_name_required_error_text ); + jQuery( '.post-type-wppb-roles-editor #major-publishing-actions .spinner' ).hide(); + jQuery( '.post-type-wppb-roles-editor #major-publishing-actions' ).find( ':button, :submit, a.submitdelete, #post-preview' ).removeClass( 'disabled' ); + jQuery( '.post-type-wppb-roles-editor #title' ).focus(); + + wppb_re_form_submit(); + + return false; + } else { + jQuery( '.post-type-wppb-roles-editor #major-publishing-actions .spinner' ).show(); + } + } ); +} ); + +function wppb_re_form_submit() { + jQuery( '.post-type-wppb-roles-editor #publishing-action #publish' ).unbind( 'click' ).one( 'click', function( e ) { + e.preventDefault(); + jQuery( this ).addClass( 'disabled' ); + jQuery( this ).siblings( '.spinner' ).addClass( 'is-active' ); + wppb_re_update_role_capabilities(); + } ); +} + +function wppb_re_no_capabilities_found() { + jQuery( '.post-type-wppb-roles-editor #wppb-role-edit-table' ).find( '#wppb-role-edit-caps-clear' ).after( + '
            ' + + '' + wppb_roles_editor_data.no_capabilities_found_text + '' + + '
            ' + ); +} + +function wppb_re_number_of_capabilities() { + var count = 0; + var i; + + for( i in wppb_re_current_role_capabilities ) { + if( wppb_re_current_role_capabilities.hasOwnProperty( i ) ) { + count++; + } + } + + jQuery( '.post-type-wppb-roles-editor .misc-pub-section.misc-pub-section-capabilities span' ).find( 'strong' ).text( count ); +} + +function wppb_re_tabs_handler( tab ) { + wppb_re_display_capabilities( jQuery( tab ).data( 'wppb-re-tab' ) ); + + jQuery( '.post-type-wppb-roles-editor .wppb-role-editor-tab-title.wppb-role-editor-tab-active' ).removeClass( 'wppb-role-editor-tab-active' ); + jQuery( tab ).closest( '.wppb-role-editor-tab-title' ).addClass( 'wppb-role-editor-tab-active' ); +} + +function wppb_re_disable_select_capabilities( wppb_re_capabilities_group, capabilities, action ) { + if( capabilities != null ) { + jQuery.each( wppb_re_capabilities_group, function( key, value ) { + jQuery.each( value['children'], function( key, value ) { + if( value['text'] in capabilities ) { + if( action == 'add' ) { + value['disabled'] = true; + } else if( action == 'delete' ) { + value['disabled'] = false; + } + } + } ); + } ); + } + + wppb_re_initialize_select2( wppb_re_capabilities_group ); +} + +function wppb_re_initialize_select2( wppb_re_capabilities_group ) { + var capabilities_select = jQuery( '.wppb-capabilities-select' ); + + capabilities_select.empty(); + capabilities_select.select2( { + placeholder: wppb_roles_editor_data.select2_placeholder_text, + allowClear: true, + data: wppb_re_capabilities_group, + templateResult: function( data ) { + if( data.id == null || jQuery.inArray( data.text, wppb_roles_editor_data.capabilities['custom']['capabilities'] ) === -1 ) { + return data.text; + } + + var option = jQuery( '' ); + var delete_cap = jQuery( '' + wppb_roles_editor_data.delete_permanently_text + '' ); + + delete_cap.on( 'mouseup', function( event ) { + event.stopPropagation(); + } ); + + delete_cap.on( 'click', function( event ) { + if( confirm( wppb_roles_editor_data.capability_text + ': ' + jQuery( this ).siblings( 'span' ).text() + '\n\n' + wppb_roles_editor_data.capability_perm_delete_text ) ) { + wppb_re_delete_capability_permanently( jQuery( this ).siblings( 'span' ).text() ); + } + } ); + + option.text( data.text ); + option = option.add( delete_cap ); + + return option; + } + } ); +} + +function wppb_re_delete_capability_permanently( capability ) { + var data = { + 'action' : 'delete_capability_permanently', + 'security' : jQuery( '.post-type-wppb-roles-editor #wppb-re-ajax-nonce' ).val(), + 'capability' : capability + }; + + jQuery( '.post-type-wppb-roles-editor .wppb-role-edit-table-entry' ).remove(); + jQuery( '.post-type-wppb-roles-editor .wppb-re-spinner-container' ).show(); + + jQuery.post( wppb_roles_editor_data.ajaxUrl, data, function( response ) { + window.location.reload(); + } ); +} + +function wppb_re_create_capabilities_group( key, value, counter ) { + var capabilities_single_group_caps = {}; + var capabilities_single_group_caps_array = []; + + jQuery.each( value['capabilities'], function( key, value ) { + capabilities_single_group_caps = { + id: value + '_' + counter, + text: value + }; + + capabilities_single_group_caps_array.push( capabilities_single_group_caps ); + } ); + + return { + category: key, + text: value['label'], + children: capabilities_single_group_caps_array + }; +} + +function wppb_re_display_capabilities( action ) { + jQuery( '.post-type-wppb-roles-editor .wppb-re-spinner-container' ).hide(); + jQuery( '.post-type-wppb-roles-editor .wppb-role-edit-table-entry' ).remove(); + + var capabilities; + if( action == 'all' ) { + capabilities = wppb_re_current_role_capabilities; + } else { + capabilities = wppb_re_capabilities_group; + } + + jQuery.each( capabilities, function( key, value ) { + var table = jQuery( '#wppb-role-edit-table' ); + + if( action == 'all' ) { + wppb_re_display_capability( key ); + } else { + if( value['category'] == action ) { + jQuery.each( value['children'], function( key, value ) { + if( wppb_re_current_role_capabilities != null && value['text'] in wppb_re_current_role_capabilities ) { + wppb_re_display_capability( value['text'] ); + } + } ); + } + + if( value['category'] == action && action == 'custom' ) { + if( ! jQuery.isEmptyObject( wppb_re_new_capabilities ) ) { + jQuery.each( wppb_re_new_capabilities, function( key, value ) { + if( ! ( value in wppb_roles_editor_data.all_capabilities ) ) { + var new_capability_check = 0; + jQuery.each( wppb_roles_editor_data.capabilities, function( key2, value2 ) { + if( value2['label'] && value2['label'] != 'Custom' && jQuery.inArray( value, value2['capabilities'] ) !== -1 ) { + new_capability_check++; + } + } ); + + if( new_capability_check == 0 ) { + wppb_re_display_capability( value ); + } + } + } ); + } + } + } + } ); + + if( jQuery( '.post-type-wppb-roles-editor .wppb-role-edit-table-entry' ).length ) { + jQuery( '.post-type-wppb-roles-editor .wppb-role-edit-no-cap' ).remove(); + } else { + wppb_re_no_capabilities_found(); + } +} + +function wppb_re_display_capability( capability ) { + var title = ''; + var wppb_capability_class = 'wppb-capability'; + if( ! wppb_roles_editor_data.current_role_capabilities || ( wppb_roles_editor_data.current_role_capabilities && ! ( capability in wppb_roles_editor_data.current_role_capabilities ) ) ) { + wppb_capability_class = wppb_capability_class + ' wppb-new-capability'; + title = 'title = "' + wppb_roles_editor_data.new_cap_update_title_text + '"'; + } else if( wppb_re_getParameterByName( 'wppb_re_clone' ) && ! wppb_roles_editor_data.current_role_capabilities ) { + wppb_capability_class = wppb_capability_class + ' wppb-new-capability'; + title = 'title = "' + wppb_roles_editor_data.new_cap_publish_title_text + '"'; + } + + var delete_link = 'Delete'; + if( wppb_roles_editor_data.current_user_role && jQuery.inArray( capability, wppb_roles_editor_data.admin_capabilities ) !== -1 ) { + delete_link = '' + wppb_roles_editor_data.delete_text + ''; + } + + jQuery( '.post-type-wppb-roles-editor #wppb-role-edit-table' ).find( '#wppb-role-edit-caps-clear' ).after( + '
            ' + + '' + capability + '' + + '' + delete_link + '' + + '
            ' + ); +} + +function wppb_re_add_capability() { + var capabilities_select = jQuery( '.post-type-wppb-roles-editor .wppb-capabilities-select' ); + var new_capability_input = jQuery( '.post-type-wppb-roles-editor .wppb-add-new-cap-input' ); + var table = jQuery( '.post-type-wppb-roles-editor #wppb-role-edit-table' ); + var capabilities = {}; + var no_duplicates = {}; + + if( jQuery( '.post-type-wppb-roles-editor .select2.select2-container' ).is( ':visible' ) && jQuery( capabilities_select ).val() != null ) { + jQuery( capabilities_select ).find( 'option:selected' ).each( function() { + if( ! no_duplicates[jQuery( this ).text()] ) { + if( ! jQuery( '.post-type-wppb-roles-editor .wppb-role-editor-tab.wppb-role-editor-all' ).closest( 'li.wppb-role-editor-tab-title' ).hasClass( 'wppb-role-editor-tab-active' ) ) { + wppb_re_tabs_handler( jQuery( '.post-type-wppb-roles-editor .wppb-role-editor-tab.wppb-role-editor-all' ) ); + } + + var title = ''; + var wppb_capability_class = 'wppb-capability'; + if( ! wppb_roles_editor_data.current_role_capabilities || ( wppb_roles_editor_data.current_role_capabilities && ! ( jQuery( this ).text() in wppb_roles_editor_data.current_role_capabilities ) ) ) { + wppb_capability_class = wppb_capability_class + ' wppb-new-capability'; + wppb_re_unsaved_capabilities[jQuery( this ).text()] = jQuery( this ).text(); + title = 'title = "' + wppb_roles_editor_data.new_cap_update_title_text + '"'; + } else if( wppb_re_getParameterByName( 'wppb_re_clone' ) && ! wppb_roles_editor_data.current_role_capabilities ) { + wppb_capability_class = wppb_capability_class + ' wppb-new-capability'; + title = 'title = "' + wppb_roles_editor_data.new_cap_publish_title_text + '"'; + } + + jQuery( '.post-type-wppb-roles-editor .wppb-role-edit-no-cap' ).remove(); + + jQuery( table ).find( '#wppb-role-edit-caps-clear' ).after( + '
            ' + + '' + jQuery( this ).text() + '' + + '' + wppb_roles_editor_data.delete_text + '' + + '
            ' ); + + capabilities[jQuery( this ).text()] = jQuery( this ).text(); + no_duplicates[jQuery( this ).text()] = jQuery( this ).text(); + + delete wppb_re_capabilities_to_delete[jQuery( this ).text()]; + } + } ); + + wppb_re_new_capability( capabilities ); + + wppb_re_disable_select_capabilities( wppb_re_capabilities_group, capabilities, 'add' ); + + jQuery( capabilities_select ).val( null ).trigger( 'change' ); + + wppb_re_number_of_capabilities(); + + setTimeout( function() { + jQuery( '.post-type-wppb-roles-editor .wppb-role-edit-table-entry' ).removeClass( 'wppb-new-capability-highlight' ); + }, 500 ); + } else if( jQuery( new_capability_input ).is( ':visible' ) && jQuery( new_capability_input ).val().length != 0 ) { + var new_capability_value = jQuery( new_capability_input ).val(); + new_capability_value = new_capability_value.trim().replace( /<.*?>/g, '' ).replace( /\s/g, '_' ).replace( /[^a-zA-Z0-9_]/g, '' ); + + if( new_capability_value && ( ! wppb_roles_editor_data.hidden_capabilities || ! ( new_capability_value in wppb_roles_editor_data.hidden_capabilities ) ) ) { + if( ! ( new_capability_value in wppb_re_current_role_capabilities ) && ! ( new_capability_value in wppb_re_new_capabilities ) ) { + wppb_re_tabs_handler( jQuery( '.post-type-wppb-roles-editor .wppb-role-editor-tab.wppb-role-editor-all' ) ); + + var title = ''; + var wppb_capability_class = 'wppb-capability'; + if( ! wppb_roles_editor_data.current_role_capabilities || ( wppb_roles_editor_data.current_role_capabilities && ! ( new_capability_value in wppb_roles_editor_data.current_role_capabilities ) ) ) { + wppb_capability_class = wppb_capability_class + ' wppb-new-capability'; + wppb_re_unsaved_capabilities[new_capability_value] = new_capability_value; + title = 'title = "' + wppb_roles_editor_data.new_cap_update_title_text + '"'; + } else if( wppb_re_getParameterByName( 'wppb_re_clone' ) && ! wppb_roles_editor_data.current_role_capabilities ) { + wppb_capability_class = wppb_capability_class + ' wppb-new-capability'; + title = 'title = "' + wppb_roles_editor_data.new_cap_publish_title_text + '"'; + } + + jQuery( '.post-type-wppb-roles-editor .wppb-role-edit-no-cap' ).remove(); + + jQuery( table ).find( '#wppb-role-edit-caps-clear' ).after( + '
            ' + + '' + new_capability_value + '' + + '' + wppb_roles_editor_data.delete_text + '' + + '
            ' ); + + capabilities[new_capability_value] = new_capability_value; + delete wppb_re_capabilities_to_delete[new_capability_value]; + + wppb_re_change_select_to_input(); + + wppb_re_new_capability( capabilities ); + + wppb_re_disable_select_capabilities( wppb_re_capabilities_group, capabilities, 'add' ); + + jQuery( new_capability_input ).val( '' ); + + wppb_re_number_of_capabilities(); + + setTimeout( function() { + jQuery( '.post-type-wppb-roles-editor .wppb-role-edit-table-entry' ).removeClass( 'wppb-new-capability-highlight' ); + }, 500 ); + } else { + jQuery( new_capability_input ).val( '' ); + + jQuery( '.post-type-wppb-roles-editor #wppb-duplicate-capability-error' ).show().delay( 3000 ).fadeOut(); + } + } else if( wppb_roles_editor_data.hidden_capabilities && new_capability_value in wppb_roles_editor_data.hidden_capabilities ) { + jQuery( '.post-type-wppb-roles-editor #wppb-hidden-capability-error' ).show().delay( 3000 ).fadeOut(); + } else { + jQuery( '.post-type-wppb-roles-editor #wppb-add-capability-error' ).show().delay( 3000 ).fadeOut(); + } + } else { + jQuery( '.post-type-wppb-roles-editor #wppb-add-capability-error' ).show().delay( 3000 ).fadeOut(); + } +} + +function wppb_re_new_capability( capabilities ) { + jQuery.each( capabilities, function( key, value ) { + if( ! ( value in wppb_roles_editor_data.all_capabilities ) || ! ( value in wppb_re_current_role_capabilities ) ) { + wppb_re_new_capabilities[value] = value; + } + } ); + + jQuery.extend( wppb_re_current_role_capabilities, wppb_re_new_capabilities ); +} + +function wppb_re_update_role_capabilities() { + jQuery( '.post-type-wppb-roles-editor #wppb-role-slug-hidden' ).val( jQuery( '#wppb-role-slug' ).val() ); + + var data = { + 'action' : 'update_role_capabilities', + 'security' : jQuery( '.post-type-wppb-roles-editor #wppb-re-ajax-nonce' ).val(), + 'role_display_name' : jQuery( '.post-type-wppb-roles-editor #titlediv' ).find( '#title' ).val(), + 'role' : jQuery( '.post-type-wppb-roles-editor #wppb-role-slug' ).val(), + 'new_capabilities' : wppb_re_unsaved_capabilities, + 'all_capabilities' : wppb_re_current_role_capabilities, + 'capabilities_to_delete' : wppb_re_capabilities_to_delete + }; + + jQuery.post( wppb_roles_editor_data.ajaxUrl, data, function( response ) { + jQuery( '.post-type-wppb-roles-editor #publishing-action #publish' ).removeClass( 'disabled' ).trigger( 'click' ); + } ); +} + +function wppb_re_change_select_to_input() { + if( jQuery( '.post-type-wppb-roles-editor .select2.select2-container' ).is( ':visible' ) ) { + jQuery( '.post-type-wppb-roles-editor .select2.select2-container' ).hide(); + jQuery( '.post-type-wppb-roles-editor .wppb-add-new-cap-input' ).show(); + jQuery( '.post-type-wppb-roles-editor a.wppb-add-new-cap-link' ).text( wppb_roles_editor_data.cancel_text ); + } else { + jQuery( '.post-type-wppb-roles-editor .select2.select2-container' ).show(); + jQuery( '.post-type-wppb-roles-editor .wppb-add-new-cap-input' ).hide(); + jQuery( '.post-type-wppb-roles-editor a.wppb-add-new-cap-link' ).text( wppb_roles_editor_data.add_new_capability_text ); + } +} + +function wppb_re_getParameterByName( name, url ) { + if( ! url ) { + url = window.location.href; + } + + name = name.replace( /[\[\]]/g, "\\$&" ); + + var regex = new RegExp( "[?&]" + name + "(=([^&#]*)|&|#|$)" ), results = regex.exec( url ); + + if( ! results ) { + return null; + } + + if( ! results[2] ) { + return ''; + } + + return decodeURIComponent( results[2].replace( /\+/g, " " ) ); +} diff --git a/profile-builder/features/roles-editor/roles-editor.php b/profile-builder/features/roles-editor/roles-editor.php index 6f1f3a6..4ace403 100644 --- a/profile-builder/features/roles-editor/roles-editor.php +++ b/profile-builder/features/roles-editor/roles-editor.php @@ -1,1053 +1,1053 @@ -wp_default_scripts(); - foreach( $wp_scripts->registered as $key => $value ) { - if( ! in_array( $key, $wp_default_scripts ) && $key != 'wppb-sitewide' ) { - wp_deregister_script( $key ); - } - } - - $wp_default_styles = $this->wp_default_styles(); - foreach( $wp_styles->registered as $key => $value ) { - if( ! in_array( $key, $wp_default_styles ) && $key != 'wppb-serial-notice-css' ) { - wp_deregister_style( $key ); - } - } - - wp_enqueue_script( 'wppb_select2_js', WPPB_PLUGIN_URL .'assets/js/select2/select2.min.js', array( 'jquery' ), PROFILE_BUILDER_VERSION ); - wp_enqueue_style( 'wppb_select2_css', WPPB_PLUGIN_URL .'assets/css/select2/select2.min.css', array(), PROFILE_BUILDER_VERSION ); - - wp_enqueue_script( 'wppb_roles_editor_js', plugin_dir_url( __FILE__ ) .'assets/js/roles-editor.js', array( 'jquery', 'wppb_select2_js' ), PROFILE_BUILDER_VERSION ); - wp_enqueue_style( 'wppb_roles_editor_css', plugin_dir_url( __FILE__ ) .'assets/css/roles-editor.css', array(), PROFILE_BUILDER_VERSION ); - - if( $current_screen->id == 'wppb-roles-editor' ) { - $role_slug = $this->sanitize_role( get_post_meta( $post->ID, 'wppb_role_slug', true ) ); - $current_role = get_role( $role_slug ); - $current_user = wp_get_current_user(); - - if( isset( $current_role ) && is_array( $current_role->capabilities ) ) { - $role_capabilities = $current_role->capabilities; - - // True if current user got this role - if( isset( $role_slug ) && in_array( $role_slug, $current_user->roles ) ) { - $current_user_role = TRUE; - } else { - $current_user_role = FALSE; - } - - // Get current role users count - $current_role_users_count = $this->count_role_users( $current_role->name ); - } else { - $role_capabilities = NULL; - $current_role_users_count = NULL; - $current_user_role = FALSE; - } - } else { - $role_capabilities = NULL; - $current_role_users_count = NULL; - $current_user_role = FALSE; - } - - // Remove old WordPress levels system - // Use filter and return FALSE if you need the old levels capability system - $remove_old_levels = apply_filters( 'wppb_remove_old_levels', TRUE ); - if( $remove_old_levels === TRUE ) { - $role_capabilities = $this->remove_old_labels( $role_capabilities ); - } - - $admin_capabilities = array( - 'manage_options', - 'activate_plugins', - 'delete_plugins', - 'install_plugins', - 'manage_network_options', - 'manage_network', - 'manage_network_plugins', - 'upload_plugins' - ); - - $group_capabilities = $this->group_capabilities(); - $hidden_capabilities = NULL; - - $remove_hidden_capabilities = apply_filters( 'wppb_re_remove_hidden_caps', TRUE ); - if( $remove_hidden_capabilities === TRUE ) { - $group_capabilities['general']['capabilities'] = array_diff( $group_capabilities['general']['capabilities'], $this->get_hidden_capabilities() ); - $group_capabilities['appearance']['capabilities'] = array_diff( $group_capabilities['appearance']['capabilities'], $this->get_hidden_capabilities() ); - $group_capabilities['plugins']['capabilities'] = array_diff( $group_capabilities['plugins']['capabilities'], $this->get_hidden_capabilities() ); - $group_capabilities['post_types']['attachment']['capabilities'] = array_diff( $group_capabilities['post_types']['attachment']['capabilities'], $this->get_hidden_capabilities() ); - - if( $role_capabilities !== NULL ) { - $role_capabilities = array_diff_key( $role_capabilities, $this->get_hidden_capabilities() ); - } - - $hidden_capabilities = $this->get_hidden_capabilities(); - if( empty( $hidden_capabilities ) ) { - $hidden_capabilities = NULL; - } - } - - $all_capabilities = $this->get_all_capabilities(); - - $custom_capabilities = get_option( 'wppb_roles_editor_capabilities', 'not_set' ); - if( $custom_capabilities != 'not_set' && ! empty( $custom_capabilities['custom']['capabilities'] ) ) { - foreach( $custom_capabilities['custom']['capabilities'] as $custom_capability_key => $custom_capability ) { - if( ! in_array( $custom_capability, $all_capabilities ) ) { - $all_capabilities[$custom_capability] = $custom_capability; - } - } - } - - $vars_array = array( - 'ajaxUrl' => admin_url( 'admin-ajax.php' ), - 'current_screen_action' => $current_screen->action, - 'capabilities' => $group_capabilities, - 'current_role_capabilities' => $role_capabilities, - 'current_role_users_count' => $current_role_users_count, - 'all_capabilities' => $all_capabilities, - 'current_user_role' => $current_user_role, - 'admin_capabilities' => $admin_capabilities, - 'hidden_capabilities' => $hidden_capabilities, - 'default_role_text' => esc_html__( 'Default Role', 'profile_builder' ), - 'your_role_text' => esc_html__( 'Your Role', 'profile_builder' ), - 'role_name_required_error_text' => esc_html__( 'Role name is required.', 'profile_builder' ), - 'no_capabilities_found_text' => esc_html__( 'No capabilities found.', 'profile_builder' ), - 'select2_placeholder_text' => esc_html__( 'Select capabilities', 'profile_builder' ), - 'delete_permanently_text' => esc_html__( 'Delete Permanently', 'profile_builder' ), - 'capability_perm_delete_text' => esc_html__( "This will permanently delete the capability from your site and from every user role.\n\nIt can't be undone!", 'profile_builder' ), - 'new_cap_update_title_text' => esc_html__( 'This capability is not saved until you click Update!', 'profile_builder' ), - 'new_cap_publish_title_text' => esc_html__( 'This capability is not saved until you click Publish!', 'profile_builder' ), - 'delete_text' => esc_html__( 'Delete', 'profile-builder' ), - 'cancel_text' => esc_html__( 'Cancel', 'profile_builder' ), - 'add_new_capability_text' => esc_html__( 'Add New Capability', 'profile_builder' ), - 'capability_text' => esc_html__( 'Capability', 'profile-builder' ), - 'cap_no_delete_text' => esc_html__( 'You can\'t delete this capability from your role.', 'profile-builder' ) - ); - - wp_localize_script( 'wppb_roles_editor_js', 'wppb_roles_editor_data', $vars_array ); - } - - } - - function count_role_users( $current_role_name ) { - - // Get current role users count - $user_count = count_users(); - - if( isset( $user_count['avail_roles'][$current_role_name] ) ) { - $current_role_users_count = $user_count['avail_roles'][$current_role_name]; - } else { - $current_role_users_count = NULL; - } - - return $current_role_users_count; - } - - function get_role_capabilities() { - - if( ! current_user_can( 'manage_options' ) ) { - die(); - } - - check_ajax_referer( 'wppb-re-ajax-nonce', 'security' ); - - $role = get_role( sanitize_text_field( $_POST['role'] ) ); - - if( isset( $role ) && ! empty( $role->capabilities ) ) { - $role_capabilities = $role->capabilities; - - // Remove old WordPress levels system - // Use filter and return FALSE if you need the old levels capability system - $remove_old_levels = apply_filters( 'wppb_remove_old_levels', TRUE ); - if( $remove_old_levels === TRUE ) { - $role_capabilities = $this->remove_old_labels( $role_capabilities ); - } - - die( json_encode( $role_capabilities ) ); - } - - die( 'no_caps' ); - } - - function edit_cpt_quick_links( $views ) { - - $edited_views = array(); - $edited_views['all'] = $views['all']; - - return $edited_views; - - } - - function create_roles_editor_cpt(){ - - $labels = array( - 'name' => esc_html__( 'Roles Editor', 'profile-builder' ), - 'singular_name' => esc_html__( 'Roles Editor', 'profile-builder' ), - 'add_new' => esc_html__( 'Add New Role', 'profile-builder' ), - 'add_new_item' => esc_html__( 'Add New Role', 'profile-builder' ), - 'edit_item' => esc_html__( 'Edit Role', 'profile-builder' ), - 'new_item' => esc_html__( 'New Role', 'profile-builder' ), - 'all_items' => esc_html__( 'Roles Editor', 'profile-builder' ), - 'view_item' => esc_html__( 'View Role', 'profile-builder' ), - 'search_items' => esc_html__( 'Search the Roles Editor', 'profile-builder' ), - 'not_found' => esc_html__( 'No roles found', 'profile-builder' ), - 'not_found_in_trash' => esc_html__( 'No roles found in trash', 'profile-builder' ), - 'name_admin_bar' => esc_html__( 'Role', 'profile-builder' ), - 'parent_item_colon' => '', - 'menu_name' => esc_html__( 'Roles Editor', 'profile-builder' ) - ); - - $args = array( - 'labels' => $labels, - 'public' => false, - 'publicly_queryable' => false, - 'show_ui' => true, - 'query_var' => true, - 'show_in_menu' => 'users.php', - 'has_archive' => false, - 'hierarchical' => false, - 'capability_type' => 'post', - 'supports' => array( 'title' ) - ); - - register_post_type( 'wppb-roles-editor', $args ); - - } - - function change_title_text( $title ) { - - $screen = get_current_screen(); - - if( $screen->post_type == 'wppb-roles-editor' ) { - $title = esc_html__( 'Enter role name here', 'profile_builder' ); - } - - return $title; - - } - - function change_post_updated_messages( $messages ) { - - global $post; - - $messages['wppb-roles-editor'] = array( - 0 => '', - 1 => esc_html__( 'Role updated.', 'profile-builder' ), - 2 => esc_html__( 'Custom field updated.', 'profile-builder' ), - 3 => esc_html__( 'Custom field deleted.', 'profile-builder' ), - 4 => esc_html__( 'Role updated.', 'profile-builder' ), - 5 => isset( $_GET['revision'] ) ? sprintf( esc_html__( 'Role restored to revision from %s' ), wp_post_revision_title( (int) $_GET['revision'], false ) ) : false, - 6 => esc_html__( 'Role created.', 'profile-builder' ), - 7 => esc_html__( 'Role saved.', 'profile-builder' ), - 8 => esc_html__( 'Role submitted.', 'profile-builder' ), - 9 => sprintf( esc_html__( 'Role scheduled for: %1$s', 'profile-builder' ), date_i18n( __( 'M j, Y @ G:i' ), strtotime( $post->post_date ) ) ), - 10 => esc_html__( 'Role draft updated.', 'profile-builder' ), - ); - - return $messages; - - } - - function create_post_for_role() { - - $screen = get_current_screen(); - - if( $screen->id == 'edit-wppb-roles-editor' ) { - global $wpdb; - global $wp_roles; - - $added_posts = array(); - - $args = array( - 'numberposts' => -1, - 'post_type' => 'wppb-roles-editor' - ); - $posts = get_posts( $args ); - - foreach( $posts as $key => $value ) { - $post_id = intval( $value->ID ); - $role_slug_meta = $this->sanitize_role( get_post_meta( $post_id, 'wppb_role_slug', true ) ); - if( ! empty( $role_slug_meta ) ) { - if( ! array_key_exists( $role_slug_meta, $wp_roles->role_names ) ) { - $post_meta = get_post_meta( $post_id ); - foreach( $post_meta as $post_meta_key => $post_meta_value ) { - delete_post_meta( $post_id, $post_meta_key ); - } - - $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->posts WHERE post_type = %s AND ID = %d", "wppb-roles-editor", $post_id ) ); - } else { - $added_posts[] = $role_slug_meta; - } - } - } - - foreach( $wp_roles->role_names as $role_slug => $role_display_name ) { - if( ! in_array( $role_slug, $added_posts ) ) { - $id = wp_insert_post( array( - 'post_title' => $role_display_name, - 'post_type' => 'wppb-roles-editor', - 'post_content' => '', - 'post_status' => 'publish' - ) ); - - update_post_meta( $id, 'wppb_role_slug', $role_slug ); - } - } - } - - } - - function add_extra_column_for_roles_editor_cpt( $columns ) { - - $columns = array( - 'title' => esc_html__( 'Role Name', 'profile-builder' ), - 'role' => esc_html__( 'Role Slug', 'profile-builder' ), - 'capabilities' => esc_html__( 'Capabilities', 'profile-builder' ), - 'users' => esc_html__( 'Users', 'profile-builder' ) - ); - - return apply_filters( 'wppb_manage_roles_columns', $columns ); - - } - - function custom_column_content_for_roles_editor_cpt( $column_name, $post_id ) { - - $role_slug = $this->sanitize_role( get_post_meta( $post_id, 'wppb_role_slug', true ) ); - - if( isset( $role_slug ) ) { - $role = get_role( $role_slug ); - - if( $column_name == 'role' ) { - echo ''; - } - - if( $column_name == 'capabilities' && isset( $role ) ) { - // Remove old WordPress levels system - // Use filter and return FALSE if you need the old levels capability system - $remove_old_levels = apply_filters( 'wppb_remove_old_levels', TRUE ); - if( $remove_old_levels === TRUE ) { - $role_capabilities = $this->remove_old_labels( $role->capabilities ); - } else { - $role_capabilities = $role->capabilities; - } - - echo count( $role_capabilities ); - } - - if( $column_name == 'users' && isset( $role ) ) { - $role_users_count = $this->count_role_users( $role->name ); - - if( ! isset( $role_users_count ) ) { - $role_users_count = 0; - } - - echo $role_users_count; - } - } - } - - function register_meta_boxes() { - - remove_meta_box( 'slugdiv', 'wppb-roles-editor', 'normal' ); - add_meta_box( 'wppb_edit_role_capabilities', esc_html__( 'Edit Role Capabilities', 'profile_builder' ), array( $this, 'edit_role_capabilities_meta_box_callback' ), 'wppb-roles-editor', 'normal', 'high' ); - - } - - function edit_role_capabilities_meta_box_callback() { - - ?> -
            -
            - - - - - - - - - - - - - -
            - -
            -
              -
            • - -
            • - -
            • - -
            • - -
            • - -
            • - -
            • - -
            • - -
            • - -
            • - -
            • - -
            • - -
            • - -
            • - -
            • - -
            • - -
            • - -
            • - -
            • - -
            • -
            - -
            -
            -
            -
            -
            -
            - - - -
            - post_type == $post_type ) { - $role_slug = $this->sanitize_role( get_post_meta( $post->ID, 'wppb_role_slug', true ) ); - - ?> - - -
            - - : 0 -
            - -
            - - : 0 -
            - -
            - - - - action == 'add' ? '' : 'disabled'; ?>> - -
            - $value ) { - unset( $capabilities[$value] ); - } - - return $capabilities; - - } - - function modify_post_title( $data ) { - - if( 'wppb-roles-editor' != $data['post_type'] || $data['post_status'] == 'auto-draft' ) { - return $data; - } - - if( ! current_user_can( 'manage_options' ) ) { - return $data; - } - - if( isset( $data['post_title'] ) ) { - $data['post_title'] = wp_strip_all_tags( $data['post_title'] ); - } - - return $data; - - } - - function add_post_meta( $post_id, $post, $update ) { - - $post_type = get_post_type( $post_id ); - - if( 'wppb-roles-editor' != $post_type || $post->post_status == 'auto-draft' ) { - return; - } - - if( ! current_user_can( 'manage_options' ) ) { - return; - } - - if( isset( $_POST['wppb-role-slug-hidden'] ) ) { - $role_slug = trim( $_POST['wppb-role-slug-hidden'] ); - $role_slug = $this->sanitize_role( $role_slug ); - - update_post_meta( $post_id, 'wppb_role_slug', $role_slug ); - } - - } - - function update_role_capabilities() { - - if( ! current_user_can( 'manage_options' ) ) { - die(); - } - - check_ajax_referer( 'wppb-re-ajax-nonce', 'security' ); - - $role_slug = $this->sanitize_role( $_POST['role'] ); - - $role = get_role( $role_slug ); - - if( $role ) { - if( isset( $_POST['new_capabilities'] ) ) { - foreach( $_POST['new_capabilities'] as $key => $value ) { - $role->add_cap( sanitize_text_field( $key ) ); - } - } - - if( isset( $_POST['capabilities_to_delete'] ) ) { - foreach( $_POST['capabilities_to_delete'] as $key => $value ) { - $role->remove_cap( sanitize_text_field( $key ) ); - } - } - } else { - $capabilities = array(); - - if( isset( $_POST['all_capabilities'] ) ) { - foreach( $_POST['all_capabilities'] as $key => $value ) { - $capabilities[sanitize_text_field( $key )] = true; - }; - } - - $role_display_name = sanitize_text_field( $_POST['role_display_name'] ); - - add_role( $role_slug, $role_display_name, $capabilities ); - } - - die( 'role_capabilities_updated' ); - - } - - function group_capabilities() { - - $capabilities = get_option( 'wppb_roles_editor_capabilities', 'not_set' ); - - if( $capabilities == 'not_set' ) { - // We remove non-custom capabilities from this array later on - $custom_capabilities = $this->get_all_capabilities(); - $custom_capabilities = $this->remove_old_labels( $custom_capabilities ); - - // General capabilities - $general_capabilities = array( - 'label' => 'General', - 'icon' => 'dashicons-wordpress', - 'capabilities' => array( 'edit_dashboard', 'edit_files', 'export', 'import', 'manage_links', 'manage_options', 'moderate_comments', 'read', 'unfiltered_html', 'update_core' ) - ); - - // Themes management capabilities - $appearance_capabilities = array( - 'label' => 'Appearance', - 'icon' => 'dashicons-admin-appearance', - 'capabilities' => array( 'delete_themes', 'edit_theme_options', 'edit_themes', 'install_themes', 'switch_themes', 'update_themes' ) - ); - - // Plugins management capabilities - $plugins_capabilities = array( - 'label' => 'Plugins', - 'icon' => 'dashicons-admin-plugins', - 'capabilities' => array( 'activate_plugins', 'delete_plugins', 'edit_plugins', 'install_plugins', 'update_plugins' ) - ); - - // Users management capabilities - $users_capabilities = array( - 'label' => 'Users', - 'icon' => 'dashicons-admin-users', - 'capabilities' => array( 'add_users', 'create_roles', 'create_users', 'delete_roles', 'delete_users', 'edit_roles', 'edit_users', 'list_roles', 'list_users', 'promote_users', 'remove_users' ) - ); - - // Taxonomies capabilities - part 1 - $taxonomies_capabilities = array(); - $taxonomies = get_taxonomies( array(), 'objects' ); - foreach( $taxonomies as $taxonomy ) { - $taxonomies_capabilities = array_merge( $taxonomies_capabilities, array_values( (array) $taxonomy->cap ) ); - } - - // Post types capabilities - $post_types_capabilities = array(); - foreach( get_post_types( array(), 'objects' ) as $type ) { - - if( in_array( $type->name, array( 'revision', 'nav_menu_item', 'custom_css', 'customize_changeset', 'wppb-rf-cpt', 'wppb-epf-cpt', 'wppb-roles-editor' ) ) ) { - continue; - } - - $post_type_capabilities = $this->post_type_group_capabilities( $type->name ); - if( empty( $post_type_capabilities ) ) { - continue; - } - - $post_type_icon = $type->hierarchical ? 'dashicons-admin-page' : 'dashicons-admin-post'; - if( is_string( $type->menu_icon ) && preg_match( '/dashicons-/i', $type->menu_icon ) ) { - $post_type_icon = $type->menu_icon; - } else if( 'attachment' === $type->name ) { - $post_type_icon = 'dashicons-admin-media'; - } else if( 'download' === $type->name ) { - $post_type_icon = 'dashicons-download'; - } else if( 'product' === $type->name ) { - $post_type_icon = 'dashicons-cart'; - } - - $post_types_capabilities[$type->name] = array( - 'label' => $type->labels->name, - 'icon' => $post_type_icon, - 'capabilities' => $post_type_capabilities - ); - - $taxonomies_capabilities = array_diff( $taxonomies_capabilities, $post_type_capabilities ); - $custom_capabilities = array_diff( $custom_capabilities, $post_type_capabilities ); - } - - // Taxonomies capabilities - part 2 - $taxonomies_capabilities = array_diff( $taxonomies_capabilities, $general_capabilities['capabilities'], $appearance_capabilities['capabilities'], $plugins_capabilities['capabilities'], $users_capabilities['capabilities'] ); - $taxonomies_capabilities = array( - 'label' => 'Taxonomies', - 'icon' => '', - 'capabilities' => array_unique( $taxonomies_capabilities ) - ); - - // Custom capabilities - $custom_capabilities = array_diff( $custom_capabilities, $general_capabilities['capabilities'], $appearance_capabilities['capabilities'], $appearance_capabilities['capabilities'], $plugins_capabilities['capabilities'], $users_capabilities['capabilities'], $taxonomies_capabilities['capabilities'] ); - $custom_capabilities = array_values( $custom_capabilities ); - $custom_capabilities = array( - 'label' => 'Custom', - 'icon' => '', - 'capabilities' => array_unique( $custom_capabilities ) - ); - - // Create capabilities array - $capabilities = array( - 'general' => $general_capabilities, - 'post_types' => $post_types_capabilities, - 'taxonomies' => $taxonomies_capabilities, - 'appearance' => $appearance_capabilities, - 'plugins' => $plugins_capabilities, - 'users' => $users_capabilities, - 'custom' => $custom_capabilities - ); - - update_option( 'wppb_roles_editor_capabilities', $capabilities ); - } else { - $custom_capabilities = $this->get_all_capabilities(); - $custom_capabilities = $this->remove_old_labels( $custom_capabilities ); - - foreach( $capabilities['post_types'] as $key => $value ) { - $custom_capabilities = array_diff( $custom_capabilities, $value['capabilities'] ); - } - - foreach( $capabilities as $key => $value ) { - if( $key != 'post_types' && $key != 'custom' ) { - $custom_capabilities = array_diff( $custom_capabilities, $value['capabilities'] ); - } - } - - $custom_capabilities = array_values( $custom_capabilities ); - $custom_capabilities = array_unique( $custom_capabilities ); - $custom_capabilities = array_diff( $custom_capabilities, $capabilities['custom']['capabilities'] ); - - if( ! empty( $custom_capabilities ) ) { - $capabilities['custom']['capabilities'] = array_merge( $capabilities['custom']['capabilities'], $custom_capabilities ); - - update_option( 'wppb_roles_editor_capabilities', $capabilities ); - } - } - - return $capabilities; - - } - - function post_type_group_capabilities( $post_type = 'post' ) { - - $capabilities = (array) get_post_type_object( $post_type )->cap; - - unset( $capabilities['edit_post'] ); - unset( $capabilities['read_post'] ); - unset( $capabilities['delete_post'] ); - - $capabilities = array_values( $capabilities ); - - if( ! in_array( $post_type, array( 'post', 'page' ) ) ) { - // Get the post and page capabilities - $post_caps = array_values( (array) get_post_type_object( 'post' )->cap ); - $page_caps = array_values( (array) get_post_type_object( 'page' )->cap ); - - // Remove post/page capabilities from the current post type capabilities - $capabilities = array_diff( $capabilities, $post_caps, $page_caps ); - } - - if( 'attachment' === $post_type ) { - $capabilities[] = 'unfiltered_upload'; - } - - return array_unique( $capabilities ); - - } - - function get_all_capabilities() { - - global $wp_roles; - - $capabilities = array(); - - foreach( $wp_roles->role_objects as $key => $role ) { - if( is_array( $role->capabilities ) ) { - foreach( $role->capabilities as $capability => $granted ) { - $capabilities[$capability] = $capability; - } - } - } - - return array_unique( $capabilities ); - - } - - function delete_capability_permanently() { - - if( ! current_user_can( 'manage_options' ) ) { - die(); - } - - check_ajax_referer( 'wppb-re-ajax-nonce', 'security' ); - - global $wp_roles; - - foreach( $wp_roles->role_names as $role_slug => $role_display_name ) { - $role = get_role( $role_slug ); - $role->remove_cap( sanitize_text_field( $_POST['capability'] ) ); - } - - $capabilities = get_option( 'wppb_roles_editor_capabilities', 'not_set' ); - - if( $capabilities != 'not_set' && ( $key = array_search( sanitize_text_field( $_POST['capability'] ), $capabilities['custom']['capabilities'] ) ) !== false ) { - unset( $capabilities['custom']['capabilities'][$key] ); - $capabilities['custom']['capabilities'] = array_values( $capabilities['custom']['capabilities'] ); - - update_option( 'wppb_roles_editor_capabilities', $capabilities ); - } - - die(); - - } - - function remove_filter_by_month_dropdown( $months, $post_type ) { - - if( $post_type == 'wppb-roles-editor' ) { - return __return_empty_array(); - } else { - return $months; - } - - } - - function modify_list_row_actions( $actions, $post ) { - global $wp_roles; - - if( $post->post_type == 'wppb-roles-editor' ) { - $current_user = wp_get_current_user(); - $default_role = get_option( 'default_role' ); - $role_slug = get_post_meta( $post->ID, 'wppb_role_slug', true ); - - $url = admin_url( 'post.php?post=' . $post->ID ); - - $edit_link = add_query_arg( array( 'action' => 'edit' ), $url ); - - $actions = array( - 'edit' => sprintf( - '%2$s', - esc_url( $edit_link ), - esc_html__( 'Edit', 'profile-builder' ) - ) - ); - - $clone_url = admin_url( 'post-new.php?post_type=wppb-roles-editor' ); - $clone_link = add_query_arg( array( 'action' => 'wppb_re_clone', 'wppb_re_clone' => $this->sanitize_role( $role_slug ) ), $clone_url ); - - $actions = array_merge( $actions, array( - 'clone' => sprintf( - '%2$s', - esc_url( $clone_link ), - esc_html__( 'Clone', 'profile-builder' ) - ) - ) - ); - - if( in_array( $role_slug, $current_user->roles ) && ( ! is_multisite() || ( is_multisite() && ! is_super_admin() ) ) && ( !empty( $wp_roles->roles[$role_slug]['capabilities'] ) && array_key_exists( 'manage_options', $wp_roles->roles[$role_slug]['capabilities'] ) ) ) { - $actions = array_merge( $actions, array( - 'delete_notify your_role' => ''. esc_html__( 'Delete', 'profile-builder' ) .'' - ) - ); - } elseif( $role_slug == $default_role ) { - $actions = array_merge( $actions, array( - 'default_role' => sprintf( - '%s', - esc_url( admin_url( 'options-general.php#default_role' ) ), - esc_html__( 'Change Default', 'profile-builder' ) ), - 'delete_notify' => ''. esc_html__( 'Delete', 'profile-builder' ) .'' - ) - ); - } else { - $delete_link = wp_nonce_url( add_query_arg( array( 'action' => 'delete' ), $url ), 'delete-post_'. $post->ID ); - - $actions = array_merge( $actions, array( - 'delete' => sprintf( - '%3$s', - esc_url( $delete_link ), - esc_html__( 'Are you sure?\nThis will permanently delete the role and cannot be undone!\nUsers assigned only on this role will be moved to the default role.', 'profile_builder' ), - esc_html__( 'Delete', 'profile-builder' ) - ) - ) - ); - } - } - - return $actions; - - } - - function sanitize_role( $role ) { - - $role = strtolower( $role ); - $role = wp_strip_all_tags( $role ); - $role = preg_replace( '/[^a-z0-9_\-\s]/', '', $role ); - $role = str_replace( ' ', '_', $role ); - - return $role; - - } - - function delete_role_permanently( $post_id ) { - - check_admin_referer( 'delete-post_'. $post_id ); - - global $post_type; - - if( $post_type != 'wppb-roles-editor' ) { - return; - } - - $role_slug = get_post_meta( $post_id, 'wppb_role_slug', true ); - $role_slug = $this->sanitize_role( $role_slug ); - - $default_role = get_option( 'default_role' ); - - if( $role_slug == $default_role ) { - return; - } - - $users = get_users( array( 'role' => $role_slug ) ); - - if( is_array( $users ) ) { - foreach( $users as $user ) { - if( $user->has_cap( $role_slug ) && count( $user->roles ) <= 1 ) { - $user->set_role( $default_role ); - } elseif( $user->has_cap( $role_slug ) ) { - $user->remove_role( $role_slug ); - } - } - } - - remove_role( $role_slug ); - - } - - function wp_default_scripts() { - - $wp_default_scripts = array( - 'jquery', 'jquery-core', 'jquery-migrate', 'jquery-ui-core', 'jquery-ui-accordion', - 'jquery-ui-autocomplete', 'jquery-ui-button', 'jquery-ui-datepicker', 'jquery-ui-dialog', - 'jquery-ui-draggable', 'jquery-ui-droppable', 'jquery-ui-menu', 'jquery-ui-mouse', - 'jquery-ui-position', 'jquery-ui-progressbar', 'jquery-ui-resizable', 'jquery-ui-selectable', - 'jquery-ui-slider', 'jquery-ui-sortable', 'jquery-ui-spinner', 'jquery-ui-tabs', - 'jquery-ui-tooltip', 'jquery-ui-widget', 'underscore', 'backbone', 'utils', 'common', - 'wp-a11y', 'sack', 'quicktags', 'colorpicker', 'editor', 'wp-fullscreen-stub', 'wp-ajax-response', - 'wp-pointer', 'heartbeat', 'wp-auth-check', 'wp-lists', 'prototype', 'scriptaculous-root', - 'scriptaculous-builder', 'scriptaculous-dragdrop', 'scriptaculous-effects', 'scriptaculous-slider', - 'scriptaculous-sound', 'scriptaculous-controls', 'scriptaculous', 'cropper', 'jquery-effects-core', - 'jquery-effects-blind', 'jquery-effects-bounce', 'jquery-effects-clip', 'jquery-effects-drop', - 'jquery-effects-explode', 'jquery-effects-fade', 'jquery-effects-fold', 'jquery-effects-highlight', - 'jquery-effects-puff', 'jquery-effects-pulsate', 'jquery-effects-scale', 'jquery-effects-shake', - 'jquery-effects-size', 'jquery-effects-slide', 'jquery-effects-transfer', 'jquery-ui-selectmenu', - 'jquery-form', 'jquery-color', 'schedule', 'jquery-query', 'jquery-serialize-object', 'jquery-hotkeys', - 'jquery-table-hotkeys', 'jquery-touch-punch', 'suggest', 'imagesloaded', 'masonry', 'jquery-masonry', - 'thickbox', 'jcrop', 'swfobject', 'plupload', 'plupload-all', 'plupload-html5', 'plupload-flash', - 'plupload-silverlight', 'plupload-html4', 'plupload-handlers', 'wp-plupload', 'swfupload', 'swfupload-swfobject', - 'swfupload-queue', 'swfupload-speed', 'swfupload-all', 'swfupload-handlers', 'comment-reply', 'json2', - 'underscore', 'backbone', 'wp-util', 'wp-backbone', 'revisions', 'imgareaselect', 'mediaelement', - 'wp-mediaelement', 'froogaloop', 'wp-playlist', 'zxcvbn-async', 'password-strength-meter', 'user-profile', - 'language-chooser', 'user-suggest', 'admin-bar', 'wplink', 'wpdialogs', 'word-count', 'media-upload', - 'hoverIntent', 'customize-base', 'customize-loader', 'customize-preview', 'customize-models', 'customize-views', - 'customize-controls', 'customize-selective-refresh', 'customize-widgets', 'customize-preview-widgets', - 'customize-preview-nav-menus', 'wp-custom-header', 'accordion', 'shortcode', 'media-models', 'wp-embed', - 'media-views', 'media-editor', 'media-audiovideo', 'mce-view', 'wp-api', 'admin-tags', 'admin-comments', 'xfn', - 'postbox', 'tags-box', 'tags-suggest', 'post', 'press-this', 'editor-expand', 'link', 'comment', 'admin-gallery', - 'admin-widgets', 'theme', 'inline-edit-post', 'inline-edit-tax', 'plugin-install', 'updates', 'farbtastic', 'iris', - 'wp-color-picker', 'dashboard', 'list-revisions', 'media-grid', 'media', 'image-edit', 'set-post-thumbnail', - 'nav-menu', 'custom-header', 'custom-background', 'media-gallery', 'svg-painter', 'customize-nav-menus', - ); - - return $wp_default_scripts; - - } - - function wp_default_styles() { - - $wp_default_styles = array( - 'admin-bar', 'colors', 'ie', 'wp-auth-check', 'wp-jquery-ui-dialog', 'wppb-serial-notice-css', - 'common', 'forms', 'admin-menu', 'dashboard', 'list-tables', 'edit', 'revisions', 'media', - 'themes', 'about', 'nav-menus', 'widgets', 'site-icon', 'l10n', 'wp-admin', 'login', 'install', - 'wp-color-picker', 'customize-controls', 'customize-widgets', 'customize-nav-menus', 'press-this', - 'buttons', 'dashicons', 'editor-buttons', 'media-views', 'wp-pointer', 'customize-preview', - 'wp-embed-template-ie', 'imgareaselect', 'mediaelement', 'wp-mediaelement', 'thickbox', - 'deprecated-media', 'farbtastic', 'jcrop', 'colors-fresh', 'open-sans', - ); - - return $wp_default_styles; - - } - - function get_hidden_capabilities() { - - $capabilities = array(); - - if( is_multisite() || ! defined( 'ALLOW_UNFILTERED_UPLOADS' ) || ! ALLOW_UNFILTERED_UPLOADS ) { - $capabilities['unfiltered_upload'] = 'unfiltered_upload'; - } - - if( is_multisite() || ( defined( 'DISALLOW_UNFILTERED_HTML' ) && DISALLOW_UNFILTERED_HTML ) ) { - $capabilities['unfiltered_html'] = 'unfiltered_html'; - } - - if( is_multisite() || ( defined( 'DISALLOW_FILE_EDIT' ) && DISALLOW_FILE_EDIT ) ) { - $capabilities['edit_files'] = 'edit_files'; - $capabilities['edit_plugins'] = 'edit_plugins'; - $capabilities['edit_themes'] = 'edit_themes'; - } - - if( is_multisite() || ( defined( 'DISALLOW_FILE_MODS' ) && DISALLOW_FILE_MODS ) ) { - $capabilities['edit_files'] = 'edit_files'; - $capabilities['edit_plugins'] = 'edit_plugins'; - $capabilities['edit_themes'] = 'edit_themes'; - $capabilities['update_plugins'] = 'update_plugins'; - $capabilities['delete_plugins'] = 'delete_plugins'; - $capabilities['install_plugins'] = 'install_plugins'; - $capabilities['upload_plugins'] = 'upload_plugins'; - $capabilities['update_themes'] = 'update_themes'; - $capabilities['delete_themes'] = 'delete_themes'; - $capabilities['install_themes'] = 'install_themes'; - $capabilities['upload_themes'] = 'upload_themes'; - $capabilities['update_core'] = 'update_core'; - } - - return array_unique( $capabilities ); - - } - -} - -$wppb_generalSettings = get_option( 'wppb_general_settings', 'not_found' ); -if( $wppb_generalSettings != 'not_found' ) { - if( ! empty( $wppb_generalSettings['rolesEditor'] ) && ( $wppb_generalSettings['rolesEditor'] == 'yes' ) ) { - $wppb_role_editor_instance = new WPPB_Roles_Editor(); - } -} +wp_default_scripts(); + $scripts_exceptions = array( 'wppb-sitewide', 'acf-field-group', 'acf-pro-field-group', 'acf-input', 'acf-pro-input' ); + foreach( $wp_scripts->registered as $key => $value ) { + if( ! in_array( $key, $wp_default_scripts ) && ! in_array( $key, $scripts_exceptions ) ) { + wp_deregister_script( $key ); + } + } + + $wp_default_styles = $this->wp_default_styles(); + $styles_exceptions = array( 'wppb-serial-notice-css', 'acf-global' ); + foreach( $wp_styles->registered as $key => $value ) { + if( ! in_array( $key, $wp_default_styles ) && ! in_array( $key, $styles_exceptions ) ) { + wp_deregister_style( $key ); + } + } + + wp_enqueue_script( 'wppb_select2_js', WPPB_PLUGIN_URL .'assets/js/select2/select2.min.js', array( 'jquery' ), PROFILE_BUILDER_VERSION ); + wp_enqueue_style( 'wppb_select2_css', WPPB_PLUGIN_URL .'assets/css/select2/select2.min.css', array(), PROFILE_BUILDER_VERSION ); + + wp_enqueue_script( 'wppb_roles_editor_js', plugin_dir_url( __FILE__ ) .'assets/js/roles-editor.js', array( 'jquery', 'wppb_select2_js' ), PROFILE_BUILDER_VERSION ); + wp_enqueue_style( 'wppb_roles_editor_css', plugin_dir_url( __FILE__ ) .'assets/css/roles-editor.css', array(), PROFILE_BUILDER_VERSION ); + + if( $current_screen->id == 'wppb-roles-editor' ) { + $role_slug = $this->sanitize_role( get_post_meta( $post->ID, 'wppb_role_slug', true ) ); + $current_role = get_role( $role_slug ); + $current_user = wp_get_current_user(); + + if( isset( $current_role ) && is_array( $current_role->capabilities ) ) { + $role_capabilities = $current_role->capabilities; + + // True if current user got this role + if( isset( $role_slug ) && in_array( $role_slug, $current_user->roles ) ) { + $current_user_role = TRUE; + } else { + $current_user_role = FALSE; + } + + // Get current role users count + $current_role_users_count = $this->count_role_users( $current_role->name ); + } else { + $role_capabilities = NULL; + $current_role_users_count = NULL; + $current_user_role = FALSE; + } + } else { + $role_capabilities = NULL; + $current_role_users_count = NULL; + $current_user_role = FALSE; + } + + // Remove old WordPress levels system + // Use filter and return FALSE if you need the old levels capability system + $remove_old_levels = apply_filters( 'wppb_remove_old_levels', TRUE ); + if( $remove_old_levels === TRUE ) { + $role_capabilities = $this->remove_old_labels( $role_capabilities ); + } + + $admin_capabilities = array( + 'manage_options', + 'activate_plugins', + 'delete_plugins', + 'install_plugins', + 'manage_network_options', + 'manage_network', + 'manage_network_plugins', + 'upload_plugins' + ); + + $group_capabilities = $this->group_capabilities(); + $hidden_capabilities = NULL; + + $remove_hidden_capabilities = apply_filters( 'wppb_re_remove_hidden_caps', TRUE ); + if( $remove_hidden_capabilities === TRUE ) { + $group_capabilities['general']['capabilities'] = array_diff( $group_capabilities['general']['capabilities'], $this->get_hidden_capabilities() ); + $group_capabilities['appearance']['capabilities'] = array_diff( $group_capabilities['appearance']['capabilities'], $this->get_hidden_capabilities() ); + $group_capabilities['plugins']['capabilities'] = array_diff( $group_capabilities['plugins']['capabilities'], $this->get_hidden_capabilities() ); + $group_capabilities['post_types']['attachment']['capabilities'] = array_diff( $group_capabilities['post_types']['attachment']['capabilities'], $this->get_hidden_capabilities() ); + + if( $role_capabilities !== NULL ) { + $role_capabilities = array_diff_key( $role_capabilities, $this->get_hidden_capabilities() ); + } + + $hidden_capabilities = $this->get_hidden_capabilities(); + if( empty( $hidden_capabilities ) ) { + $hidden_capabilities = NULL; + } + } + + $all_capabilities = $this->get_all_capabilities(); + + $custom_capabilities = get_option( 'wppb_roles_editor_capabilities', 'not_set' ); + if( $custom_capabilities != 'not_set' && ! empty( $custom_capabilities['custom']['capabilities'] ) ) { + foreach( $custom_capabilities['custom']['capabilities'] as $custom_capability_key => $custom_capability ) { + if( ! in_array( $custom_capability, $all_capabilities ) ) { + $all_capabilities[$custom_capability] = $custom_capability; + } + } + } + + $vars_array = array( + 'ajaxUrl' => admin_url( 'admin-ajax.php' ), + 'current_screen_action' => $current_screen->action, + 'capabilities' => $group_capabilities, + 'current_role_capabilities' => $role_capabilities, + 'current_role_users_count' => $current_role_users_count, + 'all_capabilities' => $all_capabilities, + 'current_user_role' => $current_user_role, + 'admin_capabilities' => $admin_capabilities, + 'hidden_capabilities' => $hidden_capabilities, + 'default_role_text' => esc_html__( 'Default Role', 'profile_builder' ), + 'your_role_text' => esc_html__( 'Your Role', 'profile_builder' ), + 'role_name_required_error_text' => esc_html__( 'Role name is required.', 'profile_builder' ), + 'no_capabilities_found_text' => esc_html__( 'No capabilities found.', 'profile_builder' ), + 'select2_placeholder_text' => esc_html__( 'Select capabilities', 'profile_builder' ), + 'delete_permanently_text' => esc_html__( 'Delete Permanently', 'profile_builder' ), + 'capability_perm_delete_text' => esc_html__( "This will permanently delete the capability from your site and from every user role.\n\nIt can't be undone!", 'profile_builder' ), + 'new_cap_update_title_text' => esc_html__( 'This capability is not saved until you click Update!', 'profile_builder' ), + 'new_cap_publish_title_text' => esc_html__( 'This capability is not saved until you click Publish!', 'profile_builder' ), + 'delete_text' => esc_html__( 'Delete', 'profile-builder' ), + 'cancel_text' => esc_html__( 'Cancel', 'profile_builder' ), + 'add_new_capability_text' => esc_html__( 'Add New Capability', 'profile_builder' ), + 'capability_text' => esc_html__( 'Capability', 'profile-builder' ), + 'cap_no_delete_text' => esc_html__( 'You can\'t delete this capability from your role.', 'profile-builder' ) + ); + + wp_localize_script( 'wppb_roles_editor_js', 'wppb_roles_editor_data', $vars_array ); + } + + } + + function count_role_users( $current_role_name ) { + + // Get current role users count + $user_count = count_users(); + + if( isset( $user_count['avail_roles'][$current_role_name] ) ) { + $current_role_users_count = $user_count['avail_roles'][$current_role_name]; + } else { + $current_role_users_count = NULL; + } + + return $current_role_users_count; + } + + function get_role_capabilities() { + + if( ! current_user_can( 'manage_options' ) ) { + die(); + } + + check_ajax_referer( 'wppb-re-ajax-nonce', 'security' ); + + $role = get_role( sanitize_text_field( $_POST['role'] ) ); + + if( isset( $role ) && ! empty( $role->capabilities ) ) { + $role_capabilities = $role->capabilities; + + // Remove old WordPress levels system + // Use filter and return FALSE if you need the old levels capability system + $remove_old_levels = apply_filters( 'wppb_remove_old_levels', TRUE ); + if( $remove_old_levels === TRUE ) { + $role_capabilities = $this->remove_old_labels( $role_capabilities ); + } + + die( json_encode( $role_capabilities ) ); + } + + die( 'no_caps' ); + } + + function edit_cpt_quick_links( $views ) { + + $edited_views = array(); + $edited_views['all'] = $views['all']; + + return $edited_views; + + } + + function create_roles_editor_cpt(){ + + $labels = array( + 'name' => esc_html__( 'Roles Editor', 'profile-builder' ), + 'singular_name' => esc_html__( 'Roles Editor', 'profile-builder' ), + 'add_new' => esc_html__( 'Add New Role', 'profile-builder' ), + 'add_new_item' => esc_html__( 'Add New Role', 'profile-builder' ), + 'edit_item' => esc_html__( 'Edit Role', 'profile-builder' ), + 'new_item' => esc_html__( 'New Role', 'profile-builder' ), + 'all_items' => esc_html__( 'Roles Editor', 'profile-builder' ), + 'view_item' => esc_html__( 'View Role', 'profile-builder' ), + 'search_items' => esc_html__( 'Search the Roles Editor', 'profile-builder' ), + 'not_found' => esc_html__( 'No roles found', 'profile-builder' ), + 'not_found_in_trash' => esc_html__( 'No roles found in trash', 'profile-builder' ), + 'name_admin_bar' => esc_html__( 'Role', 'profile-builder' ), + 'parent_item_colon' => '', + 'menu_name' => esc_html__( 'Roles Editor', 'profile-builder' ) + ); + + $args = array( + 'labels' => $labels, + 'public' => false, + 'publicly_queryable' => false, + 'show_ui' => true, + 'query_var' => true, + 'show_in_menu' => 'users.php', + 'has_archive' => false, + 'hierarchical' => false, + 'capability_type' => 'post', + 'supports' => array( 'title' ) + ); + + register_post_type( 'wppb-roles-editor', $args ); + + } + + function change_title_text( $title ) { + + $screen = get_current_screen(); + + if( $screen->post_type == 'wppb-roles-editor' ) { + $title = esc_html__( 'Enter role name here', 'profile_builder' ); + } + + return $title; + + } + + function change_post_updated_messages( $messages ) { + + global $post; + + $messages['wppb-roles-editor'] = array( + 0 => '', + 1 => esc_html__( 'Role updated.', 'profile-builder' ), + 2 => esc_html__( 'Custom field updated.', 'profile-builder' ), + 3 => esc_html__( 'Custom field deleted.', 'profile-builder' ), + 4 => esc_html__( 'Role updated.', 'profile-builder' ), + 5 => isset( $_GET['revision'] ) ? sprintf( esc_html__( 'Role restored to revision from %s' ), wp_post_revision_title( (int) $_GET['revision'], false ) ) : false, + 6 => esc_html__( 'Role created.', 'profile-builder' ), + 7 => esc_html__( 'Role saved.', 'profile-builder' ), + 8 => esc_html__( 'Role submitted.', 'profile-builder' ), + 9 => sprintf( esc_html__( 'Role scheduled for: %1$s', 'profile-builder' ), date_i18n( __( 'M j, Y @ G:i' ), strtotime( $post->post_date ) ) ), + 10 => esc_html__( 'Role draft updated.', 'profile-builder' ), + ); + + return $messages; + + } + + function create_post_for_role() { + + $screen = get_current_screen(); + + if( $screen->id == 'edit-wppb-roles-editor' ) { + global $wpdb; + global $wp_roles; + + $added_posts = array(); + + $args = array( + 'numberposts' => -1, + 'post_type' => 'wppb-roles-editor' + ); + $posts = get_posts( $args ); + + foreach( $posts as $key => $value ) { + $post_id = intval( $value->ID ); + $role_slug_meta = $this->sanitize_role( get_post_meta( $post_id, 'wppb_role_slug', true ) ); + if( ! empty( $role_slug_meta ) ) { + if( ! array_key_exists( $role_slug_meta, $wp_roles->role_names ) ) { + $post_meta = get_post_meta( $post_id ); + foreach( $post_meta as $post_meta_key => $post_meta_value ) { + delete_post_meta( $post_id, $post_meta_key ); + } + + $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->posts WHERE post_type = %s AND ID = %d", "wppb-roles-editor", $post_id ) ); + } else { + $added_posts[] = $role_slug_meta; + } + } + } + + foreach( $wp_roles->role_names as $role_slug => $role_display_name ) { + if( ! in_array( $role_slug, $added_posts ) ) { + $id = wp_insert_post( array( + 'post_title' => $role_display_name, + 'post_type' => 'wppb-roles-editor', + 'post_content' => '', + 'post_status' => 'publish' + ) ); + + update_post_meta( $id, 'wppb_role_slug', $role_slug ); + } + } + } + + } + + function add_extra_column_for_roles_editor_cpt( $columns ) { + + $columns = array( + 'title' => esc_html__( 'Role Name', 'profile-builder' ), + 'role' => esc_html__( 'Role Slug', 'profile-builder' ), + 'capabilities' => esc_html__( 'Capabilities', 'profile-builder' ), + 'users' => esc_html__( 'Users', 'profile-builder' ) + ); + + return apply_filters( 'wppb_manage_roles_columns', $columns ); + + } + + function custom_column_content_for_roles_editor_cpt( $column_name, $post_id ) { + + $role_slug = $this->sanitize_role( get_post_meta( $post_id, 'wppb_role_slug', true ) ); + + if( isset( $role_slug ) ) { + $role = get_role( $role_slug ); + + if( $column_name == 'role' ) { + echo ''; + } + + if( $column_name == 'capabilities' && isset( $role ) ) { + // Remove old WordPress levels system + // Use filter and return FALSE if you need the old levels capability system + $remove_old_levels = apply_filters( 'wppb_remove_old_levels', TRUE ); + if( $remove_old_levels === TRUE ) { + $role_capabilities = $this->remove_old_labels( $role->capabilities ); + } else { + $role_capabilities = $role->capabilities; + } + + echo count( $role_capabilities ); + } + + if( $column_name == 'users' && isset( $role ) ) { + $role_users_count = $this->count_role_users( $role->name ); + + if( ! isset( $role_users_count ) ) { + $role_users_count = 0; + } + + echo $role_users_count; + } + } + } + + function register_meta_boxes() { + + remove_meta_box( 'slugdiv', 'wppb-roles-editor', 'normal' ); + add_meta_box( 'wppb_edit_role_capabilities', esc_html__( 'Edit Role Capabilities', 'profile_builder' ), array( $this, 'edit_role_capabilities_meta_box_callback' ), 'wppb-roles-editor', 'normal', 'high' ); + + } + + function edit_role_capabilities_meta_box_callback() { + + ?> +
            +
            + + + + + + + + + + + + + +
            + +
            +
              +
            • + +
            • + +
            • + +
            • + +
            • + +
            • + +
            • + +
            • + +
            • + +
            • + +
            • + +
            • + +
            • + +
            • + +
            • + +
            • + +
            • + +
            • + +
            • + +
            • +
            + +
            +
            +
            +
            +
            +
            + + + +
            + post_type == $post_type ) { + $role_slug = $this->sanitize_role( get_post_meta( $post->ID, 'wppb_role_slug', true ) ); + + ?> + + +
            + + : 0 +
            + +
            + + : 0 +
            + +
            + + + + action == 'add' ? '' : 'disabled'; ?>> + +
            + $value ) { + unset( $capabilities[$value] ); + } + + return $capabilities; + + } + + function modify_post_title( $data ) { + + if( 'wppb-roles-editor' != $data['post_type'] || $data['post_status'] == 'auto-draft' ) { + return $data; + } + + if( ! current_user_can( 'manage_options' ) ) { + return $data; + } + + if( isset( $data['post_title'] ) ) { + $data['post_title'] = wp_strip_all_tags( $data['post_title'] ); + } + + return $data; + + } + + function add_post_meta( $post_id, $post ) { + + $post_type = get_post_type( $post_id ); + + if( 'wppb-roles-editor' != $post_type || $post->post_status == 'auto-draft' ) { + return; + } + + if( ! current_user_can( 'manage_options' ) ) { + return; + } + + if( isset( $_POST['wppb-role-slug-hidden'] ) ) { + $role_slug = trim( $_POST['wppb-role-slug-hidden'] ); + $role_slug = $this->sanitize_role( $role_slug ); + + update_post_meta( $post_id, 'wppb_role_slug', $role_slug ); + } + + } + + function update_role_capabilities() { + + if( ! current_user_can( 'manage_options' ) ) { + die(); + } + + check_ajax_referer( 'wppb-re-ajax-nonce', 'security' ); + + $role_slug = $this->sanitize_role( $_POST['role'] ); + + $role = get_role( $role_slug ); + + if( $role ) { + if( isset( $_POST['new_capabilities'] ) ) { + foreach( $_POST['new_capabilities'] as $key => $value ) { + $role->add_cap( sanitize_text_field( $key ) ); + } + } + + if( isset( $_POST['capabilities_to_delete'] ) ) { + foreach( $_POST['capabilities_to_delete'] as $key => $value ) { + $role->remove_cap( sanitize_text_field( $key ) ); + } + } + } else { + $capabilities = array(); + + if( isset( $_POST['all_capabilities'] ) ) { + foreach( $_POST['all_capabilities'] as $key => $value ) { + $capabilities[sanitize_text_field( $key )] = true; + }; + } + + $role_display_name = sanitize_text_field( $_POST['role_display_name'] ); + + add_role( $role_slug, $role_display_name, $capabilities ); + } + + die( 'role_capabilities_updated' ); + + } + + function group_capabilities() { + + $capabilities = get_option( 'wppb_roles_editor_capabilities', 'not_set' ); + + if( $capabilities == 'not_set' ) { + // We remove non-custom capabilities from this array later on + $custom_capabilities = $this->get_all_capabilities(); + $custom_capabilities = $this->remove_old_labels( $custom_capabilities ); + + // General capabilities + $general_capabilities = array( + 'label' => 'General', + 'icon' => 'dashicons-wordpress', + 'capabilities' => array( 'edit_dashboard', 'edit_files', 'export', 'import', 'manage_links', 'manage_options', 'moderate_comments', 'read', 'unfiltered_html', 'update_core' ) + ); + + // Themes management capabilities + $appearance_capabilities = array( + 'label' => 'Appearance', + 'icon' => 'dashicons-admin-appearance', + 'capabilities' => array( 'delete_themes', 'edit_theme_options', 'edit_themes', 'install_themes', 'switch_themes', 'update_themes' ) + ); + + // Plugins management capabilities + $plugins_capabilities = array( + 'label' => 'Plugins', + 'icon' => 'dashicons-admin-plugins', + 'capabilities' => array( 'activate_plugins', 'delete_plugins', 'edit_plugins', 'install_plugins', 'update_plugins' ) + ); + + // Users management capabilities + $users_capabilities = array( + 'label' => 'Users', + 'icon' => 'dashicons-admin-users', + 'capabilities' => array( 'add_users', 'create_roles', 'create_users', 'delete_roles', 'delete_users', 'edit_roles', 'edit_users', 'list_roles', 'list_users', 'promote_users', 'remove_users' ) + ); + + // Taxonomies capabilities - part 1 + $taxonomies_capabilities = array(); + $taxonomies = get_taxonomies( array(), 'objects' ); + foreach( $taxonomies as $taxonomy ) { + $taxonomies_capabilities = array_merge( $taxonomies_capabilities, array_values( (array) $taxonomy->cap ) ); + } + + // Post types capabilities + $post_types_capabilities = array(); + foreach( get_post_types( array(), 'objects' ) as $type ) { + + if( in_array( $type->name, array( 'revision', 'nav_menu_item', 'custom_css', 'customize_changeset', 'wppb-rf-cpt', 'wppb-epf-cpt', 'wppb-roles-editor' ) ) ) { + continue; + } + + $post_type_capabilities = $this->post_type_group_capabilities( $type->name ); + if( empty( $post_type_capabilities ) ) { + continue; + } + + $post_type_icon = $type->hierarchical ? 'dashicons-admin-page' : 'dashicons-admin-post'; + if( is_string( $type->menu_icon ) && preg_match( '/dashicons-/i', $type->menu_icon ) ) { + $post_type_icon = $type->menu_icon; + } else if( 'attachment' === $type->name ) { + $post_type_icon = 'dashicons-admin-media'; + } else if( 'download' === $type->name ) { + $post_type_icon = 'dashicons-download'; + } else if( 'product' === $type->name ) { + $post_type_icon = 'dashicons-cart'; + } + + $post_types_capabilities[$type->name] = array( + 'label' => $type->labels->name, + 'icon' => $post_type_icon, + 'capabilities' => $post_type_capabilities + ); + + $taxonomies_capabilities = array_diff( $taxonomies_capabilities, $post_type_capabilities ); + $custom_capabilities = array_diff( $custom_capabilities, $post_type_capabilities ); + } + + // Taxonomies capabilities - part 2 + $taxonomies_capabilities = array_diff( $taxonomies_capabilities, $general_capabilities['capabilities'], $appearance_capabilities['capabilities'], $plugins_capabilities['capabilities'], $users_capabilities['capabilities'] ); + $taxonomies_capabilities = array( + 'label' => 'Taxonomies', + 'icon' => '', + 'capabilities' => array_unique( $taxonomies_capabilities ) + ); + + // Custom capabilities + $custom_capabilities = array_diff( $custom_capabilities, $general_capabilities['capabilities'], $appearance_capabilities['capabilities'], $appearance_capabilities['capabilities'], $plugins_capabilities['capabilities'], $users_capabilities['capabilities'], $taxonomies_capabilities['capabilities'] ); + $custom_capabilities = array_values( $custom_capabilities ); + $custom_capabilities = array( + 'label' => 'Custom', + 'icon' => '', + 'capabilities' => array_unique( $custom_capabilities ) + ); + + // Create capabilities array + $capabilities = array( + 'general' => $general_capabilities, + 'post_types' => $post_types_capabilities, + 'taxonomies' => $taxonomies_capabilities, + 'appearance' => $appearance_capabilities, + 'plugins' => $plugins_capabilities, + 'users' => $users_capabilities, + 'custom' => $custom_capabilities + ); + + update_option( 'wppb_roles_editor_capabilities', $capabilities ); + } else { + $custom_capabilities = $this->get_all_capabilities(); + $custom_capabilities = $this->remove_old_labels( $custom_capabilities ); + + foreach( $capabilities['post_types'] as $key => $value ) { + $custom_capabilities = array_diff( $custom_capabilities, $value['capabilities'] ); + } + + foreach( $capabilities as $key => $value ) { + if( $key != 'post_types' && $key != 'custom' ) { + $custom_capabilities = array_diff( $custom_capabilities, $value['capabilities'] ); + } + } + + $custom_capabilities = array_values( $custom_capabilities ); + $custom_capabilities = array_unique( $custom_capabilities ); + $custom_capabilities = array_diff( $custom_capabilities, $capabilities['custom']['capabilities'] ); + + if( ! empty( $custom_capabilities ) ) { + $capabilities['custom']['capabilities'] = array_merge( $capabilities['custom']['capabilities'], $custom_capabilities ); + + update_option( 'wppb_roles_editor_capabilities', $capabilities ); + } + } + + return $capabilities; + + } + + function post_type_group_capabilities( $post_type = 'post' ) { + + $capabilities = (array) get_post_type_object( $post_type )->cap; + + unset( $capabilities['edit_post'] ); + unset( $capabilities['read_post'] ); + unset( $capabilities['delete_post'] ); + + $capabilities = array_values( $capabilities ); + + if( ! in_array( $post_type, array( 'post', 'page' ) ) ) { + // Get the post and page capabilities + $post_caps = array_values( (array) get_post_type_object( 'post' )->cap ); + $page_caps = array_values( (array) get_post_type_object( 'page' )->cap ); + + // Remove post/page capabilities from the current post type capabilities + $capabilities = array_diff( $capabilities, $post_caps, $page_caps ); + } + + if( 'attachment' === $post_type ) { + $capabilities[] = 'unfiltered_upload'; + } + + return array_unique( $capabilities ); + + } + + function get_all_capabilities() { + + global $wp_roles; + + $capabilities = array(); + + foreach( $wp_roles->role_objects as $key => $role ) { + if( is_array( $role->capabilities ) ) { + foreach( $role->capabilities as $capability => $granted ) { + $capabilities[$capability] = $capability; + } + } + } + + return array_unique( $capabilities ); + + } + + function delete_capability_permanently() { + + if( ! current_user_can( 'manage_options' ) ) { + die(); + } + + check_ajax_referer( 'wppb-re-ajax-nonce', 'security' ); + + global $wp_roles; + + foreach( $wp_roles->role_names as $role_slug => $role_display_name ) { + $role = get_role( $role_slug ); + $role->remove_cap( sanitize_text_field( $_POST['capability'] ) ); + } + + $capabilities = get_option( 'wppb_roles_editor_capabilities', 'not_set' ); + + if( $capabilities != 'not_set' && ( $key = array_search( sanitize_text_field( $_POST['capability'] ), $capabilities['custom']['capabilities'] ) ) !== false ) { + unset( $capabilities['custom']['capabilities'][$key] ); + $capabilities['custom']['capabilities'] = array_values( $capabilities['custom']['capabilities'] ); + + update_option( 'wppb_roles_editor_capabilities', $capabilities ); + } + + die(); + + } + + function remove_filter_by_month_dropdown( $months, $post_type ) { + + if( $post_type == 'wppb-roles-editor' ) { + return __return_empty_array(); + } else { + return $months; + } + + } + + function modify_list_row_actions( $actions, $post ) { + global $wp_roles; + + if( $post->post_type == 'wppb-roles-editor' ) { + $current_user = wp_get_current_user(); + $default_role = get_option( 'default_role' ); + $role_slug = get_post_meta( $post->ID, 'wppb_role_slug', true ); + + $url = admin_url( 'post.php?post=' . $post->ID ); + + $edit_link = add_query_arg( array( 'action' => 'edit' ), $url ); + + $actions = array( + 'edit' => sprintf( + '%2$s', + esc_url( $edit_link ), + esc_html__( 'Edit', 'profile-builder' ) + ) + ); + + $clone_url = admin_url( 'post-new.php?post_type=wppb-roles-editor' ); + $clone_link = add_query_arg( array( 'action' => 'wppb_re_clone', 'wppb_re_clone' => $this->sanitize_role( $role_slug ) ), $clone_url ); + + $actions = array_merge( $actions, array( + 'clone' => sprintf( + '%2$s', + esc_url( $clone_link ), + esc_html__( 'Clone', 'profile-builder' ) + ) + ) + ); + + if( in_array( $role_slug, $current_user->roles ) && ( ! is_multisite() || ( is_multisite() && ! is_super_admin() ) ) && ( !empty( $wp_roles->roles[$role_slug]['capabilities'] ) && array_key_exists( 'manage_options', $wp_roles->roles[$role_slug]['capabilities'] ) ) ) { + $actions = array_merge( $actions, array( + 'delete_notify your_role' => ''. esc_html__( 'Delete', 'profile-builder' ) .'' + ) + ); + } elseif( $role_slug == $default_role ) { + $actions = array_merge( $actions, array( + 'default_role' => sprintf( + '%s', + esc_url( admin_url( 'options-general.php#default_role' ) ), + esc_html__( 'Change Default', 'profile-builder' ) ), + 'delete_notify' => ''. esc_html__( 'Delete', 'profile-builder' ) .'' + ) + ); + } else { + $delete_link = wp_nonce_url( add_query_arg( array( 'action' => 'delete' ), $url ), 'delete-post_'. $post->ID ); + + $actions = array_merge( $actions, array( + 'delete' => sprintf( + '%3$s', + esc_url( $delete_link ), + esc_html__( 'Are you sure?\nThis will permanently delete the role and cannot be undone!\nUsers assigned only on this role will be moved to the default role.', 'profile_builder' ), + esc_html__( 'Delete', 'profile-builder' ) + ) + ) + ); + } + } + + return $actions; + + } + + function sanitize_role( $role ) { + + $role = strtolower( $role ); + $role = wp_strip_all_tags( $role ); + $role = preg_replace( '/[^a-z0-9_\-\s]/', '', $role ); + $role = str_replace( ' ', '_', $role ); + + return $role; + + } + + function delete_role_permanently( $post_id ) { + + global $post_type; + if( $post_type != 'wppb-roles-editor' ) { + return; + } + + check_admin_referer( 'delete-post_'. $post_id ); + + $role_slug = get_post_meta( $post_id, 'wppb_role_slug', true ); + $role_slug = $this->sanitize_role( $role_slug ); + + $default_role = get_option( 'default_role' ); + + if( $role_slug == $default_role ) { + return; + } + + $users = get_users( array( 'role' => $role_slug ) ); + + if( is_array( $users ) ) { + foreach( $users as $user ) { + if( $user->has_cap( $role_slug ) && count( $user->roles ) <= 1 ) { + $user->set_role( $default_role ); + } elseif( $user->has_cap( $role_slug ) ) { + $user->remove_role( $role_slug ); + } + } + } + + remove_role( $role_slug ); + + } + + function wp_default_scripts() { + + $wp_default_scripts = array( + 'jquery', 'jquery-core', 'jquery-migrate', 'jquery-ui-core', 'jquery-ui-accordion', + 'jquery-ui-autocomplete', 'jquery-ui-button', 'jquery-ui-datepicker', 'jquery-ui-dialog', + 'jquery-ui-draggable', 'jquery-ui-droppable', 'jquery-ui-menu', 'jquery-ui-mouse', + 'jquery-ui-position', 'jquery-ui-progressbar', 'jquery-ui-resizable', 'jquery-ui-selectable', + 'jquery-ui-slider', 'jquery-ui-sortable', 'jquery-ui-spinner', 'jquery-ui-tabs', + 'jquery-ui-tooltip', 'jquery-ui-widget', 'underscore', 'backbone', 'utils', 'common', + 'wp-a11y', 'sack', 'quicktags', 'colorpicker', 'editor', 'wp-fullscreen-stub', 'wp-ajax-response', + 'wp-pointer', 'heartbeat', 'wp-auth-check', 'wp-lists', 'prototype', 'scriptaculous-root', + 'scriptaculous-builder', 'scriptaculous-dragdrop', 'scriptaculous-effects', 'scriptaculous-slider', + 'scriptaculous-sound', 'scriptaculous-controls', 'scriptaculous', 'cropper', 'jquery-effects-core', + 'jquery-effects-blind', 'jquery-effects-bounce', 'jquery-effects-clip', 'jquery-effects-drop', + 'jquery-effects-explode', 'jquery-effects-fade', 'jquery-effects-fold', 'jquery-effects-highlight', + 'jquery-effects-puff', 'jquery-effects-pulsate', 'jquery-effects-scale', 'jquery-effects-shake', + 'jquery-effects-size', 'jquery-effects-slide', 'jquery-effects-transfer', 'jquery-ui-selectmenu', + 'jquery-form', 'jquery-color', 'schedule', 'jquery-query', 'jquery-serialize-object', 'jquery-hotkeys', + 'jquery-table-hotkeys', 'jquery-touch-punch', 'suggest', 'imagesloaded', 'masonry', 'jquery-masonry', + 'thickbox', 'jcrop', 'swfobject', 'plupload', 'plupload-all', 'plupload-html5', 'plupload-flash', + 'plupload-silverlight', 'plupload-html4', 'plupload-handlers', 'wp-plupload', 'swfupload', 'swfupload-swfobject', + 'swfupload-queue', 'swfupload-speed', 'swfupload-all', 'swfupload-handlers', 'comment-reply', 'json2', + 'underscore', 'backbone', 'wp-util', 'wp-backbone', 'revisions', 'imgareaselect', 'mediaelement', + 'wp-mediaelement', 'froogaloop', 'wp-playlist', 'zxcvbn-async', 'password-strength-meter', 'user-profile', + 'language-chooser', 'user-suggest', 'admin-bar', 'wplink', 'wpdialogs', 'word-count', 'media-upload', + 'hoverIntent', 'customize-base', 'customize-loader', 'customize-preview', 'customize-models', 'customize-views', + 'customize-controls', 'customize-selective-refresh', 'customize-widgets', 'customize-preview-widgets', + 'customize-preview-nav-menus', 'wp-custom-header', 'accordion', 'shortcode', 'media-models', 'wp-embed', + 'media-views', 'media-editor', 'media-audiovideo', 'mce-view', 'wp-api', 'admin-tags', 'admin-comments', 'xfn', + 'postbox', 'tags-box', 'tags-suggest', 'post', 'press-this', 'editor-expand', 'link', 'comment', 'admin-gallery', + 'admin-widgets', 'theme', 'inline-edit-post', 'inline-edit-tax', 'plugin-install', 'updates', 'farbtastic', 'iris', + 'wp-color-picker', 'dashboard', 'list-revisions', 'media-grid', 'media', 'image-edit', 'set-post-thumbnail', + 'nav-menu', 'custom-header', 'custom-background', 'media-gallery', 'svg-painter', 'customize-nav-menus', + ); + + return $wp_default_scripts; + + } + + function wp_default_styles() { + + $wp_default_styles = array( + 'admin-bar', 'colors', 'ie', 'wp-auth-check', 'wp-jquery-ui-dialog', 'wppb-serial-notice-css', + 'common', 'forms', 'admin-menu', 'dashboard', 'list-tables', 'edit', 'revisions', 'media', + 'themes', 'about', 'nav-menus', 'widgets', 'site-icon', 'l10n', 'wp-admin', 'login', 'install', + 'wp-color-picker', 'customize-controls', 'customize-widgets', 'customize-nav-menus', 'press-this', + 'buttons', 'dashicons', 'editor-buttons', 'media-views', 'wp-pointer', 'customize-preview', + 'wp-embed-template-ie', 'imgareaselect', 'mediaelement', 'wp-mediaelement', 'thickbox', + 'deprecated-media', 'farbtastic', 'jcrop', 'colors-fresh', 'open-sans', + ); + + return $wp_default_styles; + + } + + function get_hidden_capabilities() { + + $capabilities = array(); + + if( is_multisite() || ! defined( 'ALLOW_UNFILTERED_UPLOADS' ) || ! ALLOW_UNFILTERED_UPLOADS ) { + $capabilities['unfiltered_upload'] = 'unfiltered_upload'; + } + + if( is_multisite() || ( defined( 'DISALLOW_UNFILTERED_HTML' ) && DISALLOW_UNFILTERED_HTML ) ) { + $capabilities['unfiltered_html'] = 'unfiltered_html'; + } + + if( is_multisite() || ( defined( 'DISALLOW_FILE_EDIT' ) && DISALLOW_FILE_EDIT ) ) { + $capabilities['edit_files'] = 'edit_files'; + $capabilities['edit_plugins'] = 'edit_plugins'; + $capabilities['edit_themes'] = 'edit_themes'; + } + + if( is_multisite() || ( defined( 'DISALLOW_FILE_MODS' ) && DISALLOW_FILE_MODS ) ) { + $capabilities['edit_files'] = 'edit_files'; + $capabilities['edit_plugins'] = 'edit_plugins'; + $capabilities['edit_themes'] = 'edit_themes'; + $capabilities['update_plugins'] = 'update_plugins'; + $capabilities['delete_plugins'] = 'delete_plugins'; + $capabilities['install_plugins'] = 'install_plugins'; + $capabilities['upload_plugins'] = 'upload_plugins'; + $capabilities['update_themes'] = 'update_themes'; + $capabilities['delete_themes'] = 'delete_themes'; + $capabilities['install_themes'] = 'install_themes'; + $capabilities['upload_themes'] = 'upload_themes'; + $capabilities['update_core'] = 'update_core'; + } + + return array_unique( $capabilities ); + + } + +} + +$wppb_generalSettings = get_option( 'wppb_general_settings', 'not_found' ); +if( $wppb_generalSettings != 'not_found' ) { + if( ! empty( $wppb_generalSettings['rolesEditor'] ) && ( $wppb_generalSettings['rolesEditor'] == 'yes' ) ) { + $wppb_role_editor_instance = new WPPB_Roles_Editor(); + } +} diff --git a/profile-builder/features/upgrades/upgrades-functions.php b/profile-builder/features/upgrades/upgrades-functions.php index 3c58b3f..7ffe58d 100644 --- a/profile-builder/features/upgrades/upgrades-functions.php +++ b/profile-builder/features/upgrades/upgrades-functions.php @@ -1,641 +1,641 @@ - $value ){ - if ( ( $value['item_type'] == 'checkbox' ) || ( $value['item_type'] == 'radio' ) || ( $value['item_type'] == 'select' ) ){ - if ( isset( $custom_fields[$key]['item_option_values'] ) ){ - $custom_fields[$key]['item_option_labels'] = $custom_fields[$key]['item_option_values']; - unset( $custom_fields[$key]['item_option_values'] ); - } - - }else - unset( $custom_fields[$key]['item_option_values'] ); - } - - update_option( 'wppb_custom_fields', $custom_fields ); - } -} - - -/** - * Function that checks if there is at least one EP and/or R form. In the execution timeline this function runs faster than the wppb_prepopulate_fields function - * - * @since v.2.0 - * - * @return void - */ -function wppb_pro_hobbyist_free_v2_0(){ - $wppb_manage_fields = get_option( 'wppb_manage_fields', 'not_found' ); - $backed_up_manage_fields = array(); - - // part that handles the manage fields - if ( $wppb_manage_fields == 'not_found' ){ - - $old_default_fields = get_option( 'wppb_default_settings', 'not_found' ); - - if ( $old_default_fields != 'not_found' ){ - $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - Name (Heading)', '', 'No' ); - - if ( $old_default_fields['username'] == 'show' ) - $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - Username', '', ucfirst( trim( $old_default_fields['usernameRequired'] ) ), __( 'The usernames cannot be changed.', 'profile-builder' ) ); - - if ( $old_default_fields['firstname'] == 'show' ) - $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - First Name', 'first_name', ucfirst( trim( $old_default_fields['firstnameRequired'] ) ) ); - - if ( $old_default_fields['lastname'] == 'show' ) - $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - Last Name', 'last_name', ucfirst( trim( $old_default_fields['lastnameRequired'] ) ) ); - - if ( $old_default_fields['nickname'] == 'show' ) - $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - Nickname', 'nickname', ucfirst( trim( $old_default_fields['nicknameRequired'] ) ) ); - - if ( $old_default_fields['dispname'] == 'show' ) - $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - Display name publicly as', '', ucfirst( trim( $old_default_fields['dispnameRequired'] ) ) ); - - $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - Contact Info (Heading)', '', 'No' ); - - if ( $old_default_fields['email'] == 'show' ) - $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - E-mail', '', ucfirst( trim( $old_default_fields['emailRequired'] ) ), '(required)' ); - - if ( $old_default_fields['website'] == 'show' ) - $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - Website', '', ucfirst( trim( $old_default_fields['websiteRequired'] ) ) ); - - if ( $old_default_fields['aim'] == 'show' ) - $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - AIM', 'aim', ucfirst( trim( $old_default_fields['aimRequired'] ) ) ); - - if ( $old_default_fields['yahoo'] == 'show' ) - $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - Yahoo IM', 'yim', ucfirst( trim( $old_default_fields['yahooRequired'] ) ) ); - - if ( $old_default_fields['jabber'] == 'show' ) - $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - Jabber / Google Talk', 'jabber', ucfirst( trim( $old_default_fields['jabberRequired'] ) ) ); - - $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - About Yourself (Heading)', '', 'No' ); - - if ( $old_default_fields['bio'] == 'show' ) - $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - Biographical Info', 'description', ucfirst( trim( $old_default_fields['bioRequired'] ) ) ); - - if ( $old_default_fields['password'] == 'show' ){ - $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - Password', '', ucfirst( trim( $old_default_fields['passwordRequired'] ) ) ); - $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - Repeat Password', '', ucfirst( trim( $old_default_fields['passwordRequired'] ) ) ); - } - - }else{ - $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - Name (Heading)', '', 'No' ); - $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - Username', '', 'Yes', __( 'The usernames cannot be changed.', 'profile-builder' ) ); - $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - First Name', 'first_name', 'No' ); - $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - Last Name', 'last_name', 'No' ); - $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - Nickname', 'nickname', 'No' ); - $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - Display name publicly as', '', 'No' ); - $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - Contact Info (Heading)', '', 'No' ); - $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - E-mail', '', 'Yes', '(required)' ); - $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - Website', '', 'No' ); - - // Default contact methods were removed in WP 3.6. A filter dictates contact methods. - if ( apply_filters( 'wppb_remove_default_contact_methods', get_site_option( 'initial_db_version' ) < 23588 ) ){ - $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - AIM', 'aim', 'No' ); - $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - Yahoo IM', 'yim', 'No' ); - $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - Jabber / Google Talk', 'jabber', 'No' ); - } - - $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - About Yourself (Heading)', '', 'No' ); - $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - Biographical Info', 'description', 'No' ); - $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - Password', '', 'Yes' ); - $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - Repeat Password', '', 'Yes' ); - } - - $old_custom_fields = get_option( 'wppb_custom_fields', 'not_found' ); - if( $old_custom_fields != 'not_found' && count( $old_custom_fields ) != 0 ){ - $existing_ids = array(); - foreach ( $old_custom_fields as $key => $value ) { - $local_array = array(); - - if( isset( $value['id'] ) ) - $existing_ids[] = $value['id']; - - /* id will be set up at a later point */ - $local_array['id'] = ( isset( $value['id'] ) ? trim( $value['id'] ) : '' ); - $local_array['meta-name'] = ( isset( $value['item_metaName'] ) ? trim( $value['item_metaName'] ) : '' ); - $local_array['field-title'] = ( isset( $value['item_title'] ) ? trim( $value['item_title'] ) : '' ); - $local_array['description'] = ( isset( $value['item_desc'] ) ? $value['item_desc'] : '' ); - $local_array['required'] = 'No'; - $local_array['overwrite-existing'] = 'No'; - $local_array['row-count'] = '5'; - $local_array['allowed-image-extensions'] = '.*'; - $local_array['allowed-upload-extensions'] = '.*'; - $local_array['avatar-size'] = '100'; - $local_array['date-format'] = 'mm/dd/yy'; - $local_array['terms-of-agreement'] = ''; - $local_array['options'] = ''; - $local_array['labels'] = ''; - $local_array['public-key'] = ''; - $local_array['private-key'] = ''; - $local_array['default-value'] = ''; - $local_array['default-option'] = ''; - $local_array['default-options'] = ''; - $local_array['default-content'] = ''; - - switch ( $value['item_type' ] ){ - case "heading":{ - $local_array['field'] = 'Heading'; - $local_array['meta-name'] = ''; - break; - } - case "input":{ - $local_array['field'] = 'Input'; - $local_array['required'] = ucfirst( trim( $value['item_required'] ) ); - break; - } - case "hiddenInput":{ - $local_array['field'] = 'Input (Hidden)'; - $local_array['default-value'] = ( isset( $value['item_options'] ) ? trim( $value['item_options'] ) : '' ); - break; - } - case "checkbox":{ - $local_array['field'] = 'Checkbox'; - $local_array['options'] = ( isset( $value['item_options'] ) ? trim( $value['item_options'] ) : '' ); - $local_array['labels'] = ( isset( $value['item_option_labels'] ) ? trim( $value['item_option_labels'] ) : '' ); - $local_array['required'] = ucfirst( trim( $value['item_required'] ) ); - break; - } - case "agreeToTerms":{ - $local_array['field'] = 'Checkbox (Terms and Conditions)'; - $local_array['required'] = ucfirst( trim( "Yes" ) ); - break; - } - case "radio":{ - $local_array['field'] = 'Radio'; - $local_array['options'] = ( isset( $value['item_options'] ) ? trim( $value['item_options'] ) : '' ); - $local_array['labels'] = ( isset( $value['item_option_labels'] ) ? trim( $value['item_option_labels'] ) : '' ); - $local_array['required'] = ucfirst( trim( $value['item_required'] ) ); - break; - } - case "select":{ - $local_array['field'] = 'Select'; - $local_array['options'] = ( isset( $value['item_options'] ) ? trim( $value['item_options'] ) : '' ); - $local_array['labels'] = ( isset( $value['item_option_labels'] ) ? trim( $value['item_option_labels'] ) : '' ); - $local_array['required'] = ucfirst( trim( $value['item_required'] ) ); - break; - } - case "countrySelect":{ - $local_array['field'] = 'Select (Country)'; - $local_array['required'] = ucfirst( trim( $value['item_required'] ) ); - break; - } - case "timeZone":{ - $local_array['field'] = 'Select (Timezone)'; - $local_array['required'] = ucfirst( trim( $value['item_required'] ) ); - break; - } - case "datepicker":{ - $local_array['field'] = 'Datepicker'; - $local_array['required'] = ucfirst( trim( $value['item_required'] ) ); - break; - } - case "textarea":{ - $local_array['field'] = 'Textarea'; - $local_array['row-count'] = ( isset( $value['item_options'] ) ? trim( $value['item_options'] ) : '' ); - $local_array['required'] = ucfirst( trim( $value['item_required'] ) ); - break; - } - case "upload":{ - $local_array['field'] = 'Upload'; - $local_array['allowed-upload-extensions'] = ( isset( $value['item_options'] ) ? trim( $value['item_options'] ) : $local_array['allowed-upload-extensions'] ); - $local_array['required'] = ucfirst( trim( $value['item_required'] ) ); - break; - } - case "avatar":{ - $local_array['field'] = 'Avatar'; - $local_array['avatar-size'] = ( isset( $value['item_options'] ) ? trim( $value['item_options'] ) : $local_array['avatar-size'] ); - $local_array['required'] = ucfirst( trim( $value['item_required'] ) ); - break; - } - } - - array_push( $backed_up_manage_fields, $local_array ); - } - } - } - - - // part which handles the removal of the reCAPTCHA from the addon list - $wppb_module_settings = get_option( 'wppb_addon_settings', 'not_found' ); - if ( $wppb_module_settings != 'not_found' ){ - if ( isset( $wppb_module_settings['wppb_reCaptcha'] ) && ( $wppb_module_settings['wppb_reCaptcha'] == 'show' ) ){ - $recaptcha_settings = get_option( 'reCaptchaSettings' ); - - if ( ( $recaptcha_settings != 'no_found' ) || ( count( $recaptcha_settings ) != 0 ) ){ - $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'reCAPTCHA', '', 'Yes', '', trim( $recaptcha_settings['publicKey'] ), trim( $recaptcha_settings['privateKey'] ) ); - } - } - - unset( $wppb_module_settings['wppb_reCaptcha'] ); - $wppb_module_settings['wppb_multipleEditProfileForms'] = 'hide'; - $wppb_module_settings['wppb_multipleRegistrationForms'] = 'hide'; - - update_option( 'wppb_module_settings', $wppb_module_settings ); - } - - /* set up start from index. it is set from the highest existing index + 1 */ - if( !empty( $existing_ids ) ) { - rsort($existing_ids, SORT_NUMERIC ); - $start_from_index = $existing_ids[0] + 1; - } - else - $start_from_index = 1; - - /* set up ids for each field */ - if( !empty( $backed_up_manage_fields ) ){ - foreach( $backed_up_manage_fields as $key => $backed_up_manage_field ){ - if( empty( $backed_up_manage_fields[$key]['id'] ) ){ - $backed_up_manage_fields[$key]['id'] = $start_from_index; - $start_from_index ++; - } - } - } - add_option( 'wppb_manage_fields', $backed_up_manage_fields ); - - - // part which handles the general settings select->checkbox backwards comp. - $wppb_generalSettings = get_option( 'wppb_general_settings', 'not_found' ); - if ( ( $wppb_generalSettings != 'not_found' ) && ( count( $wppb_generalSettings ) > 1 ) ){ - if ( isset( $wppb_generalSettings['extraFieldsLayout'] ) && ( $wppb_generalSettings['extraFieldsLayout'] == 'no' ) ) - unset( $wppb_generalSettings['extraFieldsLayout'] ); - - else - $wppb_generalSettings['extraFieldsLayout'] = 'default'; - - update_option( 'wppb_general_settings', $wppb_generalSettings ); - } -} - - -/** - * Function that adds backwards compatibility for the userlisting - * - * @since v.2.0 - * - */ -function wppb_pro_userlisting_compatibility_upgrade(){ - if ( wppb_default_form_already_present( 'Userlisting', 'wppb-ul-cpt' ) ) - return ''; - - $old_userlisting_settings = get_option( 'customUserListingSettings', 'not_found' ); - if ( $old_userlisting_settings == 'not_found' ) - $old_userlisting_settings = get_option( 'userListingSettings' ); - - if ( $old_userlisting_settings == 'not_found' ) - return; - - $all_userlisting = ( isset( $old_userlisting_settings['allUserlisting'] ) ? wppb_replace_merge_tags( $old_userlisting_settings['allUserlisting'], true ) : '' ); - $single_userlisting = ( isset( $old_userlisting_settings['singleUserlisting'] ) ? wppb_replace_merge_tags( $old_userlisting_settings['singleUserlisting'] ) : '' ); - - if( !empty( $old_userlisting_settings['sortingNumber'] ) ) - $number_os_users_per_page = $old_userlisting_settings['sortingNumber']; - else - $number_os_users_per_page = '5'; - - if( !empty( $old_userlisting_settings['sortingCriteria'] ) ) - $default_sorting_criteria = $old_userlisting_settings['sortingCriteria']; - else - $default_sorting_criteria = 'login'; - - if( !empty( $old_userlisting_settings['sortingOrder'] ) ) - $default_sorting_order = $old_userlisting_settings['sortingOrder']; - else - $default_sorting_order = 'asc'; - - if( !empty( $old_userlisting_settings['avatarSize'] ) ) - $avatar_size_all = $old_userlisting_settings['avatarSize']; - else - $avatar_size_all = '40'; - - if( !empty( $old_userlisting_settings['avatarSize'] ) ) - $avatar_size_single = $old_userlisting_settings['avatarSize']; - else - $avatar_size_single = '60'; - - $userlisting_settings = array( array( 'roles-to-display' => '*', 'number-of-userspage' => $number_os_users_per_page, 'default-sorting-criteria' => $default_sorting_criteria, 'default-sorting-order' => $default_sorting_order, 'avatar-size-all-userlisting' => $avatar_size_all, 'avatar-size-single-userlisting' => $avatar_size_single ) ); - - $ul_post_id = wp_insert_post( array( 'post_title' => 'Userlisting', 'post_status' => 'publish', 'post_author' => get_current_user_id(), 'post_type' => 'wppb-ul-cpt', 'post_content' => 'Default Userlisting form placeholder' ), true ); - - add_post_meta( $ul_post_id, 'wppb-ul-templates', $all_userlisting ); - add_post_meta( $ul_post_id, 'wppb-single-ul-templates', $single_userlisting ); - add_post_meta( $ul_post_id, 'wppb_ul_page_settings', $userlisting_settings ); -} - - -/** - * Function that replaces the individual merge-tags in the userlisting - * - * @since v.2.0 - * - * @param string $content - * @param boolean $all_userlisting_form - * - * @return string - * - */ -function wppb_replace_merge_tags( $content, $all_userlisting_form = false ){ - $content = trim( $content ); - - $content = wppb_old_backwards_compatibility( $content ); - - $content = str_replace( '%%meta_number_of_posts%%', '{{{meta_number_of_posts}}}', $content ); - $content = str_replace( '%%extra_search_all_fields%%', '{{{extra_search_all_fields}}}', $content ); - $content = str_replace( '%%extra_more_info_link%%', '{{{more_info}}}', $content ); - $content = str_replace( '%%extra_while_users%%', '{{#users}}', $content ); - $content = str_replace( '%%extra_end_while_users%%', '{{/users}}', $content ); - $content = str_replace( '%%extra_avatar_or_gravatar%%', '{{{avatar_or_gravatar}}}', $content ); - $content = str_replace( '%%extra_go_back_link%%', '{{{extra_go_back_link}}}', $content ); - $content = str_replace( '%%meta_first_last_name%%', '{{meta_first_name}}{{meta_last_name}}', $content ); - $content = str_replace( '%%sort_first_last_name%%', '{{{sort_first_name}}}', $content ); - - preg_match_all( '/%%([a-z0-9\_]+)%%/', $content, $matches, PREG_PATTERN_ORDER ); - foreach ( $matches[0] as $key => $value ) - $content = ( ( strpos( $value, 'sort_' ) !== false ) ? str_replace( $value, '{{{'.$matches[1][$key].'}}}', $content ) : str_replace( $value, '{{'.$matches[1][$key].'}}', $content ) ); - - if ( $all_userlisting_form ) - $content .= '{{{pagination}}}'; - - return $content; -} - - -/** - * Function that replaces the individual merge-tags which existed the very first time. These consisted of %%item_title%% instead of the (then) newer %%item_meta_name%% - * - * @since v.2.0 - * - * @param string $content - * - * @return string - * - */ -function wppb_old_backwards_compatibility( $content ){ - $wppb_custom_fields = get_option( 'wppb_custom_fields', 'not_found' ); - - if ( ( $wppb_custom_fields == 'not_found' ) || ( count( $wppb_custom_fields ) < 1 ) ) - return $content; - - foreach( $wppb_custom_fields as $key => $value ){ - if ( ( isset( $value['item_type'] ) ) && ( trim( $value['item_type'] != '' ) ) ) - if ( ( isset( $value['item_metaName'] ) ) && ( trim( $value['item_metaName'] != '' ) ) ){ - /* TODO don't know what's supposed to be here and don't have time before launch */ - $string = str_replace( '%%meta_'.$value['item_title'].'%%', '%%meta_'.$value['item_metaName'].'%%', $string ); - $string = str_replace( '%%meta_description_'.$value['item_title'].'%%', '%%meta_description_'.$value['item_metaName'].'%%', $string ); - $string = str_replace( '%%sort_'.$value['item_title'].'%%', '%%sort_'.$value['item_metaName'].'%%', $string ); - } - } - - return $content; -} - - -/** - * Function that checks if a default userlisting-form is already present - * - * @since v.2.0 - * - * @param string $post_title - * @param string $post_type - * - * @return boolean - * - */ -function wppb_default_form_already_present( $post_title, $post_type ){ - $defaults = get_posts( array( 'posts_per_page' => -1, 'post_status' => array( 'publish' ), 'post_type' => $post_type, 'orderby' => 'post_date', 'order' => 'ASC' ) ); - foreach ( $defaults as $default ){ - if ( $default->post_content == 'Default '.$post_title.' form placeholder' ) - return true; - } - - return false; -} - - -/** - * Function that assures backwards compatibility for the email customizer - * - * @since v.2.0 - * - */ -function wppb_pro_email_customizer_compatibility_upgrade(){ - $email_customizer_array = get_option( 'emailCustomizer', 'not_found' ); - - if ( $email_customizer_array != 'not_found' ){ - wppb_replace_and_save( $email_customizer_array['from_name'], 'wppb_emailc_common_settings_from_name' ); - wppb_replace_and_save( $email_customizer_array['reply_to'], 'wppb_emailc_common_settings_from_reply_to_email' ); - wppb_replace_and_save( $email_customizer_array['default_registration_email_subject'], 'wppb_user_emailc_default_registration_email_subject' ); - wppb_replace_and_save( $email_customizer_array['default_registration_email_content'], 'wppb_user_emailc_default_registration_email_content' ); - wppb_replace_and_save( $email_customizer_array['registration_w_admin_approval_email_subject'], 'wppb_user_emailc_registration_with_admin_approval_email_subject' ); - wppb_replace_and_save( $email_customizer_array['registration_w_admin_approval_email_content'], 'wppb_user_emailc_registration_with_admin_approval_email_content' ); - wppb_replace_and_save( $email_customizer_array['admin_approval_aproved_status_email_subject'], 'wppb_user_emailc_admin_approval_notif_approved_email_subject' ); - wppb_replace_and_save( $email_customizer_array['admin_approval_aproved_status_email_content'], 'wppb_user_emailc_admin_approval_notif_approved_email_content' ); - wppb_replace_and_save( $email_customizer_array['admin_approval_unaproved_status_email_subject'], 'wppb_user_emailc_admin_approval_notif_unapproved_email_subject' ); - wppb_replace_and_save( $email_customizer_array['admin_approval_unaproved_status_email_content'], 'wppb_user_emailc_admin_approval_notif_unapproved_email_content' ); - wppb_replace_and_save( $email_customizer_array['registration_w_email_confirmation_email_subject'], 'wppb_user_emailc_registr_w_email_confirm_email_subject' ); - wppb_replace_and_save( $email_customizer_array['registration_w_email_confirmation_email_content'], 'wppb_user_emailc_registr_w_email_confirm_email_content' ); - wppb_replace_and_save( $email_customizer_array['admin_default_registration_email_subject'], 'wppb_admin_emailc_default_registration_email_subject' ); - wppb_replace_and_save( $email_customizer_array['admin_default_registration_email_content'], 'wppb_admin_emailc_default_registration_email_content' ); - wppb_replace_and_save( $email_customizer_array['admin_registration_w_admin_approval_email_subject'], 'wppb_admin_emailc_registration_with_admin_approval_email_subject' ); - wppb_replace_and_save( $email_customizer_array['admin_registration_w_admin_approval_email_content'], 'wppb_admin_emailc_registration_with_admin_approval_email_content' ); - } -} - - -/** - * Function that checks if a default userlisting-form is already present - * - * @since v.2.0 - * - * @param string $old_content - * @param string $option_name - * - */ -function wppb_replace_and_save( $content, $option_name ){ - preg_match_all( '/%%([a-z0-9\_]+)%%/', $content, $matches, PREG_PATTERN_ORDER ); - - foreach ( $matches[0] as $key => $value ) - $content = str_replace( $value, '{{'.$matches[1][$key].'}}', $content ); - - update_option( $option_name, $content ); -} - - -/** - * Function that adds backwards compatibility for the default fields only - * - * @since v.2.0 - * - * @param array $backed_up_manage_fields - * @param string $field - * @param string $meta_name - * @param string $required - * @param string $description - * @param string $recaptcha_public_key - * @param string $recaptcha_private_key - * - * @return array - */ -function wppb_add_existing_default_fields ( $backed_up_manage_fields = array(), $field, $meta_name, $required, $description = '', $recaptcha_public_key = '', $recaptcha_private_key = '' ){ - $local_array = array(); - - $local_array['id'] = ''; - $local_array['field'] = $field; - $local_array['meta-name'] = $meta_name; - $local_array['field-title'] = str_replace( array( 'Default - ', ' (Heading)' ), '', $field ); - $local_array['description'] = ''; - $local_array['required'] = $required; - $local_array['overwrite-existing'] = 'No'; - $local_array['row-count'] = '5'; - $local_array['allowed-image-extensions'] = '.*'; - $local_array['allowed-upload-extensions'] = '.*'; - $local_array['avatar-size'] = '100'; - $local_array['date-format'] = 'mm/dd/yy'; - $local_array['terms-of-agreement'] = ''; - $local_array['options'] = ''; - $local_array['labels'] = ''; - $local_array['public-key'] = $recaptcha_public_key; - $local_array['private-key'] = $recaptcha_private_key; - $local_array['default-value'] = ''; - $local_array['default-option'] = ''; - $local_array['default-options'] = ''; - $local_array['default-content'] = ''; - - array_push( $backed_up_manage_fields, $local_array ); - - return $backed_up_manage_fields; -} - - -/** - * Function that assures compatibility for the old Custom Redirects settings with the new Custom Redirects module - * - * @since v.2.2.5 - * - */ -function wppb_new_custom_redirects_compatibility() { - $wppb_old_cr = get_option( 'customRedirectSettings', 'not_found' ); - - $wppb_new_cr_global = array(); - $wppb_new_cr_wp_default = array(); - - if( $wppb_old_cr != 'not_found' ) { - // new Custom Redirect -> Global Redirects - if( $wppb_old_cr['afterRegister'] == 'yes' ) { - $wppb_new_cr_global[] = array( - 'type' => 'after_registration', - 'url' => $wppb_old_cr['afterRegisterTarget'], - 'id' => 1, - ); - } - - if( $wppb_old_cr['afterLogin'] == 'yes' ) { - $wppb_new_cr_global[] = array( - 'type' => 'after_login', - 'url' => $wppb_old_cr['afterLoginTarget'], - 'id' => 1, - ); - } - - if( $wppb_old_cr['loginRedirectLogout'] == 'yes' ) { - $wppb_new_cr_global[] = array( - 'type' => 'after_logout', - 'url' => $wppb_old_cr['loginRedirectTargetLogout'], - 'id' => 1, - ); - } - - if( $wppb_old_cr['dashboardRedirect'] == 'yes' ) { - $wppb_new_cr_global[] = array( - 'type' => 'dashboard_redirect', - 'url' => $wppb_old_cr['dashboardRedirectTarget'], - 'id' => 1, - ); - } - - // new Custom Redirect -> Redirect Default WordPress Forms and Pages - if( $wppb_old_cr['loginRedirect'] == 'yes' ) { - $wppb_new_cr_wp_default[] = array( - 'type' => 'login', - 'url' => $wppb_old_cr['loginRedirectTarget'], - 'id' => 1, - ); - } - - if( $wppb_old_cr['registerRedirect'] == 'yes' ) { - $wppb_new_cr_wp_default[] = array( - 'type' => 'register', - 'url' => $wppb_old_cr['registerRedirectTarget'], - 'id' => 1, - ); - } - - if( $wppb_old_cr['recoverRedirect'] == 'yes' ) { - $wppb_new_cr_wp_default[] = array( - 'type' => 'lostpassword', - 'url' => $wppb_old_cr['recoverRedirectTarget'], - 'id' => 1, - ); - } - - // add new Custom Redirect database options - if( isset( $wppb_new_cr_global ) && ! empty( $wppb_new_cr_global ) ) { - update_option( 'wppb_cr_global', $wppb_new_cr_global ); - } - - if( isset( $wppb_new_cr_wp_default ) && ! empty( $wppb_new_cr_wp_default ) ) { - update_option( 'wppb_cr_default_wp_pages', $wppb_new_cr_wp_default ); - } - } + $value ){ + if ( ( $value['item_type'] == 'checkbox' ) || ( $value['item_type'] == 'radio' ) || ( $value['item_type'] == 'select' ) ){ + if ( isset( $custom_fields[$key]['item_option_values'] ) ){ + $custom_fields[$key]['item_option_labels'] = $custom_fields[$key]['item_option_values']; + unset( $custom_fields[$key]['item_option_values'] ); + } + + }else + unset( $custom_fields[$key]['item_option_values'] ); + } + + update_option( 'wppb_custom_fields', $custom_fields ); + } +} + + +/** + * Function that checks if there is at least one EP and/or R form. In the execution timeline this function runs faster than the wppb_prepopulate_fields function + * + * @since v.2.0 + * + * @return void + */ +function wppb_pro_hobbyist_free_v2_0(){ + $wppb_manage_fields = get_option( 'wppb_manage_fields', 'not_found' ); + $backed_up_manage_fields = array(); + + // part that handles the manage fields + if ( $wppb_manage_fields == 'not_found' ){ + + $old_default_fields = get_option( 'wppb_default_settings', 'not_found' ); + + if ( $old_default_fields != 'not_found' ){ + $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - Name (Heading)', '', 'No' ); + + if ( $old_default_fields['username'] == 'show' ) + $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - Username', '', ucfirst( trim( $old_default_fields['usernameRequired'] ) ), __( 'The usernames cannot be changed.', 'profile-builder' ) ); + + if ( $old_default_fields['firstname'] == 'show' ) + $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - First Name', 'first_name', ucfirst( trim( $old_default_fields['firstnameRequired'] ) ) ); + + if ( $old_default_fields['lastname'] == 'show' ) + $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - Last Name', 'last_name', ucfirst( trim( $old_default_fields['lastnameRequired'] ) ) ); + + if ( $old_default_fields['nickname'] == 'show' ) + $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - Nickname', 'nickname', ucfirst( trim( $old_default_fields['nicknameRequired'] ) ) ); + + if ( $old_default_fields['dispname'] == 'show' ) + $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - Display name publicly as', '', ucfirst( trim( $old_default_fields['dispnameRequired'] ) ) ); + + $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - Contact Info (Heading)', '', 'No' ); + + if ( $old_default_fields['email'] == 'show' ) + $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - E-mail', '', ucfirst( trim( $old_default_fields['emailRequired'] ) ), '(required)' ); + + if ( $old_default_fields['website'] == 'show' ) + $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - Website', '', ucfirst( trim( $old_default_fields['websiteRequired'] ) ) ); + + if ( $old_default_fields['aim'] == 'show' ) + $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - AIM', 'aim', ucfirst( trim( $old_default_fields['aimRequired'] ) ) ); + + if ( $old_default_fields['yahoo'] == 'show' ) + $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - Yahoo IM', 'yim', ucfirst( trim( $old_default_fields['yahooRequired'] ) ) ); + + if ( $old_default_fields['jabber'] == 'show' ) + $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - Jabber / Google Talk', 'jabber', ucfirst( trim( $old_default_fields['jabberRequired'] ) ) ); + + $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - About Yourself (Heading)', '', 'No' ); + + if ( $old_default_fields['bio'] == 'show' ) + $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - Biographical Info', 'description', ucfirst( trim( $old_default_fields['bioRequired'] ) ) ); + + if ( $old_default_fields['password'] == 'show' ){ + $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - Password', '', ucfirst( trim( $old_default_fields['passwordRequired'] ) ) ); + $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - Repeat Password', '', ucfirst( trim( $old_default_fields['passwordRequired'] ) ) ); + } + + }else{ + $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - Name (Heading)', '', 'No' ); + $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - Username', '', 'Yes', __( 'The usernames cannot be changed.', 'profile-builder' ) ); + $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - First Name', 'first_name', 'No' ); + $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - Last Name', 'last_name', 'No' ); + $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - Nickname', 'nickname', 'No' ); + $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - Display name publicly as', '', 'No' ); + $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - Contact Info (Heading)', '', 'No' ); + $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - E-mail', '', 'Yes', '(required)' ); + $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - Website', '', 'No' ); + + // Default contact methods were removed in WP 3.6. A filter dictates contact methods. + if ( apply_filters( 'wppb_remove_default_contact_methods', get_site_option( 'initial_db_version' ) < 23588 ) ){ + $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - AIM', 'aim', 'No' ); + $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - Yahoo IM', 'yim', 'No' ); + $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - Jabber / Google Talk', 'jabber', 'No' ); + } + + $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - About Yourself (Heading)', '', 'No' ); + $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - Biographical Info', 'description', 'No' ); + $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - Password', '', 'Yes' ); + $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'Default - Repeat Password', '', 'Yes' ); + } + + $old_custom_fields = get_option( 'wppb_custom_fields', 'not_found' ); + if( $old_custom_fields != 'not_found' && count( $old_custom_fields ) != 0 ){ + $existing_ids = array(); + foreach ( $old_custom_fields as $key => $value ) { + $local_array = array(); + + if( isset( $value['id'] ) ) + $existing_ids[] = $value['id']; + + /* id will be set up at a later point */ + $local_array['id'] = ( isset( $value['id'] ) ? trim( $value['id'] ) : '' ); + $local_array['meta-name'] = ( isset( $value['item_metaName'] ) ? trim( $value['item_metaName'] ) : '' ); + $local_array['field-title'] = ( isset( $value['item_title'] ) ? trim( $value['item_title'] ) : '' ); + $local_array['description'] = ( isset( $value['item_desc'] ) ? $value['item_desc'] : '' ); + $local_array['required'] = 'No'; + $local_array['overwrite-existing'] = 'No'; + $local_array['row-count'] = '5'; + $local_array['allowed-image-extensions'] = '.*'; + $local_array['allowed-upload-extensions'] = '.*'; + $local_array['avatar-size'] = '100'; + $local_array['date-format'] = 'mm/dd/yy'; + $local_array['terms-of-agreement'] = ''; + $local_array['options'] = ''; + $local_array['labels'] = ''; + $local_array['public-key'] = ''; + $local_array['private-key'] = ''; + $local_array['default-value'] = ''; + $local_array['default-option'] = ''; + $local_array['default-options'] = ''; + $local_array['default-content'] = ''; + + switch ( $value['item_type' ] ){ + case "heading":{ + $local_array['field'] = 'Heading'; + $local_array['meta-name'] = ''; + break; + } + case "input":{ + $local_array['field'] = 'Input'; + $local_array['required'] = ucfirst( trim( $value['item_required'] ) ); + break; + } + case "hiddenInput":{ + $local_array['field'] = 'Input (Hidden)'; + $local_array['default-value'] = ( isset( $value['item_options'] ) ? trim( $value['item_options'] ) : '' ); + break; + } + case "checkbox":{ + $local_array['field'] = 'Checkbox'; + $local_array['options'] = ( isset( $value['item_options'] ) ? trim( $value['item_options'] ) : '' ); + $local_array['labels'] = ( isset( $value['item_option_labels'] ) ? trim( $value['item_option_labels'] ) : '' ); + $local_array['required'] = ucfirst( trim( $value['item_required'] ) ); + break; + } + case "agreeToTerms":{ + $local_array['field'] = 'Checkbox (Terms and Conditions)'; + $local_array['required'] = ucfirst( trim( "Yes" ) ); + break; + } + case "radio":{ + $local_array['field'] = 'Radio'; + $local_array['options'] = ( isset( $value['item_options'] ) ? trim( $value['item_options'] ) : '' ); + $local_array['labels'] = ( isset( $value['item_option_labels'] ) ? trim( $value['item_option_labels'] ) : '' ); + $local_array['required'] = ucfirst( trim( $value['item_required'] ) ); + break; + } + case "select":{ + $local_array['field'] = 'Select'; + $local_array['options'] = ( isset( $value['item_options'] ) ? trim( $value['item_options'] ) : '' ); + $local_array['labels'] = ( isset( $value['item_option_labels'] ) ? trim( $value['item_option_labels'] ) : '' ); + $local_array['required'] = ucfirst( trim( $value['item_required'] ) ); + break; + } + case "countrySelect":{ + $local_array['field'] = 'Select (Country)'; + $local_array['required'] = ucfirst( trim( $value['item_required'] ) ); + break; + } + case "timeZone":{ + $local_array['field'] = 'Select (Timezone)'; + $local_array['required'] = ucfirst( trim( $value['item_required'] ) ); + break; + } + case "datepicker":{ + $local_array['field'] = 'Datepicker'; + $local_array['required'] = ucfirst( trim( $value['item_required'] ) ); + break; + } + case "textarea":{ + $local_array['field'] = 'Textarea'; + $local_array['row-count'] = ( isset( $value['item_options'] ) ? trim( $value['item_options'] ) : '' ); + $local_array['required'] = ucfirst( trim( $value['item_required'] ) ); + break; + } + case "upload":{ + $local_array['field'] = 'Upload'; + $local_array['allowed-upload-extensions'] = ( isset( $value['item_options'] ) ? trim( $value['item_options'] ) : $local_array['allowed-upload-extensions'] ); + $local_array['required'] = ucfirst( trim( $value['item_required'] ) ); + break; + } + case "avatar":{ + $local_array['field'] = 'Avatar'; + $local_array['avatar-size'] = ( isset( $value['item_options'] ) ? trim( $value['item_options'] ) : $local_array['avatar-size'] ); + $local_array['required'] = ucfirst( trim( $value['item_required'] ) ); + break; + } + } + + array_push( $backed_up_manage_fields, $local_array ); + } + } + } + + + // part which handles the removal of the reCAPTCHA from the addon list + $wppb_module_settings = get_option( 'wppb_addon_settings', 'not_found' ); + if ( $wppb_module_settings != 'not_found' ){ + if ( isset( $wppb_module_settings['wppb_reCaptcha'] ) && ( $wppb_module_settings['wppb_reCaptcha'] == 'show' ) ){ + $recaptcha_settings = get_option( 'reCaptchaSettings' ); + + if ( ( $recaptcha_settings != 'no_found' ) || ( count( $recaptcha_settings ) != 0 ) ){ + $backed_up_manage_fields = wppb_add_existing_default_fields( $backed_up_manage_fields, 'reCAPTCHA', '', 'Yes', '', trim( $recaptcha_settings['publicKey'] ), trim( $recaptcha_settings['privateKey'] ) ); + } + } + + unset( $wppb_module_settings['wppb_reCaptcha'] ); + $wppb_module_settings['wppb_multipleEditProfileForms'] = 'hide'; + $wppb_module_settings['wppb_multipleRegistrationForms'] = 'hide'; + + update_option( 'wppb_module_settings', $wppb_module_settings ); + } + + /* set up start from index. it is set from the highest existing index + 1 */ + if( !empty( $existing_ids ) ) { + rsort($existing_ids, SORT_NUMERIC ); + $start_from_index = $existing_ids[0] + 1; + } + else + $start_from_index = 1; + + /* set up ids for each field */ + if( !empty( $backed_up_manage_fields ) ){ + foreach( $backed_up_manage_fields as $key => $backed_up_manage_field ){ + if( empty( $backed_up_manage_fields[$key]['id'] ) ){ + $backed_up_manage_fields[$key]['id'] = $start_from_index; + $start_from_index ++; + } + } + } + add_option( 'wppb_manage_fields', $backed_up_manage_fields ); + + + // part which handles the general settings select->checkbox backwards comp. + $wppb_generalSettings = get_option( 'wppb_general_settings', 'not_found' ); + if ( ( $wppb_generalSettings != 'not_found' ) && ( count( $wppb_generalSettings ) > 1 ) ){ + if ( isset( $wppb_generalSettings['extraFieldsLayout'] ) && ( $wppb_generalSettings['extraFieldsLayout'] == 'no' ) ) + unset( $wppb_generalSettings['extraFieldsLayout'] ); + + else + $wppb_generalSettings['extraFieldsLayout'] = 'default'; + + update_option( 'wppb_general_settings', $wppb_generalSettings ); + } +} + + +/** + * Function that adds backwards compatibility for the userlisting + * + * @since v.2.0 + * + */ +function wppb_pro_userlisting_compatibility_upgrade(){ + if ( wppb_default_form_already_present( 'Userlisting', 'wppb-ul-cpt' ) ) + return ''; + + $old_userlisting_settings = get_option( 'customUserListingSettings', 'not_found' ); + if ( $old_userlisting_settings == 'not_found' ) + $old_userlisting_settings = get_option( 'userListingSettings' ); + + if ( $old_userlisting_settings == 'not_found' ) + return; + + $all_userlisting = ( isset( $old_userlisting_settings['allUserlisting'] ) ? wppb_replace_merge_tags( $old_userlisting_settings['allUserlisting'], true ) : '' ); + $single_userlisting = ( isset( $old_userlisting_settings['singleUserlisting'] ) ? wppb_replace_merge_tags( $old_userlisting_settings['singleUserlisting'] ) : '' ); + + if( !empty( $old_userlisting_settings['sortingNumber'] ) ) + $number_os_users_per_page = $old_userlisting_settings['sortingNumber']; + else + $number_os_users_per_page = '5'; + + if( !empty( $old_userlisting_settings['sortingCriteria'] ) ) + $default_sorting_criteria = $old_userlisting_settings['sortingCriteria']; + else + $default_sorting_criteria = 'login'; + + if( !empty( $old_userlisting_settings['sortingOrder'] ) ) + $default_sorting_order = $old_userlisting_settings['sortingOrder']; + else + $default_sorting_order = 'asc'; + + if( !empty( $old_userlisting_settings['avatarSize'] ) ) + $avatar_size_all = $old_userlisting_settings['avatarSize']; + else + $avatar_size_all = '40'; + + if( !empty( $old_userlisting_settings['avatarSize'] ) ) + $avatar_size_single = $old_userlisting_settings['avatarSize']; + else + $avatar_size_single = '60'; + + $userlisting_settings = array( array( 'roles-to-display' => '*', 'number-of-userspage' => $number_os_users_per_page, 'default-sorting-criteria' => $default_sorting_criteria, 'default-sorting-order' => $default_sorting_order, 'avatar-size-all-userlisting' => $avatar_size_all, 'avatar-size-single-userlisting' => $avatar_size_single ) ); + + $ul_post_id = wp_insert_post( array( 'post_title' => 'Userlisting', 'post_status' => 'publish', 'post_author' => get_current_user_id(), 'post_type' => 'wppb-ul-cpt', 'post_content' => 'Default Userlisting form placeholder' ), true ); + + add_post_meta( $ul_post_id, 'wppb-ul-templates', $all_userlisting ); + add_post_meta( $ul_post_id, 'wppb-single-ul-templates', $single_userlisting ); + add_post_meta( $ul_post_id, 'wppb_ul_page_settings', $userlisting_settings ); +} + + +/** + * Function that replaces the individual merge-tags in the userlisting + * + * @since v.2.0 + * + * @param string $content + * @param boolean $all_userlisting_form + * + * @return string + * + */ +function wppb_replace_merge_tags( $content, $all_userlisting_form = false ){ + $content = trim( $content ); + + $content = wppb_old_backwards_compatibility( $content ); + + $content = str_replace( '%%meta_number_of_posts%%', '{{{meta_number_of_posts}}}', $content ); + $content = str_replace( '%%extra_search_all_fields%%', '{{{extra_search_all_fields}}}', $content ); + $content = str_replace( '%%extra_more_info_link%%', '{{{more_info}}}', $content ); + $content = str_replace( '%%extra_while_users%%', '{{#users}}', $content ); + $content = str_replace( '%%extra_end_while_users%%', '{{/users}}', $content ); + $content = str_replace( '%%extra_avatar_or_gravatar%%', '{{{avatar_or_gravatar}}}', $content ); + $content = str_replace( '%%extra_go_back_link%%', '{{{extra_go_back_link}}}', $content ); + $content = str_replace( '%%meta_first_last_name%%', '{{meta_first_name}}{{meta_last_name}}', $content ); + $content = str_replace( '%%sort_first_last_name%%', '{{{sort_first_name}}}', $content ); + + preg_match_all( '/%%([a-z0-9\_]+)%%/', $content, $matches, PREG_PATTERN_ORDER ); + foreach ( $matches[0] as $key => $value ) + $content = ( ( strpos( $value, 'sort_' ) !== false ) ? str_replace( $value, '{{{'.$matches[1][$key].'}}}', $content ) : str_replace( $value, '{{'.$matches[1][$key].'}}', $content ) ); + + if ( $all_userlisting_form ) + $content .= '{{{pagination}}}'; + + return $content; +} + + +/** + * Function that replaces the individual merge-tags which existed the very first time. These consisted of %%item_title%% instead of the (then) newer %%item_meta_name%% + * + * @since v.2.0 + * + * @param string $content + * + * @return string + * + */ +function wppb_old_backwards_compatibility( $content ){ + $wppb_custom_fields = get_option( 'wppb_custom_fields', 'not_found' ); + + if ( ( $wppb_custom_fields == 'not_found' ) || ( count( $wppb_custom_fields ) < 1 ) ) + return $content; + + foreach( $wppb_custom_fields as $key => $value ){ + if ( ( isset( $value['item_type'] ) ) && ( trim( $value['item_type'] != '' ) ) ) + if ( ( isset( $value['item_metaName'] ) ) && ( trim( $value['item_metaName'] != '' ) ) ){ + /* TODO don't know what's supposed to be here and don't have time before launch */ + $string = str_replace( '%%meta_'.$value['item_title'].'%%', '%%meta_'.$value['item_metaName'].'%%', $string ); + $string = str_replace( '%%meta_description_'.$value['item_title'].'%%', '%%meta_description_'.$value['item_metaName'].'%%', $string ); + $string = str_replace( '%%sort_'.$value['item_title'].'%%', '%%sort_'.$value['item_metaName'].'%%', $string ); + } + } + + return $content; +} + + +/** + * Function that checks if a default userlisting-form is already present + * + * @since v.2.0 + * + * @param string $post_title + * @param string $post_type + * + * @return boolean + * + */ +function wppb_default_form_already_present( $post_title, $post_type ){ + $defaults = get_posts( array( 'posts_per_page' => -1, 'post_status' => array( 'publish' ), 'post_type' => $post_type, 'orderby' => 'post_date', 'order' => 'ASC' ) ); + foreach ( $defaults as $default ){ + if ( $default->post_content == 'Default '.$post_title.' form placeholder' ) + return true; + } + + return false; +} + + +/** + * Function that assures backwards compatibility for the email customizer + * + * @since v.2.0 + * + */ +function wppb_pro_email_customizer_compatibility_upgrade(){ + $email_customizer_array = get_option( 'emailCustomizer', 'not_found' ); + + if ( $email_customizer_array != 'not_found' ){ + wppb_replace_and_save( $email_customizer_array['from_name'], 'wppb_emailc_common_settings_from_name' ); + wppb_replace_and_save( $email_customizer_array['reply_to'], 'wppb_emailc_common_settings_from_reply_to_email' ); + wppb_replace_and_save( $email_customizer_array['default_registration_email_subject'], 'wppb_user_emailc_default_registration_email_subject' ); + wppb_replace_and_save( $email_customizer_array['default_registration_email_content'], 'wppb_user_emailc_default_registration_email_content' ); + wppb_replace_and_save( $email_customizer_array['registration_w_admin_approval_email_subject'], 'wppb_user_emailc_registration_with_admin_approval_email_subject' ); + wppb_replace_and_save( $email_customizer_array['registration_w_admin_approval_email_content'], 'wppb_user_emailc_registration_with_admin_approval_email_content' ); + wppb_replace_and_save( $email_customizer_array['admin_approval_aproved_status_email_subject'], 'wppb_user_emailc_admin_approval_notif_approved_email_subject' ); + wppb_replace_and_save( $email_customizer_array['admin_approval_aproved_status_email_content'], 'wppb_user_emailc_admin_approval_notif_approved_email_content' ); + wppb_replace_and_save( $email_customizer_array['admin_approval_unaproved_status_email_subject'], 'wppb_user_emailc_admin_approval_notif_unapproved_email_subject' ); + wppb_replace_and_save( $email_customizer_array['admin_approval_unaproved_status_email_content'], 'wppb_user_emailc_admin_approval_notif_unapproved_email_content' ); + wppb_replace_and_save( $email_customizer_array['registration_w_email_confirmation_email_subject'], 'wppb_user_emailc_registr_w_email_confirm_email_subject' ); + wppb_replace_and_save( $email_customizer_array['registration_w_email_confirmation_email_content'], 'wppb_user_emailc_registr_w_email_confirm_email_content' ); + wppb_replace_and_save( $email_customizer_array['admin_default_registration_email_subject'], 'wppb_admin_emailc_default_registration_email_subject' ); + wppb_replace_and_save( $email_customizer_array['admin_default_registration_email_content'], 'wppb_admin_emailc_default_registration_email_content' ); + wppb_replace_and_save( $email_customizer_array['admin_registration_w_admin_approval_email_subject'], 'wppb_admin_emailc_registration_with_admin_approval_email_subject' ); + wppb_replace_and_save( $email_customizer_array['admin_registration_w_admin_approval_email_content'], 'wppb_admin_emailc_registration_with_admin_approval_email_content' ); + } +} + + +/** + * Function that checks if a default userlisting-form is already present + * + * @since v.2.0 + * + * @param string $old_content + * @param string $option_name + * + */ +function wppb_replace_and_save( $content, $option_name ){ + preg_match_all( '/%%([a-z0-9\_]+)%%/', $content, $matches, PREG_PATTERN_ORDER ); + + foreach ( $matches[0] as $key => $value ) + $content = str_replace( $value, '{{'.$matches[1][$key].'}}', $content ); + + update_option( $option_name, $content ); +} + + +/** + * Function that adds backwards compatibility for the default fields only + * + * @since v.2.0 + * + * @param array $backed_up_manage_fields + * @param string $field + * @param string $meta_name + * @param string $required + * @param string $description + * @param string $recaptcha_public_key + * @param string $recaptcha_private_key + * + * @return array + */ +function wppb_add_existing_default_fields ( $backed_up_manage_fields = array(), $field, $meta_name, $required, $description = '', $recaptcha_public_key = '', $recaptcha_private_key = '' ){ + $local_array = array(); + + $local_array['id'] = ''; + $local_array['field'] = $field; + $local_array['meta-name'] = $meta_name; + $local_array['field-title'] = str_replace( array( 'Default - ', ' (Heading)' ), '', $field ); + $local_array['description'] = ''; + $local_array['required'] = $required; + $local_array['overwrite-existing'] = 'No'; + $local_array['row-count'] = '5'; + $local_array['allowed-image-extensions'] = '.*'; + $local_array['allowed-upload-extensions'] = '.*'; + $local_array['avatar-size'] = '100'; + $local_array['date-format'] = 'mm/dd/yy'; + $local_array['terms-of-agreement'] = ''; + $local_array['options'] = ''; + $local_array['labels'] = ''; + $local_array['public-key'] = $recaptcha_public_key; + $local_array['private-key'] = $recaptcha_private_key; + $local_array['default-value'] = ''; + $local_array['default-option'] = ''; + $local_array['default-options'] = ''; + $local_array['default-content'] = ''; + + array_push( $backed_up_manage_fields, $local_array ); + + return $backed_up_manage_fields; +} + + +/** + * Function that assures compatibility for the old Custom Redirects settings with the new Custom Redirects module + * + * @since v.2.2.5 + * + */ +function wppb_new_custom_redirects_compatibility() { + $wppb_old_cr = get_option( 'customRedirectSettings', 'not_found' ); + + $wppb_new_cr_global = array(); + $wppb_new_cr_wp_default = array(); + + if( $wppb_old_cr != 'not_found' ) { + // new Custom Redirect -> Global Redirects + if( $wppb_old_cr['afterRegister'] == 'yes' ) { + $wppb_new_cr_global[] = array( + 'type' => 'after_registration', + 'url' => $wppb_old_cr['afterRegisterTarget'], + 'id' => 1, + ); + } + + if( $wppb_old_cr['afterLogin'] == 'yes' ) { + $wppb_new_cr_global[] = array( + 'type' => 'after_login', + 'url' => $wppb_old_cr['afterLoginTarget'], + 'id' => 1, + ); + } + + if( $wppb_old_cr['loginRedirectLogout'] == 'yes' ) { + $wppb_new_cr_global[] = array( + 'type' => 'after_logout', + 'url' => $wppb_old_cr['loginRedirectTargetLogout'], + 'id' => 1, + ); + } + + if( $wppb_old_cr['dashboardRedirect'] == 'yes' ) { + $wppb_new_cr_global[] = array( + 'type' => 'dashboard_redirect', + 'url' => $wppb_old_cr['dashboardRedirectTarget'], + 'id' => 1, + ); + } + + // new Custom Redirect -> Redirect Default WordPress Forms and Pages + if( $wppb_old_cr['loginRedirect'] == 'yes' ) { + $wppb_new_cr_wp_default[] = array( + 'type' => 'login', + 'url' => $wppb_old_cr['loginRedirectTarget'], + 'id' => 1, + ); + } + + if( $wppb_old_cr['registerRedirect'] == 'yes' ) { + $wppb_new_cr_wp_default[] = array( + 'type' => 'register', + 'url' => $wppb_old_cr['registerRedirectTarget'], + 'id' => 1, + ); + } + + if( $wppb_old_cr['recoverRedirect'] == 'yes' ) { + $wppb_new_cr_wp_default[] = array( + 'type' => 'lostpassword', + 'url' => $wppb_old_cr['recoverRedirectTarget'], + 'id' => 1, + ); + } + + // add new Custom Redirect database options + if( isset( $wppb_new_cr_global ) && ! empty( $wppb_new_cr_global ) ) { + update_option( 'wppb_cr_global', $wppb_new_cr_global ); + } + + if( isset( $wppb_new_cr_wp_default ) && ! empty( $wppb_new_cr_wp_default ) ) { + update_option( 'wppb_cr_default_wp_pages', $wppb_new_cr_wp_default ); + } + } } \ No newline at end of file diff --git a/profile-builder/features/upgrades/upgrades.php b/profile-builder/features/upgrades/upgrades.php index 9897833..78d877c 100644 --- a/profile-builder/features/upgrades/upgrades.php +++ b/profile-builder/features/upgrades/upgrades.php @@ -1,77 +1,77 @@ -' ) ) { - if ( ( PROFILE_BUILDER == 'Profile Builder Pro' ) || ( PROFILE_BUILDER == 'Profile Builder Hobbyist' ) ){ - - /* stopped creating them on 01.02.2016 */ - /*$upload_dir = wp_upload_dir(); - wp_mkdir_p( $upload_dir['basedir'].'/profile_builder' ); - wp_mkdir_p( $upload_dir['basedir'].'/profile_builder/attachments/' ); - wp_mkdir_p( $upload_dir['basedir'].'/profile_builder/avatars/' );*/ - - // Flush the rewrite rules and add them, if need be, the proper way. - if ( function_exists( 'wppb_flush_rewrite_rules' ) ) - wppb_flush_rewrite_rules(); - - wppb_pro_hobbyist_v1_3_13(); - } - - if ( PROFILE_BUILDER == 'Profile Builder Pro' ){ - wppb_pro_v1_3_15(); - } - - update_option( 'wppb_version', PROFILE_BUILDER_VERSION ); - } - - //this should run only once, mainly if the old version is < 2.0 (can be anything) - if ( version_compare( $wppb_version, 2.0, '<' ) ) { - if ( ( PROFILE_BUILDER == 'Profile Builder Pro' ) || ( PROFILE_BUILDER == 'Profile Builder Hobbyist' ) || ( PROFILE_BUILDER == 'Profile Builder Free' ) ){ - wppb_pro_hobbyist_free_v2_0(); - } - - if ( PROFILE_BUILDER == 'Profile Builder Pro' ){ - wppb_pro_userlisting_compatibility_upgrade(); - wppb_pro_email_customizer_compatibility_upgrade(); - } - } - - // this should run only once, mainly if the old version is < 2.2.5 (can be anything) - if ( version_compare( $wppb_version, '2.2.5', '<' ) ) { - if ( PROFILE_BUILDER == 'Profile Builder Pro' ) { - wppb_new_custom_redirects_compatibility(); - } - } - - if ( version_compare( $wppb_version, '2.2.5', '<=' ) ) { - if( is_multisite() ){ - $wppb_general_settings = get_option( 'wppb_general_settings', 'not_set' ); - if ( $wppb_general_settings != 'not_set' ) { - $wppb_general_settings['emailConfirmation'] = 'yes'; - update_option('wppb_general_settings', $wppb_general_settings); - } - } - - } - - do_action ( 'wppb_after_default_changes', PROFILE_BUILDER_VERSION, $wppb_version ); -} +' ) ) { + if ( ( PROFILE_BUILDER == 'Profile Builder Pro' ) || ( PROFILE_BUILDER == 'Profile Builder Hobbyist' ) ){ + + /* stopped creating them on 01.02.2016 */ + /*$upload_dir = wp_upload_dir(); + wp_mkdir_p( $upload_dir['basedir'].'/profile_builder' ); + wp_mkdir_p( $upload_dir['basedir'].'/profile_builder/attachments/' ); + wp_mkdir_p( $upload_dir['basedir'].'/profile_builder/avatars/' );*/ + + // Flush the rewrite rules and add them, if need be, the proper way. + if ( function_exists( 'wppb_flush_rewrite_rules' ) ) + wppb_flush_rewrite_rules(); + + wppb_pro_hobbyist_v1_3_13(); + } + + if ( PROFILE_BUILDER == 'Profile Builder Pro' ){ + wppb_pro_v1_3_15(); + } + + update_option( 'wppb_version', PROFILE_BUILDER_VERSION ); + } + + //this should run only once, mainly if the old version is < 2.0 (can be anything) + if ( version_compare( $wppb_version, 2.0, '<' ) ) { + if ( ( PROFILE_BUILDER == 'Profile Builder Pro' ) || ( PROFILE_BUILDER == 'Profile Builder Hobbyist' ) || ( PROFILE_BUILDER == 'Profile Builder Free' ) ){ + wppb_pro_hobbyist_free_v2_0(); + } + + if ( PROFILE_BUILDER == 'Profile Builder Pro' ){ + wppb_pro_userlisting_compatibility_upgrade(); + wppb_pro_email_customizer_compatibility_upgrade(); + } + } + + // this should run only once, mainly if the old version is < 2.2.5 (can be anything) + if ( version_compare( $wppb_version, '2.2.5', '<' ) ) { + if ( PROFILE_BUILDER == 'Profile Builder Pro' ) { + wppb_new_custom_redirects_compatibility(); + } + } + + if ( version_compare( $wppb_version, '2.2.5', '<=' ) ) { + if( is_multisite() ){ + $wppb_general_settings = get_option( 'wppb_general_settings', 'not_set' ); + if ( $wppb_general_settings != 'not_set' ) { + $wppb_general_settings['emailConfirmation'] = 'yes'; + update_option('wppb_general_settings', $wppb_general_settings); + } + } + + } + + do_action ( 'wppb_after_default_changes', PROFILE_BUILDER_VERSION, $wppb_version ); +} add_action ( 'init', 'wppb_update_patch' ); \ No newline at end of file diff --git a/profile-builder/front-end/class-formbuilder.php b/profile-builder/front-end/class-formbuilder.php index 74c6570..7dbb389 100644 --- a/profile-builder/front-end/class-formbuilder.php +++ b/profile-builder/front-end/class-formbuilder.php @@ -1,712 +1,712 @@ - '', - 'form_fields' => array(), - 'form_name' => '', - 'role' => '', //used only for the register-form settings - 'redirect_url' => '', - 'logout_redirect_url' => '', //used only for the register-form settings - 'redirect_priority' => 'normal', - 'ID' => null - ); - public $args; - - - // Constructor method for the class - function __construct( $args ) { - - /* we should stop the execution of the forms if they are in the wp_head hook because it should not be there. - SEO plugins can execute shortcodes in the auto generated descriptions */ - global $wp_current_filter; - if( !empty( $wp_current_filter ) && is_array( $wp_current_filter ) ){ - foreach( $wp_current_filter as $filter ){ - if( $filter == 'wp_head' ) - return; - } - } - - // Merge the input arguments and the defaults - $this->args = wp_parse_args( $args, $this->defaults ); - - /* set up the ID here if it is a multi form */ - if( $this->args['form_name'] != 'unspecified' ){ - $this->args['ID'] = Profile_Builder_Form_Creator::wppb_get_form_id_from_form_name( $this->args['form_name'], $this->args['form_type'] ); - } - - global $wppb_shortcode_on_front; - $wppb_shortcode_on_front = true; - - if( empty( $this->args['form_fields'] ) ) - $this->args['form_fields'] = apply_filters( 'wppb_change_form_fields', get_option( 'wppb_manage_fields' ), $this->args ); - - if ( file_exists ( WPPB_PLUGIN_DIR.'/front-end/default-fields/default-fields.php' ) ) - require_once( WPPB_PLUGIN_DIR.'/front-end/default-fields/default-fields.php' ); - - if ( file_exists ( WPPB_PLUGIN_DIR.'/front-end/extra-fields/extra-fields.php' ) ) - require_once( WPPB_PLUGIN_DIR.'/front-end/extra-fields/extra-fields.php' ); - - $this->wppb_retrieve_custom_settings(); - - if( ( !is_multisite() && current_user_can( 'edit_users' ) ) || ( is_multisite() && current_user_can( 'manage_network' ) ) ) - add_action( 'wppb_before_edit_profile_fields', array( &$this, 'wppb_edit_profile_select_user_to_edit' ) ); - } - - /** - * @param $form_name The "slug" generated from the current Form Title - * @param $form_type the form type of the form: register, edit_profile - * @return null - */ - static function wppb_get_form_id_from_form_name( $form_name, $form_type ){ - global $wpdb; - - if( $form_type == 'edit_profile' ){ - $post_type = 'wppb-epf-cpt'; - }elseif( $form_type == 'register' ){ - $post_type = 'wppb-rf-cpt'; - } - - $all_forms = $wpdb->get_results( - " - SELECT ID, post_title - FROM $wpdb->posts - WHERE post_status = 'publish' - AND post_type = '$post_type' - " - ); - - if( !empty( $all_forms ) ) { - foreach ($all_forms as $form) { - if( empty( $form->post_title ) ) - $form->post_title = '(no title)'; - - if ($form_name == Wordpress_Creation_Kit_PB::wck_generate_slug($form->post_title)) { - return $form->ID; - } - } - } - - return null; - } - - function wppb_retrieve_custom_settings(){ - $this->args['login_after_register'] = apply_filters( 'wppb_automatically_login_after_register', 'No' ); //used only for the register-form settings - $this->args['redirect_activated'] = apply_filters( 'wppb_redirect_default_setting', '-' ); - $this->args['redirect_url'] = apply_filters( 'wppb_redirect_default_location', ( $this->args['redirect_url'] != '' ) ? $this->args['redirect_url'] : '' ); - $this->args['logout_redirect_url'] = apply_filters( 'wppb_logout_redirect_default_location', ( $this->args['logout_redirect_url'] != '' ) ? $this->args['logout_redirect_url'] : '' ); - $this->args['redirect_delay'] = apply_filters( 'wppb_redirect_default_duration', 3 ); - - if ( !is_null( $this->args['ID'] ) ){ - $meta_name = ( ( $this->args['form_type'] == 'register' ) ? 'wppb_rf_page_settings' : 'wppb_epf_page_settings' ); - - $page_settings = get_post_meta( $this->args['ID'], $meta_name, true ); - - if( !empty( $page_settings[0]['set-role'] ) ){ - if( $page_settings[0]['set-role'] == 'default role' ){ - $selected_role = trim( get_option( 'default_role' ) ); - } - else - $selected_role = $page_settings[0]['set-role']; - } - - $this->args['role'] = ( isset( $selected_role ) ? $selected_role : $this->args['role'] ); - $this->args['login_after_register'] = ( isset( $page_settings[0]['automatically-log-in'] ) ? $page_settings[0]['automatically-log-in'] : $this->args['login_after_register'] ); - $this->args['redirect_activated'] = ( isset( $page_settings[0]['redirect'] ) ? $page_settings[0]['redirect'] : $this->args['redirect_activated'] ); - $this->args['redirect_url'] = ( ! empty( $page_settings[0]['url'] ) && $this->args['redirect_activated'] == 'Yes' && $this->args['redirect_priority'] != 'top' ? $page_settings[0]['url'] : $this->args['redirect_url'] ); - $this->args['redirect_delay'] = ( isset( $page_settings[0]['display-messages'] ) && $this->args['redirect_activated'] == 'Yes' ? $page_settings[0]['display-messages'] : $this->args['redirect_delay'] ); - } - - if( !empty( $this->args['role'] ) ){ - $role_in_arg = get_role( $this->args['role'] ); - if( !empty( $role_in_arg->capabilities['manage_options'] ) || !empty( $role_in_arg->capabilities['remove_users'] ) ){ - if( !current_user_can( 'manage_options' ) || !current_user_can( 'remove_users' ) ){ - $this->args['role'] = get_option('default_role'); - echo apply_filters( 'wppb_register_pre_form_user_role_message', '

            '.__( 'The role of the created user set to the default role. Only an administrator can register a user with the role assigned to this form.', 'profile-builder').'

            ' ); - } - } - } - } - - function wppb_form_logic() { - if( $this->args['form_type'] == 'register' ){ - $registration = apply_filters ( 'wppb_register_setting_override', get_option( 'users_can_register' ) ); - - if ( !is_user_logged_in() ){ - if ( !$registration ) - echo apply_filters( 'wppb_register_pre_form_message', '

            '.__( 'Only an administrator can add new users.', 'profile-builder').'

            ' ); - - elseif ( $registration ){ - $this->wppb_form_content( apply_filters( 'wppb_register_pre_form_message', '' ) ); - } - - }else{ - $current_user_capability = apply_filters ( 'wppb_registration_user_capability', 'create_users' ); - - if ( current_user_can( $current_user_capability ) && $registration ) - $this->wppb_form_content( apply_filters( 'wppb_register_pre_form_message', '

            '.__( 'Users can register themselves or you can manually create users here.', 'profile-builder'). '' . '

            ' ) ); - - elseif ( current_user_can( $current_user_capability ) && !$registration ) - $this->wppb_form_content( apply_filters( 'wppb_register_pre_form_message', '

            '.__( 'Users cannot currently register themselves, but you can manually create users here.', 'profile-builder'). '' . '

            ' ) ); - - elseif ( !current_user_can( $current_user_capability ) ){ - global $user_ID; - - $userdata = get_userdata( $user_ID ); - $display_name = ( ( $userdata->data->display_name == '' ) ? $userdata->data->user_login : $userdata->data->display_name ); - - $wppb_general_settings = get_option( 'wppb_general_settings' ); - if ( isset( $wppb_general_settings['loginWith'] ) && ( $wppb_general_settings['loginWith'] == 'email' ) ) - $display_name = $userdata->data->user_email; - - if( empty( $this->args['logout_redirect_url'] ) ) { - $this->args['logout_redirect_url'] = get_permalink(); - } - - // CHECK FOR REDIRECT - $this->args['logout_redirect_url'] = wppb_get_redirect_url( $this->args['redirect_priority'], 'after_logout', $this->args['logout_redirect_url'], $userdata ); - $this->args['logout_redirect_url'] = apply_filters( 'wppb_after_logout_redirect_url', $this->args['logout_redirect_url'] ); - - echo apply_filters( 'wppb_register_pre_form_message', '

            '.sprintf( __( "You are currently logged in as %1s. You don't need another account. %2s", 'profile-builder' ), ''.$display_name.'', ''.__( 'Logout', 'profile-builder' ).' »' ).'

            ', $user_ID ); - } - } - - }elseif ( $this->args['form_type'] == 'edit_profile' ){ - if ( !is_user_logged_in() ) - echo apply_filters( 'wppb_edit_profile_user_not_logged_in_message', '

            '.__( 'You must be logged in to edit your profile.', 'profile-builder' ) .'

            ' ); - - elseif ( is_user_logged_in() ) - $this->wppb_form_content( apply_filters( 'wppb_edit_profile_logged_in_user_message', '' ) ); - - } - } - - // Function used to automatically log in a user after register if that option is set on yes in register form settings - function wppb_log_in_user( $redirect, $redirect_old ) { - if( is_user_logged_in() ) { - return; - } - - $wppb_general_settings = get_option( 'wppb_general_settings' ); - - if ( isset( $wppb_general_settings['emailConfirmation'] ) && ( $wppb_general_settings['emailConfirmation'] == 'yes' ) ) { - return $redirect_old; - } - - /* get user id */ - $user = get_user_by( 'email', trim( sanitize_email( $_POST['email'] ) ) ); - $nonce = wp_create_nonce( 'autologin-'. $user->ID .'-'. (int)( time() / 60 ) ); - - if ( isset( $wppb_general_settings['adminApproval'] ) && ( $wppb_general_settings['adminApproval'] == 'yes' ) ) { - if( !empty( $wppb_general_settings['adminApprovalOnUserRole'] ) ) { - foreach ($user->roles as $role) { - if ( in_array( $role, $wppb_general_settings['adminApprovalOnUserRole'] ) ) { - return $redirect_old; - } - } - } - else { - return $redirect_old; - } - } - - /* define redirect location */ - if( $this->args['redirect_activated'] == 'No' ) { - if( isset( $_POST['_wp_http_referer'] ) ) { - $redirect = esc_url_raw($_POST['_wp_http_referer']); - } else { - $redirect = home_url(); - } - } - - $redirect = apply_filters( 'wppb_login_after_reg_redirect_url', $redirect, $this ); - - $redirect = add_query_arg( array( 'autologin' => 'true', 'uid' => $user->ID, '_wpnonce' => $nonce ), $redirect ); - - // CHECK FOR REDIRECT - if( $this->args['redirect_activated'] == 'No' || ( empty( $this->args['redirect_delay'] ) || $this->args['redirect_delay'] == '0' ) ) { - $redirect = wppb_build_redirect( $redirect, 0, 'register', $this->args ); - } else { - $redirect = wppb_build_redirect( $redirect, $this->args['redirect_delay'], 'register', $this->args ); - } - return $redirect; - } - - /** - * Function to get redirect for Register and Edit Profile forms - * - * @param string $form_type - type of the form - * @param string $redirect_type - type of the redirect - * @param string $user - username or user email - * @param string $user_role - user Role - * - * @return string $redirect - */ - function wppb_get_redirect( $form_type, $redirect_type, $user, $user_role ) { - $this->args['redirect_delay'] = apply_filters( 'wppb_'. $form_type .'_redirect_delay', $this->args['redirect_delay'], $user, $this->args ); - if( $this->args['redirect_activated'] == '-' ) { - $this->args['redirect_url'] = wppb_get_redirect_url( $this->args['redirect_priority'], $redirect_type, $this->args['redirect_url'], $user, $user_role ); - $redirect = wppb_build_redirect( $this->args['redirect_url'], $this->args['redirect_delay'], $form_type, $this->args ); - } elseif( $this->args['redirect_activated'] == 'Yes' ) { - $redirect = wppb_build_redirect( $this->args['redirect_url'], $this->args['redirect_delay'], $form_type, $this->args ); - } else { - $redirect = ''; - } - - return $redirect; - } - - function wppb_form_content( $message ) { - $field_check_errors = array(); - - if( isset( $_REQUEST['action'] ) && $_REQUEST['form_name'] == $this->args['form_name'] ) { - $field_check_errors = $this->wppb_test_required_form_values( $_REQUEST ); - if( empty( $field_check_errors ) ) { - - do_action( 'wppb_before_saving_form_values',$_REQUEST, $this->args ); - - // we only have a $user_id on default registration (no email confirmation, no multisite) - $user_id = $this->wppb_save_form_values( $_REQUEST ); - - if( ( 'POST' == $_SERVER['REQUEST_METHOD'] ) && ( $_POST['action'] == $this->args['form_type'] ) ) { - - $form_message_tpl_start = apply_filters( 'wppb_form_message_tpl_start', '

            ' ); - $form_message_tpl_end = apply_filters( 'wppb_form_message_tpl_end', '

            ' ); - - if( isset( $_POST['custom_field_user_role'] ) ) { - $user_role = sanitize_text_field($_POST['custom_field_user_role']); - } elseif( isset( $this->args['role'] ) ) { - $user_role = $this->args['role']; - } else { - $user_role = NULL; - } - - if( isset( $_POST['username'] ) && ( trim( $_POST['username'] ) != '' ) ) { - $account_name = sanitize_user( $_POST['username'] ); - } elseif( isset( $_POST['email'] ) && ( trim( $_POST['email'] ) != '' ) ) { - $account_name = sanitize_email( $_POST['email'] ); - }else{ - /* we are in the edit form with no username or email field */ - $current_user = wp_get_current_user(); - if( !empty( $current_user ) ) - $account_name = $current_user->user_login; - } - - if( $this->args['form_type'] == 'register' ) { - // ec = email confirmation setting - // aa = admin approval setting - $wppb_general_settings = get_option( 'wppb_general_settings', 'false' ); - if ( $wppb_general_settings ) { - if( !empty( $wppb_general_settings['emailConfirmation'] ) ) - $wppb_email_confirmation = $wppb_general_settings['emailConfirmation']; - else - $wppb_email_confirmation = 'no'; - - if( !empty( $wppb_general_settings['adminApproval'] ) ) - $wppb_admin_approval = $wppb_general_settings['adminApproval']; - else - $wppb_admin_approval = 'no'; - $account_management_settings = 'ec-' . $wppb_email_confirmation . '_' . 'aa-' . $wppb_admin_approval; - } else { - $account_management_settings = 'ec-no_aa-no'; - } - - switch( $account_management_settings ) { - case 'ec-no_aa-no': - $wppb_register_success_message = apply_filters( 'wppb_register_success_message', sprintf( __( "The account %1s has been successfully created!", 'profile-builder' ), $account_name ), $account_name ); - break; - case 'ec-yes_aa-no': - $wppb_register_success_message = apply_filters( 'wppb_register_success_message', sprintf( __( "Before you can access your account %1s, you need to confirm your email address. Please check your inbox and click the activation link.", 'profile-builder' ), $account_name ), $account_name ); - break; - case 'ec-no_aa-yes': - if( current_user_can( 'delete_users' ) ) { - $wppb_register_success_message = apply_filters( 'wppb_register_success_message', sprintf( __( "The account %1s has been successfully created!", 'profile-builder' ), $account_name ), $account_name ); - } else { - $wppb_register_success_message = apply_filters( 'wppb_register_success_message', sprintf( __( "Before you can access your account %1s, an administrator has to approve it. You will be notified via email.", 'profile-builder' ), $account_name ), $account_name ); - } - break; - case 'ec-yes_aa-yes': - $wppb_register_success_message = apply_filters( 'wppb_register_success_message', sprintf( __( "Before you can access your account %1s, you need to confirm your email address. Please check your inbox and click the activation link.", 'profile-builder' ), $account_name ), $account_name ); - break; - } - - // CHECK FOR REDIRECT - $redirect = $this->wppb_get_redirect( 'register', 'after_registration', $account_name, $user_role ); - - if( $this->args['login_after_register'] == 'Yes' ) { - $redirect = $this->wppb_log_in_user( $this->args['redirect_url'], $redirect ); - } - - echo $form_message_tpl_start . $wppb_register_success_message . $form_message_tpl_end . $redirect; - //action hook after registration success - do_action( 'wppb_register_success', $_REQUEST, $this->args['form_name'], $user_id ); - return; - } elseif( $this->args['form_type'] == 'edit_profile' ) { - // CHECK FOR REDIRECT - $redirect = $this->wppb_get_redirect( 'edit_profile', 'after_edit_profile', $account_name, $user_role ); - - echo $form_message_tpl_start . apply_filters( 'wppb_edit_profile_success_message', __( 'Your profile has been successfully updated!', 'profile-builder' ) ) . $form_message_tpl_end . $redirect; - - //action hook after edit profile success - do_action( 'wppb_edit_profile_success', $_REQUEST, $this->args['form_name'], $user_id ); - if( apply_filters( 'wppb_no_form_after_profile_update', false ) ) - return; - } - - } - - }else - echo $message.apply_filters( 'wppb_general_top_error_message', '

            '.__( 'There was an error in the submitted form', 'profile-builder' ).'

            ' ); - - }else - echo $message; - - // use this action hook to add extra content before the register form - do_action( 'wppb_before_'.$this->args['form_type'].'_fields', $this->args['form_name'], $this->args['ID'], $this->args['form_type'] ); - - $wppb_user_role_class = ''; - if( is_user_logged_in() ) { - $wppb_user = wp_get_current_user(); - - if( $wppb_user && isset( $wppb_user->roles ) ) { - foreach( $wppb_user->roles as $wppb_user_role ) { - $wppb_user_role_class .= ' wppb-user-role-'. $wppb_user_role; - } - } - } else { - $wppb_user_role_class = ' wppb-user-logged-out'; - } - $wppb_user_role_class = apply_filters( 'wppb_user_role_form_class', $wppb_user_role_class ); - - /* set up form id */ - $wppb_form_id = ''; - if( $this->args['form_type'] == 'register' ) - $wppb_form_id = 'wppb-register-user'; - elseif( $this->args['form_type'] == 'edit_profile' ) - $wppb_form_id = 'wppb-edit-user'; - if( isset($this->args['form_name']) && $this->args['form_name'] != "unspecified" ) - $wppb_form_id .= '-' . $this->args['form_name']; - - /* set up form class */ - $wppb_form_class = 'wppb-user-forms'; - if( $this->args['form_type'] == 'register' ) - $wppb_form_class .= ' wppb-register-user'; - elseif( $this->args['form_type'] == 'edit_profile' ) - $wppb_form_class .= ' wppb-edit-user'; - $wppb_form_class .= $wppb_user_role_class; - - ?> -
            - args ); - - echo apply_filters( 'wppb_before_form_fields', '
              ', $this->args['form_type'], $this->args['ID'] ); - echo $this->wppb_output_form_fields( $_REQUEST, $field_check_errors, $this->args['form_fields'] ); - echo apply_filters( 'wppb_after_form_fields', '
            ', $this->args['form_type'], $this->args['ID'] ); - - echo apply_filters( 'wppb_before_send_credentials_checkbox', '
              ', $this->args['form_type'], $this->args['ID'] ); - $this->wppb_add_send_credentials_checkbox( $_REQUEST, $this->args['form_type'] ); - echo apply_filters( 'wppb_after_send_credentials_checkbox', '
            ', $this->args['form_type'] ); - - $wppb_form_submit_extra_attr = apply_filters( 'wppb_form_submit_extra_attr', '', $this->args['form_type'], $this->args['ID'] ); - ?> -

            > - args['form_type'] == 'register' ) - $button_name = ( current_user_can( 'create_users' ) ? __( 'Add User', 'profile-builder' ) : __( 'Register', 'profile-builder' ) ); - - elseif( $this->args['form_type'] == 'edit_profile' ) - $button_name = __( 'Update', 'profile-builder' ); - ?> - args ); ?> - " value="args['form_type'] .'_button_name', $button_name ); ?>" args['form_type'] );?>/> - args ); ?> - - - '; - } - ?> -

            - args['form_type'].'_nonce_field' ); ?> - - args['form_type'] .'_fields', $this->args['form_name'], $this->args['ID'], $this->args['form_type'] ); - - } - - function wppb_output_form_fields( $global_request, $field_check_errors, $form_fields, $called_from = NULL ){ - $output_fields = ''; - - if( !empty( $form_fields ) ){ - $output_fields .= apply_filters( 'wppb_output_before_first_form_field', '', $this->args['ID'], $this->args['form_type'], $form_fields, $called_from ); - foreach( $form_fields as $field ){ - $error_var = ( ( array_key_exists( $field['id'], $field_check_errors ) ) ? ' wppb-field-error' : '' ); - $specific_message = ( ( array_key_exists( $field['id'], $field_check_errors ) ) ? $field_check_errors[$field['id']] : '' ); - - $display_field = apply_filters( 'wppb_output_display_form_field', true, $field, $this->args['form_type'], $this->args['role'], $this->wppb_get_desired_user_id() ); - - if( $display_field == false ) - continue; - - $css_class = apply_filters( 'wppb_field_css_class', 'wppb-form-field wppb-'. Wordpress_Creation_Kit_PB::wck_generate_slug( $field['field'] ) .$error_var, $field, $error_var ); - $output_fields .= apply_filters( 'wppb_output_before_form_field', '
          • ', $field, $error_var, $this->args['role'] ); - $output_fields .= apply_filters( 'wppb_output_form_field_'.Wordpress_Creation_Kit_PB::wck_generate_slug( $field['field'] ), '', $this->args['form_type'], $field, $this->wppb_get_desired_user_id(), $field_check_errors, $global_request, $this->args['role'], $this ); - $output_fields .= apply_filters( 'wppb_output_specific_error_message', $specific_message ); - $output_fields .= apply_filters( 'wppb_output_after_form_field', '
          • ', $field, $this->args['ID'], $this->args['form_type'], $called_from ); - } - - $output_fields .= apply_filters( 'wppb_output_after_last_form_field', '', $this->args['ID'], $this->args['form_type'], $called_from ); - } - - return apply_filters( 'wppb_output_fields_filter', $output_fields ); - } - - - function wppb_add_send_credentials_checkbox ( $request_data, $form ){ - if ( $form == 'edit_profile' ) - echo ''; - - else{ - $checkbox = apply_filters( 'wppb_send_credentials_checkbox_logic', '
          • ', $request_data, $form ); - - $wppb_general_settings = get_option( 'wppb_general_settings' ); - echo ( isset( $wppb_general_settings['emailConfirmation'] ) && ( $wppb_general_settings['emailConfirmation'] == 'yes' ) ? '' : $checkbox ); - } - } - - - function wppb_test_required_form_values( $global_request ){ - $output_field_errors = array(); - $form_fields = apply_filters( 'wppb_form_fields', $this->args['form_fields'], array( 'global_request' => $global_request, 'context' => 'validate_frontend', 'global_request' => $global_request, 'form_type' => $this->args['form_type'], 'role' => $this->args['role'], 'user_id' => $this->wppb_get_desired_user_id() ) ); - if( !empty( $form_fields ) ){ - foreach( $form_fields as $field ){ - $error_for_field = apply_filters( 'wppb_check_form_field_'.Wordpress_Creation_Kit_PB::wck_generate_slug( $field['field'] ), '', $field, $global_request, $this->args['form_type'], $this->args['role'], $this->wppb_get_desired_user_id() ); - - if( !empty( $error_for_field ) ) - $output_field_errors[$field['id']] = '' . $error_for_field . ''; - } - } - - return apply_filters( 'wppb_output_field_errors_filter', $output_field_errors, $this->args['form_fields'], $global_request, $this->args['form_type'] ); - } - - function wppb_save_form_values( $global_request ){ - $user_id = $this->wppb_get_desired_user_id(); - $userdata = apply_filters( 'wppb_build_userdata', array(), $global_request ); - $new_user_signup = false; - - $wppb_general_settings = get_option( 'wppb_general_settings' ); - - if( $this->args['form_type'] == 'register' ){ - - $result = $this->wppb_register_user( $global_request, $userdata ); - $user_id = $result['user_id']; - $userdata = $result['userdata']; - $new_user_signup = $result['new_user_signup']; - - }elseif( $this->args['form_type'] == 'edit_profile' ){ - if( isset( $wppb_general_settings['loginWith'] ) && ( $wppb_general_settings['loginWith'] == 'email' ) ){ - $user_info = get_userdata( $user_id ); - $userdata['user_login'] = $user_info->user_login; - } - - $userdata['ID'] = $this->wppb_get_desired_user_id(); - $userdata = wp_unslash( $userdata ); - /* if the user changes his password then we can't send it to the wp_update_user() function or - the user will be logged out and won't be logged in again because we call wp_update_user() after - the headers were sent( in the content as a shortcode ) */ - if( isset( $userdata['user_pass'] ) && !empty( $userdata['user_pass'] ) ){ - unset($userdata['user_pass']); - } - wp_update_user( $userdata ); - } - - if( !empty( $this->args['form_fields'] ) && !$new_user_signup ){ - foreach( $this->args['form_fields'] as $field ){ - do_action( 'wppb_save_form_field', $field, $user_id, $global_request, $this->args['form_type'] ); - } - - if ( $this->args['form_type'] == 'register' ){ - if ( !is_wp_error( $user_id ) ){ - $wppb_general_settings = get_option( 'wppb_general_settings' ); - if( isset( $global_request['send_credentials_via_email'] ) && ( $global_request['send_credentials_via_email'] == 'sending' ) ) - $send_credentials_via_email = 'sending'; - else - $send_credentials_via_email = ''; - wppb_notify_user_registration_email( get_bloginfo( 'name' ), ( isset( $userdata['user_login'] ) ? trim( $userdata['user_login'] ) : trim( $userdata['user_email'] ) ), trim( $userdata['user_email'] ), $send_credentials_via_email, trim( $userdata['user_pass'] ), ( isset( $wppb_general_settings['adminApproval'] ) ? $wppb_general_settings['adminApproval'] : 'no' ) ); - } - } - } - return $user_id; - } - - function wppb_register_user( $global_request, $userdata ){ - $wppb_module_settings = get_option( 'wppb_module_settings' ); - $wppb_general_settings = get_option( 'wppb_general_settings' ); - $user_id = null; - $new_user_signup = false; - - if( isset( $wppb_general_settings['loginWith'] ) && ( $wppb_general_settings['loginWith'] == 'email' ) ){ - $userdata['user_login'] = apply_filters( 'wppb_generated_random_username', Wordpress_Creation_Kit_PB::wck_generate_slug( trim( $userdata['user_email'] ) ), $userdata['user_email'] ); - } - - /* filter so we can bypass Email Confirmation on register */ - $wppb_general_settings['emailConfirmation'] = apply_filters( 'wppb_email_confirmation_on_register', $wppb_general_settings['emailConfirmation'], $global_request ); - - if ( isset( $wppb_general_settings['emailConfirmation'] ) && ( $wppb_general_settings['emailConfirmation'] == 'yes' ) ){ - $new_user_signup = true; - - $userdata = $this->wppb_add_custom_field_values( $global_request, $userdata, $this->args['form_fields'] ); - - if( ! isset( $userdata['role'] ) ) { - $userdata['role'] = $this->args['role']; - } - - $userdata['user_pass'] = wp_hash_password( $userdata['user_pass'] ); - - if( is_multisite() ){ - /* since version 2.0.7 add this meta so we know on what blog the user registered */ - $userdata['registered_for_blog_id'] = get_current_blog_id(); - $userdata = wp_unslash( $userdata ); - } - - wppb_signup_user( $userdata['user_login'], $userdata['user_email'], $userdata ); - }else{ - if( ! isset( $userdata['role'] ) ) { - $userdata['role'] = $this->args['role']; - } - - $userdata = wp_unslash( $userdata ); - - // change User Registered date and time according to timezone selected in WordPress settings - $wppb_get_date = wppb_get_date_by_timezone(); - - if( isset( $wppb_get_date ) ) { - $userdata['user_registered'] = $wppb_get_date; - } - - // insert user to database - $user_id = wp_insert_user( $userdata ); - } - - return array( 'userdata' => $userdata, 'user_id' => $user_id, 'new_user_signup' => $new_user_signup ); - } - - function wppb_add_custom_field_values( $global_request, $meta, $form_properties ){ - $form_fields = apply_filters( 'wppb_form_fields', $this->args['form_fields'], array( 'meta' => $meta, 'global_request' => $global_request, 'context' => 'user_signup' ) ); - if( !empty( $form_fields ) ){ - foreach( $form_fields as $field ){ - if( !empty( $field['meta-name'] ) ){ - $posted_value = ( !empty( $global_request[$field['meta-name']] ) ? $global_request[$field['meta-name']] : '' ); - $meta[$field['meta-name']] = apply_filters( 'wppb_add_to_user_signup_form_field_'.Wordpress_Creation_Kit_PB::wck_generate_slug( $field['field'] ), $posted_value, $field, $global_request ); - } - } - } - - return apply_filters( 'wppb_add_to_user_signup_form_meta', $meta, $global_request, $this->args['role'] ); - } - - /** - * Function that returns the id for the current logged in user or for edit profile forms for administrator it can return the id of a selected user - */ - function wppb_get_desired_user_id(){ - if( $this->args['form_type'] == 'edit_profile' ){ - //only admins - if( ( !is_multisite() && current_user_can( 'edit_users' ) ) || ( is_multisite() && current_user_can( 'manage_network' ) ) ) { - if( isset( $_GET['edit_user'] ) && ! empty( $_GET['edit_user'] ) ){ - return absint( $_GET['edit_user'] ); - } - } - } - - return get_current_user_id(); - } - - function wppb_edit_profile_select_user_to_edit(){ - - $display_edit_users_dropdown = apply_filters( 'wppb_display_edit_other_users_dropdown', true ); - if( !$display_edit_users_dropdown ) - return; - - /* add a hard cap: if we have more than 5000 users don't display the dropdown for performance considerations */ - $user_count = count_users(); - if( $user_count['total_users'] > apply_filters( 'wppb_edit_other_users_count_limit', 5000 ) ) - return; - - if( isset( $_GET['edit_user'] ) && ! empty( $_GET['edit_user'] ) ) - $selected = absint( $_GET['edit_user'] ); - else - $selected = get_current_user_id(); - - $query_args['fields'] = array( 'ID', 'user_login', 'display_name' ); - $query_args['role'] = apply_filters( 'wppb_edit_profile_user_dropdown_role', '' ); - $users = get_users( apply_filters( 'wppb_edit_other_users_dropdown_query_args', $query_args ) ); - if( !empty( $users ) ) { - ?> -
            -

            - - -

            - - - wppb_form_logic(); - $html = ob_get_clean(); - return "{$html}"; - } -} - -/* set action for automatic login after registration */ -add_action( 'init', 'wppb_autologin_after_registration' ); -function wppb_autologin_after_registration(){ - if( isset( $_GET['autologin'] ) && isset( $_GET['uid'] ) ){ - $uid = absint( $_GET['uid'] ); - $nonce = $_REQUEST['_wpnonce']; - - $arr_params = array( 'autologin', 'uid', '_wpnonce' ); - $current_page_url = remove_query_arg( $arr_params, wppb_curpageurl() ); - - if ( ! ( wp_verify_nonce( $nonce , 'autologin-'.$uid.'-'.(int)( time() / 60 ) ) || wp_verify_nonce( $nonce , 'autologin-'.$uid.'-'.(int)( time() / 60 ) - 1 ) ) ){ - wp_redirect( $current_page_url ); - exit; - } else { - wp_set_auth_cookie( $uid ); - wp_redirect( $current_page_url ); - exit; - } - } -} + '', + 'form_fields' => array(), + 'form_name' => '', + 'role' => '', //used only for the register-form settings + 'redirect_url' => '', + 'logout_redirect_url' => '', //used only for the register-form settings + 'redirect_priority' => 'normal', + 'ID' => null + ); + public $args; + + + // Constructor method for the class + function __construct( $args ) { + + /* we should stop the execution of the forms if they are in the wp_head hook because it should not be there. + SEO plugins can execute shortcodes in the auto generated descriptions */ + global $wp_current_filter; + if( !empty( $wp_current_filter ) && is_array( $wp_current_filter ) ){ + foreach( $wp_current_filter as $filter ){ + if( $filter == 'wp_head' ) + return; + } + } + + // Merge the input arguments and the defaults + $this->args = wp_parse_args( $args, $this->defaults ); + + /* set up the ID here if it is a multi form */ + if( $this->args['form_name'] != 'unspecified' ){ + $this->args['ID'] = Profile_Builder_Form_Creator::wppb_get_form_id_from_form_name( $this->args['form_name'], $this->args['form_type'] ); + } + + global $wppb_shortcode_on_front; + $wppb_shortcode_on_front = true; + + if( empty( $this->args['form_fields'] ) ) + $this->args['form_fields'] = apply_filters( 'wppb_change_form_fields', get_option( 'wppb_manage_fields' ), $this->args ); + + if ( file_exists ( WPPB_PLUGIN_DIR.'/front-end/default-fields/default-fields.php' ) ) + require_once( WPPB_PLUGIN_DIR.'/front-end/default-fields/default-fields.php' ); + + if ( file_exists ( WPPB_PLUGIN_DIR.'/front-end/extra-fields/extra-fields.php' ) ) + require_once( WPPB_PLUGIN_DIR.'/front-end/extra-fields/extra-fields.php' ); + + $this->wppb_retrieve_custom_settings(); + + if( ( !is_multisite() && current_user_can( 'edit_users' ) ) || ( is_multisite() && current_user_can( 'manage_network' ) ) ) + add_action( 'wppb_before_edit_profile_fields', array( &$this, 'wppb_edit_profile_select_user_to_edit' ) ); + } + + /** + * @param $form_name The "slug" generated from the current Form Title + * @param $form_type the form type of the form: register, edit_profile + * @return null + */ + static function wppb_get_form_id_from_form_name( $form_name, $form_type ){ + global $wpdb; + + if( $form_type == 'edit_profile' ){ + $post_type = 'wppb-epf-cpt'; + }elseif( $form_type == 'register' ){ + $post_type = 'wppb-rf-cpt'; + } + + $all_forms = $wpdb->get_results( + " + SELECT ID, post_title + FROM $wpdb->posts + WHERE post_status = 'publish' + AND post_type = '$post_type' + " + ); + + if( !empty( $all_forms ) ) { + foreach ($all_forms as $form) { + if( empty( $form->post_title ) ) + $form->post_title = '(no title)'; + + if ($form_name == Wordpress_Creation_Kit_PB::wck_generate_slug($form->post_title)) { + return $form->ID; + } + } + } + + return null; + } + + function wppb_retrieve_custom_settings(){ + $this->args['login_after_register'] = apply_filters( 'wppb_automatically_login_after_register', 'No' ); //used only for the register-form settings + $this->args['redirect_activated'] = apply_filters( 'wppb_redirect_default_setting', '-' ); + $this->args['redirect_url'] = apply_filters( 'wppb_redirect_default_location', ( $this->args['redirect_url'] != '' ) ? $this->args['redirect_url'] : '' ); + $this->args['logout_redirect_url'] = apply_filters( 'wppb_logout_redirect_default_location', ( $this->args['logout_redirect_url'] != '' ) ? $this->args['logout_redirect_url'] : '' ); + $this->args['redirect_delay'] = apply_filters( 'wppb_redirect_default_duration', 3 ); + + if ( !is_null( $this->args['ID'] ) ){ + $meta_name = ( ( $this->args['form_type'] == 'register' ) ? 'wppb_rf_page_settings' : 'wppb_epf_page_settings' ); + + $page_settings = get_post_meta( $this->args['ID'], $meta_name, true ); + + if( !empty( $page_settings[0]['set-role'] ) ){ + if( $page_settings[0]['set-role'] == 'default role' ){ + $selected_role = trim( get_option( 'default_role' ) ); + } + else + $selected_role = $page_settings[0]['set-role']; + } + + $this->args['role'] = ( isset( $selected_role ) ? $selected_role : $this->args['role'] ); + $this->args['login_after_register'] = ( isset( $page_settings[0]['automatically-log-in'] ) ? $page_settings[0]['automatically-log-in'] : $this->args['login_after_register'] ); + $this->args['redirect_activated'] = ( isset( $page_settings[0]['redirect'] ) ? $page_settings[0]['redirect'] : $this->args['redirect_activated'] ); + $this->args['redirect_url'] = ( ! empty( $page_settings[0]['url'] ) && $this->args['redirect_activated'] == 'Yes' && $this->args['redirect_priority'] != 'top' ? $page_settings[0]['url'] : $this->args['redirect_url'] ); + $this->args['redirect_delay'] = ( isset( $page_settings[0]['display-messages'] ) && $this->args['redirect_activated'] == 'Yes' ? $page_settings[0]['display-messages'] : $this->args['redirect_delay'] ); + } + + if( !empty( $this->args['role'] ) ){ + $role_in_arg = get_role( $this->args['role'] ); + if( !empty( $role_in_arg->capabilities['manage_options'] ) || !empty( $role_in_arg->capabilities['remove_users'] ) ){ + if( !current_user_can( 'manage_options' ) || !current_user_can( 'remove_users' ) ){ + $this->args['role'] = get_option('default_role'); + echo apply_filters( 'wppb_register_pre_form_user_role_message', '

            '.__( 'The role of the created user set to the default role. Only an administrator can register a user with the role assigned to this form.', 'profile-builder').'

            ' ); + } + } + } + } + + function wppb_form_logic() { + if( $this->args['form_type'] == 'register' ){ + $registration = apply_filters ( 'wppb_register_setting_override', get_option( 'users_can_register' ) ); + + if ( !is_user_logged_in() ){ + if ( !$registration ) + echo apply_filters( 'wppb_register_pre_form_message', '

            '.__( 'Only an administrator can add new users.', 'profile-builder').'

            ' ); + + elseif ( $registration ){ + $this->wppb_form_content( apply_filters( 'wppb_register_pre_form_message', '' ) ); + } + + }else{ + $current_user_capability = apply_filters ( 'wppb_registration_user_capability', 'create_users' ); + + if ( current_user_can( $current_user_capability ) && $registration ) + $this->wppb_form_content( apply_filters( 'wppb_register_pre_form_message', '

            '.__( 'Users can register themselves or you can manually create users here.', 'profile-builder'). '' . '

            ' ) ); + + elseif ( current_user_can( $current_user_capability ) && !$registration ) + $this->wppb_form_content( apply_filters( 'wppb_register_pre_form_message', '

            '.__( 'Users cannot currently register themselves, but you can manually create users here.', 'profile-builder'). '' . '

            ' ) ); + + elseif ( !current_user_can( $current_user_capability ) ){ + global $user_ID; + + $userdata = get_userdata( $user_ID ); + $display_name = ( ( $userdata->data->display_name == '' ) ? $userdata->data->user_login : $userdata->data->display_name ); + + $wppb_general_settings = get_option( 'wppb_general_settings' ); + if ( isset( $wppb_general_settings['loginWith'] ) && ( $wppb_general_settings['loginWith'] == 'email' ) ) + $display_name = $userdata->data->user_email; + + if( empty( $this->args['logout_redirect_url'] ) ) { + $this->args['logout_redirect_url'] = get_permalink(); + } + + // CHECK FOR REDIRECT + $this->args['logout_redirect_url'] = wppb_get_redirect_url( $this->args['redirect_priority'], 'after_logout', $this->args['logout_redirect_url'], $userdata ); + $this->args['logout_redirect_url'] = apply_filters( 'wppb_after_logout_redirect_url', $this->args['logout_redirect_url'] ); + + echo apply_filters( 'wppb_register_pre_form_message', '

            '.sprintf( __( "You are currently logged in as %1s. You don't need another account. %2s", 'profile-builder' ), ''.$display_name.'', ''.__( 'Logout', 'profile-builder' ).' »' ).'

            ', $user_ID ); + } + } + + }elseif ( $this->args['form_type'] == 'edit_profile' ){ + if ( !is_user_logged_in() ) + echo apply_filters( 'wppb_edit_profile_user_not_logged_in_message', '

            '.__( 'You must be logged in to edit your profile.', 'profile-builder' ) .'

            ' ); + + elseif ( is_user_logged_in() ) + $this->wppb_form_content( apply_filters( 'wppb_edit_profile_logged_in_user_message', '' ) ); + + } + } + + // Function used to automatically log in a user after register if that option is set on yes in register form settings + function wppb_log_in_user( $redirect, $redirect_old ) { + if( is_user_logged_in() ) { + return; + } + + $wppb_general_settings = get_option( 'wppb_general_settings' ); + + if ( isset( $wppb_general_settings['emailConfirmation'] ) && ( $wppb_general_settings['emailConfirmation'] == 'yes' ) ) { + return $redirect_old; + } + + /* get user id */ + $user = get_user_by( 'email', trim( sanitize_email( $_POST['email'] ) ) ); + $nonce = wp_create_nonce( 'autologin-'. $user->ID .'-'. (int)( time() / 60 ) ); + + if ( isset( $wppb_general_settings['adminApproval'] ) && ( $wppb_general_settings['adminApproval'] == 'yes' ) ) { + if( !empty( $wppb_general_settings['adminApprovalOnUserRole'] ) ) { + foreach ($user->roles as $role) { + if ( in_array( $role, $wppb_general_settings['adminApprovalOnUserRole'] ) ) { + return $redirect_old; + } + } + } + else { + return $redirect_old; + } + } + + /* define redirect location */ + if( $this->args['redirect_activated'] == 'No' ) { + if( isset( $_POST['_wp_http_referer'] ) ) { + $redirect = esc_url_raw($_POST['_wp_http_referer']); + } else { + $redirect = home_url(); + } + } + + $redirect = apply_filters( 'wppb_login_after_reg_redirect_url', $redirect, $this ); + + $redirect = add_query_arg( array( 'autologin' => 'true', 'uid' => $user->ID, '_wpnonce' => $nonce ), $redirect ); + + // CHECK FOR REDIRECT + if( $this->args['redirect_activated'] == 'No' || ( empty( $this->args['redirect_delay'] ) || $this->args['redirect_delay'] == '0' ) ) { + $redirect = wppb_build_redirect( $redirect, 0, 'register', $this->args ); + } else { + $redirect = wppb_build_redirect( $redirect, $this->args['redirect_delay'], 'register', $this->args ); + } + return $redirect; + } + + /** + * Function to get redirect for Register and Edit Profile forms + * + * @param string $form_type - type of the form + * @param string $redirect_type - type of the redirect + * @param string $user - username or user email + * @param string $user_role - user Role + * + * @return string $redirect + */ + function wppb_get_redirect( $form_type, $redirect_type, $user, $user_role ) { + $this->args['redirect_delay'] = apply_filters( 'wppb_'. $form_type .'_redirect_delay', $this->args['redirect_delay'], $user, $this->args ); + if( $this->args['redirect_activated'] == '-' ) { + $this->args['redirect_url'] = wppb_get_redirect_url( $this->args['redirect_priority'], $redirect_type, $this->args['redirect_url'], $user, $user_role ); + $redirect = wppb_build_redirect( $this->args['redirect_url'], $this->args['redirect_delay'], $form_type, $this->args ); + } elseif( $this->args['redirect_activated'] == 'Yes' ) { + $redirect = wppb_build_redirect( $this->args['redirect_url'], $this->args['redirect_delay'], $form_type, $this->args ); + } else { + $redirect = ''; + } + + return $redirect; + } + + function wppb_form_content( $message ) { + $field_check_errors = array(); + + if( isset( $_REQUEST['action'] ) && $_REQUEST['form_name'] == $this->args['form_name'] ) { + $field_check_errors = $this->wppb_test_required_form_values( $_REQUEST ); + if( empty( $field_check_errors ) ) { + + do_action( 'wppb_before_saving_form_values',$_REQUEST, $this->args ); + + // we only have a $user_id on default registration (no email confirmation, no multisite) + $user_id = $this->wppb_save_form_values( $_REQUEST ); + + if( ( 'POST' == $_SERVER['REQUEST_METHOD'] ) && ( $_POST['action'] == $this->args['form_type'] ) ) { + + $form_message_tpl_start = apply_filters( 'wppb_form_message_tpl_start', '

            ' ); + $form_message_tpl_end = apply_filters( 'wppb_form_message_tpl_end', '

            ' ); + + if( isset( $_POST['custom_field_user_role'] ) ) { + $user_role = sanitize_text_field($_POST['custom_field_user_role']); + } elseif( isset( $this->args['role'] ) ) { + $user_role = $this->args['role']; + } else { + $user_role = NULL; + } + + if( isset( $_POST['username'] ) && ( trim( $_POST['username'] ) != '' ) ) { + $account_name = sanitize_user( $_POST['username'] ); + } elseif( isset( $_POST['email'] ) && ( trim( $_POST['email'] ) != '' ) ) { + $account_name = sanitize_email( $_POST['email'] ); + }else{ + /* we are in the edit form with no username or email field */ + $current_user = wp_get_current_user(); + if( !empty( $current_user ) ) + $account_name = $current_user->user_login; + } + + if( $this->args['form_type'] == 'register' ) { + // ec = email confirmation setting + // aa = admin approval setting + $wppb_general_settings = get_option( 'wppb_general_settings', 'false' ); + if ( $wppb_general_settings ) { + if( !empty( $wppb_general_settings['emailConfirmation'] ) ) + $wppb_email_confirmation = $wppb_general_settings['emailConfirmation']; + else + $wppb_email_confirmation = 'no'; + + if( !empty( $wppb_general_settings['adminApproval'] ) ) + $wppb_admin_approval = $wppb_general_settings['adminApproval']; + else + $wppb_admin_approval = 'no'; + $account_management_settings = 'ec-' . $wppb_email_confirmation . '_' . 'aa-' . $wppb_admin_approval; + } else { + $account_management_settings = 'ec-no_aa-no'; + } + + switch( $account_management_settings ) { + case 'ec-no_aa-no': + $wppb_register_success_message = apply_filters( 'wppb_register_success_message', sprintf( __( "The account %1s has been successfully created!", 'profile-builder' ), $account_name ), $account_name ); + break; + case 'ec-yes_aa-no': + $wppb_register_success_message = apply_filters( 'wppb_register_success_message', sprintf( __( "Before you can access your account %1s, you need to confirm your email address. Please check your inbox and click the activation link.", 'profile-builder' ), $account_name ), $account_name ); + break; + case 'ec-no_aa-yes': + if( current_user_can( 'delete_users' ) ) { + $wppb_register_success_message = apply_filters( 'wppb_register_success_message', sprintf( __( "The account %1s has been successfully created!", 'profile-builder' ), $account_name ), $account_name ); + } else { + $wppb_register_success_message = apply_filters( 'wppb_register_success_message', sprintf( __( "Before you can access your account %1s, an administrator has to approve it. You will be notified via email.", 'profile-builder' ), $account_name ), $account_name ); + } + break; + case 'ec-yes_aa-yes': + $wppb_register_success_message = apply_filters( 'wppb_register_success_message', sprintf( __( "Before you can access your account %1s, you need to confirm your email address. Please check your inbox and click the activation link.", 'profile-builder' ), $account_name ), $account_name ); + break; + } + + // CHECK FOR REDIRECT + $redirect = $this->wppb_get_redirect( 'register', 'after_registration', $account_name, $user_role ); + + if( $this->args['login_after_register'] == 'Yes' ) { + $redirect = $this->wppb_log_in_user( $this->args['redirect_url'], $redirect ); + } + + echo $form_message_tpl_start . $wppb_register_success_message . $form_message_tpl_end . $redirect; + //action hook after registration success + do_action( 'wppb_register_success', $_REQUEST, $this->args['form_name'], $user_id ); + return; + } elseif( $this->args['form_type'] == 'edit_profile' ) { + // CHECK FOR REDIRECT + $redirect = $this->wppb_get_redirect( 'edit_profile', 'after_edit_profile', $account_name, $user_role ); + + echo $form_message_tpl_start . apply_filters( 'wppb_edit_profile_success_message', __( 'Your profile has been successfully updated!', 'profile-builder' ) ) . $form_message_tpl_end . $redirect; + + //action hook after edit profile success + do_action( 'wppb_edit_profile_success', $_REQUEST, $this->args['form_name'], $user_id ); + if( apply_filters( 'wppb_no_form_after_profile_update', false ) ) + return; + } + + } + + }else + echo $message.apply_filters( 'wppb_general_top_error_message', '

            '.__( 'There was an error in the submitted form', 'profile-builder' ).'

            ' ); + + }else + echo $message; + + // use this action hook to add extra content before the register form + do_action( 'wppb_before_'.$this->args['form_type'].'_fields', $this->args['form_name'], $this->args['ID'], $this->args['form_type'] ); + + $wppb_user_role_class = ''; + if( is_user_logged_in() ) { + $wppb_user = wp_get_current_user(); + + if( $wppb_user && isset( $wppb_user->roles ) ) { + foreach( $wppb_user->roles as $wppb_user_role ) { + $wppb_user_role_class .= ' wppb-user-role-'. $wppb_user_role; + } + } + } else { + $wppb_user_role_class = ' wppb-user-logged-out'; + } + $wppb_user_role_class = apply_filters( 'wppb_user_role_form_class', $wppb_user_role_class ); + + /* set up form id */ + $wppb_form_id = ''; + if( $this->args['form_type'] == 'register' ) + $wppb_form_id = 'wppb-register-user'; + elseif( $this->args['form_type'] == 'edit_profile' ) + $wppb_form_id = 'wppb-edit-user'; + if( isset($this->args['form_name']) && $this->args['form_name'] != "unspecified" ) + $wppb_form_id .= '-' . $this->args['form_name']; + + /* set up form class */ + $wppb_form_class = 'wppb-user-forms'; + if( $this->args['form_type'] == 'register' ) + $wppb_form_class .= ' wppb-register-user'; + elseif( $this->args['form_type'] == 'edit_profile' ) + $wppb_form_class .= ' wppb-edit-user'; + $wppb_form_class .= $wppb_user_role_class; + + ?> +
            + args ); + + echo apply_filters( 'wppb_before_form_fields', '
              ', $this->args['form_type'], $this->args['ID'] ); + echo $this->wppb_output_form_fields( $_REQUEST, $field_check_errors, $this->args['form_fields'] ); + echo apply_filters( 'wppb_after_form_fields', '
            ', $this->args['form_type'], $this->args['ID'] ); + + echo apply_filters( 'wppb_before_send_credentials_checkbox', '
              ', $this->args['form_type'], $this->args['ID'] ); + $this->wppb_add_send_credentials_checkbox( $_REQUEST, $this->args['form_type'] ); + echo apply_filters( 'wppb_after_send_credentials_checkbox', '
            ', $this->args['form_type'] ); + + $wppb_form_submit_extra_attr = apply_filters( 'wppb_form_submit_extra_attr', '', $this->args['form_type'], $this->args['ID'] ); + ?> +

            > + args['form_type'] == 'register' ) + $button_name = ( current_user_can( 'create_users' ) ? __( 'Add User', 'profile-builder' ) : __( 'Register', 'profile-builder' ) ); + + elseif( $this->args['form_type'] == 'edit_profile' ) + $button_name = __( 'Update', 'profile-builder' ); + ?> + args ); ?> + " value="args['form_type'] .'_button_name', $button_name ); ?>" args['form_type'] );?>/> + args ); ?> + + + '; + } + ?> +

            + args['form_type'].'_nonce_field' ); ?> + + args['form_type'] .'_fields', $this->args['form_name'], $this->args['ID'], $this->args['form_type'] ); + + } + + function wppb_output_form_fields( $global_request, $field_check_errors, $form_fields, $called_from = NULL ){ + $output_fields = ''; + + if( !empty( $form_fields ) ){ + $output_fields .= apply_filters( 'wppb_output_before_first_form_field', '', $this->args['ID'], $this->args['form_type'], $form_fields, $called_from ); + foreach( $form_fields as $field ){ + $error_var = ( ( array_key_exists( $field['id'], $field_check_errors ) ) ? ' wppb-field-error' : '' ); + $specific_message = ( ( array_key_exists( $field['id'], $field_check_errors ) ) ? $field_check_errors[$field['id']] : '' ); + + $display_field = apply_filters( 'wppb_output_display_form_field', true, $field, $this->args['form_type'], $this->args['role'], $this->wppb_get_desired_user_id() ); + + if( $display_field == false ) + continue; + + $css_class = apply_filters( 'wppb_field_css_class', 'wppb-form-field wppb-'. Wordpress_Creation_Kit_PB::wck_generate_slug( $field['field'] ) .$error_var, $field, $error_var ); + $output_fields .= apply_filters( 'wppb_output_before_form_field', '
          • ', $field, $error_var, $this->args['role'] ); + $output_fields .= apply_filters( 'wppb_output_form_field_'.Wordpress_Creation_Kit_PB::wck_generate_slug( $field['field'] ), '', $this->args['form_type'], $field, $this->wppb_get_desired_user_id(), $field_check_errors, $global_request, $this->args['role'], $this ); + $output_fields .= apply_filters( 'wppb_output_specific_error_message', $specific_message ); + $output_fields .= apply_filters( 'wppb_output_after_form_field', '
          • ', $field, $this->args['ID'], $this->args['form_type'], $called_from ); + } + + $output_fields .= apply_filters( 'wppb_output_after_last_form_field', '', $this->args['ID'], $this->args['form_type'], $called_from ); + } + + return apply_filters( 'wppb_output_fields_filter', $output_fields ); + } + + + function wppb_add_send_credentials_checkbox ( $request_data, $form ){ + if ( $form == 'edit_profile' ) + echo ''; + + else{ + $checkbox = apply_filters( 'wppb_send_credentials_checkbox_logic', '
          • ', $request_data, $form ); + + $wppb_general_settings = get_option( 'wppb_general_settings' ); + echo ( isset( $wppb_general_settings['emailConfirmation'] ) && ( $wppb_general_settings['emailConfirmation'] == 'yes' ) ? '' : $checkbox ); + } + } + + + function wppb_test_required_form_values( $global_request ){ + $output_field_errors = array(); + $form_fields = apply_filters( 'wppb_form_fields', $this->args['form_fields'], array( 'global_request' => $global_request, 'context' => 'validate_frontend', 'global_request' => $global_request, 'form_type' => $this->args['form_type'], 'role' => $this->args['role'], 'user_id' => $this->wppb_get_desired_user_id() ) ); + if( !empty( $form_fields ) ){ + foreach( $form_fields as $field ){ + $error_for_field = apply_filters( 'wppb_check_form_field_'.Wordpress_Creation_Kit_PB::wck_generate_slug( $field['field'] ), '', $field, $global_request, $this->args['form_type'], $this->args['role'], $this->wppb_get_desired_user_id() ); + + if( !empty( $error_for_field ) ) + $output_field_errors[$field['id']] = '' . $error_for_field . ''; + } + } + + return apply_filters( 'wppb_output_field_errors_filter', $output_field_errors, $this->args['form_fields'], $global_request, $this->args['form_type'] ); + } + + function wppb_save_form_values( $global_request ){ + $user_id = $this->wppb_get_desired_user_id(); + $userdata = apply_filters( 'wppb_build_userdata', array(), $global_request ); + $new_user_signup = false; + + $wppb_general_settings = get_option( 'wppb_general_settings' ); + + if( $this->args['form_type'] == 'register' ){ + + $result = $this->wppb_register_user( $global_request, $userdata ); + $user_id = $result['user_id']; + $userdata = $result['userdata']; + $new_user_signup = $result['new_user_signup']; + + }elseif( $this->args['form_type'] == 'edit_profile' ){ + if( isset( $wppb_general_settings['loginWith'] ) && ( $wppb_general_settings['loginWith'] == 'email' ) ){ + $user_info = get_userdata( $user_id ); + $userdata['user_login'] = $user_info->user_login; + } + + $userdata['ID'] = $this->wppb_get_desired_user_id(); + $userdata = wp_unslash( $userdata ); + /* if the user changes his password then we can't send it to the wp_update_user() function or + the user will be logged out and won't be logged in again because we call wp_update_user() after + the headers were sent( in the content as a shortcode ) */ + if( isset( $userdata['user_pass'] ) && !empty( $userdata['user_pass'] ) ){ + unset($userdata['user_pass']); + } + wp_update_user( $userdata ); + } + + if( !empty( $this->args['form_fields'] ) && !$new_user_signup ){ + foreach( $this->args['form_fields'] as $field ){ + do_action( 'wppb_save_form_field', $field, $user_id, $global_request, $this->args['form_type'] ); + } + + if ( $this->args['form_type'] == 'register' ){ + if ( !is_wp_error( $user_id ) ){ + $wppb_general_settings = get_option( 'wppb_general_settings' ); + if( isset( $global_request['send_credentials_via_email'] ) && ( $global_request['send_credentials_via_email'] == 'sending' ) ) + $send_credentials_via_email = 'sending'; + else + $send_credentials_via_email = ''; + wppb_notify_user_registration_email( get_bloginfo( 'name' ), ( isset( $userdata['user_login'] ) ? trim( $userdata['user_login'] ) : trim( $userdata['user_email'] ) ), trim( $userdata['user_email'] ), $send_credentials_via_email, trim( $userdata['user_pass'] ), ( isset( $wppb_general_settings['adminApproval'] ) ? $wppb_general_settings['adminApproval'] : 'no' ) ); + } + } + } + return $user_id; + } + + function wppb_register_user( $global_request, $userdata ){ + $wppb_module_settings = get_option( 'wppb_module_settings' ); + $wppb_general_settings = get_option( 'wppb_general_settings' ); + $user_id = null; + $new_user_signup = false; + + if( isset( $wppb_general_settings['loginWith'] ) && ( $wppb_general_settings['loginWith'] == 'email' ) ){ + $userdata['user_login'] = apply_filters( 'wppb_generated_random_username', Wordpress_Creation_Kit_PB::wck_generate_slug( trim( $userdata['user_email'] ) ), $userdata['user_email'] ); + } + + /* filter so we can bypass Email Confirmation on register */ + $wppb_general_settings['emailConfirmation'] = apply_filters( 'wppb_email_confirmation_on_register', $wppb_general_settings['emailConfirmation'], $global_request ); + + if ( isset( $wppb_general_settings['emailConfirmation'] ) && ( $wppb_general_settings['emailConfirmation'] == 'yes' ) ){ + $new_user_signup = true; + + $userdata = $this->wppb_add_custom_field_values( $global_request, $userdata, $this->args['form_fields'] ); + + if( ! isset( $userdata['role'] ) ) { + $userdata['role'] = $this->args['role']; + } + + $userdata['user_pass'] = wp_hash_password( $userdata['user_pass'] ); + + if( is_multisite() ){ + /* since version 2.0.7 add this meta so we know on what blog the user registered */ + $userdata['registered_for_blog_id'] = get_current_blog_id(); + $userdata = wp_unslash( $userdata ); + } + + wppb_signup_user( $userdata['user_login'], $userdata['user_email'], $userdata ); + }else{ + if( ! isset( $userdata['role'] ) ) { + $userdata['role'] = $this->args['role']; + } + + $userdata = wp_unslash( $userdata ); + + // change User Registered date and time according to timezone selected in WordPress settings + $wppb_get_date = wppb_get_date_by_timezone(); + + if( isset( $wppb_get_date ) ) { + $userdata['user_registered'] = $wppb_get_date; + } + + // insert user to database + $user_id = wp_insert_user( $userdata ); + } + + return array( 'userdata' => $userdata, 'user_id' => $user_id, 'new_user_signup' => $new_user_signup ); + } + + function wppb_add_custom_field_values( $global_request, $meta, $form_properties ){ + $form_fields = apply_filters( 'wppb_form_fields', $this->args['form_fields'], array( 'meta' => $meta, 'global_request' => $global_request, 'context' => 'user_signup' ) ); + if( !empty( $form_fields ) ){ + foreach( $form_fields as $field ){ + if( !empty( $field['meta-name'] ) ){ + $posted_value = ( !empty( $global_request[$field['meta-name']] ) ? $global_request[$field['meta-name']] : '' ); + $meta[$field['meta-name']] = apply_filters( 'wppb_add_to_user_signup_form_field_'.Wordpress_Creation_Kit_PB::wck_generate_slug( $field['field'] ), $posted_value, $field, $global_request ); + } + } + } + + return apply_filters( 'wppb_add_to_user_signup_form_meta', $meta, $global_request, $this->args['role'] ); + } + + /** + * Function that returns the id for the current logged in user or for edit profile forms for administrator it can return the id of a selected user + */ + function wppb_get_desired_user_id(){ + if( $this->args['form_type'] == 'edit_profile' ){ + //only admins + if( ( !is_multisite() && current_user_can( 'edit_users' ) ) || ( is_multisite() && current_user_can( 'manage_network' ) ) ) { + if( isset( $_GET['edit_user'] ) && ! empty( $_GET['edit_user'] ) ){ + return absint( $_GET['edit_user'] ); + } + } + } + + return get_current_user_id(); + } + + function wppb_edit_profile_select_user_to_edit(){ + + $display_edit_users_dropdown = apply_filters( 'wppb_display_edit_other_users_dropdown', true ); + if( !$display_edit_users_dropdown ) + return; + + /* add a hard cap: if we have more than 5000 users don't display the dropdown for performance considerations */ + $user_count = count_users(); + if( $user_count['total_users'] > apply_filters( 'wppb_edit_other_users_count_limit', 5000 ) ) + return; + + if( isset( $_GET['edit_user'] ) && ! empty( $_GET['edit_user'] ) ) + $selected = absint( $_GET['edit_user'] ); + else + $selected = get_current_user_id(); + + $query_args['fields'] = array( 'ID', 'user_login', 'display_name' ); + $query_args['role'] = apply_filters( 'wppb_edit_profile_user_dropdown_role', '' ); + $users = get_users( apply_filters( 'wppb_edit_other_users_dropdown_query_args', $query_args ) ); + if( !empty( $users ) ) { + ?> +
            +

            + + +

            + + + wppb_form_logic(); + $html = ob_get_clean(); + return "{$html}"; + } +} + +/* set action for automatic login after registration */ +add_action( 'init', 'wppb_autologin_after_registration' ); +function wppb_autologin_after_registration(){ + if( isset( $_GET['autologin'] ) && isset( $_GET['uid'] ) ){ + $uid = absint( $_GET['uid'] ); + $nonce = $_REQUEST['_wpnonce']; + + $arr_params = array( 'autologin', 'uid', '_wpnonce' ); + $current_page_url = remove_query_arg( $arr_params, wppb_curpageurl() ); + + if ( ! ( wp_verify_nonce( $nonce , 'autologin-'.$uid.'-'.(int)( time() / 60 ) ) || wp_verify_nonce( $nonce , 'autologin-'.$uid.'-'.(int)( time() / 60 ) - 1 ) ) ){ + wp_redirect( $current_page_url ); + exit; + } else { + wp_set_auth_cookie( $uid ); + wp_redirect( $current_page_url ); + exit; + } + } +} diff --git a/profile-builder/front-end/default-fields/aim/aim.php b/profile-builder/front-end/default-fields/aim/aim.php index 3d6330e..4b3956a 100644 --- a/profile-builder/front-end/default-fields/aim/aim.php +++ b/profile-builder/front-end/default-fields/aim/aim.php @@ -1,55 +1,55 @@ -*' : '' ); - - if ( array_key_exists( $field['id'], $field_check_errors ) ) - $error_mark = ''; - - $extra_attr = apply_filters( 'wppb_extra_attribute', '', $field, $form_location ); - - $output = ' - - '; - if( !empty( $item_description ) ) - $output .= ''. $item_description .''; - - } - - return apply_filters( 'wppb_'.$form_location.'_aim', $output, $form_location, $field, $user_id, $field_check_errors, $request_data ); -} -add_filter( 'wppb_output_form_field_default-aim', 'wppb_aim_handler', 10, 6 ); - - -/* handle field validation */ -function wppb_check_aim_value( $message, $field, $request_data, $form_location ){ - if( $field['required'] == 'Yes' ){ - if( ( isset( $request_data['aim'] ) && ( trim( $request_data['aim'] ) == '' ) ) || !isset( $request_data['aim'] ) ){ - return wppb_required_field_error($field["field-title"]); - } - } - - return $message; -} -add_filter( 'wppb_check_form_field_default-aim', 'wppb_check_aim_value', 10, 4 ); - -/* handle field save */ -function wppb_userdata_add_aim( $userdata, $global_request ){ - if ( isset( $global_request['aim'] ) ) - $userdata['aim'] = sanitize_text_field ( trim( $global_request['aim'] ) ); - - return $userdata; -} +*' : '' ); + + if ( array_key_exists( $field['id'], $field_check_errors ) ) + $error_mark = ''; + + $extra_attr = apply_filters( 'wppb_extra_attribute', '', $field, $form_location ); + + $output = ' + + '; + if( !empty( $item_description ) ) + $output .= ''. $item_description .''; + + } + + return apply_filters( 'wppb_'.$form_location.'_aim', $output, $form_location, $field, $user_id, $field_check_errors, $request_data ); +} +add_filter( 'wppb_output_form_field_default-aim', 'wppb_aim_handler', 10, 6 ); + + +/* handle field validation */ +function wppb_check_aim_value( $message, $field, $request_data, $form_location ){ + if( $field['required'] == 'Yes' ){ + if( ( isset( $request_data['aim'] ) && ( trim( $request_data['aim'] ) == '' ) ) || !isset( $request_data['aim'] ) ){ + return wppb_required_field_error($field["field-title"]); + } + } + + return $message; +} +add_filter( 'wppb_check_form_field_default-aim', 'wppb_check_aim_value', 10, 4 ); + +/* handle field save */ +function wppb_userdata_add_aim( $userdata, $global_request ){ + if ( isset( $global_request['aim'] ) ) + $userdata['aim'] = sanitize_text_field ( trim( $global_request['aim'] ) ); + + return $userdata; +} add_filter( 'wppb_build_userdata', 'wppb_userdata_add_aim', 10, 2 ); \ No newline at end of file diff --git a/profile-builder/front-end/default-fields/blog-details/blog-details.php b/profile-builder/front-end/default-fields/blog-details/blog-details.php index b1af9aa..59edb1b 100644 --- a/profile-builder/front-end/default-fields/blog-details/blog-details.php +++ b/profile-builder/front-end/default-fields/blog-details/blog-details.php @@ -1,231 +1,231 @@ -'; - - $item_description = wppb_icl_t( 'plugin profile-builder-pro', 'default_field_'.$field['id'].'_description_translation', $field['description'] ); - $heading = '
          • '.wppb_icl_t('plugin profile-builder-pro', 'custom_field_'.$field['id'].'_title_translation', $field['field-title']).'

            '.$item_description.'
          • '; - $output .= apply_filters( 'wppb_blog_details_heading', $heading ); - - - ?> .wppb-blog-details-fields {display:none;} '; - } - $create_new_site_checkbox = ' -
          • - -
          • '; - $output .= apply_filters( 'wppb_blog_details_checkbox', $create_new_site_checkbox ); - - $output .= '
              '; - - // Site URL - $item_description = __( 'Your site url will look like this:
              ', 'profile-builder' ); - if ( is_subdomain_install() ) { - global $current_site; - $subdomain_base = apply_filters( 'wppb_blogs_subdomain_base', preg_replace( '|^www\.|', '', $current_site->domain ) . $current_site->path ); - $domain = '"http://'. esc_attr( '.' ) . $subdomain_base; - } else { - $domain = '"' . esc_url( home_url( '/' ) ) . esc_attr( '' ) . '"'; - } - $blog_url_input_value = ''; - $blog_url_input_value = ( isset( $request_data['wppb_blog_url'] ) ? trim( $request_data['wppb_blog_url'] ) : $blog_url_input_value ); - $error_mark = '*'; - - $extra_attr = apply_filters( 'wppb_extra_attribute', '', $field, $form_location ); - - $error_class = ''; - $is_error = wppb_check_individual_blog_fields( 'wppb_blog_url', $request_data, $form_location ); - if ($is_error != '') { - $error_mark = ''; - $error_class = ' wppb-field-error'; - } - - $output .= ' -
            • - - '; - $output .= ''. $item_description . $domain . ''; - $output .= $is_error .'
            • '; - - - - // Site title - $blog_title_input_value = ''; - $blog_title_input_value = ( isset( $request_data['wppb_blog_title'] ) ? trim( $request_data['wppb_blog_title'] ) : $blog_title_input_value ); - $error_mark = '*'; - - $extra_attr = apply_filters( 'wppb_extra_attribute', '', $field, $form_location ); - - $error_class = ''; - $is_error = wppb_check_individual_blog_fields( 'wppb_blog_title', $request_data, $form_location ); - if ($is_error != '') { - $error_mark = ''; - $error_class = ' wppb-field-error'; - } - - $output .= ' -
            • - - ' . - $is_error . '
            • '; - - - - // Privacy - $blog_privacy_input_value = 'Yes'; - $blog_privacy_input_value = ( isset( $request_data['wppb_blog_privacy'] ) ? trim( $request_data['wppb_blog_privacy'] ) : $blog_privacy_input_value ); - $error_mark = '*'; - - $radio_values = array( 'Yes', 'No' ); - - $error_class = ''; - $is_error = wppb_check_individual_blog_fields( 'wppb_blog_privacy', $request_data, $form_location ); - if ($is_error != '') { - $error_mark = ''; - $error_class = ' wppb-field-error'; - } - - $output .= ' -
            • - '; - $output .= '
                '; - foreach( $radio_values as $key => $value){ - $output .= '
              • '. trim( $radio_values[$key] ) .'
              • '; - } - $output .= '
              ' . $is_error . '
            • '; - - // end wppb-blog-details-fields - $output .= '
            '; - - $output .= ''; - - return apply_filters( 'wppb_blog_details_output', $output, $form_location, $field, $user_id, $field_check_errors, $request_data ); - -} -add_filter( 'wppb_output_form_field_default-blog-details', 'wppb_blog_details_handler', 10, 6 ); - -/* handle field save */ -function wppb_create_blog_on_registration( $field, $user_id, $request_data, $form_location ){ - if( $form_location == 'register' && $field['field'] == 'Default - Blog Details' && isset( $request_data['wppb_create_new_site_checkbox'] ) && $request_data['wppb_create_new_site_checkbox'] == 'yes' ) { - $blog_url = $request_data['wppb_blog_url']; - $blog_title = $request_data['wppb_blog_title']; - - $usermeta['public'] = ( isset( $request_data['wppb_blog_privacy'] ) && 'Yes' == $request_data['wppb_blog_privacy'] ) ? true : false; - $blog_details = wpmu_validate_blog_signup( $blog_url, $blog_title ); - if ( empty($blog_details['errors']->errors['blogname']) && empty($blog_details['errors']->errors['blog_title'])) { - wpmu_create_blog( $blog_details['domain'], $blog_details['path'], $blog_details['blog_title'], $user_id, $usermeta ); - } - } -} -add_action( 'wppb_save_form_field', 'wppb_create_blog_on_registration', 10, 4 ); - -/* handle field validation */ -function wppb_check_blog_details_values( $message, $field, $request_data, $form_location ){ - if ( isset( $request_data['wppb_create_new_site_checkbox'] ) && $request_data['wppb_create_new_site_checkbox'] == 'yes' ){ - $blog_fields_array = wppb_blog_details_fields_array(); - foreach ( $blog_fields_array as $blog_field ){ - if( ( isset( $request_data[$blog_field] ) && ( trim( $request_data[$blog_field] ) == '' ) ) || !isset( $request_data[$blog_field] ) ){ - return wppb_required_field_error($blog_field); - } - } - } - return $message; -} -add_filter( 'wppb_check_form_field_default-blog-details', 'wppb_check_blog_details_values', 10, 4 ); - -/* Add blog details information to wp_signups table (when Email Confirmation is active) */ -function wppb_add_blog_details_to_signup_table( $meta, $global_request, $role ){ - if ( isset( $global_request['wppb_create_new_site_checkbox'] ) && $global_request['wppb_create_new_site_checkbox'] == 'yes' ) { - $blog_details_fields_array = wppb_blog_details_fields_array(); - - foreach ($blog_details_fields_array as $blog_field) { - $meta[$blog_field] = $global_request[$blog_field]; - } - } - return $meta; -} -add_filter( 'wppb_add_to_user_signup_form_meta', 'wppb_add_blog_details_to_signup_table',10, 3 ); - - - -function wppb_blog_details_fields_array(){ - return array( - 'wppb_blog_title', - 'wppb_blog_url', - 'wppb_blog_privacy', - 'wppb_create_new_site_checkbox' - ); -} - -function wppb_check_individual_blog_fields( $field_key, $request_data, $form_location ){ - if ( isset( $request_data['wppb_create_new_site_checkbox'] ) && $request_data['wppb_create_new_site_checkbox'] == 'yes' ) { - if ( $field_key == 'wppb_blog_privacy' && ( ! isset( $request_data[$field_key] ) || ( isset( $request_data[$field_key] ) && ( trim( $request_data[$field_key] ) == '' ) ) ) ) { - return '' . wppb_required_field_error($field_key) . ''; - } - - $wp_error = wpmu_validate_blog_signup($request_data['wppb_blog_url'], $request_data['wppb_blog_title']); - - if ( $field_key == 'wppb_blog_url' && !empty($wp_error['errors']->errors['blogname'])){ - return '' . $wp_error['errors']->errors['blogname'][0] . ''; - } - if ( $field_key == 'wppb_blog_title' && !empty($wp_error['errors']->errors['blog_title'])){ - return '' . $wp_error['errors']->errors['blog_title'][0] . ''; - } - - } - return ''; -} - +'; + + $item_description = wppb_icl_t( 'plugin profile-builder-pro', 'default_field_'.$field['id'].'_description_translation', $field['description'] ); + $heading = '
          • '.wppb_icl_t('plugin profile-builder-pro', 'custom_field_'.$field['id'].'_title_translation', $field['field-title']).'

            '.$item_description.'
          • '; + $output .= apply_filters( 'wppb_blog_details_heading', $heading ); + + + ?> .wppb-blog-details-fields {display:none;} '; + } + $create_new_site_checkbox = ' +
          • + +
          • '; + $output .= apply_filters( 'wppb_blog_details_checkbox', $create_new_site_checkbox ); + + $output .= '
              '; + + // Site URL + $item_description = __( 'Your site url will look like this:
              ', 'profile-builder' ); + if ( is_subdomain_install() ) { + global $current_site; + $subdomain_base = apply_filters( 'wppb_blogs_subdomain_base', preg_replace( '|^www\.|', '', $current_site->domain ) . $current_site->path ); + $domain = '"http://'. esc_attr( '.' ) . $subdomain_base; + } else { + $domain = '"' . esc_url( home_url( '/' ) ) . esc_attr( '' ) . '"'; + } + $blog_url_input_value = ''; + $blog_url_input_value = ( isset( $request_data['wppb_blog_url'] ) ? trim( $request_data['wppb_blog_url'] ) : $blog_url_input_value ); + $error_mark = '*'; + + $extra_attr = apply_filters( 'wppb_extra_attribute', '', $field, $form_location ); + + $error_class = ''; + $is_error = wppb_check_individual_blog_fields( 'wppb_blog_url', $request_data, $form_location ); + if ($is_error != '') { + $error_mark = ''; + $error_class = ' wppb-field-error'; + } + + $output .= ' +
            • + + '; + $output .= ''. $item_description . $domain . ''; + $output .= $is_error .'
            • '; + + + + // Site title + $blog_title_input_value = ''; + $blog_title_input_value = ( isset( $request_data['wppb_blog_title'] ) ? trim( $request_data['wppb_blog_title'] ) : $blog_title_input_value ); + $error_mark = '*'; + + $extra_attr = apply_filters( 'wppb_extra_attribute', '', $field, $form_location ); + + $error_class = ''; + $is_error = wppb_check_individual_blog_fields( 'wppb_blog_title', $request_data, $form_location ); + if ($is_error != '') { + $error_mark = ''; + $error_class = ' wppb-field-error'; + } + + $output .= ' +
            • + + ' . + $is_error . '
            • '; + + + + // Privacy + $blog_privacy_input_value = 'Yes'; + $blog_privacy_input_value = ( isset( $request_data['wppb_blog_privacy'] ) ? trim( $request_data['wppb_blog_privacy'] ) : $blog_privacy_input_value ); + $error_mark = '*'; + + $radio_values = array( 'Yes', 'No' ); + + $error_class = ''; + $is_error = wppb_check_individual_blog_fields( 'wppb_blog_privacy', $request_data, $form_location ); + if ($is_error != '') { + $error_mark = ''; + $error_class = ' wppb-field-error'; + } + + $output .= ' +
            • + '; + $output .= '
                '; + foreach( $radio_values as $key => $value){ + $output .= '
              • '. trim( $radio_values[$key] ) .'
              • '; + } + $output .= '
              ' . $is_error . '
            • '; + + // end wppb-blog-details-fields + $output .= '
            '; + + $output .= ''; + + return apply_filters( 'wppb_blog_details_output', $output, $form_location, $field, $user_id, $field_check_errors, $request_data ); + +} +add_filter( 'wppb_output_form_field_default-blog-details', 'wppb_blog_details_handler', 10, 6 ); + +/* handle field save */ +function wppb_create_blog_on_registration( $field, $user_id, $request_data, $form_location ){ + if( $form_location == 'register' && $field['field'] == 'Default - Blog Details' && isset( $request_data['wppb_create_new_site_checkbox'] ) && $request_data['wppb_create_new_site_checkbox'] == 'yes' ) { + $blog_url = $request_data['wppb_blog_url']; + $blog_title = $request_data['wppb_blog_title']; + + $usermeta['public'] = ( isset( $request_data['wppb_blog_privacy'] ) && 'Yes' == $request_data['wppb_blog_privacy'] ) ? true : false; + $blog_details = wpmu_validate_blog_signup( $blog_url, $blog_title ); + if ( empty($blog_details['errors']->errors['blogname']) && empty($blog_details['errors']->errors['blog_title'])) { + wpmu_create_blog( $blog_details['domain'], $blog_details['path'], $blog_details['blog_title'], $user_id, $usermeta ); + } + } +} +add_action( 'wppb_save_form_field', 'wppb_create_blog_on_registration', 10, 4 ); + +/* handle field validation */ +function wppb_check_blog_details_values( $message, $field, $request_data, $form_location ){ + if ( isset( $request_data['wppb_create_new_site_checkbox'] ) && $request_data['wppb_create_new_site_checkbox'] == 'yes' ){ + $blog_fields_array = wppb_blog_details_fields_array(); + foreach ( $blog_fields_array as $blog_field ){ + if( ( isset( $request_data[$blog_field] ) && ( trim( $request_data[$blog_field] ) == '' ) ) || !isset( $request_data[$blog_field] ) ){ + return wppb_required_field_error($blog_field); + } + } + } + return $message; +} +add_filter( 'wppb_check_form_field_default-blog-details', 'wppb_check_blog_details_values', 10, 4 ); + +/* Add blog details information to wp_signups table (when Email Confirmation is active) */ +function wppb_add_blog_details_to_signup_table( $meta, $global_request, $role ){ + if ( isset( $global_request['wppb_create_new_site_checkbox'] ) && $global_request['wppb_create_new_site_checkbox'] == 'yes' ) { + $blog_details_fields_array = wppb_blog_details_fields_array(); + + foreach ($blog_details_fields_array as $blog_field) { + $meta[$blog_field] = $global_request[$blog_field]; + } + } + return $meta; +} +add_filter( 'wppb_add_to_user_signup_form_meta', 'wppb_add_blog_details_to_signup_table',10, 3 ); + + + +function wppb_blog_details_fields_array(){ + return array( + 'wppb_blog_title', + 'wppb_blog_url', + 'wppb_blog_privacy', + 'wppb_create_new_site_checkbox' + ); +} + +function wppb_check_individual_blog_fields( $field_key, $request_data, $form_location ){ + if ( isset( $request_data['wppb_create_new_site_checkbox'] ) && $request_data['wppb_create_new_site_checkbox'] == 'yes' ) { + if ( $field_key == 'wppb_blog_privacy' && ( ! isset( $request_data[$field_key] ) || ( isset( $request_data[$field_key] ) && ( trim( $request_data[$field_key] ) == '' ) ) ) ) { + return '' . wppb_required_field_error($field_key) . ''; + } + + $wp_error = wpmu_validate_blog_signup($request_data['wppb_blog_url'], $request_data['wppb_blog_title']); + + if ( $field_key == 'wppb_blog_url' && !empty($wp_error['errors']->errors['blogname'])){ + return '' . $wp_error['errors']->errors['blogname'][0] . ''; + } + if ( $field_key == 'wppb_blog_title' && !empty($wp_error['errors']->errors['blog_title'])){ + return '' . $wp_error['errors']->errors['blog_title'][0] . ''; + } + + } + return ''; +} + diff --git a/profile-builder/front-end/default-fields/default-fields.php b/profile-builder/front-end/default-fields/default-fields.php index 356919c..f471008 100644 --- a/profile-builder/front-end/default-fields/default-fields.php +++ b/profile-builder/front-end/default-fields/default-fields.php @@ -1,45 +1,45 @@ -*' : '' ); - - if ( array_key_exists( $field['id'], $field_check_errors ) ) - $error_mark = ''; - - $output = ' - - '; - if( !empty( $item_description ) ) - $output .= ''. $item_description .''; - - } - - return apply_filters( 'wppb_'.$form_location.'_description', $output, $form_location, $field, $user_id, $field_check_errors, $request_data ); -} -add_filter( 'wppb_output_form_field_default-biographical-info', 'wppb_description_handler', 10, 6 ); - - -/* handle field validation */ -function wppb_check_description_value( $message, $field, $request_data, $form_location ){ - if( $field['required'] == 'Yes' ){ - if( ( isset( $request_data['description'] ) && ( trim( $request_data['description'] ) == '' ) ) || !isset( $request_data['description'] ) ){ - return wppb_required_field_error($field["field-title"]); - } - } - - return $message; -} -add_filter( 'wppb_check_form_field_default-biographical-info', 'wppb_check_description_value', 10, 4 ); - -/* handle field save */ -function wppb_userdata_add_description( $userdata, $global_request ){ - if ( isset( $global_request['description'] ) ){ - $description = apply_filters( 'pre_user_description', trim ( $global_request['description'] ) ); - $userdata['description'] = $description; - } - return $userdata; -} +*' : '' ); + + if ( array_key_exists( $field['id'], $field_check_errors ) ) + $error_mark = ''; + + $output = ' + + '; + if( !empty( $item_description ) ) + $output .= ''. $item_description .''; + + } + + return apply_filters( 'wppb_'.$form_location.'_description', $output, $form_location, $field, $user_id, $field_check_errors, $request_data ); +} +add_filter( 'wppb_output_form_field_default-biographical-info', 'wppb_description_handler', 10, 6 ); + + +/* handle field validation */ +function wppb_check_description_value( $message, $field, $request_data, $form_location ){ + if( $field['required'] == 'Yes' ){ + if( ( isset( $request_data['description'] ) && ( trim( $request_data['description'] ) == '' ) ) || !isset( $request_data['description'] ) ){ + return wppb_required_field_error($field["field-title"]); + } + } + + return $message; +} +add_filter( 'wppb_check_form_field_default-biographical-info', 'wppb_check_description_value', 10, 4 ); + +/* handle field save */ +function wppb_userdata_add_description( $userdata, $global_request ){ + if ( isset( $global_request['description'] ) ){ + $description = apply_filters( 'pre_user_description', trim ( $global_request['description'] ) ); + $userdata['description'] = $description; + } + return $userdata; +} add_filter( 'wppb_build_userdata', 'wppb_userdata_add_description', 10, 2 ); \ No newline at end of file diff --git a/profile-builder/front-end/default-fields/display-name/display-name.php b/profile-builder/front-end/default-fields/display-name/display-name.php index 721112f..286a7b8 100644 --- a/profile-builder/front-end/default-fields/display-name/display-name.php +++ b/profile-builder/front-end/default-fields/display-name/display-name.php @@ -1,80 +1,80 @@ -*' : '' ); - - if ( array_key_exists( $field['id'], $field_check_errors ) ) - $error_mark = ''; - - /* - * Create the options for the display_name drop-down - * They are created same as in user-edit.php of the WordPress core - */ - $user_data = get_userdata( $user_id ); - $public_display = array(); - $public_display['display_nickname'] = $user_data->nickname; - $public_display['display_username'] = $user_data->user_login; - - if ( !empty($user_data->first_name) ) - $public_display['display_firstname'] = $user_data->first_name; - - if ( !empty($user_data->last_name) ) - $public_display['display_lastname'] = $user_data->last_name; - - if ( !empty($user_data->first_name) && !empty($user_data->last_name) ) { - $public_display['display_firstlast'] = $user_data->first_name . ' ' . $user_data->last_name; - $public_display['display_lastfirst'] = $user_data->last_name . ' ' . $user_data->first_name; - } - - if ( !in_array( $user_data->display_name, $public_display ) ) // Only add this if it isn't duplicated elsewhere - $public_display = array( 'display_displayname' => $user_data->display_name ) + $public_display; - - $public_display = array_map( 'trim', $public_display ); - $public_display = array_unique( $public_display ); - - $output = ''; - $output .= ''; - - if( !empty( $item_description ) ) - $output .= ''. $item_description .''; - - } - - return apply_filters( 'wppb_'.$form_location.'_display-name', $output, $form_location, $field, $user_id, $field_check_errors, $request_data ); -} -add_filter( 'wppb_output_form_field_default-display-name-publicly-as', 'wppb_display_name_handler', 10, 6 ); - - -/* handle field validation */ -function wppb_check_display_name_value( $message, $field, $request_data, $form_location ){ - if( $form_location != 'register' ){ - if ($field['required'] == 'Yes') { - if ((isset($request_data['display_name']) && (trim($request_data['display_name']) == '')) || !isset($request_data['display_name'])) { - return wppb_required_field_error($field["field-title"]); - } - } - } - - return $message; -} -add_filter( 'wppb_check_form_field_default-display-name-publicly-as', 'wppb_check_display_name_value', 10, 4 ); - - -/* handle field save */ -function wppb_userdata_add_display_name( $userdata, $global_request ){ - if ( isset( $global_request['display_name'] ) ) - $userdata['display_name'] = trim( sanitize_text_field( $global_request['display_name'] ) ); - - return $userdata; -} +*' : '' ); + + if ( array_key_exists( $field['id'], $field_check_errors ) ) + $error_mark = ''; + + /* + * Create the options for the display_name drop-down + * They are created same as in user-edit.php of the WordPress core + */ + $user_data = get_userdata( $user_id ); + $public_display = array(); + $public_display['display_nickname'] = $user_data->nickname; + $public_display['display_username'] = $user_data->user_login; + + if ( !empty($user_data->first_name) ) + $public_display['display_firstname'] = $user_data->first_name; + + if ( !empty($user_data->last_name) ) + $public_display['display_lastname'] = $user_data->last_name; + + if ( !empty($user_data->first_name) && !empty($user_data->last_name) ) { + $public_display['display_firstlast'] = $user_data->first_name . ' ' . $user_data->last_name; + $public_display['display_lastfirst'] = $user_data->last_name . ' ' . $user_data->first_name; + } + + if ( !in_array( $user_data->display_name, $public_display ) ) // Only add this if it isn't duplicated elsewhere + $public_display = array( 'display_displayname' => $user_data->display_name ) + $public_display; + + $public_display = array_map( 'trim', $public_display ); + $public_display = array_unique( $public_display ); + + $output = ''; + $output .= ''; + + if( !empty( $item_description ) ) + $output .= ''. $item_description .''; + + } + + return apply_filters( 'wppb_'.$form_location.'_display-name', $output, $form_location, $field, $user_id, $field_check_errors, $request_data ); +} +add_filter( 'wppb_output_form_field_default-display-name-publicly-as', 'wppb_display_name_handler', 10, 6 ); + + +/* handle field validation */ +function wppb_check_display_name_value( $message, $field, $request_data, $form_location ){ + if( $form_location != 'register' ){ + if ($field['required'] == 'Yes') { + if ((isset($request_data['display_name']) && (trim($request_data['display_name']) == '')) || !isset($request_data['display_name'])) { + return wppb_required_field_error($field["field-title"]); + } + } + } + + return $message; +} +add_filter( 'wppb_check_form_field_default-display-name-publicly-as', 'wppb_check_display_name_value', 10, 4 ); + + +/* handle field save */ +function wppb_userdata_add_display_name( $userdata, $global_request ){ + if ( isset( $global_request['display_name'] ) ) + $userdata['display_name'] = trim( sanitize_text_field( $global_request['display_name'] ) ); + + return $userdata; +} add_filter( 'wppb_build_userdata', 'wppb_userdata_add_display_name', 10, 2 ); \ No newline at end of file diff --git a/profile-builder/front-end/default-fields/email/email.php b/profile-builder/front-end/default-fields/email/email.php index 7ac4609..9ce3345 100644 --- a/profile-builder/front-end/default-fields/email/email.php +++ b/profile-builder/front-end/default-fields/email/email.php @@ -1,113 +1,113 @@ -*' : '' ); - - if ( array_key_exists( $field['id'], $field_check_errors ) ) - $error_mark = ''; - - $extra_attr = apply_filters( 'wppb_extra_attribute', '', $field, $form_location ); - - $output = ' - - '; - if( !empty( $item_description ) ) - $output .= ''. $item_description .''; - - } - - return apply_filters( 'wppb_'.$form_location.'_email', $output, $form_location, $field, $user_id, $field_check_errors, $request_data ); -} -add_filter( 'wppb_output_form_field_default-e-mail', 'wppb_email_handler', 10, 6 ); - - -/* handle field validation */ -function wppb_check_email_value( $message, $field, $request_data, $form_location ){ - global $wpdb; - // apply filter to allow stripping slashes if necessary - $request_data['email'] = apply_filters( 'wppb_before_processing_email_from_forms', $request_data['email'] ); - if ( ( isset( $request_data['email'] ) && ( trim( $request_data['email'] ) == '' ) ) && ( $field['required'] == 'Yes' ) ) - return wppb_required_field_error($field["field-title"]); - - if ( isset( $request_data['email'] ) && !is_email( trim( $request_data['email'] ) ) ){ - return __( 'The email you entered is not a valid email address.', 'profile-builder' ); - } - - if ( empty( $request_data['email'] ) ) { - return __( 'You must enter a valid email address.', 'profile-builder' ); - } - - $wppb_generalSettings = get_option( 'wppb_general_settings' ); - if ( isset( $wppb_generalSettings['emailConfirmation'] ) && ( $wppb_generalSettings['emailConfirmation'] == 'yes' ) ){ - $user_signup = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM ".$wpdb->base_prefix."signups WHERE user_email = %s AND active=0", $request_data['email'] ) ); - - if ( !empty( $user_signup ) ){ - if ( $form_location == 'register' ){ - return __( 'This email is already reserved to be used soon.', 'profile-builder' ) .'
            '. __( 'Please try a different one!', 'profile-builder' ); - } - else if ( $form_location == 'edit_profile' ){ - $current_user = wp_get_current_user(); - - if( ! current_user_can( 'edit_users' ) ) { - if ( $current_user->user_email != $request_data['email'] ) - return __( 'This email is already reserved to be used soon.', 'profile-builder' ) .'
            '. __( 'Please try a different one!', 'profile-builder' ); - } - } - } - } - - $users = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->users} WHERE user_email = %s", $request_data['email'] ) ); - - if ( !empty( $users ) ){ - if ( $form_location == 'register' ) - return __( 'This email is already in use.', 'profile-builder' ) .'
            '. __( 'Please try a different one!', 'profile-builder' ); - - if ( $form_location == 'edit_profile' ){ - $url_parts = parse_url( $_SERVER['HTTP_REFERER'] ); - if( isset( $url_parts['query'] ) ) { - parse_str( $url_parts['query'], $query ); - } - - if( isset( $_GET['edit_user'] ) && ! empty( $_GET['edit_user'] ) ) { - $current_user_id = absint( $_GET['edit_user'] ); - } elseif( defined( 'DOING_AJAX' ) && DOING_AJAX && isset( $query['edit_user'] ) && ! empty( $query['edit_user'] ) ) { - $current_user_id = $query['edit_user']; - } else { - $current_user = wp_get_current_user(); - $current_user_id = $current_user->ID; - } - foreach ( $users as $user ) - if ( $user->ID != $current_user_id ) - return __( 'This email is already in use.', 'profile-builder' ) .'
            '. __( 'Please try a different one!', 'profile-builder' ); - } - } - - return $message; -} -add_filter( 'wppb_check_form_field_default-e-mail', 'wppb_check_email_value', 10, 4 ); - -/* handle field save */ -function wppb_userdata_add_email( $userdata, $global_request ){ - // apply filter to allow stripping slashes if necessary - if ( isset( $global_request['email'] ) ) { - $global_request['email'] = apply_filters( 'wppb_before_processing_email_from_forms', $global_request['email'] ); - $userdata['user_email'] = sanitize_text_field( trim( $global_request['email'] ) ); - } - - return $userdata; -} +*' : '' ); + + if ( array_key_exists( $field['id'], $field_check_errors ) ) + $error_mark = ''; + + $extra_attr = apply_filters( 'wppb_extra_attribute', '', $field, $form_location ); + + $output = ' + + '; + if( !empty( $item_description ) ) + $output .= ''. $item_description .''; + + } + + return apply_filters( 'wppb_'.$form_location.'_email', $output, $form_location, $field, $user_id, $field_check_errors, $request_data ); +} +add_filter( 'wppb_output_form_field_default-e-mail', 'wppb_email_handler', 10, 6 ); + + +/* handle field validation */ +function wppb_check_email_value( $message, $field, $request_data, $form_location ){ + global $wpdb; + // apply filter to allow stripping slashes if necessary + $request_data['email'] = apply_filters( 'wppb_before_processing_email_from_forms', $request_data['email'] ); + if ( ( isset( $request_data['email'] ) && ( trim( $request_data['email'] ) == '' ) ) && ( $field['required'] == 'Yes' ) ) + return wppb_required_field_error($field["field-title"]); + + if ( isset( $request_data['email'] ) && !is_email( trim( $request_data['email'] ) ) ){ + return __( 'The email you entered is not a valid email address.', 'profile-builder' ); + } + + if ( empty( $request_data['email'] ) ) { + return __( 'You must enter a valid email address.', 'profile-builder' ); + } + + $wppb_generalSettings = get_option( 'wppb_general_settings' ); + if ( isset( $wppb_generalSettings['emailConfirmation'] ) && ( $wppb_generalSettings['emailConfirmation'] == 'yes' ) ){ + $user_signup = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM ".$wpdb->base_prefix."signups WHERE user_email = %s AND active=0", $request_data['email'] ) ); + + if ( !empty( $user_signup ) ){ + if ( $form_location == 'register' ){ + return __( 'This email is already reserved to be used soon.', 'profile-builder' ) .'
            '. __( 'Please try a different one!', 'profile-builder' ); + } + else if ( $form_location == 'edit_profile' ){ + $current_user = wp_get_current_user(); + + if( ! current_user_can( 'edit_users' ) ) { + if ( $current_user->user_email != $request_data['email'] ) + return __( 'This email is already reserved to be used soon.', 'profile-builder' ) .'
            '. __( 'Please try a different one!', 'profile-builder' ); + } + } + } + } + + $users = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->users} WHERE user_email = %s", $request_data['email'] ) ); + + if ( !empty( $users ) ){ + if ( $form_location == 'register' ) + return __( 'This email is already in use.', 'profile-builder' ) .'
            '. __( 'Please try a different one!', 'profile-builder' ); + + if ( $form_location == 'edit_profile' ){ + $url_parts = parse_url( $_SERVER['HTTP_REFERER'] ); + if( isset( $url_parts['query'] ) ) { + parse_str( $url_parts['query'], $query ); + } + + if( isset( $_GET['edit_user'] ) && ! empty( $_GET['edit_user'] ) ) { + $current_user_id = absint( $_GET['edit_user'] ); + } elseif( defined( 'DOING_AJAX' ) && DOING_AJAX && isset( $query['edit_user'] ) && ! empty( $query['edit_user'] ) ) { + $current_user_id = $query['edit_user']; + } else { + $current_user = wp_get_current_user(); + $current_user_id = $current_user->ID; + } + foreach ( $users as $user ) + if ( $user->ID != $current_user_id ) + return __( 'This email is already in use.', 'profile-builder' ) .'
            '. __( 'Please try a different one!', 'profile-builder' ); + } + } + + return $message; +} +add_filter( 'wppb_check_form_field_default-e-mail', 'wppb_check_email_value', 10, 4 ); + +/* handle field save */ +function wppb_userdata_add_email( $userdata, $global_request ){ + // apply filter to allow stripping slashes if necessary + if ( isset( $global_request['email'] ) ) { + $global_request['email'] = apply_filters( 'wppb_before_processing_email_from_forms', $global_request['email'] ); + $userdata['user_email'] = sanitize_text_field( trim( $global_request['email'] ) ); + } + + return $userdata; +} add_filter( 'wppb_build_userdata', 'wppb_userdata_add_email', 10, 2 ); \ No newline at end of file diff --git a/profile-builder/front-end/default-fields/first-name/first-name.php b/profile-builder/front-end/default-fields/first-name/first-name.php index 667c0cb..859beb5 100644 --- a/profile-builder/front-end/default-fields/first-name/first-name.php +++ b/profile-builder/front-end/default-fields/first-name/first-name.php @@ -1,56 +1,56 @@ -*' : '' ); - - if ( array_key_exists( $field['id'], $field_check_errors ) ) - $error_mark = ''; - - $extra_attr = apply_filters( 'wppb_extra_attribute', '', $field, $form_location ); - - $output = ' - - '; - if( !empty( $item_description ) ) - $output .= ''. $item_description .''; - - } - - return apply_filters( 'wppb_'.$form_location.'_firstname', $output, $form_location, $field, $user_id, $field_check_errors, $request_data ); -} -add_filter( 'wppb_output_form_field_default-first-name', 'wppb_first_name_handler', 10, 6 ); - - -/* handle field validation */ -function wppb_check_first_name_value( $message, $field, $request_data, $form_location ){ - if( $field['required'] == 'Yes' ){ - if( ( isset( $request_data['first_name'] ) && ( trim( $request_data['first_name'] ) == '' ) ) || !isset( $request_data['first_name'] ) ){ - return wppb_required_field_error($field["field-title"]); - } - } - - return $message; -} -add_filter( 'wppb_check_form_field_default-first-name', 'wppb_check_first_name_value', 10, 4 ); - - -/* handle field save */ -function wppb_userdata_add_first_name( $userdata, $global_request ){ - if ( isset( $global_request['first_name'] ) ) - $userdata['first_name'] = sanitize_text_field( trim( $global_request['first_name'] ) ); - - return $userdata; -} +*' : '' ); + + if ( array_key_exists( $field['id'], $field_check_errors ) ) + $error_mark = ''; + + $extra_attr = apply_filters( 'wppb_extra_attribute', '', $field, $form_location ); + + $output = ' + + '; + if( !empty( $item_description ) ) + $output .= ''. $item_description .''; + + } + + return apply_filters( 'wppb_'.$form_location.'_firstname', $output, $form_location, $field, $user_id, $field_check_errors, $request_data ); +} +add_filter( 'wppb_output_form_field_default-first-name', 'wppb_first_name_handler', 10, 6 ); + + +/* handle field validation */ +function wppb_check_first_name_value( $message, $field, $request_data, $form_location ){ + if( $field['required'] == 'Yes' ){ + if( ( isset( $request_data['first_name'] ) && ( trim( $request_data['first_name'] ) == '' ) ) || !isset( $request_data['first_name'] ) ){ + return wppb_required_field_error($field["field-title"]); + } + } + + return $message; +} +add_filter( 'wppb_check_form_field_default-first-name', 'wppb_check_first_name_value', 10, 4 ); + + +/* handle field save */ +function wppb_userdata_add_first_name( $userdata, $global_request ){ + if ( isset( $global_request['first_name'] ) ) + $userdata['first_name'] = sanitize_text_field( trim( $global_request['first_name'] ) ); + + return $userdata; +} add_filter( 'wppb_build_userdata', 'wppb_userdata_add_first_name', 10, 2 ); \ No newline at end of file diff --git a/profile-builder/front-end/default-fields/headings/about-yourself.php b/profile-builder/front-end/default-fields/headings/about-yourself.php index e89fff1..26c28e1 100644 --- a/profile-builder/front-end/default-fields/headings/about-yourself.php +++ b/profile-builder/front-end/default-fields/headings/about-yourself.php @@ -1,12 +1,12 @@ -'.$item_title.''.$item_description.''; - - return apply_filters( 'wppb_'.$form_location.'_default_heading_about_yourself_'.$field['id'], $output, $form_location, $field, $user_id, $field_check_errors, $request_data ); - } -} +'.$item_title.''.$item_description.''; + + return apply_filters( 'wppb_'.$form_location.'_default_heading_about_yourself_'.$field['id'], $output, $form_location, $field, $user_id, $field_check_errors, $request_data ); + } +} add_filter( 'wppb_output_form_field_default-about-yourself-heading', 'wppb_default_about_yourself_handler', 10, 6 ); \ No newline at end of file diff --git a/profile-builder/front-end/default-fields/headings/contact-info.php b/profile-builder/front-end/default-fields/headings/contact-info.php index 63c4a58..ad35fde 100644 --- a/profile-builder/front-end/default-fields/headings/contact-info.php +++ b/profile-builder/front-end/default-fields/headings/contact-info.php @@ -1,12 +1,12 @@ -'.$item_title.''.$item_description.''; - - return apply_filters( 'wppb_'.$form_location.'_default_heading_contact_info_'.$field['id'], $ret_custom_field, $form_location, $field, $user_id, $field_check_errors, $request_data ); - } -} -add_filter( 'wppb_output_form_field_default-contact-info-heading', 'wppb_default_contact_info_handler', 10, 6 ); +'.$item_title.''.$item_description.''; + + return apply_filters( 'wppb_'.$form_location.'_default_heading_contact_info_'.$field['id'], $ret_custom_field, $form_location, $field, $user_id, $field_check_errors, $request_data ); + } +} +add_filter( 'wppb_output_form_field_default-contact-info-heading', 'wppb_default_contact_info_handler', 10, 6 ); diff --git a/profile-builder/front-end/default-fields/headings/name.php b/profile-builder/front-end/default-fields/headings/name.php index db39a54..2b3fc85 100644 --- a/profile-builder/front-end/default-fields/headings/name.php +++ b/profile-builder/front-end/default-fields/headings/name.php @@ -1,12 +1,12 @@ -'.$item_title.''.$item_description.''; - - return apply_filters( 'wppb_'.$form_location.'_default_heading_name_'.$field['id'], $ret_custom_field, $form_location, $field, $user_id, $field_check_errors, $request_data ); - } -} +'.$item_title.''.$item_description.''; + + return apply_filters( 'wppb_'.$form_location.'_default_heading_name_'.$field['id'], $ret_custom_field, $form_location, $field, $user_id, $field_check_errors, $request_data ); + } +} add_filter( 'wppb_output_form_field_default-name-heading', 'wppb_default_name_handler', 10, 6 ); \ No newline at end of file diff --git a/profile-builder/front-end/default-fields/jabber/jabber.php b/profile-builder/front-end/default-fields/jabber/jabber.php index bc5842f..bfab24d 100644 --- a/profile-builder/front-end/default-fields/jabber/jabber.php +++ b/profile-builder/front-end/default-fields/jabber/jabber.php @@ -1,55 +1,55 @@ -*' : '' ); - - if ( array_key_exists( $field['id'], $field_check_errors ) ) - $error_mark = ''; - - $extra_attr = apply_filters( 'wppb_extra_attribute', '', $field, $form_location ); - - $output = ' - - '; - if( !empty( $item_description ) ) - $output .= ''. $item_description .''; - - } - - return apply_filters( 'wppb_'.$form_location.'_jabber', $output, $form_location, $field, $user_id, $field_check_errors, $request_data ); -} -add_filter( 'wppb_output_form_field_default-jabber-google-talk', 'wppb_jabber_handler', 10, 6 ); - - -/* handle field validation */ -function wppb_check_jabber_value( $message, $field, $request_data, $form_location ){ - if( $field['required'] == 'Yes' ){ - if( ( isset( $request_data['jabber'] ) && ( trim( $request_data['jabber'] ) == '' ) ) || !isset( $request_data['jabber'] ) ){ - return wppb_required_field_error($field["field-title"]); - } - } - - return $message; -} -add_filter( 'wppb_check_form_field_default-jabber-google-talk', 'wppb_check_jabber_value', 10, 4 ); - -/* handle field save */ -function wppb_userdata_add_jabber( $userdata, $global_request ){ - if ( isset( $global_request['jabber'] ) ) - $userdata['jabber'] = sanitize_text_field( trim( $global_request['jabber'] ) ); - - return $userdata; -} +*' : '' ); + + if ( array_key_exists( $field['id'], $field_check_errors ) ) + $error_mark = ''; + + $extra_attr = apply_filters( 'wppb_extra_attribute', '', $field, $form_location ); + + $output = ' + + '; + if( !empty( $item_description ) ) + $output .= ''. $item_description .''; + + } + + return apply_filters( 'wppb_'.$form_location.'_jabber', $output, $form_location, $field, $user_id, $field_check_errors, $request_data ); +} +add_filter( 'wppb_output_form_field_default-jabber-google-talk', 'wppb_jabber_handler', 10, 6 ); + + +/* handle field validation */ +function wppb_check_jabber_value( $message, $field, $request_data, $form_location ){ + if( $field['required'] == 'Yes' ){ + if( ( isset( $request_data['jabber'] ) && ( trim( $request_data['jabber'] ) == '' ) ) || !isset( $request_data['jabber'] ) ){ + return wppb_required_field_error($field["field-title"]); + } + } + + return $message; +} +add_filter( 'wppb_check_form_field_default-jabber-google-talk', 'wppb_check_jabber_value', 10, 4 ); + +/* handle field save */ +function wppb_userdata_add_jabber( $userdata, $global_request ){ + if ( isset( $global_request['jabber'] ) ) + $userdata['jabber'] = sanitize_text_field( trim( $global_request['jabber'] ) ); + + return $userdata; +} add_filter( 'wppb_build_userdata', 'wppb_userdata_add_jabber', 10, 2 ); \ No newline at end of file diff --git a/profile-builder/front-end/default-fields/last-name/last-name.php b/profile-builder/front-end/default-fields/last-name/last-name.php index c562abb..b1b2d40 100644 --- a/profile-builder/front-end/default-fields/last-name/last-name.php +++ b/profile-builder/front-end/default-fields/last-name/last-name.php @@ -1,55 +1,55 @@ -*' : '' ); - - if ( array_key_exists( $field['id'], $field_check_errors ) ) - $error_mark = ''; - - $extra_attr = apply_filters( 'wppb_extra_attribute', '', $field, $form_location ); - - $output = ' - - '; - if( !empty( $item_description ) ) - $output .= ''. $item_description .''; - } - - return apply_filters( 'wppb_'.$form_location.'_lastname', $output, $form_location, $field, $user_id, $field_check_errors, $request_data ); -} -add_filter( 'wppb_output_form_field_default-last-name', 'wppb_last_name_handler', 10, 6 ); - - -/* handle field validation */ -function wppb_check_last_name_value( $message, $field, $request_data, $form_location ){ - if( $field['required'] == 'Yes' ){ - if( ( isset( $request_data['last_name'] ) && ( trim( $request_data['last_name'] ) == '' ) ) || !isset( $request_data['last_name'] ) ){ - return wppb_required_field_error($field["field-title"]); - } - } - - return $message; -} -add_filter( 'wppb_check_form_field_default-last-name', 'wppb_check_last_name_value', 10, 4 ); - - -/* handle field save */ -function wppb_userdata_add_last_name( $userdata, $global_request ){ - if ( isset( $global_request['last_name'] ) ) - $userdata['last_name'] = sanitize_text_field( trim( $global_request['last_name'] ) ); - - return $userdata; -} +*' : '' ); + + if ( array_key_exists( $field['id'], $field_check_errors ) ) + $error_mark = ''; + + $extra_attr = apply_filters( 'wppb_extra_attribute', '', $field, $form_location ); + + $output = ' + + '; + if( !empty( $item_description ) ) + $output .= ''. $item_description .''; + } + + return apply_filters( 'wppb_'.$form_location.'_lastname', $output, $form_location, $field, $user_id, $field_check_errors, $request_data ); +} +add_filter( 'wppb_output_form_field_default-last-name', 'wppb_last_name_handler', 10, 6 ); + + +/* handle field validation */ +function wppb_check_last_name_value( $message, $field, $request_data, $form_location ){ + if( $field['required'] == 'Yes' ){ + if( ( isset( $request_data['last_name'] ) && ( trim( $request_data['last_name'] ) == '' ) ) || !isset( $request_data['last_name'] ) ){ + return wppb_required_field_error($field["field-title"]); + } + } + + return $message; +} +add_filter( 'wppb_check_form_field_default-last-name', 'wppb_check_last_name_value', 10, 4 ); + + +/* handle field save */ +function wppb_userdata_add_last_name( $userdata, $global_request ){ + if ( isset( $global_request['last_name'] ) ) + $userdata['last_name'] = sanitize_text_field( trim( $global_request['last_name'] ) ); + + return $userdata; +} add_filter( 'wppb_build_userdata', 'wppb_userdata_add_last_name', 10, 2 ); \ No newline at end of file diff --git a/profile-builder/front-end/default-fields/nickname/nickname.php b/profile-builder/front-end/default-fields/nickname/nickname.php index 83531a9..9530e9e 100644 --- a/profile-builder/front-end/default-fields/nickname/nickname.php +++ b/profile-builder/front-end/default-fields/nickname/nickname.php @@ -1,54 +1,54 @@ -*' : '' ); - - if ( array_key_exists( $field['id'], $field_check_errors ) ) - $error_mark = ''; - - $extra_attr = apply_filters( 'wppb_extra_attribute', '', $field, $form_location ); - - $output = ' - - '; - if( !empty( $item_description ) ) - $output .= ''. $item_description .''; - - return apply_filters( 'wppb_'.$form_location.'_nickname', $output, $form_location, $field, $user_id, $field_check_errors, $request_data ); - } -} -add_filter( 'wppb_output_form_field_default-nickname', 'wppb_nickname_handler', 10, 6 ); - - -/* handle field validation */ -function wppb_check_nickname_value( $message, $field, $request_data, $form_location ){ - if( $field['required'] == 'Yes' ){ - if( ( isset( $request_data['nickname'] ) && ( trim( $request_data['nickname'] ) == '' ) ) || !isset( $request_data['nickname'] ) ){ - return wppb_required_field_error($field["field-title"]); - } - } - - return $message; -} -add_filter( 'wppb_check_form_field_default-nickname', 'wppb_check_nickname_value', 10, 4 ); - -/* handle field save */ -function wppb_userdata_add_nickname( $userdata, $global_request ){ - if ( isset( $global_request['nickname'] ) ) - $userdata['nickname'] = sanitize_text_field( trim( $global_request['nickname'] ) ); - - return $userdata; -} +*' : '' ); + + if ( array_key_exists( $field['id'], $field_check_errors ) ) + $error_mark = ''; + + $extra_attr = apply_filters( 'wppb_extra_attribute', '', $field, $form_location ); + + $output = ' + + '; + if( !empty( $item_description ) ) + $output .= ''. $item_description .''; + + return apply_filters( 'wppb_'.$form_location.'_nickname', $output, $form_location, $field, $user_id, $field_check_errors, $request_data ); + } +} +add_filter( 'wppb_output_form_field_default-nickname', 'wppb_nickname_handler', 10, 6 ); + + +/* handle field validation */ +function wppb_check_nickname_value( $message, $field, $request_data, $form_location ){ + if( $field['required'] == 'Yes' ){ + if( ( isset( $request_data['nickname'] ) && ( trim( $request_data['nickname'] ) == '' ) ) || !isset( $request_data['nickname'] ) ){ + return wppb_required_field_error($field["field-title"]); + } + } + + return $message; +} +add_filter( 'wppb_check_form_field_default-nickname', 'wppb_check_nickname_value', 10, 4 ); + +/* handle field save */ +function wppb_userdata_add_nickname( $userdata, $global_request ){ + if ( isset( $global_request['nickname'] ) ) + $userdata['nickname'] = sanitize_text_field( trim( $global_request['nickname'] ) ); + + return $userdata; +} add_filter( 'wppb_build_userdata', 'wppb_userdata_add_nickname', 10, 2 ); \ No newline at end of file diff --git a/profile-builder/front-end/default-fields/password-repeat/password-repeat.php b/profile-builder/front-end/default-fields/password-repeat/password-repeat.php index 6ba1778..1455318 100644 --- a/profile-builder/front-end/default-fields/password-repeat/password-repeat.php +++ b/profile-builder/front-end/default-fields/password-repeat/password-repeat.php @@ -1,46 +1,46 @@ -*' : '' ); - - if ( array_key_exists( $field['id'], $field_check_errors ) ) - $error_mark = ''; - - $extra_attr = apply_filters( 'wppb_extra_attribute', '', $field, $form_location ); - - $output = ' - - '; - if( !empty( $item_description ) ) - $output .= ''.$item_description.''; - } - - return apply_filters( 'wppb_'.$form_location.'_repeat_password', $output, $form_location, $field, $user_id, $field_check_errors, $request_data ); -} -add_filter( 'wppb_output_form_field_default-repeat-password', 'wppb_password_repeat_handler', 10, 6 ); - - -/* handle field validation */ -function wppb_check_repeat_password_value( $message, $field, $request_data, $form_location ){ - if ( $form_location == 'register' ){ - if ( ( isset( $request_data['passw2'] ) && ( trim( $request_data['passw2'] ) == '' ) ) && ( $field['required'] == 'Yes' ) ) - return wppb_required_field_error($field["field-title"]); - - elseif ( !isset( $request_data['passw2'] ) && ( $field['required'] == 'Yes' ) ) - return wppb_required_field_error($field["field-title"]); - - elseif ( isset( $request_data['passw1'] ) && isset( $request_data['passw2'] ) && ( trim( $request_data['passw1'] ) != trim( $request_data['passw2'] ) ) && ( $field['required'] == 'Yes' ) ) - return __( "The passwords do not match", "profile-builder" ); - - }elseif ( $form_location == 'edit_profile' ){ - if ( isset( $request_data['passw1'] ) && isset( $request_data['passw2'] ) && ( trim( $request_data['passw1'] ) != trim( $request_data['passw2'] ) ) ) - return __( "The passwords do not match", "profile-builder" ); - } - - return $message; -} +*' : '' ); + + if ( array_key_exists( $field['id'], $field_check_errors ) ) + $error_mark = ''; + + $extra_attr = apply_filters( 'wppb_extra_attribute', '', $field, $form_location ); + + $output = ' + + '; + if( !empty( $item_description ) ) + $output .= ''.$item_description.''; + } + + return apply_filters( 'wppb_'.$form_location.'_repeat_password', $output, $form_location, $field, $user_id, $field_check_errors, $request_data ); +} +add_filter( 'wppb_output_form_field_default-repeat-password', 'wppb_password_repeat_handler', 10, 6 ); + + +/* handle field validation */ +function wppb_check_repeat_password_value( $message, $field, $request_data, $form_location ){ + if ( $form_location == 'register' ){ + if ( ( isset( $request_data['passw2'] ) && ( trim( $request_data['passw2'] ) == '' ) ) && ( $field['required'] == 'Yes' ) ) + return wppb_required_field_error($field["field-title"]); + + elseif ( !isset( $request_data['passw2'] ) && ( $field['required'] == 'Yes' ) ) + return wppb_required_field_error($field["field-title"]); + + elseif ( isset( $request_data['passw1'] ) && isset( $request_data['passw2'] ) && ( trim( $request_data['passw1'] ) != trim( $request_data['passw2'] ) ) && ( $field['required'] == 'Yes' ) ) + return __( "The passwords do not match", "profile-builder" ); + + }elseif ( $form_location == 'edit_profile' ){ + if ( isset( $request_data['passw1'] ) && isset( $request_data['passw2'] ) && ( trim( $request_data['passw1'] ) != trim( $request_data['passw2'] ) ) ) + return __( "The passwords do not match", "profile-builder" ); + } + + return $message; +} add_filter( 'wppb_check_form_field_default-repeat-password', 'wppb_check_repeat_password_value', 10, 4 ); \ No newline at end of file diff --git a/profile-builder/front-end/default-fields/password/password.php b/profile-builder/front-end/default-fields/password/password.php index 389ec68..885df0b 100644 --- a/profile-builder/front-end/default-fields/password/password.php +++ b/profile-builder/front-end/default-fields/password/password.php @@ -1,65 +1,65 @@ -*' : '' ); - - if ( array_key_exists( $field['id'], $field_check_errors ) ) - $error_mark = ''; - - $extra_attr = apply_filters( 'wppb_extra_attribute', '', $field, $form_location ); - - $output = ' - - '; - if( !empty( $item_description ) ) - $output .= ''.$item_description.' '.wppb_password_length_text().''; - else - $output .= ''.wppb_password_length_text().''; - - /* if we have active the password strength checker */ - $output .= wppb_password_strength_checker_html(); - - } - - return apply_filters( 'wppb_'.$form_location.'_password', $output, $form_location, $field, $user_id, $field_check_errors, $request_data ); -} -add_filter( 'wppb_output_form_field_default-password', 'wppb_password_handler', 10, 6 ); - -/* handle field validation */ -function wppb_check_password_value( $message, $field, $request_data, $form_location ){ - if ( $form_location == 'register' ){ - if ( ( isset( $request_data['passw1'] ) && ( trim( $request_data['passw1'] ) == '' ) ) && ( $field['required'] == 'Yes' ) ) - return wppb_required_field_error($field["field-title"]); - - elseif ( !isset( $request_data['passw1'] ) && ( $field['required'] == 'Yes' ) ) - return wppb_required_field_error($field["field-title"]); - } - - if ( trim( $request_data['passw1'] ) != '' ){ - $wppb_generalSettings = get_option( 'wppb_general_settings' ); - - if( wppb_check_password_length( $request_data['passw1'] ) ) - return '
            '. sprintf( __( "The password must have the minimum length of %s characters", "profile-builder" ), $wppb_generalSettings['minimum_password_length'] ); - - - if( wppb_check_password_strength() ){ - return '
            ' . sprintf( __( "The password must have a minimum strength of %s", "profile-builder" ), wppb_check_password_strength() ); - } - } - - return $message; -} -add_filter( 'wppb_check_form_field_default-password', 'wppb_check_password_value', 10, 4 ); - -/* handle field save */ -function wppb_userdata_add_password( $userdata, $global_request ){ - if ( isset( $global_request['passw1'] ) && ( trim( $global_request['passw1'] ) != '' ) ) - $userdata['user_pass'] = trim( $global_request['passw1'] ); - - return $userdata; -} +*' : '' ); + + if ( array_key_exists( $field['id'], $field_check_errors ) ) + $error_mark = ''; + + $extra_attr = apply_filters( 'wppb_extra_attribute', '', $field, $form_location ); + + $output = ' + + '; + if( !empty( $item_description ) ) + $output .= ''.$item_description.' '.wppb_password_length_text().''; + else + $output .= ''.wppb_password_length_text().''; + + /* if we have active the password strength checker */ + $output .= wppb_password_strength_checker_html(); + + } + + return apply_filters( 'wppb_'.$form_location.'_password', $output, $form_location, $field, $user_id, $field_check_errors, $request_data ); +} +add_filter( 'wppb_output_form_field_default-password', 'wppb_password_handler', 10, 6 ); + +/* handle field validation */ +function wppb_check_password_value( $message, $field, $request_data, $form_location ){ + if ( $form_location == 'register' ){ + if ( ( isset( $request_data['passw1'] ) && ( trim( $request_data['passw1'] ) == '' ) ) && ( $field['required'] == 'Yes' ) ) + return wppb_required_field_error($field["field-title"]); + + elseif ( !isset( $request_data['passw1'] ) && ( $field['required'] == 'Yes' ) ) + return wppb_required_field_error($field["field-title"]); + } + + if ( trim( $request_data['passw1'] ) != '' ){ + $wppb_generalSettings = get_option( 'wppb_general_settings' ); + + if( wppb_check_password_length( $request_data['passw1'] ) ) + return '
            '. sprintf( __( "The password must have the minimum length of %s characters", "profile-builder" ), $wppb_generalSettings['minimum_password_length'] ); + + + if( wppb_check_password_strength() ){ + return '
            ' . sprintf( __( "The password must have a minimum strength of %s", "profile-builder" ), wppb_check_password_strength() ); + } + } + + return $message; +} +add_filter( 'wppb_check_form_field_default-password', 'wppb_check_password_value', 10, 4 ); + +/* handle field save */ +function wppb_userdata_add_password( $userdata, $global_request ){ + if ( isset( $global_request['passw1'] ) && ( trim( $global_request['passw1'] ) != '' ) ) + $userdata['user_pass'] = trim( $global_request['passw1'] ); + + return $userdata; +} add_filter( 'wppb_build_userdata', 'wppb_userdata_add_password', 10, 2 ); \ No newline at end of file diff --git a/profile-builder/front-end/default-fields/recaptcha/recaptcha.php b/profile-builder/front-end/default-fields/recaptcha/recaptcha.php index 566ac14..c000363 100644 --- a/profile-builder/front-end/default-fields/recaptcha/recaptcha.php +++ b/profile-builder/front-end/default-fields/recaptcha/recaptcha.php @@ -1,478 +1,478 @@ - $value) { - $req .= $key . '=' . urlencode(stripslashes($value)) . '&'; - } - // Cut the last '&' - $req=substr($req, 0, strlen($req)-1); - return $req; -} - - - -/** - * Submits an HTTP GET to a reCAPTCHA server - * @param string $path - * @param array $data - */ -function _wppb_submitHTTPGet($path, $data) -{ - $req = _wppb_encodeQS($data); - $response = wp_remote_get($path . $req); - - if ( ! is_wp_error( $response )) - return $response["body"]; -} - -/** - * Gets the challenge HTML (javascript and non-javascript version). - * This is called from the browser, and the resulting reCAPTCHA HTML widget - * is embedded within the HTML form it was called from. - * @param string $pubkey A public key for reCAPTCHA - * @param string $error The error given by reCAPTCHA (optional, default is null) - * @param boolean $use_ssl Should the request be made over ssl? (optional, default is false) - - * @return string - The HTML to be embedded in the user's form. - */ -function wppb_recaptcha_get_html ( $pubkey, $form_name='' ){ - global $wppb_recaptcha_forms; // will contain the name of all PB forms containing reCAPTCHA which are loaded on a certain page - - if ( empty($pubkey) ) - echo $errorMessage = ''. __("To use reCAPTCHA you must get an API key from", "profile-builder"). " https://www.google.com/recaptcha/admin/create

            "; - - // we add this number to the form name to differentiate between 2 different forms of the same type (e.g. PB Login widget + PB Login page form) which both have reCAPTCHA - $length = strval(strlen($wppb_recaptcha_forms)); - - if ($form_name != '') { - if ($wppb_recaptcha_forms != '') $wppb_recaptcha_forms .= ','.trim($form_name).$length; - else $wppb_recaptcha_forms = trim($form_name).$length; - - // reCAPTCHA html for PB forms - return ' -
            - '; - } - else { //reCAPTCHA html and scripts for default WP forms (backend) - return ' - -
            - '; - } - -} - -// For PB forms (not default WP ones) containing reCAPTCHA we'll make sure to add the script in the page's header and footer, in order to allow multiple reCAPTCHAs on the same page. -function wppb_recaptcha_script_header() { - global $wppb_recaptcha_forms; - //initialize the $wppb_recaptcha_forms global var - $wppb_recaptcha_forms = ''; -} -add_action('wp_head', 'wppb_recaptcha_script_header'); - - - -function wppb_recaptcha_script_footer(){ - global $wppb_recaptcha_forms; - if( !empty( $wppb_recaptcha_forms ) ) { - echo ''; - - $forms = explode(',',$wppb_recaptcha_forms); - - $field = wppb_get_recaptcha_field(); - - $pubkey = ''; - if( isset( $field['public-key'] ) ) { - $pubkey = trim( $field['public-key'] ); - } - - echo ''; - } -} -add_action('wp_footer','wppb_recaptcha_script_footer'); - - - -/** - * A wppb_ReCaptchaResponse is returned from wppb_recaptcha_check_answer() - */ -class wppb_ReCaptchaResponse { - var $is_valid; -} - - -/** - * Calls an HTTP POST function to verify if the user's answer was correct - * @param string $privkey - * @param string $remoteip - * @param string $response - * @return wppb_ReCaptchaResponse - */ -function wppb_recaptcha_check_answer ( $privkey, $remoteip, $response ){ - - if ( $remoteip == null || $remoteip == '' ) - echo ''. __("For security reasons, you must pass the remote ip to reCAPTCHA!", "profile-builder") .'

            '; - - // Discard empty solution submissions - if ($response == null || strlen($response) == 0) { - $recaptchaResponse = new wppb_ReCaptchaResponse(); - $recaptchaResponse->is_valid = false; - - return $recaptchaResponse; - } - $getResponse = _wppb_submitHTTPGet( - "https://www.google.com/recaptcha/api/siteverify?", - array ( - 'secret' => $privkey, - 'remoteip' => $remoteip, - 'response' => $response - ) - ); - - $answers = json_decode($getResponse, true); - $recaptchaResponse = new wppb_ReCaptchaResponse(); - if (trim($answers ['success']) == true) { - $recaptchaResponse->is_valid = true; - } else { - $recaptchaResponse->is_valid = false; - } - return $recaptchaResponse; - -} - -/* the function to display error message on the registration page */ -function wppb_validate_captcha_response( $publickey, $privatekey ){ - if (isset($_POST['g-recaptcha-response'])){ - $recaptcha_response_field = $_POST['g-recaptcha-response']; - } - else { - $recaptcha_response_field = ''; - } - - $resp = wppb_recaptcha_check_answer($privatekey, $_SERVER["REMOTE_ADDR"], $recaptcha_response_field ); - - if ( !empty( $_POST ) ) - return ( ( !$resp->is_valid ) ? false : true ); -} - -/* the function to add reCAPTCHA to the registration form of PB */ -function wppb_recaptcha_handler ( $output, $form_location, $field, $user_id, $field_check_errors, $request_data ){ - if ( $field['field'] == 'reCAPTCHA' ){ - $item_title = apply_filters( 'wppb_'.$form_location.'_recaptcha_custom_field_'.$field['id'].'_item_title', wppb_icl_t( 'plugin profile-builder-pro', 'custom_field_'.$field['id'].'_title_translation', $field['field-title'] ) ); - $item_description = wppb_icl_t( 'plugin profile-builder-pro', 'custom_field_'.$field['id'].'_description_translation', $field['description'] ); - - wppb_recaptcha_set_default_values(); - if ( ($form_location == 'register') && ( isset($field['captcha-pb-forms']) ) && (strpos($field['captcha-pb-forms'],'pb_register') !== false) ) { - $error_mark = ( ( $field['required'] == 'Yes' ) ? '*' : '' ); - - if ( array_key_exists( $field['id'], $field_check_errors ) ) - $error_mark = ''; - - $publickey = trim( $field['public-key'] ); - $privatekey = trim( $field['private-key'] ); - - if ( empty( $publickey ) || empty( $privatekey ) ) - return ''.apply_filters( 'wppb_'.$form_location.'_recaptcha_custom_field_'.$field['id'].'_error_message', __("To use reCAPTCHA you must get an API public key from:", "profile-builder"). 'https://www.google.com/recaptcha/admin/create' ).''; - - $output = ''.wppb_recaptcha_get_html( $publickey , 'pb_register'); - if( !empty( $item_description ) ) - $output .= '' . $item_description . ''; - - return $output; - - } - } -} -add_filter( 'wppb_output_form_field_recaptcha', 'wppb_recaptcha_handler', 10, 6 ); - - -/* handle reCAPTCHA field validation on PB Register form */ -function wppb_check_recaptcha_value( $message, $field, $request_data, $form_location ){ - if( $field['field'] == 'reCAPTCHA' ){ - if ( ( $form_location == 'register' ) && ( isset($field['captcha-pb-forms']) ) && (strpos($field['captcha-pb-forms'],'pb_register') !== false) ) { - if ( ( wppb_validate_captcha_response( trim( $field['public-key'] ), trim( $field['private-key'] ) ) == false ) && ( $field['required'] == 'Yes' ) ){ - return wppb_required_field_error($field["field-title"]); - } - } - } - return $message; -} -add_filter( 'wppb_check_form_field_recaptcha', 'wppb_check_recaptcha_value', 10, 4 ); - -// Get the reCAPTCHA field information -function wppb_get_recaptcha_field(){ - $wppb_manage_fields = get_option( 'wppb_manage_fields', 'not_found' ); - $field = ''; - if ( $wppb_manage_fields != 'not_found' ) { - foreach ($wppb_manage_fields as $value) { - if ($value['field'] == 'reCAPTCHA') - $field = $value; - } - } - return $field; -} - -/* Display reCAPTCHA on PB Recover Password form */ -function wppb_display_recaptcha_recover_password( $output ){ - $field = wppb_get_recaptcha_field(); - - if ( !empty($field) ) { - $publickey = trim($field['public-key']); - $item_title = apply_filters('wppb_recover_password_recaptcha_custom_field_' . $field['id'] . '_item_title', wppb_icl_t('plugin profile-builder-pro', 'custom_field_' . $field['id'] . '_title_translation', $field['field-title'])); - $item_description = wppb_icl_t('plugin profile-builder-pro', 'custom_field_' . $field['id'] . '_description_translation', $field['description']); - - // check where reCAPCHA should display and add reCAPTCHA html - if ( isset($field['captcha-pb-forms']) && ( strpos( $field['captcha-pb-forms'],'pb_recover_password' ) !== false ) ) { - $recaptcha_output = '' . wppb_recaptcha_get_html($publickey, 'pb_recover_password'); - if (!empty($item_description)) - $recaptcha_output .= '' . $item_description . ''; - - $output = str_replace('', '
          • ' . $recaptcha_output . '
          • ' . '', $output); - } - } - return $output; -} -add_filter('wppb_recover_password_generate_password_input','wppb_display_recaptcha_recover_password'); - -/* Function that changes the messageNo from the Recover Password form */ -function wppb_recaptcha_change_recover_password_message_no($messageNo) { - - if (isset($_REQUEST['action']) && $_REQUEST['action'] == 'recover_password') { - $field = wppb_get_recaptcha_field(); - if (!empty($field)) { - - global $wppb_recaptcha_response; - if (!isset($wppb_recaptcha_response)) $wppb_recaptcha_response = wppb_validate_captcha_response( trim( $field['public-key'] ), trim( $field['private-key'] ) ); - - if ( isset($field['captcha-pb-forms']) && (strpos($field['captcha-pb-forms'], 'pb_recover_password') !== false) ) { - - if ( ($wppb_recaptcha_response == false ) && ( $field['required'] == 'Yes' ) ) - $messageNo = ''; - } - } - } - - return $messageNo; -} -add_filter('wppb_recover_password_message_no', 'wppb_recaptcha_change_recover_password_message_no'); - -/* Function that adds the reCAPTCHA error message on the Recover Password form */ -function wppb_recaptcha_recover_password_displayed_message1( $message ) { - $field = wppb_get_recaptcha_field(); - - if ( !empty($field) ){ - global $wppb_recaptcha_response; - if (!isset($wppb_recaptcha_response)) $wppb_recaptcha_response = wppb_validate_captcha_response( trim( $field['public-key'] ), trim( $field['private-key'] ) ); - - if ( isset($field['captcha-pb-forms']) && ( strpos( $field['captcha-pb-forms'],'pb_recover_password' ) !== false ) && ( $wppb_recaptcha_response == false )) { - - // This message is also altered by the plugin-compatibilities.php file, in regards to Captcha plugin ( function wppb_captcha_recover_password_displayed_message1 ) - if (($message == '

            wppb_recaptcha_error

            ') || ($message == '

            wppb_captcha_error

            ')) - $message = '

            ' . wppb_recaptcha_field_error($field["field-title"]) . '

            '; - else - $message = $message . '

            ' . wppb_recaptcha_field_error($field["field-title"]) . '

            '; - - } - } - - return $message; -} -add_filter('wppb_recover_password_displayed_message1', 'wppb_recaptcha_recover_password_displayed_message1'); - -/* Function that changes the default success message to wppb_recaptcha_error if the reCAPTCHA doesn't validate - so that we can change the message displayed with the wppb_recover_password_displayed_message1 filter */ -function wppb_recaptcha_recover_password_sent_message_1($message) { - - if (isset($_REQUEST['action']) && $_REQUEST['action'] == 'recover_password') { - $field = wppb_get_recaptcha_field(); - - if (!empty($field)) { - global $wppb_recaptcha_response; - if (!isset($wppb_recaptcha_response)) $wppb_recaptcha_response = wppb_validate_captcha_response( trim( $field['public-key'] ), trim( $field['private-key'] ) ); - - if ( isset($field['captcha-pb-forms']) && ( strpos($field['captcha-pb-forms'], 'pb_recover_password') !== false ) && ( $wppb_recaptcha_response == false ) ){ - $message = 'wppb_recaptcha_error'; - } - } - - } - - return $message; -} -add_filter('wppb_recover_password_sent_message1', 'wppb_recaptcha_recover_password_sent_message_1'); - -/* Display reCAPTCHA html on PB Login form */ -function wppb_display_recaptcha_login_form($form_part, $args) { - $field = wppb_get_recaptcha_field(); - - if ( !empty($field) ) { - $item_title = apply_filters('wppb_login_recaptcha_custom_field_' . $field['id'] . '_item_title', wppb_icl_t('plugin profile-builder-pro', 'custom_field_' . $field['id'] . '_title_translation', $field['field-title'])); - $item_description = wppb_icl_t('plugin profile-builder-pro', 'custom_field_' . $field['id'] . '_description_translation', $field['description']); - - if ( isset($field['captcha-pb-forms']) && ( strpos( $field['captcha-pb-forms'],'pb_login' ) !== false ) ) { // check where reCAPTCHA should display and add reCAPTCHA html - $recaptcha_output = '' . wppb_recaptcha_get_html( trim($field['public-key']), 'pb_login' ); - if (!empty($item_description)) - $recaptcha_output .= '' . $item_description . ''; - - $form_part .= '
            '. $recaptcha_output .'
            '; - } - } - - return $form_part; -} -add_filter('login_form_middle', 'wppb_display_recaptcha_login_form', 10, 2); - -/* Display reCAPTCHA html on default WP Login form */ -function wppb_display_recaptcha_wp_login_form(){ - $field = wppb_get_recaptcha_field(); - - if ( !empty($field) ) { - $item_title = apply_filters('wppb_login_recaptcha_custom_field_' . $field['id'] . '_item_title', wppb_icl_t('plugin profile-builder-pro', 'custom_field_' . $field['id'] . '_title_translation', $field['field-title'])); - $item_description = wppb_icl_t('plugin profile-builder-pro', 'custom_field_' . $field['id'] . '_description_translation', $field['description']); - - if ( isset($field['captcha-wp-forms']) && (strpos( $field['captcha-wp-forms'],'default_wp_login' ) !== false) ) { // check where reCAPTCHA should display and add reCAPTCHA html - - $recaptcha_output = '' . wppb_recaptcha_get_html( trim($field['public-key']) ); - if (!empty($item_description)) - $recaptcha_output .= '' . $item_description . ''; - - echo '
            '. $recaptcha_output .'
            '; - } - } -} -add_action( 'login_form', 'wppb_display_recaptcha_wp_login_form' ); - -//Show reCAPTCHA error on Login form (both default and PB one) -function wppb_recaptcha_login_wp_error_message($user){ - //make sure you're on a Login form (WP or PB) - if ( (isset($_POST['wp-submit'])) && (!is_wp_error($user)) ) { - - $field = wppb_get_recaptcha_field(); - if ( !empty($field) ){ - global $wppb_recaptcha_response; - if (!isset($wppb_recaptcha_response)) $wppb_recaptcha_response = wppb_validate_captcha_response( trim( $field['public-key'] ), trim( $field['private-key'] ) ); - - //reCAPTCHA error for displaying on the PB login form - if ( isset($_POST['wppb_login']) && ($_POST['wppb_login'] == true) && (isset($field['captcha-pb-forms'])) && ( strpos( $field['captcha-pb-forms'],'pb_login' ) !== false ) && ( $wppb_recaptcha_response == false ) ) { - $user = new WP_Error('wppb_recaptcha_error', __('Please enter a (valid) reCAPTCHA value','profile-builder')); - } - - //reCAPTCHA error for displaying on the default WP login form - if ( isset($field['captcha-wp-forms']) && (strpos( $field['captcha-wp-forms'],'default_wp_login' ) !== false) && ($wppb_recaptcha_response == false) ) { - $user = new WP_Error('wppb_recaptcha_error', __('Please enter a (valid) reCAPTCHA value','profile-builder')); - } - } - } - return $user; -} -add_filter('authenticate','wppb_recaptcha_login_wp_error_message', 22); - -// Display reCAPTCHA html on default WP Recover Password form -function wppb_display_recaptcha_default_wp_recover_password() { - $field = wppb_get_recaptcha_field(); - - if (!empty($field)) { - $publickey = trim($field['public-key']); - $item_title = apply_filters('wppb_recover_password_recaptcha_custom_field_' . $field['id'] . '_item_title', wppb_icl_t('plugin profile-builder-pro', 'custom_field_' . $field['id'] . '_title_translation', $field['field-title'])); - $item_description = wppb_icl_t('plugin profile-builder-pro', 'custom_field_' . $field['id'] . '_description_translation', $field['description']); - - if ( isset($field['captcha-wp-forms']) && (strpos( $field['captcha-wp-forms'], 'default_wp_recover_password') !== false) ) { // check where reCAPTCHA should display and add reCAPTCHA html - $recaptcha_output = '' . wppb_recaptcha_get_html($publickey); - if (!empty($item_description)) - $recaptcha_output .= '' . $item_description . ''; - - echo '
            '. $recaptcha_output .'
            '; - } - } -} -add_action('lostpassword_form','wppb_display_recaptcha_default_wp_recover_password'); - -// Verify and show reCAPTCHA errors for default WP Recover Password -function wppb_verify_recaptcha_default_wp_recover_password(){ - - // If field 'username or email' is empty - return - if( isset( $_REQUEST['user_login'] ) && "" == $_REQUEST['user_login'] ) - return; - - $field = wppb_get_recaptcha_field(); - if ( !empty($field) ){ - global $wppb_recaptcha_response; - if (!isset($wppb_recaptcha_response)) $wppb_recaptcha_response = wppb_validate_captcha_response( trim( $field['public-key'] ), trim( $field['private-key'] ) ); - - // If reCAPTCHA not entered or incorrect reCAPTCHA answer - if ( isset( $_REQUEST['g-recaptcha-response'] ) && ( ( "" == $_REQUEST['g-recaptcha-response'] ) || ( $wppb_recaptcha_response == false ) ) ) { - wp_die( __('Please enter a (valid) reCAPTCHA value','profile-builder') . '
            ' . __( "Click the BACK button on your browser, and try again.", 'profile-builder' ) ) ; - } - } -} -add_action('lostpassword_post','wppb_verify_recaptcha_default_wp_recover_password'); - -/* Display reCAPTCHA html on default WP Register form */ -function wppb_display_recaptcha_default_wp_register(){ - $field = wppb_get_recaptcha_field(); - - if (!empty($field)) { - $publickey = trim($field['public-key']); - $item_title = apply_filters('wppb_register_recaptcha_custom_field_' . $field['id'] . '_item_title', wppb_icl_t('plugin profile-builder-pro', 'custom_field_' . $field['id'] . '_title_translation', $field['field-title'])); - $item_description = wppb_icl_t('plugin profile-builder-pro', 'custom_field_' . $field['id'] . '_description_translation', $field['description']); - - wppb_recaptcha_set_default_values(); - if ( isset($field['captcha-wp-forms']) && (strpos( $field['captcha-wp-forms'], 'default_wp_register') !== false) ) { // check where reCAPTCHA should display and add reCAPTCHA html - $recaptcha_output = '' . wppb_recaptcha_get_html($publickey); - if (!empty($item_description)) - $recaptcha_output .= '' . $item_description . ''; - - echo '
            ' . $recaptcha_output . '
            '; - } - } -} -add_action( 'register_form', 'wppb_display_recaptcha_default_wp_register' ); - -// Verify and show reCAPTCHA errors for default WP Register form -function wppb_verify_recaptcha_default_wp_register( $errors ){ - - $field = wppb_get_recaptcha_field(); - if ( !empty($field) ){ - global $wppb_recaptcha_response; - if (!isset($wppb_recaptcha_response)) $wppb_recaptcha_response = wppb_validate_captcha_response( trim( $field['public-key'] ), trim( $field['private-key'] ) ); - - // If reCAPTCHA not entered or incorrect reCAPTCHA answer - if ( isset( $_REQUEST['g-recaptcha-response'] ) && ( ( "" == $_REQUEST['g-recaptcha-response'] ) || ( $wppb_recaptcha_response == false ) ) ) { - $errors->add( 'wppb_recaptcha_error', __('Please enter a (valid) reCAPTCHA value','profile-builder') ); - } - } - -return $errors; -} -add_filter('registration_errors','wppb_verify_recaptcha_default_wp_register'); - -// set default "Display on which forms?" values in case there's already an existing reCAPTCHA field in Manage fields (when upgrading) -function wppb_recaptcha_set_default_values() { - $manage_fields = get_option('wppb_manage_fields', 'not_set'); - if ($manage_fields != 'not_set') { - foreach ($manage_fields as $key => $value) { - if ($value['field'] == 'reCAPTCHA') { - if ( !isset($value['captcha-pb-forms']) ) $manage_fields[$key]['captcha-pb-forms'] = 'pb_register'; - if ( !isset($value['captcha-wp-forms']) ) $manage_fields[$key]['captcha-wp-forms'] = 'default_wp_register'; - } - } - update_option('wppb_manage_fields', $manage_fields); - } + $value) { + $req .= $key . '=' . urlencode(stripslashes($value)) . '&'; + } + // Cut the last '&' + $req=substr($req, 0, strlen($req)-1); + return $req; +} + + + +/** + * Submits an HTTP GET to a reCAPTCHA server + * @param string $path + * @param array $data + */ +function _wppb_submitHTTPGet($path, $data) +{ + $req = _wppb_encodeQS($data); + $response = wp_remote_get($path . $req); + + if ( ! is_wp_error( $response )) + return $response["body"]; +} + +/** + * Gets the challenge HTML (javascript and non-javascript version). + * This is called from the browser, and the resulting reCAPTCHA HTML widget + * is embedded within the HTML form it was called from. + * @param string $pubkey A public key for reCAPTCHA + * @param string $error The error given by reCAPTCHA (optional, default is null) + * @param boolean $use_ssl Should the request be made over ssl? (optional, default is false) + + * @return string - The HTML to be embedded in the user's form. + */ +function wppb_recaptcha_get_html ( $pubkey, $form_name='' ){ + global $wppb_recaptcha_forms; // will contain the name of all PB forms containing reCAPTCHA which are loaded on a certain page + + if ( empty($pubkey) ) + echo $errorMessage = ''. __("To use reCAPTCHA you must get an API key from", "profile-builder"). " https://www.google.com/recaptcha/admin/create

            "; + + // we add this number to the form name to differentiate between 2 different forms of the same type (e.g. PB Login widget + PB Login page form) which both have reCAPTCHA + $length = strval(strlen($wppb_recaptcha_forms)); + + if ($form_name != '') { + if ($wppb_recaptcha_forms != '') $wppb_recaptcha_forms .= ','.trim($form_name).$length; + else $wppb_recaptcha_forms = trim($form_name).$length; + + // reCAPTCHA html for PB forms + return ' +
            + '; + } + else { //reCAPTCHA html and scripts for default WP forms (backend) + return ' + +
            + '; + } + +} + +// For PB forms (not default WP ones) containing reCAPTCHA we'll make sure to add the script in the page's header and footer, in order to allow multiple reCAPTCHAs on the same page. +function wppb_recaptcha_script_header() { + global $wppb_recaptcha_forms; + //initialize the $wppb_recaptcha_forms global var + $wppb_recaptcha_forms = ''; +} +add_action('wp_head', 'wppb_recaptcha_script_header'); + + + +function wppb_recaptcha_script_footer(){ + global $wppb_recaptcha_forms; + if( !empty( $wppb_recaptcha_forms ) ) { + echo ''; + + $forms = explode(',',$wppb_recaptcha_forms); + + $field = wppb_get_recaptcha_field(); + + $pubkey = ''; + if( isset( $field['public-key'] ) ) { + $pubkey = trim( $field['public-key'] ); + } + + echo ''; + } +} +add_action('wp_footer','wppb_recaptcha_script_footer'); + + + +/** + * A wppb_ReCaptchaResponse is returned from wppb_recaptcha_check_answer() + */ +class wppb_ReCaptchaResponse { + var $is_valid; +} + + +/** + * Calls an HTTP POST function to verify if the user's answer was correct + * @param string $privkey + * @param string $remoteip + * @param string $response + * @return wppb_ReCaptchaResponse + */ +function wppb_recaptcha_check_answer ( $privkey, $remoteip, $response ){ + + if ( $remoteip == null || $remoteip == '' ) + echo ''. __("For security reasons, you must pass the remote ip to reCAPTCHA!", "profile-builder") .'

            '; + + // Discard empty solution submissions + if ($response == null || strlen($response) == 0) { + $recaptchaResponse = new wppb_ReCaptchaResponse(); + $recaptchaResponse->is_valid = false; + + return $recaptchaResponse; + } + $getResponse = _wppb_submitHTTPGet( + "https://www.google.com/recaptcha/api/siteverify?", + array ( + 'secret' => $privkey, + 'remoteip' => $remoteip, + 'response' => $response + ) + ); + + $answers = json_decode($getResponse, true); + $recaptchaResponse = new wppb_ReCaptchaResponse(); + if (trim($answers ['success']) == true) { + $recaptchaResponse->is_valid = true; + } else { + $recaptchaResponse->is_valid = false; + } + return $recaptchaResponse; + +} + +/* the function to display error message on the registration page */ +function wppb_validate_captcha_response( $publickey, $privatekey ){ + if (isset($_POST['g-recaptcha-response'])){ + $recaptcha_response_field = $_POST['g-recaptcha-response']; + } + else { + $recaptcha_response_field = ''; + } + + $resp = wppb_recaptcha_check_answer($privatekey, $_SERVER["REMOTE_ADDR"], $recaptcha_response_field ); + + if ( !empty( $_POST ) ) + return ( ( !$resp->is_valid ) ? false : true ); +} + +/* the function to add reCAPTCHA to the registration form of PB */ +function wppb_recaptcha_handler ( $output, $form_location, $field, $user_id, $field_check_errors, $request_data ){ + if ( $field['field'] == 'reCAPTCHA' ){ + $item_title = apply_filters( 'wppb_'.$form_location.'_recaptcha_custom_field_'.$field['id'].'_item_title', wppb_icl_t( 'plugin profile-builder-pro', 'custom_field_'.$field['id'].'_title_translation', $field['field-title'] ) ); + $item_description = wppb_icl_t( 'plugin profile-builder-pro', 'custom_field_'.$field['id'].'_description_translation', $field['description'] ); + + wppb_recaptcha_set_default_values(); + if ( ($form_location == 'register') && ( isset($field['captcha-pb-forms']) ) && (strpos($field['captcha-pb-forms'],'pb_register') !== false) ) { + $error_mark = ( ( $field['required'] == 'Yes' ) ? '*' : '' ); + + if ( array_key_exists( $field['id'], $field_check_errors ) ) + $error_mark = ''; + + $publickey = trim( $field['public-key'] ); + $privatekey = trim( $field['private-key'] ); + + if ( empty( $publickey ) || empty( $privatekey ) ) + return ''.apply_filters( 'wppb_'.$form_location.'_recaptcha_custom_field_'.$field['id'].'_error_message', __("To use reCAPTCHA you must get an API public key from:", "profile-builder"). 'https://www.google.com/recaptcha/admin/create' ).''; + + $output = ''.wppb_recaptcha_get_html( $publickey , 'pb_register'); + if( !empty( $item_description ) ) + $output .= '' . $item_description . ''; + + return $output; + + } + } +} +add_filter( 'wppb_output_form_field_recaptcha', 'wppb_recaptcha_handler', 10, 6 ); + + +/* handle reCAPTCHA field validation on PB Register form */ +function wppb_check_recaptcha_value( $message, $field, $request_data, $form_location ){ + if( $field['field'] == 'reCAPTCHA' ){ + if ( ( $form_location == 'register' ) && ( isset($field['captcha-pb-forms']) ) && (strpos($field['captcha-pb-forms'],'pb_register') !== false) ) { + if ( ( wppb_validate_captcha_response( trim( $field['public-key'] ), trim( $field['private-key'] ) ) == false ) && ( $field['required'] == 'Yes' ) ){ + return wppb_required_field_error($field["field-title"]); + } + } + } + return $message; +} +add_filter( 'wppb_check_form_field_recaptcha', 'wppb_check_recaptcha_value', 10, 4 ); + +// Get the reCAPTCHA field information +function wppb_get_recaptcha_field(){ + $wppb_manage_fields = get_option( 'wppb_manage_fields', 'not_found' ); + $field = ''; + if ( $wppb_manage_fields != 'not_found' ) { + foreach ($wppb_manage_fields as $value) { + if ($value['field'] == 'reCAPTCHA') + $field = $value; + } + } + return $field; +} + +/* Display reCAPTCHA on PB Recover Password form */ +function wppb_display_recaptcha_recover_password( $output ){ + $field = wppb_get_recaptcha_field(); + + if ( !empty($field) ) { + $publickey = trim($field['public-key']); + $item_title = apply_filters('wppb_recover_password_recaptcha_custom_field_' . $field['id'] . '_item_title', wppb_icl_t('plugin profile-builder-pro', 'custom_field_' . $field['id'] . '_title_translation', $field['field-title'])); + $item_description = wppb_icl_t('plugin profile-builder-pro', 'custom_field_' . $field['id'] . '_description_translation', $field['description']); + + // check where reCAPCHA should display and add reCAPTCHA html + if ( isset($field['captcha-pb-forms']) && ( strpos( $field['captcha-pb-forms'],'pb_recover_password' ) !== false ) ) { + $recaptcha_output = '' . wppb_recaptcha_get_html($publickey, 'pb_recover_password'); + if (!empty($item_description)) + $recaptcha_output .= '' . $item_description . ''; + + $output = str_replace('', '
          • ' . $recaptcha_output . '
          • ' . '', $output); + } + } + return $output; +} +add_filter('wppb_recover_password_generate_password_input','wppb_display_recaptcha_recover_password'); + +/* Function that changes the messageNo from the Recover Password form */ +function wppb_recaptcha_change_recover_password_message_no($messageNo) { + + if (isset($_REQUEST['action']) && $_REQUEST['action'] == 'recover_password') { + $field = wppb_get_recaptcha_field(); + if (!empty($field)) { + + global $wppb_recaptcha_response; + if (!isset($wppb_recaptcha_response)) $wppb_recaptcha_response = wppb_validate_captcha_response( trim( $field['public-key'] ), trim( $field['private-key'] ) ); + + if ( isset($field['captcha-pb-forms']) && (strpos($field['captcha-pb-forms'], 'pb_recover_password') !== false) ) { + + if ( ($wppb_recaptcha_response == false ) && ( $field['required'] == 'Yes' ) ) + $messageNo = ''; + } + } + } + + return $messageNo; +} +add_filter('wppb_recover_password_message_no', 'wppb_recaptcha_change_recover_password_message_no'); + +/* Function that adds the reCAPTCHA error message on the Recover Password form */ +function wppb_recaptcha_recover_password_displayed_message1( $message ) { + $field = wppb_get_recaptcha_field(); + + if ( !empty($field) ){ + global $wppb_recaptcha_response; + if (!isset($wppb_recaptcha_response)) $wppb_recaptcha_response = wppb_validate_captcha_response( trim( $field['public-key'] ), trim( $field['private-key'] ) ); + + if ( isset($field['captcha-pb-forms']) && ( strpos( $field['captcha-pb-forms'],'pb_recover_password' ) !== false ) && ( $wppb_recaptcha_response == false )) { + + // This message is also altered by the plugin-compatibilities.php file, in regards to Captcha plugin ( function wppb_captcha_recover_password_displayed_message1 ) + if (($message == '

            wppb_recaptcha_error

            ') || ($message == '

            wppb_captcha_error

            ')) + $message = '

            ' . wppb_recaptcha_field_error($field["field-title"]) . '

            '; + else + $message = $message . '

            ' . wppb_recaptcha_field_error($field["field-title"]) . '

            '; + + } + } + + return $message; +} +add_filter('wppb_recover_password_displayed_message1', 'wppb_recaptcha_recover_password_displayed_message1'); + +/* Function that changes the default success message to wppb_recaptcha_error if the reCAPTCHA doesn't validate + so that we can change the message displayed with the wppb_recover_password_displayed_message1 filter */ +function wppb_recaptcha_recover_password_sent_message_1($message) { + + if (isset($_REQUEST['action']) && $_REQUEST['action'] == 'recover_password') { + $field = wppb_get_recaptcha_field(); + + if (!empty($field)) { + global $wppb_recaptcha_response; + if (!isset($wppb_recaptcha_response)) $wppb_recaptcha_response = wppb_validate_captcha_response( trim( $field['public-key'] ), trim( $field['private-key'] ) ); + + if ( isset($field['captcha-pb-forms']) && ( strpos($field['captcha-pb-forms'], 'pb_recover_password') !== false ) && ( $wppb_recaptcha_response == false ) ){ + $message = 'wppb_recaptcha_error'; + } + } + + } + + return $message; +} +add_filter('wppb_recover_password_sent_message1', 'wppb_recaptcha_recover_password_sent_message_1'); + +/* Display reCAPTCHA html on PB Login form */ +function wppb_display_recaptcha_login_form($form_part, $args) { + $field = wppb_get_recaptcha_field(); + + if ( !empty($field) ) { + $item_title = apply_filters('wppb_login_recaptcha_custom_field_' . $field['id'] . '_item_title', wppb_icl_t('plugin profile-builder-pro', 'custom_field_' . $field['id'] . '_title_translation', $field['field-title'])); + $item_description = wppb_icl_t('plugin profile-builder-pro', 'custom_field_' . $field['id'] . '_description_translation', $field['description']); + + if ( isset($field['captcha-pb-forms']) && ( strpos( $field['captcha-pb-forms'],'pb_login' ) !== false ) ) { // check where reCAPTCHA should display and add reCAPTCHA html + $recaptcha_output = '' . wppb_recaptcha_get_html( trim($field['public-key']), 'pb_login' ); + if (!empty($item_description)) + $recaptcha_output .= '' . $item_description . ''; + + $form_part .= '
            '. $recaptcha_output .'
            '; + } + } + + return $form_part; +} +add_filter('login_form_middle', 'wppb_display_recaptcha_login_form', 10, 2); + +/* Display reCAPTCHA html on default WP Login form */ +function wppb_display_recaptcha_wp_login_form(){ + $field = wppb_get_recaptcha_field(); + + if ( !empty($field) ) { + $item_title = apply_filters('wppb_login_recaptcha_custom_field_' . $field['id'] . '_item_title', wppb_icl_t('plugin profile-builder-pro', 'custom_field_' . $field['id'] . '_title_translation', $field['field-title'])); + $item_description = wppb_icl_t('plugin profile-builder-pro', 'custom_field_' . $field['id'] . '_description_translation', $field['description']); + + if ( isset($field['captcha-wp-forms']) && (strpos( $field['captcha-wp-forms'],'default_wp_login' ) !== false) ) { // check where reCAPTCHA should display and add reCAPTCHA html + + $recaptcha_output = '' . wppb_recaptcha_get_html( trim($field['public-key']) ); + if (!empty($item_description)) + $recaptcha_output .= '' . $item_description . ''; + + echo '
            '. $recaptcha_output .'
            '; + } + } +} +add_action( 'login_form', 'wppb_display_recaptcha_wp_login_form' ); + +//Show reCAPTCHA error on Login form (both default and PB one) +function wppb_recaptcha_login_wp_error_message($user){ + //make sure you're on a Login form (WP or PB) + if ( (isset($_POST['wp-submit'])) && (!is_wp_error($user)) ) { + + $field = wppb_get_recaptcha_field(); + if ( !empty($field) ){ + global $wppb_recaptcha_response; + if (!isset($wppb_recaptcha_response)) $wppb_recaptcha_response = wppb_validate_captcha_response( trim( $field['public-key'] ), trim( $field['private-key'] ) ); + + //reCAPTCHA error for displaying on the PB login form + if ( isset($_POST['wppb_login']) && ($_POST['wppb_login'] == true) && (isset($field['captcha-pb-forms'])) && ( strpos( $field['captcha-pb-forms'],'pb_login' ) !== false ) && ( $wppb_recaptcha_response == false ) ) { + $user = new WP_Error('wppb_recaptcha_error', __('Please enter a (valid) reCAPTCHA value','profile-builder')); + } + + //reCAPTCHA error for displaying on the default WP login form + if ( isset($field['captcha-wp-forms']) && (strpos( $field['captcha-wp-forms'],'default_wp_login' ) !== false) && ($wppb_recaptcha_response == false) ) { + $user = new WP_Error('wppb_recaptcha_error', __('Please enter a (valid) reCAPTCHA value','profile-builder')); + } + } + } + return $user; +} +add_filter('authenticate','wppb_recaptcha_login_wp_error_message', 22); + +// Display reCAPTCHA html on default WP Recover Password form +function wppb_display_recaptcha_default_wp_recover_password() { + $field = wppb_get_recaptcha_field(); + + if (!empty($field)) { + $publickey = trim($field['public-key']); + $item_title = apply_filters('wppb_recover_password_recaptcha_custom_field_' . $field['id'] . '_item_title', wppb_icl_t('plugin profile-builder-pro', 'custom_field_' . $field['id'] . '_title_translation', $field['field-title'])); + $item_description = wppb_icl_t('plugin profile-builder-pro', 'custom_field_' . $field['id'] . '_description_translation', $field['description']); + + if ( isset($field['captcha-wp-forms']) && (strpos( $field['captcha-wp-forms'], 'default_wp_recover_password') !== false) ) { // check where reCAPTCHA should display and add reCAPTCHA html + $recaptcha_output = '' . wppb_recaptcha_get_html($publickey); + if (!empty($item_description)) + $recaptcha_output .= '' . $item_description . ''; + + echo '
            '. $recaptcha_output .'
            '; + } + } +} +add_action('lostpassword_form','wppb_display_recaptcha_default_wp_recover_password'); + +// Verify and show reCAPTCHA errors for default WP Recover Password +function wppb_verify_recaptcha_default_wp_recover_password(){ + + // If field 'username or email' is empty - return + if( isset( $_REQUEST['user_login'] ) && "" == $_REQUEST['user_login'] ) + return; + + $field = wppb_get_recaptcha_field(); + if ( !empty($field) ){ + global $wppb_recaptcha_response; + if (!isset($wppb_recaptcha_response)) $wppb_recaptcha_response = wppb_validate_captcha_response( trim( $field['public-key'] ), trim( $field['private-key'] ) ); + + // If reCAPTCHA not entered or incorrect reCAPTCHA answer + if ( isset( $_REQUEST['g-recaptcha-response'] ) && ( ( "" == $_REQUEST['g-recaptcha-response'] ) || ( $wppb_recaptcha_response == false ) ) ) { + wp_die( __('Please enter a (valid) reCAPTCHA value','profile-builder') . '
            ' . __( "Click the BACK button on your browser, and try again.", 'profile-builder' ) ) ; + } + } +} +add_action('lostpassword_post','wppb_verify_recaptcha_default_wp_recover_password'); + +/* Display reCAPTCHA html on default WP Register form */ +function wppb_display_recaptcha_default_wp_register(){ + $field = wppb_get_recaptcha_field(); + + if (!empty($field)) { + $publickey = trim($field['public-key']); + $item_title = apply_filters('wppb_register_recaptcha_custom_field_' . $field['id'] . '_item_title', wppb_icl_t('plugin profile-builder-pro', 'custom_field_' . $field['id'] . '_title_translation', $field['field-title'])); + $item_description = wppb_icl_t('plugin profile-builder-pro', 'custom_field_' . $field['id'] . '_description_translation', $field['description']); + + wppb_recaptcha_set_default_values(); + if ( isset($field['captcha-wp-forms']) && (strpos( $field['captcha-wp-forms'], 'default_wp_register') !== false) ) { // check where reCAPTCHA should display and add reCAPTCHA html + $recaptcha_output = '' . wppb_recaptcha_get_html($publickey); + if (!empty($item_description)) + $recaptcha_output .= '' . $item_description . ''; + + echo '
            ' . $recaptcha_output . '
            '; + } + } +} +add_action( 'register_form', 'wppb_display_recaptcha_default_wp_register' ); + +// Verify and show reCAPTCHA errors for default WP Register form +function wppb_verify_recaptcha_default_wp_register( $errors ){ + + $field = wppb_get_recaptcha_field(); + if ( !empty($field) ){ + global $wppb_recaptcha_response; + if (!isset($wppb_recaptcha_response)) $wppb_recaptcha_response = wppb_validate_captcha_response( trim( $field['public-key'] ), trim( $field['private-key'] ) ); + + // If reCAPTCHA not entered or incorrect reCAPTCHA answer + if ( isset( $_REQUEST['g-recaptcha-response'] ) && ( ( "" == $_REQUEST['g-recaptcha-response'] ) || ( $wppb_recaptcha_response == false ) ) ) { + $errors->add( 'wppb_recaptcha_error', __('Please enter a (valid) reCAPTCHA value','profile-builder') ); + } + } + +return $errors; +} +add_filter('registration_errors','wppb_verify_recaptcha_default_wp_register'); + +// set default "Display on which forms?" values in case there's already an existing reCAPTCHA field in Manage fields (when upgrading) +function wppb_recaptcha_set_default_values() { + $manage_fields = get_option('wppb_manage_fields', 'not_set'); + if ($manage_fields != 'not_set') { + foreach ($manage_fields as $key => $value) { + if ($value['field'] == 'reCAPTCHA') { + if ( !isset($value['captcha-pb-forms']) ) $manage_fields[$key]['captcha-pb-forms'] = 'pb_register'; + if ( !isset($value['captcha-wp-forms']) ) $manage_fields[$key]['captcha-wp-forms'] = 'default_wp_register'; + } + } + update_option('wppb_manage_fields', $manage_fields); + } } \ No newline at end of file diff --git a/profile-builder/front-end/default-fields/user-role/user-role.php b/profile-builder/front-end/default-fields/user-role/user-role.php index 3b73ea4..adefd1f 100644 --- a/profile-builder/front-end/default-fields/user-role/user-role.php +++ b/profile-builder/front-end/default-fields/user-role/user-role.php @@ -1,137 +1,137 @@ -roles[0]; - - if( isset( $user_data->allcaps['manage_options'] ) && $user_data->allcaps['manage_options'] == 1 ) { - $user_can_manage_options = true; - } - } - - $input_value = isset( $request_data['custom_field_user_role'] ) ? $request_data['custom_field_user_role'] : $user_role; - - $item_title = apply_filters( 'wppb_'.$form_location.'_user_role_custom_field_'.$field['id'].'_item_title', wppb_icl_t( 'plugin profile-builder-pro', 'custom_field_'.$field['id'].'_title_translation', $field['field-title'] ) ); - $item_description = wppb_icl_t( 'plugin profile-builder-pro', 'custom_field_'.$field['id'].'_description_translation', $field['description'] ); - - //get user roles - if( !empty( $field['user-roles'] ) ) { - global $wp_roles; - - $available_user_roles = explode( ', ', $field['user-roles'] ); - - foreach( $available_user_roles as $key => $role_slug ) { - if( isset( $wp_roles->roles[$role_slug]['name'] ) ) { - $available_user_roles[$key] = array( - 'slug' => $role_slug, - 'name' => $wp_roles->roles[$role_slug]['name'] - ); - } else { - unset( $available_user_roles[$key] ); - } - } - } - - $extra_attr = apply_filters( 'wppb_extra_attribute', '', $field, $form_location ); - - if( $form_location == 'register' || ( $form_location == 'edit_profile' && current_user_can('manage_options') && $user_can_manage_options == false ) ) { - $error_mark = ( ( $field['required'] == 'Yes' ) ? '*' : '' ); - - if ( array_key_exists( $field['id'], $field_check_errors ) ) - $error_mark = ''; - - $output = ' - - '; - - if( $form_location == 'edit_profile' ) - $output .= ''. __( 'Only administrators can see this field on edit profile forms.', 'profile-builder' ) .''; - - if( !empty( $item_description ) ) - $output .= ''.$item_description.''; - - } elseif( $form_location == 'edit_profile' && current_user_can('manage_options') && $user_can_manage_options == true ) { - - $output = ' - -

            ' . __( 'As an administrator you cannot change your role.', 'profile-builder' ) . '

            '; - - $output .= ''; - - $output .= ''. __( 'Only administrators can see this field on edit profile forms.', 'profile-builder' ) .''; - - if( !empty( $item_description ) ) - $output .= ''.$item_description.''; - - } - - return apply_filters( 'wppb_'.$form_location.'_user_role_custom_field_'.$field['id'], $output, $form_location, $field, $user_id, $field_check_errors, $request_data, $input_value ); - } -} -add_filter( 'wppb_output_form_field_select-user-role', 'wppb_user_role_handler', 10, 6 ); - - -/* handle field validation */ -function wppb_check_user_role_value( $message, $field, $request_data, $form_location ) { - - if( $form_location == 'back_end' ) - return $message; - - $field['meta-name'] = 'custom_field_user_role'; - - if( $field['field'] == 'Select (User Role)' ){ - - if( $form_location == 'register' && $field['required'] == 'Yes' && current_user_can( 'manage_options' ) === false ) { - if( ( isset( $request_data[wppb_handle_meta_name( $field['meta-name'] )] ) && ( trim( $request_data[wppb_handle_meta_name( $field['meta-name'] )] ) == '' ) ) || !isset( $request_data[wppb_handle_meta_name( $field['meta-name'] )] ) ){ - return wppb_required_field_error($field["field-title"]); - } - } - - if( isset( $field['user-roles'] ) && isset( $request_data['custom_field_user_role'] ) ) { - $available_user_roles = explode(', ', $field['user-roles'] ); - - if( !in_array( $request_data['custom_field_user_role'], $available_user_roles ) ) { - return __( 'You cannot register this user role', 'profile-builder'); - } - } - - } - - return $message; -} -add_filter( 'wppb_check_form_field_select-user-role', 'wppb_check_user_role_value', 10, 4 ); - - -/* handle field save */ -function wppb_userdata_add_user_role( $userdata, $global_request ){ - - if ( isset( $global_request['custom_field_user_role'] ) ) - $userdata['role'] = sanitize_text_field( trim( $global_request['custom_field_user_role'] ) ); - - return $userdata; -} +roles[0]; + + if( isset( $user_data->allcaps['manage_options'] ) && $user_data->allcaps['manage_options'] == 1 ) { + $user_can_manage_options = true; + } + } + + $input_value = isset( $request_data['custom_field_user_role'] ) ? $request_data['custom_field_user_role'] : $user_role; + + $item_title = apply_filters( 'wppb_'.$form_location.'_user_role_custom_field_'.$field['id'].'_item_title', wppb_icl_t( 'plugin profile-builder-pro', 'custom_field_'.$field['id'].'_title_translation', $field['field-title'] ) ); + $item_description = wppb_icl_t( 'plugin profile-builder-pro', 'custom_field_'.$field['id'].'_description_translation', $field['description'] ); + + //get user roles + if( !empty( $field['user-roles'] ) ) { + global $wp_roles; + + $available_user_roles = explode( ', ', $field['user-roles'] ); + + foreach( $available_user_roles as $key => $role_slug ) { + if( isset( $wp_roles->roles[$role_slug]['name'] ) ) { + $available_user_roles[$key] = array( + 'slug' => $role_slug, + 'name' => $wp_roles->roles[$role_slug]['name'] + ); + } else { + unset( $available_user_roles[$key] ); + } + } + } + + $extra_attr = apply_filters( 'wppb_extra_attribute', '', $field, $form_location ); + + if( $form_location == 'register' || ( $form_location == 'edit_profile' && current_user_can('manage_options') && $user_can_manage_options == false ) ) { + $error_mark = ( ( $field['required'] == 'Yes' ) ? '*' : '' ); + + if ( array_key_exists( $field['id'], $field_check_errors ) ) + $error_mark = ''; + + $output = ' + + '; + + if( $form_location == 'edit_profile' ) + $output .= ''. __( 'Only administrators can see this field on edit profile forms.', 'profile-builder' ) .''; + + if( !empty( $item_description ) ) + $output .= ''.$item_description.''; + + } elseif( $form_location == 'edit_profile' && current_user_can('manage_options') && $user_can_manage_options == true ) { + + $output = ' + +

            ' . __( 'As an administrator you cannot change your role.', 'profile-builder' ) . '

            '; + + $output .= ''; + + $output .= ''. __( 'Only administrators can see this field on edit profile forms.', 'profile-builder' ) .''; + + if( !empty( $item_description ) ) + $output .= ''.$item_description.''; + + } + + return apply_filters( 'wppb_'.$form_location.'_user_role_custom_field_'.$field['id'], $output, $form_location, $field, $user_id, $field_check_errors, $request_data, $input_value ); + } +} +add_filter( 'wppb_output_form_field_select-user-role', 'wppb_user_role_handler', 10, 6 ); + + +/* handle field validation */ +function wppb_check_user_role_value( $message, $field, $request_data, $form_location ) { + + if( $form_location == 'back_end' ) + return $message; + + $field['meta-name'] = 'custom_field_user_role'; + + if( $field['field'] == 'Select (User Role)' ){ + + if( $form_location == 'register' && $field['required'] == 'Yes' && current_user_can( 'manage_options' ) === false ) { + if( ( isset( $request_data[wppb_handle_meta_name( $field['meta-name'] )] ) && ( trim( $request_data[wppb_handle_meta_name( $field['meta-name'] )] ) == '' ) ) || !isset( $request_data[wppb_handle_meta_name( $field['meta-name'] )] ) ){ + return wppb_required_field_error($field["field-title"]); + } + } + + if( isset( $field['user-roles'] ) && isset( $request_data['custom_field_user_role'] ) ) { + $available_user_roles = explode(', ', $field['user-roles'] ); + + if( !in_array( $request_data['custom_field_user_role'], $available_user_roles ) ) { + return __( 'You cannot register this user role', 'profile-builder'); + } + } + + } + + return $message; +} +add_filter( 'wppb_check_form_field_select-user-role', 'wppb_check_user_role_value', 10, 4 ); + + +/* handle field save */ +function wppb_userdata_add_user_role( $userdata, $global_request ){ + + if ( isset( $global_request['custom_field_user_role'] ) ) + $userdata['role'] = sanitize_text_field( trim( $global_request['custom_field_user_role'] ) ); + + return $userdata; +} add_filter( 'wppb_build_userdata', 'wppb_userdata_add_user_role', 10, 2 ); \ No newline at end of file diff --git a/profile-builder/front-end/default-fields/username/username.php b/profile-builder/front-end/default-fields/username/username.php index 75d2595..b719c8f 100644 --- a/profile-builder/front-end/default-fields/username/username.php +++ b/profile-builder/front-end/default-fields/username/username.php @@ -1,82 +1,82 @@ -*' : '' ); - - if ( array_key_exists( $field['id'], $field_check_errors ) ) - $error_mark = ''; - - $readonly = ( ( $form_location == 'edit_profile' ) ? ' disabled="disabled"' : '' ); - - $extra_attr = apply_filters( 'wppb_extra_attribute', '', $field, $form_location ); - - $output = ' - - '; - if( !empty( $item_description ) ) - $output .= ''.$item_description.''; - } - - return apply_filters( 'wppb_'.$form_location.'_username', $output, $form_location, $field, $user_id, $field_check_errors, $request_data ); -} -add_filter( 'wppb_output_form_field_default-username', 'wppb_username_handler', 10, 6 ); - - -/* handle field validation */ -function wppb_check_username_value( $message, $field, $request_data, $form_location ){ - global $wpdb; - - if( $field['required'] == 'Yes' ){ - if( ( isset( $request_data['username'] ) && ( trim( $request_data['username'] ) == '' ) ) || ( $form_location == 'register' && !isset( $request_data['username'] ) ) ){ - return wppb_required_field_error($field["field-title"]); - } - - } - - if( !empty( $request_data['username'] ) ){ - if( $form_location == 'register' ) { - if( username_exists($request_data['username'] ) ){ - return __('This username already exists.', 'profile-builder') . '
            ' . __('Please try a different one!', 'profile-builder'); - } - if (!validate_username($request_data['username'])) { - return __('This username is invalid because it uses illegal characters.', 'profile-builder') . '
            ' . __('Please enter a valid username.', 'profile-builder'); - } - } - - $wppb_generalSettings = get_option('wppb_general_settings'); - if ( $wppb_generalSettings['emailConfirmation'] == 'yes' ){ - - if( is_multisite() && $request_data['username'] != preg_replace( '/\s+/', '', $request_data['username'] ) ){ - return __( 'This username is invalid because it uses illegal characters.', 'profile-builder' ) .'
            '. __( 'Please enter a valid username.', 'profile-builder' ); - } - - $userSignup = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM ".$wpdb->prefix."signups WHERE user_login = %s", $request_data['username'] ) ); - if ( !empty( $userSignup ) ){ - return __( 'This username is already reserved to be used soon.', 'profile-builder') .'
            '. __( 'Please try a different one!', 'profile-builder' ); - } - } - } - - return $message; -} -add_filter( 'wppb_check_form_field_default-username', 'wppb_check_username_value', 10, 4 ); - - -/* handle field save */ -function wppb_userdata_add_username( $userdata, $global_request ){ - if ( isset( $global_request['username'] ) ) - $userdata['user_login'] = sanitize_user( trim( $global_request['username'] ) ); - - return $userdata; -} +*' : '' ); + + if ( array_key_exists( $field['id'], $field_check_errors ) ) + $error_mark = ''; + + $readonly = ( ( $form_location == 'edit_profile' ) ? ' disabled="disabled"' : '' ); + + $extra_attr = apply_filters( 'wppb_extra_attribute', '', $field, $form_location ); + + $output = ' + + '; + if( !empty( $item_description ) ) + $output .= ''.$item_description.''; + } + + return apply_filters( 'wppb_'.$form_location.'_username', $output, $form_location, $field, $user_id, $field_check_errors, $request_data ); +} +add_filter( 'wppb_output_form_field_default-username', 'wppb_username_handler', 10, 6 ); + + +/* handle field validation */ +function wppb_check_username_value( $message, $field, $request_data, $form_location ){ + global $wpdb; + + if( $field['required'] == 'Yes' ){ + if( ( isset( $request_data['username'] ) && ( trim( $request_data['username'] ) == '' ) ) || ( $form_location == 'register' && !isset( $request_data['username'] ) ) ){ + return wppb_required_field_error($field["field-title"]); + } + + } + + if( !empty( $request_data['username'] ) ){ + if( $form_location == 'register' ) { + if( username_exists($request_data['username'] ) ){ + return __('This username already exists.', 'profile-builder') . '
            ' . __('Please try a different one!', 'profile-builder'); + } + if (!validate_username($request_data['username'])) { + return __('This username is invalid because it uses illegal characters.', 'profile-builder') . '
            ' . __('Please enter a valid username.', 'profile-builder'); + } + } + + $wppb_generalSettings = get_option('wppb_general_settings'); + if ( $wppb_generalSettings['emailConfirmation'] == 'yes' ){ + + if( is_multisite() && $request_data['username'] != preg_replace( '/\s+/', '', $request_data['username'] ) ){ + return __( 'This username is invalid because it uses illegal characters.', 'profile-builder' ) .'
            '. __( 'Please enter a valid username.', 'profile-builder' ); + } + + $userSignup = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM ".$wpdb->prefix."signups WHERE user_login = %s", $request_data['username'] ) ); + if ( !empty( $userSignup ) ){ + return __( 'This username is already reserved to be used soon.', 'profile-builder') .'
            '. __( 'Please try a different one!', 'profile-builder' ); + } + } + } + + return $message; +} +add_filter( 'wppb_check_form_field_default-username', 'wppb_check_username_value', 10, 4 ); + + +/* handle field save */ +function wppb_userdata_add_username( $userdata, $global_request ){ + if ( isset( $global_request['username'] ) ) + $userdata['user_login'] = sanitize_user( trim( $global_request['username'] ) ); + + return $userdata; +} add_filter( 'wppb_build_userdata', 'wppb_userdata_add_username', 10, 2 ); \ No newline at end of file diff --git a/profile-builder/front-end/default-fields/website/website.php b/profile-builder/front-end/default-fields/website/website.php index e833108..b121fde 100644 --- a/profile-builder/front-end/default-fields/website/website.php +++ b/profile-builder/front-end/default-fields/website/website.php @@ -1,56 +1,56 @@ -*' : '' ); - - if ( array_key_exists( $field['id'], $field_check_errors ) ) - $error_mark = ''; - - $extra_attr = apply_filters( 'wppb_extra_attribute', '', $field, $form_location ); - - $output = ' - - '; - if( !empty( $item_description ) ) - $output .= ''. $item_description .''; - - } - - return apply_filters( 'wppb_'.$form_location.'_website', $output, $form_location, $field, $user_id, $field_check_errors, $request_data ); -} -add_filter( 'wppb_output_form_field_default-website', 'wppb_website_handler', 10, 6 ); - - -/* handle field validation */ -function wppb_check_website_value( $message, $field, $request_data, $form_location ){ - if( $field['required'] == 'Yes' ){ - if( ( isset( $request_data['website'] ) && ( trim( $request_data['website'] ) == '' ) ) || !isset( $request_data['website'] ) ){ - return wppb_required_field_error($field["field-title"]); - } - } - - return $message; -} -add_filter( 'wppb_check_form_field_default-website', 'wppb_check_website_value', 10, 4 ); - - -/* handle field save */ -function wppb_userdata_add_website( $userdata, $global_request ){ - if ( isset( $global_request['website'] ) ) - $userdata['user_url'] = esc_url_raw( trim( $global_request['website'] ) ); - - return $userdata; -} +*' : '' ); + + if ( array_key_exists( $field['id'], $field_check_errors ) ) + $error_mark = ''; + + $extra_attr = apply_filters( 'wppb_extra_attribute', '', $field, $form_location ); + + $output = ' + + '; + if( !empty( $item_description ) ) + $output .= ''. $item_description .''; + + } + + return apply_filters( 'wppb_'.$form_location.'_website', $output, $form_location, $field, $user_id, $field_check_errors, $request_data ); +} +add_filter( 'wppb_output_form_field_default-website', 'wppb_website_handler', 10, 6 ); + + +/* handle field validation */ +function wppb_check_website_value( $message, $field, $request_data, $form_location ){ + if( $field['required'] == 'Yes' ){ + if( ( isset( $request_data['website'] ) && ( trim( $request_data['website'] ) == '' ) ) || !isset( $request_data['website'] ) ){ + return wppb_required_field_error($field["field-title"]); + } + } + + return $message; +} +add_filter( 'wppb_check_form_field_default-website', 'wppb_check_website_value', 10, 4 ); + + +/* handle field save */ +function wppb_userdata_add_website( $userdata, $global_request ){ + if ( isset( $global_request['website'] ) ) + $userdata['user_url'] = esc_url_raw( trim( $global_request['website'] ) ); + + return $userdata; +} add_filter( 'wppb_build_userdata', 'wppb_userdata_add_website', 10, 2 ); \ No newline at end of file diff --git a/profile-builder/front-end/default-fields/yim/yim.php b/profile-builder/front-end/default-fields/yim/yim.php index 34512c3..2cf10ec 100644 --- a/profile-builder/front-end/default-fields/yim/yim.php +++ b/profile-builder/front-end/default-fields/yim/yim.php @@ -1,55 +1,55 @@ -*' : '' ); - - if ( array_key_exists( $field['id'], $field_check_errors ) ) - $error_mark = ''; - - $extra_attr = apply_filters( 'wppb_extra_attribute', '', $field, $form_location ); - - $output = ' - - '; - if( !empty( $item_description ) ) - $output .= ''. $item_description .''; - - } - - return apply_filters( 'wppb_'.$form_location.'_yim', $output, $form_location, $field, $user_id, $field_check_errors, $request_data ); -} -add_filter( 'wppb_output_form_field_default-yahoo-im', 'wppb_yim_handler', 10, 6 ); - - -/* handle field validation */ -function wppb_check_yim_value( $message, $field, $request_data, $form_location ){ - if( $field['required'] == 'Yes' ){ - if( ( isset( $request_data['yim'] ) && ( trim( $request_data['yim'] ) == '' ) ) || !isset( $request_data['yim'] ) ){ - return wppb_required_field_error($field["field-title"]); - } - } - - return $message; -} -add_filter( 'wppb_check_form_field_default-yahoo-im', 'wppb_check_yim_value', 10, 4 ); - -/* handle field save */ -function wppb_userdata_add_yim( $userdata, $global_request ){ - if ( isset( $global_request['yim'] ) ) - $userdata['yim'] = sanitize_text_field( trim( $global_request['yim'] ) ); - - return $userdata; -} +*' : '' ); + + if ( array_key_exists( $field['id'], $field_check_errors ) ) + $error_mark = ''; + + $extra_attr = apply_filters( 'wppb_extra_attribute', '', $field, $form_location ); + + $output = ' + + '; + if( !empty( $item_description ) ) + $output .= ''. $item_description .''; + + } + + return apply_filters( 'wppb_'.$form_location.'_yim', $output, $form_location, $field, $user_id, $field_check_errors, $request_data ); +} +add_filter( 'wppb_output_form_field_default-yahoo-im', 'wppb_yim_handler', 10, 6 ); + + +/* handle field validation */ +function wppb_check_yim_value( $message, $field, $request_data, $form_location ){ + if( $field['required'] == 'Yes' ){ + if( ( isset( $request_data['yim'] ) && ( trim( $request_data['yim'] ) == '' ) ) || !isset( $request_data['yim'] ) ){ + return wppb_required_field_error($field["field-title"]); + } + } + + return $message; +} +add_filter( 'wppb_check_form_field_default-yahoo-im', 'wppb_check_yim_value', 10, 4 ); + +/* handle field save */ +function wppb_userdata_add_yim( $userdata, $global_request ){ + if ( isset( $global_request['yim'] ) ) + $userdata['yim'] = sanitize_text_field( trim( $global_request['yim'] ) ); + + return $userdata; +} add_filter( 'wppb_build_userdata', 'wppb_userdata_add_yim', 10, 2 ); \ No newline at end of file diff --git a/profile-builder/front-end/edit-profile.php b/profile-builder/front-end/edit-profile.php index a0c07e2..583f4f5 100644 --- a/profile-builder/front-end/edit-profile.php +++ b/profile-builder/front-end/edit-profile.php @@ -1,74 +1,74 @@ - 'edit_profile', 'form_fields' => array(), 'form_name' => sanitize_text_field( $_POST['form_name'] ), 'role' => '', 'ID' => Profile_Builder_Form_Creator::wppb_get_form_id_from_form_name( sanitize_text_field( $_POST['form_name'] ), 'edit_profile' ), 'context' => 'edit_profile_auto_login_after_password_change' ) ); - if( !empty( $form_fields ) ){ - - /* check for errors in the form through the filters */ - $output_field_errors = array(); - foreach( $form_fields as $field ){ - $error_for_field = apply_filters( 'wppb_check_form_field_'.Wordpress_Creation_Kit_PB::wck_generate_slug( $field['field'] ), '', $field, $_POST, 'edit_profile' ); - if( !empty( $error_for_field ) ) - $output_field_errors[$field['id']] = '' . $error_for_field . ''; - } - - /* if we have no errors change the password */ - if( empty( $output_field_errors ) ) { - - $user_id = get_current_user_id(); - if( ( !is_multisite() && current_user_can( 'edit_users' ) ) || ( is_multisite() && current_user_can( 'manage_network' ) ) ) { - if( isset( $_GET['edit_user'] ) && ! empty( $_GET['edit_user'] ) ){ - $user_id = absint( $_GET['edit_user'] ); - } - } - - if( !isset( $_GET['edit_user'] ) ) { - wp_clear_auth_cookie(); - /* set the new password for the user */ - wp_set_password($_POST['passw1'], $user_id); - // Here we calculate the expiration length of the current auth cookie and compare it to the default expiration. - // If it's greater than this, then we know the user checked 'Remember Me' when they logged in. - $logged_in_cookie = wp_parse_auth_cookie('', 'logged_in'); - /** This filter is documented in wp-includes/pluggable.php */ - $default_cookie_life = apply_filters('auth_cookie_expiration', (2 * DAY_IN_SECONDS), $user_id, false); - $remember = (($logged_in_cookie['expiration'] - time()) > $default_cookie_life); - - wp_set_auth_cookie($user_id, $remember); - } - else{ - wp_set_password($_POST['passw1'], $user_id); - } - } - } - } - } -} - - -function wppb_front_end_profile_info( $atts ){ - // get value set in the shortcode as parameter, still need to default to something else than empty string - extract( shortcode_atts( array( 'form_name' => 'unspecified', 'redirect_url' => '', 'redirect_priority' => 'normal' ), $atts, 'wppb-edit-profile' ) ); - - global ${$form_name}; - - $$form_name = new Profile_Builder_Form_Creator( array( 'form_type' => 'edit_profile', 'form_name' => $form_name, 'redirect_url' => $redirect_url, 'redirect_priority' => $redirect_priority ) ); - - return $$form_name; + 'edit_profile', 'form_fields' => array(), 'form_name' => sanitize_text_field( $_POST['form_name'] ), 'role' => '', 'ID' => Profile_Builder_Form_Creator::wppb_get_form_id_from_form_name( sanitize_text_field( $_POST['form_name'] ), 'edit_profile' ), 'context' => 'edit_profile_auto_login_after_password_change' ) ); + if( !empty( $form_fields ) ){ + + /* check for errors in the form through the filters */ + $output_field_errors = array(); + foreach( $form_fields as $field ){ + $error_for_field = apply_filters( 'wppb_check_form_field_'.Wordpress_Creation_Kit_PB::wck_generate_slug( $field['field'] ), '', $field, $_POST, 'edit_profile' ); + if( !empty( $error_for_field ) ) + $output_field_errors[$field['id']] = '' . $error_for_field . ''; + } + + /* if we have no errors change the password */ + if( empty( $output_field_errors ) ) { + + $user_id = get_current_user_id(); + if( ( !is_multisite() && current_user_can( 'edit_users' ) ) || ( is_multisite() && current_user_can( 'manage_network' ) ) ) { + if( isset( $_GET['edit_user'] ) && ! empty( $_GET['edit_user'] ) ){ + $user_id = absint( $_GET['edit_user'] ); + } + } + + if( !isset( $_GET['edit_user'] ) ) { + wp_clear_auth_cookie(); + /* set the new password for the user */ + wp_set_password($_POST['passw1'], $user_id); + // Here we calculate the expiration length of the current auth cookie and compare it to the default expiration. + // If it's greater than this, then we know the user checked 'Remember Me' when they logged in. + $logged_in_cookie = wp_parse_auth_cookie('', 'logged_in'); + /** This filter is documented in wp-includes/pluggable.php */ + $default_cookie_life = apply_filters('auth_cookie_expiration', (2 * DAY_IN_SECONDS), $user_id, false); + $remember = (($logged_in_cookie['expiration'] - time()) > $default_cookie_life); + + wp_set_auth_cookie($user_id, $remember); + } + else{ + wp_set_password($_POST['passw1'], $user_id); + } + } + } + } + } +} + + +function wppb_front_end_profile_info( $atts ){ + // get value set in the shortcode as parameter, still need to default to something else than empty string + extract( shortcode_atts( array( 'form_name' => 'unspecified', 'redirect_url' => '', 'redirect_priority' => 'normal' ), $atts, 'wppb-edit-profile' ) ); + + global ${$form_name}; + + $$form_name = new Profile_Builder_Form_Creator( array( 'form_type' => 'edit_profile', 'form_name' => $form_name, 'redirect_url' => $redirect_url, 'redirect_priority' => $redirect_priority ) ); + + return $$form_name; } \ No newline at end of file diff --git a/profile-builder/front-end/login.php b/profile-builder/front-end/login.php index 0654485..8912534 100644 --- a/profile-builder/front-end/login.php +++ b/profile-builder/front-end/login.php @@ -1,302 +1,302 @@ -'; - $form_part .= ''; - - $form_part .= ''; - $form_part .= ''; - $form_part .= ''; - $form_part .= ''; - } - - return $form_part; -} -add_filter( 'login_form_bottom', 'wppb_login_form_bottom', 10, 2 ); - -// when email login is enabled we need to change the post data for the username -function wppb_change_login_with_email(){ - if( !empty( $_POST['log'] ) ){ - // only do this for our form - if( isset( $_POST['wppb_login'] ) ){ - global $wpdb, $_POST, $wp_version; - // apply filter to allow stripping slashes if necessary - $_POST['log'] = apply_filters( 'wppb_before_processing_email_from_forms', $_POST['log'] ); - - /* since version 4.5 there is in the core the option to login with email so we don't need the bellow code but for backward compatibility we will keep it */ - if( version_compare( $wp_version, '4.5.0' ) >= 0 ) - return; - - $wppb_generalSettings = get_option( 'wppb_general_settings' ); - - // if this setting is active, the posted username is, in fact the user's email - if( isset( $wppb_generalSettings['loginWith'] ) && ( $wppb_generalSettings['loginWith'] == 'email' ) ){ - $username = $wpdb->get_var( $wpdb->prepare( "SELECT user_login FROM $wpdb->users WHERE user_email= %s LIMIT 1", sanitize_email( $_POST['log'] ) ) ); - - if( !empty( $username ) ) - $_POST['log'] = $username; - - else { - // if we don't have a username for the email entered we can't have an empty username because we will receive a field empty error - $_POST['log'] = 'this_is_an_invalid_email'.time(); - } - } - - // if this setting is active, the posted username is, in fact the user's email or username - if( isset( $wppb_generalSettings['loginWith'] ) && ( $wppb_generalSettings['loginWith'] == 'usernameemail' ) ) { - if( is_email( $_POST['log'] ) ) { - $username = $wpdb->get_var( $wpdb->prepare( "SELECT user_login FROM $wpdb->users WHERE user_email= %s LIMIT 1", sanitize_email( $_POST['log'] ) ) ); - } else { - $username = $_POST['log']; - } - - if( !empty( $username ) ) - $_POST['log'] = $username; - - else { - // if we don't have a username for the email entered we can't have an empty username because we will receive a field empty error - $_POST['log'] = 'this_is_an_invalid_email'.time(); - } - } - } - } -} -add_action( 'login_init', 'wppb_change_login_with_email' ); - -/** - * Remove email login when username login is selected - * inspiration from https://wordpress.org/plugins/no-login-by-email-address/ - */ -$wppb_generalSettings = get_option( 'wppb_general_settings' ); -if( isset( $wppb_generalSettings['loginWith'] ) && ( $wppb_generalSettings['loginWith'] == 'username' ) ) { - function wppb_login_username_label() - { - add_filter('gettext', 'wppb_login_username_label_change', 20, 3); - function wppb_login_username_label_change($translated_text, $text, $domain) - { - if ($text === 'Username or Email') { - $translated_text = __( 'Username', 'profile-builder' ); - } - return $translated_text; - } - } - - add_action('login_head', 'wppb_login_username_label'); - - /** - * Filter wp_login_form username default - * - */ - function wppb_change_login_username_label($defaults) - { - $defaults['label_username'] = __( 'Username', 'profile-builder' ); - return $defaults; - } - - add_filter('login_form_defaults', 'wppb_change_login_username_label'); - - /** - * Remove email/password authentication - * - */ - remove_filter('authenticate', 'wp_authenticate_email_password', 20); -} - -// login redirect filter. used to redirect from wp-login.php if it errors out -function wppb_login_redirect( $redirect_to, $requested_redirect_to, $user ){ - // if login action initialized by our form - if( isset( $_POST['wppb_login'] ) ){ - if( is_wp_error( $user ) ) { - // if we don't have a successful login we must redirect to the url of the form, so make sure this happens - $redirect_to = esc_url_raw( $_POST['wppb_request_url'] ); - $request_form_location = sanitize_text_field( $_POST['wppb_form_location'] ); - $error_string = $user->get_error_message(); - - $wppb_generalSettings = get_option('wppb_general_settings'); - - if (isset($wppb_generalSettings['loginWith'])) { - $LostPassURL = site_url('/wp-login.php?action=lostpassword'); - - // if the Login shortcode has a lostpassword argument set, give the lost password error link that value - if (!empty($_POST['wppb_lostpassword_url'])) { - if ( wppb_check_missing_http( $_POST['wppb_lostpassword_url'] ) ) $LostPassURL = "http://" . $_POST['wppb_lostpassword_url']; - else $LostPassURL = $_POST['wppb_lostpassword_url']; - } - - //apply filter to allow changing Lost your Password link - $LostPassURL = apply_filters('wppb_pre_login_url_filter', $LostPassURL); - - if ($user->get_error_code() == 'incorrect_password') { - $error_string = '' . __('ERROR', 'profile-builder') . ': ' . __('The password you entered is incorrect.', 'profile-builder') . ' '; - $error_string .= '' . __('Lost your password', 'profile-builder') . '?'; - - // change the recover password link - $error_string = str_replace(site_url('/wp-login.php?action=lostpassword'), $LostPassURL, $error_string); - } - if ($user->get_error_code() == 'invalid_username') { - $error_string = '' . __('ERROR', 'profile-builder') . ': ' . __('Invalid username.', 'profile-builder') . ' '; - $error_string .= '' . __('Lost your password', 'profile-builder') . '?'; - } - // if login with email is enabled change the word username with email - if ($wppb_generalSettings['loginWith'] == 'email') - $error_string = str_replace( __('username','profile-builder'), __('email','profile-builder'), $error_string); - - // if login with username and email is enabled change the word username with username or email - if ($wppb_generalSettings['loginWith'] == 'usernameemail') - $error_string = str_replace( __('username','profile-builder'), __('username or email','profile-builder'), $error_string); - - } - // if the error string is empty it means that none of the fields were completed - if (empty($error_string)) { - $error_string = '' . __('ERROR', 'profile-builder') . ': ' . __('Both fields are empty.', 'profile-builder') . ' '; - $error_string = apply_filters('wppb_login_empty_fields_error_message', $error_string); - } - - $error_string = apply_filters('wppb_login_wp_error_message', $error_string, $user); - - // encode the error string and send it as a GET parameter - $arr_params = array('loginerror' => urlencode(base64_encode($error_string)), 'request_form_location' => $request_form_location); - $redirect_to = add_query_arg($arr_params, $redirect_to); - wp_safe_redirect($redirect_to); - } - else{ - // we don't have an error make sure to remove the error from the query arg - $redirect_to = remove_query_arg( 'loginerror', $redirect_to ); - - // CHECK FOR REDIRECT - $redirect_to = wppb_get_redirect_url( sanitize_text_field( $_POST['wppb_redirect_priority'] ), 'after_login', $redirect_to, $user ); - $redirect_to = apply_filters( 'wppb_after_login_redirect_url', $redirect_to ); - } - } - - return $redirect_to; -} -add_filter( 'login_redirect', 'wppb_login_redirect', 10, 3 ); - - -/* shortcode function */ -function wppb_front_end_login( $atts ){ - /* define a global so we now we have the shortcode login present */ - global $wppb_login_shortcode; - $wppb_login_shortcode = true; - - extract( shortcode_atts( array( 'display' => true, 'redirect' => '', 'redirect_url' => '', 'logout_redirect_url' => wppb_curpageurl(), 'register_url' => '', 'lostpassword_url' => '', 'redirect_priority' => 'normal' ), $atts ) ); - - $wppb_generalSettings = get_option('wppb_general_settings'); - - if( !is_user_logged_in() ){ - // set up the form arguments - $form_args = array( 'echo' => false, 'id_submit' => 'wppb-submit' ); - - // maybe set up the redirect argument - if( ! empty( $redirect ) ) { - $redirect_url = $redirect; - } - - if ( ! empty( $redirect_url ) ) { - if( $redirect_priority == 'top' ) { - $form_args['redirect_priority'] = 'top'; - } else { - $form_args['redirect_priority'] = 'normal'; - } - - $form_args['redirect'] = trim( $redirect_url ); - } - - // change the label argument for username is login with email is enabled - if ( isset( $wppb_generalSettings['loginWith'] ) && ( $wppb_generalSettings['loginWith'] == 'email' ) ) - $form_args['label_username'] = __( 'Email', 'profile-builder' ); - - if ( isset( $wppb_generalSettings['loginWith'] ) && ( $wppb_generalSettings['loginWith'] == 'username' ) ) - $form_args['label_username'] = __( 'Username', 'profile-builder' ); - - // change the label argument for username on login with username or email when Username and Email is enabled - if ( isset( $wppb_generalSettings['loginWith'] ) && ( $wppb_generalSettings['loginWith'] == 'usernameemail' ) ) - $form_args['label_username'] = __( 'Username or Email', 'profile-builder' ); - - // initialize our form variable - $login_form = ''; - - // display our login errors - if( isset( $_GET['loginerror'] ) || isset( $_POST['loginerror'] ) ){ - $loginerror = isset( $_GET['loginerror'] ) ? $_GET['loginerror'] : $_POST['loginerror']; - $loginerror = '

            '. preg_replace('#<(.*?)script(.*?)>(.*?)#is', '', urldecode( base64_decode( $loginerror ) ) ) .'

            '; - if( isset( $_GET['request_form_location'] ) ){ - if( $_GET['request_form_location'] == 'widget' && !in_the_loop() ){ - $login_form .= $loginerror; - } - elseif( $_GET['request_form_location'] == 'page' && in_the_loop() ){ - $login_form .= $loginerror; - } - } - } - // build our form - $login_form .= '
            '; - $form_args['lostpassword_url'] = $lostpassword_url; - $login_form .= wp_login_form( apply_filters( 'wppb_login_form_args', $form_args ) ); - - if ((!empty($register_url)) || (!empty($lostpassword_url))) { - $login_form .= ''; - } - - $login_form .= apply_filters( 'wppb_login_form_bottom', '', $form_args ); - - $login_form .= '
            '; - return $login_form; - - }else{ - $user_ID = get_current_user_id(); - $wppb_user = get_userdata( $user_ID ); - - if( isset( $wppb_generalSettings['loginWith'] ) && ( $wppb_generalSettings['loginWith'] == 'email' ) ) - $display_name = $wppb_user->user_email; - - elseif($wppb_user->display_name !== '') - $display_name = $wppb_user->user_login; - - else - $display_name = $wppb_user->display_name; - - if( isset( $wppb_generalSettings['loginWith'] ) && ( $wppb_generalSettings['loginWith'] == 'usernameemail' ) ) - if( $wppb_user->user_login == Wordpress_Creation_Kit_PB::wck_generate_slug( trim( $wppb_user->user_email ) ) ) - $display_name = $wppb_user->user_email; - - elseif($wppb_user->display_name !== '') - $display_name = $wppb_user->user_login; - - else - $display_name = $wppb_user->display_name; - - $logged_in_message = '

            '; - - // CHECK FOR REDIRECT - $logout_redirect_url = wppb_get_redirect_url( $redirect_priority, 'after_logout', $logout_redirect_url, $wppb_user ); - $logout_redirect_url = apply_filters( 'wppb_after_logout_redirect_url', $logout_redirect_url ); - - $logout_url = ''. __( 'Log out', 'profile-builder').' »'; - $logged_in_message .= sprintf(__( 'You are currently logged in as %1$s. %2$s', 'profile-builder' ), $display_name, $logout_url ); - - $logged_in_message .= '

            '; - - return apply_filters( 'wppb_login_message', $logged_in_message, $wppb_user->ID, $display_name ); - } +'; + $form_part .= ''; + + $form_part .= ''; + $form_part .= ''; + $form_part .= ''; + $form_part .= ''; + } + + return $form_part; +} +add_filter( 'login_form_bottom', 'wppb_login_form_bottom', 10, 2 ); + +// when email login is enabled we need to change the post data for the username +function wppb_change_login_with_email(){ + if( !empty( $_POST['log'] ) ){ + // only do this for our form + if( isset( $_POST['wppb_login'] ) ){ + global $wpdb, $_POST, $wp_version; + // apply filter to allow stripping slashes if necessary + $_POST['log'] = apply_filters( 'wppb_before_processing_email_from_forms', $_POST['log'] ); + + /* since version 4.5 there is in the core the option to login with email so we don't need the bellow code but for backward compatibility we will keep it */ + if( version_compare( $wp_version, '4.5.0' ) >= 0 ) + return; + + $wppb_generalSettings = get_option( 'wppb_general_settings' ); + + // if this setting is active, the posted username is, in fact the user's email + if( isset( $wppb_generalSettings['loginWith'] ) && ( $wppb_generalSettings['loginWith'] == 'email' ) ){ + $username = $wpdb->get_var( $wpdb->prepare( "SELECT user_login FROM $wpdb->users WHERE user_email= %s LIMIT 1", sanitize_email( $_POST['log'] ) ) ); + + if( !empty( $username ) ) + $_POST['log'] = $username; + + else { + // if we don't have a username for the email entered we can't have an empty username because we will receive a field empty error + $_POST['log'] = 'this_is_an_invalid_email'.time(); + } + } + + // if this setting is active, the posted username is, in fact the user's email or username + if( isset( $wppb_generalSettings['loginWith'] ) && ( $wppb_generalSettings['loginWith'] == 'usernameemail' ) ) { + if( is_email( $_POST['log'] ) ) { + $username = $wpdb->get_var( $wpdb->prepare( "SELECT user_login FROM $wpdb->users WHERE user_email= %s LIMIT 1", sanitize_email( $_POST['log'] ) ) ); + } else { + $username = $_POST['log']; + } + + if( !empty( $username ) ) + $_POST['log'] = $username; + + else { + // if we don't have a username for the email entered we can't have an empty username because we will receive a field empty error + $_POST['log'] = 'this_is_an_invalid_email'.time(); + } + } + } + } +} +add_action( 'login_init', 'wppb_change_login_with_email' ); + +/** + * Remove email login when username login is selected + * inspiration from https://wordpress.org/plugins/no-login-by-email-address/ + */ +$wppb_generalSettings = get_option( 'wppb_general_settings' ); +if( isset( $wppb_generalSettings['loginWith'] ) && ( $wppb_generalSettings['loginWith'] == 'username' ) ) { + function wppb_login_username_label() + { + add_filter('gettext', 'wppb_login_username_label_change', 20, 3); + function wppb_login_username_label_change($translated_text, $text, $domain) + { + if ($text === 'Username or Email') { + $translated_text = __( 'Username', 'profile-builder' ); + } + return $translated_text; + } + } + + add_action('login_head', 'wppb_login_username_label'); + + /** + * Filter wp_login_form username default + * + */ + function wppb_change_login_username_label($defaults) + { + $defaults['label_username'] = __( 'Username', 'profile-builder' ); + return $defaults; + } + + add_filter('login_form_defaults', 'wppb_change_login_username_label'); + + /** + * Remove email/password authentication + * + */ + remove_filter('authenticate', 'wp_authenticate_email_password', 20); +} + +// login redirect filter. used to redirect from wp-login.php if it errors out +function wppb_login_redirect( $redirect_to, $requested_redirect_to, $user ){ + // if login action initialized by our form + if( isset( $_POST['wppb_login'] ) ){ + if( is_wp_error( $user ) ) { + // if we don't have a successful login we must redirect to the url of the form, so make sure this happens + $redirect_to = esc_url_raw( $_POST['wppb_request_url'] ); + $request_form_location = sanitize_text_field( $_POST['wppb_form_location'] ); + $error_string = $user->get_error_message(); + + $wppb_generalSettings = get_option('wppb_general_settings'); + + if (isset($wppb_generalSettings['loginWith'])) { + $LostPassURL = site_url('/wp-login.php?action=lostpassword'); + + // if the Login shortcode has a lostpassword argument set, give the lost password error link that value + if (!empty($_POST['wppb_lostpassword_url'])) { + if ( wppb_check_missing_http( $_POST['wppb_lostpassword_url'] ) ) $LostPassURL = "http://" . $_POST['wppb_lostpassword_url']; + else $LostPassURL = $_POST['wppb_lostpassword_url']; + } + + //apply filter to allow changing Lost your Password link + $LostPassURL = apply_filters('wppb_pre_login_url_filter', $LostPassURL); + + if ($user->get_error_code() == 'incorrect_password') { + $error_string = '' . __('ERROR', 'profile-builder') . ': ' . __('The password you entered is incorrect.', 'profile-builder') . ' '; + $error_string .= '' . __('Lost your password', 'profile-builder') . '?'; + + // change the recover password link + $error_string = str_replace(site_url('/wp-login.php?action=lostpassword'), $LostPassURL, $error_string); + } + if ($user->get_error_code() == 'invalid_username') { + $error_string = '' . __('ERROR', 'profile-builder') . ': ' . __('Invalid username.', 'profile-builder') . ' '; + $error_string .= '' . __('Lost your password', 'profile-builder') . '?'; + } + // if login with email is enabled change the word username with email + if ($wppb_generalSettings['loginWith'] == 'email') + $error_string = str_replace( __('username','profile-builder'), __('email','profile-builder'), $error_string); + + // if login with username and email is enabled change the word username with username or email + if ($wppb_generalSettings['loginWith'] == 'usernameemail') + $error_string = str_replace( __('username','profile-builder'), __('username or email','profile-builder'), $error_string); + + } + // if the error string is empty it means that none of the fields were completed + if (empty($error_string)) { + $error_string = '' . __('ERROR', 'profile-builder') . ': ' . __('Both fields are empty.', 'profile-builder') . ' '; + $error_string = apply_filters('wppb_login_empty_fields_error_message', $error_string); + } + + $error_string = apply_filters('wppb_login_wp_error_message', $error_string, $user); + + // encode the error string and send it as a GET parameter + $arr_params = array('loginerror' => urlencode(base64_encode($error_string)), 'request_form_location' => $request_form_location); + $redirect_to = add_query_arg($arr_params, $redirect_to); + wp_safe_redirect($redirect_to); + } + else{ + // we don't have an error make sure to remove the error from the query arg + $redirect_to = remove_query_arg( 'loginerror', $redirect_to ); + + // CHECK FOR REDIRECT + $redirect_to = wppb_get_redirect_url( sanitize_text_field( $_POST['wppb_redirect_priority'] ), 'after_login', $redirect_to, $user ); + $redirect_to = apply_filters( 'wppb_after_login_redirect_url', $redirect_to ); + } + } + + return $redirect_to; +} +add_filter( 'login_redirect', 'wppb_login_redirect', 10, 3 ); + + +/* shortcode function */ +function wppb_front_end_login( $atts ){ + /* define a global so we now we have the shortcode login present */ + global $wppb_login_shortcode; + $wppb_login_shortcode = true; + + extract( shortcode_atts( array( 'display' => true, 'redirect' => '', 'redirect_url' => '', 'logout_redirect_url' => wppb_curpageurl(), 'register_url' => '', 'lostpassword_url' => '', 'redirect_priority' => 'normal' ), $atts ) ); + + $wppb_generalSettings = get_option('wppb_general_settings'); + + if( !is_user_logged_in() ){ + // set up the form arguments + $form_args = array( 'echo' => false, 'id_submit' => 'wppb-submit' ); + + // maybe set up the redirect argument + if( ! empty( $redirect ) ) { + $redirect_url = $redirect; + } + + if ( ! empty( $redirect_url ) ) { + if( $redirect_priority == 'top' ) { + $form_args['redirect_priority'] = 'top'; + } else { + $form_args['redirect_priority'] = 'normal'; + } + + $form_args['redirect'] = trim( $redirect_url ); + } + + // change the label argument for username is login with email is enabled + if ( isset( $wppb_generalSettings['loginWith'] ) && ( $wppb_generalSettings['loginWith'] == 'email' ) ) + $form_args['label_username'] = __( 'Email', 'profile-builder' ); + + if ( isset( $wppb_generalSettings['loginWith'] ) && ( $wppb_generalSettings['loginWith'] == 'username' ) ) + $form_args['label_username'] = __( 'Username', 'profile-builder' ); + + // change the label argument for username on login with username or email when Username and Email is enabled + if ( isset( $wppb_generalSettings['loginWith'] ) && ( $wppb_generalSettings['loginWith'] == 'usernameemail' ) ) + $form_args['label_username'] = __( 'Username or Email', 'profile-builder' ); + + // initialize our form variable + $login_form = ''; + + // display our login errors + if( isset( $_GET['loginerror'] ) || isset( $_POST['loginerror'] ) ){ + $loginerror = isset( $_GET['loginerror'] ) ? $_GET['loginerror'] : $_POST['loginerror']; + $loginerror = '

            '. preg_replace('#<(.*?)script(.*?)>(.*?)#is', '', urldecode( base64_decode( $loginerror ) ) ) .'

            '; + if( isset( $_GET['request_form_location'] ) ){ + if( $_GET['request_form_location'] == 'widget' && !in_the_loop() ){ + $login_form .= $loginerror; + } + elseif( $_GET['request_form_location'] == 'page' && in_the_loop() ){ + $login_form .= $loginerror; + } + } + } + // build our form + $login_form .= '
            '; + $form_args['lostpassword_url'] = $lostpassword_url; + $login_form .= wp_login_form( apply_filters( 'wppb_login_form_args', $form_args ) ); + + if ((!empty($register_url)) || (!empty($lostpassword_url))) { + $login_form .= ''; + } + + $login_form .= apply_filters( 'wppb_login_form_bottom', '', $form_args ); + + $login_form .= '
            '; + return $login_form; + + }else{ + $user_ID = get_current_user_id(); + $wppb_user = get_userdata( $user_ID ); + + if( isset( $wppb_generalSettings['loginWith'] ) && ( $wppb_generalSettings['loginWith'] == 'email' ) ) + $display_name = $wppb_user->user_email; + + elseif($wppb_user->display_name !== '') + $display_name = $wppb_user->user_login; + + else + $display_name = $wppb_user->display_name; + + if( isset( $wppb_generalSettings['loginWith'] ) && ( $wppb_generalSettings['loginWith'] == 'usernameemail' ) ) + if( $wppb_user->user_login == Wordpress_Creation_Kit_PB::wck_generate_slug( trim( $wppb_user->user_email ) ) ) + $display_name = $wppb_user->user_email; + + elseif($wppb_user->display_name !== '') + $display_name = $wppb_user->user_login; + + else + $display_name = $wppb_user->display_name; + + $logged_in_message = '

            '; + + // CHECK FOR REDIRECT + $logout_redirect_url = wppb_get_redirect_url( $redirect_priority, 'after_logout', $logout_redirect_url, $wppb_user ); + $logout_redirect_url = apply_filters( 'wppb_after_logout_redirect_url', $logout_redirect_url ); + + $logout_url = ''. __( 'Log out', 'profile-builder').' »'; + $logged_in_message .= sprintf(__( 'You are currently logged in as %1$s. %2$s', 'profile-builder' ), $display_name, $logout_url ); + + $logged_in_message .= '

            '; + + return apply_filters( 'wppb_login_message', $logged_in_message, $wppb_user->ID, $display_name ); + } } \ No newline at end of file diff --git a/profile-builder/front-end/logout.php b/profile-builder/front-end/logout.php index f968a9f..56872f7 100644 --- a/profile-builder/front-end/logout.php +++ b/profile-builder/front-end/logout.php @@ -1,33 +1,33 @@ - sprintf( __('You are currently logged in as %s. ','profile-builder') ,$current_user->user_login) , 'redirect' => '', 'redirect_url' => wppb_curpageurl(), 'redirect_priority' => 'normal', 'link_text' => __('Log out »','profile-builder')), $atts ) ); - - if( ! empty( $redirect ) ) { - $redirect_url = $redirect; - } - - // CHECK FOR REDIRECT - $redirect_url = wppb_get_redirect_url( $redirect_priority, 'after_logout', $redirect_url, $current_user ); - $redirect_url = apply_filters( 'wppb_after_logout_redirect_url', $redirect_url ); - - $logout_link = '' . $link_text . ''; - - $meta_tags = apply_filters( 'wppb_front_end_logout_meta_tags', array( '{{meta_user_name}}', '{{meta_first_name}}', '{{meta_last_name}}', '{{meta_display_name}}' ) ); - $meta_tags_values = apply_filters( 'wppb_front_end_logout_meta_tags_values', array( $current_user->user_login, $current_user->first_name, $current_user->last_name, $current_user->display_name ) ); - - $text = apply_filters( 'wppb_front_end_logout_text', str_replace( $meta_tags, $meta_tags_values, $text ), $current_user ); - - return '

            ' . $text . '' . $logout_link . '

            '; + sprintf( __('You are currently logged in as %s. ','profile-builder') ,$current_user->user_login) , 'redirect' => '', 'redirect_url' => wppb_curpageurl(), 'redirect_priority' => 'normal', 'link_text' => __('Log out »','profile-builder')), $atts ) ); + + if( ! empty( $redirect ) ) { + $redirect_url = $redirect; + } + + // CHECK FOR REDIRECT + $redirect_url = wppb_get_redirect_url( $redirect_priority, 'after_logout', $redirect_url, $current_user ); + $redirect_url = apply_filters( 'wppb_after_logout_redirect_url', $redirect_url ); + + $logout_link = '' . $link_text . ''; + + $meta_tags = apply_filters( 'wppb_front_end_logout_meta_tags', array( '{{meta_user_name}}', '{{meta_first_name}}', '{{meta_last_name}}', '{{meta_display_name}}' ) ); + $meta_tags_values = apply_filters( 'wppb_front_end_logout_meta_tags_values', array( $current_user->user_login, $current_user->first_name, $current_user->last_name, $current_user->display_name ) ); + + $text = apply_filters( 'wppb_front_end_logout_text', str_replace( $meta_tags, $meta_tags_values, $text ), $current_user ); + + return '

            ' . $text . '' . $logout_link . '

            '; } \ No newline at end of file diff --git a/profile-builder/front-end/recover.php b/profile-builder/front-end/recover.php index e55b2c2..77a54df 100644 --- a/profile-builder/front-end/recover.php +++ b/profile-builder/front-end/recover.php @@ -1,395 +1,395 @@ -data->ID, 'user_status' ) ){ - $retMessage = ''. __('ERROR', 'profile-builder') . ': ' . __('Your account has to be confirmed by an administrator before you can use the "Password Reset" feature.', 'profile-builder'); - $retMessage = apply_filters('wppb_recover_password_unapporved_user', $retMessage); - - $messageNo = '6'; - } - } - - return array( $retMessage, $messageNo ); -} - -/** - * Function that retrieves the unique user key from the database. If we don't have one we generate one and add it to the database - * - * @param string $requested_user_login the user login - * - */ -function wppb_retrieve_activation_key( $requested_user_login ){ - global $wpdb; - - $key = $wpdb->get_var( $wpdb->prepare( "SELECT user_activation_key FROM $wpdb->users WHERE user_login = %s", $requested_user_login ) ); - - if ( empty( $key ) ) { - - // Generate something random for a key... - $key = wp_generate_password( 20, false ); - do_action('wppb_retrieve_password_key', $requested_user_login, $key); - - // Now insert the new md5 key into the db - $wpdb->update($wpdb->users, array('user_activation_key' => $key), array('user_login' => $requested_user_login)); - } - - return $key; -} - - /** - * Function that creates a generate new password form - * - * @param array $post_data $_POST - * - */ -function wppb_create_recover_password_form( $user, $post_data ){ - ?> -
            -
              - - - - - -
            • - - -
            • '; - - /* if we have active the password strength checker */ - $recover_inputPassword .= wppb_password_strength_checker_html(); - - echo apply_filters( 'wppb_recover_password_form_input', $recover_inputPassword, $passw_one, $passw_two, $user->ID ); -?> -
            -

            - - " value="" /> - -

            - ID, 'password_recovery_nonce_field2' ); ?> - - -
            - ' . __( 'Please enter your username or email address.', 'profile-builder' ); - $recover_notification .= '
            '.__( 'You will receive a link to create a new password via email.', 'profile-builder' ).'

            '; - echo apply_filters( 'wppb_recover_password_message1', $recover_notification ); - - $username_email = ( isset( $post_data['username_email'] ) ? $post_data['username_email'] : '' ); - - $username_email_label = __( 'Username or E-mail', 'profile-builder' ); - - $recover_input = '
              -
            • - - -
            '; - echo apply_filters( 'wppb_recover_password_generate_password_input', $recover_input, trim( $username_email ) ); - ?> -

            - - - -

            - - - get_results( $wpdb->prepare( "SELECT * FROM $wpdb->users WHERE user_login= %s", $postedData ) ); - if( !empty( $query[0] ) ){ - $postedData = $query[0]->user_email; - } - } - else{ - $message = __( 'The username entered wasn\'t found in the database!', 'profile-builder').'
            '.__('Please check that you entered the correct username.', 'profile-builder' ); - $message = apply_filters( 'wppb_recover_password_sent_message4', $message ); - $messageNo = '4'; - } - } - - // we should have an email by this point - if ( is_email( $postedData ) ){ - if ( email_exists( $postedData ) ){ - $retVal = wppb_check_for_unapproved_user($postedData, 'user_email'); - if ($retVal[0] != ''){ - $message = $retVal[0]; - $messageNo = $retVal [1]; - - }else{ - $message = sprintf( __( 'Check your e-mail for the confirmation link.', 'profile-builder'), $postedData ); - $message = apply_filters( 'wppb_recover_password_sent_message1', $message, $postedData ); - $messageNo = '1'; - - } - - }elseif ( !email_exists( $postedData ) ){ - $message = __('The email address entered wasn\'t found in the database!', 'profile-builder').'
            '.__('Please check that you entered the correct email address.', 'profile-builder'); - $message = apply_filters('wppb_recover_password_sent_message2', $message); - $messageNo = '2'; - } - } - - // For some extra validations you can filter messageNo - $messageNo = apply_filters( 'wppb_recover_password_message_no', $messageNo ); - - if( $messageNo == '1' ) { - - //verify e-mail validity - $query = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->users WHERE user_email= %s", sanitize_email( $postedData ) ) ); - if( !empty( $query[0] ) ){ - $requestedUserID = $query[0]->ID; - $requestedUserLogin = $query[0]->user_login; - $requestedUserEmail = $query[0]->user_email; - $requestedUserNicename = $query[0]->user_nicename; - - if( $wppb_generalSettings['loginWith'] == 'username' || $wppb_generalSettings['loginWith'] == 'usernameemail' ) - $display_username_email = $query[0]->user_login; - else - $display_username_email = $query[0]->user_email; - - //search if there is already an activation key present, if not create one - $key = wppb_retrieve_activation_key( $requestedUserLogin ); - - //send primary email message - $recoveruserMailMessage1 = sprintf( __('Someone requested that the password be reset for the following account: %1$s
            If this was a mistake, just ignore this email and nothing will happen.
            To reset your password, visit the following link:%2$s', 'profile-builder'), $display_username_email, ''.esc_url( add_query_arg( array( 'loginName' => $requestedUserNicename, 'key' => $key ), wppb_curpageurl() ) ).''); - $recoveruserMailMessage1 = apply_filters( 'wppb_recover_password_message_content_sent_to_user1', $recoveruserMailMessage1, $requestedUserID, $requestedUserLogin, $requestedUserEmail ); - - $recoveruserMailMessageTitle1 = sprintf(__('Password Reset from "%1$s"', 'profile-builder'), $blogname = get_option('blogname') ); - $recoveruserMailMessageTitle1 = apply_filters('wppb_recover_password_message_title_sent_to_user1', $recoveruserMailMessageTitle1, $requestedUserLogin); - - //send mail to the user notifying him of the reset request - if (trim($recoveruserMailMessageTitle1) != ''){ - $sent = wppb_mail($requestedUserEmail, $recoveruserMailMessageTitle1, $recoveruserMailMessage1); - if ($sent === false){ - $message = ''. __( 'ERROR', 'profile-builder' ) .': ' . sprintf( __( 'There was an error while trying to send the activation link to %1$s!', 'profile-builder' ), $postedData ); - $message = apply_filters( 'wppb_recover_password_sent_message_error_sending', $message ); - $messageNo = '5'; - } - } - } - - } - - } - // If the user used the correct key-code, update his/her password - elseif ( 'POST' == $_SERVER['REQUEST_METHOD'] && !empty( $_POST['action2'] ) && $_POST['action2'] == 'recover_password2' && wp_verify_nonce( $_POST['password_recovery_nonce_field2'], 'verify_true_password_recovery2_'.absint( $_POST['userData'] ) ) ) { - - if( ( $_POST['passw1'] == $_POST['passw2'] ) && ( !empty( $_POST['passw1'] ) && !empty( $_POST['passw2'] ) ) ){ - if( !empty( $wppb_generalSettings['minimum_password_length'] ) || ( isset( $_POST['wppb_password_strength'] ) && !empty( $wppb_generalSettings['minimum_password_strength'] ) ) ){ - $message2 = ''; - if( wppb_check_password_length( $_POST['passw1'] ) ){ - $message2 .= '
            ' . sprintf( __( "The password must have the minimum length of %s characters", "profile-builder" ), $wppb_generalSettings['minimum_password_length'] ) . '
            '; - $messageNo2 = '2'; - } - if( wppb_check_password_strength() ){ - $message2 .= '
            '. sprintf( __( "The password must have a minimum strength of %s", "profile-builder" ), wppb_check_password_strength() ); - $messageNo2 = '2'; - } - } - - if( $messageNo2 != 2 ){ - - $message2 = __( 'Your password has been successfully changed!', 'profile-builder' ); - $messageNo2 = '1'; - - $userID = absint( $_POST['userData'] ); - $new_pass = $_POST['passw1']; - - //update the new password and delete the key - do_action( 'wppb_password_reset', $userID, $new_pass ); - - wp_set_password( $new_pass, $userID ); - - $user_info = get_userdata( $userID ); - - if( $wppb_generalSettings['loginWith'] == 'username' || $wppb_generalSettings['loginWith'] == 'usernameemail' ) - $display_username_email = $user_info->user_login; - else - $display_username_email = $user_info->user_email; - - //send secondary mail to the user containing the username and the new password - $recoveruserMailMessage2 = sprintf( __( 'You have successfully reset your password to: %1$s', 'profile-builder' ), $new_pass ); - $recoveruserMailMessage2 = apply_filters( 'wppb_recover_password_message_content_sent_to_user2', $recoveruserMailMessage2, $display_username_email, $new_pass, $userID ); - - $recoveruserMailMessageTitle2 = sprintf( __('Password Successfully Reset for %1$s on "%2$s"', 'profile-builder' ), $display_username_email, $blogname = get_option('blogname') ); - $recoveruserMailMessageTitle2 = apply_filters( 'wppb_recover_password_message_title_sent_to_user2', $recoveruserMailMessageTitle2, $display_username_email ); - - //send mail to the user notifying him of the reset request - if ( trim( $recoveruserMailMessageTitle2 ) != '' ) - wppb_mail( $user_info->user_email, $recoveruserMailMessageTitle2, $recoveruserMailMessage2 ); - - //send email to admin - $recoveradminMailMessage = sprintf( __( '%1$s has requested a password change via the password reset feature.
            His/her new password is:%2$s', 'profile-builder' ), $display_username_email, $_POST['passw1'] ); - $recoveradminMailMessage = apply_filters( 'wppb_recover_password_message_content_sent_to_admin', $recoveradminMailMessage, $display_username_email, $_POST['passw1'], $userID ); - - $recoveradminMailMessageTitle = sprintf( __( 'Password Successfully Reset for %1$s on "%2$s"', 'profile-builder' ), $display_username_email, $blogname = get_option('blogname'), ENT_QUOTES ); - $recoveradminMailMessageTitle = apply_filters( 'wppb_recover_password_message_title_sent_to_admin', $recoveradminMailMessageTitle, $display_username_email ); - - - //we disable the feature to send the admin a notification mail but can be still used using filters - $recoveradminMailMessageTitle = ''; - $recoveradminMailMessageTitle = apply_filters( 'wppb_recover_password_message_title_sent_to_admin', $recoveradminMailMessageTitle, $display_username_email ); - - //send mail to the admin notifying him of of a user with a password reset request - if (trim($recoveradminMailMessageTitle) != '') - wppb_mail(get_option('admin_email'), $recoveradminMailMessageTitle, $recoveradminMailMessage); - } - } - else{ - $message2 = __( 'The entered passwords don\'t match!', 'profile-builder' ); - $messageNo2 = '2'; - } - - } - -?> - -
            - -get_row( $wpdb->prepare( "SELECT * FROM $wpdb->users WHERE user_activation_key = %s AND user_nicename = %s", $key, $login_nicename ) ); - - if( !empty( $user ) ){ - //check if the "finalAction" variable is not in the address bar, if it is, don't display the form anymore - if( isset( $_GET['finalAction'] ) && ( $_GET['finalAction'] == 'yes' ) ){ - if( $messageNo2 == '2' ){ - echo apply_filters( 'wppb_recover_password_password_changed_message2', '

            '.$message2.'

            ', $message2 ); - - wppb_create_recover_password_form( $user, $_POST ); - - }elseif( $messageNo2 == '1' ) - echo apply_filters( 'wppb_recover_password_password_changed_message1', '

            '.$message2.'

            ', $message2 ); - - }else{ - wppb_create_recover_password_form( $user, $_POST ); - } - }else{ - if( $messageNo2 == '1' ) { - // CHECK FOR REDIRECT - $redirect_url = wppb_get_redirect_url( 'normal', 'after_success_password_reset', '', sanitize_user( $_GET['loginName'] ) ); - $redirect_delay = apply_filters( 'wppb_success_password_reset_redirect_delay', 3, sanitize_user( $_GET['loginName'] ) ); - $redirect_message = wppb_build_redirect( $redirect_url, $redirect_delay, 'after_success_password_reset' ); - - echo apply_filters( 'wppb_recover_password_password_changed_message1', '

            ' . $message2 . '

            ', $message2 ); - - if( isset( $redirect_message ) && ! empty( $redirect_message ) ) { - echo '

            ' . $redirect_message . '

            '; - } - } - - elseif( $messageNo2 == '2' ) - echo apply_filters( 'wppb_recover_password_password_changed_message2', '

            '.$message2.'

            ', $message2 ); - - else - echo apply_filters( 'wppb_recover_password_invalid_key_message', '

            '.__( 'ERROR:', 'profile-builder' ).''.__( 'Invalid key!', 'profile-builder' ).'

            ' ); - } - - }else{ - //display error message and the form - if (($messageNo == '') || ($messageNo == '2') || ($messageNo == '4')){ - if( !empty( $message ) ) - echo apply_filters( 'wppb_recover_password_displayed_message1', '

            '.$message.'

            ' ); - - wppb_create_generate_password_form( $_POST ); - - }elseif (($messageNo == '5') || ($messageNo == '6')) - echo apply_filters( 'wppb_recover_password_displayed_message1', '

            '.$message.'

            ' ); - - else - echo apply_filters( 'wppb_recover_password_displayed_message2', '

            '.$message.'

            ' ); //display success message - } - - // use this action hook to add extra content after the password recovery form. - do_action( 'wppb_after_recover_password_fields' ); -?> -
            - -data->ID, 'user_status' ) ){ + $retMessage = ''. __('ERROR', 'profile-builder') . ': ' . __('Your account has to be confirmed by an administrator before you can use the "Password Reset" feature.', 'profile-builder'); + $retMessage = apply_filters('wppb_recover_password_unapporved_user', $retMessage); + + $messageNo = '6'; + } + } + + return array( $retMessage, $messageNo ); +} + +/** + * Function that retrieves the unique user key from the database. If we don't have one we generate one and add it to the database + * + * @param string $requested_user_login the user login + * + */ +function wppb_retrieve_activation_key( $requested_user_login ){ + global $wpdb; + + $key = $wpdb->get_var( $wpdb->prepare( "SELECT user_activation_key FROM $wpdb->users WHERE user_login = %s", $requested_user_login ) ); + + if ( empty( $key ) ) { + + // Generate something random for a key... + $key = wp_generate_password( 20, false ); + do_action('wppb_retrieve_password_key', $requested_user_login, $key); + + // Now insert the new md5 key into the db + $wpdb->update($wpdb->users, array('user_activation_key' => $key), array('user_login' => $requested_user_login)); + } + + return $key; +} + + /** + * Function that creates a generate new password form + * + * @param array $post_data $_POST + * + */ +function wppb_create_recover_password_form( $user, $post_data ){ + ?> +
            +
              + + + + + +
            • + + +
            • '; + + /* if we have active the password strength checker */ + $recover_inputPassword .= wppb_password_strength_checker_html(); + + echo apply_filters( 'wppb_recover_password_form_input', $recover_inputPassword, $passw_one, $passw_two, $user->ID ); +?> +
            +

            + + " value="" /> + +

            + ID, 'password_recovery_nonce_field2' ); ?> + + +
            + ' . __( 'Please enter your username or email address.', 'profile-builder' ); + $recover_notification .= '
            '.__( 'You will receive a link to create a new password via email.', 'profile-builder' ).'

            '; + echo apply_filters( 'wppb_recover_password_message1', $recover_notification ); + + $username_email = ( isset( $post_data['username_email'] ) ? $post_data['username_email'] : '' ); + + $username_email_label = __( 'Username or E-mail', 'profile-builder' ); + + $recover_input = '
              +
            • + + +
            '; + echo apply_filters( 'wppb_recover_password_generate_password_input', $recover_input, trim( $username_email ) ); + ?> +

            + + + +

            + + + get_results( $wpdb->prepare( "SELECT * FROM $wpdb->users WHERE user_login= %s", $postedData ) ); + if( !empty( $query[0] ) ){ + $postedData = $query[0]->user_email; + } + } + else{ + $message = __( 'The username entered wasn\'t found in the database!', 'profile-builder').'
            '.__('Please check that you entered the correct username.', 'profile-builder' ); + $message = apply_filters( 'wppb_recover_password_sent_message4', $message ); + $messageNo = '4'; + } + } + + // we should have an email by this point + if ( is_email( $postedData ) ){ + if ( email_exists( $postedData ) ){ + $retVal = wppb_check_for_unapproved_user($postedData, 'user_email'); + if ($retVal[0] != ''){ + $message = $retVal[0]; + $messageNo = $retVal [1]; + + }else{ + $message = sprintf( __( 'Check your e-mail for the confirmation link.', 'profile-builder'), $postedData ); + $message = apply_filters( 'wppb_recover_password_sent_message1', $message, $postedData ); + $messageNo = '1'; + + } + + }elseif ( !email_exists( $postedData ) ){ + $message = __('The email address entered wasn\'t found in the database!', 'profile-builder').'
            '.__('Please check that you entered the correct email address.', 'profile-builder'); + $message = apply_filters('wppb_recover_password_sent_message2', $message); + $messageNo = '2'; + } + } + + // For some extra validations you can filter messageNo + $messageNo = apply_filters( 'wppb_recover_password_message_no', $messageNo ); + + if( $messageNo == '1' ) { + + //verify e-mail validity + $query = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->users WHERE user_email= %s", sanitize_email( $postedData ) ) ); + if( !empty( $query[0] ) ){ + $requestedUserID = $query[0]->ID; + $requestedUserLogin = $query[0]->user_login; + $requestedUserEmail = $query[0]->user_email; + $requestedUserNicename = $query[0]->user_nicename; + + if( $wppb_generalSettings['loginWith'] == 'username' || $wppb_generalSettings['loginWith'] == 'usernameemail' ) + $display_username_email = $query[0]->user_login; + else + $display_username_email = $query[0]->user_email; + + //search if there is already an activation key present, if not create one + $key = wppb_retrieve_activation_key( $requestedUserLogin ); + + //send primary email message + $recoveruserMailMessage1 = sprintf( __('Someone requested that the password be reset for the following account: %1$s
            If this was a mistake, just ignore this email and nothing will happen.
            To reset your password, visit the following link:%2$s', 'profile-builder'), $display_username_email, ''.esc_url( add_query_arg( array( 'loginName' => $requestedUserNicename, 'key' => $key ), wppb_curpageurl() ) ).''); + $recoveruserMailMessage1 = apply_filters( 'wppb_recover_password_message_content_sent_to_user1', $recoveruserMailMessage1, $requestedUserID, $requestedUserLogin, $requestedUserEmail ); + + $recoveruserMailMessageTitle1 = sprintf(__('Password Reset from "%1$s"', 'profile-builder'), $blogname = get_option('blogname') ); + $recoveruserMailMessageTitle1 = apply_filters('wppb_recover_password_message_title_sent_to_user1', $recoveruserMailMessageTitle1, $requestedUserLogin); + + //send mail to the user notifying him of the reset request + if (trim($recoveruserMailMessageTitle1) != ''){ + $sent = wppb_mail($requestedUserEmail, $recoveruserMailMessageTitle1, $recoveruserMailMessage1); + if ($sent === false){ + $message = ''. __( 'ERROR', 'profile-builder' ) .': ' . sprintf( __( 'There was an error while trying to send the activation link to %1$s!', 'profile-builder' ), $postedData ); + $message = apply_filters( 'wppb_recover_password_sent_message_error_sending', $message ); + $messageNo = '5'; + } + } + } + + } + + } + // If the user used the correct key-code, update his/her password + elseif ( 'POST' == $_SERVER['REQUEST_METHOD'] && !empty( $_POST['action2'] ) && $_POST['action2'] == 'recover_password2' && wp_verify_nonce( $_POST['password_recovery_nonce_field2'], 'verify_true_password_recovery2_'.absint( $_POST['userData'] ) ) ) { + + if( ( $_POST['passw1'] == $_POST['passw2'] ) && ( !empty( $_POST['passw1'] ) && !empty( $_POST['passw2'] ) ) ){ + if( !empty( $wppb_generalSettings['minimum_password_length'] ) || ( isset( $_POST['wppb_password_strength'] ) && !empty( $wppb_generalSettings['minimum_password_strength'] ) ) ){ + $message2 = ''; + if( wppb_check_password_length( $_POST['passw1'] ) ){ + $message2 .= '
            ' . sprintf( __( "The password must have the minimum length of %s characters", "profile-builder" ), $wppb_generalSettings['minimum_password_length'] ) . '
            '; + $messageNo2 = '2'; + } + if( wppb_check_password_strength() ){ + $message2 .= '
            '. sprintf( __( "The password must have a minimum strength of %s", "profile-builder" ), wppb_check_password_strength() ); + $messageNo2 = '2'; + } + } + + if( $messageNo2 != 2 ){ + + $message2 = __( 'Your password has been successfully changed!', 'profile-builder' ); + $messageNo2 = '1'; + + $userID = absint( $_POST['userData'] ); + $new_pass = $_POST['passw1']; + + //update the new password and delete the key + do_action( 'wppb_password_reset', $userID, $new_pass ); + + wp_set_password( $new_pass, $userID ); + + $user_info = get_userdata( $userID ); + + if( $wppb_generalSettings['loginWith'] == 'username' || $wppb_generalSettings['loginWith'] == 'usernameemail' ) + $display_username_email = $user_info->user_login; + else + $display_username_email = $user_info->user_email; + + //send secondary mail to the user containing the username and the new password + $recoveruserMailMessage2 = sprintf( __( 'You have successfully reset your password to: %1$s', 'profile-builder' ), $new_pass ); + $recoveruserMailMessage2 = apply_filters( 'wppb_recover_password_message_content_sent_to_user2', $recoveruserMailMessage2, $display_username_email, $new_pass, $userID ); + + $recoveruserMailMessageTitle2 = sprintf( __('Password Successfully Reset for %1$s on "%2$s"', 'profile-builder' ), $display_username_email, $blogname = get_option('blogname') ); + $recoveruserMailMessageTitle2 = apply_filters( 'wppb_recover_password_message_title_sent_to_user2', $recoveruserMailMessageTitle2, $display_username_email ); + + //send mail to the user notifying him of the reset request + if ( trim( $recoveruserMailMessageTitle2 ) != '' ) + wppb_mail( $user_info->user_email, $recoveruserMailMessageTitle2, $recoveruserMailMessage2 ); + + //send email to admin + $recoveradminMailMessage = sprintf( __( '%1$s has requested a password change via the password reset feature.
            His/her new password is:%2$s', 'profile-builder' ), $display_username_email, $_POST['passw1'] ); + $recoveradminMailMessage = apply_filters( 'wppb_recover_password_message_content_sent_to_admin', $recoveradminMailMessage, $display_username_email, $_POST['passw1'], $userID ); + + $recoveradminMailMessageTitle = sprintf( __( 'Password Successfully Reset for %1$s on "%2$s"', 'profile-builder' ), $display_username_email, $blogname = get_option('blogname'), ENT_QUOTES ); + $recoveradminMailMessageTitle = apply_filters( 'wppb_recover_password_message_title_sent_to_admin', $recoveradminMailMessageTitle, $display_username_email ); + + + //we disable the feature to send the admin a notification mail but can be still used using filters + $recoveradminMailMessageTitle = ''; + $recoveradminMailMessageTitle = apply_filters( 'wppb_recover_password_message_title_sent_to_admin', $recoveradminMailMessageTitle, $display_username_email ); + + //send mail to the admin notifying him of of a user with a password reset request + if (trim($recoveradminMailMessageTitle) != '') + wppb_mail(get_option('admin_email'), $recoveradminMailMessageTitle, $recoveradminMailMessage); + } + } + else{ + $message2 = __( 'The entered passwords don\'t match!', 'profile-builder' ); + $messageNo2 = '2'; + } + + } + +?> + +
            + +get_row( $wpdb->prepare( "SELECT * FROM $wpdb->users WHERE user_activation_key = %s AND user_nicename = %s", $key, $login_nicename ) ); + + if( !empty( $user ) ){ + //check if the "finalAction" variable is not in the address bar, if it is, don't display the form anymore + if( isset( $_GET['finalAction'] ) && ( $_GET['finalAction'] == 'yes' ) ){ + if( $messageNo2 == '2' ){ + echo apply_filters( 'wppb_recover_password_password_changed_message2', '

            '.$message2.'

            ', $message2 ); + + wppb_create_recover_password_form( $user, $_POST ); + + }elseif( $messageNo2 == '1' ) + echo apply_filters( 'wppb_recover_password_password_changed_message1', '

            '.$message2.'

            ', $message2 ); + + }else{ + wppb_create_recover_password_form( $user, $_POST ); + } + }else{ + if( $messageNo2 == '1' ) { + // CHECK FOR REDIRECT + $redirect_url = wppb_get_redirect_url( 'normal', 'after_success_password_reset', '', sanitize_user( $_GET['loginName'] ) ); + $redirect_delay = apply_filters( 'wppb_success_password_reset_redirect_delay', 3, sanitize_user( $_GET['loginName'] ) ); + $redirect_message = wppb_build_redirect( $redirect_url, $redirect_delay, 'after_success_password_reset' ); + + echo apply_filters( 'wppb_recover_password_password_changed_message1', '

            ' . $message2 . '

            ', $message2 ); + + if( isset( $redirect_message ) && ! empty( $redirect_message ) ) { + echo '

            ' . $redirect_message . '

            '; + } + } + + elseif( $messageNo2 == '2' ) + echo apply_filters( 'wppb_recover_password_password_changed_message2', '

            '.$message2.'

            ', $message2 ); + + else + echo apply_filters( 'wppb_recover_password_invalid_key_message', '

            '.__( 'ERROR:', 'profile-builder' ).''.__( 'Invalid key!', 'profile-builder' ).'

            ' ); + } + + }else{ + //display error message and the form + if (($messageNo == '') || ($messageNo == '2') || ($messageNo == '4')){ + if( !empty( $message ) ) + echo apply_filters( 'wppb_recover_password_displayed_message1', '

            '.$message.'

            ' ); + + wppb_create_generate_password_form( $_POST ); + + }elseif (($messageNo == '5') || ($messageNo == '6')) + echo apply_filters( 'wppb_recover_password_displayed_message1', '

            '.$message.'

            ' ); + + else + echo apply_filters( 'wppb_recover_password_displayed_message2', '

            '.$message.'

            ' ); //display success message + } + + // use this action hook to add extra content after the password recovery form. + do_action( 'wppb_after_recover_password_fields' ); +?> +
            + +get_row( $wpdb->prepare( "SELECT * FROM " . $wpdb->signups . " WHERE activation_key = %s", $key ) ) : $wpdb->get_row( $wpdb->prepare( "SELECT * FROM " . $wpdb->base_prefix . "signups WHERE activation_key = %s", $key ) ) ); - - if ( empty( $signup ) || $signup->active ) { - //bad key or already active - } else { - //check for password in signup meta - $meta = unserialize( $signup->meta ); - - if ( !empty($meta['user_pass']) ) - $password = $meta['user_pass']; - } - } - - return apply_filters( 'wppb_generated_random_password', $password, $key ); -} -add_filter( 'random_password', 'wppb_signup_password_random_password_filter' ); - -/** - * Activate a signup. - * - * - * @param string $key The activation key provided to the user. - * @return array An array containing information about the activated user and/or blog - */ -function wppb_activate_signup( $key ) { - global $wpdb; - $bloginfo = get_bloginfo( 'name' ); - $wppb_general_settings = get_option( 'wppb_general_settings' ); - - $signup = ( is_multisite() ? $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->signups WHERE activation_key = %s", $key) ) : $wpdb->get_row( $wpdb->prepare( "SELECT * FROM ".$wpdb->base_prefix."signups WHERE activation_key = %s", $key ) ) ); - - $user_login = ( ( isset( $wppb_general_settings['loginWith'] ) && ( $wppb_general_settings['loginWith'] == 'email' ) ) ? trim( $signup->user_email ) : trim( $signup->user_login ) ); - - $user_email = esc_sql( $signup->user_email ); - /* the password is in hashed form in the signup table so we will add it later */ - $password = NULL; - - $user_id = username_exists( $user_login ); - - if ( empty( $signup ) ) - return apply_filters( 'wppb_register_activate_user_error_message1', '

            '.__( 'Invalid activation key!', 'profile-builder' ).'

            '); - - if ( $signup->active ) - if ( empty( $signup->domain ) ) - return apply_filters( 'wppb_register_activate_user_error_message2', '

            '.__( 'This username is now active!', 'profile-builder' ).'

            ', $user_id ); - - $meta = unserialize( $signup->meta ); - - - if ( !$user_id ) - $user_id = wppb_create_user( $user_login, $password, $user_email ); - else - $user_already_exists = true; - - if ( ! $user_id ) - return apply_filters( 'wppb_register_activate_user_error_message4', '

            '.__('Could not create user!', 'profile-builder').'

            ' ); - - elseif ( isset( $user_already_exists ) && ( $user_already_exists == true ) ) - return apply_filters( 'wppb_register_activate_user_error_message5', '

            '.__( 'This username is already activated!', 'profile-builder' ).'

            ' ); - - else{ - $inserted_user = ( is_multisite() ? $wpdb->update( $wpdb->signups, array( 'active' => 1, 'activated' => current_time( 'mysql', true ) ), array( 'activation_key' => $key ) ) : $wpdb->update( $wpdb->base_prefix.'signups', array( 'active' => 1, 'activated' => current_time( 'mysql', true ) ), array( 'activation_key' => $key ) ) ); - - wppb_add_meta_to_user_on_activation( $user_id, '', $meta ); - - // if admin approval is activated, then block the user untill he gets approved - $wppb_generalSettings = get_option('wppb_general_settings'); - if( isset( $wppb_generalSettings['adminApproval'] ) && ( $wppb_generalSettings['adminApproval'] == 'yes' ) ){ - $user_data = get_userdata( $user_id ); - - if( $wppb_generalSettings != 'not_found' && ! empty( $wppb_generalSettings['adminApprovalOnUserRole'] ) ) { - foreach( $user_data->roles as $role ) { - if( in_array( $role, $wppb_generalSettings['adminApprovalOnUserRole'] ) ) { - wp_set_object_terms( $user_id, array( 'unapproved' ), 'user_status', false); - clean_object_term_cache( $user_id, 'user_status' ); - } else { - add_filter( 'wppb_register_success_message', 'wppb_noAdminApproval_successMessage' ); - } - } - } else { - wp_set_object_terms( $user_id, array( 'unapproved' ), 'user_status', false); - clean_object_term_cache( $user_id, 'user_status' ); - } - } - - if ( !isset( $wppb_generalSettings['adminApproval'] ) ) - $wppb_generalSettings['adminApproval'] = 'no'; - - /* copy the hashed password from signup meta to wp user table */ - if( !empty( $meta['user_pass'] ) ){ - /* we might still have the base64 encoded password in signups and not the hash */ - if( base64_encode(base64_decode($meta['user_pass'], true)) === $meta['user_pass'] ) - $meta['user_pass'] = wp_hash_password( $meta['user_pass'] ); - - $wpdb->update( $wpdb->users, array('user_pass' => $meta['user_pass'] ), array('ID' => $user_id) ); - wp_cache_delete( $user_id, 'users' ); - } - - wppb_notify_user_registration_email($bloginfo, $user_login, $user_email, 'sending', $password, $wppb_generalSettings['adminApproval']); - - do_action( 'wppb_activate_user', $user_id, $password, $meta ); - - if( $inserted_user ) { - // CHECK FOR REDIRECT - $redirect_url = wppb_get_redirect_url( 'normal', 'after_success_email_confirmation', '', $user_login ); - $redirect_delay = apply_filters( 'wppb_success_email_confirmation_redirect_delay', 3, $user_id ); - $redirect_message = wppb_build_redirect( $redirect_url, $redirect_delay, 'after_success_email_confirmation' ); - - $success_message = apply_filters( 'wppb_success_email_confirmation', '

            ' . __( 'Your email was successfully confirmed.', 'profile-builder' ) . '

            ', $user_id ); - $admin_approval_message = apply_filters( 'wppb_email_confirmation_with_admin_approval', '

            ' . __( 'Before you can access your account, an administrator needs to approve it. You will be notified via email.', 'profile-builder' ) . '

            ', $user_id ); - - $wppb_general_settings = get_option( 'wppb_general_settings', 'false' ); - - if ( !empty( $wppb_general_settings['adminApproval'] ) && $wppb_general_settings['adminApproval'] == 'yes' ){ - $user_data = get_userdata( $user_id ); - - if( $wppb_general_settings != 'not_found' && ! empty( $wppb_general_settings['adminApprovalOnUserRole'] ) ) { - foreach( $user_data->roles as $role ) { - if( in_array( $role, $wppb_general_settings['adminApprovalOnUserRole'] ) ) { - return $success_message . $admin_approval_message . ( ! empty ( $redirect_message ) ? $redirect_message : '' ); - } else { - wp_set_object_terms( $user_id, NULL, 'user_status' ); - clean_object_term_cache( $user_id, 'user_status' ); - - return $success_message . ( ! empty ( $redirect_message ) ? $redirect_message : '' ); - } - } - } else { - return $success_message . $admin_approval_message . ( ! empty ( $redirect_message ) ? $redirect_message : '' ); - } - } else { - wp_set_object_terms( $user_id, NULL, 'user_status' ); - clean_object_term_cache( $user_id, 'user_status' ); - - return $success_message . ( ! empty ( $redirect_message ) ? $redirect_message : '' ); - } - } else { - return apply_filters('wppb_register_failed_user_activation', '

            '. __('There was an error while trying to activate the user.', 'profile-builder') .'

            '); - } - } -} - -//function to display the registration page -function wppb_front_end_register( $atts ){ - extract( shortcode_atts( array( 'role' => get_option( 'default_role' ), 'form_name' => 'unspecified', 'redirect_url' => '', 'logout_redirect_url' => '', 'redirect_priority' => 'normal' ), $atts, 'wppb-register' ) ); - - global ${$form_name}; - - $$form_name = new Profile_Builder_Form_Creator( array( 'form_type' => 'register', 'form_name' => $form_name, 'role' => ( is_object( get_role( $role ) ) ? $role : get_option( 'default_role' ) ) , 'redirect_url' => $redirect_url, 'logout_redirect_url' => $logout_redirect_url, 'redirect_priority' => $redirect_priority ) ); - - return $$form_name; -} - -// function to choose whether to display the registration page or the validation message -function wppb_front_end_register_handler( $atts ){ - - return ( isset( $_GET['activation_key'] ) ? wppb_activate_signup ( sanitize_text_field( $_GET['activation_key'] ) ) : wppb_front_end_register( $atts ) ); -} - -add_action( 'user_register', 'wppbc_disable_admin_approval_for_user_role', 99, 1 ); -function wppbc_disable_admin_approval_for_user_role( $user_id ) { - if ( current_user_can( 'delete_users' ) ) { - wp_set_object_terms( $user_id, NULL, 'user_status' ); - clean_object_term_cache( $user_id, 'user_status' ); - } -} - -/* authors and contributors shouldn't be allowed to create pages with the register shortcode in them */ -add_filter( 'the_content', 'wppb_maybe_remove_register_shortcode' ); -function wppb_maybe_remove_register_shortcode( $content ){ - if ( has_shortcode( $content, 'wppb-register' ) ){ - $author_id = get_the_author_meta( 'ID' ); - if( !empty( $author_id ) ){ - if( !user_can( $author_id, 'edit_others_posts' ) ) { - remove_shortcode('wppb-register'); - } - } - } - - return $content; +get_row( $wpdb->prepare( "SELECT * FROM " . $wpdb->signups . " WHERE activation_key = %s", $key ) ) : $wpdb->get_row( $wpdb->prepare( "SELECT * FROM " . $wpdb->base_prefix . "signups WHERE activation_key = %s", $key ) ) ); + + if ( empty( $signup ) || $signup->active ) { + //bad key or already active + } else { + //check for password in signup meta + $meta = unserialize( $signup->meta ); + + if ( !empty($meta['user_pass']) ) + $password = $meta['user_pass']; + } + } + + return apply_filters( 'wppb_generated_random_password', $password, $key ); +} +add_filter( 'random_password', 'wppb_signup_password_random_password_filter' ); + +/** + * Activate a signup. + * + * + * @param string $key The activation key provided to the user. + * @return array An array containing information about the activated user and/or blog + */ +function wppb_activate_signup( $key ) { + global $wpdb; + $bloginfo = get_bloginfo( 'name' ); + $wppb_general_settings = get_option( 'wppb_general_settings' ); + + $signup = ( is_multisite() ? $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->signups WHERE activation_key = %s", $key) ) : $wpdb->get_row( $wpdb->prepare( "SELECT * FROM ".$wpdb->base_prefix."signups WHERE activation_key = %s", $key ) ) ); + + $user_login = ( ( isset( $wppb_general_settings['loginWith'] ) && ( $wppb_general_settings['loginWith'] == 'email' ) ) ? trim( $signup->user_email ) : trim( $signup->user_login ) ); + + $user_email = esc_sql( $signup->user_email ); + /* the password is in hashed form in the signup table so we will add it later */ + $password = NULL; + + $user_id = username_exists( $user_login ); + + if ( empty( $signup ) ) + return apply_filters( 'wppb_register_activate_user_error_message1', '

            '.__( 'Invalid activation key!', 'profile-builder' ).'

            '); + + if ( $signup->active ) + if ( empty( $signup->domain ) ) + return apply_filters( 'wppb_register_activate_user_error_message2', '

            '.__( 'This username is now active!', 'profile-builder' ).'

            ', $user_id ); + + $meta = unserialize( $signup->meta ); + + + if ( !$user_id ) + $user_id = wppb_create_user( $user_login, $password, $user_email ); + else + $user_already_exists = true; + + if ( ! $user_id ) + return apply_filters( 'wppb_register_activate_user_error_message4', '

            '.__('Could not create user!', 'profile-builder').'

            ' ); + + elseif ( isset( $user_already_exists ) && ( $user_already_exists == true ) ) + return apply_filters( 'wppb_register_activate_user_error_message5', '

            '.__( 'This username is already activated!', 'profile-builder' ).'

            ' ); + + else{ + $inserted_user = ( is_multisite() ? $wpdb->update( $wpdb->signups, array( 'active' => 1, 'activated' => current_time( 'mysql', true ) ), array( 'activation_key' => $key ) ) : $wpdb->update( $wpdb->base_prefix.'signups', array( 'active' => 1, 'activated' => current_time( 'mysql', true ) ), array( 'activation_key' => $key ) ) ); + + wppb_add_meta_to_user_on_activation( $user_id, '', $meta ); + + // if admin approval is activated, then block the user untill he gets approved + $wppb_generalSettings = get_option('wppb_general_settings'); + if( isset( $wppb_generalSettings['adminApproval'] ) && ( $wppb_generalSettings['adminApproval'] == 'yes' ) ){ + $user_data = get_userdata( $user_id ); + + if( $wppb_generalSettings != 'not_found' && ! empty( $wppb_generalSettings['adminApprovalOnUserRole'] ) ) { + foreach( $user_data->roles as $role ) { + if( in_array( $role, $wppb_generalSettings['adminApprovalOnUserRole'] ) ) { + wp_set_object_terms( $user_id, array( 'unapproved' ), 'user_status', false); + clean_object_term_cache( $user_id, 'user_status' ); + } else { + add_filter( 'wppb_register_success_message', 'wppb_noAdminApproval_successMessage' ); + } + } + } else { + wp_set_object_terms( $user_id, array( 'unapproved' ), 'user_status', false); + clean_object_term_cache( $user_id, 'user_status' ); + } + } + + if ( !isset( $wppb_generalSettings['adminApproval'] ) ) + $wppb_generalSettings['adminApproval'] = 'no'; + + /* copy the hashed password from signup meta to wp user table */ + if( !empty( $meta['user_pass'] ) ){ + /* we might still have the base64 encoded password in signups and not the hash */ + if( base64_encode(base64_decode($meta['user_pass'], true)) === $meta['user_pass'] ) + $meta['user_pass'] = wp_hash_password( $meta['user_pass'] ); + + $wpdb->update( $wpdb->users, array('user_pass' => $meta['user_pass'] ), array('ID' => $user_id) ); + wp_cache_delete( $user_id, 'users' ); + } + + wppb_notify_user_registration_email($bloginfo, $user_login, $user_email, 'sending', $password, $wppb_generalSettings['adminApproval']); + + do_action( 'wppb_activate_user', $user_id, $password, $meta ); + + if( $inserted_user ) { + // CHECK FOR REDIRECT + $redirect_url = wppb_get_redirect_url( 'normal', 'after_success_email_confirmation', '', $user_login ); + $redirect_delay = apply_filters( 'wppb_success_email_confirmation_redirect_delay', 3, $user_id ); + $redirect_message = wppb_build_redirect( $redirect_url, $redirect_delay, 'after_success_email_confirmation' ); + + $success_message = apply_filters( 'wppb_success_email_confirmation', '

            ' . __( 'Your email was successfully confirmed.', 'profile-builder' ) . '

            ', $user_id ); + $admin_approval_message = apply_filters( 'wppb_email_confirmation_with_admin_approval', '

            ' . __( 'Before you can access your account, an administrator needs to approve it. You will be notified via email.', 'profile-builder' ) . '

            ', $user_id ); + + $wppb_general_settings = get_option( 'wppb_general_settings', 'false' ); + + if ( !empty( $wppb_general_settings['adminApproval'] ) && $wppb_general_settings['adminApproval'] == 'yes' ){ + $user_data = get_userdata( $user_id ); + + if( $wppb_general_settings != 'not_found' && ! empty( $wppb_general_settings['adminApprovalOnUserRole'] ) ) { + foreach( $user_data->roles as $role ) { + if( in_array( $role, $wppb_general_settings['adminApprovalOnUserRole'] ) ) { + return $success_message . $admin_approval_message . ( ! empty ( $redirect_message ) ? $redirect_message : '' ); + } else { + wp_set_object_terms( $user_id, NULL, 'user_status' ); + clean_object_term_cache( $user_id, 'user_status' ); + + return $success_message . ( ! empty ( $redirect_message ) ? $redirect_message : '' ); + } + } + } else { + return $success_message . $admin_approval_message . ( ! empty ( $redirect_message ) ? $redirect_message : '' ); + } + } else { + wp_set_object_terms( $user_id, NULL, 'user_status' ); + clean_object_term_cache( $user_id, 'user_status' ); + + return $success_message . ( ! empty ( $redirect_message ) ? $redirect_message : '' ); + } + } else { + return apply_filters('wppb_register_failed_user_activation', '

            '. __('There was an error while trying to activate the user.', 'profile-builder') .'

            '); + } + } +} + +//function to display the registration page +function wppb_front_end_register( $atts ){ + extract( shortcode_atts( array( 'role' => get_option( 'default_role' ), 'form_name' => 'unspecified', 'redirect_url' => '', 'logout_redirect_url' => '', 'redirect_priority' => 'normal' ), $atts, 'wppb-register' ) ); + + global ${$form_name}; + + $$form_name = new Profile_Builder_Form_Creator( array( 'form_type' => 'register', 'form_name' => $form_name, 'role' => ( is_object( get_role( $role ) ) ? $role : get_option( 'default_role' ) ) , 'redirect_url' => $redirect_url, 'logout_redirect_url' => $logout_redirect_url, 'redirect_priority' => $redirect_priority ) ); + + return $$form_name; +} + +// function to choose whether to display the registration page or the validation message +function wppb_front_end_register_handler( $atts ){ + + return ( isset( $_GET['activation_key'] ) ? wppb_activate_signup ( sanitize_text_field( $_GET['activation_key'] ) ) : wppb_front_end_register( $atts ) ); +} + +add_action( 'user_register', 'wppbc_disable_admin_approval_for_user_role', 99, 1 ); +function wppbc_disable_admin_approval_for_user_role( $user_id ) { + if ( current_user_can( 'delete_users' ) ) { + wp_set_object_terms( $user_id, NULL, 'user_status' ); + clean_object_term_cache( $user_id, 'user_status' ); + } +} + +/* authors and contributors shouldn't be allowed to create pages with the register shortcode in them */ +add_filter( 'the_content', 'wppb_maybe_remove_register_shortcode' ); +function wppb_maybe_remove_register_shortcode( $content ){ + if ( has_shortcode( $content, 'wppb-register' ) ){ + $author_id = get_the_author_meta( 'ID' ); + if( !empty( $author_id ) ){ + if( !user_can( $author_id, 'edit_others_posts' ) ) { + remove_shortcode('wppb-register'); + } + } + } + + return $content; } \ No newline at end of file diff --git a/profile-builder/index.php b/profile-builder/index.php index 649c7f6..ff882bd 100644 --- a/profile-builder/index.php +++ b/profile-builder/index.php @@ -3,7 +3,7 @@ Plugin Name: Profile Builder Plugin URI: https://www.cozmoslabs.com/wordpress-profile-builder/ Description: Login, registration and edit profile shortcodes for the front-end. Also you can chose what fields should be displayed or add new (custom) ones both in the front-end and in the dashboard. -Version: 2.6.3 +Version: 2.6.4 Author: Cozmoslabs, Madalin Ungureanu, Antohe Cristian, Barina Gabriel, Mihai Iova Author URI: https://www.cozmoslabs.com/ License: GPL2 @@ -73,7 +73,7 @@ function wppb_free_plugin_init() { * * */ - define('PROFILE_BUILDER_VERSION', '2.6.3' ); + define('PROFILE_BUILDER_VERSION', '2.6.4' ); define('WPPB_PLUGIN_DIR', plugin_dir_path(__FILE__)); define('WPPB_PLUGIN_URL', plugin_dir_url(__FILE__)); define('WPPB_SERVER_MAX_UPLOAD_SIZE_BYTE', apply_filters('wppb_server_max_upload_size_byte_constant', wppb_return_bytes(ini_get('upload_max_filesize')))); diff --git a/profile-builder/readme.txt b/profile-builder/readme.txt index 46275af..6c1fbcc 100644 --- a/profile-builder/readme.txt +++ b/profile-builder/readme.txt @@ -5,7 +5,7 @@ Tags: user registration, user profile, user registration form, user fields, extr Requires at least: 3.1 Tested up to: 4.7.5 -Stable tag: 2.6.3 +Stable tag: 2.6.4 License: GPLv2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html @@ -154,6 +154,10 @@ This plugin adds/removes user fields in the front-end. Both default and extra pr 12. Role Editor == Changelog == += 2.6.4 = +* Fixed a bug which was preventing deleting thrashed posts +* Compatibility fixes with Advanced Custom Fields Plugin + = 2.6.3 = * Fixed a small display bug for custom capabilities on Roles Editor * Fixed a potential warning with the login form and WPML when cURL was not working properly diff --git a/profile-builder/translation/profile-builder-pl_PL.mo b/profile-builder/translation/profile-builder-pl_PL.mo index d5b5219e66a2b103b2625cae1ecc493f74bfd1cc..7bdb72cb468d268b24a022dc39a129fd07d35a58 100644 GIT binary patch delta 10544 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 delta 9335 zcmYM(34G5-{>Slekc1o}aSQSj5@({0I6@tbxKj63x1S`EkV_6nsP9s&vnaZ#`>L|q zl4`q_y1S~aYD;R1TK#8jORQRIyQ=p8dS~YU`0t~Sea_7HJ2Rj8%*;1Qd#R+tgU>3s z--T6L@9@9Y6&$BNt_xMoae^BEzabQZsV89rOu!5b$AefGKfwt6AB@C`O&q5sMx&k& z#YD`+Hh36Q9mjP_Db%8&f0X02MK2D*byx*U@vrz#Ou_Tfj?)KYnldOBBL6t&`M*v0 z6IR6K%^asHuENT=6*bwSR8{q?F5l;2yj#CXgqCfV%^i~G}h|H zrqt6g30I-c$~6qeGE_iMP=QozZMG&5^}H)8(Ect3y)eo)Ohg5giCW=I9D%Q*-YZ1~ zR%YuDP%HWmRz)3vKnOvN6OQT^jUgC|daoO5E8GDT6wySihgsMFm!JmTi`DQTdhjFE zfHzSS{R6eqhp1Ei)YfZq$u&_!)bkkB?dgD8c|T+x*BMEnd~Z=Ho@49tQ7c%2ns6;@ zO;^4BkWqa?iFuL?te21imVqZ6AMuT zE=NtU5%uBNkHqMFjGE{P>V2n!dCwm;K^?2dwl_n)-x>AY=#J{w4_!43rl5{vP?1eW zr8*1sJP)<#7>X-U6K}QdLXE!<)&E`80*;{qKGTWW^xzX3 zYTy-AhdcI#f1x`3V*M{FLw=pj0HLTA)<(VOu{K4$7i;UCQGxY9Wg^kG4{|AJ!jaYq z)+wk6vr(xoKy_SzY`e1p)$cUwUSB|EwHPLn3ejC;C0cxecSbe&f6$POBg%nwFm0GBwHU=UT6O&P|)5? zu`f(Rttj6*8+ArpEWehvz7Z2>--BAwkEn?sqWV8YO<3W1n<><(4?%rD!Z48eokkS2 z!WdL0dZT^;8Gw94oava0dr^Vb?&dfYo%+}e$Dk&91+}-!QGskl1@b29)*M8Qe+IQR z7tqy<*C@zRR3P^-8vVMPl*eE!^}eV8W}-4O7u9bGcEUBN57Y&mfX}cYj_+Z9iq6F- z>Th8DKk5ve zM|~&0Mos)T)UA2i(={D}UN8eiqOMU()E*_E_IxNR#gkAONVoMY)ZQ1OQtMh5qXJrq zns_TJumh+CoU-kotAjG|Eqd?~YGpM!S&BRy)iD}1P*+p{{cL?8D!{SGN7Knb_1l5{ z@Q=6|A7dk2+siEE2$lzYoPs)>#qszBR>GJ>bGX`~CLW7gX}YcFp;GT!msr=JQo9M2 zvHf@z591JA-rM{pbORaJb*lC;ha()7n!eWI=u3SPZpSIO8vXm4--tHgEb9M6erz~t zEcYkeiVAd9f0L1os9W(RYQ?3faqnVf{j_;Np%x8KP#r^)%!}cufFe;HVr_eS44~cx zm4V)<2?p8vWNc1-8Y<=Mu`zytf52;~+m!zzTg3d%P72z)GSu~HGQj*L^b%^IZ_fcgz*73#X(#Mbx>`C2=%JdDN+)E9I$=HUT!qbM{SY+mSv>M#xY zsycgdDSnU7VI~{c0=Hlcp2u8#jBPP(s5!)&P=Wp#^?oVpLl!d3{P60995bhA82Q&d zJwZcjyn)(^;Nd2KCKyY766(EGs8k-rw)iFTm31nOFyD!u7)E^pYOklG0-c3%xEFP} zucJTS8bSWGw?EQQ9q-!*6-Sx@0x^j8Fw_Sq!nSuprLsG!-xzDQeZBxS!BVV&Yp^Qr z#b7*wP4J9ML6QD|`taOGb@U%){#*`09m)}?LpKqt;Z)Q>bL{h_sKdAxm4VIHcQBOt zY1EhWGAi{CkYqbmd`47 zM)ms@bw(1#nST*619jMU+WL8Hq5J=cg04*jpTGLp4eQ`o)Ga8$JbV{ZvGD|RTb5!g zwPQ=XfgY?f(QIi8)RweCoq>4NLI$Dc$;aj{h1C?4fupF@oy2fFXY0361KmcY_&%QX z;r>rDDgD@MKCM?!D{o4gbnS9b*LD*Pt3-a$SMPDC>KuT3GF!c1I@jNv@P7jROF ziF6k#l_ycDe~8-i?xe$yK>A}Q^&wNtHTwv=QGbNmqIPNg9Kdl{5&hH6*$7N0|Nb;o zr$GaTqfT!$Dn*?!0!LyL&cJ548FdTJq57Ag-un&%@fjvyK!&*`15xjdv!d*?gO-|%((3TGB@m9T#yCmcV-P;52B1lrBo8?~~5 z7>1*;8csz8GzXQDrKpU)idw+V8RTCN4$`2NA4Wxd6r1Bo?2C6$nP|snQUk`LCg_X$ zRF6h|@d{D>-$T8B6cx}Z)cBXJ*HLGz)TN*fPf*uSztXB>0ID8}>KKlSxG^f=So^#k zYUR(P`t?QyIKbA&qQ;+$y3Xmgz6{mRT}?p~ZA4A93oGCOTYnoX`tWbPa3$?WXPW{0 z7MXqnQK$PQtc7W)iRPhJxZT#@M+JV>dIOoyb-t&d!*K_-g2$+cf3xis=a_GG2r9rP zsOPOv@3*yfMrEjneV&9`;Sl?LjMa;JFTMOZ`=3uikZj&kQ2hetn!v+Qx2Y*ABRx_5N8uZ~|Klm>)A%2(jeaki7aO7?ZI9~E z9W_y+Z6AaRbPQ^xUh7oUg7Q)QW??MOL*1T(sKa{#T}^O_g1m;B;5KRnKcNQx#kTv* zGZO})-VeiYY=8>9Ge+PLY=P5J<7`F+x*Ij#0aX9@=CS`OoUkumun)en^&6;;f4B8A z)QTQipPU$E6T9B@}{2i+QGE`uzT?$Io2GnmRTTrKY2Wp^qu?`+X z1#$&-y02p!e1?3ZoacUL#@T~Csqe=)EJIBgIp2JEnxQh#71f^TQqZADLQUXB?M*uB z#o4xf0eYw}#g@1q)vp92une`3pamxIP*nd07?08TJbEz&x1kQDTj>?ER}HZv4gIhY z&PVO-E^L4&PyyaR4P1&IyoY+P>OwPd3)IRwpcc{<^#vS&ns5>}#v&xsuCtYbQhgBX zv z??n9GOmG>slAqBJe?#4lN=wXtm`Z;Y zN)DlqF@2kEm{$$tP1ztW(U`K>Yo2V-UG)lolG>Z3ZgL%sJrDxhAdKnC0P zk*M*;qxz?#wqm-iyV#QY64b)pTSfkxQ@BOL5e!^y>Zgz&c+Oo^MpD+8zxj4!0`*U^ z3x>RA{`gEntuz~3;6ChuUt>3{vDWqjw$`fZHD8k@}4#G|$_5eeLNUZl{2hPkNw zdmME-PhTEH47Kfv$r{EO)2(`CSTTLJ%PytM`rlW2}E-LUM>k|9?bySA7q5?U9%D{0{M$V!; zkiu08%0Sa?=I3|^RKx>OTQCYM;&}9+7hk{ys7#&1m+=lR#PscE&+lOz_3As=S|5J4 zU{C4;cbX5_>Ye0YhwdT`5$L@lam7b*kOQ45^4XRt}dd>W!@SZ`lEhC0nZqA%9iYpjQjse8~5d!YtOLhbGF zy~QmW_w%VUG$%7P-;FJqVkTJtskeU)-JiW<*pyCN_QkxXNF=|JEe+N&S z&hhQyiW4R$`utyI?W*L4p}F3?+4*hadZcA}Gcse7bFzy6ocv|^xL$^x&9Gj^omMb= zX0|upiClYVWA)-~smuIZr(~zL^33$)rk-1no#9EIeA%ynclpjR8L;& z)YSZfJa6*UjJ1>2)bmY^_eABdZJ6D)_-xj2zvAqIeBW*_=A_XvJ0sN-IXSh+Q{c@@ z&S1*iyrS8j!gI%FCubCT^3!wj3X*eD%KLjV3nzPKW~8L078J%7M-{cM9Z=-;\n" +"POT-Creation-Date: 2017-06-09 11:54+0000\n" +"Last-Translator: admin \n" "Language-Team: Polish\n" "Language: pl-PL" @@ -26,11 +26,11 @@ msgstr "" msgid "Incorrect phone number" msgstr "" -#: features/functions.php:897 +#: features/functions.php:896 msgid "

            Also, you will be able to visit your site at " msgstr "" -#: features/functions.php:910 +#: features/functions.php:909 msgid "

            You can visit your site at " msgstr "" @@ -62,50 +62,42 @@ msgstr "" #: admin/general-settings.php:146 msgid "\"Roles Editor\" Activated:" -msgstr "\"Rola Edytora\" Aktywna:" +msgstr "" #: admin/general-settings.php:154 #, php-format msgid "You can add / edit user roles at %1$sUsers > Roles Editor%2$s." msgstr "" -#: admin/add-ons.php:103 -msgid "Available in Hobbyist and Pro Versions" -msgstr "" - -#: admin/add-ons.php:105 -msgid "Available in All Versions" -msgstr "" - -#: admin/add-ons.php:148 +#: admin/add-ons.php:149 msgid "Learn More" msgstr "" -#: admin/add-ons.php:190 +#: admin/add-ons.php:191 msgid "Recommended Plugins" msgstr "" -#: admin/add-ons.php:219 admin/pms-cross-promotion.php:102 +#: admin/add-ons.php:220 admin/pms-cross-promotion.php:102 msgid "Free" msgstr "" -#: admin/add-ons.php:221 +#: admin/add-ons.php:222 msgid "" "Accept user payments, create subscription plans and restrict content on your " "membership site." msgstr "" -#: admin/add-ons.php:240 admin/pms-cross-promotion.php:88 +#: admin/add-ons.php:241 admin/pms-cross-promotion.php:88 #: admin/pms-cross-promotion.php:123 admin/pms-cross-promotion.php:202 msgid "Plugin is inactive" msgstr "" -#: admin/add-ons.php:242 admin/pms-cross-promotion.php:87 +#: admin/add-ons.php:243 admin/pms-cross-promotion.php:87 #: admin/pms-cross-promotion.php:125 admin/pms-cross-promotion.php:204 msgid "Plugin is active" msgstr "" -#: admin/add-ons.php:256 admin/pms-cross-promotion.php:146 +#: admin/add-ons.php:257 admin/pms-cross-promotion.php:146 #, php-format msgid "" "Could not install plugin. Retry or install " @@ -844,10 +836,6 @@ msgid "" "40% off %4$s %6$sDismiss%7$s

            " msgstr "" -#: admin/admin-functions.php:41 -msgid "Display name publicly as - only appears on the Edit Profile page!" -msgstr "" - #: admin/admin-functions.php:44 msgid "Blog Details - only appears on the Registration page!" msgstr "" @@ -913,124 +901,124 @@ msgid "" "Your account has to be confirmed by an administrator before you can log in." msgstr "" -#: features/roles-editor/roles-editor.php:177 +#: features/roles-editor/roles-editor.php:178 msgid "Capability" msgstr "" -#: features/roles-editor/roles-editor.php:178 +#: features/roles-editor/roles-editor.php:179 msgid "You can't delete this capability from your role." msgstr "" -#: features/roles-editor/roles-editor.php:238 #: features/roles-editor/roles-editor.php:239 -#: features/roles-editor/roles-editor.php:244 -#: features/roles-editor/roles-editor.php:251 +#: features/roles-editor/roles-editor.php:240 +#: features/roles-editor/roles-editor.php:245 +#: features/roles-editor/roles-editor.php:252 msgid "Roles Editor" msgstr "" -#: features/roles-editor/roles-editor.php:240 #: features/roles-editor/roles-editor.php:241 +#: features/roles-editor/roles-editor.php:242 msgid "Add New Role" msgstr "" -#: features/roles-editor/roles-editor.php:242 +#: features/roles-editor/roles-editor.php:243 msgid "Edit Role" msgstr "" -#: features/roles-editor/roles-editor.php:243 +#: features/roles-editor/roles-editor.php:244 msgid "New Role" msgstr "" -#: features/roles-editor/roles-editor.php:245 +#: features/roles-editor/roles-editor.php:246 msgid "View Role" msgstr "" -#: features/roles-editor/roles-editor.php:246 +#: features/roles-editor/roles-editor.php:247 msgid "Search the Roles Editor" msgstr "" -#: features/roles-editor/roles-editor.php:247 +#: features/roles-editor/roles-editor.php:248 msgid "No roles found" msgstr "" -#: features/roles-editor/roles-editor.php:248 +#: features/roles-editor/roles-editor.php:249 msgid "No roles found in trash" msgstr "" -#: features/roles-editor/roles-editor.php:289 -#: features/roles-editor/roles-editor.php:292 +#: features/roles-editor/roles-editor.php:290 +#: features/roles-editor/roles-editor.php:293 msgid "Role updated." msgstr "" -#: features/roles-editor/roles-editor.php:290 +#: features/roles-editor/roles-editor.php:291 msgid "Custom field updated." msgstr "" -#: features/roles-editor/roles-editor.php:291 +#: features/roles-editor/roles-editor.php:292 msgid "Custom field deleted." msgstr "" -#: features/roles-editor/roles-editor.php:294 +#: features/roles-editor/roles-editor.php:295 msgid "Role created." msgstr "" -#: features/roles-editor/roles-editor.php:295 +#: features/roles-editor/roles-editor.php:296 msgid "Role saved." msgstr "" -#: features/roles-editor/roles-editor.php:296 +#: features/roles-editor/roles-editor.php:297 msgid "Role submitted." msgstr "" -#: features/roles-editor/roles-editor.php:297 +#: features/roles-editor/roles-editor.php:298 #, php-format msgid "Role scheduled for: %1$s" msgstr "" -#: features/roles-editor/roles-editor.php:298 +#: features/roles-editor/roles-editor.php:299 msgid "Role draft updated." msgstr "" -#: features/roles-editor/roles-editor.php:357 +#: features/roles-editor/roles-editor.php:358 msgid "Role Name" msgstr "" -#: features/roles-editor/roles-editor.php:358 +#: features/roles-editor/roles-editor.php:359 msgid "Role Slug" msgstr "" -#: features/roles-editor/roles-editor.php:359 +#: features/roles-editor/roles-editor.php:360 msgid "Capabilities" msgstr "" -#: features/roles-editor/roles-editor.php:360 +#: features/roles-editor/roles-editor.php:361 msgid "Users" msgstr "" -#: features/roles-editor/roles-editor.php:870 +#: features/roles-editor/roles-editor.php:871 msgid "Clone" msgstr "" -#: features/roles-editor/roles-editor.php:877 +#: features/roles-editor/roles-editor.php:878 msgid "You can't delete your role." msgstr "" -#: features/roles-editor/roles-editor.php:885 +#: features/roles-editor/roles-editor.php:886 msgid "Change Default" msgstr "" -#: features/roles-editor/roles-editor.php:886 +#: features/roles-editor/roles-editor.php:887 msgid "You can't delete the default role. Change it first." msgstr "" -#: features/email-confirmation/email-confirmation.php:400 +#: features/email-confirmation/email-confirmation.php:401 #, php-format msgid "" "To activate your user, please click the following link:

            %s%s%s

            " "After you activate it you will receive yet *another email* with your login." msgstr "" -#: features/email-confirmation/email-confirmation.php:578 +#: features/email-confirmation/email-confirmation.php:579 #, php-format msgid "Welcome to %1$s!


            Your username is:%2$s" msgstr "" @@ -1126,17 +1114,17 @@ msgid "Cancel" msgstr "Anuluj" #: features/functions.php:711 features/functions.php:725 -#: admin/manage-fields.php:1193 features/roles-editor/roles-editor.php:174 -#: features/roles-editor/roles-editor.php:877 -#: features/roles-editor/roles-editor.php:886 -#: features/roles-editor/roles-editor.php:897 +#: admin/manage-fields.php:1193 features/roles-editor/roles-editor.php:175 +#: features/roles-editor/roles-editor.php:878 +#: features/roles-editor/roles-editor.php:887 +#: features/roles-editor/roles-editor.php:898 #: features/email-confirmation/class-email-confirmation.php:120 #: features/email-confirmation/class-email-confirmation.php:217 msgid "Delete" msgstr "Usuń" #: features/functions.php:718 features/functions.php:725 -#: admin/manage-fields.php:1193 features/roles-editor/roles-editor.php:859 +#: admin/manage-fields.php:1193 features/roles-editor/roles-editor.php:860 msgid "Edit" msgstr "Edytuj" @@ -1144,11 +1132,36 @@ msgstr "Edytuj" msgid "Content" msgstr "Treść" -#: features/functions.php:995 +#: features/functions.php:736 +#, php-format +msgid "" +"To allow users to register for your website via Profile Builder, you first " +"must enable user registration. Go to %1$sNetwork Settings%2$s, and under " +"Registration Settings make sure to check “User accounts may be registered”. " +"%3$sDismiss%4$s" +msgstr "" +"Aby zezwolić użytkownikom na logowanie na Twojej stronie poprzez Profile " +"Builder, musisz najpierw zezwolić na rejestrację użytkowników. Idź do " +"%1$sUstawień Sieciowych%2$s, oraz upewnij się, że pole \"Możliwość " +"rejestracji kont użytowników\" jest zaznaczone. %3$sAnuluj%4$s" + +#: features/functions.php:740 +#, php-format +msgid "" +"To allow users to register for your website via Profile Builder, you first " +"must enable user registration. Go to %1$sSettings -> General%2$s tab, and " +"under Membership make sure to check “Anyone can register”. %3$sDismiss%4$s" +msgstr "" +"Aby zezwolić użytkownikom na rejestrację na Twojej stronie poprzez Profile " +"Builder, musisz najpierw umożliwić rejestrację użytkowników. Idź do zakładki " +"%1$sUstawienia -> Ogólne%2$s oraz upewnij się, że w sekcji Członkowstwo pole " +"“Każdy może się zarejestrować” jest zaznaczone. %3$sOdrzuć%4$s" + +#: features/functions.php:994 msgid "here" msgstr "tutaj" -#: features/functions.php:996 +#: features/functions.php:995 #, php-format msgid "" "You will soon be redirected automatically. If you see this page for more " @@ -1361,7 +1374,7 @@ msgstr "Dodaj użytkownika" msgid "Register" msgstr "Zarejestruj się" -#: front-end/class-formbuilder.php:418 admin/add-ons.php:170 +#: front-end/class-formbuilder.php:418 admin/add-ons.php:171 msgid "Update" msgstr "Aktualizuj" @@ -1382,7 +1395,7 @@ msgid "This username is now active!" msgstr "Konto tego użytkownika jest aktywne!" #: front-end/register.php:71 -#: features/email-confirmation/email-confirmation.php:441 +#: features/email-confirmation/email-confirmation.php:442 msgid "Could not create user!" msgstr "Nie udało się stworzyć użytkownika!" @@ -1395,7 +1408,7 @@ msgid "Your email was successfully confirmed." msgstr "Twój adres email został zweryfikowany poprawnie." #: front-end/register.php:125 -#: features/email-confirmation/email-confirmation.php:641 +#: features/email-confirmation/email-confirmation.php:642 msgid "" "Before you can access your account, an administrator needs to approve it. " "You will be notified via email." @@ -1617,7 +1630,7 @@ msgstr "Bardzo słabe" msgid "Add-Ons" msgstr "Wtyczki" -#: admin/add-ons.php:34 admin/add-ons.php:129 admin/add-ons.php:231 +#: admin/add-ons.php:34 admin/add-ons.php:130 admin/add-ons.php:232 #: admin/pms-cross-promotion.php:78 admin/pms-cross-promotion.php:114 #: admin/pms-cross-promotion.php:193 msgid "Activate" @@ -1643,15 +1656,15 @@ msgstr "Wtyczka została aktywowana." msgid "Retry Install" msgstr "Ponów instalację" -#: admin/add-ons.php:43 admin/add-ons.php:140 +#: admin/add-ons.php:43 admin/add-ons.php:141 msgid "Add-On is active" msgstr "Wtyczka jest aktywna" -#: admin/add-ons.php:44 admin/add-ons.php:138 +#: admin/add-ons.php:44 admin/add-ons.php:139 msgid "Add-On is inactive" msgstr "Wtyczka jest nieaktywna" -#: admin/add-ons.php:46 admin/add-ons.php:133 admin/add-ons.php:235 +#: admin/add-ons.php:46 admin/add-ons.php:134 admin/add-ons.php:236 #: admin/pms-cross-promotion.php:90 admin/pms-cross-promotion.php:118 #: admin/pms-cross-promotion.php:197 msgid "Deactivate" @@ -1669,33 +1682,33 @@ msgstr "" "Coś poszło nie tak. Nie możemy połączyć się z serwerem. Spróbuj ponownie " "później." -#: admin/add-ons.php:148 admin/add-ons.php:248 +#: admin/add-ons.php:149 admin/add-ons.php:249 #: admin/pms-cross-promotion.php:134 admin/pms-cross-promotion.php:213 msgid "Download Now" msgstr "Pobierz" -#: admin/add-ons.php:153 admin/add-ons.php:251 +#: admin/add-ons.php:154 admin/add-ons.php:252 #: admin/pms-cross-promotion.php:141 admin/pms-cross-promotion.php:220 msgid "Compatible with your version of Profile Builder." msgstr "Kompatybilność z twoją wersją Profile Builder." -#: admin/add-ons.php:162 +#: admin/add-ons.php:163 msgid "Upgrade Profile Builder" msgstr "Zaktualizuj Profile Builder" -#: admin/add-ons.php:163 +#: admin/add-ons.php:164 msgid "Not compatible with Profile Builder" msgstr "Niekompatybilne z Profile Builder" -#: admin/add-ons.php:171 +#: admin/add-ons.php:172 msgid "Not compatible with your version of Profile Builder." msgstr "Niekompatybilne z twoją wersją Profile Buildera" -#: admin/add-ons.php:172 +#: admin/add-ons.php:173 msgid "Minimum required Profile Builder version:" msgstr "Minimalna wymagana wersja Profile Buidler:" -#: admin/add-ons.php:177 +#: admin/add-ons.php:178 #, php-format msgid "" "Could not install add-on. Retry or
            install " @@ -3286,6 +3299,12 @@ msgstr "" "pojawi się na Twojej stronie! ( możesz zmienić to ustawienie w zakładce " "\"%s\" )" +#: admin/admin-functions.php:41 +msgid "Display name publicly as - only appears on the Edit Profile page!" +msgstr "" +"Wyświetlona nazwa użytkownika tylko się wyświetla w zakładce: ,,Edycja " +"profilu''" + #: admin/admin-functions.php:132 #, php-format msgid "" @@ -3334,52 +3353,52 @@ msgstr "Instaluj teraz" msgid "Basic Information" msgstr "Informacje podstawowe" -#: admin/basic-info.php:31 +#: admin/basic-info.php:32 msgid "" "The best way to add front-end registration, edit profile and login forms." msgstr "" "Najlepszy sposób, aby dodać możliwość rejestracji użytkowników, edycję ich " "profili oraz formularze do logowania." -#: admin/basic-info.php:33 +#: admin/basic-info.php:34 msgid "For Modern User Interaction" msgstr "Dla Nowoczesnej Interakcji Użytkowników" -#: admin/basic-info.php:36 features/login-widget/login-widget.php:59 +#: admin/basic-info.php:37 features/login-widget/login-widget.php:59 msgid "Login" msgstr "Login" -#: admin/basic-info.php:37 +#: admin/basic-info.php:38 #, php-format msgid "Friction-less login using %s shortcode or a widget." -msgstr "Logowanie \"bez tarcia\" przy użyciu shortcode: %s lub widgetu." +msgstr ",,Bezbolesne'' logowanie z wykorzystaniem shortcodu: %s albo widgetu" -#: admin/basic-info.php:40 +#: admin/basic-info.php:41 msgid "Registration" msgstr "Rejestracja" -#: admin/basic-info.php:41 +#: admin/basic-info.php:42 #, php-format msgid "Beautiful registration forms fully customizable using the %s shortcode." msgstr "" -"Ładne, w pełni edytowalne formularze rejestracji z wykorzystaniem shortcode: " -"%s" +"Łatwy i przyjemny formularz rejestracji (w pełni konfigurowalny) z " +"wykorzystaniem shortcodu %s. " -#: admin/basic-info.php:44 +#: admin/basic-info.php:45 msgid "Edit Profile" msgstr "Edytuj profil" -#: admin/basic-info.php:45 +#: admin/basic-info.php:46 #, php-format msgid "Straight forward edit profile forms using %s shortcode." -msgstr "Prosta edycja profilu za pomocą shortcodu: %s" +msgstr "Prosta edycja profilu w formularzu z wykorzystaniem shortcodu: %s" #: features/upgrades/upgrades-functions.php:91 #: features/upgrades/upgrades-functions.php:134 msgid "The usernames cannot be changed." msgstr "Nazwa użytkownika nie może być zmieniona." -#: features/roles-editor/roles-editor.php:249 +#: features/roles-editor/roles-editor.php:250 msgid "Role" msgstr "Rola" @@ -3408,47 +3427,47 @@ msgstr "Powiadomienie email przesłane ponownie do użytkownika" msgid "You either don't have permission for that action or there was an error!" msgstr "Nie masz uprawnień do wykonania tej akcji lub wystąpił błąd!" -#: features/email-confirmation/email-confirmation.php:397 +#: features/email-confirmation/email-confirmation.php:398 #, php-format msgid "[%1$s] Activate %2$s" msgstr "[%1$s] Aktywuj %2$s" -#: features/email-confirmation/email-confirmation.php:444 +#: features/email-confirmation/email-confirmation.php:445 msgid "That username is already activated!" msgstr "Kont tego użytkownika jest już aktywne!" -#: features/email-confirmation/email-confirmation.php:467 +#: features/email-confirmation/email-confirmation.php:468 msgid "There was an error while trying to activate the user" msgstr "Wystąpił błąd podczas aktywowania konta dla tego użytkownika" -#: features/email-confirmation/email-confirmation.php:515 +#: features/email-confirmation/email-confirmation.php:516 msgid "A new subscriber has (been) registered!" msgstr "Nowy użytkownik został zarejestrowany!" -#: features/email-confirmation/email-confirmation.php:518 +#: features/email-confirmation/email-confirmation.php:519 #, php-format msgid "New subscriber on %1$s.

            Username:%2$s
            E-mail:%3$s
            " msgstr "" "Nowy subskrybent na %1$s.

            Nazwa Użytkownika:%2$s
            E-mail:" "%3$s
            " -#: features/email-confirmation/email-confirmation.php:569 +#: features/email-confirmation/email-confirmation.php:570 #, php-format msgid "[%1$s] Your new account information" msgstr "[%1$s] Informacje o Twoim nowym koncie" -#: features/email-confirmation/email-confirmation.php:573 -#: features/email-confirmation/email-confirmation.php:582 +#: features/email-confirmation/email-confirmation.php:574 +#: features/email-confirmation/email-confirmation.php:583 msgid "Your selected password at signup" msgstr "Hasło, które podałeś podczas rejestracji" -#: features/email-confirmation/email-confirmation.php:580 +#: features/email-confirmation/email-confirmation.php:581 #, php-format msgid "Welcome to %1$s!


            Your username is:%2$s and password:%3$s" msgstr "" "Witaj na %1$s!


            Twoja nazwa użytkownika to:%2$s oraz hasło:%3$s" -#: features/email-confirmation/email-confirmation.php:633 +#: features/email-confirmation/email-confirmation.php:634 msgid "" "The \"Admin Approval\" feature was activated at the time of registration, so " "please remember that you need to approve this user before he/she can log in!" diff --git a/profile-builder/translation/profile-builder.pot b/profile-builder/translation/profile-builder.pot index 42a9543..c8276ea 100644 --- a/profile-builder/translation/profile-builder.pot +++ b/profile-builder/translation/profile-builder.pot @@ -1,5859 +1,5859 @@ -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: profile-builder\n" -"POT-Creation-Date: 2016-11-28 15:04+0200\n" -"PO-Revision-Date: 2015-04-30 10:26+0200\n" -"Last-Translator: \n" -"Language-Team: Cozmoslabs\n" -"Language: en\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 1.8.5\n" -"X-Poedit-Basepath: ../..\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Poedit-KeywordsList: __;_e;_x;_n\n" -"X-Poedit-SourceCharset: UTF-8\n" -"X-Poedit-SearchPath-0: profile-builder-2.0\n" -"X-Poedit-SearchPath-1: pb-add-on-woocommerce\n" - -#: pb-add-on-woocommerce/billing-fields.php:5 -#: pb-add-on-woocommerce/shipping-fields.php:5 -msgid "Country" -msgstr "" - -#: pb-add-on-woocommerce/billing-fields.php:6 -#: pb-add-on-woocommerce/shipping-fields.php:6 -#: profile-builder-2.0/admin/manage-fields.php:196 -msgid "First Name" -msgstr "" - -#: pb-add-on-woocommerce/billing-fields.php:7 -#: pb-add-on-woocommerce/shipping-fields.php:7 -#: profile-builder-2.0/admin/manage-fields.php:197 -msgid "Last Name" -msgstr "" - -#: pb-add-on-woocommerce/billing-fields.php:8 -#: pb-add-on-woocommerce/shipping-fields.php:8 -msgid "Company Name" -msgstr "" - -#: pb-add-on-woocommerce/billing-fields.php:9 -#: pb-add-on-woocommerce/shipping-fields.php:9 -msgid "Address" -msgstr "" - -#: pb-add-on-woocommerce/billing-fields.php:11 -#: pb-add-on-woocommerce/shipping-fields.php:11 -msgid "Town / City" -msgstr "" - -#: pb-add-on-woocommerce/billing-fields.php:12 -#: pb-add-on-woocommerce/shipping-fields.php:12 -msgid "State / County" -msgstr "" - -#: pb-add-on-woocommerce/billing-fields.php:13 -#: pb-add-on-woocommerce/shipping-fields.php:13 -msgid "Postcode / Zip" -msgstr "" - -#: pb-add-on-woocommerce/billing-fields.php:14 -msgid "Email Address" -msgstr "" - -#: pb-add-on-woocommerce/billing-fields.php:15 -msgid "Phone" -msgstr "" - -#: pb-add-on-woocommerce/billing-fields.php:278 -msgid "Ship to a different address?" -msgstr "" - -#: pb-add-on-woocommerce/index.php:169 pb-add-on-woocommerce/index.php:437 -msgid "Billing Address" -msgstr "" - -#: pb-add-on-woocommerce/index.php:169 -msgid "Displays customer billing fields in front-end. " -msgstr "" - -#: pb-add-on-woocommerce/index.php:173 pb-add-on-woocommerce/index.php:438 -msgid "Shipping Address" -msgstr "" - -#: pb-add-on-woocommerce/index.php:173 -msgid "Displays customer shipping fields in front-end. " -msgstr "" - -#: pb-add-on-woocommerce/index.php:248 pb-add-on-woocommerce/index.php:267 -#: pb-add-on-woocommerce/index.php:364 pb-add-on-woocommerce/index.php:367 -#: pb-add-on-woocommerce/index.php:493 -msgid "Address line 2" -msgstr "" - -#: pb-add-on-woocommerce/index.php:256 -msgid "Billing Fields" -msgstr "" - -#: pb-add-on-woocommerce/index.php:256 -msgid "" -"Select which WooCommerce Billing fields to display to the user ( drag and " -"drop to re-order ) and which should be required" -msgstr "" - -#: pb-add-on-woocommerce/index.php:257 -msgid "Billing Fields Order" -msgstr "" - -#: pb-add-on-woocommerce/index.php:257 -msgid "Save the billing fields order from the billing fields checkboxes" -msgstr "" - -#: pb-add-on-woocommerce/index.php:258 -msgid "Billing Fields Name" -msgstr "" - -#: pb-add-on-woocommerce/index.php:258 -msgid "Save the billing fields names" -msgstr "" - -#: pb-add-on-woocommerce/index.php:275 -msgid "Shipping Fields" -msgstr "" - -#: pb-add-on-woocommerce/index.php:275 -msgid "" -"Select which WooCommerce Shipping fields to display to the user ( drag and " -"drop to re-order ) and which should be required" -msgstr "" - -#: pb-add-on-woocommerce/index.php:276 -msgid "Shipping Fields Order" -msgstr "" - -#: pb-add-on-woocommerce/index.php:276 -msgid "Save the shipping fields order from the billing fields checkboxes" -msgstr "" - -#: pb-add-on-woocommerce/index.php:277 -msgid "Shipping Fields Name" -msgstr "" - -#: pb-add-on-woocommerce/index.php:277 -msgid "Save the shipping fields names" -msgstr "" - -#: pb-add-on-woocommerce/index.php:305 -msgid "Field Name" -msgstr "" - -#: pb-add-on-woocommerce/index.php:306 -#: profile-builder-2.0/admin/manage-fields.php:155 -msgid "Required" -msgstr "" - -#: pb-add-on-woocommerce/index.php:369 -msgid "Click to edit " -msgstr "" - -#: pb-add-on-woocommerce/index.php:393 -#: profile-builder-2.0/front-end/default-fields/email/email.php:47 -msgid "The email you entered is not a valid email address." -msgstr "" - -#: pb-add-on-woocommerce/index.php:541 -msgid "" -"WooCommerce needs to be installed and activated for Profile Builder - " -"WooCommerce Sync Add-on to work!" -msgstr "" - -#: pb-add-on-woocommerce/templates/myaccount-login-register.php:25 -#: profile-builder-2.0/admin/basic-info.php:36 -#: profile-builder-2.0/features/login-widget/login-widget.php:59 -msgid "Login" -msgstr "" - -#: pb-add-on-woocommerce/templates/myaccount-login-register.php:36 -#: profile-builder-2.0/front-end/class-formbuilder.php:420 -#: profile-builder-2.0/front-end/login.php:257 -msgid "Register" -msgstr "" - -#: pb-add-on-woocommerce/woo-checkout-field-support.php:96 -msgid "Display on WooCommerce Checkout" -msgstr "" - -#: pb-add-on-woocommerce/woo-checkout-field-support.php:96 -msgid "" -"Whether the field should be added to the WooCommerce checkout form or not" -msgstr "" - -#: pb-add-on-woocommerce/woo-checkout-field-support.php:252 -#: profile-builder-2.0/assets/lib/wck-api/fields/upload.php:43 -#: profile-builder-2.0/front-end/extra-fields/upload/upload.php:112 -msgid "Remove" -msgstr "" - -#: pb-add-on-woocommerce/woo-checkout-field-support.php:262 -#: profile-builder-2.0/front-end/extra-fields/upload/upload.php:122 -msgid "Select File" -msgstr "" - -#: pb-add-on-woocommerce/woo-checkout-field-support.php:268 -#: profile-builder-2.0/assets/lib/wck-api/fields/upload.php:75 -#: profile-builder-2.0/front-end/extra-fields/upload/upload.php:128 -msgid "Upload " -msgstr "" - -#: pb-add-on-woocommerce/woo-checkout-field-support.php:368 -msgid "is not a valid phone number." -msgstr "" - -#: pb-add-on-woocommerce/woo-checkout-field-support.php:377 -msgid "is not a number." -msgstr "" - -#: pb-add-on-woocommerce/woo-checkout-field-support.php:382 -msgid "must be a multiplier of " -msgstr "" - -#: pb-add-on-woocommerce/woo-checkout-field-support.php:387 -msgid "must be a greater than or equal to " -msgstr "" - -#: pb-add-on-woocommerce/woo-checkout-field-support.php:392 -msgid "must be less than or equal to " -msgstr "" - -#: pb-add-on-woocommerce/woosync-page.php:23 -#: pb-add-on-woocommerce/woosync-page.php:70 -msgid "WooCommerce Sync" -msgstr "" - -#: pb-add-on-woocommerce/woosync-page.php:76 -msgid "Choose Register form to display on My Account page:" -msgstr "" - -#: pb-add-on-woocommerce/woosync-page.php:80 -#: pb-add-on-woocommerce/woosync-page.php:114 -#: profile-builder-2.0/modules/user-listing/userlisting.php:486 -msgid "None" -msgstr "" - -#: pb-add-on-woocommerce/woosync-page.php:81 -msgid "Default Register" -msgstr "" - -#: pb-add-on-woocommerce/woosync-page.php:103 -msgid "" -"Select which Profile Builder Register form to display on My Account page " -"from WooCommerce.
            This will also add the Profile Builder Login form to " -"MyAccount page." -msgstr "" - -#: pb-add-on-woocommerce/woosync-page.php:110 -msgid "Choose Edit Profile form to display on My Account page:" -msgstr "" - -#: pb-add-on-woocommerce/woosync-page.php:115 -msgid "Default Edit Profile" -msgstr "" - -#: pb-add-on-woocommerce/woosync-page.php:137 -msgid "" -"Select which Profile Builder Edit-profile form to display on My Account page " -"from WooCommerce." -msgstr "" - -#: pb-add-on-woocommerce/woosync-page.php:147 -#: profile-builder-2.0/admin/admin-bar.php:86 -#: profile-builder-2.0/admin/general-settings.php:208 -#: profile-builder-2.0/admin/register-version.php:95 -#: profile-builder-2.0/features/functions.php:724 -#: profile-builder-2.0/modules/modules.php:127 -msgid "Save Changes" -msgstr "" - -#: profile-builder-2.0/admin/add-ons.php:10 -#: profile-builder-2.0/admin/add-ons.php:32 -msgid "Add-Ons" -msgstr "" - -#: profile-builder-2.0/admin/add-ons.php:34 -#: profile-builder-2.0/admin/add-ons.php:129 -#: profile-builder-2.0/admin/add-ons.php:231 -#: profile-builder-2.0/admin/pms-cross-promotion.php:78 -#: profile-builder-2.0/admin/pms-cross-promotion.php:114 -#: profile-builder-2.0/admin/pms-cross-promotion.php:193 -msgid "Activate" -msgstr "" - -#: profile-builder-2.0/admin/add-ons.php:36 -#: profile-builder-2.0/admin/pms-cross-promotion.php:80 -msgid "Downloading and installing..." -msgstr "" - -#: profile-builder-2.0/admin/add-ons.php:37 -#: profile-builder-2.0/admin/pms-cross-promotion.php:81 -msgid "Installation complete" -msgstr "" - -#: profile-builder-2.0/admin/add-ons.php:39 -msgid "Add-On is Active" -msgstr "" - -#: profile-builder-2.0/admin/add-ons.php:40 -msgid "Add-On has been activated" -msgstr "" - -#: profile-builder-2.0/admin/add-ons.php:41 -#: profile-builder-2.0/admin/pms-cross-promotion.php:85 -msgid "Retry Install" -msgstr "" - -#: profile-builder-2.0/admin/add-ons.php:43 -#: profile-builder-2.0/admin/add-ons.php:140 -msgid "Add-On is active" -msgstr "" - -#: profile-builder-2.0/admin/add-ons.php:44 -#: profile-builder-2.0/admin/add-ons.php:138 -msgid "Add-On is inactive" -msgstr "" - -#: profile-builder-2.0/admin/add-ons.php:46 -#: profile-builder-2.0/admin/add-ons.php:133 -#: profile-builder-2.0/admin/add-ons.php:235 -#: profile-builder-2.0/admin/pms-cross-promotion.php:90 -#: profile-builder-2.0/admin/pms-cross-promotion.php:118 -#: profile-builder-2.0/admin/pms-cross-promotion.php:197 -msgid "Deactivate" -msgstr "" - -#: profile-builder-2.0/admin/add-ons.php:47 -msgid "Add-On has been deactivated." -msgstr "" - -#: profile-builder-2.0/admin/add-ons.php:59 -msgid "" -"Something went wrong, we could not connect to the server. Please try again " -"later." -msgstr "" - -#: profile-builder-2.0/admin/add-ons.php:103 -msgid "Available in Hobbyist and Pro Versions" -msgstr "" - -#: profile-builder-2.0/admin/add-ons.php:105 -msgid "Available in All Versions" -msgstr "" - -#: profile-builder-2.0/admin/add-ons.php:148 -msgid "Learn More" -msgstr "" - -#: profile-builder-2.0/admin/add-ons.php:148 -#: profile-builder-2.0/admin/add-ons.php:248 -#: profile-builder-2.0/admin/pms-cross-promotion.php:134 -#: profile-builder-2.0/admin/pms-cross-promotion.php:213 -msgid "Download Now" -msgstr "" - -#: profile-builder-2.0/admin/add-ons.php:153 -#: profile-builder-2.0/admin/add-ons.php:251 -#: profile-builder-2.0/admin/pms-cross-promotion.php:141 -#: profile-builder-2.0/admin/pms-cross-promotion.php:220 -msgid "Compatible with your version of Profile Builder." -msgstr "" - -#: profile-builder-2.0/admin/add-ons.php:162 -msgid "Upgrade Profile Builder" -msgstr "" - -#: profile-builder-2.0/admin/add-ons.php:163 -msgid "Not compatible with Profile Builder" -msgstr "" - -#: profile-builder-2.0/admin/add-ons.php:170 -#: profile-builder-2.0/front-end/class-formbuilder.php:423 -msgid "Update" -msgstr "" - -#: profile-builder-2.0/admin/add-ons.php:171 -msgid "Not compatible with your version of Profile Builder." -msgstr "" - -#: profile-builder-2.0/admin/add-ons.php:172 -msgid "Minimum required Profile Builder version:" -msgstr "" - -#: profile-builder-2.0/admin/add-ons.php:177 -#, php-format -msgid "" -"Could not install add-on. Retry or
            install " -"manually." -msgstr "" - -#: profile-builder-2.0/admin/add-ons.php:190 -msgid "Recommended Plugins" -msgstr "" - -#: profile-builder-2.0/admin/add-ons.php:219 -#: profile-builder-2.0/admin/pms-cross-promotion.php:102 -msgid "Free" -msgstr "" - -#: profile-builder-2.0/admin/add-ons.php:221 -msgid "" -"Accept user payments, create subscription plans and restrict content on your " -"membership site." -msgstr "" - -#: profile-builder-2.0/admin/add-ons.php:222 -#: profile-builder-2.0/admin/pms-cross-promotion.php:105 -msgid "More Details" -msgstr "" - -#: profile-builder-2.0/admin/add-ons.php:240 -#: profile-builder-2.0/admin/pms-cross-promotion.php:88 -#: profile-builder-2.0/admin/pms-cross-promotion.php:123 -#: profile-builder-2.0/admin/pms-cross-promotion.php:202 -msgid "Plugin is inactive" -msgstr "" - -#: profile-builder-2.0/admin/add-ons.php:242 -#: profile-builder-2.0/admin/pms-cross-promotion.php:87 -#: profile-builder-2.0/admin/pms-cross-promotion.php:125 -#: profile-builder-2.0/admin/pms-cross-promotion.php:204 -msgid "Plugin is active" -msgstr "" - -#: profile-builder-2.0/admin/add-ons.php:256 -#: profile-builder-2.0/admin/pms-cross-promotion.php:146 -#, php-format -msgid "" -"Could not install plugin. Retry or install " -"manually." -msgstr "" - -#: profile-builder-2.0/admin/admin-bar.php:10 -msgid "Show/Hide the Admin Bar on the Front-End" -msgstr "" - -#: profile-builder-2.0/admin/admin-bar.php:10 -#: profile-builder-2.0/admin/admin-bar.php:47 -msgid "Admin Bar Settings" -msgstr "" - -#: profile-builder-2.0/admin/admin-bar.php:48 -msgid "" -"Choose which user roles view the admin bar in the front-end of the website." -msgstr "" - -#: profile-builder-2.0/admin/admin-bar.php:57 -msgid "User-Role" -msgstr "" - -#: profile-builder-2.0/admin/admin-bar.php:58 -msgid "Visibility" -msgstr "" - -#: profile-builder-2.0/admin/admin-bar.php:73 -msgid "Default" -msgstr "" - -#: profile-builder-2.0/admin/admin-bar.php:74 -msgid "Show" -msgstr "" - -#: profile-builder-2.0/admin/admin-bar.php:75 -#: profile-builder-2.0/modules/user-listing/userlisting.php:1496 -msgid "Hide" -msgstr "" - -#: profile-builder-2.0/admin/admin-functions.php:34 -#, php-format -msgid "" -"Login is set to be done using the E-mail. This field will NOT appear in the " -"front-end! ( you can change these settings under the \"%s\" tab )" -msgstr "" - -#: profile-builder-2.0/admin/admin-functions.php:34 -#: profile-builder-2.0/admin/general-settings.php:10 -#: profile-builder-2.0/admin/general-settings.php:38 -msgid "General Settings" -msgstr "" - -#: profile-builder-2.0/admin/admin-functions.php:40 -msgid "Display name publicly as - only appears on the Edit Profile page!" -msgstr "" - -#: profile-builder-2.0/admin/admin-functions.php:128 -#, php-format -msgid "" -"ERROR: The password must have the minimum length of %s " -"characters" -msgstr "" - -#: profile-builder-2.0/admin/admin-functions.php:134 -#: profile-builder-2.0/admin/general-settings.php:194 -msgid "Very weak" -msgstr "" - -#: profile-builder-2.0/admin/admin-functions.php:134 -#: profile-builder-2.0/admin/general-settings.php:195 -#: profile-builder-2.0/features/functions.php:579 -msgid "Weak" -msgstr "" - -#: profile-builder-2.0/admin/admin-functions.php:134 -#: profile-builder-2.0/admin/general-settings.php:196 -#: profile-builder-2.0/features/functions.php:579 -msgid "Medium" -msgstr "" - -#: profile-builder-2.0/admin/admin-functions.php:134 -#: profile-builder-2.0/admin/general-settings.php:197 -#: profile-builder-2.0/features/functions.php:579 -msgid "Strong" -msgstr "" - -#: profile-builder-2.0/admin/admin-functions.php:145 -#, php-format -msgid "ERROR: The password must have a minimum strength of %s" -msgstr "" - -#: profile-builder-2.0/admin/admin-functions.php:184 -msgid "Add Field" -msgstr "" - -#: profile-builder-2.0/admin/admin-functions.php:186 -#: profile-builder-2.0/modules/class-mustache-templates/class-mustache-templates.php:390 -msgid "Save Settings" -msgstr "" - -#: profile-builder-2.0/admin/admin-functions.php:197 -#, php-format -msgid "" -"If you enjoy using %1$s please rate us on WordPress.org. More happy users means more " -"features, less bugs and better support for everyone. " -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:10 -msgid "Basic Information" -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:29 -#, php-format -msgid "Version %s" -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:30 -msgid "Profile Builder " -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:31 -msgid "" -"The best way to add front-end registration, edit profile and login forms." -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:33 -msgid "For Modern User Interaction" -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:37 -#, php-format -msgid "Friction-less login using %s shortcode or a widget." -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:40 -msgid "Registration" -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:41 -#, php-format -msgid "Beautiful registration forms fully customizable using the %s shortcode." -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:44 -msgid "Edit Profile" -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:45 -#, php-format -msgid "Straight forward edit profile forms using %s shortcode." -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:51 -msgid "Extra Features" -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:52 -msgid "" -"Features that give you more control over your users, increased security and " -"help you fight user registration spam." -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:53 -msgid "Enable extra features" -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:57 -msgid "Recover Password" -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:58 -#, php-format -msgid "Allow users to recover their password in the front-end using the %s." -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:61 -msgid "Admin Approval (*)" -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:62 -msgid "" -"You decide who is a user on your website. Get notified via email or approve " -"multiple users at once from the WordPress UI." -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:65 -msgid "Email Confirmation" -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:66 -msgid "" -"Make sure users sign up with genuine emails. On registration users will " -"receive a notification to confirm their email address." -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:69 -msgid "Minimum Password Length and Strength Meter" -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:70 -msgid "" -"Eliminate weak passwords altogether by setting a minimum password length and " -"enforcing a certain password strength." -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:73 -msgid "Login with Email or Username" -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:74 -msgid "" -"Allow users to log in with their email or username when accessing your site." -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:87 -msgid "Customize Your Forms The Way You Want (*)" -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:88 -msgid "" -"With Extra Profile Fields you can create the exact registration form your " -"project needs." -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:90 -msgid "Extra Profile Fields are available in Hobbyist or PRO versions" -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:92 -msgid "Get started with extra fields" -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:95 -msgid "Avatar Upload" -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:96 -msgid "Generic Uploads" -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:97 -msgid "Agree To Terms Checkbox" -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:98 -msgid "Datepicker" -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:99 -msgid "Timepicker" -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:100 -msgid "Colorpicker" -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:101 -msgid "reCAPTCHA" -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:102 -msgid "Country Select" -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:103 -msgid "Currency Select" -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:104 -msgid "Timezone Select" -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:108 -msgid "Input / Hidden Input" -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:109 -msgid "Number" -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:110 -msgid "Checkbox" -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:111 -msgid "Select" -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:112 -msgid "Radio Buttons" -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:113 -msgid "Textarea" -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:114 -msgid "Validation" -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:115 -msgid "Map" -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:116 -msgid "HTML" -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:125 -msgid "Powerful Modules (**)" -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:126 -msgid "" -"Everything you will need to manage your users is probably already available " -"using the Pro Modules." -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:128 -msgid "Enable your modules" -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:131 -msgid "Find out more about PRO Modules" -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:136 -#: profile-builder-2.0/modules/modules.php:89 -#: profile-builder-2.0/modules/user-listing/userlisting.php:11 -#: profile-builder-2.0/modules/user-listing/userlisting.php:12 -#: profile-builder-2.0/modules/user-listing/userlisting.php:17 -#: profile-builder-2.0/modules/user-listing/userlisting.php:23 -msgid "User Listing" -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:138 -msgid "" -"Easy to edit templates for listing your website users as well as creating " -"single user pages. Shortcode based, offering many options to customize your " -"listings." -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:140 -#, php-format -msgid "" -"To create a page containing the users registered to this current site/blog, " -"insert the following shortcode in a page of your chosing: %s." -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:144 -msgid "Email Customizer" -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:145 -msgid "" -"Personalize all emails sent to your users or admins. On registration, email " -"confirmation, admin approval / un-approval." -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:148 -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:32 -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:33 -#: profile-builder-2.0/modules/modules.php:110 -msgid "Custom Redirects" -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:149 -msgid "" -"Keep your users out of the WordPress dashboard, redirect them to the front-" -"page after login or registration, everything is just a few clicks away." -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:154 -#: profile-builder-2.0/modules/modules.php:75 -msgid "Multiple Registration Forms" -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:155 -msgid "" -"Set up multiple registration forms with different fields for certain user " -"roles. Capture different information from different types of users." -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:158 -#: profile-builder-2.0/modules/modules.php:82 -msgid "Multiple Edit-profile Forms" -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:159 -msgid "" -"Allow different user roles to edit their specific information. Set up " -"multiple edit-profile forms with different fields for certain user roles." -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:162 -#: profile-builder-2.0/modules/modules.php:117 -msgid "Repeater Fields" -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:163 -msgid "" -"Set up a repeating group of fields on register and edit profile forms. Limit " -"the number of repeated groups for each user role." -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:187 -#, php-format -msgid " * only available in the %1$sHobbyist and Pro versions%2$s." -msgstr "" - -#: profile-builder-2.0/admin/basic-info.php:188 -#, php-format -msgid "** only available in the %1$sPro version%2$s." -msgstr "" - -#: profile-builder-2.0/admin/general-settings.php:42 -msgid "Load Profile Builder's own CSS file in the front-end:" -msgstr "" - -#: profile-builder-2.0/admin/general-settings.php:45 -#: profile-builder-2.0/admin/general-settings.php:58 -#: profile-builder-2.0/admin/general-settings.php:107 -#: profile-builder-2.0/modules/multiple-forms/register-forms.php:229 -#: profile-builder-2.0/modules/multiple-forms/register-forms.php:230 -#: profile-builder-2.0/modules/user-listing/userlisting.php:2142 -msgid "Yes" -msgstr "" - -#: profile-builder-2.0/admin/general-settings.php:47 -#, php-format -msgid "You can find the default file here: %1$s" -msgstr "" - -#: profile-builder-2.0/admin/general-settings.php:54 -msgid "\"Email Confirmation\" Activated:" -msgstr "" - -#: profile-builder-2.0/admin/general-settings.php:59 -#: profile-builder-2.0/admin/general-settings.php:108 -#: profile-builder-2.0/modules/multiple-forms/register-forms.php:229 -#: profile-builder-2.0/modules/multiple-forms/register-forms.php:230 -msgid "No" -msgstr "" - -#: profile-builder-2.0/admin/general-settings.php:62 -msgid "" -"This works with front-end forms only. Recommended to redirect WP default " -"registration to a Profile Builder one using \"Custom Redirects\" module." -msgstr "" - -#: profile-builder-2.0/admin/general-settings.php:64 -#, php-format -msgid "" -"You can find a list of unconfirmed email addresses %1$sUsers > All Users > " -"Email Confirmation%2$s." -msgstr "" - -#: profile-builder-2.0/admin/general-settings.php:72 -msgid "\"Email Confirmation\" Landing Page:" -msgstr "" - -#: profile-builder-2.0/admin/general-settings.php:77 -msgid "Existing Pages" -msgstr "" - -#: profile-builder-2.0/admin/general-settings.php:92 -msgid "" -"Specify the page where the users will be directed when confirming the email " -"account. This page can differ from the register page(s) and can be changed " -"at any time. If none selected, a simple confirmation page will be displayed " -"for the user." -msgstr "" - -#: profile-builder-2.0/admin/general-settings.php:103 -msgid "\"Admin Approval\" Activated:" -msgstr "" - -#: profile-builder-2.0/admin/general-settings.php:111 -#, php-format -msgid "" -"You can find a list of users at %1$sUsers > All Users > Admin Approval%2$s." -msgstr "" - -#: profile-builder-2.0/admin/general-settings.php:118 -msgid "\"Admin Approval\" on User Role:" -msgstr "" - -#: profile-builder-2.0/admin/general-settings.php:137 -msgid "Select on what user roles to activate Admin Approval." -msgstr "" - -#: profile-builder-2.0/admin/general-settings.php:149 -msgid "\"Admin Approval\" Feature:" -msgstr "" - -#: profile-builder-2.0/admin/general-settings.php:152 -#, php-format -msgid "" -"You decide who is a user on your website. Get notified via email or approve " -"multiple users at once from the WordPress UI. Enable Admin Approval by " -"upgrading to %1$sHobbyist or PRO versions%2$s." -msgstr "" - -#: profile-builder-2.0/admin/general-settings.php:159 -msgid "Allow Users to Log in With:" -msgstr "" - -#: profile-builder-2.0/admin/general-settings.php:163 -msgid "Username and Email" -msgstr "" - -#: profile-builder-2.0/admin/general-settings.php:164 -#: profile-builder-2.0/admin/manage-fields.php:195 -#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:166 -#: profile-builder-2.0/features/email-confirmation/class-email-confirmation.php:167 -#: profile-builder-2.0/front-end/login.php:85 -#: profile-builder-2.0/front-end/login.php:99 -#: profile-builder-2.0/front-end/login.php:225 -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:56 -#: profile-builder-2.0/modules/email-customizer/email-customizer.php:28 -#: profile-builder-2.0/modules/user-listing/userlisting.php:101 -#: profile-builder-2.0/modules/user-listing/userlisting.php:268 -#: profile-builder-2.0/modules/user-listing/userlisting.php:704 -#: profile-builder-2.0/modules/user-listing/userlisting.php:2098 -msgid "Username" -msgstr "" - -#: profile-builder-2.0/admin/general-settings.php:165 -#: profile-builder-2.0/front-end/login.php:222 -#: profile-builder-2.0/modules/email-customizer/email-customizer.php:29 -#: profile-builder-2.0/modules/user-listing/userlisting.php:710 -#: profile-builder-2.0/modules/user-listing/userlisting.php:2099 -msgid "Email" -msgstr "" - -#: profile-builder-2.0/admin/general-settings.php:168 -msgid "\"Username and Email\" - users can Log In with both Username and Email." -msgstr "" - -#: profile-builder-2.0/admin/general-settings.php:169 -msgid "\"Username\" - users can Log In only with Username." -msgstr "" - -#: profile-builder-2.0/admin/general-settings.php:170 -msgid "\"Email\" - users can Log In only with Email." -msgstr "" - -#: profile-builder-2.0/admin/general-settings.php:177 -msgid "Minimum Password Length:" -msgstr "" - -#: profile-builder-2.0/admin/general-settings.php:182 -msgid "" -"Enter the minimum characters the password should have. Leave empty for no " -"minimum limit" -msgstr "" - -#: profile-builder-2.0/admin/general-settings.php:189 -msgid "Minimum Password Strength:" -msgstr "" - -#: profile-builder-2.0/admin/general-settings.php:193 -msgid "Disabled" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:12 -msgid "Manage Fields" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:13 -msgid "Manage Default and Extra Fields" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:77 -msgid "Choose one of the supported field types" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:79 -#, php-format -msgid "" -". Extra Field Types are available in Hobbyist or PRO " -"versions." -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:113 -msgid "Field Title" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:113 -msgid "Title of the field" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:114 -#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:245 -#: profile-builder-2.0/modules/multiple-forms/register-forms.php:266 -msgid "Field" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:115 -msgid "Meta-name" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:115 -msgid "" -"Use this in conjunction with WordPress functions to display the value in the " -"page of your choosing
            Auto-completed but in some cases editable (in " -"which case it must be unique)
            Changing this might take long in case of a " -"very big user-count" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:116 -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:65 -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:95 -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:114 -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:139 -#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:246 -#: profile-builder-2.0/modules/multiple-forms/register-forms.php:267 -msgid "ID" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:116 -#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:246 -#: profile-builder-2.0/modules/multiple-forms/register-forms.php:267 -msgid "" -"A unique, auto-generated ID for this particular field
            You can use this " -"in conjuction with filters to target this element if needed
            Can't be " -"edited" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:117 -msgid "Description" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:117 -msgid "" -"Enter a (detailed) description of the option for end users to read
            Optional" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:118 -msgid "Row Count" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:118 -msgid "" -"Specify the number of rows for a 'Textarea' field
            If not specified, " -"defaults to 5" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:119 -msgid "Allowed Image Extensions" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:119 -msgid "" -"Specify the extension(s) you want to limit to upload
            Example: .ext1,." -"ext2,.ext3
            If not specified, defaults to: .jpg,.jpeg,.gif,.png (.*)" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:120 -msgid "Allowed Upload Extensions" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:120 -msgid "" -"Specify the extension(s) you want to limit to upload
            Example: .ext1,." -"ext2,.ext3
            If not specified, defaults to all WordPress allowed file " -"extensions (.*)" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:121 -msgid "Avatar Size" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:121 -msgid "" -"Enter a value (between 20 and 200) for the size of the 'Avatar'
            If not " -"specified, defaults to 100" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:122 -msgid "Date-format" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:122 -msgid "" -"Specify the format of the date when using Datepicker
            Valid options: mm/" -"dd/yy, mm/yy/dd, dd/yy/mm, dd/mm/yy, yy/dd/mm, yy/mm/dd
            If not " -"specified, defaults to mm/dd/yy" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:123 -msgid "Terms of Agreement" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:123 -msgid "" -"Enter a detailed description of the temrs of agreement for the user to read." -"
            Links can be inserted by using standard HTML syntax: <a href=" -"\"custom_url\">custom_text</a>" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:124 -msgid "Options" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:124 -msgid "" -"Enter a comma separated list of values
            This can be anything, as it is " -"hidden from the user, but should not contain special characters or " -"apostrophes" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:125 -msgid "Labels" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:125 -msgid "Enter a comma separated list of labels
            Visible for the user" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:126 -msgid "Site Key" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:126 -msgid "" -"The site key from Google, www.google.com/recaptcha" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:127 -msgid "Secret Key" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:127 -msgid "" -"The secret key from Google, www.google.com/recaptcha" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:128 -msgid "Display on PB forms" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:128 -msgid "PB Login" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:128 -msgid "PB Register" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:128 -msgid "PB Recover Password" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:128 -msgid "Select on which Profile Builder forms to display reCAPTCHA" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:129 -msgid "Display on default WP forms" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:129 -msgid "Default WP Login" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:129 -msgid "Default WP Register" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:129 -msgid "Default WP Recover Password" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:129 -msgid "Select on which default WP forms to display reCAPTCHA" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:130 -msgid "User Roles" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:130 -msgid "" -"Select which user roles to show to the user ( drag and drop to re-order )" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:131 -msgid "User Roles Order" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:131 -msgid "Save the user role order from the user roles checkboxes" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:132 -msgid "Default Value" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:132 -msgid "Default value of the field" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:133 -#: profile-builder-2.0/admin/manage-fields.php:135 -#: profile-builder-2.0/admin/manage-fields.php:136 -#: profile-builder-2.0/admin/manage-fields.php:137 -msgid "Default Option" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:133 -msgid "Specify the option which should be selected by default" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:134 -msgid "Default Option(s)" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:134 -msgid "" -"Specify the option which should be checked by default
            If there are " -"multiple values, separate them with a ',' (comma)" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:135 -#: profile-builder-2.0/admin/manage-fields.php:136 -#: profile-builder-2.0/admin/manage-fields.php:137 -msgid "Default option of the field" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:138 -msgid "Show Currency Symbol" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:138 -msgid "" -"Whether the currency symbol should be displayed after the currency name in " -"the select option." -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:139 -msgid "Show Post Type" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:139 -msgid "Posts from what post type will be displayed in the select." -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:140 -msgid "Allowable Values" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:140 -msgid "" -"Enter a comma separated list of possible values. Upon registration if the " -"value provided by the user does not match one of these values, the user will " -"not be registered." -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:141 -msgid "Error Message" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:141 -msgid "Set a custom error message that will be displayed to the user." -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:142 -msgid "Time Format" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:142 -msgid "Specify the time format." -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:143 -msgid "Google Maps API Key" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:143 -msgid "" -"Enter your Google Maps API key ( Get your API key ). If more than one map fields are added to a form the API key from the " -"first map displayed will be used." -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:144 -msgid "Default Latitude" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:144 -msgid "" -"The latitude at which the map should be displayed when no pins are attached." -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:145 -msgid "Default Longitude" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:145 -msgid "" -"The longitude at which the map should be displayed when no pins are attached." -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:146 -msgid "Default Zoom Level" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:146 -msgid "Add a number from 0 to 19. The higher the number the higher the zoom." -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:147 -msgid "Map Height" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:147 -msgid "The height of the map." -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:148 -msgid "Default Content" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:148 -msgid "Default value of the textarea" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:149 -msgid "HTML Content" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:149 -msgid "Add your HTML (or text) content" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:150 -msgid "Phone Format" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:150 -msgid "" -"You can use: # for numbers, parentheses ( ), - sign, + sign, dot . and " -"spaces." -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:150 -msgid "Eg. (###) ###-####" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:150 -msgid "Empty field won't check for correct phone number." -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:151 -msgid "Heading Tag" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:151 -msgid "Change heading field size on front-end forms" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:152 -msgid "Min Number Value" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:152 -msgid "Min allowed number value (0 to allow only positive numbers)" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:152 -msgid "Leave it empty for no min value" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:153 -msgid "Max Number Value" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:153 -msgid "Max allowed number value (0 to allow only negative numbers)" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:153 -msgid "Leave it empty for no max value" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:154 -msgid "Number Step Value" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:154 -msgid "" -"Step value 1 to allow only integers, 0.1 to allow integers and numbers with " -"1 decimal" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:154 -msgid "To allow multiple decimals use for eg. 0.01 (for 2 deciamls) and so on" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:154 -msgid "" -"You can also use step value to specify the legal number intervals (eg. step " -"value 2 will allow only -4, -2, 0, 2 and so on)" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:154 -msgid "Leave it empty for no restriction" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:155 -msgid "Whether the field is required or not" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:156 -msgid "Overwrite Existing" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:156 -msgid "" -"Selecting 'Yes' will add the field to the list, but will overwrite any other " -"field in the database that has the same meta-name
            Use this at your own " -"risk" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:162 -msgid "Field Properties" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:175 -msgid "Registration & Edit Profile" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:194 -msgid "Name" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:195 -msgid "Usernames cannot be changed." -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:198 -#: profile-builder-2.0/modules/user-listing/userlisting.php:743 -#: profile-builder-2.0/modules/user-listing/userlisting.php:2106 -msgid "Nickname" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:199 -msgid "Display name publicly as" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:200 -msgid "Contact Info" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:201 -#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:169 -#: profile-builder-2.0/features/email-confirmation/class-email-confirmation.php:168 -#: profile-builder-2.0/modules/user-listing/userlisting.php:107 -msgid "E-mail" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:202 -#: profile-builder-2.0/modules/email-customizer/email-customizer.php:32 -#: profile-builder-2.0/modules/user-listing/userlisting.php:110 -#: profile-builder-2.0/modules/user-listing/userlisting.php:725 -#: profile-builder-2.0/modules/user-listing/userlisting.php:2100 -msgid "Website" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:206 -msgid "AIM" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:207 -msgid "Yahoo IM" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:208 -msgid "Jabber / Google Talk" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:211 -msgid "About Yourself" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:212 -#: profile-builder-2.0/modules/user-listing/userlisting.php:113 -#: profile-builder-2.0/modules/user-listing/userlisting.php:728 -#: profile-builder-2.0/modules/user-listing/userlisting.php:2101 -msgid "Biographical Info" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:212 -msgid "" -"Share a little biographical information to fill out your profile. This may " -"be shown publicly." -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:213 -#: profile-builder-2.0/front-end/recover.php:73 -#: profile-builder-2.0/modules/email-customizer/email-customizer.php:30 -msgid "Password" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:213 -msgid "Type your password." -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:214 -#: profile-builder-2.0/front-end/recover.php:74 -msgid "Repeat Password" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:214 -msgid "Type your password again. " -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:273 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Afghanistan" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:274 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Aland Islands" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:275 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Albania" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:276 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Algeria" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:277 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "American Samoa" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:278 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Andorra" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:279 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Angola" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:280 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Anguilla" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:281 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Antarctica" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:282 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Antigua and Barbuda" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:283 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Argentina" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:284 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Armenia" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:285 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Aruba" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:286 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Australia" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:287 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Austria" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:288 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Azerbaijan" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:289 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Bahamas" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:290 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Bahrain" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:291 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Bangladesh" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:292 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Barbados" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:293 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Belarus" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:294 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Belgium" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:295 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Belize" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:296 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Benin" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:297 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Bermuda" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:298 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Bhutan" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:299 -msgid "Bolivia" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:300 -msgid "Bonaire, Saint Eustatius and Saba" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:301 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Bosnia and Herzegovina" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:302 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Botswana" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:303 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Bouvet Island" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:304 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Brazil" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:305 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "British Indian Ocean Territory" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:306 -msgid "British Virgin Islands" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:307 -msgid "Brunei" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:308 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Bulgaria" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:309 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Burkina Faso" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:310 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Burundi" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:311 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Cambodia" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:312 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Cameroon" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:313 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Canada" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:314 -msgid "Cape Verde" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:315 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Cayman Islands" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:316 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Central African Republic" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:317 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Chad" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:318 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Chile" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:319 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "China" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:320 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Christmas Island" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:321 -msgid "Cocos Islands" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:322 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Colombia" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:323 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Comoros" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:324 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Cook Islands" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:325 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Costa Rica" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:326 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Croatia" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:327 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Cuba" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:328 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Curacao" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:329 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Cyprus" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:330 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Czech Republic" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:331 -msgid "Democratic Republic of the Congo" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:332 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Denmark" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:333 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Djibouti" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:334 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Dominica" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:335 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Dominican Republic" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:336 -msgid "East Timor" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:337 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Ecuador" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:338 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Egypt" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:339 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "El Salvador" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:340 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Equatorial Guinea" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:341 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Eritrea" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:342 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Estonia" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:343 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Ethiopia" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:344 -msgid "Falkland Islands" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:345 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Faroe Islands" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:346 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Fiji" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:347 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Finland" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:348 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "France" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:349 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "French Guiana" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:350 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "French Polynesia" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:351 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "French Southern Territories" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:352 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Gabon" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:353 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Gambia" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:354 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Georgia" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:355 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Germany" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:356 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Ghana" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:357 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Gibraltar" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:358 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Greece" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:359 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Greenland" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:360 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Grenada" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:361 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Guadeloupe" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:362 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Guam" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:363 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Guatemala" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:364 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Guernsey" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:365 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Guinea" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:366 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Guinea-Bissau" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:367 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Guyana" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:368 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Haiti" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:369 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Heard Island and McDonald Islands" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:370 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Honduras" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:371 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Hong Kong" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:372 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Hungary" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:373 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Iceland" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:374 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "India" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:375 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Indonesia" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:376 -msgid "Iran" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:377 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Iraq" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:378 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Ireland" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:379 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Isle of Man" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:380 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Israel" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:381 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Italy" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:382 -msgid "Ivory Coast" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:383 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Jamaica" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:384 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Japan" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:385 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Jersey" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:386 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Jordan" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:387 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Kazakhstan" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:388 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Kenya" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:389 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Kiribati" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:390 -msgid "Kosovo" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:391 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Kuwait" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:392 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Kyrgyzstan" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:393 -msgid "Laos" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:394 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Latvia" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:395 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Lebanon" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:396 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Lesotho" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:397 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Liberia" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:398 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Libya" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:399 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Liechtenstein" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:400 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Lithuania" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:401 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Luxembourg" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:402 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Macao" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:403 -msgid "Macedonia" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:404 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Madagascar" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:405 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Malawi" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:406 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Malaysia" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:407 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Maldives" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:408 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Mali" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:409 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Malta" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:410 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Marshall Islands" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:411 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Martinique" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:412 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Mauritania" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:413 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Mauritius" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:414 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Mayotte" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:415 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Mexico" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:416 -msgid "Micronesia" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:417 -msgid "Moldova" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:418 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Monaco" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:419 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Mongolia" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:420 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Montenegro" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:421 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Montserrat" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:422 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Morocco" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:423 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Mozambique" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:424 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Myanmar" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:425 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Namibia" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:426 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Nauru" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:427 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Nepal" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:428 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Netherlands" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:429 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "New Caledonia" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:430 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "New Zealand" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:431 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Nicaragua" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:432 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Niger" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:433 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Nigeria" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:434 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Niue" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:435 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Norfolk Island" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:436 -msgid "North Korea" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:437 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Northern Mariana Islands" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:438 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Norway" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:439 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Oman" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:440 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Pakistan" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:441 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Palau" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:442 -msgid "Palestinian Territory" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:443 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Panama" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:444 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Papua New Guinea" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:445 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Paraguay" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:446 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Peru" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:447 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Philippines" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:448 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Pitcairn" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:449 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Poland" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:450 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Portugal" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:451 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Puerto Rico" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:452 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Qatar" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:453 -msgid "Republic of the Congo" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:454 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Reunion" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:455 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Romania" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:456 -msgid "Russia" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:457 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Rwanda" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:458 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Saint Barthelemy" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:459 -msgid "Saint Helena" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:460 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Saint Kitts and Nevis" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:461 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Saint Lucia" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:462 -msgid "Saint Martin" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:463 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Saint Pierre and Miquelon" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:464 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Saint Vincent and the Grenadines" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:465 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Samoa" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:466 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "San Marino" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:467 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Sao Tome and Principe" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:468 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Saudi Arabia" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:469 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Senegal" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:470 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Serbia" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:471 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Seychelles" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:472 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Sierra Leone" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:473 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Singapore" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:474 -msgid "Sint Maarten" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:475 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Slovakia" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:476 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Slovenia" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:477 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Solomon Islands" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:478 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Somalia" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:479 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "South Africa" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:480 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "South Georgia and the South Sandwich Islands" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:481 -msgid "South Korea" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:482 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "South Sudan" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:483 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Spain" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:484 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Sri Lanka" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:485 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Sudan" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:486 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Suriname" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:487 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Svalbard and Jan Mayen" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:488 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Swaziland" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:489 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Sweden" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:490 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Switzerland" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:491 -msgid "Syria" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:492 -msgid "Taiwan" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:493 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Tajikistan" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:494 -msgid "Tanzania" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:495 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Thailand" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:496 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Togo" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:497 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Tokelau" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:498 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Tonga" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:499 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Trinidad and Tobago" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:500 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Tunisia" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:501 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Turkey" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:502 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Turkmenistan" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:503 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Turks and Caicos Islands" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:504 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Tuvalu" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:505 -msgid "U.S. Virgin Islands" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:506 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Uganda" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:507 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Ukraine" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:508 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "United Arab Emirates" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:509 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "United Kingdom" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:510 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "United States" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:511 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "United States Minor Outlying Islands" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:512 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Uruguay" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:513 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Uzbekistan" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:514 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Vanuatu" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:515 -msgid "Vatican" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:516 -msgid "Venezuela" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:517 -msgid "Vietnam" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:518 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Wallis and Futuna" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:519 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Western Sahara" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:520 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Yemen" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:521 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Zambia" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:522 -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Zimbabwe" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:555 -msgid "Albania Lek" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:556 -msgid "Afghanistan Afghani" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:557 -msgid "Argentina Peso" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:558 -msgid "Aruba Guilder" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:559 -msgid "Australia Dollar" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:560 -msgid "Azerbaijan New Manat" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:561 -msgid "Bahamas Dollar" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:562 -msgid "Barbados Dollar" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:563 -msgid "Bangladeshi taka" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:564 -msgid "Belarus Ruble" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:565 -msgid "Belize Dollar" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:566 -msgid "Bermuda Dollar" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:567 -msgid "Bolivia Boliviano" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:568 -msgid "Bosnia and Herzegovina Convertible Marka" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:569 -msgid "Botswana Pula" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:570 -msgid "Bulgaria Lev" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:571 -msgid "Brazil Real" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:572 -msgid "Brunei Darussalam Dollar" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:573 -msgid "Cambodia Riel" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:574 -msgid "Canada Dollar" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:575 -msgid "Cayman Islands Dollar" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:576 -msgid "Chile Peso" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:577 -msgid "China Yuan Renminbi" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:578 -msgid "Colombia Peso" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:579 -msgid "Costa Rica Colon" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:580 -msgid "Croatia Kuna" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:581 -msgid "Cuba Peso" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:582 -msgid "Czech Republic Koruna" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:583 -msgid "Denmark Krone" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:584 -msgid "Dominican Republic Peso" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:585 -msgid "East Caribbean Dollar" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:586 -msgid "Egypt Pound" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:587 -msgid "El Salvador Colon" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:588 -msgid "Estonia Kroon" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:589 -msgid "Euro" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:590 -msgid "Falkland Islands (Malvinas) Pound" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:591 -msgid "Fiji Dollar" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:592 -msgid "Ghana Cedis" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:593 -msgid "Gibraltar Pound" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:594 -msgid "Guatemala Quetzal" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:595 -msgid "Guernsey Pound" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:596 -msgid "Guyana Dollar" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:597 -msgid "Honduras Lempira" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:598 -msgid "Hong Kong Dollar" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:599 -msgid "Hungary Forint" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:600 -msgid "Iceland Krona" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:601 -msgid "India Rupee" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:602 -msgid "Indonesia Rupiah" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:603 -msgid "Iran Rial" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:604 -msgid "Isle of Man Pound" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:605 -msgid "Israel Shekel" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:606 -msgid "Jamaica Dollar" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:607 -msgid "Japan Yen" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:608 -msgid "Jersey Pound" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:609 -msgid "Kazakhstan Tenge" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:610 -msgid "Korea (North) Won" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:611 -msgid "Korea (South) Won" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:612 -msgid "Kyrgyzstan Som" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:613 -msgid "Laos Kip" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:614 -msgid "Latvia Lat" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:615 -msgid "Lebanon Pound" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:616 -msgid "Liberia Dollar" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:617 -msgid "Lithuania Litas" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:618 -msgid "Macedonia Denar" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:619 -msgid "Malaysia Ringgit" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:620 -msgid "Mauritius Rupee" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:621 -msgid "Mexico Peso" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:622 -msgid "Mongolia Tughrik" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:623 -msgid "Mozambique Metical" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:624 -msgid "Namibia Dollar" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:625 -msgid "Nepal Rupee" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:626 -msgid "Netherlands Antilles Guilder" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:627 -msgid "New Zealand Dollar" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:628 -msgid "Nicaragua Cordoba" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:629 -msgid "Nigeria Naira" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:630 -msgid "Norway Krone" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:631 -msgid "Oman Rial" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:632 -msgid "Pakistan Rupee" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:633 -msgid "Panama Balboa" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:634 -msgid "Paraguay Guarani" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:635 -msgid "Peru Nuevo Sol" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:636 -msgid "Philippines Peso" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:637 -msgid "Poland Zloty" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:638 -msgid "Qatar Riyal" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:639 -msgid "Romania New Leu" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:640 -msgid "Russia Ruble" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:641 -msgid "Saint Helena Pound" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:642 -msgid "Saudi Arabia Riyal" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:643 -msgid "Serbia Dinar" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:644 -msgid "Seychelles Rupee" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:645 -msgid "Singapore Dollar" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:646 -msgid "Solomon Islands Dollar" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:647 -msgid "Somalia Shilling" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:648 -msgid "South Africa Rand" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:649 -msgid "Sri Lanka Rupee" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:650 -msgid "Sweden Krona" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:651 -msgid "Switzerland Franc" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:652 -msgid "Suriname Dollar" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:653 -msgid "Syria Pound" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:654 -msgid "Taiwan New Dollar" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:655 -msgid "Thailand Baht" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:656 -msgid "Trinidad and Tobago Dollar" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:657 -#: profile-builder-2.0/admin/manage-fields.php:658 -msgid "Turkey Lira" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:659 -msgid "Tuvalu Dollar" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:660 -msgid "Ukraine Hryvna" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:661 -msgid "United Kingdom Pound" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:662 -msgid "Uganda Shilling" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:663 -msgid "US Dollar" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:664 -msgid "Uruguay Peso" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:665 -msgid "Uzbekistan Som" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:666 -msgid "Venezuela Bolivar" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:667 -msgid "Viet Nam Dong" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:668 -msgid "Yemen Rial" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:669 -msgid "Zimbabwe Dollar" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:966 -#: profile-builder-2.0/admin/manage-fields.php:1120 -msgid "You must select a field\n" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:976 -msgid "" -"Please choose a different field type as this one already exists in your form " -"(must be unique)\n" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:987 -msgid "The entered avatar size is not between 20 and 200\n" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:990 -msgid "The entered avatar size is not numerical\n" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:998 -msgid "The entered row number is not numerical\n" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:1001 -msgid "You must enter a value for the row number\n" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:1009 -msgid "You must enter the site key\n" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:1011 -msgid "You must enter the secret key\n" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:1019 -msgid "The entered value for the Datepicker is not a valid date-format\n" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:1022 -msgid "You must enter a value for the date-format\n" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:1038 -msgid "The meta-name cannot be empty\n" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:1050 -#: profile-builder-2.0/admin/manage-fields.php:1058 -#: profile-builder-2.0/admin/manage-fields.php:1069 -msgid "That meta-name is already in use\n" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:1080 -msgid "" -"The meta-name can only contain lowercase letters, numbers, _ , - and no " -"spaces.\n" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:1100 -#, php-format -msgid "" -"The following option(s) did not coincide with the ones in the options list: " -"%s\n" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:1104 -#, php-format -msgid "" -"The following option did not coincide with the ones in the options list: %s\n" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:1111 -msgid "Please select at least one user role\n" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:1127 -msgid "That field is already added in this form\n" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:1176 -msgid "" -"
            Title
            Type
            Meta Name
            Required
            " -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:1176 -#: profile-builder-2.0/assets/lib/wck-api/wordpress-creation-kit.php:443 -#: profile-builder-2.0/assets/lib/wck-api/wordpress-creation-kit.php:535 -#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:108 -#: profile-builder-2.0/features/functions.php:745 -#: profile-builder-2.0/features/functions.php:752 -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:179 -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:193 -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:207 -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:221 -#: profile-builder-2.0/modules/multiple-forms/multiple-forms.php:406 -msgid "Edit" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:1176 -#: profile-builder-2.0/assets/lib/wck-api/wordpress-creation-kit.php:443 -#: profile-builder-2.0/assets/lib/wck-api/wordpress-creation-kit.php:536 -#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:113 -#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:224 -#: profile-builder-2.0/features/email-confirmation/class-email-confirmation.php:120 -#: profile-builder-2.0/features/email-confirmation/class-email-confirmation.php:217 -#: profile-builder-2.0/features/functions.php:738 -#: profile-builder-2.0/features/functions.php:752 -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:179 -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:193 -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:207 -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:221 -msgid "Delete" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:1191 -msgid "Use these shortcodes on the pages you want the forms to be displayed:" -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:1200 -msgid "" -"If you're interested in displaying different fields in the registration and " -"edit profile forms, please use the Multiple Registration & Edit Profile " -"Forms Addon." -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:1202 -msgid "" -"With Profile Builder Pro v2 you can display different fields in the " -"registration and edit profile forms, using the Multiple Registration & Edit " -"Profile Forms module." -msgstr "" - -#: profile-builder-2.0/admin/manage-fields.php:1296 -msgid "Search Location" -msgstr "" - -#: profile-builder-2.0/admin/pms-cross-promotion.php:10 -msgid "Paid Accounts" -msgstr "" - -#: profile-builder-2.0/admin/pms-cross-promotion.php:33 -msgid "Paid Member Subscriptions - a free WordPress plugin" -msgstr "" - -#: profile-builder-2.0/admin/pms-cross-promotion.php:37 -msgid "" -"With the new Subscriptions Field in Profile Builder, your registration forms " -"will allow your users to sign up for paid accounts." -msgstr "" - -#: profile-builder-2.0/admin/pms-cross-promotion.php:40 -msgid "Paid & Free Subscriptions" -msgstr "" - -#: profile-builder-2.0/admin/pms-cross-promotion.php:41 -msgid "Restrict Content" -msgstr "" - -#: profile-builder-2.0/admin/pms-cross-promotion.php:42 -msgid "Member Management" -msgstr "" - -#: profile-builder-2.0/admin/pms-cross-promotion.php:43 -msgid "Email Templates" -msgstr "" - -#: profile-builder-2.0/admin/pms-cross-promotion.php:44 -msgid "Account Management" -msgstr "" - -#: profile-builder-2.0/admin/pms-cross-promotion.php:45 -msgid "Subscription Management" -msgstr "" - -#: profile-builder-2.0/admin/pms-cross-promotion.php:46 -msgid "Payment Management" -msgstr "" - -#: profile-builder-2.0/admin/pms-cross-promotion.php:83 -msgid "Plugin is Active" -msgstr "" - -#: profile-builder-2.0/admin/pms-cross-promotion.php:84 -msgid "Plugin has been activated" -msgstr "" - -#: profile-builder-2.0/admin/pms-cross-promotion.php:91 -msgid "Plugin has been deactivated." -msgstr "" - -#: profile-builder-2.0/admin/pms-cross-promotion.php:104 -msgid "" -"Accept user payments, create subscription plans and restrict content on your " -"website." -msgstr "" - -#: profile-builder-2.0/admin/pms-cross-promotion.php:137 -#: profile-builder-2.0/admin/pms-cross-promotion.php:216 -msgid "Install Now" -msgstr "" - -#: profile-builder-2.0/admin/pms-cross-promotion.php:155 -msgid "Step by Step Quick Setup" -msgstr "" - -#: profile-builder-2.0/admin/pms-cross-promotion.php:239 -#, php-format -msgid "" -"Allow your users to have paid accounts with Profile Builder. %1$sFind out how >%2$s %3$sDismiss%4$s" -msgstr "" - -#: profile-builder-2.0/admin/register-version.php:14 -msgid "Register Your Version" -msgstr "" - -#: profile-builder-2.0/admin/register-version.php:14 -msgid "Register Version" -msgstr "" - -#: profile-builder-2.0/admin/register-version.php:22 -msgid "Profile Builder Register" -msgstr "" - -#: profile-builder-2.0/admin/register-version.php:69 -#, php-format -msgid "" -"Now that you acquired a copy of %s, you should take the time and register it " -"with the serial number you received" -msgstr "" - -#: profile-builder-2.0/admin/register-version.php:70 -msgid "" -"If you register this version of Profile Builder, you'll receive information " -"regarding upgrades, patches, and technical support." -msgstr "" - -#: profile-builder-2.0/admin/register-version.php:72 -msgid " Serial Number:" -msgstr "" - -#: profile-builder-2.0/admin/register-version.php:77 -msgid "The serial number was successfully validated!" -msgstr "" - -#: profile-builder-2.0/admin/register-version.php:79 -msgid "The serial number entered couldn't be validated!" -msgstr "" - -#: profile-builder-2.0/admin/register-version.php:81 -msgid "The serial number is about to expire soon!" -msgstr "" - -#: profile-builder-2.0/admin/register-version.php:81 -#, php-format -msgid "" -" Your serial number is about to expire, please %1$s Renew Your License%2$s." -msgstr "" - -#: profile-builder-2.0/admin/register-version.php:83 -msgid "The serial number couldn't be validated because it expired!" -msgstr "" - -#: profile-builder-2.0/admin/register-version.php:83 -#, php-format -msgid " Your serial number is expired, please %1$s Renew Your License%2$s." -msgstr "" - -#: profile-builder-2.0/admin/register-version.php:85 -msgid "" -"The serial number couldn't be validated because process timed out. This is " -"possible due to the server being down. Please try again later!" -msgstr "" - -#: profile-builder-2.0/admin/register-version.php:87 -msgid "(e.g. RMPB-15-SN-253a55baa4fbe7bf595b2aabb8d72985)" -msgstr "" - -#: profile-builder-2.0/admin/register-version.php:243 -#, php-format -msgid "" -"

            Your Profile Builder serial number is invalid or " -"missing.
            Please %1$sregister your copy%2$s to receive access to " -"automatic updates and support. Need a license key? %3$sPurchase one now%4$s" -msgstr "" - -#: profile-builder-2.0/admin/register-version.php:246 -#, php-format -msgid "" -"

            Your Profile Builder license has expired.
            Please " -"%1$sRenew Your Licence%2$s to continue receiving access to product " -"downloads, automatic updates and support. %3$sRenew now and get 50% off " -"%4$s %5$sDismiss%6$s

            " -msgstr "" - -#: profile-builder-2.0/admin/register-version.php:251 -#, php-format -msgid "" -"

            Your Profile Builder license is about to expire on %5$s. " -"
            Please %1$sRenew Your Licence%2$s to continue receiving access to " -"product downloads, automatic updates and support. %3$sRenew now and get " -"50% off %4$s %6$sDismiss%7$s

            " -msgstr "" - -#: profile-builder-2.0/assets/lib/wck-api/fields/country select.php:14 -#: profile-builder-2.0/assets/lib/wck-api/fields/cpt select.php:17 -#: profile-builder-2.0/assets/lib/wck-api/fields/select.php:14 -#: profile-builder-2.0/assets/lib/wck-api/fields/user select.php:15 -#: profile-builder-2.0/front-end/extra-fields/select-cpt/select-cpt.php:32 -#: profile-builder-2.0/front-end/extra-fields/select-cpt/select-cpt.php:54 -msgid "...Choose" -msgstr "" - -#: profile-builder-2.0/assets/lib/wck-api/fields/nested repeater.php:8 -#, php-format -msgid "You can add the information for the %s after you add a entry" -msgstr "" - -#: profile-builder-2.0/assets/lib/wck-api/wordpress-creation-kit.php:340 -#: profile-builder-2.0/modules/class-mustache-templates/class-mustache-templates.php:254 -msgid "Save" -msgstr "" - -#: profile-builder-2.0/assets/lib/wck-api/wordpress-creation-kit.php:340 -msgid "Add Entry" -msgstr "" - -#: profile-builder-2.0/assets/lib/wck-api/wordpress-creation-kit.php:443 -#: profile-builder-2.0/features/functions.php:752 -msgid "Content" -msgstr "" - -#: profile-builder-2.0/assets/lib/wck-api/wordpress-creation-kit.php:535 -msgid "Edit this item" -msgstr "" - -#: profile-builder-2.0/assets/lib/wck-api/wordpress-creation-kit.php:536 -msgid "Delete this item" -msgstr "" - -#: profile-builder-2.0/assets/lib/wck-api/wordpress-creation-kit.php:705 -msgid "Please enter a value for the required field " -msgstr "" - -#: profile-builder-2.0/assets/lib/wck-api/wordpress-creation-kit.php:754 -msgid "You are not allowed to do this." -msgstr "" - -#: profile-builder-2.0/assets/lib/wck-api/wordpress-creation-kit.php:1253 -msgid "Syncronize WCK" -msgstr "" - -#: profile-builder-2.0/assets/lib/wck-api/wordpress-creation-kit.php:1265 -msgid "Syncronize WCK Translation" -msgstr "" - -#: profile-builder-2.0/assets/misc/plugin-compatibilities.php:241 -msgid "" -"Your account has to be confirmed by an administrator before you can log in." -msgstr "" - -#: profile-builder-2.0/features/admin-approval/admin-approval.php:14 -#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:453 -msgid "Admin Approval" -msgstr "" - -#: profile-builder-2.0/features/admin-approval/admin-approval.php:28 -#: profile-builder-2.0/features/email-confirmation/email-confirmation.php:58 -msgid "Do you want to" -msgstr "" - -#: profile-builder-2.0/features/admin-approval/admin-approval.php:51 -msgid "Your session has expired! Please refresh the page and try again" -msgstr "" - -#: profile-builder-2.0/features/admin-approval/admin-approval.php:62 -msgid "User successfully approved!" -msgstr "" - -#: profile-builder-2.0/features/admin-approval/admin-approval.php:70 -msgid "User successfully unapproved!" -msgstr "" - -#: profile-builder-2.0/features/admin-approval/admin-approval.php:76 -msgid "User successfully deleted!" -msgstr "" - -#: profile-builder-2.0/features/admin-approval/admin-approval.php:81 -#: profile-builder-2.0/features/admin-approval/admin-approval.php:125 -#: profile-builder-2.0/features/email-confirmation/email-confirmation.php:135 -msgid "You either don't have permission for that action or there was an error!" -msgstr "" - -#: profile-builder-2.0/features/admin-approval/admin-approval.php:92 -msgid "Your session has expired! Please refresh the page and try again." -msgstr "" - -#: profile-builder-2.0/features/admin-approval/admin-approval.php:104 -msgid "Users successfully approved!" -msgstr "" - -#: profile-builder-2.0/features/admin-approval/admin-approval.php:113 -msgid "Users successfully unapproved!" -msgstr "" - -#: profile-builder-2.0/features/admin-approval/admin-approval.php:121 -msgid "Users successfully deleted!" -msgstr "" - -#: profile-builder-2.0/features/admin-approval/admin-approval.php:141 -#, php-format -msgid "Your account on %1$s has been approved!" -msgstr "" - -#: profile-builder-2.0/features/admin-approval/admin-approval.php:142 -#: profile-builder-2.0/features/admin-approval/admin-approval.php:145 -msgid "approved" -msgstr "" - -#: profile-builder-2.0/features/admin-approval/admin-approval.php:144 -#, php-format -msgid "An administrator has just approved your account on %1$s (%2$s)." -msgstr "" - -#: profile-builder-2.0/features/admin-approval/admin-approval.php:149 -#, php-format -msgid "Your account on %1$s has been unapproved!" -msgstr "" - -#: profile-builder-2.0/features/admin-approval/admin-approval.php:150 -#: profile-builder-2.0/features/admin-approval/admin-approval.php:153 -msgid "unapproved" -msgstr "" - -#: profile-builder-2.0/features/admin-approval/admin-approval.php:152 -#, php-format -msgid "An administrator has just unapproved your account on %1$s (%2$s)." -msgstr "" - -#: profile-builder-2.0/features/admin-approval/admin-approval.php:171 -msgid "" -"ERROR: Your account has to be confirmed by an administrator " -"before you can log in." -msgstr "" - -#: profile-builder-2.0/features/admin-approval/admin-approval.php:183 -msgid "" -"Your account has to be confirmed by an administrator before you can use the " -"\"Password Recovery\" feature." -msgstr "" - -#: profile-builder-2.0/features/admin-approval/admin-approval.php:210 -msgid "Your account has been successfully created!" -msgstr "" - -#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:113 -msgid "delete this user?" -msgstr "" - -#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:116 -msgid "unapprove this user?" -msgstr "" - -#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:116 -#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:223 -msgid "Unapprove" -msgstr "" - -#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:118 -msgid "approve this user?" -msgstr "" - -#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:118 -#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:222 -msgid "Approve" -msgstr "" - -#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:167 -#: profile-builder-2.0/modules/user-listing/userlisting.php:269 -#: profile-builder-2.0/modules/user-listing/userlisting.php:716 -#: profile-builder-2.0/modules/user-listing/userlisting.php:2103 -msgid "Firstname" -msgstr "" - -#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:168 -#: profile-builder-2.0/modules/user-listing/userlisting.php:719 -#: profile-builder-2.0/modules/user-listing/userlisting.php:2104 -msgid "Lastname" -msgstr "" - -#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:170 -#: profile-builder-2.0/modules/user-listing/userlisting.php:142 -#: profile-builder-2.0/modules/user-listing/userlisting.php:270 -#: profile-builder-2.0/modules/user-listing/userlisting.php:746 -#: profile-builder-2.0/modules/user-listing/userlisting.php:2108 -msgid "Role" -msgstr "" - -#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:171 -#: profile-builder-2.0/features/email-confirmation/class-email-confirmation.php:169 -msgid "Registered" -msgstr "" - -#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:172 -msgid "User-status" -msgstr "" - -#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:252 -msgid "Do you want to bulk approve the selected users?" -msgstr "" - -#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:260 -msgid "Do you want to bulk unapprove the selected users?" -msgstr "" - -#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:266 -msgid "Do you want to bulk delete the selected users?" -msgstr "" - -#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:274 -#: profile-builder-2.0/features/email-confirmation/class-email-confirmation.php:278 -msgid "Sorry, but you don't have permission to do that!" -msgstr "" - -#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:339 -msgid "Approved" -msgstr "" - -#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:341 -msgid "Unapproved" -msgstr "" - -#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:456 -#: profile-builder-2.0/features/email-confirmation/class-email-confirmation.php:454 -msgid "All Users" -msgstr "" - -#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:461 -#: profile-builder-2.0/features/email-confirmation/class-email-confirmation.php:460 -msgid "Search Users" -msgstr "" - -#: profile-builder-2.0/features/class-list-table.php:184 -msgid "No items found." -msgstr "" - -#: profile-builder-2.0/features/class-list-table.php:308 -msgid "Bulk Actions" -msgstr "" - -#: profile-builder-2.0/features/class-list-table.php:318 -msgid "Apply" -msgstr "" - -#: profile-builder-2.0/features/class-list-table.php:402 -msgid "Show all dates" -msgstr "" - -#: profile-builder-2.0/features/class-list-table.php:415 -#, php-format -msgid "%1$s %2$d" -msgstr "" - -#: profile-builder-2.0/features/class-list-table.php:431 -msgid "List View" -msgstr "" - -#: profile-builder-2.0/features/class-list-table.php:432 -msgid "Excerpt View" -msgstr "" - -#: profile-builder-2.0/features/class-list-table.php:458 -#, php-format -msgid "%s pending" -msgstr "" - -#: profile-builder-2.0/features/class-list-table.php:526 -#: profile-builder-2.0/features/class-list-table.php:942 -msgid "1 item" -msgstr "" - -#: profile-builder-2.0/features/class-list-table.php:566 -#, php-format -msgid "%1$s of %2$s" -msgstr "" - -#: profile-builder-2.0/features/class-list-table.php:713 -msgid "Select All" -msgstr "" - -#: profile-builder-2.0/features/conditional-fields/conditional-fields.php:78 -msgid "Conditional Logic" -msgstr "" - -#: profile-builder-2.0/features/conditional-fields/conditional-fields.php:79 -msgid "Conditional Rules" -msgstr "" - -#: profile-builder-2.0/features/conditional-fields/conditional-fields.php:432 -msgid "This field has conditional logic enabled." -msgstr "" - -#: profile-builder-2.0/features/email-confirmation/class-email-confirmation.php:91 -#: profile-builder-2.0/features/email-confirmation/class-email-confirmation.php:170 -msgid "User Meta" -msgstr "" - -#: profile-builder-2.0/features/email-confirmation/class-email-confirmation.php:91 -msgid "show" -msgstr "" - -#: profile-builder-2.0/features/email-confirmation/class-email-confirmation.php:120 -msgid "delete this user from the _signups table?" -msgstr "" - -#: profile-builder-2.0/features/email-confirmation/class-email-confirmation.php:121 -msgid "confirm this email yourself?" -msgstr "" - -#: profile-builder-2.0/features/email-confirmation/class-email-confirmation.php:121 -#: profile-builder-2.0/features/email-confirmation/class-email-confirmation.php:218 -msgid "Confirm Email" -msgstr "" - -#: profile-builder-2.0/features/email-confirmation/class-email-confirmation.php:122 -msgid "resend the activation link?" -msgstr "" - -#: profile-builder-2.0/features/email-confirmation/class-email-confirmation.php:122 -#: profile-builder-2.0/features/email-confirmation/class-email-confirmation.php:219 -msgid "Resend Activation Email" -msgstr "" - -#: profile-builder-2.0/features/email-confirmation/class-email-confirmation.php:249 -#, php-format -msgid "%s couldn't be deleted" -msgstr "" - -#: profile-builder-2.0/features/email-confirmation/class-email-confirmation.php:253 -msgid "All users have been successfully deleted" -msgstr "" - -#: profile-builder-2.0/features/email-confirmation/class-email-confirmation.php:263 -msgid "The selected users have been activated" -msgstr "" - -#: profile-builder-2.0/features/email-confirmation/class-email-confirmation.php:274 -msgid "The selected users have had their activation emails resent" -msgstr "" - -#: profile-builder-2.0/features/email-confirmation/class-email-confirmation.php:451 -#: profile-builder-2.0/features/email-confirmation/email-confirmation.php:47 -msgid "Users with Unconfirmed Email Address" -msgstr "" - -#: profile-builder-2.0/features/email-confirmation/email-confirmation.php:110 -msgid "There was an error performing that action!" -msgstr "" - -#: profile-builder-2.0/features/email-confirmation/email-confirmation.php:118 -msgid "The selected user couldn't be deleted" -msgstr "" - -#: profile-builder-2.0/features/email-confirmation/email-confirmation.php:129 -msgid "Email notification resent to user" -msgstr "" - -#: profile-builder-2.0/features/email-confirmation/email-confirmation.php:389 -#, php-format -msgid "[%1$s] Activate %2$s" -msgstr "" - -#: profile-builder-2.0/features/email-confirmation/email-confirmation.php:392 -#, php-format -msgid "" -"To activate your user, please click the following link:

            %s%s" -"%s

            After you activate it you will receive yet *another email* with " -"your login." -msgstr "" - -#: profile-builder-2.0/features/email-confirmation/email-confirmation.php:433 -#: profile-builder-2.0/front-end/register.php:70 -msgid "Could not create user!" -msgstr "" - -#: profile-builder-2.0/features/email-confirmation/email-confirmation.php:436 -msgid "That username is already activated!" -msgstr "" - -#: profile-builder-2.0/features/email-confirmation/email-confirmation.php:459 -msgid "There was an error while trying to activate the user" -msgstr "" - -#: profile-builder-2.0/features/email-confirmation/email-confirmation.php:507 -#: profile-builder-2.0/modules/email-customizer/admin-email-customizer.php:73 -msgid "A new subscriber has (been) registered!" -msgstr "" - -#: profile-builder-2.0/features/email-confirmation/email-confirmation.php:510 -#, php-format -msgid "New subscriber on %1$s.

            Username:%2$s
            E-mail:%3$s
            " -msgstr "" - -#: profile-builder-2.0/features/email-confirmation/email-confirmation.php:561 -#, php-format -msgid "[%1$s] Your new account information" -msgstr "" - -#: profile-builder-2.0/features/email-confirmation/email-confirmation.php:565 -#: profile-builder-2.0/features/email-confirmation/email-confirmation.php:574 -#: profile-builder-2.0/modules/email-customizer/email-customizer.php:470 -#: profile-builder-2.0/modules/email-customizer/email-customizer.php:477 -#: profile-builder-2.0/modules/email-customizer/email-customizer.php:491 -msgid "Your selected password at signup" -msgstr "" - -#: profile-builder-2.0/features/email-confirmation/email-confirmation.php:570 -#, php-format -msgid "Welcome to %1$s!


            Your username is:%2$s" -msgstr "" - -#: profile-builder-2.0/features/email-confirmation/email-confirmation.php:572 -#, php-format -msgid "Welcome to %1$s!


            Your username is:%2$s and password:%3$s" -msgstr "" - -#: profile-builder-2.0/features/email-confirmation/email-confirmation.php:625 -msgid "" -"The \"Admin Approval\" feature was activated at the time of registration, so " -"please remember that you need to approve this user before he/she can log in!" -msgstr "" - -#: profile-builder-2.0/features/email-confirmation/email-confirmation.php:633 -#: profile-builder-2.0/front-end/register.php:130 -msgid "" -"Before you can access your account, an administrator needs to approve it. " -"You will be notified via email." -msgstr "" - -#: profile-builder-2.0/features/functions.php:304 -msgid "The user-validation has failed - the avatar was not deleted!" -msgstr "" - -#: profile-builder-2.0/features/functions.php:315 -msgid "The user-validation has failed - the attachment was not deleted!" -msgstr "" - -#: profile-builder-2.0/features/functions.php:554 -msgid "Strength indicator" -msgstr "" - -#: profile-builder-2.0/features/functions.php:579 -msgid "Very Weak" -msgstr "" - -#: profile-builder-2.0/features/functions.php:593 -#, php-format -msgid "Minimum length of %d characters" -msgstr "" - -#: profile-builder-2.0/features/functions.php:667 -msgid "This field is required" -msgstr "" - -#: profile-builder-2.0/features/functions.php:705 -#: profile-builder-2.0/front-end/extra-fields/recaptcha/recaptcha.php:374 -#: profile-builder-2.0/front-end/extra-fields/recaptcha/recaptcha.php:379 -#: profile-builder-2.0/front-end/extra-fields/recaptcha/recaptcha.php:421 -#: profile-builder-2.0/front-end/extra-fields/recaptcha/recaptcha.php:458 -msgid "Please enter a (valid) reCAPTCHA value" -msgstr "" - -#: profile-builder-2.0/features/functions.php:712 -msgid "Incorrect phone number" -msgstr "" - -#: profile-builder-2.0/features/functions.php:731 -msgid "Cancel" -msgstr "" - -#: profile-builder-2.0/features/functions.php:763 -#, php-format -msgid "" -"To allow users to register for your website via Profile Builder, you first " -"must enable user registration. Go to %1$sNetwork Settings%2$s, and under " -"Registration Settings make sure to check “User accounts may be registered”. " -"%3$sDismiss%4$s" -msgstr "" - -#: profile-builder-2.0/features/functions.php:767 -#, php-format -msgid "" -"To allow users to register for your website via Profile Builder, you first " -"must enable user registration. Go to %1$sSettings -> General%2$s tab, and " -"under Membership make sure to check “Anyone can register”. %3$sDismiss%4$s" -msgstr "" - -#: profile-builder-2.0/features/login-widget/login-widget.php:10 -msgid "This login widget lets you add a login form in the sidebar." -msgstr "" - -#: profile-builder-2.0/features/login-widget/login-widget.php:15 -msgid "Profile Builder Login Widget" -msgstr "" - -#: profile-builder-2.0/features/login-widget/login-widget.php:63 -msgid "Title:" -msgstr "" - -#: profile-builder-2.0/features/login-widget/login-widget.php:68 -msgid "After login redirect URL (optional):" -msgstr "" - -#: profile-builder-2.0/features/login-widget/login-widget.php:73 -msgid "Register page URL (optional):" -msgstr "" - -#: profile-builder-2.0/features/login-widget/login-widget.php:78 -msgid "Password Recovery page URL (optional):" -msgstr "" - -#: profile-builder-2.0/features/upgrades/upgrades-functions.php:91 -#: profile-builder-2.0/features/upgrades/upgrades-functions.php:134 -msgid "The usernames cannot be changed." -msgstr "" - -#: profile-builder-2.0/front-end/class-formbuilder.php:120 -msgid "" -"The role of the created user set to the default role. Only an administrator " -"can register a user with the role assigned to this form." -msgstr "" - -#: profile-builder-2.0/front-end/class-formbuilder.php:161 -msgid "Only an administrator can add new users." -msgstr "" - -#: profile-builder-2.0/front-end/class-formbuilder.php:171 -msgid "Users can register themselves or you can manually create users here." -msgstr "" - -#: profile-builder-2.0/front-end/class-formbuilder.php:171 -#: profile-builder-2.0/front-end/class-formbuilder.php:174 -msgid "This message is only visible by administrators" -msgstr "" - -#: profile-builder-2.0/front-end/class-formbuilder.php:174 -msgid "" -"Users cannot currently register themselves, but you can manually create " -"users here." -msgstr "" - -#: profile-builder-2.0/front-end/class-formbuilder.php:196 -#, php-format -msgid "You are currently logged in as %1s. You don't need another account. %2s" -msgstr "" - -#: profile-builder-2.0/front-end/class-formbuilder.php:196 -msgid "Log out of this account." -msgstr "" - -#: profile-builder-2.0/front-end/class-formbuilder.php:196 -msgid "Logout" -msgstr "" - -#: profile-builder-2.0/front-end/class-formbuilder.php:203 -msgid "You must be logged in to edit your profile." -msgstr "" - -#: profile-builder-2.0/front-end/class-formbuilder.php:230 -#: profile-builder-2.0/front-end/class-formbuilder.php:277 -msgid "here" -msgstr "" - -#: profile-builder-2.0/front-end/class-formbuilder.php:232 -#: profile-builder-2.0/front-end/class-formbuilder.php:277 -#, php-format -msgid "" -"You will soon be redirected automatically. If you see this page for more " -"than %1$d seconds, please click %2$s.%3$s" -msgstr "" - -#: profile-builder-2.0/front-end/class-formbuilder.php:330 -#: profile-builder-2.0/front-end/class-formbuilder.php:337 -#, php-format -msgid "The account %1s has been successfully created!" -msgstr "" - -#: profile-builder-2.0/front-end/class-formbuilder.php:333 -#: profile-builder-2.0/front-end/class-formbuilder.php:343 -#, php-format -msgid "" -"Before you can access your account %1s, you need to confirm your email " -"address. Please check your inbox and click the activation link." -msgstr "" - -#: profile-builder-2.0/front-end/class-formbuilder.php:339 -#, php-format -msgid "" -"Before you can access your account %1s, an administrator has to approve it. " -"You will be notified via email." -msgstr "" - -#: profile-builder-2.0/front-end/class-formbuilder.php:353 -msgid "Your profile has been successfully updated!" -msgstr "" - -#: profile-builder-2.0/front-end/class-formbuilder.php:363 -msgid "There was an error in the submitted form" -msgstr "" - -#: profile-builder-2.0/front-end/class-formbuilder.php:420 -msgid "Add User" -msgstr "" - -#: profile-builder-2.0/front-end/class-formbuilder.php:482 -#: profile-builder-2.0/front-end/extra-fields/extra-fields.php:47 -msgid "The avatar was successfully deleted!" -msgstr "" - -#: profile-builder-2.0/front-end/class-formbuilder.php:482 -#: profile-builder-2.0/front-end/extra-fields/extra-fields.php:49 -msgid "The following attachment was successfully deleted:" -msgstr "" - -#: profile-builder-2.0/front-end/class-formbuilder.php:494 -msgid "Send these credentials via email." -msgstr "" - -#: profile-builder-2.0/front-end/class-formbuilder.php:681 -msgid "User to edit:" -msgstr "" - -#: profile-builder-2.0/front-end/default-fields/email/email.php:51 -msgid "You must enter a valid email address." -msgstr "" - -#: profile-builder-2.0/front-end/default-fields/email/email.php:60 -#: profile-builder-2.0/front-end/default-fields/email/email.php:67 -msgid "This email is already reserved to be used soon." -msgstr "" - -#: profile-builder-2.0/front-end/default-fields/email/email.php:60 -#: profile-builder-2.0/front-end/default-fields/email/email.php:67 -#: profile-builder-2.0/front-end/default-fields/email/email.php:77 -#: profile-builder-2.0/front-end/default-fields/email/email.php:95 -#: profile-builder-2.0/front-end/default-fields/username/username.php:49 -#: profile-builder-2.0/front-end/default-fields/username/username.php:65 -msgid "Please try a different one!" -msgstr "" - -#: profile-builder-2.0/front-end/default-fields/email/email.php:77 -#: profile-builder-2.0/front-end/default-fields/email/email.php:95 -msgid "This email is already in use." -msgstr "" - -#: profile-builder-2.0/front-end/default-fields/password-repeat/password-repeat.php:37 -#: profile-builder-2.0/front-end/default-fields/password-repeat/password-repeat.php:41 -msgid "The passwords do not match" -msgstr "" - -#: profile-builder-2.0/front-end/default-fields/password/password.php:46 -#: profile-builder-2.0/front-end/recover.php:251 -#, php-format -msgid "The password must have the minimum length of %s characters" -msgstr "" - -#: profile-builder-2.0/front-end/default-fields/password/password.php:50 -#: profile-builder-2.0/front-end/recover.php:255 -#, php-format -msgid "The password must have a minimum strength of %s" -msgstr "" - -#: profile-builder-2.0/front-end/default-fields/username/username.php:49 -msgid "This username already exists." -msgstr "" - -#: profile-builder-2.0/front-end/default-fields/username/username.php:52 -#: profile-builder-2.0/front-end/default-fields/username/username.php:60 -msgid "This username is invalid because it uses illegal characters." -msgstr "" - -#: profile-builder-2.0/front-end/default-fields/username/username.php:52 -#: profile-builder-2.0/front-end/default-fields/username/username.php:60 -msgid "Please enter a valid username." -msgstr "" - -#: profile-builder-2.0/front-end/default-fields/username/username.php:65 -msgid "This username is already reserved to be used soon." -msgstr "" - -#: profile-builder-2.0/front-end/extra-fields/avatar/avatar.php:72 -#: profile-builder-2.0/front-end/extra-fields/checkbox/checkbox.php:45 -#: profile-builder-2.0/front-end/extra-fields/colorpicker/colorpicker.php:45 -#: profile-builder-2.0/front-end/extra-fields/datepicker/datepicker.php:40 -#: profile-builder-2.0/front-end/extra-fields/input-hidden/input-hidden.php:34 -#: profile-builder-2.0/front-end/extra-fields/input/input.php:30 -#: profile-builder-2.0/front-end/extra-fields/map/map.php:51 -#: profile-builder-2.0/front-end/extra-fields/number/number.php:30 -#: profile-builder-2.0/front-end/extra-fields/phone/phone.php:39 -#: profile-builder-2.0/front-end/extra-fields/radio/radio.php:44 -#: profile-builder-2.0/front-end/extra-fields/select-cpt/select-cpt.php:46 -#: profile-builder-2.0/front-end/extra-fields/select-multiple/select-multiple.php:46 -#: profile-builder-2.0/front-end/extra-fields/select-timezone/select-timezone.php:49 -#: profile-builder-2.0/front-end/extra-fields/select/select.php:51 -#: profile-builder-2.0/front-end/extra-fields/textarea/textarea.php:30 -#: profile-builder-2.0/front-end/extra-fields/upload/upload.php:70 -#: profile-builder-2.0/front-end/extra-fields/wysiwyg/wysiwyg.php:33 -msgid "required" -msgstr "" - -#: profile-builder-2.0/front-end/extra-fields/extra-fields.php:111 -#: profile-builder-2.0/front-end/login.php:137 -#: profile-builder-2.0/front-end/login.php:144 -#: profile-builder-2.0/front-end/login.php:158 -#: profile-builder-2.0/front-end/recover.php:17 -#: profile-builder-2.0/front-end/recover.php:234 -msgid "ERROR" -msgstr "" - -#: profile-builder-2.0/front-end/extra-fields/map/map.php:46 -#: profile-builder-2.0/front-end/extra-fields/map/map.php:69 -msgid "Please add the Google Maps API key for this field." -msgstr "" - -#: profile-builder-2.0/front-end/extra-fields/map/map.php:134 -msgid "Something went wrong. Please try again." -msgstr "" - -#: profile-builder-2.0/front-end/extra-fields/number/number.php:69 -msgid "Please enter numbers only" -msgstr "" - -#: profile-builder-2.0/front-end/extra-fields/number/number.php:73 -#, php-format -msgid "Value must be a multiplier of %1$s" -msgstr "" - -#: profile-builder-2.0/front-end/extra-fields/number/number.php:77 -#, php-format -msgid "Value must be greater than or equal to %1$s" -msgstr "" - -#: profile-builder-2.0/front-end/extra-fields/number/number.php:81 -#, php-format -msgid "Value must be less than or equal to %1$s" -msgstr "" - -#: profile-builder-2.0/front-end/extra-fields/phone/phone.php:22 -msgid "Required phone number format: " -msgstr "" - -#: profile-builder-2.0/front-end/extra-fields/recaptcha/recaptcha.php:48 -msgid "To use reCAPTCHA you must get an API key from" -msgstr "" - -#: profile-builder-2.0/front-end/extra-fields/recaptcha/recaptcha.php:131 -msgid "For security reasons, you must pass the remote ip to reCAPTCHA!" -msgstr "" - -#: profile-builder-2.0/front-end/extra-fields/recaptcha/recaptcha.php:192 -msgid "To use reCAPTCHA you must get an API public key from:" -msgstr "" - -#: profile-builder-2.0/front-end/extra-fields/recaptcha/recaptcha.php:421 -msgid "Click the BACK button on your browser, and try again." -msgstr "" - -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Bolivia, __( Plurinational State of" -msgstr "" - -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Bonaire, __( Sint Eustatius and Saba" -msgstr "" - -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Brunei Darussalam" -msgstr "" - -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Cabo Verde" -msgstr "" - -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Cocos (Keeling) Islands" -msgstr "" - -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Congo" -msgstr "" - -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Congo, __( the Democratic Republic of the" -msgstr "" - -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Cote dIvoire" -msgstr "" - -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Falkland Islands (Malvinas)" -msgstr "" - -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Holy See (Vatican City State)" -msgstr "" - -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Iran, __( Islamic Republic of" -msgstr "" - -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Korea, __( Democratic Peoples Republic of" -msgstr "" - -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Korea, __( Republic of" -msgstr "" - -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Lao Peoples Democratic Republic" -msgstr "" - -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Macedonia, __( the former Yugoslav Republic of" -msgstr "" - -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Micronesia, __( Federated States of" -msgstr "" - -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Moldova, __( Republic of" -msgstr "" - -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Palestine, __( State of" -msgstr "" - -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Russian Federation" -msgstr "" - -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Saint Helena, __( Ascension and Tristan da Cunha" -msgstr "" - -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Saint Martin (French part)" -msgstr "" - -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Sint Maarten (Dutch part)" -msgstr "" - -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Syrian Arab Republic" -msgstr "" - -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Taiwan, __( Province of China" -msgstr "" - -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Tanzania, __( United Republic of" -msgstr "" - -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Timor-Leste" -msgstr "" - -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Venezuela, __( Bolivarian Republic of" -msgstr "" - -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Viet Nam" -msgstr "" - -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Virgin Islands, __( British" -msgstr "" - -#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 -msgid "Virgin Islands, __( U.S." -msgstr "" - -#: profile-builder-2.0/front-end/extra-fields/upload/upload_helper_functions.php:78 -#: profile-builder-2.0/front-end/extra-fields/upload/upload_helper_functions.php:87 -msgid "Sorry, you cannot upload this file type for this field." -msgstr "" - -#: profile-builder-2.0/front-end/extra-fields/upload/upload_helper_functions.php:94 -msgid "An error occurred, please try again later." -msgstr "" - -#: profile-builder-2.0/front-end/extra-fields/user-role/user-role.php:72 -#: profile-builder-2.0/front-end/extra-fields/user-role/user-role.php:85 -msgid "Only administrators can see this field on edit profile forms." -msgstr "" - -#: profile-builder-2.0/front-end/extra-fields/user-role/user-role.php:81 -msgid "As an administrator you cannot change your role." -msgstr "" - -#: profile-builder-2.0/front-end/extra-fields/user-role/user-role.php:118 -msgid "You cannot register this user role" -msgstr "" - -#: profile-builder-2.0/front-end/login.php:137 -msgid "The password you entered is incorrect." -msgstr "" - -#: profile-builder-2.0/front-end/login.php:138 -#: profile-builder-2.0/front-end/login.php:145 -msgid "Password Lost and Found." -msgstr "" - -#: profile-builder-2.0/front-end/login.php:138 -#: profile-builder-2.0/front-end/login.php:145 -msgid "Lost your password" -msgstr "" - -#: profile-builder-2.0/front-end/login.php:144 -msgid "Invalid username." -msgstr "" - -#: profile-builder-2.0/front-end/login.php:149 -#: profile-builder-2.0/front-end/login.php:153 -msgid "username" -msgstr "" - -#: profile-builder-2.0/front-end/login.php:149 -msgid "email" -msgstr "" - -#: profile-builder-2.0/front-end/login.php:153 -msgid "username or email" -msgstr "" - -#: profile-builder-2.0/front-end/login.php:158 -msgid "Both fields are empty." -msgstr "" - -#: profile-builder-2.0/front-end/login.php:229 -msgid "Username or Email" -msgstr "" - -#: profile-builder-2.0/front-end/login.php:263 -msgid "Lost your password?" -msgstr "" - -#: profile-builder-2.0/front-end/login.php:307 -#: profile-builder-2.0/front-end/logout.php:29 -msgid "Log out of this account" -msgstr "" - -#: profile-builder-2.0/front-end/login.php:307 -msgid "Log out" -msgstr "" - -#: profile-builder-2.0/front-end/login.php:308 -#, php-format -msgid "You are currently logged in as %1$s. %2$s" -msgstr "" - -#: profile-builder-2.0/front-end/logout.php:15 -#, php-format -msgid "You are currently logged in as %s. " -msgstr "" - -#: profile-builder-2.0/front-end/logout.php:15 -msgid "Log out »" -msgstr "" - -#: profile-builder-2.0/front-end/recover.php:17 -msgid "" -"Your account has to be confirmed by an administrator before you can use the " -"\"Password Reset\" feature." -msgstr "" - -#: profile-builder-2.0/front-end/recover.php:94 -msgid "Reset Password" -msgstr "" - -#: profile-builder-2.0/front-end/recover.php:114 -msgid "Please enter your username or email address." -msgstr "" - -#: profile-builder-2.0/front-end/recover.php:115 -msgid "You will receive a link to create a new password via email." -msgstr "" - -#: profile-builder-2.0/front-end/recover.php:120 -msgid "Username or E-mail" -msgstr "" - -#: profile-builder-2.0/front-end/recover.php:130 -msgid "Get New Password" -msgstr "" - -#: profile-builder-2.0/front-end/recover.php:172 -msgid "The username entered wasn't found in the database!" -msgstr "" - -#: profile-builder-2.0/front-end/recover.php:172 -msgid "Please check that you entered the correct username." -msgstr "" - -#: profile-builder-2.0/front-end/recover.php:187 -msgid "Check your e-mail for the confirmation link." -msgstr "" - -#: profile-builder-2.0/front-end/recover.php:194 -msgid "The email address entered wasn't found in the database!" -msgstr "" - -#: profile-builder-2.0/front-end/recover.php:194 -msgid "Please check that you entered the correct email address." -msgstr "" - -#: profile-builder-2.0/front-end/recover.php:222 -#, php-format -msgid "" -"Someone requested that the password be reset for the following account: " -"%1$s
            If this was a mistake, just ignore this email and nothing will " -"happen.
            To reset your password, visit the following link:%2$s" -msgstr "" - -#: profile-builder-2.0/front-end/recover.php:225 -#, php-format -msgid "Password Reset from \"%1$s\"" -msgstr "" - -#: profile-builder-2.0/front-end/recover.php:234 -#, php-format -msgid "There was an error while trying to send the activation link to %1$s!" -msgstr "" - -#: profile-builder-2.0/front-end/recover.php:262 -msgid "Your password has been successfully changed!" -msgstr "" - -#: profile-builder-2.0/front-end/recover.php:281 -#, php-format -msgid "You have successfully reset your password to: %1$s" -msgstr "" - -#: profile-builder-2.0/front-end/recover.php:284 -#: profile-builder-2.0/front-end/recover.php:298 -#, php-format -msgid "Password Successfully Reset for %1$s on \"%2$s\"" -msgstr "" - -#: profile-builder-2.0/front-end/recover.php:295 -#, php-format -msgid "" -"%1$s has requested a password change via the password reset feature.
            His/" -"her new password is:%2$s" -msgstr "" - -#: profile-builder-2.0/front-end/recover.php:314 -msgid "The entered passwords don't match!" -msgstr "" - -#: profile-builder-2.0/front-end/recover.php:381 -msgid "ERROR:" -msgstr "" - -#: profile-builder-2.0/front-end/recover.php:381 -msgid "Invalid key!" -msgstr "" - -#: profile-builder-2.0/front-end/register.php:55 -msgid "Invalid activation key!" -msgstr "" - -#: profile-builder-2.0/front-end/register.php:59 -msgid "This username is now active!" -msgstr "" - -#: profile-builder-2.0/front-end/register.php:73 -msgid "This username is already activated!" -msgstr "" - -#: profile-builder-2.0/front-end/register.php:129 -msgid "Your email was successfully confirmed." -msgstr "" - -#: profile-builder-2.0/front-end/register.php:133 -msgid "You will soon be redirected automatically." -msgstr "" - -#: profile-builder-2.0/front-end/register.php:163 -msgid "There was an error while trying to activate the user." -msgstr "" - -#: profile-builder-2.0/index.php:34 -msgid "" -" is also activated. You need to deactivate it before activating this version " -"of the plugin." -msgstr "" - -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:45 -msgid "After Login" -msgstr "" - -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:46 -msgid "After Logout" -msgstr "" - -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:47 -msgid "After Registration" -msgstr "" - -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:48 -msgid "After Edit Profile" -msgstr "" - -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:49 -msgid "After Successful Email Confirmation" -msgstr "" - -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:50 -msgid "After Successful Password Reset" -msgstr "" - -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:51 -msgid "Dashboard (redirect users from accessing the dashboard)" -msgstr "" - -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:55 -msgid "User ID" -msgstr "" - -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:61 -msgid "User ID or Username" -msgstr "" - -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:62 -msgid "User ID / Username" -msgstr "" - -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:62 -msgid "Please select and enter the ID or username of your user." -msgstr "" - -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:63 -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:93 -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:112 -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:131 -msgid "Redirect Type" -msgstr "" - -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:64 -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:94 -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:113 -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:138 -msgid "Redirect URL" -msgstr "" - -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:64 -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:94 -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:113 -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:138 -msgid "" -"Can contain the following dynamic tags:{{homeurl}}, {{siteurl}}, " -"{{user_id}}, {{user_nicename}}, {{http_referer}}" -msgstr "" - -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:71 -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:240 -msgid "Individual User Redirects" -msgstr "" - -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:84 -msgid "... Choose" -msgstr "" - -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:92 -#: profile-builder-2.0/modules/email-customizer/email-customizer.php:31 -msgid "User Role" -msgstr "" - -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:92 -msgid "Select a user role." -msgstr "" - -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:101 -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:241 -msgid "User Role based Redirects" -msgstr "" - -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:120 -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:242 -msgid "Global Redirects" -msgstr "" - -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:133 -msgid "Login ( wp_login.php )" -msgstr "" - -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:134 -msgid "Register ( wp-login.php?action=register )" -msgstr "" - -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:135 -msgid "Lost Password ( wp-login.php?action=lostpassword )" -msgstr "" - -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:136 -msgid "Author Archive ( http://sitename.com/author/admin )" -msgstr "" - -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:145 -msgid "Redirect Default WordPress Forms and Pages" -msgstr "" - -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:157 -msgid "How does this work?" -msgstr "" - -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:179 -msgid "
            User ID / Username
            Redirect
            URL
            " -msgstr "" - -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:193 -msgid "
            User Role
            Redirect
            URL
            " -msgstr "" - -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:207 -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:221 -msgid "
            Redirect
            URL
            " -msgstr "" - -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:236 -msgid "" -"These redirects happen after a successful action, like registration or after " -"a successful login." -msgstr "" - -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:238 -msgid "Which redirect happens depends on the following priority:" -msgstr "" - -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:243 -msgid "" -"Individual redirects defined in shortcodes or in the Multiple Registration " -"and Edit Profile form settings. (redirect_priority=\"top\" parameter can be added in any shortcode, then that shortcode " -"redirect will have priority over all other redirects)" -msgstr "" - -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:246 -msgid "Redirect Default WordPress forms and pages" -msgstr "" - -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:247 -msgid "" -"With these you can redirect various WordPress forms and pages to pages " -"created with profile builder." -msgstr "" - -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:249 -msgid "Available tags for dynamic URLs" -msgstr "" - -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:250 -msgid "" -"You use the following tags in your URLs to redirect users to various pages." -msgstr "" - -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:252 -msgid "generates a url of the current website homepage." -msgstr "" - -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:253 -msgid "" -"in WordPress the
            site url can be different then the home url" -msgstr "" - -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:254 -msgid "the ID of the user" -msgstr "" - -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:255 -msgid "" -"the URL sanitized version of the username, the user nicename can be safely " -"used in URLs since it can't contain special characters or spaces." -msgstr "" - -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:256 -msgid "the URL of the previously visited page" -msgstr "" - -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:339 -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:345 -#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:351 -msgid "You can't add duplicate redirects!" -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/admin-email-customizer.php:11 -#: profile-builder-2.0/modules/email-customizer/admin-email-customizer.php:12 -#: profile-builder-2.0/modules/modules.php:96 -msgid "Admin Email Customizer" -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/admin-email-customizer.php:38 -msgid "" -"These settings are also replicated in the \"User Email Customizer\" settings-" -"page upon save." -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/admin-email-customizer.php:38 -#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:38 -msgid "Valid tags {{reply_to}} and {{site_name}}" -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/admin-email-customizer.php:41 -#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:41 -msgid "From (name)" -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/admin-email-customizer.php:49 -#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:49 -msgid "From (reply-to email)" -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/admin-email-customizer.php:54 -#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:54 -msgid "" -"Must be a valid email address or the tag {{reply_to}} which defaults to the " -"administrator email" -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/admin-email-customizer.php:57 -#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:57 -msgid "Common Settings" -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/admin-email-customizer.php:60 -msgid "" -"\n" -"

            New subscriber on {{site_name}}.

            \n" -"

            Username:{{username}}

            \n" -"

            E-mail:{{user_email}}

            \n" -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/admin-email-customizer.php:69 -#: profile-builder-2.0/modules/email-customizer/admin-email-customizer.php:99 -#: profile-builder-2.0/modules/email-customizer/admin-email-customizer.php:126 -#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:71 -#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:99 -#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:128 -#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:155 -#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:183 -#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:214 -#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:241 -#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:274 -msgid "Email Subject" -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/admin-email-customizer.php:84 -msgid "Default Registration & Registration with Email Confirmation" -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/admin-email-customizer.php:87 -msgid "" -"\n" -"

            New subscriber on {{site_name}}.

            \n" -"

            Username:{{username}}

            \n" -"

            E-mail:{{user_email}}

            \n" -"

            The Admin Approval feature was activated at the time of registration,\n" -"so please remember that you need to approve this user before he/she can log " -"in!

            \n" -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/admin-email-customizer.php:114 -#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:143 -msgid "Registration with Admin Approval" -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/admin-email-customizer.php:117 -msgid "" -"\n" -"

            {{username}} has requested a password change via the password reset " -"feature.

            \n" -"

            His/her new password is: {{password}}

            \n" -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/admin-email-customizer.php:141 -msgid "Admin Notification for User Password Reset" -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/email-customizer.php:7 -msgid "Available Tags" -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/email-customizer.php:11 -#: profile-builder-2.0/modules/user-listing/userlisting.php:179 -msgid "User Fields Tags" -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/email-customizer.php:21 -msgid "Site Url" -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/email-customizer.php:22 -msgid "Site Name" -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/email-customizer.php:25 -#: profile-builder-2.0/modules/user-listing/userlisting.php:151 -msgid "User Id" -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/email-customizer.php:33 -msgid "Reply To" -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/email-customizer.php:36 -msgid "Activation Key" -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/email-customizer.php:37 -msgid "Activation Url" -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/email-customizer.php:38 -msgid "Activation Link" -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/email-customizer.php:42 -msgid "Reset Key" -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/email-customizer.php:43 -msgid "Reset Url" -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/email-customizer.php:44 -msgid "Reset Link" -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/email-customizer.php:462 -msgid "The users selected password at signup" -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:11 -#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:12 -#: profile-builder-2.0/modules/modules.php:103 -msgid "User Email Customizer" -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:38 -msgid "" -"These settings are also replicated in the \"Admin Email Customizer\" " -"settings-page upon save." -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:64 -msgid "" -"\n" -"

            Welcome to {{site_name}}!

            \n" -"

            Your username is:{{username}} and password:{{password}}

            \n" -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:85 -msgid "Default Registration" -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:91 -msgid "" -"\n" -"

            To activate your user, please click the following link:
            \n" -"{{{activation_link}}}

            \n" -"

            After you activate, you will receive another email with your credentials." -"

            \n" -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:103 -msgid "[{{site_name}}] Activate {{username}}" -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:114 -msgid "Registration with Email Confirmation" -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:120 -msgid "" -"\n" -"

            Welcome to {{site_name}}!

            \n" -"

            Your username is:{{username}} and password:{{password}}

            \n" -"

            Before you can access your account, an administrator needs to approve it. " -"You will be notified via email.

            \n" -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:132 -msgid "A new account has been created for you on {{site_name}}" -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:148 -msgid "" -"\n" -"

            Good News!

            \n" -"

            An administrator has just approved your account: {{username}} on " -"{{site_name}}.

            \n" -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:159 -msgid "Your account on {{site_name}} has been approved!" -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:170 -msgid "User Approval Notification" -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:175 -msgid "" -"\n" -"

            Hello,

            \n" -"

            Unfortunatelly an administrator has just unapproved your account: " -"{{username}} on {{site_name}}.

            \n" -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:187 -msgid "Your account on {{site_name}} has been unapproved!" -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:198 -msgid "Unapproved User Notification" -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:204 -msgid "" -"\n" -"

            Someone requested that the password be reset for the following account: " -"{{site_name}}
            \n" -"Username: {{username}}

            \n" -"

            If this was a mistake, just ignore this email and nothing will happen.\n" -"

            To reset your password, visit the following address:
            \n" -"{{{reset_link}}}

            \n" -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:218 -msgid "[{{site_name}}] Password Reset" -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:229 -msgid "Password Reset Email" -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:235 -msgid "" -"\n" -"

            You have successfully reset your password to: {{password}}

            \n" -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:245 -msgid "[{{site_name}}] Password Reset Successfully" -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:256 -msgid "Password Reset Success Email" -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:278 -msgid "[{{site_name}}] Notice of Email Change" -msgstr "" - -#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:289 -msgid "Changed Email Address Notification" -msgstr "" - -#: profile-builder-2.0/modules/modules.php:11 -#: profile-builder-2.0/modules/modules.php:58 -msgid "Modules" -msgstr "" - -#: profile-builder-2.0/modules/modules.php:59 -msgid "" -"Here you can activate / deactivate available modules for Profile Builder." -msgstr "" - -#: profile-builder-2.0/modules/modules.php:69 -msgid "Name/Description" -msgstr "" - -#: profile-builder-2.0/modules/modules.php:70 -msgid "Status" -msgstr "" - -#: profile-builder-2.0/modules/modules.php:77 -#: profile-builder-2.0/modules/modules.php:84 -#: profile-builder-2.0/modules/modules.php:91 -#: profile-builder-2.0/modules/modules.php:98 -#: profile-builder-2.0/modules/modules.php:105 -#: profile-builder-2.0/modules/modules.php:112 -#: profile-builder-2.0/modules/modules.php:119 -msgid "Active" -msgstr "" - -#: profile-builder-2.0/modules/modules.php:78 -#: profile-builder-2.0/modules/modules.php:85 -#: profile-builder-2.0/modules/modules.php:92 -#: profile-builder-2.0/modules/modules.php:99 -#: profile-builder-2.0/modules/modules.php:106 -#: profile-builder-2.0/modules/modules.php:113 -#: profile-builder-2.0/modules/modules.php:120 -msgid "Inactive" -msgstr "" - -#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:11 -#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:12 -msgid "Edit-profile Form" -msgstr "" - -#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:13 -#: profile-builder-2.0/modules/multiple-forms/register-forms.php:13 -#: profile-builder-2.0/modules/user-listing/userlisting.php:13 -msgid "Add New" -msgstr "" - -#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:14 -msgid "Add new Edit-profile Form" -msgstr "" - -#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:15 -msgid "Edit the Edit-profile Forms" -msgstr "" - -#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:16 -msgid "New Edit-profile Form" -msgstr "" - -#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:17 -#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:23 -msgid "Edit-profile Forms" -msgstr "" - -#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:18 -msgid "View the Edit-profile Form" -msgstr "" - -#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:19 -msgid "Search the Edit-profile Forms" -msgstr "" - -#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:20 -msgid "No Edit-profile Form found" -msgstr "" - -#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:21 -msgid "No Edit-profile Forms found in trash" -msgstr "" - -#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:135 -#: profile-builder-2.0/modules/multiple-forms/register-forms.php:138 -#: profile-builder-2.0/modules/user-listing/userlisting.php:1994 -msgid "Shortcode" -msgstr "" - -#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:155 -#: profile-builder-2.0/modules/multiple-forms/register-forms.php:159 -#: profile-builder-2.0/modules/user-listing/userlisting.php:2015 -msgid "(no title)" -msgstr "" - -#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:175 -#: profile-builder-2.0/modules/multiple-forms/register-forms.php:178 -#: profile-builder-2.0/modules/user-listing/userlisting.php:2035 -msgid "The shortcode will be available after you publish this form." -msgstr "" - -#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:177 -#: profile-builder-2.0/modules/multiple-forms/register-forms.php:180 -#: profile-builder-2.0/modules/user-listing/userlisting.php:2037 -msgid "Use this shortcode on the page you want the form to be displayed:" -msgstr "" - -#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:181 -#: profile-builder-2.0/modules/multiple-forms/register-forms.php:184 -#: profile-builder-2.0/modules/user-listing/userlisting.php:2041 -msgid "" -"Note: changing the form title also changes " -"the shortcode!" -msgstr "" - -#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:187 -#: profile-builder-2.0/modules/multiple-forms/register-forms.php:190 -#: profile-builder-2.0/modules/user-listing/userlisting.php:2074 -msgid "Form Shortcode" -msgstr "" - -#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:206 -#: profile-builder-2.0/modules/multiple-forms/register-forms.php:230 -msgid "Redirect" -msgstr "" - -#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:206 -#: profile-builder-2.0/modules/multiple-forms/register-forms.php:230 -msgid "Whether to redirect the user to a specific page or not" -msgstr "" - -#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:207 -#: profile-builder-2.0/modules/multiple-forms/register-forms.php:231 -msgid "Display Messages" -msgstr "" - -#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:207 -#: profile-builder-2.0/modules/multiple-forms/register-forms.php:231 -msgid "Allowed time to display any success messages (in seconds)" -msgstr "" - -#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:208 -#: profile-builder-2.0/modules/multiple-forms/register-forms.php:232 -msgid "URL" -msgstr "" - -#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:208 -msgid "" -"Specify the URL of the page users will be redirected once they updated their " -"profile using this form
            Use the following format: http://www.mysite.com" -msgstr "" - -#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:215 -msgid "After Profile Update..." -msgstr "" - -#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:241 -#: profile-builder-2.0/modules/multiple-forms/register-forms.php:262 -msgid "Add New Field to the List" -msgstr "" - -#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:245 -#: profile-builder-2.0/modules/multiple-forms/register-forms.php:266 -msgid "Choose one of the supported fields you manage Title (Type)" -msgstr "" - -#: profile-builder-2.0/modules/multiple-forms/multiple-forms.php:406 -msgid "Delete all items" -msgstr "" - -#: profile-builder-2.0/modules/multiple-forms/multiple-forms.php:406 -msgid "Delete all" -msgstr "" - -#: profile-builder-2.0/modules/multiple-forms/register-forms.php:11 -#: profile-builder-2.0/modules/multiple-forms/register-forms.php:12 -msgid "Registration Form" -msgstr "" - -#: profile-builder-2.0/modules/multiple-forms/register-forms.php:14 -msgid "Add new Registration Form" -msgstr "" - -#: profile-builder-2.0/modules/multiple-forms/register-forms.php:15 -msgid "Edit the Registration Forms" -msgstr "" - -#: profile-builder-2.0/modules/multiple-forms/register-forms.php:16 -msgid "New Registration Form" -msgstr "" - -#: profile-builder-2.0/modules/multiple-forms/register-forms.php:17 -#: profile-builder-2.0/modules/multiple-forms/register-forms.php:23 -msgid "Registration Forms" -msgstr "" - -#: profile-builder-2.0/modules/multiple-forms/register-forms.php:18 -msgid "View the Registration Form" -msgstr "" - -#: profile-builder-2.0/modules/multiple-forms/register-forms.php:19 -msgid "Search the Registration Forms" -msgstr "" - -#: profile-builder-2.0/modules/multiple-forms/register-forms.php:20 -msgid "No Registration Form found" -msgstr "" - -#: profile-builder-2.0/modules/multiple-forms/register-forms.php:21 -msgid "No Registration Forms found in trash" -msgstr "" - -#: profile-builder-2.0/modules/multiple-forms/register-forms.php:219 -msgid "Default Role" -msgstr "" - -#: profile-builder-2.0/modules/multiple-forms/register-forms.php:228 -msgid "Set Role" -msgstr "" - -#: profile-builder-2.0/modules/multiple-forms/register-forms.php:228 -msgid "" -"Choose what role the user will have after (s)he registered
            If not " -"specified, defaults to the role set in the WordPress settings" -msgstr "" - -#: profile-builder-2.0/modules/multiple-forms/register-forms.php:229 -msgid "Automatically Log In" -msgstr "" - -#: profile-builder-2.0/modules/multiple-forms/register-forms.php:229 -msgid "" -"Whether to automatically log in the newly registered user or not
            Only " -"works on single-sites without \"Admin Approval\" and \"Email Confirmation\" " -"features activated
            WARNING: Caching the registration form will make " -"automatic login not work" -msgstr "" - -#: profile-builder-2.0/modules/multiple-forms/register-forms.php:230 -#: profile-builder-2.0/modules/user-listing/userlisting.php:1551 -msgid "Choose..." -msgstr "" - -#: profile-builder-2.0/modules/multiple-forms/register-forms.php:232 -msgid "" -"Specify the URL of the page users will be redirected once registered using " -"this form
            Use the following format: http://www.mysite.com" -msgstr "" - -#: profile-builder-2.0/modules/multiple-forms/register-forms.php:238 -msgid "After Registration..." -msgstr "" - -#: profile-builder-2.0/modules/repeater-field/admin/repeater-manage-fields.php:189 -msgid "Limit" -msgstr "" - -#: profile-builder-2.0/modules/repeater-field/admin/repeater-manage-fields.php:189 -msgid "" -"Enable limit to the number of fields to be generated by users in front end " -"forms " -msgstr "" - -#: profile-builder-2.0/modules/repeater-field/admin/repeater-manage-fields.php:190 -msgid "General Limit" -msgstr "" - -#: profile-builder-2.0/modules/repeater-field/admin/repeater-manage-fields.php:190 -msgid "Default limit for this repeater group.
            Leave 0 for unlimited." -msgstr "" - -#: profile-builder-2.0/modules/repeater-field/admin/repeater-manage-fields.php:191 -msgid "Limit reached message" -msgstr "" - -#: profile-builder-2.0/modules/repeater-field/admin/repeater-manage-fields.php:191 -msgid "The maximum number of fields has been reached." -msgstr "" - -#: profile-builder-2.0/modules/repeater-field/admin/repeater-manage-fields.php:191 -msgid "" -"The popup message to display when the limit of repeater groups is reached." -msgstr "" - -#: profile-builder-2.0/modules/repeater-field/admin/repeater-manage-fields.php:192 -msgid "Limit per Role" -msgstr "" - -#: profile-builder-2.0/modules/repeater-field/admin/repeater-manage-fields.php:192 -msgid "Leave 0 for unlimited." -msgstr "" - -#: profile-builder-2.0/modules/repeater-field/admin/repeater-manage-fields.php:193 -msgid "Repeated field group" -msgstr "" - -#: profile-builder-2.0/modules/repeater-field/admin/repeater-manage-fields.php:193 -msgid "Manage field or group of fields that will be repeatable." -msgstr "" - -#: profile-builder-2.0/modules/repeater-field/admin/repeater-manage-fields.php:258 -msgid "Edit field group" -msgstr "" - -#: profile-builder-2.0/modules/repeater-field/admin/repeater-manage-fields.php:259 -msgid "Repeatable fields saved!" -msgstr "" - -#: profile-builder-2.0/modules/repeater-field/admin/repeater-manage-fields.php:276 -#: profile-builder-2.0/modules/repeater-field/admin/repeater-manage-fields.php:325 -msgid "Please enter a unique field title.\n" -msgstr "" - -#: profile-builder-2.0/modules/repeater-field/repeater-field.php:258 -msgid "Are you sure you want to delete this?" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:14 -msgid "Add new User Listing" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:15 -msgid "Edit the User Listing" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:16 -msgid "New User Listing" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:18 -msgid "View the User Listing" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:19 -msgid "Search the User Listing" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:20 -msgid "No User Listing found" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:21 -msgid "No User Listing found in trash" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:104 -msgid "Display name as" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:143 -#: profile-builder-2.0/modules/user-listing/userlisting.php:2102 -msgid "Registration Date" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:144 -#: profile-builder-2.0/modules/user-listing/userlisting.php:2107 -msgid "Number of Posts" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:148 -msgid "More Info" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:149 -msgid "More Info Url" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:150 -msgid "Avatar or Gravatar" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:152 -msgid "User Nicename" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:185 -msgid "Sort Tags" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:189 -#: profile-builder-2.0/modules/user-listing/userlisting.php:218 -msgid "Extra Functions" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:191 -msgid "Pagination" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:192 -msgid "Search all Fields" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:193 -#: profile-builder-2.0/modules/user-listing/userlisting.php:2178 -msgid "Faceted Menus" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:194 -msgid "User Count" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:220 -msgid "Go Back Link" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:238 -msgid "All-userlisting Template" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:241 -msgid "Single-userlisting Template" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:267 -msgid "Avatar" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:271 -#: profile-builder-2.0/modules/user-listing/userlisting.php:731 -msgid "Posts" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:272 -#: profile-builder-2.0/modules/user-listing/userlisting.php:713 -msgid "Sign-up Date" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:273 -msgid "More" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:367 -msgid "You do not have permission to view this user list." -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:380 -msgid "You do not have the required user role to view this user list." -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:404 -msgid "User not found" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:707 -msgid "First/Lastname" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:722 -#: profile-builder-2.0/modules/user-listing/userlisting.php:2105 -msgid "Display Name" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:734 -#: profile-builder-2.0/modules/user-listing/userlisting.php:2112 -msgid "Aim" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:737 -#: profile-builder-2.0/modules/user-listing/userlisting.php:2113 -msgid "Yim" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:740 -#: profile-builder-2.0/modules/user-listing/userlisting.php:2114 -msgid "Jabber" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:987 -#: profile-builder-2.0/modules/user-listing/userlisting.php:1429 -#: profile-builder-2.0/modules/user-listing/userlisting.php:1832 -#: profile-builder-2.0/modules/user-listing/userlisting.php:2294 -msgid "Search Users by All Fields" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:1239 -msgid "Click here to see more information about this user" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:1239 -msgid "More..." -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:1242 -msgid "Click here to see more information about this user." -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:1269 -msgid "View Map" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:1383 -#: profile-builder-2.0/modules/user-listing/userlisting.php:1386 -msgid "Click here to go back" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:1383 -msgid "Back" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:1416 -msgid "«« First" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:1417 -msgid "« Prev" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:1418 -msgid "Next » " -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:1419 -msgid "Last »»" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:1448 -msgid "You don't have any pagination settings on this userlisting!" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:1495 -msgid "Show All" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:1538 -#: profile-builder-2.0/modules/user-listing/userlisting.php:1560 -#: profile-builder-2.0/modules/user-listing/userlisting.php:1613 -msgid "No options available" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:1753 -msgid "Remove All Filters" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:1849 -msgid "Search" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:1850 -msgid "Clear Results" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:2044 -#: profile-builder-2.0/modules/user-listing/userlisting.php:2048 -msgid "Extra shortcode parameters" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:2046 -msgid "View all extra shortcode parameters" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:2051 -msgid "" -"displays users having a certain meta-value within a certain (extra) meta-" -"field" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:2052 -msgid "Example:" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:2054 -msgid "" -"Remember though, that the field-value combination must exist in the database." -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:2060 -msgid "displays only the users that you specified the user_id for" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:2066 -msgid "displays all users except the ones you specified the user_id for" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:2124 -msgid "Random (very slow on large databases > 10K user)" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:2127 -msgid "Ascending" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:2128 -msgid "Descending" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:2136 -msgid "Roles to Display" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:2136 -msgid "" -"Restrict the userlisting to these selected roles only
            If not specified, " -"defaults to all existing roles" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:2137 -msgid "Number of Users/Page" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:2137 -msgid "" -"Set the number of users to be displayed on every paginated part of the all-" -"userlisting" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:2138 -msgid "Default Sorting Criteria" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:2138 -msgid "" -"Set the default sorting criteria
            This can temporarily be changed for " -"each new session" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:2139 -msgid "Default Sorting Order" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:2139 -msgid "" -"Set the default sorting order
            This can temporarily be changed for each " -"new session" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:2140 -msgid "Avatar Size (All-userlisting)" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:2140 -msgid "Set the avatar size on the all-userlisting only" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:2141 -msgid "Avatar Size (Single-userlisting)" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:2141 -msgid "Set the avatar size on the single-userlisting only" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:2142 -msgid "Visible only to logged in users?" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:2142 -msgid "The userlisting will only be visible only to the logged in users" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:2143 -msgid "Visible to following Roles" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:2143 -msgid "The userlisting will only be visible to the following roles" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:2149 -msgid "Userlisting Settings" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:2168 -msgid "Label" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:2168 -msgid "Choose the facet name that appears on the frontend" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:2169 -msgid "Facet Type" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:2169 -msgid "Choose the facet menu type" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:2170 -msgid "Facet Meta" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:2170 -msgid "Choose the meta field for the facet menu" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:2171 -msgid "Behaviour" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:2171 -msgid "Narrow the results" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:2171 -msgid "Expand the results" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:2171 -msgid "Choose how multiple selections affect the results" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:2172 -msgid "Visible choices" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:2172 -msgid "Show a toggle link after this many choices. Leave blank for all" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:2195 -msgid "Search Fields" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:2195 -msgid "Choose the fields in which the Search Field will look in" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:2200 -msgid "Search Settings" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:2270 -msgid "" -"You need to activate the Userlisting feature from within the \"Modules\" tab!" -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:2270 -msgid "You can find it in the Profile Builder menu." -msgstr "" - -#: profile-builder-2.0/modules/user-listing/userlisting.php:2433 -msgid "No results found!" -msgstr "" +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: profile-builder\n" +"POT-Creation-Date: 2016-11-28 15:04+0200\n" +"PO-Revision-Date: 2015-04-30 10:26+0200\n" +"Last-Translator: \n" +"Language-Team: Cozmoslabs\n" +"Language: en\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.8.5\n" +"X-Poedit-Basepath: ../..\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Poedit-KeywordsList: __;_e;_x;_n\n" +"X-Poedit-SourceCharset: UTF-8\n" +"X-Poedit-SearchPath-0: profile-builder-2.0\n" +"X-Poedit-SearchPath-1: pb-add-on-woocommerce\n" + +#: pb-add-on-woocommerce/billing-fields.php:5 +#: pb-add-on-woocommerce/shipping-fields.php:5 +msgid "Country" +msgstr "" + +#: pb-add-on-woocommerce/billing-fields.php:6 +#: pb-add-on-woocommerce/shipping-fields.php:6 +#: profile-builder-2.0/admin/manage-fields.php:196 +msgid "First Name" +msgstr "" + +#: pb-add-on-woocommerce/billing-fields.php:7 +#: pb-add-on-woocommerce/shipping-fields.php:7 +#: profile-builder-2.0/admin/manage-fields.php:197 +msgid "Last Name" +msgstr "" + +#: pb-add-on-woocommerce/billing-fields.php:8 +#: pb-add-on-woocommerce/shipping-fields.php:8 +msgid "Company Name" +msgstr "" + +#: pb-add-on-woocommerce/billing-fields.php:9 +#: pb-add-on-woocommerce/shipping-fields.php:9 +msgid "Address" +msgstr "" + +#: pb-add-on-woocommerce/billing-fields.php:11 +#: pb-add-on-woocommerce/shipping-fields.php:11 +msgid "Town / City" +msgstr "" + +#: pb-add-on-woocommerce/billing-fields.php:12 +#: pb-add-on-woocommerce/shipping-fields.php:12 +msgid "State / County" +msgstr "" + +#: pb-add-on-woocommerce/billing-fields.php:13 +#: pb-add-on-woocommerce/shipping-fields.php:13 +msgid "Postcode / Zip" +msgstr "" + +#: pb-add-on-woocommerce/billing-fields.php:14 +msgid "Email Address" +msgstr "" + +#: pb-add-on-woocommerce/billing-fields.php:15 +msgid "Phone" +msgstr "" + +#: pb-add-on-woocommerce/billing-fields.php:278 +msgid "Ship to a different address?" +msgstr "" + +#: pb-add-on-woocommerce/index.php:169 pb-add-on-woocommerce/index.php:437 +msgid "Billing Address" +msgstr "" + +#: pb-add-on-woocommerce/index.php:169 +msgid "Displays customer billing fields in front-end. " +msgstr "" + +#: pb-add-on-woocommerce/index.php:173 pb-add-on-woocommerce/index.php:438 +msgid "Shipping Address" +msgstr "" + +#: pb-add-on-woocommerce/index.php:173 +msgid "Displays customer shipping fields in front-end. " +msgstr "" + +#: pb-add-on-woocommerce/index.php:248 pb-add-on-woocommerce/index.php:267 +#: pb-add-on-woocommerce/index.php:364 pb-add-on-woocommerce/index.php:367 +#: pb-add-on-woocommerce/index.php:493 +msgid "Address line 2" +msgstr "" + +#: pb-add-on-woocommerce/index.php:256 +msgid "Billing Fields" +msgstr "" + +#: pb-add-on-woocommerce/index.php:256 +msgid "" +"Select which WooCommerce Billing fields to display to the user ( drag and " +"drop to re-order ) and which should be required" +msgstr "" + +#: pb-add-on-woocommerce/index.php:257 +msgid "Billing Fields Order" +msgstr "" + +#: pb-add-on-woocommerce/index.php:257 +msgid "Save the billing fields order from the billing fields checkboxes" +msgstr "" + +#: pb-add-on-woocommerce/index.php:258 +msgid "Billing Fields Name" +msgstr "" + +#: pb-add-on-woocommerce/index.php:258 +msgid "Save the billing fields names" +msgstr "" + +#: pb-add-on-woocommerce/index.php:275 +msgid "Shipping Fields" +msgstr "" + +#: pb-add-on-woocommerce/index.php:275 +msgid "" +"Select which WooCommerce Shipping fields to display to the user ( drag and " +"drop to re-order ) and which should be required" +msgstr "" + +#: pb-add-on-woocommerce/index.php:276 +msgid "Shipping Fields Order" +msgstr "" + +#: pb-add-on-woocommerce/index.php:276 +msgid "Save the shipping fields order from the billing fields checkboxes" +msgstr "" + +#: pb-add-on-woocommerce/index.php:277 +msgid "Shipping Fields Name" +msgstr "" + +#: pb-add-on-woocommerce/index.php:277 +msgid "Save the shipping fields names" +msgstr "" + +#: pb-add-on-woocommerce/index.php:305 +msgid "Field Name" +msgstr "" + +#: pb-add-on-woocommerce/index.php:306 +#: profile-builder-2.0/admin/manage-fields.php:155 +msgid "Required" +msgstr "" + +#: pb-add-on-woocommerce/index.php:369 +msgid "Click to edit " +msgstr "" + +#: pb-add-on-woocommerce/index.php:393 +#: profile-builder-2.0/front-end/default-fields/email/email.php:47 +msgid "The email you entered is not a valid email address." +msgstr "" + +#: pb-add-on-woocommerce/index.php:541 +msgid "" +"WooCommerce needs to be installed and activated for Profile Builder - " +"WooCommerce Sync Add-on to work!" +msgstr "" + +#: pb-add-on-woocommerce/templates/myaccount-login-register.php:25 +#: profile-builder-2.0/admin/basic-info.php:36 +#: profile-builder-2.0/features/login-widget/login-widget.php:59 +msgid "Login" +msgstr "" + +#: pb-add-on-woocommerce/templates/myaccount-login-register.php:36 +#: profile-builder-2.0/front-end/class-formbuilder.php:420 +#: profile-builder-2.0/front-end/login.php:257 +msgid "Register" +msgstr "" + +#: pb-add-on-woocommerce/woo-checkout-field-support.php:96 +msgid "Display on WooCommerce Checkout" +msgstr "" + +#: pb-add-on-woocommerce/woo-checkout-field-support.php:96 +msgid "" +"Whether the field should be added to the WooCommerce checkout form or not" +msgstr "" + +#: pb-add-on-woocommerce/woo-checkout-field-support.php:252 +#: profile-builder-2.0/assets/lib/wck-api/fields/upload.php:43 +#: profile-builder-2.0/front-end/extra-fields/upload/upload.php:112 +msgid "Remove" +msgstr "" + +#: pb-add-on-woocommerce/woo-checkout-field-support.php:262 +#: profile-builder-2.0/front-end/extra-fields/upload/upload.php:122 +msgid "Select File" +msgstr "" + +#: pb-add-on-woocommerce/woo-checkout-field-support.php:268 +#: profile-builder-2.0/assets/lib/wck-api/fields/upload.php:75 +#: profile-builder-2.0/front-end/extra-fields/upload/upload.php:128 +msgid "Upload " +msgstr "" + +#: pb-add-on-woocommerce/woo-checkout-field-support.php:368 +msgid "is not a valid phone number." +msgstr "" + +#: pb-add-on-woocommerce/woo-checkout-field-support.php:377 +msgid "is not a number." +msgstr "" + +#: pb-add-on-woocommerce/woo-checkout-field-support.php:382 +msgid "must be a multiplier of " +msgstr "" + +#: pb-add-on-woocommerce/woo-checkout-field-support.php:387 +msgid "must be a greater than or equal to " +msgstr "" + +#: pb-add-on-woocommerce/woo-checkout-field-support.php:392 +msgid "must be less than or equal to " +msgstr "" + +#: pb-add-on-woocommerce/woosync-page.php:23 +#: pb-add-on-woocommerce/woosync-page.php:70 +msgid "WooCommerce Sync" +msgstr "" + +#: pb-add-on-woocommerce/woosync-page.php:76 +msgid "Choose Register form to display on My Account page:" +msgstr "" + +#: pb-add-on-woocommerce/woosync-page.php:80 +#: pb-add-on-woocommerce/woosync-page.php:114 +#: profile-builder-2.0/modules/user-listing/userlisting.php:486 +msgid "None" +msgstr "" + +#: pb-add-on-woocommerce/woosync-page.php:81 +msgid "Default Register" +msgstr "" + +#: pb-add-on-woocommerce/woosync-page.php:103 +msgid "" +"Select which Profile Builder Register form to display on My Account page " +"from WooCommerce.
            This will also add the Profile Builder Login form to " +"MyAccount page." +msgstr "" + +#: pb-add-on-woocommerce/woosync-page.php:110 +msgid "Choose Edit Profile form to display on My Account page:" +msgstr "" + +#: pb-add-on-woocommerce/woosync-page.php:115 +msgid "Default Edit Profile" +msgstr "" + +#: pb-add-on-woocommerce/woosync-page.php:137 +msgid "" +"Select which Profile Builder Edit-profile form to display on My Account page " +"from WooCommerce." +msgstr "" + +#: pb-add-on-woocommerce/woosync-page.php:147 +#: profile-builder-2.0/admin/admin-bar.php:86 +#: profile-builder-2.0/admin/general-settings.php:208 +#: profile-builder-2.0/admin/register-version.php:95 +#: profile-builder-2.0/features/functions.php:724 +#: profile-builder-2.0/modules/modules.php:127 +msgid "Save Changes" +msgstr "" + +#: profile-builder-2.0/admin/add-ons.php:10 +#: profile-builder-2.0/admin/add-ons.php:32 +msgid "Add-Ons" +msgstr "" + +#: profile-builder-2.0/admin/add-ons.php:34 +#: profile-builder-2.0/admin/add-ons.php:129 +#: profile-builder-2.0/admin/add-ons.php:231 +#: profile-builder-2.0/admin/pms-cross-promotion.php:78 +#: profile-builder-2.0/admin/pms-cross-promotion.php:114 +#: profile-builder-2.0/admin/pms-cross-promotion.php:193 +msgid "Activate" +msgstr "" + +#: profile-builder-2.0/admin/add-ons.php:36 +#: profile-builder-2.0/admin/pms-cross-promotion.php:80 +msgid "Downloading and installing..." +msgstr "" + +#: profile-builder-2.0/admin/add-ons.php:37 +#: profile-builder-2.0/admin/pms-cross-promotion.php:81 +msgid "Installation complete" +msgstr "" + +#: profile-builder-2.0/admin/add-ons.php:39 +msgid "Add-On is Active" +msgstr "" + +#: profile-builder-2.0/admin/add-ons.php:40 +msgid "Add-On has been activated" +msgstr "" + +#: profile-builder-2.0/admin/add-ons.php:41 +#: profile-builder-2.0/admin/pms-cross-promotion.php:85 +msgid "Retry Install" +msgstr "" + +#: profile-builder-2.0/admin/add-ons.php:43 +#: profile-builder-2.0/admin/add-ons.php:140 +msgid "Add-On is active" +msgstr "" + +#: profile-builder-2.0/admin/add-ons.php:44 +#: profile-builder-2.0/admin/add-ons.php:138 +msgid "Add-On is inactive" +msgstr "" + +#: profile-builder-2.0/admin/add-ons.php:46 +#: profile-builder-2.0/admin/add-ons.php:133 +#: profile-builder-2.0/admin/add-ons.php:235 +#: profile-builder-2.0/admin/pms-cross-promotion.php:90 +#: profile-builder-2.0/admin/pms-cross-promotion.php:118 +#: profile-builder-2.0/admin/pms-cross-promotion.php:197 +msgid "Deactivate" +msgstr "" + +#: profile-builder-2.0/admin/add-ons.php:47 +msgid "Add-On has been deactivated." +msgstr "" + +#: profile-builder-2.0/admin/add-ons.php:59 +msgid "" +"Something went wrong, we could not connect to the server. Please try again " +"later." +msgstr "" + +#: profile-builder-2.0/admin/add-ons.php:103 +msgid "Available in Hobbyist and Pro Versions" +msgstr "" + +#: profile-builder-2.0/admin/add-ons.php:105 +msgid "Available in All Versions" +msgstr "" + +#: profile-builder-2.0/admin/add-ons.php:148 +msgid "Learn More" +msgstr "" + +#: profile-builder-2.0/admin/add-ons.php:148 +#: profile-builder-2.0/admin/add-ons.php:248 +#: profile-builder-2.0/admin/pms-cross-promotion.php:134 +#: profile-builder-2.0/admin/pms-cross-promotion.php:213 +msgid "Download Now" +msgstr "" + +#: profile-builder-2.0/admin/add-ons.php:153 +#: profile-builder-2.0/admin/add-ons.php:251 +#: profile-builder-2.0/admin/pms-cross-promotion.php:141 +#: profile-builder-2.0/admin/pms-cross-promotion.php:220 +msgid "Compatible with your version of Profile Builder." +msgstr "" + +#: profile-builder-2.0/admin/add-ons.php:162 +msgid "Upgrade Profile Builder" +msgstr "" + +#: profile-builder-2.0/admin/add-ons.php:163 +msgid "Not compatible with Profile Builder" +msgstr "" + +#: profile-builder-2.0/admin/add-ons.php:170 +#: profile-builder-2.0/front-end/class-formbuilder.php:423 +msgid "Update" +msgstr "" + +#: profile-builder-2.0/admin/add-ons.php:171 +msgid "Not compatible with your version of Profile Builder." +msgstr "" + +#: profile-builder-2.0/admin/add-ons.php:172 +msgid "Minimum required Profile Builder version:" +msgstr "" + +#: profile-builder-2.0/admin/add-ons.php:177 +#, php-format +msgid "" +"Could not install add-on. Retry or
            install " +"manually." +msgstr "" + +#: profile-builder-2.0/admin/add-ons.php:190 +msgid "Recommended Plugins" +msgstr "" + +#: profile-builder-2.0/admin/add-ons.php:219 +#: profile-builder-2.0/admin/pms-cross-promotion.php:102 +msgid "Free" +msgstr "" + +#: profile-builder-2.0/admin/add-ons.php:221 +msgid "" +"Accept user payments, create subscription plans and restrict content on your " +"membership site." +msgstr "" + +#: profile-builder-2.0/admin/add-ons.php:222 +#: profile-builder-2.0/admin/pms-cross-promotion.php:105 +msgid "More Details" +msgstr "" + +#: profile-builder-2.0/admin/add-ons.php:240 +#: profile-builder-2.0/admin/pms-cross-promotion.php:88 +#: profile-builder-2.0/admin/pms-cross-promotion.php:123 +#: profile-builder-2.0/admin/pms-cross-promotion.php:202 +msgid "Plugin is inactive" +msgstr "" + +#: profile-builder-2.0/admin/add-ons.php:242 +#: profile-builder-2.0/admin/pms-cross-promotion.php:87 +#: profile-builder-2.0/admin/pms-cross-promotion.php:125 +#: profile-builder-2.0/admin/pms-cross-promotion.php:204 +msgid "Plugin is active" +msgstr "" + +#: profile-builder-2.0/admin/add-ons.php:256 +#: profile-builder-2.0/admin/pms-cross-promotion.php:146 +#, php-format +msgid "" +"Could not install plugin. Retry or install " +"manually." +msgstr "" + +#: profile-builder-2.0/admin/admin-bar.php:10 +msgid "Show/Hide the Admin Bar on the Front-End" +msgstr "" + +#: profile-builder-2.0/admin/admin-bar.php:10 +#: profile-builder-2.0/admin/admin-bar.php:47 +msgid "Admin Bar Settings" +msgstr "" + +#: profile-builder-2.0/admin/admin-bar.php:48 +msgid "" +"Choose which user roles view the admin bar in the front-end of the website." +msgstr "" + +#: profile-builder-2.0/admin/admin-bar.php:57 +msgid "User-Role" +msgstr "" + +#: profile-builder-2.0/admin/admin-bar.php:58 +msgid "Visibility" +msgstr "" + +#: profile-builder-2.0/admin/admin-bar.php:73 +msgid "Default" +msgstr "" + +#: profile-builder-2.0/admin/admin-bar.php:74 +msgid "Show" +msgstr "" + +#: profile-builder-2.0/admin/admin-bar.php:75 +#: profile-builder-2.0/modules/user-listing/userlisting.php:1496 +msgid "Hide" +msgstr "" + +#: profile-builder-2.0/admin/admin-functions.php:34 +#, php-format +msgid "" +"Login is set to be done using the E-mail. This field will NOT appear in the " +"front-end! ( you can change these settings under the \"%s\" tab )" +msgstr "" + +#: profile-builder-2.0/admin/admin-functions.php:34 +#: profile-builder-2.0/admin/general-settings.php:10 +#: profile-builder-2.0/admin/general-settings.php:38 +msgid "General Settings" +msgstr "" + +#: profile-builder-2.0/admin/admin-functions.php:40 +msgid "Display name publicly as - only appears on the Edit Profile page!" +msgstr "" + +#: profile-builder-2.0/admin/admin-functions.php:128 +#, php-format +msgid "" +"ERROR: The password must have the minimum length of %s " +"characters" +msgstr "" + +#: profile-builder-2.0/admin/admin-functions.php:134 +#: profile-builder-2.0/admin/general-settings.php:194 +msgid "Very weak" +msgstr "" + +#: profile-builder-2.0/admin/admin-functions.php:134 +#: profile-builder-2.0/admin/general-settings.php:195 +#: profile-builder-2.0/features/functions.php:579 +msgid "Weak" +msgstr "" + +#: profile-builder-2.0/admin/admin-functions.php:134 +#: profile-builder-2.0/admin/general-settings.php:196 +#: profile-builder-2.0/features/functions.php:579 +msgid "Medium" +msgstr "" + +#: profile-builder-2.0/admin/admin-functions.php:134 +#: profile-builder-2.0/admin/general-settings.php:197 +#: profile-builder-2.0/features/functions.php:579 +msgid "Strong" +msgstr "" + +#: profile-builder-2.0/admin/admin-functions.php:145 +#, php-format +msgid "ERROR: The password must have a minimum strength of %s" +msgstr "" + +#: profile-builder-2.0/admin/admin-functions.php:184 +msgid "Add Field" +msgstr "" + +#: profile-builder-2.0/admin/admin-functions.php:186 +#: profile-builder-2.0/modules/class-mustache-templates/class-mustache-templates.php:390 +msgid "Save Settings" +msgstr "" + +#: profile-builder-2.0/admin/admin-functions.php:197 +#, php-format +msgid "" +"If you enjoy using %1$s please rate us on WordPress.org. More happy users means more " +"features, less bugs and better support for everyone. " +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:10 +msgid "Basic Information" +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:29 +#, php-format +msgid "Version %s" +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:30 +msgid "Profile Builder " +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:31 +msgid "" +"The best way to add front-end registration, edit profile and login forms." +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:33 +msgid "For Modern User Interaction" +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:37 +#, php-format +msgid "Friction-less login using %s shortcode or a widget." +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:40 +msgid "Registration" +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:41 +#, php-format +msgid "Beautiful registration forms fully customizable using the %s shortcode." +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:44 +msgid "Edit Profile" +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:45 +#, php-format +msgid "Straight forward edit profile forms using %s shortcode." +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:51 +msgid "Extra Features" +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:52 +msgid "" +"Features that give you more control over your users, increased security and " +"help you fight user registration spam." +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:53 +msgid "Enable extra features" +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:57 +msgid "Recover Password" +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:58 +#, php-format +msgid "Allow users to recover their password in the front-end using the %s." +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:61 +msgid "Admin Approval (*)" +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:62 +msgid "" +"You decide who is a user on your website. Get notified via email or approve " +"multiple users at once from the WordPress UI." +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:65 +msgid "Email Confirmation" +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:66 +msgid "" +"Make sure users sign up with genuine emails. On registration users will " +"receive a notification to confirm their email address." +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:69 +msgid "Minimum Password Length and Strength Meter" +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:70 +msgid "" +"Eliminate weak passwords altogether by setting a minimum password length and " +"enforcing a certain password strength." +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:73 +msgid "Login with Email or Username" +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:74 +msgid "" +"Allow users to log in with their email or username when accessing your site." +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:87 +msgid "Customize Your Forms The Way You Want (*)" +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:88 +msgid "" +"With Extra Profile Fields you can create the exact registration form your " +"project needs." +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:90 +msgid "Extra Profile Fields are available in Hobbyist or PRO versions" +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:92 +msgid "Get started with extra fields" +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:95 +msgid "Avatar Upload" +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:96 +msgid "Generic Uploads" +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:97 +msgid "Agree To Terms Checkbox" +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:98 +msgid "Datepicker" +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:99 +msgid "Timepicker" +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:100 +msgid "Colorpicker" +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:101 +msgid "reCAPTCHA" +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:102 +msgid "Country Select" +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:103 +msgid "Currency Select" +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:104 +msgid "Timezone Select" +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:108 +msgid "Input / Hidden Input" +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:109 +msgid "Number" +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:110 +msgid "Checkbox" +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:111 +msgid "Select" +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:112 +msgid "Radio Buttons" +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:113 +msgid "Textarea" +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:114 +msgid "Validation" +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:115 +msgid "Map" +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:116 +msgid "HTML" +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:125 +msgid "Powerful Modules (**)" +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:126 +msgid "" +"Everything you will need to manage your users is probably already available " +"using the Pro Modules." +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:128 +msgid "Enable your modules" +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:131 +msgid "Find out more about PRO Modules" +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:136 +#: profile-builder-2.0/modules/modules.php:89 +#: profile-builder-2.0/modules/user-listing/userlisting.php:11 +#: profile-builder-2.0/modules/user-listing/userlisting.php:12 +#: profile-builder-2.0/modules/user-listing/userlisting.php:17 +#: profile-builder-2.0/modules/user-listing/userlisting.php:23 +msgid "User Listing" +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:138 +msgid "" +"Easy to edit templates for listing your website users as well as creating " +"single user pages. Shortcode based, offering many options to customize your " +"listings." +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:140 +#, php-format +msgid "" +"To create a page containing the users registered to this current site/blog, " +"insert the following shortcode in a page of your chosing: %s." +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:144 +msgid "Email Customizer" +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:145 +msgid "" +"Personalize all emails sent to your users or admins. On registration, email " +"confirmation, admin approval / un-approval." +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:148 +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:32 +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:33 +#: profile-builder-2.0/modules/modules.php:110 +msgid "Custom Redirects" +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:149 +msgid "" +"Keep your users out of the WordPress dashboard, redirect them to the front-" +"page after login or registration, everything is just a few clicks away." +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:154 +#: profile-builder-2.0/modules/modules.php:75 +msgid "Multiple Registration Forms" +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:155 +msgid "" +"Set up multiple registration forms with different fields for certain user " +"roles. Capture different information from different types of users." +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:158 +#: profile-builder-2.0/modules/modules.php:82 +msgid "Multiple Edit-profile Forms" +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:159 +msgid "" +"Allow different user roles to edit their specific information. Set up " +"multiple edit-profile forms with different fields for certain user roles." +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:162 +#: profile-builder-2.0/modules/modules.php:117 +msgid "Repeater Fields" +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:163 +msgid "" +"Set up a repeating group of fields on register and edit profile forms. Limit " +"the number of repeated groups for each user role." +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:187 +#, php-format +msgid " * only available in the %1$sHobbyist and Pro versions%2$s." +msgstr "" + +#: profile-builder-2.0/admin/basic-info.php:188 +#, php-format +msgid "** only available in the %1$sPro version%2$s." +msgstr "" + +#: profile-builder-2.0/admin/general-settings.php:42 +msgid "Load Profile Builder's own CSS file in the front-end:" +msgstr "" + +#: profile-builder-2.0/admin/general-settings.php:45 +#: profile-builder-2.0/admin/general-settings.php:58 +#: profile-builder-2.0/admin/general-settings.php:107 +#: profile-builder-2.0/modules/multiple-forms/register-forms.php:229 +#: profile-builder-2.0/modules/multiple-forms/register-forms.php:230 +#: profile-builder-2.0/modules/user-listing/userlisting.php:2142 +msgid "Yes" +msgstr "" + +#: profile-builder-2.0/admin/general-settings.php:47 +#, php-format +msgid "You can find the default file here: %1$s" +msgstr "" + +#: profile-builder-2.0/admin/general-settings.php:54 +msgid "\"Email Confirmation\" Activated:" +msgstr "" + +#: profile-builder-2.0/admin/general-settings.php:59 +#: profile-builder-2.0/admin/general-settings.php:108 +#: profile-builder-2.0/modules/multiple-forms/register-forms.php:229 +#: profile-builder-2.0/modules/multiple-forms/register-forms.php:230 +msgid "No" +msgstr "" + +#: profile-builder-2.0/admin/general-settings.php:62 +msgid "" +"This works with front-end forms only. Recommended to redirect WP default " +"registration to a Profile Builder one using \"Custom Redirects\" module." +msgstr "" + +#: profile-builder-2.0/admin/general-settings.php:64 +#, php-format +msgid "" +"You can find a list of unconfirmed email addresses %1$sUsers > All Users > " +"Email Confirmation%2$s." +msgstr "" + +#: profile-builder-2.0/admin/general-settings.php:72 +msgid "\"Email Confirmation\" Landing Page:" +msgstr "" + +#: profile-builder-2.0/admin/general-settings.php:77 +msgid "Existing Pages" +msgstr "" + +#: profile-builder-2.0/admin/general-settings.php:92 +msgid "" +"Specify the page where the users will be directed when confirming the email " +"account. This page can differ from the register page(s) and can be changed " +"at any time. If none selected, a simple confirmation page will be displayed " +"for the user." +msgstr "" + +#: profile-builder-2.0/admin/general-settings.php:103 +msgid "\"Admin Approval\" Activated:" +msgstr "" + +#: profile-builder-2.0/admin/general-settings.php:111 +#, php-format +msgid "" +"You can find a list of users at %1$sUsers > All Users > Admin Approval%2$s." +msgstr "" + +#: profile-builder-2.0/admin/general-settings.php:118 +msgid "\"Admin Approval\" on User Role:" +msgstr "" + +#: profile-builder-2.0/admin/general-settings.php:137 +msgid "Select on what user roles to activate Admin Approval." +msgstr "" + +#: profile-builder-2.0/admin/general-settings.php:149 +msgid "\"Admin Approval\" Feature:" +msgstr "" + +#: profile-builder-2.0/admin/general-settings.php:152 +#, php-format +msgid "" +"You decide who is a user on your website. Get notified via email or approve " +"multiple users at once from the WordPress UI. Enable Admin Approval by " +"upgrading to %1$sHobbyist or PRO versions%2$s." +msgstr "" + +#: profile-builder-2.0/admin/general-settings.php:159 +msgid "Allow Users to Log in With:" +msgstr "" + +#: profile-builder-2.0/admin/general-settings.php:163 +msgid "Username and Email" +msgstr "" + +#: profile-builder-2.0/admin/general-settings.php:164 +#: profile-builder-2.0/admin/manage-fields.php:195 +#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:166 +#: profile-builder-2.0/features/email-confirmation/class-email-confirmation.php:167 +#: profile-builder-2.0/front-end/login.php:85 +#: profile-builder-2.0/front-end/login.php:99 +#: profile-builder-2.0/front-end/login.php:225 +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:56 +#: profile-builder-2.0/modules/email-customizer/email-customizer.php:28 +#: profile-builder-2.0/modules/user-listing/userlisting.php:101 +#: profile-builder-2.0/modules/user-listing/userlisting.php:268 +#: profile-builder-2.0/modules/user-listing/userlisting.php:704 +#: profile-builder-2.0/modules/user-listing/userlisting.php:2098 +msgid "Username" +msgstr "" + +#: profile-builder-2.0/admin/general-settings.php:165 +#: profile-builder-2.0/front-end/login.php:222 +#: profile-builder-2.0/modules/email-customizer/email-customizer.php:29 +#: profile-builder-2.0/modules/user-listing/userlisting.php:710 +#: profile-builder-2.0/modules/user-listing/userlisting.php:2099 +msgid "Email" +msgstr "" + +#: profile-builder-2.0/admin/general-settings.php:168 +msgid "\"Username and Email\" - users can Log In with both Username and Email." +msgstr "" + +#: profile-builder-2.0/admin/general-settings.php:169 +msgid "\"Username\" - users can Log In only with Username." +msgstr "" + +#: profile-builder-2.0/admin/general-settings.php:170 +msgid "\"Email\" - users can Log In only with Email." +msgstr "" + +#: profile-builder-2.0/admin/general-settings.php:177 +msgid "Minimum Password Length:" +msgstr "" + +#: profile-builder-2.0/admin/general-settings.php:182 +msgid "" +"Enter the minimum characters the password should have. Leave empty for no " +"minimum limit" +msgstr "" + +#: profile-builder-2.0/admin/general-settings.php:189 +msgid "Minimum Password Strength:" +msgstr "" + +#: profile-builder-2.0/admin/general-settings.php:193 +msgid "Disabled" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:12 +msgid "Manage Fields" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:13 +msgid "Manage Default and Extra Fields" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:77 +msgid "Choose one of the supported field types" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:79 +#, php-format +msgid "" +". Extra Field Types are available in Hobbyist or PRO " +"versions." +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:113 +msgid "Field Title" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:113 +msgid "Title of the field" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:114 +#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:245 +#: profile-builder-2.0/modules/multiple-forms/register-forms.php:266 +msgid "Field" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:115 +msgid "Meta-name" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:115 +msgid "" +"Use this in conjunction with WordPress functions to display the value in the " +"page of your choosing
            Auto-completed but in some cases editable (in " +"which case it must be unique)
            Changing this might take long in case of a " +"very big user-count" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:116 +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:65 +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:95 +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:114 +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:139 +#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:246 +#: profile-builder-2.0/modules/multiple-forms/register-forms.php:267 +msgid "ID" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:116 +#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:246 +#: profile-builder-2.0/modules/multiple-forms/register-forms.php:267 +msgid "" +"A unique, auto-generated ID for this particular field
            You can use this " +"in conjuction with filters to target this element if needed
            Can't be " +"edited" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:117 +msgid "Description" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:117 +msgid "" +"Enter a (detailed) description of the option for end users to read
            Optional" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:118 +msgid "Row Count" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:118 +msgid "" +"Specify the number of rows for a 'Textarea' field
            If not specified, " +"defaults to 5" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:119 +msgid "Allowed Image Extensions" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:119 +msgid "" +"Specify the extension(s) you want to limit to upload
            Example: .ext1,." +"ext2,.ext3
            If not specified, defaults to: .jpg,.jpeg,.gif,.png (.*)" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:120 +msgid "Allowed Upload Extensions" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:120 +msgid "" +"Specify the extension(s) you want to limit to upload
            Example: .ext1,." +"ext2,.ext3
            If not specified, defaults to all WordPress allowed file " +"extensions (.*)" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:121 +msgid "Avatar Size" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:121 +msgid "" +"Enter a value (between 20 and 200) for the size of the 'Avatar'
            If not " +"specified, defaults to 100" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:122 +msgid "Date-format" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:122 +msgid "" +"Specify the format of the date when using Datepicker
            Valid options: mm/" +"dd/yy, mm/yy/dd, dd/yy/mm, dd/mm/yy, yy/dd/mm, yy/mm/dd
            If not " +"specified, defaults to mm/dd/yy" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:123 +msgid "Terms of Agreement" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:123 +msgid "" +"Enter a detailed description of the temrs of agreement for the user to read." +"
            Links can be inserted by using standard HTML syntax: <a href=" +"\"custom_url\">custom_text</a>" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:124 +msgid "Options" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:124 +msgid "" +"Enter a comma separated list of values
            This can be anything, as it is " +"hidden from the user, but should not contain special characters or " +"apostrophes" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:125 +msgid "Labels" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:125 +msgid "Enter a comma separated list of labels
            Visible for the user" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:126 +msgid "Site Key" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:126 +msgid "" +"The site key from Google, www.google.com/recaptcha" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:127 +msgid "Secret Key" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:127 +msgid "" +"The secret key from Google, www.google.com/recaptcha" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:128 +msgid "Display on PB forms" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:128 +msgid "PB Login" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:128 +msgid "PB Register" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:128 +msgid "PB Recover Password" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:128 +msgid "Select on which Profile Builder forms to display reCAPTCHA" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:129 +msgid "Display on default WP forms" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:129 +msgid "Default WP Login" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:129 +msgid "Default WP Register" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:129 +msgid "Default WP Recover Password" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:129 +msgid "Select on which default WP forms to display reCAPTCHA" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:130 +msgid "User Roles" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:130 +msgid "" +"Select which user roles to show to the user ( drag and drop to re-order )" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:131 +msgid "User Roles Order" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:131 +msgid "Save the user role order from the user roles checkboxes" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:132 +msgid "Default Value" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:132 +msgid "Default value of the field" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:133 +#: profile-builder-2.0/admin/manage-fields.php:135 +#: profile-builder-2.0/admin/manage-fields.php:136 +#: profile-builder-2.0/admin/manage-fields.php:137 +msgid "Default Option" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:133 +msgid "Specify the option which should be selected by default" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:134 +msgid "Default Option(s)" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:134 +msgid "" +"Specify the option which should be checked by default
            If there are " +"multiple values, separate them with a ',' (comma)" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:135 +#: profile-builder-2.0/admin/manage-fields.php:136 +#: profile-builder-2.0/admin/manage-fields.php:137 +msgid "Default option of the field" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:138 +msgid "Show Currency Symbol" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:138 +msgid "" +"Whether the currency symbol should be displayed after the currency name in " +"the select option." +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:139 +msgid "Show Post Type" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:139 +msgid "Posts from what post type will be displayed in the select." +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:140 +msgid "Allowable Values" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:140 +msgid "" +"Enter a comma separated list of possible values. Upon registration if the " +"value provided by the user does not match one of these values, the user will " +"not be registered." +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:141 +msgid "Error Message" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:141 +msgid "Set a custom error message that will be displayed to the user." +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:142 +msgid "Time Format" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:142 +msgid "Specify the time format." +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:143 +msgid "Google Maps API Key" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:143 +msgid "" +"Enter your Google Maps API key ( Get your API key ). If more than one map fields are added to a form the API key from the " +"first map displayed will be used." +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:144 +msgid "Default Latitude" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:144 +msgid "" +"The latitude at which the map should be displayed when no pins are attached." +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:145 +msgid "Default Longitude" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:145 +msgid "" +"The longitude at which the map should be displayed when no pins are attached." +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:146 +msgid "Default Zoom Level" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:146 +msgid "Add a number from 0 to 19. The higher the number the higher the zoom." +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:147 +msgid "Map Height" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:147 +msgid "The height of the map." +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:148 +msgid "Default Content" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:148 +msgid "Default value of the textarea" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:149 +msgid "HTML Content" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:149 +msgid "Add your HTML (or text) content" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:150 +msgid "Phone Format" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:150 +msgid "" +"You can use: # for numbers, parentheses ( ), - sign, + sign, dot . and " +"spaces." +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:150 +msgid "Eg. (###) ###-####" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:150 +msgid "Empty field won't check for correct phone number." +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:151 +msgid "Heading Tag" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:151 +msgid "Change heading field size on front-end forms" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:152 +msgid "Min Number Value" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:152 +msgid "Min allowed number value (0 to allow only positive numbers)" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:152 +msgid "Leave it empty for no min value" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:153 +msgid "Max Number Value" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:153 +msgid "Max allowed number value (0 to allow only negative numbers)" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:153 +msgid "Leave it empty for no max value" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:154 +msgid "Number Step Value" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:154 +msgid "" +"Step value 1 to allow only integers, 0.1 to allow integers and numbers with " +"1 decimal" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:154 +msgid "To allow multiple decimals use for eg. 0.01 (for 2 deciamls) and so on" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:154 +msgid "" +"You can also use step value to specify the legal number intervals (eg. step " +"value 2 will allow only -4, -2, 0, 2 and so on)" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:154 +msgid "Leave it empty for no restriction" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:155 +msgid "Whether the field is required or not" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:156 +msgid "Overwrite Existing" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:156 +msgid "" +"Selecting 'Yes' will add the field to the list, but will overwrite any other " +"field in the database that has the same meta-name
            Use this at your own " +"risk" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:162 +msgid "Field Properties" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:175 +msgid "Registration & Edit Profile" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:194 +msgid "Name" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:195 +msgid "Usernames cannot be changed." +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:198 +#: profile-builder-2.0/modules/user-listing/userlisting.php:743 +#: profile-builder-2.0/modules/user-listing/userlisting.php:2106 +msgid "Nickname" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:199 +msgid "Display name publicly as" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:200 +msgid "Contact Info" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:201 +#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:169 +#: profile-builder-2.0/features/email-confirmation/class-email-confirmation.php:168 +#: profile-builder-2.0/modules/user-listing/userlisting.php:107 +msgid "E-mail" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:202 +#: profile-builder-2.0/modules/email-customizer/email-customizer.php:32 +#: profile-builder-2.0/modules/user-listing/userlisting.php:110 +#: profile-builder-2.0/modules/user-listing/userlisting.php:725 +#: profile-builder-2.0/modules/user-listing/userlisting.php:2100 +msgid "Website" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:206 +msgid "AIM" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:207 +msgid "Yahoo IM" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:208 +msgid "Jabber / Google Talk" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:211 +msgid "About Yourself" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:212 +#: profile-builder-2.0/modules/user-listing/userlisting.php:113 +#: profile-builder-2.0/modules/user-listing/userlisting.php:728 +#: profile-builder-2.0/modules/user-listing/userlisting.php:2101 +msgid "Biographical Info" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:212 +msgid "" +"Share a little biographical information to fill out your profile. This may " +"be shown publicly." +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:213 +#: profile-builder-2.0/front-end/recover.php:73 +#: profile-builder-2.0/modules/email-customizer/email-customizer.php:30 +msgid "Password" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:213 +msgid "Type your password." +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:214 +#: profile-builder-2.0/front-end/recover.php:74 +msgid "Repeat Password" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:214 +msgid "Type your password again. " +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:273 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Afghanistan" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:274 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Aland Islands" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:275 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Albania" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:276 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Algeria" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:277 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "American Samoa" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:278 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Andorra" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:279 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Angola" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:280 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Anguilla" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:281 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Antarctica" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:282 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Antigua and Barbuda" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:283 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Argentina" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:284 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Armenia" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:285 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Aruba" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:286 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Australia" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:287 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Austria" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:288 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Azerbaijan" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:289 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Bahamas" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:290 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Bahrain" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:291 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Bangladesh" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:292 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Barbados" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:293 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Belarus" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:294 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Belgium" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:295 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Belize" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:296 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Benin" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:297 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Bermuda" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:298 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Bhutan" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:299 +msgid "Bolivia" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:300 +msgid "Bonaire, Saint Eustatius and Saba" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:301 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Bosnia and Herzegovina" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:302 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Botswana" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:303 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Bouvet Island" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:304 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Brazil" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:305 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "British Indian Ocean Territory" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:306 +msgid "British Virgin Islands" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:307 +msgid "Brunei" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:308 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Bulgaria" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:309 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Burkina Faso" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:310 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Burundi" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:311 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Cambodia" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:312 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Cameroon" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:313 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Canada" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:314 +msgid "Cape Verde" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:315 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Cayman Islands" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:316 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Central African Republic" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:317 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Chad" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:318 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Chile" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:319 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "China" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:320 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Christmas Island" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:321 +msgid "Cocos Islands" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:322 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Colombia" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:323 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Comoros" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:324 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Cook Islands" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:325 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Costa Rica" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:326 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Croatia" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:327 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Cuba" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:328 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Curacao" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:329 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Cyprus" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:330 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Czech Republic" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:331 +msgid "Democratic Republic of the Congo" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:332 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Denmark" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:333 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Djibouti" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:334 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Dominica" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:335 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Dominican Republic" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:336 +msgid "East Timor" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:337 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Ecuador" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:338 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Egypt" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:339 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "El Salvador" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:340 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Equatorial Guinea" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:341 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Eritrea" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:342 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Estonia" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:343 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Ethiopia" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:344 +msgid "Falkland Islands" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:345 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Faroe Islands" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:346 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Fiji" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:347 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Finland" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:348 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "France" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:349 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "French Guiana" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:350 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "French Polynesia" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:351 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "French Southern Territories" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:352 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Gabon" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:353 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Gambia" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:354 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Georgia" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:355 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Germany" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:356 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Ghana" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:357 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Gibraltar" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:358 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Greece" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:359 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Greenland" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:360 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Grenada" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:361 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Guadeloupe" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:362 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Guam" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:363 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Guatemala" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:364 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Guernsey" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:365 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Guinea" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:366 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Guinea-Bissau" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:367 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Guyana" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:368 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Haiti" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:369 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Heard Island and McDonald Islands" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:370 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Honduras" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:371 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Hong Kong" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:372 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Hungary" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:373 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Iceland" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:374 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "India" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:375 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Indonesia" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:376 +msgid "Iran" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:377 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Iraq" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:378 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Ireland" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:379 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Isle of Man" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:380 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Israel" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:381 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Italy" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:382 +msgid "Ivory Coast" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:383 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Jamaica" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:384 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Japan" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:385 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Jersey" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:386 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Jordan" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:387 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Kazakhstan" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:388 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Kenya" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:389 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Kiribati" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:390 +msgid "Kosovo" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:391 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Kuwait" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:392 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Kyrgyzstan" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:393 +msgid "Laos" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:394 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Latvia" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:395 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Lebanon" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:396 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Lesotho" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:397 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Liberia" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:398 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Libya" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:399 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Liechtenstein" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:400 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Lithuania" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:401 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Luxembourg" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:402 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Macao" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:403 +msgid "Macedonia" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:404 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Madagascar" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:405 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Malawi" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:406 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Malaysia" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:407 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Maldives" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:408 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Mali" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:409 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Malta" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:410 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Marshall Islands" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:411 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Martinique" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:412 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Mauritania" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:413 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Mauritius" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:414 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Mayotte" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:415 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Mexico" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:416 +msgid "Micronesia" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:417 +msgid "Moldova" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:418 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Monaco" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:419 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Mongolia" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:420 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Montenegro" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:421 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Montserrat" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:422 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Morocco" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:423 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Mozambique" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:424 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Myanmar" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:425 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Namibia" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:426 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Nauru" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:427 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Nepal" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:428 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Netherlands" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:429 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "New Caledonia" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:430 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "New Zealand" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:431 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Nicaragua" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:432 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Niger" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:433 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Nigeria" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:434 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Niue" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:435 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Norfolk Island" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:436 +msgid "North Korea" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:437 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Northern Mariana Islands" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:438 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Norway" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:439 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Oman" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:440 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Pakistan" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:441 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Palau" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:442 +msgid "Palestinian Territory" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:443 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Panama" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:444 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Papua New Guinea" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:445 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Paraguay" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:446 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Peru" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:447 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Philippines" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:448 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Pitcairn" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:449 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Poland" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:450 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Portugal" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:451 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Puerto Rico" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:452 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Qatar" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:453 +msgid "Republic of the Congo" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:454 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Reunion" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:455 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Romania" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:456 +msgid "Russia" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:457 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Rwanda" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:458 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Saint Barthelemy" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:459 +msgid "Saint Helena" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:460 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Saint Kitts and Nevis" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:461 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Saint Lucia" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:462 +msgid "Saint Martin" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:463 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Saint Pierre and Miquelon" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:464 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Saint Vincent and the Grenadines" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:465 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Samoa" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:466 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "San Marino" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:467 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Sao Tome and Principe" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:468 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Saudi Arabia" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:469 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Senegal" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:470 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Serbia" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:471 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Seychelles" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:472 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Sierra Leone" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:473 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Singapore" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:474 +msgid "Sint Maarten" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:475 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Slovakia" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:476 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Slovenia" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:477 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Solomon Islands" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:478 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Somalia" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:479 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "South Africa" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:480 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "South Georgia and the South Sandwich Islands" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:481 +msgid "South Korea" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:482 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "South Sudan" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:483 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Spain" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:484 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Sri Lanka" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:485 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Sudan" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:486 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Suriname" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:487 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Svalbard and Jan Mayen" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:488 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Swaziland" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:489 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Sweden" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:490 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Switzerland" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:491 +msgid "Syria" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:492 +msgid "Taiwan" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:493 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Tajikistan" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:494 +msgid "Tanzania" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:495 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Thailand" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:496 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Togo" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:497 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Tokelau" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:498 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Tonga" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:499 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Trinidad and Tobago" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:500 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Tunisia" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:501 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Turkey" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:502 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Turkmenistan" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:503 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Turks and Caicos Islands" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:504 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Tuvalu" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:505 +msgid "U.S. Virgin Islands" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:506 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Uganda" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:507 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Ukraine" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:508 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "United Arab Emirates" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:509 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "United Kingdom" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:510 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "United States" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:511 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "United States Minor Outlying Islands" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:512 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Uruguay" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:513 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Uzbekistan" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:514 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Vanuatu" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:515 +msgid "Vatican" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:516 +msgid "Venezuela" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:517 +msgid "Vietnam" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:518 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Wallis and Futuna" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:519 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Western Sahara" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:520 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Yemen" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:521 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Zambia" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:522 +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Zimbabwe" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:555 +msgid "Albania Lek" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:556 +msgid "Afghanistan Afghani" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:557 +msgid "Argentina Peso" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:558 +msgid "Aruba Guilder" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:559 +msgid "Australia Dollar" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:560 +msgid "Azerbaijan New Manat" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:561 +msgid "Bahamas Dollar" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:562 +msgid "Barbados Dollar" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:563 +msgid "Bangladeshi taka" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:564 +msgid "Belarus Ruble" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:565 +msgid "Belize Dollar" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:566 +msgid "Bermuda Dollar" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:567 +msgid "Bolivia Boliviano" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:568 +msgid "Bosnia and Herzegovina Convertible Marka" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:569 +msgid "Botswana Pula" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:570 +msgid "Bulgaria Lev" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:571 +msgid "Brazil Real" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:572 +msgid "Brunei Darussalam Dollar" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:573 +msgid "Cambodia Riel" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:574 +msgid "Canada Dollar" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:575 +msgid "Cayman Islands Dollar" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:576 +msgid "Chile Peso" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:577 +msgid "China Yuan Renminbi" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:578 +msgid "Colombia Peso" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:579 +msgid "Costa Rica Colon" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:580 +msgid "Croatia Kuna" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:581 +msgid "Cuba Peso" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:582 +msgid "Czech Republic Koruna" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:583 +msgid "Denmark Krone" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:584 +msgid "Dominican Republic Peso" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:585 +msgid "East Caribbean Dollar" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:586 +msgid "Egypt Pound" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:587 +msgid "El Salvador Colon" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:588 +msgid "Estonia Kroon" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:589 +msgid "Euro" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:590 +msgid "Falkland Islands (Malvinas) Pound" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:591 +msgid "Fiji Dollar" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:592 +msgid "Ghana Cedis" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:593 +msgid "Gibraltar Pound" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:594 +msgid "Guatemala Quetzal" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:595 +msgid "Guernsey Pound" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:596 +msgid "Guyana Dollar" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:597 +msgid "Honduras Lempira" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:598 +msgid "Hong Kong Dollar" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:599 +msgid "Hungary Forint" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:600 +msgid "Iceland Krona" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:601 +msgid "India Rupee" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:602 +msgid "Indonesia Rupiah" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:603 +msgid "Iran Rial" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:604 +msgid "Isle of Man Pound" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:605 +msgid "Israel Shekel" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:606 +msgid "Jamaica Dollar" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:607 +msgid "Japan Yen" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:608 +msgid "Jersey Pound" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:609 +msgid "Kazakhstan Tenge" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:610 +msgid "Korea (North) Won" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:611 +msgid "Korea (South) Won" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:612 +msgid "Kyrgyzstan Som" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:613 +msgid "Laos Kip" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:614 +msgid "Latvia Lat" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:615 +msgid "Lebanon Pound" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:616 +msgid "Liberia Dollar" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:617 +msgid "Lithuania Litas" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:618 +msgid "Macedonia Denar" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:619 +msgid "Malaysia Ringgit" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:620 +msgid "Mauritius Rupee" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:621 +msgid "Mexico Peso" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:622 +msgid "Mongolia Tughrik" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:623 +msgid "Mozambique Metical" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:624 +msgid "Namibia Dollar" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:625 +msgid "Nepal Rupee" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:626 +msgid "Netherlands Antilles Guilder" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:627 +msgid "New Zealand Dollar" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:628 +msgid "Nicaragua Cordoba" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:629 +msgid "Nigeria Naira" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:630 +msgid "Norway Krone" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:631 +msgid "Oman Rial" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:632 +msgid "Pakistan Rupee" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:633 +msgid "Panama Balboa" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:634 +msgid "Paraguay Guarani" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:635 +msgid "Peru Nuevo Sol" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:636 +msgid "Philippines Peso" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:637 +msgid "Poland Zloty" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:638 +msgid "Qatar Riyal" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:639 +msgid "Romania New Leu" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:640 +msgid "Russia Ruble" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:641 +msgid "Saint Helena Pound" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:642 +msgid "Saudi Arabia Riyal" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:643 +msgid "Serbia Dinar" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:644 +msgid "Seychelles Rupee" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:645 +msgid "Singapore Dollar" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:646 +msgid "Solomon Islands Dollar" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:647 +msgid "Somalia Shilling" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:648 +msgid "South Africa Rand" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:649 +msgid "Sri Lanka Rupee" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:650 +msgid "Sweden Krona" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:651 +msgid "Switzerland Franc" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:652 +msgid "Suriname Dollar" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:653 +msgid "Syria Pound" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:654 +msgid "Taiwan New Dollar" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:655 +msgid "Thailand Baht" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:656 +msgid "Trinidad and Tobago Dollar" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:657 +#: profile-builder-2.0/admin/manage-fields.php:658 +msgid "Turkey Lira" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:659 +msgid "Tuvalu Dollar" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:660 +msgid "Ukraine Hryvna" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:661 +msgid "United Kingdom Pound" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:662 +msgid "Uganda Shilling" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:663 +msgid "US Dollar" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:664 +msgid "Uruguay Peso" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:665 +msgid "Uzbekistan Som" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:666 +msgid "Venezuela Bolivar" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:667 +msgid "Viet Nam Dong" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:668 +msgid "Yemen Rial" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:669 +msgid "Zimbabwe Dollar" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:966 +#: profile-builder-2.0/admin/manage-fields.php:1120 +msgid "You must select a field\n" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:976 +msgid "" +"Please choose a different field type as this one already exists in your form " +"(must be unique)\n" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:987 +msgid "The entered avatar size is not between 20 and 200\n" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:990 +msgid "The entered avatar size is not numerical\n" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:998 +msgid "The entered row number is not numerical\n" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:1001 +msgid "You must enter a value for the row number\n" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:1009 +msgid "You must enter the site key\n" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:1011 +msgid "You must enter the secret key\n" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:1019 +msgid "The entered value for the Datepicker is not a valid date-format\n" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:1022 +msgid "You must enter a value for the date-format\n" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:1038 +msgid "The meta-name cannot be empty\n" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:1050 +#: profile-builder-2.0/admin/manage-fields.php:1058 +#: profile-builder-2.0/admin/manage-fields.php:1069 +msgid "That meta-name is already in use\n" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:1080 +msgid "" +"The meta-name can only contain lowercase letters, numbers, _ , - and no " +"spaces.\n" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:1100 +#, php-format +msgid "" +"The following option(s) did not coincide with the ones in the options list: " +"%s\n" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:1104 +#, php-format +msgid "" +"The following option did not coincide with the ones in the options list: %s\n" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:1111 +msgid "Please select at least one user role\n" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:1127 +msgid "That field is already added in this form\n" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:1176 +msgid "" +"
            Title
            Type
            Meta Name
            Required
            " +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:1176 +#: profile-builder-2.0/assets/lib/wck-api/wordpress-creation-kit.php:443 +#: profile-builder-2.0/assets/lib/wck-api/wordpress-creation-kit.php:535 +#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:108 +#: profile-builder-2.0/features/functions.php:745 +#: profile-builder-2.0/features/functions.php:752 +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:179 +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:193 +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:207 +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:221 +#: profile-builder-2.0/modules/multiple-forms/multiple-forms.php:406 +msgid "Edit" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:1176 +#: profile-builder-2.0/assets/lib/wck-api/wordpress-creation-kit.php:443 +#: profile-builder-2.0/assets/lib/wck-api/wordpress-creation-kit.php:536 +#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:113 +#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:224 +#: profile-builder-2.0/features/email-confirmation/class-email-confirmation.php:120 +#: profile-builder-2.0/features/email-confirmation/class-email-confirmation.php:217 +#: profile-builder-2.0/features/functions.php:738 +#: profile-builder-2.0/features/functions.php:752 +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:179 +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:193 +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:207 +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:221 +msgid "Delete" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:1191 +msgid "Use these shortcodes on the pages you want the forms to be displayed:" +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:1200 +msgid "" +"If you're interested in displaying different fields in the registration and " +"edit profile forms, please use the Multiple Registration & Edit Profile " +"Forms Addon." +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:1202 +msgid "" +"With Profile Builder Pro v2 you can display different fields in the " +"registration and edit profile forms, using the Multiple Registration & Edit " +"Profile Forms module." +msgstr "" + +#: profile-builder-2.0/admin/manage-fields.php:1296 +msgid "Search Location" +msgstr "" + +#: profile-builder-2.0/admin/pms-cross-promotion.php:10 +msgid "Paid Accounts" +msgstr "" + +#: profile-builder-2.0/admin/pms-cross-promotion.php:33 +msgid "Paid Member Subscriptions - a free WordPress plugin" +msgstr "" + +#: profile-builder-2.0/admin/pms-cross-promotion.php:37 +msgid "" +"With the new Subscriptions Field in Profile Builder, your registration forms " +"will allow your users to sign up for paid accounts." +msgstr "" + +#: profile-builder-2.0/admin/pms-cross-promotion.php:40 +msgid "Paid & Free Subscriptions" +msgstr "" + +#: profile-builder-2.0/admin/pms-cross-promotion.php:41 +msgid "Restrict Content" +msgstr "" + +#: profile-builder-2.0/admin/pms-cross-promotion.php:42 +msgid "Member Management" +msgstr "" + +#: profile-builder-2.0/admin/pms-cross-promotion.php:43 +msgid "Email Templates" +msgstr "" + +#: profile-builder-2.0/admin/pms-cross-promotion.php:44 +msgid "Account Management" +msgstr "" + +#: profile-builder-2.0/admin/pms-cross-promotion.php:45 +msgid "Subscription Management" +msgstr "" + +#: profile-builder-2.0/admin/pms-cross-promotion.php:46 +msgid "Payment Management" +msgstr "" + +#: profile-builder-2.0/admin/pms-cross-promotion.php:83 +msgid "Plugin is Active" +msgstr "" + +#: profile-builder-2.0/admin/pms-cross-promotion.php:84 +msgid "Plugin has been activated" +msgstr "" + +#: profile-builder-2.0/admin/pms-cross-promotion.php:91 +msgid "Plugin has been deactivated." +msgstr "" + +#: profile-builder-2.0/admin/pms-cross-promotion.php:104 +msgid "" +"Accept user payments, create subscription plans and restrict content on your " +"website." +msgstr "" + +#: profile-builder-2.0/admin/pms-cross-promotion.php:137 +#: profile-builder-2.0/admin/pms-cross-promotion.php:216 +msgid "Install Now" +msgstr "" + +#: profile-builder-2.0/admin/pms-cross-promotion.php:155 +msgid "Step by Step Quick Setup" +msgstr "" + +#: profile-builder-2.0/admin/pms-cross-promotion.php:239 +#, php-format +msgid "" +"Allow your users to have paid accounts with Profile Builder. %1$sFind out how >%2$s %3$sDismiss%4$s" +msgstr "" + +#: profile-builder-2.0/admin/register-version.php:14 +msgid "Register Your Version" +msgstr "" + +#: profile-builder-2.0/admin/register-version.php:14 +msgid "Register Version" +msgstr "" + +#: profile-builder-2.0/admin/register-version.php:22 +msgid "Profile Builder Register" +msgstr "" + +#: profile-builder-2.0/admin/register-version.php:69 +#, php-format +msgid "" +"Now that you acquired a copy of %s, you should take the time and register it " +"with the serial number you received" +msgstr "" + +#: profile-builder-2.0/admin/register-version.php:70 +msgid "" +"If you register this version of Profile Builder, you'll receive information " +"regarding upgrades, patches, and technical support." +msgstr "" + +#: profile-builder-2.0/admin/register-version.php:72 +msgid " Serial Number:" +msgstr "" + +#: profile-builder-2.0/admin/register-version.php:77 +msgid "The serial number was successfully validated!" +msgstr "" + +#: profile-builder-2.0/admin/register-version.php:79 +msgid "The serial number entered couldn't be validated!" +msgstr "" + +#: profile-builder-2.0/admin/register-version.php:81 +msgid "The serial number is about to expire soon!" +msgstr "" + +#: profile-builder-2.0/admin/register-version.php:81 +#, php-format +msgid "" +" Your serial number is about to expire, please %1$s Renew Your License%2$s." +msgstr "" + +#: profile-builder-2.0/admin/register-version.php:83 +msgid "The serial number couldn't be validated because it expired!" +msgstr "" + +#: profile-builder-2.0/admin/register-version.php:83 +#, php-format +msgid " Your serial number is expired, please %1$s Renew Your License%2$s." +msgstr "" + +#: profile-builder-2.0/admin/register-version.php:85 +msgid "" +"The serial number couldn't be validated because process timed out. This is " +"possible due to the server being down. Please try again later!" +msgstr "" + +#: profile-builder-2.0/admin/register-version.php:87 +msgid "(e.g. RMPB-15-SN-253a55baa4fbe7bf595b2aabb8d72985)" +msgstr "" + +#: profile-builder-2.0/admin/register-version.php:243 +#, php-format +msgid "" +"

            Your Profile Builder serial number is invalid or " +"missing.
            Please %1$sregister your copy%2$s to receive access to " +"automatic updates and support. Need a license key? %3$sPurchase one now%4$s" +msgstr "" + +#: profile-builder-2.0/admin/register-version.php:246 +#, php-format +msgid "" +"

            Your Profile Builder license has expired.
            Please " +"%1$sRenew Your Licence%2$s to continue receiving access to product " +"downloads, automatic updates and support. %3$sRenew now and get 50% off " +"%4$s %5$sDismiss%6$s

            " +msgstr "" + +#: profile-builder-2.0/admin/register-version.php:251 +#, php-format +msgid "" +"

            Your Profile Builder license is about to expire on %5$s. " +"
            Please %1$sRenew Your Licence%2$s to continue receiving access to " +"product downloads, automatic updates and support. %3$sRenew now and get " +"50% off %4$s %6$sDismiss%7$s

            " +msgstr "" + +#: profile-builder-2.0/assets/lib/wck-api/fields/country select.php:14 +#: profile-builder-2.0/assets/lib/wck-api/fields/cpt select.php:17 +#: profile-builder-2.0/assets/lib/wck-api/fields/select.php:14 +#: profile-builder-2.0/assets/lib/wck-api/fields/user select.php:15 +#: profile-builder-2.0/front-end/extra-fields/select-cpt/select-cpt.php:32 +#: profile-builder-2.0/front-end/extra-fields/select-cpt/select-cpt.php:54 +msgid "...Choose" +msgstr "" + +#: profile-builder-2.0/assets/lib/wck-api/fields/nested repeater.php:8 +#, php-format +msgid "You can add the information for the %s after you add a entry" +msgstr "" + +#: profile-builder-2.0/assets/lib/wck-api/wordpress-creation-kit.php:340 +#: profile-builder-2.0/modules/class-mustache-templates/class-mustache-templates.php:254 +msgid "Save" +msgstr "" + +#: profile-builder-2.0/assets/lib/wck-api/wordpress-creation-kit.php:340 +msgid "Add Entry" +msgstr "" + +#: profile-builder-2.0/assets/lib/wck-api/wordpress-creation-kit.php:443 +#: profile-builder-2.0/features/functions.php:752 +msgid "Content" +msgstr "" + +#: profile-builder-2.0/assets/lib/wck-api/wordpress-creation-kit.php:535 +msgid "Edit this item" +msgstr "" + +#: profile-builder-2.0/assets/lib/wck-api/wordpress-creation-kit.php:536 +msgid "Delete this item" +msgstr "" + +#: profile-builder-2.0/assets/lib/wck-api/wordpress-creation-kit.php:705 +msgid "Please enter a value for the required field " +msgstr "" + +#: profile-builder-2.0/assets/lib/wck-api/wordpress-creation-kit.php:754 +msgid "You are not allowed to do this." +msgstr "" + +#: profile-builder-2.0/assets/lib/wck-api/wordpress-creation-kit.php:1253 +msgid "Syncronize WCK" +msgstr "" + +#: profile-builder-2.0/assets/lib/wck-api/wordpress-creation-kit.php:1265 +msgid "Syncronize WCK Translation" +msgstr "" + +#: profile-builder-2.0/assets/misc/plugin-compatibilities.php:241 +msgid "" +"Your account has to be confirmed by an administrator before you can log in." +msgstr "" + +#: profile-builder-2.0/features/admin-approval/admin-approval.php:14 +#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:453 +msgid "Admin Approval" +msgstr "" + +#: profile-builder-2.0/features/admin-approval/admin-approval.php:28 +#: profile-builder-2.0/features/email-confirmation/email-confirmation.php:58 +msgid "Do you want to" +msgstr "" + +#: profile-builder-2.0/features/admin-approval/admin-approval.php:51 +msgid "Your session has expired! Please refresh the page and try again" +msgstr "" + +#: profile-builder-2.0/features/admin-approval/admin-approval.php:62 +msgid "User successfully approved!" +msgstr "" + +#: profile-builder-2.0/features/admin-approval/admin-approval.php:70 +msgid "User successfully unapproved!" +msgstr "" + +#: profile-builder-2.0/features/admin-approval/admin-approval.php:76 +msgid "User successfully deleted!" +msgstr "" + +#: profile-builder-2.0/features/admin-approval/admin-approval.php:81 +#: profile-builder-2.0/features/admin-approval/admin-approval.php:125 +#: profile-builder-2.0/features/email-confirmation/email-confirmation.php:135 +msgid "You either don't have permission for that action or there was an error!" +msgstr "" + +#: profile-builder-2.0/features/admin-approval/admin-approval.php:92 +msgid "Your session has expired! Please refresh the page and try again." +msgstr "" + +#: profile-builder-2.0/features/admin-approval/admin-approval.php:104 +msgid "Users successfully approved!" +msgstr "" + +#: profile-builder-2.0/features/admin-approval/admin-approval.php:113 +msgid "Users successfully unapproved!" +msgstr "" + +#: profile-builder-2.0/features/admin-approval/admin-approval.php:121 +msgid "Users successfully deleted!" +msgstr "" + +#: profile-builder-2.0/features/admin-approval/admin-approval.php:141 +#, php-format +msgid "Your account on %1$s has been approved!" +msgstr "" + +#: profile-builder-2.0/features/admin-approval/admin-approval.php:142 +#: profile-builder-2.0/features/admin-approval/admin-approval.php:145 +msgid "approved" +msgstr "" + +#: profile-builder-2.0/features/admin-approval/admin-approval.php:144 +#, php-format +msgid "An administrator has just approved your account on %1$s (%2$s)." +msgstr "" + +#: profile-builder-2.0/features/admin-approval/admin-approval.php:149 +#, php-format +msgid "Your account on %1$s has been unapproved!" +msgstr "" + +#: profile-builder-2.0/features/admin-approval/admin-approval.php:150 +#: profile-builder-2.0/features/admin-approval/admin-approval.php:153 +msgid "unapproved" +msgstr "" + +#: profile-builder-2.0/features/admin-approval/admin-approval.php:152 +#, php-format +msgid "An administrator has just unapproved your account on %1$s (%2$s)." +msgstr "" + +#: profile-builder-2.0/features/admin-approval/admin-approval.php:171 +msgid "" +"ERROR: Your account has to be confirmed by an administrator " +"before you can log in." +msgstr "" + +#: profile-builder-2.0/features/admin-approval/admin-approval.php:183 +msgid "" +"Your account has to be confirmed by an administrator before you can use the " +"\"Password Recovery\" feature." +msgstr "" + +#: profile-builder-2.0/features/admin-approval/admin-approval.php:210 +msgid "Your account has been successfully created!" +msgstr "" + +#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:113 +msgid "delete this user?" +msgstr "" + +#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:116 +msgid "unapprove this user?" +msgstr "" + +#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:116 +#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:223 +msgid "Unapprove" +msgstr "" + +#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:118 +msgid "approve this user?" +msgstr "" + +#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:118 +#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:222 +msgid "Approve" +msgstr "" + +#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:167 +#: profile-builder-2.0/modules/user-listing/userlisting.php:269 +#: profile-builder-2.0/modules/user-listing/userlisting.php:716 +#: profile-builder-2.0/modules/user-listing/userlisting.php:2103 +msgid "Firstname" +msgstr "" + +#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:168 +#: profile-builder-2.0/modules/user-listing/userlisting.php:719 +#: profile-builder-2.0/modules/user-listing/userlisting.php:2104 +msgid "Lastname" +msgstr "" + +#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:170 +#: profile-builder-2.0/modules/user-listing/userlisting.php:142 +#: profile-builder-2.0/modules/user-listing/userlisting.php:270 +#: profile-builder-2.0/modules/user-listing/userlisting.php:746 +#: profile-builder-2.0/modules/user-listing/userlisting.php:2108 +msgid "Role" +msgstr "" + +#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:171 +#: profile-builder-2.0/features/email-confirmation/class-email-confirmation.php:169 +msgid "Registered" +msgstr "" + +#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:172 +msgid "User-status" +msgstr "" + +#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:252 +msgid "Do you want to bulk approve the selected users?" +msgstr "" + +#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:260 +msgid "Do you want to bulk unapprove the selected users?" +msgstr "" + +#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:266 +msgid "Do you want to bulk delete the selected users?" +msgstr "" + +#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:274 +#: profile-builder-2.0/features/email-confirmation/class-email-confirmation.php:278 +msgid "Sorry, but you don't have permission to do that!" +msgstr "" + +#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:339 +msgid "Approved" +msgstr "" + +#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:341 +msgid "Unapproved" +msgstr "" + +#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:456 +#: profile-builder-2.0/features/email-confirmation/class-email-confirmation.php:454 +msgid "All Users" +msgstr "" + +#: profile-builder-2.0/features/admin-approval/class-admin-approval.php:461 +#: profile-builder-2.0/features/email-confirmation/class-email-confirmation.php:460 +msgid "Search Users" +msgstr "" + +#: profile-builder-2.0/features/class-list-table.php:184 +msgid "No items found." +msgstr "" + +#: profile-builder-2.0/features/class-list-table.php:308 +msgid "Bulk Actions" +msgstr "" + +#: profile-builder-2.0/features/class-list-table.php:318 +msgid "Apply" +msgstr "" + +#: profile-builder-2.0/features/class-list-table.php:402 +msgid "Show all dates" +msgstr "" + +#: profile-builder-2.0/features/class-list-table.php:415 +#, php-format +msgid "%1$s %2$d" +msgstr "" + +#: profile-builder-2.0/features/class-list-table.php:431 +msgid "List View" +msgstr "" + +#: profile-builder-2.0/features/class-list-table.php:432 +msgid "Excerpt View" +msgstr "" + +#: profile-builder-2.0/features/class-list-table.php:458 +#, php-format +msgid "%s pending" +msgstr "" + +#: profile-builder-2.0/features/class-list-table.php:526 +#: profile-builder-2.0/features/class-list-table.php:942 +msgid "1 item" +msgstr "" + +#: profile-builder-2.0/features/class-list-table.php:566 +#, php-format +msgid "%1$s of %2$s" +msgstr "" + +#: profile-builder-2.0/features/class-list-table.php:713 +msgid "Select All" +msgstr "" + +#: profile-builder-2.0/features/conditional-fields/conditional-fields.php:78 +msgid "Conditional Logic" +msgstr "" + +#: profile-builder-2.0/features/conditional-fields/conditional-fields.php:79 +msgid "Conditional Rules" +msgstr "" + +#: profile-builder-2.0/features/conditional-fields/conditional-fields.php:432 +msgid "This field has conditional logic enabled." +msgstr "" + +#: profile-builder-2.0/features/email-confirmation/class-email-confirmation.php:91 +#: profile-builder-2.0/features/email-confirmation/class-email-confirmation.php:170 +msgid "User Meta" +msgstr "" + +#: profile-builder-2.0/features/email-confirmation/class-email-confirmation.php:91 +msgid "show" +msgstr "" + +#: profile-builder-2.0/features/email-confirmation/class-email-confirmation.php:120 +msgid "delete this user from the _signups table?" +msgstr "" + +#: profile-builder-2.0/features/email-confirmation/class-email-confirmation.php:121 +msgid "confirm this email yourself?" +msgstr "" + +#: profile-builder-2.0/features/email-confirmation/class-email-confirmation.php:121 +#: profile-builder-2.0/features/email-confirmation/class-email-confirmation.php:218 +msgid "Confirm Email" +msgstr "" + +#: profile-builder-2.0/features/email-confirmation/class-email-confirmation.php:122 +msgid "resend the activation link?" +msgstr "" + +#: profile-builder-2.0/features/email-confirmation/class-email-confirmation.php:122 +#: profile-builder-2.0/features/email-confirmation/class-email-confirmation.php:219 +msgid "Resend Activation Email" +msgstr "" + +#: profile-builder-2.0/features/email-confirmation/class-email-confirmation.php:249 +#, php-format +msgid "%s couldn't be deleted" +msgstr "" + +#: profile-builder-2.0/features/email-confirmation/class-email-confirmation.php:253 +msgid "All users have been successfully deleted" +msgstr "" + +#: profile-builder-2.0/features/email-confirmation/class-email-confirmation.php:263 +msgid "The selected users have been activated" +msgstr "" + +#: profile-builder-2.0/features/email-confirmation/class-email-confirmation.php:274 +msgid "The selected users have had their activation emails resent" +msgstr "" + +#: profile-builder-2.0/features/email-confirmation/class-email-confirmation.php:451 +#: profile-builder-2.0/features/email-confirmation/email-confirmation.php:47 +msgid "Users with Unconfirmed Email Address" +msgstr "" + +#: profile-builder-2.0/features/email-confirmation/email-confirmation.php:110 +msgid "There was an error performing that action!" +msgstr "" + +#: profile-builder-2.0/features/email-confirmation/email-confirmation.php:118 +msgid "The selected user couldn't be deleted" +msgstr "" + +#: profile-builder-2.0/features/email-confirmation/email-confirmation.php:129 +msgid "Email notification resent to user" +msgstr "" + +#: profile-builder-2.0/features/email-confirmation/email-confirmation.php:389 +#, php-format +msgid "[%1$s] Activate %2$s" +msgstr "" + +#: profile-builder-2.0/features/email-confirmation/email-confirmation.php:392 +#, php-format +msgid "" +"To activate your user, please click the following link:

            %s%s" +"%s

            After you activate it you will receive yet *another email* with " +"your login." +msgstr "" + +#: profile-builder-2.0/features/email-confirmation/email-confirmation.php:433 +#: profile-builder-2.0/front-end/register.php:70 +msgid "Could not create user!" +msgstr "" + +#: profile-builder-2.0/features/email-confirmation/email-confirmation.php:436 +msgid "That username is already activated!" +msgstr "" + +#: profile-builder-2.0/features/email-confirmation/email-confirmation.php:459 +msgid "There was an error while trying to activate the user" +msgstr "" + +#: profile-builder-2.0/features/email-confirmation/email-confirmation.php:507 +#: profile-builder-2.0/modules/email-customizer/admin-email-customizer.php:73 +msgid "A new subscriber has (been) registered!" +msgstr "" + +#: profile-builder-2.0/features/email-confirmation/email-confirmation.php:510 +#, php-format +msgid "New subscriber on %1$s.

            Username:%2$s
            E-mail:%3$s
            " +msgstr "" + +#: profile-builder-2.0/features/email-confirmation/email-confirmation.php:561 +#, php-format +msgid "[%1$s] Your new account information" +msgstr "" + +#: profile-builder-2.0/features/email-confirmation/email-confirmation.php:565 +#: profile-builder-2.0/features/email-confirmation/email-confirmation.php:574 +#: profile-builder-2.0/modules/email-customizer/email-customizer.php:470 +#: profile-builder-2.0/modules/email-customizer/email-customizer.php:477 +#: profile-builder-2.0/modules/email-customizer/email-customizer.php:491 +msgid "Your selected password at signup" +msgstr "" + +#: profile-builder-2.0/features/email-confirmation/email-confirmation.php:570 +#, php-format +msgid "Welcome to %1$s!


            Your username is:%2$s" +msgstr "" + +#: profile-builder-2.0/features/email-confirmation/email-confirmation.php:572 +#, php-format +msgid "Welcome to %1$s!


            Your username is:%2$s and password:%3$s" +msgstr "" + +#: profile-builder-2.0/features/email-confirmation/email-confirmation.php:625 +msgid "" +"The \"Admin Approval\" feature was activated at the time of registration, so " +"please remember that you need to approve this user before he/she can log in!" +msgstr "" + +#: profile-builder-2.0/features/email-confirmation/email-confirmation.php:633 +#: profile-builder-2.0/front-end/register.php:130 +msgid "" +"Before you can access your account, an administrator needs to approve it. " +"You will be notified via email." +msgstr "" + +#: profile-builder-2.0/features/functions.php:304 +msgid "The user-validation has failed - the avatar was not deleted!" +msgstr "" + +#: profile-builder-2.0/features/functions.php:315 +msgid "The user-validation has failed - the attachment was not deleted!" +msgstr "" + +#: profile-builder-2.0/features/functions.php:554 +msgid "Strength indicator" +msgstr "" + +#: profile-builder-2.0/features/functions.php:579 +msgid "Very Weak" +msgstr "" + +#: profile-builder-2.0/features/functions.php:593 +#, php-format +msgid "Minimum length of %d characters" +msgstr "" + +#: profile-builder-2.0/features/functions.php:667 +msgid "This field is required" +msgstr "" + +#: profile-builder-2.0/features/functions.php:705 +#: profile-builder-2.0/front-end/extra-fields/recaptcha/recaptcha.php:374 +#: profile-builder-2.0/front-end/extra-fields/recaptcha/recaptcha.php:379 +#: profile-builder-2.0/front-end/extra-fields/recaptcha/recaptcha.php:421 +#: profile-builder-2.0/front-end/extra-fields/recaptcha/recaptcha.php:458 +msgid "Please enter a (valid) reCAPTCHA value" +msgstr "" + +#: profile-builder-2.0/features/functions.php:712 +msgid "Incorrect phone number" +msgstr "" + +#: profile-builder-2.0/features/functions.php:731 +msgid "Cancel" +msgstr "" + +#: profile-builder-2.0/features/functions.php:763 +#, php-format +msgid "" +"To allow users to register for your website via Profile Builder, you first " +"must enable user registration. Go to %1$sNetwork Settings%2$s, and under " +"Registration Settings make sure to check “User accounts may be registered”. " +"%3$sDismiss%4$s" +msgstr "" + +#: profile-builder-2.0/features/functions.php:767 +#, php-format +msgid "" +"To allow users to register for your website via Profile Builder, you first " +"must enable user registration. Go to %1$sSettings -> General%2$s tab, and " +"under Membership make sure to check “Anyone can register”. %3$sDismiss%4$s" +msgstr "" + +#: profile-builder-2.0/features/login-widget/login-widget.php:10 +msgid "This login widget lets you add a login form in the sidebar." +msgstr "" + +#: profile-builder-2.0/features/login-widget/login-widget.php:15 +msgid "Profile Builder Login Widget" +msgstr "" + +#: profile-builder-2.0/features/login-widget/login-widget.php:63 +msgid "Title:" +msgstr "" + +#: profile-builder-2.0/features/login-widget/login-widget.php:68 +msgid "After login redirect URL (optional):" +msgstr "" + +#: profile-builder-2.0/features/login-widget/login-widget.php:73 +msgid "Register page URL (optional):" +msgstr "" + +#: profile-builder-2.0/features/login-widget/login-widget.php:78 +msgid "Password Recovery page URL (optional):" +msgstr "" + +#: profile-builder-2.0/features/upgrades/upgrades-functions.php:91 +#: profile-builder-2.0/features/upgrades/upgrades-functions.php:134 +msgid "The usernames cannot be changed." +msgstr "" + +#: profile-builder-2.0/front-end/class-formbuilder.php:120 +msgid "" +"The role of the created user set to the default role. Only an administrator " +"can register a user with the role assigned to this form." +msgstr "" + +#: profile-builder-2.0/front-end/class-formbuilder.php:161 +msgid "Only an administrator can add new users." +msgstr "" + +#: profile-builder-2.0/front-end/class-formbuilder.php:171 +msgid "Users can register themselves or you can manually create users here." +msgstr "" + +#: profile-builder-2.0/front-end/class-formbuilder.php:171 +#: profile-builder-2.0/front-end/class-formbuilder.php:174 +msgid "This message is only visible by administrators" +msgstr "" + +#: profile-builder-2.0/front-end/class-formbuilder.php:174 +msgid "" +"Users cannot currently register themselves, but you can manually create " +"users here." +msgstr "" + +#: profile-builder-2.0/front-end/class-formbuilder.php:196 +#, php-format +msgid "You are currently logged in as %1s. You don't need another account. %2s" +msgstr "" + +#: profile-builder-2.0/front-end/class-formbuilder.php:196 +msgid "Log out of this account." +msgstr "" + +#: profile-builder-2.0/front-end/class-formbuilder.php:196 +msgid "Logout" +msgstr "" + +#: profile-builder-2.0/front-end/class-formbuilder.php:203 +msgid "You must be logged in to edit your profile." +msgstr "" + +#: profile-builder-2.0/front-end/class-formbuilder.php:230 +#: profile-builder-2.0/front-end/class-formbuilder.php:277 +msgid "here" +msgstr "" + +#: profile-builder-2.0/front-end/class-formbuilder.php:232 +#: profile-builder-2.0/front-end/class-formbuilder.php:277 +#, php-format +msgid "" +"You will soon be redirected automatically. If you see this page for more " +"than %1$d seconds, please click %2$s.%3$s" +msgstr "" + +#: profile-builder-2.0/front-end/class-formbuilder.php:330 +#: profile-builder-2.0/front-end/class-formbuilder.php:337 +#, php-format +msgid "The account %1s has been successfully created!" +msgstr "" + +#: profile-builder-2.0/front-end/class-formbuilder.php:333 +#: profile-builder-2.0/front-end/class-formbuilder.php:343 +#, php-format +msgid "" +"Before you can access your account %1s, you need to confirm your email " +"address. Please check your inbox and click the activation link." +msgstr "" + +#: profile-builder-2.0/front-end/class-formbuilder.php:339 +#, php-format +msgid "" +"Before you can access your account %1s, an administrator has to approve it. " +"You will be notified via email." +msgstr "" + +#: profile-builder-2.0/front-end/class-formbuilder.php:353 +msgid "Your profile has been successfully updated!" +msgstr "" + +#: profile-builder-2.0/front-end/class-formbuilder.php:363 +msgid "There was an error in the submitted form" +msgstr "" + +#: profile-builder-2.0/front-end/class-formbuilder.php:420 +msgid "Add User" +msgstr "" + +#: profile-builder-2.0/front-end/class-formbuilder.php:482 +#: profile-builder-2.0/front-end/extra-fields/extra-fields.php:47 +msgid "The avatar was successfully deleted!" +msgstr "" + +#: profile-builder-2.0/front-end/class-formbuilder.php:482 +#: profile-builder-2.0/front-end/extra-fields/extra-fields.php:49 +msgid "The following attachment was successfully deleted:" +msgstr "" + +#: profile-builder-2.0/front-end/class-formbuilder.php:494 +msgid "Send these credentials via email." +msgstr "" + +#: profile-builder-2.0/front-end/class-formbuilder.php:681 +msgid "User to edit:" +msgstr "" + +#: profile-builder-2.0/front-end/default-fields/email/email.php:51 +msgid "You must enter a valid email address." +msgstr "" + +#: profile-builder-2.0/front-end/default-fields/email/email.php:60 +#: profile-builder-2.0/front-end/default-fields/email/email.php:67 +msgid "This email is already reserved to be used soon." +msgstr "" + +#: profile-builder-2.0/front-end/default-fields/email/email.php:60 +#: profile-builder-2.0/front-end/default-fields/email/email.php:67 +#: profile-builder-2.0/front-end/default-fields/email/email.php:77 +#: profile-builder-2.0/front-end/default-fields/email/email.php:95 +#: profile-builder-2.0/front-end/default-fields/username/username.php:49 +#: profile-builder-2.0/front-end/default-fields/username/username.php:65 +msgid "Please try a different one!" +msgstr "" + +#: profile-builder-2.0/front-end/default-fields/email/email.php:77 +#: profile-builder-2.0/front-end/default-fields/email/email.php:95 +msgid "This email is already in use." +msgstr "" + +#: profile-builder-2.0/front-end/default-fields/password-repeat/password-repeat.php:37 +#: profile-builder-2.0/front-end/default-fields/password-repeat/password-repeat.php:41 +msgid "The passwords do not match" +msgstr "" + +#: profile-builder-2.0/front-end/default-fields/password/password.php:46 +#: profile-builder-2.0/front-end/recover.php:251 +#, php-format +msgid "The password must have the minimum length of %s characters" +msgstr "" + +#: profile-builder-2.0/front-end/default-fields/password/password.php:50 +#: profile-builder-2.0/front-end/recover.php:255 +#, php-format +msgid "The password must have a minimum strength of %s" +msgstr "" + +#: profile-builder-2.0/front-end/default-fields/username/username.php:49 +msgid "This username already exists." +msgstr "" + +#: profile-builder-2.0/front-end/default-fields/username/username.php:52 +#: profile-builder-2.0/front-end/default-fields/username/username.php:60 +msgid "This username is invalid because it uses illegal characters." +msgstr "" + +#: profile-builder-2.0/front-end/default-fields/username/username.php:52 +#: profile-builder-2.0/front-end/default-fields/username/username.php:60 +msgid "Please enter a valid username." +msgstr "" + +#: profile-builder-2.0/front-end/default-fields/username/username.php:65 +msgid "This username is already reserved to be used soon." +msgstr "" + +#: profile-builder-2.0/front-end/extra-fields/avatar/avatar.php:72 +#: profile-builder-2.0/front-end/extra-fields/checkbox/checkbox.php:45 +#: profile-builder-2.0/front-end/extra-fields/colorpicker/colorpicker.php:45 +#: profile-builder-2.0/front-end/extra-fields/datepicker/datepicker.php:40 +#: profile-builder-2.0/front-end/extra-fields/input-hidden/input-hidden.php:34 +#: profile-builder-2.0/front-end/extra-fields/input/input.php:30 +#: profile-builder-2.0/front-end/extra-fields/map/map.php:51 +#: profile-builder-2.0/front-end/extra-fields/number/number.php:30 +#: profile-builder-2.0/front-end/extra-fields/phone/phone.php:39 +#: profile-builder-2.0/front-end/extra-fields/radio/radio.php:44 +#: profile-builder-2.0/front-end/extra-fields/select-cpt/select-cpt.php:46 +#: profile-builder-2.0/front-end/extra-fields/select-multiple/select-multiple.php:46 +#: profile-builder-2.0/front-end/extra-fields/select-timezone/select-timezone.php:49 +#: profile-builder-2.0/front-end/extra-fields/select/select.php:51 +#: profile-builder-2.0/front-end/extra-fields/textarea/textarea.php:30 +#: profile-builder-2.0/front-end/extra-fields/upload/upload.php:70 +#: profile-builder-2.0/front-end/extra-fields/wysiwyg/wysiwyg.php:33 +msgid "required" +msgstr "" + +#: profile-builder-2.0/front-end/extra-fields/extra-fields.php:111 +#: profile-builder-2.0/front-end/login.php:137 +#: profile-builder-2.0/front-end/login.php:144 +#: profile-builder-2.0/front-end/login.php:158 +#: profile-builder-2.0/front-end/recover.php:17 +#: profile-builder-2.0/front-end/recover.php:234 +msgid "ERROR" +msgstr "" + +#: profile-builder-2.0/front-end/extra-fields/map/map.php:46 +#: profile-builder-2.0/front-end/extra-fields/map/map.php:69 +msgid "Please add the Google Maps API key for this field." +msgstr "" + +#: profile-builder-2.0/front-end/extra-fields/map/map.php:134 +msgid "Something went wrong. Please try again." +msgstr "" + +#: profile-builder-2.0/front-end/extra-fields/number/number.php:69 +msgid "Please enter numbers only" +msgstr "" + +#: profile-builder-2.0/front-end/extra-fields/number/number.php:73 +#, php-format +msgid "Value must be a multiplier of %1$s" +msgstr "" + +#: profile-builder-2.0/front-end/extra-fields/number/number.php:77 +#, php-format +msgid "Value must be greater than or equal to %1$s" +msgstr "" + +#: profile-builder-2.0/front-end/extra-fields/number/number.php:81 +#, php-format +msgid "Value must be less than or equal to %1$s" +msgstr "" + +#: profile-builder-2.0/front-end/extra-fields/phone/phone.php:22 +msgid "Required phone number format: " +msgstr "" + +#: profile-builder-2.0/front-end/extra-fields/recaptcha/recaptcha.php:48 +msgid "To use reCAPTCHA you must get an API key from" +msgstr "" + +#: profile-builder-2.0/front-end/extra-fields/recaptcha/recaptcha.php:131 +msgid "For security reasons, you must pass the remote ip to reCAPTCHA!" +msgstr "" + +#: profile-builder-2.0/front-end/extra-fields/recaptcha/recaptcha.php:192 +msgid "To use reCAPTCHA you must get an API public key from:" +msgstr "" + +#: profile-builder-2.0/front-end/extra-fields/recaptcha/recaptcha.php:421 +msgid "Click the BACK button on your browser, and try again." +msgstr "" + +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Bolivia, __( Plurinational State of" +msgstr "" + +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Bonaire, __( Sint Eustatius and Saba" +msgstr "" + +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Brunei Darussalam" +msgstr "" + +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Cabo Verde" +msgstr "" + +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Cocos (Keeling) Islands" +msgstr "" + +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Congo" +msgstr "" + +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Congo, __( the Democratic Republic of the" +msgstr "" + +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Cote dIvoire" +msgstr "" + +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Falkland Islands (Malvinas)" +msgstr "" + +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Holy See (Vatican City State)" +msgstr "" + +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Iran, __( Islamic Republic of" +msgstr "" + +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Korea, __( Democratic Peoples Republic of" +msgstr "" + +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Korea, __( Republic of" +msgstr "" + +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Lao Peoples Democratic Republic" +msgstr "" + +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Macedonia, __( the former Yugoslav Republic of" +msgstr "" + +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Micronesia, __( Federated States of" +msgstr "" + +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Moldova, __( Republic of" +msgstr "" + +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Palestine, __( State of" +msgstr "" + +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Russian Federation" +msgstr "" + +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Saint Helena, __( Ascension and Tristan da Cunha" +msgstr "" + +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Saint Martin (French part)" +msgstr "" + +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Sint Maarten (Dutch part)" +msgstr "" + +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Syrian Arab Republic" +msgstr "" + +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Taiwan, __( Province of China" +msgstr "" + +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Tanzania, __( United Republic of" +msgstr "" + +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Timor-Leste" +msgstr "" + +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Venezuela, __( Bolivarian Republic of" +msgstr "" + +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Viet Nam" +msgstr "" + +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Virgin Islands, __( British" +msgstr "" + +#: profile-builder-2.0/front-end/extra-fields/select-country/select-country.php:10 +msgid "Virgin Islands, __( U.S." +msgstr "" + +#: profile-builder-2.0/front-end/extra-fields/upload/upload_helper_functions.php:78 +#: profile-builder-2.0/front-end/extra-fields/upload/upload_helper_functions.php:87 +msgid "Sorry, you cannot upload this file type for this field." +msgstr "" + +#: profile-builder-2.0/front-end/extra-fields/upload/upload_helper_functions.php:94 +msgid "An error occurred, please try again later." +msgstr "" + +#: profile-builder-2.0/front-end/extra-fields/user-role/user-role.php:72 +#: profile-builder-2.0/front-end/extra-fields/user-role/user-role.php:85 +msgid "Only administrators can see this field on edit profile forms." +msgstr "" + +#: profile-builder-2.0/front-end/extra-fields/user-role/user-role.php:81 +msgid "As an administrator you cannot change your role." +msgstr "" + +#: profile-builder-2.0/front-end/extra-fields/user-role/user-role.php:118 +msgid "You cannot register this user role" +msgstr "" + +#: profile-builder-2.0/front-end/login.php:137 +msgid "The password you entered is incorrect." +msgstr "" + +#: profile-builder-2.0/front-end/login.php:138 +#: profile-builder-2.0/front-end/login.php:145 +msgid "Password Lost and Found." +msgstr "" + +#: profile-builder-2.0/front-end/login.php:138 +#: profile-builder-2.0/front-end/login.php:145 +msgid "Lost your password" +msgstr "" + +#: profile-builder-2.0/front-end/login.php:144 +msgid "Invalid username." +msgstr "" + +#: profile-builder-2.0/front-end/login.php:149 +#: profile-builder-2.0/front-end/login.php:153 +msgid "username" +msgstr "" + +#: profile-builder-2.0/front-end/login.php:149 +msgid "email" +msgstr "" + +#: profile-builder-2.0/front-end/login.php:153 +msgid "username or email" +msgstr "" + +#: profile-builder-2.0/front-end/login.php:158 +msgid "Both fields are empty." +msgstr "" + +#: profile-builder-2.0/front-end/login.php:229 +msgid "Username or Email" +msgstr "" + +#: profile-builder-2.0/front-end/login.php:263 +msgid "Lost your password?" +msgstr "" + +#: profile-builder-2.0/front-end/login.php:307 +#: profile-builder-2.0/front-end/logout.php:29 +msgid "Log out of this account" +msgstr "" + +#: profile-builder-2.0/front-end/login.php:307 +msgid "Log out" +msgstr "" + +#: profile-builder-2.0/front-end/login.php:308 +#, php-format +msgid "You are currently logged in as %1$s. %2$s" +msgstr "" + +#: profile-builder-2.0/front-end/logout.php:15 +#, php-format +msgid "You are currently logged in as %s. " +msgstr "" + +#: profile-builder-2.0/front-end/logout.php:15 +msgid "Log out »" +msgstr "" + +#: profile-builder-2.0/front-end/recover.php:17 +msgid "" +"Your account has to be confirmed by an administrator before you can use the " +"\"Password Reset\" feature." +msgstr "" + +#: profile-builder-2.0/front-end/recover.php:94 +msgid "Reset Password" +msgstr "" + +#: profile-builder-2.0/front-end/recover.php:114 +msgid "Please enter your username or email address." +msgstr "" + +#: profile-builder-2.0/front-end/recover.php:115 +msgid "You will receive a link to create a new password via email." +msgstr "" + +#: profile-builder-2.0/front-end/recover.php:120 +msgid "Username or E-mail" +msgstr "" + +#: profile-builder-2.0/front-end/recover.php:130 +msgid "Get New Password" +msgstr "" + +#: profile-builder-2.0/front-end/recover.php:172 +msgid "The username entered wasn't found in the database!" +msgstr "" + +#: profile-builder-2.0/front-end/recover.php:172 +msgid "Please check that you entered the correct username." +msgstr "" + +#: profile-builder-2.0/front-end/recover.php:187 +msgid "Check your e-mail for the confirmation link." +msgstr "" + +#: profile-builder-2.0/front-end/recover.php:194 +msgid "The email address entered wasn't found in the database!" +msgstr "" + +#: profile-builder-2.0/front-end/recover.php:194 +msgid "Please check that you entered the correct email address." +msgstr "" + +#: profile-builder-2.0/front-end/recover.php:222 +#, php-format +msgid "" +"Someone requested that the password be reset for the following account: " +"%1$s
            If this was a mistake, just ignore this email and nothing will " +"happen.
            To reset your password, visit the following link:%2$s" +msgstr "" + +#: profile-builder-2.0/front-end/recover.php:225 +#, php-format +msgid "Password Reset from \"%1$s\"" +msgstr "" + +#: profile-builder-2.0/front-end/recover.php:234 +#, php-format +msgid "There was an error while trying to send the activation link to %1$s!" +msgstr "" + +#: profile-builder-2.0/front-end/recover.php:262 +msgid "Your password has been successfully changed!" +msgstr "" + +#: profile-builder-2.0/front-end/recover.php:281 +#, php-format +msgid "You have successfully reset your password to: %1$s" +msgstr "" + +#: profile-builder-2.0/front-end/recover.php:284 +#: profile-builder-2.0/front-end/recover.php:298 +#, php-format +msgid "Password Successfully Reset for %1$s on \"%2$s\"" +msgstr "" + +#: profile-builder-2.0/front-end/recover.php:295 +#, php-format +msgid "" +"%1$s has requested a password change via the password reset feature.
            His/" +"her new password is:%2$s" +msgstr "" + +#: profile-builder-2.0/front-end/recover.php:314 +msgid "The entered passwords don't match!" +msgstr "" + +#: profile-builder-2.0/front-end/recover.php:381 +msgid "ERROR:" +msgstr "" + +#: profile-builder-2.0/front-end/recover.php:381 +msgid "Invalid key!" +msgstr "" + +#: profile-builder-2.0/front-end/register.php:55 +msgid "Invalid activation key!" +msgstr "" + +#: profile-builder-2.0/front-end/register.php:59 +msgid "This username is now active!" +msgstr "" + +#: profile-builder-2.0/front-end/register.php:73 +msgid "This username is already activated!" +msgstr "" + +#: profile-builder-2.0/front-end/register.php:129 +msgid "Your email was successfully confirmed." +msgstr "" + +#: profile-builder-2.0/front-end/register.php:133 +msgid "You will soon be redirected automatically." +msgstr "" + +#: profile-builder-2.0/front-end/register.php:163 +msgid "There was an error while trying to activate the user." +msgstr "" + +#: profile-builder-2.0/index.php:34 +msgid "" +" is also activated. You need to deactivate it before activating this version " +"of the plugin." +msgstr "" + +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:45 +msgid "After Login" +msgstr "" + +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:46 +msgid "After Logout" +msgstr "" + +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:47 +msgid "After Registration" +msgstr "" + +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:48 +msgid "After Edit Profile" +msgstr "" + +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:49 +msgid "After Successful Email Confirmation" +msgstr "" + +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:50 +msgid "After Successful Password Reset" +msgstr "" + +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:51 +msgid "Dashboard (redirect users from accessing the dashboard)" +msgstr "" + +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:55 +msgid "User ID" +msgstr "" + +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:61 +msgid "User ID or Username" +msgstr "" + +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:62 +msgid "User ID / Username" +msgstr "" + +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:62 +msgid "Please select and enter the ID or username of your user." +msgstr "" + +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:63 +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:93 +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:112 +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:131 +msgid "Redirect Type" +msgstr "" + +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:64 +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:94 +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:113 +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:138 +msgid "Redirect URL" +msgstr "" + +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:64 +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:94 +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:113 +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:138 +msgid "" +"Can contain the following dynamic tags:{{homeurl}}, {{siteurl}}, " +"{{user_id}}, {{user_nicename}}, {{http_referer}}" +msgstr "" + +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:71 +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:240 +msgid "Individual User Redirects" +msgstr "" + +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:84 +msgid "... Choose" +msgstr "" + +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:92 +#: profile-builder-2.0/modules/email-customizer/email-customizer.php:31 +msgid "User Role" +msgstr "" + +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:92 +msgid "Select a user role." +msgstr "" + +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:101 +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:241 +msgid "User Role based Redirects" +msgstr "" + +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:120 +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:242 +msgid "Global Redirects" +msgstr "" + +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:133 +msgid "Login ( wp_login.php )" +msgstr "" + +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:134 +msgid "Register ( wp-login.php?action=register )" +msgstr "" + +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:135 +msgid "Lost Password ( wp-login.php?action=lostpassword )" +msgstr "" + +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:136 +msgid "Author Archive ( http://sitename.com/author/admin )" +msgstr "" + +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:145 +msgid "Redirect Default WordPress Forms and Pages" +msgstr "" + +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:157 +msgid "How does this work?" +msgstr "" + +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:179 +msgid "
            User ID / Username
            Redirect
            URL
            " +msgstr "" + +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:193 +msgid "
            User Role
            Redirect
            URL
            " +msgstr "" + +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:207 +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:221 +msgid "
            Redirect
            URL
            " +msgstr "" + +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:236 +msgid "" +"These redirects happen after a successful action, like registration or after " +"a successful login." +msgstr "" + +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:238 +msgid "Which redirect happens depends on the following priority:" +msgstr "" + +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:243 +msgid "" +"Individual redirects defined in shortcodes or in the Multiple Registration " +"and Edit Profile form settings. (redirect_priority=\"top\" parameter can be added in any shortcode, then that shortcode " +"redirect will have priority over all other redirects)" +msgstr "" + +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:246 +msgid "Redirect Default WordPress forms and pages" +msgstr "" + +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:247 +msgid "" +"With these you can redirect various WordPress forms and pages to pages " +"created with profile builder." +msgstr "" + +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:249 +msgid "Available tags for dynamic URLs" +msgstr "" + +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:250 +msgid "" +"You use the following tags in your URLs to redirect users to various pages." +msgstr "" + +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:252 +msgid "generates a url of the current website homepage." +msgstr "" + +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:253 +msgid "" +"in WordPress the
            site url can be different then the home url" +msgstr "" + +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:254 +msgid "the ID of the user" +msgstr "" + +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:255 +msgid "" +"the URL sanitized version of the username, the user nicename can be safely " +"used in URLs since it can't contain special characters or spaces." +msgstr "" + +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:256 +msgid "the URL of the previously visited page" +msgstr "" + +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:339 +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:345 +#: profile-builder-2.0/modules/custom-redirects/custom_redirects_admin.php:351 +msgid "You can't add duplicate redirects!" +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/admin-email-customizer.php:11 +#: profile-builder-2.0/modules/email-customizer/admin-email-customizer.php:12 +#: profile-builder-2.0/modules/modules.php:96 +msgid "Admin Email Customizer" +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/admin-email-customizer.php:38 +msgid "" +"These settings are also replicated in the \"User Email Customizer\" settings-" +"page upon save." +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/admin-email-customizer.php:38 +#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:38 +msgid "Valid tags {{reply_to}} and {{site_name}}" +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/admin-email-customizer.php:41 +#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:41 +msgid "From (name)" +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/admin-email-customizer.php:49 +#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:49 +msgid "From (reply-to email)" +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/admin-email-customizer.php:54 +#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:54 +msgid "" +"Must be a valid email address or the tag {{reply_to}} which defaults to the " +"administrator email" +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/admin-email-customizer.php:57 +#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:57 +msgid "Common Settings" +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/admin-email-customizer.php:60 +msgid "" +"\n" +"

            New subscriber on {{site_name}}.

            \n" +"

            Username:{{username}}

            \n" +"

            E-mail:{{user_email}}

            \n" +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/admin-email-customizer.php:69 +#: profile-builder-2.0/modules/email-customizer/admin-email-customizer.php:99 +#: profile-builder-2.0/modules/email-customizer/admin-email-customizer.php:126 +#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:71 +#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:99 +#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:128 +#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:155 +#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:183 +#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:214 +#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:241 +#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:274 +msgid "Email Subject" +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/admin-email-customizer.php:84 +msgid "Default Registration & Registration with Email Confirmation" +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/admin-email-customizer.php:87 +msgid "" +"\n" +"

            New subscriber on {{site_name}}.

            \n" +"

            Username:{{username}}

            \n" +"

            E-mail:{{user_email}}

            \n" +"

            The Admin Approval feature was activated at the time of registration,\n" +"so please remember that you need to approve this user before he/she can log " +"in!

            \n" +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/admin-email-customizer.php:114 +#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:143 +msgid "Registration with Admin Approval" +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/admin-email-customizer.php:117 +msgid "" +"\n" +"

            {{username}} has requested a password change via the password reset " +"feature.

            \n" +"

            His/her new password is: {{password}}

            \n" +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/admin-email-customizer.php:141 +msgid "Admin Notification for User Password Reset" +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/email-customizer.php:7 +msgid "Available Tags" +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/email-customizer.php:11 +#: profile-builder-2.0/modules/user-listing/userlisting.php:179 +msgid "User Fields Tags" +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/email-customizer.php:21 +msgid "Site Url" +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/email-customizer.php:22 +msgid "Site Name" +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/email-customizer.php:25 +#: profile-builder-2.0/modules/user-listing/userlisting.php:151 +msgid "User Id" +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/email-customizer.php:33 +msgid "Reply To" +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/email-customizer.php:36 +msgid "Activation Key" +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/email-customizer.php:37 +msgid "Activation Url" +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/email-customizer.php:38 +msgid "Activation Link" +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/email-customizer.php:42 +msgid "Reset Key" +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/email-customizer.php:43 +msgid "Reset Url" +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/email-customizer.php:44 +msgid "Reset Link" +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/email-customizer.php:462 +msgid "The users selected password at signup" +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:11 +#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:12 +#: profile-builder-2.0/modules/modules.php:103 +msgid "User Email Customizer" +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:38 +msgid "" +"These settings are also replicated in the \"Admin Email Customizer\" " +"settings-page upon save." +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:64 +msgid "" +"\n" +"

            Welcome to {{site_name}}!

            \n" +"

            Your username is:{{username}} and password:{{password}}

            \n" +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:85 +msgid "Default Registration" +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:91 +msgid "" +"\n" +"

            To activate your user, please click the following link:
            \n" +"{{{activation_link}}}

            \n" +"

            After you activate, you will receive another email with your credentials." +"

            \n" +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:103 +msgid "[{{site_name}}] Activate {{username}}" +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:114 +msgid "Registration with Email Confirmation" +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:120 +msgid "" +"\n" +"

            Welcome to {{site_name}}!

            \n" +"

            Your username is:{{username}} and password:{{password}}

            \n" +"

            Before you can access your account, an administrator needs to approve it. " +"You will be notified via email.

            \n" +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:132 +msgid "A new account has been created for you on {{site_name}}" +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:148 +msgid "" +"\n" +"

            Good News!

            \n" +"

            An administrator has just approved your account: {{username}} on " +"{{site_name}}.

            \n" +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:159 +msgid "Your account on {{site_name}} has been approved!" +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:170 +msgid "User Approval Notification" +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:175 +msgid "" +"\n" +"

            Hello,

            \n" +"

            Unfortunatelly an administrator has just unapproved your account: " +"{{username}} on {{site_name}}.

            \n" +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:187 +msgid "Your account on {{site_name}} has been unapproved!" +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:198 +msgid "Unapproved User Notification" +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:204 +msgid "" +"\n" +"

            Someone requested that the password be reset for the following account: " +"{{site_name}}
            \n" +"Username: {{username}}

            \n" +"

            If this was a mistake, just ignore this email and nothing will happen.\n" +"

            To reset your password, visit the following address:
            \n" +"{{{reset_link}}}

            \n" +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:218 +msgid "[{{site_name}}] Password Reset" +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:229 +msgid "Password Reset Email" +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:235 +msgid "" +"\n" +"

            You have successfully reset your password to: {{password}}

            \n" +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:245 +msgid "[{{site_name}}] Password Reset Successfully" +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:256 +msgid "Password Reset Success Email" +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:278 +msgid "[{{site_name}}] Notice of Email Change" +msgstr "" + +#: profile-builder-2.0/modules/email-customizer/user-email-customizer.php:289 +msgid "Changed Email Address Notification" +msgstr "" + +#: profile-builder-2.0/modules/modules.php:11 +#: profile-builder-2.0/modules/modules.php:58 +msgid "Modules" +msgstr "" + +#: profile-builder-2.0/modules/modules.php:59 +msgid "" +"Here you can activate / deactivate available modules for Profile Builder." +msgstr "" + +#: profile-builder-2.0/modules/modules.php:69 +msgid "Name/Description" +msgstr "" + +#: profile-builder-2.0/modules/modules.php:70 +msgid "Status" +msgstr "" + +#: profile-builder-2.0/modules/modules.php:77 +#: profile-builder-2.0/modules/modules.php:84 +#: profile-builder-2.0/modules/modules.php:91 +#: profile-builder-2.0/modules/modules.php:98 +#: profile-builder-2.0/modules/modules.php:105 +#: profile-builder-2.0/modules/modules.php:112 +#: profile-builder-2.0/modules/modules.php:119 +msgid "Active" +msgstr "" + +#: profile-builder-2.0/modules/modules.php:78 +#: profile-builder-2.0/modules/modules.php:85 +#: profile-builder-2.0/modules/modules.php:92 +#: profile-builder-2.0/modules/modules.php:99 +#: profile-builder-2.0/modules/modules.php:106 +#: profile-builder-2.0/modules/modules.php:113 +#: profile-builder-2.0/modules/modules.php:120 +msgid "Inactive" +msgstr "" + +#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:11 +#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:12 +msgid "Edit-profile Form" +msgstr "" + +#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:13 +#: profile-builder-2.0/modules/multiple-forms/register-forms.php:13 +#: profile-builder-2.0/modules/user-listing/userlisting.php:13 +msgid "Add New" +msgstr "" + +#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:14 +msgid "Add new Edit-profile Form" +msgstr "" + +#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:15 +msgid "Edit the Edit-profile Forms" +msgstr "" + +#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:16 +msgid "New Edit-profile Form" +msgstr "" + +#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:17 +#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:23 +msgid "Edit-profile Forms" +msgstr "" + +#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:18 +msgid "View the Edit-profile Form" +msgstr "" + +#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:19 +msgid "Search the Edit-profile Forms" +msgstr "" + +#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:20 +msgid "No Edit-profile Form found" +msgstr "" + +#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:21 +msgid "No Edit-profile Forms found in trash" +msgstr "" + +#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:135 +#: profile-builder-2.0/modules/multiple-forms/register-forms.php:138 +#: profile-builder-2.0/modules/user-listing/userlisting.php:1994 +msgid "Shortcode" +msgstr "" + +#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:155 +#: profile-builder-2.0/modules/multiple-forms/register-forms.php:159 +#: profile-builder-2.0/modules/user-listing/userlisting.php:2015 +msgid "(no title)" +msgstr "" + +#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:175 +#: profile-builder-2.0/modules/multiple-forms/register-forms.php:178 +#: profile-builder-2.0/modules/user-listing/userlisting.php:2035 +msgid "The shortcode will be available after you publish this form." +msgstr "" + +#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:177 +#: profile-builder-2.0/modules/multiple-forms/register-forms.php:180 +#: profile-builder-2.0/modules/user-listing/userlisting.php:2037 +msgid "Use this shortcode on the page you want the form to be displayed:" +msgstr "" + +#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:181 +#: profile-builder-2.0/modules/multiple-forms/register-forms.php:184 +#: profile-builder-2.0/modules/user-listing/userlisting.php:2041 +msgid "" +"Note: changing the form title also changes " +"the shortcode!" +msgstr "" + +#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:187 +#: profile-builder-2.0/modules/multiple-forms/register-forms.php:190 +#: profile-builder-2.0/modules/user-listing/userlisting.php:2074 +msgid "Form Shortcode" +msgstr "" + +#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:206 +#: profile-builder-2.0/modules/multiple-forms/register-forms.php:230 +msgid "Redirect" +msgstr "" + +#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:206 +#: profile-builder-2.0/modules/multiple-forms/register-forms.php:230 +msgid "Whether to redirect the user to a specific page or not" +msgstr "" + +#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:207 +#: profile-builder-2.0/modules/multiple-forms/register-forms.php:231 +msgid "Display Messages" +msgstr "" + +#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:207 +#: profile-builder-2.0/modules/multiple-forms/register-forms.php:231 +msgid "Allowed time to display any success messages (in seconds)" +msgstr "" + +#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:208 +#: profile-builder-2.0/modules/multiple-forms/register-forms.php:232 +msgid "URL" +msgstr "" + +#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:208 +msgid "" +"Specify the URL of the page users will be redirected once they updated their " +"profile using this form
            Use the following format: http://www.mysite.com" +msgstr "" + +#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:215 +msgid "After Profile Update..." +msgstr "" + +#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:241 +#: profile-builder-2.0/modules/multiple-forms/register-forms.php:262 +msgid "Add New Field to the List" +msgstr "" + +#: profile-builder-2.0/modules/multiple-forms/edit-profile-forms.php:245 +#: profile-builder-2.0/modules/multiple-forms/register-forms.php:266 +msgid "Choose one of the supported fields you manage Title (Type)" +msgstr "" + +#: profile-builder-2.0/modules/multiple-forms/multiple-forms.php:406 +msgid "Delete all items" +msgstr "" + +#: profile-builder-2.0/modules/multiple-forms/multiple-forms.php:406 +msgid "Delete all" +msgstr "" + +#: profile-builder-2.0/modules/multiple-forms/register-forms.php:11 +#: profile-builder-2.0/modules/multiple-forms/register-forms.php:12 +msgid "Registration Form" +msgstr "" + +#: profile-builder-2.0/modules/multiple-forms/register-forms.php:14 +msgid "Add new Registration Form" +msgstr "" + +#: profile-builder-2.0/modules/multiple-forms/register-forms.php:15 +msgid "Edit the Registration Forms" +msgstr "" + +#: profile-builder-2.0/modules/multiple-forms/register-forms.php:16 +msgid "New Registration Form" +msgstr "" + +#: profile-builder-2.0/modules/multiple-forms/register-forms.php:17 +#: profile-builder-2.0/modules/multiple-forms/register-forms.php:23 +msgid "Registration Forms" +msgstr "" + +#: profile-builder-2.0/modules/multiple-forms/register-forms.php:18 +msgid "View the Registration Form" +msgstr "" + +#: profile-builder-2.0/modules/multiple-forms/register-forms.php:19 +msgid "Search the Registration Forms" +msgstr "" + +#: profile-builder-2.0/modules/multiple-forms/register-forms.php:20 +msgid "No Registration Form found" +msgstr "" + +#: profile-builder-2.0/modules/multiple-forms/register-forms.php:21 +msgid "No Registration Forms found in trash" +msgstr "" + +#: profile-builder-2.0/modules/multiple-forms/register-forms.php:219 +msgid "Default Role" +msgstr "" + +#: profile-builder-2.0/modules/multiple-forms/register-forms.php:228 +msgid "Set Role" +msgstr "" + +#: profile-builder-2.0/modules/multiple-forms/register-forms.php:228 +msgid "" +"Choose what role the user will have after (s)he registered
            If not " +"specified, defaults to the role set in the WordPress settings" +msgstr "" + +#: profile-builder-2.0/modules/multiple-forms/register-forms.php:229 +msgid "Automatically Log In" +msgstr "" + +#: profile-builder-2.0/modules/multiple-forms/register-forms.php:229 +msgid "" +"Whether to automatically log in the newly registered user or not
            Only " +"works on single-sites without \"Admin Approval\" and \"Email Confirmation\" " +"features activated
            WARNING: Caching the registration form will make " +"automatic login not work" +msgstr "" + +#: profile-builder-2.0/modules/multiple-forms/register-forms.php:230 +#: profile-builder-2.0/modules/user-listing/userlisting.php:1551 +msgid "Choose..." +msgstr "" + +#: profile-builder-2.0/modules/multiple-forms/register-forms.php:232 +msgid "" +"Specify the URL of the page users will be redirected once registered using " +"this form
            Use the following format: http://www.mysite.com" +msgstr "" + +#: profile-builder-2.0/modules/multiple-forms/register-forms.php:238 +msgid "After Registration..." +msgstr "" + +#: profile-builder-2.0/modules/repeater-field/admin/repeater-manage-fields.php:189 +msgid "Limit" +msgstr "" + +#: profile-builder-2.0/modules/repeater-field/admin/repeater-manage-fields.php:189 +msgid "" +"Enable limit to the number of fields to be generated by users in front end " +"forms " +msgstr "" + +#: profile-builder-2.0/modules/repeater-field/admin/repeater-manage-fields.php:190 +msgid "General Limit" +msgstr "" + +#: profile-builder-2.0/modules/repeater-field/admin/repeater-manage-fields.php:190 +msgid "Default limit for this repeater group.
            Leave 0 for unlimited." +msgstr "" + +#: profile-builder-2.0/modules/repeater-field/admin/repeater-manage-fields.php:191 +msgid "Limit reached message" +msgstr "" + +#: profile-builder-2.0/modules/repeater-field/admin/repeater-manage-fields.php:191 +msgid "The maximum number of fields has been reached." +msgstr "" + +#: profile-builder-2.0/modules/repeater-field/admin/repeater-manage-fields.php:191 +msgid "" +"The popup message to display when the limit of repeater groups is reached." +msgstr "" + +#: profile-builder-2.0/modules/repeater-field/admin/repeater-manage-fields.php:192 +msgid "Limit per Role" +msgstr "" + +#: profile-builder-2.0/modules/repeater-field/admin/repeater-manage-fields.php:192 +msgid "Leave 0 for unlimited." +msgstr "" + +#: profile-builder-2.0/modules/repeater-field/admin/repeater-manage-fields.php:193 +msgid "Repeated field group" +msgstr "" + +#: profile-builder-2.0/modules/repeater-field/admin/repeater-manage-fields.php:193 +msgid "Manage field or group of fields that will be repeatable." +msgstr "" + +#: profile-builder-2.0/modules/repeater-field/admin/repeater-manage-fields.php:258 +msgid "Edit field group" +msgstr "" + +#: profile-builder-2.0/modules/repeater-field/admin/repeater-manage-fields.php:259 +msgid "Repeatable fields saved!" +msgstr "" + +#: profile-builder-2.0/modules/repeater-field/admin/repeater-manage-fields.php:276 +#: profile-builder-2.0/modules/repeater-field/admin/repeater-manage-fields.php:325 +msgid "Please enter a unique field title.\n" +msgstr "" + +#: profile-builder-2.0/modules/repeater-field/repeater-field.php:258 +msgid "Are you sure you want to delete this?" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:14 +msgid "Add new User Listing" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:15 +msgid "Edit the User Listing" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:16 +msgid "New User Listing" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:18 +msgid "View the User Listing" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:19 +msgid "Search the User Listing" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:20 +msgid "No User Listing found" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:21 +msgid "No User Listing found in trash" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:104 +msgid "Display name as" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:143 +#: profile-builder-2.0/modules/user-listing/userlisting.php:2102 +msgid "Registration Date" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:144 +#: profile-builder-2.0/modules/user-listing/userlisting.php:2107 +msgid "Number of Posts" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:148 +msgid "More Info" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:149 +msgid "More Info Url" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:150 +msgid "Avatar or Gravatar" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:152 +msgid "User Nicename" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:185 +msgid "Sort Tags" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:189 +#: profile-builder-2.0/modules/user-listing/userlisting.php:218 +msgid "Extra Functions" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:191 +msgid "Pagination" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:192 +msgid "Search all Fields" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:193 +#: profile-builder-2.0/modules/user-listing/userlisting.php:2178 +msgid "Faceted Menus" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:194 +msgid "User Count" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:220 +msgid "Go Back Link" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:238 +msgid "All-userlisting Template" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:241 +msgid "Single-userlisting Template" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:267 +msgid "Avatar" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:271 +#: profile-builder-2.0/modules/user-listing/userlisting.php:731 +msgid "Posts" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:272 +#: profile-builder-2.0/modules/user-listing/userlisting.php:713 +msgid "Sign-up Date" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:273 +msgid "More" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:367 +msgid "You do not have permission to view this user list." +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:380 +msgid "You do not have the required user role to view this user list." +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:404 +msgid "User not found" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:707 +msgid "First/Lastname" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:722 +#: profile-builder-2.0/modules/user-listing/userlisting.php:2105 +msgid "Display Name" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:734 +#: profile-builder-2.0/modules/user-listing/userlisting.php:2112 +msgid "Aim" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:737 +#: profile-builder-2.0/modules/user-listing/userlisting.php:2113 +msgid "Yim" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:740 +#: profile-builder-2.0/modules/user-listing/userlisting.php:2114 +msgid "Jabber" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:987 +#: profile-builder-2.0/modules/user-listing/userlisting.php:1429 +#: profile-builder-2.0/modules/user-listing/userlisting.php:1832 +#: profile-builder-2.0/modules/user-listing/userlisting.php:2294 +msgid "Search Users by All Fields" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:1239 +msgid "Click here to see more information about this user" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:1239 +msgid "More..." +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:1242 +msgid "Click here to see more information about this user." +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:1269 +msgid "View Map" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:1383 +#: profile-builder-2.0/modules/user-listing/userlisting.php:1386 +msgid "Click here to go back" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:1383 +msgid "Back" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:1416 +msgid "«« First" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:1417 +msgid "« Prev" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:1418 +msgid "Next » " +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:1419 +msgid "Last »»" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:1448 +msgid "You don't have any pagination settings on this userlisting!" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:1495 +msgid "Show All" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:1538 +#: profile-builder-2.0/modules/user-listing/userlisting.php:1560 +#: profile-builder-2.0/modules/user-listing/userlisting.php:1613 +msgid "No options available" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:1753 +msgid "Remove All Filters" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:1849 +msgid "Search" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:1850 +msgid "Clear Results" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:2044 +#: profile-builder-2.0/modules/user-listing/userlisting.php:2048 +msgid "Extra shortcode parameters" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:2046 +msgid "View all extra shortcode parameters" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:2051 +msgid "" +"displays users having a certain meta-value within a certain (extra) meta-" +"field" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:2052 +msgid "Example:" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:2054 +msgid "" +"Remember though, that the field-value combination must exist in the database." +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:2060 +msgid "displays only the users that you specified the user_id for" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:2066 +msgid "displays all users except the ones you specified the user_id for" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:2124 +msgid "Random (very slow on large databases > 10K user)" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:2127 +msgid "Ascending" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:2128 +msgid "Descending" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:2136 +msgid "Roles to Display" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:2136 +msgid "" +"Restrict the userlisting to these selected roles only
            If not specified, " +"defaults to all existing roles" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:2137 +msgid "Number of Users/Page" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:2137 +msgid "" +"Set the number of users to be displayed on every paginated part of the all-" +"userlisting" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:2138 +msgid "Default Sorting Criteria" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:2138 +msgid "" +"Set the default sorting criteria
            This can temporarily be changed for " +"each new session" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:2139 +msgid "Default Sorting Order" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:2139 +msgid "" +"Set the default sorting order
            This can temporarily be changed for each " +"new session" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:2140 +msgid "Avatar Size (All-userlisting)" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:2140 +msgid "Set the avatar size on the all-userlisting only" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:2141 +msgid "Avatar Size (Single-userlisting)" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:2141 +msgid "Set the avatar size on the single-userlisting only" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:2142 +msgid "Visible only to logged in users?" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:2142 +msgid "The userlisting will only be visible only to the logged in users" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:2143 +msgid "Visible to following Roles" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:2143 +msgid "The userlisting will only be visible to the following roles" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:2149 +msgid "Userlisting Settings" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:2168 +msgid "Label" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:2168 +msgid "Choose the facet name that appears on the frontend" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:2169 +msgid "Facet Type" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:2169 +msgid "Choose the facet menu type" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:2170 +msgid "Facet Meta" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:2170 +msgid "Choose the meta field for the facet menu" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:2171 +msgid "Behaviour" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:2171 +msgid "Narrow the results" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:2171 +msgid "Expand the results" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:2171 +msgid "Choose how multiple selections affect the results" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:2172 +msgid "Visible choices" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:2172 +msgid "Show a toggle link after this many choices. Leave blank for all" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:2195 +msgid "Search Fields" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:2195 +msgid "Choose the fields in which the Search Field will look in" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:2200 +msgid "Search Settings" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:2270 +msgid "" +"You need to activate the Userlisting feature from within the \"Modules\" tab!" +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:2270 +msgid "You can find it in the Profile Builder menu." +msgstr "" + +#: profile-builder-2.0/modules/user-listing/userlisting.php:2433 +msgid "No results found!" +msgstr "" diff --git a/profile-builder/wpml-config.xml b/profile-builder/wpml-config.xml index c99953f..7ac1607 100644 --- a/profile-builder/wpml-config.xml +++ b/profile-builder/wpml-config.xml @@ -1,25 +1,25 @@ - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/questions.zip b/questions.zip index a617bbcef48c48465ab668e64e16c466b003ac25..77677757d21f275d69f80d51e4deae2d8c0df3d0 100644 GIT binary patch delta 40149 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 F{2xOf2m}BC diff --git a/user-private-files-pl_PL.mo b/user-private-files-pl_PL.mo deleted file mode 100644 index 0df33f7caf00026e8160d26d3cabcbba4243206c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2197 zcmai!&u<$=6vu~BN-;mguTp*qJqnaoWF0#VP@JZPCQYeGTB~tdsD#jXcVdsdo>^vQ zv#eEw6k72YR4D3!e}E#PUVE!8xN_jap%=ISH%=Tt@SU~Olv0Ex`{OtBX5M?>H#0XL z-F}JT^Ax_%;`@^~@cHttE$+hKE3h8~uY)_m@4$z^AIAI{+yVP{a5wlD_yD+j8)Nr_ zFM^+g70{1=3;O-O2mL-jf{%f}jqM$G!x#20@Ck4M+z!4E-Ul|v<1zRQ>`y_z&llhf z_!a2$_yrswmu*-)4f~sWM)~{!-V1vtlJ2>5cKum03QK=1^vE%fT$LerQmc`X(~8A{dYrbTBB!ax6*i{C$TjXn z5#7?NHk888mgzm6QpgphiBIR2`CO-CC%+93L!>w{p65o8R&h>iQe?is$!J_pQMTXS zwFO1O%9cXdXdI0#^EE+pZLV6vvSksYNaDpLEa#+ZS@J#+TW;%&cpM`+CtBJ_zhHAL z7u;CZKnSlUxjey7n>#|%FC)UJ7=)FUl=dO&^9yCRGODq#Ml0LG2v#WOe+Y7qOsbFd z@*|e21BLU6Q{0i7-8BE&64*WJT^sG(n%r ztnFMm_@*_MogqiM?q z4PB#B{Zu2EGom;w!8}y0(Nv}SdQf>Ss8p%?Mr~^Pl?py^3{HzR>0{i{Z+h&v$gK++ zhASI$r%jD`)We}WlyH;V>Z@HQkZu3zzpX7%7~dkf>x>@@!F^W&96)ynzv#lOO( zvi}HGv1V%jOlj%F(y=Y^s^v;)PAiA51PvUZ8m`nwZZe6vR5KK|al(X~U1=-?2e55^YSYiH<4SVs>L}mOPBlfSatI;2tgf3hy&ju5)DS)0fnB*RSI3Xbv`_!9^6jDF@={rs%-k z*F8bQ%b^@xY$-X|2r=ODxT}juS>8ks^00k-Om>bZ5+VCgMCI&kUI=xo7phu;u$eEM zQy;PUa6LzTSjUxs5?wyLMw#{cccD#p^X2*X6b?LxMzT9GDhcfwmpWWWXUI$25f=B| zmo0k!{lOLPV=k7RV$=_jOC9g9l`Z+a^0NDnwD0utj2@($#UwX-I=sM6xeOxrDZ>Ml zi4Mvzcza0F**r37H|?;KFnb(grHSEaxENk24xi|F-8m^vjll+4XS5n@{O6POHy@Ln ASpWb4 diff --git a/user-private-files-pl_PL.po b/user-private-files-pl_PL.po deleted file mode 100644 index 9adecdb..0000000 --- a/user-private-files-pl_PL.po +++ /dev/null @@ -1,117 +0,0 @@ -msgid "" -msgstr "" -"Project-Id-Version: User Private Files 1.1\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-06-01 19:24+0000\n" -"PO-Revision-Date: 2017-06-01 19:44+0000\n" -"Last-Translator: admin \n" -"Language-Team: \n" -"Language: pl_PL\n" -"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10 >= 2 && n%10<=4 " -"&&(n%100<10||n%100 >= 20)? 1 : 2);\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Loco https://localise.biz/" - -#: user-private-files.php:53 -msgid "You do not have sufficient permissions to access this page." -msgstr "Nie masz uprawnień do wejścia na Tę stronę" - -#: user-private-files.php:66 -msgid "Settings Saved" -msgstr "Ustawienia zostały zapisane" - -#: user-private-files.php:74 -msgid "User Private Files Settings" -msgstr "Ustawienia powiadomień" - -#: user-private-files.php:76 -msgid "Notification" -msgstr "Powiadomienie " - -#: user-private-files.php:80 -msgid "Email Subject:" -msgstr "Tytuł email " - -#: user-private-files.php:84 -msgid "Email Message:" -msgstr "Treść email" - -#: user-private-files.php:87 -msgid "Available Variables: " -msgstr "Dostępne \"zmienne\" (możliwe do wykorzystania kody)" - -#: user-private-files.php:93 -msgid "Save Changes" -msgstr "Zapisz zmainy" - -#: user-private-files.php:186 -msgid "User" -msgstr "Użytkownik " - -#: user-private-files.php:258 -msgid "User File" -msgstr "Plik użytkownika" - -#: user-private-files.php:269 -msgid "Current file:" -msgstr "Obecny plik" - -#: user-private-files.php:273 -msgid "Upload a PDF file here" -msgstr "Prześlij plik PDF tutaj" - -#: user-private-files.php:275 -msgid "Select a user" -msgstr "Wybierz użytkownika " - -#: user-private-files.php:286 -msgid "Notify User" -msgstr "Powiadom użytkownika " - -#: user-private-files.php:337 -msgid "The file type that you've uploaded is not a PDF." -msgstr "Plik, który przesłałeś nie jest plikiem PDF" - -#: user-private-files.php:538 -msgid "Show all years" -msgstr "Pokaż wszystkie lata" - -#: user-private-files.php:555 -msgid "Show all categories" -msgstr "Pokaż wszystkie kategorie" - -#: user-private-files.php:565 -msgid "Filter" -msgstr "Filter" - -#: user-private-files.php:600 user-private-files.php:656 -msgid "View and Print" -msgstr "Otwórz w nowej karcie i Wydrukuj" - -#: user-private-files.php:601 user-private-files.php:657 -msgid "Download" -msgstr "Pobierz" - -#. Name of the plugin -msgid "User Private Files 1.1" -msgstr "User Private Files 1.1" - -#. Description of the plugin -msgid "" -"Plugin to manage private files for users. You can upload files for your " -"users to access, files are only viewable/downloadable for the designated " -"users." -msgstr "" -"Plugin do zarządzania prywatnymi plikami dla użytkowników. Możesz przesłać " -"pliki które będą dostępne do obejrzenia , ściągnięcia tylko dla wybranych " -"użytkowników." - -#. Author of the plugin -msgid "Hai Bui - FLDtrace team" -msgstr "Hai Bui - FLDtrace team" - -#. Author URI of the plugin -msgid "http://www.fldtrace.com" -msgstr "http://www.fldtrace.com" diff --git a/user-private-files.zip b/user-private-files.zip index dff10b844e9953036b9316670085f58c54b06d30..c27edded2eee774f00f59e2f76c9b594a6ea2e8c 100644 GIT binary patch literal 188 zcmWIWW@h1H00F&K$GpG{C?U)s!%$kBTBKW0lv$QolB%1QnUh+q9~#2Rz%~U ztH{y{ZU#n{7t9O{U?RYqkx7mjmvItMg9RA=I)a#34QGWIj$tq>8%PTy5Jm!NUl4}@ E02AvZhyVZp literal 7508 zcma)>Wl$Wd{a}Ktu!lt@tb{XdmjrgFuRSt z6WEj8&B@!=-i6)S!qW@v!Ktf*1b|!8+ttURIBWgFT880$dgtI7t*FBwlJ<;PAiAC zZ}X3u=!iu^m!DafgHo#-HawNBcS(hLiq+UBesdIa6`>CI@5TRnNHnyo`_Ci*z>zKh zAn>n*{O8-?aI)!(t3>)Gt`@yjP=_;AL3+B9!Q0a zq{v{v8vyV}ot`!uD0vV<0n99c`rh>;$Tk6gs|P+zivCzz_mZlu zYLyZ19r4aw{DTlGZTA@wyP|Qgf_wL0^4ldE2+ayp8#9GUIIQ=;LG@A@Hh}66yia9O zMBOC@Ba(XoQ7^i!8WJ&MP1wvEf2G3?!!EG z#qELM3oPZWR&zDC$s$6bb2L8akN zGH3ut9M9$O)?&$j50Wmyz*FB(vdoNZx3HnMSv-s5xoWxh3h?v{@V|qhQiT=Huu{_PULLq_AsA87xDPuau{ws3 z{p<;Tb5YrE64crG$QFusKdrpBb5c?*xUy|xCwXC&fuS)VEC1uOK8$juhSxKqxF2;9kBp>%m7u}l<>nD8qh?VF z-l1AYnBAW$J*PJ*PRe z^|v@h*|~_sLDj|uvba4?aNx~+@ECsQMT5<7df3!n*5b|&e)yyPSza)AYRN~-7bkne zOJr;fCb-U@WHZy? z&KdKY1atbd#>JFK)KKk}Un2uRV}oL^77C(P0qz1;M&nVB&>L#Qm`;bK##=p`TuQa0 zT-DqipPJa!3!|37ns_^>(65c}69^S)hNq~v5t^Eo59~US;03apc43XEkS6vFRZc1J zFijo@1Kx*I1PYvpwu||U_E{p;@=Abna!lPSUf2-g-dkM{3R~8|?{KPtcSs;47G0rL5_6N=8F>$n1+_s-~FRRn%Y7cklOz>R48i(yeZ4B59pz zO?E(kX4hJUkNKX^V@9cz9#wiP$vX4}h_?8nuN7?st4Vs@1G25>0i=J* zhh7=>rdx?848GEUm!+WVbF6UMeW>f7Cll>@kL{>e>+Pd;IjsFjSu}bOBvLC^=f9`D z8mk3c6F;*SXeD1@V8Gczzg)Bm@sux-JO^MpGzUExl-*tV z)pX9xqew{6!1D9&?^7t^*iQ%`WuINWzE9$G3Qp+y=Z2TXO)FHMK4(1THm|||cJtWd zRnp^BW>Ms6c4^rjFTnAWOM`VW<@0P_Tj!wD)Tq+h9B0ZCBbWH!X`;sY=~x*`C@z;) z2Z?wNSFcwDO`S_=AWRELO>J10XY@!-%jCiQpCN~x)0*5Yw^Ki0f#bP2^uCbJ`Q4mg zz?H1bXiIeztw4BC;k&d$d|m-LT~^~pZR8JZpBHc=@U}&NOpJ2Zt6B`HiP0dPC0L$0 z5q|pi1^k$LI>pQ zfCJG?yY!1%n|Mm_T`p(C5i0=J`zREu4nJhD)g1LGTvscC@3O_e@~N*O*3ru z0=X zhADzbe8W9b33`T#IUUwPI*Tz5a+cp?`Jj>fGqhcqahix0Pi`&hdR3D#ZFsYi{gW^o zYh{2aztNzo)l0Z+P`>(#|4xhxR|4Ab@zLd4#w*WZOj*u118FZP^!wl*@}O|mJe41a zz3WfI;d3GJbt`bT3hUEI+c@<~E|E82g6X{4-Is3dIj?Zm4&M>?j*YAu@y{_qIo7W) zVdK|b#%Yq#I6}B;Zma{QS)}xCVh6Jkbqe@(!b*s~AR9ki)<{*&8jNW&UChIr@XhP2 zuSh=H737jLVV6Zb@`;;G`8ThD=McQ57sd4F4E2<*d3S8~o*#n*o3@z4{5-~do3|B` zj)x>2m1TaJ`3XL&HoT9)?q%4s)8T3cQ^Rd0Li8%t!z)O}r|!xuOv5#seKR^s`YQ|& z&7%Ei)ReRju~Q&LyOg6KK8YDRVcGbaidw=FJ8r`*;fIyagU8cPyjbhH7Va17IbjuR zJqpQ?9KN&#_}y=)k40QUV6$v`GYq9-^AS=9u)JzmtaxZC*7O}tQP-4-aT!}3qFz*B z;*{np2A>~$wyU4jij+$XkJ)EKUVY_it5hR$FY;605l3hh3HQJx6kk;4M*9;8C?9c7 zMfxN&1yjZ?uKXd3kKvY>uN|3;tIj~X?k(tPZ;}4Yo0;qIV#&;<6#aS;krg^vTuQQbg&5p59?XE>BsWmYgt`=OVu|>C2-^iU>tUgzl zq=_ujT)E1Y)S_Xc?MqSSH*S579C8oM1z$_h=E1P5>ZHvp7h%;y=SJp%$-s{Y(I^&g z*tumt91CHBw0l11BhP-ryvL`wT$=H`8xe$bVj`JBp7fo}Buh~G zC5~Bc!A@<#oH1L#89s%A!d~`dNhqq>LBB2w3iAb7-SgYYrYlYwz3FuLt-76)R0^3W z>^V2bqQ;%qGGY5ErZ;DDqPVbQg7+TTOek!AkPV-LCnyg#pZk^BS;xf_>X(ny+vEQ2 z3-~lrQ!op|wif*`HDBw`j|@60ML?VZu%JE(b{v0x>BvrXo@EqQ+U@uDhP?WG?3((1 zh>L^nWb^8oV}GIDR4K+ve+pNq`ezjt22nL#W1p6fFoL?GO+*$C+Fu{Dqol#QZmtxC z*NHod`f;5TN9jHY577HcyVjQ@rpymvu#I4dVA=M-1T_o^OT@HmgfWr9y(*`f@hNHz z6tYaH{{PVrj7ZQ{gGwOm>x(;6I9>jr-*C9b zv&$A>WLyMZHH}DBe6-gNnk77f1dr)Iu^0PhGI3V|=p_D!!O6n? z*!S(EzLZG45?fauRw_K&^j>p!f?i<;fN#$1Aj^5p!G7Z1SS=Hx6Zqym+Y_l1v-Tb6 zKvJ??%a}gdCUxMA?tCsZ&5n6pL&IM^IX-R6>GF8ea|o-UNzr*kn?jz0*%3>=%)(0m zMv}lTe=y?0k5KTbzOX|-+jn?U0 zp+2Z67Z>0DZG;n6EWraO=nQ|!Gwg?vt4v~3!)le%$xKIYnG%%Vz^Hf80VzaqKfsGF zj#Z*-4YGqiTRYV_xW&{5j2*eY`6i~u>6s;y!dWYjllqo56ntcvVfk#-RTi=TgGw^f zhYM($X~;4m_2}C0CMWHTME(6Cmmc2^GrPXPp-3J=oyaX?ut`A6R74PpkuSZjB+|iv z?}_9IdYyu8yyUrULtEnPqCGmhs_vOVE8?jPRpnqQ*`fJ!L!l8F>?uI>olTLNFY|~o zB_Mo@?k$#y8+u*O5=xbn4sA1U`Zt@*Sbu$rOwYF-ym)*BeSWJlQyj!_zSbIP ztn2XlNDj60-pB=eZ?^oMx0n-bJ-_6mmrsZx1#C7pt6u)*O<8hHwMkN2dD%Lu5%M< zu>yN62NB=O*V4~DEj~4#Pxo_baHL+ld@Im7*Qj2-Q~5j~P4*?a5_fXM>8$s-xa}Sa zPi|RY%x6hzkF=lVj&Jw$;im4JPvyNS#frymW(J9>5DED!@a(RBb-my?uLrmpK!D0t zDRA}8t=6zXMe`E!Dq!-P?Bmzy$-?fpUh?=)-M1X*8$$cg!Fu6b@ocrN@6S^|_46Ac zSCO_2RKSR^+s4+P8bW2>cEqbRDzh~4gv6?CzhJ&Hx#w!!s^cUm4W9OL*YvXEi^Iv3 zcpCfsqVs*lnQa0(m#oRe;pr;WwC^@Qc>CNQT@5cDoZ5}sP;Hrf`~46 z{4!!*fTv=k7@&SMKY1xTLnAVG!@%lS6g0ST4AB~(WF?gSX5)ywf?i$DFpM&_i!QAD(&U0?_F`v1sGwyKVa-F2chAY%vP%7^4|pDyTQ zTpes_-d$$8N6uS{^l3f*ZYpTM`m<>@KYfvzJ3Fu+on7FuE#4@;kyUIckr65qjev~|MOV{ zLlSRrnk)|Iu-AH#MZ&nU7-hFEQ2LWGV1#8?U7UG2Q8I*on6u3N9G@Rygw#raO%YA6 zQF4>%(*hUeY_#SI`LG9l@I8E<7$dqd^LVPvV985v7%uyAtVm&ZMMG=NwiQMi0)EIy z`sKs#oqkZ5;5|hAMf&tLsI&jgYpgHjZzEw5$8*a>nca>@7^E-Mfm_~Qmw3R2nj4I< z{@C5^c<}4yY6JVsxFzg>@#1o9AZj?5YVwEM`FUS+-6@|UKu@>2TRTvPZ;WXlTS-f|sU%_+d z<3ZJG7Kh+mF&pHj8n67C`+kT%^a_pp@@vCllE()|O*ZK>M#I?hC=ZlXXI_TtjLn2} z-ISDljNS%9JYv-ho`|N8e?3wMCdEym^O)v6B1?1qu!&uGQq_loL^#|8m)zX>#;9Of z!C%xVQv)L;Jxy$U=2$r4O{l+1z8RK9A;x>zu)g*UH1wweu~MW-qC6ZKcd3-ni+=c) z@N#s0lvcv_Jz56LD9bQ-zT^;4!&@9h46wFnaeYL|EaSRDM&FEImb3NO(WWf5uFBg)DBW>N~w;R1EC2@z$w7BBMc%Sn;>90t(8Wi!h4*cDCZX|Et4wYgg&eD2sZg_ z2#gj$a1O~N=x$dg#DN?i5HaM-Ww?I&og_zdSJkp+X>Kynj7`YCqW$98EL$>Z$*w`S z@ngqFghz3Ht?2sYvVOY!_KzH!ZzPI01;4kt-CF5@%LbM>#^%r1miV=9^cdffgYBb4 zRccn7-L>%Xcl})tRUftX%MIql3oU8KI@gobMK9(bx1kzvcO279#?^p;uR|Hs>YU$s zO-e?-LX4QOl%~z@{fm@Z4_X-j&Od8vWOBS{n-b0u4iR(8r5Yh z9;oaI9ddFuqb?yZD+(T>exRtH6D4BG=+;-G68-RGj14sPn=yx$h6GYIyEPhn zgQ?oC4C`Y*WThNG@lDVid|_QZ=JS~c?D2~(aCKLhAOX4=4RpHn8niYrL+e&C9HM%; z{EAwrd1GpFKXoxf+gx)5LIQ)-YMf5=AczPk#tLzgW zRj{n5vT6fYp~;xC{gi5DGFK*A=nwC74N|{CBnOQkH zHXLNgSEu?iS~oTNvi)LCl16@c4(`}H*1jLGJJcNWLD7#ai|hu%GPrR8FVXl9`XV4=Jzhx2r4}=-4vclr>(I ziu|9jp4zZb?;6W&XTQ6+Jv1~c=^5=uXy8uESa!~jZo)AeJ1v-S`$>QWMV*T)CuEcP zqMzt~ms~lDG+4{jIfT=Yzj$TYpEzI4t8NVAx*nsUyuUu*nc@hBB@@qb_^0MiuwSao z3v3cSnbPj*eK{_Q5kFzt=^iF$dV7@4ep7JNGw7p~WA%Vy9jC6e88N9m7wdui{Y7T{ zE)h|et-c9#G9}v|rqxwFQJ}3!a6o(18JdhTP2R=H(xrXa{O=+OzuWm2_2S59%yh=J?V!tHh9H<#-x`IecIHVwJv;Uptoun zT9y$lKZo8t=OhZ779M@)H9UHota0}8Mnf469su~ih2OusKkR=fz<(BA|F{185AOdi z0RIMr`#V+Pum1mX|5*qASMYxy@IU3
            '; + $this->no_items(); + echo '
            '; + echo $this->column_cb( $item ); + echo '"; + echo call_user_func( array( $this, 'column_' . $column_name ), $item ); + echo ""; + echo $this->column_default( $item, $column_name ); + echo " - **************************************************************************/ - function column_default($item, $column_name){ - switch($column_name){ - case 'email': - case 'registered': - return $item[$column_name]; - case 'user-meta': - global $wpdb; - $sql_result = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM " . $wpdb->base_prefix . "signups WHERE user_email = %s", $item['email'] ), ARRAY_A ); - $user_meta = $sql_result['meta']; - $user_meta_content = ''; - if( !empty( $user_meta ) ){ - foreach( maybe_unserialize( $user_meta ) as $key => $value ){ - if( $key != 'user_pass' ){ - if ( is_array($value) ) $value = implode(',',$value); - $user_meta_content .= $key.':'.$value.'
            '; - } - } - } - return ''. __( 'show', 'profile-builder' ) .''; - default: - return print_r($item,true); //Show the whole array for troubleshooting purposes - } - } - - - /** ************************************************************************ - * Recommended. This is a custom column method and is responsible for what - * is rendered in any column with a name/slug of 'username'. Every time the class - * needs to render a column, it first looks for a method named - * column_{$column_title} - if it exists, that method is run. If it doesn't - * exist, column_default() is called instead. - * - * This example also illustrates how to implement rollover actions. Actions - * should be an associative array formatted as 'slug'=>'link html' - and you - * will need to generate the URLs yourself. You could even ensure the links - * - * - * @see PB_WP_List_Table::::single_row_columns() - * @param array $item A singular item (one full row's worth of data) - * @return string Text to be placed inside the column
            - **************************************************************************/ - function column_username($item){ - - $GRavatar = get_avatar( $item['email'], 32, '' ); - - //Build row actions - $actions = array( - 'delete' => sprintf( '' . __( 'Delete', 'profile-builder' ) . '', wppb_curpageurl(), 'delete', $item['ID'] ), - 'confirm' => sprintf( '' . __( 'Confirm Email', 'profile-builder' ) . '', wppb_curpageurl(), 'confirm', $item['ID'] ), - 'resend' => sprintf( '' . __( 'Resend Activation Email', 'profile-builder' ) . '', wppb_curpageurl(), 'resend', $item['ID'] ) - ); - - //Return the user row - return sprintf('%1$s %2$s %3$s', - /*$1%s*/ $GRavatar, - /*$2%s*/ $item['username'], - /*$3%s*/ $this->row_actions($actions) - ); - } - - /** ************************************************************************ - * REQUIRED if displaying checkboxes or using bulk actions! The 'cb' column - * is given special treatment when columns are processed. It ALWAYS needs to - * have it's own method. - * - * @see PB_WP_List_Table::::single_row_columns() - * @param array $item A singular item (one full row's worth of data) - * @return string Text to be placed inside the column - **************************************************************************/ - function column_cb($item){ - return sprintf( - '', - /*$1%s*/ $this->_args['singular'], //Let's simply repurpose the table's singular label - /*$2%s*/ $item['ID'] //The value of the checkbox should be the record's id - ); - } - - - /** ************************************************************************ - * REQUIRED! This method dictates the table's columns and titles. This should - * return an array where the key is the column slug (and class) and the value - * is the column's title text. If you need a checkbox for bulk actions, refer - * to the $columns array below. - * - * The 'cb' column is treated differently than the rest. If including a checkbox - * column in your table you must create a column_cb() method. If you don't need - * bulk actions or checkboxes, simply leave the 'cb' entry out of your array. - * - * @see PB_WP_List_Table::::single_row_columns() - * @return array An associative array containing column information: 'slugs'=>'Visible Titles' - **************************************************************************/ - function get_columns(){ - $columns = array( - 'cb' => '', //Render a checkbox instead of text - 'username' => __( 'Username', 'profile-builder' ), - 'email' => __( 'E-mail', 'profile-builder' ), - 'registered' => __( 'Registered', 'profile-builder' ), - 'user-meta' => __( 'User Meta', 'profile-builder' ) - ); - - return $columns; - } - - /** ************************************************************************ - * Optional. If you want one or more columns to be sortable (ASC/DESC toggle), - * you will need to register it here. This should return an array where the - * key is the column that needs to be sortable, and the value is db column to - * sort by. Often, the key and value will be the same, but this is not always - * the case (as the value is a column name from the database, not the list table). - * - * This method merely defines which columns should be sortable and makes them - * clickable - it does not handle the actual sorting. You still need to detect - * the ORDERBY and ORDER querystring variables within prepare_items() and sort - * your data accordingly (usually by modifying your query). - * - * @return array An associative array containing all the columns that should be sortable: 'slugs'=>array('data_values',bool) - **************************************************************************/ - function get_sortable_columns() { - $sortable_columns = array( - 'username' => array('username',false), //true means it's already sorted - 'email' => array('email',false), - 'registered' => array('registered',false) - ); - - return $sortable_columns; - } - - - /** ************************************************************************ - * Optional. If you need to include bulk actions in your list table, this is - * the place to define them. Bulk actions are an associative array in the format - * 'slug'=>'Visible Title' - * - * If this method returns an empty value, no bulk action will be rendered. If - * you specify any bulk actions, the bulk actions box will be rendered with - * the table automatically on display(). - * - * Also note that list tables are not automatically wrapped in
            elements, - * so you will need to create those manually in order for bulk actions to function. - * - * @return array An associative array containing all the bulk actions: 'slugs'=>'Visible Titles' - **************************************************************************/ - function get_bulk_actions() { - $actions = array( - 'delete' => __( 'Delete', 'profile-builder' ), - 'confirm' => __( 'Confirm Email', 'profile-builder' ), - 'resend' => __( 'Resend Activation Email', 'profile-builder' ) - ); - - return $actions; - } - - - /** ************************************************************************ - * Optional. You can handle your bulk actions anywhere or anyhow you prefer. - * For this example package, we will handle it in the class to keep things - * clean and organized. - * - * @see $this->prepare_items() - **************************************************************************/ - - function wppb_process_bulk_action_message( $message, $url ){ - - echo ""; - } - - function wppb_process_bulk_action() { - global $current_user; - global $wpdb; - - if ( current_user_can( 'delete_users' ) ){ - if( 'delete' === $this->current_action() ) { - foreach ( $_GET['user'] as $user ){ - $sql_result = $wpdb->query( $wpdb->prepare( "DELETE FROM ".$wpdb->base_prefix."signups WHERE user_email = %s", sanitize_email( $user ) ) ); - - if ( !$sql_result ) - $this->wppb_process_bulk_action_message( sprintf( __( "%s couldn't be deleted", "profile-builder" ), $result->user_login ), get_bloginfo('url').'/wp-admin/users.php?page=unconfirmed_emails' ); - - } - - $this->wppb_process_bulk_action_message( __( 'All users have been successfully deleted', 'profile-builder' ), get_bloginfo('url').'/wp-admin/users.php?page=unconfirmed_emails' ); - - }elseif( 'confirm' === $this->current_action() ) { - foreach ( $_GET['user'] as $user ){ - $sql_result = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM " . $wpdb->base_prefix . "signups WHERE user_email = %s", sanitize_email( $user ) ), ARRAY_A ); - - if ( $sql_result ) - wppb_manual_activate_signup( $sql_result['activation_key'] ); - } - - $this->wppb_process_bulk_action_message( __( 'The selected users have been activated', 'profile-builder' ), get_bloginfo('url').'/wp-admin/users.php?page=unconfirmed_emails' ); - - }elseif( 'resend' === $this->current_action() ) { - foreach ( $_GET['user'] as $user ){ - $sql_result = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM " . $wpdb->base_prefix . "signups WHERE user_email = %s", sanitize_email( $user ) ), ARRAY_A ); - - if ( $sql_result ) - wppb_signup_user_notification( esc_sql( $sql_result['user_login'] ), esc_sql( $sql_result['user_email'] ), $sql_result['activation_key'], $sql_result['meta'] ); - - } - - $this->wppb_process_bulk_action_message( __( 'The selected users have had their activation emails resent', 'profile-builder' ), get_bloginfo('url').'/wp-admin/users.php?page=unconfirmed_emails' ); - } - - }else - $this->wppb_process_bulk_action_message( __( "Sorry, but you don't have permission to do that!", "profile-builder" ), get_bloginfo('url').'/wp-admin/' ); - } - - - /** ************************************************************************ - * REQUIRED! This is where you prepare your data for display. This method will - * usually be used to query the database, sort and filter the data, and generally - * get it ready to be displayed. At a minimum, we should set $this->items and - * $this->set_pagination_args(), although the following properties and methods - * are frequently interacted with here... - * - * @global WPDB $wpdb - * @uses $this->_column_headers - * @uses $this->items - * @uses $this->get_columns() - * @uses $this->get_sortable_columns() - * @uses $this->get_pagenum() - * @uses $this->set_pagination_args() - **************************************************************************/ - function prepare_items() { - global $wpdb; - - $this->dataArray = array(); - - /** - * First, lets decide how many records per page to show - */ - $per_page = apply_filters('wppb_email_confirmation_user_per_page_number', 20); - /* determine offset */ - if( !empty( $_REQUEST['paged'] ) ){ - $offset = ( esc_attr( $_REQUEST['paged'] ) -1 ) * $per_page; - } - else - $offset = 0; - - /* handle order and orderby attr */ - if( !empty( $_REQUEST['orderby'] ) ){ - $orderby = sanitize_text_field( $_REQUEST['orderby'] ); - if( $orderby == 'username' ) - $orderby = 'user_login'; - elseif ( $orderby == 'email' ) - $orderby = 'user_email'; - } - else - $orderby = 'user_login'; - if( !empty( $_REQUEST['order'] ) && $_REQUEST['order'] == 'desc' ) - $order = "DESC"; - else - $order = 'ASC'; - - /* handle the WHERE clause */ - $where = "active = 0"; - if( isset( $_REQUEST['s'] ) && !empty( $_REQUEST['s'] ) ){ - $where .= " AND ( user_login LIKE '%".sanitize_text_field($_REQUEST['s'])."%' OR user_email LIKE '%".sanitize_text_field($_REQUEST['s'])."%' OR registered LIKE '%".sanitize_text_field($_REQUEST['s'])."%' )"; - } - /* since version 2.0.7 for multisite we add a 'registered_for_blog_id' meta in the registration process - so we can display only the users registered on that blog. Also for backwards compatibility we display the users that don't have that meta at all */ - if( is_multisite() ){ - $where .= " AND ( meta NOT LIKE '%\"registered_for_blog_id\"%' OR meta LIKE '%\"registered_for_blog_id\";i:".get_current_blog_id()."%' )"; - } - - $results = $wpdb->get_results("SELECT * FROM ".$wpdb->base_prefix."signups WHERE $where ORDER BY $orderby $order LIMIT $offset, $per_page"); - - foreach ($results as $result){ - $tempArray = array('ID' => $result->user_email, 'username' => $result->user_login, 'email' => $result->user_email, 'registered' => $result->registered); - array_push($this->dataArray, $tempArray); - } - - /** - * REQUIRED for pagination. Let's check how many items are in our data array. - * In real-world use, this would be the total number of items in your database, - * without filtering. We'll need this later, so you should always include it - * in your own package classes. - */ - $total_items = $wpdb->get_var("SELECT COUNT(*) FROM ".$wpdb->base_prefix."signups WHERE $where"); - - /** - * REQUIRED. Now we need to define our column headers. This includes a complete - * array of columns to be displayed (slugs & titles), a list of columns - * to keep hidden, and a list of columns that are sortable. Each of these - * can be defined in another method (as we've done here) before being - * used to build the value for our _column_headers property. - */ - $columns = $this->get_columns(); - $hidden = array(); - $sortable = $this->get_sortable_columns(); - - - /** - * REQUIRED. Finally, we build an array to be used by the class for column - * headers. The $this->_column_headers property takes an array which contains - * 3 other arrays. One for all columns, one for hidden columns, and one - * for sortable columns. - */ - $this->_column_headers = array($columns, $hidden, $sortable); - - - /** - * Optional. You can handle your bulk actions however you see fit. In this - * case, we'll handle them within our package just to keep things clean. - */ - $this->wppb_process_bulk_action(); - - - /** - * Instead of querying a database, we're going to fetch the example data - * property we created for use in this plugin. This makes this example - * package slightly different than one you might build on your own. In - * this example, we'll be using array manipulation to sort and paginate - * our data. In a real-world implementation, you will probably want to - * use sort and pagination data to build a custom query instead, as you'll - * be able to use your precisely-queried data immediately. - */ - $data = $this->dataArray; - - /** - * REQUIRED. Now we can add our *sorted* data to the items property, where - * it can be used by the rest of the class. - */ - $this->items = $data; - - - /** - * REQUIRED. We also have to register our pagination options & calculations. - */ - $this->set_pagination_args( array( - 'total_items' => $total_items, //WE have to calculate the total number of items - 'per_page' => $per_page, //WE have to determine how many items to show on a page - 'total_pages' => ceil($total_items/$per_page) //WE have to calculate the total number of pages - ) ); - } - -} - - - - - -/** ************************ REGISTER THE PAGE **************************** - ******************************************************************************* - * Now we just need to define an admin page. - */ -function wppb_add_ec_submenu_page() { - $wppb_generalSettings = get_option('wppb_general_settings', 'not_found'); - if($wppb_generalSettings != 'not_found') { - if( !empty($wppb_generalSettings['emailConfirmation']) && ($wppb_generalSettings['emailConfirmation'] == 'yes') ){ - add_submenu_page('users.php', 'Unconfirmed Email Address', 'Unconfirmed Email Address', 'manage_options', 'unconfirmed_emails', 'wppb_unconfirmed_email_address_custom_menu_page'); - remove_submenu_page('users.php', 'unconfirmed_emails'); //hide the page in the admin menu - } - } -} -add_action('admin_menu', 'wppb_add_ec_submenu_page'); - - - -/***************************** RENDER PAGE ******************************** - ******************************************************************************* - * This function renders the admin page. Although it's - * possible to call prepare_items() and display() from the constructor, there - * are often times where you may need to include logic here between those steps, - * so we've instead called those methods explicitly. It keeps things flexible, and - * it's the way the list tables are used in the WordPress core. - */ -function wppb_unconfirmed_email_address_custom_menu_page(){ - - //Create an instance of our package class... - $listTable = new wpp_list_unfonfirmed_email_table(); - //Fetch, prepare, sort, and filter our data... - $listTable->prepare_items(); - - ?> -
            - -

            - -
              -
            • -
            - - - - - search_box( __( 'Search Users' ), 'user' ); ?> - - - display() ?> - - -
            - prepare_items() to handle any data manipulation, then + * finally call $yourInstance->display() to render the table to the page. + * + */ +class wpp_list_unfonfirmed_email_table extends PB_WP_List_Table { + + /** ************************************************************************ + * REQUIRED. Set up a constructor that references the parent constructor. We + * use the parent reference to set some default configs. + ***************************************************************************/ + function __construct(){ + global $status, $page; + global $wpdb; + + //Set parent defaults + parent::__construct( array( + 'singular' => 'user', //singular name of the listed records + 'plural' => 'users', //plural name of the listed records + 'ajax' => false //does this table support ajax? + ) ); + + } + + + /** ************************************************************************ + * Recommended. This method is called when the parent class can't find a method + * specifically build for a given column. Generally, it's recommended to include + * one method for each column you want to render, keeping your package class + * neat and organized. For example, if the class needs to process a column + * named 'username', it would first see if a method named $this->column_title() + * exists - if it does, that method will be used. If it doesn't, this one will + * be used. Generally, you should try to use custom column methods as much as + * possible. + * + * Since we have defined a column_title() method later on, this method doesn't + * need to concern itself with any column with a name of 'username'. Instead, it + * needs to handle everything else. + * + * For more detailed insight into how columns are handled, take a look at + * PB_WP_List_Table::single_row_columns() + * + * @param array $item A singular item (one full row's worth of data) + * @param array $column_name The name/slug of the column to be processed + * @return string Text or HTML to be placed inside the column
            + **************************************************************************/ + function column_default($item, $column_name){ + switch($column_name){ + case 'email': + case 'registered': + return $item[$column_name]; + case 'user-meta': + global $wpdb; + $sql_result = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM " . $wpdb->base_prefix . "signups WHERE user_email = %s", $item['email'] ), ARRAY_A ); + $user_meta = $sql_result['meta']; + $user_meta_content = ''; + if( !empty( $user_meta ) ){ + foreach( maybe_unserialize( $user_meta ) as $key => $value ){ + if( $key != 'user_pass' ){ + if ( is_array($value) ) $value = implode(',',$value); + $user_meta_content .= $key.':'.$value.'
            '; + } + } + } + return ''. __( 'show', 'profile-builder' ) .''; + default: + return print_r($item,true); //Show the whole array for troubleshooting purposes + } + } + + + /** ************************************************************************ + * Recommended. This is a custom column method and is responsible for what + * is rendered in any column with a name/slug of 'username'. Every time the class + * needs to render a column, it first looks for a method named + * column_{$column_title} - if it exists, that method is run. If it doesn't + * exist, column_default() is called instead. + * + * This example also illustrates how to implement rollover actions. Actions + * should be an associative array formatted as 'slug'=>'link html' - and you + * will need to generate the URLs yourself. You could even ensure the links + * + * + * @see PB_WP_List_Table::::single_row_columns() + * @param array $item A singular item (one full row's worth of data) + * @return string Text to be placed inside the column
            + **************************************************************************/ + function column_username($item){ + + $GRavatar = get_avatar( $item['email'], 32, '' ); + + //Build row actions + $actions = array( + 'delete' => sprintf( '' . __( 'Delete', 'profile-builder' ) . '', wppb_curpageurl(), 'delete', $item['ID'] ), + 'confirm' => sprintf( '' . __( 'Confirm Email', 'profile-builder' ) . '', wppb_curpageurl(), 'confirm', $item['ID'] ), + 'resend' => sprintf( '' . __( 'Resend Activation Email', 'profile-builder' ) . '', wppb_curpageurl(), 'resend', $item['ID'] ) + ); + + //Return the user row + return sprintf('%1$s %2$s %3$s', + /*$1%s*/ $GRavatar, + /*$2%s*/ $item['username'], + /*$3%s*/ $this->row_actions($actions) + ); + } + + /** ************************************************************************ + * REQUIRED if displaying checkboxes or using bulk actions! The 'cb' column + * is given special treatment when columns are processed. It ALWAYS needs to + * have it's own method. + * + * @see PB_WP_List_Table::::single_row_columns() + * @param array $item A singular item (one full row's worth of data) + * @return string Text to be placed inside the column + **************************************************************************/ + function column_cb($item){ + return sprintf( + '', + /*$1%s*/ $this->_args['singular'], //Let's simply repurpose the table's singular label + /*$2%s*/ $item['ID'] //The value of the checkbox should be the record's id + ); + } + + + /** ************************************************************************ + * REQUIRED! This method dictates the table's columns and titles. This should + * return an array where the key is the column slug (and class) and the value + * is the column's title text. If you need a checkbox for bulk actions, refer + * to the $columns array below. + * + * The 'cb' column is treated differently than the rest. If including a checkbox + * column in your table you must create a column_cb() method. If you don't need + * bulk actions or checkboxes, simply leave the 'cb' entry out of your array. + * + * @see PB_WP_List_Table::::single_row_columns() + * @return array An associative array containing column information: 'slugs'=>'Visible Titles' + **************************************************************************/ + function get_columns(){ + $columns = array( + 'cb' => '', //Render a checkbox instead of text + 'username' => __( 'Username', 'profile-builder' ), + 'email' => __( 'E-mail', 'profile-builder' ), + 'registered' => __( 'Registered', 'profile-builder' ), + 'user-meta' => __( 'User Meta', 'profile-builder' ) + ); + + return $columns; + } + + /** ************************************************************************ + * Optional. If you want one or more columns to be sortable (ASC/DESC toggle), + * you will need to register it here. This should return an array where the + * key is the column that needs to be sortable, and the value is db column to + * sort by. Often, the key and value will be the same, but this is not always + * the case (as the value is a column name from the database, not the list table). + * + * This method merely defines which columns should be sortable and makes them + * clickable - it does not handle the actual sorting. You still need to detect + * the ORDERBY and ORDER querystring variables within prepare_items() and sort + * your data accordingly (usually by modifying your query). + * + * @return array An associative array containing all the columns that should be sortable: 'slugs'=>array('data_values',bool) + **************************************************************************/ + function get_sortable_columns() { + $sortable_columns = array( + 'username' => array('username',false), //true means it's already sorted + 'email' => array('email',false), + 'registered' => array('registered',false) + ); + + return $sortable_columns; + } + + + /** ************************************************************************ + * Optional. If you need to include bulk actions in your list table, this is + * the place to define them. Bulk actions are an associative array in the format + * 'slug'=>'Visible Title' + * + * If this method returns an empty value, no bulk action will be rendered. If + * you specify any bulk actions, the bulk actions box will be rendered with + * the table automatically on display(). + * + * Also note that list tables are not automatically wrapped in
            elements, + * so you will need to create those manually in order for bulk actions to function. + * + * @return array An associative array containing all the bulk actions: 'slugs'=>'Visible Titles' + **************************************************************************/ + function get_bulk_actions() { + $actions = array( + 'delete' => __( 'Delete', 'profile-builder' ), + 'confirm' => __( 'Confirm Email', 'profile-builder' ), + 'resend' => __( 'Resend Activation Email', 'profile-builder' ) + ); + + return $actions; + } + + + /** ************************************************************************ + * Optional. You can handle your bulk actions anywhere or anyhow you prefer. + * For this example package, we will handle it in the class to keep things + * clean and organized. + * + * @see $this->prepare_items() + **************************************************************************/ + + function wppb_process_bulk_action_message( $message, $url ){ + + echo ""; + } + + function wppb_process_bulk_action() { + global $current_user; + global $wpdb; + + if ( current_user_can( 'delete_users' ) ){ + if( 'delete' === $this->current_action() ) { + foreach ( $_GET['user'] as $user ){ + $sql_result = $wpdb->query( $wpdb->prepare( "DELETE FROM ".$wpdb->base_prefix."signups WHERE user_email = %s", sanitize_email( $user ) ) ); + + if ( !$sql_result ) + $this->wppb_process_bulk_action_message( sprintf( __( "%s couldn't be deleted", "profile-builder" ), $result->user_login ), get_bloginfo('url').'/wp-admin/users.php?page=unconfirmed_emails' ); + + } + + $this->wppb_process_bulk_action_message( __( 'All users have been successfully deleted', 'profile-builder' ), get_bloginfo('url').'/wp-admin/users.php?page=unconfirmed_emails' ); + + }elseif( 'confirm' === $this->current_action() ) { + foreach ( $_GET['user'] as $user ){ + $sql_result = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM " . $wpdb->base_prefix . "signups WHERE user_email = %s", sanitize_email( $user ) ), ARRAY_A ); + + if ( $sql_result ) + wppb_manual_activate_signup( $sql_result['activation_key'] ); + } + + $this->wppb_process_bulk_action_message( __( 'The selected users have been activated', 'profile-builder' ), get_bloginfo('url').'/wp-admin/users.php?page=unconfirmed_emails' ); + + }elseif( 'resend' === $this->current_action() ) { + foreach ( $_GET['user'] as $user ){ + $sql_result = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM " . $wpdb->base_prefix . "signups WHERE user_email = %s", sanitize_email( $user ) ), ARRAY_A ); + + if ( $sql_result ) + wppb_signup_user_notification( esc_sql( $sql_result['user_login'] ), esc_sql( $sql_result['user_email'] ), $sql_result['activation_key'], $sql_result['meta'] ); + + } + + $this->wppb_process_bulk_action_message( __( 'The selected users have had their activation emails resent', 'profile-builder' ), get_bloginfo('url').'/wp-admin/users.php?page=unconfirmed_emails' ); + } + + }else + $this->wppb_process_bulk_action_message( __( "Sorry, but you don't have permission to do that!", "profile-builder" ), get_bloginfo('url').'/wp-admin/' ); + } + + + /** ************************************************************************ + * REQUIRED! This is where you prepare your data for display. This method will + * usually be used to query the database, sort and filter the data, and generally + * get it ready to be displayed. At a minimum, we should set $this->items and + * $this->set_pagination_args(), although the following properties and methods + * are frequently interacted with here... + * + * @global WPDB $wpdb + * @uses $this->_column_headers + * @uses $this->items + * @uses $this->get_columns() + * @uses $this->get_sortable_columns() + * @uses $this->get_pagenum() + * @uses $this->set_pagination_args() + **************************************************************************/ + function prepare_items() { + global $wpdb; + + $this->dataArray = array(); + + /** + * First, lets decide how many records per page to show + */ + $per_page = apply_filters('wppb_email_confirmation_user_per_page_number', 20); + /* determine offset */ + if( !empty( $_REQUEST['paged'] ) ){ + $offset = ( esc_attr( $_REQUEST['paged'] ) -1 ) * $per_page; + } + else + $offset = 0; + + /* handle order and orderby attr */ + if( !empty( $_REQUEST['orderby'] ) ){ + $orderby = sanitize_text_field( $_REQUEST['orderby'] ); + if( $orderby == 'username' ) + $orderby = 'user_login'; + elseif ( $orderby == 'email' ) + $orderby = 'user_email'; + } + else + $orderby = 'user_login'; + if( !empty( $_REQUEST['order'] ) && $_REQUEST['order'] == 'desc' ) + $order = "DESC"; + else + $order = 'ASC'; + + /* handle the WHERE clause */ + $where = "active = 0"; + if( isset( $_REQUEST['s'] ) && !empty( $_REQUEST['s'] ) ){ + $where .= " AND ( user_login LIKE '%".sanitize_text_field($_REQUEST['s'])."%' OR user_email LIKE '%".sanitize_text_field($_REQUEST['s'])."%' OR registered LIKE '%".sanitize_text_field($_REQUEST['s'])."%' )"; + } + /* since version 2.0.7 for multisite we add a 'registered_for_blog_id' meta in the registration process + so we can display only the users registered on that blog. Also for backwards compatibility we display the users that don't have that meta at all */ + if( is_multisite() ){ + $where .= " AND ( meta NOT LIKE '%\"registered_for_blog_id\"%' OR meta LIKE '%\"registered_for_blog_id\";i:".get_current_blog_id()."%' )"; + } + + $results = $wpdb->get_results("SELECT * FROM ".$wpdb->base_prefix."signups WHERE $where ORDER BY $orderby $order LIMIT $offset, $per_page"); + + foreach ($results as $result){ + $tempArray = array('ID' => $result->user_email, 'username' => $result->user_login, 'email' => $result->user_email, 'registered' => $result->registered); + array_push($this->dataArray, $tempArray); + } + + /** + * REQUIRED for pagination. Let's check how many items are in our data array. + * In real-world use, this would be the total number of items in your database, + * without filtering. We'll need this later, so you should always include it + * in your own package classes. + */ + $total_items = $wpdb->get_var("SELECT COUNT(*) FROM ".$wpdb->base_prefix."signups WHERE $where"); + + /** + * REQUIRED. Now we need to define our column headers. This includes a complete + * array of columns to be displayed (slugs & titles), a list of columns + * to keep hidden, and a list of columns that are sortable. Each of these + * can be defined in another method (as we've done here) before being + * used to build the value for our _column_headers property. + */ + $columns = $this->get_columns(); + $hidden = array(); + $sortable = $this->get_sortable_columns(); + + + /** + * REQUIRED. Finally, we build an array to be used by the class for column + * headers. The $this->_column_headers property takes an array which contains + * 3 other arrays. One for all columns, one for hidden columns, and one + * for sortable columns. + */ + $this->_column_headers = array($columns, $hidden, $sortable); + + + /** + * Optional. You can handle your bulk actions however you see fit. In this + * case, we'll handle them within our package just to keep things clean. + */ + $this->wppb_process_bulk_action(); + + + /** + * Instead of querying a database, we're going to fetch the example data + * property we created for use in this plugin. This makes this example + * package slightly different than one you might build on your own. In + * this example, we'll be using array manipulation to sort and paginate + * our data. In a real-world implementation, you will probably want to + * use sort and pagination data to build a custom query instead, as you'll + * be able to use your precisely-queried data immediately. + */ + $data = $this->dataArray; + + /** + * REQUIRED. Now we can add our *sorted* data to the items property, where + * it can be used by the rest of the class. + */ + $this->items = $data; + + + /** + * REQUIRED. We also have to register our pagination options & calculations. + */ + $this->set_pagination_args( array( + 'total_items' => $total_items, //WE have to calculate the total number of items + 'per_page' => $per_page, //WE have to determine how many items to show on a page + 'total_pages' => ceil($total_items/$per_page) //WE have to calculate the total number of pages + ) ); + } + +} + + + + + +/** ************************ REGISTER THE PAGE **************************** + ******************************************************************************* + * Now we just need to define an admin page. + */ +function wppb_add_ec_submenu_page() { + $wppb_generalSettings = get_option('wppb_general_settings', 'not_found'); + if($wppb_generalSettings != 'not_found') { + if( !empty($wppb_generalSettings['emailConfirmation']) && ($wppb_generalSettings['emailConfirmation'] == 'yes') ){ + add_submenu_page('users.php', 'Unconfirmed Email Address', 'Unconfirmed Email Address', 'manage_options', 'unconfirmed_emails', 'wppb_unconfirmed_email_address_custom_menu_page'); + remove_submenu_page('users.php', 'unconfirmed_emails'); //hide the page in the admin menu + } + } +} +add_action('admin_menu', 'wppb_add_ec_submenu_page'); + + + +/***************************** RENDER PAGE ******************************** + ******************************************************************************* + * This function renders the admin page. Although it's + * possible to call prepare_items() and display() from the constructor, there + * are often times where you may need to include logic here between those steps, + * so we've instead called those methods explicitly. It keeps things flexible, and + * it's the way the list tables are used in the WordPress core. + */ +function wppb_unconfirmed_email_address_custom_menu_page(){ + + //Create an instance of our package class... + $listTable = new wpp_list_unfonfirmed_email_table(); + //Fetch, prepare, sort, and filter our data... + $listTable->prepare_items(); + + ?> +
            + +

            + +
              +
            • +
            + + + + + search_box( __( 'Search Users' ), 'user' ); ?> + + + display() ?> + + +
            + charset ) ) - $charset_collate = "DEFAULT CHARACTER SET ".$wpdb->charset; - if ( ! empty( $wpdb->collate ) ) - $charset_collate .= " COLLATE ".$wpdb->collate; - $tableName = $wpdb->prefix.'signups'; - - $sql = " - CREATE TABLE $tableName ( - domain varchar(200) NOT NULL default '', - path varchar(100) NOT NULL default '', - title longtext NOT NULL, - user_login varchar(60) NOT NULL default '', - user_email varchar(100) NOT NULL default '', - registered datetime NOT NULL default '0000-00-00 00:00:00', - activated datetime NOT NULL default '0000-00-00 00:00:00', - active tinyint(1) NOT NULL default '0', - activation_key varchar(50) NOT NULL default '', - meta longtext, - KEY activation_key (activation_key), - KEY domain (domain) - ) $charset_collate;"; - - require_once(ABSPATH . 'wp-admin/includes/upgrade.php'); - $res = dbDelta($sql); - } -} -add_action( 'update_option_wppb_general_settings', 'wppb_signup_schema', 10, 2 ); - - -//function to add new tab in the default WP userlisting with all the users who didn't confirm their account yet -function wppb_add_pending_users_header_script(){ -?> - -get_results("SELECT * FROM ".$wpdb->base_prefix."signups WHERE active = 0"); - foreach ($results as $result){ - if( !empty( $result->meta ) ){ - $user_meta = maybe_unserialize( $result->meta ); - if( empty( $user_meta['registered_for_blog_id'] ) || $user_meta['registered_for_blog_id'] == get_current_blog_id() ){ - $number_of_users++; - } - } - } - - header( 'Content-type: application/json' ); - die( json_encode( array( 'number' => $number_of_users ) ) ); -} - - -function wppb_handle_email_confirmation_cases() { - global $wpdb; - - $todo = sanitize_text_field($_POST['todo']); - $user_email = sanitize_email($_POST['user_email']); - - if ( current_user_can( 'delete_users' ) ) - if ( ( $todo != '' ) && ( $user_email != '' ) ){ - - $results = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM " . $wpdb->base_prefix . "signups WHERE active = 0 AND user_email = %s", $user_email ) ); - - if ( count( $results ) != 1 ) - die( __( "There was an error performing that action!", "profile-builder" ) ); - - elseif ( $todo == 'delete' ){ - $sql_result = $wpdb->delete( $wpdb->base_prefix.'signups', array( 'user_login' => $results[0]->user_login, 'user_email' => $results[0]->user_email ) ); - if ( $sql_result ) - die( 'ok' ); - - else - die( __( "The selected user couldn't be deleted", "profile-builder" ) ); - - }elseif ( $todo == 'confirm' ){ - die( wppb_manual_activate_signup( $results[0]->activation_key ) ); - - }elseif ( $todo == 'resend' ){ - $sql_result = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM " . $wpdb->base_prefix . "signups WHERE user_login = %s AND user_email = %s", $results[0]->user_login, $results[0]->user_email ), ARRAY_A ); - - if ( $sql_result ){ - wppb_signup_user_notification( trim( $sql_result['user_login'] ), trim( $sql_result['user_email'] ), $sql_result['activation_key'], $sql_result['meta'] ); - - die( __( "Email notification resent to user", "profile-builder" ) ); - } - - } - } - - die( __("You either don't have permission for that action or there was an error!", "profile-builder") ); -} - - - -// FUNCTIONS USED BOTH ON THE REGISTRATION PAGE AND THE EMAIL CONFIRMATION TABLE - -// Hook to add AP user meta after signup autentification -add_action( 'wpmu_activate_user', 'wppb_add_meta_to_user_on_activation', 10, 3 ); - -//function that adds AP user meta after signup autentification and it is also used when editing the user uprofile -function wppb_add_meta_to_user_on_activation( $user_id, $password, $meta ){ - $user = new WP_User( $user_id ); - - //copy the data from the meta field (default fields) - if( !empty( $meta['first_name'] ) ) - update_user_meta( $user_id, 'first_name', $meta['first_name'] ); - if( !empty( $meta['last_name'] ) ) - update_user_meta( $user_id, 'last_name', $meta['last_name'] ); - if( !empty( $meta['nickname'] ) ) - update_user_meta( $user_id, 'nickname', $meta['nickname'] ); - if( !empty( $meta['user_url'] ) ) - wp_update_user(array('ID' => $user_id, 'user_url' => $meta['user_url'])); - if( !empty( $meta['aim'] ) ) - update_user_meta( $user_id, 'aim', $meta['aim'] ); - if( !empty( $meta['yim'] ) ) - update_user_meta( $user_id, 'yim', $meta['yim'] ); - if( !empty( $meta['jabber'] ) ) - update_user_meta( $user_id, 'jabber', $meta['jabber'] ); - if( !empty( $meta['description'] ) ) - update_user_meta( $user_id, 'description', $meta['description'] ); - - if( !empty( $meta['role'] ) ) - $user->set_role( $meta['role'] ); //update the users role (s)he registered for - - if( !empty( $meta['first_name'] ) && !empty( $meta['last_name'] ) ) - wp_update_user(array('ID' => $user_id, 'display_name' => $meta['first_name'].' '.$meta['last_name'] )); - else if( !empty( $meta['nickname'] ) ) - wp_update_user(array('ID' => $user_id, 'display_name' => $meta['nickname'] )); - - //copy the data from the meta fields (custom fields) - $manage_fields = apply_filters( 'wppb_form_fields', get_option( 'wppb_manage_fields', 'not_set' ), array( 'meta' => $meta, 'user_id' => $user_id, 'context' => 'user_activation' ) ); - if ( $manage_fields != 'not_set' ){ - foreach ( $manage_fields as $key => $value){ - switch ( $value['field'] ) { - case 'Input': - case 'Input (Hidden)': - case 'Checkbox': - case 'Checkbox (Terms and Conditions)': - case 'Radio': - case 'Select': - case 'Select (Country)': - case 'Select (Multiple)': - case 'Select (Timezone)': - case 'Datepicker': - case 'Textarea':{ - if ( isset( $meta[$value['meta-name']] ) ) - update_user_meta( $user_id, $value['meta-name'], trim( $meta[$value['meta-name']] ) ); - break; - } - case 'Timepicker':{ - if ( isset( $meta[$value['meta-name']] ) ) { - $time = $meta[$value['meta-name']]; - if( !empty( $time['hours'] ) && !empty( $time['minutes'] ) ) { - update_user_meta( $user_id, $value['meta-name'], $time['hours'] . ':' . $time['minutes'] ); - } - - } - break; - } - case 'Map':{ - if ( isset( $meta[$value['meta-name']] ) ) { - // Add new markers - if( is_array( $meta[$value['meta-name']] ) ) { - foreach( $meta[$value['meta-name']] as $key => $position ) - update_user_meta( $user_id, $value['meta-name'] . '_' . $key, $position ); - } - } - break; - } - case 'Upload':{ - if ( isset( $meta[$value['meta-name']] ) ){ - if( !empty( $meta[$value['meta-name']] ) ) { - if (is_numeric($meta[$value['meta-name']])) { - update_user_meta($user_id, $value['meta-name'], trim($meta[$value['meta-name']])); - } else { - $wp_upload_array = wp_upload_dir(); // Array of key => value pairs - - $file = trim($meta[$value['meta-name']]); - $file_name = substr($file, strpos($file, '_attachment_') + 12); - - $random_user_number = apply_filters('wppb_register_wpmu_upload_random_user_number2', substr(md5($user->data->user_email), 0, 12), $user, $meta); - - $old_path_on_disk = $wp_upload_array['basedir'] . '/profile_builder/attachments/' . substr($file, strpos($file, 'wpmuRandomID_')); - if (PHP_OS == "WIN32" || PHP_OS == "WINNT") - $old_path_on_disk = str_replace('\\', '/', $old_path_on_disk); - - $new_path_on_disk = $wp_upload_array['basedir'] . '/profile_builder/attachments/userID_' . $user_id . '_attachment_' . $file_name; - if (PHP_OS == "WIN32" || PHP_OS == "WINNT") - $new_path_on_disk = str_replace('\\', '/', $new_path_on_disk); - - if (rename($old_path_on_disk, $new_path_on_disk)) - update_user_meta($user_id, $value['meta-name'], $wp_upload_array['baseurl'] . '/profile_builder/attachments/userID_' . $user_id . '_attachment_' . $file_name); - } - } - else{ - update_user_meta( $user_id, $value['meta-name'], '' ); - } - } - break; - } - case 'Avatar':{ - if ( isset( $meta[$value['meta-name']] ) ) { - if( !empty( $meta[$value['meta-name']] ) ) { - if (is_numeric($meta[$value['meta-name']])) { - update_user_meta($user_id, $value['meta-name'], trim($meta[$value['meta-name']])); - } else { - $wp_upload_array = wp_upload_dir(); // Array of key => value pairs - - $file = trim($meta[$value['meta-name']]); - $file_name = substr($file, strpos($file, '_originalAvatar_') + 16); - - $random_user_number = apply_filters('wppb_register_wpmu_avatar_random_user_number2', substr(md5($user->data->user_email), 0, 12), $user, $meta); - - $old_path_on_disk = $wp_upload_array['basedir'] . '/profile_builder/avatars/' . substr($file, strpos($file, 'wpmuRandomID_')); - if (PHP_OS == "WIN32" || PHP_OS == "WINNT") - $old_path_on_disk = str_replace('\\', '/', $old_path_on_disk); - - $new_path_on_disk = $wp_upload_array['basedir'] . '/profile_builder/avatars/userID_' . $user_id . '_originalAvatar_' . $file_name; - if (PHP_OS == "WIN32" || PHP_OS == "WINNT") - $new_path_on_disk = str_replace('\\', '/', $new_path_on_disk); - - if (rename($old_path_on_disk, $new_path_on_disk)) { - $wp_filetype = wp_check_filetype(basename($file_name), null); - $attachment = array('post_mime_type' => $wp_filetype['type'], - 'post_title' => $file_name, - 'post_content' => '', - 'post_status' => 'inherit' - ); - - $attach_id = wp_insert_attachment($attachment, $new_path_on_disk); - - $avatar = image_downsize($attach_id, 'thumbnail'); - - update_user_meta($user_id, $value['meta-name'], $avatar[0]); - update_user_meta($user_id, 'avatar_directory_path_' . $value['id'], $new_path_on_disk); - update_user_meta($user_id, 'resized_avatar_' . $value['id'] . '_relative_path', $new_path_on_disk); - wppb_resize_avatar($user_id); - } - } - } - else{ - update_user_meta( $user_id, $value['meta-name'], '' ); - } - break; - } - } - case 'Default - Blog Details':{ - if ( is_multisite() && isset( $meta['wppb_create_new_site_checkbox'] ) && $meta['wppb_create_new_site_checkbox'] == 'yes' ) { - $blog_url = $meta['wppb_blog_url']; - $blog_title = $meta['wppb_blog_title']; - - $privacy['public'] = ( isset( $meta['wppb_blog_privacy'] ) && 'Yes' == $meta['wppb_blog_privacy'] ) ? true : false; - $blog_details = wpmu_validate_blog_signup( $blog_url, $blog_title ); - if ( empty($blog_details['errors']->errors['blogname']) && empty($blog_details['errors']->errors['blog_title'])) { - wpmu_create_blog( $blog_details['domain'], $blog_details['path'], $blog_details['blog_title'], $user_id, $privacy ); - } - } - } - default: { - if ( isset( $meta[$value['meta-name']] ) ) { - update_user_meta($user_id, $value['meta-name'], $meta[$value['meta-name']]); - } - do_action('wppb_add_meta_on_user_activation_' . Wordpress_Creation_Kit_PB::wck_generate_slug($value['field']), $user_id, $password, $meta, $value); - } - } - } - } - do_action( 'wppb_add_other_meta_on_user_activation', $user_id, $meta ); -} - - -// function to add the new user to the signup table if email confirmation is selected as active or it is a wpmu installation -function wppb_signup_user( $username, $user_email, $meta = '' ) { - global $wpdb; - - // Format data - $user = sanitize_user( $username, true ); - if( is_multisite() ) - $user = preg_replace( '/\s+/', '', $user ); - - $user_email = sanitize_email( $user_email ); - $activation_key = substr( md5( time() . rand() . $user_email ), 0, 16 ); - $meta = serialize( $meta ); - - // change User Registered date and time according to timezone selected in WordPress settings - $wppb_get_date = wppb_get_date_by_timezone(); - - if( isset( $wppb_get_date ) ) { - $wppb_user_registered = $wppb_get_date; - } else { - $wppb_user_registered = current_time( 'mysql', true ); - } - - if ( is_multisite() ) - $wpdb->insert( $wpdb->signups, array('domain' => '', 'path' => '', 'title' => '', 'user_login' => $user, 'user_email' => $user_email, 'registered' => $wppb_user_registered, 'activation_key' => $activation_key, 'meta' => $meta ) ); - else - $wpdb->insert( $wpdb->prefix.'signups', array('domain' => '', 'path' => '', 'title' => '', 'user_login' => $user, 'user_email' => $user_email, 'registered' => $wppb_user_registered, 'activation_key' => $activation_key, 'meta' => $meta ) ); - - do_action ( 'wppb_signup_user', $username, $user_email, $activation_key, $meta ); - - wppb_signup_user_notification( $username, $user_email, $activation_key, $meta ); -} - -/** - * Notify user of signup success. - * - * Filter 'wppb_signup_user_notification_filter' to bypass this function or - * replace it with your own notification behavior. - * - * Filter 'wppb_signup_user_notification_email' and - * 'wppb_signup_user_notification_subject' to change the content - * and subject line of the email sent to newly registered users. - * - * @param string $user The user's login name. - * @param string $user_email The user's email address. - * @param array $meta By default, an empty array. - * @param string $activation_key The activation key created in wppb_signup_user() - * @return bool - */ -function wppb_signup_user_notification( $user, $user_email, $activation_key, $meta = '' ) { - if ( !apply_filters( 'wppb_signup_user_notification_filter', $user, $user_email, $activation_key, $meta ) ) - return false; - - $wppb_general_settings = get_option( 'wppb_general_settings' ); - $admin_email = get_site_option( 'admin_email' ); - - if ( $admin_email == '' ) - $admin_email = 'support@' . $_SERVER['SERVER_NAME']; - - $from_name = apply_filters ( 'wppb_signup_user_notification_email_from_field', get_bloginfo( 'name' ) ); - - $message_headers = apply_filters ( 'wppb_signup_user_notification_from', "From: \"{$from_name}\" <{$admin_email}>\n" . "Content-Type: text/plain; charset=\"" . get_option('blog_charset') . "\"\n" ); - - if( isset( $wppb_general_settings['activationLandingPage'] ) && ( trim( $wppb_general_settings['activationLandingPage'] ) != '' ) ) { - $registration_page_url = add_query_arg( array('activation_key' => $activation_key), get_permalink( $wppb_general_settings['activationLandingPage'] ) ); - } else { - $registration_page_url = 'not_set'; - } - - if ( $registration_page_url == 'not_set' ){ - global $post; - if( !empty( $post->ID ) ) - $permalink = get_permalink( $post->ID ); - else - $permalink = get_bloginfo( 'url' ); - - if( !empty( $post->post_content ) ) - $post_content = $post->post_content; - else - $post_content = ''; - - $registration_page_url = ( ( strpos( $post_content, '[wppb-register' ) !== false ) ? add_query_arg( array( 'activation_key' => $activation_key ), $permalink ) : add_query_arg( array( 'activation_key' => $activation_key ), get_bloginfo( 'url' ) ) ); - } - - $subject = sprintf( __( '[%1$s] Activate %2$s', 'profile-builder'), $from_name, $user ); - $subject = apply_filters( 'wppb_signup_user_notification_email_subject', $subject, $user_email, $user, $activation_key, $registration_page_url, $meta, $from_name, 'wppb_user_emailc_registr_w_email_confirm_email_subject' ); - - $message = sprintf( __( "To activate your user, please click the following link:

            %s%s%s

            After you activate it you will receive yet *another email* with your login.", "profile-builder" ), '', $registration_page_url, '.' ); - $message = apply_filters( 'wppb_signup_user_notification_email_content', $message, $user_email, $user, $activation_key, $registration_page_url, $meta, $from_name, 'wppb_user_emailc_registr_w_email_confirm_email_content' ); - - $message_context = 'email_user_activate'; - - wppb_mail( $user_email, $subject, $message, $from_name, $message_context ); - - return true; -} - - -/** - * Activate a signup. - * - * - * @param string $activation_key The activation key provided to the user. - * @return array An array containing information about the activated user and/or blog - */ -function wppb_manual_activate_signup( $activation_key ) { - global $wpdb; - - if ( is_multisite() ) - $signup = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->signups WHERE activation_key = %s", $activation_key ) ); - else - $signup = $wpdb->get_row( $wpdb->prepare("SELECT * FROM ".$wpdb->prefix."signups WHERE activation_key = %s", $activation_key) ); - - if ( !empty( $signup ) && !$signup->active ){ - $meta = unserialize( $signup->meta ); - $user_login = esc_sql( $signup->user_login ); - $user_email = esc_sql( $signup->user_email ); - /* the password is in hashed form in the signup table and we will copy it later to the user */ - $password = NULL; - - $user_id = username_exists($user_login); - - if ( ! $user_id ) - $user_id = wppb_create_user( $user_login, $password, $user_email ); - else - $user_already_exists = true; - - if ( !$user_id ) - return __( 'Could not create user!', 'profile-builder' ); - - elseif ( isset( $user_already_exists ) && ( $user_already_exists == true ) ) - return __( 'That username is already activated!', 'profile-builder' ); - - else{ - $now = current_time('mysql', true); - - $retVal = ( is_multisite() ? $wpdb->update( $wpdb->signups, array('active' => 1, 'activated' => $now), array('activation_key' => $activation_key) ) : $wpdb->update( $wpdb->base_prefix.'signups', array('active' => 1, 'activated' => $now), array('activation_key' => $activation_key) ) ); - - wppb_add_meta_to_user_on_activation( $user_id, '', $meta ); - - /* copy the hashed password from signup meta to wp user table */ - if( !empty( $meta['user_pass'] ) ){ - /* we might still have the base64 encoded password in signups and not the hash */ - if( base64_encode(base64_decode($meta['user_pass'], true)) === $meta['user_pass'] ) - $meta['user_pass'] = wp_hash_password( $meta['user_pass'] ); - - $wpdb->update( $wpdb->users, array('user_pass' => $meta['user_pass'] ), array('ID' => $user_id) ); - //This is required so that the APC cached data is updated with the new password. Thanks to @foliovision - wp_cache_delete( $user_id, 'users' ); - } - - wppb_notify_user_registration_email( get_bloginfo( 'name' ), $user_login, $user_email, 'sending', $password, ( isset( $wppb_general_settings['adminApproval'] ) ? $wppb_general_settings['adminApproval'] : 'no' ) ); - - do_action('wppb_activate_user', $user_id, $password, $meta); - return ( $retVal ? 'ok' : __( 'There was an error while trying to activate the user', 'profile-builder' ) ); - } - } -} - -/** - * Create a user. - * - * @param string $user_name The new user's login name. - * @param string $password The new user's password. - * @param string $email The new user's email address. - * @return mixed Returns false on failure, or int $user_id on success - */ -function wppb_create_user( $user_name, $password, $email) { - if( is_email( $user_name ) ) - $user_name = apply_filters( 'wppb_generated_random_username', Wordpress_Creation_Kit_PB::wck_generate_slug( trim( $user_name ) ), $user_name ); - else { - $user_name = sanitize_user($user_name, true); - if( is_multisite() ) - $user_name = preg_replace( '/\s+/', '', $user_name ); - } - - - $user_id = wp_create_user( $user_name, $password, $email ); - if ( is_wp_error($user_id) ) - return false; - - // Newly created users have no roles or caps until they are added to a blog. - delete_user_option( $user_id, 'capabilities' ); - delete_user_option( $user_id, 'user_level' ); - - do_action( 'wppb_new_user', $user_id ); - - return $user_id; -} - -//send an email to the admin regarding each and every new subscriber, and - if selected - to the user himself -function wppb_notify_user_registration_email( $bloginfo, $user_name, $email, $send_credentials_via_email, $password, $adminApproval ){ - - /* if login with email is enabled user_name gets the value of the users email */ - $wppb_general_settings = get_option( 'wppb_general_settings' ); - if ( isset( $wppb_general_settings['loginWith'] ) && ( $wppb_general_settings['loginWith'] == 'email' ) ) { - $user_name = $email; - } - - //send email to the admin - $message_from = apply_filters( 'wppb_register_from_email_message_admin_email', $bloginfo ); - - $message_subject = '['.$message_from.'] '.__( 'A new subscriber has (been) registered!', 'profile-builder' ); - $message_subject = apply_filters ('wppb_register_admin_email_subject_without_admin_approval', $message_subject, $email, $password, $message_from, 'wppb_admin_emailc_default_registration_email_subject' ); - - $message_content = sprintf( __( 'New subscriber on %1$s.

            Username:%2$s
            E-mail:%3$s
            ', 'profile-builder'), $message_from, $user_name, $email ); - - $message_context = 'email_admin_new_subscriber'; - - if ( $adminApproval == 'yes' ) { - $user_data = get_user_by( 'email', $email ); - - $wppb_generalSettings = get_option( 'wppb_general_settings', 'not_found' ); - - $adminApproval_mailAdmin = 0; - - if( $wppb_generalSettings != 'not_found' && ! empty( $wppb_generalSettings['adminApprovalOnUserRole'] ) ) { - foreach( $user_data->roles as $role ) { - if( in_array( $role, $wppb_generalSettings['adminApprovalOnUserRole'] ) ) { - if( ! current_user_can( 'delete_users' ) ) { - $adminApproval_mailAdmin = 1; - } - } - } - } else { - if( ! current_user_can( 'delete_users' ) ) { - $adminApproval_mailAdmin = 1; - } - } - - if( $adminApproval_mailAdmin == 1 ) { - $message_subject = apply_filters( 'wppb_register_admin_email_subject_with_admin_approval', $message_subject, $email, $password, $message_from, 'wppb_admin_emailc_registration_with_admin_approval_email_subject' ); - - $message_content .= wppb_adminApproval_adminEmailContent(); - $message_content = apply_filters( 'wppb_register_admin_email_message_with_admin_approval', $message_content, $email, $password, $message_from, 'wppb_admin_emailc_registration_with_admin_approval_email_content' ); - - $message_context = 'email_admin_approve'; - } - else{ - $message_content = apply_filters( 'wppb_register_admin_email_message_without_admin_approval', $message_content, $email, $password, $message_from, 'wppb_admin_emailc_default_registration_email_content' ); - } - } else { - $message_content = apply_filters( 'wppb_register_admin_email_message_without_admin_approval', $message_content, $email, $password, $message_from, 'wppb_admin_emailc_default_registration_email_content' ); - } - - if ( trim( $message_content ) != '' ){ - $admin_email = apply_filters('wppb_send_to_admin_email', get_option('admin_email'), get_user_by( 'email', $email ), $message_context); - wppb_mail( $admin_email, $message_subject, $message_content, $message_from, $message_context ); - } - - - - //send an email to the newly registered user, if this option was selected - if ( isset( $send_credentials_via_email ) && ( $send_credentials_via_email == 'sending' ) ){ - $user_message_from = apply_filters( 'wppb_register_from_email_message_user_email', $bloginfo ); - - $user_message_subject = sprintf( __( '[%1$s] Your new account information', 'profile-builder' ), $user_message_from, $user_name, $password ); - $user_message_subject = apply_filters( 'wppb_register_user_email_subject_without_admin_approval', $user_message_subject, $email, $password, $user_message_from, 'wppb_user_emailc_default_registration_email_subject' ); - - if ( $password === NULL ) { - $password = __( 'Your selected password at signup', 'profile-builder' ); - } - - $send_password = apply_filters( 'wppb_send_password_in_default_email_message', false ); - if( !$send_password ) - $user_message_content = sprintf( __( 'Welcome to %1$s!


            Your username is:%2$s', 'profile-builder' ), $user_message_from, $user_name ); - else - $user_message_content = sprintf( __( 'Welcome to %1$s!


            Your username is:%2$s and password:%3$s', 'profile-builder' ), $user_message_from, $user_name, $password ); - - if ( $password === __( 'Your selected password at signup', 'profile-builder' ) ) { - $password = NULL; - } - - $user_message_context = 'email_user_account_info'; - - if ( $adminApproval == 'yes' ){ - $user_data = get_user_by( 'email', $email ); - - $wppb_generalSettings = get_option( 'wppb_general_settings', 'not_found' ); - - $adminApproval_mailUser = 0; - - if( $wppb_generalSettings != 'not_found' && ! empty( $wppb_generalSettings['adminApprovalOnUserRole'] ) ) { - foreach( $user_data->roles as $role ) { - if( in_array( $role, $wppb_generalSettings['adminApprovalOnUserRole'] ) ) { - if( ! current_user_can( 'delete_users' ) ) { - $adminApproval_mailUser = 1; - } - } - } - } else { - if( ! current_user_can( 'delete_users' ) ) { - $adminApproval_mailUser = 1; - } - } - - if( $adminApproval_mailUser == 1 ) { - $user_message_subject = apply_filters( 'wppb_register_user_email_subject_with_admin_approval', $user_message_subject, $email, $password, $user_message_subject, 'wppb_user_emailc_registration_with_admin_approval_email_subject' ); - - $user_message_content .= wppb_adminApproval_userEmailContent(); - - $user_message_context = 'email_user_need_approval'; - - $user_message_content = apply_filters( 'wppb_register_user_email_message_with_admin_approval', $user_message_content, $email, $password, $user_message_subject, 'wppb_user_emailc_registration_with_admin_approval_email_content' ); - } - else{ - $user_message_content = apply_filters( 'wppb_register_user_email_message_without_admin_approval', $user_message_content, $email, $password, $user_message_subject, 'wppb_user_emailc_default_registration_email_content' ); - } - } else - $user_message_content = apply_filters( 'wppb_register_user_email_message_without_admin_approval', $user_message_content, $email, $password, $user_message_subject, 'wppb_user_emailc_default_registration_email_content' ); - - $message_sent = wppb_mail( $email, $user_message_subject, $user_message_content, $user_message_from, $user_message_context ); - - return ( ( $message_sent ) ? 2 : 1 ); - } -} - - -// function with content to be added in email sent to admin if "Admin Approval" is on -function wppb_adminApproval_adminEmailContent() { - $emailContent = '
            ' . __( 'The "Admin Approval" feature was activated at the time of registration, so please remember that you need to approve this user before he/she can log in!', 'profile-builder') ."\r\n"; - - return $emailContent; -} - - -// function with content to be added in email sent to user if "Admin Approval" is on -function wppb_adminApproval_userEmailContent() { - $emailContent = '

            ' . __( 'Before you can access your account, an administrator needs to approve it. You will be notified via email.', 'profile-builder' ); - - return $emailContent; -} -// END FUNCTIONS USED BOTH ON THE REGISTRATION PAGE AND THE EMAIL CONFIRMATION TABLE - - -// Set up the AJAX hooks -add_action( 'wp_ajax_wppb_get_unconfirmed_email_number', 'wppb_get_unconfirmed_email_number' ); -add_action( 'wp_ajax_wppb_handle_email_confirmation_cases', 'wppb_handle_email_confirmation_cases' ); - - -$wppb_general_settings = get_option( 'wppb_general_settings', 'not_found' ); -if( $wppb_general_settings != 'not_found' ) - if( !empty($wppb_general_settings['emailConfirmation'] ) && ( $wppb_general_settings['emailConfirmation'] == 'yes' ) ){ - if ( is_multisite() ){ - /* don't display on network admin */ - if( strpos($_SERVER['SCRIPT_NAME'], 'users.php') && !is_network_admin() ){ //global $pagenow doesn't seem to work - add_action( 'admin_head', 'wppb_add_pending_users_header_script' ); - } - }else{ - global $pagenow; - if ( $pagenow == 'users.php' ){ - add_action( 'admin_head', 'wppb_add_pending_users_header_script' ); - } - } - - if ( file_exists ( WPPB_PLUGIN_DIR . '/features/admin-approval/admin-approval.php' ) ) - add_action( 'user_register', 'wppb_update_user_status_on_admin_registration' ); - } - - -// function to delete the users from the _signups table also -function wppb_delete_user_from_signups( $user_id ) { - global $wpdb; - - $user = get_user_by( 'id', $user_id ); - $wpdb->delete( $wpdb->base_prefix.'signups', array( 'user_email' => $user->user_email ) ); -} +charset ) ) + $charset_collate = "DEFAULT CHARACTER SET ".$wpdb->charset; + if ( ! empty( $wpdb->collate ) ) + $charset_collate .= " COLLATE ".$wpdb->collate; + $tableName = $wpdb->prefix.'signups'; + + $sql = " + CREATE TABLE $tableName ( + domain varchar(200) NOT NULL default '', + path varchar(100) NOT NULL default '', + title longtext NOT NULL, + user_login varchar(60) NOT NULL default '', + user_email varchar(100) NOT NULL default '', + registered datetime NOT NULL default '0000-00-00 00:00:00', + activated datetime NOT NULL default '0000-00-00 00:00:00', + active tinyint(1) NOT NULL default '0', + activation_key varchar(50) NOT NULL default '', + meta longtext, + KEY activation_key (activation_key), + KEY domain (domain) + ) $charset_collate;"; + + require_once(ABSPATH . 'wp-admin/includes/upgrade.php'); + $res = dbDelta($sql); + } +} +add_action( 'update_option_wppb_general_settings', 'wppb_signup_schema', 10, 2 ); + + +//function to add new tab in the default WP userlisting with all the users who didn't confirm their account yet +function wppb_add_pending_users_header_script(){ +?> + +get_results("SELECT * FROM ".$wpdb->base_prefix."signups WHERE active = 0"); + foreach ($results as $result){ + if( !empty( $result->meta ) ){ + $user_meta = maybe_unserialize( $result->meta ); + if( empty( $user_meta['registered_for_blog_id'] ) || $user_meta['registered_for_blog_id'] == get_current_blog_id() ){ + $number_of_users++; + } + } + } + + header( 'Content-type: application/json' ); + die( json_encode( array( 'number' => $number_of_users ) ) ); +} + + +function wppb_handle_email_confirmation_cases() { + global $wpdb; + + $todo = sanitize_text_field($_POST['todo']); + $user_email = sanitize_email($_POST['user_email']); + + if ( current_user_can( 'delete_users' ) ) + if ( ( $todo != '' ) && ( $user_email != '' ) ){ + + $results = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM " . $wpdb->base_prefix . "signups WHERE active = 0 AND user_email = %s", $user_email ) ); + + if ( count( $results ) != 1 ) + die( __( "There was an error performing that action!", "profile-builder" ) ); + + elseif ( $todo == 'delete' ){ + $sql_result = $wpdb->delete( $wpdb->base_prefix.'signups', array( 'user_login' => $results[0]->user_login, 'user_email' => $results[0]->user_email ) ); + if ( $sql_result ) + die( 'ok' ); + + else + die( __( "The selected user couldn't be deleted", "profile-builder" ) ); + + }elseif ( $todo == 'confirm' ){ + die( wppb_manual_activate_signup( $results[0]->activation_key ) ); + + }elseif ( $todo == 'resend' ){ + $sql_result = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM " . $wpdb->base_prefix . "signups WHERE user_login = %s AND user_email = %s", $results[0]->user_login, $results[0]->user_email ), ARRAY_A ); + + if ( $sql_result ){ + wppb_signup_user_notification( trim( $sql_result['user_login'] ), trim( $sql_result['user_email'] ), $sql_result['activation_key'], $sql_result['meta'] ); + + die( __( "Email notification resent to user", "profile-builder" ) ); + } + + } + } + + die( __("You either don't have permission for that action or there was an error!", "profile-builder") ); +} + + + +// FUNCTIONS USED BOTH ON THE REGISTRATION PAGE AND THE EMAIL CONFIRMATION TABLE + +// Hook to add AP user meta after signup autentification +add_action( 'wpmu_activate_user', 'wppb_add_meta_to_user_on_activation', 10, 3 ); + +//function that adds AP user meta after signup autentification and it is also used when editing the user uprofile +function wppb_add_meta_to_user_on_activation( $user_id, $password, $meta ){ + $user = new WP_User( $user_id ); + + //copy the data from the meta field (default fields) + if( !empty( $meta['first_name'] ) ) + update_user_meta( $user_id, 'first_name', $meta['first_name'] ); + if( !empty( $meta['last_name'] ) ) + update_user_meta( $user_id, 'last_name', $meta['last_name'] ); + if( !empty( $meta['nickname'] ) ) + update_user_meta( $user_id, 'nickname', $meta['nickname'] ); + if( !empty( $meta['user_url'] ) ) + wp_update_user(array('ID' => $user_id, 'user_url' => $meta['user_url'])); + if( !empty( $meta['aim'] ) ) + update_user_meta( $user_id, 'aim', $meta['aim'] ); + if( !empty( $meta['yim'] ) ) + update_user_meta( $user_id, 'yim', $meta['yim'] ); + if( !empty( $meta['jabber'] ) ) + update_user_meta( $user_id, 'jabber', $meta['jabber'] ); + if( !empty( $meta['description'] ) ) + update_user_meta( $user_id, 'description', $meta['description'] ); + + if( !empty( $meta['role'] ) ) + $user->set_role( $meta['role'] ); //update the users role (s)he registered for + + if( !empty( $meta['first_name'] ) && !empty( $meta['last_name'] ) ) + wp_update_user(array('ID' => $user_id, 'display_name' => $meta['first_name'].' '.$meta['last_name'] )); + else if( !empty( $meta['nickname'] ) ) + wp_update_user(array('ID' => $user_id, 'display_name' => $meta['nickname'] )); + + //copy the data from the meta fields (custom fields) + $manage_fields = apply_filters( 'wppb_form_fields', get_option( 'wppb_manage_fields', 'not_set' ), array( 'meta' => $meta, 'user_id' => $user_id, 'context' => 'user_activation' ) ); + if ( $manage_fields != 'not_set' ){ + foreach ( $manage_fields as $key => $value){ + switch ( $value['field'] ) { + case 'Input': + case 'Input (Hidden)': + case 'Checkbox': + case 'Checkbox (Terms and Conditions)': + case 'Radio': + case 'Select': + case 'Select (Country)': + case 'Select (Multiple)': + case 'Select (Timezone)': + case 'Datepicker': + case 'Textarea':{ + if ( isset( $meta[$value['meta-name']] ) ) + update_user_meta( $user_id, $value['meta-name'], trim( $meta[$value['meta-name']] ) ); + break; + } + case 'Timepicker':{ + if ( isset( $meta[$value['meta-name']] ) ) { + $time = $meta[$value['meta-name']]; + if( !empty( $time['hours'] ) && !empty( $time['minutes'] ) ) { + update_user_meta( $user_id, $value['meta-name'], $time['hours'] . ':' . $time['minutes'] ); + } + + } + break; + } + case 'Map':{ + if ( isset( $meta[$value['meta-name']] ) ) { + // Add new markers + if( is_array( $meta[$value['meta-name']] ) ) { + foreach( $meta[$value['meta-name']] as $key => $position ) + update_user_meta( $user_id, $value['meta-name'] . '_' . $key, $position ); + } + } + break; + } + case 'Upload':{ + if ( isset( $meta[$value['meta-name']] ) ){ + if( !empty( $meta[$value['meta-name']] ) ) { + if (is_numeric($meta[$value['meta-name']])) { + update_user_meta($user_id, $value['meta-name'], trim($meta[$value['meta-name']])); + } else { + $wp_upload_array = wp_upload_dir(); // Array of key => value pairs + + $file = trim($meta[$value['meta-name']]); + $file_name = substr($file, strpos($file, '_attachment_') + 12); + + $random_user_number = apply_filters('wppb_register_wpmu_upload_random_user_number2', substr(md5($user->data->user_email), 0, 12), $user, $meta); + + $old_path_on_disk = $wp_upload_array['basedir'] . '/profile_builder/attachments/' . substr($file, strpos($file, 'wpmuRandomID_')); + if (PHP_OS == "WIN32" || PHP_OS == "WINNT") + $old_path_on_disk = str_replace('\\', '/', $old_path_on_disk); + + $new_path_on_disk = $wp_upload_array['basedir'] . '/profile_builder/attachments/userID_' . $user_id . '_attachment_' . $file_name; + if (PHP_OS == "WIN32" || PHP_OS == "WINNT") + $new_path_on_disk = str_replace('\\', '/', $new_path_on_disk); + + if (rename($old_path_on_disk, $new_path_on_disk)) + update_user_meta($user_id, $value['meta-name'], $wp_upload_array['baseurl'] . '/profile_builder/attachments/userID_' . $user_id . '_attachment_' . $file_name); + } + } + else{ + update_user_meta( $user_id, $value['meta-name'], '' ); + } + } + break; + } + case 'Avatar':{ + if ( isset( $meta[$value['meta-name']] ) ) { + if( !empty( $meta[$value['meta-name']] ) ) { + if (is_numeric($meta[$value['meta-name']])) { + update_user_meta($user_id, $value['meta-name'], trim($meta[$value['meta-name']])); + } else { + $wp_upload_array = wp_upload_dir(); // Array of key => value pairs + + $file = trim($meta[$value['meta-name']]); + $file_name = substr($file, strpos($file, '_originalAvatar_') + 16); + + $random_user_number = apply_filters('wppb_register_wpmu_avatar_random_user_number2', substr(md5($user->data->user_email), 0, 12), $user, $meta); + + $old_path_on_disk = $wp_upload_array['basedir'] . '/profile_builder/avatars/' . substr($file, strpos($file, 'wpmuRandomID_')); + if (PHP_OS == "WIN32" || PHP_OS == "WINNT") + $old_path_on_disk = str_replace('\\', '/', $old_path_on_disk); + + $new_path_on_disk = $wp_upload_array['basedir'] . '/profile_builder/avatars/userID_' . $user_id . '_originalAvatar_' . $file_name; + if (PHP_OS == "WIN32" || PHP_OS == "WINNT") + $new_path_on_disk = str_replace('\\', '/', $new_path_on_disk); + + if (rename($old_path_on_disk, $new_path_on_disk)) { + $wp_filetype = wp_check_filetype(basename($file_name), null); + $attachment = array('post_mime_type' => $wp_filetype['type'], + 'post_title' => $file_name, + 'post_content' => '', + 'post_status' => 'inherit' + ); + + $attach_id = wp_insert_attachment($attachment, $new_path_on_disk); + + $avatar = image_downsize($attach_id, 'thumbnail'); + + update_user_meta($user_id, $value['meta-name'], $avatar[0]); + update_user_meta($user_id, 'avatar_directory_path_' . $value['id'], $new_path_on_disk); + update_user_meta($user_id, 'resized_avatar_' . $value['id'] . '_relative_path', $new_path_on_disk); + wppb_resize_avatar($user_id); + } + } + } + else{ + update_user_meta( $user_id, $value['meta-name'], '' ); + } + break; + } + } + case 'Default - Blog Details':{ + if ( is_multisite() && isset( $meta['wppb_create_new_site_checkbox'] ) && $meta['wppb_create_new_site_checkbox'] == 'yes' ) { + $blog_url = $meta['wppb_blog_url']; + $blog_title = $meta['wppb_blog_title']; + + $privacy['public'] = ( isset( $meta['wppb_blog_privacy'] ) && 'Yes' == $meta['wppb_blog_privacy'] ) ? true : false; + $blog_details = wpmu_validate_blog_signup( $blog_url, $blog_title ); + if ( empty($blog_details['errors']->errors['blogname']) && empty($blog_details['errors']->errors['blog_title'])) { + wpmu_create_blog( $blog_details['domain'], $blog_details['path'], $blog_details['blog_title'], $user_id, $privacy ); + } + } + } + default: { + if ( isset( $meta[$value['meta-name']] ) ) { + update_user_meta($user_id, $value['meta-name'], $meta[$value['meta-name']]); + } + do_action('wppb_add_meta_on_user_activation_' . Wordpress_Creation_Kit_PB::wck_generate_slug($value['field']), $user_id, $password, $meta, $value); + } + } + } + } + do_action( 'wppb_add_other_meta_on_user_activation', $user_id, $meta ); +} + + +// function to add the new user to the signup table if email confirmation is selected as active or it is a wpmu installation +function wppb_signup_user( $username, $user_email, $meta = '' ) { + global $wpdb; + + // Format data + $user = sanitize_user( $username, true ); + if( is_multisite() ) + $user = preg_replace( '/\s+/', '', $user ); + + $user_email = sanitize_email( $user_email ); + $activation_key = substr( md5( time() . rand() . $user_email ), 0, 16 ); + $meta = serialize( $meta ); + + // change User Registered date and time according to timezone selected in WordPress settings + $wppb_get_date = wppb_get_date_by_timezone(); + + if( isset( $wppb_get_date ) ) { + $wppb_user_registered = $wppb_get_date; + } else { + $wppb_user_registered = current_time( 'mysql', true ); + } + + if ( is_multisite() ) + $wpdb->insert( $wpdb->signups, array('domain' => '', 'path' => '', 'title' => '', 'user_login' => $user, 'user_email' => $user_email, 'registered' => $wppb_user_registered, 'activation_key' => $activation_key, 'meta' => $meta ) ); + else + $wpdb->insert( $wpdb->prefix.'signups', array('domain' => '', 'path' => '', 'title' => '', 'user_login' => $user, 'user_email' => $user_email, 'registered' => $wppb_user_registered, 'activation_key' => $activation_key, 'meta' => $meta ) ); + + do_action ( 'wppb_signup_user', $username, $user_email, $activation_key, $meta ); + + wppb_signup_user_notification( $username, $user_email, $activation_key, $meta ); +} + +/** + * Notify user of signup success. + * + * Filter 'wppb_signup_user_notification_filter' to bypass this function or + * replace it with your own notification behavior. + * + * Filter 'wppb_signup_user_notification_email' and + * 'wppb_signup_user_notification_subject' to change the content + * and subject line of the email sent to newly registered users. + * + * @param string $user The user's login name. + * @param string $user_email The user's email address. + * @param array $meta By default, an empty array. + * @param string $activation_key The activation key created in wppb_signup_user() + * @return bool + */ +function wppb_signup_user_notification( $user, $user_email, $activation_key, $meta = '' ) { + if ( !apply_filters( 'wppb_signup_user_notification_filter', $user, $user_email, $activation_key, $meta ) ) + return false; + + $wppb_general_settings = get_option( 'wppb_general_settings' ); + $admin_email = get_site_option( 'admin_email' ); + + if ( $admin_email == '' ) + $admin_email = 'support@' . $_SERVER['SERVER_NAME']; + + $from_name = apply_filters ( 'wppb_signup_user_notification_email_from_field', get_bloginfo( 'name' ) ); + + //we don't use this anymore do we ? + /*$message_headers = apply_filters ( 'wppb_signup_user_notification_from', "From: \"{$from_name}\" <{$admin_email}>\n" . "Content-Type: text/plain; charset=\"" . get_option('blog_charset') . "\"\n" );*/ + + if( isset( $wppb_general_settings['activationLandingPage'] ) && ( trim( $wppb_general_settings['activationLandingPage'] ) != '' ) ) { + $registration_page_url = add_query_arg( array('activation_key' => $activation_key), get_permalink( $wppb_general_settings['activationLandingPage'] ) ); + } else { + $registration_page_url = 'not_set'; + } + + if ( $registration_page_url == 'not_set' ){ + global $post; + if( !empty( $post->ID ) ) + $permalink = get_permalink( $post->ID ); + else + $permalink = get_bloginfo( 'url' ); + + if( !empty( $post->post_content ) ) + $post_content = $post->post_content; + else + $post_content = ''; + + $registration_page_url = ( ( strpos( $post_content, '[wppb-register' ) !== false ) ? add_query_arg( array( 'activation_key' => $activation_key ), $permalink ) : add_query_arg( array( 'activation_key' => $activation_key ), get_bloginfo( 'url' ) ) ); + } + + $subject = sprintf( __( '[%1$s] Activate %2$s', 'profile-builder'), $from_name, $user ); + $subject = apply_filters( 'wppb_signup_user_notification_email_subject', $subject, $user_email, $user, $activation_key, $registration_page_url, $meta, $from_name, 'wppb_user_emailc_registr_w_email_confirm_email_subject' ); + + $message = sprintf( __( "To activate your user, please click the following link:

            %s%s%s

            After you activate it you will receive yet *another email* with your login.", "profile-builder" ), '', $registration_page_url, '.' ); + $message = apply_filters( 'wppb_signup_user_notification_email_content', $message, $user_email, $user, $activation_key, $registration_page_url, $meta, $from_name, 'wppb_user_emailc_registr_w_email_confirm_email_content' ); + + $message_context = 'email_user_activate'; + + wppb_mail( $user_email, $subject, $message, $from_name, $message_context ); + + return true; +} + + +/** + * Activate a signup. + * + * + * @param string $activation_key The activation key provided to the user. + * @return array An array containing information about the activated user and/or blog + */ +function wppb_manual_activate_signup( $activation_key ) { + global $wpdb; + + if ( is_multisite() ) + $signup = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->signups WHERE activation_key = %s", $activation_key ) ); + else + $signup = $wpdb->get_row( $wpdb->prepare("SELECT * FROM ".$wpdb->prefix."signups WHERE activation_key = %s", $activation_key) ); + + if ( !empty( $signup ) && !$signup->active ){ + $meta = unserialize( $signup->meta ); + $user_login = esc_sql( $signup->user_login ); + $user_email = esc_sql( $signup->user_email ); + /* the password is in hashed form in the signup table and we will copy it later to the user */ + $password = NULL; + + $user_id = username_exists($user_login); + + if ( ! $user_id ) + $user_id = wppb_create_user( $user_login, $password, $user_email ); + else + $user_already_exists = true; + + if ( !$user_id ) + return __( 'Could not create user!', 'profile-builder' ); + + elseif ( isset( $user_already_exists ) && ( $user_already_exists == true ) ) + return __( 'That username is already activated!', 'profile-builder' ); + + else{ + $now = current_time('mysql', true); + + $retVal = ( is_multisite() ? $wpdb->update( $wpdb->signups, array('active' => 1, 'activated' => $now), array('activation_key' => $activation_key) ) : $wpdb->update( $wpdb->base_prefix.'signups', array('active' => 1, 'activated' => $now), array('activation_key' => $activation_key) ) ); + + wppb_add_meta_to_user_on_activation( $user_id, '', $meta ); + + /* copy the hashed password from signup meta to wp user table */ + if( !empty( $meta['user_pass'] ) ){ + /* we might still have the base64 encoded password in signups and not the hash */ + if( base64_encode(base64_decode($meta['user_pass'], true)) === $meta['user_pass'] ) + $meta['user_pass'] = wp_hash_password( $meta['user_pass'] ); + + $wpdb->update( $wpdb->users, array('user_pass' => $meta['user_pass'] ), array('ID' => $user_id) ); + //This is required so that the APC cached data is updated with the new password. Thanks to @foliovision + wp_cache_delete( $user_id, 'users' ); + } + + wppb_notify_user_registration_email( get_bloginfo( 'name' ), $user_login, $user_email, 'sending', $password, ( isset( $wppb_general_settings['adminApproval'] ) ? $wppb_general_settings['adminApproval'] : 'no' ) ); + + do_action('wppb_activate_user', $user_id, $password, $meta); + return ( $retVal ? 'ok' : __( 'There was an error while trying to activate the user', 'profile-builder' ) ); + } + } +} + +/** + * Create a user. + * + * @param string $user_name The new user's login name. + * @param string $password The new user's password. + * @param string $email The new user's email address. + * @return mixed Returns false on failure, or int $user_id on success + */ +function wppb_create_user( $user_name, $password, $email) { + if( is_email( $user_name ) ) + $user_name = apply_filters( 'wppb_generated_random_username', Wordpress_Creation_Kit_PB::wck_generate_slug( trim( $user_name ) ), $user_name ); + else { + $user_name = sanitize_user($user_name, true); + if( is_multisite() ) + $user_name = preg_replace( '/\s+/', '', $user_name ); + } + + + $user_id = wp_create_user( $user_name, $password, $email ); + if ( is_wp_error($user_id) ) + return false; + + // Newly created users have no roles or caps until they are added to a blog. + delete_user_option( $user_id, 'capabilities' ); + delete_user_option( $user_id, 'user_level' ); + + do_action( 'wppb_new_user', $user_id ); + + return $user_id; +} + +//send an email to the admin regarding each and every new subscriber, and - if selected - to the user himself +function wppb_notify_user_registration_email( $bloginfo, $user_name, $email, $send_credentials_via_email, $password, $adminApproval ){ + + /* if login with email is enabled user_name gets the value of the users email */ + $wppb_general_settings = get_option( 'wppb_general_settings' ); + if ( isset( $wppb_general_settings['loginWith'] ) && ( $wppb_general_settings['loginWith'] == 'email' ) ) { + $user_name = $email; + } + + //send email to the admin + $message_from = apply_filters( 'wppb_register_from_email_message_admin_email', $bloginfo ); + + $message_subject = '['.$message_from.'] '.__( 'A new subscriber has (been) registered!', 'profile-builder' ); + $message_subject = apply_filters ('wppb_register_admin_email_subject_without_admin_approval', $message_subject, $email, $password, $message_from, 'wppb_admin_emailc_default_registration_email_subject' ); + + $message_content = sprintf( __( 'New subscriber on %1$s.

            Username:%2$s
            E-mail:%3$s
            ', 'profile-builder'), $message_from, $user_name, $email ); + + $message_context = 'email_admin_new_subscriber'; + + if ( $adminApproval == 'yes' ) { + $user_data = get_user_by( 'email', $email ); + + $wppb_generalSettings = get_option( 'wppb_general_settings', 'not_found' ); + + $adminApproval_mailAdmin = 0; + + if( $wppb_generalSettings != 'not_found' && ! empty( $wppb_generalSettings['adminApprovalOnUserRole'] ) ) { + foreach( $user_data->roles as $role ) { + if( in_array( $role, $wppb_generalSettings['adminApprovalOnUserRole'] ) ) { + if( ! current_user_can( 'delete_users' ) ) { + $adminApproval_mailAdmin = 1; + } + } + } + } else { + if( ! current_user_can( 'delete_users' ) ) { + $adminApproval_mailAdmin = 1; + } + } + + if( $adminApproval_mailAdmin == 1 ) { + $message_subject = apply_filters( 'wppb_register_admin_email_subject_with_admin_approval', $message_subject, $email, $password, $message_from, 'wppb_admin_emailc_registration_with_admin_approval_email_subject' ); + + $message_content .= wppb_adminApproval_adminEmailContent(); + $message_content = apply_filters( 'wppb_register_admin_email_message_with_admin_approval', $message_content, $email, $password, $message_from, 'wppb_admin_emailc_registration_with_admin_approval_email_content' ); + + $message_context = 'email_admin_approve'; + } + else{ + $message_content = apply_filters( 'wppb_register_admin_email_message_without_admin_approval', $message_content, $email, $password, $message_from, 'wppb_admin_emailc_default_registration_email_content' ); + } + } else { + $message_content = apply_filters( 'wppb_register_admin_email_message_without_admin_approval', $message_content, $email, $password, $message_from, 'wppb_admin_emailc_default_registration_email_content' ); + } + + if ( trim( $message_content ) != '' ){ + $admin_email = apply_filters('wppb_send_to_admin_email', get_option('admin_email'), get_user_by( 'email', $email ), $message_context); + wppb_mail( $admin_email, $message_subject, $message_content, $message_from, $message_context ); + } + + + + //send an email to the newly registered user, if this option was selected + if ( isset( $send_credentials_via_email ) && ( $send_credentials_via_email == 'sending' ) ){ + $user_message_from = apply_filters( 'wppb_register_from_email_message_user_email', $bloginfo ); + + $user_message_subject = sprintf( __( '[%1$s] Your new account information', 'profile-builder' ), $user_message_from, $user_name, $password ); + $user_message_subject = apply_filters( 'wppb_register_user_email_subject_without_admin_approval', $user_message_subject, $email, $password, $user_message_from, 'wppb_user_emailc_default_registration_email_subject' ); + + if ( $password === NULL ) { + $password = __( 'Your selected password at signup', 'profile-builder' ); + } + + $send_password = apply_filters( 'wppb_send_password_in_default_email_message', false ); + if( !$send_password ) + $user_message_content = sprintf( __( 'Welcome to %1$s!


            Your username is:%2$s', 'profile-builder' ), $user_message_from, $user_name ); + else + $user_message_content = sprintf( __( 'Welcome to %1$s!


            Your username is:%2$s and password:%3$s', 'profile-builder' ), $user_message_from, $user_name, $password ); + + if ( $password === __( 'Your selected password at signup', 'profile-builder' ) ) { + $password = NULL; + } + + $user_message_context = 'email_user_account_info'; + + if ( $adminApproval == 'yes' ){ + $user_data = get_user_by( 'email', $email ); + + $wppb_generalSettings = get_option( 'wppb_general_settings', 'not_found' ); + + $adminApproval_mailUser = 0; + + if( $wppb_generalSettings != 'not_found' && ! empty( $wppb_generalSettings['adminApprovalOnUserRole'] ) ) { + foreach( $user_data->roles as $role ) { + if( in_array( $role, $wppb_generalSettings['adminApprovalOnUserRole'] ) ) { + if( ! current_user_can( 'delete_users' ) ) { + $adminApproval_mailUser = 1; + } + } + } + } else { + if( ! current_user_can( 'delete_users' ) ) { + $adminApproval_mailUser = 1; + } + } + + if( $adminApproval_mailUser == 1 ) { + $user_message_subject = apply_filters( 'wppb_register_user_email_subject_with_admin_approval', $user_message_subject, $email, $password, $user_message_subject, 'wppb_user_emailc_registration_with_admin_approval_email_subject' ); + + $user_message_content .= wppb_adminApproval_userEmailContent(); + + $user_message_context = 'email_user_need_approval'; + + $user_message_content = apply_filters( 'wppb_register_user_email_message_with_admin_approval', $user_message_content, $email, $password, $user_message_subject, 'wppb_user_emailc_registration_with_admin_approval_email_content' ); + } + else{ + $user_message_content = apply_filters( 'wppb_register_user_email_message_without_admin_approval', $user_message_content, $email, $password, $user_message_subject, 'wppb_user_emailc_default_registration_email_content' ); + } + } else + $user_message_content = apply_filters( 'wppb_register_user_email_message_without_admin_approval', $user_message_content, $email, $password, $user_message_subject, 'wppb_user_emailc_default_registration_email_content' ); + + $message_sent = wppb_mail( $email, $user_message_subject, $user_message_content, $user_message_from, $user_message_context ); + + return ( ( $message_sent ) ? 2 : 1 ); + } +} + + +// function with content to be added in email sent to admin if "Admin Approval" is on +function wppb_adminApproval_adminEmailContent() { + $emailContent = '
            ' . __( 'The "Admin Approval" feature was activated at the time of registration, so please remember that you need to approve this user before he/she can log in!', 'profile-builder') ."\r\n"; + + return $emailContent; +} + + +// function with content to be added in email sent to user if "Admin Approval" is on +function wppb_adminApproval_userEmailContent() { + $emailContent = '

            ' . __( 'Before you can access your account, an administrator needs to approve it. You will be notified via email.', 'profile-builder' ); + + return $emailContent; +} +// END FUNCTIONS USED BOTH ON THE REGISTRATION PAGE AND THE EMAIL CONFIRMATION TABLE + + +// Set up the AJAX hooks +add_action( 'wp_ajax_wppb_get_unconfirmed_email_number', 'wppb_get_unconfirmed_email_number' ); +add_action( 'wp_ajax_wppb_handle_email_confirmation_cases', 'wppb_handle_email_confirmation_cases' ); + + +$wppb_general_settings = get_option( 'wppb_general_settings', 'not_found' ); +if( $wppb_general_settings != 'not_found' ) + if( !empty($wppb_general_settings['emailConfirmation'] ) && ( $wppb_general_settings['emailConfirmation'] == 'yes' ) ){ + if ( is_multisite() ){ + /* don't display on network admin */ + if( strpos($_SERVER['SCRIPT_NAME'], 'users.php') && !is_network_admin() ){ //global $pagenow doesn't seem to work + add_action( 'admin_head', 'wppb_add_pending_users_header_script' ); + } + }else{ + global $pagenow; + if ( $pagenow == 'users.php' ){ + add_action( 'admin_head', 'wppb_add_pending_users_header_script' ); + } + } + + if ( file_exists ( WPPB_PLUGIN_DIR . '/features/admin-approval/admin-approval.php' ) ) + add_action( 'user_register', 'wppb_update_user_status_on_admin_registration' ); + } + + +// function to delete the users from the _signups table also +function wppb_delete_user_from_signups( $user_id ) { + global $wpdb; + + $user = get_user_by( 'id', $user_id ); + $wpdb->delete( $wpdb->base_prefix.'signups', array( 'user_email' => $user->user_email ) ); +} add_action( 'delete_user', 'wppb_delete_user_from_signups' ); \ No newline at end of file diff --git a/profile-builder/features/functions.php b/profile-builder/features/functions.php index 56e5437..65312dc 100644 --- a/profile-builder/features/functions.php +++ b/profile-builder/features/functions.php @@ -1,1010 +1,1009 @@ -ID) - foreach ($current_user->roles as $role_key) { - if (empty($GLOBALS['wp_roles']->roles[$role_key])) - continue; - $role = $GLOBALS['wp_roles']->roles[$role_key]; - if (isset($adminSettingsPresent[$role['name']])) { - if ($adminSettingsPresent[$role['name']] == 'show') - $show = true; - if ($adminSettingsPresent[$role['name']] == 'hide' && $show === null) - $show = false; - } - } - return $show === null ? $content : $show; -} - - -if(!function_exists('wppb_curpageurl')){ - function wppb_curpageurl() { - $pageURL = 'http'; - - if ((isset($_SERVER["HTTPS"])) && ($_SERVER["HTTPS"] == "on")) - $pageURL .= "s"; - - $pageURL .= "://"; - - if( strpos( $_SERVER["HTTP_HOST"], $_SERVER["SERVER_NAME"] ) !== false ){ - $pageURL .=$_SERVER["HTTP_HOST"].$_SERVER["REQUEST_URI"]; - } - else { - if ($_SERVER["SERVER_PORT"] != "80") - $pageURL .= $_SERVER["SERVER_NAME"] . ":" . $_SERVER["SERVER_PORT"] . $_SERVER["REQUEST_URI"]; - else - $pageURL .= $_SERVER["SERVER_NAME"] . $_SERVER["REQUEST_URI"]; - } - - if ( function_exists('apply_filters') ) $pageURL = apply_filters('wppb_curpageurl', $pageURL); - - return $pageURL; - } -} - - -if ( is_admin() ){ - - // register the settings for the menu only display sidebar menu for a user with a certain capability, in this case only the "admin" - add_action( 'admin_init', 'wppb_register_settings' ); - - // display the same extra profile fields in the admin panel also - if ( file_exists ( WPPB_PLUGIN_DIR.'/front-end/extra-fields/extra-fields.php' ) ){ - require_once( WPPB_PLUGIN_DIR.'/front-end/extra-fields/extra-fields.php' ); - - add_action( 'show_user_profile', 'display_profile_extra_fields_in_admin', 10 ); - add_action( 'edit_user_profile', 'display_profile_extra_fields_in_admin', 10 ); - global $pagenow; - if( $pagenow != 'user-new.php' ) - add_action( 'user_profile_update_errors', 'wppb_validate_backend_fields', 10, 3 ); - add_action( 'personal_options_update', 'save_profile_extra_fields_in_admin', 10 ); - add_action( 'edit_user_profile_update', 'save_profile_extra_fields_in_admin', 10 ); - } - -}else if ( !is_admin() ){ - // include the stylesheet - add_action( 'wp_print_styles', 'wppb_add_plugin_stylesheet' ); - - // include the menu file for the profile informations - include_once( WPPB_PLUGIN_DIR.'/front-end/edit-profile.php' ); - include_once( WPPB_PLUGIN_DIR.'/front-end/class-formbuilder.php' ); - add_shortcode( 'wppb-edit-profile', 'wppb_front_end_profile_info' ); - - // include the menu file for the login screen - include_once( WPPB_PLUGIN_DIR.'/front-end/login.php' ); - add_shortcode( 'wppb-login', 'wppb_front_end_login' ); - - // include the menu file for the logout screen - include_once( WPPB_PLUGIN_DIR.'/front-end/logout.php' ); - add_shortcode( 'wppb-logout', 'wppb_front_end_logout' ); - - // include the menu file for the register screen - include_once( WPPB_PLUGIN_DIR.'/front-end/register.php' ); - add_shortcode( 'wppb-register', 'wppb_front_end_register_handler' ); - - // include the menu file for the recover password screen - include_once( WPPB_PLUGIN_DIR.'/front-end/recover.php' ); - add_shortcode( 'wppb-recover-password', 'wppb_front_end_password_recovery' ); - - // set the front-end admin bar to show/hide - add_filter( 'show_admin_bar' , 'wppb_show_admin_bar'); - - // Shortcodes used for the widget area - add_filter( 'widget_text', 'do_shortcode', 11 ); -} - - -/** - * Function that overwrites the default wp_mail function and sends out emails - * - * @since v.2.0 - * - * @param string $to - * @param string $subject - * @param string $message - * @param string $message_from - * - */ -function wppb_mail( $to, $subject, $message, $message_from = null, $context = null ) { - $to = apply_filters( 'wppb_send_email_to', $to ); - $send_email = apply_filters( 'wppb_send_email', true, $to, $subject, $message, $context ); - - $message = apply_filters( 'wppb_email_message', $message, $context ); - - do_action( 'wppb_before_sending_email', $to, $subject, $message, $send_email, $context ); - - if ( $send_email ) { - //we add this filter to enable html encoding - add_filter( 'wp_mail_content_type', create_function( '', 'return "text/html"; ' ) ); - - $sent = wp_mail( $to , html_entity_decode( htmlspecialchars_decode( $subject, ENT_QUOTES ), ENT_QUOTES ), $message ); - - do_action( 'wppb_after_sending_email', $sent, $to, $subject, $message, $send_email, $context ); - - return $sent; - } - - return ''; -} - -function wppb_activate_account_check(){ - if ( ( isset( $_GET['activation_key'] ) ) && ( trim( $_GET['activation_key'] ) != '' ) ){ - global $post; - $activation_key = sanitize_text_field( $_GET['activation_key'] ); - - $wppb_generalSettings = get_option( 'wppb_general_settings' ); - $activation_landing_page_id = ( ( isset( $wppb_generalSettings['activationLandingPage'] ) && ( trim( $wppb_generalSettings['activationLandingPage'] ) != '' ) ) ? $wppb_generalSettings['activationLandingPage'] : 'not_set' ); - - if ( $activation_landing_page_id != 'not_set' ){ - //an activation page was selected, but we still need to check if the current page doesn't already have the registration shortcode - if ( strpos( $post->post_content, '[wppb-register' ) === false ) - add_filter( 'the_content', 'wppb_add_activation_message' ); - - }elseif ( strpos( $post->post_content, '[wppb-register' ) === false ){ - //no activation page was selected, and the sent link pointed to the home url - wp_redirect( apply_filters( 'wppb_activatate_account_redirect_url', WPPB_PLUGIN_URL.'assets/misc/fallback-page.php?activation_key='.urlencode( $activation_key ).'&site_name='.urlencode( get_bloginfo( 'name' ) ).'&site_url='.urlencode( get_bloginfo( 'url' ) ).'&message='.urlencode( $activation_message = wppb_activate_signup( $activation_key ) ), $activation_key, $activation_message ) ); - exit; - } - } -} -add_action( 'template_redirect', 'wppb_activate_account_check' ); - - -function wppb_add_activation_message( $content ){ - - return wppb_activate_signup( sanitize_text_field( $_GET['activation_key'] ) ) . $content; -} - - -// Create a new, top-level page -$args = array( - 'page_title' => 'Profile Builder', - 'menu_title' => 'Profile Builder', - 'capability' => 'manage_options', - 'menu_slug' => 'profile-builder', - 'page_type' => 'menu_page', - 'position' => '70,69', - 'priority' => 1, - 'icon_url' => WPPB_PLUGIN_URL . 'assets/images/pb-menu-icon.png' - ); -new WCK_Page_Creator_PB( $args ); - -/** - * Remove the automatically created submenu page - * - * @since v.2.0 - * - * @return void - */ -function wppb_remove_main_menu_page(){ - remove_submenu_page( 'profile-builder', 'profile-builder' ); -} -add_action( 'admin_menu', 'wppb_remove_main_menu_page', 11 ); - -/** - * Add scripts to the back-end CPT's to remove the slug from the edit page - * - * @since v.2.0 - * - * @return void - */ -function wppb_print_cpt_script( $hook ){ - wp_enqueue_script( 'jquery-ui-dialog' ); - wp_enqueue_style( 'wp-jquery-ui-dialog' ); - - if ( $hook == 'profile-builder_page_manage-fields' ){ - wp_enqueue_script( 'wppb-manage-fields-live-change', WPPB_PLUGIN_URL . 'assets/js/jquery-manage-fields-live-change.js', array(), PROFILE_BUILDER_VERSION, true ); - } - - if (( $hook == 'profile-builder_page_manage-fields' ) || - ( $hook == 'profile-builder_page_profile-builder-basic-info' ) || - ( $hook == 'profile-builder_page_profile-builder-modules' ) || - ( $hook == 'profile-builder_page_profile-builder-general-settings' ) || - ( $hook == 'profile-builder_page_profile-builder-admin-bar-settings' ) || - ( $hook == 'profile-builder_page_profile-builder-register' ) || - ( $hook == 'profile-builder_page_profile-builder-wppb_userListing' ) || - ( $hook == 'profile-builder_page_custom-redirects' ) || - ( $hook == 'profile-builder_page_profile-builder-wppb_emailCustomizer' ) || - ( $hook == 'profile-builder_page_profile-builder-wppb_emailCustomizerAdmin' ) || - ( $hook == 'profile-builder_page_profile-builder-add-ons' ) || - ( $hook == 'profile-builder_page_profile-builder-woocommerce-sync' ) || - ( $hook == 'profile-builder_page_profile-builder-bbpress') || - ( $hook == 'admin_page_profile-builder-pms-promo') ) { - wp_enqueue_style( 'wppb-back-end-style', WPPB_PLUGIN_URL . 'assets/css/style-back-end.css', false, PROFILE_BUILDER_VERSION ); - } - - if ( $hook == 'profile-builder_page_profile-builder-general-settings' ) - wp_enqueue_script( 'wppb-manage-fields-live-change', WPPB_PLUGIN_URL . 'assets/js/jquery-email-confirmation.js', array(), PROFILE_BUILDER_VERSION, true ); - - if( ($hook == 'profile-builder_page_profile-builder-add-ons' ) || - ($hook == 'admin_page_profile-builder-pms-promo' ) ) { - wp_enqueue_script('wppb-add-ons', WPPB_PLUGIN_URL . 'assets/js/jquery-pb-add-ons.js', array(), PROFILE_BUILDER_VERSION, true); - wp_enqueue_style( 'thickbox' ); - wp_enqueue_script( 'thickbox' ); - } - - if ( isset( $_GET['post_type'] ) || isset( $_GET['post'] ) ){ - if ( isset( $_GET['post_type'] ) ) - $post_type = sanitize_text_field( $_GET['post_type'] ); - - elseif ( isset( $_GET['post'] ) ) - $post_type = get_post_type( absint( $_GET['post'] ) ); - - if ( ( 'wppb-epf-cpt' == $post_type ) || ( 'wppb-rf-cpt' == $post_type ) || ( 'wppb-ul-cpt' == $post_type ) ){ - wp_enqueue_style( 'wppb-back-end-style', WPPB_PLUGIN_URL . 'assets/css/style-back-end.css', false, PROFILE_BUILDER_VERSION ); - wp_enqueue_script( 'wppb-epf-rf', WPPB_PLUGIN_URL . 'assets/js/jquery-epf-rf.js', array(), PROFILE_BUILDER_VERSION, true ); - } - } - if ( file_exists ( WPPB_PLUGIN_DIR.'/update/update-checker.php' ) ) { - wp_enqueue_script( 'wppb-sitewide', WPPB_PLUGIN_URL . 'assets/js/jquery-pb-sitewide.js', array(), PROFILE_BUILDER_VERSION, true ); - } - wp_enqueue_style( 'wppb-serial-notice-css', WPPB_PLUGIN_URL . 'assets/css/serial-notice.css', false, PROFILE_BUILDER_VERSION ); -} -add_action( 'admin_enqueue_scripts', 'wppb_print_cpt_script' ); - - -//the function used to overwrite the avatar across the wp installation -function wppb_changeDefaultAvatar( $avatar, $id_or_email, $size, $default, $alt ){ - /* Get user info. */ - if(is_object($id_or_email)){ - $my_user_id = $id_or_email->user_id; - - }elseif(is_numeric($id_or_email)){ - $my_user_id = $id_or_email; - - }elseif(!is_integer($id_or_email)){ - $user_info = get_user_by( 'email', $id_or_email ); - $my_user_id = ( is_object( $user_info ) ? $user_info->ID : '' ); - }else - $my_user_id = $id_or_email; - - $wppb_manage_fields = get_option( 'wppb_manage_fields', 'not_found' ); - if ( $wppb_manage_fields != 'not_found' ){ - foreach( $wppb_manage_fields as $value ){ - if ( $value['field'] == 'Avatar'){ - $avatar_field = $value; - } - } - } - - /* for multisite if we don't have an avatar try to get it from the main blog */ - if( is_multisite() && empty( $avatar_field ) ){ - switch_to_blog(1); - $wppb_switched_blog = true; - $wppb_manage_fields = get_option( 'wppb_manage_fields', 'not_found' ); - if ( $wppb_manage_fields != 'not_found' ){ - foreach( $wppb_manage_fields as $value ){ - if ( $value['field'] == 'Avatar'){ - $avatar_field = $value; - } - } - } - } - - if ( !empty( $avatar_field ) ){ - - $customUserAvatar = get_user_meta( $my_user_id, $avatar_field['meta-name'], true ); - if( !empty( $customUserAvatar ) ){ - if( is_numeric( $customUserAvatar ) ){ - $img_attr = wp_get_attachment_image_src( $customUserAvatar, 'wppb-avatar-size-'.$size ); - if( $img_attr[3] === false ){ - $img_attr = wp_get_attachment_image_src( $customUserAvatar, 'thumbnail' ); - $avatar = "{$alt}"; - } - else - $avatar = "{$alt}"; - } - else { - $customUserAvatar = get_user_meta($my_user_id, 'resized_avatar_' . $avatar_field['id'], true); - $customUserAvatarRelativePath = get_user_meta($my_user_id, 'resized_avatar_' . $avatar_field['id'] . '_relative_path', true); - - if ((($customUserAvatar != '') || ($customUserAvatar != null)) && file_exists($customUserAvatarRelativePath)) { - $avatar = "{$alt}"; - } - } - } - - } - - /* if we switched the blog restore it */ - if( is_multisite() && !empty( $wppb_switched_blog ) && $wppb_switched_blog ) - restore_current_blog(); - - return $avatar; -} -add_filter( 'get_avatar', 'wppb_changeDefaultAvatar', 21, 5 ); - - -//the function used to resize the avatar image; the new function uses a user ID as parameter to make pages load faster -function wppb_resize_avatar( $userID, $userlisting_size = null, $userlisting_crop = null ){ - // include the admin image API - require_once( ABSPATH . '/wp-admin/includes/image.php' ); - - // retrieve first a list of all the current custom fields - $wppb_manage_fields = get_option( 'wppb_manage_fields', 'not_found' ); - if ( $wppb_manage_fields != 'not_found' ){ - foreach( $wppb_manage_fields as $value ){ - if ( $value['field'] == 'Avatar'){ - $avatar_field = $value; - } - } - } - - /* for multisite if we don't have an avatar try to get it from the main blog */ - if( is_multisite() && empty( $avatar_field ) ){ - switch_to_blog(1); - $wppb_switched_blog = true; - $wppb_manage_fields = get_option( 'wppb_manage_fields', 'not_found' ); - if ( $wppb_manage_fields != 'not_found' ){ - foreach( $wppb_manage_fields as $value ){ - if ( $value['field'] == 'Avatar'){ - $avatar_field = $value; - } - } - } - } - - - if ( !empty( $avatar_field ) ){ - - // retrieve width and height of the image - $width = $height = ''; - - //this checks if it only has 1 component - if ( is_numeric( $avatar_field['avatar-size'] ) ){ - $width = $height = $avatar_field['avatar-size']; - - }else{ - //this checks if the entered value has 2 components - $sentValue = explode( ',', $avatar_field['avatar-size'] ); - $width = $sentValue[0]; - $height = $sentValue[1]; - } - - $width = ( !empty( $userlisting_size ) ? $userlisting_size : $width ); - $height = ( !empty( $userlisting_size ) ? $userlisting_size : $height ); - - if( !strpos( get_user_meta( $userID, 'resized_avatar_'.$avatar_field['id'], true ), $width . 'x' . $height ) ) { - // retrieve the original image (in original size) - $avatar_directory_path = get_user_meta( $userID, 'avatar_directory_path_'.$avatar_field['id'], true ); - - $image = wp_get_image_editor( $avatar_directory_path ); - if ( !is_wp_error( $image ) ) { - do_action( 'wppb_before_avatar_resizing', $image, $userID, $avatar_field['meta-name'], $avatar_field['avatar-size'] ); - - $crop = apply_filters( 'wppb_avatar_crop_resize', ( !empty( $userlisting_crop ) ? $userlisting_crop : false ) ); - - $resize = $image->resize( $width, $height, $crop ); - - if ($resize !== FALSE) { - do_action( 'wppb_avatar_resizing', $image, $resize ); - - $fileType = apply_filters( 'wppb_resized_file_extension', 'png' ); - - $wp_upload_array = wp_upload_dir(); // Array of key => value pairs - - //create file(name); both with directory and url - $fileName_dir = $image->generate_filename( NULL, $wp_upload_array['basedir'].'/profile_builder/avatars/', $fileType ); - - if ( PHP_OS == "WIN32" || PHP_OS == "WINNT" ) - $fileName_dir = str_replace( '\\', '/', $fileName_dir ); - - $fileName_url = str_replace( str_replace( '\\', '/', $wp_upload_array['basedir'] ), $wp_upload_array['baseurl'], $fileName_dir ); - - //save the newly created (resized) avatar on the disc - $saved_image = $image->save( $fileName_dir ); - - if ( !is_wp_error( $saved_image ) ) { - /* the image save sometimes doesn't save with the desired extension so we need to see with what extension it saved it with and - if it differs replace the extension in the path and url that we save as meta */ - $validate_saved_image = wp_check_filetype_and_ext( $saved_image['path'], $saved_image['path'] ); - $ext = substr( $fileName_dir,strrpos( $fileName_dir, '.', -1 ), strlen($fileName_dir) ); - if( !empty( $validate_saved_image['ext'] ) && $validate_saved_image['ext'] != $ext ){ - $fileName_url = str_replace( $ext, '.'.$validate_saved_image['ext'], $fileName_url ); - $fileName_dir = str_replace( $ext, '.'.$validate_saved_image['ext'], $fileName_dir ); - } - - update_user_meta( $userID, 'resized_avatar_'.$avatar_field['id'], $fileName_url ); - update_user_meta( $userID, 'resized_avatar_'.$avatar_field['id'].'_relative_path', $fileName_dir ); - - do_action( 'wppb_after_avatar_resizing', $image, $fileName_dir, $fileName_url ); - } - } - } - } - } - - /* if we switched the blog restore it */ - if( is_multisite() && !empty( $wppb_switched_blog ) && $wppb_switched_blog ) - restore_current_blog(); - -} - - -if ( is_admin() ){ - // add a hook to delete the user from the _signups table if either the email confirmation is activated, or it is a wpmu installation - function wppb_delete_user_from_signups_table($user_id) { - global $wpdb; - - $userLogin = $wpdb->get_var( $wpdb->prepare( "SELECT user_login, user_email FROM " . $wpdb->users . " WHERE ID = %d LIMIT 1", $user_id ) ); - if ( is_multisite() ) - $delete = $wpdb->delete( $wpdb->signups, array( 'user_login' => $userLogin ) ); - else - $delete = $wpdb->delete( $wpdb->prefix.'signups', array( 'user_login' => $userLogin ) ); - } - - $wppb_generalSettings = get_option( 'wppb_general_settings' ); - if ( !empty( $wppb_generalSettings['emailConfirmation'] ) && ( $wppb_generalSettings['emailConfirmation'] == 'yes' ) ) { - if( is_multisite() ) - add_action( 'wpmu_delete_user', 'wppb_delete_user_from_signups_table' ); - else - add_action('delete_user', 'wppb_delete_user_from_signups_table'); - } -} - - - -// This function offers compatibility with the all in one event calendar plugin -function wppb_aioec_compatibility(){ - - wp_deregister_script( 'jquery.tools-form'); -} -add_action('admin_print_styles-users_page_ProfileBuilderOptionsAndSettings', 'wppb_aioec_compatibility'); - - -function wppb_user_meta_exists( $id, $meta_name ){ - global $wpdb; - - return $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->usermeta WHERE user_id = %d AND meta_key = %s", $id, $meta_name ) ); -} - - -// function to check if there is a need to add the http:// prefix -function wppb_check_missing_http( $redirectLink ) { - return preg_match( '#^(?:[a-z\d]+(?:-+[a-z\d]+)*\.)+[a-z]+(?::\d+)?(?:/|$)#i', $redirectLink ); -} - - - -//function to output the password strength checker on frontend forms -function wppb_password_strength_checker_html(){ - $wppb_generalSettings = get_option( 'wppb_general_settings' ); - if( !empty( $wppb_generalSettings['minimum_password_strength'] ) ){ - $password_strength = ''.__('Strength indicator', 'profile-builder' ).' - '; - return $password_strength; - } - return ''; -} - -//function to check password length check -function wppb_check_password_length( $password ){ - $wppb_generalSettings = get_option( 'wppb_general_settings' ); - if( !empty( $wppb_generalSettings['minimum_password_length'] ) ){ - if( strlen( $password ) < $wppb_generalSettings['minimum_password_length'] ){ - return true; - } - else - return false; - } - return false; -} - -//function to check password strength -function wppb_check_password_strength(){ - $wppb_generalSettings = get_option( 'wppb_general_settings' ); - if( isset( $_POST['wppb_password_strength'] ) && !empty( $wppb_generalSettings['minimum_password_strength'] ) ){ - $wppb_password_strength = sanitize_text_field( $_POST['wppb_password_strength'] ); - $password_strength_array = array( 'short' => 0, 'bad' => 1, 'good' => 2, 'strong' => 3 ); - $password_strength_text = array( 'short' => __( 'Very Weak', 'profile-builder' ), 'bad' => __( 'Weak', 'profile-builder' ), 'good' => __( 'Medium', 'profile-builder' ), 'strong' => __( 'Strong', 'profile-builder' ) ); - if( $password_strength_array[$wppb_password_strength] < $password_strength_array[$wppb_generalSettings['minimum_password_strength']] ){ - return $password_strength_text[$wppb_generalSettings['minimum_password_strength']]; - } - else - return false; - } - return false; -} - -/* function to output password length requirements text */ -function wppb_password_length_text(){ - $wppb_generalSettings = get_option( 'wppb_general_settings' ); - if( !empty( $wppb_generalSettings['minimum_password_length'] ) ){ - return sprintf(__('Minimum length of %d characters', 'profile-builder'), $wppb_generalSettings['minimum_password_length']); - } - return ''; -} - -/** - * Include password strength check scripts on frontend where we have shortoces present - */ -add_action( 'wp_footer', 'wppb_enqueue_password_strength_check' ); -function wppb_enqueue_password_strength_check() { - global $wppb_shortcode_on_front; - if( $wppb_shortcode_on_front ){ - $wppb_generalSettings = get_option( 'wppb_general_settings' ); - if( !empty( $wppb_generalSettings['minimum_password_strength'] ) ){ - wp_enqueue_script( 'password-strength-meter' ); - } - } -} -add_action( 'wp_footer', 'wppb_password_strength_check', 102 ); -function wppb_password_strength_check(){ - global $wppb_shortcode_on_front; - if( $wppb_shortcode_on_front ){ - $wppb_generalSettings = get_option( 'wppb_general_settings' ); - if( !empty( $wppb_generalSettings['minimum_password_strength'] ) ){ - ?> - - $field) { - if ( (!empty($id)) && ($field['id'] == $id) ) - return $field; - if ( (!empty($meta)) && ($field['meta-name'] == $meta) ) - return $field; - } - - } - - return ''; -} - - -/* Function for displaying reCAPTCHA error on Login and Recover Password forms */ -function wppb_recaptcha_field_error($field_title='') { - $recaptcha_error = apply_filters('wppb_recaptcha_error' , __('Please enter a (valid) reCAPTCHA value','profile-builder') , $field_title); - - return $recaptcha_error; - -} -/* Function for displaying phone field error */ -function wppb_phone_field_error( $field_title = '' ) { - $phone_error = apply_filters( 'wppb_phone_error' , __( 'Incorrect phone number', 'profile-builder' ) , $field_title ); - - return $phone_error; -} - -/* Create a wrapper function for get_query_var */ -function wppb_get_query_var( $varname ){ - return apply_filters( 'wppb_get_query_var_'.$varname, get_query_var( $varname ) ); -} - -/* Filter the "Save Changes" button text, to make it translatable */ -function wppb_change_save_changes_button($value){ - $value = __('Save Changes','profile-builder'); - return $value; -} -add_filter( 'wck_save_changes_button', 'wppb_change_save_changes_button', 10, 2); - -/* Filter the "Cancel" button text, to make it translatable */ -function wppb_change_cancel_button($value){ - $value = __('Cancel','profile-builder'); - return $value; -} -add_filter( 'wck_cancel_button', 'wppb_change_cancel_button', 10, 2); - -/* ilter the "Delete" button text, to make it translatable */ -function wppb_change_delete_button($value){ - $value = __('Delete','profile-builder'); - return $value; -} -add_filter( 'wck_delete_button', 'wppb_change_delete_button', 10, 2); - -/*Filter the "Edit" button text, to make it translatable*/ -function wppb_change_edit_button($value){ - $value = __('Edit','profile-builder'); - return $value; -} -add_filter( 'wck_edit_button', 'wppb_change_edit_button', 10, 2); - -/*Filter the User Listing, Register Forms and Edit Profile forms metabox header content, to make it translatable*/ -function wppb_change_metabox_content_header(){ - return '
            #'. __( 'Content', 'profile-builder' ) .''. __( 'Edit', 'profile-builder' ) .''. __( 'Delete', 'profile-builder' ) .'
            #'. __( 'Content', 'profile-builder' ) .''. __( 'Edit', 'profile-builder' ) .''. __( 'Delete', 'profile-builder' ) .'
            - -

            - - - - - - - - - - - active', 'profile-builder' ); ?> - inactive', 'profile-builder' ); ?> - - - - -
            - - $wppb_add_on ) { - - $wppb_add_on_exists = 0; - $wppb_add_on_is_active = 0; - $wppb_add_on_is_network_active = 0; - - // Check to see if add-on is in the plugins folder - foreach ($wppb_get_all_plugins as $wppb_plugin_key => $wppb_plugin) { - if (strpos(strtolower($wppb_plugin['Name']), strtolower($wppb_add_on['name'])) !== false && strpos(strtolower($wppb_plugin['AuthorName']), strtolower('Cozmoslabs')) !== false) { - $wppb_add_on_exists = 1; - - if (in_array($wppb_plugin_key, $wppb_get_active_plugins)) { - $wppb_add_on_is_active = 1; - } - - // Consider the add-on active if it's network active - if (is_plugin_active_for_network($wppb_plugin_key)) { - $wppb_add_on_is_network_active = 1; - $wppb_add_on_is_active = 1; - } - - $wppb_add_on['plugin_file'] = $wppb_plugin_key; - } - } - - echo '
            '; - echo '
            '; - - echo ''; - echo ''; - echo ''; - - echo '

            '; - echo ''; - echo $wppb_add_on['name']; - echo ''; - echo '

            '; - - //echo '

            ' . $wppb_add_on['price'] . '

            '; - if( $wppb_add_on['type'] == 'paid' ) - echo '

            ' . __( 'Available in Hobbyist and Pro Versions', 'profile-builder' ) . '

            '; - else - echo '

            ' . __( 'Available in All Versions', 'profile-builder' ) . '

            '; - - echo '

            ' . $wppb_add_on['description'] . '

            '; - - echo '
            '; - - $wppb_version_validation = version_compare(PROFILE_BUILDER_VERSION, $wppb_add_on['product_version']); - - ($wppb_version_validation != -1) ? $wppb_version_validation_class = 'wppb-add-on-compatible' : $wppb_version_validation_class = 'wppb-add-on-not-compatible'; - - echo '
            '; - - // PB minimum version number is all good - if ($wppb_version_validation != -1) { - - // PB version type does match - if (in_array(strtolower($version), $wppb_add_on['product_version_type'])) { - - $ajax_nonce = wp_create_nonce("wppb-activate-addon"); - - if ($wppb_add_on_exists) { - - // Display activate/deactivate buttons - if (!$wppb_add_on_is_active) { - echo '' . __('Activate', 'profile-builder') . ''; - - // If add-on is network activated don't allow deactivation - } elseif (!$wppb_add_on_is_network_active) { - echo '' . __('Deactivate', 'profile-builder') . ''; - } - - // Display message to the user - if (!$wppb_add_on_is_active) { - echo '' . __('Add-On is inactive', 'profile-builder') . ''; - } else { - echo '' . __('Add-On is active', 'profile-builder') . ''; - } - - } else { - - // If we're on a multisite don't add the wpp-add-on-download class to the button so we don't fire the js that - // handles the in-page download - ($wppb_add_on['paid']) ? $wppb_paid_link_class = 'button-primary' : $wppb_paid_link_class = 'button-secondary'; - ($wppb_add_on['paid']) ? $wppb_paid_link_text = __('Learn More', 'profile-builder') : $wppb_paid_link_text = __('Download Now', 'profile-builder'); - - ($wppb_add_on['paid']) ? $wppb_paid_href_utm_text = '?utm_source=wpbackend&utm_medium=clientsite&utm_content=add-on-page-buy-button&utm_campaign=PB' . $version : $wppb_paid_href_utm_text = '?utm_source=wpbackend&utm_medium=clientsite&utm_content=add-on-page&utm_campaign=PB' . $version; - - echo '' . $wppb_paid_link_text . ''; - echo '' . __('Compatible with your version of Profile Builder.', 'profile-builder') . ''; - - } - - echo '
            '; - - // PB version type does not match - } else { - - echo '' . __('Upgrade Profile Builder', 'profile-builder') . ''; - echo '' . __('Not compatible with Profile Builder', 'profile-builder') . ' ' . $version . ''; - - } - - } else { - - // If PB version is older than the minimum required version of the add-on - echo ' ' . '' . __('Update', 'profile-builder') . ''; - echo '' . __('Not compatible with your version of Profile Builder.', 'profile-builder') . '
            '; - echo '' . __('Minimum required Profile Builder version:', 'profile-builder') . ' ' . $wppb_add_on['product_version'] . ''; - - } - - // We had to put this error here because we need the url of the add-on - echo '' . sprintf(__('Could not install add-on. Retry or install manually.', 'profile-builder'), esc_url($wppb_add_on['url'])) . ''; - - echo '
            '; - echo '
            '; - - } /* end $wppb_add_ons foreach */ - } - - ?> -
            - -
            -
            -

            - $wppb_plugin) { - if( strtolower($wppb_plugin['Name']) == strtolower( 'Paid Member Subscriptions' ) && strpos(strtolower($wppb_plugin['AuthorName']), strtolower('Cozmoslabs')) !== false) { - $pms_add_on_exists = 1; - if (in_array($wppb_plugin_key, $wppb_get_active_plugins)) { - $pms_add_on_is_active = 1; - } - // Consider the add-on active if it's network active - if (is_plugin_active_for_network($wppb_plugin_key)) { - $pms_add_on_is_network_active = 1; - $pms_add_on_is_active = 1; - } - $plugin_file = $wppb_plugin_key; - } - } - ?> - -
            - -

            u;uOl0A5@>l8q$7DhssFPLNeof z4}VT8aDRI!;9~b&qBLV0j0Y$7@z8{5RuY(xSLD3yo zGf@s=;LO6<8Bu^pD9|I!%fNM&k=77A_}ToNnED?*LJS+vOWerfbi6*9X3R5bxe~Jg z6MaAu=m)?UIDSxHNc0`Uj*6DaF<@&r;2-sUGLG*%l8Nd6;T(DZa6VOJV;p%hWA)LP z{@r;2=xHDvkz|~kPPF~lL^@v3so5q(N2bMw;#T#vbc*EyVkh9jjG+(Gp8rm=Vq*@~ zeO$m!P)e&HZN)@Y#`0e+CN4$whXnvy2!N7;VF)k)05l3=2L2j_SCrCZz)DX;&XnnR z$!|Q0WgM3agRTy(MPT+oK?H=MG*0$_wFm-g5g`hz5H*KkIe~tN=JGExL?(+%>~@+U z&f3fhf{kKoajuN4eNH4IvtQy==(I@27N`(W(Ly43h{(^_oyH3ZtOPKIQ6TZ3MU-H? zecTi(cN%J!YF6vpo_v0H6z@0YJ*bEyKnm0L#8RMtm-0 z^I_0vjpULUUuC7x1i^9w!6bDl(_;p#4dGT6H@vMh^I;>H24NtC{sF?^c3?eaBu9!_ z=fyr9Iv-jD>&|03cCq`R^Pu|&{qcGjS}MURP7mw{!84t)-_jI^H9T}2;RKMyek73b z3$Zc3#hM$64jfMlk<7zuscEAn?DMV1_M>r!Iv%r3VD$&F3k}}G$C)jN2OGM`@gR2J zj2EMDu%{7&rvtwvV%C4E2?%{?J8`DzpW6v)MWuvnEXJ#4X)a)}XkMc`kf9aiAT$X_ zlT8@Az}^I6z<;0zrmwm{vN7YWw5MWGla~25&n0uK*{3CkW-w6<(f}0e!!Q9T{N&U` zJZ6)*7_&liWGpLgU_Y8f0V|q}_tTz_^&tqrAP`iL+61OcVyq*h13quOLBJm&6K(~Q zSuNyNKVAVfj@{T0gq#EKH)dS8FxaVy$UVWEX^wBlstocCRE9JApg9h9D+F8=@iYvG zJd7D1uegpA7kz=nN+ZbDFyc^Szf{Hvcn+06)G9F8(3#J(KxVTA)>Wx+tAXrdBQoo% zqoHTIvjF$7`K8u6N{Cf4UaeBk!Ih5&>>muSiR|oU)@<1AHb8o`RzNNi#Tn~<-0ChH z%svJI?%|;*v^uJL!BsfD=e}iJvHw9EG|okd28_3 zeRlx&r4@VN$OorNuiZ-Z-;as0D?GsdM~%80cq)9pL8dY(i`QG>i4XgpF8OngM2mR5RA*!OuEyoY%{QHmFq3%)F zxiz0G{tu6*2`*HHC-`__i|zVnfyV>SL&ryg$igEyN7%H^|92W_3^q#;H5gV0wC#U{ z;aX0nVYt|ooG^Z^3{Jp+_u4Xi@|)LxxD*7tV6?1x6~nadv7A$NuYt7AX1X56IxTD@ zQ5;;9N|wd3{kYdQ)N&QTTS<$lT|AIn84>)5bL^t}k$NlX(lgsk7`O1m0# zUd&0BQg5GNVFP+TYImI}M4YCK20M2bFx5t){WpE0fyo6P}fA%nI+ zd;Z}23z}owWs#C}E*?ZEmy4aD7a^O{xuhx6a=G+4U~8B@&u6_Gpd>~|X$cq3&9040 zxct!l8>?&QXMp|MlL!R0aZYsBa&aQv85(M5*A5s-P~H1$Xtw?U({Y)&9w|A@NeZaY^bQO$UvizgLcw9El&pzcS#np+-M zmHNxLLQpAQ9MS#xk!nhsE8%NFHkFG7wdd!p0>`uf4@Q6ot#MO;$ig{}1VN?C@s|tJ z(twP@7V?w{#J6q1qHu2@MFLpxqds7}3PW2U*VXNVpetD{KDS33e1he+9PN6c6w=GB#R zpzq?`4~$vXB0?b4yNtaz0XaZ!?J38(Zu4SKIYk6&6ScA z4wcH%a-1s$Jf-D#P&FKF-=8i7-hbFDMcb}~$lb%6qE023OLIaIJ|_j}iwF}4Wpilz zWs#+uDsj|Uv8i&hFy?KBry48|8o>;$9J~qw$M--JIH#rJYsz|Sg(s+-q>!H)TsSuXMKrnU zgy4R)TX}~$z?(FZ;C&wSjUxCyMB5H74t$6~nz*041UB&m zn2gTus5FF-FEx1mLRyQ_Z8UmZS!RTbf~53CaO~V`oDrN}vAoSl7EOvyD%awaKtkK% zHU@*}{-|2K`G4pMBONgqHK&&E(+mVcsDQwSNfF)O(rtu;AD!JsQ7He{`(+j3*9c{% z5(v8E`-k=!;WP~I_Zh9?fzMAly!p0*3V{$7MRNryWXPNg=iG4EoJ&gu?yspn`)m#< z&~!A$iZnD-K~lsia?@qF{Q3Wq58->6s7C_u;G2LyU^6>ZC5;C1eFqog0VFNQ7boj$ zRf8BW1?3)<4=L5el(b0j!9To@j0tmdHK1wj-id+L62K<9K(ElbQAYf#@pSUOz-S83 zUvvWB3@cT#Rhoc0J`;Aia)8A86NCpm-visVk-WoXZbbGl-VKIJwsu13XWLvxrq8Yc z;jsX`=;jQF#b;bc&4=;wggy}3knrD)ehZCHdXU*_l^k7z(1pV zD{SSA;<>b&iOmtf1^A31dN}QQnXIX7rxTv71L!b>;LrX}Jt!k^^Y|Y;ZS*`!Hn!D? zj*Y-0LH{PTF;8H@Ns#0SAQ`~^8da)%xg95xvcQhWu#Ti;FR;6SzBp?9cBV@LunZIj zzOs6+hdhn()*vJM6jls?$A<3UeGLjHJAfK+!Ud!;MOwS@x|)|1yRT@`G_)@@eQ+0n za28}Ew3P2BtII54sL6-V9iHxj5x;VWfX`J_1+1uF>D8017<0dBwdFlj@Y)l_D|Z60 zfPzCKq@E(1Dl%b3X?FW|evJ5AjaR3=0pisMd|4cX{KhB^o}wcmh-1$HxRrxebU)tTO$M0)z{A=Uiw;1czr?(eoZEp^{_ z+gIqr4P`&1ae!!eD>)WZrF($!HFw+K>^ItNBZP*+vlAxLLLl>Bo56ylrmg4+PO_m8>Wwr}-wY>y9I0KlXI;jpKa~aRFYx!o3qCCuVSTH*d z1gh-Jv6u12lMN9G>clH>_lMbKqOrQhH$dyTA&eC^TEHnWk@qON^KCz(AM~Bd{)Ar) zObRjvs1DjhHf1VARw`P{p|b*Q9G zUDOoZ4n8n8P6K8&W1K|#lx$^9QELt#2s-#%J%}WU&%kL~vczX}a$w2`nXV;l52zS{ zEp9mw-FCbi2hOH8Bd8)G>+CO{1D=%yA_P{rK#>lN#i*s&Tt^f6qBw=hI-tYdIxJ`% z2&#ywi0nl?d=MZzwxAl^DdoRB7zD*au&9NE67u>CnUA?z2+7m1kAv!Lm@1KcdmDie zNUa88L4Z>Yevow--UjzR{+hfkO9wCj-~|m%;73e(a_~}{eDtmHS@JU{8v_M;0)xU@ z6lg(%u>#+oaj-)bXv8+U&k<~m16$Flc0bB2PnOd`Cz(HRieRsvV{wH1x^03(X%0S)eC(BOS3gXWjq)TdZWP#-A zTH(0y3SFx^odZ;G3=|-A{R~sF zylTB&2s(wp7KGSH;z6{w;y^ToRvKa<2^K=2dN4)YTJXYw21!^Zs8y*65^{j~=l@Ba z-m@p7&ZEbwMm?y}fYx##RU#u@RyeiXhc2r?G#1Qs!c$tQ4HC5$G(pby+TnP_)n2ehSaf?fkTe zOLcANnxN#-l*bz%QEm@7EXIy*UT+s*KS&L6IF^I$q7pNstbliRo!B79&LH5p6GocC zOr3CMXBgt~Vq2a9r{JMhfS?97L#$U>;$W52D$AGS*DZdJ5h`TaOrT}_Lk@Fcoc%%W zBL6K&A>zPF6cM;UCQg70tb5VruL=6tU7h~@H^Ah#$z!Zl0)r`>!AOCK{X=vRpY&?& zb{#Nv-VO@t@zw&-J&T7CgSPgjlORT%i3-1H4GIAbD{37|9rxlKWSBVExk$tPTAesrmB7zCjkj0G-DbQ>;XmPk%)(&Tm z(IRW-gBEti{O_*8p1>CH0EVF$4E6qt-Z|FXH=b zea{-2F~;;nPdR49icXVckK#>(Ob^*1Sa6xQ=iP1CFT_ zBSNP36A8=c#f5Lq01lu}!c%eJ2RNtVy#g}^{xk2#raZohdtTCI-- zIcgPQf~=Os+fPfNx7Brgj{u)A0Pcl$y0inOogH|I{GgRx4_e=0M})B95Z;Z~^@Hi) z8MNJ5T&pj!hMIqAQ3=mpm_ev>!FE+B1Lmw2X4}Atl#w!KM)`dw-i40`7p&XSv#6gO z&tJe=&IMD;sn{_!7~FW!X{?^}U3_O=3{?_%zX24vIQPLa`WzClRm3X+2hQW*Mp>ug z*b9#+LV+^`4&-hZ9?Th5+nq=6#BEj{SIK28I==>6tm4tsI}# z|9(eF9?)oCPoBsZu7@>phOPsb8l>JqgWHiMbs9JaNX2y;56}YS{`ckk_*q#9mtTzy z$kF{a2$@G=7GBR-G<|S7W%{7L1ggs=!wnsVMqGsJ!b0dog+>S|sU&kSEXs=78a2Su z1WOAnZLoB}ng*6GSbCJU#_2XjP~k=Uf2^v`0hb7C*y$d^_-<~|>bv@28BkW=HEhU% zbS9?`$c%!#bOGE7g-t2S>;?ocyC(Y^v7uTc%`5Fw1D-1nu46*OgZ((Kok><}Oh?ND z&Ua1T`#}T44lcIA>*DayO39fSxK{#Nf{c!$%}ZCtZiyKp1i}jdhA=Io%+F6TV*KgP zxD+EVv}=$FI9vA!c#Idw$*@{Qw{H$J;y`rbjBr{9vpA#Ir~=e^{35MD+jAJ4Nz-@$ zL~z`0XPA*4k$O<|yYtHdUceP3N#rj09>fGL5H+>Q&i@b%0yvQswFQmF)Z~nWV5V*x zmqxRHj>epyJwLZ%8h{1R;EuHw<0Kh(H^|#vZ069rjCPp&3<2fz0q=tMg~zuOmBN^~ z`aCU_?HLi0Y0Ta2Edn6knse;q(+68@Pm>p zSp2q~1*jtd96!U(9yQWt2fQ17ajk58s3uBHjV1|#B1MRwCCAM@J5eS=!EWady7>CTV$E#Fy&Dc(% ziLWoy#?ca}W4-O~ocwgavq|e=HfK~Pa!2Fy=Ky`GflEa22$Sach-)qzP8mEWmo3=v zKbNYN02PowB$3t%GVcU1TcKl#oeWUy3(yasZ_ZL_Fuwjy(Lc&H71e3fCV9^1XB7w` zFV)B19~|cakzbGVHJzfyJ}$7h!Qugn7c4%o_`wnYOAss}u!O-90ZSAtF|a0qH5n{% zuq42e1WO7mX|Se%B?Fc$SaM*=gQWnLB3MdbDTAc~mMU0kU`?eo_Njk3`yXw>3~1XK zC_e#3y1FgrrhsE<_8nu_X25n0#P}x8hb4+uBt(K0MOl#$eask!+Y3)yfg9i139D6j zQ1k(G^bwDw5XKizihPnnzzPK`46Ja9Pg2Cg?~q=YLH&I5ckBd-QEv2;n1G%Ea)Ic@ zF0Yf35yj~CV$su{xnTK%qAhyw7Csq?sIqj7lDK4)Eq~vL-U^Iu5QC z#T}UimK#{J!Ey)7gA#YdQ+_6-8M$X(!_*h71TjYr^vDbFsaE-PExU@gU2;MMF0Wsf zEH3)8WC`WV5|aK4NYDD9R*l~mc0$NDZgeCJcr;>M`>NebE>gRf0#+(mX%w}4>ET}> zDfthjZJXb*5)OcV6($5|T6MSNq-5q;D{qJ{DsPCPlsCjSqv|VE6^OsD$VR9I7p393 z5LHyhC!R%IPuGIA4y+Oi*VEFMijcL*pP!lJwXqX2q`1*m7?84NEM;D2U{PM@Jh0}2 z6-3GF3@%1*O*zV?r?nqtC&XxSqj&KDDb!II=ZT^rq8C`+VEKSGhcZN*d-y11ZO=A~ zmcmw6!i9(I=*LK@QnDl3gWwIgb9eB(r8jD6QE${TN^jKi(pE^YRZ!Zp?h-5Ex&#M$ zdj(4nyq1XP%}=CO7Cn(#MR_7s+;R!hvzGF@efJA1VV)%i>LE0GKL&BKLDB7(#bB+b z+~#ifCRi?%!d}-+sMm2zHUy3UaUJA2#_fv+*qA-$ z-@z#ziwffNz{;l-#20)q`ZAmYt~FKLpA`DN7$qR5mk}F<9PSa9v`3KgU*oS4w`NoW@95;0GMc$afbt*s+*;9}EbS_$@6Z6f9D^SAJrL^7-h*3 z`qolK;;>?0;``zq+mk$N@pm)STIAgPx;RpJECef$UR`$Q)j95kM+8UMhS=mdhKOLtnPyw>!|l=|84uG}o}wj4Rz@10l|w9_*9 zq~O}~j;V8=kv=T!`LgpKtI5u)BD1?rC#RAct}Siz7GC%DP}a9cS?l`bc|RJ=JDycQ ze!Q3c)s-DPSa+Cbw`4v%5xdLHaH;a+{5?(gWp_DBJo3Jib5Hq3Xt-H|LEK*FImd>T z_GxTLx?nL!yc5< z*5tV3-s*Ne#S53dE4*cHe4EAbq+Y$C>&#tGckNHs*d&KDs@}b6A&}MHz;57$@z8fi*DWi+B$5Ld!zX7qiM&aHnJ{Atk7N3ACvXy z-L8^V4Gj-uM2uXLNIJRiLlOj%KXe#4e;vuow$Inse;%{`^~{rtLR4%W(H^MiLwFSAMcF1?e!BJ=fwx~Yn9D|W8$4S%LS z;4WHLA;tcz@8{P8-#F;6r*-+APV@pZdeFiXBv}Do?|OjuEpxv1%6Tj#h^)z;TBY!d z?&hFtWsIxw4ciNwY?^O+;v$B;=(pKjJgxTZbZ?~3My&i8;n$ zF?(fAEaj7Tm5^*UYqf>{s$yLwh4fRam917soc$2-@+o453*oE}i9@cDnI=$o#8j z4{Fqh4{|9#QhXnpa?(xVUC}#z(OK&^nw96X6ID+&+#I^ICer4DbW8fl;f}yhBX>UK zJI!`!HGiu7f!Mk4N}U@oS?)CW@?ra8(%pmKXXy5*&dBUNeEFSL@3vX}>s)L|It3>6 zvtDuPUA$Q*%xV_HskrQrO;+d9N$*dlb)D+CT==k-dv?I_mmQiWXT5SNC6yfcO}yUu zcV|X;AFzzr8p`c^V(Y0Xdz_{H6ry*AF8sQFn+OYE;k>1#HkS-Gem4B^+^47Z!b#HH z2u`14wIx$Sb{tL2STj`fraMs2ia#OrDrt&)eaOwh)8CWq(~qn*D0@=W5yG#rAxzdN zFR1@=qu@asUjIPd)@$*cKgFG4`htK1#R5=w9zIj}dL~>%Vxv@IrFFb6jf7$^ozb z<0IO)y5w#je(iYSh=9OXvdK-S_el{8@7V5nvUVCtN9sxQno5t6K`EbYYi3;)o+d6A z?OipzCuH`vg3!fxIEI>Qj&F_9Ew5%(9gNTl7dyL5g>S{?{nzU2jox@2Jn;FOyDq|! zu6RzXKhHkNW5bFexAkANxB1v_{IO=udaIlj*)K)ev*rwV&+OT&uy<}&c24_80ZqZy zL)tNKD=(hkM%q@qM)gt6ijN0V{LXPds^S`Y_O#D)xAy3g)>VTXO@~>&xHpeXIbvp5 zv6)-{q05o*K29IghwN^ht8RETKYDWE#qmAUM^6rT@ConxA+so3Z{fpzZuOC@i;)Gb zT_Y_uP27u)Wo*ug>-#wQN1WoGa3jr(ZPUB$COaM9cdS=k;1(hR|c(^Qn(F?UHiI?C^Q~_DbF%+@!C zsnY(g9}VKdt}=+WC2OxwKY9n7K_VY zZ3kFMv<9`RS%UrS5_BkG6B1cEq?82CBW zd`NAqc1Bzrs`zFa>BOZ(qhukoIApWsW}V$D%0e&&8G@edQ7J@7j4bA2I1zI1dF8Bz zz&*HuAHQ>XN{0mz79)$2^zrG9sqpucB>|e$P=z1CEiG!t5SpGInE~4cph@^UrhgQ9 zoF-|%3)KGjp9mdME0*7hg0F7i5dLMN^H%rxn*m{SkZfhCbiw}u6RrA17csCPi#sxF zp7OZ&K_h?!{5@@HI+ANxSxYy{kf6+eHS@U4^dbw>iF|?Wcah`pB*u`PGOkDPUr9Q; z((J6rkR@4aOw_-c<(Kw^=Xy6W;OK5J z0(PlbdVCdQta&6RM?`7^3+u#zPpdFeJHgl&mzn;JxR&qw%`f?ffd$ybo9RHv6tUsrJ4fATOihm zuXjA90W1pF6go=o`s~OL3$hH;OkFpqI@AK{$A_SPRHP%-ug_kd!>+_MrD65sCQlm( zgmdSAhn8z5>?pLj=;1@lFH7!h$&HnK06rE04s_^|Pk4|@Z~8>&*=au0seKAw9F_Q; z-om3CW6)=SPY)AYn9!mR*_dX|ap=p4OiW1#%|M4GjL;7iTMw!g1f1v*k~Z73-TB;_%ghiQ7Zczw-$0lh3R?V_i* zeGiqM!0-g<={S8(dI2H=%xHh37qFj7uM6-;VmA2ILiD4(K*Sb-h#fb{7(~?_pqXSW zDUBT*Gs2W#mL_2=O%S5$5uAB~EN69?MmIJoJRviJIZG2xfYxo6RyUiI5V#g)22YW( zP_=@dDw62MDvU_mkom?eB@YH;f6Sr3f~St4o(gl)9AGIGI@-GDIL8Kp(!s2POk3Vf zG&rCcXjK^;(W=wY)9mL&LcLgJyh0-qW0SN)Q>fnnWTe_(d|s-*|J(#vYygZZ>EXxp z29-}iyK%Yyij2SLxo}qqrviF5zDnLdhI#P{ysjMZ~ zP9WcXRg(y80P{~r{om=We}vLgc3|x1zZ??lkH4T1`eWq?Vmpg0IYxlR_ixy^R> zarD;7$N?Y!Vb1FU^I|Urn-B;h@$i@*8+o~JX>5W|yly0OFeN(7$bPgD4Gy~PlCU**Ki-)UaikD-|- zYQf1gJZ`NQE8$ZFUw6s=U7uoexRIlu%oJS5KmN&_V;1y%;ui<6tnHlfI~3(*1A_3Q zgw54tUK|Gh43gu}Hikv-%DB-V4|QPJkpA*+?1!wU(}lKsIiLi8i*H>FnfYXjrKe9v zPkud+G#UK9;gK?;Fv=biIS)(DkdEBjO75|bcE<+dD(;uK*pF}1vv;bB8~%od0gerR zk;1ZOMaNoA4OMf#v1Dnc>Ct}=9t*PBwWyD1AU{8G;`zug{wlL12jFk2!f!g8(ecN# z5v8YuWUeAhFwGxUbp~|w?rq{8`~8saJ4D|9yJh#+QQ3n(>Vd>>Ch{>$vskr534Y9< z1VlEWV{uhI%Aztd?KE*Rv*fTArgxUmtyC88uyKhnOAhBtH0pxWd4eWDPvvZN!|)xtgY8=c@6 zzj=_9>=%1ra8Wu#jTE?pCh06lsKY}o_Q5B}u&jCi6D)AX=5 zrl+T{j|y4lab)J{EqIHpguel?98}o!F8FRgH9){GRB<3N;AfSXW)kby^hWMIK=tbz zPl*D|I%3Xcfs#1D<0rtQ1)WW{9Kt%{t?UUj_nlF?0j7ZHFfa^#)+{(o4P~1s=3@`b zBRy`Z9YJ|CWm2Cnfbxv z-|2N92O$T3KndABmnhAwb+P2=on^~OYJDIue*%pxmL7eC(4zQ`8z&IjJs54_EY-aF2t z0HBQAav_T{O%KZ&eTrgcqdu0F^B5OE_C5h`xx*Ce;=x?n5fFM z{;;q|AH7vier0Z^qZcbEy?GZs13m|fsjpEJ=!dZM=mU4|3l!irk(BAo*C{fN%Z0&M z1g%Bs6SvmLFK}VLoy4+79~bPeQF=O40jr%R6dW z0e%{lh|GS;d`F2b9O;u$-Un*om^(z|XV#su64QsT?9Sb5-BP6G+@By%&3SXg@W zxw4s!O3%<^0{s>Cw-Mb_G^ohO!J5R%{}_4n*v&K@C$sZ$P!`VzYY87r*kaa zsJu!@n;i2q18e}(yYv+vR9sDjlsAE59xJXpT|(N)_e*_T$mYX9`jOo6`yxz?C9#~+ zgX>NK9wc??1jdM1pP?s}FT{hexJ`f*782-5iHcCo0U+U@AfKMxBT>{_l#v`M=7SB( z9er?6CQ)NocisfB3QLdPnb(O^=?(f%pr^+gLXXZ{!X#1cP5-Ajqj%)DQap%o0w^_p zB#@b}>9OucuezI4P)F86B=aUP_reB-HJzw?Wq%6{=9$FWgC6S}fG$5dH4%^5WUhZ=)s4=lxu*SMRg-CYSS`}$wzs-y467iu z2@~kvurWv9XPuf3!o!=){EQC^2lS*`4S2?W2>w<-^R+mZ9KEC~jL^U}X12!tJEb5K zl#(VQ_k{W59IOfG0U{~`e{wz93U?oRFAAA zPGQ!vSQn;e&%}4kg}rRkq9ciY6&GJss+e@+dnLP5NdK}qYDHh~W4@9I+sM@uNfe~Mpv2izOMGj=Rz z5%!PqLEo{giUOi8B5ER6;wK;~*7N8mAz?A7WtEYDH=I(;#v7I#{ixb94rNanG0r4T z{TFidz^s};)!u4P<_DSBR)t>J(L`#i0*< zwwdV}6FeZoa!F71#3HI`dM9$f1B+VpAiZM=N>2k>!%bv<==%5EX_iOz?56w)ObxO0 z=v_yofZAQjpZ~Y&lwN&Lmr~htz4`wU$48cwv1_=)y|}iHL&IpBNkUX`(@}(8Pj*Vv7Y7P^r=s3mC2eJD=K1-#vYBv=uiCb?Cid`vtr&%Jja|v&hg{U+>E{i|?CuR3HFA?%p&q>PlbF_}F6tmN28st~F7wUh*- zI9)?#Dc^62ujfdnGpB<6gO+j=X~#P~4;K9tPWT;}&Jp94cy#%&Z2`e6d}76ZTkqut z+avfe89uK{>ts!#l%fxbXZJg$GH7eeTO?Xz6BN>&qd})Uy-AA~wM4S+Z=10PJf(Pa z%Fw7tw7}NPW}<|mW7G4c#F$au0QSRZN;q1rN0&)fd}T1lHDVTTgq>Zy*#J+LL zmShy=WD{3OiAU&Xx;p5yee9>m-jA7FEYZt)XDc7pbnyKVuIIPnihWR#B}ast5v0q& z$C|Nc(Czx`Yeh#3W0g#)3%YN$uSCjwpQLi=R=HAIw`ha3($XFr1)S2!=vI!;CdpPN zjMQnEU1N2T_0$yDxrwlI^m=VKi#yi@)p^PO4gbvjurZjT@aJqgHTZQ4h=)(Obj{)5 z6eWYwp1XUiWOrJ3EB3>h*Z1T-OO_0UuDVuj7nz_b(hmA}=ig}xo$#H+1lK?LcZ^IM zOUy2D_t;YnWn`p7S>rtt!O32lRB|PnHYfE%sK8KKrW=lH5>l*?BBcv}i=KmssHtjalxKa#vSbBPtPVEdr zeg*%FzD9icq(MmbJ25A!H!pt!@+|=QXuPTCMLch2eOS51pKb=#r3S9h())Mq0uile zZhq#_>fD z*ZiW{`Ad1Q@&_w|B|XHRNQbU$ozH&W_uSotxT_%IJ-BvFhmlc@iHJS262W<@^~=kyWaCT1MeqX@l>xnUMpfYEu1@_{mkI^ zTXy8y!$sz8u4=f&fn?dJ;SG*YNq=PxYE=(L+sx~y#;Y4bmW)1MR>-cF-+WANeG47@ z`EVbc{<=CNM#N)3C-jxi%zYOxz$}{TdMYYd+E)_o;!Tb&`RUm8zZAl&8_uoO)Np zTrfPvEZ_Mi%2*cZfbrO$GupB7>DphxWAmNVZ`0(*IFRe;_X|20b6FN%-aW_xZ=8FV zG$SvW)eI&-??U2P-B<#Kdg$b@+zd?bG<4Mmr$MW|AR5s{TaE(H9=%?|QK)t|=`zd# zg7|9~B10D-TjC8uvcI*~x#`99#*h%Kj8=1f%OnXexrpP->QB?Q`^Lhen*vGENyg56 z32(!J0Cv)=IH~y%KcDU4g-04GZx!WFl<=-?4`8oUbIO-jHfkyeLzC4OIP|}w1-hbZ z?X204s4Q80{C+>k#I-)^Y`kitga_${vFfO1Ba|P=Ax5}hkK`f1e3J7r7@;z=qV@5+ z5)W0cvu6MDF(bQ`-(ujZxsctlm5q$%e( zH%JerR9g0vGY)9V2AD8;vXrBz(`!^|c?Y2B{6=`Rp%Tybk^@RC)&<4H^z37phs%~* zx1l#PCW$q0-h!<_n+`jkEW#jD(c!F;VHH#XMDI7b0yK{S!A~i z&^lha{P++7T~_UY$2GTLhDu9ZXZsY4IUHD#Zf)lZj(EvIsPq6wd3|mB$lNLzb9EfT zyj&U*(W*=x#qsQ&$Fus~m+S2MUJ&=rRBzk_t6>>nt>Wp zaWo@@+yXp2`qZ~9lpXK>!9X{A$lNY=!Sgni4DYdb@MhFGoo~H987O}b8=-Bn8SQIEz1z~8`vY#Fln95i`Uxk-~0$<><>nLS>#88Mn$p&@%Y3a4592l+kt1e+e7Hm9WhoOwjiQJhJK zm-)Tgj?i`+eOB!%XAZ-%VJI}OGy6BWQ>VHVdH^R4y+PtE@mGKjkLbL*MrxS@`{SIg z%c1ooJcGY-G$v$oU`7KHP9Q0&g_iH*$Xf4=J6;77tb{a(D|Byg*31T?i0D9YM`K@? zYW5eoz9UQi=xc%p_Q@3zb;D2K_0qJ@)Qb%U(QCRUw9d~3NJMOKy zLl9gG+o^7&ce*ATPg~~5eCO`YA-ifUA&xmaiIEg#Idx$#xjpt5nB9^nu`5MkPc=^Z z!pQ=)+`@7AE@?%_(-z{t6gmXeK zq&dw&hZ|i7PKyWo{S5xfX(7Q|8w8>?4r`2_9@c%pp9!z_a?Y+?BM7nYR1tY?ov<%^ zvsV$nzR6xQR*SvNOiwoWr$<;P&TlfQ{nsUKTG?LKCu#J|y0aRH}(A3}+>8z)QTF9@M zBjhQ`nl4fzdWxVyD0%~jKP!c#@rrsmcnBpS`y z4OPm~9&!Ftr7A_f_(0Yhc}~P*e>1JTV)KRZz%{rBA{WU7D(nGh7jih9AQ@X~%?T3S zg=+Fxq(LvP)M@%fVP(Z2HRCl@i! zNAh$ZpRTnt-zBjYT{50M0`fs`C5ox_ZP-L*yHNfbLzH4x0h?fJU)=qc1eu7Au#s73vPe2?_SoE*=x1%b!{ya zbaGit`0DTrVkoHPaSr}FoILDw2&8X5!G@HOC^o^?m87kZX0m@a_S@Sx)(W@}yDrUF z?#)F!Qj;+GZ_SFPKQ_(vamB3f$IF7tYE4*#KOo@N6wTAs1ko3@JI~QYniSSrw+l+d z#xU+pZY>bK4EA>wTMOv=dJa=8N)i5yg!CVmP4Yo({L`Z;vqL4lEZ2k^Yd;zYrcLeV z7jYRI1~SsIJ#q-_V2Q4i5w9~qZSam>a3KV;{xaA;s?u4I=t{ig^{Wu}=ao}~4j!3b zq_5y~6c2X!A@w~caYyXkq=25sEKk!mTwNzldddV4oiw=9gk_cpPp zmGdkqBcl1`ii;#4{xHtO(+2x)XWG8)8aQeY&;&kdQysX=?rww{syA|+lzeOP;33ZT zySgrTTO#T|B{^G`#K0ILKdVfwYSpn*(@_ z!&;zqJ2>LH@|YC;S>rYm@tUAh-bSl-gNG=2Mh>1tyG4uK4Jjsiw27n9b84zEx&pr4 zxeis6_ReqI#d-vldTiCql5w;K?0hv(7;U`|3n*8)DsG~O&ob*Aa z2G_*p2BDn1VD=AJRVD)-TLVi!hCZ;&3&do`-H=p_+utZ;4~LLH&!4)!pe4NNu|S;! zzq}<1*%sCL+GvBzu!+j5T_y)&GtV3~xUFFP#1LU=^>AlTy}{rygTFax(3XYrBvOX6 zop*imu2q07SG{why`wXMLIo>)*v|&ste&>LwyBA5?up?mB3b8Djf5A9bhWxg@ib8i z?ylbRNr1IbQP*D84}Im?P+TvzH^1O)W$GlX_=Oul1 zK&5RC$L8tlep9Q6Xi?c?M)Q1o*+06>xl27kcnH)lXGTQ0#W$tJ4$cW+o^#_d==h2| zV1>OQJCchX0@vk*1h;%>fCbW~2e8+%-n9lK1w+kV4u_>^8POX9s4>&7+3OloUf15t z2VXpJLD%7FLZTH0*DKkq8T=vz=q1xsrQn51yk6O(Gve8tgVZgJB8k(8IV@BWRm-VR!Q7^<&J*V-9(F#}; z@}&iPK0gQgaShYb_JNg<701fKO z5v_BwVm_~&0#~E2o2snzU~?sCLTyX-kX>vy>$^2@yTh`LTK!ff66l=%=IrX9^Sjld zKyagE5R@j6y1NxZMyHHQ9L}?&LmYxE+=1if1IN*3RdQB=8#OL7nFlt}{_d~Gp_)Dq zy#)H!OtVS_EDC*V!QQTXGuYW{4RF*akg3sTHT1q=Pp#40P8{iYt5sP)=D{Is$Kz(I z4M=~glypcJj2FNGR=Vo2ZEInT0=*53JJ~g*G!c_65-pehZd9Yc&A~Fv3f1O37^` zP|VI~QUM2*Y|6^quqQwemcyufdgbBaO3gX4{agh$@`6CfnnT=}yB&lY(uH2UOi&5NePys)q*3fmhi z$;YtX?$Oh1zJv2e=IhkwMF$cnAJpbD$HRaRdxhCusx}v9Hm#-SHL~6>PV~Z}wL&pj z3C0di8hmDG>s5o>JvSGeU)ksjt`EyfYC-f}ja6_O5KTX9V`t**@ z&dTN%ae6bm5jQ_H6N;8t=nnxB+|1h}~3az*T zot4=Yx>_+khi0UW9FxSemz^5sj@t6Qxsd8>qwnPsw>&z!g59QNZxb28Ypyxc08R z{@PTC>tLZWru)?s4Y+?-$z;iJi{k3Bh9QSaErjJUw)(`7$QlH*+p$%3 z;OnWyHY%=6T8B)k;7HMseNoov_(cv8ZCqBzK89sScv`6Rp0RX>VcDXd24Ce!ivJ$} z=?4Sh!(90R^!N8=Zzv%l4B=eHx^$7iO(AB`-ajZGnAELV zU}}T2(7I~_rDYSURNI=MLt8?1PH1nK&Tf(zd~V;~Ghj@ftzcq)5BDc4U@}Ig?!g70XV%)--jXwxm7E7=GmJd8RBdKm*p@bRz=i{DZ*0c)Jbx w!we_S3tK?i5YT`uG5Ia0vqgcOTS{m(ifjSaDF{bQj+iXC2*uhc=vNE>2PT|PM*si- delta 48322 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 R;gUl1PJuwhUkv~2{{X#|yLkWr diff --git a/profile-builder.2.6.3.zip b/profile-builder.zip similarity index 90% rename from profile-builder.2.6.3.zip rename to profile-builder.zip index c780e6f776eb47cfa4258652c0dfa4403b4b5d50..ab46ad86f7bfd8c9047f520811a73e193ba0e08a 100644 GIT binary patch delta 171418 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