From 23d3b570f04db895a8f8105f2fa700a48a252ad7 Mon Sep 17 00:00:00 2001 From: Kevin Cristiano <kcristiano@tadpole.cc> Date: Fri, 31 Mar 2017 08:21:02 -0400 Subject: [PATCH] civicrm-47 4.7.17 update --- civicrm/CRM/Activity/DAO/Activity.php | 4 +- civicrm/CRM/Activity/Form/Task/Batch.php | 6 +- civicrm/CRM/Admin/Form.php | 2 +- civicrm/CRM/Admin/Form/Setting.php | 15 +- civicrm/CRM/Admin/Form/Setting/UF.php | 1 + civicrm/CRM/Admin/Page/AJAX.php | 106 +- civicrm/CRM/Batch/Form/Entry.php | 4 +- .../CRM/Contact/BAO/Contact/Permission.php | 2 +- civicrm/CRM/Contact/BAO/Group.php | 2 +- civicrm/CRM/Contact/BAO/GroupContact.php | 3 + civicrm/CRM/Contact/BAO/Query.php | 231 +- civicrm/CRM/Contact/DAO/Contact.php | 6 +- civicrm/CRM/Contact/Form/Merge.php | 111 +- civicrm/CRM/Contact/Page/DedupeFind.php | 2 +- civicrm/CRM/Contact/Page/DedupeMerge.php | 10 +- civicrm/CRM/Contact/Page/SavedSearch.php | 2 +- civicrm/CRM/Contact/Selector.php | 14 - civicrm/CRM/Contribute/BAO/Contribution.php | 65 +- .../CRM/Contribute/BAO/Contribution/Utils.php | 19 +- civicrm/CRM/Contribute/BAO/Query.php | 83 +- civicrm/CRM/Contribute/DAO/Contribution.php | 26 +- .../CRM/Contribute/Form/AdditionalPayment.php | 9 - civicrm/CRM/Contribute/Form/Contribution.php | 2 +- .../CRM/Contribute/Form/ContributionBase.php | 7 +- civicrm/CRM/Contribute/Form/Search.php | 21 +- civicrm/CRM/Contribute/Form/Task/Batch.php | 1 - civicrm/CRM/Core/BAO/CustomField.php | 2 +- civicrm/CRM/Core/BAO/CustomGroup.php | 12 +- civicrm/CRM/Core/BAO/EntityTag.php | 39 +- civicrm/CRM/Core/BAO/Tag.php | 16 +- civicrm/CRM/Core/BAO/UFGroup.php | 128 +- civicrm/CRM/Core/BAO/UFMatch.php | 8 +- civicrm/CRM/Core/CodeGen/Specification.php | 2 +- civicrm/CRM/Core/DAO/AllCoreTables.data.php | 2 +- civicrm/CRM/Core/Error.php | 5 + civicrm/CRM/Core/Form.php | 2 + civicrm/CRM/Core/OptionGroup.php | 22 +- civicrm/CRM/Core/Payment/PayPalIPN.php | 2 +- civicrm/CRM/Core/SelectValues.php | 32 +- .../Core/Smarty/plugins/modifier.crmDate.php | 4 + civicrm/CRM/Core/xml/Menu/Admin.xml | 10 - civicrm/CRM/Core/xml/Menu/Tag.xml | 15 +- civicrm/CRM/Dashlet/Page/GettingStarted.php | 2 +- civicrm/CRM/Dedupe/Merger.php | 10 +- civicrm/CRM/Event/BAO/Participant.php | 1 + civicrm/CRM/Event/DAO/Participant.php | 4 +- civicrm/CRM/Event/Form/EventFees.php | 2 +- civicrm/CRM/Event/Form/Participant.php | 1 + civicrm/CRM/Event/Form/Registration.php | 4 +- .../CRM/Event/Form/Registration/Confirm.php | 42 +- .../CRM/Event/Form/Registration/Register.php | 1 + civicrm/CRM/Export/BAO/Export.php | 25 - civicrm/CRM/Financial/BAO/FinancialType.php | 28 +- civicrm/CRM/Financial/DAO/FinancialTrxn.php | 42 +- civicrm/CRM/Group/Page/Group.php | 15 - civicrm/CRM/Logging/Reverter.php | 26 - civicrm/CRM/Mailing/ActionTokens.php | 7 + civicrm/CRM/Mailing/BAO/Mailing.php | 4 + civicrm/CRM/Mailing/Event/BAO/Bounce.php | 84 +- civicrm/CRM/Mailing/Event/BAO/Unsubscribe.php | 20 +- civicrm/CRM/Member/DAO/Membership.php | 8 +- civicrm/CRM/Price/BAO/LineItem.php | 32 +- civicrm/CRM/Price/BAO/PriceField.php | 1 + civicrm/CRM/Price/BAO/PriceFieldValue.php | 8 +- civicrm/CRM/Price/BAO/PriceSet.php | 246 +- civicrm/CRM/Price/Form/DeleteSet.php | 2 - civicrm/CRM/Price/Form/Field.php | 7 - civicrm/CRM/Price/Form/Option.php | 3 +- civicrm/CRM/Price/Page/Option.php | 12 +- civicrm/CRM/Price/Page/Set.php | 5 +- civicrm/CRM/Profile/Form.php | 6 +- civicrm/CRM/Report/Form.php | 3 + civicrm/CRM/Report/Form/Activity.php | 14 + civicrm/CRM/Report/Form/ActivitySummary.php | 18 +- .../CRM/Report/Form/Contribute/Summary.php | 30 +- civicrm/CRM/Report/Form/Event/Summary.php | 7 +- civicrm/CRM/Tag/Form/Edit.php | 131 +- civicrm/CRM/Tag/Form/Merge.php | 126 + civicrm/CRM/Tag/Page/Tag.php | 205 +- .../CRM/Upgrade/Incremental/php/FourSeven.php | 16 + .../Upgrade/Incremental/sql/4.7.17.mysql.tpl | 14 + .../Incremental/sql/4.7.alpha1.mysql.tpl | 1 - .../CRM/Utils/Check/Component/PriceFields.php | 76 + civicrm/CRM/Utils/Date.php | 102 + civicrm/CRM/Utils/Mail/EmailProcessor.php | 16 +- civicrm/CRM/Utils/PDF/Document.php | 1 + civicrm/CRM/Utils/Pager.php | 4 +- civicrm/CRM/Utils/Rule.php | 13 +- civicrm/CRM/Utils/System.php | 2 +- civicrm/CRM/Utils/System/Joomla.php | 14 +- civicrm/CRM/Utils/Type.php | 22 + civicrm/Civi/API/Api3SelectQuery.php | 41 +- civicrm/api/v3/Activity.php | 164 +- civicrm/api/v3/Case.php | 6 + civicrm/api/v3/Contact.php | 37 +- civicrm/api/v3/Contribution.php | 59 +- civicrm/api/v3/Extension.php | 10 +- civicrm/api/v3/GroupContact.php | 6 +- civicrm/api/v3/Job.php | 6 +- civicrm/api/v3/Logging.php | 17 +- civicrm/api/v3/MailingGroup.php | 8 +- civicrm/api/v3/MembershipType.php | 1 + civicrm/api/v3/PriceSet.php | 8 +- civicrm/api/v3/Profile.php | 2 +- .../Activity/ContactRefCustomField.php | 4 +- .../Activity/ContactRefCustomFieldGet.php | 9 +- civicrm/api/v3/examples/Activity/Create.php | 6 +- .../api/v3/examples/Activity/DateTimeHigh.php | 2 +- .../api/v3/examples/Activity/DateTimeLow.php | 2 +- civicrm/api/v3/examples/Activity/Get.php | 4 +- .../api/v3/examples/Activity/GetFields.php | 76 + .../Activity/GetTargetandAssigneeName.php | 14 +- .../Activity/ReturnAssigneeContact.php | 2 +- .../api/v3/examples/ActivityType/Create.php | 10 +- civicrm/api/v3/examples/ActivityType/Get.php | 2 +- civicrm/api/v3/examples/Constant/Get.php | 2 +- .../v3/examples/Contact/APIChainedArray.php | 26 +- .../Contact/APIChainedArrayFormats.php | 14 +- .../Contact/APIChainedArrayMultipleCustom.php | 50 +- ...IChainedArrayValuesFromSiblingFunction.php | 6 +- .../v3/examples/Contact/ChainTwoWebsites.php | 12 +- .../Contact/ChainTwoWebsitesSyntax2.php | 12 +- civicrm/api/v3/examples/Contact/Create.php | 6 +- .../Contact/CreateParticipantPayment.php | 7 +- .../v3/examples/Contact/CustomFieldGet.php | 10 +- .../CustomFieldGetReturnSyntaxVariation.php | 10 +- civicrm/api/v3/examples/Contact/Delete.php | 2 +- civicrm/api/v3/examples/Contact/Get.php | 12 +- .../api/v3/examples/Contact/GetActions.php | 41 +- .../v3/examples/Contact/GetFieldsOptions.php | 162 +- .../Contact/GroupFilterUsingContactAPI.php | 33 +- .../ContributionCreateWithHonoreeContact.php | 10 +- .../ContributionCreateWithNote.php | 8 +- .../ContributionCreateWithSoftCredit.php | 10 +- ...ntributionCreateWithSoftCreditDefaults.php | 10 +- .../api/v3/examples/Contribution/Create.php | 14 +- .../CreateWithNestedLineItems.php | 84 +- .../api/v3/examples/Contribution/Delete.php | 5 +- civicrm/api/v3/examples/Contribution/Get.php | 15 +- .../v3/examples/ContributionPage/Create.php | 11 +- .../api/v3/examples/ContributionPage/Get.php | 10 +- .../v3/examples/ContributionPage/Submit.php | 19 +- .../v3/examples/ContributionRecur/Delete.php | 2 +- civicrm/api/v3/examples/Country/Create.php | 6 +- civicrm/api/v3/examples/Country/Delete.php | 2 +- civicrm/api/v3/examples/Country/Get.php | 6 +- civicrm/api/v3/examples/EntityTag/Delete.php | 4 +- civicrm/api/v3/examples/EntityTag/Get.php | 11 +- .../api/v3/examples/Event/IsFullOption.php | 2 +- civicrm/api/v3/examples/Group/GetFields.php | 60 + civicrm/api/v3/examples/Job/Create.php | 5 +- civicrm/api/v3/examples/Job/Delete.php | 2 +- civicrm/api/v3/examples/Logging/Get.php | 50 +- civicrm/api/v3/examples/Logging/Revert.php | 2 +- civicrm/api/v3/examples/Mailing/Create.php | 30 +- civicrm/api/v3/examples/Mailing/Delete.php | 2 +- civicrm/api/v3/examples/Mailing/Submit.php | 23 +- civicrm/api/v3/examples/MailingAB/Create.php | 8 +- civicrm/api/v3/examples/Membership/Create.php | 12 +- .../Membership/CreateWithCustomData.php | 12 +- .../examples/Membership/FilterIsCurrent.php | 8 +- civicrm/api/v3/examples/Membership/Get.php | 10 +- .../examples/Membership/UpdateCustomData.php | 12 +- .../api/v3/examples/MembershipType/Create.php | 4 +- .../api/v3/examples/MembershipType/Get.php | 3 +- .../v3/examples/MessageTemplate/Create.php | 26 +- .../v3/examples/MessageTemplate/Delete.php | 2 +- .../api/v3/examples/MessageTemplate/Get.php | 28 +- .../api/v3/examples/OptionGroup/Create.php | 7 +- .../api/v3/examples/OptionGroup/Delete.php | 2 +- civicrm/api/v3/examples/Order/Cancel.php | 2 +- civicrm/api/v3/examples/Order/Create.php | 6 +- .../examples/Order/CreateOrderParticipant.php | 6 +- civicrm/api/v3/examples/Order/Get.php | 9 +- .../api/v3/examples/Participant/Create.php | 8 +- civicrm/api/v3/examples/Participant/Get.php | 4 +- .../v3/examples/Participant/NestedDelete.php | 10 +- .../examples/Participant/NestedEventGet.php | 8 +- .../examples/ParticipantStatusType/Create.php | 6 +- .../examples/ParticipantStatusType/Delete.php | 2 +- .../v3/examples/ParticipantStatusType/Get.php | 6 +- civicrm/api/v3/examples/Payment/Cancel.php | 5 +- civicrm/api/v3/examples/Payment/Create.php | 5 +- .../Payment/CreatePaymentWithLineItems.php | 5 +- civicrm/api/v3/examples/Payment/Delete.php | 3 +- civicrm/api/v3/examples/Payment/Get.php | 3 +- .../api/v3/examples/Payment/UpdatePayment.php | 5 +- .../v3/examples/PaymentProcessor/Create.php | 4 +- .../v3/examples/PaymentProcessor/Delete.php | 5 +- .../examples/PaymentProcessorType/Create.php | 8 +- .../examples/PaymentProcessorType/Delete.php | 5 +- .../api/v3/examples/PaymentToken/Create.php | 93 + .../api/v3/examples/PaymentToken/Delete.php | 70 + civicrm/api/v3/examples/PaymentToken/Get.php | 83 + civicrm/api/v3/examples/Pcp/Create.php | 93 + civicrm/api/v3/examples/Phone/Create.php | 3 +- civicrm/api/v3/examples/Phone/Delete.php | 5 +- civicrm/api/v3/examples/Phone/Get.php | 3 +- civicrm/api/v3/examples/Pledge/Create.php | 9 +- civicrm/api/v3/examples/Pledge/Delete.php | 3 +- civicrm/api/v3/examples/Pledge/Get.php | 8 +- .../v3/examples/Pledge/GetFilterHighDate.php | 10 +- .../api/v3/examples/PledgePayment/Create.php | 3 +- .../api/v3/examples/PledgePayment/Delete.php | 3 +- civicrm/api/v3/examples/PledgePayment/Get.php | 3 +- .../api/v3/examples/PledgePayment/Update.php | 3 +- civicrm/api/v3/examples/PriceField/Create.php | 3 +- civicrm/api/v3/examples/PriceField/Delete.php | 3 +- civicrm/api/v3/examples/PriceField/Get.php | 3 +- .../v3/examples/PriceFieldValue/Create.php | 7 +- .../v3/examples/PriceFieldValue/Delete.php | 5 +- .../api/v3/examples/PriceFieldValue/Get.php | 6 +- civicrm/api/v3/examples/PriceSet/Create.php | 4 +- civicrm/api/v3/examples/PriceSet/Delete.php | 3 +- civicrm/api/v3/examples/PriceSet/Get.php | 4 +- civicrm/api/v3/examples/Profile/Apply.php | 3 +- civicrm/api/v3/examples/Profile/Get.php | 3 +- civicrm/api/v3/examples/Profile/GetFields.php | 68 +- civicrm/api/v3/examples/Profile/Submit.php | 3 +- .../Relationship/BetweenRelationshipType.php | 28 +- .../api/v3/examples/Relationship/Create.php | 3 +- .../api/v3/examples/Relationship/Delete.php | 3 +- civicrm/api/v3/examples/Relationship/Get.php | 4 +- .../Relationship/INRelationshipType.php | 21 +- .../NotBetweenRelationshipType.php | 14 +- .../Relationship/NotInRelationshipType.php | 21 +- .../examples/Relationship/filterIsCurrent.php | 10 +- .../v3/examples/RelationshipType/Create.php | 3 +- .../v3/examples/RelationshipType/Delete.php | 5 +- .../v3/examples/ReportTemplate/Getrows.php | 17 +- .../examples/ReportTemplate/Getstatistics.php | 17 +- .../api/v3/examples/SavedSearch/Create.php | 127 + .../api/v3/examples/SavedSearch/Delete.php | 70 + civicrm/api/v3/examples/SavedSearch/Get.php | 79 + civicrm/api/v3/examples/Setting/Create.php | 3 +- .../v3/examples/Setting/CreateAllDomains.php | 3 +- .../Setting/CreateSettingCurrentDomain.php | 3 +- .../Setting/CreateSpecifiedDomains.php | 3 +- civicrm/api/v3/examples/Setting/Get.php | 3 +- .../api/v3/examples/Setting/GetAllDomains.php | 3 +- .../api/v3/examples/Setting/GetDefaults.php | 3 +- civicrm/api/v3/examples/Setting/GetFields.php | 1546 ++- .../Setting/GetSettingCurrentDomain.php | 3 +- .../examples/Setting/GetSpecifiedDomains.php | 3 +- civicrm/api/v3/examples/Setting/GetValue.php | 3 +- civicrm/api/v3/examples/Setting/Revert.php | 3 +- .../api/v3/examples/StateProvince/Create.php | 80 + .../api/v3/examples/StateProvince/Delete.php | 70 + civicrm/api/v3/examples/StateProvince/Get.php | 78 + .../v3/examples/StatusPreference/Create.php | 85 + .../v3/examples/StatusPreference/Delete.php | 70 + .../api/v3/examples/StatusPreference/Get.php | 79 + .../v3/examples/Survey/ChainedGetDelete.php | 5 +- civicrm/api/v3/examples/Survey/Create.php | 3 +- civicrm/api/v3/examples/Survey/Delete.php | 5 +- civicrm/api/v3/examples/Survey/Get.php | 3 +- .../api/v3/examples/SurveyRespondant/Get.php | 3 +- civicrm/api/v3/examples/System/Flush.php | 3 +- civicrm/api/v3/examples/Tag/Create.php | 4 +- civicrm/api/v3/examples/Tag/Delete.php | 5 +- civicrm/api/v3/examples/Tag/Get.php | 3 +- civicrm/api/v3/examples/Tag/GetFields.php | 57 +- civicrm/api/v3/examples/Tag/GetList.php | 3 +- .../api/v3/examples/Tag/GetReturnArray.php | 3 +- civicrm/api/v3/examples/UFField/Create.php | 3 +- civicrm/api/v3/examples/UFField/Delete.php | 3 +- civicrm/api/v3/examples/UFField/Get.php | 3 +- civicrm/api/v3/examples/UFField/Replace.php | 3 +- civicrm/api/v3/examples/UFGroup/Create.php | 5 +- civicrm/api/v3/examples/UFGroup/Delete.php | 5 +- civicrm/api/v3/examples/UFGroup/Get.php | 5 +- civicrm/api/v3/examples/UFJoin/Create.php | 13 +- civicrm/api/v3/examples/UFJoin/Get.php | 3 +- civicrm/api/v3/examples/UFMatch/Get.php | 3 +- civicrm/api/v3/examples/Website/Create.php | 3 +- civicrm/api/v3/examples/Website/Delete.php | 3 +- civicrm/api/v3/examples/Website/Get.php | 3 +- civicrm/api/v3/examples/Website/GetFields.php | 24 +- .../v3/examples/Website/GetWithMetadata.php | 24 +- civicrm/api/v3/utils.php | 6 +- civicrm/bower.json | 1 + civicrm/bower_components/jstree/.bower.json | 42 + civicrm/bower_components/jstree/LICENSE-MIT | 22 + civicrm/bower_components/jstree/bower.json | 32 + civicrm/bower_components/jstree/composer.json | 46 + .../bower_components/jstree/dist/jstree.js | 8305 +++++++++++++++++ .../jstree/dist/jstree.min.js | 6 + .../jstree/dist/themes/default-dark/32px.png | Bin 0 -> 1562 bytes .../jstree/dist/themes/default-dark/40px.png | Bin 0 -> 5717 bytes .../jstree/dist/themes/default-dark/style.css | 1146 +++ .../dist/themes/default-dark/style.min.css | 1 + .../dist/themes/default-dark/throbber.gif | Bin 0 -> 1720 bytes .../jstree/dist/themes/default/32px.png | Bin 0 -> 3121 bytes .../jstree/dist/themes/default/40px.png | Bin 0 -> 1880 bytes .../jstree/dist/themes/default/style.css | 1102 +++ .../jstree/dist/themes/default/style.min.css | 1 + .../jstree/dist/themes/default/throbber.gif | Bin 0 -> 1720 bytes civicrm/bower_components/jstree/src/intro.js | 14 + .../jstree/src/jstree.changed.js | 69 + .../jstree/src/jstree.checkbox.js | 871 ++ .../jstree/src/jstree.conditionalselect.js | 38 + .../jstree/src/jstree.contextmenu.js | 653 ++ .../bower_components/jstree/src/jstree.dnd.js | 653 ++ civicrm/bower_components/jstree/src/jstree.js | 4810 ++++++++++ .../jstree/src/jstree.massload.js | 137 + .../jstree/src/jstree.search.js | 421 + .../jstree/src/jstree.sort.js | 74 + .../jstree/src/jstree.state.js | 125 + .../jstree/src/jstree.types.js | 372 + .../jstree/src/jstree.unique.js | 121 + .../jstree/src/jstree.wholerow.js | 122 + civicrm/bower_components/jstree/src/misc.js | 601 ++ civicrm/bower_components/jstree/src/outro.js | 1 + civicrm/bower_components/jstree/src/sample.js | 93 + .../jstree/src/themes/base.less | 88 + .../jstree/src/themes/default-dark/32px.png | Bin 0 -> 1525 bytes .../jstree/src/themes/default-dark/40px.png | Bin 0 -> 11488 bytes .../jstree/src/themes/default-dark/style.css | 1146 +++ .../jstree/src/themes/default-dark/style.less | 50 + .../src/themes/default-dark/throbber.gif | Bin 0 -> 1849 bytes .../jstree/src/themes/default/32px.png | Bin 0 -> 8740 bytes .../jstree/src/themes/default/40px.png | Bin 0 -> 6055 bytes .../jstree/src/themes/default/style.css | 1102 +++ .../jstree/src/themes/default/style.less | 22 + .../jstree/src/themes/default/throbber.gif | Bin 0 -> 1849 bytes .../jstree/src/themes/main.less | 77 + .../jstree/src/themes/mixins.less | 105 + .../jstree/src/themes/responsive.less | 67 + .../jstree/src/vakata-jstree.js | 38 + civicrm/civicrm-version.php | 4 +- civicrm/css/contactSummary.css | 24 + civicrm/js/Common.js | 12 +- civicrm/js/crm.ajax.js | 10 +- civicrm/js/crm.drupal.js | 10 +- civicrm/packages/DB/DataObject.php | 23 +- civicrm/release-notes.md | 9 + civicrm/release-notes/4.7.17.md | 556 ++ civicrm/settings/Core.setting.php | 14 + civicrm/sql/civicrm.mysql | 4 +- civicrm/sql/civicrm_data.mysql | 6 +- civicrm/sql/civicrm_generated.mysql | 4 +- .../templates/CRM/Admin/Form/Setting/UF.tpl | 4 + .../templates/CRM/Admin/Page/APIExplorer.js | 57 +- .../templates/CRM/Admin/Page/APIExplorer.tpl | 73 +- civicrm/templates/CRM/Batch/Form/Entry.js | 1 + .../CRM/Campaign/Form/Task/Interview.tpl | 2 +- civicrm/templates/CRM/Contact/Form/Merge.tpl | 64 +- .../templates/CRM/Event/Form/EventFees.tpl | 7 - .../CRM/Event/Form/SelfSvcUpdate.tpl | 2 +- civicrm/templates/CRM/Price/Page/LineItem.tpl | 2 +- civicrm/templates/CRM/Tag/Form/Edit.tpl | 9 +- civicrm/templates/CRM/Tag/Form/Merge.tpl | 39 + civicrm/templates/CRM/Tag/Form/Tag.tpl | 55 +- civicrm/templates/CRM/Tag/Form/Tagtree.tpl | 4 +- civicrm/templates/CRM/Tag/Page/Tag.tpl | 678 +- civicrm/templates/CRM/UF/Form/Block.tpl | 143 +- civicrm/templates/CRM/UF/Form/Fields.tpl | 143 + civicrm/templates/CRM/UF/Form/Preview.tpl | 101 +- civicrm/templates/CRM/common/version.tpl | 2 +- civicrm/vendor/autoload.php | 2 +- civicrm/vendor/composer/autoload_real.php | 10 +- 361 files changed, 29407 insertions(+), 2488 deletions(-) create mode 100644 civicrm/CRM/Tag/Form/Merge.php create mode 100644 civicrm/CRM/Upgrade/Incremental/sql/4.7.17.mysql.tpl create mode 100644 civicrm/CRM/Utils/Check/Component/PriceFields.php create mode 100644 civicrm/api/v3/examples/PaymentToken/Create.php create mode 100644 civicrm/api/v3/examples/PaymentToken/Delete.php create mode 100644 civicrm/api/v3/examples/PaymentToken/Get.php create mode 100644 civicrm/api/v3/examples/Pcp/Create.php create mode 100644 civicrm/api/v3/examples/SavedSearch/Create.php create mode 100644 civicrm/api/v3/examples/SavedSearch/Delete.php create mode 100644 civicrm/api/v3/examples/SavedSearch/Get.php create mode 100644 civicrm/api/v3/examples/StateProvince/Create.php create mode 100644 civicrm/api/v3/examples/StateProvince/Delete.php create mode 100644 civicrm/api/v3/examples/StateProvince/Get.php create mode 100644 civicrm/api/v3/examples/StatusPreference/Create.php create mode 100644 civicrm/api/v3/examples/StatusPreference/Delete.php create mode 100644 civicrm/api/v3/examples/StatusPreference/Get.php create mode 100644 civicrm/bower_components/jstree/.bower.json create mode 100644 civicrm/bower_components/jstree/LICENSE-MIT create mode 100644 civicrm/bower_components/jstree/bower.json create mode 100644 civicrm/bower_components/jstree/composer.json create mode 100644 civicrm/bower_components/jstree/dist/jstree.js create mode 100644 civicrm/bower_components/jstree/dist/jstree.min.js create mode 100644 civicrm/bower_components/jstree/dist/themes/default-dark/32px.png create mode 100644 civicrm/bower_components/jstree/dist/themes/default-dark/40px.png create mode 100644 civicrm/bower_components/jstree/dist/themes/default-dark/style.css create mode 100644 civicrm/bower_components/jstree/dist/themes/default-dark/style.min.css create mode 100644 civicrm/bower_components/jstree/dist/themes/default-dark/throbber.gif create mode 100644 civicrm/bower_components/jstree/dist/themes/default/32px.png create mode 100644 civicrm/bower_components/jstree/dist/themes/default/40px.png create mode 100644 civicrm/bower_components/jstree/dist/themes/default/style.css create mode 100644 civicrm/bower_components/jstree/dist/themes/default/style.min.css create mode 100644 civicrm/bower_components/jstree/dist/themes/default/throbber.gif create mode 100644 civicrm/bower_components/jstree/src/intro.js create mode 100644 civicrm/bower_components/jstree/src/jstree.changed.js create mode 100644 civicrm/bower_components/jstree/src/jstree.checkbox.js create mode 100644 civicrm/bower_components/jstree/src/jstree.conditionalselect.js create mode 100644 civicrm/bower_components/jstree/src/jstree.contextmenu.js create mode 100644 civicrm/bower_components/jstree/src/jstree.dnd.js create mode 100644 civicrm/bower_components/jstree/src/jstree.js create mode 100644 civicrm/bower_components/jstree/src/jstree.massload.js create mode 100644 civicrm/bower_components/jstree/src/jstree.search.js create mode 100644 civicrm/bower_components/jstree/src/jstree.sort.js create mode 100644 civicrm/bower_components/jstree/src/jstree.state.js create mode 100644 civicrm/bower_components/jstree/src/jstree.types.js create mode 100644 civicrm/bower_components/jstree/src/jstree.unique.js create mode 100644 civicrm/bower_components/jstree/src/jstree.wholerow.js create mode 100644 civicrm/bower_components/jstree/src/misc.js create mode 100644 civicrm/bower_components/jstree/src/outro.js create mode 100644 civicrm/bower_components/jstree/src/sample.js create mode 100644 civicrm/bower_components/jstree/src/themes/base.less create mode 100644 civicrm/bower_components/jstree/src/themes/default-dark/32px.png create mode 100644 civicrm/bower_components/jstree/src/themes/default-dark/40px.png create mode 100644 civicrm/bower_components/jstree/src/themes/default-dark/style.css create mode 100644 civicrm/bower_components/jstree/src/themes/default-dark/style.less create mode 100644 civicrm/bower_components/jstree/src/themes/default-dark/throbber.gif create mode 100644 civicrm/bower_components/jstree/src/themes/default/32px.png create mode 100644 civicrm/bower_components/jstree/src/themes/default/40px.png create mode 100644 civicrm/bower_components/jstree/src/themes/default/style.css create mode 100644 civicrm/bower_components/jstree/src/themes/default/style.less create mode 100644 civicrm/bower_components/jstree/src/themes/default/throbber.gif create mode 100644 civicrm/bower_components/jstree/src/themes/main.less create mode 100644 civicrm/bower_components/jstree/src/themes/mixins.less create mode 100644 civicrm/bower_components/jstree/src/themes/responsive.less create mode 100644 civicrm/bower_components/jstree/src/vakata-jstree.js create mode 100644 civicrm/release-notes/4.7.17.md create mode 100644 civicrm/templates/CRM/Tag/Form/Merge.tpl create mode 100644 civicrm/templates/CRM/UF/Form/Fields.tpl diff --git a/civicrm/CRM/Activity/DAO/Activity.php b/civicrm/CRM/Activity/DAO/Activity.php index 5cbc7a0d8c..26a5ec64c8 100644 --- a/civicrm/CRM/Activity/DAO/Activity.php +++ b/civicrm/CRM/Activity/DAO/Activity.php @@ -30,7 +30,7 @@ * * Generated from xml/schema/CRM/Activity/Activity.xml * DO NOT EDIT. Generated by CRM_Core_CodeGen - * (GenCodeChecksum:0dd661946f59d928e2b928c3c3f67d44) + * (GenCodeChecksum:e29dddab1cbaae042d11ea6e022f3dd5) */ require_once 'CRM/Core/DAO.php'; require_once 'CRM/Utils/Type.php'; @@ -309,7 +309,7 @@ class CRM_Activity_DAO_Activity extends CRM_Core_DAO { 'bao' => 'CRM_Activity_BAO_Activity', 'html' => array( 'type' => 'Select Date', - 'format' => 'activityDateTime', + 'formatType' => 'activityDateTime', ) , ) , 'activity_duration' => array( diff --git a/civicrm/CRM/Activity/Form/Task/Batch.php b/civicrm/CRM/Activity/Form/Task/Batch.php index 5e0598cb96..980ef2c808 100644 --- a/civicrm/CRM/Activity/Form/Task/Batch.php +++ b/civicrm/CRM/Activity/Form/Task/Batch.php @@ -78,8 +78,8 @@ class CRM_Activity_Form_Task_Batch extends CRM_Activity_Form_Task { if (!empty($contactDetails)) { foreach ($contactDetails as $key => $value) { $assignee = CRM_Activity_BAO_ActivityAssignment::retrieveAssigneeIdsByActivityId($key); - foreach ($assignee as $keys => $values) { - $assigneeContact[] = CRM_Contact_BAO_Contact::displayname($values); + foreach ($assignee as $values) { + $assigneeContact[] = CRM_Contact_BAO_Contact::displayName($values); } $contactDetails[$key]['assignee_display_name'] = !empty($assigneeContact) ? implode(';', $assigneeContact) : NULL; } @@ -138,7 +138,6 @@ class CRM_Activity_Form_Task_Batch extends CRM_Activity_Form_Task { $this->assign('profileTitle', $this->_title); $this->assign('componentIds', $this->_activityHolderIds); - $fileFieldExists = FALSE; // Load all campaigns. if (array_key_exists('activity_campaign_id', $this->_fields)) { @@ -197,7 +196,6 @@ class CRM_Activity_Form_Task_Batch extends CRM_Activity_Form_Task { $defaults = array(); foreach ($this->_activityHolderIds as $activityId) { - $details[$activityId] = array(); CRM_Core_BAO_UFGroup::setProfileDefaults(NULL, $this->_fields, $defaults, FALSE, $activityId, 'Activity'); } diff --git a/civicrm/CRM/Admin/Form.php b/civicrm/CRM/Admin/Form.php index cc3186887f..8129e3f184 100644 --- a/civicrm/CRM/Admin/Form.php +++ b/civicrm/CRM/Admin/Form.php @@ -91,7 +91,7 @@ class CRM_Admin_Form extends CRM_Core_Form { */ public function setDefaultValues() { // Fetch defaults from the db - if (isset($this->_id) && empty($this->_values)) { + if (!empty($this->_id) && empty($this->_values) && CRM_Utils_Rule::positiveInteger($this->_id)) { $this->_values = array(); $params = array('id' => $this->_id); $baoName = $this->_BAOName; diff --git a/civicrm/CRM/Admin/Form/Setting.php b/civicrm/CRM/Admin/Form/Setting.php index 16df7ca1e2..671c8fe7ed 100644 --- a/civicrm/CRM/Admin/Form/Setting.php +++ b/civicrm/CRM/Admin/Form/Setting.php @@ -203,16 +203,11 @@ class CRM_Admin_Form_Setting extends CRM_Core_Form { unset($params['enableComponents']); } - // verify ssl peer option - if (isset($params['verifySSL'])) { - Civi::settings()->set('verifySSL', $params['verifySSL']); - unset($params['verifySSL']); - } - - // force secure URLs - if (isset($params['enableSSL'])) { - Civi::settings()->set('enableSSL', $params['enableSSL']); - unset($params['enableSSL']); + foreach (array('verifySSL', 'enableSSL') as $name) { + if (isset($params[$name])) { + Civi::settings()->set($name, $params[$name]); + unset($params[$name]); + } } $settings = array_intersect_key($params, $this->_settings); $result = civicrm_api('setting', 'create', $settings + array('version' => 3)); diff --git a/civicrm/CRM/Admin/Form/Setting/UF.php b/civicrm/CRM/Admin/Form/Setting/UF.php index 342d6f357a..ab290514d3 100644 --- a/civicrm/CRM/Admin/Form/Setting/UF.php +++ b/civicrm/CRM/Admin/Form/Setting/UF.php @@ -46,6 +46,7 @@ class CRM_Admin_Form_Setting_UF extends CRM_Admin_Form_Setting { public function buildQuickForm() { $config = CRM_Core_Config::singleton(); $this->_uf = $config->userFramework; + $this->_settings['syncCMSEmail'] = CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME; if ($this->_uf == 'WordPress') { $this->_settings['wpBasePage'] = CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME; diff --git a/civicrm/CRM/Admin/Page/AJAX.php b/civicrm/CRM/Admin/Page/AJAX.php index 5740851eaa..ebf77802a8 100644 --- a/civicrm/CRM/Admin/Page/AJAX.php +++ b/civicrm/CRM/Admin/Page/AJAX.php @@ -247,55 +247,6 @@ class CRM_Admin_Page_AJAX { CRM_Core_Page_AJAX::returnJsonResponse($ret); } - public static function mergeTagList() { - $name = CRM_Utils_Type::escape($_GET['term'], 'String'); - $fromId = CRM_Utils_Type::escape($_GET['fromId'], 'Integer'); - $limit = Civi::settings()->get('search_autocomplete_count'); - - // build used-for clause to be used in main query - $usedForTagA = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_Tag', $fromId, 'used_for'); - $usedForClause = array(); - if ($usedForTagA) { - $usedForTagA = explode(",", $usedForTagA); - foreach ($usedForTagA as $key => $value) { - $usedForClause[] = "t1.used_for LIKE '%{$value}%'"; - } - } - $usedForClause = !empty($usedForClause) ? implode(' OR ', $usedForClause) : '1'; - sort($usedForTagA); - - // query to list mergable tags - $query = " -SELECT t1.name, t1.id, t1.used_for, t1.color, t2.name as parent -FROM civicrm_tag t1 -LEFT JOIN civicrm_tag t2 ON t1.parent_id = t2.id -WHERE t1.id <> {$fromId} AND - t1.name LIKE '%{$name}%' AND - ({$usedForClause}) -LIMIT $limit"; - $dao = CRM_Core_DAO::executeQuery($query); - $result = array(); - - while ($dao->fetch()) { - $row = array( - 'id' => $dao->id, - 'text' => ($dao->parent ? "{$dao->parent} :: " : '') . $dao->name, - 'color' => isset($dao->color) ? $dao->color : NULL, - ); - // Add warning about used_for types - if (!empty($dao->used_for)) { - $usedForTagB = explode(',', $dao->used_for); - sort($usedForTagB); - $usedForDiff = array_diff($usedForTagA, $usedForTagB); - if (!empty($usedForDiff)) { - $row['warning'] = TRUE; - } - } - $result[] = $row; - } - CRM_Utils_JSON::output($result); - } - /** * Get a list of mappings. * @@ -352,24 +303,53 @@ LIMIT $limit"; )); } - public static function mergeTags() { - $tagAId = CRM_Utils_Type::escape($_POST['fromId'], 'Integer'); - $tagBId = CRM_Utils_Type::escape($_POST['toId'], 'Integer'); - - $result = CRM_Core_BAO_EntityTag::mergeTags($tagAId, $tagBId); + /** + * Outputs one branch in the tag tree + * + * Used by jstree to incrementally load tags + */ + public static function getTagTree() { + $parent = CRM_Utils_Type::escape(CRM_Utils_Array::value('parent_id', $_GET, 0), 'Integer'); + $result = array(); - if (!empty($result['tagB_used_for'])) { - $usedFor = CRM_Core_OptionGroup::values('tag_used_for'); - foreach ($result['tagB_used_for'] as & $val) { - $val = $usedFor[$val]; + $parentClause = $parent ? "AND tag.parent_id = $parent" : 'AND tag.parent_id IS NULL'; + $sql = "SELECT tag.*, child.id AS child, COUNT(et.id) as usages + FROM civicrm_tag tag + LEFT JOIN civicrm_entity_tag et ON et.tag_id = tag.id + LEFT JOIN civicrm_tag child ON child.parent_id = tag.id + WHERE tag.is_tagset <> 1 $parentClause + GROUP BY tag.id + ORDER BY tag.name"; + $dao = CRM_Core_DAO::executeQuery($sql); + while ($dao->fetch()) { + $style = ''; + if ($dao->color) { + $style = "background-color: {$dao->color}; color: " . CRM_Utils_Color::getContrast($dao->color); } - $result['tagB_used_for'] = implode(', ', $result['tagB_used_for']); + $result[] = array( + 'id' => $dao->id, + 'text' => $dao->name, + 'icon' => FALSE, + 'li_attr' => array( + 'title' => ((string) $dao->description) . ($dao->is_reserved ? ' (*' . ts('Reserved') . ')' : ''), + 'class' => $dao->is_reserved ? 'is-reserved' : '', + ), + 'a_attr' => array( + 'style' => $style, + 'class' => 'crm-tag-item', + ), + 'children' => (bool) $dao->child, + 'data' => array( + 'description' => (string) $dao->description, + 'is_selectable' => (bool) $dao->is_selectable, + 'is_reserved' => (bool) $dao->is_reserved, + 'used_for' => $dao->used_for ? explode(',', $dao->used_for) : array(), + 'color' => $dao->color ? $dao->color : '#ffffff', + 'usages' => (int) $dao->usages, + ), + ); } - $result['message'] = ts('"%1" has been merged with "%2". All records previously tagged "%1" are now tagged "%2".', - array(1 => $result['tagA'], 2 => $result['tagB']) - ); - CRM_Utils_JSON::output($result); } diff --git a/civicrm/CRM/Batch/Form/Entry.php b/civicrm/CRM/Batch/Form/Entry.php index dd61256132..60e967723d 100644 --- a/civicrm/CRM/Batch/Form/Entry.php +++ b/civicrm/CRM/Batch/Form/Entry.php @@ -382,9 +382,7 @@ class CRM_Batch_Form_Entry extends CRM_Core_Form { if ($this->_action & CRM_Core_Action::ADD) { list($currentDate, $currentTime) = CRM_Utils_Date::setDateDefaults(NULL, 'activityDateTime'); - //get all status - $allStatus = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name'); - $completeStatus = array_search('Completed', $allStatus); + $completeStatus = CRM_Contribute_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Completed'); $specialFields = array( 'join_date' => $currentDate, 'receive_date' => $currentDate, diff --git a/civicrm/CRM/Contact/BAO/Contact/Permission.php b/civicrm/CRM/Contact/BAO/Contact/Permission.php index 3948de9dd8..a37e40e7f8 100644 --- a/civicrm/CRM/Contact/BAO/Contact/Permission.php +++ b/civicrm/CRM/Contact/BAO/Contact/Permission.php @@ -170,7 +170,7 @@ WHERE contact_id IN ({$contact_id_list}) $tables = array(); $whereTables = array(); - $permission = CRM_ACL_API::whereClause($type, $tables, $whereTables); + $permission = CRM_ACL_API::whereClause($type, $tables, $whereTables, NULL, FALSE, FALSE, TRUE); $from = CRM_Contact_BAO_Query::fromClause($whereTables); $query = " diff --git a/civicrm/CRM/Contact/BAO/Group.php b/civicrm/CRM/Contact/BAO/Group.php index fe781a5cc3..aab9bc9cd9 100644 --- a/civicrm/CRM/Contact/BAO/Group.php +++ b/civicrm/CRM/Contact/BAO/Group.php @@ -900,7 +900,7 @@ class CRM_Contact_BAO_Group extends CRM_Contact_DAO_Group { $visibility = CRM_Core_SelectValues::ufVisibility(); while ($object->fetch()) { - $permission = CRM_Contact_BAO_Group::checkPermission($object->id, $object->title); + $permission = CRM_Contact_BAO_Group::checkPermission($object->id, TRUE); //@todo CRM-12209 introduced an ACL check in the whereClause function // it may be that this checking is now obsolete - or that what remains // should be removed to the whereClause (which is also accessed by getCount) diff --git a/civicrm/CRM/Contact/BAO/GroupContact.php b/civicrm/CRM/Contact/BAO/GroupContact.php index e50f028ad3..8833d1958d 100644 --- a/civicrm/CRM/Contact/BAO/GroupContact.php +++ b/civicrm/CRM/Contact/BAO/GroupContact.php @@ -134,6 +134,9 @@ class CRM_Contact_BAO_GroupContact extends CRM_Contact_DAO_GroupContact { $status = 'Added', $tracking = NULL ) { + if (empty($contactIds) || empty($groupId)) { + return array(); + } CRM_Utils_Hook::pre('create', 'GroupContact', $groupId, $contactIds); diff --git a/civicrm/CRM/Contact/BAO/Query.php b/civicrm/CRM/Contact/BAO/Query.php index f0bda01fa8..e905154411 100644 --- a/civicrm/CRM/Contact/BAO/Query.php +++ b/civicrm/CRM/Contact/BAO/Query.php @@ -654,8 +654,6 @@ class CRM_Contact_BAO_Query { (substr($name, 0, 12) == 'participant_') || (substr($name, 0, 7) == 'pledge_') || (substr($name, 0, 5) == 'case_') || - (substr($name, 0, 13) == 'contribution_' && - (strpos($name, 'source') !== FALSE && strpos($name, 'recur') !== FALSE)) || (substr($name, 0, 8) == 'payment_') ) { continue; @@ -700,15 +698,12 @@ class CRM_Contact_BAO_Query { } } - if (in_array($name, array('prefix_id', 'suffix_id', 'gender_id', 'communication_style_id'))) { - if (CRM_Utils_Array::value($field['pseudoconstant']['optionGroupName'], $this->_returnProperties)) { - $makeException = TRUE; - } - } - $cfID = CRM_Core_BAO_CustomField::getKeyID($name); - if (!empty($this->_paramLookup[$name]) || !empty($this->_returnProperties[$name]) || - $makeException + if ( + !empty($this->_paramLookup[$name]) + || !empty($this->_returnProperties[$name]) + || $this->pseudoConstantNameIsInReturnProperties($field) + || $makeException ) { if ($cfID) { // add to cfIDs array if not present @@ -828,42 +823,12 @@ class CRM_Contact_BAO_Query { $this->_element['provider_id'] = 1; } - if ($tName == 'contact') { + if ($tName == 'contact' && $fieldName == 'organization_name') { // special case, when current employer is set for Individual contact - if ($fieldName == 'organization_name') { - $this->_select[$name] = "IF ( contact_a.contact_type = 'Individual', NULL, contact_a.organization_name ) as organization_name"; - } - elseif ($fieldName != 'id') { - if ($fieldName == 'prefix_id') { - $this->_pseudoConstantsSelect['individual_prefix'] = array( - 'pseudoField' => 'prefix_id', - 'idCol' => "prefix_id", - 'bao' => 'CRM_Contact_BAO_Contact', - ); - } - if ($fieldName == 'suffix_id') { - $this->_pseudoConstantsSelect['individual_suffix'] = array( - 'pseudoField' => 'suffix_id', - 'idCol' => "suffix_id", - 'bao' => 'CRM_Contact_BAO_Contact', - ); - } - if ($fieldName == 'gender_id') { - $this->_pseudoConstantsSelect['gender'] = array( - 'pseudoField' => 'gender_id', - 'idCol' => "gender_id", - 'bao' => 'CRM_Contact_BAO_Contact', - ); - } - if ($name == 'communication_style_id') { - $this->_pseudoConstantsSelect['communication_style'] = array( - 'pseudoField' => 'communication_style_id', - 'idCol' => "communication_style_id", - 'bao' => 'CRM_Contact_BAO_Contact', - ); - } - $this->_select[$name] = "contact_a.{$fieldName} as `$name`"; - } + $this->_select[$name] = "IF ( contact_a.contact_type = 'Individual', NULL, contact_a.organization_name ) as organization_name"; + } + elseif ($tName == 'contact' && $fieldName === 'id') { + // Handled elsewhere, explicitly ignore. Possibly for all tables... } elseif (in_array($tName, array('country', 'county'))) { $this->_pseudoConstantsSelect[$name]['select'] = "{$field['where']} as `$name`"; @@ -879,7 +844,22 @@ class CRM_Contact_BAO_Query { } } else { - $this->_select[$name] = "{$field['where']} as `$name`"; + // If we have an option group defined then rather than joining the option value table in + // (which is an unindexed join) we render the option value on output. + // @todo - extend this to other pseudoconstants. + if ($this->pseudoConstantNameIsInReturnProperties($field)) { + $pseudoFieldName = $field['pseudoconstant']['optionGroupName']; + $this->_pseudoConstantsSelect[$pseudoFieldName] = array( + 'pseudoField' => $field['name'], + 'idCol' => $field['name'], + 'field_name' => $field['name'], + 'bao' => $field['bao'], + 'pseudoconstant' => $field['pseudoconstant'], + ); + $this->_tables[$tableName] = 1; + $this->_element[$pseudoFieldName] = 1; + } + $this->_select[$name] = str_replace('civicrm_contact.', 'contact_a.', "{$field['where']} as `$name`"); } if (!in_array($tName, array('state_province', 'country', 'county'))) { $this->_element[$name] = 1; @@ -2968,7 +2948,6 @@ class CRM_Contact_BAO_Query { else { $statii[] = "'Added'"; } - $groupClause = array(); if (count($regularGroupIDs) || empty($value)) { $groupIds = implode(',', (array) $regularGroupIDs); @@ -4340,7 +4319,7 @@ civicrm_relationship.is_permission_a_b = 0 $smartGroupCache = TRUE, $count = FALSE, $skipPermissions = TRUE, - $mode = 1, + $mode = CRM_Contact_BAO_Query::MODE_CONTACTS, $apiEntity = NULL ) { @@ -4403,7 +4382,7 @@ civicrm_relationship.is_permission_a_b = 0 return array($noRows, NULL); } $val = $query->store($dao); - $convertedVals = $query->convertToPseudoNames($dao, TRUE); + $convertedVals = $query->convertToPseudoNames($dao, TRUE, TRUE); if (!empty($convertedVals)) { $val = array_replace_recursive($val, $convertedVals); @@ -5832,12 +5811,40 @@ AND displayRelType.is_active = 1 $val = $dao->{$value['idCol']}; if ($key == 'groups') { $dao->groups = $this->convertGroupIDStringToLabelString($dao, $val); - return; + continue; } if (CRM_Utils_System::isNull($val)) { $dao->$key = NULL; } + elseif (!empty($value['pseudoconstant'])) { + // If pseudoconstant is set that is kind of defacto for 'we have a bit more info about this' + // and we can use the metadata to figure it out. + // ideally this bit of IF will absorb & replace all the rest in time as we move to + // more metadata based choices. + if (strpos($val, CRM_Core_DAO::VALUE_SEPARATOR) !== FALSE) { + $dbValues = explode(CRM_Core_DAO::VALUE_SEPARATOR, trim($val, CRM_Core_DAO::VALUE_SEPARATOR)); + foreach ($dbValues as $pseudoValue) { + $convertedValues[] = CRM_Core_PseudoConstant::getLabel($value['bao'], $value['idCol'], $pseudoValue); + } + + $dao->$key = ($usedForAPI) ? $convertedValues : implode(', ', $convertedValues); + $realFieldName = CRM_Utils_Array::value('field_name', $this->_pseudoConstantsSelect[$key]); + if ($usedForAPI && $realFieldName) { + // normally we would see 2 fields returned for pseudoConstants. An exception is + // preferred_communication_method where there is no id-variant. + // For the api we prioritise getting the real data returned. + // over the resolved version + $dao->$realFieldName = $dbValues; + } + + } + else { + // This is basically the same as the default but since we have the bao we can use + // a cached function. + $dao->$key = CRM_Core_PseudoConstant::getLabel($value['bao'], $value['idCol'], $val); + } + } elseif ($baoName = CRM_Utils_Array::value('bao', $value, NULL)) { //preserve id value $idColumn = "{$key}_id"; @@ -5853,8 +5860,7 @@ AND displayRelType.is_active = 1 elseif ($value['pseudoField'] == 'state_province_abbreviation') { $dao->$key = CRM_Core_PseudoConstant::stateProvinceAbbreviation($val); } - // FIX ME: we should potentially move this to component Query and write a wrapper function that - // handles pseudoconstant fixes for all component + // @todo handle this in the section above for pseudoconstants. elseif (in_array($value['pseudoField'], array('participant_role_id', 'participant_role'))) { // @todo define bao on this & merge into the above condition. $viewValues = explode(CRM_Core_DAO::VALUE_SEPARATOR, $val); @@ -5892,6 +5898,21 @@ AND displayRelType.is_active = 1 } } } + if (!$usedForAPI) { + foreach (array( + 'gender_id' => 'gender', + 'prefix_id' => 'individual_prefix', + 'suffix_id' => 'individual_suffix', + 'communication_style_id' => 'communication_style', + ) as $realField => $labelField) { + // This is a temporary routine for handling these fields while + // we figure out how to handled them based on metadata in + /// export and search builder. CRM-19815, CRM-19830. + if (isset($dao->$realField) && is_numeric($dao->$realField) && isset($dao->$labelField)) { + $dao->$realField = $dao->$labelField; + } + } + } return $values; } @@ -6132,6 +6153,7 @@ AND displayRelType.is_active = 1 */ protected function prepareOrderBy($sort, $sortByChar, $sortOrder, $additionalFromClause) { $order = NULL; + $orderByArray = array(); $config = CRM_Core_Config::singleton(); if ($config->includeOrderByClause || isset($this->_distinctComponentClause) @@ -6168,60 +6190,62 @@ AND displayRelType.is_active = 1 } } elseif ($sortByChar) { - $order = " ORDER BY UPPER(LEFT(contact_a.sort_name, 1)) asc"; + $orderByArray = array("UPPER(LEFT(contact_a.sort_name, 1)) asc"); } else { $order = " ORDER BY contact_a.sort_name asc, contact_a.id"; } } + if (!$order && empty($orderByArray)) { + return array($order, $additionalFromClause); + } + // Remove this here & add it at the end for simplicity. + $order = trim(str_replace('ORDER BY', '', $order)); // hack for order clause - if ($order) { - $fieldStr = trim(str_replace('ORDER BY', '', $order)); - $fieldOrder = explode(' ', $fieldStr); - $field = $fieldOrder[0]; - - if ($field) { - switch ($field) { - case 'city': - case 'postal_code': - $this->_tables["civicrm_address"] = $this->_whereTables["civicrm_address"] = 1; - $order = str_replace($field, "civicrm_address.{$field}", $order); - break; - - case 'country': - case 'state_province': - $this->_tables["civicrm_{$field}"] = $this->_whereTables["civicrm_{$field}"] = 1; - if (is_array($this->_returnProperties) && empty($this->_returnProperties)) { - $additionalFromClause .= " LEFT JOIN civicrm_{$field} ON civicrm_{$field}.id = civicrm_address.{$field}_id"; - } - $order = str_replace($field, "civicrm_{$field}.name", $order); - break; + $fieldOrder = explode(' ', $order); + $field = $fieldOrder[0]; + + if ($field) { + switch ($field) { + case 'city': + case 'postal_code': + $this->_tables["civicrm_address"] = $this->_whereTables["civicrm_address"] = 1; + $order = str_replace($field, "civicrm_address.{$field}", $order); + break; + + case 'country': + case 'state_province': + $this->_tables["civicrm_{$field}"] = $this->_whereTables["civicrm_{$field}"] = 1; + if (is_array($this->_returnProperties) && empty($this->_returnProperties)) { + $additionalFromClause .= " LEFT JOIN civicrm_{$field} ON civicrm_{$field}.id = civicrm_address.{$field}_id"; + } + $order = str_replace($field, "civicrm_{$field}.name", $order); + break; - case 'email': - $this->_tables["civicrm_email"] = $this->_whereTables["civicrm_email"] = 1; - $order = str_replace($field, "civicrm_email.{$field}", $order); - break; + case 'email': + $this->_tables["civicrm_email"] = $this->_whereTables["civicrm_email"] = 1; + $order = str_replace($field, "civicrm_email.{$field}", $order); + break; - default: - //CRM-12565 add "`" around $field if it is a pseudo constant - foreach ($this->_pseudoConstantsSelect as $key => $value) { - if (!empty($value['element']) && $value['element'] == $field) { - $order = str_replace($field, "`{$field}`", $order); - } + default: + //CRM-12565 add "`" around $field if it is a pseudo constant + foreach ($this->_pseudoConstantsSelect as $key => $value) { + if (!empty($value['element']) && $value['element'] == $field) { + $order = str_replace($field, "`{$field}`", $order); } - } - $this->_fromClause = self::fromClause($this->_tables, NULL, NULL, $this->_primaryLocation, $this->_mode); - $this->_simpleFromClause = self::fromClause($this->_whereTables, NULL, NULL, $this->_primaryLocation, $this->_mode); + } } + $this->_fromClause = self::fromClause($this->_tables, NULL, NULL, $this->_primaryLocation, $this->_mode); + $this->_simpleFromClause = self::fromClause($this->_whereTables, NULL, NULL, $this->_primaryLocation, $this->_mode); } // The above code relies on crazy brittle string manipulation of a peculiarly-encoded ORDER BY // clause. But this magic helper which forgivingly reescapes ORDER BY. // Note: $sortByChar implies that $order was hard-coded/trusted, so it can do funky things. if ($order && !$sortByChar) { - $order = ' ORDER BY ' . CRM_Utils_Type::escape(preg_replace('/^\s*ORDER BY\s*/', '', $order), 'MysqlOrderBy'); - return array($order, $additionalFromClause); + $order = CRM_Utils_Type::escape($order, 'MysqlOrderBy'); + return array(' ORDER BY ' . $order, $additionalFromClause); } return array($order, $additionalFromClause); } @@ -6273,4 +6297,33 @@ AND displayRelType.is_active = 1 )); } + /** + * Has the pseudoconstant of the field been requested. + * + * For example if the field is payment_instrument_id then it + * has been requested if either payment_instrument_id or payment_instrument + * have been requested. Payment_instrument is the option groun name field value. + * + * @param array $field + * + * @return bool + */ + private function pseudoConstantNameIsInReturnProperties($field) { + if (!isset($field['pseudoconstant']['optionGroupName'])) { + return FALSE; + } + if (empty($field['bao']) || $field['bao'] != 'CRM_Contact_BAO_Contact') { + // For now.... + return FALSE; + } + + if (CRM_Utils_Array::value($field['pseudoconstant']['optionGroupName'], $this->_returnProperties)) { + return TRUE; + } + if (CRM_Utils_Array::value($field['name'], $this->_returnProperties)) { + return TRUE; + } + return FALSE; + } + } diff --git a/civicrm/CRM/Contact/DAO/Contact.php b/civicrm/CRM/Contact/DAO/Contact.php index dd66d1e924..0f375714fc 100644 --- a/civicrm/CRM/Contact/DAO/Contact.php +++ b/civicrm/CRM/Contact/DAO/Contact.php @@ -30,7 +30,7 @@ * * Generated from xml/schema/CRM/Contact/Contact.xml * DO NOT EDIT. Generated by CRM_Core_CodeGen - * (GenCodeChecksum:0c8e687501dbd8f44354ee5f5cdf9b52) + * (GenCodeChecksum:b16421c318c1224c65e18a9e2aa15a5e) */ require_once 'CRM/Core/DAO.php'; require_once 'CRM/Utils/Type.php'; @@ -1114,7 +1114,7 @@ class CRM_Contact_DAO_Contact extends CRM_Core_DAO { 'bao' => 'CRM_Contact_BAO_Contact', 'html' => array( 'type' => 'Select Date', - 'format' => 'birth', + 'formatType' => 'birth', ) , ) , 'is_deceased' => array( @@ -1148,7 +1148,7 @@ class CRM_Contact_DAO_Contact extends CRM_Core_DAO { 'bao' => 'CRM_Contact_BAO_Contact', 'html' => array( 'type' => 'Select Date', - 'format' => 'birth', + 'formatType' => 'birth', ) , ) , 'household_name' => array( diff --git a/civicrm/CRM/Contact/Form/Merge.php b/civicrm/CRM/Contact/Form/Merge.php index ad9a8e6563..9445834f0a 100644 --- a/civicrm/CRM/Contact/Form/Merge.php +++ b/civicrm/CRM/Contact/Form/Merge.php @@ -78,24 +78,25 @@ class CRM_Contact_Form_Merge extends CRM_Core_Form { $this->limit = CRM_Utils_Request::retrieve('limit', 'Positive', $this, FALSE); $urlParams = "reset=1&rgid={$this->_rgid}&gid={$this->_gid}&limit=" . $this->limit; - // Sanity check - if ($cid == $oid) { - CRM_Core_Error::statusBounce(ts('Cannot merge a contact with itself.')); - } + $this->bounceIfInvalid($cid, $oid); - if (!CRM_Dedupe_BAO_Rule::validateContacts($cid, $oid)) { - CRM_Core_Error::statusBounce(ts('The selected pair of contacts are marked as non duplicates. If these records should be merged, you can remove this exception on the <a href="%1">Dedupe Exceptions</a> page.', array(1 => CRM_Utils_System::url('civicrm/dedupe/exception', 'reset=1')))); - } $this->_contactType = civicrm_api3('Contact', 'getvalue', array('id' => $cid, 'return' => 'contact_type')); - $isFromDedupeScreen = TRUE; + + $browseUrl = CRM_Utils_System::url('civicrm/contact/dedupefind', $urlParams . '&action=browse'); + if (!$this->_rgid) { - $isFromDedupeScreen = FALSE; + // Unset browse URL as we have come from the search screen. + $browseUrl = ''; $this->_rgid = civicrm_api3('RuleGroup', 'getvalue', array( 'contact_type' => $this->_contactType, 'used' => 'Supervised', 'return' => 'id', )); } + $this->assign('browseUrl', $browseUrl); + if ($browseUrl) { + CRM_Core_Session::singleton()->pushUserContext($browseUrl); + } $cacheKey = CRM_Dedupe_Merger::getMergeCacheKeyString($this->_rgid, $gid); @@ -104,14 +105,6 @@ class CRM_Contact_Form_Merge extends CRM_Core_Form { $pos = CRM_Core_BAO_PrevNextCache::getPositions($cacheKey, $cid, $oid, $this->_mergeId, $join, $where, $flip); - // Block access if user does not have EDIT permissions for both contacts. - if (!(CRM_Contact_BAO_Contact_Permission::allow($cid, CRM_Core_Permission::EDIT) && - CRM_Contact_BAO_Contact_Permission::allow($oid, CRM_Core_Permission::EDIT) - ) - ) { - CRM_Utils_System::permissionDenied(); - } - // get user info of main contact. $config = CRM_Core_Config::singleton(); $config->doNotResetCache = 1; @@ -176,25 +169,9 @@ class CRM_Contact_Form_Merge extends CRM_Core_Form { $session = CRM_Core_Session::singleton(); - // context fixed. - if ($isFromDedupeScreen) { - $browseUrl = CRM_Utils_System::url('civicrm/contact/dedupefind', $urlParams . '&action=browse'); - $session->pushUserContext($browseUrl); - } - $this->assign('browseUrl', empty($browseUrl) ? '' : $browseUrl); - - // ensure that oid is not the current user, if so refuse to do the merge - if ($session->get('userID') == $oid) { - $display_name = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $oid, 'display_name'); - $message = ts('The contact record which is linked to the currently logged in user account - \'%1\' - cannot be deleted.', - array(1 => $display_name) - ); - CRM_Core_Error::statusBounce($message); - } - $rowsElementsAndInfo = CRM_Dedupe_Merger::getRowsElementsAndInfo($cid, $oid); - $main = $this->_mainDetails = &$rowsElementsAndInfo['main_details']; - $other = $this->_otherDetails = &$rowsElementsAndInfo['other_details']; + $main = $this->_mainDetails = $rowsElementsAndInfo['main_details']; + $other = $this->_otherDetails = $rowsElementsAndInfo['other_details']; if ($main['contact_id'] != $cid) { CRM_Core_Error::fatal(ts('The main contact record does not exist')); @@ -222,6 +199,19 @@ class CRM_Contact_Form_Merge extends CRM_Core_Form { // add elements foreach ($rowsElementsAndInfo['elements'] as $element) { + // We could push this down to the getRowsElementsAndInfo function but it's + // already so overloaded - let's start moving towards doing form-things + // on the form. + if (substr($element[1], 0, 13) === 'move_location') { + $element[4] = array_merge( + (array) CRM_Utils_Array::value(4, $element, array()), + array('data-location' => substr($element[1], 14), 'data-is_location' => TRUE)); + } + if (substr($element[1], 0, 15) === 'location_blocks') { + // @todo We could add some data elements here to make jquery manipulation more straight-forward + // @todo consider enabling if it is an add & defaulting to true. + $element[4] = array_merge((array) CRM_Utils_Array::value(4, $element, array()), array('disabled' => TRUE)); + } $this->addElement($element[0], $element[1], array_key_exists('2', $element) ? $element[2] : NULL, @@ -241,22 +231,6 @@ class CRM_Contact_Form_Merge extends CRM_Core_Form { $this->assign('userContextURL', $session->readUserContext()); } - /** - * This virtual function is used to set the default values of - * various form elements - * - * access public - * - * @return array - * reference to the array of default values - */ - /** - * @return array - */ - public function setDefaultValues() { - return array('deleteOther' => 1); - } - public function addRules() { } @@ -366,4 +340,39 @@ class CRM_Contact_Form_Merge extends CRM_Core_Form { CRM_Utils_System::redirect($url); } + /** + * Bounce if the merge action is invalid. + * + * We don't allow the merge if it is nonsensical, marked as a duplicate + * or outside the user's permission. + * + * @param int $cid + * Contact ID to retain + * @param int $oid + * Contact ID to delete. + */ + public function bounceIfInvalid($cid, $oid) { + if ($cid == $oid) { + CRM_Core_Error::statusBounce(ts('Cannot merge a contact with itself.')); + } + + if (!CRM_Dedupe_BAO_Rule::validateContacts($cid, $oid)) { + CRM_Core_Error::statusBounce(ts('The selected pair of contacts are marked as non duplicates. If these records should be merged, you can remove this exception on the <a href="%1">Dedupe Exceptions</a> page.', array(1 => CRM_Utils_System::url('civicrm/dedupe/exception', 'reset=1')))); + } + + if (!(CRM_Contact_BAO_Contact_Permission::allow($cid, CRM_Core_Permission::EDIT) && + CRM_Contact_BAO_Contact_Permission::allow($oid, CRM_Core_Permission::EDIT) + ) + ) { + CRM_Utils_System::permissionDenied(); + } + // ensure that oid is not the current user, if so refuse to do the merge + if (CRM_Core_Session::singleton()->getLoggedInContactID() == $oid) { + $message = ts('The contact record which is linked to the currently logged in user account - \'%1\' - cannot be deleted.', + array(1 => CRM_Core_Session::singleton()->getLoggedInContactDisplayName()) + ); + CRM_Core_Error::statusBounce($message); + } + } + } diff --git a/civicrm/CRM/Contact/Page/DedupeFind.php b/civicrm/CRM/Contact/Page/DedupeFind.php index aaaebefe4b..affce8e20d 100644 --- a/civicrm/CRM/Contact/Page/DedupeFind.php +++ b/civicrm/CRM/Contact/Page/DedupeFind.php @@ -88,7 +88,7 @@ class CRM_Contact_Page_DedupeFind extends CRM_Core_Page_Basic { } elseif ($action & CRM_Core_Action::MAP) { // do a batch merge if requested - $result = CRM_Dedupe_Merger::batchMerge($rgid, $gid, 'safe', TRUE, 75); + $result = CRM_Dedupe_Merger::batchMerge($rgid, $gid, 'safe', 75); $skippedCount = CRM_Utils_Request::retrieve('skipped', 'Positive', $this, FALSE, 0); $skippedCount = $skippedCount + count($result['skipped']); diff --git a/civicrm/CRM/Contact/Page/DedupeMerge.php b/civicrm/CRM/Contact/Page/DedupeMerge.php index ffcd028def..df91a146f4 100644 --- a/civicrm/CRM/Contact/Page/DedupeMerge.php +++ b/civicrm/CRM/Contact/Page/DedupeMerge.php @@ -98,7 +98,7 @@ class CRM_Contact_Page_DedupeMerge extends CRM_Core_Page { for ($i = 1; $i <= ceil($total / self::BATCHLIMIT); $i++) { $task = new CRM_Queue_Task( array('CRM_Contact_Page_DedupeMerge', 'callBatchMerge'), - array($rgid, $gid, $mode, FALSE, self::BATCHLIMIT, $isSelected), + array($rgid, $gid, $mode, self::BATCHLIMIT, $isSelected), "Processed " . $i * self::BATCHLIMIT . " pair of duplicates out of " . $total ); @@ -126,17 +126,13 @@ class CRM_Contact_Page_DedupeMerge extends CRM_Core_Page { * @param int $gid * @param string $mode * 'safe' mode or 'force' mode. - * @param bool $autoFlip - * Override the values in the prevnext table & use the lowest value? - * As the form offers the user to flip the values themselves this should - * only be TRUE if you wish to ignore the user. * @param int $batchLimit * @param int $isSelected * * @return int */ - public static function callBatchMerge(CRM_Queue_TaskContext $ctx, $rgid, $gid, $mode = 'safe', $autoFlip, $batchLimit, $isSelected) { - CRM_Dedupe_Merger::batchMerge($rgid, $gid, $mode, $autoFlip, $batchLimit, $isSelected); + public static function callBatchMerge(CRM_Queue_TaskContext $ctx, $rgid, $gid, $mode = 'safe', $batchLimit, $isSelected) { + CRM_Dedupe_Merger::batchMerge($rgid, $gid, $mode, $batchLimit, $isSelected); return CRM_Queue_Task::TASK_SUCCESS; } diff --git a/civicrm/CRM/Contact/Page/SavedSearch.php b/civicrm/CRM/Contact/Page/SavedSearch.php index 950531d28b..ab9f39bd2d 100644 --- a/civicrm/CRM/Contact/Page/SavedSearch.php +++ b/civicrm/CRM/Contact/Page/SavedSearch.php @@ -83,7 +83,7 @@ class CRM_Contact_Page_SavedSearch extends CRM_Core_Page { $group = new CRM_Contact_DAO_Group(); $group->saved_search_id = $savedSearch->id; if ($group->find(TRUE)) { - $permissions = CRM_Group_Page_Group::checkPermission($group->id, $group->title); + $permissions = CRM_Contact_BAO_Group::checkPermission($group->id, TRUE); if (!CRM_Utils_System::isNull($permissions)) { $row = array(); diff --git a/civicrm/CRM/Contact/Selector.php b/civicrm/CRM/Contact/Selector.php index 8a92ce1a09..8cb3ec84e6 100644 --- a/civicrm/CRM/Contact/Selector.php +++ b/civicrm/CRM/Contact/Selector.php @@ -637,8 +637,6 @@ class CRM_Contact_Selector extends CRM_Core_Selector_Base implements CRM_Core_Se $names = self::$_properties; } - $multipleSelectFields = array('preferred_communication_method' => 1); - $links = self::links($this->_context, $this->_contextMenu, $this->_key); //check explicitly added contact to a Smart Group. @@ -656,7 +654,6 @@ class CRM_Contact_Selector extends CRM_Core_Selector_Base implements CRM_Core_Se while ($result->fetch()) { $row = array(); $this->_query->convertToPseudoNames($result); - // the columns we are interested in foreach ($names as $property) { if ($property == 'status') { @@ -669,17 +666,6 @@ class CRM_Contact_Selector extends CRM_Core_Selector_Base implements CRM_Core_Se $result->contact_id ); } - elseif ( - $multipleSelectFields && - array_key_exists($property, $multipleSelectFields) - ) { - $key = $property; - $paramsNew = array($key => $result->$property); - $name = array($key => array('newName' => $key, 'groupName' => $key)); - - CRM_Core_OptionGroup::lookupValues($paramsNew, $name, FALSE); - $row[$key] = $paramsNew[$key]; - } elseif (strpos($property, '-im')) { $row[$property] = $result->$property; if (!empty($result->$property)) { diff --git a/civicrm/CRM/Contribute/BAO/Contribution.php b/civicrm/CRM/Contribute/BAO/Contribution.php index e74a29f2f0..ab6c479f01 100644 --- a/civicrm/CRM/Contribute/BAO/Contribution.php +++ b/civicrm/CRM/Contribute/BAO/Contribution.php @@ -825,15 +825,6 @@ class CRM_Contribute_BAO_Contribution extends CRM_Contribute_DAO_Contribution { ), ); - $contributionRecurId = array( - 'contribution_recur_id' => array( - 'title' => ts('Recurring Contributions ID'), - 'name' => 'contribution_recur_id', - 'where' => 'civicrm_contribution.contribution_recur_id', - 'data_type' => CRM_Utils_Type::T_INT, - ), - ); - $extraFields = array( 'contribution_batch' => array( 'title' => ts('Batch Name'), @@ -893,7 +884,7 @@ class CRM_Contribute_BAO_Contribution extends CRM_Contribute_DAO_Contribution { ); $fields = array_merge($impFields, $typeField, $contributionStatus, $contributionPage, $optionField, $expFieldProduct, - $expFieldsContrib, $contributionNote, $contributionRecurId, $extraFields, $softCreditFields, $financialAccount, $premiums, $campaignTitle, + $expFieldsContrib, $contributionNote, $extraFields, $softCreditFields, $financialAccount, $premiums, $campaignTitle, CRM_Core_BAO_CustomField::getFieldsForImport('Contribution', FALSE, FALSE, FALSE, $checkPermission) ); @@ -4476,6 +4467,12 @@ WHERE eft.financial_trxn_id IN ({$trxnId}, {$baseTrxnId['financialTrxnId']}) )); $contributionParams['payment_processor'] = $input['payment_processor'] = $paymentProcessorId; + // If paymentProcessor is not set then the payment_instrument_id would not be correct. + // not clear when or if this would occur if you encounter this please fix here & add a unit test. + if (empty($contributionParams['payment_instrument_id']) && isset($contribution->_relatedObjects['paymentProcessor']['payment_instrument_id'])) { + $contributionParams['payment_instrument_id'] = $contribution->_relatedObjects['paymentProcessor']['payment_instrument_id']; + } + if ($recurringContributionID) { $contributionParams['contribution_recur_id'] = $recurringContributionID; } @@ -4718,14 +4715,8 @@ LIMIT 1;"; $contribution->loadRelatedObjects($input, $ids, TRUE); // set receipt from e-mail and name in value if (!$returnMessageText) { - $userID = CRM_Core_Session::singleton()->getLoggedInContactID(); - if (!empty($userID)) { - list($userName, $userEmail) = CRM_Contact_BAO_Contact_Location::getEmailDetails($userID); - $values['receipt_from_email'] = CRM_Utils_Array::value('receipt_from_email', $input, $userEmail); - $values['receipt_from_name'] = CRM_Utils_Array::value('receipt_from_name', $input, $userName); - } + list($values['receipt_from_name'], $values['receipt_from_email']) = self::generateFromEmailAndName($input, $contribution); } - $return = $contribution->composeMessageArray($input, $ids, $values, $recur, $returnMessageText); // Contribution ID should really always be set. But ? if (!$returnMessageText && (!isset($input['receipt_update']) || $input['receipt_update']) && empty($contribution->receipt_date)) { @@ -4734,6 +4725,42 @@ LIMIT 1;"; return $return; } + /** + * Generate From email and from name in an array values + */ + public static function generateFromEmailAndName($input, $contribution) { + // Use input valuse if supplied. + if (!empty($input['receipt_from_email'])) { + return array(CRM_Utils_array::value('receipt_from_name', $input, ''), $input['receipt_from_email']); + } + // if we are still empty see if we can use anything from a contribution page. + $pageValues = array(); + if (!empty($contribution->contribution_page_id)) { + $pageValues = civicrm_api3('ContributionPage', 'getsingle', array('id' => $contribution->contribution_page_id)); + } + // if we are still empty see if we can use anything from a contribution page. + if (!empty($pageValues['receipt_from_email'])) { + return array($pageValues['receipt_from_name'], $pageValues['receipt_from_email']); + } + // If we are still empty fall back to the domain. + $domain = civicrm_api3('domain', 'getsingle', array('id' => CRM_Core_Config::domainID())); + if (!empty($domain['from_email'])) { + return array($domain['from_name'], $domain['from_email']); + } + if (!empty($domain['domain_email'])) { + return array($domain['name'], $domain['domain_email']); + } + $userID = CRM_Core_Session::singleton()->getLoggedInContactID(); + $userName = ''; + $userEmail = ''; + if (!empty($userID)) { + list($userName, $userEmail) = CRM_Contact_BAO_Contact_Location::getEmailDetails($userID); + } + // If still empty fall back to the logged in user details. + // return empty values no matter what. + return array($userName, $userEmail); + } + /** * Generate credit note id with next avaible number * @@ -5390,8 +5417,8 @@ LEFT JOIN civicrm_contribution on (civicrm_contribution.contact_id = civicrm_co */ public static function createProportionalEntry($entityParams, $eftParams) { $paid = $entityParams['line_item_amount'] * ($entityParams['trxn_total_amount'] / $entityParams['contribution_total_amount']); - // Record Entity Financial Trxn - $eftParams['amount'] = round($paid, 2); + // Record Entity Financial Trxn; CRM-20145 + $eftParams['amount'] = CRM_Contribute_BAO_Contribution_Utils::formatAmount($paid); civicrm_api3('EntityFinancialTrxn', 'create', $eftParams); } diff --git a/civicrm/CRM/Contribute/BAO/Contribution/Utils.php b/civicrm/CRM/Contribute/BAO/Contribution/Utils.php index 6ea7c5b271..6633d2fe43 100644 --- a/civicrm/CRM/Contribute/BAO/Contribution/Utils.php +++ b/civicrm/CRM/Contribute/BAO/Contribution/Utils.php @@ -475,9 +475,26 @@ LIMIT 1 */ public static function calculateTaxAmount($amount, $taxRate) { $taxAmount = array(); - $taxAmount['tax_amount'] = round(($taxRate / 100) * CRM_Utils_Rule::cleanMoney($amount), 2); + // There can not be any rounding at this stage - as this is prior to quantity multiplication + $taxAmount['tax_amount'] = ($taxRate / 100) * CRM_Utils_Rule::cleanMoney($amount); return $taxAmount; } + /** + * Format monetary amount: round and return to desired decimal place + * CRM-20145 + * + * @param float $amount + * Monetary amount + * @param int $decimals + * How many decimal places to round to and return + * + * @return float + * Amount rounded and returned with the desired decimal places + */ + public static function formatAmount($amount, $decimals = 2) { + return number_format((float) round($amount, (int) $decimals), (int) $decimals, '.', ''); + } + } diff --git a/civicrm/CRM/Contribute/BAO/Query.php b/civicrm/CRM/Contribute/BAO/Query.php index e09ddd64d1..f7e4f5d06c 100644 --- a/civicrm/CRM/Contribute/BAO/Query.php +++ b/civicrm/CRM/Contribute/BAO/Query.php @@ -97,12 +97,6 @@ class CRM_Contribute_BAO_Query extends CRM_Core_BAO_Query { $query->_tables['contribution_batch'] = 1; } - if (!empty($query->_returnProperties['contribution_source'])) { - $query->_select['contribution_source'] = "civicrm_contribution.source as contribution_source"; - $query->_element['contribution_source'] = 1; - $query->_tables['civicrm_contribution'] = 1; - } - // get contribution_status if (!empty($query->_returnProperties['contribution_status_id'])) { $query->_select['contribution_status_id'] = "contribution_status.value as contribution_status_id"; @@ -136,39 +130,11 @@ class CRM_Contribute_BAO_Query extends CRM_Core_BAO_Query { $query->_tables['contribution_payment_instrument'] = 1; } - if (!empty($query->_returnProperties['check_number'])) { - $query->_select['contribution_check_number'] = "civicrm_contribution.check_number as contribution_check_number"; - $query->_element['contribution_check_number'] = 1; - $query->_tables['civicrm_contribution'] = 1; - } - - if (!empty($query->_returnProperties['contribution_campaign_id'])) { - $query->_select['contribution_campaign_id'] = 'civicrm_contribution.campaign_id as contribution_campaign_id'; - $query->_element['contribution_campaign_id'] = 1; - $query->_tables['civicrm_contribution'] = 1; - } - if (!empty($query->_returnProperties['contribution_campaign_title'])) { $query->_select['contribution_campaign_title'] = "civicrm_campaign.title as contribution_campaign_title"; $query->_element['contribution_campaign_title'] = $query->_tables['civicrm_campaign'] = 1; } - // Adding address_id in a way that is more easily extendable since the above is a bit ... wordy. - $supportedBasicReturnValues = array('address_id'); - foreach ($supportedBasicReturnValues as $fieldName) { - if (!empty($query->_returnProperties[$fieldName]) && empty($query->_select[$fieldName])) { - $query->_select[$fieldName] = "civicrm_contribution.{$fieldName} as $fieldName"; - $query->_element[$fieldName] = $query->_tables['civicrm_contribution'] = 1; - } - } - - //CRM-16116: get financial_type_id - if (!empty($query->_returnProperties['financial_type_id'])) { - $query->_select['financial_type_id'] = "civicrm_contribution.financial_type_id as financial_type_id"; - $query->_element['financial_type_id'] = $query->_tables['civicrm_contribution'] = 1; - } - // LCD 716 END - self::addSoftCreditFields($query); } @@ -230,6 +196,20 @@ class CRM_Contribute_BAO_Query extends CRM_Core_BAO_Query { return; } } + // These are legacy names. + // @todo enotices when these are hit so we can start to elimnate them. + $fieldAliases = array( + 'financial_type' => 'financial_type_id', + 'contribution_page' => 'contribution_page_id', + 'payment_instrument' => 'payment_instrument_id', + // or payment_instrument_id? + 'contribution_payment_instrument' => 'contribution_payment_instrument_id', + 'contribution_status' => 'contribution_status_id', + ); + $name = isset($fieldAliases[$name]) ? $fieldAliases[$name] : $name; + $qillName = $name; + $pseudoExtraParam = array(); + switch ($name) { case 'contribution_date': case 'contribution_date_low': @@ -279,12 +259,6 @@ class CRM_Contribute_BAO_Query extends CRM_Core_BAO_Query { $query->_tables['civicrm_contribution'] = $query->_whereTables['civicrm_contribution'] = 1; return; - case 'financial_type': - case 'contribution_page': - case 'payment_instrument': - case 'contribution_payment_instrument': - case 'contribution_status': - $name .= '_id'; case 'financial_type_id': // @todo we need to make this resemble a hook approach. CRM_Financial_BAO_FinancialType::getAvailableFinancialTypes($financialTypes); @@ -304,26 +278,19 @@ class CRM_Contribute_BAO_Query extends CRM_Core_BAO_Query { case (strpos($name, '_amount') !== FALSE): case (strpos($name, '_date') !== FALSE && $name != 'contribution_fulfilled_date'): case 'contribution_campaign_id': - $qillName = $name; - $pseudoExtraParam = array(); - // @todo including names using a switch statement & then using an 'if' to filter them out is ... odd! - if ((strpos($name, '_amount') !== FALSE) || (strpos($name, '_date') !== FALSE) || in_array($name, - array( - 'contribution_id', - 'contribution_currency', - 'contribution_source', - 'contribution_trxn_id', - 'contribution_check_number', - 'contribution_payment_instrument_id', - 'contribution_contact_id', - 'contribution_campaign_id', - ) - ) + + $fieldNamesNotToStripContributionFrom = array( + 'contribution_currency_type', + 'contribution_status_id', + 'contribution_page_id', + ); + // @todo these are mostly legacy params. Find a better way to deal with them. + if (!in_array($name, $fieldNamesNotToStripContributionFrom) ) { - $name = str_replace('contribution_', '', $name); - if (!in_array($name, array('source', 'id', 'contact_id', 'campaign_id'))) { + if (!isset($fields[$name])) { $qillName = str_replace('contribution_', '', $qillName); } + $name = str_replace('contribution_', '', $name); } if (in_array($name, array('contribution_currency', 'contribution_currency_type'))) { $qillName = $name = 'currency'; @@ -859,7 +826,7 @@ class CRM_Contribute_BAO_Query extends CRM_Core_BAO_Query { // kittens 'payment_instrument_id' => 1, // argh - 'check_number' => 1, + 'contribution_check_number' => 1, // no 'non_deductible_amount' => 1, // not diff --git a/civicrm/CRM/Contribute/DAO/Contribution.php b/civicrm/CRM/Contribute/DAO/Contribution.php index f35c3c7707..0a1a2f3eb3 100644 --- a/civicrm/CRM/Contribute/DAO/Contribution.php +++ b/civicrm/CRM/Contribute/DAO/Contribution.php @@ -30,7 +30,7 @@ * * Generated from xml/schema/CRM/Contribute/Contribution.xml * DO NOT EDIT. Generated by CRM_Core_CodeGen - * (GenCodeChecksum:f066fa296dca6ef9876c7372a61c1a4a) + * (GenCodeChecksum:b25399b3b6cf17e97809102666de8ee7) */ require_once 'CRM/Core/DAO.php'; require_once 'CRM/Utils/Type.php'; @@ -291,7 +291,7 @@ class CRM_Contribute_DAO_Contribution extends CRM_Core_DAO { 'type' => CRM_Utils_Type::T_INT, 'title' => ts('Financial Type') , 'description' => 'FK to Financial Type for (total_amount - non_deductible_amount).', - 'export' => false, + 'export' => true, 'where' => 'civicrm_contribution.financial_type_id', 'headerPattern' => '', 'dataPattern' => '', @@ -362,7 +362,7 @@ class CRM_Contribute_DAO_Contribution extends CRM_Core_DAO { 'bao' => 'CRM_Contribute_BAO_Contribution', 'html' => array( 'type' => 'Select Date', - 'format' => 'activityDateTime', + 'formatType' => 'activityDateTime', ) , ) , 'non_deductible_amount' => array( @@ -529,7 +529,7 @@ class CRM_Contribute_DAO_Contribution extends CRM_Core_DAO { 'bao' => 'CRM_Contribute_BAO_Contribution', 'html' => array( 'type' => 'Select Date', - 'format' => 'activityDateTime', + 'formatType' => 'activityDateTime', ) , ) , 'cancel_reason' => array( @@ -563,7 +563,7 @@ class CRM_Contribute_DAO_Contribution extends CRM_Core_DAO { 'bao' => 'CRM_Contribute_BAO_Contribution', 'html' => array( 'type' => 'Select Date', - 'format' => 'activityDateTime', + 'formatType' => 'activityDateTime', ) , ) , 'thankyou_date' => array( @@ -581,7 +581,7 @@ class CRM_Contribute_DAO_Contribution extends CRM_Core_DAO { 'bao' => 'CRM_Contribute_BAO_Contribution', 'html' => array( 'type' => 'Select Date', - 'format' => 'activityDateTime', + 'formatType' => 'activityDateTime', ) , ) , 'contribution_source' => array( @@ -624,6 +624,10 @@ class CRM_Contribute_DAO_Contribution extends CRM_Core_DAO { 'type' => CRM_Utils_Type::T_INT, 'title' => ts('Recurring Contribution ID') , 'description' => 'Conditional foreign key to civicrm_contribution_recur id. Each contribution made in connection with a recurring contribution carries a foreign key to the recurring contribution record. This assumes we can track these processor initiated events.', + 'export' => true, + 'where' => 'civicrm_contribution.contribution_recur_id', + 'headerPattern' => '', + 'dataPattern' => '', 'table_name' => 'civicrm_contribution', 'entity' => 'Contribution', 'bao' => 'CRM_Contribute_BAO_Contribution', @@ -682,17 +686,21 @@ class CRM_Contribute_DAO_Contribution extends CRM_Core_DAO { 'optionEditPath' => 'civicrm/admin/options/contribution_status', ) ) , - 'address_id' => array( + 'contribution_address_id' => array( 'name' => 'address_id', 'type' => CRM_Utils_Type::T_INT, 'title' => ts('Contribution Address') , 'description' => 'Conditional foreign key to civicrm_address.id. We insert an address record for each contribution when we have associated billing name and address data.', + 'export' => true, + 'where' => 'civicrm_contribution.address_id', + 'headerPattern' => '', + 'dataPattern' => '', 'table_name' => 'civicrm_contribution', 'entity' => 'Contribution', 'bao' => 'CRM_Contribute_BAO_Contribution', 'FKClassName' => 'CRM_Core_DAO_Address', ) , - 'check_number' => array( + 'contribution_check_number' => array( 'name' => 'check_number', 'type' => CRM_Utils_Type::T_STRING, 'title' => ts('Check Number') , @@ -788,7 +796,7 @@ class CRM_Contribute_DAO_Contribution extends CRM_Core_DAO { 'bao' => 'CRM_Contribute_BAO_Contribution', 'html' => array( 'type' => 'Select Date', - 'format' => 'activityDateTime', + 'formatType' => 'activityDateTime', ) , ) , ); diff --git a/civicrm/CRM/Contribute/Form/AdditionalPayment.php b/civicrm/CRM/Contribute/Form/AdditionalPayment.php index 993af0b77c..b6cee86c1b 100644 --- a/civicrm/CRM/Contribute/Form/AdditionalPayment.php +++ b/civicrm/CRM/Contribute/Form/AdditionalPayment.php @@ -429,15 +429,6 @@ class CRM_Contribute_Form_AdditionalPayment extends CRM_Contribute_Form_Abstract if (!empty($submittedValues['is_email_receipt']) && $sendReceipt) { $statusMsg .= ' ' . ts('A receipt has been emailed to the contributor.'); } - // email sending - if (!empty($result) && !empty($submittedValues['is_email_receipt'])) { - $submittedValues['contact_id'] = $this->_contactId; - $submittedValues['contribution_id'] = $this->_contributionId; - // to get 'from email id' for send receipt - $this->fromEmailId = $submittedValues['from_email_address']; - $sendReceipt = $this->emailReceipt($submittedValues); - } - CRM_Core_Session::setStatus($statusMsg, ts('Saved'), 'success'); $session = CRM_Core_Session::singleton(); diff --git a/civicrm/CRM/Contribute/Form/Contribution.php b/civicrm/CRM/Contribute/Form/Contribution.php index 450c1bac94..1f8b49c513 100644 --- a/civicrm/CRM/Contribute/Form/Contribution.php +++ b/civicrm/CRM/Contribute/Form/Contribution.php @@ -776,7 +776,7 @@ class CRM_Contribute_Form_Contribution extends CRM_Contribute_Form_AbstractEditP if ($this->_online) { $this->assign('hideCalender', TRUE); } - $checkNumber = $this->add('text', 'check_number', ts('Check Number'), $attributes['check_number']); + $checkNumber = $this->add('text', 'check_number', ts('Check Number'), $attributes['contribution_check_number']); $this->addDateTime('receipt_date', ts('Receipt Date'), FALSE, array('formatType' => 'activityDateTime')); $this->addDateTime('cancel_date', ts('Cancelled / Refunded Date'), FALSE, array('formatType' => 'activityDateTime')); diff --git a/civicrm/CRM/Contribute/Form/ContributionBase.php b/civicrm/CRM/Contribute/Form/ContributionBase.php index 8be7ccfad4..9465253007 100644 --- a/civicrm/CRM/Contribute/Form/ContributionBase.php +++ b/civicrm/CRM/Contribute/Form/ContributionBase.php @@ -609,8 +609,11 @@ class CRM_Contribute_Form_ContributionBase extends CRM_Core_Form { 'total_amount' => 1, 'amount_level' => 1, 'contribution_status_id' => 1, + // @todo replace payment_instrument with payment instrument id. + // both are available now but the id field is the most consistent. 'payment_instrument' => 1, - 'check_number' => 1, + 'payment_instrument_id' => 1, + 'contribution_check_number' => 1, 'financial_type' => 1, ); @@ -633,7 +636,7 @@ class CRM_Contribute_Form_ContributionBase extends CRM_Core_Form { //remove common fields only if profile is not configured for onbehalf/honor if (!in_array($profileContactType, array('honor', 'onbehalf'))) { - $fields = array_diff_assoc($fields, $this->_fields); + $fields = array_diff_key($fields, $this->_fields); } CRM_Core_BAO_Address::checkContactSharedAddressFields($fields, $contactID); diff --git a/civicrm/CRM/Contribute/Form/Search.php b/civicrm/CRM/Contribute/Form/Search.php index e4e2df3d84..14c3ace64a 100644 --- a/civicrm/CRM/Contribute/Form/Search.php +++ b/civicrm/CRM/Contribute/Form/Search.php @@ -297,20 +297,19 @@ class CRM_Contribute_Form_Search extends CRM_Core_Form_Search { } } - if (!defined('CIVICRM_GROUPTREE')) { - $group = CRM_Utils_Array::value('group', $this->_formValues); - if ($group && !is_array($group)) { - unset($this->_formValues['group']); - $this->_formValues['group'][$group] = 1; - } + $group = CRM_Utils_Array::value('group', $this->_formValues); + if ($group && !is_array($group)) { + unset($this->_formValues['group']); + $this->_formValues['group'][$group] = 1; + } - if ($group && is_array($group)) { - unset($this->_formValues['group']); - foreach ($group as $notImportant => $groupID) { - $this->_formValues['group'][$groupID] = 1; - } + if ($group && is_array($group)) { + unset($this->_formValues['group']); + foreach ($group as $groupID) { + $this->_formValues['group'][$groupID] = 1; } } + } CRM_Core_BAO_CustomValue::fixCustomFieldValue($this->_formValues); diff --git a/civicrm/CRM/Contribute/Form/Task/Batch.php b/civicrm/CRM/Contribute/Form/Task/Batch.php index ca6c15eeb9..f1b47a4375 100644 --- a/civicrm/CRM/Contribute/Form/Task/Batch.php +++ b/civicrm/CRM/Contribute/Form/Task/Batch.php @@ -187,7 +187,6 @@ class CRM_Contribute_Form_Task_Batch extends CRM_Contribute_Form_Task { $defaults = array(); foreach ($this->_contributionIds as $contributionId) { - $details[$contributionId] = array(); CRM_Core_BAO_UFGroup::setProfileDefaults(NULL, $this->_fields, $defaults, FALSE, $contributionId, 'Contribute'); } diff --git a/civicrm/CRM/Core/BAO/CustomField.php b/civicrm/CRM/Core/BAO/CustomField.php index 1aff500d45..82bfee3e06 100644 --- a/civicrm/CRM/Core/BAO/CustomField.php +++ b/civicrm/CRM/Core/BAO/CustomField.php @@ -1443,7 +1443,7 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField { $entityId = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_EntityFile', $fileID, 'entity_id', - 'id' + 'file_id' ); list($path) = CRM_Core_BAO_File::path($fileID, $entityId, NULL, NULL); $url = CRM_Utils_System::url('civicrm/file', diff --git a/civicrm/CRM/Core/BAO/CustomGroup.php b/civicrm/CRM/Core/BAO/CustomGroup.php index 703572d298..924fb74a2b 100644 --- a/civicrm/CRM/Core/BAO/CustomGroup.php +++ b/civicrm/CRM/Core/BAO/CustomGroup.php @@ -1884,12 +1884,6 @@ SELECT IF( EXISTS(SELECT name FROM civicrm_contact_type WHERE name like %1), 1, // add field information foreach ($value['fields'] as $k => $properties) { $properties['element_name'] = "custom_{$k}_-{$groupCount}"; - if ($value = CRM_Utils_Request::retrieve($properties['element_name'], 'String', $form, FALSE, NULL, 'POST')) { - $formValues[$properties['element_name']] = $value; - } - elseif (isset($submittedValues[$properties['element_name']])) { - $properties['element_value'] = $submittedValues[$properties['element_name']]; - } if (isset($properties['customValue']) && !CRM_Utils_System::isNull($properties['customValue']) && !isset($properties['element_value']) @@ -1906,6 +1900,12 @@ SELECT IF( EXISTS(SELECT name FROM civicrm_contact_type WHERE name like %1), 1, } } } + if ($value = CRM_Utils_Request::retrieve($properties['element_name'], 'String', $form, FALSE, NULL, 'POST')) { + $formValues[$properties['element_name']] = $value; + } + elseif (isset($submittedValues[$properties['element_name']])) { + $properties['element_value'] = $submittedValues[$properties['element_name']]; + } unset($properties['customValue']); $formattedGroupTree[$key]['fields'][$k] = $properties; } diff --git a/civicrm/CRM/Core/BAO/EntityTag.php b/civicrm/CRM/Core/BAO/EntityTag.php index 6b4a74e913..accc5d6d08 100644 --- a/civicrm/CRM/Core/BAO/EntityTag.php +++ b/civicrm/CRM/Core/BAO/EntityTag.php @@ -81,6 +81,9 @@ class CRM_Core_BAO_EntityTag extends CRM_Core_DAO_EntityTag { // dont save the object if it already exists, CRM-1276 if (!$entityTag->find(TRUE)) { + //invoke pre hook + CRM_Utils_Hook::pre('create', 'EntityTag', $params['tag_id'], $params); + $entityTag->save(); //invoke post hook on entityTag @@ -111,6 +114,11 @@ class CRM_Core_BAO_EntityTag extends CRM_Core_DAO_EntityTag { * (reference ) an assoc array of name/value pairs. */ public static function del(&$params) { + //invoke pre hook + if (!empty($params['tag_id'])) { + CRM_Utils_Hook::pre('delete', 'EntityTag', $params['tag_id'], $params); + } + $entityTag = new CRM_Core_BAO_EntityTag(); $entityTag->copyValues($params); $entityTag->delete(); @@ -142,6 +150,10 @@ class CRM_Core_BAO_EntityTag extends CRM_Core_DAO_EntityTag { $numEntitiesNotAdded = 0; $entityIdsAdded = array(); + //invoke pre hook for entityTag + $preObject = array($entityIds, $entityTable); + CRM_Utils_Hook::pre('create', 'EntityTag', $tagId, $preObject); + foreach ($entityIds as $entityId) { // CRM-17350 - check if we have permission to edit the contact // that this tag belongs to. @@ -216,6 +228,10 @@ class CRM_Core_BAO_EntityTag extends CRM_Core_DAO_EntityTag { $numEntitiesNotRemoved = 0; $entityIdsRemoved = array(); + //invoke pre hook for entityTag + $preObject = array($entityIds, $entityTable); + CRM_Utils_Hook::pre('delete', 'EntityTag', $tagId, $preObject); + foreach ($entityIds as $entityId) { // CRM-17350 - check if we have permission to edit the contact // that this tag belongs to. @@ -376,7 +392,10 @@ class CRM_Core_BAO_EntityTag extends CRM_Core_DAO_EntityTag { } /** - * Merge two tags: tag B into tag A. + * Merge two tags + * + * Tag A will inherit all of tag B's properties. + * Tag B will be deleted. * * @param int $tagAId * @param int $tagBId @@ -385,8 +404,8 @@ class CRM_Core_BAO_EntityTag extends CRM_Core_DAO_EntityTag { */ public function mergeTags($tagAId, $tagBId) { $queryParams = array( - 1 => array($tagBId, 'Integer'), - 2 => array($tagAId, 'Integer'), + 1 => array($tagAId, 'Integer'), + 2 => array($tagBId, 'Integer'), ); // re-compute used_for field @@ -400,19 +419,21 @@ class CRM_Core_BAO_EntityTag extends CRM_Core_DAO_EntityTag { } $usedFor = array_merge($tags["tagA_used_for"], $tags["tagB_used_for"]); $usedFor = implode(',', array_unique($usedFor)); - $tags["tagB_used_for"] = explode(",", $usedFor); + $tags["used_for"] = explode(",", $usedFor); // get all merge queries together $sqls = array( // 1. update entity tag entries "UPDATE IGNORE civicrm_entity_tag SET tag_id = %1 WHERE tag_id = %2", - // 2. update used_for info for tag B - "UPDATE civicrm_tag SET used_for = '{$usedFor}' WHERE id = %1", - // 3. remove tag A, if tag A is getting merged into B + // 2. move children + "UPDATE civicrm_tag SET parent_id = %1 WHERE parent_id = %2", + // 3. update used_for info for tag A & children + "UPDATE civicrm_tag SET used_for = '{$usedFor}' WHERE id = %1 OR parent_id = %1", + // 4. delete tag B "DELETE FROM civicrm_tag WHERE id = %2", - // 4. remove duplicate entity tag records + // 5. remove duplicate entity tag records "DELETE et2.* from civicrm_entity_tag et1 INNER JOIN civicrm_entity_tag et2 ON et1.entity_table = et2.entity_table AND et1.entity_id = et2.entity_id AND et1.tag_id = et2.tag_id WHERE et1.id < et2.id", - // 5. remove orphaned entity_tags + // 6. remove orphaned entity_tags "DELETE FROM civicrm_entity_tag WHERE tag_id = %2", ); $tables = array('civicrm_entity_tag', 'civicrm_tag'); diff --git a/civicrm/CRM/Core/BAO/Tag.php b/civicrm/CRM/Core/BAO/Tag.php index c1b4ae44f4..936998aa99 100644 --- a/civicrm/CRM/Core/BAO/Tag.php +++ b/civicrm/CRM/Core/BAO/Tag.php @@ -395,8 +395,8 @@ class CRM_Core_BAO_Tag extends CRM_Core_DAO_Tag { * (optional) the array that holds all the db ids - we are moving away from this in bao. * signatures * - * @return object - * CRM_Core_DAO_Tag object on success, otherwise null + * @return CRM_Core_DAO_Tag|null + * object on success, otherwise null */ public static function add(&$params, $ids = array()) { $id = CRM_Utils_Array::value('id', $params, CRM_Utils_Array::value('tag', $ids)); @@ -411,6 +411,13 @@ class CRM_Core_BAO_Tag extends CRM_Core_DAO_Tag { // get parent details $params['used_for'] = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_Tag', $params['parent_id'], 'used_for'); } + elseif (isset($params['used_for']) && is_array($params['used_for'])) { + $params['used_for'] = implode(',', $params['used_for']); + } + + if (isset($params['color']) && strtolower($params['color']) === '#ffffff') { + $params['color'] = ''; + } $tag->copyValues($params); $tag->id = $id; @@ -428,10 +435,11 @@ class CRM_Core_BAO_Tag extends CRM_Core_DAO_Tag { CRM_Utils_Hook::post($hook, 'Tag', $tag->id, $tag); // if we modify parent tag, then we need to update all children - if ($tag->parent_id === 'null') { + $tag->find(TRUE); + if (!$tag->parent_id && $tag->used_for) { CRM_Core_DAO::executeQuery("UPDATE civicrm_tag SET used_for=%1 WHERE parent_id = %2", array( - 1 => array($params['used_for'], 'String'), + 1 => array($tag->used_for, 'String'), 2 => array($tag->id, 'Integer'), ) ); diff --git a/civicrm/CRM/Core/BAO/UFGroup.php b/civicrm/CRM/Core/BAO/UFGroup.php index de3cb70ce0..272cf8be89 100644 --- a/civicrm/CRM/Core/BAO/UFGroup.php +++ b/civicrm/CRM/Core/BAO/UFGroup.php @@ -348,9 +348,7 @@ class CRM_Core_BAO_UFGroup extends CRM_Core_DAO_UFGroup { $query = self::createUFFieldQuery($group->id, $searchable, $showAll, $visibility, $orderBy); $field = CRM_Core_DAO::executeQuery($query); - $profileType = CRM_Core_BAO_UFField::getProfileType($group->id); - $contactActivityProfile = CRM_Core_BAO_UFField::checkContactActivityProfileType($group->id); - $importableFields = self::getImportableFields($showAll, $profileType, $contactActivityProfile); + $importableFields = self::getProfileFieldMetadata($showAll); list($customFields, $addressCustomFields) = self::getCustomFields($ctype); while ($field->fetch()) { @@ -478,6 +476,7 @@ class CRM_Core_BAO_UFGroup extends CRM_Core_DAO_UFGroup { if (isset($field->phone_type_id)) { $name .= "-{$field->phone_type_id}"; } + $fieldMetaData = CRM_Utils_Array::value($name, $importableFields, (isset($importableFields[$field->field_name]) ? $importableFields[$field->field_name] : array())); // No lie: this is bizarre; why do we need to mix so many UFGroup properties into UFFields? // I guess to make field self sufficient with all the required data and avoid additional calls @@ -515,8 +514,15 @@ class CRM_Core_BAO_UFGroup extends CRM_Core_DAO_UFGroup { CRM_Utils_Array::value($field->field_name, $importableFields) ), 'skipDisplay' => 0, + 'data_type' => CRM_Utils_Type::getDataTypeFromFieldMetadata($fieldMetaData), + 'bao' => CRM_Utils_Array::value('bao', $fieldMetaData), ); + $formattedField = CRM_Utils_Date::addDateMetadataToField($fieldMetaData, $formattedField); + if (in_array($name, array_keys(self::getNonUpgradedDateFields()))) { + $formattedField['is_legacy_date'] = 1; + } + //adding custom field property if (substr($field->field_name, 0, 6) == 'custom' || substr($field->field_name, 0, 14) === 'address_custom' @@ -527,12 +533,16 @@ class CRM_Core_BAO_UFGroup extends CRM_Core_DAO_UFGroup { $formattedField['is_search_range'] = $customFields[$field->field_name]['is_search_range']; // fix for CRM-1994 $formattedField['options_per_line'] = $customFields[$field->field_name]['options_per_line']; - $formattedField['data_type'] = $customFields[$field->field_name]['data_type']; $formattedField['html_type'] = $customFields[$field->field_name]['html_type']; if (CRM_Utils_Array::value('html_type', $formattedField) == 'Select Date') { $formattedField['date_format'] = $customFields[$field->field_name]['date_format']; $formattedField['time_format'] = $customFields[$field->field_name]['time_format']; + $formattedField['php_datetime_format'] = CRM_Utils_Date::getPhpDateFormatFromInputStyleDateFormat($customFields[$field->field_name]['date_format']); + if ($formattedField['time_format']) { + $formattedField['php_datetime_format'] .= ' H-i-s'; + } + $formattedField['is_datetime_field'] = TRUE; } $formattedField['is_multi_summary'] = $field->is_multi_summary; @@ -636,13 +646,24 @@ class CRM_Core_BAO_UFGroup extends CRM_Core_DAO_UFGroup { } /** + * Get a list of filtered field metadata. + * + * @deprecated use getProfileFieldMetadata + * * @param $showAll * @param $profileType * @param $contactActivityProfile + * @param bool $filterMode + * Filter mode means you are using importable fields for filtering rather than just getting metadata. + * With filter mode = FALSE BOTH activity fields and component fields are returned. + * I can't see why you would ever want to use this function in filter mode as the component fields are + * still unfiltered. However, I feel scared enough to leave it as it is. I have marked this function as + * deprecated and am recommending the wrapper 'getProfileFieldMetadata' in order to try to + * send this confusion to history. * * @return array */ - protected static function getImportableFields($showAll, $profileType, $contactActivityProfile) { + protected static function getImportableFields($showAll, $profileType, $contactActivityProfile, $filterMode = TRUE) { if (!$showAll) { $importableFields = CRM_Contact_BAO_Contact::importableFields('All', FALSE, FALSE, FALSE, TRUE, TRUE); } @@ -650,15 +671,20 @@ class CRM_Core_BAO_UFGroup extends CRM_Core_DAO_UFGroup { $importableFields = CRM_Contact_BAO_Contact::importableFields('All', FALSE, TRUE, FALSE, TRUE, TRUE); } - if ($profileType == 'Activity' || $contactActivityProfile) { - $componentFields = CRM_Activity_BAO_Activity::getProfileFields(); + $activityFields = CRM_Activity_BAO_Activity::getProfileFields(); + $componentFields = CRM_Core_Component::getQueryFields(); + if ($filterMode == TRUE) { + if ($profileType == 'Activity' || $contactActivityProfile) { + $importableFields = array_merge($importableFields, $activityFields); + } + else { + $importableFields = array_merge($importableFields, $componentFields); + } } else { - $componentFields = CRM_Core_Component::getQueryFields(); + $importableFields = array_merge($importableFields, $activityFields, $componentFields); } - $importableFields = array_merge($importableFields, $componentFields); - $importableFields['group']['title'] = ts('Group(s)'); $importableFields['group']['where'] = NULL; $importableFields['tag']['title'] = ts('Tag(s)'); @@ -666,6 +692,19 @@ class CRM_Core_BAO_UFGroup extends CRM_Core_DAO_UFGroup { return $importableFields; } + /** + * Get the metadata for all potential profile fields. + * + * @param bool $isIncludeInactive + * Should disabled fields be included. + * + * @return array + * Field metadata for all fields that might potentially be in a profile. + */ + protected static function getProfileFieldMetadata($isIncludeInactive) { + return self::getImportableFields($isIncludeInactive, NULL, NULL, NULL, TRUE); + } + /** * Get the fields relating to locations. * @@ -1039,19 +1078,6 @@ class CRM_Core_BAO_UFGroup extends CRM_Core_DAO_UFGroup { $idx = $name . '_id'; $params[$index] = $details->$idx; } - elseif ($name === 'preferred_communication_method') { - $communicationFields = CRM_Core_PseudoConstant::get('CRM_Contact_DAO_Contact', 'preferred_communication_method'); - $compref = array(); - $pref = explode(CRM_Core_DAO::VALUE_SEPARATOR, $details->$name); - - foreach ($pref as $k) { - if ($k) { - $compref[] = $communicationFields[$k]; - } - } - $params[$index] = $details->$name; - $values[$index] = implode(',', $compref); - } elseif ($name === 'preferred_language') { $params[$index] = $details->$name; $values[$index] = CRM_Core_PseudoConstant::getLabel('CRM_Contact_DAO_Contact', 'preferred_language', $details->$name); @@ -1063,7 +1089,7 @@ class CRM_Core_BAO_UFGroup extends CRM_Core_DAO_UFGroup { foreach ($groups as $g) { // CRM-8362: User and User Admin visibility groups should be included in display if user has // VIEW permission on that group - $groupPerm = CRM_Contact_BAO_Group::checkPermission($g['group_id'], $g['title']); + $groupPerm = CRM_Contact_BAO_Group::checkPermission($g['group_id'], TRUE); if ($g['visibility'] != 'User and User Admin Only' || CRM_Utils_Array::key(CRM_Core_Permission::VIEW, $groupPerm) @@ -1197,6 +1223,7 @@ class CRM_Core_BAO_UFGroup extends CRM_Core_DAO_UFGroup { 'membership_end_date', 'join_date', ))) { + // @todo this set should be determined from metadata, not hard-coded. $values[$index] = CRM_Utils_Date::customFormat($details->$name); $params[$index] = CRM_Utils_Date::isoToMysql($details->$name); } @@ -1869,6 +1896,7 @@ AND ( entity_id IS NULL OR entity_id <= 0 ) $addressOptions = CRM_Core_BAO_Setting::valueOptions(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, 'address_options', TRUE, NULL, TRUE ); + $legacyHandledDateFields = self::getNonUpgradedDateFields(); if (substr($fieldName, 0, 14) === 'state_province') { $form->addChainSelect($name, array('label' => $title, 'required' => $required)); @@ -1931,15 +1959,8 @@ AND ( entity_id IS NULL OR entity_id <= 0 ) } } } - elseif (($fieldName === 'birth_date') || ($fieldName === 'deceased_date')) { - $form->addDate($name, $title, $required, array('formatType' => 'birth')); - } - elseif (in_array($fieldName, array( - 'membership_start_date', - 'membership_end_date', - 'join_date', - ))) { - $form->addDate($name, $title, $required, array('formatType' => 'activityDate')); + elseif (isset($legacyHandledDateFields[$fieldName])) { + $form->addDate($name, $title, $required, array('formatType' => $legacyHandledDateFields[$fieldName])); } elseif (CRM_Utils_Array::value('name', $field) == 'membership_type') { list($orgInfo, $types) = CRM_Member_BAO_MembershipType::getMembershipTypeInfo(); @@ -2115,14 +2136,6 @@ AND ( entity_id IS NULL OR entity_id <= 0 ) CRM_Core_BAO_CustomField::addQuickFormElement($form, $name, $customFieldID, $required, $search, $title); } } - elseif (in_array($fieldName, array( - 'receive_date', - 'receipt_date', - 'thankyou_date', - 'cancel_date', - ))) { - $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime')); - } elseif ($fieldName == 'send_receipt') { $form->addElement('checkbox', $name, $title); } @@ -2194,9 +2207,6 @@ AND ( entity_id IS NULL OR entity_id <= 0 ) ) + CRM_Contribute_PseudoConstant::contributionPage(), $required, 'class="big"' ); } - elseif ($fieldName == 'participant_register_date') { - $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime')); - } elseif ($fieldName == 'activity_status_id') { $form->add('select', $name, $title, array( @@ -2211,9 +2221,6 @@ AND ( entity_id IS NULL OR entity_id <= 0 ) ) + CRM_Campaign_PseudoConstant::engagementLevel(), $required ); } - elseif ($fieldName == 'activity_date_time') { - $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime')); - } elseif ($fieldName == 'participant_status') { $cond = NULL; if ($online == TRUE) { @@ -2311,6 +2318,30 @@ AND ( entity_id IS NULL OR entity_id <= 0 ) } } + /** + * Get fields that have not been upgraded to use datepicker. + * + * Fields that use the old code have jcalendar in the tpl and + * the form uses a customised format. We are moving towards datepicker + * which among other things passes dates back and forth using a standardised + * format. Remove fields from here as they are tested and converted. + */ + static public function getNonUpgradedDateFields() { + return array( + 'birth_date' => 'birth', + 'deceased_date' => 'birth', + 'membership_start_date' => 'activityDate', + 'membership_end_date' => 'activityDate', + 'join_date' => 'activityDate', + 'receive_date' => 'activityDateTime', + 'receipt_date' => 'activityDateTime', + 'thankyou_date' => 'activityDateTime', + 'cancel_date' => 'activityDateTime', + 'participant_register_date' => 'activityDateTime', + 'activity_date_time' => 'activityDateTime', + ); + } + /** * Set profile defaults. * @@ -2383,7 +2414,7 @@ AND ( entity_id IS NULL OR entity_id <= 0 ) $defaults[$fldName] = $details['worldregion_id']; } elseif ($customFieldId = CRM_Core_BAO_CustomField::getKeyID($name)) { - //fix for custom fields + // @todo retrieving the custom fields here seems obsolete - $field holds more data for the fields. $customFields = CRM_Core_BAO_CustomField::getFields(CRM_Utils_Array::value('contact_type', $details)); // hack to add custom data for components @@ -3254,6 +3285,7 @@ AND ( entity_id IS NULL OR entity_id <= 0 ) } $formattedGroupTree = array(); + // @todo - as we put these on datepicker they need to be removed from here. $dateTimeFields = array( 'participant_register_date', 'activity_date_time', diff --git a/civicrm/CRM/Core/BAO/UFMatch.php b/civicrm/CRM/Core/BAO/UFMatch.php index bfd6a9b5cd..f20be6680d 100644 --- a/civicrm/CRM/Core/BAO/UFMatch.php +++ b/civicrm/CRM/Core/BAO/UFMatch.php @@ -356,9 +356,10 @@ AND domain_id = %4 * Id of the contact to update. */ public static function updateUFName($contactId) { - if (!$contactId) { + if (!Civi::settings()->get('syncCMSEmail') || !$contactId) { return; } + $config = CRM_Core_Config::singleton(); $ufName = CRM_Contact_BAO_Contact::getPrimaryEmail($contactId); @@ -420,6 +421,11 @@ AND domain_id = %4 $ufmatch->uf_name = $emailAddress; CRM_Core_BAO_UFMatch::create((array) $ufmatch); + // If CMS integration is disabled skip Civi email update if CMS user email is changed + if (Civi::settings()->get('syncCMSEmail') == FALSE) { + return; + } + //check if the primary email for the contact exists //$contactDetails[1] - email //$contactDetails[3] - email id diff --git a/civicrm/CRM/Core/CodeGen/Specification.php b/civicrm/CRM/Core/CodeGen/Specification.php index dbebd3291f..2a94606859 100644 --- a/civicrm/CRM/Core/CodeGen/Specification.php +++ b/civicrm/CRM/Core/CodeGen/Specification.php @@ -365,7 +365,7 @@ class CRM_Core_CodeGen_Specification { if (!empty($field['html'])) { $validOptions = array( 'type', - 'format', + 'formatType', /* Fixme: prior to CRM-13497 these were in a flat structure // CRM-13497 moved them to be nested within 'html' but there's no point // making that change in the DAOs right now since we are in the process of diff --git a/civicrm/CRM/Core/DAO/AllCoreTables.data.php b/civicrm/CRM/Core/DAO/AllCoreTables.data.php index d64334f521..7ca1c70776 100644 --- a/civicrm/CRM/Core/DAO/AllCoreTables.data.php +++ b/civicrm/CRM/Core/DAO/AllCoreTables.data.php @@ -24,7 +24,7 @@ | see the CiviCRM license FAQ at http://civicrm.org/licensing | +--------------------------------------------------------------------+ */ -// (GenCodeChecksum:616d65664572d5eaffb63dd660d6ff36) +// (GenCodeChecksum:9f38a12c446ece781c1ef9c46dd95a5d) return array( 'CRM_Core_DAO_AddressFormat' => array( 'name' => 'AddressFormat', diff --git a/civicrm/CRM/Core/Error.php b/civicrm/CRM/Core/Error.php index 07dfc50b87..81b470bbc0 100644 --- a/civicrm/CRM/Core/Error.php +++ b/civicrm/CRM/Core/Error.php @@ -310,6 +310,11 @@ class CRM_Core_Error extends PEAR_ErrorStack { /** * Display an error page with an error message describing what happened. * + * @deprecated + * This is a really annoying function. We ⤠exceptions. Be exceptional! + * + * @see CRM-20181 + * * @param string $message * The error message. * @param string $code diff --git a/civicrm/CRM/Core/Form.php b/civicrm/CRM/Core/Form.php index fadce93d65..68d4ceabea 100644 --- a/civicrm/CRM/Core/Form.php +++ b/civicrm/CRM/Core/Form.php @@ -337,6 +337,8 @@ class CRM_Core_Form extends HTML_QuickForm_Page { * @param bool $required * @param array $extra * (attributes for select elements). + * For datepicker elements this is consistent with the data + * from CRM_Utils_Date::getDatePickerExtra * * @return HTML_QuickForm_Element * Could be an error object diff --git a/civicrm/CRM/Core/OptionGroup.php b/civicrm/CRM/Core/OptionGroup.php index 8fdecdfdb5..1227803a5f 100644 --- a/civicrm/CRM/Core/OptionGroup.php +++ b/civicrm/CRM/Core/OptionGroup.php @@ -109,6 +109,7 @@ class CRM_Core_OptionGroup { * @param string $keyColumnName * the column to use for 'key'. * @param string $orderBy + * the column to use for ordering. * * @return array * The values as specified by the params @@ -120,7 +121,7 @@ class CRM_Core_OptionGroup { $orderBy = 'weight' ) { $cache = CRM_Utils_Cache::singleton(); - $cacheKey = self::createCacheKey($name, $flip, $grouping, $localize, $condition, $labelColumnName, $onlyActive, $keyColumnName); + $cacheKey = self::createCacheKey($name, $flip, $grouping, $localize, $condition, $labelColumnName, $onlyActive, $keyColumnName, $orderBy); if (!$fresh) { // Fetch from static var @@ -144,6 +145,14 @@ WHERE v.option_group_id = g.id if ($onlyActive) { $query .= " AND v.is_active = 1 "; + // Only show options for enabled components + $componentClause = ' v.component_id IS NULL '; + $enabledComponents = CRM_Core_Config::singleton()->enableComponents; + if ($enabledComponents) { + $enabledComponents = '"' . implode('","', $enabledComponents) . '"'; + $componentClause .= " OR v.component_id IN (SELECT id FROM civicrm_component WHERE name IN ($enabledComponents)) "; + } + $query .= " AND ($componentClause) "; } if (in_array($name, self::$_domainIDGroups)) { $query .= " AND v.domain_id = " . CRM_Core_Config::domainID(); @@ -253,9 +262,9 @@ WHERE v.option_group_id = g.id } /** - * Lookup titles OR ids for a set of option_value populated fields. The retrieved value - * is assigned a new fieldname by id or id's by title - * (each within a specificied option_group) + * Lookup titles OR ids for a set of option_value populated fields. The + * retrieved value is assigned a new field name by id or id's by title + * (each within a specified option_group). * * @param array $params * Reference array of values submitted by the form. Based on. @@ -265,14 +274,13 @@ WHERE v.option_group_id = g.id * If $flip = true, adds actual field name => id * * @param array $names - * Reference array of fieldnames we want transformed. + * Array of field names we want transformed. * Array key = 'postName' (field name submitted by form in $params). * Array value = array('newName' => $newName, 'groupName' => $groupName). * - * * @param bool $flip */ - public static function lookupValues(&$params, &$names, $flip = FALSE) { + public static function lookupValues(&$params, $names, $flip = FALSE) { foreach ($names as $postName => $value) { // See if $params field is in $names array (i.e. is a value that we need to lookup) if ($postalName = CRM_Utils_Array::value($postName, $params)) { diff --git a/civicrm/CRM/Core/Payment/PayPalIPN.php b/civicrm/CRM/Core/Payment/PayPalIPN.php index f4d116ae39..9aa5874869 100644 --- a/civicrm/CRM/Core/Payment/PayPalIPN.php +++ b/civicrm/CRM/Core/Payment/PayPalIPN.php @@ -340,7 +340,7 @@ class CRM_Core_Payment_PayPalIPN extends CRM_Core_Payment_BaseIPN { $paymentProcessorID = $this->retrieve('processor_id', 'Integer', FALSE); if (empty($paymentProcessorID)) { $processorParams = array( - 'user_name' => $this->retrieve('receiver_email', 'String', FALSE), + 'user_name' => $this->retrieve('business', 'String', FALSE), 'payment_processor_type_id' => CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_PaymentProcessorType', 'PayPal_Standard', 'id', 'name'), 'is_test' => empty($input['is_test']) ? 0 : 1, ); diff --git a/civicrm/CRM/Core/SelectValues.php b/civicrm/CRM/Core/SelectValues.php index ba24f9d6a8..344219ef5a 100644 --- a/civicrm/CRM/Core/SelectValues.php +++ b/civicrm/CRM/Core/SelectValues.php @@ -311,7 +311,8 @@ class CRM_Core_SelectValues { * @return array * the date array */ - public static function date($type = NULL, $format = NULL, $minOffset = NULL, $maxOffset = NULL) { + public static function date($type = NULL, $format = NULL, $minOffset = NULL, $maxOffset = NULL, $context = 'display') { + // These options are deprecated. Definitely not used in datepicker. Possibly not even in jcalendar+addDateTime. $date = array( 'addEmptyOption' => TRUE, 'emptyOptionText' => ts('- select -'), @@ -328,25 +329,34 @@ class CRM_Core_SelectValues { if (!$dao->find(TRUE)) { CRM_Core_Error::fatal(); } - } + if (!$maxOffset) { + $maxOffset = $dao->end; + } + if (!$minOffset) { + $minOffset = $dao->start; + } - if ($type == 'creditCard') { - $minOffset = $dao->start; - $maxOffset = $dao->end; $date['format'] = $dao->date_format; - $date['addEmptyOption'] = TRUE; - $date['emptyOptionText'] = ts('- select -'); - $date['emptyOptionValue'] = ''; + $date['time'] = (bool) $dao->time_format; } if (empty($date['format'])) { - $date['format'] = 'M d'; + if ($context == 'Input') { + $date['format'] = Civi::settings()->get('dateInputFormat'); + $date['php_datetime_format'] = self::datePluginToPHPFormats(Civi::settings()->get('dateInputFormat')); + } + else { + $date['format'] = 'M d'; + } } } + if (!isset($date['time'])) { + $date['time'] = FALSE; + } $year = date('Y'); - $date['minYear'] = $year - $minOffset; - $date['maxYear'] = $year + $maxOffset; + $date['minYear'] = $year - (int) $minOffset; + $date['maxYear'] = $year + (int) $maxOffset; return $date; } diff --git a/civicrm/CRM/Core/Smarty/plugins/modifier.crmDate.php b/civicrm/CRM/Core/Smarty/plugins/modifier.crmDate.php index 11b001abd7..8e2afb6a59 100644 --- a/civicrm/CRM/Core/Smarty/plugins/modifier.crmDate.php +++ b/civicrm/CRM/Core/Smarty/plugins/modifier.crmDate.php @@ -56,6 +56,10 @@ function smarty_modifier_crmDate($dateString, $dateFormat = NULL, $onlyTime = FA $config = CRM_Core_Config::singleton(); $dateFormat = $config->dateformatTime; } + // Handle possibility we only have a date function style date format. + if ($dateFormat && !stristr($dateFormat, '%')) { + return date($dateFormat, strtotime($dateString)); + } return CRM_Utils_Date::customFormat($dateString, $dateFormat); } diff --git a/civicrm/CRM/Core/xml/Menu/Admin.xml b/civicrm/CRM/Core/xml/Menu/Admin.xml index 718e814979..1e913a2af2 100644 --- a/civicrm/CRM/Core/xml/Menu/Admin.xml +++ b/civicrm/CRM/Core/xml/Menu/Admin.xml @@ -653,11 +653,6 @@ <page_callback>CRM_Admin_Page_AJAX::getStatusMsg</page_callback> <access_arguments>access CiviCRM</access_arguments> </item> - <item> - <path>civicrm/ajax/mergeTags</path> - <page_callback>CRM_Admin_Page_AJAX::mergeTags</page_callback> - <access_arguments>access CiviCRM</access_arguments> - </item> <item> <path>civicrm/admin/price</path> <title>Price Sets</title> @@ -687,11 +682,6 @@ <title>Price Field Options</title> <page_callback>CRM_Price_Page_Option</page_callback> </item> - <item> - <path>civicrm/ajax/mergeTagList</path> - <page_callback>CRM_Admin_Page_AJAX::mergeTagList</page_callback> - <access_arguments>access CiviCRM</access_arguments> - </item> <item> <path>civicrm/admin/tplstrings/add</path> <page_callback>CRM_Admin_Form_Persistent</page_callback> diff --git a/civicrm/CRM/Core/xml/Menu/Tag.xml b/civicrm/CRM/Core/xml/Menu/Tag.xml index 104f896806..e05e6eed8b 100644 --- a/civicrm/CRM/Core/xml/Menu/Tag.xml +++ b/civicrm/CRM/Core/xml/Menu/Tag.xml @@ -12,10 +12,21 @@ <weight>25</weight> </item> <item> - <path>civicrm/tag/add</path> + <path>civicrm/tag/edit</path> <title>New Tag</title> - <page_callback>CRM_Tag_Page_Tag</page_callback> + <page_callback>CRM_Tag_Form_Edit</page_callback> <path_arguments>action=add</path_arguments> <access_arguments>administer CiviCRM;manage tags</access_arguments> </item> + <item> + <path>civicrm/tag/merge</path> + <title>Merge Tags</title> + <page_callback>CRM_Tag_Form_Merge</page_callback> + <access_arguments>administer CiviCRM;manage tags</access_arguments> + </item> + <item> + <path>civicrm/ajax/tagTree</path> + <page_callback>CRM_Admin_Page_AJAX::getTagTree</page_callback> + <access_arguments>administer CiviCRM;manage tags</access_arguments> + </item> </menu> diff --git a/civicrm/CRM/Dashlet/Page/GettingStarted.php b/civicrm/CRM/Dashlet/Page/GettingStarted.php index 7811256a21..775726b06d 100644 --- a/civicrm/CRM/Dashlet/Page/GettingStarted.php +++ b/civicrm/CRM/Dashlet/Page/GettingStarted.php @@ -143,7 +143,7 @@ class CRM_Dashlet_Page_GettingStarted extends CRM_Core_Page { if (!empty(self::$_tokens[$categories][$token])) { $value = self::$_tokens[$categories][$token]; if ($categories == 'crmurl') { - $value = CRM_Utils_System::url($value, "reset=1", FALSE, NULL, TRUE, TRUE); + $value = CRM_Utils_System::url($value, "reset=1"); } } CRM_Utils_Token::token_replace($categories, $token, $value, $str); diff --git a/civicrm/CRM/Dedupe/Merger.php b/civicrm/CRM/Dedupe/Merger.php index 183dd63b7d..1905a85fdc 100644 --- a/civicrm/CRM/Dedupe/Merger.php +++ b/civicrm/CRM/Dedupe/Merger.php @@ -589,8 +589,6 @@ INNER JOIN civicrm_membership membership2 ON membership1.membership_type_id = m * Helps decide how to behave when there are conflicts. * A 'safe' value skips the merge if there are any un-resolved conflicts, wheras 'aggressive' * mode does a force merge. - * @param bool $autoFlip to let api decide which contact to retain and which to delete. - * Whether to let api decide which contact to retain and which to delete. * @param int $batchLimit number of merges to carry out in one batch. * @param int $isSelected if records with is_selected column needs to be processed. * @@ -602,7 +600,7 @@ INNER JOIN civicrm_membership membership2 ON membership1.membership_type_id = m * * @return array|bool */ - public static function batchMerge($rgid, $gid = NULL, $mode = 'safe', $autoFlip = TRUE, $batchLimit = 1, $isSelected = 2, $criteria = array(), $checkPermissions = TRUE) { + public static function batchMerge($rgid, $gid = NULL, $mode = 'safe', $batchLimit = 1, $isSelected = 2, $criteria = array(), $checkPermissions = TRUE) { $redirectForPerformance = ($batchLimit > 1) ? TRUE : FALSE; $reloadCacheIfEmpty = (!$redirectForPerformance && $isSelected == 2); $dupePairs = self::getDuplicatePairs($rgid, $gid, $reloadCacheIfEmpty, $batchLimit, $isSelected, '', ($mode == 'aggressive'), $criteria, $checkPermissions); @@ -614,7 +612,7 @@ INNER JOIN civicrm_membership membership2 ON membership1.membership_type_id = m 'join' => self::getJoinOnDedupeTable(), 'where' => self::getWhereString($batchLimit, $isSelected), ); - return CRM_Dedupe_Merger::merge($dupePairs, $cacheParams, $mode, $autoFlip, $redirectForPerformance, $checkPermissions); + return CRM_Dedupe_Merger::merge($dupePairs, $cacheParams, $mode, $redirectForPerformance, $checkPermissions); } /** @@ -748,8 +746,6 @@ INNER JOIN civicrm_membership membership2 ON membership1.membership_type_id = m * Helps decide how to behave when there are conflicts. * A 'safe' value skips the merge if there are any un-resolved conflicts. * Does a force merge otherwise (aggressive mode). - * @param bool $autoFlip to let api decide which contact to retain and which to delete. - * Whether to let api decide which contact to retain and which to delete. * * @param bool $redirectForPerformance * Redirect to a url for batch processing. @@ -760,7 +756,7 @@ INNER JOIN civicrm_membership membership2 ON membership1.membership_type_id = m * @return array|bool */ public static function merge($dupePairs = array(), $cacheParams = array(), $mode = 'safe', - $autoFlip = TRUE, $redirectForPerformance = FALSE, $checkPermissions = TRUE + $redirectForPerformance = FALSE, $checkPermissions = TRUE ) { $cacheKeyString = CRM_Utils_Array::value('cache_key_string', $cacheParams); $resultStats = array('merged' => array(), 'skipped' => array()); diff --git a/civicrm/CRM/Event/BAO/Participant.php b/civicrm/CRM/Event/BAO/Participant.php index 25347945cd..2b4dbc402a 100644 --- a/civicrm/CRM/Event/BAO/Participant.php +++ b/civicrm/CRM/Event/BAO/Participant.php @@ -648,6 +648,7 @@ GROUP BY participant.event_id 'title' => ts('Participant Note'), 'name' => 'participant_note', 'headerPattern' => '/(participant.)?note$/i', + 'type' => 'text', ), ); diff --git a/civicrm/CRM/Event/DAO/Participant.php b/civicrm/CRM/Event/DAO/Participant.php index b497955e61..8da34792f3 100644 --- a/civicrm/CRM/Event/DAO/Participant.php +++ b/civicrm/CRM/Event/DAO/Participant.php @@ -30,7 +30,7 @@ * * Generated from xml/schema/CRM/Event/Participant.xml * DO NOT EDIT. Generated by CRM_Core_CodeGen - * (GenCodeChecksum:3c53d2d7a62cf0428fef11b9df02fcd2) + * (GenCodeChecksum:87c3d1afa18e39e10ba019d773eb6ce8) */ require_once 'CRM/Core/DAO.php'; require_once 'CRM/Utils/Type.php'; @@ -310,7 +310,7 @@ class CRM_Event_DAO_Participant extends CRM_Core_DAO { 'bao' => 'CRM_Event_BAO_Participant', 'html' => array( 'type' => 'Select Date', - 'format' => 'activityDateTime', + 'formatType' => 'activityDateTime', ) , ) , 'participant_source' => array( diff --git a/civicrm/CRM/Event/Form/EventFees.php b/civicrm/CRM/Event/Form/EventFees.php index 0a01313035..036165c28a 100644 --- a/civicrm/CRM/Event/Form/EventFees.php +++ b/civicrm/CRM/Event/Form/EventFees.php @@ -407,7 +407,7 @@ SELECT id, html_type && !CRM_Utils_Array::value('fee', $form->_values) && CRM_Utils_Array::value('snippet', $_REQUEST) == CRM_Core_Smarty::PRINT_NOFORM ) { - $form->assign('isFTPermissionDenied', TRUE); + CRM_Core_Session::setStatus(ts('You do not have all the permissions needed for this page.'), 'Permission Denied', 'error'); return FALSE; } if ($form->_mode) { diff --git a/civicrm/CRM/Event/Form/Participant.php b/civicrm/CRM/Event/Form/Participant.php index 876e008096..06216727c8 100644 --- a/civicrm/CRM/Event/Form/Participant.php +++ b/civicrm/CRM/Event/Form/Participant.php @@ -820,6 +820,7 @@ class CRM_Event_Form_Participant extends CRM_Contribute_Form_AbstractEditPayment if (empty($values['payment_instrument_id'])) { $errorMsg['payment_instrument_id'] = ts('Payment Method is a required field.'); } + CRM_Price_BAO_PriceField::priceSetValidation($values['priceSetId'], $values, $errorMsg); } // validate contribution status for 'Failed'. diff --git a/civicrm/CRM/Event/Form/Registration.php b/civicrm/CRM/Event/Form/Registration.php index 5143206ee7..cf567cc3da 100644 --- a/civicrm/CRM/Event/Form/Registration.php +++ b/civicrm/CRM/Event/Form/Registration.php @@ -1467,7 +1467,7 @@ WHERE v.option_group_id = g.id $startDate && $startDate >= $now ) { - CRM_Core_Error::statusBounce(ts('Registration for this event begins on %1', array(1 => CRM_Utils_Date::customFormat(CRM_Utils_Array::value('registration_start_date', $this->_values['event'])))), $redirect); + CRM_Core_Error::statusBounce(ts('Registration for this event begins on %1', array(1 => CRM_Utils_Date::customFormat(CRM_Utils_Array::value('registration_start_date', $this->_values['event'])))), $redirect, ts('Sorry')); } $regEndDate = CRM_Utils_Date::processDate(CRM_Utils_Array::value('registration_end_date', @@ -1479,7 +1479,7 @@ WHERE v.option_group_id = g.id if (empty($regEndDate)) { $endDate = CRM_Utils_Date::customFormat(CRM_Utils_Array::value('event_end_date', $this->_values['event'])); } - CRM_Core_Error::statusBounce(ts('Registration for this event ended on %1', array(1 => $endDate)), $redirect); + CRM_Core_Error::statusBounce(ts('Registration for this event ended on %1', array(1 => $endDate)), $redirect, ts('Sorry')); } } diff --git a/civicrm/CRM/Event/Form/Registration/Confirm.php b/civicrm/CRM/Event/Form/Registration/Confirm.php index 0f4c774d74..155f8e6c13 100644 --- a/civicrm/CRM/Event/Form/Registration/Confirm.php +++ b/civicrm/CRM/Event/Form/Registration/Confirm.php @@ -573,14 +573,10 @@ class CRM_Event_Form_Registration_Confirm extends CRM_Event_Form_Registration { } if (is_object($payment)) { - try { - $result = $payment->doPayment($value); - $value = array_merge($value, $result); - } - catch (\Civi\Payment\Exception\PaymentProcessorException $e) { - CRM_Core_Session::singleton()->setStatus($e->getMessage()); - CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/event/register', "id={$this->_eventId}")); - } + // Not quite sure why we don't just user $value since it contains the data + // from result + // @todo ditch $result & retest. + list($result, $value) = $this->processPayment($payment, $value); } else { CRM_Core_Error::fatal($paymentObjError); @@ -643,9 +639,9 @@ class CRM_Event_Form_Registration_Confirm extends CRM_Event_Form_Registration { !$this->_allowWaitlist && !$this->_requireApproval ) { // transactionID & receive date required while building email template - $this->assign('trxn_id', $value['trxn_id']); - $this->assign('receive_date', CRM_Utils_Date::mysqlToIso($value['receive_date'])); - $this->set('receiveDate', CRM_Utils_Date::mysqlToIso($value['receive_date'])); + $this->assign('trxn_id', CRM_Utils_Array::value('trxn_id', $value)); + $this->assign('receive_date', CRM_Utils_Date::mysqlToIso(CRM_Utils_Array::value('receive_date', $value))); + $this->set('receiveDate', CRM_Utils_Date::mysqlToIso(CRM_Utils_Array::value('receive_date', $value))); $this->set('trxnId', CRM_Utils_Array::value('trxn_id', $value)); } } @@ -824,7 +820,8 @@ class CRM_Event_Form_Registration_Confirm extends CRM_Event_Form_Registration { // call postprocess hook before leaving $this->postProcessHook(); // this does not return - $payment->doPayment($primaryParticipant, 'event'); + + $this->processPayment($payment, $primaryParticipant); } else { CRM_Core_Error::fatal($paymentObjError); @@ -1306,4 +1303,25 @@ class CRM_Event_Form_Registration_Confirm extends CRM_Event_Form_Registration { $form->postProcess(); } + /** + * Process the payment, redirecting back to the page on error. + * + * @param $payment + * @param $value + * + * @return array + */ + private function processPayment($payment, $value) { + try { + $result = $payment->doPayment($value, 'event'); + return array($result, $value); + } + catch (\Civi\Payment\Exception\PaymentProcessorException $e) { + Civi::log()->error('Payment processor exception: ' . $e->getMessage()); + CRM_Core_Session::singleton()->setStatus($e->getMessage()); + CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/event/register', "id={$this->_eventId}")); + } + return array(); + } + } diff --git a/civicrm/CRM/Event/Form/Registration/Register.php b/civicrm/CRM/Event/Form/Registration/Register.php index 50999a089b..6bc629a735 100644 --- a/civicrm/CRM/Event/Form/Registration/Register.php +++ b/civicrm/CRM/Event/Form/Registration/Register.php @@ -1015,6 +1015,7 @@ class CRM_Event_Form_Registration_Register extends CRM_Event_Form_Registration { else { $submittedLineItems = array($lineItem); } + $submittedLineItems = array_filter($submittedLineItems); $this->set('lineItem', $submittedLineItems); $this->set('lineItemParticipantsCount', array($primaryParticipantCount)); } diff --git a/civicrm/CRM/Export/BAO/Export.php b/civicrm/CRM/Export/BAO/Export.php index cb0c0c762c..22fa793331 100644 --- a/civicrm/CRM/Export/BAO/Export.php +++ b/civicrm/CRM/Export/BAO/Export.php @@ -721,8 +721,6 @@ INSERT INTO {$componentTable} SELECT distinct gc.contact_id FROM civicrm_group_c } } - $multipleSelectFields = array('preferred_communication_method' => 1); - $addPaymentHeader = FALSE; $paymentDetails = array(); @@ -790,7 +788,6 @@ INSERT INTO {$componentTable} SELECT distinct gc.contact_id FROM civicrm_group_c $query->convertToPseudoNames($iterationDAO); //first loop through output columns so that we return what is required, and in same order. - $relationshipField = 0; foreach ($outputColumns as $field => $value) { // add im_provider to $dao object @@ -868,12 +865,6 @@ INSERT INTO {$componentTable} SELECT distinct gc.contact_id FROM civicrm_group_c } $field = $field . '_'; - if (array_key_exists($relationField, $multipleSelectFields)) { - $param = array($relationField => $fieldValue); - $names = array($relationField => array('newName' => $relationField, 'groupName' => $relationField)); - CRM_Core_OptionGroup::lookupValues($param, $names, FALSE); - $fieldValue = $param[$relationField]; - } if (is_object($relDAO) && $relationField == 'id') { $row[$field . $relationField] = $relDAO->contact_id; } @@ -949,22 +940,6 @@ INSERT INTO {$componentTable} SELECT distinct gc.contact_id FROM civicrm_group_c if ($cfID = CRM_Core_BAO_CustomField::getKeyID($field)) { $row[$field] = CRM_Core_BAO_CustomField::displayValue($fieldValue, $cfID); } - elseif (array_key_exists($field, $multipleSelectFields)) { - //option group fixes - $paramsNew = array($field => $fieldValue); - if ($field == 'test_tutoring') { - $name = array($field => array('newName' => $field, 'groupName' => 'test')); - // for readers group - } - elseif (substr($field, 0, 4) == 'cmr_') { - $name = array($field => array('newName' => $field, 'groupName' => substr($field, 0, -3))); - } - else { - $name = array($field => array('newName' => $field, 'groupName' => $field)); - } - CRM_Core_OptionGroup::lookupValues($paramsNew, $name, FALSE); - $row[$field] = $paramsNew[$field]; - } elseif (in_array($field, array( 'email_greeting', diff --git a/civicrm/CRM/Financial/BAO/FinancialType.php b/civicrm/CRM/Financial/BAO/FinancialType.php index 538b01ccd0..919b221707 100644 --- a/civicrm/CRM/Financial/BAO/FinancialType.php +++ b/civicrm/CRM/Financial/BAO/FinancialType.php @@ -395,7 +395,33 @@ class CRM_Financial_BAO_FinancialType extends CRM_Financial_DAO_FinancialType { } /** - * Check if FT-ACL is turned on or off + * Check if the logged in user has permission to edit the given financial type. + * + * This is called when determining if they can edit things like option values + * in price sets. At the moment it is not possible to change an option value from + * a type you do not have permission to to a type that you do. + * + * @todo it is currently not possible to edit disabled types if you have ACLs on. + * Do ACLs still apply once disabled? That question should be resolved if tackling + * that gap. + * + * @param int $financialTypeID + * + * @return bool + */ + public static function checkPermissionToEditFinancialType($financialTypeID) { + if (!self::isACLFinancialTypeStatus()) { + return TRUE; + } + // @todo consider adding back in disabled types here. + CRM_Financial_BAO_FinancialType::getAvailableFinancialTypes($financialTypes, CRM_Core_Action::UPDATE); + return isset($financialTypes[$financialTypeID]); + } + + /** + * Check if FT-ACL is turned on or off. + * + * @todo rename this function e.g isFinancialTypeACLsEnabled. * * @return bool */ diff --git a/civicrm/CRM/Financial/DAO/FinancialTrxn.php b/civicrm/CRM/Financial/DAO/FinancialTrxn.php index d7f37ea86a..2a13482928 100644 --- a/civicrm/CRM/Financial/DAO/FinancialTrxn.php +++ b/civicrm/CRM/Financial/DAO/FinancialTrxn.php @@ -30,7 +30,7 @@ * * Generated from xml/schema/CRM/Financial/FinancialTrxn.xml * DO NOT EDIT. Generated by CRM_Core_CodeGen - * (GenCodeChecksum:f8e72183039a2faadf244264d5f5da22) + * (GenCodeChecksum:52a627d344bca95d30eb8b22aad1e245) */ require_once 'CRM/Core/DAO.php'; require_once 'CRM/Utils/Type.php'; @@ -133,12 +133,24 @@ class CRM_Financial_DAO_FinancialTrxn extends CRM_Core_DAO { * @var int unsigned */ public $payment_instrument_id; + /** + * FK to accept_creditcard option group values + * + * @var int unsigned + */ + public $card_type; /** * Check number * * @var string */ public $check_number; + /** + * Last 4 digits of credit card + * + * @var int unsigned + */ + public $pan_truncation; /** * Class constructor. */ @@ -371,6 +383,22 @@ class CRM_Financial_DAO_FinancialTrxn extends CRM_Core_DAO { 'optionEditPath' => 'civicrm/admin/options/payment_instrument', ) ) , + 'financial_trxn_card_type' => array( + 'name' => 'card_type', + 'type' => CRM_Utils_Type::T_INT, + 'title' => ts('Card Type') , + 'description' => 'FK to accept_creditcard option group values', + 'table_name' => 'civicrm_financial_trxn', + 'entity' => 'FinancialTrxn', + 'bao' => 'CRM_Financial_DAO_FinancialTrxn', + 'html' => array( + 'type' => 'Select', + ) , + 'pseudoconstant' => array( + 'optionGroupName' => 'accept_creditcard', + 'optionEditPath' => 'civicrm/admin/options/accept_creditcard', + ) + ) , 'financial_trxn_check_number' => array( 'name' => 'check_number', 'type' => CRM_Utils_Type::T_STRING, @@ -385,6 +413,18 @@ class CRM_Financial_DAO_FinancialTrxn extends CRM_Core_DAO { 'type' => 'Text', ) , ) , + 'financial_trxn_pan_truncation' => array( + 'name' => 'pan_truncation', + 'type' => CRM_Utils_Type::T_INT, + 'title' => ts('Pan Truncation') , + 'description' => 'Last 4 digits of credit card', + 'table_name' => 'civicrm_financial_trxn', + 'entity' => 'FinancialTrxn', + 'bao' => 'CRM_Financial_DAO_FinancialTrxn', + 'html' => array( + 'type' => 'Text', + ) , + ) , ); CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'fields_callback', Civi::$statics[__CLASS__]['fields']); } diff --git a/civicrm/CRM/Group/Page/Group.php b/civicrm/CRM/Group/Page/Group.php index da6e8eec70..d78bec5cfc 100644 --- a/civicrm/CRM/Group/Page/Group.php +++ b/civicrm/CRM/Group/Page/Group.php @@ -99,21 +99,6 @@ class CRM_Group_Page_Group extends CRM_Core_Page_Basic { return 'reset=1&action=browse'; } - /** - * Make sure that the user has permission to access this group. - * - * @param int $id - * The id of the object. - * @param int $title - * Name or title of the object. - * - * @return string - * the permission that the user has (or null) - */ - public function checkPermission($id, $title) { - return CRM_Contact_BAO_Group::checkPermission($id, $title); - } - /** * Re-implement browse. * diff --git a/civicrm/CRM/Logging/Reverter.php b/civicrm/CRM/Logging/Reverter.php index 7d838dc641..4e9310ff03 100644 --- a/civicrm/CRM/Logging/Reverter.php +++ b/civicrm/CRM/Logging/Reverter.php @@ -200,32 +200,6 @@ class CRM_Logging_Reverter { } } - // CRM-7353: if nothing altered civicrm_contact, touch it; this will - // make sure there’s an entry in log_civicrm_contact for this revert - if (empty($diffs['civicrm_contact'])) { - $query = " - SELECT id FROM `{$this->db}`.log_civicrm_contact - WHERE log_conn_id = %1 AND log_date BETWEEN DATE_SUB(%2, INTERVAL 10 SECOND) AND DATE_ADD(%2, INTERVAL 10 SECOND) - ORDER BY log_date DESC LIMIT 1 - "; - $params = array( - 1 => array($this->log_conn_id, 'String'), - 2 => array($this->log_date, 'String'), - ); - $cid = CRM_Core_DAO::singleValueQuery($query, $params); - if (!$cid) { - return; - } - - $dao = new CRM_Contact_DAO_Contact(); - $dao->id = $cid; - if ($dao->find(TRUE)) { - // CRM-8102: MySQL can’t parse its own dates - $dao->birth_date = CRM_Utils_Date::isoToMysql($dao->birth_date); - $dao->deceased_date = CRM_Utils_Date::isoToMysql($dao->deceased_date); - $dao->save(); - } - } } } diff --git a/civicrm/CRM/Mailing/ActionTokens.php b/civicrm/CRM/Mailing/ActionTokens.php index 130b5cd1b2..28158cbbe6 100644 --- a/civicrm/CRM/Mailing/ActionTokens.php +++ b/civicrm/CRM/Mailing/ActionTokens.php @@ -61,6 +61,13 @@ class CRM_Mailing_ActionTokens extends \Civi\Token\AbstractTokenSubscriber { )); } + /** + * @inheritDoc + */ + public function checkActive(\Civi\Token\TokenProcessor $processor) { + return !empty($processor->context['mailingId']) || !empty($processor->context['mailing']); + } + /** * @inheritDoc */ diff --git a/civicrm/CRM/Mailing/BAO/Mailing.php b/civicrm/CRM/Mailing/BAO/Mailing.php index 80056cae31..d746b5abc8 100644 --- a/civicrm/CRM/Mailing/BAO/Mailing.php +++ b/civicrm/CRM/Mailing/BAO/Mailing.php @@ -1093,6 +1093,10 @@ ORDER BY civicrm_email.is_bulkmail DESC $localpart = CRM_Core_BAO_MailSettings::defaultLocalpart(); $emailDomain = CRM_Core_BAO_MailSettings::defaultDomain(); + // Make sure the user configured the site correctly, otherwise you just get "Could not identify any recipients. Perhaps the group is empty?" from the mailing UI + if (empty($emailDomain)) { + CRM_Core_Error::debug_log_message('Error setting verp parameters, defaultDomain is NULL. Did you configure the bounce processing account for this domain?'); + } foreach ($verpTokens as $key => $value) { $verp[$key] = implode($config->verpSeparator, diff --git a/civicrm/CRM/Mailing/Event/BAO/Bounce.php b/civicrm/CRM/Mailing/Event/BAO/Bounce.php index 612b1783af..ae9944f0b9 100644 --- a/civicrm/CRM/Mailing/Event/BAO/Bounce.php +++ b/civicrm/CRM/Mailing/Event/BAO/Bounce.php @@ -46,8 +46,8 @@ class CRM_Mailing_Event_BAO_Bounce extends CRM_Mailing_Event_DAO_Bounce { * * @return bool|null */ - public static function &create(&$params) { - $q = &CRM_Mailing_Event_BAO_Queue::verify($params['job_id'], + public static function create(&$params) { + $q = CRM_Mailing_Event_BAO_Queue::verify($params['job_id'], $params['event_queue_id'], $params['hash'] ); @@ -79,45 +79,13 @@ class CRM_Mailing_Event_BAO_Bounce extends CRM_Mailing_Event_DAO_Bounce { $bounce->copyValues($params); $bounce->save(); - $success = TRUE; - $bounceTable = CRM_Mailing_Event_BAO_Bounce::getTableName(); - $bounceType = CRM_Mailing_DAO_BounceType::getTableName(); - $emailTable = CRM_Core_BAO_Email::getTableName(); - $queueTable = CRM_Mailing_Event_BAO_Queue::getTableName(); - - $bounce->reset(); - // might want to put distinct inside the count - $query = "SELECT count($bounceTable.id) as bounces, - $bounceType.hold_threshold as threshold - FROM $bounceTable - INNER JOIN $bounceType - ON $bounceTable.bounce_type_id = $bounceType.id - INNER JOIN $queueTable - ON $bounceTable.event_queue_id = $queueTable.id - INNER JOIN $emailTable - ON $queueTable.email_id = $emailTable.id - WHERE $emailTable.id = {$q->email_id} - AND ($emailTable.reset_date IS NULL - OR $bounceTable.time_stamp >= $emailTable.reset_date) - GROUP BY $bounceTable.bounce_type_id - ORDER BY threshold, bounces desc"; - - $bounce->query($query); - - while ($bounce->fetch()) { - if ($bounce->bounces >= $bounce->threshold) { - $email = new CRM_Core_BAO_Email(); - $email->id = $q->email_id; - $email->on_hold = TRUE; - $email->hold_date = date('YmdHis'); - $email->save(); - break; - } + if ($q->email_id) { + self::putEmailOnHold($q->email_id); } $transaction->commit(); - return $success; + return TRUE; } /** @@ -279,4 +247,46 @@ class CRM_Mailing_Event_BAO_Bounce extends CRM_Mailing_Event_DAO_Bounce { return $results; } + /** + * Put the email on hold if it has met the threshold. + * + * @param int $email_id + */ + protected static function putEmailOnHold($email_id) { + + $bounceTable = CRM_Mailing_Event_BAO_Bounce::getTableName(); + $bounceType = CRM_Mailing_DAO_BounceType::getTableName(); + $emailTable = CRM_Core_BAO_Email::getTableName(); + $queueTable = CRM_Mailing_Event_BAO_Queue::getTableName(); + + // might want to put distinct inside the count + $query = "SELECT count($bounceTable.id) as bounces, + $bounceType.hold_threshold as threshold + FROM $bounceTable + INNER JOIN $bounceType + ON $bounceTable.bounce_type_id = $bounceType.id + INNER JOIN $queueTable + ON $bounceTable.event_queue_id = $queueTable.id + INNER JOIN $emailTable + ON $queueTable.email_id = $emailTable.id + WHERE $emailTable.id = $email_id + AND ($emailTable.reset_date IS NULL + OR $bounceTable.time_stamp >= $emailTable.reset_date) + GROUP BY $bounceTable.bounce_type_id + ORDER BY threshold, bounces desc"; + + $dao = CRM_Core_DAO::executeQuery($query); + + while ($dao->fetch()) { + if ($dao->bounces >= $dao->threshold) { + $email = new CRM_Core_BAO_Email(); + $email->id = $email_id; + $email->on_hold = TRUE; + $email->hold_date = date('YmdHis'); + $email->save(); + break; + } + } + } + } diff --git a/civicrm/CRM/Mailing/Event/BAO/Unsubscribe.php b/civicrm/CRM/Mailing/Event/BAO/Unsubscribe.php index 461ba9bd78..01ab5a1751 100644 --- a/civicrm/CRM/Mailing/Event/BAO/Unsubscribe.php +++ b/civicrm/CRM/Mailing/Event/BAO/Unsubscribe.php @@ -216,21 +216,23 @@ WHERE email = %2 } //Pass the groups to be unsubscribed from through a hook. - $group_ids = array_keys($groups); - $base_group_ids = array_keys($base_groups); - CRM_Utils_Hook::unsubscribeGroups('unsubscribe', $mailing_id, $contact_id, $group_ids, $base_group_ids); + $groupIds = array_keys($groups); + //include child groups if any + $groupIds = array_merge($groupIds, CRM_Contact_BAO_Group::getChildGroupIds($groupIds)); + + $baseGroupIds = array_keys($base_groups); + CRM_Utils_Hook::unsubscribeGroups('unsubscribe', $mailing_id, $contact_id, $groupIds, $baseGroupIds); // Now we have a complete list of recipient groups. Filter out all // those except smart groups, those that the contact belongs to and // base groups from search based mailings. - $baseGroupClause = ''; - if (!empty($base_group_ids)) { - $baseGroupClause = "OR $group.id IN(" . implode(', ', $base_group_ids) . ")"; + if (!empty($baseGroupIds)) { + $baseGroupClause = "OR $group.id IN(" . implode(', ', $baseGroupIds) . ")"; } $groupIdClause = ''; - if ($group_ids || $base_group_ids) { - $groupIdClause = "AND $group.id IN (" . implode(', ', array_merge($group_ids, $base_group_ids)) . ")"; + if ($groupIds || $baseGroupIds) { + $groupIdClause = "AND $group.id IN (" . implode(', ', array_merge($groupIds, $baseGroupIds)) . ")"; } $do->query(" SELECT $group.id as group_id, @@ -267,7 +269,7 @@ WHERE email = %2 foreach ($groups as $group_id => $group_name) { $notremoved = FALSE; if ($group_name) { - if (in_array($group_id, $base_group_ids)) { + if (in_array($group_id, $baseGroupIds)) { list($total, $removed, $notremoved) = CRM_Contact_BAO_GroupContact::addContactsToGroup($contacts, $group_id, 'Email', 'Removed'); } else { diff --git a/civicrm/CRM/Member/DAO/Membership.php b/civicrm/CRM/Member/DAO/Membership.php index 45a038c724..a3cb6c7097 100644 --- a/civicrm/CRM/Member/DAO/Membership.php +++ b/civicrm/CRM/Member/DAO/Membership.php @@ -30,7 +30,7 @@ * * Generated from xml/schema/CRM/Member/Membership.xml * DO NOT EDIT. Generated by CRM_Core_CodeGen - * (GenCodeChecksum:794bd904da5edcacc20dd5784fcdcf0c) + * (GenCodeChecksum:d92ffd88f95da56ec5e4463369c59155) */ require_once 'CRM/Core/DAO.php'; require_once 'CRM/Utils/Type.php'; @@ -244,7 +244,7 @@ class CRM_Member_DAO_Membership extends CRM_Core_DAO { 'bao' => 'CRM_Member_BAO_Membership', 'html' => array( 'type' => 'Select Date', - 'format' => 'activityDate', + 'formatType' => 'activityDate', ) , ) , 'membership_start_date' => array( @@ -262,7 +262,7 @@ class CRM_Member_DAO_Membership extends CRM_Core_DAO { 'bao' => 'CRM_Member_BAO_Membership', 'html' => array( 'type' => 'Select Date', - 'format' => 'activityDate', + 'formatType' => 'activityDate', ) , ) , 'membership_end_date' => array( @@ -280,7 +280,7 @@ class CRM_Member_DAO_Membership extends CRM_Core_DAO { 'bao' => 'CRM_Member_BAO_Membership', 'html' => array( 'type' => 'Select Date', - 'format' => 'activityDate', + 'formatType' => 'activityDate', ) , ) , 'membership_source' => array( diff --git a/civicrm/CRM/Price/BAO/LineItem.php b/civicrm/CRM/Price/BAO/LineItem.php index 4767d5e7ff..56694bd71c 100644 --- a/civicrm/CRM/Price/BAO/LineItem.php +++ b/civicrm/CRM/Price/BAO/LineItem.php @@ -298,7 +298,15 @@ WHERE li.contribution_id = %1"; 'tax_amount' => $dao->tax_amount, 'price_set_id' => $dao->price_set_id, ); - $lineItems[$dao->id]['tax_rate'] = CRM_Price_BAO_LineItem::calculateTaxRate($lineItems[$dao->id]); + $taxRates = CRM_Core_PseudoConstant::getTaxRates(); + if (isset($lineItems[$dao->id]['financial_type_id']) && array_key_exists($lineItems[$dao->id]['financial_type_id'], $taxRates)) { + // We are close to output/display here - so apply some rounding at output/display level - to not show Tax Rate in all 8 decimals + $lineItems[$dao->id]['tax_rate'] = round($taxRates[$lineItems[$dao->id]['financial_type_id']], 3); + } + else { + // There is no Tax Rate associated with this Financial Type + $lineItems[$dao->id]['tax_rate'] = FALSE; + } $lineItems[$dao->id]['subTotal'] = $lineItems[$dao->id]['qty'] * $lineItems[$dao->id]['unit_price']; if ($lineItems[$dao->id]['tax_amount'] != '') { $getTaxDetails = TRUE; @@ -597,26 +605,4 @@ WHERE li.contribution_id = %1"; } } - /** - * Calculate tax rate in percentage. - * - * @param array $lineItemId - * An assoc array of lineItem. - * - * @return int|void - * tax rate - */ - public static function calculateTaxRate($lineItemId) { - if ($lineItemId['unit_price'] == 0 || $lineItemId['qty'] == 0) { - return FALSE; - } - if ($lineItemId['html_type'] == 'Text') { - $tax = round($lineItemId['tax_amount'] / ($lineItemId['unit_price'] * $lineItemId['qty']) * 100, 2); - } - else { - $tax = round(($lineItemId['tax_amount'] / $lineItemId['unit_price']) * 100, 2); - } - return $tax; - } - } diff --git a/civicrm/CRM/Price/BAO/PriceField.php b/civicrm/CRM/Price/BAO/PriceField.php index 5b56b2eeaa..6f3284c63b 100644 --- a/civicrm/CRM/Price/BAO/PriceField.php +++ b/civicrm/CRM/Price/BAO/PriceField.php @@ -143,6 +143,7 @@ class CRM_Price_BAO_PriceField extends CRM_Price_DAO_PriceField { if ($options['membership_type_id']) { $options['membership_num_terms'] = CRM_Utils_Array::value($index, CRM_Utils_Array::value('membership_num_terms', $params), 1); + $options['is_default'] = CRM_Utils_Array::value($params['membership_type_id'][$index], $defaultArray) ? $defaultArray[$params['membership_type_id'][$index]] : 0; } if (CRM_Utils_Array::value($index, CRM_Utils_Array::value('option_financial_type_id', $params))) { diff --git a/civicrm/CRM/Price/BAO/PriceFieldValue.php b/civicrm/CRM/Price/BAO/PriceFieldValue.php index b02b7cb4ce..2f337386d5 100644 --- a/civicrm/CRM/Price/BAO/PriceFieldValue.php +++ b/civicrm/CRM/Price/BAO/PriceFieldValue.php @@ -29,8 +29,6 @@ * * @package CRM * @copyright CiviCRM LLC (c) 2004-2017 - * $Id$ - * */ /** @@ -43,9 +41,9 @@ class CRM_Price_BAO_PriceFieldValue extends CRM_Price_DAO_PriceFieldValue { * Insert/update a new entry in the database. * * @param array $params - * (reference), array $ids. * - * @param $ids + * @param array $ids + * Deprecated variable. * * @return CRM_Price_DAO_PriceFieldValue */ @@ -157,7 +155,7 @@ class CRM_Price_BAO_PriceFieldValue extends CRM_Price_DAO_PriceFieldValue { } /** - * Retrive the all values for given field id. + * Retrieve all values for given field id. * * @param int $fieldId * Price_field_id. diff --git a/civicrm/CRM/Price/BAO/PriceSet.php b/civicrm/CRM/Price/BAO/PriceSet.php index 39fa2d567c..af7518f3ec 100644 --- a/civicrm/CRM/Price/BAO/PriceSet.php +++ b/civicrm/CRM/Price/BAO/PriceSet.php @@ -29,12 +29,10 @@ * * @package CRM * @copyright CiviCRM LLC (c) 2004-2017 - * $Id$ - * */ /** - * Business object for managing price sets + * Business object for managing price sets. * */ class CRM_Price_BAO_PriceSet extends CRM_Price_DAO_PriceSet { @@ -191,23 +189,17 @@ WHERE ps.name = '{$entityName}' * * @return array */ - public static function &getUsedBy($id, $simpleReturn = FALSE) { - $usedBy = $forms = $tables = array(); - $queryString = " -SELECT entity_table, entity_id -FROM civicrm_price_set_entity -WHERE price_set_id = %1"; - $params = array(1 => array($id, 'Integer')); - $crmFormDAO = CRM_Core_DAO::executeQuery($queryString, $params); - - while ($crmFormDAO->fetch()) { - $forms[$crmFormDAO->entity_table][] = $crmFormDAO->entity_id; - $tables[] = $crmFormDAO->entity_table; - } - // Return only tables + public static function getUsedBy($id, $simpleReturn = FALSE) { + $usedBy = array(); + $forms = self::getFormsUsingPriceSet($id); + $tables = array_keys($forms); + // @todo - this is really clumsy overloading the signature like this. Instead + // move towards having a function that does not call reformatUsedByFormsWithEntityData + // and call that when that data is not used. if ($simpleReturn == 'table') { return $tables; } + // @todo - this is painfully slow in some cases. if (empty($forms)) { $queryString = " SELECT cli.entity_table, cli.entity_id @@ -224,74 +216,17 @@ WHERE cpf.price_set_id = %1"; return $usedBy; } } - // Return only entity data + // @todo - this is really clumsy overloading the signature like this. See above. if ($simpleReturn == 'entity') { return $forms; } - foreach ($forms as $table => $entities) { - switch ($table) { - case 'civicrm_event': - $ids = implode(',', $entities); - $queryString = "SELECT ce.id as id, ce.title as title, ce.is_public as isPublic, ce.start_date as startDate, ce.end_date as endDate, civicrm_option_value.label as eventType, ce.is_template as isTemplate, ce.template_title as templateTitle -FROM civicrm_event ce -LEFT JOIN civicrm_option_value ON - ( ce.event_type_id = civicrm_option_value.value ) -LEFT JOIN civicrm_option_group ON - ( civicrm_option_group.id = civicrm_option_value.option_group_id ) -WHERE - civicrm_option_group.name = 'event_type' AND - ce.id IN ($ids) AND - ce.is_active = 1;"; - $crmDAO = CRM_Core_DAO::executeQuery($queryString); - while ($crmDAO->fetch()) { - if ($crmDAO->isTemplate) { - $usedBy['civicrm_event_template'][$crmDAO->id]['title'] = $crmDAO->templateTitle; - $usedBy['civicrm_event_template'][$crmDAO->id]['eventType'] = $crmDAO->eventType; - $usedBy['civicrm_event_template'][$crmDAO->id]['isPublic'] = $crmDAO->isPublic; - } - else { - $usedBy[$table][$crmDAO->id]['title'] = $crmDAO->title; - $usedBy[$table][$crmDAO->id]['eventType'] = $crmDAO->eventType; - $usedBy[$table][$crmDAO->id]['startDate'] = $crmDAO->startDate; - $usedBy[$table][$crmDAO->id]['endDate'] = $crmDAO->endDate; - $usedBy[$table][$crmDAO->id]['isPublic'] = $crmDAO->isPublic; - } - } - break; - - case 'civicrm_contribution_page': - $ids = implode(',', $entities); - $queryString = "SELECT cp.id as id, cp.title as title, cp.start_date as startDate, cp.end_date as endDate,ct.name as type -FROM civicrm_contribution_page cp, civicrm_financial_type ct -WHERE ct.id = cp.financial_type_id AND - cp.id IN ($ids) AND - cp.is_active = 1;"; - $crmDAO = CRM_Core_DAO::executeQuery($queryString); - while ($crmDAO->fetch()) { - $usedBy[$table][$crmDAO->id]['title'] = $crmDAO->title; - $usedBy[$table][$crmDAO->id]['type'] = $crmDAO->type; - $usedBy[$table][$crmDAO->id]['startDate'] = $crmDAO->startDate; - $usedBy[$table][$crmDAO->id]['endDate'] = $crmDAO->endDate; - } - break; - - case 'civicrm_contribution': - case 'civicrm_membership': - case 'civicrm_participant': - $usedBy[$table] = 1; - break; - - default: - CRM_Core_Error::fatal("$table is not supported in PriceSet::usedBy()"); - break; - } - } + $usedBy = self::reformatUsedByFormsWithEntityData($forms, $usedBy); return $usedBy; } /** - * Delete the price set. + * Delete the price set, including the fields. * * @param int $id * Price Set id. @@ -302,19 +237,6 @@ WHERE ct.id = cp.financial_type_id AND * */ public static function deleteSet($id) { - // remove from all inactive forms - $usedBy = self::getUsedBy($id); - if (isset($usedBy['civicrm_event'])) { - foreach ($usedBy['civicrm_event'] as $eventId => $unused) { - $eventDAO = new CRM_Event_DAO_Event(); - $eventDAO->id = $eventId; - $eventDAO->find(); - while ($eventDAO->fetch()) { - self::removeFrom('civicrm_event', $eventDAO->id); - } - } - } - // delete price fields $priceField = new CRM_Price_DAO_PriceField(); $priceField->price_set_id = $id; @@ -374,7 +296,7 @@ WHERE ct.id = cp.financial_type_id AND } /** - * Find a price_set_id associatied with the given table, id and usedFor + * Find a price_set_id associated with the given table, id and usedFor * Used For value for events:1, contribution:2, membership:3 * * @param string $entityTable @@ -549,17 +471,18 @@ WHERE ct.id = cp.financial_type_id AND $select = 'SELECT ' . implode(',', $priceFields); $from = ' FROM civicrm_price_field'; - $params = array(); - $params[1] = array($setID, 'Integer'); - $where = ' + $params = array( + 1 => array($setID, 'Integer'), + ); + $currentTime = date('YmdHis'); + $where = " WHERE price_set_id = %1 AND is_active = 1 -'; +AND ( active_on IS NULL OR active_on <= {$currentTime} ) +"; $dateSelect = ''; if ($validOnly) { - $currentTime = date('YmdHis'); $dateSelect = " -AND ( active_on IS NULL OR active_on <= {$currentTime} ) AND ( expire_on IS NULL OR expire_on >= {$currentTime} ) "; } @@ -624,7 +547,7 @@ WHERE id = %1"; */ public static function getOnlyPriceFieldID(array $priceSet) { if (count($priceSet['fields']) > 1) { - throw new CRM_Core_Exception(ts('expected only one price field to be in priceset but multiple are present')); + throw new CRM_Core_Exception(ts('expected only one price field to be in price set but multiple are present')); } return (int) implode('_', array_keys($priceSet['fields'])); } @@ -640,7 +563,7 @@ WHERE id = %1"; public static function getOnlyPriceFieldValueID(array $priceSet) { $priceFieldID = self::getOnlyPriceFieldID($priceSet); if (count($priceSet['fields'][$priceFieldID]['options']) > 1) { - throw new CRM_Core_Exception(ts('expected only one price field to be in priceset but multiple are present')); + throw new CRM_Core_Exception(ts('expected only one price field to be in price set but multiple are present')); } return (int) implode('_', array_keys($priceSet['fields'][$priceFieldID]['options'])); } @@ -666,7 +589,7 @@ WHERE id = %1"; $priceSetId = self::getFor($entityTable, $id); } - //check if priceset is is_config + //check if price set is is_config if (is_numeric($priceSetId)) { if (CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceSet', $priceSetId, 'is_quick_config') && $form->getVar('_name') != 'Participant') { $form->assign('quickConfig', 1); @@ -714,16 +637,16 @@ WHERE id = %1"; //get option count info. $form->_priceSet['optionsCountTotal'] = self::getPricesetCount($priceSetId); if ($form->_priceSet['optionsCountTotal']) { - $optionsCountDeails = array(); + $optionsCountDetails = array(); if (!empty($form->_priceSet['fields'])) { foreach ($form->_priceSet['fields'] as $field) { foreach ($field['options'] as $option) { $count = CRM_Utils_Array::value('count', $option, 0); - $optionsCountDeails['fields'][$field['id']]['options'][$option['id']] = $count; + $optionsCountDetails['fields'][$field['id']]['options'][$option['id']] = $count; } } } - $form->_priceSet['optionsCountDetails'] = $optionsCountDeails; + $form->_priceSet['optionsCountDetails'] = $optionsCountDetails; } //get option max value info. @@ -769,6 +692,7 @@ WHERE id = %1"; * @param string $component * This parameter appears to only be relevant to determining whether memberships should be auto-renewed. * (and is effectively a boolean for 'is_membership' which could be calculated from the line items.) + * @param int $priceSetID */ public static function processAmount($fields, &$params, &$lineItem, $component = '', $priceSetID = NULL) { // using price set @@ -1190,7 +1114,7 @@ WHERE id = %1"; return $defaults; } - foreach ($form->_priceSet['fields'] as $key => $val) { + foreach ($form->_priceSet['fields'] as $val) { foreach ($val['options'] as $keys => $values) { // build price field index which is passed via URL // url format will be appended by "&price_5=11" @@ -1666,11 +1590,12 @@ WHERE ps.id = %1 * @return array */ public static function setLineItem($field, $lineItem, $optionValueId, &$totalTax) { + // Here we round - i.e. after multiplying by quantity if ($field['html_type'] == 'Text') { - $taxAmount = $field['options'][$optionValueId]['tax_amount'] * $lineItem[$optionValueId]['qty']; + $taxAmount = round($field['options'][$optionValueId]['tax_amount'] * $lineItem[$optionValueId]['qty'], 2); } else { - $taxAmount = $field['options'][$optionValueId]['tax_amount']; + $taxAmount = round($field['options'][$optionValueId]['tax_amount'], 2); } $taxRate = $field['options'][$optionValueId]['tax_rate']; $lineItem[$optionValueId]['tax_amount'] = $taxAmount; @@ -1744,7 +1669,7 @@ WHERE ps.id = %1 public static function getNonDeductibleAmountFromPriceSet($priceSetId, $lineItem) { $nonDeductibleAmount = 0; if (!empty($lineItem[$priceSetId])) { - foreach ($lineItem[$priceSetId] as $fieldId => $options) { + foreach ($lineItem[$priceSetId] as $options) { $nonDeductibleAmount += $options['non_deductible_amount'] * $options['qty']; } } @@ -1752,4 +1677,111 @@ WHERE ps.id = %1 return $nonDeductibleAmount; } + /** + * Get an array of all forms using a given price set. + * + * @param int $id + * + * @return array + * Pages using the price set, keyed by type. e.g + * array(' + * 'civicrm_contribution_page' => array(2,5,6), + * 'civicrm_event' => array(5,6), + * 'civicrm_event_template' => array(7), + * ) + */ + public static function getFormsUsingPriceSet($id) { + $forms = array(); + $queryString = " +SELECT entity_table, entity_id +FROM civicrm_price_set_entity +WHERE price_set_id = %1"; + $params = array(1 => array($id, 'Integer')); + $crmFormDAO = CRM_Core_DAO::executeQuery($queryString, $params); + + while ($crmFormDAO->fetch()) { + $forms[$crmFormDAO->entity_table][] = $crmFormDAO->entity_id; + } + return $forms; + } + + /** + * @param array $forms + * Array of forms that use a price set keyed by entity. e.g + * array(' + * 'civicrm_contribution_page' => array(2,5,6), + * 'civicrm_event' => array(5,6), + * 'civicrm_event_template' => array(7), + * ) + * + * @return mixed + * Array of entities suppliemented with per entity information. + * e.g + * array('civicrm_event' => array(7 => array('title' => 'x'...)) + * + * @throws \Exception + */ + protected static function reformatUsedByFormsWithEntityData($forms) { + $usedBy = array(); + foreach ($forms as $table => $entities) { + switch ($table) { + case 'civicrm_event': + $ids = implode(',', $entities); + $queryString = "SELECT ce.id as id, ce.title as title, ce.is_public as isPublic, ce.start_date as startDate, ce.end_date as endDate, civicrm_option_value.label as eventType, ce.is_template as isTemplate, ce.template_title as templateTitle +FROM civicrm_event ce +LEFT JOIN civicrm_option_value ON + ( ce.event_type_id = civicrm_option_value.value ) +LEFT JOIN civicrm_option_group ON + ( civicrm_option_group.id = civicrm_option_value.option_group_id ) +WHERE + civicrm_option_group.name = 'event_type' AND + ce.id IN ($ids) AND + ce.is_active = 1;"; + $crmDAO = CRM_Core_DAO::executeQuery($queryString); + while ($crmDAO->fetch()) { + if ($crmDAO->isTemplate) { + $usedBy['civicrm_event_template'][$crmDAO->id]['title'] = $crmDAO->templateTitle; + $usedBy['civicrm_event_template'][$crmDAO->id]['eventType'] = $crmDAO->eventType; + $usedBy['civicrm_event_template'][$crmDAO->id]['isPublic'] = $crmDAO->isPublic; + } + else { + $usedBy[$table][$crmDAO->id]['title'] = $crmDAO->title; + $usedBy[$table][$crmDAO->id]['eventType'] = $crmDAO->eventType; + $usedBy[$table][$crmDAO->id]['startDate'] = $crmDAO->startDate; + $usedBy[$table][$crmDAO->id]['endDate'] = $crmDAO->endDate; + $usedBy[$table][$crmDAO->id]['isPublic'] = $crmDAO->isPublic; + } + } + break; + + case 'civicrm_contribution_page': + $ids = implode(',', $entities); + $queryString = "SELECT cp.id as id, cp.title as title, cp.start_date as startDate, cp.end_date as endDate,ct.name as type +FROM civicrm_contribution_page cp, civicrm_financial_type ct +WHERE ct.id = cp.financial_type_id AND + cp.id IN ($ids) AND + cp.is_active = 1;"; + $crmDAO = CRM_Core_DAO::executeQuery($queryString); + while ($crmDAO->fetch()) { + $usedBy[$table][$crmDAO->id]['title'] = $crmDAO->title; + $usedBy[$table][$crmDAO->id]['type'] = $crmDAO->type; + $usedBy[$table][$crmDAO->id]['startDate'] = $crmDAO->startDate; + $usedBy[$table][$crmDAO->id]['endDate'] = $crmDAO->endDate; + } + break; + + case 'civicrm_contribution': + case 'civicrm_membership': + case 'civicrm_participant': + $usedBy[$table] = 1; + break; + + default: + CRM_Core_Error::fatal("$table is not supported in PriceSet::usedBy()"); + break; + } + } + return $usedBy; + } + } diff --git a/civicrm/CRM/Price/Form/DeleteSet.php b/civicrm/CRM/Price/Form/DeleteSet.php index 7adc42f22d..a4bb5a0d8a 100644 --- a/civicrm/CRM/Price/Form/DeleteSet.php +++ b/civicrm/CRM/Price/Form/DeleteSet.php @@ -29,8 +29,6 @@ * * @package CRM * @copyright CiviCRM LLC (c) 2004-2017 - * $Id$ - * */ /** diff --git a/civicrm/CRM/Price/Form/Field.php b/civicrm/CRM/Price/Form/Field.php index bf39aa55b7..51f7d3fd05 100644 --- a/civicrm/CRM/Price/Form/Field.php +++ b/civicrm/CRM/Price/Form/Field.php @@ -327,13 +327,6 @@ class CRM_Price_Form_Field extends CRM_Core_Form { CRM_Core_DAO::getAttribute('CRM_Price_DAO_PriceField', 'help_post') ); - // active_on - $date_options = array( - 'format' => 'dmY His', - 'minYear' => date('Y') - 1, - 'maxYear' => date('Y') + 5, - 'addEmptyOption' => TRUE, - ); $this->addDateTime('active_on', ts('Active On'), FALSE, array('formatType' => 'activityDateTime')); // expire_on diff --git a/civicrm/CRM/Price/Form/Option.php b/civicrm/CRM/Price/Form/Option.php index 477ec36c9b..99126381c8 100644 --- a/civicrm/CRM/Price/Form/Option.php +++ b/civicrm/CRM/Price/Form/Option.php @@ -115,8 +115,7 @@ class CRM_Price_Form_Option extends CRM_Core_Form { public function buildQuickForm() { if ($this->_action == CRM_Core_Action::UPDATE) { $finTypeId = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceFieldValue', $this->_oid, 'financial_type_id'); - CRM_Financial_BAO_FinancialType::getAvailableFinancialTypes($financialTypes, CRM_Core_Action::UPDATE); - if (!array_key_exists($finTypeId, $financialTypes)) { + if (!CRM_Financial_BAO_FinancialType::checkPermissionToEditFinancialType($finTypeId)) { CRM_Core_Error::fatal(ts("You do not have permission to access this page")); } } diff --git a/civicrm/CRM/Price/Page/Option.php b/civicrm/CRM/Price/Page/Option.php index 2a7f82f351..5e3daafb18 100644 --- a/civicrm/CRM/Price/Page/Option.php +++ b/civicrm/CRM/Price/Page/Option.php @@ -121,8 +121,13 @@ class CRM_Price_Page_Option extends CRM_Core_Page { * @return void */ public function browse() { - $customOption = array(); - CRM_Price_BAO_PriceFieldValue::getValues($this->_fid, $customOption); + $priceOptions = civicrm_api3('PriceFieldValue', 'get', array( + 'price_field_id' => $this->_fid, + // Explicitly do not check permissions so we are not + // restricted by financial type, so we can change them. + 'check_permissions' => FALSE, + )); + $customOption = $priceOptions['values']; // CRM-15378 - check if these price options are in an Event price set $isEvent = FALSE; @@ -134,7 +139,6 @@ class CRM_Price_Page_Option extends CRM_Core_Page { } $config = CRM_Core_Config::singleton(); - $financialType = CRM_Contribute_PseudoConstant::financialType(); $taxRate = CRM_Core_PseudoConstant::getTaxRates(); // display taxTerm for priceFields $invoiceSettings = Civi::settings()->get('contribution_invoice_settings'); @@ -153,7 +157,7 @@ class CRM_Price_Page_Option extends CRM_Core_Page { $customOption[$id]['tax_amount'] = $taxAmount['tax_amount']; } if (!empty($values['financial_type_id'])) { - $customOption[$id]['financial_type_id'] = $financialType[$values['financial_type_id']]; + $customOption[$id]['financial_type_id'] = CRM_Contribute_PseudoConstant::financialType($values['financial_type_id']); } // update enable/disable links depending on price_field properties. if ($this->_isSetReserved) { diff --git a/civicrm/CRM/Price/Page/Set.php b/civicrm/CRM/Price/Page/Set.php index 1a54f36603..c3ec481e7b 100644 --- a/civicrm/CRM/Price/Page/Set.php +++ b/civicrm/CRM/Price/Page/Set.php @@ -143,7 +143,6 @@ class CRM_Price_Page_Set extends CRM_Core_Page { $this->preview($sid); } elseif ($action & CRM_Core_Action::COPY) { - $session = CRM_Core_Session::singleton(); CRM_Core_Session::setStatus(ts('A copy of the price set has been created'), ts('Saved'), 'success'); $this->copy(); } @@ -155,10 +154,8 @@ class CRM_Price_Page_Set extends CRM_Core_Page { if (empty($usedBy)) { // prompt to delete - $session = CRM_Core_Session::singleton(); - $session->pushUserContext(CRM_Utils_System::url('civicrm/admin/price', 'action=browse')); + CRM_Core_Session::singleton()->pushUserContext(CRM_Utils_System::url('civicrm/admin/price', 'action=browse')); $controller = new CRM_Core_Controller_Simple('CRM_Price_Form_DeleteSet', 'Delete Price Set', NULL); - // $id = CRM_Utils_Request::retrieve('sid', 'Positive', $this, false, 0); $controller->set('sid', $sid); $controller->setEmbedded(TRUE); $controller->process(); diff --git a/civicrm/CRM/Profile/Form.php b/civicrm/CRM/Profile/Form.php index 9bcf0b9ee7..d6abda6e3d 100644 --- a/civicrm/CRM/Profile/Form.php +++ b/civicrm/CRM/Profile/Form.php @@ -500,7 +500,11 @@ class CRM_Profile_Form extends CRM_Core_Form { ) { $entityId = $this->_activityId; } - $url = CRM_Core_BAO_CustomField::getFileURL($entityId, $key); + + $url = ''; + if (isset($value)) { + $url = CRM_Core_BAO_CustomField::getFileURL($entityId, $key, $value); + } if ($url) { $customFiles[$name]['displayURL'] = ts("Attached File") . ": {$url['file_url']}"; diff --git a/civicrm/CRM/Report/Form.php b/civicrm/CRM/Report/Form.php index afb8857a44..5e1812e5f9 100644 --- a/civicrm/CRM/Report/Form.php +++ b/civicrm/CRM/Report/Form.php @@ -3433,6 +3433,9 @@ WHERE cg.extends IN ('" . implode("','", $this->_customGroupExtends) . "') AND if (!is_array($value)) { $value = array($value); } + //include child groups if any + $value = array_merge($value, CRM_Contact_BAO_Group::getChildGroupIds($value)); + $clause = "{$field['dbAlias']} IN (" . implode(', ', $value) . ")"; $contactAlias = $this->_aliases['civicrm_contact']; diff --git a/civicrm/CRM/Report/Form/Activity.php b/civicrm/CRM/Report/Form/Activity.php index 346d943b11..820b6f6d1e 100644 --- a/civicrm/CRM/Report/Form/Activity.php +++ b/civicrm/CRM/Report/Form/Activity.php @@ -283,6 +283,12 @@ class CRM_Report_Form_Activity extends CRM_Report_Form { 'title' => ts('Activity Details'), 'type' => CRM_Utils_Type::T_TEXT, ), + 'priority_id' => array( + 'title' => ts('Activity Priority'), + 'type' => CRM_Utils_Type::T_STRING, + 'operatorType' => CRM_Report_Form::OP_MULTISELECT, + 'options' => CRM_Core_PseudoConstant::get('CRM_Activity_DAO_Activity', 'priority_id'), + ), ), 'order_bys' => array( 'activity_date_time' => array( @@ -882,6 +888,7 @@ FROM civireport_activity_temp_target tar $entryFound = FALSE; $activityType = CRM_Core_PseudoConstant::activityType(TRUE, TRUE, FALSE, 'label', TRUE); $activityStatus = CRM_Core_PseudoConstant::activityStatus(); + $priority = CRM_Core_PseudoConstant::get('CRM_Activity_DAO_Activity', 'priority_id'); $viewLinks = FALSE; $context = CRM_Utils_Request::retrieve('context', 'String', $this, FALSE, 'report'); $actUrl = ''; @@ -998,6 +1005,13 @@ FROM civireport_activity_temp_target tar } } + if (array_key_exists('civicrm_activity_priority_id', $row)) { + if ($value = $row['civicrm_activity_priority_id']) { + $rows[$rowNum]['civicrm_activity_priority_id'] = $priority[$value]; + $entryFound = TRUE; + } + } + if (array_key_exists('civicrm_activity_details', $row) && $this->_outputMode == 'html') { if ($value = $row['civicrm_activity_details']) { $fullDetails = $rows[$rowNum]['civicrm_activity_details']; diff --git a/civicrm/CRM/Report/Form/ActivitySummary.php b/civicrm/CRM/Report/Form/ActivitySummary.php index e1a1049a90..c8978ec05c 100644 --- a/civicrm/CRM/Report/Form/ActivitySummary.php +++ b/civicrm/CRM/Report/Form/ActivitySummary.php @@ -155,7 +155,7 @@ class CRM_Report_Form_ActivitySummary extends CRM_Report_Form { 'options' => CRM_Core_PseudoConstant::activityStatus(), ), 'priority_id' => array( - 'title' => ts('Priority'), + 'title' => ts('Activity Priority'), 'type' => CRM_Utils_Type::T_INT, 'operatorType' => CRM_Report_Form::OP_MULTISELECT, 'options' => CRM_Core_PseudoConstant::get('CRM_Activity_DAO_Activity', 'priority_id'), @@ -251,7 +251,7 @@ class CRM_Report_Form_ActivitySummary extends CRM_Report_Form { if (array_key_exists('fields', $table)) { foreach ($table['fields'] as $fieldName => $field) { if (!empty($field['required']) || !empty($this->_params['fields'][$fieldName])) { - if ($tableName == 'civicrm_email') { + if ($tableName == 'civicrm_email' || in_array('email', CRM_Utils_Array::collect('column', $this->_params['order_bys']))) { $this->_emailField = TRUE; } if ($tableName == 'civicrm_phone') { @@ -337,13 +337,6 @@ class CRM_Report_Form_ActivitySummary extends CRM_Report_Form { LEFT JOIN civicrm_case_contact ON civicrm_case_contact.case_id = civicrm_case.id "; - if ($this->_emailField) { - $this->_from .= " - LEFT JOIN civicrm_email {$this->_aliases['civicrm_email']} - ON {$this->_aliases['civicrm_contact']}.id = {$this->_aliases['civicrm_email']}.contact_id AND - {$this->_aliases['civicrm_email']}.is_primary = 1 "; - } - if ($this->_phoneField) { $this->_from .= " LEFT JOIN civicrm_phone {$this->_aliases['civicrm_phone']} @@ -361,6 +354,13 @@ class CRM_Report_Form_ActivitySummary extends CRM_Report_Form { ON target_activity.contact_id = contact_civireport.id {$this->_aclFrom}"; } + + if ($this->_emailField) { + $this->_from .= " + LEFT JOIN civicrm_email {$this->_aliases['civicrm_email']} + ON {$this->_aliases['civicrm_contact']}.id = {$this->_aliases['civicrm_email']}.contact_id AND + {$this->_aliases['civicrm_email']}.is_primary = 1 "; + } } /** diff --git a/civicrm/CRM/Report/Form/Contribute/Summary.php b/civicrm/CRM/Report/Form/Contribute/Summary.php index 684032ad1f..9b59afb436 100644 --- a/civicrm/CRM/Report/Form/Contribute/Summary.php +++ b/civicrm/CRM/Report/Form/Contribute/Summary.php @@ -229,6 +229,12 @@ class CRM_Report_Form_Contribute_Summary extends CRM_Report_Form { 'civicrm_batch' => array( 'dao' => 'CRM_Batch_DAO_EntityBatch', 'grouping' => 'contri-fields', + 'fields' => array( + 'batch_id' => array( + 'name' => 'batch_id', + 'title' => ts('Batch Title'), + ), + ), 'filters' => array( 'batch_id' => array( 'title' => ts('Batch Title'), @@ -237,6 +243,9 @@ class CRM_Report_Form_Contribute_Summary extends CRM_Report_Form { 'type' => CRM_Utils_Type::T_INT, ), ), + 'group_bys' => array( + 'batch_id' => array('title' => ts('Batch ID')), + ), ), 'civicrm_contribution_soft' => array( 'dao' => 'CRM_Contribute_DAO_ContributionSoft', @@ -495,14 +504,15 @@ class CRM_Report_Form_Contribute_Summary extends CRM_Report_Form { {$this->_aliases['civicrm_phone']}.is_primary = 1)"; $this->addAddressFromClause(); - if (!empty($this->_params['batch_id_value'])) { + //for contribution batches + if ($this->isTableSelected('civicrm_batch')) { $this->_from .= " - LEFT JOIN civicrm_entity_financial_trxn eft - ON eft.entity_id = {$this->_aliases['civicrm_contribution']}.id AND - eft.entity_table = 'civicrm_contribution' - LEFT JOIN civicrm_entity_batch {$this->_aliases['civicrm_batch']} - ON {$this->_aliases['civicrm_batch']}.entity_id = eft.financial_trxn_id AND - {$this->_aliases['civicrm_batch']}.entity_table = 'civicrm_financial_trxn'\n"; + LEFT JOIN civicrm_entity_financial_trxn eft + ON eft.entity_id = {$this->_aliases['civicrm_contribution']}.id AND + eft.entity_table = 'civicrm_contribution' + LEFT JOIN civicrm_entity_batch {$this->_aliases['civicrm_batch']} + ON ({$this->_aliases['civicrm_batch']}.entity_id = eft.financial_trxn_id + AND {$this->_aliases['civicrm_batch']}.entity_table = 'civicrm_financial_trxn')"; } } @@ -936,6 +946,12 @@ ROUND(AVG({$this->_aliases['civicrm_contribution_soft']}.amount), 2) as civicrm_ $entryFound = TRUE; } + // convert batch id to batch title + if (!empty($row['civicrm_batch_batch_id'])) { + $rows[$rowNum]['civicrm_batch_batch_id'] = CRM_Core_DAO::getFieldValue('CRM_Batch_BAO_Batch', $row['civicrm_batch_batch_id'], 'title'); + $entryFound = TRUE; + } + $entryFound = $this->alterDisplayAddressFields($row, $rows, $rowNum, 'contribute/detail', 'List all contribution(s) for this ') ? TRUE : $entryFound; $entryFound = $this->alterDisplayContactFields($row, $rows, $rowNum, 'contribute/detail', 'List all contribution(s) for this ') ? TRUE : $entryFound; diff --git a/civicrm/CRM/Report/Form/Event/Summary.php b/civicrm/CRM/Report/Form/Event/Summary.php index 9254f8bdca..99a69328da 100644 --- a/civicrm/CRM/Report/Form/Event/Summary.php +++ b/civicrm/CRM/Report/Form/Event/Summary.php @@ -202,8 +202,7 @@ class CRM_Report_Form_Event_Summary extends CRM_Report_Form_Event { $this->_participantWhere GROUP BY civicrm_participant.event_id, - civicrm_participant.status_id, - civicrm_participant.fee_currency"; + civicrm_participant.status_id"; $info = CRM_Core_DAO::executeQuery($sql); $participant_data = $participant_info = $currency = array(); @@ -262,8 +261,8 @@ class CRM_Report_Form_Event_Summary extends CRM_Report_Form_Event { } } - $statusType1 = CRM_Event_PseudoConstant::participantStatus(NULL, 'is_counted = 1'); - $statusType2 = CRM_Event_PseudoConstant::participantStatus(NULL, 'is_counted = 0'); + $statusType1 = CRM_Event_PseudoConstant::participantStatus(NULL, 'is_counted = 1', 'label'); + $statusType2 = CRM_Event_PseudoConstant::participantStatus(NULL, 'is_counted = 0', 'label'); //make column header for participant status Registered/Attended $type1_header = implode('/', $statusType1); diff --git a/civicrm/CRM/Tag/Form/Edit.php b/civicrm/CRM/Tag/Form/Edit.php index 6f7cc03d22..0919c7f070 100644 --- a/civicrm/CRM/Tag/Form/Edit.php +++ b/civicrm/CRM/Tag/Form/Edit.php @@ -44,27 +44,44 @@ class CRM_Tag_Form_Edit extends CRM_Admin_Form { return 'Tag'; } + public function preProcess() { + CRM_Utils_Request::retrieve('id', 'Integer', $this, FALSE); + $this->set('BAOName', 'CRM_Core_BAO_Tag'); + parent::preProcess(); + } + /** * Build the form object. */ public function buildQuickForm() { if ($this->_action == CRM_Core_Action::DELETE) { - if ($this->_id && $tag = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_Tag', $this->_id, 'name', 'parent_id')) { - $url = CRM_Utils_System::url('civicrm/tag', "reset=1"); - CRM_Core_Error::statusBounce(ts("This tag cannot be deleted. You must delete all its child tags ('%1', etc) prior to deleting this tag.", array(1 => $tag)), $url); + $url = CRM_Utils_System::url('civicrm/tag'); + if (!$this->_id) { + $this->_id = explode(',', CRM_Utils_Request::retrieve('id', 'String')); } - if ($this->_values['is_reserved'] == 1 && !CRM_Core_Permission::check('administer reserved tags')) { - CRM_Core_Error::statusBounce(ts("You do not have sufficient permission to delete this reserved tag.")); + $this->_id = (array) $this->_id; + if (!$this->_id) { + CRM_Core_Error::statusBounce(ts("Unknown tag."), $url); + } + foreach ($this->_id as $id) { + if (!CRM_Utils_Rule::positiveInteger($id)) { + CRM_Core_Error::statusBounce(ts("Unknown tag."), $url); + } + if ($tag = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_Tag', $id, 'name', 'parent_id')) { + CRM_Core_Error::statusBounce(ts("This tag cannot be deleted. You must delete all its child tags ('%1', etc) prior to deleting this tag.", array(1 => $tag)), $url); + } + if (!CRM_Core_Permission::check('administer reserved tags') && CRM_Core_DAO::getFieldValue('CRM_Core_DAO_Tag', $id, 'is_reserved')) { + CRM_Core_Error::statusBounce(ts("You do not have sufficient permission to delete this reserved tag."), $url); + } + } + if (count($this->_id) > 1) { + $this->assign('delName', ts('%1 tags', array(1 => count($this->_id)))); } } else { - $parentId = NULL; - $isTagSetChild = FALSE; - $this->_isTagSet = CRM_Utils_Request::retrieve('tagset', 'Positive', $this); - if (!$this->_isTagSet && - $this->_id && + if (!$this->_isTagSet && $this->_id && CRM_Core_DAO::getFieldValue('CRM_Core_DAO_Tag', $this->_id, 'is_tagset') ) { $this->_isTagSet = TRUE; @@ -72,8 +89,11 @@ class CRM_Tag_Form_Edit extends CRM_Admin_Form { if ($this->_id) { $parentId = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_Tag', $this->_id, 'parent_id'); - $isTagSetChild = $parentId ? CRM_Core_DAO::getFieldValue('CRM_Core_DAO_Tag', $parentId, 'is_tagset') : FALSE; } + else { + $parentId = CRM_Utils_Request::retrieve('parent_id', 'Integer', $this); + } + $isTagSetChild = $parentId ? CRM_Core_DAO::getFieldValue('CRM_Core_DAO_Tag', $parentId, 'is_tagset') : FALSE; if (!$this->_isTagSet) { if (!$isTagSetChild) { @@ -109,7 +129,9 @@ class CRM_Tag_Form_Edit extends CRM_Admin_Form { $isReserved = $this->add('checkbox', 'is_reserved', ts('Reserved?')); - $this->addSelect('used_for', array('multiple' => TRUE, 'option_url' => NULL)); + if (!$isTagSetChild) { + $this->addSelect('used_for', array('multiple' => TRUE, 'option_url' => NULL)); + } $adminTagset = TRUE; if (!CRM_Core_Permission::check('administer Tagsets')) { @@ -135,10 +157,17 @@ class CRM_Tag_Form_Edit extends CRM_Admin_Form { */ public function setDefaultValues() { $defaults = parent::setDefaultValues(); - if (empty($this->_id) || !CRM_Core_DAO::getFieldValue('CRM_Core_DAO_Tag', $this->_id, 'color')) { + $cloneFrom = CRM_Utils_Request::retrieve('clone_from', 'Integer'); + if (empty($this->_id) && $cloneFrom) { + $params = array('id' => $cloneFrom); + CRM_Core_BAO_Tag::retrieve($params, $this->_values); + $this->_values['name'] .= ' (' . ts('copy') . ')'; + $defaults = $this->_values; + } + if (empty($defaults['color'])) { $defaults['color'] = '#ffffff'; } - if (empty($this->_id)) { + if (empty($this->_id) && empty($defaults['used_for'])) { $defaults['used_for'] = 'civicrm_contact'; } return $defaults; @@ -148,46 +177,60 @@ class CRM_Tag_Form_Edit extends CRM_Admin_Form { * Process the form submission. */ public function postProcess() { - // store the submitted values in an array - $params = $this->exportValues(); - if ($this->_id) { - $params['id'] = $this->_id; - } - - if ($this->_action == CRM_Core_Action::ADD || - $this->_action == CRM_Core_Action::UPDATE - ) { - $params['used_for'] = implode(",", $params['used_for']); + if ($this->_action == CRM_Core_Action::DELETE) { + $deleted = 0; + $tag = civicrm_api3('tag', 'getsingle', array('id' => $this->_id[0])); + foreach ($this->_id as $id) { + if (CRM_Core_BAO_Tag::del($id)) { + $deleted++; + } + } + if (count($this->_id) == 1 && $deleted == 1) { + if ($tag['is_tagset']) { + CRM_Core_Session::setStatus(ts("The tag set '%1' has been deleted.", array(1 => $tag['name'])), ts('Deleted'), 'success'); + } + else { + CRM_Core_Session::setStatus(ts("The tag '%1' has been deleted.", array(1 => $tag['name'])), ts('Deleted'), 'success'); + } + } + else { + CRM_Core_Session::setStatus(ts("Deleted %1 tags.", array(1 => $deleted)), ts('Deleted'), 'success'); + } } + else { + $params = $this->exportValues(); + if ($this->_id) { + $params['id'] = $this->_id; + } - $params['is_tagset'] = 0; - if ($this->_isTagSet) { - $params['is_tagset'] = 1; - } + if (isset($params['used_for']) && ($this->_action == CRM_Core_Action::ADD || $this->_action == CRM_Core_Action::UPDATE)) { + $params['used_for'] = implode(",", $params['used_for']); + } - if (!isset($params['is_reserved'])) { - $params['is_reserved'] = 0; - } + $params['is_tagset'] = 0; + if ($this->_isTagSet) { + $params['is_tagset'] = 1; + } - if (!isset($params['is_selectable'])) { - $params['is_selectable'] = 0; - } + if (!isset($params['is_reserved'])) { + $params['is_reserved'] = 0; + } - if (strtolower($params['color']) == '#ffffff') { - $params['color'] = 'null'; - } + if (!isset($params['parent_id']) && $this->get('parent_id')) { + $params['parent_id'] = $this->get('parent_id'); + } + if (empty($params['parent_id'])) { + $params['parent_id'] = ''; + } - if ($this->_action == CRM_Core_Action::DELETE) { - if ($this->_id > 0) { - $tag = civicrm_api3('tag', 'getsingle', array('id' => $this->_id)); - CRM_Core_BAO_Tag::del($this->_id); - CRM_Core_Session::setStatus(ts("The tag '%1' has been deleted.", array(1 => $tag['name'])), ts('Deleted'), 'success'); + if (!isset($params['is_selectable'])) { + $params['is_selectable'] = 0; } - } - else { $tag = CRM_Core_BAO_Tag::add($params); CRM_Core_Session::setStatus(ts("The tag '%1' has been saved.", array(1 => $tag->name)), ts('Saved'), 'success'); + $this->ajaxResponse['tag'] = $tag->toArray(); } + CRM_Core_Session::singleton()->pushUserContext(CRM_Utils_System::url('civicrm/tag')); } } diff --git a/civicrm/CRM/Tag/Form/Merge.php b/civicrm/CRM/Tag/Form/Merge.php new file mode 100644 index 0000000000..f6778083d0 --- /dev/null +++ b/civicrm/CRM/Tag/Form/Merge.php @@ -0,0 +1,126 @@ +<?php +/* + +--------------------------------------------------------------------+ + | CiviCRM version 4.7 | + +--------------------------------------------------------------------+ + | Copyright CiviCRM LLC (c) 2004-2017 | + +--------------------------------------------------------------------+ + | This file is a part of CiviCRM. | + | | + | CiviCRM is free software; you can copy, modify, and distribute it | + | under the terms of the GNU Affero General Public License | + | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. | + | | + | CiviCRM 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 Affero General Public License for more details. | + | | + | You should have received a copy of the GNU Affero General Public | + | License and the CiviCRM Licensing Exception along | + | with this program; if not, contact CiviCRM LLC | + | at info[AT]civicrm[DOT]org. If you have questions about the | + | GNU Affero General Public License or the licensing of CiviCRM, | + | see the CiviCRM license FAQ at http://civicrm.org/licensing | + +--------------------------------------------------------------------+ + */ + +/** + * + * @package CRM + * @copyright CiviCRM LLC (c) 2004-2017 + */ + +/** + * Form for merging tags. + */ +class CRM_Tag_Form_Merge extends CRM_Core_Form { + protected $_id; + protected $_tags; + + public function preProcess() { + $this->_id = CRM_Utils_Request::retrieve('id', 'String', $this, FALSE); + $this->_id = explode(',', $this->_id); + $url = CRM_Utils_System::url('civicrm/tag'); + if (count($this->_id) < 2) { + CRM_Core_Error::statusBounce(ts("You must select at least 2 tags for merging."), $url); + } + $tags = civicrm_api3('Tag', 'get', array('id' => array('IN' => $this->_id), 'options' => array('limit' => 0))); + $this->_tags = $tags['values']; + if (count($this->_id) != count($this->_tags)) { + CRM_Core_Error::statusBounce(ts("Unknown tag."), $url); + } + if (!CRM_Core_Permission::check('administer reserved tags')) { + foreach ($tags['values'] as $tag) { + if (!empty($tag['is_reserved'])) { + CRM_Core_Error::statusBounce(ts("You do not have permission to administer reserved tags."), $url); + } + } + } + } + + /** + * Build the form object. + */ + public function buildQuickForm() { + $this->add('text', 'name', ts('Name of combined tag'), TRUE); + $this->assign('tags', CRM_Utils_Array::collect('name', $this->_tags)); + + $this->addButtons(array( + array( + 'type' => 'next', + 'name' => ts('Merge'), + 'spacing' => ' ', + 'isDefault' => TRUE, + ), + array( + 'type' => 'cancel', + 'name' => ts('Cancel'), + ), + ) + ); + } + + /** + * Set default values for the form. + * + * @return array + */ + public function setDefaultValues() { + $primary = CRM_Utils_Array::first($this->_tags); + return array( + 'name' => $primary['name'], + ); + } + + /** + * Process the form submission. + */ + public function postProcess() { + $params = $this->exportValues(); + $deleted = CRM_Utils_Array::collect('name', $this->_tags); + $primary = array_shift($this->_tags); + + foreach ($this->_tags as $tag) { + CRM_Core_BAO_EntityTag::mergeTags($primary['id'], $tag['id']); + } + + if ($params['name'] != $primary['name']) { + civicrm_api3('Tag', 'create', array('id' => $primary['id'], 'name' => $params['name'])); + } + + $key = array_search($params['name'], $deleted); + if ($key !== FALSE) { + unset($deleted[$key]); + } + + CRM_Core_Session::setStatus( + ts('All records previously tagged %1 are now tagged %2.', array(1 => implode(' ' . ts('or') . ' ', $deleted), 2 => $params['name'])), + ts('%1 Tags Merged', array(1 => count($this->_id))), + 'success' + ); + + CRM_Core_Session::singleton()->pushUserContext(CRM_Utils_System::url('civicrm/tag')); + } + +} diff --git a/civicrm/CRM/Tag/Page/Tag.php b/civicrm/CRM/Tag/Page/Tag.php index 5a1c18259a..1c98beca04 100644 --- a/civicrm/CRM/Tag/Page/Tag.php +++ b/civicrm/CRM/Tag/Page/Tag.php @@ -32,187 +32,48 @@ */ /** - * Page for displaying list of categories. + * Page for managing tags. */ -class CRM_Tag_Page_Tag extends CRM_Core_Page_Basic { - - public $useLivePageJS = TRUE; - - /** - * The action links that we need to display for the browse screen. - * - * @var array - */ - static $_links = NULL; - - /** - * Get BAO. - * - * @return string - * Classname of BAO. - */ - public function getBAOName() { - return 'CRM_Core_BAO_Tag'; - } - - /** - * Get action Links. - * - * @return array - * (reference) of action links - */ - public function &links() { - if (!(self::$_links)) { - self::$_links = array( - CRM_Core_Action::UPDATE => array( - 'name' => ts('Edit'), - 'url' => 'civicrm/tag', - 'qs' => 'action=update&id=%%id%%&reset=1', - 'title' => ts('Edit Tag'), - ), - CRM_Core_Action::DELETE => array( - 'name' => ts('Delete'), - 'url' => 'civicrm/tag', - 'qs' => 'action=delete&id=%%id%%', - 'title' => ts('Delete Tag'), - ), - CRM_Core_Action::FOLLOWUP => array( - 'name' => ts('Merge'), - 'class' => 'merge_tag', - 'title' => ts('Merge Tag'), - ), - ); - } - return self::$_links; - } - - /** - * Get name of edit form. - * - * @return string - * Classname of edit form. - */ - public function editForm() { - return 'CRM_Tag_Form_Edit'; - } - - /** - * Get form name for edit form. - * - * @return string - * name of this page. - */ - public function editName() { - return 'Tag'; - } - - /** - * Get form name for delete form. - * - * @return string - * name of this page. - */ - public function deleteName() { - return 'Tag'; - } - - /** - * Get user context. - * - * @param null $mode - * - * @return string - * user context. - */ - public function userContext($mode = NULL) { - return 'civicrm/tag'; - } - - /** - * Get name of delete form. - * - * @return string - * Classname of delete form. - */ - public function deleteForm() { - return 'CRM_Tag_Form_Edit'; - } +class CRM_Tag_Page_Tag extends CRM_Core_Page { /** - * Override function browse() - * - * @param null $action - * @param null $sort + * Run page */ - public function browse($action = NULL, $sort = NULL) { - $adminTagSet = FALSE; - if (CRM_Core_Permission::check('administer Tagsets')) { - $adminTagSet = TRUE; + public function run() { + CRM_Core_Resources::singleton() + ->addScriptFile('civicrm', 'bower_components/jstree/dist/jstree.min.js', 0, 'html-header') + ->addStyleFile('civicrm', 'bower_components/jstree/dist/themes/default/style.min.css') + ->addPermissions(array('administer reserved tags', 'administer Tagsets')); + + $usedFor = $tagsets = array(); + + $result = civicrm_api3('OptionValue', 'get', array( + 'return' => array("value", "name"), + 'option_group_id' => "tag_used_for", + )); + foreach ($result['values'] as $value) { + $usedFor[$value['value']] = $value['name']; } - $this->assign('adminTagSet', $adminTagSet); - - $reservedClause = !CRM_Core_Permission::check('administer reserved tags') ? "AND t1.is_reserved != 1" : ''; - $query = "SELECT t1.name, t1.id -FROM civicrm_tag t1 LEFT JOIN civicrm_tag t2 ON t1.id = t2.parent_id -WHERE t2.id IS NULL {$reservedClause}"; - $tag = CRM_Core_DAO::executeQuery($query); - - $mergeableTags = array(); - while ($tag->fetch()) { - $mergeableTags[$tag->id] = 1; - } - - $usedFor = CRM_Core_OptionGroup::values('tag_used_for'); - - $query = " SELECT t1.name, t1.id, t2.name as parent, t1.description, t1.used_for, t1.is_tagset as is_tagset, - t1.is_reserved, t1.parent_id, t1.used_for, t1.color, t2.is_tagset as is_tagset_child, t2.parent_id as grandparent_id - FROM civicrm_tag t1 - LEFT JOIN civicrm_tag t2 ON t1.parent_id = t2.id - LEFT JOIN civicrm_tag t3 ON t2.parent_id = t3.id - ORDER BY CONCAT(IFNULL(t3.name, ''), IFNULL(t2.name, ''), t1.name)"; - - $tag = CRM_Core_DAO::executeQuery($query); - $values = array(); - $action = CRM_Core_Action::UPDATE + CRM_Core_Action::DELETE; - $permission = CRM_Core_Permission::EDIT; - - while ($tag->fetch()) { - $values[$tag->id] = (array) $tag; - - $used = array(); - if ($values[$tag->id]['used_for']) { - $usedArray = explode(",", $values[$tag->id]['used_for']); - foreach ($usedArray as $key => $value) { - $used[$key] = $usedFor[$value]; - } - } - - $values[$tag->id]['used_for'] = implode(", ", $used); - - $newAction = $action; - if ($values[$tag->id]['is_reserved']) { - $newAction = CRM_Core_Action::UPDATE; - } - - if ($values[$tag->id]['is_tagset'] && !CRM_Core_Permission::check('administer Tagsets')) { - $newAction = 0; - } - - if (array_key_exists($tag->id, $mergeableTags)) { - $newAction += CRM_Core_Action::FOLLOWUP; - } - - // populate action links - if ($newAction) { - $this->action($tag, $newAction, $values[$tag->id], self::links(), $permission, TRUE); - } - else { - $values[$tag->id]['action'] = ''; + $result = civicrm_api3('Tag', 'get', array( + 'return' => array("name", "used_for", "description", "created_id.display_name", "created_date", "is_reserved"), + 'is_tagset' => 1, + 'options' => array('limit' => 0), + )); + foreach ($result['values'] as $id => $tagset) { + $used = explode(',', CRM_Utils_Array::value('used_for', $tagset, '')); + $tagset['used_for_label'] = array_values(array_intersect_key($usedFor, array_flip($used))); + if (isset($tagset['created_id.display_name'])) { + $tagset['display_name'] = $tagset['created_id.display_name']; } + unset($tagset['created_id.display_name']); + $tagsets[$id] = $tagset; } - $this->assign('rows', $values); + $this->assign('usedFor', $usedFor); + $this->assign('tagsets', $tagsets); + + return parent::run(); } } diff --git a/civicrm/CRM/Upgrade/Incremental/php/FourSeven.php b/civicrm/CRM/Upgrade/Incremental/php/FourSeven.php index a1a3c58152..36b4313e9c 100644 --- a/civicrm/CRM/Upgrade/Incremental/php/FourSeven.php +++ b/civicrm/CRM/Upgrade/Incremental/php/FourSeven.php @@ -59,6 +59,9 @@ class CRM_Upgrade_Incremental_php_FourSeven extends CRM_Upgrade_Incremental_Base $preUpgradeMessage .= '<p>' . ts('The %1 payment processor is no longer bundled with CiviCRM. After upgrading you will need to install the extension to continue using it.', array(1 => 'Moneris')) . '</p>'; } } + if ($rev == '4.7.13') { + $preUpgradeMessage .= '<p>' . ts('A new permission has been added called %1 This Permission is now used to control access to the Manage Tags screen', array(1 => 'manage tags')) . '</p>'; + } } /** @@ -119,6 +122,7 @@ class CRM_Upgrade_Incremental_php_FourSeven extends CRM_Upgrade_Incremental_Base * @param string $rev */ public function upgrade_4_7_alpha1($rev) { + $this->addTask('Drop action scheudle mapping foreign key', 'dropActionScheudleMappingForeignKey'); $this->addTask('Migrate \'on behalf of\' information to module_data', 'migrateOnBehalfOfInfo'); $this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev); $this->addTask(ts('Migrate Settings to %1', array(1 => $rev)), 'migrateSettings', $rev); @@ -780,6 +784,18 @@ FROM `civicrm_dashboard_contact` JOIN `civicrm_contact` WHERE civicrm_dashboard_ return TRUE; } + /** + * CRM-18464 Check if Foreign key exists and also drop any index of same name accidentially created. + * + * @param \CRM_Queue_TaskContext $ctx + * + * @return bool + */ + public static function dropActionScheudleMappingForeignKey(CRM_Queue_TaskContext $ctx) { + CRM_Core_BAO_SchemaHandler::safeRemoveFK('civicrm_action_schedule', 'FK_civicrm_action_schedule_mapping_id'); + return TRUE; + } + /** * CRM-18345 Don't delete mailing data on email/phone deletion * Implemented here in CRM-18526 diff --git a/civicrm/CRM/Upgrade/Incremental/sql/4.7.17.mysql.tpl b/civicrm/CRM/Upgrade/Incremental/sql/4.7.17.mysql.tpl new file mode 100644 index 0000000000..03a47793e2 --- /dev/null +++ b/civicrm/CRM/Upgrade/Incremental/sql/4.7.17.mysql.tpl @@ -0,0 +1,14 @@ +{* file to handle db changes in 4.7.17 during upgrade *} + +-- CRM-19943 +UPDATE civicrm_navigation SET url = 'civicrm/tag' WHERE url = 'civicrm/tag?reset=1'; +UPDATE civicrm_navigation SET url = REPLACE(url, 'civicrm/tag', 'civicrm/tag/edit') WHERE url LIKE 'civicrm/tag?%'; + +-- CRM-19815, CRM-19830 update references to check_number to reflect unique name +UPDATE civicrm_uf_field SET field_name = 'contribution_check_number' WHERE field_name = 'check_number'; +UPDATE civicrm_mapping_field SET name = 'contribution_check_number' WHERE name = 'check_number'; + +-- CRM-20158 +ALTER TABLE `civicrm_financial_trxn` + ADD card_type INT( 10 ) UNSIGNED NULL DEFAULT NULL COMMENT 'FK to accept_creditcard option group values' AFTER payment_instrument_id, + ADD pan_truncation INT UNSIGNED NULL COMMENT 'Last 4 digits of credit card.' AFTER check_number; diff --git a/civicrm/CRM/Upgrade/Incremental/sql/4.7.alpha1.mysql.tpl b/civicrm/CRM/Upgrade/Incremental/sql/4.7.alpha1.mysql.tpl index 7ef1d6af18..df1ad7d5c7 100644 --- a/civicrm/CRM/Upgrade/Incremental/sql/4.7.alpha1.mysql.tpl +++ b/civicrm/CRM/Upgrade/Incremental/sql/4.7.alpha1.mysql.tpl @@ -3,7 +3,6 @@ -- Add new columns for multilingual purpose ALTER TABLE `civicrm_action_schedule` ADD COLUMN `filter_contact_language` varchar(128) DEFAULT NULL COMMENT 'Used for multilingual installation'; ALTER TABLE `civicrm_action_schedule` ADD COLUMN `communication_language` varchar(8) DEFAULT NULL COMMENT 'Used for multilingual installation'; -ALTER TABLE `civicrm_action_schedule` DROP FOREIGN KEY `FK_civicrm_action_schedule_mapping_id`; ALTER TABLE `civicrm_action_schedule` MODIFY COLUMN mapping_id varchar(64); -- Q: Should we validate that local civicrm_action_mapping records have expected IDs? diff --git a/civicrm/CRM/Utils/Check/Component/PriceFields.php b/civicrm/CRM/Utils/Check/Component/PriceFields.php new file mode 100644 index 0000000000..a36d9a5584 --- /dev/null +++ b/civicrm/CRM/Utils/Check/Component/PriceFields.php @@ -0,0 +1,76 @@ +<?php + +/* + +--------------------------------------------------------------------+ + | CiviCRM version 4.7 | + +--------------------------------------------------------------------+ + | Copyright CiviCRM LLC (c) 2004-2016 | + +--------------------------------------------------------------------+ + | This file is a part of CiviCRM. | + | | + | CiviCRM is free software; you can copy, modify, and distribute it | + | under the terms of the GNU Affero General Public License | + | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. | + | | + | CiviCRM 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 Affero General Public License for more details. | + | | + | You should have received a copy of the GNU Affero General Public | + | License and the CiviCRM Licensing Exception along | + | with this program; if not, contact CiviCRM LLC | + | at info[AT]civicrm[DOT]org. If you have questions about the | + | GNU Affero General Public License or the licensing of CiviCRM, | + | see the CiviCRM license FAQ at http://civicrm.org/licensing | + +--------------------------------------------------------------------+ + */ + +/** + * + * @package CRM + * @copyright CiviCRM LLC (c) 2004-2016 + */ +class CRM_Utils_Check_Component_PriceFields extends CRM_Utils_Check_Component { + + /** + * Display warning about invalid priceFields + * + */ + public function checkPriceFields() { + $sql = "SELECT DISTINCT ps.title as ps_title, ps.id as ps_id, psf.label as psf_label + FROM civicrm_price_set ps + INNER JOIN civicrm_price_field psf ON psf.price_set_id = ps.id + INNER JOIN civicrm_price_field_value pfv ON pfv.price_field_id = psf.id + LEFT JOIN civicrm_financial_type cft ON cft.id = pfv.financial_type_id + WHERE cft.id IS NULL OR cft.is_active = 0"; + $dao = CRM_Core_DAO::executeQuery($sql); + $count = 0; + $html = ''; + $messages = array(); + while ($dao->fetch()) { + $count++; + $url = CRM_Utils_System::url('civicrm/admin/price/field', array( + 'reset' => 1, + 'action' => 'browse', + 'sid' => $dao->ps_id)); + $html .= "<tr><td>$dao->ps_title</td><td>$dao->psf_label</td><td><a href='$url'>View Price Set Fields</a></td></tr>"; + } + if ($count > 0) { + $msg = "<p>the following Price Set Fields use disabled or invalid financial types and need to be fixed if they are to still be used.<p> + <p><table><thead><tr><th>Price Set</th><th>Price Set Field</th><th>Action Link</th> + </tr></thead><tbody> + $html + </tbody></table></p>"; + $messages[] = new CRM_Utils_Check_Message( + __FUNCTION__, + ts($msg), + ts('Invalid Price Fields'), + \Psr\Log\LogLevel::WARNING, + 'fa-lock' + ); + } + return $messages; + } + +} diff --git a/civicrm/CRM/Utils/Date.php b/civicrm/CRM/Utils/Date.php index 2f2a17d055..3d8ed11f93 100644 --- a/civicrm/CRM/Utils/Date.php +++ b/civicrm/CRM/Utils/Date.php @@ -1741,6 +1741,108 @@ class CRM_Utils_Date { return $mysqlDate; } + /** + * Convert a Civi-special date string to a standard php date string. + * + * For historical reasons CiviCRM has it's own (possibly Smarty derived) + * format for defined date strings. This renders something php can use. + * + * @param string $dateFormatString + * e.g mm/dd/yy + * These map to the values used in the date_format field in civicrm_custom_field.date_format. + * + * @return string + * A proper php strotime formatted equivalent of the string. + * eg m/d/y for the above. + * + * http://php.net/manual/en/function.strtotime.php + */ + public static function getPhpDateFormatFromInputStyleDateFormat($dateFormatString) { + $formats = CRM_Core_SelectValues::datePluginToPHPFormats(); + return $formats[$dateFormatString]; + } + + /** + * Add the metadata about a date field to the field. + * + * This metadata will work with the call $form->add('datepicker', ... + * + * @param array $fieldMetaData + * @param array $field + * + * @return array + */ + public static function addDateMetadataToField($fieldMetaData, $field) { + if (isset($fieldMetaData['html'])) { + $field['html_type'] = $fieldMetaData['html']['type']; + if ($field['html_type'] === 'Select Date') { + if (!isset($field['date_format'])) { + $dateAttributes = CRM_Core_SelectValues::date($fieldMetaData['html']['formatType'], NULL, NULL, NULL, 'Input'); + $field['start_date_years'] = $dateAttributes['minYear']; + $field['end_date_years'] = $dateAttributes['maxYear']; + $field['date_format'] = $dateAttributes['format']; + $field['is_datetime_field'] = TRUE; + $field['time_format'] = $dateAttributes['time']; + $field['php_datetime_format'] = CRM_Utils_Date::getPhpDateFormatFromInputStyleDateFormat($field['date_format']); + if ($field['time_format']) { + $field['php_datetime_format'] .= ' H-i-s'; + } + } + $field['datepicker']['extra'] = self::getDatePickerExtra($field); + $field['datepicker']['attributes'] = self::getDatePickerAttributes($field); + } + } + return $field; + } + + + /** + * Get the fields required for the 'extra' parameter when adding a datepicker. + * + * @param array $field + * + * @return array + */ + public static function getDatePickerExtra($field) { + $extra = array(); + if (isset($field['date_format'])) { + $extra['date'] = $field['date_format']; + $extra['time'] = $field['time_format']; + } + $thisYear = date('Y'); + if (isset($field['start_date_years'])) { + $extra['minDate'] = date('Y-m-d', strtotime('-' . ($thisYear - $field['start_date_years']) . ' years')); + } + if (isset($field['end_date_years'])) { + $extra['maxDate'] = date('Y-m-d', strtotime('-' . ($thisYear - $field['end_date_years']) . ' years')); + } + return $extra; + } + + /** + * Get the attributes parameters required for datepicker. + * + * @param array $field + * Field metadata + * + * @return array + * Array ready to pass to $this->addForm('datepicker' as attributes. + */ + public static function getDatePickerAttributes(&$field) { + $attributes = array(); + $dateAttributes = array( + 'start_date_years' => 'minYear', + 'end_date_years' => 'maxYear', + 'date_format' => 'format', + ); + foreach ($dateAttributes as $dateAttribute => $mapTo) { + if (isset($field[$dateAttribute])) { + $attributes[$mapTo] = $field[$dateAttribute]; + } + } + return $attributes; + } + /** * Function to convert mysql to date plugin format. * diff --git a/civicrm/CRM/Utils/Mail/EmailProcessor.php b/civicrm/CRM/Utils/Mail/EmailProcessor.php index a995b7af8f..2e8c14a991 100644 --- a/civicrm/CRM/Utils/Mail/EmailProcessor.php +++ b/civicrm/CRM/Utils/Mail/EmailProcessor.php @@ -136,11 +136,9 @@ class CRM_Utils_Mail_EmailProcessor { $usedfor = $dao->is_default; $emailActivityTypeId - = (defined('EMAIL_ACTIVITY_TYPE_ID') && EMAIL_ACTIVITY_TYPE_ID) ? EMAIL_ACTIVITY_TYPE_ID : CRM_Core_OptionGroup::getValue( - 'activity_type', - 'Inbound Email', - 'name' - ); + = (defined('EMAIL_ACTIVITY_TYPE_ID') && EMAIL_ACTIVITY_TYPE_ID) + ? EMAIL_ACTIVITY_TYPE_ID + : CRM_Core_OptionGroup::getValue('activity_type', 'Inbound Email', 'name'); if (!$emailActivityTypeId) { CRM_Core_Error::fatal(ts('Could not find a valid Activity Type ID for Inbound Email')); @@ -376,6 +374,14 @@ class CRM_Utils_Mail_EmailProcessor { 'hash' => $hash, 'body' => $text, 'version' => 3, + // Setting is_transactional means it will rollback if + // it crashes part way through creating the bounce. + // If the api were standard & had a create this would be the + // default. Adding the standard api & deprecating this one + // would probably be the + // most consistent way to address this - but this is + // a quick hack. + 'is_transactional' => 1, ); $result = civicrm_api('Mailing', 'event_bounce', $params); break; diff --git a/civicrm/CRM/Utils/PDF/Document.php b/civicrm/CRM/Utils/PDF/Document.php index ff98f858b7..e841d67ca0 100644 --- a/civicrm/CRM/Utils/PDF/Document.php +++ b/civicrm/CRM/Utils/PDF/Document.php @@ -115,6 +115,7 @@ class CRM_Utils_PDF_Document { $phpWord = \PhpOffice\PhpWord\IOFactory::load($fileName, $formats[$ext]); } + \PhpOffice\PhpWord\Settings::setOutputEscapingEnabled(TRUE); //CRM-20015 $objWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, $formats[$ext]); CRM_Utils_System::setHttpHeader('Content-Type', "application/$ext"); diff --git a/civicrm/CRM/Utils/Pager.php b/civicrm/CRM/Utils/Pager.php index 2595bee080..bd33490a83 100644 --- a/civicrm/CRM/Utils/Pager.php +++ b/civicrm/CRM/Utils/Pager.php @@ -112,11 +112,11 @@ class CRM_Utils_Pager extends Pager_Sliding { * page variable, but a different form element for one at the bottom. */ $this->_response['titleTop'] = ts('Page %1 of %2', array( - 1 => '<input size="2" maxlength="3" name="' . self::PAGE_ID . '" type="text" value="' . $this->_response['currentPage'] . '" />', + 1 => '<input size="2" maxlength="4" name="' . self::PAGE_ID . '" type="text" value="' . $this->_response['currentPage'] . '" />', 2 => $this->_response['numPages'], )); $this->_response['titleBottom'] = ts('Page %1 of %2', array( - 1 => '<input size="2" maxlength="3" name="' . self::PAGE_ID_BOTTOM . '" type="text" value="' . $this->_response['currentPage'] . '" />', + 1 => '<input size="2" maxlength="4" name="' . self::PAGE_ID_BOTTOM . '" type="text" value="' . $this->_response['currentPage'] . '" />', 2 => $this->_response['numPages'], )); } diff --git a/civicrm/CRM/Utils/Rule.php b/civicrm/CRM/Utils/Rule.php index 34f346937a..034bec2116 100644 --- a/civicrm/CRM/Utils/Rule.php +++ b/civicrm/CRM/Utils/Rule.php @@ -100,10 +100,15 @@ class CRM_Utils_Rule { return FALSE; } - // Ensure the string contains only valid characters: - // For column names: alphanumeric and underscores - // For aliases: backticks, alphanumeric hyphens and underscores. - if (!preg_match('/^((`[\w-]{1,64}`|[\w-]{1,64})\.)?(`[\w-]{1,64}`|[\w-]{1,64})$/i', $str)) { + // Ensure $str conforms to expected format. Not a complete expression of + // what MySQL permits; this should permit the formats CiviCRM generates. + // + // * Table name prefix is optional. + // * Table & column names & aliases: + // * Composed of alphanumeric chars, underscore and hyphens. + // * Maximum length of 64 chars. + // * Optionally surrounded by backticks, in which case spaces also OK. + if (!preg_match('/^((`[\w- ]{1,64}`|[\w-]{1,64})\.)?(`[\w- ]{1,64}`|[\w-]{1,64})$/i', $str)) { return FALSE; } diff --git a/civicrm/CRM/Utils/System.php b/civicrm/CRM/Utils/System.php index 8079cec6f2..3ded33fe19 100644 --- a/civicrm/CRM/Utils/System.php +++ b/civicrm/CRM/Utils/System.php @@ -1391,7 +1391,7 @@ class CRM_Utils_System { * @return mixed */ public static function formatDocUrl($url) { - return preg_replace('#^user/((\w\w/)?stable/)?#', 'user/en/stable/', $url); + return preg_replace('#^user/((\w\w/)?(stable|current)/)?#', 'user/en/stable/', $url); } /** diff --git a/civicrm/CRM/Utils/System/Joomla.php b/civicrm/CRM/Utils/System/Joomla.php index 2758d11758..8162ac8a61 100644 --- a/civicrm/CRM/Utils/System/Joomla.php +++ b/civicrm/CRM/Utils/System/Joomla.php @@ -712,8 +712,20 @@ class CRM_Utils_System_Joomla extends CRM_Utils_System_Base { '', $config->userFrameworkBaseURL ); + // CRM-19453 revisited. Under Windows, the pattern wasn't recognised. + // This is the original pattern, but it doesn't work under Windows. + // By setting the pattern to the one used before the change first and only + // changing it means that the change code only affects Windows users. + $pattern = '|/media/civicrm/.*$|'; + if (DIRECTORY_SEPARATOR == '\\') { + // This regular expression will handle Windows as well as Linux + // and any combination of forward and back slashes in directory + // separators. We only apply it if the directory separator is the one + // used by Windows. + $pattern = '|[\\\\/]media[\\\\/]civicrm[\\\\/].*$|'; + } $siteRoot = preg_replace( - '|/media/civicrm/.*$|', + $pattern, '', $config->imageUploadDir ); diff --git a/civicrm/CRM/Utils/Type.php b/civicrm/CRM/Utils/Type.php index c782e5cec5..65b726c98f 100644 --- a/civicrm/CRM/Utils/Type.php +++ b/civicrm/CRM/Utils/Type.php @@ -143,6 +143,28 @@ class CRM_Utils_Type { return (isset($string)) ? $string : ""; } + /** + * Get the data_type for the field. + * + * @param array $fieldMetadata + * Metadata about the field. + * + * @return string + */ + public static function getDataTypeFromFieldMetadata($fieldMetadata) { + if (isset($fieldMetadata['data_type'])) { + return $fieldMetadata['data_type']; + } + if (empty($fieldMetadata['type'])) { + // I would prefer to throw an e-notice but there is some, + // probably unnecessary logic, that only retrieves activity fields + // if they are 'in the profile' and probably they are not 'in' + // until they are added - which might lead to ? who knows! + return ''; + } + return self::typeToString($fieldMetadata['type']); + } + /** * Helper function to call escape on arrays. * diff --git a/civicrm/Civi/API/Api3SelectQuery.php b/civicrm/Civi/API/Api3SelectQuery.php index 984b174668..77bdd1b4b7 100644 --- a/civicrm/Civi/API/Api3SelectQuery.php +++ b/civicrm/Civi/API/Api3SelectQuery.php @@ -36,6 +36,7 @@ class Api3SelectQuery extends SelectQuery { * @inheritDoc */ protected function buildWhereClause() { + $filters = array(); foreach ($this->where as $key => $value) { $table_name = NULL; $column_name = NULL; @@ -104,23 +105,37 @@ class Api3SelectQuery extends SelectQuery { // Just ignore this for the $where_clause. continue; } - if (!is_array($value)) { - $this->query->where(array("`$table_name`.`$column_name` = @value"), array( - "@value" => $value, - )); + $operator = is_array($value) ? \CRM_Utils_Array::first(array_keys($value)) : NULL; + if (!in_array($operator, \CRM_Core_DAO::acceptedSQLOperators())) { + $value = array('=' => $value); } - else { - // We expect only one element in the array, of the form - // "operator" => "rhs". - $operator = \CRM_Utils_Array::first(array_keys($value)); - if (!in_array($operator, \CRM_Core_DAO::acceptedSQLOperators())) { - $this->query->where(array("{$table_name}.{$column_name} = @value"), array("@value" => $value)); - } - else { - $this->query->where(\CRM_Core_DAO::createSQLFilter("{$table_name}.{$column_name}", $value)); + $filters[$key] = \CRM_Core_DAO::createSQLFilter("{$table_name}.{$column_name}", $value); + } + // Support OR groups + if (!empty($this->where['options']['or'])) { + $orGroups = $this->where['options']['or']; + if (is_string($orGroups)) { + $orGroups = array_map('trim', explode(',', $orGroups)); + } + if (!is_array(\CRM_Utils_Array::first($orGroups))) { + $orGroups = array($orGroups); + } + foreach ($orGroups as $orGroup) { + $orClause = array(); + foreach ($orGroup as $key) { + if (!isset($filters[$key])) { + throw new \CiviCRM_API3_Exception("'$key' specified in OR group but not added to params"); + } + $orClause[] = $filters[$key]; + unset($filters[$key]); } + $this->query->where(implode(' OR ', $orClause)); } } + // Add the remaining params using AND + foreach ($filters as $filter) { + $this->query->where($filter); + } } /** diff --git a/civicrm/api/v3/Activity.php b/civicrm/api/v3/Activity.php index 20284c2bb2..ba87a024a0 100644 --- a/civicrm/api/v3/Activity.php +++ b/civicrm/api/v3/Activity.php @@ -230,23 +230,35 @@ function _civicrm_api3_activity_create_spec(&$params) { */ function _civicrm_api3_activity_get_spec(&$params) { $params['tag_id'] = array( - 'name' => 'tag_id', 'title' => 'Tags', 'description' => 'Find activities with specified tags.', 'type' => 1, 'FKClassName' => 'CRM_Core_DAO_Tag', 'FKApiName' => 'Tag', + 'supports_joins' => TRUE, + ); + $params['file_id'] = array( + 'title' => 'Attached Files', + 'description' => 'Find activities with attached files.', + 'type' => 1, + 'FKClassName' => 'CRM_Core_DAO_File', + 'FKApiName' => 'File', ); $params['case_id'] = array( - 'name' => 'case_id', 'title' => 'Cases', 'description' => 'Find activities within specified cases.', 'type' => 1, 'FKClassName' => 'CRM_Case_DAO_Case', 'FKApiName' => 'Case', ); + $params['contact_id'] = array( + 'title' => 'Activity Contact ID', + 'description' => 'Find activities involving this contact (as target, source, OR assignee).', + 'type' => 1, + 'FKClassName' => 'CRM_Contact_DAO_Contact', + 'FKApiName' => 'Contact', + ); $params['target_contact_id'] = array( - 'name' => 'target_contact_id', 'title' => 'Target Contact ID', 'description' => 'Find activities with specified target contact.', 'type' => 1, @@ -254,7 +266,6 @@ function _civicrm_api3_activity_get_spec(&$params) { 'FKApiName' => 'Contact', ); $params['source_contact_id'] = array( - 'name' => 'source_contact_id', 'title' => 'Source Contact ID', 'description' => 'Find activities with specified source contact.', 'type' => 1, @@ -262,7 +273,6 @@ function _civicrm_api3_activity_get_spec(&$params) { 'FKApiName' => 'Contact', ); $params['assignee_contact_id'] = array( - 'name' => 'assignee_contact_id', 'title' => 'Assignee Contact ID', 'description' => 'Find activities with specified assignee contact.', 'type' => 1, @@ -304,55 +314,62 @@ function civicrm_api3_activity_get($params) { } } - if (!empty($params['contact_id'])) { - $activities = CRM_Activity_BAO_Activity::getContactActivity($params['contact_id']); - // BAO function doesn't actually return a contact ID - hack api for now & add to test so when api re-write - // happens it won't get missed. - foreach ($activities as $key => $activityArray) { - $activities[$key]['id'] = $key; + $sql = CRM_Utils_SQL_Select::fragment(); + // Support search by activity_contact + $extraFieldSpecs = array(); + _civicrm_api3_activity_create_spec($extraFieldSpecs); + $options = civicrm_api3('ActivityContact', 'getoptions', array('field' => 'record_type_id')); + $options = $options['values']; + $activityContactOptions = array( + 'contact_id' => NULL, + 'target_contact_id' => array_search('Activity Targets', $options), + 'source_contact_id' => array_search('Activity Source', $options), + 'assignee_contact_id' => array_search('Activity Assignees', $options), + ); + foreach ($activityContactOptions as $activityContactName => $activityContactValue) { + if (!empty($params[$activityContactName])) { + _civicrm_api3_validate_integer($params, $activityContactName, $extraFieldSpecs[$activityContactName], 'Activity'); + if (!is_array($params[$activityContactName])) { + $params[$activityContactName] = array('=' => $params[$activityContactName]); + } + $clause = \CRM_Core_DAO::createSQLFilter('contact_id', $params[$activityContactName]); + $typeClause = $activityContactValue ? 'record_type_id = #typeId AND ' : ''; + $sql->where("a.id IN (SELECT activity_id FROM civicrm_activity_contact WHERE $typeClause !clause)", + array('#typeId' => $activityContactValue, '!clause' => $clause) + ); } } - else { - $sql = CRM_Utils_SQL_Select::fragment(); - // Support search by activity_contact - $options = civicrm_api3('ActivityContact', 'getoptions', array('field' => 'record_type_id')); - $options = $options['values']; - $activityContactOptions = array( - 'target_contact_id' => array_search('Activity Targets', $options), - 'source_contact_id' => array_search('Activity Source', $options), - 'assignee_contact_id' => array_search('Activity Assignees', $options), - ); - foreach ($activityContactOptions as $activityContactName => $activityContactValue) { - if (!empty($params[$activityContactName])) { - if (!is_array($params[$activityContactName])) { - $params[$activityContactName] = array('=' => $params[$activityContactName]); - } - $clause = \CRM_Core_DAO::createSQLFilter('contact_id', $params[$activityContactName]); - $sql->where('a.id IN (SELECT activity_id FROM civicrm_activity_contact WHERE record_type_id = #typeId AND !clause)', - array('#typeId' => $activityContactValue, '!clause' => $clause) - ); - } + if (!empty($params['tag_id'])) { + _civicrm_api3_validate_integer($params, 'tag_id', $extraFieldSpecs['tag_id'], 'Activity'); + if (!is_array($params['tag_id'])) { + $params['tag_id'] = array('=' => $params['tag_id']); } - if (!empty($params['tag_id'])) { - if (!is_array($params['tag_id'])) { - $params['tag_id'] = array('=' => $params['tag_id']); - } - $clause = \CRM_Core_DAO::createSQLFilter('tag_id', $params['tag_id']); - if ($clause) { - $sql->where('a.id IN (SELECT entity_id FROM civicrm_entity_tag WHERE entity_table = "civicrm_activity" AND !clause)', array('!clause' => $clause)); - } + $clause = \CRM_Core_DAO::createSQLFilter('tag_id', $params['tag_id']); + if ($clause) { + $sql->where('a.id IN (SELECT entity_id FROM civicrm_entity_tag WHERE entity_table = "civicrm_activity" AND !clause)', array('!clause' => $clause)); } - if (!empty($params['case_id'])) { - if (!is_array($params['case_id'])) { - $params['case_id'] = array('=' => $params['case_id']); - } - $clause = \CRM_Core_DAO::createSQLFilter('case_id', $params['case_id']); - if ($clause) { - $sql->where('a.id IN (SELECT activity_id FROM civicrm_case_activity WHERE !clause)', array('!clause' => $clause)); - } + } + if (!empty($params['file_id'])) { + _civicrm_api3_validate_integer($params, 'file_id', $extraFieldSpecs['file_id'], 'Activity'); + if (!is_array($params['file_id'])) { + $params['file_id'] = array('=' => $params['file_id']); + } + $clause = \CRM_Core_DAO::createSQLFilter('file_id', $params['file_id']); + if ($clause) { + $sql->where('a.id IN (SELECT entity_id FROM civicrm_entity_file WHERE entity_table = "civicrm_activity" AND !clause)', array('!clause' => $clause)); } - $activities = _civicrm_api3_basic_get(_civicrm_api3_get_BAO(__FUNCTION__), $params, FALSE, 'Activity', $sql); } + if (!empty($params['case_id'])) { + _civicrm_api3_validate_integer($params, 'case_id', $extraFieldSpecs['case_id'], 'Activity'); + if (!is_array($params['case_id'])) { + $params['case_id'] = array('=' => $params['case_id']); + } + $clause = \CRM_Core_DAO::createSQLFilter('case_id', $params['case_id']); + if ($clause) { + $sql->where('a.id IN (SELECT activity_id FROM civicrm_case_activity WHERE !clause)', array('!clause' => $clause)); + } + } + $activities = _civicrm_api3_basic_get(_civicrm_api3_get_BAO(__FUNCTION__), $params, FALSE, 'Activity', $sql); $options = _civicrm_api3_get_options_from_params($params, FALSE, 'Activity', 'get'); if ($options['is_count']) { return civicrm_api3_create_success($activities, $params, 'Activity', 'get'); @@ -376,6 +393,10 @@ function civicrm_api3_activity_get($params) { * new activities list */ function _civicrm_api3_activity_get_formatResult($params, $activities) { + if (!$activities) { + return $activities; + } + $returns = CRM_Utils_Array::value('return', $params, array()); if (!is_array($returns)) { $returns = str_replace(' ', '', $returns); @@ -398,6 +419,14 @@ function _civicrm_api3_activity_get_formatResult($params, $activities) { $returns['assignee_contact_id'] = 1; } + $tagGet = array('tag_id', 'entity_id'); + foreach (array_keys($returns) as $key) { + if (strpos($key, 'tag_id.') === 0) { + $tagGet[] = $key; + $returns['tag_id'] = 1; + } + } + foreach ($returns as $n => $v) { switch ($n) { case 'assignee_contact_id': @@ -431,13 +460,50 @@ function _civicrm_api3_activity_get_formatResult($params, $activities) { } break; + case 'tag_id': + $tags = civicrm_api3('EntityTag', 'get', array( + 'entity_table' => 'civicrm_activity', + 'entity_id' => array('IN' => array_keys($activities)), + 'return' => $tagGet, + 'options' => array('limit' => 0), + )); + foreach ($tags['values'] as $tag) { + $key = (int) $tag['entity_id']; + unset($tag['entity_id'], $tag['id']); + $activities[$key]['tag_id'][$tag['tag_id']] = $tag; + } + break; + + case 'file_id': + $dao = CRM_Core_DAO::executeQuery("SELECT entity_id, file_id FROM civicrm_entity_file WHERE entity_table = 'civicrm_activity' AND entity_id IN (%1)", + array(1 => array(implode(',', array_keys($activities)), 'String', CRM_Core_DAO::QUERY_FORMAT_NO_QUOTES))); + while ($dao->fetch()) { + $activities[$dao->entity_id]['file_id'][] = $dao->file_id; + } + break; + default: if (substr($n, 0, 6) == 'custom') { $returnProperties[$n] = $v; } } } - if (!empty($activities) && (!empty($returnProperties) || !empty($params['contact_id']))) { + + // Legacy extras + if (!empty($params['contact_id'])) { + $statusOptions = CRM_Activity_BAO_Activity::buildOptions('status_id', 'get'); + $typeOptions = CRM_Activity_BAO_Activity::buildOptions('activity_type_id', 'validate'); + foreach ($activities as $key => &$activityArray) { + if (!empty($activityArray['status_id'])) { + $activityArray['status'] = $statusOptions[$activityArray['status_id']]; + } + if (!empty($activityArray['activity_type_id'])) { + $activityArray['activity_name'] = $typeOptions[$activityArray['activity_type_id']]; + } + } + } + + if (!empty($returnProperties) || !empty($params['contact_id'])) { foreach ($activities as $activityId => $values) { //@todo - should possibly load activity type id if not loaded (update with id) _civicrm_api3_custom_data_get($activities[$activityId], CRM_Utils_Array::value('check_permissions', $params), 'Activity', $activityId, NULL, CRM_Utils_Array::value('activity_type_id', $values)); diff --git a/civicrm/api/v3/Case.php b/civicrm/api/v3/Case.php index 8cfdfe1d2d..efddd0904b 100644 --- a/civicrm/api/v3/Case.php +++ b/civicrm/api/v3/Case.php @@ -453,6 +453,11 @@ function _civicrm_api3_case_format_params(&$params) { function civicrm_api3_case_getList($params) { require_once 'api/v3/Generic/Getlist.php'; require_once 'api/v3/CaseContact.php'; + //CRM:19956 - Assign case_id param if both id and case_id is passed to retrieve the case + if (!empty($params['id']) && !empty($params['params']) && !empty($params['params']['case_id'])) { + $params['params']['case_id'] = array('IN' => $params['id']); + unset($params['id']); + } $params['id_field'] = 'case_id'; $params['label_field'] = $params['search_field'] = 'contact_id.sort_name'; $params['description_field'] = array( @@ -463,6 +468,7 @@ function civicrm_api3_case_getList($params) { 'case_id.start_date', ); $apiRequest = array( + 'version' => 3, 'entity' => 'CaseContact', 'action' => 'getlist', 'params' => $params, diff --git a/civicrm/api/v3/Contact.php b/civicrm/api/v3/Contact.php index af3028d59c..773068f4bb 100644 --- a/civicrm/api/v3/Contact.php +++ b/civicrm/api/v3/Contact.php @@ -376,6 +376,37 @@ function _civicrm_api3_contact_get_supportanomalies(&$params, &$options) { unset($params['filter.group_id']); $options['input_params']['group'] = $groups; } + if (isset($params['group'])) { + $groups = $params['group']; + $allGroups = CRM_Core_PseudoConstant::group(); + if (is_array($groups) && in_array(key($groups), CRM_Core_DAO::acceptedSQLOperators(), TRUE)) { + // Get the groups array. + $groupsArray = $groups[key($groups)]; + foreach ($groupsArray as &$group) { + if (!is_numeric($group) && array_search($group, $allGroups)) { + $group = array_search($group, $allGroups); + } + } + // Now reset the $groups array with the ids not the titles. + $groups[key($groups)] = $groupsArray; + } + // handle format like 'group' => array('title1', 'title2'). + elseif (is_array($groups)) { + foreach ($groups as $k => &$group) { + if (!is_numeric($group) && array_search($group, $allGroups)) { + $group = array_search($group, $allGroups); + } + if (!is_numeric($k) && array_search($k, $allGroups)) { + unset($groups[$k]); + $groups[array_search($k, $allGroups)] = $group; + } + } + } + elseif (!is_numeric($groups) && array_search($groups, $allGroups)) { + $groups = array_search($groups, $allGroups); + } + $params['group'] = $groups; + } } /** @@ -1085,7 +1116,7 @@ function civicrm_api3_contact_merge($params) { 'srcID' => $params['to_remove_id'], 'dstID' => $params['to_keep_id'], ), - ), array(), $params['mode'], $params['auto_flip'])) != FALSE) { + ), array(), $params['mode'])) != FALSE) { return civicrm_api3_create_success($result, $params); } throw new CiviCRM_API3_Exception('Merge failed'); @@ -1111,10 +1142,6 @@ function _civicrm_api3_contact_merge_spec(&$params) { 'type' => CRM_Utils_Type::T_INT, 'api.aliases' => array('other_id'), ); - $params['auto_flip'] = array( - 'title' => 'Swap destination and source to retain lowest id?', - 'api.default' => TRUE, - ); $params['mode'] = array( // @todo need more detail on what this means. 'title' => 'Dedupe mode', diff --git a/civicrm/api/v3/Contribution.php b/civicrm/api/v3/Contribution.php index 976ad8cc65..c6e2b1e7ab 100644 --- a/civicrm/api/v3/Contribution.php +++ b/civicrm/api/v3/Contribution.php @@ -240,19 +240,69 @@ function _civicrm_api3_contribution_delete_spec(&$params) { function civicrm_api3_contribution_get($params) { $mode = CRM_Contact_BAO_Query::MODE_CONTRIBUTE; + $additionalOptions = _civicrm_api3_contribution_get_support_nonunique_returns($params); $returnProperties = CRM_Contribute_BAO_Query::defaultReturnProperties($mode); - $contributions = _civicrm_api3_get_using_query_object('Contribution', $params, array(), NULL, $mode, $returnProperties); + $contributions = _civicrm_api3_get_using_query_object('Contribution', $params, $additionalOptions, NULL, $mode, $returnProperties); foreach ($contributions as $id => $contribution) { $softContribution = CRM_Contribute_BAO_ContributionSoft::getSoftContribution($id, TRUE); $contributions[$id] = array_merge($contribution, $softContribution); // format soft credit for backward compatibility _civicrm_api3_format_soft_credit($contributions[$id]); + _civicrm_api3_contribution_add_supported_fields($contributions[$id]); + } return civicrm_api3_create_success($contributions, $params, 'Contribution', 'get'); } +/** + * Fix the return values to reflect cases where the schema has been changed. + * + * At the query object level using uniquenames dismbiguates between tables. + * + * However, adding uniquename can change inputs accepted by the api, so we need + * to ensure we are asking for the unique name return fields. + * + * @param array $params + * + * @return array + * @throws \API_Exception + */ +function _civicrm_api3_contribution_get_support_nonunique_returns($params) { + $additionalOptions = array(); + $options = _civicrm_api3_get_options_from_params($params, TRUE); + foreach (array('check_number', 'address_id') as $changedVariable) { + if (isset($options['return']) && !empty($options['return'][$changedVariable])) { + $additionalOptions['return']['contribution_' . $changedVariable] = 1; + } + } + return $additionalOptions; +} + +/** + * Support for supported output variables. + * + * @param $contribution + */ +function _civicrm_api3_contribution_add_supported_fields(&$contribution) { + // These are output fields that are supported in our test contract. + // Arguably we should also do the same with 'campaign_id' & + // 'source' - which are also fields being rendered with unique names. + // That seems more consistent with other api where we output the actual field names. + $outputAliases = array( + 'contribution_check_number' => 'check_number', + 'contribution_address_id' => 'address_id', + 'payment_instrument_id' => 'instrument_id', + ); + foreach ($outputAliases as $returnName => $copyTo) { + if (array_key_exists($returnName, $contribution)) { + $contribution[$copyTo] = $contribution[$returnName]; + } + } + +} + /** * Get number of contacts matching the supplied criteria. * @@ -528,7 +578,7 @@ function _civicrm_api3_contribution_completetransaction_spec(&$params) { $params['trxn_date'] = array( 'title' => 'Transaction Date', 'description' => 'Date this transaction occurred', - 'type' => CRM_Utils_Type::T_DATE, + 'type' => CRM_Utils_Type::T_DATE + CRM_Utils_Type::T_TIME, ); } @@ -552,9 +602,12 @@ function civicrm_api3_contribution_repeattransaction(&$params) { $input = $ids = array(); civicrm_api3_verify_one_mandatory($params, NULL, array('contribution_recur_id', 'original_contribution_id')); if (empty($params['original_contribution_id'])) { + // CRM-19873 call with test mode. $params['original_contribution_id'] = civicrm_api3('contribution', 'getvalue', array( 'return' => 'id', + 'contribution_status_id' => array('IN' => array('Completed')), 'contribution_recur_id' => $params['contribution_recur_id'], + 'contribution_test' => CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_ContributionRecur', $params['contribution_recur_id'], 'is_test'), 'options' => array('limit' => 1, 'sort' => 'id DESC'), )); } @@ -680,7 +733,7 @@ function _civicrm_api3_contribution_repeattransaction_spec(&$params) { $params['receive_date'] = array( 'title' => 'Contribution Receive Date', 'name' => 'receive_date', - 'type' => CRM_Utils_Type::T_DATE, + 'type' => CRM_Utils_Type::T_DATE + CRM_Utils_Type::T_TIME, 'api.default' => 'now', ); $params['trxn_id'] = array( diff --git a/civicrm/api/v3/Extension.php b/civicrm/api/v3/Extension.php index 3862ac0cec..367ad7b66d 100644 --- a/civicrm/api/v3/Extension.php +++ b/civicrm/api/v3/Extension.php @@ -244,7 +244,9 @@ function civicrm_api3_extension_download($params) { } CRM_Extension_System::singleton()->getCache()->flush(); CRM_Extension_System::singleton(TRUE); - CRM_Extension_System::singleton()->getManager()->install(array($params['key'])); + if (CRM_Utils_Array::value('install', $params, TRUE)) { + CRM_Extension_System::singleton()->getManager()->install(array($params['key'])); + } return civicrm_api3_create_success(); } @@ -265,6 +267,12 @@ function _civicrm_api3_extension_download_spec(&$fields) { 'type' => CRM_Utils_Type::T_STRING, 'description' => 'Optional as the system can determine the url automatically for public extensions', ); + $fields['install'] = array( + 'title' => 'Auto-install', + 'type' => CRM_Utils_Type::T_STRING, + 'description' => 'Automatically install the downloaded extension', + 'api.default' => TRUE, + ); } /** diff --git a/civicrm/api/v3/GroupContact.php b/civicrm/api/v3/GroupContact.php index 50378c1d96..53f055e82b 100644 --- a/civicrm/api/v3/GroupContact.php +++ b/civicrm/api/v3/GroupContact.php @@ -148,17 +148,17 @@ function civicrm_api3_group_contact_create($params) { function civicrm_api3_group_contact_delete($params) { $checkParams = $params; if (!empty($checkParams['status']) && in_array($checkParams['status'], array('Removed', 'Deleted'))) { - $checkParams['status'] = 'Added'; + $checkParams['status'] = array('IN' => array('Added', 'Pending')); } elseif (!empty($checkParams['status']) && $checkParams['status'] == 'Added') { - $checkParams['status'] = 'Removed'; + $checkParams['status'] = array('IN' => array('Pending', 'Removed')); } elseif (!empty($checkParams['status'])) { unset($checkParams['status']); } $groupContact = civicrm_api3('GroupContact', 'get', $checkParams); if ($groupContact['count'] == 0 && !empty($params['skip_undelete'])) { - $checkParams['status'] = 'removed'; + $checkParams['status'] = array('IN' => array('Removed', 'Pending')); } $groupContact2 = civicrm_api3('GroupContact', 'get', $checkParams); if ($groupContact['count'] == 0 && $groupContact2['count'] == 0) { diff --git a/civicrm/api/v3/Job.php b/civicrm/api/v3/Job.php index 381ce17665..89f4fb0d3b 100644 --- a/civicrm/api/v3/Job.php +++ b/civicrm/api/v3/Job.php @@ -390,7 +390,7 @@ function civicrm_api3_job_fetch_activities($params) { } catch (Exception $e) { $lock->release(); - return civicrm_api3_create_error('Process Activities failed'); + return civicrm_api3_create_error($e->getMessage()); } } @@ -487,11 +487,9 @@ function civicrm_api3_job_process_batch_merge($params) { )); } $gid = CRM_Utils_Array::value('gid', $params); - $mode = CRM_Utils_Array::value('mode', $params, 'safe'); - $autoFlip = CRM_Utils_Array::value('auto_flip', $params, TRUE); - $result = CRM_Dedupe_Merger::batchMerge($rule_group_id, $gid, $mode, $autoFlip, 1, 2, CRM_Utils_Array::value('criteria', $params, array()), CRM_Utils_Array::value('check_permissions', $params)); + $result = CRM_Dedupe_Merger::batchMerge($rule_group_id, $gid, $mode, 1, 2, CRM_Utils_Array::value('criteria', $params, array()), CRM_Utils_Array::value('check_permissions', $params)); return civicrm_api3_create_success($result, $params); } diff --git a/civicrm/api/v3/Logging.php b/civicrm/api/v3/Logging.php index c1a9010a77..3287b8794f 100644 --- a/civicrm/api/v3/Logging.php +++ b/civicrm/api/v3/Logging.php @@ -44,7 +44,8 @@ function civicrm_api3_logging_revert($params) { $schema = new CRM_Logging_Schema(); $reverter = new CRM_Logging_Reverter($params['log_conn_id'], CRM_Utils_Array::value('log_date', $params)); - $reverter->calculateDiffsFromLogConnAndDate($schema->getLogTablesForContact()); + $tables = !empty($params['tables']) ? (array) $params['tables'] : $schema->getLogTablesForContact(); + $reverter->calculateDiffsFromLogConnAndDate($tables); $reverter->revert(); return civicrm_api3_create_success(1); } @@ -73,6 +74,12 @@ function _civicrm_api3_logging_revert_spec(&$params) { 'api.default' => '10 SECOND', 'description' => ts('Used when log_date is passed in'), ); + + $params['tables'] = array( + 'title' => ts('Tables to revert'), + 'type' => CRM_Utils_Type::T_STRING, + 'description' => ts('Tables to revert, if not set all contact-referring entities will be reverted'), + ); } /** @@ -89,7 +96,8 @@ function civicrm_api3_logging_get($params) { $schema = new CRM_Logging_Schema(); $interval = (empty($params['log_date'])) ? NULL : $params['interval']; $differ = new CRM_Logging_Differ($params['log_conn_id'], CRM_Utils_Array::value('log_date', $params), $interval); - return civicrm_api3_create_success($differ->getAllChangesForConnection($schema->getLogTablesForContact())); + $tables = !empty($params['tables']) ? (array) $params['tables'] : $schema->getLogTablesForContact(); + return civicrm_api3_create_success($differ->getAllChangesForConnection($tables)); } /** @@ -116,4 +124,9 @@ function _civicrm_api3_logging_get_spec(&$params) { 'api.default' => '10 SECOND', 'description' => ts('Used when log_date is passed in'), ); + $params['tables'] = array( + 'title' => ts('Tables to query'), + 'type' => CRM_Utils_Type::T_STRING, + 'description' => ts('Tables to query, if not set all contact-referring entities will be queried'), + ); } diff --git a/civicrm/api/v3/MailingGroup.php b/civicrm/api/v3/MailingGroup.php index 0dbac4513f..9a7a6ef67a 100644 --- a/civicrm/api/v3/MailingGroup.php +++ b/civicrm/api/v3/MailingGroup.php @@ -40,7 +40,13 @@ * to indicate this entire api entity is deprecated */ function _civicrm_api3_mailing_group_deprecation() { - return 'The MailingGroup api is deprecated. Use the mailing_event apis instead.'; + $message = 'This action is deprecated. Use the mailing_event API instead.'; + return array( + 'event_unsubscribe' => $message, + 'event_domain_unsubscribe' => $message, + 'event_resubscribe' => $message, + 'event_subscribe' => $message, + ); } /** diff --git a/civicrm/api/v3/MembershipType.php b/civicrm/api/v3/MembershipType.php index d1db1fec13..a8b29405c5 100644 --- a/civicrm/api/v3/MembershipType.php +++ b/civicrm/api/v3/MembershipType.php @@ -66,6 +66,7 @@ function _civicrm_api3_membership_type_create_spec(&$params) { $params['name']['api.required'] = 1; $params['duration_unit']['api.required'] = 1; $params['duration_interval']['api.required'] = 1; + $params['period_type']['api.required'] = 1; $params['is_active']['api.default'] = 1; } diff --git a/civicrm/api/v3/PriceSet.php b/civicrm/api/v3/PriceSet.php index b31ced3848..b7b15e6019 100644 --- a/civicrm/api/v3/PriceSet.php +++ b/civicrm/api/v3/PriceSet.php @@ -91,9 +91,11 @@ function civicrm_api3_price_set_get($params) { return _civicrm_api3_basic_get(_civicrm_api3_get_BAO(__FUNCTION__), $params); } $result = _civicrm_api3_basic_get(_civicrm_api3_get_BAO(__FUNCTION__), $params, FALSE); - // Fetch associated entities - foreach ($result as &$item) { - $item['entity'] = CRM_Price_BAO_PriceSet::getUsedBy($item['id'], 'entity'); + // Fetch associated entities if the return has not been previously limited. + if (!isset($params['return'])) { + foreach ($result as &$item) { + $item['entity'] = CRM_Price_BAO_PriceSet::getUsedBy($item['id'], 'entity'); + } } return civicrm_api3_create_success($result, $params); } diff --git a/civicrm/api/v3/Profile.php b/civicrm/api/v3/Profile.php index c948d7a378..7a0e431751 100644 --- a/civicrm/api/v3/Profile.php +++ b/civicrm/api/v3/Profile.php @@ -657,7 +657,7 @@ function _civicrm_api3_map_profile_fields_to_entity(&$field) { 'total_amount' => 'contribution', 'receive_date' => 'contribution', 'payment_instrument' => 'contribution', - 'check_number' => 'contribution', + 'contribution_check_number' => 'contribution', 'contribution_status_id' => 'contribution', 'soft_credit' => 'contribution', 'soft_credit_type' => 'contribution_soft', diff --git a/civicrm/api/v3/examples/Activity/ContactRefCustomField.php b/civicrm/api/v3/examples/Activity/ContactRefCustomField.php index adf4230f13..b830541308 100644 --- a/civicrm/api/v3/examples/Activity/ContactRefCustomField.php +++ b/civicrm/api/v3/examples/Activity/ContactRefCustomField.php @@ -10,7 +10,7 @@ function activity_create_example() { $params = array( 'source_contact_id' => 1, - 'activity_type_id' => '51', + 'activity_type_id' => '55', 'subject' => 'test activity type id', 'activity_date_time' => '2011-06-02 14:36:13', 'status_id' => 2, @@ -57,7 +57,7 @@ function activity_create_expectedresult() { '1' => array( 'id' => '1', 'source_record_id' => '', - 'activity_type_id' => '51', + 'activity_type_id' => '55', 'subject' => 'test activity type id', 'activity_date_time' => '20110602143613', 'duration' => '120', diff --git a/civicrm/api/v3/examples/Activity/ContactRefCustomFieldGet.php b/civicrm/api/v3/examples/Activity/ContactRefCustomFieldGet.php index 6cd8188ccb..8603caf946 100644 --- a/civicrm/api/v3/examples/Activity/ContactRefCustomFieldGet.php +++ b/civicrm/api/v3/examples/Activity/ContactRefCustomFieldGet.php @@ -48,7 +48,7 @@ function activity_get_expectedresult() { 'values' => array( '1' => array( 'id' => '1', - 'activity_type_id' => '51', + 'activity_type_id' => '55', 'subject' => 'test activity type id', 'activity_date_time' => '2011-06-02 14:36:13', 'duration' => '120', @@ -60,13 +60,14 @@ function activity_get_expectedresult() { 'is_auto' => 0, 'is_current_revision' => '1', 'is_deleted' => 0, - 'source_contact_id' => '1', + 'is_star' => 0, 'custom_1' => 'defaultValue', - 'custom_1_1' => 'defaultValue', + 'custom_2_id' => '1', 'custom_2' => 'Anderson, Anthony', + 'source_contact_id' => '1', + 'custom_1_1' => 'defaultValue', 'custom_2_1' => 'Anderson, Anthony', 'custom_2_1_id' => '1', - 'custom_2_id' => '1', ), ), ); diff --git a/civicrm/api/v3/examples/Activity/Create.php b/civicrm/api/v3/examples/Activity/Create.php index 6615362918..a380f128d0 100644 --- a/civicrm/api/v3/examples/Activity/Create.php +++ b/civicrm/api/v3/examples/Activity/Create.php @@ -8,7 +8,7 @@ function activity_create_example() { $params = array( 'source_contact_id' => 1, - 'activity_type_id' => '51', + 'activity_type_id' => '55', 'subject' => 'test activity type id', 'activity_date_time' => '2011-06-02 14:36:13', 'status_id' => 2, @@ -55,7 +55,7 @@ function activity_create_expectedresult() { '1' => array( 'id' => '1', 'source_record_id' => '', - 'activity_type_id' => '51', + 'activity_type_id' => '55', 'subject' => 'test activity type id', 'activity_date_time' => '20110602143613', 'duration' => '120', @@ -87,7 +87,7 @@ function activity_create_expectedresult() { /* * This example has been generated from the API test suite. -* The test that created it is called "testActivityCreateCustom" +* The test that created it is called "testActivityCreateCustomSubType" * and can be found at: * https://github.com/civicrm/civicrm-core/blob/master/tests/phpunit/api/v3/ActivityTest.php * diff --git a/civicrm/api/v3/examples/Activity/DateTimeHigh.php b/civicrm/api/v3/examples/Activity/DateTimeHigh.php index 4833a1885b..54d9ace232 100644 --- a/civicrm/api/v3/examples/Activity/DateTimeHigh.php +++ b/civicrm/api/v3/examples/Activity/DateTimeHigh.php @@ -49,7 +49,7 @@ function activity_get_expectedresult() { 'values' => array( '0' => array( 'id' => '1', - 'activity_type_id' => '51', + 'activity_type_id' => '55', 'subject' => 'Make-it-Happen Meeting', 'activity_date_time' => '2011-01-01 00:00:00', 'duration' => '120', diff --git a/civicrm/api/v3/examples/Activity/DateTimeLow.php b/civicrm/api/v3/examples/Activity/DateTimeLow.php index f7052bc2aa..e670e377e2 100644 --- a/civicrm/api/v3/examples/Activity/DateTimeLow.php +++ b/civicrm/api/v3/examples/Activity/DateTimeLow.php @@ -48,7 +48,7 @@ function activity_get_expectedresult() { 'values' => array( '0' => array( 'id' => '2', - 'activity_type_id' => '51', + 'activity_type_id' => '55', 'subject' => 'Make-it-Happen Meeting', 'activity_date_time' => '2012-02-16 00:00:00', 'duration' => '120', diff --git a/civicrm/api/v3/examples/Activity/Get.php b/civicrm/api/v3/examples/Activity/Get.php index ac52fab260..1d98195589 100644 --- a/civicrm/api/v3/examples/Activity/Get.php +++ b/civicrm/api/v3/examples/Activity/Get.php @@ -8,7 +8,7 @@ function activity_get_example() { $params = array( 'contact_id' => 1, - 'activity_type_id' => '51', + 'activity_type_id' => '55', 'sequential' => 1, 'return.custom_1' => 1, ); @@ -49,7 +49,7 @@ function activity_get_expectedresult() { '0' => array( 'source_contact_id' => '1', 'id' => '1', - 'activity_type_id' => '51', + 'activity_type_id' => '55', 'subject' => 'test activity type id', 'location' => 'Pennsylvania', 'activity_date_time' => '2011-06-02 14:36:13', diff --git a/civicrm/api/v3/examples/Activity/GetFields.php b/civicrm/api/v3/examples/Activity/GetFields.php index a6269d125a..76bca1d500 100644 --- a/civicrm/api/v3/examples/Activity/GetFields.php +++ b/civicrm/api/v3/examples/Activity/GetFields.php @@ -47,6 +47,9 @@ function activity_getfields_expectedresult() { 'type' => 1, 'title' => 'Source Record', 'description' => 'Artificial FK to original transaction (e.g. contribution) IF it is not an Activity. Table can be figured out through activity_type_id, and further through component registry.', + 'table_name' => 'civicrm_activity', + 'entity' => 'Activity', + 'bao' => 'CRM_Activity_BAO_Activity', ), 'activity_type_id' => array( 'name' => 'activity_type_id', @@ -59,6 +62,9 @@ function activity_getfields_expectedresult() { 'headerPattern' => '/(activity.)?type(.id$)/i', 'export' => TRUE, 'default' => '1', + 'table_name' => 'civicrm_activity', + 'entity' => 'Activity', + 'bao' => 'CRM_Activity_BAO_Activity', 'html' => array( 'type' => 'Select', 'size' => 6, @@ -78,8 +84,12 @@ function activity_getfields_expectedresult() { 'where' => 'civicrm_activity.activity_date_time', 'headerPattern' => '/(activity.)?date(.time$)?/i', 'export' => TRUE, + 'table_name' => 'civicrm_activity', + 'entity' => 'Activity', + 'bao' => 'CRM_Activity_BAO_Activity', 'html' => array( 'type' => 'Select Date', + 'format' => 'activityDateTime', ), ), 'phone_id' => array( @@ -87,6 +97,9 @@ function activity_getfields_expectedresult() { 'type' => 1, 'title' => 'Phone (called) ID', 'description' => 'Phone ID of the number called (optional - used if an existing phone number is selected).', + 'table_name' => 'civicrm_activity', + 'entity' => 'Activity', + 'bao' => 'CRM_Activity_BAO_Activity', 'FKClassName' => 'CRM_Core_DAO_Phone', 'html' => array( 'type' => 'EntityRef', @@ -102,6 +115,9 @@ function activity_getfields_expectedresult() { 'description' => 'Phone number in case the number does not exist in the civicrm_phone table.', 'maxlength' => 64, 'size' => 30, + 'table_name' => 'civicrm_activity', + 'entity' => 'Activity', + 'bao' => 'CRM_Activity_BAO_Activity', 'html' => array( 'type' => 'Text', 'maxlength' => 64, @@ -113,6 +129,9 @@ function activity_getfields_expectedresult() { 'type' => 1, 'title' => 'Priority', 'description' => 'ID of the priority given to this activity. Foreign key to civicrm_option_value.', + 'table_name' => 'civicrm_activity', + 'entity' => 'Activity', + 'bao' => 'CRM_Activity_BAO_Activity', 'html' => array( 'type' => 'Select', 'size' => 6, @@ -128,6 +147,9 @@ function activity_getfields_expectedresult() { 'type' => 1, 'title' => 'Parent Activity Id', 'description' => 'Parent meeting ID (if this is a follow-up item). This is not currently implemented', + 'table_name' => 'civicrm_activity', + 'entity' => 'Activity', + 'bao' => 'CRM_Activity_BAO_Activity', 'FKClassName' => 'CRM_Activity_DAO_Activity', 'FKApiName' => 'Activity', ), @@ -135,6 +157,9 @@ function activity_getfields_expectedresult() { 'name' => 'is_auto', 'type' => 16, 'title' => 'Auto', + 'table_name' => 'civicrm_activity', + 'entity' => 'Activity', + 'bao' => 'CRM_Activity_BAO_Activity', ), 'relationship_id' => array( 'name' => 'relationship_id', @@ -142,6 +167,9 @@ function activity_getfields_expectedresult() { 'title' => 'Relationship Id', 'description' => 'FK to Relationship ID', 'default' => 'NULL', + 'table_name' => 'civicrm_activity', + 'entity' => 'Activity', + 'bao' => 'CRM_Activity_BAO_Activity', 'FKClassName' => 'CRM_Contact_DAO_Relationship', 'FKApiName' => 'Relationship', ), @@ -154,6 +182,9 @@ function activity_getfields_expectedresult() { 'headerPattern' => '/(is.)?(current.)?(revision|version(ing)?)/i', 'export' => TRUE, 'default' => '1', + 'table_name' => 'civicrm_activity', + 'entity' => 'Activity', + 'bao' => 'CRM_Activity_BAO_Activity', 'html' => array( 'type' => 'CheckBox', ), @@ -163,6 +194,9 @@ function activity_getfields_expectedresult() { 'type' => 1, 'title' => 'Original Activity ID ', 'description' => 'Activity ID of the first activity record in versioning chain.', + 'table_name' => 'civicrm_activity', + 'entity' => 'Activity', + 'bao' => 'CRM_Activity_BAO_Activity', 'FKClassName' => 'CRM_Activity_DAO_Activity', 'FKApiName' => 'Activity', ), @@ -170,6 +204,9 @@ function activity_getfields_expectedresult() { 'name' => 'weight', 'type' => 1, 'title' => 'Order', + 'table_name' => 'civicrm_activity', + 'entity' => 'Activity', + 'bao' => 'CRM_Activity_BAO_Activity', 'html' => array( 'type' => 'Text', 'size' => 6, @@ -185,6 +222,9 @@ function activity_getfields_expectedresult() { 'where' => 'civicrm_activity.is_star', 'headerPattern' => '/(activity.)?(star|favorite)/i', 'export' => TRUE, + 'table_name' => 'civicrm_activity', + 'entity' => 'Activity', + 'bao' => 'CRM_Activity_BAO_Activity', ), 'id' => array( 'name' => 'id', @@ -195,6 +235,9 @@ function activity_getfields_expectedresult() { 'import' => TRUE, 'where' => 'civicrm_activity.id', 'export' => TRUE, + 'table_name' => 'civicrm_activity', + 'entity' => 'Activity', + 'bao' => 'CRM_Activity_BAO_Activity', 'uniqueName' => 'activity_id', 'api.aliases' => array( '0' => 'activity_id', @@ -211,6 +254,9 @@ function activity_getfields_expectedresult() { 'where' => 'civicrm_activity.subject', 'headerPattern' => '/(activity.)?subject/i', 'export' => TRUE, + 'table_name' => 'civicrm_activity', + 'entity' => 'Activity', + 'bao' => 'CRM_Activity_BAO_Activity', 'html' => array( 'type' => 'Text', 'maxlength' => 255, @@ -227,6 +273,9 @@ function activity_getfields_expectedresult() { 'where' => 'civicrm_activity.duration', 'headerPattern' => '/(activity.)?duration(s)?$/i', 'export' => TRUE, + 'table_name' => 'civicrm_activity', + 'entity' => 'Activity', + 'bao' => 'CRM_Activity_BAO_Activity', 'html' => array( 'type' => 'Text', 'size' => 6, @@ -245,6 +294,9 @@ function activity_getfields_expectedresult() { 'where' => 'civicrm_activity.location', 'headerPattern' => '/(activity.)?location$/i', 'export' => TRUE, + 'table_name' => 'civicrm_activity', + 'entity' => 'Activity', + 'bao' => 'CRM_Activity_BAO_Activity', 'html' => array( 'type' => 'Text', 'maxlength' => 255, @@ -261,6 +313,9 @@ function activity_getfields_expectedresult() { 'where' => 'civicrm_activity.details', 'headerPattern' => '/(activity.)?detail(s)?$/i', 'export' => TRUE, + 'table_name' => 'civicrm_activity', + 'entity' => 'Activity', + 'bao' => 'CRM_Activity_BAO_Activity', 'html' => array( 'type' => 'RichTextEditor', 'rows' => 2, @@ -276,6 +331,9 @@ function activity_getfields_expectedresult() { 'import' => TRUE, 'where' => 'civicrm_activity.status_id', 'headerPattern' => '/(activity.)?status(.label$)?/i', + 'table_name' => 'civicrm_activity', + 'entity' => 'Activity', + 'bao' => 'CRM_Activity_BAO_Activity', 'html' => array( 'type' => 'Select', 'size' => 6, @@ -298,6 +356,9 @@ function activity_getfields_expectedresult() { 'where' => 'civicrm_activity.is_test', 'headerPattern' => '/(is.)?test(.activity)?/i', 'export' => TRUE, + 'table_name' => 'civicrm_activity', + 'entity' => 'Activity', + 'bao' => 'CRM_Activity_BAO_Activity', 'html' => array( 'type' => 'Select', ), @@ -309,6 +370,9 @@ function activity_getfields_expectedresult() { 'title' => 'Activity Medium', 'description' => 'Activity Medium, Implicit FK to civicrm_option_value where option_group = encounter_medium.', 'default' => 'NULL', + 'table_name' => 'civicrm_activity', + 'entity' => 'Activity', + 'bao' => 'CRM_Activity_BAO_Activity', 'html' => array( 'type' => 'Select', 'size' => 6, @@ -327,6 +391,9 @@ function activity_getfields_expectedresult() { 'description' => 'Currently being used to store result id for survey activity, FK to option value.', 'maxlength' => 255, 'size' => 45, + 'table_name' => 'civicrm_activity', + 'entity' => 'Activity', + 'bao' => 'CRM_Activity_BAO_Activity', 'html' => array( 'type' => 'Text', 'maxlength' => 255, @@ -342,6 +409,9 @@ function activity_getfields_expectedresult() { 'where' => 'civicrm_activity.is_deleted', 'headerPattern' => '/(activity.)?(trash|deleted)/i', 'export' => TRUE, + 'table_name' => 'civicrm_activity', + 'entity' => 'Activity', + 'bao' => 'CRM_Activity_BAO_Activity', 'html' => array( 'type' => 'Text', ), @@ -355,6 +425,9 @@ function activity_getfields_expectedresult() { 'import' => TRUE, 'where' => 'civicrm_activity.campaign_id', 'export' => TRUE, + 'table_name' => 'civicrm_activity', + 'entity' => 'Activity', + 'bao' => 'CRM_Activity_BAO_Activity', 'FKClassName' => 'CRM_Campaign_DAO_Campaign', 'html' => array( 'type' => 'CheckBox', @@ -377,6 +450,9 @@ function activity_getfields_expectedresult() { 'import' => TRUE, 'where' => 'civicrm_activity.engagement_level', 'export' => TRUE, + 'table_name' => 'civicrm_activity', + 'entity' => 'Activity', + 'bao' => 'CRM_Activity_BAO_Activity', 'html' => array( 'type' => 'Select', 'size' => 6, diff --git a/civicrm/api/v3/examples/Activity/GetTargetandAssigneeName.php b/civicrm/api/v3/examples/Activity/GetTargetandAssigneeName.php index 77b45f7bbb..003b333d37 100644 --- a/civicrm/api/v3/examples/Activity/GetTargetandAssigneeName.php +++ b/civicrm/api/v3/examples/Activity/GetTargetandAssigneeName.php @@ -48,16 +48,18 @@ function activity_getsingle_expectedresult() { $expectedResult = array( 'id' => '1', 'subject' => 'Make-it-Happen Meeting', - 'source_contact_id' => '8', + 'source_contact_id' => '6', 'source_contact_name' => 'D Bug', - 'target_contact_id' => array('5', '6'), + 'target_contact_id' => array( + '1' => '4', + ), 'target_contact_name' => array( - '5' => 'A Cat', - '6' => 'B Good', + '3' => 'A Cat', + '4' => 'B Good', ), - 'assignee_contact_id' => array('7'), + 'assignee_contact_id' => array(), 'assignee_contact_name' => array( - '7' => 'C Shore', + '5' => 'C Shore', ), ); diff --git a/civicrm/api/v3/examples/Activity/ReturnAssigneeContact.php b/civicrm/api/v3/examples/Activity/ReturnAssigneeContact.php index 574a34a7b2..4042c39fff 100644 --- a/civicrm/api/v3/examples/Activity/ReturnAssigneeContact.php +++ b/civicrm/api/v3/examples/Activity/ReturnAssigneeContact.php @@ -52,7 +52,7 @@ function activity_get_expectedresult() { 'values' => array( '0' => array( 'id' => '1', - 'activity_type_id' => '51', + 'activity_type_id' => '55', 'subject' => 'test activity type id', 'activity_date_time' => '2011-06-02 14:36:13', 'duration' => '120', diff --git a/civicrm/api/v3/examples/ActivityType/Create.php b/civicrm/api/v3/examples/ActivityType/Create.php index ac5da5ced8..b3a231503b 100644 --- a/civicrm/api/v3/examples/ActivityType/Create.php +++ b/civicrm/api/v3/examples/ActivityType/Create.php @@ -49,13 +49,13 @@ function activity_type_create_expectedresult() { 'is_error' => 0, 'version' => 3, 'count' => 1, - 'id' => 784, + 'id' => 849, 'values' => array( - '784' => array( - 'id' => '784', + '849' => array( + 'id' => '849', 'option_group_id' => '2', 'label' => 'send out letters', - 'value' => '51', + 'value' => '55', 'name' => 'send out letters', 'grouping' => '', 'filter' => 0, @@ -68,6 +68,8 @@ function activity_type_create_expectedresult() { 'component_id' => '', 'domain_id' => '', 'visibility_id' => '', + 'icon' => '', + 'color' => '', ), ), 'deprecated' => 'The ActivityType api is deprecated. Please use the OptionValue api instead.', diff --git a/civicrm/api/v3/examples/ActivityType/Get.php b/civicrm/api/v3/examples/ActivityType/Get.php index a2158500c1..3befa05035 100644 --- a/civicrm/api/v3/examples/ActivityType/Get.php +++ b/civicrm/api/v3/examples/ActivityType/Get.php @@ -41,7 +41,7 @@ function activity_type_get_expectedresult() { $expectedResult = array( 'is_error' => 0, 'version' => 3, - 'count' => 50, + 'count' => 54, 'values' => array( '1' => 'Meeting', '2' => 'Phone Call', diff --git a/civicrm/api/v3/examples/Constant/Get.php b/civicrm/api/v3/examples/Constant/Get.php index a6c11087a0..561e259a1e 100644 --- a/civicrm/api/v3/examples/Constant/Get.php +++ b/civicrm/api/v3/examples/Constant/Get.php @@ -43,7 +43,7 @@ function constant_get_expectedresult() { $expectedResult = array( 'is_error' => 0, 'version' => 3, - 'count' => 32, + 'count' => 36, 'values' => array( '1' => 'Meeting', '2' => 'Phone Call', diff --git a/civicrm/api/v3/examples/Contact/APIChainedArray.php b/civicrm/api/v3/examples/Contact/APIChainedArray.php index 839b99005e..35f3a002d4 100644 --- a/civicrm/api/v3/examples/Contact/APIChainedArray.php +++ b/civicrm/api/v3/examples/Contact/APIChainedArray.php @@ -10,7 +10,7 @@ */ function contact_get_example() { $params = array( - 'id' => 1, + 'id' => 3, 'api.website.get' => array(), 'api.Contribution.get' => array( 'total_amount' => '120.00', @@ -50,10 +50,10 @@ function contact_get_expectedresult() { 'is_error' => 0, 'version' => 3, 'count' => 1, - 'id' => 1, + 'id' => 3, 'values' => array( - '1' => array( - 'contact_id' => '1', + '3' => array( + 'contact_id' => '3', 'contact_type' => 'Individual', 'contact_sub_type' => '', 'sort_name' => 'xyz3, abc3', @@ -89,8 +89,8 @@ function contact_get_expectedresult() { 'sic_code' => '', 'contact_is_deleted' => 0, 'current_employer' => '', - 'address_id' => '2', - 'street_address' => '1 my road', + 'address_id' => '', + 'street_address' => '', 'supplemental_address_1' => '', 'supplemental_address_2' => '', 'city' => '', @@ -118,7 +118,7 @@ function contact_get_expectedresult() { 'state_province_name' => '', 'state_province' => '', 'country' => '', - 'id' => '1', + 'id' => '3', 'api.website.get' => array( 'is_error' => 0, 'version' => 3, @@ -127,7 +127,7 @@ function contact_get_expectedresult() { 'values' => array( '0' => array( 'id' => '1', - 'contact_id' => '1', + 'contact_id' => '3', 'url' => 'http://civicrm.org', ), ), @@ -139,7 +139,7 @@ function contact_get_expectedresult() { 'id' => 2, 'values' => array( '0' => array( - 'contact_id' => '1', + 'contact_id' => '3', 'contact_type' => 'Individual', 'contact_sub_type' => '', 'sort_name' => 'xyz3, abc3', @@ -159,10 +159,11 @@ function contact_get_expectedresult() { 'thankyou_date' => '', 'contribution_source' => 'SSF', 'amount_level' => '', + 'contribution_recur_id' => '', 'is_test' => 0, 'is_pay_later' => 0, 'contribution_status_id' => '1', - 'check_number' => '', + 'contribution_check_number' => '', 'contribution_campaign_id' => '', 'financial_type_id' => '1', 'financial_type' => 'Donation', @@ -174,16 +175,17 @@ function contact_get_expectedresult() { 'fulfilled_date' => '', 'contribution_start_date' => '', 'contribution_end_date' => '', - 'contribution_recur_id' => '', 'financial_account_id' => '1', 'accounting_code' => '4200', + 'campaign_id' => '', + 'contribution_campaign_title' => '', 'contribution_note' => '', 'contribution_batch' => '', 'contribution_status' => 'Completed', 'payment_instrument' => 'Credit Card', 'payment_instrument_id' => '1', 'instrument_id' => '1', - 'contribution_check_number' => '', + 'check_number' => '', 'id' => '2', 'contribution_type_id' => '1', ), diff --git a/civicrm/api/v3/examples/Contact/APIChainedArrayFormats.php b/civicrm/api/v3/examples/Contact/APIChainedArrayFormats.php index c79c27a426..5145682730 100644 --- a/civicrm/api/v3/examples/Contact/APIChainedArrayFormats.php +++ b/civicrm/api/v3/examples/Contact/APIChainedArrayFormats.php @@ -10,7 +10,7 @@ */ function contact_get_example() { $params = array( - 'id' => 1, + 'id' => 3, 'api.website.getValue' => array( 'return' => 'url', ), @@ -51,10 +51,10 @@ function contact_get_expectedresult() { 'is_error' => 0, 'version' => 3, 'count' => 1, - 'id' => 1, + 'id' => 3, 'values' => array( - '1' => array( - 'contact_id' => '1', + '3' => array( + 'contact_id' => '3', 'contact_type' => 'Individual', 'contact_sub_type' => '', 'sort_name' => 'xyz3, abc3', @@ -90,8 +90,8 @@ function contact_get_expectedresult() { 'sic_code' => '', 'contact_is_deleted' => 0, 'current_employer' => '', - 'address_id' => '2', - 'street_address' => '1 my road', + 'address_id' => '', + 'street_address' => '', 'supplemental_address_1' => '', 'supplemental_address_2' => '', 'city' => '', @@ -119,7 +119,7 @@ function contact_get_expectedresult() { 'state_province_name' => '', 'state_province' => '', 'country' => '', - 'id' => '1', + 'id' => '3', 'api.website.getValue' => 'http://civicrm.org', 'api.Contribution.getCount' => 2, 'api.CustomValue.get' => array( diff --git a/civicrm/api/v3/examples/Contact/APIChainedArrayMultipleCustom.php b/civicrm/api/v3/examples/Contact/APIChainedArrayMultipleCustom.php index c484a896c6..d9d6b8f49e 100644 --- a/civicrm/api/v3/examples/Contact/APIChainedArrayMultipleCustom.php +++ b/civicrm/api/v3/examples/Contact/APIChainedArrayMultipleCustom.php @@ -9,7 +9,7 @@ */ function contact_get_example() { $params = array( - 'id' => 1, + 'id' => 3, 'api.website.getValue' => array( 'return' => 'url', ), @@ -48,10 +48,10 @@ function contact_get_expectedresult() { 'is_error' => 0, 'version' => 3, 'count' => 1, - 'id' => 1, + 'id' => 3, 'values' => array( - '1' => array( - 'contact_id' => '1', + '3' => array( + 'contact_id' => '3', 'contact_type' => 'Individual', 'contact_sub_type' => '', 'sort_name' => 'xyz3, abc3', @@ -87,8 +87,8 @@ function contact_get_expectedresult() { 'sic_code' => '', 'contact_is_deleted' => 0, 'current_employer' => '', - 'address_id' => '2', - 'street_address' => '1 my road', + 'address_id' => '', + 'street_address' => '', 'supplemental_address_1' => '', 'supplemental_address_2' => '', 'city' => '', @@ -116,59 +116,61 @@ function contact_get_expectedresult() { 'state_province_name' => '', 'state_province' => '', 'country' => '', - 'id' => '1', + 'id' => '3', 'api.website.getValue' => 'http://civicrm.org', 'api.Contribution.getCount' => 2, 'api.CustomValue.get' => array( 'is_error' => 0, 'version' => 3, - 'count' => 8, + 'count' => 7, 'values' => array( '0' => array( - 'entity_id' => '1', + 'entity_id' => '3', + 'entity_table' => 'Contact', 'latest' => 'value 4', 'id' => '1', - 'entity_table' => 'Contact', ), '1' => array( + 'entity_id' => '3', 'entity_table' => 'Contact', - ), - '2' => array( - 'entity_id' => '1', 'latest' => 'value 3', 'id' => '2', '1' => 'value 2', - 'entity_table' => 'Contact', '2' => 'value 3', ), - '3' => array( - 'entity_id' => '1', + '2' => array( + 'entity_id' => '3', + 'entity_table' => 'Contact', 'latest' => '', 'id' => '3', '1' => 'warm beer', '2' => '', ), - '4' => array( - 'entity_id' => '1', + '3' => array( + 'entity_id' => '3', + 'entity_table' => 'Contact', 'latest' => '', 'id' => '4', '1' => '', '2' => '', ), - '5' => array( - 'entity_id' => '1', + '4' => array( + 'entity_id' => '3', + 'entity_table' => 'Contact', 'latest' => 'defaultValue', 'id' => '5', '1' => 'defaultValue', ), - '6' => array( - 'entity_id' => '1', + '5' => array( + 'entity_id' => '3', + 'entity_table' => 'Contact', 'latest' => 'vegemite', 'id' => '6', '1' => 'vegemite', ), - '7' => array( - 'entity_id' => '1', + '6' => array( + 'entity_id' => '3', + 'entity_table' => 'Contact', 'latest' => '', 'id' => '7', '1' => '', diff --git a/civicrm/api/v3/examples/Contact/APIChainedArrayValuesFromSiblingFunction.php b/civicrm/api/v3/examples/Contact/APIChainedArrayValuesFromSiblingFunction.php index a1b3a68db3..6bca265586 100644 --- a/civicrm/api/v3/examples/Contact/APIChainedArrayValuesFromSiblingFunction.php +++ b/civicrm/api/v3/examples/Contact/APIChainedArrayValuesFromSiblingFunction.php @@ -53,10 +53,10 @@ function contact_create_expectedresult() { 'is_error' => 0, 'version' => 3, 'count' => 1, - 'id' => 1, + 'id' => 3, 'values' => array( - '1' => array( - 'id' => '1', + '3' => array( + 'id' => '3', 'contact_type' => 'Individual', 'contact_sub_type' => '', 'do_not_email' => 0, diff --git a/civicrm/api/v3/examples/Contact/ChainTwoWebsites.php b/civicrm/api/v3/examples/Contact/ChainTwoWebsites.php index 8d2a4d3ff5..0c1f887ed4 100644 --- a/civicrm/api/v3/examples/Contact/ChainTwoWebsites.php +++ b/civicrm/api/v3/examples/Contact/ChainTwoWebsites.php @@ -65,10 +65,10 @@ function contact_create_expectedresult() { 'is_error' => 0, 'version' => 3, 'count' => 1, - 'id' => 1, + 'id' => 3, 'values' => array( - '1' => array( - 'id' => '1', + '3' => array( + 'id' => '3', 'contact_type' => 'Individual', 'contact_sub_type' => '', 'do_not_email' => 0, @@ -125,7 +125,7 @@ function contact_create_expectedresult() { 'values' => array( '0' => array( 'id' => '1', - 'contact_id' => '1', + 'contact_id' => '3', 'financial_type_id' => '1', 'contribution_page_id' => '', 'payment_instrument_id' => '1', @@ -165,7 +165,7 @@ function contact_create_expectedresult() { 'values' => array( '0' => array( 'id' => '1', - 'contact_id' => '1', + 'contact_id' => '3', 'url' => 'http://civicrm.org', 'website_type_id' => '', ), @@ -179,7 +179,7 @@ function contact_create_expectedresult() { 'values' => array( '0' => array( 'id' => '2', - 'contact_id' => '1', + 'contact_id' => '3', 'url' => 'http://chained.org', 'website_type_id' => '', ), diff --git a/civicrm/api/v3/examples/Contact/ChainTwoWebsitesSyntax2.php b/civicrm/api/v3/examples/Contact/ChainTwoWebsitesSyntax2.php index 99e6a75588..f6ae673091 100644 --- a/civicrm/api/v3/examples/Contact/ChainTwoWebsitesSyntax2.php +++ b/civicrm/api/v3/examples/Contact/ChainTwoWebsitesSyntax2.php @@ -68,10 +68,10 @@ function contact_create_expectedresult() { 'is_error' => 0, 'version' => 3, 'count' => 1, - 'id' => 1, + 'id' => 3, 'values' => array( - '1' => array( - 'id' => '1', + '3' => array( + 'id' => '3', 'contact_type' => 'Individual', 'contact_sub_type' => '', 'do_not_email' => 0, @@ -128,7 +128,7 @@ function contact_create_expectedresult() { 'values' => array( '0' => array( 'id' => '1', - 'contact_id' => '1', + 'contact_id' => '3', 'financial_type_id' => '1', 'contribution_page_id' => '', 'payment_instrument_id' => '1', @@ -169,7 +169,7 @@ function contact_create_expectedresult() { 'values' => array( '0' => array( 'id' => '1', - 'contact_id' => '1', + 'contact_id' => '3', 'url' => 'http://civicrm.org', 'website_type_id' => '', ), @@ -183,7 +183,7 @@ function contact_create_expectedresult() { 'values' => array( '0' => array( 'id' => '2', - 'contact_id' => '1', + 'contact_id' => '3', 'url' => 'http://chained.org', 'website_type_id' => '2', ), diff --git a/civicrm/api/v3/examples/Contact/Create.php b/civicrm/api/v3/examples/Contact/Create.php index 9e0392a4dc..107c95ded3 100644 --- a/civicrm/api/v3/examples/Contact/Create.php +++ b/civicrm/api/v3/examples/Contact/Create.php @@ -46,10 +46,10 @@ function contact_create_expectedresult() { 'is_error' => 0, 'version' => 3, 'count' => 1, - 'id' => 1, + 'id' => 3, 'values' => array( - '1' => array( - 'id' => '1', + '3' => array( + 'id' => '3', 'contact_type' => 'Individual', 'contact_sub_type' => '', 'do_not_email' => 0, diff --git a/civicrm/api/v3/examples/Contact/CreateParticipantPayment.php b/civicrm/api/v3/examples/Contact/CreateParticipantPayment.php index 80021fa595..7a66c4277b 100644 --- a/civicrm/api/v3/examples/Contact/CreateParticipantPayment.php +++ b/civicrm/api/v3/examples/Contact/CreateParticipantPayment.php @@ -13,7 +13,7 @@ function contact_create_example() { 'contact_type' => 'Individual', 'display_name' => 'dlobo', 'api.participant' => array( - 'event_id' => 40, + 'event_id' => 42, 'status_id' => 1, 'role_id' => 1, 'format.only_id' => 1, @@ -38,7 +38,8 @@ function contact_create_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); @@ -73,7 +74,7 @@ function contact_create_expectedresult() { 'is_opt_out' => 0, 'legal_identifier' => '', 'external_identifier' => '', - 'sort_name' => '', + 'sort_name' => 'dlobo', 'display_name' => 'dlobo', 'nick_name' => '', 'legal_name' => '', diff --git a/civicrm/api/v3/examples/Contact/CustomFieldGet.php b/civicrm/api/v3/examples/Contact/CustomFieldGet.php index ac3e7b3ab6..07e8ae1e6e 100644 --- a/civicrm/api/v3/examples/Contact/CustomFieldGet.php +++ b/civicrm/api/v3/examples/Contact/CustomFieldGet.php @@ -10,7 +10,7 @@ function contact_get_example() { $params = array( 'return.custom_1' => 1, - 'id' => 1, + 'id' => 3, ); try{ @@ -44,13 +44,13 @@ function contact_get_expectedresult() { 'is_error' => 0, 'version' => 3, 'count' => 1, - 'id' => 1, + 'id' => 3, 'values' => array( - '1' => array( - 'contact_id' => '1', + '3' => array( + 'contact_id' => '3', 'civicrm_value_testgetwithcu_1_id' => '1', 'custom_1' => 'custom string', - 'id' => '1', + 'id' => '3', ), ), ); diff --git a/civicrm/api/v3/examples/Contact/CustomFieldGetReturnSyntaxVariation.php b/civicrm/api/v3/examples/Contact/CustomFieldGetReturnSyntaxVariation.php index d5ac755842..c1e47702bf 100644 --- a/civicrm/api/v3/examples/Contact/CustomFieldGetReturnSyntaxVariation.php +++ b/civicrm/api/v3/examples/Contact/CustomFieldGetReturnSyntaxVariation.php @@ -10,7 +10,7 @@ function contact_get_example() { $params = array( 'return' => 'custom_1', - 'id' => 1, + 'id' => 3, ); try{ @@ -44,13 +44,13 @@ function contact_get_expectedresult() { 'is_error' => 0, 'version' => 3, 'count' => 1, - 'id' => 1, + 'id' => 3, 'values' => array( - '1' => array( - 'contact_id' => '1', + '3' => array( + 'contact_id' => '3', 'civicrm_value_testgetwithcu_1_id' => '1', 'custom_1' => 'custom string', - 'id' => '1', + 'id' => '3', ), ), ); diff --git a/civicrm/api/v3/examples/Contact/Delete.php b/civicrm/api/v3/examples/Contact/Delete.php index bfb4f9976e..1bb7f83feb 100644 --- a/civicrm/api/v3/examples/Contact/Delete.php +++ b/civicrm/api/v3/examples/Contact/Delete.php @@ -7,7 +7,7 @@ */ function contact_delete_example() { $params = array( - 'id' => 1, + 'id' => 3, ); try{ diff --git a/civicrm/api/v3/examples/Contact/Get.php b/civicrm/api/v3/examples/Contact/Get.php index fb2556c9f4..9f666711fc 100644 --- a/civicrm/api/v3/examples/Contact/Get.php +++ b/civicrm/api/v3/examples/Contact/Get.php @@ -41,10 +41,10 @@ function contact_get_expectedresult() { 'is_error' => 0, 'version' => 3, 'count' => 1, - 'id' => 1, + 'id' => 3, 'values' => array( - '1' => array( - 'contact_id' => '1', + '3' => array( + 'contact_id' => '3', 'contact_type' => 'Individual', 'contact_sub_type' => '', 'sort_name' => 'man2@yahoo.com', @@ -80,8 +80,8 @@ function contact_get_expectedresult() { 'sic_code' => '', 'contact_is_deleted' => 0, 'current_employer' => '', - 'address_id' => '2', - 'street_address' => '1 my road', + 'address_id' => '', + 'street_address' => '', 'supplemental_address_1' => '', 'supplemental_address_2' => '', 'city' => '', @@ -109,7 +109,7 @@ function contact_get_expectedresult() { 'state_province_name' => '', 'state_province' => '', 'country' => '', - 'id' => '1', + 'id' => '3', ), ), ); diff --git a/civicrm/api/v3/examples/Contact/GetActions.php b/civicrm/api/v3/examples/Contact/GetActions.php index d2c85713ed..585e5e8dca 100644 --- a/civicrm/api/v3/examples/Contact/GetActions.php +++ b/civicrm/api/v3/examples/Contact/GetActions.php @@ -40,33 +40,28 @@ function contact_getactions_expectedresult() { $expectedResult = array( 'is_error' => 0, 'version' => 3, - 'count' => 25, + 'count' => 20, 'values' => array( '0' => 'create', '1' => 'delete', '2' => 'duplicatecheck', - '3' => 'example_action1', - '4' => 'example_action2', - '5' => 'get', - '6' => 'getactions', - '7' => 'getcount', - '8' => 'getfield', - '9' => 'getfields', - '10' => 'getlist', - '11' => 'getoptions', - '12' => 'getquick', - '13' => 'getrefcount', - '14' => 'getsingle', - '15' => 'getvalue', - '16' => 'merge', - '17' => 'proximity', - '18' => 'replace', - '19' => 'setvalue', - '20' => 'type_create', - '21' => 'type_delete', - '22' => 'type_get', - '23' => 'update', - '24' => 'validate', + '3' => 'get', + '4' => 'getactions', + '5' => 'getcount', + '6' => 'getfield', + '7' => 'getfields', + '8' => 'getlist', + '9' => 'getoptions', + '10' => 'getquick', + '11' => 'getrefcount', + '12' => 'getsingle', + '13' => 'getvalue', + '14' => 'merge', + '15' => 'proximity', + '16' => 'replace', + '17' => 'setvalue', + '18' => 'update', + '19' => 'validate', ), 'deprecated' => array( 'getquick' => 'The "getquick" action is deprecated in favor of "getlist".', diff --git a/civicrm/api/v3/examples/Contact/GetFieldsOptions.php b/civicrm/api/v3/examples/Contact/GetFieldsOptions.php index a366b40958..57972c5252 100644 --- a/civicrm/api/v3/examples/Contact/GetFieldsOptions.php +++ b/civicrm/api/v3/examples/Contact/GetFieldsOptions.php @@ -57,6 +57,9 @@ function contact_getfields_expectedresult() { 'where' => 'civicrm_contact.id', 'headerPattern' => '/internal|contact?|id$/i', 'export' => TRUE, + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', 'api.aliases' => array( '0' => 'contact_id', ), @@ -70,6 +73,9 @@ function contact_getfields_expectedresult() { 'size' => 30, 'export' => TRUE, 'where' => 'civicrm_contact.contact_type', + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', 'html' => array( 'type' => 'Select', 'maxlength' => 64, @@ -94,6 +100,9 @@ function contact_getfields_expectedresult() { 'where' => 'civicrm_contact.contact_sub_type', 'headerPattern' => '/C(ontact )?(subtype|sub-type|sub type)/i', 'export' => TRUE, + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', 'html' => array( 'type' => 'Select', 'maxlength' => 255, @@ -115,6 +124,9 @@ function contact_getfields_expectedresult() { 'headerPattern' => '/d(o )?(not )?(email)/i', 'dataPattern' => '/^\\d{1,}$/', 'export' => TRUE, + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', 'html' => array( 'type' => 'CheckBox', ), @@ -128,6 +140,9 @@ function contact_getfields_expectedresult() { 'headerPattern' => '/d(o )?(not )?(call|phone)/i', 'dataPattern' => '/^\\d{1,}$/', 'export' => TRUE, + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', 'html' => array( 'type' => 'CheckBox', ), @@ -141,6 +156,9 @@ function contact_getfields_expectedresult() { 'headerPattern' => '/^(d(o\\s)?n(ot\\s)?mail)|(\\w*)?bulk\\s?(\\w*)$/i', 'dataPattern' => '/^\\d{1,}$/', 'export' => TRUE, + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', 'html' => array( 'type' => 'CheckBox', ), @@ -154,6 +172,9 @@ function contact_getfields_expectedresult() { 'headerPattern' => '/d(o )?(not )?(sms)/i', 'dataPattern' => '/^\\d{1,}$/', 'export' => TRUE, + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', 'html' => array( 'type' => 'CheckBox', ), @@ -167,6 +188,9 @@ function contact_getfields_expectedresult() { 'headerPattern' => '/d(o )?(not )?(trade)/i', 'dataPattern' => '/^\\d{1,}$/', 'export' => TRUE, + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', 'html' => array( 'type' => 'CheckBox', ), @@ -180,6 +204,9 @@ function contact_getfields_expectedresult() { 'import' => TRUE, 'where' => 'civicrm_contact.is_opt_out', 'export' => TRUE, + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', 'html' => array( 'type' => 'CheckBox', ), @@ -197,6 +224,9 @@ function contact_getfields_expectedresult() { 'headerPattern' => '/legal\\s?id/i', 'dataPattern' => '/\\w+?\\d{5,}/', 'export' => TRUE, + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', 'html' => array( 'type' => 'Text', 'maxlength' => 32, @@ -215,6 +245,9 @@ function contact_getfields_expectedresult() { 'headerPattern' => '/external\\s?id/i', 'dataPattern' => '/^\\d{11,}$/', 'export' => TRUE, + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', 'html' => array( 'type' => 'Text', 'maxlength' => 64, @@ -230,6 +263,9 @@ function contact_getfields_expectedresult() { 'size' => 30, 'export' => TRUE, 'where' => 'civicrm_contact.sort_name', + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', 'html' => array( 'type' => 'Text', 'maxlength' => 128, @@ -245,6 +281,9 @@ function contact_getfields_expectedresult() { 'size' => 30, 'export' => TRUE, 'where' => 'civicrm_contact.display_name', + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', 'html' => array( 'type' => 'Text', 'maxlength' => 128, @@ -263,6 +302,9 @@ function contact_getfields_expectedresult() { 'headerPattern' => '/n(ick\\s)name|nick$/i', 'dataPattern' => '/^\\w+$/', 'export' => TRUE, + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', 'html' => array( 'type' => 'Text', 'maxlength' => 128, @@ -280,6 +322,9 @@ function contact_getfields_expectedresult() { 'where' => 'civicrm_contact.legal_name', 'headerPattern' => '/^legal|(l(egal\\s)?name)$/i', 'export' => TRUE, + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', 'html' => array( 'type' => 'Text', 'maxlength' => 128, @@ -294,6 +339,9 @@ function contact_getfields_expectedresult() { 'import' => TRUE, 'where' => 'civicrm_contact.image_URL', 'export' => TRUE, + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', 'html' => array( 'type' => 'File', 'rows' => 2, @@ -312,6 +360,9 @@ function contact_getfields_expectedresult() { 'headerPattern' => '/^p(ref\\w*\\s)?c(omm\\w*)|( meth\\w*)$/i', 'dataPattern' => '/^\\w+$/', 'export' => TRUE, + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', 'html' => array( 'type' => 'Select', 'maxlength' => 255, @@ -333,6 +384,9 @@ function contact_getfields_expectedresult() { 'where' => 'civicrm_contact.preferred_language', 'headerPattern' => '/^lang/i', 'export' => TRUE, + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', 'html' => array( 'type' => 'Select', 'maxlength' => 5, @@ -356,6 +410,9 @@ function contact_getfields_expectedresult() { 'headerPattern' => '/^p(ref\\w*\\s)?m(ail\\s)?f(orm\\w*)$/i', 'export' => TRUE, 'default' => 'Both', + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', 'html' => array( 'type' => 'Select', 'maxlength' => 8, @@ -374,6 +431,9 @@ function contact_getfields_expectedresult() { 'size' => 20, 'export' => TRUE, 'where' => 'civicrm_contact.hash', + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', ), 'api_key' => array( 'name' => 'api_key', @@ -382,6 +442,9 @@ function contact_getfields_expectedresult() { 'description' => 'API Key for validating requests related to this contact.', 'maxlength' => 32, 'size' => 20, + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', ), 'first_name' => array( 'name' => 'first_name', @@ -395,6 +458,9 @@ function contact_getfields_expectedresult() { 'headerPattern' => '/^first|(f(irst\\s)?name)$/i', 'dataPattern' => '/^\\w+$/', 'export' => TRUE, + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', 'html' => array( 'type' => 'Text', 'maxlength' => 64, @@ -413,6 +479,9 @@ function contact_getfields_expectedresult() { 'headerPattern' => '/^middle|(m(iddle\\s)?name)$/i', 'dataPattern' => '/^\\w+$/', 'export' => TRUE, + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', 'html' => array( 'type' => 'Text', 'maxlength' => 64, @@ -431,6 +500,9 @@ function contact_getfields_expectedresult() { 'headerPattern' => '/^last|(l(ast\\s)?name)$/i', 'dataPattern' => '/^\\w+(\\s\\w+)?+$/', 'export' => TRUE, + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', 'html' => array( 'type' => 'Text', 'maxlength' => 64, @@ -447,6 +519,9 @@ function contact_getfields_expectedresult() { 'headerPattern' => '/^(prefix|title)/i', 'dataPattern' => '/^(mr|ms|mrs|sir|dr)\\.?$/i', 'export' => TRUE, + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', 'html' => array( 'type' => 'Select', 'size' => 6, @@ -471,6 +546,9 @@ function contact_getfields_expectedresult() { 'headerPattern' => '/^suffix$/i', 'dataPattern' => '/^(sr|jr)\\.?|i{2,}$/', 'export' => TRUE, + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', 'html' => array( 'type' => 'Select', 'size' => 6, @@ -496,6 +574,9 @@ function contact_getfields_expectedresult() { 'where' => 'civicrm_contact.formal_title', 'headerPattern' => '/^title/i', 'export' => TRUE, + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', 'html' => array( 'type' => 'Text', 'maxlength' => 64, @@ -509,6 +590,9 @@ function contact_getfields_expectedresult() { 'description' => 'Communication style (e.g. formal vs. familiar) to use with this contact. FK to communication styles in civicrm_option_value.', 'export' => TRUE, 'where' => 'civicrm_contact.communication_style_id', + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', 'html' => array( 'type' => 'Select', 'size' => 6, @@ -524,6 +608,9 @@ function contact_getfields_expectedresult() { 'type' => 1, 'title' => 'Email Greeting ID', 'description' => 'FK to civicrm_option_value.id, that has to be valid registered Email Greeting.', + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', ), 'email_greeting_custom' => array( 'name' => 'email_greeting_custom', @@ -534,6 +621,9 @@ function contact_getfields_expectedresult() { 'size' => 45, 'import' => TRUE, 'where' => 'civicrm_contact.email_greeting_custom', + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', 'html' => array( 'type' => 'Text', 'maxlength' => 128, @@ -547,6 +637,9 @@ function contact_getfields_expectedresult() { 'description' => 'Cache Email Greeting.', 'maxlength' => 255, 'size' => 45, + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', 'html' => array( 'type' => 'Text', 'maxlength' => 255, @@ -558,6 +651,9 @@ function contact_getfields_expectedresult() { 'type' => 1, 'title' => 'Postal Greeting ID', 'description' => 'FK to civicrm_option_value.id, that has to be valid registered Postal Greeting.', + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', 'html' => array( 'type' => 'Text', 'size' => 6, @@ -573,6 +669,9 @@ function contact_getfields_expectedresult() { 'size' => 45, 'import' => TRUE, 'where' => 'civicrm_contact.postal_greeting_custom', + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', 'html' => array( 'type' => 'Text', 'maxlength' => 128, @@ -586,6 +685,9 @@ function contact_getfields_expectedresult() { 'description' => 'Cache Postal greeting.', 'maxlength' => 255, 'size' => 45, + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', 'html' => array( 'type' => 'Text', 'maxlength' => 255, @@ -597,6 +699,9 @@ function contact_getfields_expectedresult() { 'type' => 1, 'title' => 'Addressee ID', 'description' => 'FK to civicrm_option_value.id, that has to be valid registered Addressee.', + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', ), 'addressee_custom' => array( 'name' => 'addressee_custom', @@ -607,6 +712,9 @@ function contact_getfields_expectedresult() { 'size' => 45, 'import' => TRUE, 'where' => 'civicrm_contact.addressee_custom', + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', 'html' => array( 'type' => 'Text', 'maxlength' => 128, @@ -620,6 +728,9 @@ function contact_getfields_expectedresult() { 'description' => 'Cache Addressee.', 'maxlength' => 255, 'size' => 45, + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', 'html' => array( 'type' => 'Text', 'maxlength' => 255, @@ -638,6 +749,9 @@ function contact_getfields_expectedresult() { 'headerPattern' => '/^job|(j(ob\\s)?title)$/i', 'dataPattern' => '//', 'export' => TRUE, + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', 'html' => array( 'type' => 'Text', 'maxlength' => 255, @@ -653,6 +767,9 @@ function contact_getfields_expectedresult() { 'where' => 'civicrm_contact.gender_id', 'headerPattern' => '/^gender$/i', 'export' => TRUE, + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', 'html' => array( 'type' => 'Select', 'size' => 6, @@ -676,8 +793,12 @@ function contact_getfields_expectedresult() { 'headerPattern' => '/^birth|(b(irth\\s)?date)|D(\\W*)O(\\W*)B(\\W*)$/i', 'dataPattern' => '/\\d{4}-?\\d{2}-?\\d{2}/', 'export' => TRUE, + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', 'html' => array( 'type' => 'Select Date', + 'format' => 'birth', ), ), 'is_deceased' => array( @@ -688,6 +809,9 @@ function contact_getfields_expectedresult() { 'where' => 'civicrm_contact.is_deceased', 'headerPattern' => '/i(s\\s)?d(eceased)$/i', 'export' => TRUE, + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', 'html' => array( 'type' => 'CheckBox', ), @@ -701,8 +825,12 @@ function contact_getfields_expectedresult() { 'where' => 'civicrm_contact.deceased_date', 'headerPattern' => '/^deceased|(d(eceased\\s)?date)$/i', 'export' => TRUE, + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', 'html' => array( 'type' => 'Select Date', + 'format' => 'birth', ), ), 'household_name' => array( @@ -717,6 +845,9 @@ function contact_getfields_expectedresult() { 'headerPattern' => '/^household|(h(ousehold\\s)?name)$/i', 'dataPattern' => '/^\\w+$/', 'export' => TRUE, + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', 'html' => array( 'type' => 'Text', 'maxlength' => 128, @@ -728,6 +859,9 @@ function contact_getfields_expectedresult() { 'type' => 1, 'title' => 'Household Primary Contact ID', 'description' => 'Optional FK to Primary Contact for this household.', + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', 'FKClassName' => 'CRM_Contact_DAO_Contact', 'html' => array( 'type' => 'Select', @@ -748,6 +882,9 @@ function contact_getfields_expectedresult() { 'headerPattern' => '/^organization|(o(rganization\\s)?name)$/i', 'dataPattern' => '/^\\w+$/', 'export' => TRUE, + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', 'html' => array( 'type' => 'Text', 'maxlength' => 128, @@ -765,6 +902,9 @@ function contact_getfields_expectedresult() { 'where' => 'civicrm_contact.sic_code', 'headerPattern' => '/^sic|(s(ic\\s)?code)$/i', 'export' => TRUE, + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', 'html' => array( 'type' => 'Text', 'maxlength' => 8, @@ -784,6 +924,9 @@ function contact_getfields_expectedresult() { 'dataPattern' => '/^[\\w\\/\\:\\.]+$/', 'export' => TRUE, 'rule' => 'url', + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', 'html' => array( 'type' => 'Text', 'maxlength' => 255, @@ -799,6 +942,9 @@ function contact_getfields_expectedresult() { 'export' => TRUE, 'where' => 'civicrm_contact.created_date', 'default' => 'NULL', + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', ), 'modified_date' => array( 'name' => 'modified_date', @@ -809,6 +955,9 @@ function contact_getfields_expectedresult() { 'export' => TRUE, 'where' => 'civicrm_contact.modified_date', 'default' => 'CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP', + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', ), 'source' => array( 'name' => 'source', @@ -821,6 +970,9 @@ function contact_getfields_expectedresult() { 'where' => 'civicrm_contact.source', 'headerPattern' => '/(C(ontact\\s)?Source)$/i', 'export' => TRUE, + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', 'html' => array( 'type' => 'Text', 'maxlength' => 255, @@ -835,6 +987,9 @@ function contact_getfields_expectedresult() { 'description' => 'OPTIONAL FK to civicrm_contact record.', 'export' => TRUE, 'where' => 'civicrm_contact.employer_id', + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', 'FKClassName' => 'CRM_Contact_DAO_Contact', 'html' => array( 'type' => 'EntityRef', @@ -851,6 +1006,9 @@ function contact_getfields_expectedresult() { 'required' => TRUE, 'export' => TRUE, 'where' => 'civicrm_contact.is_deleted', + 'table_name' => 'civicrm_contact', + 'entity' => 'Contact', + 'bao' => 'CRM_Contact_BAO_Contact', 'html' => array( 'type' => 'CheckBox', ), @@ -878,8 +1036,8 @@ function contact_getfields_expectedresult() { 'table_name' => 'civicrm_value_select_test_g_1', 'column_name' => 'our_special_field_1', 'pseudoconstant' => array( - 'optionGroupName' => 'our_special_field_20170124082923', - 'optionEditPath' => 'civicrm/admin/options/our_special_field_20170124082923', + 'optionGroupName' => 'our_special_field_20170207021937', + 'optionEditPath' => 'civicrm/admin/options/our_special_field_20170207021937', ), 'name' => 'custom_1', 'title' => 'Our special field', diff --git a/civicrm/api/v3/examples/Contact/GroupFilterUsingContactAPI.php b/civicrm/api/v3/examples/Contact/GroupFilterUsingContactAPI.php index 67fadede7a..879b059fa5 100644 --- a/civicrm/api/v3/examples/Contact/GroupFilterUsingContactAPI.php +++ b/civicrm/api/v3/examples/Contact/GroupFilterUsingContactAPI.php @@ -9,11 +9,12 @@ */ function contact_get_example() { $params = array( - 'filter.group_id' => array( - '0' => 1, - '1' => 26, + 'group' => array( + 'IN' => array( + '0' => 'Test group C', + '1' => 'Test group D', + ), ), - 'contact_type' => 'Individual', ); try{ @@ -47,14 +48,14 @@ function contact_get_expectedresult() { 'is_error' => 0, 'version' => 3, 'count' => 1, - 'id' => 1, + 'id' => 3, 'values' => array( - '1' => array( - 'contact_id' => '1', + '3' => array( + 'contact_id' => '3', 'contact_type' => 'Individual', 'contact_sub_type' => '', - 'sort_name' => 'man2@yahoo.com', - 'display_name' => 'man2@yahoo.com', + 'sort_name' => 'Groupmember, Test2', + 'display_name' => 'Test2 Groupmember', 'do_not_email' => 0, 'do_not_phone' => 0, 'do_not_mail' => 0, @@ -69,9 +70,9 @@ function contact_get_expectedresult() { 'preferred_communication_method' => '', 'preferred_language' => 'en_US', 'preferred_mail_format' => 'Both', - 'first_name' => '', + 'first_name' => 'Test2', 'middle_name' => '', - 'last_name' => '', + 'last_name' => 'Groupmember', 'prefix_id' => '', 'suffix_id' => '', 'formal_title' => '', @@ -86,8 +87,8 @@ function contact_get_expectedresult() { 'sic_code' => '', 'contact_is_deleted' => 0, 'current_employer' => '', - 'address_id' => '2', - 'street_address' => '1 my road', + 'address_id' => '', + 'street_address' => '', 'supplemental_address_1' => '', 'supplemental_address_2' => '', 'city' => '', @@ -101,7 +102,7 @@ function contact_get_expectedresult() { 'phone_type_id' => '', 'phone' => '', 'email_id' => '1', - 'email' => 'man2@yahoo.com', + 'email' => 'test@example.org', 'on_hold' => 0, 'im_id' => '', 'provider_id' => '', @@ -115,7 +116,7 @@ function contact_get_expectedresult() { 'state_province_name' => '', 'state_province' => '', 'country' => '', - 'id' => '1', + 'id' => '3', ), ), ); @@ -125,7 +126,7 @@ function contact_get_expectedresult() { /* * This example has been generated from the API test suite. -* The test that created it is called "testGetGroupIDFromContact" +* The test that created it is called "testContactGetWithGroupTitleMultipleGroups" * and can be found at: * https://github.com/civicrm/civicrm-core/blob/master/tests/phpunit/api/v3/ContactTest.php * diff --git a/civicrm/api/v3/examples/Contribution/ContributionCreateWithHonoreeContact.php b/civicrm/api/v3/examples/Contribution/ContributionCreateWithHonoreeContact.php index fe6ec8ee09..0ed2701530 100644 --- a/civicrm/api/v3/examples/Contribution/ContributionCreateWithHonoreeContact.php +++ b/civicrm/api/v3/examples/Contribution/ContributionCreateWithHonoreeContact.php @@ -9,7 +9,7 @@ */ function contribution_create_example() { $params = array( - 'contact_id' => 23, + 'contact_id' => 28, 'receive_date' => '20120511', 'total_amount' => '100', 'financial_type_id' => 1, @@ -18,7 +18,7 @@ function contribution_create_example() { 'net_amount' => '95', 'source' => 'SSF', 'contribution_status_id' => 1, - 'honor_contact_id' => 24, + 'honor_contact_id' => 29, ); try{ @@ -30,7 +30,8 @@ function contribution_create_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); @@ -55,7 +56,7 @@ function contribution_create_expectedresult() { 'values' => array( '1' => array( 'id' => '1', - 'contact_id' => '23', + 'contact_id' => '28', 'financial_type_id' => '1', 'contribution_page_id' => '', 'payment_instrument_id' => '4', @@ -82,6 +83,7 @@ function contribution_create_expectedresult() { 'campaign_id' => '', 'creditnote_id' => '', 'tax_amount' => '', + 'revenue_recognition_date' => '', 'contribution_type_id' => '1', ), ), diff --git a/civicrm/api/v3/examples/Contribution/ContributionCreateWithNote.php b/civicrm/api/v3/examples/Contribution/ContributionCreateWithNote.php index 4a19762036..394b0c36ad 100644 --- a/civicrm/api/v3/examples/Contribution/ContributionCreateWithNote.php +++ b/civicrm/api/v3/examples/Contribution/ContributionCreateWithNote.php @@ -9,7 +9,7 @@ */ function contribution_create_example() { $params = array( - 'contact_id' => 17, + 'contact_id' => 22, 'receive_date' => '2012-01-01', 'total_amount' => '100', 'financial_type_id' => 1, @@ -33,7 +33,8 @@ function contribution_create_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); @@ -58,7 +59,7 @@ function contribution_create_expectedresult() { 'values' => array( '1' => array( 'id' => '1', - 'contact_id' => '17', + 'contact_id' => '22', 'financial_type_id' => '1', 'contribution_page_id' => '', 'payment_instrument_id' => '1', @@ -85,6 +86,7 @@ function contribution_create_expectedresult() { 'campaign_id' => '', 'creditnote_id' => '', 'tax_amount' => '', + 'revenue_recognition_date' => '', 'contribution_type_id' => '1', ), ), diff --git a/civicrm/api/v3/examples/Contribution/ContributionCreateWithSoftCredit.php b/civicrm/api/v3/examples/Contribution/ContributionCreateWithSoftCredit.php index f756efed96..a798c940b1 100644 --- a/civicrm/api/v3/examples/Contribution/ContributionCreateWithSoftCredit.php +++ b/civicrm/api/v3/examples/Contribution/ContributionCreateWithSoftCredit.php @@ -9,7 +9,7 @@ */ function contribution_create_example() { $params = array( - 'contact_id' => 19, + 'contact_id' => 24, 'receive_date' => '20120511', 'total_amount' => '100', 'financial_type_id' => 1, @@ -20,7 +20,7 @@ function contribution_create_example() { 'contribution_status_id' => 1, 'soft_credit' => array( '1' => array( - 'contact_id' => 20, + 'contact_id' => 25, 'amount' => 50, 'soft_credit_type_id' => 3, ), @@ -36,7 +36,8 @@ function contribution_create_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); @@ -61,7 +62,7 @@ function contribution_create_expectedresult() { 'values' => array( '1' => array( 'id' => '1', - 'contact_id' => '19', + 'contact_id' => '24', 'financial_type_id' => '1', 'contribution_page_id' => '', 'payment_instrument_id' => '4', @@ -88,6 +89,7 @@ function contribution_create_expectedresult() { 'campaign_id' => '', 'creditnote_id' => '', 'tax_amount' => '', + 'revenue_recognition_date' => '', 'contribution_type_id' => '1', ), ), diff --git a/civicrm/api/v3/examples/Contribution/ContributionCreateWithSoftCreditDefaults.php b/civicrm/api/v3/examples/Contribution/ContributionCreateWithSoftCreditDefaults.php index 8d7126cb89..5209aa9aea 100644 --- a/civicrm/api/v3/examples/Contribution/ContributionCreateWithSoftCreditDefaults.php +++ b/civicrm/api/v3/examples/Contribution/ContributionCreateWithSoftCreditDefaults.php @@ -9,7 +9,7 @@ */ function contribution_create_example() { $params = array( - 'contact_id' => 21, + 'contact_id' => 26, 'receive_date' => '20120511', 'total_amount' => '100', 'financial_type_id' => 1, @@ -18,7 +18,7 @@ function contribution_create_example() { 'net_amount' => '95', 'source' => 'SSF', 'contribution_status_id' => 1, - 'soft_credit_to' => 22, + 'soft_credit_to' => 27, ); try{ @@ -30,7 +30,8 @@ function contribution_create_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); @@ -55,7 +56,7 @@ function contribution_create_expectedresult() { 'values' => array( '1' => array( 'id' => '1', - 'contact_id' => '21', + 'contact_id' => '26', 'financial_type_id' => '1', 'contribution_page_id' => '', 'payment_instrument_id' => '4', @@ -82,6 +83,7 @@ function contribution_create_expectedresult() { 'campaign_id' => '', 'creditnote_id' => '', 'tax_amount' => '', + 'revenue_recognition_date' => '', 'contribution_type_id' => '1', ), ), diff --git a/civicrm/api/v3/examples/Contribution/Create.php b/civicrm/api/v3/examples/Contribution/Create.php index 9135fe3f92..9b49970393 100644 --- a/civicrm/api/v3/examples/Contribution/Create.php +++ b/civicrm/api/v3/examples/Contribution/Create.php @@ -13,6 +13,7 @@ function contribution_create_example() { 'financial_type_id' => 1, 'contribution_page_id' => 1, 'trxn_id' => 12345, + 'is_pay_later' => 1, 'invoice_id' => 67890, 'source' => 'SSF', 'contribution_status_id' => 2, @@ -27,7 +28,8 @@ function contribution_create_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); @@ -59,7 +61,7 @@ function contribution_create_expectedresult() { 'receive_date' => '20120511000000', 'non_deductible_amount' => '', 'total_amount' => '100', - 'fee_amount' => '0', + 'fee_amount' => 0, 'net_amount' => '100', 'trxn_id' => '12345', 'invoice_id' => '67890', @@ -72,15 +74,15 @@ function contribution_create_expectedresult() { 'amount_level' => '', 'contribution_recur_id' => '', 'is_test' => '', - 'is_pay_later' => '', + 'is_pay_later' => '1', 'contribution_status_id' => '2', 'address_id' => '', 'check_number' => '', 'campaign_id' => '', 'creditnote_id' => '', 'tax_amount' => '', - 'contribution_type_id' => '1', 'revenue_recognition_date' => '', + 'contribution_type_id' => '1', ), ), ); @@ -90,9 +92,9 @@ function contribution_create_expectedresult() { /* * This example has been generated from the API test suite. -* The test that created it is called "testCreateContributionPendingOnline" +* The test that created it is called "testCreateContributionPayLaterOnline" * and can be found at: -* https://github.com/civicrm/civicrm-core/blob/master/tests/phpunit/api/v3/TaxContributionPageTest.php +* https://github.com/civicrm/civicrm-core/blob/master/tests/phpunit/api/v3/ContributionTest.php * * You can see the outcome of the API tests at * https://test.civicrm.org/job/CiviCRM-master-git/ diff --git a/civicrm/api/v3/examples/Contribution/CreateWithNestedLineItems.php b/civicrm/api/v3/examples/Contribution/CreateWithNestedLineItems.php index 2c7234e419..741e176397 100644 --- a/civicrm/api/v3/examples/Contribution/CreateWithNestedLineItems.php +++ b/civicrm/api/v3/examples/Contribution/CreateWithNestedLineItems.php @@ -9,10 +9,14 @@ */ function contribution_create_example() { $params = array( - 'contact_id' => 1, + 'contact_id' => 11, 'receive_date' => '20120511', - 'total_amount' => '400', - 'financial_type_id' => 7, + 'total_amount' => '100', + 'financial_type_id' => 1, + 'payment_instrument_id' => 1, + 'non_deductible_amount' => '10', + 'fee_amount' => '50', + 'net_amount' => '90', 'trxn_id' => 12345, 'invoice_id' => 67890, 'source' => 'SSF', @@ -20,22 +24,16 @@ function contribution_create_example() { 'skipLineItem' => 1, 'api.line_item.create' => array( '0' => array( - 'price_field_id' => array( - '0' => 3, - ), - 'qty' => 1, - 'line_total' => '100', - 'unit_price' => '100', - 'financial_type_id' => 7, + 'price_field_id' => 1, + 'qty' => 2, + 'line_total' => '20', + 'unit_price' => '10', ), '1' => array( - 'price_field_id' => array( - '0' => 3, - ), + 'price_field_id' => 1, 'qty' => 1, - 'line_total' => '300', - 'unit_price' => '300', - 'financial_type_id' => 8, + 'line_total' => '80', + 'unit_price' => '80', ), ), ); @@ -49,7 +47,8 @@ function contribution_create_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); @@ -74,15 +73,15 @@ function contribution_create_expectedresult() { 'values' => array( '1' => array( 'id' => '1', - 'contact_id' => '1', - 'financial_type_id' => '7', + 'contact_id' => '11', + 'financial_type_id' => '1', 'contribution_page_id' => '', - 'payment_instrument_id' => '4', + 'payment_instrument_id' => '1', 'receive_date' => '20120511000000', - 'non_deductible_amount' => '', - 'total_amount' => '435', - 'fee_amount' => 0, - 'net_amount' => '435', + 'non_deductible_amount' => '10', + 'total_amount' => '100', + 'fee_amount' => '50', + 'net_amount' => '90', 'trxn_id' => '12345', 'invoice_id' => '67890', 'currency' => 'USD', @@ -100,8 +99,9 @@ function contribution_create_expectedresult() { 'check_number' => '', 'campaign_id' => '', 'creditnote_id' => '', - 'tax_amount' => '35', - 'contribution_type_id' => '7', + 'tax_amount' => 0, + 'revenue_recognition_date' => '', + 'contribution_type_id' => '1', 'api.line_item.create' => array( '0' => array( 'is_error' => 0, @@ -114,18 +114,16 @@ function contribution_create_expectedresult() { 'entity_table' => 'civicrm_contribution', 'entity_id' => '1', 'contribution_id' => '1', - 'price_field_id' => array( - '0' => '3', - ), + 'price_field_id' => '1', 'label' => 'line item', - 'qty' => '1', - 'unit_price' => '100', - 'line_total' => '100', + 'qty' => '2', + 'unit_price' => '10', + 'line_total' => '20', 'participant_count' => '', 'price_field_value_id' => '', - 'financial_type_id' => '7', - 'deductible_amount' => '', - 'tax_amount' => '20', + 'financial_type_id' => '', + 'non_deductible_amount' => '', + 'tax_amount' => '', ), ), ), @@ -140,18 +138,16 @@ function contribution_create_expectedresult() { 'entity_table' => 'civicrm_contribution', 'entity_id' => '1', 'contribution_id' => '1', - 'price_field_id' => array( - '0' => '3', - ), + 'price_field_id' => '1', 'label' => 'line item', 'qty' => '1', - 'unit_price' => '300', - 'line_total' => '300', + 'unit_price' => '80', + 'line_total' => '80', 'participant_count' => '', 'price_field_value_id' => '', - 'financial_type_id' => '8', - 'deductible_amount' => '', - 'tax_amount' => '15', + 'financial_type_id' => '', + 'non_deductible_amount' => '', + 'tax_amount' => '', ), ), ), @@ -167,7 +163,7 @@ function contribution_create_expectedresult() { * This example has been generated from the API test suite. * The test that created it is called "testCreateContributionChainedLineItems" * and can be found at: -* https://github.com/civicrm/civicrm-core/blob/master/tests/phpunit/api/v3/TaxContributionPageTest.php +* https://github.com/civicrm/civicrm-core/blob/master/tests/phpunit/api/v3/ContributionTest.php * * You can see the outcome of the API tests at * https://test.civicrm.org/job/CiviCRM-master-git/ diff --git a/civicrm/api/v3/examples/Contribution/Delete.php b/civicrm/api/v3/examples/Contribution/Delete.php index 0242584211..c22b1b102d 100644 --- a/civicrm/api/v3/examples/Contribution/Delete.php +++ b/civicrm/api/v3/examples/Contribution/Delete.php @@ -19,7 +19,8 @@ function contribution_delete_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); @@ -53,7 +54,7 @@ function contribution_delete_expectedresult() { * This example has been generated from the API test suite. * The test that created it is called "testDeleteContribution" * and can be found at: -* https://github.com/civicrm/civicrm-core/blob/master/tests/phpunit/api/v3/TaxContributionPageTest.php +* https://github.com/civicrm/civicrm-core/blob/master/tests/phpunit/api/v3/ContributionTest.php * * You can see the outcome of the API tests at * https://test.civicrm.org/job/CiviCRM-master-git/ diff --git a/civicrm/api/v3/examples/Contribution/Get.php b/civicrm/api/v3/examples/Contribution/Get.php index 3649403bea..0c5c06f58f 100644 --- a/civicrm/api/v3/examples/Contribution/Get.php +++ b/civicrm/api/v3/examples/Contribution/Get.php @@ -19,7 +19,8 @@ function contribution_get_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); @@ -43,7 +44,7 @@ function contribution_get_expectedresult() { 'id' => 1, 'values' => array( '1' => array( - 'contact_id' => '4', + 'contact_id' => '3', 'contact_type' => 'Individual', 'contact_sub_type' => '', 'sort_name' => 'Anderson, Anthony', @@ -63,10 +64,11 @@ function contribution_get_expectedresult() { 'thankyou_date' => '', 'contribution_source' => 'SSF', 'amount_level' => '', + 'contribution_recur_id' => '', 'is_test' => 0, 'is_pay_later' => 0, 'contribution_status_id' => '1', - 'check_number' => '', + 'contribution_check_number' => '', 'contribution_campaign_id' => '', 'financial_type_id' => '1', 'financial_type' => 'Donation', @@ -78,16 +80,17 @@ function contribution_get_expectedresult() { 'fulfilled_date' => '', 'contribution_start_date' => '', 'contribution_end_date' => '', - 'contribution_recur_id' => '', 'financial_account_id' => '1', 'accounting_code' => '4200', + 'campaign_id' => '', + 'contribution_campaign_title' => '', 'contribution_note' => '', 'contribution_batch' => '', 'contribution_status' => 'Completed', 'payment_instrument' => 'Check', 'payment_instrument_id' => '4', 'instrument_id' => '4', - 'contribution_check_number' => '', + 'check_number' => '', 'id' => '1', 'contribution_type_id' => '1', ), @@ -99,7 +102,7 @@ function contribution_get_expectedresult() { /* * This example has been generated from the API test suite. -* The test that created it is called "testGetContributionLegacyBehaviour" +* The test that created it is called "testGetContribution" * and can be found at: * https://github.com/civicrm/civicrm-core/blob/master/tests/phpunit/api/v3/ContributionTest.php * diff --git a/civicrm/api/v3/examples/ContributionPage/Create.php b/civicrm/api/v3/examples/ContributionPage/Create.php index bff46b83de..8139aa301a 100644 --- a/civicrm/api/v3/examples/ContributionPage/Create.php +++ b/civicrm/api/v3/examples/ContributionPage/Create.php @@ -13,6 +13,9 @@ function contribution_page_create_example() { 'goal_amount' => 34567, 'is_pay_later' => 1, 'is_monetary' => TRUE, + 'is_email_receipt' => TRUE, + 'receipt_from_email' => 'yourconscience@donate.com', + 'receipt_from_name' => 'Ego Freud', ); try{ @@ -77,11 +80,9 @@ function contribution_page_create_expectedresult() { 'thankyou_title' => '', 'thankyou_text' => '', 'thankyou_footer' => '', - 'is_for_organization' => '', - 'for_organization' => '', - 'is_email_receipt' => '', - 'receipt_from_name' => '', - 'receipt_from_email' => '', + 'is_email_receipt' => '1', + 'receipt_from_name' => 'Ego Freud', + 'receipt_from_email' => 'yourconscience@donate.com', 'cc_receipt' => '', 'bcc_receipt' => '', 'receipt_text' => '', diff --git a/civicrm/api/v3/examples/ContributionPage/Get.php b/civicrm/api/v3/examples/ContributionPage/Get.php index cc7cd888b2..0a6b234e90 100644 --- a/civicrm/api/v3/examples/ContributionPage/Get.php +++ b/civicrm/api/v3/examples/ContributionPage/Get.php @@ -7,7 +7,6 @@ */ function contribution_page_get_example() { $params = array( - 'amount' => '34567', 'currency' => 'NZD', 'financial_type_id' => 1, ); @@ -55,17 +54,20 @@ function contribution_page_get_expectedresult() { 'is_confirm_enabled' => '1', 'is_recur_interval' => 0, 'is_recur_installments' => 0, + 'adjust_recur_start_date' => 0, 'is_pay_later' => '1', 'is_partial_payment' => 0, 'is_allow_other_amount' => 0, 'goal_amount' => '34567.00', - 'is_for_organization' => 0, - 'is_email_receipt' => 0, + 'is_email_receipt' => '1', + 'receipt_from_name' => 'Ego Freud', + 'receipt_from_email' => 'yourconscience@donate.com', 'is_active' => '1', 'amount_block_is_active' => '1', 'currency' => 'NZD', 'is_share' => '1', 'is_billing_required' => 0, + 'contribution_type_id' => '1', ), ), ); @@ -75,7 +77,7 @@ function contribution_page_get_expectedresult() { /* * This example has been generated from the API test suite. -* The test that created it is called "testGetContributionPageByAmount" +* The test that created it is called "testGetBasicContributionPage" * and can be found at: * https://github.com/civicrm/civicrm-core/blob/master/tests/phpunit/api/v3/ContributionPageTest.php * diff --git a/civicrm/api/v3/examples/ContributionPage/Submit.php b/civicrm/api/v3/examples/ContributionPage/Submit.php index db56853f5d..c24c4dbcb3 100644 --- a/civicrm/api/v3/examples/ContributionPage/Submit.php +++ b/civicrm/api/v3/examples/ContributionPage/Submit.php @@ -9,16 +9,14 @@ */ function contribution_page_submit_example() { $params = array( - 'price_3' => '', 'id' => 1, - 'amount' => 10, + 'pledge_amount' => array( + '2' => 1, + ), 'billing_first_name' => 'Billy', 'billing_middle_name' => 'Goat', 'billing_last_name' => 'Gruff', 'email' => 'billy@goat.gruff', - 'selectMembership' => array( - '0' => 1, - ), 'payment_processor_id' => 1, 'credit_card_number' => '4111111111111111', 'credit_card_type' => 'Visa', @@ -27,9 +25,12 @@ function contribution_page_submit_example() { 'Y' => 2040, ), 'cvv2' => 123, - 'is_recur' => 1, - 'frequency_interval' => 1, - 'frequency_unit' => 'month', + 'pledge_id' => '1', + 'cid' => '77', + 'contact_id' => '77', + 'amount' => '100', + 'is_pledge' => TRUE, + 'pledge_block_id' => 2, ); try{ @@ -71,7 +72,7 @@ function contribution_page_submit_expectedresult() { /* * This example has been generated from the API test suite. -* The test that created it is called "testSubmitMembershipPriceSetPaymentPaymentProcessorRecurDelayed" +* The test that created it is called "testSubmitPledgePayment" * and can be found at: * https://github.com/civicrm/civicrm-core/blob/master/tests/phpunit/api/v3/ContributionPageTest.php * diff --git a/civicrm/api/v3/examples/ContributionRecur/Delete.php b/civicrm/api/v3/examples/ContributionRecur/Delete.php index f5b732f6f0..fba4f05850 100644 --- a/civicrm/api/v3/examples/ContributionRecur/Delete.php +++ b/civicrm/api/v3/examples/ContributionRecur/Delete.php @@ -7,7 +7,7 @@ */ function contribution_recur_delete_example() { $params = array( - 'id' => 3, + 'id' => 4, ); try{ diff --git a/civicrm/api/v3/examples/Country/Create.php b/civicrm/api/v3/examples/Country/Create.php index 091baaa5ef..988b9bcfc9 100644 --- a/civicrm/api/v3/examples/Country/Create.php +++ b/civicrm/api/v3/examples/Country/Create.php @@ -43,10 +43,10 @@ function country_create_expectedresult() { 'is_error' => 0, 'version' => 3, 'count' => 1, - 'id' => 1252, + 'id' => 1254, 'values' => array( - '1252' => array( - 'id' => '1252', + '1254' => array( + 'id' => '1254', 'name' => 'Made Up Land', 'iso_code' => 'ZZ', 'country_code' => '', diff --git a/civicrm/api/v3/examples/Country/Delete.php b/civicrm/api/v3/examples/Country/Delete.php index a631c34a07..79fcb15348 100644 --- a/civicrm/api/v3/examples/Country/Delete.php +++ b/civicrm/api/v3/examples/Country/Delete.php @@ -7,7 +7,7 @@ */ function country_delete_example() { $params = array( - 'id' => 1253, + 'id' => 1255, ); try{ diff --git a/civicrm/api/v3/examples/Country/Get.php b/civicrm/api/v3/examples/Country/Get.php index d1cf00f99c..dcd4d4431e 100644 --- a/civicrm/api/v3/examples/Country/Get.php +++ b/civicrm/api/v3/examples/Country/Get.php @@ -41,10 +41,10 @@ function country_get_expectedresult() { 'is_error' => 0, 'version' => 3, 'count' => 1, - 'id' => 1254, + 'id' => 1256, 'values' => array( - '1254' => array( - 'id' => '1254', + '1256' => array( + 'id' => '1256', 'name' => 'Made Up Land', 'iso_code' => 'ZZ', 'region_id' => '1', diff --git a/civicrm/api/v3/examples/EntityTag/Delete.php b/civicrm/api/v3/examples/EntityTag/Delete.php index 9d117d4b9b..83d812b1bf 100644 --- a/civicrm/api/v3/examples/EntityTag/Delete.php +++ b/civicrm/api/v3/examples/EntityTag/Delete.php @@ -7,8 +7,8 @@ */ function entity_tag_delete_example() { $params = array( - 'contact_id_h' => 37, - 'tag_id' => '17', + 'contact_id_h' => 31, + 'tag_id' => '15', ); try{ diff --git a/civicrm/api/v3/examples/EntityTag/Get.php b/civicrm/api/v3/examples/EntityTag/Get.php index a51e13c015..d3b1392145 100644 --- a/civicrm/api/v3/examples/EntityTag/Get.php +++ b/civicrm/api/v3/examples/EntityTag/Get.php @@ -7,7 +7,7 @@ */ function entity_tag_get_example() { $params = array( - 'contact_id' => 3, + 'contact_id' => 15, ); try{ @@ -41,10 +41,13 @@ function entity_tag_get_expectedresult() { 'is_error' => 0, 'version' => 3, 'count' => 1, - 'id' => 6, + 'id' => 5, 'values' => array( - '6' => array( - 'tag_id' => '6', + '5' => array( + 'id' => '5', + 'entity_table' => 'civicrm_contact', + 'entity_id' => '15', + 'tag_id' => '10', ), ), ); diff --git a/civicrm/api/v3/examples/Event/IsFullOption.php b/civicrm/api/v3/examples/Event/IsFullOption.php index 0eca96b971..556e307c48 100644 --- a/civicrm/api/v3/examples/Event/IsFullOption.php +++ b/civicrm/api/v3/examples/Event/IsFullOption.php @@ -67,7 +67,7 @@ function event_getsingle_expectedresult() { 'allow_selfcancelxfer' => 0, 'selfcancelxfer_time' => 0, 'is_template' => 0, - 'created_date' => '2017-01-24 08:34:25', + 'created_date' => '2017-02-07 02:22:22', 'is_share' => '1', 'is_confirm_enabled' => '1', 'is_billing_required' => 0, diff --git a/civicrm/api/v3/examples/Group/GetFields.php b/civicrm/api/v3/examples/Group/GetFields.php index 22dfe5250c..0247cb3e9e 100644 --- a/civicrm/api/v3/examples/Group/GetFields.php +++ b/civicrm/api/v3/examples/Group/GetFields.php @@ -50,6 +50,9 @@ function group_getfields_expectedresult() { 'title' => 'Group ID', 'description' => 'Group ID', 'required' => TRUE, + 'table_name' => 'civicrm_group', + 'entity' => 'Group', + 'bao' => 'CRM_Contact_BAO_Group', 'api.aliases' => array( '0' => 'group_id', ), @@ -61,6 +64,9 @@ function group_getfields_expectedresult() { 'description' => 'Internal name of Group.', 'maxlength' => 64, 'size' => 30, + 'table_name' => 'civicrm_group', + 'entity' => 'Group', + 'bao' => 'CRM_Contact_BAO_Group', ), 'title' => array( 'name' => 'title', @@ -69,6 +75,9 @@ function group_getfields_expectedresult() { 'description' => 'Name of Group.', 'maxlength' => 64, 'size' => 30, + 'table_name' => 'civicrm_group', + 'entity' => 'Group', + 'bao' => 'CRM_Contact_BAO_Group', 'api.required' => 1, ), 'description' => array( @@ -78,6 +87,9 @@ function group_getfields_expectedresult() { 'description' => 'Optional verbose description of the group.', 'rows' => 2, 'cols' => 60, + 'table_name' => 'civicrm_group', + 'entity' => 'Group', + 'bao' => 'CRM_Contact_BAO_Group', 'html' => array( 'type' => 'TextArea', 'rows' => 2, @@ -91,12 +103,18 @@ function group_getfields_expectedresult() { 'description' => 'Module or process which created this group.', 'maxlength' => 64, 'size' => 30, + 'table_name' => 'civicrm_group', + 'entity' => 'Group', + 'bao' => 'CRM_Contact_BAO_Group', ), 'saved_search_id' => array( 'name' => 'saved_search_id', 'type' => 1, 'title' => 'Saved Search ID', 'description' => 'FK to saved search table.', + 'table_name' => 'civicrm_group', + 'entity' => 'Group', + 'bao' => 'CRM_Contact_BAO_Group', 'FKClassName' => 'CRM_Contact_DAO_SavedSearch', 'FKApiName' => 'SavedSearch', ), @@ -105,6 +123,9 @@ function group_getfields_expectedresult() { 'type' => 16, 'title' => 'Group Enabled', 'description' => 'Is this entry active?', + 'table_name' => 'civicrm_group', + 'entity' => 'Group', + 'bao' => 'CRM_Contact_BAO_Group', 'api.default' => 1, ), 'visibility' => array( @@ -115,6 +136,9 @@ function group_getfields_expectedresult() { 'maxlength' => 24, 'size' => 20, 'default' => 'User and User Admin Only', + 'table_name' => 'civicrm_group', + 'entity' => 'Group', + 'bao' => 'CRM_Contact_BAO_Group', 'html' => array( 'type' => 'Select', 'maxlength' => 24, @@ -129,18 +153,27 @@ function group_getfields_expectedresult() { 'type' => 32, 'title' => 'Group Where Clause', 'description' => 'the sql where clause if a saved search acl', + 'table_name' => 'civicrm_group', + 'entity' => 'Group', + 'bao' => 'CRM_Contact_BAO_Group', ), 'select_tables' => array( 'name' => 'select_tables', 'type' => 32, 'title' => 'Tables For Select Clause', 'description' => 'the tables to be included in a select data', + 'table_name' => 'civicrm_group', + 'entity' => 'Group', + 'bao' => 'CRM_Contact_BAO_Group', ), 'where_tables' => array( 'name' => 'where_tables', 'type' => 32, 'title' => 'Tables For Where Clause', 'description' => 'the tables to be included in the count statement', + 'table_name' => 'civicrm_group', + 'entity' => 'Group', + 'bao' => 'CRM_Contact_BAO_Group', ), 'group_type' => array( 'name' => 'group_type', @@ -149,6 +182,9 @@ function group_getfields_expectedresult() { 'description' => 'FK to group type', 'maxlength' => 128, 'size' => 45, + 'table_name' => 'civicrm_group', + 'entity' => 'Group', + 'bao' => 'CRM_Contact_BAO_Group', 'pseudoconstant' => array( 'optionGroupName' => 'group_type', 'optionEditPath' => 'civicrm/admin/options/group_type', @@ -160,6 +196,9 @@ function group_getfields_expectedresult() { 'title' => 'Group Cache Date', 'description' => 'Date when we created the cache for a smart group', 'required' => '', + 'table_name' => 'civicrm_group', + 'entity' => 'Group', + 'bao' => 'CRM_Contact_BAO_Group', ), 'refresh_date' => array( 'name' => 'refresh_date', @@ -167,35 +206,53 @@ function group_getfields_expectedresult() { 'title' => 'Next Group Refresh Time', 'description' => 'Date and time when we need to refresh the cache next.', 'required' => '', + 'table_name' => 'civicrm_group', + 'entity' => 'Group', + 'bao' => 'CRM_Contact_BAO_Group', ), 'parents' => array( 'name' => 'parents', 'type' => 32, 'title' => 'Group Parents', 'description' => 'IDs of the parent(s)', + 'table_name' => 'civicrm_group', + 'entity' => 'Group', + 'bao' => 'CRM_Contact_BAO_Group', ), 'children' => array( 'name' => 'children', 'type' => 32, 'title' => 'Group Children', 'description' => 'IDs of the child(ren)', + 'table_name' => 'civicrm_group', + 'entity' => 'Group', + 'bao' => 'CRM_Contact_BAO_Group', ), 'is_hidden' => array( 'name' => 'is_hidden', 'type' => 16, 'title' => 'Group is Hidden', 'description' => 'Is this group hidden?', + 'table_name' => 'civicrm_group', + 'entity' => 'Group', + 'bao' => 'CRM_Contact_BAO_Group', ), 'is_reserved' => array( 'name' => 'is_reserved', 'type' => 16, 'title' => 'Group is Reserved', + 'table_name' => 'civicrm_group', + 'entity' => 'Group', + 'bao' => 'CRM_Contact_BAO_Group', ), 'created_id' => array( 'name' => 'created_id', 'type' => 1, 'title' => 'Group Created By', 'description' => 'FK to contact table.', + 'table_name' => 'civicrm_group', + 'entity' => 'Group', + 'bao' => 'CRM_Contact_BAO_Group', 'FKClassName' => 'CRM_Contact_DAO_Contact', 'FKApiName' => 'Contact', ), @@ -204,6 +261,9 @@ function group_getfields_expectedresult() { 'type' => 1, 'title' => 'Group Modified By', 'description' => 'FK to contact table.', + 'table_name' => 'civicrm_group', + 'entity' => 'Group', + 'bao' => 'CRM_Contact_BAO_Group', 'FKClassName' => 'CRM_Contact_DAO_Contact', 'FKApiName' => 'Contact', ), diff --git a/civicrm/api/v3/examples/Job/Create.php b/civicrm/api/v3/examples/Job/Create.php index 5c8514e02f..1060d3ccf7 100644 --- a/civicrm/api/v3/examples/Job/Create.php +++ b/civicrm/api/v3/examples/Job/Create.php @@ -48,13 +48,14 @@ function job_create_expectedresult() { 'is_error' => 0, 'version' => 3, 'count' => 1, - 'id' => 29, + 'id' => 30, 'values' => array( '0' => array( - 'id' => '29', + 'id' => '30', 'domain_id' => '1', 'run_frequency' => 'Daily', 'last_run' => '', + 'scheduled_run_date' => '', 'name' => 'API_Test_Job', 'description' => 'A long description written by hand in cursive', 'api_entity' => 'ApiTestEntity', diff --git a/civicrm/api/v3/examples/Job/Delete.php b/civicrm/api/v3/examples/Job/Delete.php index fe854b3d27..40264b4c11 100644 --- a/civicrm/api/v3/examples/Job/Delete.php +++ b/civicrm/api/v3/examples/Job/Delete.php @@ -7,7 +7,7 @@ */ function job_delete_example() { $params = array( - 'id' => 30, + 'id' => 31, ); try{ diff --git a/civicrm/api/v3/examples/Logging/Get.php b/civicrm/api/v3/examples/Logging/Get.php index 2f9a4dae9b..0e95cdaf50 100644 --- a/civicrm/api/v3/examples/Logging/Get.php +++ b/civicrm/api/v3/examples/Logging/Get.php @@ -44,52 +44,52 @@ function logging_get_expectedresult() { 'values' => array( '0' => array( 'action' => 'Update', - 'id' => '9', + 'id' => '3', 'field' => 'sort_name', 'from' => 'Anderson, Anthony', 'to' => 'Dwarf, Dopey', 'table' => 'civicrm_contact', - 'log_date' => '2016-04-06 02:53:44', + 'log_date' => '2017-02-07 02:36:46', 'log_conn_id' => 'wooty wop wop', ), '1' => array( 'action' => 'Update', - 'id' => '9', + 'id' => '3', 'field' => 'display_name', 'from' => 'Mr. Anthony Anderson II', 'to' => 'Mr. Dopey Dwarf II', 'table' => 'civicrm_contact', - 'log_date' => '2016-04-06 02:53:44', + 'log_date' => '2017-02-07 02:36:46', 'log_conn_id' => 'wooty wop wop', ), '2' => array( 'action' => 'Update', - 'id' => '9', + 'id' => '3', 'field' => 'first_name', 'from' => 'Anthony', 'to' => 'Dopey', 'table' => 'civicrm_contact', - 'log_date' => '2016-04-06 02:53:44', + 'log_date' => '2017-02-07 02:36:46', 'log_conn_id' => 'wooty wop wop', ), '3' => array( 'action' => 'Update', - 'id' => '9', + 'id' => '3', 'field' => 'last_name', 'from' => 'Anderson', 'to' => 'Dwarf', 'table' => 'civicrm_contact', - 'log_date' => '2016-04-06 02:53:44', + 'log_date' => '2017-02-07 02:36:46', 'log_conn_id' => 'wooty wop wop', ), '4' => array( 'action' => 'Update', - 'id' => '9', + 'id' => '3', 'field' => 'modified_date', - 'from' => '2016-04-06 02:53:27', - 'to' => '2016-04-06 02:53:44', + 'from' => '2017-02-07 02:36:28', + 'to' => '2017-02-07 02:36:46', 'table' => 'civicrm_contact', - 'log_date' => '2016-04-06 02:53:44', + 'log_date' => '2017-02-07 02:36:46', 'log_conn_id' => 'wooty wop wop', ), '5' => array( @@ -99,7 +99,7 @@ function logging_get_expectedresult() { 'from' => '', 'to' => '2', 'table' => 'civicrm_email', - 'log_date' => '2016-04-06 02:53:44', + 'log_date' => '2017-02-07 02:36:46', 'log_conn_id' => 'wooty wop wop', ), '6' => array( @@ -107,9 +107,9 @@ function logging_get_expectedresult() { 'id' => '2', 'field' => 'contact_id', 'from' => '', - 'to' => '9', + 'to' => '3', 'table' => 'civicrm_email', - 'log_date' => '2016-04-06 02:53:44', + 'log_date' => '2017-02-07 02:36:46', 'log_conn_id' => 'wooty wop wop', ), '7' => array( @@ -119,7 +119,7 @@ function logging_get_expectedresult() { 'from' => '', 'to' => '', 'table' => 'civicrm_email', - 'log_date' => '2016-04-06 02:53:44', + 'log_date' => '2017-02-07 02:36:46', 'log_conn_id' => 'wooty wop wop', ), '8' => array( @@ -129,7 +129,7 @@ function logging_get_expectedresult() { 'from' => '', 'to' => 'dopey@mail.com', 'table' => 'civicrm_email', - 'log_date' => '2016-04-06 02:53:44', + 'log_date' => '2017-02-07 02:36:46', 'log_conn_id' => 'wooty wop wop', ), '9' => array( @@ -139,7 +139,7 @@ function logging_get_expectedresult() { 'from' => '', 'to' => 0, 'table' => 'civicrm_email', - 'log_date' => '2016-04-06 02:53:44', + 'log_date' => '2017-02-07 02:36:46', 'log_conn_id' => 'wooty wop wop', ), '10' => array( @@ -149,7 +149,7 @@ function logging_get_expectedresult() { 'from' => '', 'to' => 0, 'table' => 'civicrm_email', - 'log_date' => '2016-04-06 02:53:44', + 'log_date' => '2017-02-07 02:36:46', 'log_conn_id' => 'wooty wop wop', ), '11' => array( @@ -159,7 +159,7 @@ function logging_get_expectedresult() { 'from' => '', 'to' => 0, 'table' => 'civicrm_email', - 'log_date' => '2016-04-06 02:53:44', + 'log_date' => '2017-02-07 02:36:46', 'log_conn_id' => 'wooty wop wop', ), '12' => array( @@ -169,7 +169,7 @@ function logging_get_expectedresult() { 'from' => '', 'to' => 0, 'table' => 'civicrm_email', - 'log_date' => '2016-04-06 02:53:44', + 'log_date' => '2017-02-07 02:36:46', 'log_conn_id' => 'wooty wop wop', ), '13' => array( @@ -179,7 +179,7 @@ function logging_get_expectedresult() { 'from' => '', 'to' => '', 'table' => 'civicrm_email', - 'log_date' => '2016-04-06 02:53:44', + 'log_date' => '2017-02-07 02:36:46', 'log_conn_id' => 'wooty wop wop', ), '14' => array( @@ -189,7 +189,7 @@ function logging_get_expectedresult() { 'from' => '', 'to' => '', 'table' => 'civicrm_email', - 'log_date' => '2016-04-06 02:53:44', + 'log_date' => '2017-02-07 02:36:46', 'log_conn_id' => 'wooty wop wop', ), '15' => array( @@ -199,7 +199,7 @@ function logging_get_expectedresult() { 'from' => '', 'to' => '', 'table' => 'civicrm_email', - 'log_date' => '2016-04-06 02:53:44', + 'log_date' => '2017-02-07 02:36:46', 'log_conn_id' => 'wooty wop wop', ), '16' => array( @@ -209,7 +209,7 @@ function logging_get_expectedresult() { 'from' => '', 'to' => '', 'table' => 'civicrm_email', - 'log_date' => '2016-04-06 02:53:44', + 'log_date' => '2017-02-07 02:36:46', 'log_conn_id' => 'wooty wop wop', ), ), diff --git a/civicrm/api/v3/examples/Logging/Revert.php b/civicrm/api/v3/examples/Logging/Revert.php index 1dad994344..c085b4497c 100644 --- a/civicrm/api/v3/examples/Logging/Revert.php +++ b/civicrm/api/v3/examples/Logging/Revert.php @@ -8,7 +8,7 @@ function logging_revert_example() { $params = array( 'log_conn_id' => 'woot', - 'log_date' => '2016-04-06 02:52:07', + 'log_date' => '2017-02-07 02:35:06', ); try{ diff --git a/civicrm/api/v3/examples/Mailing/Create.php b/civicrm/api/v3/examples/Mailing/Create.php index 0c5410ce6f..b4bcf6f713 100644 --- a/civicrm/api/v3/examples/Mailing/Create.php +++ b/civicrm/api/v3/examples/Mailing/Create.php @@ -9,18 +9,19 @@ function mailing_create_example() { $params = array( 'subject' => 'Hello {contact.display_name}', 'body_text' => 'This is {contact.display_name}. +https://civicrm.org {domain.address}{action.optOutUrl}', - 'body_html' => '<p>This is {contact.display_name}.</p><p>{domain.address}{action.optOutUrl}</p>', + 'body_html' => '<p>This is {contact.display_name}.</p><p><a href='https://civicrm.org/'>CiviCRM.org</a></p><p>{domain.address}{action.optOutUrl}</p>', 'name' => 'mailing name', - 'created_id' => 9, + 'created_id' => 11, 'header_id' => '', 'footer_id' => '', 'groups' => array( 'include' => array( - '0' => 7, + '0' => 9, ), 'exclude' => array( - '0' => 8, + '0' => 10, ), ), 'mailings' => array( @@ -73,10 +74,10 @@ function mailing_create_expectedresult() { 'is_error' => 0, 'version' => 3, 'count' => 1, - 'id' => 4, + 'id' => 5, 'values' => array( - '4' => array( - 'id' => '4', + '5' => array( + 'id' => '5', 'domain_id' => '1', 'header_id' => '', 'footer_id' => '', @@ -93,9 +94,9 @@ function mailing_create_expectedresult() { 'template_options' => '', 'subject' => 'Hello {contact.display_name}', 'body_text' => 'This is {contact.display_name}. -https://civiÅ„crm.org +https://civicrm.org {domain.address}{action.optOutUrl}', - 'body_html' => '<p>This is {contact.display_name}.</p><p><a href=\'https://civiÅ„crm.org/\'>CiviCRM.org</a></p><p>{domain.address}{action.optOutUrl}</p>', + 'body_html' => '<p>This is {contact.display_name}.</p><p><a href=\'https://civicrm.org/\'>CiviCRM.org</a></p><p>{domain.address}{action.optOutUrl}</p>', 'url_tracking' => '1', 'forward_replies' => '', 'auto_responder' => '', @@ -103,7 +104,7 @@ https://civiÅ„crm.org 'is_completed' => '', 'msg_template_id' => '', 'override_verp' => '1', - 'created_id' => '9', + 'created_id' => '11', 'created_date' => '2013-07-28 08:49:19', 'scheduled_id' => '', 'scheduled_date' => '', @@ -119,6 +120,7 @@ https://civiÅ„crm.org 'hash' => '', 'location_type_id' => '', 'email_selection_method' => '', + 'language' => '', 'api.mailing_job.create' => array( 'is_error' => 0, 'version' => 3, @@ -127,7 +129,7 @@ https://civiÅ„crm.org 'values' => array( '0' => array( 'id' => '5', - 'mailing_id' => '4', + 'mailing_id' => '5', 'scheduled_date' => '20130728085413', 'start_date' => '', 'end_date' => '', @@ -148,9 +150,9 @@ https://civiÅ„crm.org 'values' => array( '0' => array( 'id' => '4', - 'mailing_id' => '4', - 'contact_id' => '10', - 'email_id' => '10', + 'mailing_id' => '5', + 'contact_id' => '12', + 'email_id' => '12', 'api.contact.getvalue' => 'Mr. Includer Person II', 'api.email.getvalue' => 'include.me@example.org', ), diff --git a/civicrm/api/v3/examples/Mailing/Delete.php b/civicrm/api/v3/examples/Mailing/Delete.php index d274d8c825..b7f02cbc76 100644 --- a/civicrm/api/v3/examples/Mailing/Delete.php +++ b/civicrm/api/v3/examples/Mailing/Delete.php @@ -7,7 +7,7 @@ */ function mailing_delete_example() { $params = array( - 'id' => 18, + 'id' => 20, ); try{ diff --git a/civicrm/api/v3/examples/Mailing/Submit.php b/civicrm/api/v3/examples/Mailing/Submit.php index 1b328b7e6c..ffaae8983d 100644 --- a/civicrm/api/v3/examples/Mailing/Submit.php +++ b/civicrm/api/v3/examples/Mailing/Submit.php @@ -9,7 +9,7 @@ function mailing_submit_example() { $params = array( 'scheduled_date' => '2014-12-13 10:00:00', 'approval_date' => '2014-12-13 00:00:00', - 'id' => 16, + 'id' => 18, ); try{ @@ -43,23 +43,27 @@ function mailing_submit_expectedresult() { 'is_error' => 0, 'version' => 3, 'count' => 1, - 'id' => 16, + 'id' => 18, 'values' => array( - '16' => array( - 'id' => '16', + '18' => array( + 'id' => '18', 'domain_id' => '1', 'header_id' => '', - 'footer_id' => '24', + 'footer_id' => '27', 'reply_id' => '8', 'unsubscribe_id' => '5', 'resubscribe_id' => '6', 'optout_id' => '7', 'name' => 'mailing name', + 'mailing_type' => 'standalone', 'from_name' => 'FIXME', 'from_email' => 'info@EXAMPLE.ORG', 'replyto_email' => 'info@EXAMPLE.ORG', + 'template_type' => 'traditional', + 'template_options' => '', 'subject' => 'Hello {contact.display_name}', 'body_text' => 'This is {contact.display_name}. +https://civicrm.org {domain.address}{action.optOutUrl}', 'body_html' => '<p>Look ma, magic tokens in the markup!</p>', 'url_tracking' => '1', @@ -69,11 +73,11 @@ function mailing_submit_expectedresult() { 'is_completed' => '', 'msg_template_id' => '', 'override_verp' => '1', - 'created_id' => '35', + 'created_id' => '40', 'created_date' => '2013-07-28 08:49:19', - 'scheduled_id' => '36', + 'scheduled_id' => '41', 'scheduled_date' => '20130728085413', - 'approver_id' => '36', + 'approver_id' => '41', 'approval_date' => '20130728085413', 'approval_status_id' => '1', 'approval_note' => '', @@ -83,8 +87,9 @@ function mailing_submit_expectedresult() { 'dedupe_email' => '1', 'sms_provider_id' => '', 'hash' => '67eac7789eaee00', - 'location_type_id' => 0, + 'location_type_id' => '', 'email_selection_method' => 'automatic', + 'language' => '', ), ), ); diff --git a/civicrm/api/v3/examples/MailingAB/Create.php b/civicrm/api/v3/examples/MailingAB/Create.php index e1189215f1..c7ac42c59d 100644 --- a/civicrm/api/v3/examples/MailingAB/Create.php +++ b/civicrm/api/v3/examples/MailingAB/Create.php @@ -57,11 +57,13 @@ function mailing_a_b_create_expectedresult() { 'mailing_id_b' => '2', 'mailing_id_c' => '3', 'domain_id' => '1', - 'testing_criteria_id' => '', - 'winner_criteria_id' => '', + 'testing_criteria' => 'subject', + 'winner_criteria' => 'open', 'specific_url' => '', - 'declare_winning_time' => '20150224231452', + 'declare_winning_time' => '20170209023708', 'group_percentage' => '10', + 'created_id' => '3', + 'created_date' => '2013-07-28 08:49:19', ), ), ); diff --git a/civicrm/api/v3/examples/Membership/Create.php b/civicrm/api/v3/examples/Membership/Create.php index 5f765f3f79..107c3cc7c3 100644 --- a/civicrm/api/v3/examples/Membership/Create.php +++ b/civicrm/api/v3/examples/Membership/Create.php @@ -7,14 +7,14 @@ */ function membership_create_example() { $params = array( - 'contact_id' => 76, - 'membership_type_id' => 45, + 'contact_id' => 79, + 'membership_type_id' => 47, 'join_date' => '2006-01-21', 'start_date' => '2006-01-21', 'end_date' => '2006-12-21', 'source' => 'Payment', 'is_override' => 1, - 'status_id' => 29, + 'status_id' => 30, ); try{ @@ -52,13 +52,13 @@ function membership_create_expectedresult() { 'values' => array( '1' => array( 'id' => '1', - 'contact_id' => '76', - 'membership_type_id' => '45', + 'contact_id' => '79', + 'membership_type_id' => '47', 'join_date' => '20060121000000', 'start_date' => '2013-07-29 00:00:00', 'end_date' => '2013-08-04 00:00:00', 'source' => 'Payment', - 'status_id' => '29', + 'status_id' => '30', 'is_override' => '1', 'owner_membership_id' => '', 'max_related' => '', diff --git a/civicrm/api/v3/examples/Membership/CreateWithCustomData.php b/civicrm/api/v3/examples/Membership/CreateWithCustomData.php index fe9516e663..42fa4d5b8b 100644 --- a/civicrm/api/v3/examples/Membership/CreateWithCustomData.php +++ b/civicrm/api/v3/examples/Membership/CreateWithCustomData.php @@ -7,14 +7,14 @@ */ function membership_create_example() { $params = array( - 'contact_id' => 88, - 'membership_type_id' => 53, + 'contact_id' => 91, + 'membership_type_id' => 55, 'join_date' => '2009-01-21', 'start_date' => '2009-01-21', 'end_date' => '2009-12-21', 'source' => 'Payment', 'is_override' => 1, - 'status_id' => 33, + 'status_id' => 34, 'custom_1' => 'custom string', ); @@ -53,13 +53,13 @@ function membership_create_expectedresult() { 'values' => array( '1' => array( 'id' => '1', - 'contact_id' => '88', - 'membership_type_id' => '53', + 'contact_id' => '91', + 'membership_type_id' => '55', 'join_date' => '20090121000000', 'start_date' => '2013-07-29 00:00:00', 'end_date' => '2013-08-04 00:00:00', 'source' => 'Payment', - 'status_id' => '33', + 'status_id' => '34', 'is_override' => '1', 'owner_membership_id' => '', 'max_related' => '', diff --git a/civicrm/api/v3/examples/Membership/FilterIsCurrent.php b/civicrm/api/v3/examples/Membership/FilterIsCurrent.php index 13dc628132..92109b857a 100644 --- a/civicrm/api/v3/examples/Membership/FilterIsCurrent.php +++ b/civicrm/api/v3/examples/Membership/FilterIsCurrent.php @@ -9,7 +9,7 @@ */ function membership_get_example() { $params = array( - 'contact_id' => 44, + 'contact_id' => 47, 'filters' => array( 'is_current' => 1, ), @@ -50,13 +50,13 @@ function membership_get_expectedresult() { 'values' => array( '1' => array( 'id' => '1', - 'contact_id' => '44', - 'membership_type_id' => '27', + 'contact_id' => '47', + 'membership_type_id' => '29', 'join_date' => '2009-01-21', 'start_date' => '2013-07-29 00:00:00', 'end_date' => '2013-08-04 00:00:00', 'source' => 'Payment', - 'status_id' => '21', + 'status_id' => '22', 'is_override' => '1', 'is_test' => 0, 'is_pay_later' => 0, diff --git a/civicrm/api/v3/examples/Membership/Get.php b/civicrm/api/v3/examples/Membership/Get.php index 20f24d537d..8c4fb2aed6 100644 --- a/civicrm/api/v3/examples/Membership/Get.php +++ b/civicrm/api/v3/examples/Membership/Get.php @@ -7,7 +7,7 @@ */ function membership_get_example() { $params = array( - 'membership_type_id' => 21, + 'membership_type_id' => 23, ); try{ @@ -45,19 +45,19 @@ function membership_get_expectedresult() { 'values' => array( '1' => array( 'id' => '1', - 'contact_id' => '35', - 'membership_type_id' => '21', + 'contact_id' => '38', + 'membership_type_id' => '23', 'join_date' => '2009-01-21', 'start_date' => '2013-07-29 00:00:00', 'end_date' => '2013-08-04 00:00:00', 'source' => 'Payment', - 'status_id' => '18', + 'status_id' => '19', 'is_override' => '1', 'is_test' => 0, 'is_pay_later' => 0, + 'custom_1' => 'custom string', 'membership_name' => 'General', 'relationship_name' => 'Child of', - 'custom_1' => 'custom string', 'custom_1_1' => 'custom string', ), ), diff --git a/civicrm/api/v3/examples/Membership/UpdateCustomData.php b/civicrm/api/v3/examples/Membership/UpdateCustomData.php index 1b593b34c2..f93f9d1bcd 100644 --- a/civicrm/api/v3/examples/Membership/UpdateCustomData.php +++ b/civicrm/api/v3/examples/Membership/UpdateCustomData.php @@ -7,14 +7,14 @@ */ function membership_create_example() { $params = array( - 'contact_id' => 106, - 'membership_type_id' => 65, + 'contact_id' => 112, + 'membership_type_id' => 69, 'join_date' => '2009-01-21', 'start_date' => '2009-01-21', 'end_date' => '2009-12-21', 'source' => 'Payment', 'is_override' => 1, - 'status_id' => 39, + 'status_id' => 41, 'custom_1' => 'custom string', ); @@ -53,13 +53,13 @@ function membership_create_expectedresult() { 'values' => array( '1' => array( 'id' => '1', - 'contact_id' => '106', - 'membership_type_id' => '65', + 'contact_id' => '112', + 'membership_type_id' => '69', 'join_date' => '20090121000000', 'start_date' => '2013-07-29 00:00:00', 'end_date' => '2013-08-04 00:00:00', 'source' => 'Payment', - 'status_id' => '39', + 'status_id' => '41', 'is_override' => '1', 'owner_membership_id' => '', 'max_related' => '', diff --git a/civicrm/api/v3/examples/MembershipType/Create.php b/civicrm/api/v3/examples/MembershipType/Create.php index 81cff6e5ae..1a01818506 100644 --- a/civicrm/api/v3/examples/MembershipType/Create.php +++ b/civicrm/api/v3/examples/MembershipType/Create.php @@ -9,7 +9,7 @@ function membership_type_create_example() { $params = array( 'name' => '40+ Membership', 'description' => 'people above 40 are given health instructions', - 'member_of_contact_id' => 13, + 'member_of_contact_id' => 7, 'financial_type_id' => 1, 'domain_id' => '1', 'minimum_fee' => '200', @@ -57,7 +57,7 @@ function membership_type_create_expectedresult() { 'domain_id' => '1', 'name' => '40+ Membership', 'description' => 'people above 40 are given health instructions', - 'member_of_contact_id' => '13', + 'member_of_contact_id' => '7', 'financial_type_id' => '1', 'minimum_fee' => '200', 'duration_unit' => 'month', diff --git a/civicrm/api/v3/examples/MembershipType/Get.php b/civicrm/api/v3/examples/MembershipType/Get.php index f111b04bd4..e9904be804 100644 --- a/civicrm/api/v3/examples/MembershipType/Get.php +++ b/civicrm/api/v3/examples/MembershipType/Get.php @@ -48,7 +48,7 @@ function membership_type_get_expectedresult() { 'domain_id' => '1', 'name' => 'General', 'member_of_contact_id' => '4', - 'financial_type_id' => '1', + 'financial_type_id' => '2', 'minimum_fee' => '0.00', 'duration_unit' => 'year', 'duration_interval' => '1', @@ -56,6 +56,7 @@ function membership_type_get_expectedresult() { 'visibility' => 'Public', 'auto_renew' => 0, 'is_active' => '1', + 'contribution_type_id' => '2', ), ), ); diff --git a/civicrm/api/v3/examples/MessageTemplate/Create.php b/civicrm/api/v3/examples/MessageTemplate/Create.php index 0941182339..7f2f51393b 100644 --- a/civicrm/api/v3/examples/MessageTemplate/Create.php +++ b/civicrm/api/v3/examples/MessageTemplate/Create.php @@ -7,11 +7,11 @@ */ function message_template_create_example() { $params = array( - 'msg_title' => 'msg_title_165', - 'msg_subject' => 'msg_subject_165', - 'msg_text' => 'msg_text_165', - 'msg_html' => 'msg_html_165', - 'workflow_id' => 165, + 'msg_title' => 'msg_title_284', + 'msg_subject' => 'msg_subject_284', + 'msg_text' => 'msg_text_284', + 'msg_html' => 'msg_html_284', + 'workflow_id' => 284, 'is_default' => '1', 'is_reserved' => 1, ); @@ -47,16 +47,16 @@ function message_template_create_expectedresult() { 'is_error' => 0, 'version' => 3, 'count' => 1, - 'id' => 67, + 'id' => 69, 'values' => array( - '67' => array( - 'id' => '67', - 'msg_title' => 'msg_title_165', - 'msg_subject' => 'msg_subject_165', - 'msg_text' => 'msg_text_165', - 'msg_html' => 'msg_html_165', + '69' => array( + 'id' => '69', + 'msg_title' => 'msg_title_284', + 'msg_subject' => 'msg_subject_284', + 'msg_text' => 'msg_text_284', + 'msg_html' => 'msg_html_284', 'is_active' => '1', - 'workflow_id' => '165', + 'workflow_id' => '284', 'is_default' => '1', 'is_reserved' => '1', 'is_sms' => '', diff --git a/civicrm/api/v3/examples/MessageTemplate/Delete.php b/civicrm/api/v3/examples/MessageTemplate/Delete.php index 1d47b6f0c8..388e12c2ae 100644 --- a/civicrm/api/v3/examples/MessageTemplate/Delete.php +++ b/civicrm/api/v3/examples/MessageTemplate/Delete.php @@ -7,7 +7,7 @@ */ function message_template_delete_example() { $params = array( - 'id' => 70, + 'id' => 72, ); try{ diff --git a/civicrm/api/v3/examples/MessageTemplate/Get.php b/civicrm/api/v3/examples/MessageTemplate/Get.php index d3ab1005bc..318d8aada3 100644 --- a/civicrm/api/v3/examples/MessageTemplate/Get.php +++ b/civicrm/api/v3/examples/MessageTemplate/Get.php @@ -7,11 +7,11 @@ */ function message_template_get_example() { $params = array( - 'msg_title' => 'msg_title_166', - 'msg_subject' => 'msg_subject_166', - 'msg_text' => 'msg_text_166', - 'msg_html' => 'msg_html_166', - 'workflow_id' => 166, + 'msg_title' => 'msg_title_285', + 'msg_subject' => 'msg_subject_285', + 'msg_text' => 'msg_text_285', + 'msg_html' => 'msg_html_285', + 'workflow_id' => 285, 'is_default' => '1', 'is_reserved' => 1, ); @@ -47,20 +47,20 @@ function message_template_get_expectedresult() { 'is_error' => 0, 'version' => 3, 'count' => 1, - 'id' => 68, + 'id' => 70, 'values' => array( - '68' => array( - 'id' => '68', - 'msg_title' => 'msg_title_166', - 'msg_subject' => 'msg_subject_166', - 'msg_text' => 'msg_text_166', - 'msg_html' => 'msg_html_166', + '70' => array( + 'id' => '70', + 'msg_title' => 'msg_title_285', + 'msg_subject' => 'msg_subject_285', + 'msg_text' => 'msg_text_285', + 'msg_html' => 'msg_html_285', 'is_active' => '1', - 'workflow_id' => '166', + 'workflow_id' => '285', 'is_default' => '1', 'is_reserved' => '1', 'is_sms' => '1', - 'pdf_format_id' => '166', + 'pdf_format_id' => '285', ), ), ); diff --git a/civicrm/api/v3/examples/OptionGroup/Create.php b/civicrm/api/v3/examples/OptionGroup/Create.php index 7220e3db6e..cee25ba50b 100644 --- a/civicrm/api/v3/examples/OptionGroup/Create.php +++ b/civicrm/api/v3/examples/OptionGroup/Create.php @@ -51,17 +51,18 @@ function option_group_create_expectedresult() { 'is_error' => 0, 'version' => 3, 'count' => 1, - 'id' => 93, + 'id' => 92, 'values' => array( '0' => array( - 'id' => '93', + 'id' => '92', 'name' => 'civicrm_event.amount.560', 'title' => '', 'description' => '', + 'data_type' => '', 'is_reserved' => '1', 'is_active' => '1', 'is_locked' => '', - 'api.OptionValue.create' => 784, + 'api.OptionValue.create' => 849, ), ), ); diff --git a/civicrm/api/v3/examples/OptionGroup/Delete.php b/civicrm/api/v3/examples/OptionGroup/Delete.php index cdf194ec75..20839505b8 100644 --- a/civicrm/api/v3/examples/OptionGroup/Delete.php +++ b/civicrm/api/v3/examples/OptionGroup/Delete.php @@ -7,7 +7,7 @@ */ function option_group_delete_example() { $params = array( - 'id' => 98, + 'id' => 97, ); try{ diff --git a/civicrm/api/v3/examples/Order/Cancel.php b/civicrm/api/v3/examples/Order/Cancel.php index 30f5aad2c5..2e6ea262ca 100644 --- a/civicrm/api/v3/examples/Order/Cancel.php +++ b/civicrm/api/v3/examples/Order/Cancel.php @@ -45,7 +45,7 @@ function order_cancel_expectedresult() { 'values' => array( '1' => array( 'id' => '1', - 'contact_id' => '14', + 'contact_id' => '16', 'financial_type_id' => '1', 'contribution_page_id' => '', 'payment_instrument_id' => '4', diff --git a/civicrm/api/v3/examples/Order/Create.php b/civicrm/api/v3/examples/Order/Create.php index 45ea551fcd..264b1493bd 100644 --- a/civicrm/api/v3/examples/Order/Create.php +++ b/civicrm/api/v3/examples/Order/Create.php @@ -7,7 +7,7 @@ */ function order_create_example() { $params = array( - 'contact_id' => 7, + 'contact_id' => 8, 'receive_date' => '2010-01-20', 'total_amount' => 200, 'financial_type_id' => 1, @@ -29,7 +29,7 @@ function order_create_example() { ), ), 'params' => array( - 'contact_id' => 7, + 'contact_id' => 8, 'membership_type_id' => 2, 'join_date' => '2006-01-21', 'start_date' => '2006-01-21', @@ -77,7 +77,7 @@ function order_create_expectedresult() { 'values' => array( '1' => array( 'id' => '1', - 'contact_id' => '7', + 'contact_id' => '8', 'financial_type_id' => '1', 'contribution_page_id' => '', 'payment_instrument_id' => '4', diff --git a/civicrm/api/v3/examples/Order/CreateOrderParticipant.php b/civicrm/api/v3/examples/Order/CreateOrderParticipant.php index aa65ab5fd0..b1a8a10401 100644 --- a/civicrm/api/v3/examples/Order/CreateOrderParticipant.php +++ b/civicrm/api/v3/examples/Order/CreateOrderParticipant.php @@ -9,7 +9,7 @@ */ function order_create_example() { $params = array( - 'contact_id' => 10, + 'contact_id' => 11, 'receive_date' => '2010-01-20', 'total_amount' => 300, 'financial_type_id' => 1, @@ -41,7 +41,7 @@ function order_create_example() { ), ), 'params' => array( - 'contact_id' => 10, + 'contact_id' => 11, 'event_id' => 1, 'status_id' => 1, 'role_id' => 1, @@ -87,7 +87,7 @@ function order_create_expectedresult() { 'values' => array( '1' => array( 'id' => '1', - 'contact_id' => '10', + 'contact_id' => '11', 'financial_type_id' => '1', 'contribution_page_id' => '', 'payment_instrument_id' => '4', diff --git a/civicrm/api/v3/examples/Order/Get.php b/civicrm/api/v3/examples/Order/Get.php index 10a3c2c849..720596c3d7 100644 --- a/civicrm/api/v3/examples/Order/Get.php +++ b/civicrm/api/v3/examples/Order/Get.php @@ -64,10 +64,11 @@ function order_get_expectedresult() { 'thankyou_date' => '', 'contribution_source' => '', 'amount_level' => '', + 'contribution_recur_id' => '', 'is_test' => 0, 'is_pay_later' => 0, 'contribution_status_id' => '1', - 'check_number' => '', + 'contribution_check_number' => '', 'contribution_campaign_id' => '', 'financial_type_id' => '1', 'financial_type' => 'Donation', @@ -79,7 +80,6 @@ function order_get_expectedresult() { 'fulfilled_date' => '', 'contribution_start_date' => '', 'contribution_end_date' => '', - 'contribution_recur_id' => '', 'financial_account_id' => '1', 'accounting_code' => '4200', 'campaign_id' => '', @@ -90,7 +90,7 @@ function order_get_expectedresult() { 'payment_instrument' => 'Check', 'payment_instrument_id' => '4', 'instrument_id' => '4', - 'contribution_check_number' => '', + 'check_number' => '', 'id' => '1', 'contribution_type_id' => '1', 'line_items' => array( @@ -106,7 +106,8 @@ function order_get_expectedresult() { 'line_total' => '100.00', 'price_field_value_id' => '1', 'financial_type_id' => '1', - 'deductible_amount' => '0.00', + 'non_deductible_amount' => '0.00', + 'contribution_type_id' => '1', ), ), ), diff --git a/civicrm/api/v3/examples/Participant/Create.php b/civicrm/api/v3/examples/Participant/Create.php index 8ab8b98dda..15aa07367e 100644 --- a/civicrm/api/v3/examples/Participant/Create.php +++ b/civicrm/api/v3/examples/Participant/Create.php @@ -7,8 +7,8 @@ */ function participant_create_example() { $params = array( - 'contact_id' => 4, - 'event_id' => 1, + 'contact_id' => 2, + 'event_id' => 2, 'status_id' => 1, 'role_id' => 1, 'register_date' => '2007-07-21 00:00:00', @@ -51,8 +51,8 @@ function participant_create_expectedresult() { 'values' => array( '4' => array( 'id' => '4', - 'contact_id' => '4', - 'event_id' => '1', + 'contact_id' => '2', + 'event_id' => '2', 'status_id' => '1', 'role_id' => '1', 'register_date' => '20070721000000', diff --git a/civicrm/api/v3/examples/Participant/Get.php b/civicrm/api/v3/examples/Participant/Get.php index 1e06e9540e..52ad6116ac 100644 --- a/civicrm/api/v3/examples/Participant/Get.php +++ b/civicrm/api/v3/examples/Participant/Get.php @@ -49,7 +49,7 @@ function participant_get_expectedresult() { 'contact_sub_type' => '', 'sort_name' => 'Anderson, Anthony', 'display_name' => 'Mr. Anthony Anderson II', - 'event_id' => '5', + 'event_id' => '6', 'event_title' => 'Annual CiviCRM meet', 'event_start_date' => '2013-07-29 00:00:00', 'event_end_date' => '2013-08-04 00:00:00', @@ -60,8 +60,8 @@ function participant_get_expectedresult() { 'event_type' => 'Conference', 'participant_status_id' => '2', 'participant_status' => 'Attended', - 'participant_role' => 'Attendee', 'participant_role_id' => '1', + 'participant_role' => 'Attendee', 'participant_register_date' => '2007-02-19 00:00:00', 'participant_source' => 'Wimbeldon', 'participant_note' => '', diff --git a/civicrm/api/v3/examples/Participant/NestedDelete.php b/civicrm/api/v3/examples/Participant/NestedDelete.php index b9429731c7..37555e4beb 100644 --- a/civicrm/api/v3/examples/Participant/NestedDelete.php +++ b/civicrm/api/v3/examples/Participant/NestedDelete.php @@ -51,7 +51,7 @@ function participant_get_expectedresult() { 'contact_sub_type' => '', 'sort_name' => 'Anderson, Anthony', 'display_name' => 'Mr. Anthony Anderson II', - 'event_id' => '39', + 'event_id' => '41', 'event_title' => 'Annual CiviCRM meet', 'event_start_date' => '2013-07-29 00:00:00', 'event_end_date' => '2013-08-04 00:00:00', @@ -62,14 +62,14 @@ function participant_get_expectedresult() { 'event_type' => 'Conference', 'participant_status_id' => '2', 'participant_status' => 'Attended', - 'participant_role' => 'Attendee', 'participant_role_id' => '1', + 'participant_role' => 'Attendee', 'participant_register_date' => '2007-02-19 00:00:00', 'participant_source' => 'Wimbeldon', 'participant_note' => '', 'participant_is_pay_later' => 0, 'participant_is_test' => 0, - 'participant_registered_by_id' => '', + 'participant_registered_by_id' => '1', 'participant_discount_name' => '', 'participant_campaign_id' => '', 'id' => '2', @@ -86,7 +86,7 @@ function participant_get_expectedresult() { 'contact_sub_type' => '', 'sort_name' => 'Anderson, Anthony', 'display_name' => 'Mr. Anthony Anderson II', - 'event_id' => '39', + 'event_id' => '41', 'event_title' => 'Annual CiviCRM meet', 'event_start_date' => '2013-07-29 00:00:00', 'event_end_date' => '2013-08-04 00:00:00', @@ -97,8 +97,8 @@ function participant_get_expectedresult() { 'event_type' => 'Conference', 'participant_status_id' => '2', 'participant_status' => 'Attended', - 'participant_role' => 'Attendee', 'participant_role_id' => '1', + 'participant_role' => 'Attendee', 'participant_register_date' => '2007-02-19 00:00:00', 'participant_source' => 'Wimbeldon', 'participant_note' => '', diff --git a/civicrm/api/v3/examples/Participant/NestedEventGet.php b/civicrm/api/v3/examples/Participant/NestedEventGet.php index 78f22366da..c6b335e63d 100644 --- a/civicrm/api/v3/examples/Participant/NestedEventGet.php +++ b/civicrm/api/v3/examples/Participant/NestedEventGet.php @@ -52,7 +52,7 @@ function participant_get_expectedresult() { 'contact_sub_type' => '', 'sort_name' => 'Anderson, Anthony', 'display_name' => 'Mr. Anthony Anderson II', - 'event_id' => '6', + 'event_id' => '7', 'event_title' => 'Annual CiviCRM meet', 'event_start_date' => '2013-07-29 00:00:00', 'event_end_date' => '2013-08-04 00:00:00', @@ -63,8 +63,8 @@ function participant_get_expectedresult() { 'event_type' => 'Conference', 'participant_status_id' => '2', 'participant_status' => 'Attended', - 'participant_role' => 'Attendee', 'participant_role_id' => '1', + 'participant_role' => 'Attendee', 'participant_register_date' => '2007-02-19 00:00:00', 'participant_source' => 'Wimbeldon', 'participant_note' => '', @@ -78,10 +78,10 @@ function participant_get_expectedresult() { 'is_error' => 0, 'version' => 3, 'count' => 1, - 'id' => 6, + 'id' => 7, 'values' => array( '0' => array( - 'id' => '6', + 'id' => '7', 'title' => 'Annual CiviCRM meet', 'event_title' => 'Annual CiviCRM meet', 'summary' => 'If you have any CiviCRM related issues or want to track where CiviCRM is heading, Sign up now', diff --git a/civicrm/api/v3/examples/ParticipantStatusType/Create.php b/civicrm/api/v3/examples/ParticipantStatusType/Create.php index 96a4481c51..9059a8b322 100644 --- a/civicrm/api/v3/examples/ParticipantStatusType/Create.php +++ b/civicrm/api/v3/examples/ParticipantStatusType/Create.php @@ -48,10 +48,10 @@ function participant_status_type_create_expectedresult() { 'is_error' => 0, 'version' => 3, 'count' => 1, - 'id' => 17, + 'id' => 18, 'values' => array( - '17' => array( - 'id' => '17', + '18' => array( + 'id' => '18', 'name' => 'test status', 'label' => 'I am a test', 'class' => 'Positive', diff --git a/civicrm/api/v3/examples/ParticipantStatusType/Delete.php b/civicrm/api/v3/examples/ParticipantStatusType/Delete.php index 258aa4af10..ae4fa45657 100644 --- a/civicrm/api/v3/examples/ParticipantStatusType/Delete.php +++ b/civicrm/api/v3/examples/ParticipantStatusType/Delete.php @@ -7,7 +7,7 @@ */ function participant_status_type_delete_example() { $params = array( - 'id' => 18, + 'id' => 19, ); try{ diff --git a/civicrm/api/v3/examples/ParticipantStatusType/Get.php b/civicrm/api/v3/examples/ParticipantStatusType/Get.php index 318d9b5e79..7eb41e6d0f 100644 --- a/civicrm/api/v3/examples/ParticipantStatusType/Get.php +++ b/civicrm/api/v3/examples/ParticipantStatusType/Get.php @@ -48,10 +48,10 @@ function participant_status_type_get_expectedresult() { 'is_error' => 0, 'version' => 3, 'count' => 1, - 'id' => 17, + 'id' => 18, 'values' => array( - '17' => array( - 'id' => '17', + '18' => array( + 'id' => '18', 'name' => 'test status', 'label' => 'I am a test', 'class' => 'Positive', diff --git a/civicrm/api/v3/examples/Payment/Cancel.php b/civicrm/api/v3/examples/Payment/Cancel.php index bd71ea4426..84e18f4407 100644 --- a/civicrm/api/v3/examples/Payment/Cancel.php +++ b/civicrm/api/v3/examples/Payment/Cancel.php @@ -20,7 +20,8 @@ function payment_cancel_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); @@ -47,7 +48,7 @@ function payment_cancel_expectedresult() { 'id' => 3, 'from_financial_account_id' => '7', 'to_financial_account_id' => '6', - 'trxn_date' => '20160217204840', + 'trxn_date' => '20170207024650', 'total_amount' => '-150', 'fee_amount' => '0.00', 'net_amount' => '150.00', diff --git a/civicrm/api/v3/examples/Payment/Create.php b/civicrm/api/v3/examples/Payment/Create.php index 4a8efaae33..6ece14b33a 100644 --- a/civicrm/api/v3/examples/Payment/Create.php +++ b/civicrm/api/v3/examples/Payment/Create.php @@ -20,7 +20,8 @@ function payment_create_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); @@ -47,7 +48,7 @@ function payment_create_expectedresult() { 'id' => '3', 'from_financial_account_id' => '7', 'to_financial_account_id' => '6', - 'trxn_date' => '20160217204833', + 'trxn_date' => '20170207024646', 'total_amount' => '50', 'fee_amount' => '', 'net_amount' => '50', diff --git a/civicrm/api/v3/examples/Payment/CreatePaymentWithLineItems.php b/civicrm/api/v3/examples/Payment/CreatePaymentWithLineItems.php index b9a9b971c1..f2b1613a61 100644 --- a/civicrm/api/v3/examples/Payment/CreatePaymentWithLineItems.php +++ b/civicrm/api/v3/examples/Payment/CreatePaymentWithLineItems.php @@ -30,7 +30,8 @@ function payment_create_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); @@ -57,7 +58,7 @@ function payment_create_expectedresult() { 'id' => '3', 'from_financial_account_id' => '7', 'to_financial_account_id' => '6', - 'trxn_date' => '20160217204836', + 'trxn_date' => '20170207024648', 'total_amount' => '50', 'fee_amount' => '', 'net_amount' => '50', diff --git a/civicrm/api/v3/examples/Payment/Delete.php b/civicrm/api/v3/examples/Payment/Delete.php index c5be86b58c..51bc8727f9 100644 --- a/civicrm/api/v3/examples/Payment/Delete.php +++ b/civicrm/api/v3/examples/Payment/Delete.php @@ -20,7 +20,8 @@ function payment_delete_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); diff --git a/civicrm/api/v3/examples/Payment/Get.php b/civicrm/api/v3/examples/Payment/Get.php index c56d91ec57..ac1263d504 100644 --- a/civicrm/api/v3/examples/Payment/Get.php +++ b/civicrm/api/v3/examples/Payment/Get.php @@ -20,7 +20,8 @@ function payment_get_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); diff --git a/civicrm/api/v3/examples/Payment/UpdatePayment.php b/civicrm/api/v3/examples/Payment/UpdatePayment.php index d240cbfe2e..81e017e223 100644 --- a/civicrm/api/v3/examples/Payment/UpdatePayment.php +++ b/civicrm/api/v3/examples/Payment/UpdatePayment.php @@ -24,7 +24,8 @@ function payment_create_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); @@ -51,7 +52,7 @@ function payment_create_expectedresult() { 'id' => '5', 'from_financial_account_id' => '7', 'to_financial_account_id' => '6', - 'trxn_date' => '20160217204847', + 'trxn_date' => '20170207024653', 'total_amount' => '100', 'fee_amount' => '', 'net_amount' => '100', diff --git a/civicrm/api/v3/examples/PaymentProcessor/Create.php b/civicrm/api/v3/examples/PaymentProcessor/Create.php index 7d911e279a..aa481f9fbc 100644 --- a/civicrm/api/v3/examples/PaymentProcessor/Create.php +++ b/civicrm/api/v3/examples/PaymentProcessor/Create.php @@ -52,7 +52,7 @@ function payment_processor_create_expectedresult() { 'domain_id' => '1', 'name' => 'API Test PP', 'description' => '', - 'payment_processor_type_id' => '18', + 'payment_processor_type_id' => '1', 'is_active' => '', 'is_default' => 0, 'is_test' => 0, @@ -68,6 +68,8 @@ function payment_processor_create_expectedresult() { 'billing_mode' => '1', 'is_recur' => 0, 'payment_type' => '1', + 'payment_instrument_id' => '1', + 'accepted_credit_cards' => '', ), ), ); diff --git a/civicrm/api/v3/examples/PaymentProcessor/Delete.php b/civicrm/api/v3/examples/PaymentProcessor/Delete.php index d726926a9a..a633f4c4bf 100644 --- a/civicrm/api/v3/examples/PaymentProcessor/Delete.php +++ b/civicrm/api/v3/examples/PaymentProcessor/Delete.php @@ -19,7 +19,8 @@ function payment_processor_delete_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); @@ -40,7 +41,7 @@ function payment_processor_delete_expectedresult() { 'is_error' => 0, 'version' => 3, 'count' => 1, - 'values' => TRUE, + 'values' => 1, ); return $expectedResult; diff --git a/civicrm/api/v3/examples/PaymentProcessorType/Create.php b/civicrm/api/v3/examples/PaymentProcessorType/Create.php index d7803ec404..d6fc4c1e14 100644 --- a/civicrm/api/v3/examples/PaymentProcessorType/Create.php +++ b/civicrm/api/v3/examples/PaymentProcessorType/Create.php @@ -24,7 +24,8 @@ function payment_processor_type_create_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); @@ -45,10 +46,10 @@ function payment_processor_type_create_expectedresult() { 'is_error' => 0, 'version' => 3, 'count' => 1, - 'id' => 15, + 'id' => 13, 'values' => array( '0' => array( - 'id' => '15', + 'id' => '13', 'name' => 'API_Test_PP', 'title' => 'API Test Payment Processor', 'description' => '', @@ -70,6 +71,7 @@ function payment_processor_type_create_expectedresult() { 'billing_mode' => '1', 'is_recur' => 0, 'payment_type' => '', + 'payment_instrument_id' => '1', ), ), ); diff --git a/civicrm/api/v3/examples/PaymentProcessorType/Delete.php b/civicrm/api/v3/examples/PaymentProcessorType/Delete.php index 49ac762dd3..d5a6c6d5b0 100644 --- a/civicrm/api/v3/examples/PaymentProcessorType/Delete.php +++ b/civicrm/api/v3/examples/PaymentProcessorType/Delete.php @@ -7,7 +7,7 @@ */ function payment_processor_type_delete_example() { $params = array( - 'id' => 17, + 'id' => 15, ); try{ @@ -19,7 +19,8 @@ function payment_processor_type_delete_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); diff --git a/civicrm/api/v3/examples/PaymentToken/Create.php b/civicrm/api/v3/examples/PaymentToken/Create.php new file mode 100644 index 0000000000..854c185c46 --- /dev/null +++ b/civicrm/api/v3/examples/PaymentToken/Create.php @@ -0,0 +1,93 @@ +<?php +/** + * Test Generated example demonstrating the PaymentToken.create API. + * + * Create a payment token - Note use of relative dates here: + * @link http://www.php.net/manual/en/datetime.formats.relative.php. + * + * @return array + * API result array + */ +function payment_token_create_example() { + $params = array( + 'token' => 'fancy-token-xxxx', + 'contact_id' => 3, + 'created_id' => 3, + 'payment_processor_id' => 1, + ); + + try{ + $result = civicrm_api3('PaymentToken', 'create', $params); + } + catch (CiviCRM_API3_Exception $e) { + // Handle error here. + $errorMessage = $e->getMessage(); + $errorCode = $e->getErrorCode(); + $errorData = $e->getExtraParams(); + return array( + 'is_error' => 1, + 'error_message' => $errorMessage, + 'error_code' => $errorCode, + 'error_data' => $errorData, + ); + } + + return $result; +} + +/** + * Function returns array of result expected from previous function. + * + * @return array + * API result array + */ +function payment_token_create_expectedresult() { + + $expectedResult = array( + 'is_error' => 0, + 'version' => 3, + 'count' => 1, + 'id' => 1, + 'values' => array( + '1' => array( + 'id' => '1', + 'contact_id' => '3', + 'payment_processor_id' => '1', + 'token' => 'fancy-token-xxxx', + 'created_date' => '2013-07-28 08:49:19', + 'created_id' => '3', + 'expiry_date' => '', + 'email' => '', + 'billing_first_name' => '', + 'billing_middle_name' => '', + 'billing_last_name' => '', + 'masked_account_number' => '', + 'ip_address' => '', + ), + ), + ); + + return $expectedResult; +} + +/* +* This example has been generated from the API test suite. +* The test that created it is called "testCreatePaymentToken" +* and can be found at: +* https://github.com/civicrm/civicrm-core/blob/master/tests/phpunit/api/v3/PaymentTokenTest.php +* +* You can see the outcome of the API tests at +* https://test.civicrm.org/job/CiviCRM-master-git/ +* +* To Learn about the API read +* http://wiki.civicrm.org/confluence/display/CRMDOC/Using+the+API +* +* Browse the api on your own site with the api explorer +* http://MYSITE.ORG/path/to/civicrm/api +* +* Read more about testing here +* http://wiki.civicrm.org/confluence/display/CRM/Testing +* +* API Standards documentation: +* http://wiki.civicrm.org/confluence/display/CRM/API+Architecture+Standards +*/ diff --git a/civicrm/api/v3/examples/PaymentToken/Delete.php b/civicrm/api/v3/examples/PaymentToken/Delete.php new file mode 100644 index 0000000000..460d6ad136 --- /dev/null +++ b/civicrm/api/v3/examples/PaymentToken/Delete.php @@ -0,0 +1,70 @@ +<?php +/** + * Test Generated example demonstrating the PaymentToken.delete API. + * + * @return array + * API result array + */ +function payment_token_delete_example() { + $params = array( + 'id' => 3, + ); + + try{ + $result = civicrm_api3('PaymentToken', 'delete', $params); + } + catch (CiviCRM_API3_Exception $e) { + // Handle error here. + $errorMessage = $e->getMessage(); + $errorCode = $e->getErrorCode(); + $errorData = $e->getExtraParams(); + return array( + 'is_error' => 1, + 'error_message' => $errorMessage, + 'error_code' => $errorCode, + 'error_data' => $errorData, + ); + } + + return $result; +} + +/** + * Function returns array of result expected from previous function. + * + * @return array + * API result array + */ +function payment_token_delete_expectedresult() { + + $expectedResult = array( + 'is_error' => 0, + 'version' => 3, + 'count' => 1, + 'values' => 1, + ); + + return $expectedResult; +} + +/* +* This example has been generated from the API test suite. +* The test that created it is called "testDeletePaymentToken" +* and can be found at: +* https://github.com/civicrm/civicrm-core/blob/master/tests/phpunit/api/v3/PaymentTokenTest.php +* +* You can see the outcome of the API tests at +* https://test.civicrm.org/job/CiviCRM-master-git/ +* +* To Learn about the API read +* http://wiki.civicrm.org/confluence/display/CRMDOC/Using+the+API +* +* Browse the api on your own site with the api explorer +* http://MYSITE.ORG/path/to/civicrm/api +* +* Read more about testing here +* http://wiki.civicrm.org/confluence/display/CRM/Testing +* +* API Standards documentation: +* http://wiki.civicrm.org/confluence/display/CRM/API+Architecture+Standards +*/ diff --git a/civicrm/api/v3/examples/PaymentToken/Get.php b/civicrm/api/v3/examples/PaymentToken/Get.php new file mode 100644 index 0000000000..101c847b40 --- /dev/null +++ b/civicrm/api/v3/examples/PaymentToken/Get.php @@ -0,0 +1,83 @@ +<?php +/** + * Test Generated example demonstrating the PaymentToken.get API. + * + * @return array + * API result array + */ +function payment_token_get_example() { + $params = array( + 'token' => 'fancy-token-xxxx', + 'contact_id' => 4, + 'created_id' => 4, + 'payment_processor_id' => 2, + ); + + try{ + $result = civicrm_api3('PaymentToken', 'get', $params); + } + catch (CiviCRM_API3_Exception $e) { + // Handle error here. + $errorMessage = $e->getMessage(); + $errorCode = $e->getErrorCode(); + $errorData = $e->getExtraParams(); + return array( + 'is_error' => 1, + 'error_message' => $errorMessage, + 'error_code' => $errorCode, + 'error_data' => $errorData, + ); + } + + return $result; +} + +/** + * Function returns array of result expected from previous function. + * + * @return array + * API result array + */ +function payment_token_get_expectedresult() { + + $expectedResult = array( + 'is_error' => 0, + 'version' => 3, + 'count' => 1, + 'id' => 2, + 'values' => array( + '2' => array( + 'id' => '2', + 'contact_id' => '4', + 'payment_processor_id' => '2', + 'token' => 'fancy-token-xxxx', + 'created_date' => '2013-07-28 08:49:19', + 'created_id' => '4', + ), + ), + ); + + return $expectedResult; +} + +/* +* This example has been generated from the API test suite. +* The test that created it is called "testGetPaymentToken" +* and can be found at: +* https://github.com/civicrm/civicrm-core/blob/master/tests/phpunit/api/v3/PaymentTokenTest.php +* +* You can see the outcome of the API tests at +* https://test.civicrm.org/job/CiviCRM-master-git/ +* +* To Learn about the API read +* http://wiki.civicrm.org/confluence/display/CRMDOC/Using+the+API +* +* Browse the api on your own site with the api explorer +* http://MYSITE.ORG/path/to/civicrm/api +* +* Read more about testing here +* http://wiki.civicrm.org/confluence/display/CRM/Testing +* +* API Standards documentation: +* http://wiki.civicrm.org/confluence/display/CRM/API+Architecture+Standards +*/ diff --git a/civicrm/api/v3/examples/Pcp/Create.php b/civicrm/api/v3/examples/Pcp/Create.php new file mode 100644 index 0000000000..d3481c70a9 --- /dev/null +++ b/civicrm/api/v3/examples/Pcp/Create.php @@ -0,0 +1,93 @@ +<?php +/** + * Test Generated example demonstrating the Pcp.create API. + * + * @return array + * API result array + */ +function pcp_create_example() { + $params = array( + 'title' => 'Pcp title', + 'contact_id' => 1, + 'page_id' => 1, + 'pcp_block_id' => 1, + ); + + try{ + $result = civicrm_api3('Pcp', 'create', $params); + } + catch (CiviCRM_API3_Exception $e) { + // Handle error here. + $errorMessage = $e->getMessage(); + $errorCode = $e->getErrorCode(); + $errorData = $e->getExtraParams(); + return array( + 'is_error' => 1, + 'error_message' => $errorMessage, + 'error_code' => $errorCode, + 'error_data' => $errorData, + ); + } + + return $result; +} + +/** + * Function returns array of result expected from previous function. + * + * @return array + * API result array + */ +function pcp_create_expectedresult() { + + $expectedResult = array( + 'is_error' => 0, + 'version' => 3, + 'count' => 1, + 'id' => 1, + 'values' => array( + '1' => array( + 'id' => '1', + 'contact_id' => '1', + 'status_id' => 0, + 'title' => 'Pcp title', + 'intro_text' => '', + 'page_text' => '', + 'donate_link_text' => '', + 'page_id' => '1', + 'page_type' => '', + 'pcp_block_id' => '1', + 'is_thermometer' => '', + 'is_honor_roll' => '', + 'goal_amount' => '', + 'currency' => 'USD', + 'is_active' => '', + 'is_notify' => '', + ), + ), + ); + + return $expectedResult; +} + +/* +* This example has been generated from the API test suite. +* The test that created it is called "testCreatePcp" +* and can be found at: +* https://github.com/civicrm/civicrm-core/blob/master/tests/phpunit/api/v3/PcpTest.php +* +* You can see the outcome of the API tests at +* https://test.civicrm.org/job/CiviCRM-master-git/ +* +* To Learn about the API read +* http://wiki.civicrm.org/confluence/display/CRMDOC/Using+the+API +* +* Browse the api on your own site with the api explorer +* http://MYSITE.ORG/path/to/civicrm/api +* +* Read more about testing here +* http://wiki.civicrm.org/confluence/display/CRM/Testing +* +* API Standards documentation: +* http://wiki.civicrm.org/confluence/display/CRM/API+Architecture+Standards +*/ diff --git a/civicrm/api/v3/examples/Phone/Create.php b/civicrm/api/v3/examples/Phone/Create.php index ea022ea735..384cf28e1f 100644 --- a/civicrm/api/v3/examples/Phone/Create.php +++ b/civicrm/api/v3/examples/Phone/Create.php @@ -23,7 +23,8 @@ function phone_create_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); diff --git a/civicrm/api/v3/examples/Phone/Delete.php b/civicrm/api/v3/examples/Phone/Delete.php index 363998ab9b..6f4b97e22a 100644 --- a/civicrm/api/v3/examples/Phone/Delete.php +++ b/civicrm/api/v3/examples/Phone/Delete.php @@ -19,7 +19,8 @@ function phone_delete_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); @@ -40,7 +41,7 @@ function phone_delete_expectedresult() { 'is_error' => 0, 'version' => 3, 'count' => 1, - 'values' => TRUE, + 'values' => 1, ); return $expectedResult; diff --git a/civicrm/api/v3/examples/Phone/Get.php b/civicrm/api/v3/examples/Phone/Get.php index f22274d9e2..ef1a0794c9 100644 --- a/civicrm/api/v3/examples/Phone/Get.php +++ b/civicrm/api/v3/examples/Phone/Get.php @@ -20,7 +20,8 @@ function phone_get_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); diff --git a/civicrm/api/v3/examples/Pledge/Create.php b/civicrm/api/v3/examples/Pledge/Create.php index 6bd0f386de..c138d72251 100644 --- a/civicrm/api/v3/examples/Pledge/Create.php +++ b/civicrm/api/v3/examples/Pledge/Create.php @@ -8,9 +8,9 @@ function pledge_create_example() { $params = array( 'contact_id' => 11, - 'pledge_create_date' => '20150222', - 'start_date' => '20150222', - 'scheduled_date' => '20150224', + 'pledge_create_date' => '20170207', + 'start_date' => '20170207', + 'scheduled_date' => '20170209', 'amount' => '100', 'pledge_status_id' => '2', 'pledge_financial_type_id' => '1', @@ -31,7 +31,8 @@ function pledge_create_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); diff --git a/civicrm/api/v3/examples/Pledge/Delete.php b/civicrm/api/v3/examples/Pledge/Delete.php index 02b53fdf62..17e4780458 100644 --- a/civicrm/api/v3/examples/Pledge/Delete.php +++ b/civicrm/api/v3/examples/Pledge/Delete.php @@ -19,7 +19,8 @@ function pledge_delete_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); diff --git a/civicrm/api/v3/examples/Pledge/Get.php b/civicrm/api/v3/examples/Pledge/Get.php index 0ac2a32645..541ca67466 100644 --- a/civicrm/api/v3/examples/Pledge/Get.php +++ b/civicrm/api/v3/examples/Pledge/Get.php @@ -19,7 +19,8 @@ function pledge_get_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); @@ -50,10 +51,11 @@ function pledge_get_expectedresult() { 'display_name' => 'Mr. Anthony Anderson II', 'pledge_id' => '1', 'pledge_amount' => '100.00', - 'pledge_create_date' => '2015-02-22 00:00:00', + 'pledge_create_date' => '2017-02-07 00:00:00', + 'pledge_start_date' => '2017-02-07 00:00:00', 'pledge_status' => 'Pending', 'pledge_total_paid' => '', - 'pledge_next_pay_date' => '2015-02-24 00:00:00', + 'pledge_next_pay_date' => '2017-02-09 00:00:00', 'pledge_next_pay_amount' => '20.00', 'pledge_outstanding_amount' => '', 'pledge_financial_type' => 'Donation', diff --git a/civicrm/api/v3/examples/Pledge/GetFilterHighDate.php b/civicrm/api/v3/examples/Pledge/GetFilterHighDate.php index 6e52589e8e..64b6b3ce57 100644 --- a/civicrm/api/v3/examples/Pledge/GetFilterHighDate.php +++ b/civicrm/api/v3/examples/Pledge/GetFilterHighDate.php @@ -9,7 +9,7 @@ */ function pledge_get_example() { $params = array( - 'pledge_start_date_high' => '20150220231942', + 'pledge_start_date_high' => '20170205024740', ); try{ @@ -21,7 +21,8 @@ function pledge_get_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); @@ -52,10 +53,11 @@ function pledge_get_expectedresult() { 'display_name' => 'Mr. Anthony Anderson II', 'pledge_id' => '2', 'pledge_amount' => '100.00', - 'pledge_create_date' => '2015-02-22 00:00:00', + 'pledge_create_date' => '2017-02-07 00:00:00', + 'pledge_start_date' => '2016-03-04 00:00:00', 'pledge_status' => 'Overdue', 'pledge_total_paid' => '', - 'pledge_next_pay_date' => '2014-03-07 00:00:00', + 'pledge_next_pay_date' => '2016-03-04 00:00:00', 'pledge_next_pay_amount' => '20.00', 'pledge_outstanding_amount' => '20.00', 'pledge_financial_type' => 'Donation', diff --git a/civicrm/api/v3/examples/PledgePayment/Create.php b/civicrm/api/v3/examples/PledgePayment/Create.php index 1e8c21e3eb..bfbe8f64fa 100644 --- a/civicrm/api/v3/examples/PledgePayment/Create.php +++ b/civicrm/api/v3/examples/PledgePayment/Create.php @@ -23,7 +23,8 @@ function pledge_payment_create_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); diff --git a/civicrm/api/v3/examples/PledgePayment/Delete.php b/civicrm/api/v3/examples/PledgePayment/Delete.php index d54893ba45..3a0faa1372 100644 --- a/civicrm/api/v3/examples/PledgePayment/Delete.php +++ b/civicrm/api/v3/examples/PledgePayment/Delete.php @@ -19,7 +19,8 @@ function pledge_payment_delete_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); diff --git a/civicrm/api/v3/examples/PledgePayment/Get.php b/civicrm/api/v3/examples/PledgePayment/Get.php index 17f2e27c27..20018f0088 100644 --- a/civicrm/api/v3/examples/PledgePayment/Get.php +++ b/civicrm/api/v3/examples/PledgePayment/Get.php @@ -17,7 +17,8 @@ function pledge_payment_get_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); diff --git a/civicrm/api/v3/examples/PledgePayment/Update.php b/civicrm/api/v3/examples/PledgePayment/Update.php index eaa3178cee..202ba48ac8 100644 --- a/civicrm/api/v3/examples/PledgePayment/Update.php +++ b/civicrm/api/v3/examples/PledgePayment/Update.php @@ -20,7 +20,8 @@ function pledge_payment_update_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); diff --git a/civicrm/api/v3/examples/PriceField/Create.php b/civicrm/api/v3/examples/PriceField/Create.php index 8339479cb3..054a7a65fb 100644 --- a/civicrm/api/v3/examples/PriceField/Create.php +++ b/civicrm/api/v3/examples/PriceField/Create.php @@ -24,7 +24,8 @@ function price_field_create_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); diff --git a/civicrm/api/v3/examples/PriceField/Delete.php b/civicrm/api/v3/examples/PriceField/Delete.php index 3d23332a44..2e1f037fff 100644 --- a/civicrm/api/v3/examples/PriceField/Delete.php +++ b/civicrm/api/v3/examples/PriceField/Delete.php @@ -19,7 +19,8 @@ function price_field_delete_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); diff --git a/civicrm/api/v3/examples/PriceField/Get.php b/civicrm/api/v3/examples/PriceField/Get.php index 953f6d1957..c3da7002da 100644 --- a/civicrm/api/v3/examples/PriceField/Get.php +++ b/civicrm/api/v3/examples/PriceField/Get.php @@ -19,7 +19,8 @@ function price_field_get_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); diff --git a/civicrm/api/v3/examples/PriceFieldValue/Create.php b/civicrm/api/v3/examples/PriceFieldValue/Create.php index 567c0b9d06..a833aa785e 100644 --- a/civicrm/api/v3/examples/PriceFieldValue/Create.php +++ b/civicrm/api/v3/examples/PriceFieldValue/Create.php @@ -26,7 +26,8 @@ function price_field_value_create_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); @@ -55,6 +56,8 @@ function price_field_value_create_expectedresult() { 'name' => 'memType1', 'label' => 'memType1', 'description' => '', + 'help_pre' => '', + 'help_post' => '', 'amount' => '90', 'count' => '', 'max_value' => '', @@ -64,7 +67,7 @@ function price_field_value_create_expectedresult() { 'is_default' => '', 'is_active' => '1', 'financial_type_id' => '2', - 'deductible_amount' => '', + 'non_deductible_amount' => '', 'contribution_type_id' => '2', ), ), diff --git a/civicrm/api/v3/examples/PriceFieldValue/Delete.php b/civicrm/api/v3/examples/PriceFieldValue/Delete.php index 1eb72a66d3..084aac721b 100644 --- a/civicrm/api/v3/examples/PriceFieldValue/Delete.php +++ b/civicrm/api/v3/examples/PriceFieldValue/Delete.php @@ -19,7 +19,8 @@ function price_field_value_delete_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); @@ -40,7 +41,7 @@ function price_field_value_delete_expectedresult() { 'is_error' => 0, 'version' => 3, 'count' => 1, - 'values' => TRUE, + 'values' => 1, ); return $expectedResult; diff --git a/civicrm/api/v3/examples/PriceFieldValue/Get.php b/civicrm/api/v3/examples/PriceFieldValue/Get.php index 1944cde832..9443533d1c 100644 --- a/civicrm/api/v3/examples/PriceFieldValue/Get.php +++ b/civicrm/api/v3/examples/PriceFieldValue/Get.php @@ -19,7 +19,8 @@ function price_field_value_get_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); @@ -52,7 +53,8 @@ function price_field_value_get_expectedresult() { 'is_default' => 0, 'is_active' => '1', 'financial_type_id' => '1', - 'deductible_amount' => '0.00', + 'non_deductible_amount' => '0.00', + 'contribution_type_id' => '1', ), ), ); diff --git a/civicrm/api/v3/examples/PriceSet/Create.php b/civicrm/api/v3/examples/PriceSet/Create.php index 52734d083e..bf801c3eac 100644 --- a/civicrm/api/v3/examples/PriceSet/Create.php +++ b/civicrm/api/v3/examples/PriceSet/Create.php @@ -23,7 +23,8 @@ function price_set_create_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); @@ -59,6 +60,7 @@ function price_set_create_expectedresult() { 'financial_type_id' => '', 'is_quick_config' => '', 'is_reserved' => '', + 'min_amount' => '', ), ), ); diff --git a/civicrm/api/v3/examples/PriceSet/Delete.php b/civicrm/api/v3/examples/PriceSet/Delete.php index 5360087383..3929b96906 100644 --- a/civicrm/api/v3/examples/PriceSet/Delete.php +++ b/civicrm/api/v3/examples/PriceSet/Delete.php @@ -19,7 +19,8 @@ function price_set_delete_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); diff --git a/civicrm/api/v3/examples/PriceSet/Get.php b/civicrm/api/v3/examples/PriceSet/Get.php index b5468e8277..7be052caa0 100644 --- a/civicrm/api/v3/examples/PriceSet/Get.php +++ b/civicrm/api/v3/examples/PriceSet/Get.php @@ -19,7 +19,8 @@ function price_set_get_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); @@ -50,6 +51,7 @@ function price_set_get_expectedresult() { 'extends' => '2', 'is_quick_config' => '1', 'is_reserved' => '1', + 'min_amount' => 0, 'entity' => array(), ), ), diff --git a/civicrm/api/v3/examples/Profile/Apply.php b/civicrm/api/v3/examples/Profile/Apply.php index 60c8da1e7e..57b867c4d3 100644 --- a/civicrm/api/v3/examples/Profile/Apply.php +++ b/civicrm/api/v3/examples/Profile/Apply.php @@ -26,7 +26,8 @@ function profile_apply_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); diff --git a/civicrm/api/v3/examples/Profile/Get.php b/civicrm/api/v3/examples/Profile/Get.php index 415ba5cde9..9a34012a83 100644 --- a/civicrm/api/v3/examples/Profile/Get.php +++ b/civicrm/api/v3/examples/Profile/Get.php @@ -24,7 +24,8 @@ function profile_get_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); diff --git a/civicrm/api/v3/examples/Profile/GetFields.php b/civicrm/api/v3/examples/Profile/GetFields.php index 81ec33c5c6..48b62cee42 100644 --- a/civicrm/api/v3/examples/Profile/GetFields.php +++ b/civicrm/api/v3/examples/Profile/GetFields.php @@ -22,7 +22,8 @@ function profile_getfields_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); @@ -63,6 +64,8 @@ function profile_getfields_expectedresult() { 'date_format' => '', 'time_format' => '', 'is_required' => 0, + 'table_name' => 'civicrm_value__addcustomfie_1', + 'column_name' => '_addcustomfieldtoprofile_1', 'name' => 'custom_1', 'title' => 'first_name', 'type' => 2, @@ -77,17 +80,25 @@ function profile_getfields_expectedresult() { 'name' => 'postal_code', 'type' => 2, 'title' => 'State Province', - 'maxlength' => 12, - 'size' => 12, + 'description' => 'Store both US (zip5) AND international postal codes. App is responsible for country/region appropriate validation.', + 'maxlength' => 64, + 'size' => 6, 'import' => TRUE, 'where' => 'civicrm_address.postal_code', 'headerPattern' => '/postal|zip/i', 'dataPattern' => '/\\d?\\d{4}(-\\d{4})?/', 'export' => TRUE, + 'table_name' => 'civicrm_address', + 'entity' => 'address', + 'bao' => 'CRM_Core_BAO_Address', + 'html' => array( + 'type' => 'Text', + 'maxlength' => 64, + 'size' => 6, + ), 'api.required' => 0, 'help_pre' => '', 'help_post' => '', - 'entity' => 'address', 'weight' => '2', 'api.aliases' => array(), ), @@ -95,9 +106,15 @@ function profile_getfields_expectedresult() { 'name' => 'state_province_id', 'type' => 1, 'title' => 'State Province', + 'description' => 'Which State_Province does this address belong to.', + 'table_name' => 'civicrm_address', + 'entity' => 'address', + 'bao' => 'CRM_Core_BAO_Address', 'FKClassName' => 'CRM_Core_DAO_StateProvince', 'html' => array( - 'type' => 'Select', + 'type' => 'ChainSelect', + 'size' => 6, + 'maxlength' => 14, ), 'pseudoconstant' => array( 'table' => 'civicrm_state_province', @@ -108,7 +125,6 @@ function profile_getfields_expectedresult() { 'api.required' => '1', 'help_pre' => '', 'help_post' => '', - 'entity' => 'address', 'weight' => '3', 'api.aliases' => array(), ), @@ -116,9 +132,15 @@ function profile_getfields_expectedresult() { 'name' => 'country_id', 'type' => 1, 'title' => 'Country', + 'description' => 'Which Country does this address belong to.', + 'table_name' => 'civicrm_address', + 'entity' => 'address', + 'bao' => 'CRM_Core_BAO_Address', 'FKClassName' => 'CRM_Core_DAO_Country', 'html' => array( 'type' => 'Select', + 'size' => 6, + 'maxlength' => 14, ), 'pseudoconstant' => array( 'table' => 'civicrm_country', @@ -130,7 +152,6 @@ function profile_getfields_expectedresult() { 'api.required' => '1', 'help_pre' => '', 'help_post' => '', - 'entity' => 'address', 'weight' => '4', 'api.aliases' => array(), ), @@ -138,6 +159,7 @@ function profile_getfields_expectedresult() { 'name' => 'phone', 'type' => 2, 'title' => 'Phone', + 'description' => 'Complete phone number.', 'maxlength' => 32, 'size' => 20, 'import' => TRUE, @@ -145,10 +167,17 @@ function profile_getfields_expectedresult() { 'headerPattern' => '/phone/i', 'dataPattern' => '/^[\\d\\(\\)\\-\\.\\s]+$/', 'export' => TRUE, + 'table_name' => 'civicrm_phone', + 'entity' => 'phone', + 'bao' => 'CRM_Core_BAO_Phone', + 'html' => array( + 'type' => 'Text', + 'maxlength' => 32, + 'size' => 20, + ), 'api.required' => '1', 'help_pre' => '', 'help_post' => '', - 'entity' => 'phone', 'weight' => '5', 'api.aliases' => array(), ), @@ -156,21 +185,26 @@ function profile_getfields_expectedresult() { 'name' => 'email', 'type' => 2, 'title' => 'Email', + 'description' => 'Email address', 'maxlength' => 254, - 'size' => 20, + 'size' => 30, 'import' => TRUE, 'where' => 'civicrm_email.email', 'headerPattern' => '/e.?mail/i', 'dataPattern' => '/^[a-zA-Z][\\w\\.-]*[a-zA-Z0-9]@[a-zA-Z0-9][\\w\\.-]*[a-zA-Z0-9]\\.[a-zA-Z][a-zA-Z\\.]*[a-zA-Z]$/', 'export' => TRUE, 'rule' => 'email', + 'table_name' => 'civicrm_email', + 'entity' => 'email', + 'bao' => 'CRM_Core_BAO_Email', 'html' => array( 'type' => 'Text', + 'maxlength' => 254, + 'size' => 30, ), 'api.required' => '1', 'help_pre' => '', 'help_post' => '', - 'entity' => 'email', 'weight' => '6', 'api.aliases' => array( '0' => 'email-Primary', @@ -180,6 +214,7 @@ function profile_getfields_expectedresult() { 'name' => 'last_name', 'type' => 2, 'title' => 'Last Name', + 'description' => 'Last Name.', 'maxlength' => 64, 'size' => 30, 'import' => TRUE, @@ -187,13 +222,17 @@ function profile_getfields_expectedresult() { 'headerPattern' => '/^last|(l(ast\\s)?name)$/i', 'dataPattern' => '/^\\w+(\\s\\w+)?+$/', 'export' => TRUE, + 'table_name' => 'civicrm_contact', + 'entity' => 'contact', + 'bao' => 'CRM_Contact_BAO_Contact', 'html' => array( 'type' => 'Text', + 'maxlength' => 64, + 'size' => 30, ), 'api.required' => '1', 'help_pre' => '', 'help_post' => '', - 'entity' => 'contact', 'weight' => '7', 'api.aliases' => array(), ), @@ -201,6 +240,7 @@ function profile_getfields_expectedresult() { 'name' => 'first_name', 'type' => 2, 'title' => 'First Name', + 'description' => 'First Name.', 'maxlength' => 64, 'size' => 30, 'import' => TRUE, @@ -208,13 +248,17 @@ function profile_getfields_expectedresult() { 'headerPattern' => '/^first|(f(irst\\s)?name)$/i', 'dataPattern' => '/^\\w+$/', 'export' => TRUE, + 'table_name' => 'civicrm_contact', + 'entity' => 'contact', + 'bao' => 'CRM_Contact_BAO_Contact', 'html' => array( 'type' => 'Text', + 'maxlength' => 64, + 'size' => 30, ), 'api.required' => '1', 'help_pre' => '', 'help_post' => '', - 'entity' => 'contact', 'weight' => '8', 'api.aliases' => array(), ), diff --git a/civicrm/api/v3/examples/Profile/Submit.php b/civicrm/api/v3/examples/Profile/Submit.php index 03c6ef75d7..a8b26e325c 100644 --- a/civicrm/api/v3/examples/Profile/Submit.php +++ b/civicrm/api/v3/examples/Profile/Submit.php @@ -26,7 +26,8 @@ function profile_submit_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); diff --git a/civicrm/api/v3/examples/Relationship/BetweenRelationshipType.php b/civicrm/api/v3/examples/Relationship/BetweenRelationshipType.php index 2a04935a83..d7dfa39ddd 100644 --- a/civicrm/api/v3/examples/Relationship/BetweenRelationshipType.php +++ b/civicrm/api/v3/examples/Relationship/BetweenRelationshipType.php @@ -11,8 +11,8 @@ function relationship_get_example() { $params = array( 'relationship_type_id' => array( 'BETWEEN' => array( - '0' => 33, - '1' => 35, + '0' => 36, + '1' => 38, ), ), ); @@ -26,7 +26,8 @@ function relationship_get_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); @@ -50,34 +51,31 @@ function relationship_get_expectedresult() { 'values' => array( '2' => array( 'id' => '2', - 'contact_id_a' => '87', - 'contact_id_b' => '89', - 'relationship_type_id' => '33', + 'contact_id_a' => '99', + 'contact_id_b' => '101', + 'relationship_type_id' => '36', 'start_date' => '2013-07-29 00:00:00', 'is_active' => '1', - 'description' => '', 'is_permission_a_b' => 0, 'is_permission_b_a' => 0, ), '3' => array( 'id' => '3', - 'contact_id_a' => '87', - 'contact_id_b' => '89', - 'relationship_type_id' => '34', + 'contact_id_a' => '99', + 'contact_id_b' => '101', + 'relationship_type_id' => '37', 'start_date' => '2013-07-29 00:00:00', 'is_active' => '1', - 'description' => '', 'is_permission_a_b' => 0, 'is_permission_b_a' => 0, ), '4' => array( 'id' => '4', - 'contact_id_a' => '87', - 'contact_id_b' => '89', - 'relationship_type_id' => '35', + 'contact_id_a' => '99', + 'contact_id_b' => '101', + 'relationship_type_id' => '38', 'start_date' => '2013-07-29 00:00:00', 'is_active' => '1', - 'description' => '', 'is_permission_a_b' => 0, 'is_permission_b_a' => 0, ), diff --git a/civicrm/api/v3/examples/Relationship/Create.php b/civicrm/api/v3/examples/Relationship/Create.php index 1c4c1586f1..1978de2bde 100644 --- a/civicrm/api/v3/examples/Relationship/Create.php +++ b/civicrm/api/v3/examples/Relationship/Create.php @@ -25,7 +25,8 @@ function relationship_create_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); diff --git a/civicrm/api/v3/examples/Relationship/Delete.php b/civicrm/api/v3/examples/Relationship/Delete.php index 1e8cafd512..74e4ffc302 100644 --- a/civicrm/api/v3/examples/Relationship/Delete.php +++ b/civicrm/api/v3/examples/Relationship/Delete.php @@ -19,7 +19,8 @@ function relationship_delete_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); diff --git a/civicrm/api/v3/examples/Relationship/Get.php b/civicrm/api/v3/examples/Relationship/Get.php index b1a865ccb1..9d21e1f781 100644 --- a/civicrm/api/v3/examples/Relationship/Get.php +++ b/civicrm/api/v3/examples/Relationship/Get.php @@ -19,7 +19,8 @@ function relationship_get_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); @@ -49,7 +50,6 @@ function relationship_get_expectedresult() { 'relationship_type_id' => '22', 'start_date' => '2013-07-29 00:00:00', 'is_active' => '1', - 'description' => '', 'is_permission_a_b' => 0, 'is_permission_b_a' => 0, 'custom_1' => 'custom string', diff --git a/civicrm/api/v3/examples/Relationship/INRelationshipType.php b/civicrm/api/v3/examples/Relationship/INRelationshipType.php index afbd42c465..3a907c0f1a 100644 --- a/civicrm/api/v3/examples/Relationship/INRelationshipType.php +++ b/civicrm/api/v3/examples/Relationship/INRelationshipType.php @@ -11,8 +11,8 @@ function relationship_get_example() { $params = array( 'relationship_type_id' => array( 'IN' => array( - '0' => 33, - '1' => 34, + '0' => 36, + '1' => 37, ), ), ); @@ -26,7 +26,8 @@ function relationship_get_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); @@ -50,23 +51,21 @@ function relationship_get_expectedresult() { 'values' => array( '2' => array( 'id' => '2', - 'contact_id_a' => '87', - 'contact_id_b' => '89', - 'relationship_type_id' => '33', + 'contact_id_a' => '99', + 'contact_id_b' => '101', + 'relationship_type_id' => '36', 'start_date' => '2013-07-29 00:00:00', 'is_active' => '1', - 'description' => '', 'is_permission_a_b' => 0, 'is_permission_b_a' => 0, ), '3' => array( 'id' => '3', - 'contact_id_a' => '87', - 'contact_id_b' => '89', - 'relationship_type_id' => '34', + 'contact_id_a' => '99', + 'contact_id_b' => '101', + 'relationship_type_id' => '37', 'start_date' => '2013-07-29 00:00:00', 'is_active' => '1', - 'description' => '', 'is_permission_a_b' => 0, 'is_permission_b_a' => 0, ), diff --git a/civicrm/api/v3/examples/Relationship/NotBetweenRelationshipType.php b/civicrm/api/v3/examples/Relationship/NotBetweenRelationshipType.php index 091ea47cec..31a8a73454 100644 --- a/civicrm/api/v3/examples/Relationship/NotBetweenRelationshipType.php +++ b/civicrm/api/v3/examples/Relationship/NotBetweenRelationshipType.php @@ -11,8 +11,8 @@ function relationship_get_example() { $params = array( 'relationship_type_id' => array( 'NOT BETWEEN' => array( - '0' => 33, - '1' => 35, + '0' => 36, + '1' => 38, ), ), ); @@ -26,7 +26,8 @@ function relationship_get_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); @@ -51,12 +52,11 @@ function relationship_get_expectedresult() { 'values' => array( '1' => array( 'id' => '1', - 'contact_id_a' => '87', - 'contact_id_b' => '89', - 'relationship_type_id' => '32', + 'contact_id_a' => '99', + 'contact_id_b' => '101', + 'relationship_type_id' => '35', 'start_date' => '2013-07-29 00:00:00', 'is_active' => '1', - 'description' => '', 'is_permission_a_b' => 0, 'is_permission_b_a' => 0, ), diff --git a/civicrm/api/v3/examples/Relationship/NotInRelationshipType.php b/civicrm/api/v3/examples/Relationship/NotInRelationshipType.php index 024c3952e8..5e77fe8b30 100644 --- a/civicrm/api/v3/examples/Relationship/NotInRelationshipType.php +++ b/civicrm/api/v3/examples/Relationship/NotInRelationshipType.php @@ -11,8 +11,8 @@ function relationship_get_example() { $params = array( 'relationship_type_id' => array( 'NOT IN' => array( - '0' => 33, - '1' => 34, + '0' => 36, + '1' => 37, ), ), ); @@ -26,7 +26,8 @@ function relationship_get_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); @@ -50,23 +51,21 @@ function relationship_get_expectedresult() { 'values' => array( '1' => array( 'id' => '1', - 'contact_id_a' => '87', - 'contact_id_b' => '89', - 'relationship_type_id' => '32', + 'contact_id_a' => '99', + 'contact_id_b' => '101', + 'relationship_type_id' => '35', 'start_date' => '2013-07-29 00:00:00', 'is_active' => '1', - 'description' => '', 'is_permission_a_b' => 0, 'is_permission_b_a' => 0, ), '4' => array( 'id' => '4', - 'contact_id_a' => '87', - 'contact_id_b' => '89', - 'relationship_type_id' => '35', + 'contact_id_a' => '99', + 'contact_id_b' => '101', + 'relationship_type_id' => '38', 'start_date' => '2013-07-29 00:00:00', 'is_active' => '1', - 'description' => '', 'is_permission_a_b' => 0, 'is_permission_b_a' => 0, ), diff --git a/civicrm/api/v3/examples/Relationship/filterIsCurrent.php b/civicrm/api/v3/examples/Relationship/filterIsCurrent.php index d12bccc3f9..c4aee7a37a 100644 --- a/civicrm/api/v3/examples/Relationship/filterIsCurrent.php +++ b/civicrm/api/v3/examples/Relationship/filterIsCurrent.php @@ -23,7 +23,8 @@ function relationship_get_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); @@ -48,12 +49,11 @@ function relationship_get_expectedresult() { 'values' => array( '2' => array( 'id' => '2', - 'contact_id_a' => '83', - 'contact_id_b' => '85', - 'relationship_type_id' => '31', + 'contact_id_a' => '95', + 'contact_id_b' => '97', + 'relationship_type_id' => '34', 'start_date' => '2013-07-29 00:00:00', 'is_active' => '1', - 'description' => '', 'is_permission_a_b' => 0, 'is_permission_b_a' => 0, ), diff --git a/civicrm/api/v3/examples/RelationshipType/Create.php b/civicrm/api/v3/examples/RelationshipType/Create.php index 2d458c4dbf..42826f114c 100644 --- a/civicrm/api/v3/examples/RelationshipType/Create.php +++ b/civicrm/api/v3/examples/RelationshipType/Create.php @@ -25,7 +25,8 @@ function relationship_type_create_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); diff --git a/civicrm/api/v3/examples/RelationshipType/Delete.php b/civicrm/api/v3/examples/RelationshipType/Delete.php index 6b1dd50373..d331378cdc 100644 --- a/civicrm/api/v3/examples/RelationshipType/Delete.php +++ b/civicrm/api/v3/examples/RelationshipType/Delete.php @@ -19,7 +19,8 @@ function relationship_type_delete_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); @@ -40,7 +41,7 @@ function relationship_type_delete_expectedresult() { 'is_error' => 0, 'version' => 3, 'count' => 1, - 'values' => TRUE, + 'values' => 1, ); return $expectedResult; diff --git a/civicrm/api/v3/examples/ReportTemplate/Getrows.php b/civicrm/api/v3/examples/ReportTemplate/Getrows.php index 8c790439fd..25dc1d5fc6 100644 --- a/civicrm/api/v3/examples/ReportTemplate/Getrows.php +++ b/civicrm/api/v3/examples/ReportTemplate/Getrows.php @@ -27,7 +27,8 @@ function report_template_getrows_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); @@ -50,16 +51,16 @@ function report_template_getrows_expectedresult() { 'count' => 2, 'values' => array( '0' => array( - 'civicrm_contact_sort_name' => 'Default Organization', - 'civicrm_contact_id' => '1', - 'civicrm_contact_sort_name_link' => '/index.php?q=civicrm/report/contact/detail&reset=1&force=1&id_op=eq&id_value=1', - 'civicrm_contact_sort_name_hover' => 'View Constituent Detail Report for this contact.', - ), - '1' => array( 'civicrm_contact_sort_name' => 'Second Domain', 'civicrm_contact_id' => '2', 'civicrm_contact_sort_name_link' => '/index.php?q=civicrm/report/contact/detail&reset=1&force=1&id_op=eq&id_value=2', - 'civicrm_contact_sort_name_hover' => 'View Constituent Detail Report for this contact.', + 'civicrm_contact_sort_name_hover' => 'View Contact Detail Report for this contact', + ), + '1' => array( + 'civicrm_contact_sort_name' => 'Unit Test Organization', + 'civicrm_contact_id' => '1', + 'civicrm_contact_sort_name_link' => '/index.php?q=civicrm/report/contact/detail&reset=1&force=1&id_op=eq&id_value=1', + 'civicrm_contact_sort_name_hover' => 'View Contact Detail Report for this contact', ), ), 'metadata' => array( diff --git a/civicrm/api/v3/examples/ReportTemplate/Getstatistics.php b/civicrm/api/v3/examples/ReportTemplate/Getstatistics.php index bc98a485fe..d9c9dc340c 100644 --- a/civicrm/api/v3/examples/ReportTemplate/Getstatistics.php +++ b/civicrm/api/v3/examples/ReportTemplate/Getstatistics.php @@ -9,7 +9,7 @@ */ function report_template_getstatistics_example() { $params = array( - 'report_id' => 'contribute/recursummary', + 'report_id' => 'contribute/deferredrevenue', ); try{ @@ -21,7 +21,8 @@ function report_template_getstatistics_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); @@ -41,16 +42,8 @@ function report_template_getstatistics_expectedresult() { $expectedResult = array( 'is_error' => 0, 'version' => 3, - 'count' => 1, - 'id' => 'counts', - 'values' => array( - 'counts' => array( - 'rowCount' => array( - 'title' => 'Row(s) Listed', - 'value' => 0, - ), - ), - ), + 'count' => 0, + 'values' => '', ); return $expectedResult; diff --git a/civicrm/api/v3/examples/SavedSearch/Create.php b/civicrm/api/v3/examples/SavedSearch/Create.php new file mode 100644 index 0000000000..31d677d93a --- /dev/null +++ b/civicrm/api/v3/examples/SavedSearch/Create.php @@ -0,0 +1,127 @@ +<?php +/** + * Test Generated example demonstrating the SavedSearch.create API. + * + * @return array + * API result array + */ +function saved_search_create_example() { + $params = array( + 'form_values' => array( + 'relation_type_id' => '6_a_b', + 'relation_target_name' => 'Default Organization', + ), + 'api.Group.create' => array( + 'name' => 'my_smartgroup', + 'title' => 'my smartgroup', + 'description' => 'Volunteers for the default organization', + 'saved_search_id' => '$value.id', + 'is_active' => 1, + 'visibility' => 'User and User Admin Only', + 'is_hidden' => 0, + 'is_reserved' => 0, + ), + ); + + try{ + $result = civicrm_api3('SavedSearch', 'create', $params); + } + catch (CiviCRM_API3_Exception $e) { + // Handle error here. + $errorMessage = $e->getMessage(); + $errorCode = $e->getErrorCode(); + $errorData = $e->getExtraParams(); + return array( + 'is_error' => 1, + 'error_message' => $errorMessage, + 'error_code' => $errorCode, + 'error_data' => $errorData, + ); + } + + return $result; +} + +/** + * Function returns array of result expected from previous function. + * + * @return array + * API result array + */ +function saved_search_create_expectedresult() { + + $expectedResult = array( + 'is_error' => 0, + 'version' => 3, + 'count' => 1, + 'id' => 3, + 'values' => array( + '3' => array( + 'id' => '3', + 'form_values' => array( + 'relation_type_id' => '6_a_b', + 'relation_target_name' => 'Default Organization', + ), + 'mapping_id' => '', + 'search_custom_id' => '', + 'where_clause' => '', + 'select_tables' => '', + 'where_tables' => '', + 'api.Group.create' => array( + 'is_error' => 0, + 'version' => 3, + 'count' => 1, + 'id' => 1, + 'values' => array( + '0' => array( + 'id' => '1', + 'name' => 'my_smartgroup', + 'title' => 'my smartgroup', + 'description' => 'Volunteers for the default organization', + 'source' => '', + 'saved_search_id' => '3', + 'is_active' => '1', + 'visibility' => 'User and User Admin Only', + 'where_clause' => ' ( ( `civicrm_group_contact_cache_1`.group_id IN (\"1\") ) ) ', + 'select_tables' => 'a:8:{s:15:\"civicrm_contact\";i:1;s:15:\"civicrm_address\";i:1;s:15:\"civicrm_country\";i:1;s:13:\"civicrm_email\";i:1;s:13:\"civicrm_phone\";i:1;s:10:\"civicrm_im\";i:1;s:19:\"civicrm_worldregion\";i:1;s:31:\"`civicrm_group_contact_cache_1`\";s:132:\" LEFT JOIN civicrm_group_contact_cache `civicrm_group_contact_cache_1` ON contact_a.id = `civicrm_group_contact_cache_1`.contact_id \";}', + 'where_tables' => 'a:2:{s:15:\"civicrm_contact\";i:1;s:31:\"`civicrm_group_contact_cache_1`\";s:132:\" LEFT JOIN civicrm_group_contact_cache `civicrm_group_contact_cache_1` ON contact_a.id = `civicrm_group_contact_cache_1`.contact_id \";}', + 'group_type' => '', + 'cache_date' => '', + 'refresh_date' => '', + 'parents' => '', + 'children' => '', + 'is_hidden' => 0, + 'is_reserved' => 0, + 'created_id' => '', + 'modified_id' => '', + ), + ), + ), + ), + ), + ); + + return $expectedResult; +} + +/* +* This example has been generated from the API test suite. +* The test that created it is called "testCreateSavedSearchWithSmartGroup" +* and can be found at: +* https://github.com/civicrm/civicrm-core/blob/master/tests/phpunit/api/v3/SavedSearchTest.php +* +* You can see the outcome of the API tests at +* https://test.civicrm.org/job/CiviCRM-master-git/ +* +* To Learn about the API read +* http://wiki.civicrm.org/confluence/display/CRMDOC/Using+the+API +* +* Browse the api on your own site with the api explorer +* http://MYSITE.ORG/path/to/civicrm/api +* +* Read more about testing here +* http://wiki.civicrm.org/confluence/display/CRM/Testing +* +* API Standards documentation: +* http://wiki.civicrm.org/confluence/display/CRM/API+Architecture+Standards +*/ diff --git a/civicrm/api/v3/examples/SavedSearch/Delete.php b/civicrm/api/v3/examples/SavedSearch/Delete.php new file mode 100644 index 0000000000..3d0052b6b9 --- /dev/null +++ b/civicrm/api/v3/examples/SavedSearch/Delete.php @@ -0,0 +1,70 @@ +<?php +/** + * Test Generated example demonstrating the SavedSearch.delete API. + * + * @return array + * API result array + */ +function saved_search_delete_example() { + $params = array( + 'id' => 4, + ); + + try{ + $result = civicrm_api3('SavedSearch', 'delete', $params); + } + catch (CiviCRM_API3_Exception $e) { + // Handle error here. + $errorMessage = $e->getMessage(); + $errorCode = $e->getErrorCode(); + $errorData = $e->getExtraParams(); + return array( + 'is_error' => 1, + 'error_message' => $errorMessage, + 'error_code' => $errorCode, + 'error_data' => $errorData, + ); + } + + return $result; +} + +/** + * Function returns array of result expected from previous function. + * + * @return array + * API result array + */ +function saved_search_delete_expectedresult() { + + $expectedResult = array( + 'is_error' => 0, + 'version' => 3, + 'count' => 1, + 'values' => 1, + ); + + return $expectedResult; +} + +/* +* This example has been generated from the API test suite. +* The test that created it is called "testDeleteSavedSearch" +* and can be found at: +* https://github.com/civicrm/civicrm-core/blob/master/tests/phpunit/api/v3/SavedSearchTest.php +* +* You can see the outcome of the API tests at +* https://test.civicrm.org/job/CiviCRM-master-git/ +* +* To Learn about the API read +* http://wiki.civicrm.org/confluence/display/CRMDOC/Using+the+API +* +* Browse the api on your own site with the api explorer +* http://MYSITE.ORG/path/to/civicrm/api +* +* Read more about testing here +* http://wiki.civicrm.org/confluence/display/CRM/Testing +* +* API Standards documentation: +* http://wiki.civicrm.org/confluence/display/CRM/API+Architecture+Standards +*/ diff --git a/civicrm/api/v3/examples/SavedSearch/Get.php b/civicrm/api/v3/examples/SavedSearch/Get.php new file mode 100644 index 0000000000..14adb3a11b --- /dev/null +++ b/civicrm/api/v3/examples/SavedSearch/Get.php @@ -0,0 +1,79 @@ +<?php +/** + * Test Generated example demonstrating the SavedSearch.get API. + * + * @return array + * API result array + */ +function saved_search_get_example() { + $params = array( + 'id' => 2, + ); + + try{ + $result = civicrm_api3('SavedSearch', 'get', $params); + } + catch (CiviCRM_API3_Exception $e) { + // Handle error here. + $errorMessage = $e->getMessage(); + $errorCode = $e->getErrorCode(); + $errorData = $e->getExtraParams(); + return array( + 'is_error' => 1, + 'error_message' => $errorMessage, + 'error_code' => $errorCode, + 'error_data' => $errorData, + ); + } + + return $result; +} + +/** + * Function returns array of result expected from previous function. + * + * @return array + * API result array + */ +function saved_search_get_expectedresult() { + + $expectedResult = array( + 'is_error' => 0, + 'version' => 3, + 'count' => 1, + 'id' => 2, + 'values' => array( + '2' => array( + 'id' => '2', + 'form_values' => array( + 'relation_type_id' => '6_a_b', + 'relation_target_name' => 'Default Organization', + ), + ), + ), + ); + + return $expectedResult; +} + +/* +* This example has been generated from the API test suite. +* The test that created it is called "testCreateAndGetSavedSearch" +* and can be found at: +* https://github.com/civicrm/civicrm-core/blob/master/tests/phpunit/api/v3/SavedSearchTest.php +* +* You can see the outcome of the API tests at +* https://test.civicrm.org/job/CiviCRM-master-git/ +* +* To Learn about the API read +* http://wiki.civicrm.org/confluence/display/CRMDOC/Using+the+API +* +* Browse the api on your own site with the api explorer +* http://MYSITE.ORG/path/to/civicrm/api +* +* Read more about testing here +* http://wiki.civicrm.org/confluence/display/CRM/Testing +* +* API Standards documentation: +* http://wiki.civicrm.org/confluence/display/CRM/API+Architecture+Standards +*/ diff --git a/civicrm/api/v3/examples/Setting/Create.php b/civicrm/api/v3/examples/Setting/Create.php index 466890049c..3f92f96137 100644 --- a/civicrm/api/v3/examples/Setting/Create.php +++ b/civicrm/api/v3/examples/Setting/Create.php @@ -20,7 +20,8 @@ function setting_create_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); diff --git a/civicrm/api/v3/examples/Setting/CreateAllDomains.php b/civicrm/api/v3/examples/Setting/CreateAllDomains.php index ec21159633..37a4d5efc4 100644 --- a/civicrm/api/v3/examples/Setting/CreateAllDomains.php +++ b/civicrm/api/v3/examples/Setting/CreateAllDomains.php @@ -22,7 +22,8 @@ function setting_create_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); diff --git a/civicrm/api/v3/examples/Setting/CreateSettingCurrentDomain.php b/civicrm/api/v3/examples/Setting/CreateSettingCurrentDomain.php index a43b968efc..c0e189dcb2 100644 --- a/civicrm/api/v3/examples/Setting/CreateSettingCurrentDomain.php +++ b/civicrm/api/v3/examples/Setting/CreateSettingCurrentDomain.php @@ -21,7 +21,8 @@ function setting_create_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); diff --git a/civicrm/api/v3/examples/Setting/CreateSpecifiedDomains.php b/civicrm/api/v3/examples/Setting/CreateSpecifiedDomains.php index e889f6c3a0..a54f24ab94 100644 --- a/civicrm/api/v3/examples/Setting/CreateSpecifiedDomains.php +++ b/civicrm/api/v3/examples/Setting/CreateSpecifiedDomains.php @@ -25,7 +25,8 @@ function setting_create_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); diff --git a/civicrm/api/v3/examples/Setting/Get.php b/civicrm/api/v3/examples/Setting/Get.php index 270c1e5e54..522fb14a8e 100644 --- a/civicrm/api/v3/examples/Setting/Get.php +++ b/civicrm/api/v3/examples/Setting/Get.php @@ -20,7 +20,8 @@ function setting_get_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); diff --git a/civicrm/api/v3/examples/Setting/GetAllDomains.php b/civicrm/api/v3/examples/Setting/GetAllDomains.php index 4aab2582fa..3a446f13d8 100644 --- a/civicrm/api/v3/examples/Setting/GetAllDomains.php +++ b/civicrm/api/v3/examples/Setting/GetAllDomains.php @@ -22,7 +22,8 @@ function setting_get_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); diff --git a/civicrm/api/v3/examples/Setting/GetDefaults.php b/civicrm/api/v3/examples/Setting/GetDefaults.php index 3cb02ca813..1a5e7d9b2d 100644 --- a/civicrm/api/v3/examples/Setting/GetDefaults.php +++ b/civicrm/api/v3/examples/Setting/GetDefaults.php @@ -21,7 +21,8 @@ function setting_getdefaults_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); diff --git a/civicrm/api/v3/examples/Setting/GetFields.php b/civicrm/api/v3/examples/Setting/GetFields.php index df623eb6ce..9e6170e70d 100644 --- a/civicrm/api/v3/examples/Setting/GetFields.php +++ b/civicrm/api/v3/examples/Setting/GetFields.php @@ -19,7 +19,8 @@ function setting_getfields_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); @@ -39,7 +40,7 @@ function setting_getfields_expectedresult() { $expectedResult = array( 'is_error' => 0, 'version' => 3, - 'count' => 91, + 'count' => 151, 'values' => array( 'address_standardization_provider' => array( 'group_name' => 'Address Preferences', @@ -84,6 +85,20 @@ function setting_getfields_expectedresult() { 'help_text' => 'Web Service URL', 'validate_callback' => 'CRM_Utils_Rule::url', ), + 'hideCountryMailingLabels' => array( + 'group_name' => 'Address Preferences', + 'group' => 'address', + 'name' => 'hideCountryMailingLabels', + 'type' => 'Boolean', + 'quick_form_type' => 'YesNo', + 'default' => 0, + 'add' => '4.7', + 'title' => 'Hide Country in Mailing Labels when same as domain country', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => 'Do not display the country field in mailing labels when the country is the same as that of the domain', + 'help_text' => '', + ), 'tag_unconfirmed' => array( 'group_name' => 'Campaign Preferences', 'group' => 'campaign', @@ -126,6 +141,135 @@ function setting_getfields_expectedresult() { 'description' => 'Is the CVV code required for back office credit card transactions', 'help_text' => 'If set it back-office credit card transactions will required a cvv code. Leave as required unless you have a very strong reason to change', ), + 'contribution_invoice_settings' => array( + 'group_name' => 'Contribute Preferences', + 'group' => 'contribute', + 'name' => 'contribution_invoice_settings', + 'type' => 'Array', + 'default' => array( + 'invoice_prefix' => 'INV_', + 'credit_notes_prefix' => 'CN_', + 'due_date' => '10', + 'due_date_period' => 'days', + 'notes' => '', + 'tax_term' => 'Sales Tax', + 'tax_display_settings' => 'Inclusive', + ), + 'add' => '4.7', + 'title' => 'Contribution Invoice Settings', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => '', + 'help_text' => '', + ), + 'invoicing' => array( + 'group_name' => 'Contribute Preferences', + 'group' => 'contribute', + 'name' => 'invoicing', + 'type' => 'Integer', + 'html_type' => 'checkbox', + 'quick_form_type' => 'Element', + 'default' => 0, + 'add' => '4.7', + 'title' => 'Enable Tax and Invoicing', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => '', + 'help_text' => '', + ), + 'acl_financial_type' => array( + 'group_name' => 'Contribute Preferences', + 'group' => 'contribute', + 'name' => 'acl_financial_type', + 'type' => 'Integer', + 'html_type' => 'checkbox', + 'quick_form_type' => 'Element', + 'default' => 0, + 'add' => '4.7', + 'title' => 'Enable Access Control by Financial Type', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => '', + 'help_text' => '', + ), + 'deferred_revenue_enabled' => array( + 'group_name' => 'Contribute Preferences', + 'group' => 'contribute', + 'name' => 'deferred_revenue_enabled', + 'type' => 'Integer', + 'html_type' => 'checkbox', + 'quick_form_type' => 'Element', + 'default' => 0, + 'add' => '4.7', + 'title' => 'Enable Deferred Revenue', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => '', + 'help_text' => '', + ), + 'default_invoice_page' => array( + 'group_name' => 'Contribute Preferences', + 'group' => 'contribute', + 'name' => 'default_invoice_page', + 'type' => 'Integer', + 'quick_form_type' => 'Element', + 'default' => '', + 'pseudoconstant' => array( + 'name' => 'contributionPage', + ), + 'html_type' => 'select', + 'add' => '4.7', + 'title' => 'Default invoice payment page', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => '', + 'help_text' => '', + ), + 'financial_account_bal_enable' => array( + 'group_name' => 'Contribute Preferences', + 'group' => 'contribute', + 'name' => 'financial_account_bal_enable', + 'type' => 'Integer', + 'html_type' => 'checkbox', + 'quick_form_type' => 'Element', + 'default' => 0, + 'add' => '4.7', + 'title' => 'Enable Financial Account Balances', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => '', + 'help_text' => '', + ), + 'prior_financial_period' => array( + 'group_name' => 'Contribute Preferences', + 'group' => 'contribute', + 'name' => 'prior_financial_period', + 'type' => 'activityDate', + 'quick_form_type' => 'Date', + 'html_type' => 'Date', + 'default' => '', + 'add' => '4.7', + 'title' => 'Prior Financial Period', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => '', + 'help_text' => '', + ), + 'always_post_to_accounts_receivable' => array( + 'group_name' => 'Contribute Preferences', + 'group' => 'contribute', + 'name' => 'always_post_to_accounts_receivable', + 'type' => 'Integer', + 'html_type' => 'checkbox', + 'quick_form_type' => 'Element', + 'default' => 0, + 'add' => '4.7', + 'title' => 'Always post to Accounts Receivable?', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => '', + 'help_text' => '', + ), 'contact_view_options' => array( 'group_name' => 'CiviCRM Preferences', 'group' => 'core', @@ -135,20 +279,7 @@ function setting_getfields_expectedresult() { 'pseudoconstant' => array( 'optionGroupName' => 'contact_view_options', ), - 'default' => array( - '0' => '1', - '1' => '2', - '2' => '3', - '3' => '4', - '4' => '5', - '5' => '6', - '6' => '7', - '7' => '8', - '8' => '9', - '9' => '10', - '10' => '11', - '11' => '13', - ), + 'default' => '123456789101113', 'add' => '4.1', 'title' => 'Viewing Contacts', 'is_domain' => '1', @@ -165,19 +296,7 @@ function setting_getfields_expectedresult() { 'pseudoconstant' => array( 'optionGroupName' => 'contact_edit_options', ), - 'default' => array( - '0' => '1', - '1' => '2', - '2' => '3', - '3' => '4', - '4' => '5', - '5' => '6', - '6' => '7', - '7' => '8', - '8' => '9', - '9' => '10', - '10' => '11', - ), + 'default' => '123456789111214151617', 'add' => '4.1', 'title' => 'Editing Contacts', 'is_domain' => 1, @@ -193,25 +312,7 @@ function setting_getfields_expectedresult() { 'pseudoconstant' => array( 'optionGroupName' => 'advanced_search_options', ), - 'default' => array( - '0' => '1', - '1' => '2', - '2' => '3', - '3' => '4', - '4' => '5', - '5' => '6', - '6' => '7', - '7' => '8', - '8' => '9', - '9' => '10', - '10' => '12', - '11' => '13', - '12' => '15', - '13' => '16', - '14' => '17', - '15' => '18', - '16' => '19', - ), + 'default' => '123456789101112131516171819', 'add' => '4.1', 'title' => 'Contact Search', 'is_domain' => 1, @@ -228,16 +329,7 @@ function setting_getfields_expectedresult() { 'pseudoconstant' => array( 'optionGroupName' => 'user_dashboard_options', ), - 'default' => array( - '0' => '1', - '1' => '2', - '2' => '3', - '3' => '4', - '4' => '5', - '5' => '7', - '6' => '8', - '7' => '9', - ), + 'default' => '1234578', 'add' => '4.1', 'title' => 'Contact Dashboard', 'is_domain' => 1, @@ -254,16 +346,7 @@ function setting_getfields_expectedresult() { 'pseudoconstant' => array( 'optionGroupName' => 'address_options', ), - 'default' => array( - '0' => '1', - '1' => '2', - '2' => '4', - '3' => '5', - '4' => '8', - '5' => '9', - '6' => '10', - '7' => '11', - ), + 'default' => '123456891011', 'add' => '4.1', 'title' => 'Addressing Options', 'is_domain' => 1, @@ -337,13 +420,28 @@ function setting_getfields_expectedresult() { 'description' => '', 'help_text' => '', ), + 'remote_profile_submissions' => array( + 'group_name' => 'CiviCRM Preferences', + 'group' => 'core', + 'name' => 'remote_profile_submissions', + 'type' => 'Boolean', + 'quick_form_type' => 'YesNo', + 'default' => '', + 'html_type' => 'radio', + 'add' => '4.7', + 'title' => 'Accept profile submissions from external sites', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => 'If enabled, CiviCRM will permit submissions from external sites to profiles. This is disabled by default to limit abuse.', + 'help_text' => '', + ), 'editor_id' => array( 'group_name' => 'CiviCRM Preferences', 'group' => 'core', 'name' => 'editor_id', 'type' => 'String', - 'html_type' => 'Text', - 'default' => '', + 'html_type' => 'Select', + 'default' => 'CKEditor', 'add' => '4.1', 'title' => 'Wysiwig Editor', 'is_domain' => 1, @@ -357,7 +455,7 @@ function setting_getfields_expectedresult() { 'name' => 'contact_ajax_check_similar', 'type' => 'String', 'html_type' => 'Text', - 'default' => '', + 'default' => '1', 'add' => '4.1', 'title' => 'Ajax Check Similar', 'is_domain' => 1, @@ -385,7 +483,7 @@ function setting_getfields_expectedresult() { 'name' => 'activity_assignee_notification', 'type' => 'String', 'html_type' => 'Text', - 'default' => '', + 'default' => '1', 'add' => '4.1', 'title' => 'Notify Activity Assignees', 'is_domain' => 1, @@ -399,7 +497,7 @@ function setting_getfields_expectedresult() { 'name' => 'activity_assignee_notification_ics', 'type' => 'String', 'html_type' => 'Text', - 'default' => '', + 'default' => 0, 'add' => '4.3', 'title' => 'Include ICal Invite to Activity Assignees', 'is_domain' => 1, @@ -412,24 +510,16 @@ function setting_getfields_expectedresult() { 'group' => 'core', 'name' => 'contact_autocomplete_options', 'type' => 'String', - 'html_type' => 'checkboxes', + 'quick_form_type' => 'CheckBox', 'pseudoconstant' => array( - 'optionGroupName' => 'contact_autocomplete_options', - ), - 'default' => array( - '0' => '1', - '1' => '2', - '2' => '3', - '3' => '4', - '4' => '5', - '5' => '6', - '6' => '7', + 'callback' => 'CRM_Admin_Form_Setting_Search::getContactAutocompleteOptions', ), + 'default' => '12', 'add' => '4.1', - 'title' => 'Contact Reference Autocomplete Options', + 'title' => 'Autocomplete Contact Search', 'is_domain' => 1, 'is_contact' => 0, - 'description' => '', + 'description' => 'Selected fields will be displayed in back-office autocomplete dropdown search results (Quick Search, etc.). Contact Name is always included.', 'help_text' => '', ), 'contact_reference_options' => array( @@ -437,32 +527,69 @@ function setting_getfields_expectedresult() { 'group' => 'core', 'name' => 'contact_reference_options', 'type' => 'String', - 'html_type' => 'checkboxes', + 'quick_form_type' => 'CheckBox', 'pseudoconstant' => array( - 'optionGroupName' => 'contact_reference_options', - ), - 'default' => array( - '0' => '1', - '1' => '2', - '2' => '3', - '3' => '4', - '4' => '5', - '5' => '6', - '6' => '7', + 'callback' => 'CRM_Admin_Form_Setting_Search::getContactReferenceOptions', ), + 'default' => '12', 'add' => '4.1', 'title' => 'Contact Reference Options', 'is_domain' => 1, 'is_contact' => 0, + 'description' => 'Selected fields will be displayed in autocomplete dropdown search results for \'Contact Reference\' custom fields. Contact Name is always included. NOTE: You must assign \'access contact reference fields\' permission to the anonymous role if you want to use custom contact reference fields in profiles on public pages. For most situations, you should use the \'Limit List to Group\' setting when configuring a contact reference field which will be used in public forms to prevent exposing your entire contact list.', + 'help_text' => '', + ), + 'contact_smart_group_display' => array( + 'group_name' => 'CiviCRM Preferences', + 'group' => 'core', + 'name' => 'contact_smart_group_display', + 'type' => 'String', + 'html_type' => 'radio', + 'default' => '1', + 'add' => '4.7', + 'title' => 'Viewing Smart Groups', + 'is_domain' => 1, + 'is_contact' => 0, 'description' => '', 'help_text' => '', ), + 'smart_group_cache_refresh_mode' => array( + 'group_name' => 'CiviCRM Preferences', + 'group' => 'core', + 'name' => 'smart_group_cache_refresh_mode', + 'type' => 'String', + 'html_type' => 'radio', + 'default' => 'opportunistic', + 'add' => '4.7', + 'title' => 'Smart Group Refresh Mode', + 'is_domain' => 1, + 'is_contact' => 0, + 'pseudoconstant' => array( + 'callback' => 'CRM_Contact_BAO_GroupContactCache::getModes', + ), + 'description' => 'Should the smart groups be by cron jobs or user actions', + 'help_text' => 'In \"Opportunistic Flush\" mode, caches are flushed in response to user actions; this mode is broadly compatible but may add latency during form-submissions. In \"Cron Flush\" mode, you should schedule a cron job to flush caches; this can improve latency on form-submissions but requires more setup.', + ), + 'installed' => array( + 'bootstrap_comment' => 'This is a boot setting which may be loaded during bootstrap. Defaults are loaded via SettingsBag::getSystemDefaults().', + 'group_name' => 'CiviCRM Preferences', + 'group' => 'core', + 'name' => 'installed', + 'type' => 'Boolean', + 'quick_form_type' => 'YesNo', + 'default' => '', + 'add' => '4.7', + 'title' => 'System Installed', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => 'A flag indicating whether this system has run a post-installation routine', + 'help_text' => '', + ), 'max_attachments' => array( 'group_name' => 'CiviCRM Preferences', 'group' => 'core', 'name' => 'max_attachments', 'legacy_key' => 'maxAttachments', - 'prefetch' => 0, 'type' => 'Integer', 'quick_form_type' => 'Element', 'html_type' => 'text', @@ -482,8 +609,6 @@ function setting_getfields_expectedresult() { 'group_name' => 'CiviCRM Preferences', 'group' => 'core', 'name' => 'maxFileSize', - 'prefetch' => 1, - 'config_only' => 1, 'type' => 'Integer', 'quick_form_type' => 'Element', 'html_type' => 'text', @@ -535,21 +660,19 @@ function setting_getfields_expectedresult() { 'quick_form_type' => 'YesNo', 'default' => 1, 'add' => '4.4', - 'title' => 'Security Audits', + 'title' => 'Status Alerts', 'is_domain' => 1, 'is_contact' => 0, - 'description' => 'If enabled, CiviCRM will automatically run checks for significant mis-configurations such as ineffective file protections.', + 'description' => 'If enabled, CiviCRM will display pop-up notifications (no more than once per day) for security and misconfiguration issues identified in the system check.', 'help_text' => '', ), 'doNotAttachPDFReceipt' => array( 'group_name' => 'CiviCRM Preferences', 'group' => 'core', 'name' => 'doNotAttachPDFReceipt', - 'prefetch' => 1, - 'config_only' => 1, 'type' => 'Boolean', 'quick_form_type' => 'YesNo', - 'default' => 1, + 'default' => 0, 'add' => '4.3', 'title' => 'Attach PDF copy to receipts', 'is_domain' => 1, @@ -561,8 +684,6 @@ function setting_getfields_expectedresult() { 'group_name' => 'CiviCRM Preferences', 'group' => 'core', 'name' => 'wkhtmltopdfPath', - 'prefetch' => 1, - 'config_only' => 1, 'type' => 'String', 'quick_form_type' => 'Element', 'html_attributes' => array( @@ -578,12 +699,29 @@ function setting_getfields_expectedresult() { 'description' => '', 'help_text' => '', ), + 'recaptchaOptions' => array( + 'group_name' => 'CiviCRM Preferences', + 'group' => 'core', + 'name' => 'recaptchaOptions', + 'type' => 'String', + 'quick_form_type' => 'Element', + 'html_attributes' => array( + 'size' => 64, + 'maxlength' => 64, + ), + 'html_type' => 'Text', + 'default' => '', + 'add' => '4.3', + 'title' => 'Recaptcha Options', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => 'You can specify the reCAPTCHA theme options as comma separated data.(eg: theme:\'blackglass\', lang : \'fr\' ). Check the available options at <a href=\"https://developers.google.com/recaptcha/docs/display#config\">Customizing the Look and Feel of reCAPTCHA</a>.', + 'help_text' => '', + ), 'recaptchaPublicKey' => array( 'group_name' => 'CiviCRM Preferences', 'group' => 'core', 'name' => 'recaptchaPublicKey', - 'prefetch' => 1, - 'config_only' => 1, 'type' => 'String', 'quick_form_type' => 'Element', 'html_attributes' => array( @@ -603,8 +741,6 @@ function setting_getfields_expectedresult() { 'group_name' => 'CiviCRM Preferences', 'group' => 'core', 'name' => 'recaptchaPrivateKey', - 'prefetch' => 1, - 'config_only' => 1, 'type' => 'String', 'quick_form_type' => 'Element', 'html_attributes' => array( @@ -620,11 +756,10 @@ function setting_getfields_expectedresult() { 'description' => '', 'help_text' => '', ), - 'checksumTimeout' => array( + 'checksum_timeout' => array( 'group_name' => 'CiviCRM Preferences', 'group' => 'core', - 'name' => 'checksumTimeout', - 'prefetch' => 1, + 'name' => 'checksum_timeout', 'type' => 'Integer', 'quick_form_type' => 'Element', 'html_attributes' => array( @@ -644,7 +779,6 @@ function setting_getfields_expectedresult() { 'group_name' => 'CiviCRM Preferences', 'group' => 'core', 'name' => 'blogUrl', - 'prefetch' => 0, 'type' => 'String', 'quick_form_type' => 'Element', 'html_attributes' => array( @@ -664,7 +798,6 @@ function setting_getfields_expectedresult() { 'group_name' => 'CiviCRM Preferences', 'group' => 'core', 'name' => 'communityMessagesUrl', - 'prefetch' => 0, 'type' => 'String', 'quick_form_type' => 'Element', 'html_attributes' => array( @@ -680,22 +813,35 @@ function setting_getfields_expectedresult() { 'description' => 'Service providing CiviCRM community messages', 'help_text' => 'Use \"*default*\" for the system default or override with a custom URL', ), - 'resCacheCode' => array( + 'gettingStartedUrl' => array( 'group_name' => 'CiviCRM Preferences', 'group' => 'core', - 'name' => 'resCacheCode', - 'prefetch' => 1, - 'config_only' => 1, + 'name' => 'gettingStartedUrl', 'type' => 'String', 'quick_form_type' => 'Element', 'html_attributes' => array( - 'size' => 16, - 'maxlength' => 16, + 'size' => 64, + 'maxlength' => 128, ), 'html_type' => 'Text', + 'default' => '*default*', + 'add' => '4.3', + 'title' => 'Getting Started URL', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => 'Service providing the Getting Started data', + 'help_text' => 'Use \"*default*\" for the system default or override with a custom URL', + ), + 'resCacheCode' => array( + 'group_name' => 'CiviCRM Preferences', + 'group' => 'core', + 'name' => 'resCacheCode', + 'type' => 'String', + 'quick_form_type' => 'Element', + 'html_type' => 'text', 'default' => '', 'add' => '4.3', - 'title' => 'Resource Cache Code', + 'title' => 'resCacheCode', 'is_domain' => 1, 'is_contact' => 0, 'description' => 'Code appended to resource URLs (JS/CSS) to coerce HTTP caching', @@ -712,9 +858,23 @@ function setting_getfields_expectedresult() { 'title' => 'Verify SSL?', 'is_domain' => 1, 'is_contact' => 0, - 'description' => 'If disabled, backend HTTPS services will allow unverified, insecure connections', + 'description' => 'If disabled, outbound web-service requests will allow unverified, insecure HTTPS connections', 'help_text' => 'Unless you are absolutely unable to configure your server to check the SSL certificate of the remote server you should leave this set to Yes', ), + 'enableSSL' => array( + 'group_name' => 'CiviCRM Preferences', + 'group' => 'core', + 'name' => 'enableSSL', + 'type' => 'Boolean', + 'quick_form_type' => 'YesNo', + 'default' => 0, + 'add' => '4.5', + 'title' => 'Force SSL?', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => 'If enabled, inbound HTTP requests for sensitive pages will be redirected to HTTPS.', + 'help_text' => 'If enabled, inbound HTTP requests for sensitive pages will be redirected to HTTPS.', + ), 'wpBasePage' => array( 'group_name' => 'CiviCRM Preferences', 'group' => 'core', @@ -722,7 +882,6 @@ function setting_getfields_expectedresult() { 'type' => 'String', 'html_type' => 'text', 'quick_form_type' => 'Element', - 'prefetch' => 1, 'default' => '', 'add' => '4.3', 'title' => 'WordPress Base Page', @@ -735,7 +894,6 @@ function setting_getfields_expectedresult() { 'group_name' => 'CiviCRM Preferences', 'group' => 'core', 'name' => 'secondDegRelPermissions', - 'prefetch' => 1, 'type' => 'Boolean', 'quick_form_type' => 'YesNo', 'default' => 0, @@ -747,6 +905,7 @@ function setting_getfields_expectedresult() { 'help_text' => '', ), 'enable_components' => array( + 'bootstrap_comment' => 'This is a boot setting which may be loaded during bootstrap. Defaults are loaded via SettingsBag::getSystemDefaults().', 'group_name' => 'CiviCRM Preferences', 'group' => 'core', 'name' => 'enable_components', @@ -758,14 +917,7 @@ function setting_getfields_expectedresult() { 'style' => 'width:150px', 'class' => 'advmultiselect', ), - 'default' => array( - '0' => 'CiviEvent', - '1' => 'CiviContribute', - '2' => 'CiviMember', - '3' => 'CiviMail', - '4' => 'CiviReport', - '5' => 'CiviPledge', - ), + 'default' => '', 'add' => '4.4', 'title' => 'Enable Components', 'is_domain' => '1', @@ -796,7 +948,6 @@ function setting_getfields_expectedresult() { 'group_name' => 'CiviCRM Preferences', 'group' => 'core', 'name' => 'empoweredBy', - 'prefetch' => 1, 'type' => 'Boolean', 'quick_form_type' => 'YesNo', 'default' => 1, @@ -807,176 +958,446 @@ function setting_getfields_expectedresult() { 'description' => 'When enabled, \"empowered by CiviCRM\" is displayed at the bottom of public forms.', 'help_text' => '', ), - 'userFrameworkLogging' => array( - 'group_name' => 'Developer Preferences', - 'group' => 'developer', - 'name' => 'userFrameworkLogging', + 'logging_no_trigger_permission' => array( + 'add' => '4.7', + 'is_domain' => 1, + 'is_contact' => 0, + 'group_name' => 'CiviCRM Preferences', + 'group' => 'core', + 'help_text' => '(EXPERIMENTAL) If the MySQL user does not have permission to administer triggers, then you must create the triggers outside CiviCRM. No support is provided for this configuration.', + 'name' => 'logging_no_trigger_permission', 'type' => 'Boolean', 'quick_form_type' => 'YesNo', + 'html_type' => '', 'default' => 0, - 'add' => '4.3', - 'title' => 'Enable Drupal Watchdog Logging', + 'title' => '(EXPERIMENTAL) MySQL user does not have trigger permissions', + 'description' => 'Set this when you intend to manage trigger creation outside of CiviCRM', + ), + 'logging' => array( + 'add' => '4.7', + 'help_text' => '', 'is_domain' => 1, 'is_contact' => 0, - 'description' => 'Set this value to Yes if you want CiviCRM error/debugging messages to appear in the Drupal error logs', - 'prefetch' => 1, - 'help_text' => 'Set this value to Yes if you want CiviCRM error/debugging messages the appear in your CMS\' error log. In the case of Drupal, this will cause all CiviCRM error messages to appear in the watchdog (assuming you have Drupal\'s watchdog enabled)', - ), - 'debug_enabled' => array( - 'group_name' => 'Developer Preferences', - 'group' => 'developer', - 'name' => 'debug_enabled', - 'config_key' => 'debug', + 'group_name' => 'CiviCRM Preferences', + 'group' => 'core', + 'name' => 'logging', 'type' => 'Boolean', 'quick_form_type' => 'YesNo', + 'html_type' => '', 'default' => 0, - 'add' => '4.3', - 'title' => 'Enable Debugging', + 'title' => 'Logging', + 'description' => 'If enabled, all actions will be logged with a complete record of changes.', + 'validate_callback' => 'CRM_Logging_Schema::checkLoggingSupport', + 'on_change' => array( + '0' => 'CRM_Logging_Schema::onToggle', + ), + ), + 'logging_uniqueid_date' => array( + 'add' => '4.7', + 'help_text' => 'This is the date when CRM-18193 was implemented', 'is_domain' => 1, 'is_contact' => 0, - 'description' => 'Set this value to Yes if you want to use one of CiviCRM\'s debugging tools. This feature should NOT be enabled for production sites', - 'prefetch' => 1, - 'help_text' => 'Do not turn this on on production sites', + 'group_name' => 'CiviCRM Preferences', + 'group' => 'core', + 'name' => 'logging_uniqueid_date', + 'type' => 'Date', + 'quick_form_type' => 'DateTime', + 'html_type' => '', + 'default' => '', + 'title' => 'Logging Unique ID not recorded before', + 'description' => 'This is the date when CRM-18193 was implemented', ), - 'backtrace' => array( - 'group_name' => 'Developer Preferences', - 'group' => 'developer', - 'name' => 'backtrace', + 'logging_all_tables_uniquid' => array( + 'add' => '4.7', + 'help_text' => 'This indicates there are no tables holdng pre-uniqid log_conn_id values (CRM-18193)', + 'is_domain' => 1, + 'is_contact' => 0, + 'group_name' => 'CiviCRM Preferences', + 'group' => 'core', + 'name' => 'logging_all_tables_uniquid', 'type' => 'Boolean', 'quick_form_type' => 'YesNo', + 'html_type' => '', 'default' => 0, - 'add' => '4.3', - 'title' => 'Display Backtrace', + 'title' => 'All tables use Unique Connection ID', + 'description' => 'Do some tables pre-date CRM-18193?', + ), + 'userFrameworkUsersTableName' => array( + 'add' => '4.7', + 'help_text' => '', 'is_domain' => 1, 'is_contact' => 0, - 'description' => 'Set this value to Yes if you want to display a backtrace listing when a fatal error is encountered. This feature should NOT be enabled for production sites', - 'prefetch' => 1, - ), - 'fatalErrorHandler' => array( - 'group_name' => 'Developer Preferences', - 'group' => 'developer', - 'name' => 'fatalErrorHandler', + 'group_name' => 'CiviCRM Preferences', + 'group' => 'core', + 'name' => 'userFrameworkUsersTableName', 'type' => 'String', 'quick_form_type' => 'Element', 'html_type' => 'text', + 'html_attributes' => array( + 'size' => '32', + 'maxlength' => '64', + ), 'default' => '', - 'add' => '4.3', + 'title' => 'Drupal Users Table Name', + 'description' => '', + ), + 'wpLoadPhp' => array( + 'group_name' => 'CiviCRM Preferences', + 'group' => 'core', + 'name' => 'wpLoadPhp', + 'type' => 'String', + 'html_type' => 'text', + 'quick_form_type' => 'Element', + 'default' => '', + 'add' => '4.6', + 'title' => 'WordPress Path to wp-load.php', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => 'CiviCRM will use this setting as path to bootstrap WP.', + 'help_text' => '', + ), + 'secure_cache_timeout_minutes' => array( + 'group_name' => 'CiviCRM Preferences', + 'group' => 'core', + 'name' => 'secure_cache_timeout_minutes', + 'type' => 'Integer', + 'quick_form_type' => 'Element', + 'html_type' => 'text', + 'html_attributes' => array( + 'size' => 2, + 'maxlength' => 8, + ), + 'default' => 20, + 'add' => '4.7', + 'title' => 'Secure Cache Timeout', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => 'Maximum number of minutes that secure form data should linger', + 'help_text' => '', + ), + 'site_id' => array( + 'group_name' => 'CiviCRM Preferences', + 'group' => 'core', + 'name' => 'site_id', + 'type' => 'String', + 'quick_form_type' => 'Element', + 'html_type' => 'text', + 'default' => '', + 'add' => '4.6', + 'title' => 'Unique Site ID', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => '', + 'help_text' => '', + ), + 'systemStatusCheckResult' => array( + 'group_name' => 'CiviCRM Preferences', + 'group' => 'core', + 'name' => 'systemStatusCheckResult', + 'type' => 'Integer', + 'quick_form_type' => 'Element', + 'html_type' => 'text', + 'default' => 0, + 'add' => '4.7', + 'title' => 'systemStatusCheckResult', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => '', + 'help_text' => '', + ), + 'recentItemsMaxCount' => array( + 'group_name' => 'CiviCRM Preferences', + 'group' => 'core', + 'name' => 'recentItemsMaxCount', + 'type' => 'Integer', + 'quick_form_type' => 'Element', + 'html_type' => 'text', + 'html_attributes' => array( + 'size' => 2, + 'maxlength' => 3, + ), + 'default' => 20, + 'add' => '4.7', + 'title' => 'Size of \"Recent Items\" stack', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => 'How many items should CiviCRM store in it\'s \"Recently viewed\" list.', + 'help_text' => '', + ), + 'recentItemsProviders' => array( + 'group_name' => 'CiviCRM Preferences', + 'group' => 'core', + 'name' => 'recentItemsProviders', + 'type' => 'Array', + 'html_type' => 'Select', + 'quick_form_type' => 'Select', + 'html_attributes' => array( + 'multiple' => 1, + 'class' => 'crm-select2', + ), + 'default' => '', + 'add' => '4.7', + 'title' => 'Recent Items Providers', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => 'What providers may save views in CiviCRM\'s \"Recently viewed\" list. If empty, all are in.', + 'help_text' => '', + 'pseudoconstant' => array( + 'callback' => 'CRM_Utils_Recent::getProviders', + ), + ), + 'dedupe_default_limit' => array( + 'group_name' => 'CiviCRM Preferences', + 'group' => 'core', + 'name' => 'dedupe_default_limit', + 'type' => 'Integer', + 'default' => 0, + 'quick_form_type' => 'Element', + 'html_type' => 'text', + 'add' => '4.7', + 'title' => 'Default limit for dedupe screen', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => 'Default to only loading matches against this number of contacts', + 'help_text' => 'Deduping larger databases can crash the server. By configuring a limit other than 0 here the dedupe query will only search for matches against a limited number of contacts.', + ), + 'syncCMSEmail' => array( + 'group_name' => 'CiviCRM Preferences', + 'group' => 'core', + 'name' => 'syncCMSEmail', + 'type' => 'Boolean', + 'quick_form_type' => 'YesNo', + 'default' => 1, + 'add' => '4.7', + 'title' => 'Sync CMS Email', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => 'If enabled, then CMS email id will be syncronised with CiviCRM contacts\'s primary email.', + 'help_text' => '', + ), + 'userFrameworkLogging' => array( + 'group_name' => 'Developer Preferences', + 'group' => 'developer', + 'name' => 'userFrameworkLogging', + 'type' => 'Boolean', + 'quick_form_type' => 'YesNo', + 'default' => 0, + 'add' => '4.3', + 'title' => 'Enable Drupal Watchdog Logging', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => 'Set this value to Yes if you want CiviCRM error/debugging messages to appear in the Drupal error logs', + 'help_text' => 'Set this value to Yes if you want CiviCRM error/debugging messages the appear in your CMS\' error log. In the case of Drupal, this will cause all CiviCRM error messages to appear in the watchdog (assuming you have Drupal\'s watchdog enabled)', + ), + 'debug_enabled' => array( + 'group_name' => 'Developer Preferences', + 'group' => 'developer', + 'name' => 'debug_enabled', + 'config_key' => 'debug', + 'type' => 'Boolean', + 'quick_form_type' => 'YesNo', + 'default' => 0, + 'add' => '4.3', + 'title' => 'Enable Debugging', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => 'Set this value to Yes if you want to use one of CiviCRM\'s debugging tools. This feature should NOT be enabled for production sites', + 'help_text' => 'Do not turn this on on production sites', + ), + 'backtrace' => array( + 'group_name' => 'Developer Preferences', + 'group' => 'developer', + 'name' => 'backtrace', + 'type' => 'Boolean', + 'quick_form_type' => 'YesNo', + 'default' => 0, + 'add' => '4.3', + 'title' => 'Display Backtrace', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => 'Set this value to Yes if you want to display a backtrace listing when a fatal error is encountered. This feature should NOT be enabled for production sites', + ), + 'fatalErrorHandler' => array( + 'group_name' => 'Developer Preferences', + 'group' => 'developer', + 'name' => 'fatalErrorHandler', + 'type' => 'String', + 'quick_form_type' => 'Element', + 'html_type' => 'text', + 'default' => '', + 'add' => '4.3', 'title' => 'Fatal Error Handler', 'is_domain' => 1, 'is_contact' => 0, 'description' => 'Enter the path and class for a custom PHP error-handling function if you want to override built-in CiviCRM error handling for your site.', - 'prefetch' => 1, ), 'uploadDir' => array( + 'bootstrap_comment' => 'This is a boot setting which may be loaded during bootstrap. Defaults are loaded via SettingsBag::getSystemDefaults().', 'group_name' => 'Directory Preferences', 'group' => 'directory', 'name' => 'uploadDir', - 'type' => 'Url', + 'type' => 'String', 'html_type' => 'Text', + 'quick_form_type' => 'Element', 'default' => '', 'add' => '4.1', - 'prefetch' => 1, - 'title' => 'Upload Directory', + 'title' => 'Temporary Files Directory', 'is_domain' => 1, 'is_contact' => 0, 'description' => '', - 'help_text' => '', + 'help_text' => 'File system path where temporary CiviCRM files - such as import data files - are uploaded.', ), 'imageUploadDir' => array( + 'bootstrap_comment' => 'This is a boot setting which may be loaded during bootstrap. Defaults are loaded via SettingsBag::getSystemDefaults().', 'group_name' => 'Directory Preferences', 'group' => 'directory', 'name' => 'imageUploadDir', - 'type' => 'Url', + 'type' => 'String', 'html_type' => 'Text', + 'quick_form_type' => 'Element', 'default' => '', 'add' => '4.1', - 'prefetch' => 1, 'title' => 'Image Directory', 'is_domain' => 1, 'is_contact' => 0, - 'description' => '', + 'description' => 'File system path where image files are uploaded. Currently, this path is used for images associated with premiums (CiviContribute thank-you gifts).', 'help_text' => '', ), 'customFileUploadDir' => array( + 'bootstrap_comment' => 'This is a boot setting which may be loaded during bootstrap. Defaults are loaded via SettingsBag::getSystemDefaults().', 'group_name' => 'Directory Preferences', 'group' => 'directory', 'name' => 'customFileUploadDir', - 'type' => 'Url', + 'type' => 'String', 'html_type' => 'Text', + 'quick_form_type' => 'Element', 'default' => '', 'add' => '4.1', - 'prefetch' => 1, - 'title' => 'Custom Files Upload Directory', + 'title' => 'Custom Files Directory', 'is_domain' => 1, 'is_contact' => 0, - 'description' => '', + 'description' => 'Path where documents and images which are attachments to contact records are stored (e.g. contact photos, resumes, contracts, etc.). These attachments are defined using \'file\' type custom fields.', 'help_text' => '', ), 'customTemplateDir' => array( + 'bootstrap_comment' => 'This is a boot setting which may be loaded during bootstrap. Defaults are loaded via SettingsBag::getSystemDefaults().', 'group_name' => 'Directory Preferences', 'group' => 'directory', 'name' => 'customTemplateDir', - 'type' => 'Url', + 'type' => 'String', 'html_type' => 'Text', + 'quick_form_type' => 'Element', 'default' => '', 'add' => '4.1', - 'prefetch' => 1, 'title' => 'Custom Template Directory', 'is_domain' => 1, 'is_contact' => 0, - 'description' => '', + 'description' => 'Path where site specific templates are stored if any. This directory is searched first if set. Custom JavaScript code can be added to templates by creating files named templateFile.extra.tpl. (learn more...)', 'help_text' => '', ), 'customPHPPathDir' => array( + 'bootstrap_comment' => 'This is a boot setting which may be loaded during bootstrap. Defaults are loaded via SettingsBag::getSystemDefaults().', 'group_name' => 'Directory Preferences', 'group' => 'directory', 'name' => 'customPHPPathDir', - 'type' => 'Url', + 'type' => 'String', 'html_type' => 'Text', + 'quick_form_type' => 'Element', 'default' => '', 'add' => '4.1', - 'prefetch' => 1, - 'title' => 'Custom PHP Path', + 'title' => 'Custom PHP Directory', 'is_domain' => 1, 'is_contact' => 0, - 'description' => '', + 'description' => 'Path where site specific PHP code files are stored if any. This directory is searched first if set.', 'help_text' => '', ), 'extensionsDir' => array( + 'bootstrap_comment' => 'This is a boot setting which may be loaded during bootstrap. Defaults are loaded via SettingsBag::getSystemDefaults().', 'group_name' => 'Directory Preferences', 'group' => 'directory', 'name' => 'extensionsDir', - 'type' => 'Url', + 'type' => 'String', 'html_type' => 'Text', + 'quick_form_type' => 'Element', 'default' => '', 'add' => '4.1', - 'prefetch' => 1, 'title' => 'Extensions Directory', 'is_domain' => 1, 'is_contact' => 0, - 'description' => '', + 'description' => 'Path where CiviCRM extensions are stored.', 'help_text' => '', ), - 'event_enable_cart' => array( + 'enable_cart' => array( 'name' => 'enable_cart', 'group_name' => 'Event Preferences', 'group' => 'event', - 'type' => 'String', + 'type' => 'Boolean', 'quick_form_type' => 'Element', 'default' => 0, 'add' => '4.1', 'title' => 'Enable Event Cart', 'is_domain' => 1, - 'is_contact' => 1, + 'is_contact' => 0, 'description' => 'WRITE ME', 'help_text' => 'WRITE ME', ), + 'show_events' => array( + 'name' => 'show_events', + 'group_name' => 'Event Preferences', + 'group' => 'event', + 'type' => 'Integer', + 'quick_form_type' => 'Element', + 'default' => 10, + 'add' => '4.5', + 'title' => 'Dashboard entries', + 'html_type' => 'select', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => 'Configure how many events should be shown on the dashboard. This overrides the default value of 10 entries.', + 'help_text' => '', + ), + 'ext_repo_url' => array( + 'group_name' => 'Extension Preferences', + 'group' => 'ext', + 'name' => 'ext_repo_url', + 'type' => 'String', + 'quick_form_type' => 'Element', + 'html_attributes' => array( + 'size' => 64, + 'maxlength' => 128, + ), + 'html_type' => 'Text', + 'default' => 'https://civicrm.org/extdir/ver={ver}|cms={uf}', + 'add' => '4.3', + 'title' => 'Extension Repo URL', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => '', + 'help_text' => '', + ), + 'customTranslateFunction' => array( + 'add' => '4.7', + 'help_text' => '', + 'is_domain' => 1, + 'is_contact' => 0, + 'group_name' => 'Localization Preferences', + 'group' => 'localization', + 'name' => 'customTranslateFunction', + 'type' => 'String', + 'quick_form_type' => 'Element', + 'html_type' => 'text', + 'html_attributes' => array( + 'size' => '30', + 'maxlength' => '100', + ), + 'default' => '', + 'title' => 'Custom Translate Function', + 'description' => '', + ), 'monetaryThousandSeparator' => array( 'group_name' => 'Localization Preferences', 'group' => 'localization', 'name' => 'monetaryThousandSeparator', - 'prefetch' => 1, - 'config_only' => 1, 'type' => 'String', 'quick_form_type' => 'Element', 'html_type' => 'text', @@ -995,8 +1416,6 @@ function setting_getfields_expectedresult() { 'group_name' => 'Localization Preferences', 'group' => 'localization', 'name' => 'monetaryDecimalPoint', - 'prefetch' => 1, - 'config_only' => 1, 'type' => 'String', 'quick_form_type' => 'Element', 'html_type' => 'text', @@ -1015,8 +1434,6 @@ function setting_getfields_expectedresult() { 'group_name' => 'Localization Preferences', 'group' => 'localization', 'name' => 'moneyformat', - 'prefetch' => 1, - 'config_only' => 1, 'type' => 'String', 'quick_form_type' => 'Element', 'html_type' => 'text', @@ -1032,14 +1449,12 @@ function setting_getfields_expectedresult() { 'group_name' => 'Localization Preferences', 'group' => 'localization', 'name' => 'moneyvalueformat', - 'prefetch' => 1, - 'config_only' => 1, 'type' => 'String', 'quick_form_type' => 'Element', 'html_type' => 'text', 'default' => '%!i', 'add' => '4.3', - 'title' => 'Monetary Amount Display', + 'title' => 'Monetary Value Display', 'is_domain' => 1, 'is_contact' => 0, 'description' => '', @@ -1049,13 +1464,11 @@ function setting_getfields_expectedresult() { 'group_name' => 'Localization Preferences', 'group' => 'localization', 'name' => 'defaultCurrency', - 'prefetch' => 1, - 'config_only' => 1, 'type' => 'String', - 'quick_form_type' => 'Element', - 'html_type' => 'text', + 'quick_form_type' => 'Select', + 'html_type' => 'Select', 'html_attributes' => array( - 'size' => 2, + 'class' => 'crm-select2', ), 'default' => 'USD', 'add' => '4.3', @@ -1064,19 +1477,18 @@ function setting_getfields_expectedresult() { 'is_contact' => 0, 'description' => 'Default currency assigned to contributions and other monetary transactions.', 'help_text' => '', + 'pseudoconstant' => array( + 'callback' => 'CRM_Admin_Form_Setting_Localization::getCurrencySymbols', + ), ), 'defaultContactCountry' => array( 'group_name' => 'Localization Preferences', 'group' => 'localization', 'name' => 'defaultContactCountry', - 'prefetch' => 1, - 'config_only' => 1, 'type' => 'String', - 'quick_form_type' => 'Element', - 'html_type' => 'text', - 'html_attributes' => array( - 'size' => 4, - ), + 'quick_form_type' => 'Select', + 'html_type' => 'Select', + 'html_attributes' => array(), 'default' => '1228', 'add' => '4.4', 'title' => 'Default Country', @@ -1084,13 +1496,29 @@ function setting_getfields_expectedresult() { 'is_contact' => 0, 'description' => 'This value is selected by default when adding a new contact address.', 'help_text' => '', + 'pseudoconstant' => array( + 'callback' => 'CRM_Admin_Form_Setting_Localization::getAvailableCountries', + ), + ), + 'defaultContactStateProvince' => array( + 'add' => '4.7', + 'help_text' => '', + 'is_domain' => 1, + 'is_contact' => 0, + 'group_name' => 'Localization Preferences', + 'group' => 'localization', + 'name' => 'defaultContactStateProvince', + 'type' => 'Integer', + 'quick_form_type' => 'ChainSelect', + 'html_type' => 'ChainSelect', + 'default' => '', + 'title' => 'Default State/Province', + 'description' => 'This value is selected by default when adding a new contact address.', ), 'countryLimit' => array( 'group_name' => 'Localization Preferences', 'group' => 'localization', 'name' => 'countryLimit', - 'prefetch' => 1, - 'config_only' => 1, 'type' => 'Array', 'quick_form_type' => 'Element', 'html_type' => 'advmultiselect', @@ -1099,20 +1527,21 @@ function setting_getfields_expectedresult() { 'style' => 'width:150px', 'class' => 'advmultiselect', ), - 'default' => 'null', + 'default' => array(), 'add' => '4.3', 'title' => 'Available Countries', 'is_domain' => 1, 'is_contact' => 0, 'description' => '', 'help_text' => '', + 'pseudoconstant' => array( + 'callback' => 'CRM_Admin_Form_Setting_Localization::getAvailableCountries', + ), ), 'provinceLimit' => array( 'group_name' => 'Localization Preferences', 'group' => 'localization', 'name' => 'provinceLimit', - 'prefetch' => 1, - 'config_only' => 1, 'type' => 'Array', 'quick_form_type' => 'Element', 'html_type' => 'advmultiselect', @@ -1121,20 +1550,21 @@ function setting_getfields_expectedresult() { 'style' => 'width:150px', 'class' => 'advmultiselect', ), - 'default' => 'null', + 'default' => array(), 'add' => '4.3', - 'title' => 'Available States and Provinces', + 'title' => 'Available States and Provinces (by Country)', 'is_domain' => 1, 'is_contact' => 0, 'description' => '', 'help_text' => '', + 'pseudoconstant' => array( + 'callback' => 'CRM_Admin_Form_Setting_Localization::getAvailableCountries', + ), ), 'inheritLocale' => array( 'group_name' => 'Localization Preferences', 'group' => 'localization', 'name' => 'inheritLocale', - 'prefetch' => 1, - 'config_only' => 1, 'type' => 'Boolean', 'quick_form_type' => 'YesNo', 'default' => 0, @@ -1149,12 +1579,12 @@ function setting_getfields_expectedresult() { 'group_name' => 'Localization Preferences', 'group' => 'localization', 'name' => 'dateformatDatetime', - 'prefetch' => 1, - 'config_only' => 1, 'type' => 'String', + 'quick_form_type' => 'Element', + 'html_type' => 'text', 'default' => '%B %E%f, %Y %l:%M %P', 'add' => '4.3', - 'title' => 'Complete Date and Time', + 'title' => 'Date Format: Complete Date and Time', 'is_domain' => 1, 'is_contact' => 0, 'description' => '', @@ -1164,12 +1594,12 @@ function setting_getfields_expectedresult() { 'group_name' => 'Localization Preferences', 'group' => 'localization', 'name' => 'dateformatFull', - 'prefetch' => 1, - 'config_only' => 1, 'type' => 'String', + 'quick_form_type' => 'Element', + 'html_type' => 'text', 'default' => '%B %E%f, %Y', 'add' => '4.3', - 'title' => 'Complete Date', + 'title' => 'Date Format: Complete Date', 'is_domain' => 1, 'is_contact' => 0, 'description' => '', @@ -1179,31 +1609,272 @@ function setting_getfields_expectedresult() { 'group_name' => 'Localization Preferences', 'group' => 'localization', 'name' => 'dateformatPartial', - 'prefetch' => 1, - 'config_only' => 1, 'type' => 'String', + 'quick_form_type' => 'Element', + 'html_type' => 'text', 'default' => '%B %Y', 'add' => '4.3', - 'title' => 'Month and Year', + 'title' => 'Date Format: Month and Year', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => '', + 'help_text' => '', + ), + 'dateformatTime' => array( + 'add' => '4.7', + 'help_text' => '', + 'is_domain' => 1, + 'is_contact' => 0, + 'group_name' => 'Localization Preferences', + 'group' => 'localization', + 'name' => 'dateformatTime', + 'type' => 'String', + 'quick_form_type' => 'Element', + 'html_type' => 'text', + 'html_attributes' => array( + 'size' => '12', + 'maxlength' => '60', + ), + 'default' => '%l:%M %P', + 'title' => 'Date Format: Time Only', + 'description' => '', + ), + 'dateformatYear' => array( + 'add' => '4.7', + 'help_text' => '', + 'is_domain' => 1, + 'is_contact' => 0, + 'group_name' => 'Localization Preferences', + 'group' => 'localization', + 'name' => 'dateformatYear', + 'type' => 'String', + 'quick_form_type' => 'Element', + 'html_type' => 'text', + 'html_attributes' => array( + 'size' => '12', + 'maxlength' => '60', + ), + 'default' => '%Y', + 'title' => 'Date Format: Year Only', + 'description' => '', + ), + 'dateformatFinancialBatch' => array( + 'add' => '4.7', + 'help_text' => '', 'is_domain' => 1, 'is_contact' => 0, + 'group_name' => 'Localization Preferences', + 'group' => 'localization', + 'name' => 'dateformatFinancialBatch', + 'type' => 'String', + 'quick_form_type' => 'Element', + 'html_type' => 'text', + 'html_attributes' => array( + 'size' => '12', + 'maxlength' => '60', + ), + 'default' => '%m/%d/%Y', + 'title' => 'Date Format: Financial Batch', 'description' => '', + ), + 'dateformatshortdate' => array( + 'add' => '4.7', 'help_text' => '', + 'is_domain' => 1, + 'is_contact' => 0, + 'group_name' => 'Localization Preferences', + 'group' => 'localization', + 'name' => 'dateformatshortdate', + 'type' => 'String', + 'quick_form_type' => 'Element', + 'html_type' => 'text', + 'html_attributes' => array( + 'size' => '12', + 'maxlength' => '60', + ), + 'default' => '%m/%d/%Y', + 'title' => 'Date Format: Short date Month Day Year', + 'description' => '', + ), + 'dateInputFormat' => array( + 'add' => '4.7', + 'help_text' => '', + 'is_domain' => 1, + 'is_contact' => 0, + 'group_name' => 'Localization Preferences', + 'group' => 'localization', + 'name' => 'dateInputFormat', + 'type' => 'String', + 'quick_form_type' => 'Select', + 'html_type' => 'Select', + 'pseudoconstant' => array( + 'callback' => 'CRM_Core_SelectValues::getDatePluginInputFormats', + ), + 'default' => 'mm/dd/yy', + 'title' => 'Date Input Format', + 'description' => '', + ), + 'fieldSeparator' => array( + 'add' => '4.7', + 'help_text' => '', + 'is_domain' => 1, + 'is_contact' => 0, + 'group_name' => 'Localization Preferences', + 'group' => 'localization', + 'name' => 'fieldSeparator', + 'type' => 'String', + 'quick_form_type' => 'Element', + 'html_type' => 'text', + 'html_attributes' => array( + 'size' => '2', + 'maxlength' => '8', + ), + 'default' => ',', + 'title' => 'Import / Export Field Separator', + 'description' => 'Global CSV separator character. Modify this setting to enable import and export of different kinds of CSV files (for example: \',\' \';\' \':\' \'|\' ).', + ), + 'fiscalYearStart' => array( + 'add' => '4.7', + 'help_text' => '', + 'is_domain' => 1, + 'is_contact' => 0, + 'group_name' => 'Localization Preferences', + 'group' => 'localization', + 'name' => 'fiscalYearStart', + 'type' => 'Array', + 'quick_form_type' => 'MonthDay', + 'html_type' => 'MonthDay', + 'default' => array( + 'M' => 1, + 'd' => 1, + ), + 'title' => 'Fiscal Year Start', + 'description' => '', + ), + 'languageLimit' => array( + 'group_name' => 'Localization Preferences', + 'group' => 'localization', + 'name' => 'languageLimit', + 'type' => 'Array', + 'quick_form_type' => 'Select', + 'html_type' => 'Select', + 'html_attributes' => array( + 'multiple' => 1, + 'class' => 'crm-select2', + ), + 'default' => '', + 'add' => '4.3', + 'title' => 'Available Languages (Multi-lingual)', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => '', + 'help_text' => '', + 'pseudoconstant' => array( + 'callback' => 'CRM_Core_I18n::languages', + ), ), 'lcMessages' => array( 'group_name' => 'Localization Preferences', 'group' => 'localization', 'name' => 'lcMessages', - 'prefetch' => 1, - 'config_only' => 1, 'type' => 'String', + 'quick_form_type' => 'Select', + 'html_type' => 'Select', + 'html_attributes' => array( + 'class' => 'crm-select2', + ), 'default' => 'en_US', 'add' => '4.3', 'title' => 'Default Language', 'is_domain' => 1, 'is_contact' => 0, - 'description' => '', - 'help_text' => '', + 'description' => '', + 'help_text' => '', + 'pseudoconstant' => array( + 'callback' => 'CRM_Admin_Form_Setting_Localization::getDefaultLocaleOptions', + ), + 'on_change' => array( + '0' => 'CRM_Admin_Form_Setting_Localization::onChangeLcMessages', + ), + ), + 'legacyEncoding' => array( + 'add' => '4.7', + 'help_text' => '', + 'is_domain' => 1, + 'is_contact' => 0, + 'group_name' => 'Localization Preferences', + 'group' => 'localization', + 'name' => 'legacyEncoding', + 'type' => 'String', + 'quick_form_type' => 'Element', + 'html_type' => 'text', + 'html_attributes' => array( + 'size' => '12', + 'maxlength' => '30', + ), + 'default' => 'Windows-1252', + 'title' => 'Legacy Encoding', + 'description' => 'If import files are NOT encoded as UTF-8, specify an alternate character encoding for these files. The default of Windows-1252 will work for Excel-created .CSV files on many computers.', + ), + 'timeInputFormat' => array( + 'add' => '4.7', + 'help_text' => '', + 'is_domain' => 1, + 'is_contact' => 0, + 'group_name' => 'Localization Preferences', + 'group' => 'localization', + 'name' => 'timeInputFormat', + 'type' => 'String', + 'quick_form_type' => 'Select', + 'html_type' => 'Select', + 'pseudoconstant' => array( + 'callback' => 'CRM_Core_SelectValues::getTimeFormats', + ), + 'default' => '1', + 'title' => 'Time Input Format', + 'description' => '', + 'on_change' => array( + '0' => 'CRM_Core_BAO_PreferencesDate::onChangeSetting', + ), + ), + 'weekBegins' => array( + 'group_name' => 'Localization Preferences', + 'group' => 'localization', + 'name' => 'weekBegins', + 'type' => 'String', + 'quick_form_type' => 'Select', + 'html_type' => 'Select', + 'pseudoconstant' => array( + 'callback' => 'CRM_Utils_Date::getFullWeekdayNames', + ), + 'default' => 0, + 'add' => '4.7', + 'title' => 'Week begins on', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => '', + 'help_text' => '', + ), + 'contact_default_language' => array( + 'group_name' => 'Localization Preferences', + 'group' => 'localization', + 'name' => 'contact_default_language', + 'type' => 'String', + 'quick_form_type' => 'Select', + 'html_type' => 'Select', + 'html_attributes' => array( + 'class' => 'crm-select2', + ), + 'pseudoconstant' => array( + 'callback' => 'CRM_Admin_Form_Setting_Localization::getDefaultLanguageOptions', + ), + 'default' => '*default*', + 'add' => '4.7', + 'title' => 'Default Language for contacts', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => 'Default language (if any) for contact records', + 'help_text' => 'If a contact is created with no language this setting will determine the language data (if any) to save.You may or may not wish to make an assumption here about whether it matches the site language', ), 'profile_double_optin' => array( 'group_name' => 'Mailing Preferences', @@ -1211,7 +1882,7 @@ function setting_getfields_expectedresult() { 'name' => 'profile_double_optin', 'type' => 'Integer', 'html_type' => 'checkbox', - 'default' => 0, + 'default' => '1', 'add' => '4.1', 'title' => 'Enable Double Opt-in for Profile Group(s) field', 'is_domain' => 1, @@ -1262,13 +1933,29 @@ function setting_getfields_expectedresult() { 'description' => '', 'help_text' => '', ), + 'replyTo' => array( + 'group_name' => 'Mailing Preferences', + 'group' => 'mailing', + 'name' => 'replyTo', + 'type' => 'Boolean', + 'quick_form_type' => 'YesNo', + 'default' => 0, + 'add' => '4.6', + 'title' => 'Enable Custom Reply-To', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => 'Allow CiviMail users to send mailings with a custom Reply-To header', + 'help_text' => '', + ), 'mailing_backend' => array( 'group_name' => 'Mailing Preferences', 'group' => 'mailing', 'name' => 'mailing_backend', 'type' => 'Array', 'html_type' => 'checkbox', - 'default' => 0, + 'default' => array( + 'outBound_option' => '3', + ), 'add' => '4.1', 'title' => 'Mailing Backend', 'is_domain' => 1, @@ -1332,6 +2019,223 @@ function setting_getfields_expectedresult() { 'description' => 'If enabled, a randomized hash key will be used to reference the mailing URL in the mailing.viewUrl token, instead of the mailing ID', 'help_text' => '', ), + 'civimail_multiple_bulk_emails' => array( + 'group_name' => 'Mailing Preferences', + 'group' => 'mailing', + 'name' => 'civimail_multiple_bulk_emails', + 'type' => 'Integer', + 'html_type' => 'checkbox', + 'default' => 0, + 'add' => '4.5', + 'title' => ' Multiple Bulk Emails', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => 'If enabled, CiviMail will deliver a copy of the email to each bulk email listed for the contact.', + 'help_text' => '', + ), + 'include_message_id' => array( + 'group_name' => 'Mailing Preferences', + 'group' => 'mailing', + 'name' => 'include_message_id', + 'type' => 'Integer', + 'html_type' => 'checkbox', + 'default' => '', + 'add' => '4.5', + 'title' => 'Enable CiviMail to generate Message-ID header', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => '', + 'help_text' => '', + ), + 'mailerBatchLimit' => array( + 'group_name' => 'Mailing Preferences', + 'group' => 'mailing', + 'name' => 'mailerBatchLimit', + 'type' => 'Integer', + 'quick_form_type' => 'Element', + 'html_type' => 'text', + 'html_attributes' => array( + 'size' => 4, + 'maxlength' => 8, + ), + 'default' => 0, + 'add' => '4.7', + 'title' => 'Mailer Batch Limit', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => 'Throttle email delivery by setting the maximum number of emails sent during each CiviMail run (0 = unlimited).', + 'help_text' => '', + ), + 'mailerJobSize' => array( + 'group_name' => 'Mailing Preferences', + 'group' => 'mailing', + 'name' => 'mailerJobSize', + 'type' => 'Integer', + 'quick_form_type' => 'Element', + 'html_type' => 'text', + 'html_attributes' => array( + 'size' => 4, + 'maxlength' => 8, + ), + 'default' => 0, + 'add' => '4.7', + 'title' => 'Mailer Job Size', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => 'If you want to utilize multi-threading enter the size you want your sub jobs to be split into. Recommended values are between 1,000 and 10,000. Use a lower value if your server has multiple cron jobs running simultaneously, but do not use values smaller than 1,000. Enter \"0\" to disable multi-threading and process mail as one single job - batch limits still apply.', + 'help_text' => '', + ), + 'mailerJobsMax' => array( + 'group_name' => 'Mailing Preferences', + 'group' => 'mailing', + 'name' => 'mailerJobsMax', + 'type' => 'Integer', + 'quick_form_type' => 'Element', + 'html_type' => 'text', + 'html_attributes' => array( + 'size' => 4, + 'maxlength' => 8, + ), + 'default' => 0, + 'add' => '4.7', + 'title' => 'Mailer Cron Job Limit', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => 'The maximum number of mailer delivery jobs executing simultaneously (0 = allow as many processes to execute as started by cron)', + 'help_text' => '', + ), + 'mailThrottleTime' => array( + 'group_name' => 'Mailing Preferences', + 'group' => 'mailing', + 'name' => 'mailThrottleTime', + 'type' => 'Integer', + 'quick_form_type' => 'Element', + 'html_type' => 'text', + 'html_attributes' => array( + 'size' => 4, + 'maxlength' => 8, + ), + 'default' => 0, + 'add' => '4.7', + 'title' => 'Mailer Throttle Time', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => 'The time to sleep in between each e-mail in micro seconds. Setting this above 0 allows you to control the rate at which e-mail messages are sent to the mail server, avoiding filling up the mail queue very quickly. Set to 0 to disable.', + 'help_text' => '', + ), + 'verpSeparator' => array( + 'group_name' => 'Mailing Preferences', + 'group' => 'mailing', + 'name' => 'verpSeparator', + 'type' => 'String', + 'quick_form_type' => 'Element', + 'html_type' => 'text', + 'html_attributes' => array( + 'size' => 4, + 'maxlength' => 32, + ), + 'default' => '.', + 'add' => '4.7', + 'title' => 'VERP Separator', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => 'Separator character used when CiviMail generates VERP (variable envelope return path) Mail-From addresses.', + 'help_text' => '', + ), + 'write_activity_record' => array( + 'group_name' => 'Mailing Preferences', + 'group' => 'mailing', + 'name' => 'write_activity_record', + 'type' => 'Boolean', + 'quick_form_type' => 'YesNo', + 'default' => '1', + 'add' => '4.7', + 'title' => 'Enable CiviMail to create activities on delivery', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => '', + 'help_text' => '', + ), + 'geoAPIKey' => array( + 'add' => '4.7', + 'help_text' => '', + 'is_domain' => 1, + 'is_contact' => 0, + 'group_name' => 'Map Preferences', + 'group' => 'map', + 'name' => 'geoAPIKey', + 'type' => 'String', + 'quick_form_type' => 'Element', + 'html_type' => 'text', + 'html_attributes' => array( + 'size' => '32', + 'maxlength' => '64', + ), + 'default' => '', + 'title' => 'Geo Provider Key', + 'description' => 'Enter the API key or Application ID associated with your geocoding provider (not required for Yahoo).', + ), + 'geoProvider' => array( + 'add' => '4.7', + 'help_text' => '', + 'is_domain' => 1, + 'is_contact' => 0, + 'group_name' => 'Map Preferences', + 'group' => 'map', + 'name' => 'geoProvider', + 'type' => 'String', + 'quick_form_type' => 'Select', + 'html_type' => 'Select', + 'html_attributes' => array( + 'class' => 'crm-select2', + ), + 'pseudoconstant' => array( + 'callback' => 'CRM_Core_SelectValues::geoProvider', + ), + 'default' => '', + 'title' => 'Geocoding Provider', + 'description' => 'You may choose a different webservice for geocoding. This is required if there is no geo-coding plugin for your selected mapping provider. You can leave the Geocoding fields blank if you are using Google as your mapping provider.', + ), + 'mapAPIKey' => array( + 'add' => '4.7', + 'help_text' => '', + 'is_domain' => 1, + 'is_contact' => 0, + 'group_name' => 'Map Preferences', + 'group' => 'map', + 'name' => 'mapAPIKey', + 'type' => 'String', + 'quick_form_type' => 'Element', + 'html_type' => 'text', + 'html_attributes' => array( + 'size' => '32', + 'maxlength' => '64', + ), + 'default' => '', + 'title' => 'Map Provider Key', + 'description' => 'Enter your API Key or Application ID. An API Key is currently optional for Google Maps API, but may be helpful diagnosing any problems and required for higher volumes of requests. Refer to developers.google.com for the latest information.', + ), + 'mapProvider' => array( + 'add' => '4.7', + 'help_text' => '', + 'is_domain' => 1, + 'is_contact' => 0, + 'group_name' => 'Map Preferences', + 'group' => 'map', + 'name' => 'mapProvider', + 'type' => 'String', + 'quick_form_type' => 'Select', + 'html_type' => 'Select', + 'html_attributes' => array( + 'class' => 'crm-select2', + ), + 'pseudoconstant' => array( + 'callback' => 'CRM_Core_SelectValues::mapProvider', + ), + 'default' => '', + 'title' => 'Mapping Provider', + 'description' => 'Choose the mapping provider that has the best coverage for the majority of your contact addresses.', + ), 'default_renewal_contribution_page' => array( 'group_name' => 'Member Preferences', 'group' => 'member', @@ -1355,7 +2259,7 @@ function setting_getfields_expectedresult() { 'name' => 'is_enabled', 'title' => 'Multisite Is enabled', 'type' => 'Integer', - 'default' => '', + 'default' => 0, 'add' => '4.1', 'is_domain' => 1, 'is_contact' => 0, @@ -1368,7 +2272,7 @@ function setting_getfields_expectedresult() { 'name' => 'domain_group_id', 'title' => 'Multisite Domain Group', 'type' => 'Integer', - 'default' => '', + 'default' => 0, 'add' => '4.1', 'is_domain' => 1, 'is_contact' => 0, @@ -1381,7 +2285,7 @@ function setting_getfields_expectedresult() { 'name' => 'event_price_set_domain_id', 'title' => 'Domain Event Price Set', 'type' => 'Integer', - 'default' => '', + 'default' => 0, 'add' => '4.1', 'is_domain' => 1, 'is_contact' => 0, @@ -1394,7 +2298,7 @@ function setting_getfields_expectedresult() { 'name' => 'uniq_email_per_site', 'type' => 'Integer', 'title' => 'Unique Email per Domain?', - 'default' => '', + 'default' => 0, 'add' => '4.1', 'is_domain' => 1, 'is_contact' => 0, @@ -1405,7 +2309,6 @@ function setting_getfields_expectedresult() { 'group_name' => 'Search Preferences', 'group' => 'Search Preferences', 'name' => 'search_autocomplete_count', - 'prefetch' => 0, 'type' => 'Integer', 'quick_form_type' => 'Element', 'html_type' => 'text', @@ -1425,7 +2328,6 @@ function setting_getfields_expectedresult() { 'group_name' => 'Search Preferences', 'group' => 'Search Preferences', 'name' => 'enable_innodb_fts', - 'prefetch' => 0, 'type' => 'Boolean', 'quick_form_type' => 'YesNo', 'default' => 0, @@ -1446,7 +2348,6 @@ function setting_getfields_expectedresult() { 'group_name' => 'Search Preferences', 'group' => 'Search Preferences', 'name' => 'fts_query_mode', - 'prefetch' => 0, 'type' => 'String', 'quick_form_type' => 'Element', 'html_attributes' => array( @@ -1462,50 +2363,179 @@ function setting_getfields_expectedresult() { 'description' => '', 'help_text' => '', ), + 'includeOrderByClause' => array( + 'group_name' => 'Search Preferences', + 'group' => 'Search Preferences', + 'name' => 'includeOrderByClause', + 'type' => 'Boolean', + 'quick_form_type' => 'YesNo', + 'default' => 1, + 'add' => '4.6', + 'title' => 'Include Order By Clause', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => 'If disabled, the search results will not be ordered. This may improve response time on search results on large datasets', + 'help_text' => '', + ), + 'includeWildCardInName' => array( + 'group_name' => 'Search Preferences', + 'group' => 'Search Preferences', + 'name' => 'includeWildCardInName', + 'type' => 'Boolean', + 'quick_form_type' => 'YesNo', + 'default' => 1, + 'add' => '4.6', + 'title' => 'Automatic Wildcard', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => 'If enabled, wildcards are automatically added to the beginning AND end of the search term when users search for contacts by Name. EXAMPLE: Searching for \'ada\' will return any contact whose name includes those letters - e.g. \'Adams, Janet\', \'Nadal, Jorge\', etc. If disabled, a wildcard is added to the end of the search term only. EXAMPLE: Searching for \'ada\' will return any contact whose last name begins with those letters - e.g. \'Adams, Janet\' but NOT \'Nadal, Jorge\'. Disabling this feature will speed up search significantly for larger databases, but users must manually enter wildcards (\'%\' or \'_\') to the beginning of the search term if they want to find all records which contain those letters. EXAMPLE: \'%ada\' will return \'Nadal, Jorge\'.', + 'help_text' => '', + ), + 'includeEmailInName' => array( + 'group_name' => 'Search Preferences', + 'group' => 'Search Preferences', + 'name' => 'includeEmailInName', + 'type' => 'Boolean', + 'quick_form_type' => 'YesNo', + 'default' => 1, + 'add' => '4.6', + 'title' => 'Include Email', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => 'If enabled, email addresses are automatically included when users search by Name. Disabling this feature will speed up search significantly for larger databases, but users will need to use the Email search fields (from Advanced Search, Search Builder, or Profiles) to find contacts by email address.', + 'help_text' => '', + ), + 'includeNickNameInName' => array( + 'group_name' => 'Search Preferences', + 'group' => 'Search Preferences', + 'name' => 'includeNickNameInName', + 'type' => 'Boolean', + 'quick_form_type' => 'YesNo', + 'default' => 0, + 'add' => '4.6', + 'title' => 'Include Nickname', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => 'If enabled, nicknames are automatically included when users search by Name.', + 'help_text' => '', + ), + 'includeAlphabeticalPager' => array( + 'group_name' => 'Search Preferences', + 'group' => 'Search Preferences', + 'name' => 'includeAlphabeticalPager', + 'type' => 'Boolean', + 'quick_form_type' => 'YesNo', + 'default' => 1, + 'add' => '4.6', + 'title' => 'Include Alphabetical Pager', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => 'If disabled, the alphabetical pager will not be displayed on the search screens. This will improve response time on search results on large datasets.', + 'help_text' => '', + ), + 'smartGroupCacheTimeout' => array( + 'group_name' => 'Search Preferences', + 'group' => 'Search Preferences', + 'name' => 'smartGroupCacheTimeout', + 'type' => 'Integer', + 'quick_form_type' => 'Element', + 'html_type' => 'text', + 'default' => 5, + 'add' => '4.6', + 'title' => 'Smart group cache timeout', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => 'The number of minutes to cache smart group contacts. We strongly recommend that this value be greater than zero, since a value of zero means no caching at all. If your contact data changes frequently, you should set this value to at least 5 minutes.', + 'help_text' => '', + ), + 'defaultSearchProfileID' => array( + 'group_name' => 'Search Preferences', + 'group' => 'Search Preferences', + 'name' => 'defaultSearchProfileID', + 'type' => 'Integer', + 'quick_form_type' => 'Select', + 'html_type' => 'Select', + 'html_attributes' => array( + 'class' => 'crm-select2', + ), + 'pseudoconstant' => array( + 'callback' => 'CRM_Admin_Form_Setting_Search::getAvailableProfiles', + ), + 'default' => '', + 'add' => '4.6', + 'title' => 'Default Contact Search Profile', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => 'If set, this will be the default profile used for contact search.', + 'help_text' => '', + ), 'userFrameworkResourceURL' => array( + 'bootstrap_comment' => 'This is a boot setting which may be loaded during bootstrap. Defaults are loaded via SettingsBag::getSystemDefaults().', 'group' => 'url', 'group_name' => 'URL Preferences', 'name' => 'userFrameworkResourceURL', - 'title' => 'Script and CSS Resources URL', + 'title' => 'CiviCRM Resource URL', 'type' => 'String', + 'html_type' => 'Text', + 'quick_form_type' => 'Element', 'default' => '', 'add' => '4.1', - 'prefetch' => 1, 'is_domain' => 1, 'is_contact' => 0, - 'description' => 'CiviCRM Resource URL', + 'description' => 'Absolute URL of the location where the civicrm module or component has been installed.', 'help_text' => '', - 'validate_callback' => 'CRM_Utils_Rule::url', + 'validate_callback' => 'CRM_Utils_Rule::urlish', ), 'imageUploadURL' => array( + 'bootstrap_comment' => 'This is a boot setting which may be loaded during bootstrap. Defaults are loaded via SettingsBag::getSystemDefaults().', 'group' => 'url', 'group_name' => 'URL Preferences', - 'title' => 'Image URL Prefix', + 'title' => 'Image Upload URL', 'name' => 'imageUploadURL', 'type' => 'String', + 'html_type' => 'Text', + 'quick_form_type' => 'Element', 'default' => '', 'add' => '4.1', - 'prefetch' => 1, 'is_domain' => 1, 'is_contact' => 0, - 'description' => 'Image Upload URL', + 'description' => 'URL of the location for uploaded image files.', 'help_text' => '', - 'validate_callback' => 'CRM_Utils_Rule::url', + 'validate_callback' => 'CRM_Utils_Rule::urlish', ), 'customCSSURL' => array( + 'bootstrap_comment' => 'This is a boot setting which may be loaded during bootstrap. Defaults are loaded via SettingsBag::getSystemDefaults().', 'group' => 'url', 'group_name' => 'URL Preferences', 'name' => 'customCSSURL', - 'title' => 'Custom CSS', + 'title' => 'Custom CSS URL', 'type' => 'String', + 'html_type' => 'Text', + 'quick_form_type' => 'Element', 'default' => '', 'add' => '4.1', - 'prefetch' => 1, 'is_domain' => 1, 'is_contact' => 0, - 'description' => 'Custom CiviCRM CSS URL', + 'description' => 'You can modify the look and feel of CiviCRM by adding your own stylesheet. For small to medium sized modifications, use your css file to override some of the styles in civicrm.css. Or if you need to make drastic changes, you can choose to disable civicrm.css completely.', 'help_text' => '', - 'validate_callback' => 'CRM_Utils_Rule::url', + 'validate_callback' => 'CRM_Utils_Rule::urlish', + ), + 'extensionsURL' => array( + 'bootstrap_comment' => 'This is a boot setting which may be loaded during bootstrap. Defaults are loaded via SettingsBag::getSystemDefaults().', + 'group' => 'url', + 'group_name' => 'URL Preferences', + 'title' => 'Extension Resource URL', + 'name' => 'extensionsURL', + 'type' => 'String', + 'html_type' => 'Text', + 'quick_form_type' => 'Element', + 'default' => '', + 'add' => '4.1', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => 'Base URL for extension resources (images, stylesheets, etc). This should match extensionsDir.', + 'help_text' => '', + 'validate_callback' => 'CRM_Utils_Rule::urlish', ), ), ); diff --git a/civicrm/api/v3/examples/Setting/GetSettingCurrentDomain.php b/civicrm/api/v3/examples/Setting/GetSettingCurrentDomain.php index 5ace770b00..3b46544817 100644 --- a/civicrm/api/v3/examples/Setting/GetSettingCurrentDomain.php +++ b/civicrm/api/v3/examples/Setting/GetSettingCurrentDomain.php @@ -21,7 +21,8 @@ function setting_get_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); diff --git a/civicrm/api/v3/examples/Setting/GetSpecifiedDomains.php b/civicrm/api/v3/examples/Setting/GetSpecifiedDomains.php index 683e6618b3..ef6db54e00 100644 --- a/civicrm/api/v3/examples/Setting/GetSpecifiedDomains.php +++ b/civicrm/api/v3/examples/Setting/GetSpecifiedDomains.php @@ -27,7 +27,8 @@ function setting_get_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); diff --git a/civicrm/api/v3/examples/Setting/GetValue.php b/civicrm/api/v3/examples/Setting/GetValue.php index 8ee9aa41f2..10991cc435 100644 --- a/civicrm/api/v3/examples/Setting/GetValue.php +++ b/civicrm/api/v3/examples/Setting/GetValue.php @@ -22,7 +22,8 @@ function setting_getvalue_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); diff --git a/civicrm/api/v3/examples/Setting/Revert.php b/civicrm/api/v3/examples/Setting/Revert.php index 9eb77d993e..40631b92af 100644 --- a/civicrm/api/v3/examples/Setting/Revert.php +++ b/civicrm/api/v3/examples/Setting/Revert.php @@ -21,7 +21,8 @@ function setting_revert_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); diff --git a/civicrm/api/v3/examples/StateProvince/Create.php b/civicrm/api/v3/examples/StateProvince/Create.php new file mode 100644 index 0000000000..d8e8e56d0c --- /dev/null +++ b/civicrm/api/v3/examples/StateProvince/Create.php @@ -0,0 +1,80 @@ +<?php +/** + * Test Generated example demonstrating the StateProvince.create API. + * + * @return array + * API result array + */ +function state_province_create_example() { + $params = array( + 'name' => 'Wessex', + 'abbreviation' => 'WEX', + 'country_id' => 1226, + ); + + try{ + $result = civicrm_api3('StateProvince', 'create', $params); + } + catch (CiviCRM_API3_Exception $e) { + // Handle error here. + $errorMessage = $e->getMessage(); + $errorCode = $e->getErrorCode(); + $errorData = $e->getExtraParams(); + return array( + 'is_error' => 1, + 'error_message' => $errorMessage, + 'error_code' => $errorCode, + 'error_data' => $errorData, + ); + } + + return $result; +} + +/** + * Function returns array of result expected from previous function. + * + * @return array + * API result array + */ +function state_province_create_expectedresult() { + + $expectedResult = array( + 'is_error' => 0, + 'version' => 3, + 'count' => 1, + 'id' => 13947, + 'values' => array( + '13947' => array( + 'id' => '13947', + 'name' => 'Wessex', + 'abbreviation' => 'WEX', + 'country_id' => '1226', + ), + ), + ); + + return $expectedResult; +} + +/* +* This example has been generated from the API test suite. +* The test that created it is called "testCreateStateProvince" +* and can be found at: +* https://github.com/civicrm/civicrm-core/blob/master/tests/phpunit/api/v3/StateProvinceTest.php +* +* You can see the outcome of the API tests at +* https://test.civicrm.org/job/CiviCRM-master-git/ +* +* To Learn about the API read +* http://wiki.civicrm.org/confluence/display/CRMDOC/Using+the+API +* +* Browse the api on your own site with the api explorer +* http://MYSITE.ORG/path/to/civicrm/api +* +* Read more about testing here +* http://wiki.civicrm.org/confluence/display/CRM/Testing +* +* API Standards documentation: +* http://wiki.civicrm.org/confluence/display/CRM/API+Architecture+Standards +*/ diff --git a/civicrm/api/v3/examples/StateProvince/Delete.php b/civicrm/api/v3/examples/StateProvince/Delete.php new file mode 100644 index 0000000000..6d3d142420 --- /dev/null +++ b/civicrm/api/v3/examples/StateProvince/Delete.php @@ -0,0 +1,70 @@ +<?php +/** + * Test Generated example demonstrating the StateProvince.delete API. + * + * @return array + * API result array + */ +function state_province_delete_example() { + $params = array( + 'id' => 13948, + ); + + try{ + $result = civicrm_api3('StateProvince', 'delete', $params); + } + catch (CiviCRM_API3_Exception $e) { + // Handle error here. + $errorMessage = $e->getMessage(); + $errorCode = $e->getErrorCode(); + $errorData = $e->getExtraParams(); + return array( + 'is_error' => 1, + 'error_message' => $errorMessage, + 'error_code' => $errorCode, + 'error_data' => $errorData, + ); + } + + return $result; +} + +/** + * Function returns array of result expected from previous function. + * + * @return array + * API result array + */ +function state_province_delete_expectedresult() { + + $expectedResult = array( + 'is_error' => 0, + 'version' => 3, + 'count' => 1, + 'values' => 1, + ); + + return $expectedResult; +} + +/* +* This example has been generated from the API test suite. +* The test that created it is called "testDeleteStateProvince" +* and can be found at: +* https://github.com/civicrm/civicrm-core/blob/master/tests/phpunit/api/v3/StateProvinceTest.php +* +* You can see the outcome of the API tests at +* https://test.civicrm.org/job/CiviCRM-master-git/ +* +* To Learn about the API read +* http://wiki.civicrm.org/confluence/display/CRMDOC/Using+the+API +* +* Browse the api on your own site with the api explorer +* http://MYSITE.ORG/path/to/civicrm/api +* +* Read more about testing here +* http://wiki.civicrm.org/confluence/display/CRM/Testing +* +* API Standards documentation: +* http://wiki.civicrm.org/confluence/display/CRM/API+Architecture+Standards +*/ diff --git a/civicrm/api/v3/examples/StateProvince/Get.php b/civicrm/api/v3/examples/StateProvince/Get.php new file mode 100644 index 0000000000..c4f1ace0fb --- /dev/null +++ b/civicrm/api/v3/examples/StateProvince/Get.php @@ -0,0 +1,78 @@ +<?php +/** + * Test Generated example demonstrating the StateProvince.get API. + * + * @return array + * API result array + */ +function state_province_get_example() { + $params = array( + 'name' => 'Wessex', + ); + + try{ + $result = civicrm_api3('StateProvince', 'get', $params); + } + catch (CiviCRM_API3_Exception $e) { + // Handle error here. + $errorMessage = $e->getMessage(); + $errorCode = $e->getErrorCode(); + $errorData = $e->getExtraParams(); + return array( + 'is_error' => 1, + 'error_message' => $errorMessage, + 'error_code' => $errorCode, + 'error_data' => $errorData, + ); + } + + return $result; +} + +/** + * Function returns array of result expected from previous function. + * + * @return array + * API result array + */ +function state_province_get_expectedresult() { + + $expectedResult = array( + 'is_error' => 0, + 'version' => 3, + 'count' => 1, + 'id' => 13949, + 'values' => array( + '13949' => array( + 'id' => '13949', + 'name' => 'Wessex', + 'abbreviation' => 'WEX', + 'country_id' => '1226', + ), + ), + ); + + return $expectedResult; +} + +/* +* This example has been generated from the API test suite. +* The test that created it is called "testGet" +* and can be found at: +* https://github.com/civicrm/civicrm-core/blob/master/tests/phpunit/api/v3/StateProvinceTest.php +* +* You can see the outcome of the API tests at +* https://test.civicrm.org/job/CiviCRM-master-git/ +* +* To Learn about the API read +* http://wiki.civicrm.org/confluence/display/CRMDOC/Using+the+API +* +* Browse the api on your own site with the api explorer +* http://MYSITE.ORG/path/to/civicrm/api +* +* Read more about testing here +* http://wiki.civicrm.org/confluence/display/CRM/Testing +* +* API Standards documentation: +* http://wiki.civicrm.org/confluence/display/CRM/API+Architecture+Standards +*/ diff --git a/civicrm/api/v3/examples/StatusPreference/Create.php b/civicrm/api/v3/examples/StatusPreference/Create.php new file mode 100644 index 0000000000..01ae882c12 --- /dev/null +++ b/civicrm/api/v3/examples/StatusPreference/Create.php @@ -0,0 +1,85 @@ +<?php +/** + * Test Generated example demonstrating the StatusPreference.create API. + * + * @return array + * API result array + */ +function status_preference_create_example() { + $params = array( + 'name' => 'test_check', + 'domain_id' => 1, + 'hush_until' => '20151212', + 'ignore_severity' => 'cRItical', + 'check_info' => '', + ); + + try{ + $result = civicrm_api3('StatusPreference', 'create', $params); + } + catch (CiviCRM_API3_Exception $e) { + // Handle error here. + $errorMessage = $e->getMessage(); + $errorCode = $e->getErrorCode(); + $errorData = $e->getExtraParams(); + return array( + 'is_error' => 1, + 'error_message' => $errorMessage, + 'error_code' => $errorCode, + 'error_data' => $errorData, + ); + } + + return $result; +} + +/** + * Function returns array of result expected from previous function. + * + * @return array + * API result array + */ +function status_preference_create_expectedresult() { + + $expectedResult = array( + 'is_error' => 0, + 'version' => 3, + 'count' => 1, + 'id' => 4, + 'values' => array( + '4' => array( + 'id' => '4', + 'domain_id' => '1', + 'name' => 'test_check', + 'hush_until' => '20151212000000', + 'ignore_severity' => '5', + 'prefs' => '', + 'check_info' => '', + ), + ), + ); + + return $expectedResult; +} + +/* +* This example has been generated from the API test suite. +* The test that created it is called "testCreateSeverityByName" +* and can be found at: +* https://github.com/civicrm/civicrm-core/blob/master/tests/phpunit/api/v3/StatusPreferenceTest.php +* +* You can see the outcome of the API tests at +* https://test.civicrm.org/job/CiviCRM-master-git/ +* +* To Learn about the API read +* http://wiki.civicrm.org/confluence/display/CRMDOC/Using+the+API +* +* Browse the api on your own site with the api explorer +* http://MYSITE.ORG/path/to/civicrm/api +* +* Read more about testing here +* http://wiki.civicrm.org/confluence/display/CRM/Testing +* +* API Standards documentation: +* http://wiki.civicrm.org/confluence/display/CRM/API+Architecture+Standards +*/ diff --git a/civicrm/api/v3/examples/StatusPreference/Delete.php b/civicrm/api/v3/examples/StatusPreference/Delete.php new file mode 100644 index 0000000000..8c3d75f677 --- /dev/null +++ b/civicrm/api/v3/examples/StatusPreference/Delete.php @@ -0,0 +1,70 @@ +<?php +/** + * Test Generated example demonstrating the StatusPreference.delete API. + * + * @return array + * API result array + */ +function status_preference_delete_example() { + $params = array( + 'id' => 2, + ); + + try{ + $result = civicrm_api3('StatusPreference', 'delete', $params); + } + catch (CiviCRM_API3_Exception $e) { + // Handle error here. + $errorMessage = $e->getMessage(); + $errorCode = $e->getErrorCode(); + $errorData = $e->getExtraParams(); + return array( + 'is_error' => 1, + 'error_message' => $errorMessage, + 'error_code' => $errorCode, + 'error_data' => $errorData, + ); + } + + return $result; +} + +/** + * Function returns array of result expected from previous function. + * + * @return array + * API result array + */ +function status_preference_delete_expectedresult() { + + $expectedResult = array( + 'is_error' => 0, + 'version' => 3, + 'count' => 1, + 'values' => 1, + ); + + return $expectedResult; +} + +/* +* This example has been generated from the API test suite. +* The test that created it is called "testDeleteStatusPreference" +* and can be found at: +* https://github.com/civicrm/civicrm-core/blob/master/tests/phpunit/api/v3/StatusPreferenceTest.php +* +* You can see the outcome of the API tests at +* https://test.civicrm.org/job/CiviCRM-master-git/ +* +* To Learn about the API read +* http://wiki.civicrm.org/confluence/display/CRMDOC/Using+the+API +* +* Browse the api on your own site with the api explorer +* http://MYSITE.ORG/path/to/civicrm/api +* +* Read more about testing here +* http://wiki.civicrm.org/confluence/display/CRM/Testing +* +* API Standards documentation: +* http://wiki.civicrm.org/confluence/display/CRM/API+Architecture+Standards +*/ diff --git a/civicrm/api/v3/examples/StatusPreference/Get.php b/civicrm/api/v3/examples/StatusPreference/Get.php new file mode 100644 index 0000000000..b1334a9cae --- /dev/null +++ b/civicrm/api/v3/examples/StatusPreference/Get.php @@ -0,0 +1,79 @@ +<?php +/** + * Test Generated example demonstrating the StatusPreference.get API. + * + * @return array + * API result array + */ +function status_preference_get_example() { + $params = array( + 'id' => 3, + ); + + try{ + $result = civicrm_api3('StatusPreference', 'get', $params); + } + catch (CiviCRM_API3_Exception $e) { + // Handle error here. + $errorMessage = $e->getMessage(); + $errorCode = $e->getErrorCode(); + $errorData = $e->getExtraParams(); + return array( + 'is_error' => 1, + 'error_message' => $errorMessage, + 'error_code' => $errorCode, + 'error_data' => $errorData, + ); + } + + return $result; +} + +/** + * Function returns array of result expected from previous function. + * + * @return array + * API result array + */ +function status_preference_get_expectedresult() { + + $expectedResult = array( + 'is_error' => 0, + 'version' => 3, + 'count' => 1, + 'id' => 3, + 'values' => array( + '3' => array( + 'id' => '3', + 'domain_id' => '1', + 'name' => 'test_check', + 'hush_until' => '2015-12-12', + 'ignore_severity' => '4', + ), + ), + ); + + return $expectedResult; +} + +/* +* This example has been generated from the API test suite. +* The test that created it is called "testStatusPreferenceGet" +* and can be found at: +* https://github.com/civicrm/civicrm-core/blob/master/tests/phpunit/api/v3/StatusPreferenceTest.php +* +* You can see the outcome of the API tests at +* https://test.civicrm.org/job/CiviCRM-master-git/ +* +* To Learn about the API read +* http://wiki.civicrm.org/confluence/display/CRMDOC/Using+the+API +* +* Browse the api on your own site with the api explorer +* http://MYSITE.ORG/path/to/civicrm/api +* +* Read more about testing here +* http://wiki.civicrm.org/confluence/display/CRM/Testing +* +* API Standards documentation: +* http://wiki.civicrm.org/confluence/display/CRM/API+Architecture+Standards +*/ diff --git a/civicrm/api/v3/examples/Survey/ChainedGetDelete.php b/civicrm/api/v3/examples/Survey/ChainedGetDelete.php index 2a218305a4..860366008b 100644 --- a/civicrm/api/v3/examples/Survey/ChainedGetDelete.php +++ b/civicrm/api/v3/examples/Survey/ChainedGetDelete.php @@ -22,7 +22,8 @@ function survey_get_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); @@ -60,7 +61,7 @@ function survey_get_expectedresult() { 'is_error' => 0, 'version' => 3, 'count' => 1, - 'values' => TRUE, + 'values' => 1, ), ), ), diff --git a/civicrm/api/v3/examples/Survey/Create.php b/civicrm/api/v3/examples/Survey/Create.php index 11a8482914..09a7387251 100644 --- a/civicrm/api/v3/examples/Survey/Create.php +++ b/civicrm/api/v3/examples/Survey/Create.php @@ -22,7 +22,8 @@ function survey_create_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); diff --git a/civicrm/api/v3/examples/Survey/Delete.php b/civicrm/api/v3/examples/Survey/Delete.php index b2b7f6d1a6..2a15ecb7be 100644 --- a/civicrm/api/v3/examples/Survey/Delete.php +++ b/civicrm/api/v3/examples/Survey/Delete.php @@ -19,7 +19,8 @@ function survey_delete_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); @@ -40,7 +41,7 @@ function survey_delete_expectedresult() { 'is_error' => 0, 'version' => 3, 'count' => 1, - 'values' => TRUE, + 'values' => 1, ); return $expectedResult; diff --git a/civicrm/api/v3/examples/Survey/Get.php b/civicrm/api/v3/examples/Survey/Get.php index 43038c1830..f1c14e1b44 100644 --- a/civicrm/api/v3/examples/Survey/Get.php +++ b/civicrm/api/v3/examples/Survey/Get.php @@ -22,7 +22,8 @@ function survey_get_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); diff --git a/civicrm/api/v3/examples/SurveyRespondant/Get.php b/civicrm/api/v3/examples/SurveyRespondant/Get.php index b07f6a770f..93614aacf4 100644 --- a/civicrm/api/v3/examples/SurveyRespondant/Get.php +++ b/civicrm/api/v3/examples/SurveyRespondant/Get.php @@ -23,7 +23,8 @@ function survey_respondant_get_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); diff --git a/civicrm/api/v3/examples/System/Flush.php b/civicrm/api/v3/examples/System/Flush.php index 0d124c2144..dab2f325a4 100644 --- a/civicrm/api/v3/examples/System/Flush.php +++ b/civicrm/api/v3/examples/System/Flush.php @@ -19,7 +19,8 @@ function system_flush_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); diff --git a/civicrm/api/v3/examples/Tag/Create.php b/civicrm/api/v3/examples/Tag/Create.php index 503eacabdb..3add021f74 100644 --- a/civicrm/api/v3/examples/Tag/Create.php +++ b/civicrm/api/v3/examples/Tag/Create.php @@ -20,7 +20,8 @@ function tag_create_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); @@ -53,6 +54,7 @@ function tag_create_expectedresult() { 'is_tagset' => '', 'used_for' => 'civicrm_contact', 'created_id' => '', + 'color' => '', 'created_date' => '2013-07-28 08:49:19', ), ), diff --git a/civicrm/api/v3/examples/Tag/Delete.php b/civicrm/api/v3/examples/Tag/Delete.php index b1112ad56b..75f072716a 100644 --- a/civicrm/api/v3/examples/Tag/Delete.php +++ b/civicrm/api/v3/examples/Tag/Delete.php @@ -19,7 +19,8 @@ function tag_delete_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); @@ -40,7 +41,7 @@ function tag_delete_expectedresult() { 'is_error' => 0, 'version' => 3, 'count' => 1, - 'values' => TRUE, + 'values' => 1, ); return $expectedResult; diff --git a/civicrm/api/v3/examples/Tag/Get.php b/civicrm/api/v3/examples/Tag/Get.php index 8860a11c72..a39d5c6a8e 100644 --- a/civicrm/api/v3/examples/Tag/Get.php +++ b/civicrm/api/v3/examples/Tag/Get.php @@ -20,7 +20,8 @@ function tag_get_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); diff --git a/civicrm/api/v3/examples/Tag/GetFields.php b/civicrm/api/v3/examples/Tag/GetFields.php index eb38f18192..c00491e909 100644 --- a/civicrm/api/v3/examples/Tag/GetFields.php +++ b/civicrm/api/v3/examples/Tag/GetFields.php @@ -21,7 +21,8 @@ function tag_getfields_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); @@ -41,13 +42,17 @@ function tag_getfields_expectedresult() { $expectedResult = array( 'is_error' => 0, 'version' => 3, - 'count' => 10, + 'count' => 11, 'values' => array( 'id' => array( 'name' => 'id', 'type' => 1, 'title' => 'Tag ID', + 'description' => 'Tag ID', 'required' => TRUE, + 'table_name' => 'civicrm_tag', + 'entity' => 'Tag', + 'bao' => 'CRM_Core_BAO_Tag', 'api.aliases' => array( '0' => 'tag', ), @@ -56,23 +61,35 @@ function tag_getfields_expectedresult() { 'name' => 'name', 'type' => 2, 'title' => 'Tag Name', + 'description' => 'Name of Tag.', 'required' => TRUE, 'maxlength' => 64, 'size' => 30, + 'table_name' => 'civicrm_tag', + 'entity' => 'Tag', + 'bao' => 'CRM_Core_BAO_Tag', 'api.required' => 1, ), 'description' => array( 'name' => 'description', 'type' => 2, 'title' => 'Description', + 'description' => 'Optional verbose description of the tag.', 'maxlength' => 255, 'size' => 45, + 'table_name' => 'civicrm_tag', + 'entity' => 'Tag', + 'bao' => 'CRM_Core_BAO_Tag', ), 'parent_id' => array( 'name' => 'parent_id', 'type' => 1, 'title' => 'Parent Tag', + 'description' => 'Optional parent id for this tag.', 'default' => 'NULL', + 'table_name' => 'civicrm_tag', + 'entity' => 'Tag', + 'bao' => 'CRM_Core_BAO_Tag', 'FKClassName' => 'CRM_Core_DAO_Tag', 'FKApiName' => 'Tag', ), @@ -80,17 +97,27 @@ function tag_getfields_expectedresult() { 'name' => 'is_selectable', 'type' => 16, 'title' => 'Display Tag?', + 'description' => 'Is this tag selectable / displayed', 'default' => '1', + 'table_name' => 'civicrm_tag', + 'entity' => 'Tag', + 'bao' => 'CRM_Core_BAO_Tag', ), 'is_reserved' => array( 'name' => 'is_reserved', 'type' => 16, 'title' => 'Reserved', + 'table_name' => 'civicrm_tag', + 'entity' => 'Tag', + 'bao' => 'CRM_Core_BAO_Tag', ), 'is_tagset' => array( 'name' => 'is_tagset', 'type' => 16, 'title' => 'Tagset', + 'table_name' => 'civicrm_tag', + 'entity' => 'Tag', + 'bao' => 'CRM_Core_BAO_Tag', ), 'used_for' => array( 'name' => 'used_for', @@ -99,11 +126,17 @@ function tag_getfields_expectedresult() { 'maxlength' => 64, 'size' => 30, 'default' => 'NULL', + 'table_name' => 'civicrm_tag', + 'entity' => 'Tag', + 'bao' => 'CRM_Core_BAO_Tag', 'html' => array( 'type' => 'Select', + 'maxlength' => 64, + 'size' => 30, ), 'pseudoconstant' => array( 'optionGroupName' => 'tag_used_for', + 'optionEditPath' => 'civicrm/admin/options/tag_used_for', ), 'api.default' => 'civicrm_contact', ), @@ -111,13 +144,33 @@ function tag_getfields_expectedresult() { 'name' => 'created_id', 'type' => 1, 'title' => 'Tag Created By', + 'description' => 'FK to civicrm_contact, who created this tag', + 'table_name' => 'civicrm_tag', + 'entity' => 'Tag', + 'bao' => 'CRM_Core_BAO_Tag', 'FKClassName' => 'CRM_Contact_DAO_Contact', 'FKApiName' => 'Contact', ), + 'color' => array( + 'name' => 'color', + 'type' => 2, + 'title' => 'Color', + 'description' => 'Hex color value e.g. #ffffff', + 'maxlength' => 255, + 'size' => 45, + 'default' => 'NULL', + 'table_name' => 'civicrm_tag', + 'entity' => 'Tag', + 'bao' => 'CRM_Core_BAO_Tag', + ), 'created_date' => array( 'name' => 'created_date', 'type' => 12, 'title' => 'Tag Created Date', + 'description' => 'Date and time that tag was created.', + 'table_name' => 'civicrm_tag', + 'entity' => 'Tag', + 'bao' => 'CRM_Core_BAO_Tag', ), ), ); diff --git a/civicrm/api/v3/examples/Tag/GetList.php b/civicrm/api/v3/examples/Tag/GetList.php index 9dd6c6ebc8..08db458290 100644 --- a/civicrm/api/v3/examples/Tag/GetList.php +++ b/civicrm/api/v3/examples/Tag/GetList.php @@ -24,7 +24,8 @@ function tag_getlist_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); diff --git a/civicrm/api/v3/examples/Tag/GetReturnArray.php b/civicrm/api/v3/examples/Tag/GetReturnArray.php index e3cb5b396b..ae5465dce7 100644 --- a/civicrm/api/v3/examples/Tag/GetReturnArray.php +++ b/civicrm/api/v3/examples/Tag/GetReturnArray.php @@ -25,7 +25,8 @@ function tag_get_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); diff --git a/civicrm/api/v3/examples/UFField/Create.php b/civicrm/api/v3/examples/UFField/Create.php index ec39ee0013..6710ce7375 100644 --- a/civicrm/api/v3/examples/UFField/Create.php +++ b/civicrm/api/v3/examples/UFField/Create.php @@ -28,7 +28,8 @@ function uf_field_create_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); diff --git a/civicrm/api/v3/examples/UFField/Delete.php b/civicrm/api/v3/examples/UFField/Delete.php index a766ac7584..996cb148ee 100644 --- a/civicrm/api/v3/examples/UFField/Delete.php +++ b/civicrm/api/v3/examples/UFField/Delete.php @@ -19,7 +19,8 @@ function uf_field_delete_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); diff --git a/civicrm/api/v3/examples/UFField/Get.php b/civicrm/api/v3/examples/UFField/Get.php index 9c52c59d20..c6c1a6b2df 100644 --- a/civicrm/api/v3/examples/UFField/Get.php +++ b/civicrm/api/v3/examples/UFField/Get.php @@ -17,7 +17,8 @@ function uf_field_get_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); diff --git a/civicrm/api/v3/examples/UFField/Replace.php b/civicrm/api/v3/examples/UFField/Replace.php index f94ad49347..992d678986 100644 --- a/civicrm/api/v3/examples/UFField/Replace.php +++ b/civicrm/api/v3/examples/UFField/Replace.php @@ -53,7 +53,8 @@ function uf_field_replace_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); diff --git a/civicrm/api/v3/examples/UFGroup/Create.php b/civicrm/api/v3/examples/UFGroup/Create.php index fdf7ada935..ade13f1fbe 100644 --- a/civicrm/api/v3/examples/UFGroup/Create.php +++ b/civicrm/api/v3/examples/UFGroup/Create.php @@ -38,7 +38,8 @@ function uf_group_create_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); @@ -81,7 +82,7 @@ function uf_group_create_expectedresult() { 'is_cms_user' => '1', 'notify' => 'admin@example.org', 'is_reserved' => '1', - 'name' => 'Test_Group_2', + 'name' => 'Test_Group', 'created_id' => '1', 'created_date' => '2013-07-28 08:49:19', 'is_proximity_search' => '', diff --git a/civicrm/api/v3/examples/UFGroup/Delete.php b/civicrm/api/v3/examples/UFGroup/Delete.php index c2be5ea330..68855a931e 100644 --- a/civicrm/api/v3/examples/UFGroup/Delete.php +++ b/civicrm/api/v3/examples/UFGroup/Delete.php @@ -19,7 +19,8 @@ function uf_group_delete_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); @@ -40,7 +41,7 @@ function uf_group_delete_expectedresult() { 'is_error' => 0, 'version' => 3, 'count' => 1, - 'values' => TRUE, + 'values' => 1, ); return $expectedResult; diff --git a/civicrm/api/v3/examples/UFGroup/Get.php b/civicrm/api/v3/examples/UFGroup/Get.php index b35be5d2ba..1ce438b38b 100644 --- a/civicrm/api/v3/examples/UFGroup/Get.php +++ b/civicrm/api/v3/examples/UFGroup/Get.php @@ -19,7 +19,8 @@ function uf_group_get_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); @@ -61,7 +62,7 @@ function uf_group_get_expectedresult() { 'is_cms_user' => '1', 'notify' => 'admin@example.org', 'is_reserved' => '1', - 'name' => 'Test_Group_2', + 'name' => 'Test_Group', 'created_id' => '1', 'created_date' => '2013-07-28 08:49:19', 'is_proximity_search' => 0, diff --git a/civicrm/api/v3/examples/UFJoin/Create.php b/civicrm/api/v3/examples/UFJoin/Create.php index fa380d97d2..45eb69fec1 100644 --- a/civicrm/api/v3/examples/UFJoin/Create.php +++ b/civicrm/api/v3/examples/UFJoin/Create.php @@ -7,8 +7,8 @@ */ function uf_join_create_example() { $params = array( - 'module' => 'CiviContribute', - 'entity_table' => 'civicrm_contribution_page', + 'module' => 'CiviCampaign', + 'entity_table' => 'civicrm_survey', 'entity_id' => 1, 'weight' => 1, 'uf_group_id' => 11, @@ -25,7 +25,8 @@ function uf_join_create_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); @@ -51,8 +52,8 @@ function uf_join_create_expectedresult() { '0' => array( 'id' => '1', 'is_active' => '1', - 'module' => 'CiviContribute', - 'entity_table' => 'civicrm_contribution_page', + 'module' => 'CiviCampaign', + 'entity_table' => 'civicrm_survey', 'entity_id' => '1', 'weight' => '1', 'uf_group_id' => '11', @@ -66,7 +67,7 @@ function uf_join_create_expectedresult() { /* * This example has been generated from the API test suite. -* The test that created it is called "testCreateUFJoin" +* The test that created it is called "testCreateSurveyUFJoin" * and can be found at: * https://github.com/civicrm/civicrm-core/blob/master/tests/phpunit/api/v3/UFJoinTest.php * diff --git a/civicrm/api/v3/examples/UFJoin/Get.php b/civicrm/api/v3/examples/UFJoin/Get.php index 1328f59812..6f38609a02 100644 --- a/civicrm/api/v3/examples/UFJoin/Get.php +++ b/civicrm/api/v3/examples/UFJoin/Get.php @@ -21,7 +21,8 @@ function uf_join_get_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); diff --git a/civicrm/api/v3/examples/UFMatch/Get.php b/civicrm/api/v3/examples/UFMatch/Get.php index de24f6be46..dddd476237 100644 --- a/civicrm/api/v3/examples/UFMatch/Get.php +++ b/civicrm/api/v3/examples/UFMatch/Get.php @@ -19,7 +19,8 @@ function uf_match_get_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); diff --git a/civicrm/api/v3/examples/Website/Create.php b/civicrm/api/v3/examples/Website/Create.php index 89a347ffbd..1e1d4e10fa 100644 --- a/civicrm/api/v3/examples/Website/Create.php +++ b/civicrm/api/v3/examples/Website/Create.php @@ -21,7 +21,8 @@ function website_create_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); diff --git a/civicrm/api/v3/examples/Website/Delete.php b/civicrm/api/v3/examples/Website/Delete.php index fea28bf164..e40f33ac4b 100644 --- a/civicrm/api/v3/examples/Website/Delete.php +++ b/civicrm/api/v3/examples/Website/Delete.php @@ -19,7 +19,8 @@ function website_delete_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); diff --git a/civicrm/api/v3/examples/Website/Get.php b/civicrm/api/v3/examples/Website/Get.php index 4b26815ce9..7547491227 100644 --- a/civicrm/api/v3/examples/Website/Get.php +++ b/civicrm/api/v3/examples/Website/Get.php @@ -21,7 +21,8 @@ function website_get_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); diff --git a/civicrm/api/v3/examples/Website/GetFields.php b/civicrm/api/v3/examples/Website/GetFields.php index 915c3c238a..1f163d8dc5 100644 --- a/civicrm/api/v3/examples/Website/GetFields.php +++ b/civicrm/api/v3/examples/Website/GetFields.php @@ -19,7 +19,8 @@ function website_getfields_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); @@ -45,7 +46,11 @@ function website_getfields_expectedresult() { 'name' => 'id', 'type' => 1, 'title' => 'Website ID', + 'description' => 'Unique Website ID', 'required' => TRUE, + 'table_name' => 'civicrm_website', + 'entity' => 'Website', + 'bao' => 'CRM_Core_BAO_Website', 'api.aliases' => array( '0' => 'website_id', ), @@ -54,6 +59,10 @@ function website_getfields_expectedresult() { 'name' => 'contact_id', 'type' => 1, 'title' => 'Contact', + 'description' => 'FK to Contact ID', + 'table_name' => 'civicrm_website', + 'entity' => 'Website', + 'bao' => 'CRM_Core_BAO_Website', 'FKClassName' => 'CRM_Contact_DAO_Contact', 'FKApiName' => 'Contact', ), @@ -61,6 +70,7 @@ function website_getfields_expectedresult() { 'name' => 'url', 'type' => 2, 'title' => 'Website', + 'description' => 'Website', 'maxlength' => 128, 'size' => 30, 'import' => TRUE, @@ -68,19 +78,31 @@ function website_getfields_expectedresult() { 'headerPattern' => '/Website/i', 'dataPattern' => '/^[A-Za-z][0-9A-Za-z]{20,}$/', 'export' => TRUE, + 'table_name' => 'civicrm_website', + 'entity' => 'Website', + 'bao' => 'CRM_Core_BAO_Website', 'html' => array( 'type' => 'Text', + 'maxlength' => 128, + 'size' => 30, ), ), 'website_type_id' => array( 'name' => 'website_type_id', 'type' => 1, 'title' => 'Website Type', + 'description' => 'Which Website type does this website belong to.', + 'table_name' => 'civicrm_website', + 'entity' => 'Website', + 'bao' => 'CRM_Core_BAO_Website', 'html' => array( 'type' => 'Select', + 'size' => 6, + 'maxlength' => 14, ), 'pseudoconstant' => array( 'optionGroupName' => 'website_type', + 'optionEditPath' => 'civicrm/admin/options/website_type', ), ), ), diff --git a/civicrm/api/v3/examples/Website/GetWithMetadata.php b/civicrm/api/v3/examples/Website/GetWithMetadata.php index db2e42874c..24c4467ddd 100644 --- a/civicrm/api/v3/examples/Website/GetWithMetadata.php +++ b/civicrm/api/v3/examples/Website/GetWithMetadata.php @@ -25,7 +25,8 @@ function website_get_example() { $errorCode = $e->getErrorCode(); $errorData = $e->getExtraParams(); return array( - 'error' => $errorMessage, + 'is_error' => 1, + 'error_message' => $errorMessage, 'error_code' => $errorCode, 'error_data' => $errorData, ); @@ -53,7 +54,11 @@ function website_get_expectedresult() { 'name' => 'id', 'type' => '1', 'title' => 'Website ID', + 'description' => 'Unique Website ID', 'required' => '1', + 'table_name' => 'civicrm_website', + 'entity' => 'Website', + 'bao' => 'CRM_Core_BAO_Website', 'api.aliases' => array( '0' => 'website_id', ), @@ -62,6 +67,10 @@ function website_get_expectedresult() { 'name' => 'contact_id', 'type' => '1', 'title' => 'Contact', + 'description' => 'FK to Contact ID', + 'table_name' => 'civicrm_website', + 'entity' => 'Website', + 'bao' => 'CRM_Core_BAO_Website', 'FKClassName' => 'CRM_Contact_DAO_Contact', 'FKApiName' => 'Contact', ), @@ -69,6 +78,7 @@ function website_get_expectedresult() { 'name' => 'url', 'type' => '2', 'title' => 'Website', + 'description' => 'Website', 'maxlength' => '128', 'size' => '30', 'import' => '1', @@ -76,19 +86,31 @@ function website_get_expectedresult() { 'headerPattern' => '/Website/i', 'dataPattern' => '/^[A-Za-z][0-9A-Za-z]{20,}$/', 'export' => '1', + 'table_name' => 'civicrm_website', + 'entity' => 'Website', + 'bao' => 'CRM_Core_BAO_Website', 'html' => array( 'type' => 'Text', + 'maxlength' => '128', + 'size' => '30', ), ), 'website_type_id' => array( 'name' => 'website_type_id', 'type' => '1', 'title' => 'Website Type', + 'description' => 'Which Website type does this website belong to.', + 'table_name' => 'civicrm_website', + 'entity' => 'Website', + 'bao' => 'CRM_Core_BAO_Website', 'html' => array( 'type' => 'Select', + 'size' => '6', + 'maxlength' => '14', ), 'pseudoconstant' => array( 'optionGroupName' => 'website_type', + 'optionEditPath' => 'civicrm/admin/options/website_type', ), ), ), diff --git a/civicrm/api/v3/utils.php b/civicrm/api/v3/utils.php index 741ab966cd..1e5400b419 100644 --- a/civicrm/api/v3/utils.php +++ b/civicrm/api/v3/utils.php @@ -1887,8 +1887,10 @@ function _civicrm_api_get_fields($entity, $unique = FALSE, &$params = array()) { $d = new $dao(); $fields = $d->fields(); - // Set html attributes for text fields foreach ($fields as $name => &$field) { + // Denote as core field + $field['is_core_field'] = TRUE; + // Set html attributes for text fields if (isset($field['html'])) { $field['html'] += (array) $d::makeAttribute($field); } @@ -2062,7 +2064,7 @@ function _civicrm_api3_swap_out_aliases(&$apiRequest, $fields) { * * @throws API_Exception */ -function _civicrm_api3_validate_integer(&$params, &$fieldName, &$fieldInfo, $entity) { +function _civicrm_api3_validate_integer(&$params, $fieldName, &$fieldInfo, $entity) { list($fieldValue, $op) = _civicrm_api3_field_value_check($params, $fieldName); if (strpos($op, 'NULL') !== FALSE || strpos($op, 'EMPTY') !== FALSE) { return; diff --git a/civicrm/bower.json b/civicrm/bower.json index 7db9f6bb6e..d5cda3c0d0 100644 --- a/civicrm/bower.json +++ b/civicrm/bower.json @@ -22,6 +22,7 @@ "select2": "colemanw/select2#stable/3.5", "jquery-validation": "~1.13", "datatables": "~1.10", + "jstree": "~3", "ckeditor": "~4.5", "font-awesome": "~4", "angular-sanitize": "~1.3.15" diff --git a/civicrm/bower_components/jstree/.bower.json b/civicrm/bower_components/jstree/.bower.json new file mode 100644 index 0000000000..fa43841037 --- /dev/null +++ b/civicrm/bower_components/jstree/.bower.json @@ -0,0 +1,42 @@ +{ + "name": "jstree", + "version": "3.3.3", + "main": [ + "./dist/jstree.js", + "./dist/themes/default/style.css" + ], + "ignore": [ + "**/.*", + "docs", + "demo", + "libs", + "node_modules", + "test", + "libs", + "jstree.jquery.json", + "gruntfile.js", + "package.json", + "bower.json", + "component.json", + "LICENCE-MIT", + "README.md" + ], + "dependencies": { + "jquery": ">=1.9.1" + }, + "keywords": [ + "ui", + "tree", + "jstree" + ], + "homepage": "https://github.com/vakata/jstree", + "_release": "3.3.3", + "_resolution": { + "type": "version", + "tag": "3.3.3", + "commit": "9770c6711f0a155ec494f635aaf0add9b3cfb45c" + }, + "_source": "https://github.com/vakata/jstree.git", + "_target": "~3", + "_originalSource": "jstree" +} \ No newline at end of file diff --git a/civicrm/bower_components/jstree/LICENSE-MIT b/civicrm/bower_components/jstree/LICENSE-MIT new file mode 100644 index 0000000000..9c90a3d398 --- /dev/null +++ b/civicrm/bower_components/jstree/LICENSE-MIT @@ -0,0 +1,22 @@ +Copyright (c) 2014 Ivan Bozhanov + +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/civicrm/bower_components/jstree/bower.json b/civicrm/bower_components/jstree/bower.json new file mode 100644 index 0000000000..535b66c151 --- /dev/null +++ b/civicrm/bower_components/jstree/bower.json @@ -0,0 +1,32 @@ +{ + "name": "jstree", + "version": "3.3.3", + "main" : [ + "./dist/jstree.js", + "./dist/themes/default/style.css" + ], + "ignore": [ + "**/.*", + "docs", + "demo", + "libs", + "node_modules", + "test", + "libs", + "jstree.jquery.json", + "gruntfile.js", + "package.json", + "bower.json", + "component.json", + "LICENCE-MIT", + "README.md" + ], + "dependencies": { + "jquery": ">=1.9.1" + }, + "keywords": [ + "ui", + "tree", + "jstree" + ] +} diff --git a/civicrm/bower_components/jstree/composer.json b/civicrm/bower_components/jstree/composer.json new file mode 100644 index 0000000000..282b768a68 --- /dev/null +++ b/civicrm/bower_components/jstree/composer.json @@ -0,0 +1,46 @@ +{ + "name": "vakata/jstree", + "description": "jsTree is jquery plugin, that provides interactive trees.", + "type": "component", + "homepage": "http://jstree.com", + "license": "MIT", + "support": { + "issues": "https://github.com/vakata/jstree/issues", + "forum": "https://groups.google.com/forum/#!forum/jstree", + "source": "https://github.com/vakata/jstree" + }, + "authors": [ + { + "name": "Ivan Bozhanov", + "email": "jstree@jstree.com" + } + ], + "require": { + "components/jquery": ">=1.9.1" + }, + "suggest": { + "robloach/component-installer": "Allows installation of Components via Composer" + }, + "extra": { + "component": { + "scripts": [ + "dist/jstree.js" + ], + "styles": [ + "dist/themes/default/style.css" + ], + "images": [ + "dist/themes/default/32px.png", + "dist/themes/default/40px.png", + "dist/themes/default/throbber.gif" + ], + "files": [ + "dist/jstree.min.js", + "dist/themes/default/style.min.css", + "dist/themes/default/32px.png", + "dist/themes/default/40px.png", + "dist/themes/default/throbber.gif" + ] + } + } +} \ No newline at end of file diff --git a/civicrm/bower_components/jstree/dist/jstree.js b/civicrm/bower_components/jstree/dist/jstree.js new file mode 100644 index 0000000000..b6509d4671 --- /dev/null +++ b/civicrm/bower_components/jstree/dist/jstree.js @@ -0,0 +1,8305 @@ +/*globals jQuery, define, module, exports, require, window, document, postMessage */ +(function (factory) { + "use strict"; + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } + else if(typeof module !== 'undefined' && module.exports) { + module.exports = factory(require('jquery')); + } + else { + factory(jQuery); + } +}(function ($, undefined) { + "use strict"; +/*! + * jsTree 3.3.3 + * http://jstree.com/ + * + * Copyright (c) 2014 Ivan Bozhanov (http://vakata.com) + * + * Licensed same as jquery - under the terms of the MIT License + * http://www.opensource.org/licenses/mit-license.php + */ +/*! + * if using jslint please allow for the jQuery global and use following options: + * jslint: loopfunc: true, browser: true, ass: true, bitwise: true, continue: true, nomen: true, plusplus: true, regexp: true, unparam: true, todo: true, white: true + */ +/*jshint -W083 */ + + // prevent another load? maybe there is a better way? + if($.jstree) { + return; + } + + /** + * ### jsTree core functionality + */ + + // internal variables + var instance_counter = 0, + ccp_node = false, + ccp_mode = false, + ccp_inst = false, + themes_loaded = [], + src = $('script:last').attr('src'), + document = window.document; // local variable is always faster to access then a global + + /** + * holds all jstree related functions and variables, including the actual class and methods to create, access and manipulate instances. + * @name $.jstree + */ + $.jstree = { + /** + * specifies the jstree version in use + * @name $.jstree.version + */ + version : '3.3.3', + /** + * holds all the default options used when creating new instances + * @name $.jstree.defaults + */ + defaults : { + /** + * configure which plugins will be active on an instance. Should be an array of strings, where each element is a plugin name. The default is `[]` + * @name $.jstree.defaults.plugins + */ + plugins : [] + }, + /** + * stores all loaded jstree plugins (used internally) + * @name $.jstree.plugins + */ + plugins : {}, + path : src && src.indexOf('/') !== -1 ? src.replace(/\/[^\/]+$/,'') : '', + idregex : /[\\:&!^|()\[\]<>@*'+~#";.,=\- \/${}%?`]/g, + root : '#' + }; + + /** + * creates a jstree instance + * @name $.jstree.create(el [, options]) + * @param {DOMElement|jQuery|String} el the element to create the instance on, can be jQuery extended or a selector + * @param {Object} options options for this instance (extends `$.jstree.defaults`) + * @return {jsTree} the new instance + */ + $.jstree.create = function (el, options) { + var tmp = new $.jstree.core(++instance_counter), + opt = options; + options = $.extend(true, {}, $.jstree.defaults, options); + if(opt && opt.plugins) { + options.plugins = opt.plugins; + } + $.each(options.plugins, function (i, k) { + if(i !== 'core') { + tmp = tmp.plugin(k, options[k]); + } + }); + $(el).data('jstree', tmp); + tmp.init(el, options); + return tmp; + }; + /** + * remove all traces of jstree from the DOM and destroy all instances + * @name $.jstree.destroy() + */ + $.jstree.destroy = function () { + $('.jstree:jstree').jstree('destroy'); + $(document).off('.jstree'); + }; + /** + * the jstree class constructor, used only internally + * @private + * @name $.jstree.core(id) + * @param {Number} id this instance's index + */ + $.jstree.core = function (id) { + this._id = id; + this._cnt = 0; + this._wrk = null; + this._data = { + core : { + themes : { + name : false, + dots : false, + icons : false, + ellipsis : false + }, + selected : [], + last_error : {}, + working : false, + worker_queue : [], + focused : null + } + }; + }; + /** + * get a reference to an existing instance + * + * __Examples__ + * + * // provided a container with an ID of "tree", and a nested node with an ID of "branch" + * // all of there will return the same instance + * $.jstree.reference('tree'); + * $.jstree.reference('#tree'); + * $.jstree.reference($('#tree')); + * $.jstree.reference(document.getElementByID('tree')); + * $.jstree.reference('branch'); + * $.jstree.reference('#branch'); + * $.jstree.reference($('#branch')); + * $.jstree.reference(document.getElementByID('branch')); + * + * @name $.jstree.reference(needle) + * @param {DOMElement|jQuery|String} needle + * @return {jsTree|null} the instance or `null` if not found + */ + $.jstree.reference = function (needle) { + var tmp = null, + obj = null; + if(needle && needle.id && (!needle.tagName || !needle.nodeType)) { needle = needle.id; } + + if(!obj || !obj.length) { + try { obj = $(needle); } catch (ignore) { } + } + if(!obj || !obj.length) { + try { obj = $('#' + needle.replace($.jstree.idregex,'\\$&')); } catch (ignore) { } + } + if(obj && obj.length && (obj = obj.closest('.jstree')).length && (obj = obj.data('jstree'))) { + tmp = obj; + } + else { + $('.jstree').each(function () { + var inst = $(this).data('jstree'); + if(inst && inst._model.data[needle]) { + tmp = inst; + return false; + } + }); + } + return tmp; + }; + /** + * Create an instance, get an instance or invoke a command on a instance. + * + * If there is no instance associated with the current node a new one is created and `arg` is used to extend `$.jstree.defaults` for this new instance. There would be no return value (chaining is not broken). + * + * If there is an existing instance and `arg` is a string the command specified by `arg` is executed on the instance, with any additional arguments passed to the function. If the function returns a value it will be returned (chaining could break depending on function). + * + * If there is an existing instance and `arg` is not a string the instance itself is returned (similar to `$.jstree.reference`). + * + * In any other case - nothing is returned and chaining is not broken. + * + * __Examples__ + * + * $('#tree1').jstree(); // creates an instance + * $('#tree2').jstree({ plugins : [] }); // create an instance with some options + * $('#tree1').jstree('open_node', '#branch_1'); // call a method on an existing instance, passing additional arguments + * $('#tree2').jstree(); // get an existing instance (or create an instance) + * $('#tree2').jstree(true); // get an existing instance (will not create new instance) + * $('#branch_1').jstree().select_node('#branch_1'); // get an instance (using a nested element and call a method) + * + * @name $().jstree([arg]) + * @param {String|Object} arg + * @return {Mixed} + */ + $.fn.jstree = function (arg) { + // check for string argument + var is_method = (typeof arg === 'string'), + args = Array.prototype.slice.call(arguments, 1), + result = null; + if(arg === true && !this.length) { return false; } + this.each(function () { + // get the instance (if there is one) and method (if it exists) + var instance = $.jstree.reference(this), + method = is_method && instance ? instance[arg] : null; + // if calling a method, and method is available - execute on the instance + result = is_method && method ? + method.apply(instance, args) : + null; + // if there is no instance and no method is being called - create one + if(!instance && !is_method && (arg === undefined || $.isPlainObject(arg))) { + $.jstree.create(this, arg); + } + // if there is an instance and no method is called - return the instance + if( (instance && !is_method) || arg === true ) { + result = instance || false; + } + // if there was a method call which returned a result - break and return the value + if(result !== null && result !== undefined) { + return false; + } + }); + // if there was a method call with a valid return value - return that, otherwise continue the chain + return result !== null && result !== undefined ? + result : this; + }; + /** + * used to find elements containing an instance + * + * __Examples__ + * + * $('div:jstree').each(function () { + * $(this).jstree('destroy'); + * }); + * + * @name $(':jstree') + * @return {jQuery} + */ + $.expr.pseudos.jstree = $.expr.createPseudo(function(search) { + return function(a) { + return $(a).hasClass('jstree') && + $(a).data('jstree') !== undefined; + }; + }); + + /** + * stores all defaults for the core + * @name $.jstree.defaults.core + */ + $.jstree.defaults.core = { + /** + * data configuration + * + * If left as `false` the HTML inside the jstree container element is used to populate the tree (that should be an unordered list with list items). + * + * You can also pass in a HTML string or a JSON array here. + * + * It is possible to pass in a standard jQuery-like AJAX config and jstree will automatically determine if the response is JSON or HTML and use that to populate the tree. + * In addition to the standard jQuery ajax options here you can suppy functions for `data` and `url`, the functions will be run in the current instance's scope and a param will be passed indicating which node is being loaded, the return value of those functions will be used. + * + * The last option is to specify a function, that function will receive the node being loaded as argument and a second param which is a function which should be called with the result. + * + * __Examples__ + * + * // AJAX + * $('#tree').jstree({ + * 'core' : { + * 'data' : { + * 'url' : '/get/children/', + * 'data' : function (node) { + * return { 'id' : node.id }; + * } + * } + * }); + * + * // direct data + * $('#tree').jstree({ + * 'core' : { + * 'data' : [ + * 'Simple root node', + * { + * 'id' : 'node_2', + * 'text' : 'Root node with options', + * 'state' : { 'opened' : true, 'selected' : true }, + * 'children' : [ { 'text' : 'Child 1' }, 'Child 2'] + * } + * ] + * } + * }); + * + * // function + * $('#tree').jstree({ + * 'core' : { + * 'data' : function (obj, callback) { + * callback.call(this, ['Root 1', 'Root 2']); + * } + * }); + * + * @name $.jstree.defaults.core.data + */ + data : false, + /** + * configure the various strings used throughout the tree + * + * You can use an object where the key is the string you need to replace and the value is your replacement. + * Another option is to specify a function which will be called with an argument of the needed string and should return the replacement. + * If left as `false` no replacement is made. + * + * __Examples__ + * + * $('#tree').jstree({ + * 'core' : { + * 'strings' : { + * 'Loading ...' : 'Please wait ...' + * } + * } + * }); + * + * @name $.jstree.defaults.core.strings + */ + strings : false, + /** + * determines what happens when a user tries to modify the structure of the tree + * If left as `false` all operations like create, rename, delete, move or copy are prevented. + * You can set this to `true` to allow all interactions or use a function to have better control. + * + * __Examples__ + * + * $('#tree').jstree({ + * 'core' : { + * 'check_callback' : function (operation, node, node_parent, node_position, more) { + * // operation can be 'create_node', 'rename_node', 'delete_node', 'move_node' or 'copy_node' + * // in case of 'rename_node' node_position is filled with the new node name + * return operation === 'rename_node' ? true : false; + * } + * } + * }); + * + * @name $.jstree.defaults.core.check_callback + */ + check_callback : false, + /** + * a callback called with a single object parameter in the instance's scope when something goes wrong (operation prevented, ajax failed, etc) + * @name $.jstree.defaults.core.error + */ + error : $.noop, + /** + * the open / close animation duration in milliseconds - set this to `false` to disable the animation (default is `200`) + * @name $.jstree.defaults.core.animation + */ + animation : 200, + /** + * a boolean indicating if multiple nodes can be selected + * @name $.jstree.defaults.core.multiple + */ + multiple : true, + /** + * theme configuration object + * @name $.jstree.defaults.core.themes + */ + themes : { + /** + * the name of the theme to use (if left as `false` the default theme is used) + * @name $.jstree.defaults.core.themes.name + */ + name : false, + /** + * the URL of the theme's CSS file, leave this as `false` if you have manually included the theme CSS (recommended). You can set this to `true` too which will try to autoload the theme. + * @name $.jstree.defaults.core.themes.url + */ + url : false, + /** + * the location of all jstree themes - only used if `url` is set to `true` + * @name $.jstree.defaults.core.themes.dir + */ + dir : false, + /** + * a boolean indicating if connecting dots are shown + * @name $.jstree.defaults.core.themes.dots + */ + dots : true, + /** + * a boolean indicating if node icons are shown + * @name $.jstree.defaults.core.themes.icons + */ + icons : true, + /** + * a boolean indicating if node ellipsis should be shown - this only works with a fixed with on the container + * @name $.jstree.defaults.core.themes.ellipsis + */ + ellipsis : false, + /** + * a boolean indicating if the tree background is striped + * @name $.jstree.defaults.core.themes.stripes + */ + stripes : false, + /** + * a string (or boolean `false`) specifying the theme variant to use (if the theme supports variants) + * @name $.jstree.defaults.core.themes.variant + */ + variant : false, + /** + * a boolean specifying if a reponsive version of the theme should kick in on smaller screens (if the theme supports it). Defaults to `false`. + * @name $.jstree.defaults.core.themes.responsive + */ + responsive : false + }, + /** + * if left as `true` all parents of all selected nodes will be opened once the tree loads (so that all selected nodes are visible to the user) + * @name $.jstree.defaults.core.expand_selected_onload + */ + expand_selected_onload : true, + /** + * if left as `true` web workers will be used to parse incoming JSON data where possible, so that the UI will not be blocked by large requests. Workers are however about 30% slower. Defaults to `true` + * @name $.jstree.defaults.core.worker + */ + worker : true, + /** + * Force node text to plain text (and escape HTML). Defaults to `false` + * @name $.jstree.defaults.core.force_text + */ + force_text : false, + /** + * Should the node should be toggled if the text is double clicked . Defaults to `true` + * @name $.jstree.defaults.core.dblclick_toggle + */ + dblclick_toggle : true + }; + $.jstree.core.prototype = { + /** + * used to decorate an instance with a plugin. Used internally. + * @private + * @name plugin(deco [, opts]) + * @param {String} deco the plugin to decorate with + * @param {Object} opts options for the plugin + * @return {jsTree} + */ + plugin : function (deco, opts) { + var Child = $.jstree.plugins[deco]; + if(Child) { + this._data[deco] = {}; + Child.prototype = this; + return new Child(opts, this); + } + return this; + }, + /** + * initialize the instance. Used internally. + * @private + * @name init(el, optons) + * @param {DOMElement|jQuery|String} el the element we are transforming + * @param {Object} options options for this instance + * @trigger init.jstree, loading.jstree, loaded.jstree, ready.jstree, changed.jstree + */ + init : function (el, options) { + this._model = { + data : {}, + changed : [], + force_full_redraw : false, + redraw_timeout : false, + default_state : { + loaded : true, + opened : false, + selected : false, + disabled : false + } + }; + this._model.data[$.jstree.root] = { + id : $.jstree.root, + parent : null, + parents : [], + children : [], + children_d : [], + state : { loaded : false } + }; + + this.element = $(el).addClass('jstree jstree-' + this._id); + this.settings = options; + + this._data.core.ready = false; + this._data.core.loaded = false; + this._data.core.rtl = (this.element.css("direction") === "rtl"); + this.element[this._data.core.rtl ? 'addClass' : 'removeClass']("jstree-rtl"); + this.element.attr('role','tree'); + if(this.settings.core.multiple) { + this.element.attr('aria-multiselectable', true); + } + if(!this.element.attr('tabindex')) { + this.element.attr('tabindex','0'); + } + + this.bind(); + /** + * triggered after all events are bound + * @event + * @name init.jstree + */ + this.trigger("init"); + + this._data.core.original_container_html = this.element.find(" > ul > li").clone(true); + this._data.core.original_container_html + .find("li").addBack() + .contents().filter(function() { + return this.nodeType === 3 && (!this.nodeValue || /^\s+$/.test(this.nodeValue)); + }) + .remove(); + this.element.html("<"+"ul class='jstree-container-ul jstree-children' role='group'><"+"li id='j"+this._id+"_loading' class='jstree-initial-node jstree-loading jstree-leaf jstree-last' role='tree-item'><i class='jstree-icon jstree-ocl'></i><"+"a class='jstree-anchor' href='#'><i class='jstree-icon jstree-themeicon-hidden'></i>" + this.get_string("Loading ...") + "</a></li></ul>"); + this.element.attr('aria-activedescendant','j' + this._id + '_loading'); + this._data.core.li_height = this.get_container_ul().children("li").first().height() || 24; + this._data.core.node = this._create_prototype_node(); + /** + * triggered after the loading text is shown and before loading starts + * @event + * @name loading.jstree + */ + this.trigger("loading"); + this.load_node($.jstree.root); + }, + /** + * destroy an instance + * @name destroy() + * @param {Boolean} keep_html if not set to `true` the container will be emptied, otherwise the current DOM elements will be kept intact + */ + destroy : function (keep_html) { + if(this._wrk) { + try { + window.URL.revokeObjectURL(this._wrk); + this._wrk = null; + } + catch (ignore) { } + } + if(!keep_html) { this.element.empty(); } + this.teardown(); + }, + /** + * Create prototype node + */ + _create_prototype_node : function () { + var _node = document.createElement('LI'), _temp1, _temp2; + _node.setAttribute('role', 'treeitem'); + _temp1 = document.createElement('I'); + _temp1.className = 'jstree-icon jstree-ocl'; + _temp1.setAttribute('role', 'presentation'); + _node.appendChild(_temp1); + _temp1 = document.createElement('A'); + _temp1.className = 'jstree-anchor'; + _temp1.setAttribute('href','#'); + _temp1.setAttribute('tabindex','-1'); + _temp2 = document.createElement('I'); + _temp2.className = 'jstree-icon jstree-themeicon'; + _temp2.setAttribute('role', 'presentation'); + _temp1.appendChild(_temp2); + _node.appendChild(_temp1); + _temp1 = _temp2 = null; + + return _node; + }, + /** + * part of the destroying of an instance. Used internally. + * @private + * @name teardown() + */ + teardown : function () { + this.unbind(); + this.element + .removeClass('jstree') + .removeData('jstree') + .find("[class^='jstree']") + .addBack() + .attr("class", function () { return this.className.replace(/jstree[^ ]*|$/ig,''); }); + this.element = null; + }, + /** + * bind all events. Used internally. + * @private + * @name bind() + */ + bind : function () { + var word = '', + tout = null, + was_click = 0; + this.element + .on("dblclick.jstree", function (e) { + if(e.target.tagName && e.target.tagName.toLowerCase() === "input") { return true; } + if(document.selection && document.selection.empty) { + document.selection.empty(); + } + else { + if(window.getSelection) { + var sel = window.getSelection(); + try { + sel.removeAllRanges(); + sel.collapse(); + } catch (ignore) { } + } + } + }) + .on("mousedown.jstree", $.proxy(function (e) { + if(e.target === this.element[0]) { + e.preventDefault(); // prevent losing focus when clicking scroll arrows (FF, Chrome) + was_click = +(new Date()); // ie does not allow to prevent losing focus + } + }, this)) + .on("mousedown.jstree", ".jstree-ocl", function (e) { + e.preventDefault(); // prevent any node inside from losing focus when clicking the open/close icon + }) + .on("click.jstree", ".jstree-ocl", $.proxy(function (e) { + this.toggle_node(e.target); + }, this)) + .on("dblclick.jstree", ".jstree-anchor", $.proxy(function (e) { + if(e.target.tagName && e.target.tagName.toLowerCase() === "input") { return true; } + if(this.settings.core.dblclick_toggle) { + this.toggle_node(e.target); + } + }, this)) + .on("click.jstree", ".jstree-anchor", $.proxy(function (e) { + e.preventDefault(); + if(e.currentTarget !== document.activeElement) { $(e.currentTarget).focus(); } + this.activate_node(e.currentTarget, e); + }, this)) + .on('keydown.jstree', '.jstree-anchor', $.proxy(function (e) { + if(e.target.tagName && e.target.tagName.toLowerCase() === "input") { return true; } + if(e.which !== 32 && e.which !== 13 && (e.shiftKey || e.ctrlKey || e.altKey || e.metaKey)) { return true; } + var o = null; + if(this._data.core.rtl) { + if(e.which === 37) { e.which = 39; } + else if(e.which === 39) { e.which = 37; } + } + switch(e.which) { + case 32: // aria defines space only with Ctrl + if(e.ctrlKey) { + e.type = "click"; + $(e.currentTarget).trigger(e); + } + break; + case 13: // enter + e.type = "click"; + $(e.currentTarget).trigger(e); + break; + case 37: // left + e.preventDefault(); + if(this.is_open(e.currentTarget)) { + this.close_node(e.currentTarget); + } + else { + o = this.get_parent(e.currentTarget); + if(o && o.id !== $.jstree.root) { this.get_node(o, true).children('.jstree-anchor').focus(); } + } + break; + case 38: // up + e.preventDefault(); + o = this.get_prev_dom(e.currentTarget); + if(o && o.length) { o.children('.jstree-anchor').focus(); } + break; + case 39: // right + e.preventDefault(); + if(this.is_closed(e.currentTarget)) { + this.open_node(e.currentTarget, function (o) { this.get_node(o, true).children('.jstree-anchor').focus(); }); + } + else if (this.is_open(e.currentTarget)) { + o = this.get_node(e.currentTarget, true).children('.jstree-children')[0]; + if(o) { $(this._firstChild(o)).children('.jstree-anchor').focus(); } + } + break; + case 40: // down + e.preventDefault(); + o = this.get_next_dom(e.currentTarget); + if(o && o.length) { o.children('.jstree-anchor').focus(); } + break; + case 106: // aria defines * on numpad as open_all - not very common + this.open_all(); + break; + case 36: // home + e.preventDefault(); + o = this._firstChild(this.get_container_ul()[0]); + if(o) { $(o).children('.jstree-anchor').filter(':visible').focus(); } + break; + case 35: // end + e.preventDefault(); + this.element.find('.jstree-anchor').filter(':visible').last().focus(); + break; + case 113: // f2 - safe to include - if check_callback is false it will fail + e.preventDefault(); + this.edit(e.currentTarget); + break; + default: + break; + /*! + // delete + case 46: + e.preventDefault(); + o = this.get_node(e.currentTarget); + if(o && o.id && o.id !== $.jstree.root) { + o = this.is_selected(o) ? this.get_selected() : o; + this.delete_node(o); + } + break; + + */ + } + }, this)) + .on("load_node.jstree", $.proxy(function (e, data) { + if(data.status) { + if(data.node.id === $.jstree.root && !this._data.core.loaded) { + this._data.core.loaded = true; + if(this._firstChild(this.get_container_ul()[0])) { + this.element.attr('aria-activedescendant',this._firstChild(this.get_container_ul()[0]).id); + } + /** + * triggered after the root node is loaded for the first time + * @event + * @name loaded.jstree + */ + this.trigger("loaded"); + } + if(!this._data.core.ready) { + setTimeout($.proxy(function() { + if(this.element && !this.get_container_ul().find('.jstree-loading').length) { + this._data.core.ready = true; + if(this._data.core.selected.length) { + if(this.settings.core.expand_selected_onload) { + var tmp = [], i, j; + for(i = 0, j = this._data.core.selected.length; i < j; i++) { + tmp = tmp.concat(this._model.data[this._data.core.selected[i]].parents); + } + tmp = $.vakata.array_unique(tmp); + for(i = 0, j = tmp.length; i < j; i++) { + this.open_node(tmp[i], false, 0); + } + } + this.trigger('changed', { 'action' : 'ready', 'selected' : this._data.core.selected }); + } + /** + * triggered after all nodes are finished loading + * @event + * @name ready.jstree + */ + this.trigger("ready"); + } + }, this), 0); + } + } + }, this)) + // quick searching when the tree is focused + .on('keypress.jstree', $.proxy(function (e) { + if(e.target.tagName && e.target.tagName.toLowerCase() === "input") { return true; } + if(tout) { clearTimeout(tout); } + tout = setTimeout(function () { + word = ''; + }, 500); + + var chr = String.fromCharCode(e.which).toLowerCase(), + col = this.element.find('.jstree-anchor').filter(':visible'), + ind = col.index(document.activeElement) || 0, + end = false; + word += chr; + + // match for whole word from current node down (including the current node) + if(word.length > 1) { + col.slice(ind).each($.proxy(function (i, v) { + if($(v).text().toLowerCase().indexOf(word) === 0) { + $(v).focus(); + end = true; + return false; + } + }, this)); + if(end) { return; } + + // match for whole word from the beginning of the tree + col.slice(0, ind).each($.proxy(function (i, v) { + if($(v).text().toLowerCase().indexOf(word) === 0) { + $(v).focus(); + end = true; + return false; + } + }, this)); + if(end) { return; } + } + // list nodes that start with that letter (only if word consists of a single char) + if(new RegExp('^' + chr.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') + '+$').test(word)) { + // search for the next node starting with that letter + col.slice(ind + 1).each($.proxy(function (i, v) { + if($(v).text().toLowerCase().charAt(0) === chr) { + $(v).focus(); + end = true; + return false; + } + }, this)); + if(end) { return; } + + // search from the beginning + col.slice(0, ind + 1).each($.proxy(function (i, v) { + if($(v).text().toLowerCase().charAt(0) === chr) { + $(v).focus(); + end = true; + return false; + } + }, this)); + if(end) { return; } + } + }, this)) + // THEME RELATED + .on("init.jstree", $.proxy(function () { + var s = this.settings.core.themes; + this._data.core.themes.dots = s.dots; + this._data.core.themes.stripes = s.stripes; + this._data.core.themes.icons = s.icons; + this._data.core.themes.ellipsis = s.ellipsis; + this.set_theme(s.name || "default", s.url); + this.set_theme_variant(s.variant); + }, this)) + .on("loading.jstree", $.proxy(function () { + this[ this._data.core.themes.dots ? "show_dots" : "hide_dots" ](); + this[ this._data.core.themes.icons ? "show_icons" : "hide_icons" ](); + this[ this._data.core.themes.stripes ? "show_stripes" : "hide_stripes" ](); + this[ this._data.core.themes.ellipsis ? "show_ellipsis" : "hide_ellipsis" ](); + }, this)) + .on('blur.jstree', '.jstree-anchor', $.proxy(function (e) { + this._data.core.focused = null; + $(e.currentTarget).filter('.jstree-hovered').mouseleave(); + this.element.attr('tabindex', '0'); + }, this)) + .on('focus.jstree', '.jstree-anchor', $.proxy(function (e) { + var tmp = this.get_node(e.currentTarget); + if(tmp && tmp.id) { + this._data.core.focused = tmp.id; + } + this.element.find('.jstree-hovered').not(e.currentTarget).mouseleave(); + $(e.currentTarget).mouseenter(); + this.element.attr('tabindex', '-1'); + }, this)) + .on('focus.jstree', $.proxy(function () { + if(+(new Date()) - was_click > 500 && !this._data.core.focused) { + was_click = 0; + var act = this.get_node(this.element.attr('aria-activedescendant'), true); + if(act) { + act.find('> .jstree-anchor').focus(); + } + } + }, this)) + .on('mouseenter.jstree', '.jstree-anchor', $.proxy(function (e) { + this.hover_node(e.currentTarget); + }, this)) + .on('mouseleave.jstree', '.jstree-anchor', $.proxy(function (e) { + this.dehover_node(e.currentTarget); + }, this)); + }, + /** + * part of the destroying of an instance. Used internally. + * @private + * @name unbind() + */ + unbind : function () { + this.element.off('.jstree'); + $(document).off('.jstree-' + this._id); + }, + /** + * trigger an event. Used internally. + * @private + * @name trigger(ev [, data]) + * @param {String} ev the name of the event to trigger + * @param {Object} data additional data to pass with the event + */ + trigger : function (ev, data) { + if(!data) { + data = {}; + } + data.instance = this; + this.element.triggerHandler(ev.replace('.jstree','') + '.jstree', data); + }, + /** + * returns the jQuery extended instance container + * @name get_container() + * @return {jQuery} + */ + get_container : function () { + return this.element; + }, + /** + * returns the jQuery extended main UL node inside the instance container. Used internally. + * @private + * @name get_container_ul() + * @return {jQuery} + */ + get_container_ul : function () { + return this.element.children(".jstree-children").first(); + }, + /** + * gets string replacements (localization). Used internally. + * @private + * @name get_string(key) + * @param {String} key + * @return {String} + */ + get_string : function (key) { + var a = this.settings.core.strings; + if($.isFunction(a)) { return a.call(this, key); } + if(a && a[key]) { return a[key]; } + return key; + }, + /** + * gets the first child of a DOM node. Used internally. + * @private + * @name _firstChild(dom) + * @param {DOMElement} dom + * @return {DOMElement} + */ + _firstChild : function (dom) { + dom = dom ? dom.firstChild : null; + while(dom !== null && dom.nodeType !== 1) { + dom = dom.nextSibling; + } + return dom; + }, + /** + * gets the next sibling of a DOM node. Used internally. + * @private + * @name _nextSibling(dom) + * @param {DOMElement} dom + * @return {DOMElement} + */ + _nextSibling : function (dom) { + dom = dom ? dom.nextSibling : null; + while(dom !== null && dom.nodeType !== 1) { + dom = dom.nextSibling; + } + return dom; + }, + /** + * gets the previous sibling of a DOM node. Used internally. + * @private + * @name _previousSibling(dom) + * @param {DOMElement} dom + * @return {DOMElement} + */ + _previousSibling : function (dom) { + dom = dom ? dom.previousSibling : null; + while(dom !== null && dom.nodeType !== 1) { + dom = dom.previousSibling; + } + return dom; + }, + /** + * get the JSON representation of a node (or the actual jQuery extended DOM node) by using any input (child DOM element, ID string, selector, etc) + * @name get_node(obj [, as_dom]) + * @param {mixed} obj + * @param {Boolean} as_dom + * @return {Object|jQuery} + */ + get_node : function (obj, as_dom) { + if(obj && obj.id) { + obj = obj.id; + } + var dom; + try { + if(this._model.data[obj]) { + obj = this._model.data[obj]; + } + else if(typeof obj === "string" && this._model.data[obj.replace(/^#/, '')]) { + obj = this._model.data[obj.replace(/^#/, '')]; + } + else if(typeof obj === "string" && (dom = $('#' + obj.replace($.jstree.idregex,'\\$&'), this.element)).length && this._model.data[dom.closest('.jstree-node').attr('id')]) { + obj = this._model.data[dom.closest('.jstree-node').attr('id')]; + } + else if((dom = $(obj, this.element)).length && this._model.data[dom.closest('.jstree-node').attr('id')]) { + obj = this._model.data[dom.closest('.jstree-node').attr('id')]; + } + else if((dom = $(obj, this.element)).length && dom.hasClass('jstree')) { + obj = this._model.data[$.jstree.root]; + } + else { + return false; + } + + if(as_dom) { + obj = obj.id === $.jstree.root ? this.element : $('#' + obj.id.replace($.jstree.idregex,'\\$&'), this.element); + } + return obj; + } catch (ex) { return false; } + }, + /** + * get the path to a node, either consisting of node texts, or of node IDs, optionally glued together (otherwise an array) + * @name get_path(obj [, glue, ids]) + * @param {mixed} obj the node + * @param {String} glue if you want the path as a string - pass the glue here (for example '/'), if a falsy value is supplied here, an array is returned + * @param {Boolean} ids if set to true build the path using ID, otherwise node text is used + * @return {mixed} + */ + get_path : function (obj, glue, ids) { + obj = obj.parents ? obj : this.get_node(obj); + if(!obj || obj.id === $.jstree.root || !obj.parents) { + return false; + } + var i, j, p = []; + p.push(ids ? obj.id : obj.text); + for(i = 0, j = obj.parents.length; i < j; i++) { + p.push(ids ? obj.parents[i] : this.get_text(obj.parents[i])); + } + p = p.reverse().slice(1); + return glue ? p.join(glue) : p; + }, + /** + * get the next visible node that is below the `obj` node. If `strict` is set to `true` only sibling nodes are returned. + * @name get_next_dom(obj [, strict]) + * @param {mixed} obj + * @param {Boolean} strict + * @return {jQuery} + */ + get_next_dom : function (obj, strict) { + var tmp; + obj = this.get_node(obj, true); + if(obj[0] === this.element[0]) { + tmp = this._firstChild(this.get_container_ul()[0]); + while (tmp && tmp.offsetHeight === 0) { + tmp = this._nextSibling(tmp); + } + return tmp ? $(tmp) : false; + } + if(!obj || !obj.length) { + return false; + } + if(strict) { + tmp = obj[0]; + do { + tmp = this._nextSibling(tmp); + } while (tmp && tmp.offsetHeight === 0); + return tmp ? $(tmp) : false; + } + if(obj.hasClass("jstree-open")) { + tmp = this._firstChild(obj.children('.jstree-children')[0]); + while (tmp && tmp.offsetHeight === 0) { + tmp = this._nextSibling(tmp); + } + if(tmp !== null) { + return $(tmp); + } + } + tmp = obj[0]; + do { + tmp = this._nextSibling(tmp); + } while (tmp && tmp.offsetHeight === 0); + if(tmp !== null) { + return $(tmp); + } + return obj.parentsUntil(".jstree",".jstree-node").nextAll(".jstree-node:visible").first(); + }, + /** + * get the previous visible node that is above the `obj` node. If `strict` is set to `true` only sibling nodes are returned. + * @name get_prev_dom(obj [, strict]) + * @param {mixed} obj + * @param {Boolean} strict + * @return {jQuery} + */ + get_prev_dom : function (obj, strict) { + var tmp; + obj = this.get_node(obj, true); + if(obj[0] === this.element[0]) { + tmp = this.get_container_ul()[0].lastChild; + while (tmp && tmp.offsetHeight === 0) { + tmp = this._previousSibling(tmp); + } + return tmp ? $(tmp) : false; + } + if(!obj || !obj.length) { + return false; + } + if(strict) { + tmp = obj[0]; + do { + tmp = this._previousSibling(tmp); + } while (tmp && tmp.offsetHeight === 0); + return tmp ? $(tmp) : false; + } + tmp = obj[0]; + do { + tmp = this._previousSibling(tmp); + } while (tmp && tmp.offsetHeight === 0); + if(tmp !== null) { + obj = $(tmp); + while(obj.hasClass("jstree-open")) { + obj = obj.children(".jstree-children").first().children(".jstree-node:visible:last"); + } + return obj; + } + tmp = obj[0].parentNode.parentNode; + return tmp && tmp.className && tmp.className.indexOf('jstree-node') !== -1 ? $(tmp) : false; + }, + /** + * get the parent ID of a node + * @name get_parent(obj) + * @param {mixed} obj + * @return {String} + */ + get_parent : function (obj) { + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { + return false; + } + return obj.parent; + }, + /** + * get a jQuery collection of all the children of a node (node must be rendered) + * @name get_children_dom(obj) + * @param {mixed} obj + * @return {jQuery} + */ + get_children_dom : function (obj) { + obj = this.get_node(obj, true); + if(obj[0] === this.element[0]) { + return this.get_container_ul().children(".jstree-node"); + } + if(!obj || !obj.length) { + return false; + } + return obj.children(".jstree-children").children(".jstree-node"); + }, + /** + * checks if a node has children + * @name is_parent(obj) + * @param {mixed} obj + * @return {Boolean} + */ + is_parent : function (obj) { + obj = this.get_node(obj); + return obj && (obj.state.loaded === false || obj.children.length > 0); + }, + /** + * checks if a node is loaded (its children are available) + * @name is_loaded(obj) + * @param {mixed} obj + * @return {Boolean} + */ + is_loaded : function (obj) { + obj = this.get_node(obj); + return obj && obj.state.loaded; + }, + /** + * check if a node is currently loading (fetching children) + * @name is_loading(obj) + * @param {mixed} obj + * @return {Boolean} + */ + is_loading : function (obj) { + obj = this.get_node(obj); + return obj && obj.state && obj.state.loading; + }, + /** + * check if a node is opened + * @name is_open(obj) + * @param {mixed} obj + * @return {Boolean} + */ + is_open : function (obj) { + obj = this.get_node(obj); + return obj && obj.state.opened; + }, + /** + * check if a node is in a closed state + * @name is_closed(obj) + * @param {mixed} obj + * @return {Boolean} + */ + is_closed : function (obj) { + obj = this.get_node(obj); + return obj && this.is_parent(obj) && !obj.state.opened; + }, + /** + * check if a node has no children + * @name is_leaf(obj) + * @param {mixed} obj + * @return {Boolean} + */ + is_leaf : function (obj) { + return !this.is_parent(obj); + }, + /** + * loads a node (fetches its children using the `core.data` setting). Multiple nodes can be passed to by using an array. + * @name load_node(obj [, callback]) + * @param {mixed} obj + * @param {function} callback a function to be executed once loading is complete, the function is executed in the instance's scope and receives two arguments - the node and a boolean status + * @return {Boolean} + * @trigger load_node.jstree + */ + load_node : function (obj, callback) { + var k, l, i, j, c; + if($.isArray(obj)) { + this._load_nodes(obj.slice(), callback); + return true; + } + obj = this.get_node(obj); + if(!obj) { + if(callback) { callback.call(this, obj, false); } + return false; + } + // if(obj.state.loading) { } // the node is already loading - just wait for it to load and invoke callback? but if called implicitly it should be loaded again? + if(obj.state.loaded) { + obj.state.loaded = false; + for(i = 0, j = obj.parents.length; i < j; i++) { + this._model.data[obj.parents[i]].children_d = $.vakata.array_filter(this._model.data[obj.parents[i]].children_d, function (v) { + return $.inArray(v, obj.children_d) === -1; + }); + } + for(k = 0, l = obj.children_d.length; k < l; k++) { + if(this._model.data[obj.children_d[k]].state.selected) { + c = true; + } + delete this._model.data[obj.children_d[k]]; + } + if (c) { + this._data.core.selected = $.vakata.array_filter(this._data.core.selected, function (v) { + return $.inArray(v, obj.children_d) === -1; + }); + } + obj.children = []; + obj.children_d = []; + if(c) { + this.trigger('changed', { 'action' : 'load_node', 'node' : obj, 'selected' : this._data.core.selected }); + } + } + obj.state.failed = false; + obj.state.loading = true; + this.get_node(obj, true).addClass("jstree-loading").attr('aria-busy',true); + this._load_node(obj, $.proxy(function (status) { + obj = this._model.data[obj.id]; + obj.state.loading = false; + obj.state.loaded = status; + obj.state.failed = !obj.state.loaded; + var dom = this.get_node(obj, true), i = 0, j = 0, m = this._model.data, has_children = false; + for(i = 0, j = obj.children.length; i < j; i++) { + if(m[obj.children[i]] && !m[obj.children[i]].state.hidden) { + has_children = true; + break; + } + } + if(obj.state.loaded && dom && dom.length) { + dom.removeClass('jstree-closed jstree-open jstree-leaf'); + if (!has_children) { + dom.addClass('jstree-leaf'); + } + else { + if (obj.id !== '#') { + dom.addClass(obj.state.opened ? 'jstree-open' : 'jstree-closed'); + } + } + } + dom.removeClass("jstree-loading").attr('aria-busy',false); + /** + * triggered after a node is loaded + * @event + * @name load_node.jstree + * @param {Object} node the node that was loading + * @param {Boolean} status was the node loaded successfully + */ + this.trigger('load_node', { "node" : obj, "status" : status }); + if(callback) { + callback.call(this, obj, status); + } + }, this)); + return true; + }, + /** + * load an array of nodes (will also load unavailable nodes as soon as the appear in the structure). Used internally. + * @private + * @name _load_nodes(nodes [, callback]) + * @param {array} nodes + * @param {function} callback a function to be executed once loading is complete, the function is executed in the instance's scope and receives one argument - the array passed to _load_nodes + */ + _load_nodes : function (nodes, callback, is_callback, force_reload) { + var r = true, + c = function () { this._load_nodes(nodes, callback, true); }, + m = this._model.data, i, j, tmp = []; + for(i = 0, j = nodes.length; i < j; i++) { + if(m[nodes[i]] && ( (!m[nodes[i]].state.loaded && !m[nodes[i]].state.failed) || (!is_callback && force_reload) )) { + if(!this.is_loading(nodes[i])) { + this.load_node(nodes[i], c); + } + r = false; + } + } + if(r) { + for(i = 0, j = nodes.length; i < j; i++) { + if(m[nodes[i]] && m[nodes[i]].state.loaded) { + tmp.push(nodes[i]); + } + } + if(callback && !callback.done) { + callback.call(this, tmp); + callback.done = true; + } + } + }, + /** + * loads all unloaded nodes + * @name load_all([obj, callback]) + * @param {mixed} obj the node to load recursively, omit to load all nodes in the tree + * @param {function} callback a function to be executed once loading all the nodes is complete, + * @trigger load_all.jstree + */ + load_all : function (obj, callback) { + if(!obj) { obj = $.jstree.root; } + obj = this.get_node(obj); + if(!obj) { return false; } + var to_load = [], + m = this._model.data, + c = m[obj.id].children_d, + i, j; + if(obj.state && !obj.state.loaded) { + to_load.push(obj.id); + } + for(i = 0, j = c.length; i < j; i++) { + if(m[c[i]] && m[c[i]].state && !m[c[i]].state.loaded) { + to_load.push(c[i]); + } + } + if(to_load.length) { + this._load_nodes(to_load, function () { + this.load_all(obj, callback); + }); + } + else { + /** + * triggered after a load_all call completes + * @event + * @name load_all.jstree + * @param {Object} node the recursively loaded node + */ + if(callback) { callback.call(this, obj); } + this.trigger('load_all', { "node" : obj }); + } + }, + /** + * handles the actual loading of a node. Used only internally. + * @private + * @name _load_node(obj [, callback]) + * @param {mixed} obj + * @param {function} callback a function to be executed once loading is complete, the function is executed in the instance's scope and receives one argument - a boolean status + * @return {Boolean} + */ + _load_node : function (obj, callback) { + var s = this.settings.core.data, t; + var notTextOrCommentNode = function notTextOrCommentNode () { + return this.nodeType !== 3 && this.nodeType !== 8; + }; + // use original HTML + if(!s) { + if(obj.id === $.jstree.root) { + return this._append_html_data(obj, this._data.core.original_container_html.clone(true), function (status) { + callback.call(this, status); + }); + } + else { + return callback.call(this, false); + } + // return callback.call(this, obj.id === $.jstree.root ? this._append_html_data(obj, this._data.core.original_container_html.clone(true)) : false); + } + if($.isFunction(s)) { + return s.call(this, obj, $.proxy(function (d) { + if(d === false) { + callback.call(this, false); + } + else { + this[typeof d === 'string' ? '_append_html_data' : '_append_json_data'](obj, typeof d === 'string' ? $($.parseHTML(d)).filter(notTextOrCommentNode) : d, function (status) { + callback.call(this, status); + }); + } + // return d === false ? callback.call(this, false) : callback.call(this, this[typeof d === 'string' ? '_append_html_data' : '_append_json_data'](obj, typeof d === 'string' ? $(d) : d)); + }, this)); + } + if(typeof s === 'object') { + if(s.url) { + s = $.extend(true, {}, s); + if($.isFunction(s.url)) { + s.url = s.url.call(this, obj); + } + if($.isFunction(s.data)) { + s.data = s.data.call(this, obj); + } + return $.ajax(s) + .done($.proxy(function (d,t,x) { + var type = x.getResponseHeader('Content-Type'); + if((type && type.indexOf('json') !== -1) || typeof d === "object") { + return this._append_json_data(obj, d, function (status) { callback.call(this, status); }); + //return callback.call(this, this._append_json_data(obj, d)); + } + if((type && type.indexOf('html') !== -1) || typeof d === "string") { + return this._append_html_data(obj, $($.parseHTML(d)).filter(notTextOrCommentNode), function (status) { callback.call(this, status); }); + // return callback.call(this, this._append_html_data(obj, $(d))); + } + this._data.core.last_error = { 'error' : 'ajax', 'plugin' : 'core', 'id' : 'core_04', 'reason' : 'Could not load node', 'data' : JSON.stringify({ 'id' : obj.id, 'xhr' : x }) }; + this.settings.core.error.call(this, this._data.core.last_error); + return callback.call(this, false); + }, this)) + .fail($.proxy(function (f) { + callback.call(this, false); + this._data.core.last_error = { 'error' : 'ajax', 'plugin' : 'core', 'id' : 'core_04', 'reason' : 'Could not load node', 'data' : JSON.stringify({ 'id' : obj.id, 'xhr' : f }) }; + this.settings.core.error.call(this, this._data.core.last_error); + }, this)); + } + t = ($.isArray(s) || $.isPlainObject(s)) ? JSON.parse(JSON.stringify(s)) : s; + if(obj.id === $.jstree.root) { + return this._append_json_data(obj, t, function (status) { + callback.call(this, status); + }); + } + else { + this._data.core.last_error = { 'error' : 'nodata', 'plugin' : 'core', 'id' : 'core_05', 'reason' : 'Could not load node', 'data' : JSON.stringify({ 'id' : obj.id }) }; + this.settings.core.error.call(this, this._data.core.last_error); + return callback.call(this, false); + } + //return callback.call(this, (obj.id === $.jstree.root ? this._append_json_data(obj, t) : false) ); + } + if(typeof s === 'string') { + if(obj.id === $.jstree.root) { + return this._append_html_data(obj, $($.parseHTML(s)).filter(notTextOrCommentNode), function (status) { + callback.call(this, status); + }); + } + else { + this._data.core.last_error = { 'error' : 'nodata', 'plugin' : 'core', 'id' : 'core_06', 'reason' : 'Could not load node', 'data' : JSON.stringify({ 'id' : obj.id }) }; + this.settings.core.error.call(this, this._data.core.last_error); + return callback.call(this, false); + } + //return callback.call(this, (obj.id === $.jstree.root ? this._append_html_data(obj, $(s)) : false) ); + } + return callback.call(this, false); + }, + /** + * adds a node to the list of nodes to redraw. Used only internally. + * @private + * @name _node_changed(obj [, callback]) + * @param {mixed} obj + */ + _node_changed : function (obj) { + obj = this.get_node(obj); + if(obj) { + this._model.changed.push(obj.id); + } + }, + /** + * appends HTML content to the tree. Used internally. + * @private + * @name _append_html_data(obj, data) + * @param {mixed} obj the node to append to + * @param {String} data the HTML string to parse and append + * @trigger model.jstree, changed.jstree + */ + _append_html_data : function (dom, data, cb) { + dom = this.get_node(dom); + dom.children = []; + dom.children_d = []; + var dat = data.is('ul') ? data.children() : data, + par = dom.id, + chd = [], + dpc = [], + m = this._model.data, + p = m[par], + s = this._data.core.selected.length, + tmp, i, j; + dat.each($.proxy(function (i, v) { + tmp = this._parse_model_from_html($(v), par, p.parents.concat()); + if(tmp) { + chd.push(tmp); + dpc.push(tmp); + if(m[tmp].children_d.length) { + dpc = dpc.concat(m[tmp].children_d); + } + } + }, this)); + p.children = chd; + p.children_d = dpc; + for(i = 0, j = p.parents.length; i < j; i++) { + m[p.parents[i]].children_d = m[p.parents[i]].children_d.concat(dpc); + } + /** + * triggered when new data is inserted to the tree model + * @event + * @name model.jstree + * @param {Array} nodes an array of node IDs + * @param {String} parent the parent ID of the nodes + */ + this.trigger('model', { "nodes" : dpc, 'parent' : par }); + if(par !== $.jstree.root) { + this._node_changed(par); + this.redraw(); + } + else { + this.get_container_ul().children('.jstree-initial-node').remove(); + this.redraw(true); + } + if(this._data.core.selected.length !== s) { + this.trigger('changed', { 'action' : 'model', 'selected' : this._data.core.selected }); + } + cb.call(this, true); + }, + /** + * appends JSON content to the tree. Used internally. + * @private + * @name _append_json_data(obj, data) + * @param {mixed} obj the node to append to + * @param {String} data the JSON object to parse and append + * @param {Boolean} force_processing internal param - do not set + * @trigger model.jstree, changed.jstree + */ + _append_json_data : function (dom, data, cb, force_processing) { + if(this.element === null) { return; } + dom = this.get_node(dom); + dom.children = []; + dom.children_d = []; + // *%$@!!! + if(data.d) { + data = data.d; + if(typeof data === "string") { + data = JSON.parse(data); + } + } + if(!$.isArray(data)) { data = [data]; } + var w = null, + args = { + 'df' : this._model.default_state, + 'dat' : data, + 'par' : dom.id, + 'm' : this._model.data, + 't_id' : this._id, + 't_cnt' : this._cnt, + 'sel' : this._data.core.selected + }, + func = function (data, undefined) { + if(data.data) { data = data.data; } + var dat = data.dat, + par = data.par, + chd = [], + dpc = [], + add = [], + df = data.df, + t_id = data.t_id, + t_cnt = data.t_cnt, + m = data.m, + p = m[par], + sel = data.sel, + tmp, i, j, rslt, + parse_flat = function (d, p, ps) { + if(!ps) { ps = []; } + else { ps = ps.concat(); } + if(p) { ps.unshift(p); } + var tid = d.id.toString(), + i, j, c, e, + tmp = { + id : tid, + text : d.text || '', + icon : d.icon !== undefined ? d.icon : true, + parent : p, + parents : ps, + children : d.children || [], + children_d : d.children_d || [], + data : d.data, + state : { }, + li_attr : { id : false }, + a_attr : { href : '#' }, + original : false + }; + for(i in df) { + if(df.hasOwnProperty(i)) { + tmp.state[i] = df[i]; + } + } + if(d && d.data && d.data.jstree && d.data.jstree.icon) { + tmp.icon = d.data.jstree.icon; + } + if(tmp.icon === undefined || tmp.icon === null || tmp.icon === "") { + tmp.icon = true; + } + if(d && d.data) { + tmp.data = d.data; + if(d.data.jstree) { + for(i in d.data.jstree) { + if(d.data.jstree.hasOwnProperty(i)) { + tmp.state[i] = d.data.jstree[i]; + } + } + } + } + if(d && typeof d.state === 'object') { + for (i in d.state) { + if(d.state.hasOwnProperty(i)) { + tmp.state[i] = d.state[i]; + } + } + } + if(d && typeof d.li_attr === 'object') { + for (i in d.li_attr) { + if(d.li_attr.hasOwnProperty(i)) { + tmp.li_attr[i] = d.li_attr[i]; + } + } + } + if(!tmp.li_attr.id) { + tmp.li_attr.id = tid; + } + if(d && typeof d.a_attr === 'object') { + for (i in d.a_attr) { + if(d.a_attr.hasOwnProperty(i)) { + tmp.a_attr[i] = d.a_attr[i]; + } + } + } + if(d && d.children && d.children === true) { + tmp.state.loaded = false; + tmp.children = []; + tmp.children_d = []; + } + m[tmp.id] = tmp; + for(i = 0, j = tmp.children.length; i < j; i++) { + c = parse_flat(m[tmp.children[i]], tmp.id, ps); + e = m[c]; + tmp.children_d.push(c); + if(e.children_d.length) { + tmp.children_d = tmp.children_d.concat(e.children_d); + } + } + delete d.data; + delete d.children; + m[tmp.id].original = d; + if(tmp.state.selected) { + add.push(tmp.id); + } + return tmp.id; + }, + parse_nest = function (d, p, ps) { + if(!ps) { ps = []; } + else { ps = ps.concat(); } + if(p) { ps.unshift(p); } + var tid = false, i, j, c, e, tmp; + do { + tid = 'j' + t_id + '_' + (++t_cnt); + } while(m[tid]); + + tmp = { + id : false, + text : typeof d === 'string' ? d : '', + icon : typeof d === 'object' && d.icon !== undefined ? d.icon : true, + parent : p, + parents : ps, + children : [], + children_d : [], + data : null, + state : { }, + li_attr : { id : false }, + a_attr : { href : '#' }, + original : false + }; + for(i in df) { + if(df.hasOwnProperty(i)) { + tmp.state[i] = df[i]; + } + } + if(d && d.id) { tmp.id = d.id.toString(); } + if(d && d.text) { tmp.text = d.text; } + if(d && d.data && d.data.jstree && d.data.jstree.icon) { + tmp.icon = d.data.jstree.icon; + } + if(tmp.icon === undefined || tmp.icon === null || tmp.icon === "") { + tmp.icon = true; + } + if(d && d.data) { + tmp.data = d.data; + if(d.data.jstree) { + for(i in d.data.jstree) { + if(d.data.jstree.hasOwnProperty(i)) { + tmp.state[i] = d.data.jstree[i]; + } + } + } + } + if(d && typeof d.state === 'object') { + for (i in d.state) { + if(d.state.hasOwnProperty(i)) { + tmp.state[i] = d.state[i]; + } + } + } + if(d && typeof d.li_attr === 'object') { + for (i in d.li_attr) { + if(d.li_attr.hasOwnProperty(i)) { + tmp.li_attr[i] = d.li_attr[i]; + } + } + } + if(tmp.li_attr.id && !tmp.id) { + tmp.id = tmp.li_attr.id.toString(); + } + if(!tmp.id) { + tmp.id = tid; + } + if(!tmp.li_attr.id) { + tmp.li_attr.id = tmp.id; + } + if(d && typeof d.a_attr === 'object') { + for (i in d.a_attr) { + if(d.a_attr.hasOwnProperty(i)) { + tmp.a_attr[i] = d.a_attr[i]; + } + } + } + if(d && d.children && d.children.length) { + for(i = 0, j = d.children.length; i < j; i++) { + c = parse_nest(d.children[i], tmp.id, ps); + e = m[c]; + tmp.children.push(c); + if(e.children_d.length) { + tmp.children_d = tmp.children_d.concat(e.children_d); + } + } + tmp.children_d = tmp.children_d.concat(tmp.children); + } + if(d && d.children && d.children === true) { + tmp.state.loaded = false; + tmp.children = []; + tmp.children_d = []; + } + delete d.data; + delete d.children; + tmp.original = d; + m[tmp.id] = tmp; + if(tmp.state.selected) { + add.push(tmp.id); + } + return tmp.id; + }; + + if(dat.length && dat[0].id !== undefined && dat[0].parent !== undefined) { + // Flat JSON support (for easy import from DB): + // 1) convert to object (foreach) + for(i = 0, j = dat.length; i < j; i++) { + if(!dat[i].children) { + dat[i].children = []; + } + m[dat[i].id.toString()] = dat[i]; + } + // 2) populate children (foreach) + for(i = 0, j = dat.length; i < j; i++) { + m[dat[i].parent.toString()].children.push(dat[i].id.toString()); + // populate parent.children_d + p.children_d.push(dat[i].id.toString()); + } + // 3) normalize && populate parents and children_d with recursion + for(i = 0, j = p.children.length; i < j; i++) { + tmp = parse_flat(m[p.children[i]], par, p.parents.concat()); + dpc.push(tmp); + if(m[tmp].children_d.length) { + dpc = dpc.concat(m[tmp].children_d); + } + } + for(i = 0, j = p.parents.length; i < j; i++) { + m[p.parents[i]].children_d = m[p.parents[i]].children_d.concat(dpc); + } + // ?) three_state selection - p.state.selected && t - (if three_state foreach(dat => ch) -> foreach(parents) if(parent.selected) child.selected = true; + rslt = { + 'cnt' : t_cnt, + 'mod' : m, + 'sel' : sel, + 'par' : par, + 'dpc' : dpc, + 'add' : add + }; + } + else { + for(i = 0, j = dat.length; i < j; i++) { + tmp = parse_nest(dat[i], par, p.parents.concat()); + if(tmp) { + chd.push(tmp); + dpc.push(tmp); + if(m[tmp].children_d.length) { + dpc = dpc.concat(m[tmp].children_d); + } + } + } + p.children = chd; + p.children_d = dpc; + for(i = 0, j = p.parents.length; i < j; i++) { + m[p.parents[i]].children_d = m[p.parents[i]].children_d.concat(dpc); + } + rslt = { + 'cnt' : t_cnt, + 'mod' : m, + 'sel' : sel, + 'par' : par, + 'dpc' : dpc, + 'add' : add + }; + } + if(typeof window === 'undefined' || typeof window.document === 'undefined') { + postMessage(rslt); + } + else { + return rslt; + } + }, + rslt = function (rslt, worker) { + if(this.element === null) { return; } + this._cnt = rslt.cnt; + var i, m = this._model.data; + for (i in m) { + if (m.hasOwnProperty(i) && m[i].state && m[i].state.loading && rslt.mod[i]) { + rslt.mod[i].state.loading = true; + } + } + this._model.data = rslt.mod; // breaks the reference in load_node - careful + + if(worker) { + var j, a = rslt.add, r = rslt.sel, s = this._data.core.selected.slice(); + m = this._model.data; + // if selection was changed while calculating in worker + if(r.length !== s.length || $.vakata.array_unique(r.concat(s)).length !== r.length) { + // deselect nodes that are no longer selected + for(i = 0, j = r.length; i < j; i++) { + if($.inArray(r[i], a) === -1 && $.inArray(r[i], s) === -1) { + m[r[i]].state.selected = false; + } + } + // select nodes that were selected in the mean time + for(i = 0, j = s.length; i < j; i++) { + if($.inArray(s[i], r) === -1) { + m[s[i]].state.selected = true; + } + } + } + } + if(rslt.add.length) { + this._data.core.selected = this._data.core.selected.concat(rslt.add); + } + + this.trigger('model', { "nodes" : rslt.dpc, 'parent' : rslt.par }); + + if(rslt.par !== $.jstree.root) { + this._node_changed(rslt.par); + this.redraw(); + } + else { + // this.get_container_ul().children('.jstree-initial-node').remove(); + this.redraw(true); + } + if(rslt.add.length) { + this.trigger('changed', { 'action' : 'model', 'selected' : this._data.core.selected }); + } + cb.call(this, true); + }; + if(this.settings.core.worker && window.Blob && window.URL && window.Worker) { + try { + if(this._wrk === null) { + this._wrk = window.URL.createObjectURL( + new window.Blob( + ['self.onmessage = ' + func.toString()], + {type:"text/javascript"} + ) + ); + } + if(!this._data.core.working || force_processing) { + this._data.core.working = true; + w = new window.Worker(this._wrk); + w.onmessage = $.proxy(function (e) { + rslt.call(this, e.data, true); + try { w.terminate(); w = null; } catch(ignore) { } + if(this._data.core.worker_queue.length) { + this._append_json_data.apply(this, this._data.core.worker_queue.shift()); + } + else { + this._data.core.working = false; + } + }, this); + if(!args.par) { + if(this._data.core.worker_queue.length) { + this._append_json_data.apply(this, this._data.core.worker_queue.shift()); + } + else { + this._data.core.working = false; + } + } + else { + w.postMessage(args); + } + } + else { + this._data.core.worker_queue.push([dom, data, cb, true]); + } + } + catch(e) { + rslt.call(this, func(args), false); + if(this._data.core.worker_queue.length) { + this._append_json_data.apply(this, this._data.core.worker_queue.shift()); + } + else { + this._data.core.working = false; + } + } + } + else { + rslt.call(this, func(args), false); + } + }, + /** + * parses a node from a jQuery object and appends them to the in memory tree model. Used internally. + * @private + * @name _parse_model_from_html(d [, p, ps]) + * @param {jQuery} d the jQuery object to parse + * @param {String} p the parent ID + * @param {Array} ps list of all parents + * @return {String} the ID of the object added to the model + */ + _parse_model_from_html : function (d, p, ps) { + if(!ps) { ps = []; } + else { ps = [].concat(ps); } + if(p) { ps.unshift(p); } + var c, e, m = this._model.data, + data = { + id : false, + text : false, + icon : true, + parent : p, + parents : ps, + children : [], + children_d : [], + data : null, + state : { }, + li_attr : { id : false }, + a_attr : { href : '#' }, + original : false + }, i, tmp, tid; + for(i in this._model.default_state) { + if(this._model.default_state.hasOwnProperty(i)) { + data.state[i] = this._model.default_state[i]; + } + } + tmp = $.vakata.attributes(d, true); + $.each(tmp, function (i, v) { + v = $.trim(v); + if(!v.length) { return true; } + data.li_attr[i] = v; + if(i === 'id') { + data.id = v.toString(); + } + }); + tmp = d.children('a').first(); + if(tmp.length) { + tmp = $.vakata.attributes(tmp, true); + $.each(tmp, function (i, v) { + v = $.trim(v); + if(v.length) { + data.a_attr[i] = v; + } + }); + } + tmp = d.children("a").first().length ? d.children("a").first().clone() : d.clone(); + tmp.children("ins, i, ul").remove(); + tmp = tmp.html(); + tmp = $('<div />').html(tmp); + data.text = this.settings.core.force_text ? tmp.text() : tmp.html(); + tmp = d.data(); + data.data = tmp ? $.extend(true, {}, tmp) : null; + data.state.opened = d.hasClass('jstree-open'); + data.state.selected = d.children('a').hasClass('jstree-clicked'); + data.state.disabled = d.children('a').hasClass('jstree-disabled'); + if(data.data && data.data.jstree) { + for(i in data.data.jstree) { + if(data.data.jstree.hasOwnProperty(i)) { + data.state[i] = data.data.jstree[i]; + } + } + } + tmp = d.children("a").children(".jstree-themeicon"); + if(tmp.length) { + data.icon = tmp.hasClass('jstree-themeicon-hidden') ? false : tmp.attr('rel'); + } + if(data.state.icon !== undefined) { + data.icon = data.state.icon; + } + if(data.icon === undefined || data.icon === null || data.icon === "") { + data.icon = true; + } + tmp = d.children("ul").children("li"); + do { + tid = 'j' + this._id + '_' + (++this._cnt); + } while(m[tid]); + data.id = data.li_attr.id ? data.li_attr.id.toString() : tid; + if(tmp.length) { + tmp.each($.proxy(function (i, v) { + c = this._parse_model_from_html($(v), data.id, ps); + e = this._model.data[c]; + data.children.push(c); + if(e.children_d.length) { + data.children_d = data.children_d.concat(e.children_d); + } + }, this)); + data.children_d = data.children_d.concat(data.children); + } + else { + if(d.hasClass('jstree-closed')) { + data.state.loaded = false; + } + } + if(data.li_attr['class']) { + data.li_attr['class'] = data.li_attr['class'].replace('jstree-closed','').replace('jstree-open',''); + } + if(data.a_attr['class']) { + data.a_attr['class'] = data.a_attr['class'].replace('jstree-clicked','').replace('jstree-disabled',''); + } + m[data.id] = data; + if(data.state.selected) { + this._data.core.selected.push(data.id); + } + return data.id; + }, + /** + * parses a node from a JSON object (used when dealing with flat data, which has no nesting of children, but has id and parent properties) and appends it to the in memory tree model. Used internally. + * @private + * @name _parse_model_from_flat_json(d [, p, ps]) + * @param {Object} d the JSON object to parse + * @param {String} p the parent ID + * @param {Array} ps list of all parents + * @return {String} the ID of the object added to the model + */ + _parse_model_from_flat_json : function (d, p, ps) { + if(!ps) { ps = []; } + else { ps = ps.concat(); } + if(p) { ps.unshift(p); } + var tid = d.id.toString(), + m = this._model.data, + df = this._model.default_state, + i, j, c, e, + tmp = { + id : tid, + text : d.text || '', + icon : d.icon !== undefined ? d.icon : true, + parent : p, + parents : ps, + children : d.children || [], + children_d : d.children_d || [], + data : d.data, + state : { }, + li_attr : { id : false }, + a_attr : { href : '#' }, + original : false + }; + for(i in df) { + if(df.hasOwnProperty(i)) { + tmp.state[i] = df[i]; + } + } + if(d && d.data && d.data.jstree && d.data.jstree.icon) { + tmp.icon = d.data.jstree.icon; + } + if(tmp.icon === undefined || tmp.icon === null || tmp.icon === "") { + tmp.icon = true; + } + if(d && d.data) { + tmp.data = d.data; + if(d.data.jstree) { + for(i in d.data.jstree) { + if(d.data.jstree.hasOwnProperty(i)) { + tmp.state[i] = d.data.jstree[i]; + } + } + } + } + if(d && typeof d.state === 'object') { + for (i in d.state) { + if(d.state.hasOwnProperty(i)) { + tmp.state[i] = d.state[i]; + } + } + } + if(d && typeof d.li_attr === 'object') { + for (i in d.li_attr) { + if(d.li_attr.hasOwnProperty(i)) { + tmp.li_attr[i] = d.li_attr[i]; + } + } + } + if(!tmp.li_attr.id) { + tmp.li_attr.id = tid; + } + if(d && typeof d.a_attr === 'object') { + for (i in d.a_attr) { + if(d.a_attr.hasOwnProperty(i)) { + tmp.a_attr[i] = d.a_attr[i]; + } + } + } + if(d && d.children && d.children === true) { + tmp.state.loaded = false; + tmp.children = []; + tmp.children_d = []; + } + m[tmp.id] = tmp; + for(i = 0, j = tmp.children.length; i < j; i++) { + c = this._parse_model_from_flat_json(m[tmp.children[i]], tmp.id, ps); + e = m[c]; + tmp.children_d.push(c); + if(e.children_d.length) { + tmp.children_d = tmp.children_d.concat(e.children_d); + } + } + delete d.data; + delete d.children; + m[tmp.id].original = d; + if(tmp.state.selected) { + this._data.core.selected.push(tmp.id); + } + return tmp.id; + }, + /** + * parses a node from a JSON object and appends it to the in memory tree model. Used internally. + * @private + * @name _parse_model_from_json(d [, p, ps]) + * @param {Object} d the JSON object to parse + * @param {String} p the parent ID + * @param {Array} ps list of all parents + * @return {String} the ID of the object added to the model + */ + _parse_model_from_json : function (d, p, ps) { + if(!ps) { ps = []; } + else { ps = ps.concat(); } + if(p) { ps.unshift(p); } + var tid = false, i, j, c, e, m = this._model.data, df = this._model.default_state, tmp; + do { + tid = 'j' + this._id + '_' + (++this._cnt); + } while(m[tid]); + + tmp = { + id : false, + text : typeof d === 'string' ? d : '', + icon : typeof d === 'object' && d.icon !== undefined ? d.icon : true, + parent : p, + parents : ps, + children : [], + children_d : [], + data : null, + state : { }, + li_attr : { id : false }, + a_attr : { href : '#' }, + original : false + }; + for(i in df) { + if(df.hasOwnProperty(i)) { + tmp.state[i] = df[i]; + } + } + if(d && d.id) { tmp.id = d.id.toString(); } + if(d && d.text) { tmp.text = d.text; } + if(d && d.data && d.data.jstree && d.data.jstree.icon) { + tmp.icon = d.data.jstree.icon; + } + if(tmp.icon === undefined || tmp.icon === null || tmp.icon === "") { + tmp.icon = true; + } + if(d && d.data) { + tmp.data = d.data; + if(d.data.jstree) { + for(i in d.data.jstree) { + if(d.data.jstree.hasOwnProperty(i)) { + tmp.state[i] = d.data.jstree[i]; + } + } + } + } + if(d && typeof d.state === 'object') { + for (i in d.state) { + if(d.state.hasOwnProperty(i)) { + tmp.state[i] = d.state[i]; + } + } + } + if(d && typeof d.li_attr === 'object') { + for (i in d.li_attr) { + if(d.li_attr.hasOwnProperty(i)) { + tmp.li_attr[i] = d.li_attr[i]; + } + } + } + if(tmp.li_attr.id && !tmp.id) { + tmp.id = tmp.li_attr.id.toString(); + } + if(!tmp.id) { + tmp.id = tid; + } + if(!tmp.li_attr.id) { + tmp.li_attr.id = tmp.id; + } + if(d && typeof d.a_attr === 'object') { + for (i in d.a_attr) { + if(d.a_attr.hasOwnProperty(i)) { + tmp.a_attr[i] = d.a_attr[i]; + } + } + } + if(d && d.children && d.children.length) { + for(i = 0, j = d.children.length; i < j; i++) { + c = this._parse_model_from_json(d.children[i], tmp.id, ps); + e = m[c]; + tmp.children.push(c); + if(e.children_d.length) { + tmp.children_d = tmp.children_d.concat(e.children_d); + } + } + tmp.children_d = tmp.children_d.concat(tmp.children); + } + if(d && d.children && d.children === true) { + tmp.state.loaded = false; + tmp.children = []; + tmp.children_d = []; + } + delete d.data; + delete d.children; + tmp.original = d; + m[tmp.id] = tmp; + if(tmp.state.selected) { + this._data.core.selected.push(tmp.id); + } + return tmp.id; + }, + /** + * redraws all nodes that need to be redrawn. Used internally. + * @private + * @name _redraw() + * @trigger redraw.jstree + */ + _redraw : function () { + var nodes = this._model.force_full_redraw ? this._model.data[$.jstree.root].children.concat([]) : this._model.changed.concat([]), + f = document.createElement('UL'), tmp, i, j, fe = this._data.core.focused; + for(i = 0, j = nodes.length; i < j; i++) { + tmp = this.redraw_node(nodes[i], true, this._model.force_full_redraw); + if(tmp && this._model.force_full_redraw) { + f.appendChild(tmp); + } + } + if(this._model.force_full_redraw) { + f.className = this.get_container_ul()[0].className; + f.setAttribute('role','group'); + this.element.empty().append(f); + //this.get_container_ul()[0].appendChild(f); + } + if(fe !== null) { + tmp = this.get_node(fe, true); + if(tmp && tmp.length && tmp.children('.jstree-anchor')[0] !== document.activeElement) { + tmp.children('.jstree-anchor').focus(); + } + else { + this._data.core.focused = null; + } + } + this._model.force_full_redraw = false; + this._model.changed = []; + /** + * triggered after nodes are redrawn + * @event + * @name redraw.jstree + * @param {array} nodes the redrawn nodes + */ + this.trigger('redraw', { "nodes" : nodes }); + }, + /** + * redraws all nodes that need to be redrawn or optionally - the whole tree + * @name redraw([full]) + * @param {Boolean} full if set to `true` all nodes are redrawn. + */ + redraw : function (full) { + if(full) { + this._model.force_full_redraw = true; + } + //if(this._model.redraw_timeout) { + // clearTimeout(this._model.redraw_timeout); + //} + //this._model.redraw_timeout = setTimeout($.proxy(this._redraw, this),0); + this._redraw(); + }, + /** + * redraws a single node's children. Used internally. + * @private + * @name draw_children(node) + * @param {mixed} node the node whose children will be redrawn + */ + draw_children : function (node) { + var obj = this.get_node(node), + i = false, + j = false, + k = false, + d = document; + if(!obj) { return false; } + if(obj.id === $.jstree.root) { return this.redraw(true); } + node = this.get_node(node, true); + if(!node || !node.length) { return false; } // TODO: quick toggle + + node.children('.jstree-children').remove(); + node = node[0]; + if(obj.children.length && obj.state.loaded) { + k = d.createElement('UL'); + k.setAttribute('role', 'group'); + k.className = 'jstree-children'; + for(i = 0, j = obj.children.length; i < j; i++) { + k.appendChild(this.redraw_node(obj.children[i], true, true)); + } + node.appendChild(k); + } + }, + /** + * redraws a single node. Used internally. + * @private + * @name redraw_node(node, deep, is_callback, force_render) + * @param {mixed} node the node to redraw + * @param {Boolean} deep should child nodes be redrawn too + * @param {Boolean} is_callback is this a recursion call + * @param {Boolean} force_render should children of closed parents be drawn anyway + */ + redraw_node : function (node, deep, is_callback, force_render) { + var obj = this.get_node(node), + par = false, + ind = false, + old = false, + i = false, + j = false, + k = false, + c = '', + d = document, + m = this._model.data, + f = false, + s = false, + tmp = null, + t = 0, + l = 0, + has_children = false, + last_sibling = false; + if(!obj) { return false; } + if(obj.id === $.jstree.root) { return this.redraw(true); } + deep = deep || obj.children.length === 0; + node = !document.querySelector ? document.getElementById(obj.id) : this.element[0].querySelector('#' + ("0123456789".indexOf(obj.id[0]) !== -1 ? '\\3' + obj.id[0] + ' ' + obj.id.substr(1).replace($.jstree.idregex,'\\$&') : obj.id.replace($.jstree.idregex,'\\$&')) ); //, this.element); + if(!node) { + deep = true; + //node = d.createElement('LI'); + if(!is_callback) { + par = obj.parent !== $.jstree.root ? $('#' + obj.parent.replace($.jstree.idregex,'\\$&'), this.element)[0] : null; + if(par !== null && (!par || !m[obj.parent].state.opened)) { + return false; + } + ind = $.inArray(obj.id, par === null ? m[$.jstree.root].children : m[obj.parent].children); + } + } + else { + node = $(node); + if(!is_callback) { + par = node.parent().parent()[0]; + if(par === this.element[0]) { + par = null; + } + ind = node.index(); + } + // m[obj.id].data = node.data(); // use only node's data, no need to touch jquery storage + if(!deep && obj.children.length && !node.children('.jstree-children').length) { + deep = true; + } + if(!deep) { + old = node.children('.jstree-children')[0]; + } + f = node.children('.jstree-anchor')[0] === document.activeElement; + node.remove(); + //node = d.createElement('LI'); + //node = node[0]; + } + node = this._data.core.node.cloneNode(true); + // node is DOM, deep is boolean + + c = 'jstree-node '; + for(i in obj.li_attr) { + if(obj.li_attr.hasOwnProperty(i)) { + if(i === 'id') { continue; } + if(i !== 'class') { + node.setAttribute(i, obj.li_attr[i]); + } + else { + c += obj.li_attr[i]; + } + } + } + if(!obj.a_attr.id) { + obj.a_attr.id = obj.id + '_anchor'; + } + node.setAttribute('aria-selected', !!obj.state.selected); + node.setAttribute('aria-level', obj.parents.length); + node.setAttribute('aria-labelledby', obj.a_attr.id); + if(obj.state.disabled) { + node.setAttribute('aria-disabled', true); + } + + for(i = 0, j = obj.children.length; i < j; i++) { + if(!m[obj.children[i]].state.hidden) { + has_children = true; + break; + } + } + if(obj.parent !== null && m[obj.parent] && !obj.state.hidden) { + i = $.inArray(obj.id, m[obj.parent].children); + last_sibling = obj.id; + if(i !== -1) { + i++; + for(j = m[obj.parent].children.length; i < j; i++) { + if(!m[m[obj.parent].children[i]].state.hidden) { + last_sibling = m[obj.parent].children[i]; + } + if(last_sibling !== obj.id) { + break; + } + } + } + } + + if(obj.state.hidden) { + c += ' jstree-hidden'; + } + if(obj.state.loaded && !has_children) { + c += ' jstree-leaf'; + } + else { + c += obj.state.opened && obj.state.loaded ? ' jstree-open' : ' jstree-closed'; + node.setAttribute('aria-expanded', (obj.state.opened && obj.state.loaded) ); + } + if(last_sibling === obj.id) { + c += ' jstree-last'; + } + node.id = obj.id; + node.className = c; + c = ( obj.state.selected ? ' jstree-clicked' : '') + ( obj.state.disabled ? ' jstree-disabled' : ''); + for(j in obj.a_attr) { + if(obj.a_attr.hasOwnProperty(j)) { + if(j === 'href' && obj.a_attr[j] === '#') { continue; } + if(j !== 'class') { + node.childNodes[1].setAttribute(j, obj.a_attr[j]); + } + else { + c += ' ' + obj.a_attr[j]; + } + } + } + if(c.length) { + node.childNodes[1].className = 'jstree-anchor ' + c; + } + if((obj.icon && obj.icon !== true) || obj.icon === false) { + if(obj.icon === false) { + node.childNodes[1].childNodes[0].className += ' jstree-themeicon-hidden'; + } + else if(obj.icon.indexOf('/') === -1 && obj.icon.indexOf('.') === -1) { + node.childNodes[1].childNodes[0].className += ' ' + obj.icon + ' jstree-themeicon-custom'; + } + else { + node.childNodes[1].childNodes[0].style.backgroundImage = 'url("'+obj.icon+'")'; + node.childNodes[1].childNodes[0].style.backgroundPosition = 'center center'; + node.childNodes[1].childNodes[0].style.backgroundSize = 'auto'; + node.childNodes[1].childNodes[0].className += ' jstree-themeicon-custom'; + } + } + + if(this.settings.core.force_text) { + node.childNodes[1].appendChild(d.createTextNode(obj.text)); + } + else { + node.childNodes[1].innerHTML += obj.text; + } + + + if(deep && obj.children.length && (obj.state.opened || force_render) && obj.state.loaded) { + k = d.createElement('UL'); + k.setAttribute('role', 'group'); + k.className = 'jstree-children'; + for(i = 0, j = obj.children.length; i < j; i++) { + k.appendChild(this.redraw_node(obj.children[i], deep, true)); + } + node.appendChild(k); + } + if(old) { + node.appendChild(old); + } + if(!is_callback) { + // append back using par / ind + if(!par) { + par = this.element[0]; + } + for(i = 0, j = par.childNodes.length; i < j; i++) { + if(par.childNodes[i] && par.childNodes[i].className && par.childNodes[i].className.indexOf('jstree-children') !== -1) { + tmp = par.childNodes[i]; + break; + } + } + if(!tmp) { + tmp = d.createElement('UL'); + tmp.setAttribute('role', 'group'); + tmp.className = 'jstree-children'; + par.appendChild(tmp); + } + par = tmp; + + if(ind < par.childNodes.length) { + par.insertBefore(node, par.childNodes[ind]); + } + else { + par.appendChild(node); + } + if(f) { + t = this.element[0].scrollTop; + l = this.element[0].scrollLeft; + node.childNodes[1].focus(); + this.element[0].scrollTop = t; + this.element[0].scrollLeft = l; + } + } + if(obj.state.opened && !obj.state.loaded) { + obj.state.opened = false; + setTimeout($.proxy(function () { + this.open_node(obj.id, false, 0); + }, this), 0); + } + return node; + }, + /** + * opens a node, revaling its children. If the node is not loaded it will be loaded and opened once ready. + * @name open_node(obj [, callback, animation]) + * @param {mixed} obj the node to open + * @param {Function} callback a function to execute once the node is opened + * @param {Number} animation the animation duration in milliseconds when opening the node (overrides the `core.animation` setting). Use `false` for no animation. + * @trigger open_node.jstree, after_open.jstree, before_open.jstree + */ + open_node : function (obj, callback, animation) { + var t1, t2, d, t; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.open_node(obj[t1], callback, animation); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { + return false; + } + animation = animation === undefined ? this.settings.core.animation : animation; + if(!this.is_closed(obj)) { + if(callback) { + callback.call(this, obj, false); + } + return false; + } + if(!this.is_loaded(obj)) { + if(this.is_loading(obj)) { + return setTimeout($.proxy(function () { + this.open_node(obj, callback, animation); + }, this), 500); + } + this.load_node(obj, function (o, ok) { + return ok ? this.open_node(o, callback, animation) : (callback ? callback.call(this, o, false) : false); + }); + } + else { + d = this.get_node(obj, true); + t = this; + if(d.length) { + if(animation && d.children(".jstree-children").length) { + d.children(".jstree-children").stop(true, true); + } + if(obj.children.length && !this._firstChild(d.children('.jstree-children')[0])) { + this.draw_children(obj); + //d = this.get_node(obj, true); + } + if(!animation) { + this.trigger('before_open', { "node" : obj }); + d[0].className = d[0].className.replace('jstree-closed', 'jstree-open'); + d[0].setAttribute("aria-expanded", true); + } + else { + this.trigger('before_open', { "node" : obj }); + d + .children(".jstree-children").css("display","none").end() + .removeClass("jstree-closed").addClass("jstree-open").attr("aria-expanded", true) + .children(".jstree-children").stop(true, true) + .slideDown(animation, function () { + this.style.display = ""; + if (t.element) { + t.trigger("after_open", { "node" : obj }); + } + }); + } + } + obj.state.opened = true; + if(callback) { + callback.call(this, obj, true); + } + if(!d.length) { + /** + * triggered when a node is about to be opened (if the node is supposed to be in the DOM, it will be, but it won't be visible yet) + * @event + * @name before_open.jstree + * @param {Object} node the opened node + */ + this.trigger('before_open', { "node" : obj }); + } + /** + * triggered when a node is opened (if there is an animation it will not be completed yet) + * @event + * @name open_node.jstree + * @param {Object} node the opened node + */ + this.trigger('open_node', { "node" : obj }); + if(!animation || !d.length) { + /** + * triggered when a node is opened and the animation is complete + * @event + * @name after_open.jstree + * @param {Object} node the opened node + */ + this.trigger("after_open", { "node" : obj }); + } + return true; + } + }, + /** + * opens every parent of a node (node should be loaded) + * @name _open_to(obj) + * @param {mixed} obj the node to reveal + * @private + */ + _open_to : function (obj) { + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { + return false; + } + var i, j, p = obj.parents; + for(i = 0, j = p.length; i < j; i+=1) { + if(i !== $.jstree.root) { + this.open_node(p[i], false, 0); + } + } + return $('#' + obj.id.replace($.jstree.idregex,'\\$&'), this.element); + }, + /** + * closes a node, hiding its children + * @name close_node(obj [, animation]) + * @param {mixed} obj the node to close + * @param {Number} animation the animation duration in milliseconds when closing the node (overrides the `core.animation` setting). Use `false` for no animation. + * @trigger close_node.jstree, after_close.jstree + */ + close_node : function (obj, animation) { + var t1, t2, t, d; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.close_node(obj[t1], animation); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { + return false; + } + if(this.is_closed(obj)) { + return false; + } + animation = animation === undefined ? this.settings.core.animation : animation; + t = this; + d = this.get_node(obj, true); + + obj.state.opened = false; + /** + * triggered when a node is closed (if there is an animation it will not be complete yet) + * @event + * @name close_node.jstree + * @param {Object} node the closed node + */ + this.trigger('close_node',{ "node" : obj }); + if(!d.length) { + /** + * triggered when a node is closed and the animation is complete + * @event + * @name after_close.jstree + * @param {Object} node the closed node + */ + this.trigger("after_close", { "node" : obj }); + } + else { + if(!animation) { + d[0].className = d[0].className.replace('jstree-open', 'jstree-closed'); + d.attr("aria-expanded", false).children('.jstree-children').remove(); + this.trigger("after_close", { "node" : obj }); + } + else { + d + .children(".jstree-children").attr("style","display:block !important").end() + .removeClass("jstree-open").addClass("jstree-closed").attr("aria-expanded", false) + .children(".jstree-children").stop(true, true).slideUp(animation, function () { + this.style.display = ""; + d.children('.jstree-children').remove(); + if (t.element) { + t.trigger("after_close", { "node" : obj }); + } + }); + } + } + }, + /** + * toggles a node - closing it if it is open, opening it if it is closed + * @name toggle_node(obj) + * @param {mixed} obj the node to toggle + */ + toggle_node : function (obj) { + var t1, t2; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.toggle_node(obj[t1]); + } + return true; + } + if(this.is_closed(obj)) { + return this.open_node(obj); + } + if(this.is_open(obj)) { + return this.close_node(obj); + } + }, + /** + * opens all nodes within a node (or the tree), revaling their children. If the node is not loaded it will be loaded and opened once ready. + * @name open_all([obj, animation, original_obj]) + * @param {mixed} obj the node to open recursively, omit to open all nodes in the tree + * @param {Number} animation the animation duration in milliseconds when opening the nodes, the default is no animation + * @param {jQuery} reference to the node that started the process (internal use) + * @trigger open_all.jstree + */ + open_all : function (obj, animation, original_obj) { + if(!obj) { obj = $.jstree.root; } + obj = this.get_node(obj); + if(!obj) { return false; } + var dom = obj.id === $.jstree.root ? this.get_container_ul() : this.get_node(obj, true), i, j, _this; + if(!dom.length) { + for(i = 0, j = obj.children_d.length; i < j; i++) { + if(this.is_closed(this._model.data[obj.children_d[i]])) { + this._model.data[obj.children_d[i]].state.opened = true; + } + } + return this.trigger('open_all', { "node" : obj }); + } + original_obj = original_obj || dom; + _this = this; + dom = this.is_closed(obj) ? dom.find('.jstree-closed').addBack() : dom.find('.jstree-closed'); + dom.each(function () { + _this.open_node( + this, + function(node, status) { if(status && this.is_parent(node)) { this.open_all(node, animation, original_obj); } }, + animation || 0 + ); + }); + if(original_obj.find('.jstree-closed').length === 0) { + /** + * triggered when an `open_all` call completes + * @event + * @name open_all.jstree + * @param {Object} node the opened node + */ + this.trigger('open_all', { "node" : this.get_node(original_obj) }); + } + }, + /** + * closes all nodes within a node (or the tree), revaling their children + * @name close_all([obj, animation]) + * @param {mixed} obj the node to close recursively, omit to close all nodes in the tree + * @param {Number} animation the animation duration in milliseconds when closing the nodes, the default is no animation + * @trigger close_all.jstree + */ + close_all : function (obj, animation) { + if(!obj) { obj = $.jstree.root; } + obj = this.get_node(obj); + if(!obj) { return false; } + var dom = obj.id === $.jstree.root ? this.get_container_ul() : this.get_node(obj, true), + _this = this, i, j; + if(dom.length) { + dom = this.is_open(obj) ? dom.find('.jstree-open').addBack() : dom.find('.jstree-open'); + $(dom.get().reverse()).each(function () { _this.close_node(this, animation || 0); }); + } + for(i = 0, j = obj.children_d.length; i < j; i++) { + this._model.data[obj.children_d[i]].state.opened = false; + } + /** + * triggered when an `close_all` call completes + * @event + * @name close_all.jstree + * @param {Object} node the closed node + */ + this.trigger('close_all', { "node" : obj }); + }, + /** + * checks if a node is disabled (not selectable) + * @name is_disabled(obj) + * @param {mixed} obj + * @return {Boolean} + */ + is_disabled : function (obj) { + obj = this.get_node(obj); + return obj && obj.state && obj.state.disabled; + }, + /** + * enables a node - so that it can be selected + * @name enable_node(obj) + * @param {mixed} obj the node to enable + * @trigger enable_node.jstree + */ + enable_node : function (obj) { + var t1, t2; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.enable_node(obj[t1]); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { + return false; + } + obj.state.disabled = false; + this.get_node(obj,true).children('.jstree-anchor').removeClass('jstree-disabled').attr('aria-disabled', false); + /** + * triggered when an node is enabled + * @event + * @name enable_node.jstree + * @param {Object} node the enabled node + */ + this.trigger('enable_node', { 'node' : obj }); + }, + /** + * disables a node - so that it can not be selected + * @name disable_node(obj) + * @param {mixed} obj the node to disable + * @trigger disable_node.jstree + */ + disable_node : function (obj) { + var t1, t2; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.disable_node(obj[t1]); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { + return false; + } + obj.state.disabled = true; + this.get_node(obj,true).children('.jstree-anchor').addClass('jstree-disabled').attr('aria-disabled', true); + /** + * triggered when an node is disabled + * @event + * @name disable_node.jstree + * @param {Object} node the disabled node + */ + this.trigger('disable_node', { 'node' : obj }); + }, + /** + * determines if a node is hidden + * @name is_hidden(obj) + * @param {mixed} obj the node + */ + is_hidden : function (obj) { + obj = this.get_node(obj); + return obj.state.hidden === true; + }, + /** + * hides a node - it is still in the structure but will not be visible + * @name hide_node(obj) + * @param {mixed} obj the node to hide + * @param {Boolean} skip_redraw internal parameter controlling if redraw is called + * @trigger hide_node.jstree + */ + hide_node : function (obj, skip_redraw) { + var t1, t2; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.hide_node(obj[t1], true); + } + if (!skip_redraw) { + this.redraw(); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { + return false; + } + if(!obj.state.hidden) { + obj.state.hidden = true; + this._node_changed(obj.parent); + if(!skip_redraw) { + this.redraw(); + } + /** + * triggered when an node is hidden + * @event + * @name hide_node.jstree + * @param {Object} node the hidden node + */ + this.trigger('hide_node', { 'node' : obj }); + } + }, + /** + * shows a node + * @name show_node(obj) + * @param {mixed} obj the node to show + * @param {Boolean} skip_redraw internal parameter controlling if redraw is called + * @trigger show_node.jstree + */ + show_node : function (obj, skip_redraw) { + var t1, t2; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.show_node(obj[t1], true); + } + if (!skip_redraw) { + this.redraw(); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { + return false; + } + if(obj.state.hidden) { + obj.state.hidden = false; + this._node_changed(obj.parent); + if(!skip_redraw) { + this.redraw(); + } + /** + * triggered when an node is shown + * @event + * @name show_node.jstree + * @param {Object} node the shown node + */ + this.trigger('show_node', { 'node' : obj }); + } + }, + /** + * hides all nodes + * @name hide_all() + * @trigger hide_all.jstree + */ + hide_all : function (skip_redraw) { + var i, m = this._model.data, ids = []; + for(i in m) { + if(m.hasOwnProperty(i) && i !== $.jstree.root && !m[i].state.hidden) { + m[i].state.hidden = true; + ids.push(i); + } + } + this._model.force_full_redraw = true; + if(!skip_redraw) { + this.redraw(); + } + /** + * triggered when all nodes are hidden + * @event + * @name hide_all.jstree + * @param {Array} nodes the IDs of all hidden nodes + */ + this.trigger('hide_all', { 'nodes' : ids }); + return ids; + }, + /** + * shows all nodes + * @name show_all() + * @trigger show_all.jstree + */ + show_all : function (skip_redraw) { + var i, m = this._model.data, ids = []; + for(i in m) { + if(m.hasOwnProperty(i) && i !== $.jstree.root && m[i].state.hidden) { + m[i].state.hidden = false; + ids.push(i); + } + } + this._model.force_full_redraw = true; + if(!skip_redraw) { + this.redraw(); + } + /** + * triggered when all nodes are shown + * @event + * @name show_all.jstree + * @param {Array} nodes the IDs of all shown nodes + */ + this.trigger('show_all', { 'nodes' : ids }); + return ids; + }, + /** + * called when a node is selected by the user. Used internally. + * @private + * @name activate_node(obj, e) + * @param {mixed} obj the node + * @param {Object} e the related event + * @trigger activate_node.jstree, changed.jstree + */ + activate_node : function (obj, e) { + if(this.is_disabled(obj)) { + return false; + } + if(!e || typeof e !== 'object') { + e = {}; + } + + // ensure last_clicked is still in the DOM, make it fresh (maybe it was moved?) and make sure it is still selected, if not - make last_clicked the last selected node + this._data.core.last_clicked = this._data.core.last_clicked && this._data.core.last_clicked.id !== undefined ? this.get_node(this._data.core.last_clicked.id) : null; + if(this._data.core.last_clicked && !this._data.core.last_clicked.state.selected) { this._data.core.last_clicked = null; } + if(!this._data.core.last_clicked && this._data.core.selected.length) { this._data.core.last_clicked = this.get_node(this._data.core.selected[this._data.core.selected.length - 1]); } + + if(!this.settings.core.multiple || (!e.metaKey && !e.ctrlKey && !e.shiftKey) || (e.shiftKey && (!this._data.core.last_clicked || !this.get_parent(obj) || this.get_parent(obj) !== this._data.core.last_clicked.parent ) )) { + if(!this.settings.core.multiple && (e.metaKey || e.ctrlKey || e.shiftKey) && this.is_selected(obj)) { + this.deselect_node(obj, false, e); + } + else { + this.deselect_all(true); + this.select_node(obj, false, false, e); + this._data.core.last_clicked = this.get_node(obj); + } + } + else { + if(e.shiftKey) { + var o = this.get_node(obj).id, + l = this._data.core.last_clicked.id, + p = this.get_node(this._data.core.last_clicked.parent).children, + c = false, + i, j; + for(i = 0, j = p.length; i < j; i += 1) { + // separate IFs work whem o and l are the same + if(p[i] === o) { + c = !c; + } + if(p[i] === l) { + c = !c; + } + if(!this.is_disabled(p[i]) && (c || p[i] === o || p[i] === l)) { + if (!this.is_hidden(p[i])) { + this.select_node(p[i], true, false, e); + } + } + else { + this.deselect_node(p[i], true, e); + } + } + this.trigger('changed', { 'action' : 'select_node', 'node' : this.get_node(obj), 'selected' : this._data.core.selected, 'event' : e }); + } + else { + if(!this.is_selected(obj)) { + this.select_node(obj, false, false, e); + } + else { + this.deselect_node(obj, false, e); + } + } + } + /** + * triggered when an node is clicked or intercated with by the user + * @event + * @name activate_node.jstree + * @param {Object} node + * @param {Object} event the ooriginal event (if any) which triggered the call (may be an empty object) + */ + this.trigger('activate_node', { 'node' : this.get_node(obj), 'event' : e }); + }, + /** + * applies the hover state on a node, called when a node is hovered by the user. Used internally. + * @private + * @name hover_node(obj) + * @param {mixed} obj + * @trigger hover_node.jstree + */ + hover_node : function (obj) { + obj = this.get_node(obj, true); + if(!obj || !obj.length || obj.children('.jstree-hovered').length) { + return false; + } + var o = this.element.find('.jstree-hovered'), t = this.element; + if(o && o.length) { this.dehover_node(o); } + + obj.children('.jstree-anchor').addClass('jstree-hovered'); + /** + * triggered when an node is hovered + * @event + * @name hover_node.jstree + * @param {Object} node + */ + this.trigger('hover_node', { 'node' : this.get_node(obj) }); + setTimeout(function () { t.attr('aria-activedescendant', obj[0].id); }, 0); + }, + /** + * removes the hover state from a nodecalled when a node is no longer hovered by the user. Used internally. + * @private + * @name dehover_node(obj) + * @param {mixed} obj + * @trigger dehover_node.jstree + */ + dehover_node : function (obj) { + obj = this.get_node(obj, true); + if(!obj || !obj.length || !obj.children('.jstree-hovered').length) { + return false; + } + obj.children('.jstree-anchor').removeClass('jstree-hovered'); + /** + * triggered when an node is no longer hovered + * @event + * @name dehover_node.jstree + * @param {Object} node + */ + this.trigger('dehover_node', { 'node' : this.get_node(obj) }); + }, + /** + * select a node + * @name select_node(obj [, supress_event, prevent_open]) + * @param {mixed} obj an array can be used to select multiple nodes + * @param {Boolean} supress_event if set to `true` the `changed.jstree` event won't be triggered + * @param {Boolean} prevent_open if set to `true` parents of the selected node won't be opened + * @trigger select_node.jstree, changed.jstree + */ + select_node : function (obj, supress_event, prevent_open, e) { + var dom, t1, t2, th; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.select_node(obj[t1], supress_event, prevent_open, e); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { + return false; + } + dom = this.get_node(obj, true); + if(!obj.state.selected) { + obj.state.selected = true; + this._data.core.selected.push(obj.id); + if(!prevent_open) { + dom = this._open_to(obj); + } + if(dom && dom.length) { + dom.attr('aria-selected', true).children('.jstree-anchor').addClass('jstree-clicked'); + } + /** + * triggered when an node is selected + * @event + * @name select_node.jstree + * @param {Object} node + * @param {Array} selected the current selection + * @param {Object} event the event (if any) that triggered this select_node + */ + this.trigger('select_node', { 'node' : obj, 'selected' : this._data.core.selected, 'event' : e }); + if(!supress_event) { + /** + * triggered when selection changes + * @event + * @name changed.jstree + * @param {Object} node + * @param {Object} action the action that caused the selection to change + * @param {Array} selected the current selection + * @param {Object} event the event (if any) that triggered this changed event + */ + this.trigger('changed', { 'action' : 'select_node', 'node' : obj, 'selected' : this._data.core.selected, 'event' : e }); + } + } + }, + /** + * deselect a node + * @name deselect_node(obj [, supress_event]) + * @param {mixed} obj an array can be used to deselect multiple nodes + * @param {Boolean} supress_event if set to `true` the `changed.jstree` event won't be triggered + * @trigger deselect_node.jstree, changed.jstree + */ + deselect_node : function (obj, supress_event, e) { + var t1, t2, dom; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.deselect_node(obj[t1], supress_event, e); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { + return false; + } + dom = this.get_node(obj, true); + if(obj.state.selected) { + obj.state.selected = false; + this._data.core.selected = $.vakata.array_remove_item(this._data.core.selected, obj.id); + if(dom.length) { + dom.attr('aria-selected', false).children('.jstree-anchor').removeClass('jstree-clicked'); + } + /** + * triggered when an node is deselected + * @event + * @name deselect_node.jstree + * @param {Object} node + * @param {Array} selected the current selection + * @param {Object} event the event (if any) that triggered this deselect_node + */ + this.trigger('deselect_node', { 'node' : obj, 'selected' : this._data.core.selected, 'event' : e }); + if(!supress_event) { + this.trigger('changed', { 'action' : 'deselect_node', 'node' : obj, 'selected' : this._data.core.selected, 'event' : e }); + } + } + }, + /** + * select all nodes in the tree + * @name select_all([supress_event]) + * @param {Boolean} supress_event if set to `true` the `changed.jstree` event won't be triggered + * @trigger select_all.jstree, changed.jstree + */ + select_all : function (supress_event) { + var tmp = this._data.core.selected.concat([]), i, j; + this._data.core.selected = this._model.data[$.jstree.root].children_d.concat(); + for(i = 0, j = this._data.core.selected.length; i < j; i++) { + if(this._model.data[this._data.core.selected[i]]) { + this._model.data[this._data.core.selected[i]].state.selected = true; + } + } + this.redraw(true); + /** + * triggered when all nodes are selected + * @event + * @name select_all.jstree + * @param {Array} selected the current selection + */ + this.trigger('select_all', { 'selected' : this._data.core.selected }); + if(!supress_event) { + this.trigger('changed', { 'action' : 'select_all', 'selected' : this._data.core.selected, 'old_selection' : tmp }); + } + }, + /** + * deselect all selected nodes + * @name deselect_all([supress_event]) + * @param {Boolean} supress_event if set to `true` the `changed.jstree` event won't be triggered + * @trigger deselect_all.jstree, changed.jstree + */ + deselect_all : function (supress_event) { + var tmp = this._data.core.selected.concat([]), i, j; + for(i = 0, j = this._data.core.selected.length; i < j; i++) { + if(this._model.data[this._data.core.selected[i]]) { + this._model.data[this._data.core.selected[i]].state.selected = false; + } + } + this._data.core.selected = []; + this.element.find('.jstree-clicked').removeClass('jstree-clicked').parent().attr('aria-selected', false); + /** + * triggered when all nodes are deselected + * @event + * @name deselect_all.jstree + * @param {Object} node the previous selection + * @param {Array} selected the current selection + */ + this.trigger('deselect_all', { 'selected' : this._data.core.selected, 'node' : tmp }); + if(!supress_event) { + this.trigger('changed', { 'action' : 'deselect_all', 'selected' : this._data.core.selected, 'old_selection' : tmp }); + } + }, + /** + * checks if a node is selected + * @name is_selected(obj) + * @param {mixed} obj + * @return {Boolean} + */ + is_selected : function (obj) { + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { + return false; + } + return obj.state.selected; + }, + /** + * get an array of all selected nodes + * @name get_selected([full]) + * @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned + * @return {Array} + */ + get_selected : function (full) { + return full ? $.map(this._data.core.selected, $.proxy(function (i) { return this.get_node(i); }, this)) : this._data.core.selected.slice(); + }, + /** + * get an array of all top level selected nodes (ignoring children of selected nodes) + * @name get_top_selected([full]) + * @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned + * @return {Array} + */ + get_top_selected : function (full) { + var tmp = this.get_selected(true), + obj = {}, i, j, k, l; + for(i = 0, j = tmp.length; i < j; i++) { + obj[tmp[i].id] = tmp[i]; + } + for(i = 0, j = tmp.length; i < j; i++) { + for(k = 0, l = tmp[i].children_d.length; k < l; k++) { + if(obj[tmp[i].children_d[k]]) { + delete obj[tmp[i].children_d[k]]; + } + } + } + tmp = []; + for(i in obj) { + if(obj.hasOwnProperty(i)) { + tmp.push(i); + } + } + return full ? $.map(tmp, $.proxy(function (i) { return this.get_node(i); }, this)) : tmp; + }, + /** + * get an array of all bottom level selected nodes (ignoring selected parents) + * @name get_bottom_selected([full]) + * @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned + * @return {Array} + */ + get_bottom_selected : function (full) { + var tmp = this.get_selected(true), + obj = [], i, j; + for(i = 0, j = tmp.length; i < j; i++) { + if(!tmp[i].children.length) { + obj.push(tmp[i].id); + } + } + return full ? $.map(obj, $.proxy(function (i) { return this.get_node(i); }, this)) : obj; + }, + /** + * gets the current state of the tree so that it can be restored later with `set_state(state)`. Used internally. + * @name get_state() + * @private + * @return {Object} + */ + get_state : function () { + var state = { + 'core' : { + 'open' : [], + 'scroll' : { + 'left' : this.element.scrollLeft(), + 'top' : this.element.scrollTop() + }, + /*! + 'themes' : { + 'name' : this.get_theme(), + 'icons' : this._data.core.themes.icons, + 'dots' : this._data.core.themes.dots + }, + */ + 'selected' : [] + } + }, i; + for(i in this._model.data) { + if(this._model.data.hasOwnProperty(i)) { + if(i !== $.jstree.root) { + if(this._model.data[i].state.opened) { + state.core.open.push(i); + } + if(this._model.data[i].state.selected) { + state.core.selected.push(i); + } + } + } + } + return state; + }, + /** + * sets the state of the tree. Used internally. + * @name set_state(state [, callback]) + * @private + * @param {Object} state the state to restore. Keep in mind this object is passed by reference and jstree will modify it. + * @param {Function} callback an optional function to execute once the state is restored. + * @trigger set_state.jstree + */ + set_state : function (state, callback) { + if(state) { + if(state.core) { + var res, n, t, _this, i; + if(state.core.open) { + if(!$.isArray(state.core.open) || !state.core.open.length) { + delete state.core.open; + this.set_state(state, callback); + } + else { + this._load_nodes(state.core.open, function (nodes) { + this.open_node(nodes, false, 0); + delete state.core.open; + this.set_state(state, callback); + }); + } + return false; + } + if(state.core.scroll) { + if(state.core.scroll && state.core.scroll.left !== undefined) { + this.element.scrollLeft(state.core.scroll.left); + } + if(state.core.scroll && state.core.scroll.top !== undefined) { + this.element.scrollTop(state.core.scroll.top); + } + delete state.core.scroll; + this.set_state(state, callback); + return false; + } + if(state.core.selected) { + _this = this; + this.deselect_all(); + $.each(state.core.selected, function (i, v) { + _this.select_node(v, false, true); + }); + delete state.core.selected; + this.set_state(state, callback); + return false; + } + for(i in state) { + if(state.hasOwnProperty(i) && i !== "core" && $.inArray(i, this.settings.plugins) === -1) { + delete state[i]; + } + } + if($.isEmptyObject(state.core)) { + delete state.core; + this.set_state(state, callback); + return false; + } + } + if($.isEmptyObject(state)) { + state = null; + if(callback) { callback.call(this); } + /** + * triggered when a `set_state` call completes + * @event + * @name set_state.jstree + */ + this.trigger('set_state'); + return false; + } + return true; + } + return false; + }, + /** + * refreshes the tree - all nodes are reloaded with calls to `load_node`. + * @name refresh() + * @param {Boolean} skip_loading an option to skip showing the loading indicator + * @param {Mixed} forget_state if set to `true` state will not be reapplied, if set to a function (receiving the current state as argument) the result of that function will be used as state + * @trigger refresh.jstree + */ + refresh : function (skip_loading, forget_state) { + this._data.core.state = forget_state === true ? {} : this.get_state(); + if(forget_state && $.isFunction(forget_state)) { this._data.core.state = forget_state.call(this, this._data.core.state); } + this._cnt = 0; + this._model.data = {}; + this._model.data[$.jstree.root] = { + id : $.jstree.root, + parent : null, + parents : [], + children : [], + children_d : [], + state : { loaded : false } + }; + this._data.core.selected = []; + this._data.core.last_clicked = null; + this._data.core.focused = null; + + var c = this.get_container_ul()[0].className; + if(!skip_loading) { + this.element.html("<"+"ul class='"+c+"' role='group'><"+"li class='jstree-initial-node jstree-loading jstree-leaf jstree-last' role='treeitem' id='j"+this._id+"_loading'><i class='jstree-icon jstree-ocl'></i><"+"a class='jstree-anchor' href='#'><i class='jstree-icon jstree-themeicon-hidden'></i>" + this.get_string("Loading ...") + "</a></li></ul>"); + this.element.attr('aria-activedescendant','j'+this._id+'_loading'); + } + this.load_node($.jstree.root, function (o, s) { + if(s) { + this.get_container_ul()[0].className = c; + if(this._firstChild(this.get_container_ul()[0])) { + this.element.attr('aria-activedescendant',this._firstChild(this.get_container_ul()[0]).id); + } + this.set_state($.extend(true, {}, this._data.core.state), function () { + /** + * triggered when a `refresh` call completes + * @event + * @name refresh.jstree + */ + this.trigger('refresh'); + }); + } + this._data.core.state = null; + }); + }, + /** + * refreshes a node in the tree (reload its children) all opened nodes inside that node are reloaded with calls to `load_node`. + * @name refresh_node(obj) + * @param {mixed} obj the node + * @trigger refresh_node.jstree + */ + refresh_node : function (obj) { + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { return false; } + var opened = [], to_load = [], s = this._data.core.selected.concat([]); + to_load.push(obj.id); + if(obj.state.opened === true) { opened.push(obj.id); } + this.get_node(obj, true).find('.jstree-open').each(function() { to_load.push(this.id); opened.push(this.id); }); + this._load_nodes(to_load, $.proxy(function (nodes) { + this.open_node(opened, false, 0); + this.select_node(s); + /** + * triggered when a node is refreshed + * @event + * @name refresh_node.jstree + * @param {Object} node - the refreshed node + * @param {Array} nodes - an array of the IDs of the nodes that were reloaded + */ + this.trigger('refresh_node', { 'node' : obj, 'nodes' : nodes }); + }, this), false, true); + }, + /** + * set (change) the ID of a node + * @name set_id(obj, id) + * @param {mixed} obj the node + * @param {String} id the new ID + * @return {Boolean} + * @trigger set_id.jstree + */ + set_id : function (obj, id) { + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { return false; } + var i, j, m = this._model.data, old = obj.id; + id = id.toString(); + // update parents (replace current ID with new one in children and children_d) + m[obj.parent].children[$.inArray(obj.id, m[obj.parent].children)] = id; + for(i = 0, j = obj.parents.length; i < j; i++) { + m[obj.parents[i]].children_d[$.inArray(obj.id, m[obj.parents[i]].children_d)] = id; + } + // update children (replace current ID with new one in parent and parents) + for(i = 0, j = obj.children.length; i < j; i++) { + m[obj.children[i]].parent = id; + } + for(i = 0, j = obj.children_d.length; i < j; i++) { + m[obj.children_d[i]].parents[$.inArray(obj.id, m[obj.children_d[i]].parents)] = id; + } + i = $.inArray(obj.id, this._data.core.selected); + if(i !== -1) { this._data.core.selected[i] = id; } + // update model and obj itself (obj.id, this._model.data[KEY]) + i = this.get_node(obj.id, true); + if(i) { + i.attr('id', id); //.children('.jstree-anchor').attr('id', id + '_anchor').end().attr('aria-labelledby', id + '_anchor'); + if(this.element.attr('aria-activedescendant') === obj.id) { + this.element.attr('aria-activedescendant', id); + } + } + delete m[obj.id]; + obj.id = id; + obj.li_attr.id = id; + m[id] = obj; + /** + * triggered when a node id value is changed + * @event + * @name set_id.jstree + * @param {Object} node + * @param {String} old the old id + */ + this.trigger('set_id',{ "node" : obj, "new" : obj.id, "old" : old }); + return true; + }, + /** + * get the text value of a node + * @name get_text(obj) + * @param {mixed} obj the node + * @return {String} + */ + get_text : function (obj) { + obj = this.get_node(obj); + return (!obj || obj.id === $.jstree.root) ? false : obj.text; + }, + /** + * set the text value of a node. Used internally, please use `rename_node(obj, val)`. + * @private + * @name set_text(obj, val) + * @param {mixed} obj the node, you can pass an array to set the text on multiple nodes + * @param {String} val the new text value + * @return {Boolean} + * @trigger set_text.jstree + */ + set_text : function (obj, val) { + var t1, t2; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.set_text(obj[t1], val); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { return false; } + obj.text = val; + if(this.get_node(obj, true).length) { + this.redraw_node(obj.id); + } + /** + * triggered when a node text value is changed + * @event + * @name set_text.jstree + * @param {Object} obj + * @param {String} text the new value + */ + this.trigger('set_text',{ "obj" : obj, "text" : val }); + return true; + }, + /** + * gets a JSON representation of a node (or the whole tree) + * @name get_json([obj, options]) + * @param {mixed} obj + * @param {Object} options + * @param {Boolean} options.no_state do not return state information + * @param {Boolean} options.no_id do not return ID + * @param {Boolean} options.no_children do not include children + * @param {Boolean} options.no_data do not include node data + * @param {Boolean} options.no_li_attr do not include LI attributes + * @param {Boolean} options.no_a_attr do not include A attributes + * @param {Boolean} options.flat return flat JSON instead of nested + * @return {Object} + */ + get_json : function (obj, options, flat) { + obj = this.get_node(obj || $.jstree.root); + if(!obj) { return false; } + if(options && options.flat && !flat) { flat = []; } + var tmp = { + 'id' : obj.id, + 'text' : obj.text, + 'icon' : this.get_icon(obj), + 'li_attr' : $.extend(true, {}, obj.li_attr), + 'a_attr' : $.extend(true, {}, obj.a_attr), + 'state' : {}, + 'data' : options && options.no_data ? false : $.extend(true, {}, obj.data) + //( this.get_node(obj, true).length ? this.get_node(obj, true).data() : obj.data ), + }, i, j; + if(options && options.flat) { + tmp.parent = obj.parent; + } + else { + tmp.children = []; + } + if(!options || !options.no_state) { + for(i in obj.state) { + if(obj.state.hasOwnProperty(i)) { + tmp.state[i] = obj.state[i]; + } + } + } else { + delete tmp.state; + } + if(options && options.no_li_attr) { + delete tmp.li_attr; + } + if(options && options.no_a_attr) { + delete tmp.a_attr; + } + if(options && options.no_id) { + delete tmp.id; + if(tmp.li_attr && tmp.li_attr.id) { + delete tmp.li_attr.id; + } + if(tmp.a_attr && tmp.a_attr.id) { + delete tmp.a_attr.id; + } + } + if(options && options.flat && obj.id !== $.jstree.root) { + flat.push(tmp); + } + if(!options || !options.no_children) { + for(i = 0, j = obj.children.length; i < j; i++) { + if(options && options.flat) { + this.get_json(obj.children[i], options, flat); + } + else { + tmp.children.push(this.get_json(obj.children[i], options)); + } + } + } + return options && options.flat ? flat : (obj.id === $.jstree.root ? tmp.children : tmp); + }, + /** + * create a new node (do not confuse with load_node) + * @name create_node([par, node, pos, callback, is_loaded]) + * @param {mixed} par the parent node (to create a root node use either "#" (string) or `null`) + * @param {mixed} node the data for the new node (a valid JSON object, or a simple string with the name) + * @param {mixed} pos the index at which to insert the node, "first" and "last" are also supported, default is "last" + * @param {Function} callback a function to be called once the node is created + * @param {Boolean} is_loaded internal argument indicating if the parent node was succesfully loaded + * @return {String} the ID of the newly create node + * @trigger model.jstree, create_node.jstree + */ + create_node : function (par, node, pos, callback, is_loaded) { + if(par === null) { par = $.jstree.root; } + par = this.get_node(par); + if(!par) { return false; } + pos = pos === undefined ? "last" : pos; + if(!pos.toString().match(/^(before|after)$/) && !is_loaded && !this.is_loaded(par)) { + return this.load_node(par, function () { this.create_node(par, node, pos, callback, true); }); + } + if(!node) { node = { "text" : this.get_string('New node') }; } + if(typeof node === "string") { node = { "text" : node }; } + if(node.text === undefined) { node.text = this.get_string('New node'); } + var tmp, dpc, i, j; + + if(par.id === $.jstree.root) { + if(pos === "before") { pos = "first"; } + if(pos === "after") { pos = "last"; } + } + switch(pos) { + case "before": + tmp = this.get_node(par.parent); + pos = $.inArray(par.id, tmp.children); + par = tmp; + break; + case "after" : + tmp = this.get_node(par.parent); + pos = $.inArray(par.id, tmp.children) + 1; + par = tmp; + break; + case "inside": + case "first": + pos = 0; + break; + case "last": + pos = par.children.length; + break; + default: + if(!pos) { pos = 0; } + break; + } + if(pos > par.children.length) { pos = par.children.length; } + if(!node.id) { node.id = true; } + if(!this.check("create_node", node, par, pos)) { + this.settings.core.error.call(this, this._data.core.last_error); + return false; + } + if(node.id === true) { delete node.id; } + node = this._parse_model_from_json(node, par.id, par.parents.concat()); + if(!node) { return false; } + tmp = this.get_node(node); + dpc = []; + dpc.push(node); + dpc = dpc.concat(tmp.children_d); + this.trigger('model', { "nodes" : dpc, "parent" : par.id }); + + par.children_d = par.children_d.concat(dpc); + for(i = 0, j = par.parents.length; i < j; i++) { + this._model.data[par.parents[i]].children_d = this._model.data[par.parents[i]].children_d.concat(dpc); + } + node = tmp; + tmp = []; + for(i = 0, j = par.children.length; i < j; i++) { + tmp[i >= pos ? i+1 : i] = par.children[i]; + } + tmp[pos] = node.id; + par.children = tmp; + + this.redraw_node(par, true); + if(callback) { callback.call(this, this.get_node(node)); } + /** + * triggered when a node is created + * @event + * @name create_node.jstree + * @param {Object} node + * @param {String} parent the parent's ID + * @param {Number} position the position of the new node among the parent's children + */ + this.trigger('create_node', { "node" : this.get_node(node), "parent" : par.id, "position" : pos }); + return node.id; + }, + /** + * set the text value of a node + * @name rename_node(obj, val) + * @param {mixed} obj the node, you can pass an array to rename multiple nodes to the same name + * @param {String} val the new text value + * @return {Boolean} + * @trigger rename_node.jstree + */ + rename_node : function (obj, val) { + var t1, t2, old; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.rename_node(obj[t1], val); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { return false; } + old = obj.text; + if(!this.check("rename_node", obj, this.get_parent(obj), val)) { + this.settings.core.error.call(this, this._data.core.last_error); + return false; + } + this.set_text(obj, val); // .apply(this, Array.prototype.slice.call(arguments)) + /** + * triggered when a node is renamed + * @event + * @name rename_node.jstree + * @param {Object} node + * @param {String} text the new value + * @param {String} old the old value + */ + this.trigger('rename_node', { "node" : obj, "text" : val, "old" : old }); + return true; + }, + /** + * remove a node + * @name delete_node(obj) + * @param {mixed} obj the node, you can pass an array to delete multiple nodes + * @return {Boolean} + * @trigger delete_node.jstree, changed.jstree + */ + delete_node : function (obj) { + var t1, t2, par, pos, tmp, i, j, k, l, c, top, lft; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.delete_node(obj[t1]); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { return false; } + par = this.get_node(obj.parent); + pos = $.inArray(obj.id, par.children); + c = false; + if(!this.check("delete_node", obj, par, pos)) { + this.settings.core.error.call(this, this._data.core.last_error); + return false; + } + if(pos !== -1) { + par.children = $.vakata.array_remove(par.children, pos); + } + tmp = obj.children_d.concat([]); + tmp.push(obj.id); + for(i = 0, j = obj.parents.length; i < j; i++) { + this._model.data[obj.parents[i]].children_d = $.vakata.array_filter(this._model.data[obj.parents[i]].children_d, function (v) { + return $.inArray(v, tmp) === -1; + }); + } + for(k = 0, l = tmp.length; k < l; k++) { + if(this._model.data[tmp[k]].state.selected) { + c = true; + break; + } + } + if (c) { + this._data.core.selected = $.vakata.array_filter(this._data.core.selected, function (v) { + return $.inArray(v, tmp) === -1; + }); + } + /** + * triggered when a node is deleted + * @event + * @name delete_node.jstree + * @param {Object} node + * @param {String} parent the parent's ID + */ + this.trigger('delete_node', { "node" : obj, "parent" : par.id }); + if(c) { + this.trigger('changed', { 'action' : 'delete_node', 'node' : obj, 'selected' : this._data.core.selected, 'parent' : par.id }); + } + for(k = 0, l = tmp.length; k < l; k++) { + delete this._model.data[tmp[k]]; + } + if($.inArray(this._data.core.focused, tmp) !== -1) { + this._data.core.focused = null; + top = this.element[0].scrollTop; + lft = this.element[0].scrollLeft; + if(par.id === $.jstree.root) { + if (this._model.data[$.jstree.root].children[0]) { + this.get_node(this._model.data[$.jstree.root].children[0], true).children('.jstree-anchor').focus(); + } + } + else { + this.get_node(par, true).children('.jstree-anchor').focus(); + } + this.element[0].scrollTop = top; + this.element[0].scrollLeft = lft; + } + this.redraw_node(par, true); + return true; + }, + /** + * check if an operation is premitted on the tree. Used internally. + * @private + * @name check(chk, obj, par, pos) + * @param {String} chk the operation to check, can be "create_node", "rename_node", "delete_node", "copy_node" or "move_node" + * @param {mixed} obj the node + * @param {mixed} par the parent + * @param {mixed} pos the position to insert at, or if "rename_node" - the new name + * @param {mixed} more some various additional information, for example if a "move_node" operations is triggered by DND this will be the hovered node + * @return {Boolean} + */ + check : function (chk, obj, par, pos, more) { + obj = obj && obj.id ? obj : this.get_node(obj); + par = par && par.id ? par : this.get_node(par); + var tmp = chk.match(/^move_node|copy_node|create_node$/i) ? par : obj, + chc = this.settings.core.check_callback; + if(chk === "move_node" || chk === "copy_node") { + if((!more || !more.is_multi) && (obj.id === par.id || (chk === "move_node" && $.inArray(obj.id, par.children) === pos) || $.inArray(par.id, obj.children_d) !== -1)) { + this._data.core.last_error = { 'error' : 'check', 'plugin' : 'core', 'id' : 'core_01', 'reason' : 'Moving parent inside child', 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) }; + return false; + } + } + if(tmp && tmp.data) { tmp = tmp.data; } + if(tmp && tmp.functions && (tmp.functions[chk] === false || tmp.functions[chk] === true)) { + if(tmp.functions[chk] === false) { + this._data.core.last_error = { 'error' : 'check', 'plugin' : 'core', 'id' : 'core_02', 'reason' : 'Node data prevents function: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) }; + } + return tmp.functions[chk]; + } + if(chc === false || ($.isFunction(chc) && chc.call(this, chk, obj, par, pos, more) === false) || (chc && chc[chk] === false)) { + this._data.core.last_error = { 'error' : 'check', 'plugin' : 'core', 'id' : 'core_03', 'reason' : 'User config for core.check_callback prevents function: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) }; + return false; + } + return true; + }, + /** + * get the last error + * @name last_error() + * @return {Object} + */ + last_error : function () { + return this._data.core.last_error; + }, + /** + * move a node to a new parent + * @name move_node(obj, par [, pos, callback, is_loaded]) + * @param {mixed} obj the node to move, pass an array to move multiple nodes + * @param {mixed} par the new parent + * @param {mixed} pos the position to insert at (besides integer values, "first" and "last" are supported, as well as "before" and "after"), defaults to integer `0` + * @param {function} callback a function to call once the move is completed, receives 3 arguments - the node, the new parent and the position + * @param {Boolean} is_loaded internal parameter indicating if the parent node has been loaded + * @param {Boolean} skip_redraw internal parameter indicating if the tree should be redrawn + * @param {Boolean} instance internal parameter indicating if the node comes from another instance + * @trigger move_node.jstree + */ + move_node : function (obj, par, pos, callback, is_loaded, skip_redraw, origin) { + var t1, t2, old_par, old_pos, new_par, old_ins, is_multi, dpc, tmp, i, j, k, l, p; + + par = this.get_node(par); + pos = pos === undefined ? 0 : pos; + if(!par) { return false; } + if(!pos.toString().match(/^(before|after)$/) && !is_loaded && !this.is_loaded(par)) { + return this.load_node(par, function () { this.move_node(obj, par, pos, callback, true, false, origin); }); + } + + if($.isArray(obj)) { + if(obj.length === 1) { + obj = obj[0]; + } + else { + //obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + if((tmp = this.move_node(obj[t1], par, pos, callback, is_loaded, false, origin))) { + par = tmp; + pos = "after"; + } + } + this.redraw(); + return true; + } + } + obj = obj && obj.id ? obj : this.get_node(obj); + + if(!obj || obj.id === $.jstree.root) { return false; } + + old_par = (obj.parent || $.jstree.root).toString(); + new_par = (!pos.toString().match(/^(before|after)$/) || par.id === $.jstree.root) ? par : this.get_node(par.parent); + old_ins = origin ? origin : (this._model.data[obj.id] ? this : $.jstree.reference(obj.id)); + is_multi = !old_ins || !old_ins._id || (this._id !== old_ins._id); + old_pos = old_ins && old_ins._id && old_par && old_ins._model.data[old_par] && old_ins._model.data[old_par].children ? $.inArray(obj.id, old_ins._model.data[old_par].children) : -1; + if(old_ins && old_ins._id) { + obj = old_ins._model.data[obj.id]; + } + + if(is_multi) { + if((tmp = this.copy_node(obj, par, pos, callback, is_loaded, false, origin))) { + if(old_ins) { old_ins.delete_node(obj); } + return tmp; + } + return false; + } + //var m = this._model.data; + if(par.id === $.jstree.root) { + if(pos === "before") { pos = "first"; } + if(pos === "after") { pos = "last"; } + } + switch(pos) { + case "before": + pos = $.inArray(par.id, new_par.children); + break; + case "after" : + pos = $.inArray(par.id, new_par.children) + 1; + break; + case "inside": + case "first": + pos = 0; + break; + case "last": + pos = new_par.children.length; + break; + default: + if(!pos) { pos = 0; } + break; + } + if(pos > new_par.children.length) { pos = new_par.children.length; } + if(!this.check("move_node", obj, new_par, pos, { 'core' : true, 'origin' : origin, 'is_multi' : (old_ins && old_ins._id && old_ins._id !== this._id), 'is_foreign' : (!old_ins || !old_ins._id) })) { + this.settings.core.error.call(this, this._data.core.last_error); + return false; + } + if(obj.parent === new_par.id) { + dpc = new_par.children.concat(); + tmp = $.inArray(obj.id, dpc); + if(tmp !== -1) { + dpc = $.vakata.array_remove(dpc, tmp); + if(pos > tmp) { pos--; } + } + tmp = []; + for(i = 0, j = dpc.length; i < j; i++) { + tmp[i >= pos ? i+1 : i] = dpc[i]; + } + tmp[pos] = obj.id; + new_par.children = tmp; + this._node_changed(new_par.id); + this.redraw(new_par.id === $.jstree.root); + } + else { + // clean old parent and up + tmp = obj.children_d.concat(); + tmp.push(obj.id); + for(i = 0, j = obj.parents.length; i < j; i++) { + dpc = []; + p = old_ins._model.data[obj.parents[i]].children_d; + for(k = 0, l = p.length; k < l; k++) { + if($.inArray(p[k], tmp) === -1) { + dpc.push(p[k]); + } + } + old_ins._model.data[obj.parents[i]].children_d = dpc; + } + old_ins._model.data[old_par].children = $.vakata.array_remove_item(old_ins._model.data[old_par].children, obj.id); + + // insert into new parent and up + for(i = 0, j = new_par.parents.length; i < j; i++) { + this._model.data[new_par.parents[i]].children_d = this._model.data[new_par.parents[i]].children_d.concat(tmp); + } + dpc = []; + for(i = 0, j = new_par.children.length; i < j; i++) { + dpc[i >= pos ? i+1 : i] = new_par.children[i]; + } + dpc[pos] = obj.id; + new_par.children = dpc; + new_par.children_d.push(obj.id); + new_par.children_d = new_par.children_d.concat(obj.children_d); + + // update object + obj.parent = new_par.id; + tmp = new_par.parents.concat(); + tmp.unshift(new_par.id); + p = obj.parents.length; + obj.parents = tmp; + + // update object children + tmp = tmp.concat(); + for(i = 0, j = obj.children_d.length; i < j; i++) { + this._model.data[obj.children_d[i]].parents = this._model.data[obj.children_d[i]].parents.slice(0,p*-1); + Array.prototype.push.apply(this._model.data[obj.children_d[i]].parents, tmp); + } + + if(old_par === $.jstree.root || new_par.id === $.jstree.root) { + this._model.force_full_redraw = true; + } + if(!this._model.force_full_redraw) { + this._node_changed(old_par); + this._node_changed(new_par.id); + } + if(!skip_redraw) { + this.redraw(); + } + } + if(callback) { callback.call(this, obj, new_par, pos); } + /** + * triggered when a node is moved + * @event + * @name move_node.jstree + * @param {Object} node + * @param {String} parent the parent's ID + * @param {Number} position the position of the node among the parent's children + * @param {String} old_parent the old parent of the node + * @param {Number} old_position the old position of the node + * @param {Boolean} is_multi do the node and new parent belong to different instances + * @param {jsTree} old_instance the instance the node came from + * @param {jsTree} new_instance the instance of the new parent + */ + this.trigger('move_node', { "node" : obj, "parent" : new_par.id, "position" : pos, "old_parent" : old_par, "old_position" : old_pos, 'is_multi' : (old_ins && old_ins._id && old_ins._id !== this._id), 'is_foreign' : (!old_ins || !old_ins._id), 'old_instance' : old_ins, 'new_instance' : this }); + return obj.id; + }, + /** + * copy a node to a new parent + * @name copy_node(obj, par [, pos, callback, is_loaded]) + * @param {mixed} obj the node to copy, pass an array to copy multiple nodes + * @param {mixed} par the new parent + * @param {mixed} pos the position to insert at (besides integer values, "first" and "last" are supported, as well as "before" and "after"), defaults to integer `0` + * @param {function} callback a function to call once the move is completed, receives 3 arguments - the node, the new parent and the position + * @param {Boolean} is_loaded internal parameter indicating if the parent node has been loaded + * @param {Boolean} skip_redraw internal parameter indicating if the tree should be redrawn + * @param {Boolean} instance internal parameter indicating if the node comes from another instance + * @trigger model.jstree copy_node.jstree + */ + copy_node : function (obj, par, pos, callback, is_loaded, skip_redraw, origin) { + var t1, t2, dpc, tmp, i, j, node, old_par, new_par, old_ins, is_multi; + + par = this.get_node(par); + pos = pos === undefined ? 0 : pos; + if(!par) { return false; } + if(!pos.toString().match(/^(before|after)$/) && !is_loaded && !this.is_loaded(par)) { + return this.load_node(par, function () { this.copy_node(obj, par, pos, callback, true, false, origin); }); + } + + if($.isArray(obj)) { + if(obj.length === 1) { + obj = obj[0]; + } + else { + //obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + if((tmp = this.copy_node(obj[t1], par, pos, callback, is_loaded, true, origin))) { + par = tmp; + pos = "after"; + } + } + this.redraw(); + return true; + } + } + obj = obj && obj.id ? obj : this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { return false; } + + old_par = (obj.parent || $.jstree.root).toString(); + new_par = (!pos.toString().match(/^(before|after)$/) || par.id === $.jstree.root) ? par : this.get_node(par.parent); + old_ins = origin ? origin : (this._model.data[obj.id] ? this : $.jstree.reference(obj.id)); + is_multi = !old_ins || !old_ins._id || (this._id !== old_ins._id); + + if(old_ins && old_ins._id) { + obj = old_ins._model.data[obj.id]; + } + + if(par.id === $.jstree.root) { + if(pos === "before") { pos = "first"; } + if(pos === "after") { pos = "last"; } + } + switch(pos) { + case "before": + pos = $.inArray(par.id, new_par.children); + break; + case "after" : + pos = $.inArray(par.id, new_par.children) + 1; + break; + case "inside": + case "first": + pos = 0; + break; + case "last": + pos = new_par.children.length; + break; + default: + if(!pos) { pos = 0; } + break; + } + if(pos > new_par.children.length) { pos = new_par.children.length; } + if(!this.check("copy_node", obj, new_par, pos, { 'core' : true, 'origin' : origin, 'is_multi' : (old_ins && old_ins._id && old_ins._id !== this._id), 'is_foreign' : (!old_ins || !old_ins._id) })) { + this.settings.core.error.call(this, this._data.core.last_error); + return false; + } + node = old_ins ? old_ins.get_json(obj, { no_id : true, no_data : true, no_state : true }) : obj; + if(!node) { return false; } + if(node.id === true) { delete node.id; } + node = this._parse_model_from_json(node, new_par.id, new_par.parents.concat()); + if(!node) { return false; } + tmp = this.get_node(node); + if(obj && obj.state && obj.state.loaded === false) { tmp.state.loaded = false; } + dpc = []; + dpc.push(node); + dpc = dpc.concat(tmp.children_d); + this.trigger('model', { "nodes" : dpc, "parent" : new_par.id }); + + // insert into new parent and up + for(i = 0, j = new_par.parents.length; i < j; i++) { + this._model.data[new_par.parents[i]].children_d = this._model.data[new_par.parents[i]].children_d.concat(dpc); + } + dpc = []; + for(i = 0, j = new_par.children.length; i < j; i++) { + dpc[i >= pos ? i+1 : i] = new_par.children[i]; + } + dpc[pos] = tmp.id; + new_par.children = dpc; + new_par.children_d.push(tmp.id); + new_par.children_d = new_par.children_d.concat(tmp.children_d); + + if(new_par.id === $.jstree.root) { + this._model.force_full_redraw = true; + } + if(!this._model.force_full_redraw) { + this._node_changed(new_par.id); + } + if(!skip_redraw) { + this.redraw(new_par.id === $.jstree.root); + } + if(callback) { callback.call(this, tmp, new_par, pos); } + /** + * triggered when a node is copied + * @event + * @name copy_node.jstree + * @param {Object} node the copied node + * @param {Object} original the original node + * @param {String} parent the parent's ID + * @param {Number} position the position of the node among the parent's children + * @param {String} old_parent the old parent of the node + * @param {Number} old_position the position of the original node + * @param {Boolean} is_multi do the node and new parent belong to different instances + * @param {jsTree} old_instance the instance the node came from + * @param {jsTree} new_instance the instance of the new parent + */ + this.trigger('copy_node', { "node" : tmp, "original" : obj, "parent" : new_par.id, "position" : pos, "old_parent" : old_par, "old_position" : old_ins && old_ins._id && old_par && old_ins._model.data[old_par] && old_ins._model.data[old_par].children ? $.inArray(obj.id, old_ins._model.data[old_par].children) : -1,'is_multi' : (old_ins && old_ins._id && old_ins._id !== this._id), 'is_foreign' : (!old_ins || !old_ins._id), 'old_instance' : old_ins, 'new_instance' : this }); + return tmp.id; + }, + /** + * cut a node (a later call to `paste(obj)` would move the node) + * @name cut(obj) + * @param {mixed} obj multiple objects can be passed using an array + * @trigger cut.jstree + */ + cut : function (obj) { + if(!obj) { obj = this._data.core.selected.concat(); } + if(!$.isArray(obj)) { obj = [obj]; } + if(!obj.length) { return false; } + var tmp = [], o, t1, t2; + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + o = this.get_node(obj[t1]); + if(o && o.id && o.id !== $.jstree.root) { tmp.push(o); } + } + if(!tmp.length) { return false; } + ccp_node = tmp; + ccp_inst = this; + ccp_mode = 'move_node'; + /** + * triggered when nodes are added to the buffer for moving + * @event + * @name cut.jstree + * @param {Array} node + */ + this.trigger('cut', { "node" : obj }); + }, + /** + * copy a node (a later call to `paste(obj)` would copy the node) + * @name copy(obj) + * @param {mixed} obj multiple objects can be passed using an array + * @trigger copy.jstree + */ + copy : function (obj) { + if(!obj) { obj = this._data.core.selected.concat(); } + if(!$.isArray(obj)) { obj = [obj]; } + if(!obj.length) { return false; } + var tmp = [], o, t1, t2; + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + o = this.get_node(obj[t1]); + if(o && o.id && o.id !== $.jstree.root) { tmp.push(o); } + } + if(!tmp.length) { return false; } + ccp_node = tmp; + ccp_inst = this; + ccp_mode = 'copy_node'; + /** + * triggered when nodes are added to the buffer for copying + * @event + * @name copy.jstree + * @param {Array} node + */ + this.trigger('copy', { "node" : obj }); + }, + /** + * get the current buffer (any nodes that are waiting for a paste operation) + * @name get_buffer() + * @return {Object} an object consisting of `mode` ("copy_node" or "move_node"), `node` (an array of objects) and `inst` (the instance) + */ + get_buffer : function () { + return { 'mode' : ccp_mode, 'node' : ccp_node, 'inst' : ccp_inst }; + }, + /** + * check if there is something in the buffer to paste + * @name can_paste() + * @return {Boolean} + */ + can_paste : function () { + return ccp_mode !== false && ccp_node !== false; // && ccp_inst._model.data[ccp_node]; + }, + /** + * copy or move the previously cut or copied nodes to a new parent + * @name paste(obj [, pos]) + * @param {mixed} obj the new parent + * @param {mixed} pos the position to insert at (besides integer, "first" and "last" are supported), defaults to integer `0` + * @trigger paste.jstree + */ + paste : function (obj, pos) { + obj = this.get_node(obj); + if(!obj || !ccp_mode || !ccp_mode.match(/^(copy_node|move_node)$/) || !ccp_node) { return false; } + if(this[ccp_mode](ccp_node, obj, pos, false, false, false, ccp_inst)) { + /** + * triggered when paste is invoked + * @event + * @name paste.jstree + * @param {String} parent the ID of the receiving node + * @param {Array} node the nodes in the buffer + * @param {String} mode the performed operation - "copy_node" or "move_node" + */ + this.trigger('paste', { "parent" : obj.id, "node" : ccp_node, "mode" : ccp_mode }); + } + ccp_node = false; + ccp_mode = false; + ccp_inst = false; + }, + /** + * clear the buffer of previously copied or cut nodes + * @name clear_buffer() + * @trigger clear_buffer.jstree + */ + clear_buffer : function () { + ccp_node = false; + ccp_mode = false; + ccp_inst = false; + /** + * triggered when the copy / cut buffer is cleared + * @event + * @name clear_buffer.jstree + */ + this.trigger('clear_buffer'); + }, + /** + * put a node in edit mode (input field to rename the node) + * @name edit(obj [, default_text, callback]) + * @param {mixed} obj + * @param {String} default_text the text to populate the input with (if omitted or set to a non-string value the node's text value is used) + * @param {Function} callback a function to be called once the text box is blurred, it is called in the instance's scope and receives the node, a status parameter (true if the rename is successful, false otherwise) and a boolean indicating if the user cancelled the edit. You can access the node's title using .text + */ + edit : function (obj, default_text, callback) { + var rtl, w, a, s, t, h1, h2, fn, tmp, cancel = false; + obj = this.get_node(obj); + if(!obj) { return false; } + if(this.settings.core.check_callback === false) { + this._data.core.last_error = { 'error' : 'check', 'plugin' : 'core', 'id' : 'core_07', 'reason' : 'Could not edit node because of check_callback' }; + this.settings.core.error.call(this, this._data.core.last_error); + return false; + } + tmp = obj; + default_text = typeof default_text === 'string' ? default_text : obj.text; + this.set_text(obj, ""); + obj = this._open_to(obj); + tmp.text = default_text; + + rtl = this._data.core.rtl; + w = this.element.width(); + this._data.core.focused = tmp.id; + a = obj.children('.jstree-anchor').focus(); + s = $('<span>'); + /*! + oi = obj.children("i:visible"), + ai = a.children("i:visible"), + w1 = oi.width() * oi.length, + w2 = ai.width() * ai.length, + */ + t = default_text; + h1 = $("<"+"div />", { css : { "position" : "absolute", "top" : "-200px", "left" : (rtl ? "0px" : "-1000px"), "visibility" : "hidden" } }).appendTo("body"); + h2 = $("<"+"input />", { + "value" : t, + "class" : "jstree-rename-input", + // "size" : t.length, + "css" : { + "padding" : "0", + "border" : "1px solid silver", + "box-sizing" : "border-box", + "display" : "inline-block", + "height" : (this._data.core.li_height) + "px", + "lineHeight" : (this._data.core.li_height) + "px", + "width" : "150px" // will be set a bit further down + }, + "blur" : $.proxy(function (e) { + e.stopImmediatePropagation(); + e.preventDefault(); + var i = s.children(".jstree-rename-input"), + v = i.val(), + f = this.settings.core.force_text, + nv; + if(v === "") { v = t; } + h1.remove(); + s.replaceWith(a); + s.remove(); + t = f ? t : $('<div></div>').append($.parseHTML(t)).html(); + this.set_text(obj, t); + nv = !!this.rename_node(obj, f ? $('<div></div>').text(v).text() : $('<div></div>').append($.parseHTML(v)).html()); + if(!nv) { + this.set_text(obj, t); // move this up? and fix #483 + } + this._data.core.focused = tmp.id; + setTimeout($.proxy(function () { + var node = this.get_node(tmp.id, true); + if(node.length) { + this._data.core.focused = tmp.id; + node.children('.jstree-anchor').focus(); + } + }, this), 0); + if(callback) { + callback.call(this, tmp, nv, cancel); + } + h2 = null; + }, this), + "keydown" : function (e) { + var key = e.which; + if(key === 27) { + cancel = true; + this.value = t; + } + if(key === 27 || key === 13 || key === 37 || key === 38 || key === 39 || key === 40 || key === 32) { + e.stopImmediatePropagation(); + } + if(key === 27 || key === 13) { + e.preventDefault(); + this.blur(); + } + }, + "click" : function (e) { e.stopImmediatePropagation(); }, + "mousedown" : function (e) { e.stopImmediatePropagation(); }, + "keyup" : function (e) { + h2.width(Math.min(h1.text("pW" + this.value).width(),w)); + }, + "keypress" : function(e) { + if(e.which === 13) { return false; } + } + }); + fn = { + fontFamily : a.css('fontFamily') || '', + fontSize : a.css('fontSize') || '', + fontWeight : a.css('fontWeight') || '', + fontStyle : a.css('fontStyle') || '', + fontStretch : a.css('fontStretch') || '', + fontVariant : a.css('fontVariant') || '', + letterSpacing : a.css('letterSpacing') || '', + wordSpacing : a.css('wordSpacing') || '' + }; + s.attr('class', a.attr('class')).append(a.contents().clone()).append(h2); + a.replaceWith(s); + h1.css(fn); + h2.css(fn).width(Math.min(h1.text("pW" + h2[0].value).width(),w))[0].select(); + $(document).one('mousedown.jstree touchstart.jstree dnd_start.vakata', function (e) { + if (h2 && e.target !== h2) { + $(h2).blur(); + } + }); + }, + + + /** + * changes the theme + * @name set_theme(theme_name [, theme_url]) + * @param {String} theme_name the name of the new theme to apply + * @param {mixed} theme_url the location of the CSS file for this theme. Omit or set to `false` if you manually included the file. Set to `true` to autoload from the `core.themes.dir` directory. + * @trigger set_theme.jstree + */ + set_theme : function (theme_name, theme_url) { + if(!theme_name) { return false; } + if(theme_url === true) { + var dir = this.settings.core.themes.dir; + if(!dir) { dir = $.jstree.path + '/themes'; } + theme_url = dir + '/' + theme_name + '/style.css'; + } + if(theme_url && $.inArray(theme_url, themes_loaded) === -1) { + $('head').append('<'+'link rel="stylesheet" href="' + theme_url + '" type="text/css" />'); + themes_loaded.push(theme_url); + } + if(this._data.core.themes.name) { + this.element.removeClass('jstree-' + this._data.core.themes.name); + } + this._data.core.themes.name = theme_name; + this.element.addClass('jstree-' + theme_name); + this.element[this.settings.core.themes.responsive ? 'addClass' : 'removeClass' ]('jstree-' + theme_name + '-responsive'); + /** + * triggered when a theme is set + * @event + * @name set_theme.jstree + * @param {String} theme the new theme + */ + this.trigger('set_theme', { 'theme' : theme_name }); + }, + /** + * gets the name of the currently applied theme name + * @name get_theme() + * @return {String} + */ + get_theme : function () { return this._data.core.themes.name; }, + /** + * changes the theme variant (if the theme has variants) + * @name set_theme_variant(variant_name) + * @param {String|Boolean} variant_name the variant to apply (if `false` is used the current variant is removed) + */ + set_theme_variant : function (variant_name) { + if(this._data.core.themes.variant) { + this.element.removeClass('jstree-' + this._data.core.themes.name + '-' + this._data.core.themes.variant); + } + this._data.core.themes.variant = variant_name; + if(variant_name) { + this.element.addClass('jstree-' + this._data.core.themes.name + '-' + this._data.core.themes.variant); + } + }, + /** + * gets the name of the currently applied theme variant + * @name get_theme() + * @return {String} + */ + get_theme_variant : function () { return this._data.core.themes.variant; }, + /** + * shows a striped background on the container (if the theme supports it) + * @name show_stripes() + */ + show_stripes : function () { + this._data.core.themes.stripes = true; + this.get_container_ul().addClass("jstree-striped"); + /** + * triggered when stripes are shown + * @event + * @name show_stripes.jstree + */ + this.trigger('show_stripes'); + }, + /** + * hides the striped background on the container + * @name hide_stripes() + */ + hide_stripes : function () { + this._data.core.themes.stripes = false; + this.get_container_ul().removeClass("jstree-striped"); + /** + * triggered when stripes are hidden + * @event + * @name hide_stripes.jstree + */ + this.trigger('hide_stripes'); + }, + /** + * toggles the striped background on the container + * @name toggle_stripes() + */ + toggle_stripes : function () { if(this._data.core.themes.stripes) { this.hide_stripes(); } else { this.show_stripes(); } }, + /** + * shows the connecting dots (if the theme supports it) + * @name show_dots() + */ + show_dots : function () { + this._data.core.themes.dots = true; + this.get_container_ul().removeClass("jstree-no-dots"); + /** + * triggered when dots are shown + * @event + * @name show_dots.jstree + */ + this.trigger('show_dots'); + }, + /** + * hides the connecting dots + * @name hide_dots() + */ + hide_dots : function () { + this._data.core.themes.dots = false; + this.get_container_ul().addClass("jstree-no-dots"); + /** + * triggered when dots are hidden + * @event + * @name hide_dots.jstree + */ + this.trigger('hide_dots'); + }, + /** + * toggles the connecting dots + * @name toggle_dots() + */ + toggle_dots : function () { if(this._data.core.themes.dots) { this.hide_dots(); } else { this.show_dots(); } }, + /** + * show the node icons + * @name show_icons() + */ + show_icons : function () { + this._data.core.themes.icons = true; + this.get_container_ul().removeClass("jstree-no-icons"); + /** + * triggered when icons are shown + * @event + * @name show_icons.jstree + */ + this.trigger('show_icons'); + }, + /** + * hide the node icons + * @name hide_icons() + */ + hide_icons : function () { + this._data.core.themes.icons = false; + this.get_container_ul().addClass("jstree-no-icons"); + /** + * triggered when icons are hidden + * @event + * @name hide_icons.jstree + */ + this.trigger('hide_icons'); + }, + /** + * toggle the node icons + * @name toggle_icons() + */ + toggle_icons : function () { if(this._data.core.themes.icons) { this.hide_icons(); } else { this.show_icons(); } }, + /** + * show the node ellipsis + * @name show_icons() + */ + show_ellipsis : function () { + this._data.core.themes.ellipsis = true; + this.get_container_ul().addClass("jstree-ellipsis"); + /** + * triggered when ellisis is shown + * @event + * @name show_ellipsis.jstree + */ + this.trigger('show_ellipsis'); + }, + /** + * hide the node ellipsis + * @name hide_ellipsis() + */ + hide_ellipsis : function () { + this._data.core.themes.ellipsis = false; + this.get_container_ul().removeClass("jstree-ellipsis"); + /** + * triggered when ellisis is hidden + * @event + * @name hide_ellipsis.jstree + */ + this.trigger('hide_ellipsis'); + }, + /** + * toggle the node ellipsis + * @name toggle_icons() + */ + toggle_ellipsis : function () { if(this._data.core.themes.ellipsis) { this.hide_ellipsis(); } else { this.show_ellipsis(); } }, + /** + * set the node icon for a node + * @name set_icon(obj, icon) + * @param {mixed} obj + * @param {String} icon the new icon - can be a path to an icon or a className, if using an image that is in the current directory use a `./` prefix, otherwise it will be detected as a class + */ + set_icon : function (obj, icon) { + var t1, t2, dom, old; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.set_icon(obj[t1], icon); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { return false; } + old = obj.icon; + obj.icon = icon === true || icon === null || icon === undefined || icon === '' ? true : icon; + dom = this.get_node(obj, true).children(".jstree-anchor").children(".jstree-themeicon"); + if(icon === false) { + this.hide_icon(obj); + } + else if(icon === true || icon === null || icon === undefined || icon === '') { + dom.removeClass('jstree-themeicon-custom ' + old).css("background","").removeAttr("rel"); + if(old === false) { this.show_icon(obj); } + } + else if(icon.indexOf("/") === -1 && icon.indexOf(".") === -1) { + dom.removeClass(old).css("background",""); + dom.addClass(icon + ' jstree-themeicon-custom').attr("rel",icon); + if(old === false) { this.show_icon(obj); } + } + else { + dom.removeClass(old).css("background",""); + dom.addClass('jstree-themeicon-custom').css("background", "url('" + icon + "') center center no-repeat").attr("rel",icon); + if(old === false) { this.show_icon(obj); } + } + return true; + }, + /** + * get the node icon for a node + * @name get_icon(obj) + * @param {mixed} obj + * @return {String} + */ + get_icon : function (obj) { + obj = this.get_node(obj); + return (!obj || obj.id === $.jstree.root) ? false : obj.icon; + }, + /** + * hide the icon on an individual node + * @name hide_icon(obj) + * @param {mixed} obj + */ + hide_icon : function (obj) { + var t1, t2; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.hide_icon(obj[t1]); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj === $.jstree.root) { return false; } + obj.icon = false; + this.get_node(obj, true).children(".jstree-anchor").children(".jstree-themeicon").addClass('jstree-themeicon-hidden'); + return true; + }, + /** + * show the icon on an individual node + * @name show_icon(obj) + * @param {mixed} obj + */ + show_icon : function (obj) { + var t1, t2, dom; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.show_icon(obj[t1]); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj === $.jstree.root) { return false; } + dom = this.get_node(obj, true); + obj.icon = dom.length ? dom.children(".jstree-anchor").children(".jstree-themeicon").attr('rel') : true; + if(!obj.icon) { obj.icon = true; } + dom.children(".jstree-anchor").children(".jstree-themeicon").removeClass('jstree-themeicon-hidden'); + return true; + } + }; + + // helpers + $.vakata = {}; + // collect attributes + $.vakata.attributes = function(node, with_values) { + node = $(node)[0]; + var attr = with_values ? {} : []; + if(node && node.attributes) { + $.each(node.attributes, function (i, v) { + if($.inArray(v.name.toLowerCase(),['style','contenteditable','hasfocus','tabindex']) !== -1) { return; } + if(v.value !== null && $.trim(v.value) !== '') { + if(with_values) { attr[v.name] = v.value; } + else { attr.push(v.name); } + } + }); + } + return attr; + }; + $.vakata.array_unique = function(array) { + var a = [], i, j, l, o = {}; + for(i = 0, l = array.length; i < l; i++) { + if(o[array[i]] === undefined) { + a.push(array[i]); + o[array[i]] = true; + } + } + return a; + }; + // remove item from array + $.vakata.array_remove = function(array, from) { + array.splice(from, 1); + return array; + //var rest = array.slice((to || from) + 1 || array.length); + //array.length = from < 0 ? array.length + from : from; + //array.push.apply(array, rest); + //return array; + }; + // remove item from array + $.vakata.array_remove_item = function(array, item) { + var tmp = $.inArray(item, array); + return tmp !== -1 ? $.vakata.array_remove(array, tmp) : array; + }; + $.vakata.array_filter = function(c,a,b,d,e) { + if (c.filter) { + return c.filter(a, b); + } + d=[]; + for (e in c) { + if (~~e+''===e+'' && e>=0 && a.call(b,c[e],+e,c)) { + d.push(c[e]); + } + } + return d; + }; + + +/** + * ### Changed plugin + * + * This plugin adds more information to the `changed.jstree` event. The new data is contained in the `changed` event data property, and contains a lists of `selected` and `deselected` nodes. + */ + + $.jstree.plugins.changed = function (options, parent) { + var last = []; + this.trigger = function (ev, data) { + var i, j; + if(!data) { + data = {}; + } + if(ev.replace('.jstree','') === 'changed') { + data.changed = { selected : [], deselected : [] }; + var tmp = {}; + for(i = 0, j = last.length; i < j; i++) { + tmp[last[i]] = 1; + } + for(i = 0, j = data.selected.length; i < j; i++) { + if(!tmp[data.selected[i]]) { + data.changed.selected.push(data.selected[i]); + } + else { + tmp[data.selected[i]] = 2; + } + } + for(i = 0, j = last.length; i < j; i++) { + if(tmp[last[i]] === 1) { + data.changed.deselected.push(last[i]); + } + } + last = data.selected.slice(); + } + /** + * triggered when selection changes (the "changed" plugin enhances the original event with more data) + * @event + * @name changed.jstree + * @param {Object} node + * @param {Object} action the action that caused the selection to change + * @param {Array} selected the current selection + * @param {Object} changed an object containing two properties `selected` and `deselected` - both arrays of node IDs, which were selected or deselected since the last changed event + * @param {Object} event the event (if any) that triggered this changed event + * @plugin changed + */ + parent.trigger.call(this, ev, data); + }; + this.refresh = function (skip_loading, forget_state) { + last = []; + return parent.refresh.apply(this, arguments); + }; + }; + +/** + * ### Checkbox plugin + * + * This plugin renders checkbox icons in front of each node, making multiple selection much easier. + * It also supports tri-state behavior, meaning that if a node has a few of its children checked it will be rendered as undetermined, and state will be propagated up. + */ + + var _i = document.createElement('I'); + _i.className = 'jstree-icon jstree-checkbox'; + _i.setAttribute('role', 'presentation'); + /** + * stores all defaults for the checkbox plugin + * @name $.jstree.defaults.checkbox + * @plugin checkbox + */ + $.jstree.defaults.checkbox = { + /** + * a boolean indicating if checkboxes should be visible (can be changed at a later time using `show_checkboxes()` and `hide_checkboxes`). Defaults to `true`. + * @name $.jstree.defaults.checkbox.visible + * @plugin checkbox + */ + visible : true, + /** + * a boolean indicating if checkboxes should cascade down and have an undetermined state. Defaults to `true`. + * @name $.jstree.defaults.checkbox.three_state + * @plugin checkbox + */ + three_state : true, + /** + * a boolean indicating if clicking anywhere on the node should act as clicking on the checkbox. Defaults to `true`. + * @name $.jstree.defaults.checkbox.whole_node + * @plugin checkbox + */ + whole_node : true, + /** + * a boolean indicating if the selected style of a node should be kept, or removed. Defaults to `true`. + * @name $.jstree.defaults.checkbox.keep_selected_style + * @plugin checkbox + */ + keep_selected_style : true, + /** + * This setting controls how cascading and undetermined nodes are applied. + * If 'up' is in the string - cascading up is enabled, if 'down' is in the string - cascading down is enabled, if 'undetermined' is in the string - undetermined nodes will be used. + * If `three_state` is set to `true` this setting is automatically set to 'up+down+undetermined'. Defaults to ''. + * @name $.jstree.defaults.checkbox.cascade + * @plugin checkbox + */ + cascade : '', + /** + * This setting controls if checkbox are bound to the general tree selection or to an internal array maintained by the checkbox plugin. Defaults to `true`, only set to `false` if you know exactly what you are doing. + * @name $.jstree.defaults.checkbox.tie_selection + * @plugin checkbox + */ + tie_selection : true + }; + $.jstree.plugins.checkbox = function (options, parent) { + this.bind = function () { + parent.bind.call(this); + this._data.checkbox.uto = false; + this._data.checkbox.selected = []; + if(this.settings.checkbox.three_state) { + this.settings.checkbox.cascade = 'up+down+undetermined'; + } + this.element + .on("init.jstree", $.proxy(function () { + this._data.checkbox.visible = this.settings.checkbox.visible; + if(!this.settings.checkbox.keep_selected_style) { + this.element.addClass('jstree-checkbox-no-clicked'); + } + if(this.settings.checkbox.tie_selection) { + this.element.addClass('jstree-checkbox-selection'); + } + }, this)) + .on("loading.jstree", $.proxy(function () { + this[ this._data.checkbox.visible ? 'show_checkboxes' : 'hide_checkboxes' ](); + }, this)); + if(this.settings.checkbox.cascade.indexOf('undetermined') !== -1) { + this.element + .on('changed.jstree uncheck_node.jstree check_node.jstree uncheck_all.jstree check_all.jstree move_node.jstree copy_node.jstree redraw.jstree open_node.jstree', $.proxy(function () { + // only if undetermined is in setting + if(this._data.checkbox.uto) { clearTimeout(this._data.checkbox.uto); } + this._data.checkbox.uto = setTimeout($.proxy(this._undetermined, this), 50); + }, this)); + } + if(!this.settings.checkbox.tie_selection) { + this.element + .on('model.jstree', $.proxy(function (e, data) { + var m = this._model.data, + p = m[data.parent], + dpc = data.nodes, + i, j; + for(i = 0, j = dpc.length; i < j; i++) { + m[dpc[i]].state.checked = m[dpc[i]].state.checked || (m[dpc[i]].original && m[dpc[i]].original.state && m[dpc[i]].original.state.checked); + if(m[dpc[i]].state.checked) { + this._data.checkbox.selected.push(dpc[i]); + } + } + }, this)); + } + if(this.settings.checkbox.cascade.indexOf('up') !== -1 || this.settings.checkbox.cascade.indexOf('down') !== -1) { + this.element + .on('model.jstree', $.proxy(function (e, data) { + var m = this._model.data, + p = m[data.parent], + dpc = data.nodes, + chd = [], + c, i, j, k, l, tmp, s = this.settings.checkbox.cascade, t = this.settings.checkbox.tie_selection; + + if(s.indexOf('down') !== -1) { + // apply down + if(p.state[ t ? 'selected' : 'checked' ]) { + for(i = 0, j = dpc.length; i < j; i++) { + m[dpc[i]].state[ t ? 'selected' : 'checked' ] = true; + } + this._data[ t ? 'core' : 'checkbox' ].selected = this._data[ t ? 'core' : 'checkbox' ].selected.concat(dpc); + } + else { + for(i = 0, j = dpc.length; i < j; i++) { + if(m[dpc[i]].state[ t ? 'selected' : 'checked' ]) { + for(k = 0, l = m[dpc[i]].children_d.length; k < l; k++) { + m[m[dpc[i]].children_d[k]].state[ t ? 'selected' : 'checked' ] = true; + } + this._data[ t ? 'core' : 'checkbox' ].selected = this._data[ t ? 'core' : 'checkbox' ].selected.concat(m[dpc[i]].children_d); + } + } + } + } + + if(s.indexOf('up') !== -1) { + // apply up + for(i = 0, j = p.children_d.length; i < j; i++) { + if(!m[p.children_d[i]].children.length) { + chd.push(m[p.children_d[i]].parent); + } + } + chd = $.vakata.array_unique(chd); + for(k = 0, l = chd.length; k < l; k++) { + p = m[chd[k]]; + while(p && p.id !== $.jstree.root) { + c = 0; + for(i = 0, j = p.children.length; i < j; i++) { + c += m[p.children[i]].state[ t ? 'selected' : 'checked' ]; + } + if(c === j) { + p.state[ t ? 'selected' : 'checked' ] = true; + this._data[ t ? 'core' : 'checkbox' ].selected.push(p.id); + tmp = this.get_node(p, true); + if(tmp && tmp.length) { + tmp.attr('aria-selected', true).children('.jstree-anchor').addClass( t ? 'jstree-clicked' : 'jstree-checked'); + } + } + else { + break; + } + p = this.get_node(p.parent); + } + } + } + + this._data[ t ? 'core' : 'checkbox' ].selected = $.vakata.array_unique(this._data[ t ? 'core' : 'checkbox' ].selected); + }, this)) + .on(this.settings.checkbox.tie_selection ? 'select_node.jstree' : 'check_node.jstree', $.proxy(function (e, data) { + var obj = data.node, + m = this._model.data, + par = this.get_node(obj.parent), + dom = this.get_node(obj, true), + i, j, c, tmp, s = this.settings.checkbox.cascade, t = this.settings.checkbox.tie_selection, + sel = {}, cur = this._data[ t ? 'core' : 'checkbox' ].selected; + + for (i = 0, j = cur.length; i < j; i++) { + sel[cur[i]] = true; + } + // apply down + if(s.indexOf('down') !== -1) { + //this._data[ t ? 'core' : 'checkbox' ].selected = $.vakata.array_unique(this._data[ t ? 'core' : 'checkbox' ].selected.concat(obj.children_d)); + for(i = 0, j = obj.children_d.length; i < j; i++) { + sel[obj.children_d[i]] = true; + tmp = m[obj.children_d[i]]; + tmp.state[ t ? 'selected' : 'checked' ] = true; + if(tmp && tmp.original && tmp.original.state && tmp.original.state.undetermined) { + tmp.original.state.undetermined = false; + } + } + } + + // apply up + if(s.indexOf('up') !== -1) { + while(par && par.id !== $.jstree.root) { + c = 0; + for(i = 0, j = par.children.length; i < j; i++) { + c += m[par.children[i]].state[ t ? 'selected' : 'checked' ]; + } + if(c === j) { + par.state[ t ? 'selected' : 'checked' ] = true; + sel[par.id] = true; + //this._data[ t ? 'core' : 'checkbox' ].selected.push(par.id); + tmp = this.get_node(par, true); + if(tmp && tmp.length) { + tmp.attr('aria-selected', true).children('.jstree-anchor').addClass(t ? 'jstree-clicked' : 'jstree-checked'); + } + } + else { + break; + } + par = this.get_node(par.parent); + } + } + + cur = []; + for (i in sel) { + if (sel.hasOwnProperty(i)) { + cur.push(i); + } + } + this._data[ t ? 'core' : 'checkbox' ].selected = cur; + + // apply down (process .children separately?) + if(s.indexOf('down') !== -1 && dom.length) { + dom.find('.jstree-anchor').addClass(t ? 'jstree-clicked' : 'jstree-checked').parent().attr('aria-selected', true); + } + }, this)) + .on(this.settings.checkbox.tie_selection ? 'deselect_all.jstree' : 'uncheck_all.jstree', $.proxy(function (e, data) { + var obj = this.get_node($.jstree.root), + m = this._model.data, + i, j, tmp; + for(i = 0, j = obj.children_d.length; i < j; i++) { + tmp = m[obj.children_d[i]]; + if(tmp && tmp.original && tmp.original.state && tmp.original.state.undetermined) { + tmp.original.state.undetermined = false; + } + } + }, this)) + .on(this.settings.checkbox.tie_selection ? 'deselect_node.jstree' : 'uncheck_node.jstree', $.proxy(function (e, data) { + var obj = data.node, + dom = this.get_node(obj, true), + i, j, tmp, s = this.settings.checkbox.cascade, t = this.settings.checkbox.tie_selection, + cur = this._data[ t ? 'core' : 'checkbox' ].selected, sel = {}; + if(obj && obj.original && obj.original.state && obj.original.state.undetermined) { + obj.original.state.undetermined = false; + } + + // apply down + if(s.indexOf('down') !== -1) { + for(i = 0, j = obj.children_d.length; i < j; i++) { + tmp = this._model.data[obj.children_d[i]]; + tmp.state[ t ? 'selected' : 'checked' ] = false; + if(tmp && tmp.original && tmp.original.state && tmp.original.state.undetermined) { + tmp.original.state.undetermined = false; + } + } + } + + // apply up + if(s.indexOf('up') !== -1) { + for(i = 0, j = obj.parents.length; i < j; i++) { + tmp = this._model.data[obj.parents[i]]; + tmp.state[ t ? 'selected' : 'checked' ] = false; + if(tmp && tmp.original && tmp.original.state && tmp.original.state.undetermined) { + tmp.original.state.undetermined = false; + } + tmp = this.get_node(obj.parents[i], true); + if(tmp && tmp.length) { + tmp.attr('aria-selected', false).children('.jstree-anchor').removeClass(t ? 'jstree-clicked' : 'jstree-checked'); + } + } + } + sel = {}; + for(i = 0, j = cur.length; i < j; i++) { + // apply down + apply up + if( + (s.indexOf('down') === -1 || $.inArray(cur[i], obj.children_d) === -1) && + (s.indexOf('up') === -1 || $.inArray(cur[i], obj.parents) === -1) + ) { + sel[cur[i]] = true; + } + } + cur = []; + for (i in sel) { + if (sel.hasOwnProperty(i)) { + cur.push(i); + } + } + this._data[ t ? 'core' : 'checkbox' ].selected = cur; + + // apply down (process .children separately?) + if(s.indexOf('down') !== -1 && dom.length) { + dom.find('.jstree-anchor').removeClass(t ? 'jstree-clicked' : 'jstree-checked').parent().attr('aria-selected', false); + } + }, this)); + } + if(this.settings.checkbox.cascade.indexOf('up') !== -1) { + this.element + .on('delete_node.jstree', $.proxy(function (e, data) { + // apply up (whole handler) + var p = this.get_node(data.parent), + m = this._model.data, + i, j, c, tmp, t = this.settings.checkbox.tie_selection; + while(p && p.id !== $.jstree.root && !p.state[ t ? 'selected' : 'checked' ]) { + c = 0; + for(i = 0, j = p.children.length; i < j; i++) { + c += m[p.children[i]].state[ t ? 'selected' : 'checked' ]; + } + if(j > 0 && c === j) { + p.state[ t ? 'selected' : 'checked' ] = true; + this._data[ t ? 'core' : 'checkbox' ].selected.push(p.id); + tmp = this.get_node(p, true); + if(tmp && tmp.length) { + tmp.attr('aria-selected', true).children('.jstree-anchor').addClass(t ? 'jstree-clicked' : 'jstree-checked'); + } + } + else { + break; + } + p = this.get_node(p.parent); + } + }, this)) + .on('move_node.jstree', $.proxy(function (e, data) { + // apply up (whole handler) + var is_multi = data.is_multi, + old_par = data.old_parent, + new_par = this.get_node(data.parent), + m = this._model.data, + p, c, i, j, tmp, t = this.settings.checkbox.tie_selection; + if(!is_multi) { + p = this.get_node(old_par); + while(p && p.id !== $.jstree.root && !p.state[ t ? 'selected' : 'checked' ]) { + c = 0; + for(i = 0, j = p.children.length; i < j; i++) { + c += m[p.children[i]].state[ t ? 'selected' : 'checked' ]; + } + if(j > 0 && c === j) { + p.state[ t ? 'selected' : 'checked' ] = true; + this._data[ t ? 'core' : 'checkbox' ].selected.push(p.id); + tmp = this.get_node(p, true); + if(tmp && tmp.length) { + tmp.attr('aria-selected', true).children('.jstree-anchor').addClass(t ? 'jstree-clicked' : 'jstree-checked'); + } + } + else { + break; + } + p = this.get_node(p.parent); + } + } + p = new_par; + while(p && p.id !== $.jstree.root) { + c = 0; + for(i = 0, j = p.children.length; i < j; i++) { + c += m[p.children[i]].state[ t ? 'selected' : 'checked' ]; + } + if(c === j) { + if(!p.state[ t ? 'selected' : 'checked' ]) { + p.state[ t ? 'selected' : 'checked' ] = true; + this._data[ t ? 'core' : 'checkbox' ].selected.push(p.id); + tmp = this.get_node(p, true); + if(tmp && tmp.length) { + tmp.attr('aria-selected', true).children('.jstree-anchor').addClass(t ? 'jstree-clicked' : 'jstree-checked'); + } + } + } + else { + if(p.state[ t ? 'selected' : 'checked' ]) { + p.state[ t ? 'selected' : 'checked' ] = false; + this._data[ t ? 'core' : 'checkbox' ].selected = $.vakata.array_remove_item(this._data[ t ? 'core' : 'checkbox' ].selected, p.id); + tmp = this.get_node(p, true); + if(tmp && tmp.length) { + tmp.attr('aria-selected', false).children('.jstree-anchor').removeClass(t ? 'jstree-clicked' : 'jstree-checked'); + } + } + else { + break; + } + } + p = this.get_node(p.parent); + } + }, this)); + } + }; + /** + * set the undetermined state where and if necessary. Used internally. + * @private + * @name _undetermined() + * @plugin checkbox + */ + this._undetermined = function () { + if(this.element === null) { return; } + var i, j, k, l, o = {}, m = this._model.data, t = this.settings.checkbox.tie_selection, s = this._data[ t ? 'core' : 'checkbox' ].selected, p = [], tt = this; + for(i = 0, j = s.length; i < j; i++) { + if(m[s[i]] && m[s[i]].parents) { + for(k = 0, l = m[s[i]].parents.length; k < l; k++) { + if(o[m[s[i]].parents[k]] !== undefined) { + break; + } + if(m[s[i]].parents[k] !== $.jstree.root) { + o[m[s[i]].parents[k]] = true; + p.push(m[s[i]].parents[k]); + } + } + } + } + // attempt for server side undetermined state + this.element.find('.jstree-closed').not(':has(.jstree-children)') + .each(function () { + var tmp = tt.get_node(this), tmp2; + if(!tmp.state.loaded) { + if(tmp.original && tmp.original.state && tmp.original.state.undetermined && tmp.original.state.undetermined === true) { + if(o[tmp.id] === undefined && tmp.id !== $.jstree.root) { + o[tmp.id] = true; + p.push(tmp.id); + } + for(k = 0, l = tmp.parents.length; k < l; k++) { + if(o[tmp.parents[k]] === undefined && tmp.parents[k] !== $.jstree.root) { + o[tmp.parents[k]] = true; + p.push(tmp.parents[k]); + } + } + } + } + else { + for(i = 0, j = tmp.children_d.length; i < j; i++) { + tmp2 = m[tmp.children_d[i]]; + if(!tmp2.state.loaded && tmp2.original && tmp2.original.state && tmp2.original.state.undetermined && tmp2.original.state.undetermined === true) { + if(o[tmp2.id] === undefined && tmp2.id !== $.jstree.root) { + o[tmp2.id] = true; + p.push(tmp2.id); + } + for(k = 0, l = tmp2.parents.length; k < l; k++) { + if(o[tmp2.parents[k]] === undefined && tmp2.parents[k] !== $.jstree.root) { + o[tmp2.parents[k]] = true; + p.push(tmp2.parents[k]); + } + } + } + } + } + }); + + this.element.find('.jstree-undetermined').removeClass('jstree-undetermined'); + for(i = 0, j = p.length; i < j; i++) { + if(!m[p[i]].state[ t ? 'selected' : 'checked' ]) { + s = this.get_node(p[i], true); + if(s && s.length) { + s.children('.jstree-anchor').children('.jstree-checkbox').addClass('jstree-undetermined'); + } + } + } + }; + this.redraw_node = function(obj, deep, is_callback, force_render) { + obj = parent.redraw_node.apply(this, arguments); + if(obj) { + var i, j, tmp = null, icon = null; + for(i = 0, j = obj.childNodes.length; i < j; i++) { + if(obj.childNodes[i] && obj.childNodes[i].className && obj.childNodes[i].className.indexOf("jstree-anchor") !== -1) { + tmp = obj.childNodes[i]; + break; + } + } + if(tmp) { + if(!this.settings.checkbox.tie_selection && this._model.data[obj.id].state.checked) { tmp.className += ' jstree-checked'; } + icon = _i.cloneNode(false); + if(this._model.data[obj.id].state.checkbox_disabled) { icon.className += ' jstree-checkbox-disabled'; } + tmp.insertBefore(icon, tmp.childNodes[0]); + } + } + if(!is_callback && this.settings.checkbox.cascade.indexOf('undetermined') !== -1) { + if(this._data.checkbox.uto) { clearTimeout(this._data.checkbox.uto); } + this._data.checkbox.uto = setTimeout($.proxy(this._undetermined, this), 50); + } + return obj; + }; + /** + * show the node checkbox icons + * @name show_checkboxes() + * @plugin checkbox + */ + this.show_checkboxes = function () { this._data.core.themes.checkboxes = true; this.get_container_ul().removeClass("jstree-no-checkboxes"); }; + /** + * hide the node checkbox icons + * @name hide_checkboxes() + * @plugin checkbox + */ + this.hide_checkboxes = function () { this._data.core.themes.checkboxes = false; this.get_container_ul().addClass("jstree-no-checkboxes"); }; + /** + * toggle the node icons + * @name toggle_checkboxes() + * @plugin checkbox + */ + this.toggle_checkboxes = function () { if(this._data.core.themes.checkboxes) { this.hide_checkboxes(); } else { this.show_checkboxes(); } }; + /** + * checks if a node is in an undetermined state + * @name is_undetermined(obj) + * @param {mixed} obj + * @return {Boolean} + */ + this.is_undetermined = function (obj) { + obj = this.get_node(obj); + var s = this.settings.checkbox.cascade, i, j, t = this.settings.checkbox.tie_selection, d = this._data[ t ? 'core' : 'checkbox' ].selected, m = this._model.data; + if(!obj || obj.state[ t ? 'selected' : 'checked' ] === true || s.indexOf('undetermined') === -1 || (s.indexOf('down') === -1 && s.indexOf('up') === -1)) { + return false; + } + if(!obj.state.loaded && obj.original.state.undetermined === true) { + return true; + } + for(i = 0, j = obj.children_d.length; i < j; i++) { + if($.inArray(obj.children_d[i], d) !== -1 || (!m[obj.children_d[i]].state.loaded && m[obj.children_d[i]].original.state.undetermined)) { + return true; + } + } + return false; + }; + /** + * disable a node's checkbox + * @name disable_checkbox(obj) + * @param {mixed} obj an array can be used too + * @trigger disable_checkbox.jstree + * @plugin checkbox + */ + this.disable_checkbox = function (obj) { + var t1, t2, dom; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.disable_checkbox(obj[t1]); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { + return false; + } + dom = this.get_node(obj, true); + if(!obj.state.checkbox_disabled) { + obj.state.checkbox_disabled = true; + if(dom && dom.length) { + dom.children('.jstree-anchor').children('.jstree-checkbox').addClass('jstree-checkbox-disabled'); + } + /** + * triggered when an node's checkbox is disabled + * @event + * @name disable_checkbox.jstree + * @param {Object} node + * @plugin checkbox + */ + this.trigger('disable_checkbox', { 'node' : obj }); + } + }; + /** + * enable a node's checkbox + * @name disable_checkbox(obj) + * @param {mixed} obj an array can be used too + * @trigger enable_checkbox.jstree + * @plugin checkbox + */ + this.enable_checkbox = function (obj) { + var t1, t2, dom; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.enable_checkbox(obj[t1]); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { + return false; + } + dom = this.get_node(obj, true); + if(obj.state.checkbox_disabled) { + obj.state.checkbox_disabled = false; + if(dom && dom.length) { + dom.children('.jstree-anchor').children('.jstree-checkbox').removeClass('jstree-checkbox-disabled'); + } + /** + * triggered when an node's checkbox is enabled + * @event + * @name enable_checkbox.jstree + * @param {Object} node + * @plugin checkbox + */ + this.trigger('enable_checkbox', { 'node' : obj }); + } + }; + + this.activate_node = function (obj, e) { + if($(e.target).hasClass('jstree-checkbox-disabled')) { + return false; + } + if(this.settings.checkbox.tie_selection && (this.settings.checkbox.whole_node || $(e.target).hasClass('jstree-checkbox'))) { + e.ctrlKey = true; + } + if(this.settings.checkbox.tie_selection || (!this.settings.checkbox.whole_node && !$(e.target).hasClass('jstree-checkbox'))) { + return parent.activate_node.call(this, obj, e); + } + if(this.is_disabled(obj)) { + return false; + } + if(this.is_checked(obj)) { + this.uncheck_node(obj, e); + } + else { + this.check_node(obj, e); + } + this.trigger('activate_node', { 'node' : this.get_node(obj) }); + }; + + /** + * check a node (only if tie_selection in checkbox settings is false, otherwise select_node will be called internally) + * @name check_node(obj) + * @param {mixed} obj an array can be used to check multiple nodes + * @trigger check_node.jstree + * @plugin checkbox + */ + this.check_node = function (obj, e) { + if(this.settings.checkbox.tie_selection) { return this.select_node(obj, false, true, e); } + var dom, t1, t2, th; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.check_node(obj[t1], e); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { + return false; + } + dom = this.get_node(obj, true); + if(!obj.state.checked) { + obj.state.checked = true; + this._data.checkbox.selected.push(obj.id); + if(dom && dom.length) { + dom.children('.jstree-anchor').addClass('jstree-checked'); + } + /** + * triggered when an node is checked (only if tie_selection in checkbox settings is false) + * @event + * @name check_node.jstree + * @param {Object} node + * @param {Array} selected the current selection + * @param {Object} event the event (if any) that triggered this check_node + * @plugin checkbox + */ + this.trigger('check_node', { 'node' : obj, 'selected' : this._data.checkbox.selected, 'event' : e }); + } + }; + /** + * uncheck a node (only if tie_selection in checkbox settings is false, otherwise deselect_node will be called internally) + * @name uncheck_node(obj) + * @param {mixed} obj an array can be used to uncheck multiple nodes + * @trigger uncheck_node.jstree + * @plugin checkbox + */ + this.uncheck_node = function (obj, e) { + if(this.settings.checkbox.tie_selection) { return this.deselect_node(obj, false, e); } + var t1, t2, dom; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.uncheck_node(obj[t1], e); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { + return false; + } + dom = this.get_node(obj, true); + if(obj.state.checked) { + obj.state.checked = false; + this._data.checkbox.selected = $.vakata.array_remove_item(this._data.checkbox.selected, obj.id); + if(dom.length) { + dom.children('.jstree-anchor').removeClass('jstree-checked'); + } + /** + * triggered when an node is unchecked (only if tie_selection in checkbox settings is false) + * @event + * @name uncheck_node.jstree + * @param {Object} node + * @param {Array} selected the current selection + * @param {Object} event the event (if any) that triggered this uncheck_node + * @plugin checkbox + */ + this.trigger('uncheck_node', { 'node' : obj, 'selected' : this._data.checkbox.selected, 'event' : e }); + } + }; + /** + * checks all nodes in the tree (only if tie_selection in checkbox settings is false, otherwise select_all will be called internally) + * @name check_all() + * @trigger check_all.jstree, changed.jstree + * @plugin checkbox + */ + this.check_all = function () { + if(this.settings.checkbox.tie_selection) { return this.select_all(); } + var tmp = this._data.checkbox.selected.concat([]), i, j; + this._data.checkbox.selected = this._model.data[$.jstree.root].children_d.concat(); + for(i = 0, j = this._data.checkbox.selected.length; i < j; i++) { + if(this._model.data[this._data.checkbox.selected[i]]) { + this._model.data[this._data.checkbox.selected[i]].state.checked = true; + } + } + this.redraw(true); + /** + * triggered when all nodes are checked (only if tie_selection in checkbox settings is false) + * @event + * @name check_all.jstree + * @param {Array} selected the current selection + * @plugin checkbox + */ + this.trigger('check_all', { 'selected' : this._data.checkbox.selected }); + }; + /** + * uncheck all checked nodes (only if tie_selection in checkbox settings is false, otherwise deselect_all will be called internally) + * @name uncheck_all() + * @trigger uncheck_all.jstree + * @plugin checkbox + */ + this.uncheck_all = function () { + if(this.settings.checkbox.tie_selection) { return this.deselect_all(); } + var tmp = this._data.checkbox.selected.concat([]), i, j; + for(i = 0, j = this._data.checkbox.selected.length; i < j; i++) { + if(this._model.data[this._data.checkbox.selected[i]]) { + this._model.data[this._data.checkbox.selected[i]].state.checked = false; + } + } + this._data.checkbox.selected = []; + this.element.find('.jstree-checked').removeClass('jstree-checked'); + /** + * triggered when all nodes are unchecked (only if tie_selection in checkbox settings is false) + * @event + * @name uncheck_all.jstree + * @param {Object} node the previous selection + * @param {Array} selected the current selection + * @plugin checkbox + */ + this.trigger('uncheck_all', { 'selected' : this._data.checkbox.selected, 'node' : tmp }); + }; + /** + * checks if a node is checked (if tie_selection is on in the settings this function will return the same as is_selected) + * @name is_checked(obj) + * @param {mixed} obj + * @return {Boolean} + * @plugin checkbox + */ + this.is_checked = function (obj) { + if(this.settings.checkbox.tie_selection) { return this.is_selected(obj); } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { return false; } + return obj.state.checked; + }; + /** + * get an array of all checked nodes (if tie_selection is on in the settings this function will return the same as get_selected) + * @name get_checked([full]) + * @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned + * @return {Array} + * @plugin checkbox + */ + this.get_checked = function (full) { + if(this.settings.checkbox.tie_selection) { return this.get_selected(full); } + return full ? $.map(this._data.checkbox.selected, $.proxy(function (i) { return this.get_node(i); }, this)) : this._data.checkbox.selected; + }; + /** + * get an array of all top level checked nodes (ignoring children of checked nodes) (if tie_selection is on in the settings this function will return the same as get_top_selected) + * @name get_top_checked([full]) + * @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned + * @return {Array} + * @plugin checkbox + */ + this.get_top_checked = function (full) { + if(this.settings.checkbox.tie_selection) { return this.get_top_selected(full); } + var tmp = this.get_checked(true), + obj = {}, i, j, k, l; + for(i = 0, j = tmp.length; i < j; i++) { + obj[tmp[i].id] = tmp[i]; + } + for(i = 0, j = tmp.length; i < j; i++) { + for(k = 0, l = tmp[i].children_d.length; k < l; k++) { + if(obj[tmp[i].children_d[k]]) { + delete obj[tmp[i].children_d[k]]; + } + } + } + tmp = []; + for(i in obj) { + if(obj.hasOwnProperty(i)) { + tmp.push(i); + } + } + return full ? $.map(tmp, $.proxy(function (i) { return this.get_node(i); }, this)) : tmp; + }; + /** + * get an array of all bottom level checked nodes (ignoring selected parents) (if tie_selection is on in the settings this function will return the same as get_bottom_selected) + * @name get_bottom_checked([full]) + * @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned + * @return {Array} + * @plugin checkbox + */ + this.get_bottom_checked = function (full) { + if(this.settings.checkbox.tie_selection) { return this.get_bottom_selected(full); } + var tmp = this.get_checked(true), + obj = [], i, j; + for(i = 0, j = tmp.length; i < j; i++) { + if(!tmp[i].children.length) { + obj.push(tmp[i].id); + } + } + return full ? $.map(obj, $.proxy(function (i) { return this.get_node(i); }, this)) : obj; + }; + this.load_node = function (obj, callback) { + var k, l, i, j, c, tmp; + if(!$.isArray(obj) && !this.settings.checkbox.tie_selection) { + tmp = this.get_node(obj); + if(tmp && tmp.state.loaded) { + for(k = 0, l = tmp.children_d.length; k < l; k++) { + if(this._model.data[tmp.children_d[k]].state.checked) { + c = true; + this._data.checkbox.selected = $.vakata.array_remove_item(this._data.checkbox.selected, tmp.children_d[k]); + } + } + } + } + return parent.load_node.apply(this, arguments); + }; + this.get_state = function () { + var state = parent.get_state.apply(this, arguments); + if(this.settings.checkbox.tie_selection) { return state; } + state.checkbox = this._data.checkbox.selected.slice(); + return state; + }; + this.set_state = function (state, callback) { + var res = parent.set_state.apply(this, arguments); + if(res && state.checkbox) { + if(!this.settings.checkbox.tie_selection) { + this.uncheck_all(); + var _this = this; + $.each(state.checkbox, function (i, v) { + _this.check_node(v); + }); + } + delete state.checkbox; + this.set_state(state, callback); + return false; + } + return res; + }; + this.refresh = function (skip_loading, forget_state) { + if(!this.settings.checkbox.tie_selection) { + this._data.checkbox.selected = []; + } + return parent.refresh.apply(this, arguments); + }; + }; + + // include the checkbox plugin by default + // $.jstree.defaults.plugins.push("checkbox"); + +/** + * ### Conditionalselect plugin + * + * This plugin allows defining a callback to allow or deny node selection by user input (activate node method). + */ + + /** + * a callback (function) which is invoked in the instance's scope and receives two arguments - the node and the event that triggered the `activate_node` call. Returning false prevents working with the node, returning true allows invoking activate_node. Defaults to returning `true`. + * @name $.jstree.defaults.checkbox.visible + * @plugin checkbox + */ + $.jstree.defaults.conditionalselect = function () { return true; }; + $.jstree.plugins.conditionalselect = function (options, parent) { + // own function + this.activate_node = function (obj, e) { + if(this.settings.conditionalselect.call(this, this.get_node(obj), e)) { + parent.activate_node.call(this, obj, e); + } + }; + }; + + +/** + * ### Contextmenu plugin + * + * Shows a context menu when a node is right-clicked. + */ + + /** + * stores all defaults for the contextmenu plugin + * @name $.jstree.defaults.contextmenu + * @plugin contextmenu + */ + $.jstree.defaults.contextmenu = { + /** + * a boolean indicating if the node should be selected when the context menu is invoked on it. Defaults to `true`. + * @name $.jstree.defaults.contextmenu.select_node + * @plugin contextmenu + */ + select_node : true, + /** + * a boolean indicating if the menu should be shown aligned with the node. Defaults to `true`, otherwise the mouse coordinates are used. + * @name $.jstree.defaults.contextmenu.show_at_node + * @plugin contextmenu + */ + show_at_node : true, + /** + * an object of actions, or a function that accepts a node and a callback function and calls the callback function with an object of actions available for that node (you can also return the items too). + * + * Each action consists of a key (a unique name) and a value which is an object with the following properties (only label and action are required). Once a menu item is activated the `action` function will be invoked with an object containing the following keys: item - the contextmenu item definition as seen below, reference - the DOM node that was used (the tree node), element - the contextmenu DOM element, position - an object with x/y properties indicating the position of the menu. + * + * * `separator_before` - a boolean indicating if there should be a separator before this item + * * `separator_after` - a boolean indicating if there should be a separator after this item + * * `_disabled` - a boolean indicating if this action should be disabled + * * `label` - a string - the name of the action (could be a function returning a string) + * * `title` - a string - an optional tooltip for the item + * * `action` - a function to be executed if this item is chosen, the function will receive + * * `icon` - a string, can be a path to an icon or a className, if using an image that is in the current directory use a `./` prefix, otherwise it will be detected as a class + * * `shortcut` - keyCode which will trigger the action if the menu is open (for example `113` for rename, which equals F2) + * * `shortcut_label` - shortcut label (like for example `F2` for rename) + * * `submenu` - an object with the same structure as $.jstree.defaults.contextmenu.items which can be used to create a submenu - each key will be rendered as a separate option in a submenu that will appear once the current item is hovered + * + * @name $.jstree.defaults.contextmenu.items + * @plugin contextmenu + */ + items : function (o, cb) { // Could be an object directly + return { + "create" : { + "separator_before" : false, + "separator_after" : true, + "_disabled" : false, //(this.check("create_node", data.reference, {}, "last")), + "label" : "Create", + "action" : function (data) { + var inst = $.jstree.reference(data.reference), + obj = inst.get_node(data.reference); + inst.create_node(obj, {}, "last", function (new_node) { + setTimeout(function () { inst.edit(new_node); },0); + }); + } + }, + "rename" : { + "separator_before" : false, + "separator_after" : false, + "_disabled" : false, //(this.check("rename_node", data.reference, this.get_parent(data.reference), "")), + "label" : "Rename", + /*! + "shortcut" : 113, + "shortcut_label" : 'F2', + "icon" : "glyphicon glyphicon-leaf", + */ + "action" : function (data) { + var inst = $.jstree.reference(data.reference), + obj = inst.get_node(data.reference); + inst.edit(obj); + } + }, + "remove" : { + "separator_before" : false, + "icon" : false, + "separator_after" : false, + "_disabled" : false, //(this.check("delete_node", data.reference, this.get_parent(data.reference), "")), + "label" : "Delete", + "action" : function (data) { + var inst = $.jstree.reference(data.reference), + obj = inst.get_node(data.reference); + if(inst.is_selected(obj)) { + inst.delete_node(inst.get_selected()); + } + else { + inst.delete_node(obj); + } + } + }, + "ccp" : { + "separator_before" : true, + "icon" : false, + "separator_after" : false, + "label" : "Edit", + "action" : false, + "submenu" : { + "cut" : { + "separator_before" : false, + "separator_after" : false, + "label" : "Cut", + "action" : function (data) { + var inst = $.jstree.reference(data.reference), + obj = inst.get_node(data.reference); + if(inst.is_selected(obj)) { + inst.cut(inst.get_top_selected()); + } + else { + inst.cut(obj); + } + } + }, + "copy" : { + "separator_before" : false, + "icon" : false, + "separator_after" : false, + "label" : "Copy", + "action" : function (data) { + var inst = $.jstree.reference(data.reference), + obj = inst.get_node(data.reference); + if(inst.is_selected(obj)) { + inst.copy(inst.get_top_selected()); + } + else { + inst.copy(obj); + } + } + }, + "paste" : { + "separator_before" : false, + "icon" : false, + "_disabled" : function (data) { + return !$.jstree.reference(data.reference).can_paste(); + }, + "separator_after" : false, + "label" : "Paste", + "action" : function (data) { + var inst = $.jstree.reference(data.reference), + obj = inst.get_node(data.reference); + inst.paste(obj); + } + } + } + } + }; + } + }; + + $.jstree.plugins.contextmenu = function (options, parent) { + this.bind = function () { + parent.bind.call(this); + + var last_ts = 0, cto = null, ex, ey; + this.element + .on("contextmenu.jstree", ".jstree-anchor", $.proxy(function (e, data) { + if (e.target.tagName.toLowerCase() === 'input') { + return; + } + e.preventDefault(); + last_ts = e.ctrlKey ? +new Date() : 0; + if(data || cto) { + last_ts = (+new Date()) + 10000; + } + if(cto) { + clearTimeout(cto); + } + if(!this.is_loading(e.currentTarget)) { + this.show_contextmenu(e.currentTarget, e.pageX, e.pageY, e); + } + }, this)) + .on("click.jstree", ".jstree-anchor", $.proxy(function (e) { + if(this._data.contextmenu.visible && (!last_ts || (+new Date()) - last_ts > 250)) { // work around safari & macOS ctrl+click + $.vakata.context.hide(); + } + last_ts = 0; + }, this)) + .on("touchstart.jstree", ".jstree-anchor", function (e) { + if(!e.originalEvent || !e.originalEvent.changedTouches || !e.originalEvent.changedTouches[0]) { + return; + } + ex = e.originalEvent.changedTouches[0].clientX; + ey = e.originalEvent.changedTouches[0].clientY; + cto = setTimeout(function () { + $(e.currentTarget).trigger('contextmenu', true); + }, 750); + }) + .on('touchmove.vakata.jstree', function (e) { + if(cto && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0] && (Math.abs(ex - e.originalEvent.changedTouches[0].clientX) > 50 || Math.abs(ey - e.originalEvent.changedTouches[0].clientY) > 50)) { + clearTimeout(cto); + } + }) + .on('touchend.vakata.jstree', function (e) { + if(cto) { + clearTimeout(cto); + } + }); + + /*! + if(!('oncontextmenu' in document.body) && ('ontouchstart' in document.body)) { + var el = null, tm = null; + this.element + .on("touchstart", ".jstree-anchor", function (e) { + el = e.currentTarget; + tm = +new Date(); + $(document).one("touchend", function (e) { + e.target = document.elementFromPoint(e.originalEvent.targetTouches[0].pageX - window.pageXOffset, e.originalEvent.targetTouches[0].pageY - window.pageYOffset); + e.currentTarget = e.target; + tm = ((+(new Date())) - tm); + if(e.target === el && tm > 600 && tm < 1000) { + e.preventDefault(); + $(el).trigger('contextmenu', e); + } + el = null; + tm = null; + }); + }); + } + */ + $(document).on("context_hide.vakata.jstree", $.proxy(function (e, data) { + this._data.contextmenu.visible = false; + $(data.reference).removeClass('jstree-context'); + }, this)); + }; + this.teardown = function () { + if(this._data.contextmenu.visible) { + $.vakata.context.hide(); + } + parent.teardown.call(this); + }; + + /** + * prepare and show the context menu for a node + * @name show_contextmenu(obj [, x, y]) + * @param {mixed} obj the node + * @param {Number} x the x-coordinate relative to the document to show the menu at + * @param {Number} y the y-coordinate relative to the document to show the menu at + * @param {Object} e the event if available that triggered the contextmenu + * @plugin contextmenu + * @trigger show_contextmenu.jstree + */ + this.show_contextmenu = function (obj, x, y, e) { + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { return false; } + var s = this.settings.contextmenu, + d = this.get_node(obj, true), + a = d.children(".jstree-anchor"), + o = false, + i = false; + if(s.show_at_node || x === undefined || y === undefined) { + o = a.offset(); + x = o.left; + y = o.top + this._data.core.li_height; + } + if(this.settings.contextmenu.select_node && !this.is_selected(obj)) { + this.activate_node(obj, e); + } + + i = s.items; + if($.isFunction(i)) { + i = i.call(this, obj, $.proxy(function (i) { + this._show_contextmenu(obj, x, y, i); + }, this)); + } + if($.isPlainObject(i)) { + this._show_contextmenu(obj, x, y, i); + } + }; + /** + * show the prepared context menu for a node + * @name _show_contextmenu(obj, x, y, i) + * @param {mixed} obj the node + * @param {Number} x the x-coordinate relative to the document to show the menu at + * @param {Number} y the y-coordinate relative to the document to show the menu at + * @param {Number} i the object of items to show + * @plugin contextmenu + * @trigger show_contextmenu.jstree + * @private + */ + this._show_contextmenu = function (obj, x, y, i) { + var d = this.get_node(obj, true), + a = d.children(".jstree-anchor"); + $(document).one("context_show.vakata.jstree", $.proxy(function (e, data) { + var cls = 'jstree-contextmenu jstree-' + this.get_theme() + '-contextmenu'; + $(data.element).addClass(cls); + a.addClass('jstree-context'); + }, this)); + this._data.contextmenu.visible = true; + $.vakata.context.show(a, { 'x' : x, 'y' : y }, i); + /** + * triggered when the contextmenu is shown for a node + * @event + * @name show_contextmenu.jstree + * @param {Object} node the node + * @param {Number} x the x-coordinate of the menu relative to the document + * @param {Number} y the y-coordinate of the menu relative to the document + * @plugin contextmenu + */ + this.trigger('show_contextmenu', { "node" : obj, "x" : x, "y" : y }); + }; + }; + + // contextmenu helper + (function ($) { + var right_to_left = false, + vakata_context = { + element : false, + reference : false, + position_x : 0, + position_y : 0, + items : [], + html : "", + is_visible : false + }; + + $.vakata.context = { + settings : { + hide_onmouseleave : 0, + icons : true + }, + _trigger : function (event_name) { + $(document).triggerHandler("context_" + event_name + ".vakata", { + "reference" : vakata_context.reference, + "element" : vakata_context.element, + "position" : { + "x" : vakata_context.position_x, + "y" : vakata_context.position_y + } + }); + }, + _execute : function (i) { + i = vakata_context.items[i]; + return i && (!i._disabled || ($.isFunction(i._disabled) && !i._disabled({ "item" : i, "reference" : vakata_context.reference, "element" : vakata_context.element }))) && i.action ? i.action.call(null, { + "item" : i, + "reference" : vakata_context.reference, + "element" : vakata_context.element, + "position" : { + "x" : vakata_context.position_x, + "y" : vakata_context.position_y + } + }) : false; + }, + _parse : function (o, is_callback) { + if(!o) { return false; } + if(!is_callback) { + vakata_context.html = ""; + vakata_context.items = []; + } + var str = "", + sep = false, + tmp; + + if(is_callback) { str += "<"+"ul>"; } + $.each(o, function (i, val) { + if(!val) { return true; } + vakata_context.items.push(val); + if(!sep && val.separator_before) { + str += "<"+"li class='vakata-context-separator'><"+"a href='#' " + ($.vakata.context.settings.icons ? '' : 'style="margin-left:0px;"') + "> <"+"/a><"+"/li>"; + } + sep = false; + str += "<"+"li class='" + (val._class || "") + (val._disabled === true || ($.isFunction(val._disabled) && val._disabled({ "item" : val, "reference" : vakata_context.reference, "element" : vakata_context.element })) ? " vakata-contextmenu-disabled " : "") + "' "+(val.shortcut?" data-shortcut='"+val.shortcut+"' ":'')+">"; + str += "<"+"a href='#' rel='" + (vakata_context.items.length - 1) + "' " + (val.title ? "title='" + val.title + "'" : "") + ">"; + if($.vakata.context.settings.icons) { + str += "<"+"i "; + if(val.icon) { + if(val.icon.indexOf("/") !== -1 || val.icon.indexOf(".") !== -1) { str += " style='background:url(\"" + val.icon + "\") center center no-repeat' "; } + else { str += " class='" + val.icon + "' "; } + } + str += "><"+"/i><"+"span class='vakata-contextmenu-sep'> <"+"/span>"; + } + str += ($.isFunction(val.label) ? val.label({ "item" : i, "reference" : vakata_context.reference, "element" : vakata_context.element }) : val.label) + (val.shortcut?' <span class="vakata-contextmenu-shortcut vakata-contextmenu-shortcut-'+val.shortcut+'">'+ (val.shortcut_label || '') +'</span>':'') + "<"+"/a>"; + if(val.submenu) { + tmp = $.vakata.context._parse(val.submenu, true); + if(tmp) { str += tmp; } + } + str += "<"+"/li>"; + if(val.separator_after) { + str += "<"+"li class='vakata-context-separator'><"+"a href='#' " + ($.vakata.context.settings.icons ? '' : 'style="margin-left:0px;"') + "> <"+"/a><"+"/li>"; + sep = true; + } + }); + str = str.replace(/<li class\='vakata-context-separator'\><\/li\>$/,""); + if(is_callback) { str += "</ul>"; } + /** + * triggered on the document when the contextmenu is parsed (HTML is built) + * @event + * @plugin contextmenu + * @name context_parse.vakata + * @param {jQuery} reference the element that was right clicked + * @param {jQuery} element the DOM element of the menu itself + * @param {Object} position the x & y coordinates of the menu + */ + if(!is_callback) { vakata_context.html = str; $.vakata.context._trigger("parse"); } + return str.length > 10 ? str : false; + }, + _show_submenu : function (o) { + o = $(o); + if(!o.length || !o.children("ul").length) { return; } + var e = o.children("ul"), + xl = o.offset().left, + x = xl + o.outerWidth(), + y = o.offset().top, + w = e.width(), + h = e.height(), + dw = $(window).width() + $(window).scrollLeft(), + dh = $(window).height() + $(window).scrollTop(); + // може да Ñе ÑпеÑти е една проверка - дали нÑма нÑкой от клаÑовете вече нагоре + if(right_to_left) { + o[x - (w + 10 + o.outerWidth()) < 0 ? "addClass" : "removeClass"]("vakata-context-left"); + } + else { + o[x + w > dw && xl > dw - x ? "addClass" : "removeClass"]("vakata-context-right"); + } + if(y + h + 10 > dh) { + e.css("bottom","-1px"); + } + + //if does not fit - stick it to the side + if (o.hasClass('vakata-context-right')) { + if (xl < w) { + e.css("margin-right", xl - w); + } + } else { + if (dw - x < w) { + e.css("margin-left", dw - x - w); + } + } + + e.show(); + }, + show : function (reference, position, data) { + var o, e, x, y, w, h, dw, dh, cond = true; + if(vakata_context.element && vakata_context.element.length) { + vakata_context.element.width(''); + } + switch(cond) { + case (!position && !reference): + return false; + case (!!position && !!reference): + vakata_context.reference = reference; + vakata_context.position_x = position.x; + vakata_context.position_y = position.y; + break; + case (!position && !!reference): + vakata_context.reference = reference; + o = reference.offset(); + vakata_context.position_x = o.left + reference.outerHeight(); + vakata_context.position_y = o.top; + break; + case (!!position && !reference): + vakata_context.position_x = position.x; + vakata_context.position_y = position.y; + break; + } + if(!!reference && !data && $(reference).data('vakata_contextmenu')) { + data = $(reference).data('vakata_contextmenu'); + } + if($.vakata.context._parse(data)) { + vakata_context.element.html(vakata_context.html); + } + if(vakata_context.items.length) { + vakata_context.element.appendTo("body"); + e = vakata_context.element; + x = vakata_context.position_x; + y = vakata_context.position_y; + w = e.width(); + h = e.height(); + dw = $(window).width() + $(window).scrollLeft(); + dh = $(window).height() + $(window).scrollTop(); + if(right_to_left) { + x -= (e.outerWidth() - $(reference).outerWidth()); + if(x < $(window).scrollLeft() + 20) { + x = $(window).scrollLeft() + 20; + } + } + if(x + w + 20 > dw) { + x = dw - (w + 20); + } + if(y + h + 20 > dh) { + y = dh - (h + 20); + } + + vakata_context.element + .css({ "left" : x, "top" : y }) + .show() + .find('a').first().focus().parent().addClass("vakata-context-hover"); + vakata_context.is_visible = true; + /** + * triggered on the document when the contextmenu is shown + * @event + * @plugin contextmenu + * @name context_show.vakata + * @param {jQuery} reference the element that was right clicked + * @param {jQuery} element the DOM element of the menu itself + * @param {Object} position the x & y coordinates of the menu + */ + $.vakata.context._trigger("show"); + } + }, + hide : function () { + if(vakata_context.is_visible) { + vakata_context.element.hide().find("ul").hide().end().find(':focus').blur().end().detach(); + vakata_context.is_visible = false; + /** + * triggered on the document when the contextmenu is hidden + * @event + * @plugin contextmenu + * @name context_hide.vakata + * @param {jQuery} reference the element that was right clicked + * @param {jQuery} element the DOM element of the menu itself + * @param {Object} position the x & y coordinates of the menu + */ + $.vakata.context._trigger("hide"); + } + } + }; + $(function () { + right_to_left = $("body").css("direction") === "rtl"; + var to = false; + + vakata_context.element = $("<ul class='vakata-context'></ul>"); + vakata_context.element + .on("mouseenter", "li", function (e) { + e.stopImmediatePropagation(); + + if($.contains(this, e.relatedTarget)) { + // премахнато заради delegate mouseleave по-долу + // $(this).find(".vakata-context-hover").removeClass("vakata-context-hover"); + return; + } + + if(to) { clearTimeout(to); } + vakata_context.element.find(".vakata-context-hover").removeClass("vakata-context-hover").end(); + + $(this) + .siblings().find("ul").hide().end().end() + .parentsUntil(".vakata-context", "li").addBack().addClass("vakata-context-hover"); + $.vakata.context._show_submenu(this); + }) + // теÑтово - дали не натоварва? + .on("mouseleave", "li", function (e) { + if($.contains(this, e.relatedTarget)) { return; } + $(this).find(".vakata-context-hover").addBack().removeClass("vakata-context-hover"); + }) + .on("mouseleave", function (e) { + $(this).find(".vakata-context-hover").removeClass("vakata-context-hover"); + if($.vakata.context.settings.hide_onmouseleave) { + to = setTimeout( + (function (t) { + return function () { $.vakata.context.hide(); }; + }(this)), $.vakata.context.settings.hide_onmouseleave); + } + }) + .on("click", "a", function (e) { + e.preventDefault(); + //}) + //.on("mouseup", "a", function (e) { + if(!$(this).blur().parent().hasClass("vakata-context-disabled") && $.vakata.context._execute($(this).attr("rel")) !== false) { + $.vakata.context.hide(); + } + }) + .on('keydown', 'a', function (e) { + var o = null; + switch(e.which) { + case 13: + case 32: + e.type = "click"; + e.preventDefault(); + $(e.currentTarget).trigger(e); + break; + case 37: + if(vakata_context.is_visible) { + vakata_context.element.find(".vakata-context-hover").last().closest("li").first().find("ul").hide().find(".vakata-context-hover").removeClass("vakata-context-hover").end().end().children('a').focus(); + e.stopImmediatePropagation(); + e.preventDefault(); + } + break; + case 38: + if(vakata_context.is_visible) { + o = vakata_context.element.find("ul:visible").addBack().last().children(".vakata-context-hover").removeClass("vakata-context-hover").prevAll("li:not(.vakata-context-separator)").first(); + if(!o.length) { o = vakata_context.element.find("ul:visible").addBack().last().children("li:not(.vakata-context-separator)").last(); } + o.addClass("vakata-context-hover").children('a').focus(); + e.stopImmediatePropagation(); + e.preventDefault(); + } + break; + case 39: + if(vakata_context.is_visible) { + vakata_context.element.find(".vakata-context-hover").last().children("ul").show().children("li:not(.vakata-context-separator)").removeClass("vakata-context-hover").first().addClass("vakata-context-hover").children('a').focus(); + e.stopImmediatePropagation(); + e.preventDefault(); + } + break; + case 40: + if(vakata_context.is_visible) { + o = vakata_context.element.find("ul:visible").addBack().last().children(".vakata-context-hover").removeClass("vakata-context-hover").nextAll("li:not(.vakata-context-separator)").first(); + if(!o.length) { o = vakata_context.element.find("ul:visible").addBack().last().children("li:not(.vakata-context-separator)").first(); } + o.addClass("vakata-context-hover").children('a').focus(); + e.stopImmediatePropagation(); + e.preventDefault(); + } + break; + case 27: + $.vakata.context.hide(); + e.preventDefault(); + break; + default: + //console.log(e.which); + break; + } + }) + .on('keydown', function (e) { + e.preventDefault(); + var a = vakata_context.element.find('.vakata-contextmenu-shortcut-' + e.which).parent(); + if(a.parent().not('.vakata-context-disabled')) { + a.click(); + } + }); + + $(document) + .on("mousedown.vakata.jstree", function (e) { + if(vakata_context.is_visible && !$.contains(vakata_context.element[0], e.target)) { + $.vakata.context.hide(); + } + }) + .on("context_show.vakata.jstree", function (e, data) { + vakata_context.element.find("li:has(ul)").children("a").addClass("vakata-context-parent"); + if(right_to_left) { + vakata_context.element.addClass("vakata-context-rtl").css("direction", "rtl"); + } + // also apply a RTL class? + vakata_context.element.find("ul").hide().end(); + }); + }); + }($)); + // $.jstree.defaults.plugins.push("contextmenu"); + + +/** + * ### Drag'n'drop plugin + * + * Enables dragging and dropping of nodes in the tree, resulting in a move or copy operations. + */ + + /** + * stores all defaults for the drag'n'drop plugin + * @name $.jstree.defaults.dnd + * @plugin dnd + */ + $.jstree.defaults.dnd = { + /** + * a boolean indicating if a copy should be possible while dragging (by pressint the meta key or Ctrl). Defaults to `true`. + * @name $.jstree.defaults.dnd.copy + * @plugin dnd + */ + copy : true, + /** + * a number indicating how long a node should remain hovered while dragging to be opened. Defaults to `500`. + * @name $.jstree.defaults.dnd.open_timeout + * @plugin dnd + */ + open_timeout : 500, + /** + * a function invoked each time a node is about to be dragged, invoked in the tree's scope and receives the nodes about to be dragged as an argument (array) and the event that started the drag - return `false` to prevent dragging + * @name $.jstree.defaults.dnd.is_draggable + * @plugin dnd + */ + is_draggable : true, + /** + * a boolean indicating if checks should constantly be made while the user is dragging the node (as opposed to checking only on drop), default is `true` + * @name $.jstree.defaults.dnd.check_while_dragging + * @plugin dnd + */ + check_while_dragging : true, + /** + * a boolean indicating if nodes from this tree should only be copied with dnd (as opposed to moved), default is `false` + * @name $.jstree.defaults.dnd.always_copy + * @plugin dnd + */ + always_copy : false, + /** + * when dropping a node "inside", this setting indicates the position the node should go to - it can be an integer or a string: "first" (same as 0) or "last", default is `0` + * @name $.jstree.defaults.dnd.inside_pos + * @plugin dnd + */ + inside_pos : 0, + /** + * when starting the drag on a node that is selected this setting controls if all selected nodes are dragged or only the single node, default is `true`, which means all selected nodes are dragged when the drag is started on a selected node + * @name $.jstree.defaults.dnd.drag_selection + * @plugin dnd + */ + drag_selection : true, + /** + * controls whether dnd works on touch devices. If left as boolean true dnd will work the same as in desktop browsers, which in some cases may impair scrolling. If set to boolean false dnd will not work on touch devices. There is a special third option - string "selected" which means only selected nodes can be dragged on touch devices. + * @name $.jstree.defaults.dnd.touch + * @plugin dnd + */ + touch : true, + /** + * controls whether items can be dropped anywhere on the node, not just on the anchor, by default only the node anchor is a valid drop target. Works best with the wholerow plugin. If enabled on mobile depending on the interface it might be hard for the user to cancel the drop, since the whole tree container will be a valid drop target. + * @name $.jstree.defaults.dnd.large_drop_target + * @plugin dnd + */ + large_drop_target : false, + /** + * controls whether a drag can be initiated from any part of the node and not just the text/icon part, works best with the wholerow plugin. Keep in mind it can cause problems with tree scrolling on mobile depending on the interface - in that case set the touch option to "selected". + * @name $.jstree.defaults.dnd.large_drag_target + * @plugin dnd + */ + large_drag_target : false, + /** + * controls whether use HTML5 dnd api instead of classical. That will allow better integration of dnd events with other HTML5 controls. + * @reference http://caniuse.com/#feat=dragndrop + * @name $.jstree.defaults.dnd.use_html5 + * @plugin dnd + */ + use_html5: false + }; + var drg, elm; + // TODO: now check works by checking for each node individually, how about max_children, unique, etc? + $.jstree.plugins.dnd = function (options, parent) { + this.init = function (el, options) { + parent.init.call(this, el, options); + this.settings.dnd.use_html5 = this.settings.dnd.use_html5 && ('draggable' in document.createElement('span')); + }; + this.bind = function () { + parent.bind.call(this); + + this.element + .on(this.settings.dnd.use_html5 ? 'dragstart.jstree' : 'mousedown.jstree touchstart.jstree', this.settings.dnd.large_drag_target ? '.jstree-node' : '.jstree-anchor', $.proxy(function (e) { + if(this.settings.dnd.large_drag_target && $(e.target).closest('.jstree-node')[0] !== e.currentTarget) { + return true; + } + if(e.type === "touchstart" && (!this.settings.dnd.touch || (this.settings.dnd.touch === 'selected' && !$(e.currentTarget).closest('.jstree-node').children('.jstree-anchor').hasClass('jstree-clicked')))) { + return true; + } + var obj = this.get_node(e.target), + mlt = this.is_selected(obj) && this.settings.dnd.drag_selection ? this.get_top_selected().length : 1, + txt = (mlt > 1 ? mlt + ' ' + this.get_string('nodes') : this.get_text(e.currentTarget)); + if(this.settings.core.force_text) { + txt = $.vakata.html.escape(txt); + } + if(obj && obj.id && obj.id !== $.jstree.root && (e.which === 1 || e.type === "touchstart" || e.type === "dragstart") && + (this.settings.dnd.is_draggable === true || ($.isFunction(this.settings.dnd.is_draggable) && this.settings.dnd.is_draggable.call(this, (mlt > 1 ? this.get_top_selected(true) : [obj]), e))) + ) { + drg = { 'jstree' : true, 'origin' : this, 'obj' : this.get_node(obj,true), 'nodes' : mlt > 1 ? this.get_top_selected() : [obj.id] }; + elm = e.currentTarget; + if (this.settings.dnd.use_html5) { + $.vakata.dnd._trigger('start', e, { 'helper': $(), 'element': elm, 'data': drg }); + } else { + this.element.trigger('mousedown.jstree'); + return $.vakata.dnd.start(e, drg, '<div id="jstree-dnd" class="jstree-' + this.get_theme() + ' jstree-' + this.get_theme() + '-' + this.get_theme_variant() + ' ' + ( this.settings.core.themes.responsive ? ' jstree-dnd-responsive' : '' ) + '"><i class="jstree-icon jstree-er"></i>' + txt + '<ins class="jstree-copy" style="display:none;">+</ins></div>'); + } + } + }, this)); + if (this.settings.dnd.use_html5) { + this.element + .on('dragover.jstree', function (e) { + e.preventDefault(); + $.vakata.dnd._trigger('move', e, { 'helper': $(), 'element': elm, 'data': drg }); + return false; + }) + //.on('dragenter.jstree', this.settings.dnd.large_drop_target ? '.jstree-node' : '.jstree-anchor', $.proxy(function (e) { + // e.preventDefault(); + // $.vakata.dnd._trigger('move', e, { 'helper': $(), 'element': elm, 'data': drg }); + // return false; + // }, this)) + .on('drop.jstree', $.proxy(function (e) { + e.preventDefault(); + $.vakata.dnd._trigger('stop', e, { 'helper': $(), 'element': elm, 'data': drg }); + return false; + }, this)); + } + }; + this.redraw_node = function(obj, deep, callback, force_render) { + obj = parent.redraw_node.apply(this, arguments); + if (obj && this.settings.dnd.use_html5) { + if (this.settings.dnd.large_drag_target) { + obj.setAttribute('draggable', true); + } else { + var i, j, tmp = null; + for(i = 0, j = obj.childNodes.length; i < j; i++) { + if(obj.childNodes[i] && obj.childNodes[i].className && obj.childNodes[i].className.indexOf("jstree-anchor") !== -1) { + tmp = obj.childNodes[i]; + break; + } + } + if(tmp) { + tmp.setAttribute('draggable', true); + } + } + } + return obj; + }; + }; + + $(function() { + // bind only once for all instances + var lastmv = false, + laster = false, + lastev = false, + opento = false, + marker = $('<div id="jstree-marker"> </div>').hide(); //.appendTo('body'); + + $(document) + .on('dnd_start.vakata.jstree', function (e, data) { + lastmv = false; + lastev = false; + if(!data || !data.data || !data.data.jstree) { return; } + marker.appendTo('body'); //.show(); + }) + .on('dnd_move.vakata.jstree', function (e, data) { + if(opento) { + if (!data.event || data.event.type !== 'dragover' || data.event.target !== lastev.target) { + clearTimeout(opento); + } + } + if(!data || !data.data || !data.data.jstree) { return; } + + // if we are hovering the marker image do nothing (can happen on "inside" drags) + if(data.event.target.id && data.event.target.id === 'jstree-marker') { + return; + } + lastev = data.event; + + var ins = $.jstree.reference(data.event.target), + ref = false, + off = false, + rel = false, + tmp, l, t, h, p, i, o, ok, t1, t2, op, ps, pr, ip, tm, is_copy, pn; + // if we are over an instance + if(ins && ins._data && ins._data.dnd) { + marker.attr('class', 'jstree-' + ins.get_theme() + ( ins.settings.core.themes.responsive ? ' jstree-dnd-responsive' : '' )); + is_copy = data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (data.event.metaKey || data.event.ctrlKey))); + data.helper + .children().attr('class', 'jstree-' + ins.get_theme() + ' jstree-' + ins.get_theme() + '-' + ins.get_theme_variant() + ' ' + ( ins.settings.core.themes.responsive ? ' jstree-dnd-responsive' : '' )) + .find('.jstree-copy').first()[ is_copy ? 'show' : 'hide' ](); + + // if are hovering the container itself add a new root node + //console.log(data.event); + if( (data.event.target === ins.element[0] || data.event.target === ins.get_container_ul()[0]) && ins.get_container_ul().children().length === 0) { + ok = true; + for(t1 = 0, t2 = data.data.nodes.length; t1 < t2; t1++) { + ok = ok && ins.check( (data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (data.event.metaKey || data.event.ctrlKey)) ) ? "copy_node" : "move_node"), (data.data.origin && data.data.origin !== ins ? data.data.origin.get_node(data.data.nodes[t1]) : data.data.nodes[t1]), $.jstree.root, 'last', { 'dnd' : true, 'ref' : ins.get_node($.jstree.root), 'pos' : 'i', 'origin' : data.data.origin, 'is_multi' : (data.data.origin && data.data.origin !== ins), 'is_foreign' : (!data.data.origin) }); + if(!ok) { break; } + } + if(ok) { + lastmv = { 'ins' : ins, 'par' : $.jstree.root, 'pos' : 'last' }; + marker.hide(); + data.helper.find('.jstree-icon').first().removeClass('jstree-er').addClass('jstree-ok'); + if (data.event.originalEvent && data.event.originalEvent.dataTransfer) { + data.event.originalEvent.dataTransfer.dropEffect = is_copy ? 'copy' : 'move'; + } + return; + } + } + else { + // if we are hovering a tree node + ref = ins.settings.dnd.large_drop_target ? $(data.event.target).closest('.jstree-node').children('.jstree-anchor') : $(data.event.target).closest('.jstree-anchor'); + if(ref && ref.length && ref.parent().is('.jstree-closed, .jstree-open, .jstree-leaf')) { + off = ref.offset(); + rel = (data.event.pageY !== undefined ? data.event.pageY : data.event.originalEvent.pageY) - off.top; + h = ref.outerHeight(); + if(rel < h / 3) { + o = ['b', 'i', 'a']; + } + else if(rel > h - h / 3) { + o = ['a', 'i', 'b']; + } + else { + o = rel > h / 2 ? ['i', 'a', 'b'] : ['i', 'b', 'a']; + } + $.each(o, function (j, v) { + switch(v) { + case 'b': + l = off.left - 6; + t = off.top; + p = ins.get_parent(ref); + i = ref.parent().index(); + break; + case 'i': + ip = ins.settings.dnd.inside_pos; + tm = ins.get_node(ref.parent()); + l = off.left - 2; + t = off.top + h / 2 + 1; + p = tm.id; + i = ip === 'first' ? 0 : (ip === 'last' ? tm.children.length : Math.min(ip, tm.children.length)); + break; + case 'a': + l = off.left - 6; + t = off.top + h; + p = ins.get_parent(ref); + i = ref.parent().index() + 1; + break; + } + ok = true; + for(t1 = 0, t2 = data.data.nodes.length; t1 < t2; t1++) { + op = data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (data.event.metaKey || data.event.ctrlKey))) ? "copy_node" : "move_node"; + ps = i; + if(op === "move_node" && v === 'a' && (data.data.origin && data.data.origin === ins) && p === ins.get_parent(data.data.nodes[t1])) { + pr = ins.get_node(p); + if(ps > $.inArray(data.data.nodes[t1], pr.children)) { + ps -= 1; + } + } + ok = ok && ( (ins && ins.settings && ins.settings.dnd && ins.settings.dnd.check_while_dragging === false) || ins.check(op, (data.data.origin && data.data.origin !== ins ? data.data.origin.get_node(data.data.nodes[t1]) : data.data.nodes[t1]), p, ps, { 'dnd' : true, 'ref' : ins.get_node(ref.parent()), 'pos' : v, 'origin' : data.data.origin, 'is_multi' : (data.data.origin && data.data.origin !== ins), 'is_foreign' : (!data.data.origin) }) ); + if(!ok) { + if(ins && ins.last_error) { laster = ins.last_error(); } + break; + } + } + if(v === 'i' && ref.parent().is('.jstree-closed') && ins.settings.dnd.open_timeout) { + opento = setTimeout((function (x, z) { return function () { x.open_node(z); }; }(ins, ref)), ins.settings.dnd.open_timeout); + } + if(ok) { + pn = ins.get_node(p, true); + if (!pn.hasClass('.jstree-dnd-parent')) { + $('.jstree-dnd-parent').removeClass('jstree-dnd-parent'); + pn.addClass('jstree-dnd-parent'); + } + lastmv = { 'ins' : ins, 'par' : p, 'pos' : v === 'i' && ip === 'last' && i === 0 && !ins.is_loaded(tm) ? 'last' : i }; + marker.css({ 'left' : l + 'px', 'top' : t + 'px' }).show(); + data.helper.find('.jstree-icon').first().removeClass('jstree-er').addClass('jstree-ok'); + if (data.event.originalEvent && data.event.originalEvent.dataTransfer) { + data.event.originalEvent.dataTransfer.dropEffect = is_copy ? 'copy' : 'move'; + } + laster = {}; + o = true; + return false; + } + }); + if(o === true) { return; } + } + } + } + $('.jstree-dnd-parent').removeClass('jstree-dnd-parent'); + lastmv = false; + data.helper.find('.jstree-icon').removeClass('jstree-ok').addClass('jstree-er'); + if (data.event.originalEvent && data.event.originalEvent.dataTransfer) { + data.event.originalEvent.dataTransfer.dropEffect = 'none'; + } + marker.hide(); + }) + .on('dnd_scroll.vakata.jstree', function (e, data) { + if(!data || !data.data || !data.data.jstree) { return; } + marker.hide(); + lastmv = false; + lastev = false; + data.helper.find('.jstree-icon').first().removeClass('jstree-ok').addClass('jstree-er'); + }) + .on('dnd_stop.vakata.jstree', function (e, data) { + $('.jstree-dnd-parent').removeClass('jstree-dnd-parent'); + if(opento) { clearTimeout(opento); } + if(!data || !data.data || !data.data.jstree) { return; } + marker.hide().detach(); + var i, j, nodes = []; + if(lastmv) { + for(i = 0, j = data.data.nodes.length; i < j; i++) { + nodes[i] = data.data.origin ? data.data.origin.get_node(data.data.nodes[i]) : data.data.nodes[i]; + } + lastmv.ins[ data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (data.event.metaKey || data.event.ctrlKey))) ? 'copy_node' : 'move_node' ](nodes, lastmv.par, lastmv.pos, false, false, false, data.data.origin); + } + else { + i = $(data.event.target).closest('.jstree'); + if(i.length && laster && laster.error && laster.error === 'check') { + i = i.jstree(true); + if(i) { + i.settings.core.error.call(this, laster); + } + } + } + lastev = false; + lastmv = false; + }) + .on('keyup.jstree keydown.jstree', function (e, data) { + data = $.vakata.dnd._get(); + if(data && data.data && data.data.jstree) { + if (e.type === "keyup" && e.which === 27) { + if (opento) { clearTimeout(opento); } + lastmv = false; + laster = false; + lastev = false; + opento = false; + marker.hide().detach(); + $.vakata.dnd._clean(); + } else { + data.helper.find('.jstree-copy').first()[ data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (e.metaKey || e.ctrlKey))) ? 'show' : 'hide' ](); + if(lastev) { + lastev.metaKey = e.metaKey; + lastev.ctrlKey = e.ctrlKey; + $.vakata.dnd._trigger('move', lastev); + } + } + } + }); + }); + + // helpers + (function ($) { + $.vakata.html = { + div : $('<div />'), + escape : function (str) { + return $.vakata.html.div.text(str).html(); + }, + strip : function (str) { + return $.vakata.html.div.empty().append($.parseHTML(str)).text(); + } + }; + // private variable + var vakata_dnd = { + element : false, + target : false, + is_down : false, + is_drag : false, + helper : false, + helper_w: 0, + data : false, + init_x : 0, + init_y : 0, + scroll_l: 0, + scroll_t: 0, + scroll_e: false, + scroll_i: false, + is_touch: false + }; + $.vakata.dnd = { + settings : { + scroll_speed : 10, + scroll_proximity : 20, + helper_left : 5, + helper_top : 10, + threshold : 5, + threshold_touch : 50 + }, + _trigger : function (event_name, e, data) { + if (data === undefined) { + data = $.vakata.dnd._get(); + } + data.event = e; + $(document).triggerHandler("dnd_" + event_name + ".vakata", data); + }, + _get : function () { + return { + "data" : vakata_dnd.data, + "element" : vakata_dnd.element, + "helper" : vakata_dnd.helper + }; + }, + _clean : function () { + if(vakata_dnd.helper) { vakata_dnd.helper.remove(); } + if(vakata_dnd.scroll_i) { clearInterval(vakata_dnd.scroll_i); vakata_dnd.scroll_i = false; } + vakata_dnd = { + element : false, + target : false, + is_down : false, + is_drag : false, + helper : false, + helper_w: 0, + data : false, + init_x : 0, + init_y : 0, + scroll_l: 0, + scroll_t: 0, + scroll_e: false, + scroll_i: false, + is_touch: false + }; + $(document).off("mousemove.vakata.jstree touchmove.vakata.jstree", $.vakata.dnd.drag); + $(document).off("mouseup.vakata.jstree touchend.vakata.jstree", $.vakata.dnd.stop); + }, + _scroll : function (init_only) { + if(!vakata_dnd.scroll_e || (!vakata_dnd.scroll_l && !vakata_dnd.scroll_t)) { + if(vakata_dnd.scroll_i) { clearInterval(vakata_dnd.scroll_i); vakata_dnd.scroll_i = false; } + return false; + } + if(!vakata_dnd.scroll_i) { + vakata_dnd.scroll_i = setInterval($.vakata.dnd._scroll, 100); + return false; + } + if(init_only === true) { return false; } + + var i = vakata_dnd.scroll_e.scrollTop(), + j = vakata_dnd.scroll_e.scrollLeft(); + vakata_dnd.scroll_e.scrollTop(i + vakata_dnd.scroll_t * $.vakata.dnd.settings.scroll_speed); + vakata_dnd.scroll_e.scrollLeft(j + vakata_dnd.scroll_l * $.vakata.dnd.settings.scroll_speed); + if(i !== vakata_dnd.scroll_e.scrollTop() || j !== vakata_dnd.scroll_e.scrollLeft()) { + /** + * triggered on the document when a drag causes an element to scroll + * @event + * @plugin dnd + * @name dnd_scroll.vakata + * @param {Mixed} data any data supplied with the call to $.vakata.dnd.start + * @param {DOM} element the DOM element being dragged + * @param {jQuery} helper the helper shown next to the mouse + * @param {jQuery} event the element that is scrolling + */ + $.vakata.dnd._trigger("scroll", vakata_dnd.scroll_e); + } + }, + start : function (e, data, html) { + if(e.type === "touchstart" && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0]) { + e.pageX = e.originalEvent.changedTouches[0].pageX; + e.pageY = e.originalEvent.changedTouches[0].pageY; + e.target = document.elementFromPoint(e.originalEvent.changedTouches[0].pageX - window.pageXOffset, e.originalEvent.changedTouches[0].pageY - window.pageYOffset); + } + if(vakata_dnd.is_drag) { $.vakata.dnd.stop({}); } + try { + e.currentTarget.unselectable = "on"; + e.currentTarget.onselectstart = function() { return false; }; + if(e.currentTarget.style) { + e.currentTarget.style.touchAction = "none"; + e.currentTarget.style.msTouchAction = "none"; + e.currentTarget.style.MozUserSelect = "none"; + } + } catch(ignore) { } + vakata_dnd.init_x = e.pageX; + vakata_dnd.init_y = e.pageY; + vakata_dnd.data = data; + vakata_dnd.is_down = true; + vakata_dnd.element = e.currentTarget; + vakata_dnd.target = e.target; + vakata_dnd.is_touch = e.type === "touchstart"; + if(html !== false) { + vakata_dnd.helper = $("<div id='vakata-dnd'></div>").html(html).css({ + "display" : "block", + "margin" : "0", + "padding" : "0", + "position" : "absolute", + "top" : "-2000px", + "lineHeight" : "16px", + "zIndex" : "10000" + }); + } + $(document).on("mousemove.vakata.jstree touchmove.vakata.jstree", $.vakata.dnd.drag); + $(document).on("mouseup.vakata.jstree touchend.vakata.jstree", $.vakata.dnd.stop); + return false; + }, + drag : function (e) { + if(e.type === "touchmove" && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0]) { + e.pageX = e.originalEvent.changedTouches[0].pageX; + e.pageY = e.originalEvent.changedTouches[0].pageY; + e.target = document.elementFromPoint(e.originalEvent.changedTouches[0].pageX - window.pageXOffset, e.originalEvent.changedTouches[0].pageY - window.pageYOffset); + } + if(!vakata_dnd.is_down) { return; } + if(!vakata_dnd.is_drag) { + if( + Math.abs(e.pageX - vakata_dnd.init_x) > (vakata_dnd.is_touch ? $.vakata.dnd.settings.threshold_touch : $.vakata.dnd.settings.threshold) || + Math.abs(e.pageY - vakata_dnd.init_y) > (vakata_dnd.is_touch ? $.vakata.dnd.settings.threshold_touch : $.vakata.dnd.settings.threshold) + ) { + if(vakata_dnd.helper) { + vakata_dnd.helper.appendTo("body"); + vakata_dnd.helper_w = vakata_dnd.helper.outerWidth(); + } + vakata_dnd.is_drag = true; + $(vakata_dnd.target).one('click.vakata', false); + /** + * triggered on the document when a drag starts + * @event + * @plugin dnd + * @name dnd_start.vakata + * @param {Mixed} data any data supplied with the call to $.vakata.dnd.start + * @param {DOM} element the DOM element being dragged + * @param {jQuery} helper the helper shown next to the mouse + * @param {Object} event the event that caused the start (probably mousemove) + */ + $.vakata.dnd._trigger("start", e); + } + else { return; } + } + + var d = false, w = false, + dh = false, wh = false, + dw = false, ww = false, + dt = false, dl = false, + ht = false, hl = false; + + vakata_dnd.scroll_t = 0; + vakata_dnd.scroll_l = 0; + vakata_dnd.scroll_e = false; + $($(e.target).parentsUntil("body").addBack().get().reverse()) + .filter(function () { + return (/^auto|scroll$/).test($(this).css("overflow")) && + (this.scrollHeight > this.offsetHeight || this.scrollWidth > this.offsetWidth); + }) + .each(function () { + var t = $(this), o = t.offset(); + if(this.scrollHeight > this.offsetHeight) { + if(o.top + t.height() - e.pageY < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_t = 1; } + if(e.pageY - o.top < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_t = -1; } + } + if(this.scrollWidth > this.offsetWidth) { + if(o.left + t.width() - e.pageX < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_l = 1; } + if(e.pageX - o.left < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_l = -1; } + } + if(vakata_dnd.scroll_t || vakata_dnd.scroll_l) { + vakata_dnd.scroll_e = $(this); + return false; + } + }); + + if(!vakata_dnd.scroll_e) { + d = $(document); w = $(window); + dh = d.height(); wh = w.height(); + dw = d.width(); ww = w.width(); + dt = d.scrollTop(); dl = d.scrollLeft(); + if(dh > wh && e.pageY - dt < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_t = -1; } + if(dh > wh && wh - (e.pageY - dt) < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_t = 1; } + if(dw > ww && e.pageX - dl < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_l = -1; } + if(dw > ww && ww - (e.pageX - dl) < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_l = 1; } + if(vakata_dnd.scroll_t || vakata_dnd.scroll_l) { + vakata_dnd.scroll_e = d; + } + } + if(vakata_dnd.scroll_e) { $.vakata.dnd._scroll(true); } + + if(vakata_dnd.helper) { + ht = parseInt(e.pageY + $.vakata.dnd.settings.helper_top, 10); + hl = parseInt(e.pageX + $.vakata.dnd.settings.helper_left, 10); + if(dh && ht + 25 > dh) { ht = dh - 50; } + if(dw && hl + vakata_dnd.helper_w > dw) { hl = dw - (vakata_dnd.helper_w + 2); } + vakata_dnd.helper.css({ + left : hl + "px", + top : ht + "px" + }); + } + /** + * triggered on the document when a drag is in progress + * @event + * @plugin dnd + * @name dnd_move.vakata + * @param {Mixed} data any data supplied with the call to $.vakata.dnd.start + * @param {DOM} element the DOM element being dragged + * @param {jQuery} helper the helper shown next to the mouse + * @param {Object} event the event that caused this to trigger (most likely mousemove) + */ + $.vakata.dnd._trigger("move", e); + return false; + }, + stop : function (e) { + if(e.type === "touchend" && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0]) { + e.pageX = e.originalEvent.changedTouches[0].pageX; + e.pageY = e.originalEvent.changedTouches[0].pageY; + e.target = document.elementFromPoint(e.originalEvent.changedTouches[0].pageX - window.pageXOffset, e.originalEvent.changedTouches[0].pageY - window.pageYOffset); + } + if(vakata_dnd.is_drag) { + /** + * triggered on the document when a drag stops (the dragged element is dropped) + * @event + * @plugin dnd + * @name dnd_stop.vakata + * @param {Mixed} data any data supplied with the call to $.vakata.dnd.start + * @param {DOM} element the DOM element being dragged + * @param {jQuery} helper the helper shown next to the mouse + * @param {Object} event the event that caused the stop + */ + if (e.target !== vakata_dnd.target) { + $(vakata_dnd.target).off('click.vakata'); + } + $.vakata.dnd._trigger("stop", e); + } + else { + if(e.type === "touchend" && e.target === vakata_dnd.target) { + var to = setTimeout(function () { $(e.target).click(); }, 100); + $(e.target).one('click', function() { if(to) { clearTimeout(to); } }); + } + } + $.vakata.dnd._clean(); + return false; + } + }; + }($)); + + // include the dnd plugin by default + // $.jstree.defaults.plugins.push("dnd"); + + +/** + * ### Massload plugin + * + * Adds massload functionality to jsTree, so that multiple nodes can be loaded in a single request (only useful with lazy loading). + */ + + /** + * massload configuration + * + * It is possible to set this to a standard jQuery-like AJAX config. + * In addition to the standard jQuery ajax options here you can supply functions for `data` and `url`, the functions will be run in the current instance's scope and a param will be passed indicating which node IDs need to be loaded, the return value of those functions will be used. + * + * You can also set this to a function, that function will receive the node IDs being loaded as argument and a second param which is a function (callback) which should be called with the result. + * + * Both the AJAX and the function approach rely on the same return value - an object where the keys are the node IDs, and the value is the children of that node as an array. + * + * { + * "id1" : [{ "text" : "Child of ID1", "id" : "c1" }, { "text" : "Another child of ID1", "id" : "c2" }], + * "id2" : [{ "text" : "Child of ID2", "id" : "c3" }] + * } + * + * @name $.jstree.defaults.massload + * @plugin massload + */ + $.jstree.defaults.massload = null; + $.jstree.plugins.massload = function (options, parent) { + this.init = function (el, options) { + this._data.massload = {}; + parent.init.call(this, el, options); + }; + this._load_nodes = function (nodes, callback, is_callback, force_reload) { + var s = this.settings.massload, + nodesString = JSON.stringify(nodes), + toLoad = [], + m = this._model.data, + i, j, dom; + if (!is_callback) { + for(i = 0, j = nodes.length; i < j; i++) { + if(!m[nodes[i]] || ( (!m[nodes[i]].state.loaded && !m[nodes[i]].state.failed) || force_reload) ) { + toLoad.push(nodes[i]); + dom = this.get_node(nodes[i], true); + if (dom && dom.length) { + dom.addClass("jstree-loading").attr('aria-busy',true); + } + } + } + this._data.massload = {}; + if (toLoad.length) { + if($.isFunction(s)) { + return s.call(this, toLoad, $.proxy(function (data) { + var i, j; + if(data) { + for(i in data) { + if(data.hasOwnProperty(i)) { + this._data.massload[i] = data[i]; + } + } + } + for(i = 0, j = nodes.length; i < j; i++) { + dom = this.get_node(nodes[i], true); + if (dom && dom.length) { + dom.removeClass("jstree-loading").attr('aria-busy',false); + } + } + parent._load_nodes.call(this, nodes, callback, is_callback, force_reload); + }, this)); + } + if(typeof s === 'object' && s && s.url) { + s = $.extend(true, {}, s); + if($.isFunction(s.url)) { + s.url = s.url.call(this, toLoad); + } + if($.isFunction(s.data)) { + s.data = s.data.call(this, toLoad); + } + return $.ajax(s) + .done($.proxy(function (data,t,x) { + var i, j; + if(data) { + for(i in data) { + if(data.hasOwnProperty(i)) { + this._data.massload[i] = data[i]; + } + } + } + for(i = 0, j = nodes.length; i < j; i++) { + dom = this.get_node(nodes[i], true); + if (dom && dom.length) { + dom.removeClass("jstree-loading").attr('aria-busy',false); + } + } + parent._load_nodes.call(this, nodes, callback, is_callback, force_reload); + }, this)) + .fail($.proxy(function (f) { + parent._load_nodes.call(this, nodes, callback, is_callback, force_reload); + }, this)); + } + } + } + return parent._load_nodes.call(this, nodes, callback, is_callback, force_reload); + }; + this._load_node = function (obj, callback) { + var data = this._data.massload[obj.id], + rslt = null, dom; + if(data) { + rslt = this[typeof data === 'string' ? '_append_html_data' : '_append_json_data']( + obj, + typeof data === 'string' ? $($.parseHTML(data)).filter(function () { return this.nodeType !== 3; }) : data, + function (status) { callback.call(this, status); } + ); + dom = this.get_node(obj.id, true); + if (dom && dom.length) { + dom.removeClass("jstree-loading").attr('aria-busy',false); + } + delete this._data.massload[obj.id]; + return rslt; + } + return parent._load_node.call(this, obj, callback); + }; + }; + +/** + * ### Search plugin + * + * Adds search functionality to jsTree. + */ + + /** + * stores all defaults for the search plugin + * @name $.jstree.defaults.search + * @plugin search + */ + $.jstree.defaults.search = { + /** + * a jQuery-like AJAX config, which jstree uses if a server should be queried for results. + * + * A `str` (which is the search string) parameter will be added with the request, an optional `inside` parameter will be added if the search is limited to a node id. The expected result is a JSON array with nodes that need to be opened so that matching nodes will be revealed. + * Leave this setting as `false` to not query the server. You can also set this to a function, which will be invoked in the instance's scope and receive 3 parameters - the search string, the callback to call with the array of nodes to load, and the optional node ID to limit the search to + * @name $.jstree.defaults.search.ajax + * @plugin search + */ + ajax : false, + /** + * Indicates if the search should be fuzzy or not (should `chnd3` match `child node 3`). Default is `false`. + * @name $.jstree.defaults.search.fuzzy + * @plugin search + */ + fuzzy : false, + /** + * Indicates if the search should be case sensitive. Default is `false`. + * @name $.jstree.defaults.search.case_sensitive + * @plugin search + */ + case_sensitive : false, + /** + * Indicates if the tree should be filtered (by default) to show only matching nodes (keep in mind this can be a heavy on large trees in old browsers). + * This setting can be changed at runtime when calling the search method. Default is `false`. + * @name $.jstree.defaults.search.show_only_matches + * @plugin search + */ + show_only_matches : false, + /** + * Indicates if the children of matched element are shown (when show_only_matches is true) + * This setting can be changed at runtime when calling the search method. Default is `false`. + * @name $.jstree.defaults.search.show_only_matches_children + * @plugin search + */ + show_only_matches_children : false, + /** + * Indicates if all nodes opened to reveal the search result, should be closed when the search is cleared or a new search is performed. Default is `true`. + * @name $.jstree.defaults.search.close_opened_onclear + * @plugin search + */ + close_opened_onclear : true, + /** + * Indicates if only leaf nodes should be included in search results. Default is `false`. + * @name $.jstree.defaults.search.search_leaves_only + * @plugin search + */ + search_leaves_only : false, + /** + * If set to a function it wil be called in the instance's scope with two arguments - search string and node (where node will be every node in the structure, so use with caution). + * If the function returns a truthy value the node will be considered a match (it might not be displayed if search_only_leaves is set to true and the node is not a leaf). Default is `false`. + * @name $.jstree.defaults.search.search_callback + * @plugin search + */ + search_callback : false + }; + + $.jstree.plugins.search = function (options, parent) { + this.bind = function () { + parent.bind.call(this); + + this._data.search.str = ""; + this._data.search.dom = $(); + this._data.search.res = []; + this._data.search.opn = []; + this._data.search.som = false; + this._data.search.smc = false; + this._data.search.hdn = []; + + this.element + .on("search.jstree", $.proxy(function (e, data) { + if(this._data.search.som && data.res.length) { + var m = this._model.data, i, j, p = [], k, l; + for(i = 0, j = data.res.length; i < j; i++) { + if(m[data.res[i]] && !m[data.res[i]].state.hidden) { + p.push(data.res[i]); + p = p.concat(m[data.res[i]].parents); + if(this._data.search.smc) { + for (k = 0, l = m[data.res[i]].children_d.length; k < l; k++) { + if (m[m[data.res[i]].children_d[k]] && !m[m[data.res[i]].children_d[k]].state.hidden) { + p.push(m[data.res[i]].children_d[k]); + } + } + } + } + } + p = $.vakata.array_remove_item($.vakata.array_unique(p), $.jstree.root); + this._data.search.hdn = this.hide_all(true); + this.show_node(p, true); + this.redraw(true); + } + }, this)) + .on("clear_search.jstree", $.proxy(function (e, data) { + if(this._data.search.som && data.res.length) { + this.show_node(this._data.search.hdn, true); + this.redraw(true); + } + }, this)); + }; + /** + * used to search the tree nodes for a given string + * @name search(str [, skip_async]) + * @param {String} str the search string + * @param {Boolean} skip_async if set to true server will not be queried even if configured + * @param {Boolean} show_only_matches if set to true only matching nodes will be shown (keep in mind this can be very slow on large trees or old browsers) + * @param {mixed} inside an optional node to whose children to limit the search + * @param {Boolean} append if set to true the results of this search are appended to the previous search + * @plugin search + * @trigger search.jstree + */ + this.search = function (str, skip_async, show_only_matches, inside, append, show_only_matches_children) { + if(str === false || $.trim(str.toString()) === "") { + return this.clear_search(); + } + inside = this.get_node(inside); + inside = inside && inside.id ? inside.id : null; + str = str.toString(); + var s = this.settings.search, + a = s.ajax ? s.ajax : false, + m = this._model.data, + f = null, + r = [], + p = [], i, j; + if(this._data.search.res.length && !append) { + this.clear_search(); + } + if(show_only_matches === undefined) { + show_only_matches = s.show_only_matches; + } + if(show_only_matches_children === undefined) { + show_only_matches_children = s.show_only_matches_children; + } + if(!skip_async && a !== false) { + if($.isFunction(a)) { + return a.call(this, str, $.proxy(function (d) { + if(d && d.d) { d = d.d; } + this._load_nodes(!$.isArray(d) ? [] : $.vakata.array_unique(d), function () { + this.search(str, true, show_only_matches, inside, append, show_only_matches_children); + }); + }, this), inside); + } + else { + a = $.extend({}, a); + if(!a.data) { a.data = {}; } + a.data.str = str; + if(inside) { + a.data.inside = inside; + } + if (this._data.search.lastRequest) { + this._data.search.lastRequest.abort(); + } + this._data.search.lastRequest = $.ajax(a) + .fail($.proxy(function () { + this._data.core.last_error = { 'error' : 'ajax', 'plugin' : 'search', 'id' : 'search_01', 'reason' : 'Could not load search parents', 'data' : JSON.stringify(a) }; + this.settings.core.error.call(this, this._data.core.last_error); + }, this)) + .done($.proxy(function (d) { + if(d && d.d) { d = d.d; } + this._load_nodes(!$.isArray(d) ? [] : $.vakata.array_unique(d), function () { + this.search(str, true, show_only_matches, inside, append, show_only_matches_children); + }); + }, this)); + return this._data.search.lastRequest; + } + } + if(!append) { + this._data.search.str = str; + this._data.search.dom = $(); + this._data.search.res = []; + this._data.search.opn = []; + this._data.search.som = show_only_matches; + this._data.search.smc = show_only_matches_children; + } + + f = new $.vakata.search(str, true, { caseSensitive : s.case_sensitive, fuzzy : s.fuzzy }); + $.each(m[inside ? inside : $.jstree.root].children_d, function (ii, i) { + var v = m[i]; + if(v.text && !v.state.hidden && (!s.search_leaves_only || (v.state.loaded && v.children.length === 0)) && ( (s.search_callback && s.search_callback.call(this, str, v)) || (!s.search_callback && f.search(v.text).isMatch) ) ) { + r.push(i); + p = p.concat(v.parents); + } + }); + if(r.length) { + p = $.vakata.array_unique(p); + for(i = 0, j = p.length; i < j; i++) { + if(p[i] !== $.jstree.root && m[p[i]] && this.open_node(p[i], null, 0) === true) { + this._data.search.opn.push(p[i]); + } + } + if(!append) { + this._data.search.dom = $(this.element[0].querySelectorAll('#' + $.map(r, function (v) { return "0123456789".indexOf(v[0]) !== -1 ? '\\3' + v[0] + ' ' + v.substr(1).replace($.jstree.idregex,'\\$&') : v.replace($.jstree.idregex,'\\$&'); }).join(', #'))); + this._data.search.res = r; + } + else { + this._data.search.dom = this._data.search.dom.add($(this.element[0].querySelectorAll('#' + $.map(r, function (v) { return "0123456789".indexOf(v[0]) !== -1 ? '\\3' + v[0] + ' ' + v.substr(1).replace($.jstree.idregex,'\\$&') : v.replace($.jstree.idregex,'\\$&'); }).join(', #')))); + this._data.search.res = $.vakata.array_unique(this._data.search.res.concat(r)); + } + this._data.search.dom.children(".jstree-anchor").addClass('jstree-search'); + } + /** + * triggered after search is complete + * @event + * @name search.jstree + * @param {jQuery} nodes a jQuery collection of matching nodes + * @param {String} str the search string + * @param {Array} res a collection of objects represeing the matching nodes + * @plugin search + */ + this.trigger('search', { nodes : this._data.search.dom, str : str, res : this._data.search.res, show_only_matches : show_only_matches }); + }; + /** + * used to clear the last search (removes classes and shows all nodes if filtering is on) + * @name clear_search() + * @plugin search + * @trigger clear_search.jstree + */ + this.clear_search = function () { + if(this.settings.search.close_opened_onclear) { + this.close_node(this._data.search.opn, 0); + } + /** + * triggered after search is complete + * @event + * @name clear_search.jstree + * @param {jQuery} nodes a jQuery collection of matching nodes (the result from the last search) + * @param {String} str the search string (the last search string) + * @param {Array} res a collection of objects represeing the matching nodes (the result from the last search) + * @plugin search + */ + this.trigger('clear_search', { 'nodes' : this._data.search.dom, str : this._data.search.str, res : this._data.search.res }); + if(this._data.search.res.length) { + this._data.search.dom = $(this.element[0].querySelectorAll('#' + $.map(this._data.search.res, function (v) { + return "0123456789".indexOf(v[0]) !== -1 ? '\\3' + v[0] + ' ' + v.substr(1).replace($.jstree.idregex,'\\$&') : v.replace($.jstree.idregex,'\\$&'); + }).join(', #'))); + this._data.search.dom.children(".jstree-anchor").removeClass("jstree-search"); + } + this._data.search.str = ""; + this._data.search.res = []; + this._data.search.opn = []; + this._data.search.dom = $(); + }; + + this.redraw_node = function(obj, deep, callback, force_render) { + obj = parent.redraw_node.apply(this, arguments); + if(obj) { + if($.inArray(obj.id, this._data.search.res) !== -1) { + var i, j, tmp = null; + for(i = 0, j = obj.childNodes.length; i < j; i++) { + if(obj.childNodes[i] && obj.childNodes[i].className && obj.childNodes[i].className.indexOf("jstree-anchor") !== -1) { + tmp = obj.childNodes[i]; + break; + } + } + if(tmp) { + tmp.className += ' jstree-search'; + } + } + } + return obj; + }; + }; + + // helpers + (function ($) { + // from http://kiro.me/projects/fuse.html + $.vakata.search = function(pattern, txt, options) { + options = options || {}; + options = $.extend({}, $.vakata.search.defaults, options); + if(options.fuzzy !== false) { + options.fuzzy = true; + } + pattern = options.caseSensitive ? pattern : pattern.toLowerCase(); + var MATCH_LOCATION = options.location, + MATCH_DISTANCE = options.distance, + MATCH_THRESHOLD = options.threshold, + patternLen = pattern.length, + matchmask, pattern_alphabet, match_bitapScore, search; + if(patternLen > 32) { + options.fuzzy = false; + } + if(options.fuzzy) { + matchmask = 1 << (patternLen - 1); + pattern_alphabet = (function () { + var mask = {}, + i = 0; + for (i = 0; i < patternLen; i++) { + mask[pattern.charAt(i)] = 0; + } + for (i = 0; i < patternLen; i++) { + mask[pattern.charAt(i)] |= 1 << (patternLen - i - 1); + } + return mask; + }()); + match_bitapScore = function (e, x) { + var accuracy = e / patternLen, + proximity = Math.abs(MATCH_LOCATION - x); + if(!MATCH_DISTANCE) { + return proximity ? 1.0 : accuracy; + } + return accuracy + (proximity / MATCH_DISTANCE); + }; + } + search = function (text) { + text = options.caseSensitive ? text : text.toLowerCase(); + if(pattern === text || text.indexOf(pattern) !== -1) { + return { + isMatch: true, + score: 0 + }; + } + if(!options.fuzzy) { + return { + isMatch: false, + score: 1 + }; + } + var i, j, + textLen = text.length, + scoreThreshold = MATCH_THRESHOLD, + bestLoc = text.indexOf(pattern, MATCH_LOCATION), + binMin, binMid, + binMax = patternLen + textLen, + lastRd, start, finish, rd, charMatch, + score = 1, + locations = []; + if (bestLoc !== -1) { + scoreThreshold = Math.min(match_bitapScore(0, bestLoc), scoreThreshold); + bestLoc = text.lastIndexOf(pattern, MATCH_LOCATION + patternLen); + if (bestLoc !== -1) { + scoreThreshold = Math.min(match_bitapScore(0, bestLoc), scoreThreshold); + } + } + bestLoc = -1; + for (i = 0; i < patternLen; i++) { + binMin = 0; + binMid = binMax; + while (binMin < binMid) { + if (match_bitapScore(i, MATCH_LOCATION + binMid) <= scoreThreshold) { + binMin = binMid; + } else { + binMax = binMid; + } + binMid = Math.floor((binMax - binMin) / 2 + binMin); + } + binMax = binMid; + start = Math.max(1, MATCH_LOCATION - binMid + 1); + finish = Math.min(MATCH_LOCATION + binMid, textLen) + patternLen; + rd = new Array(finish + 2); + rd[finish + 1] = (1 << i) - 1; + for (j = finish; j >= start; j--) { + charMatch = pattern_alphabet[text.charAt(j - 1)]; + if (i === 0) { + rd[j] = ((rd[j + 1] << 1) | 1) & charMatch; + } else { + rd[j] = ((rd[j + 1] << 1) | 1) & charMatch | (((lastRd[j + 1] | lastRd[j]) << 1) | 1) | lastRd[j + 1]; + } + if (rd[j] & matchmask) { + score = match_bitapScore(i, j - 1); + if (score <= scoreThreshold) { + scoreThreshold = score; + bestLoc = j - 1; + locations.push(bestLoc); + if (bestLoc > MATCH_LOCATION) { + start = Math.max(1, 2 * MATCH_LOCATION - bestLoc); + } else { + break; + } + } + } + } + if (match_bitapScore(i + 1, MATCH_LOCATION) > scoreThreshold) { + break; + } + lastRd = rd; + } + return { + isMatch: bestLoc >= 0, + score: score + }; + }; + return txt === true ? { 'search' : search } : search(txt); + }; + $.vakata.search.defaults = { + location : 0, + distance : 100, + threshold : 0.6, + fuzzy : false, + caseSensitive : false + }; + }($)); + + // include the search plugin by default + // $.jstree.defaults.plugins.push("search"); + + +/** + * ### Sort plugin + * + * Automatically sorts all siblings in the tree according to a sorting function. + */ + + /** + * the settings function used to sort the nodes. + * It is executed in the tree's context, accepts two nodes as arguments and should return `1` or `-1`. + * @name $.jstree.defaults.sort + * @plugin sort + */ + $.jstree.defaults.sort = function (a, b) { + //return this.get_type(a) === this.get_type(b) ? (this.get_text(a) > this.get_text(b) ? 1 : -1) : this.get_type(a) >= this.get_type(b); + return this.get_text(a) > this.get_text(b) ? 1 : -1; + }; + $.jstree.plugins.sort = function (options, parent) { + this.bind = function () { + parent.bind.call(this); + this.element + .on("model.jstree", $.proxy(function (e, data) { + this.sort(data.parent, true); + }, this)) + .on("rename_node.jstree create_node.jstree", $.proxy(function (e, data) { + this.sort(data.parent || data.node.parent, false); + this.redraw_node(data.parent || data.node.parent, true); + }, this)) + .on("move_node.jstree copy_node.jstree", $.proxy(function (e, data) { + this.sort(data.parent, false); + this.redraw_node(data.parent, true); + }, this)); + }; + /** + * used to sort a node's children + * @private + * @name sort(obj [, deep]) + * @param {mixed} obj the node + * @param {Boolean} deep if set to `true` nodes are sorted recursively. + * @plugin sort + * @trigger search.jstree + */ + this.sort = function (obj, deep) { + var i, j; + obj = this.get_node(obj); + if(obj && obj.children && obj.children.length) { + obj.children.sort($.proxy(this.settings.sort, this)); + if(deep) { + for(i = 0, j = obj.children_d.length; i < j; i++) { + this.sort(obj.children_d[i], false); + } + } + } + }; + }; + + // include the sort plugin by default + // $.jstree.defaults.plugins.push("sort"); + +/** + * ### State plugin + * + * Saves the state of the tree (selected nodes, opened nodes) on the user's computer using available options (localStorage, cookies, etc) + */ + + var to = false; + /** + * stores all defaults for the state plugin + * @name $.jstree.defaults.state + * @plugin state + */ + $.jstree.defaults.state = { + /** + * A string for the key to use when saving the current tree (change if using multiple trees in your project). Defaults to `jstree`. + * @name $.jstree.defaults.state.key + * @plugin state + */ + key : 'jstree', + /** + * A space separated list of events that trigger a state save. Defaults to `changed.jstree open_node.jstree close_node.jstree`. + * @name $.jstree.defaults.state.events + * @plugin state + */ + events : 'changed.jstree open_node.jstree close_node.jstree check_node.jstree uncheck_node.jstree', + /** + * Time in milliseconds after which the state will expire. Defaults to 'false' meaning - no expire. + * @name $.jstree.defaults.state.ttl + * @plugin state + */ + ttl : false, + /** + * A function that will be executed prior to restoring state with one argument - the state object. Can be used to clear unwanted parts of the state. + * @name $.jstree.defaults.state.filter + * @plugin state + */ + filter : false + }; + $.jstree.plugins.state = function (options, parent) { + this.bind = function () { + parent.bind.call(this); + var bind = $.proxy(function () { + this.element.on(this.settings.state.events, $.proxy(function () { + if(to) { clearTimeout(to); } + to = setTimeout($.proxy(function () { this.save_state(); }, this), 100); + }, this)); + /** + * triggered when the state plugin is finished restoring the state (and immediately after ready if there is no state to restore). + * @event + * @name state_ready.jstree + * @plugin state + */ + this.trigger('state_ready'); + }, this); + this.element + .on("ready.jstree", $.proxy(function (e, data) { + this.element.one("restore_state.jstree", bind); + if(!this.restore_state()) { bind(); } + }, this)); + }; + /** + * save the state + * @name save_state() + * @plugin state + */ + this.save_state = function () { + var st = { 'state' : this.get_state(), 'ttl' : this.settings.state.ttl, 'sec' : +(new Date()) }; + $.vakata.storage.set(this.settings.state.key, JSON.stringify(st)); + }; + /** + * restore the state from the user's computer + * @name restore_state() + * @plugin state + */ + this.restore_state = function () { + var k = $.vakata.storage.get(this.settings.state.key); + if(!!k) { try { k = JSON.parse(k); } catch(ex) { return false; } } + if(!!k && k.ttl && k.sec && +(new Date()) - k.sec > k.ttl) { return false; } + if(!!k && k.state) { k = k.state; } + if(!!k && $.isFunction(this.settings.state.filter)) { k = this.settings.state.filter.call(this, k); } + if(!!k) { + this.element.one("set_state.jstree", function (e, data) { data.instance.trigger('restore_state', { 'state' : $.extend(true, {}, k) }); }); + this.set_state(k); + return true; + } + return false; + }; + /** + * clear the state on the user's computer + * @name clear_state() + * @plugin state + */ + this.clear_state = function () { + return $.vakata.storage.del(this.settings.state.key); + }; + }; + + (function ($, undefined) { + $.vakata.storage = { + // simply specifying the functions in FF throws an error + set : function (key, val) { return window.localStorage.setItem(key, val); }, + get : function (key) { return window.localStorage.getItem(key); }, + del : function (key) { return window.localStorage.removeItem(key); } + }; + }($)); + + // include the state plugin by default + // $.jstree.defaults.plugins.push("state"); + +/** + * ### Types plugin + * + * Makes it possible to add predefined types for groups of nodes, which make it possible to easily control nesting rules and icon for each group. + */ + + /** + * An object storing all types as key value pairs, where the key is the type name and the value is an object that could contain following keys (all optional). + * + * * `max_children` the maximum number of immediate children this node type can have. Do not specify or set to `-1` for unlimited. + * * `max_depth` the maximum number of nesting this node type can have. A value of `1` would mean that the node can have children, but no grandchildren. Do not specify or set to `-1` for unlimited. + * * `valid_children` an array of node type strings, that nodes of this type can have as children. Do not specify or set to `-1` for no limits. + * * `icon` a string - can be a path to an icon or a className, if using an image that is in the current directory use a `./` prefix, otherwise it will be detected as a class. Omit to use the default icon from your theme. + * * `li_attr` an object of values which will be used to add HTML attributes on the resulting LI DOM node (merged with the node's own data) + * * `a_attr` an object of values which will be used to add HTML attributes on the resulting A DOM node (merged with the node's own data) + * + * There are two predefined types: + * + * * `#` represents the root of the tree, for example `max_children` would control the maximum number of root nodes. + * * `default` represents the default node - any settings here will be applied to all nodes that do not have a type specified. + * + * @name $.jstree.defaults.types + * @plugin types + */ + $.jstree.defaults.types = { + 'default' : {} + }; + $.jstree.defaults.types[$.jstree.root] = {}; + + $.jstree.plugins.types = function (options, parent) { + this.init = function (el, options) { + var i, j; + if(options && options.types && options.types['default']) { + for(i in options.types) { + if(i !== "default" && i !== $.jstree.root && options.types.hasOwnProperty(i)) { + for(j in options.types['default']) { + if(options.types['default'].hasOwnProperty(j) && options.types[i][j] === undefined) { + options.types[i][j] = options.types['default'][j]; + } + } + } + } + } + parent.init.call(this, el, options); + this._model.data[$.jstree.root].type = $.jstree.root; + }; + this.refresh = function (skip_loading, forget_state) { + parent.refresh.call(this, skip_loading, forget_state); + this._model.data[$.jstree.root].type = $.jstree.root; + }; + this.bind = function () { + this.element + .on('model.jstree', $.proxy(function (e, data) { + var m = this._model.data, + dpc = data.nodes, + t = this.settings.types, + i, j, c = 'default', k; + for(i = 0, j = dpc.length; i < j; i++) { + c = 'default'; + if(m[dpc[i]].original && m[dpc[i]].original.type && t[m[dpc[i]].original.type]) { + c = m[dpc[i]].original.type; + } + if(m[dpc[i]].data && m[dpc[i]].data.jstree && m[dpc[i]].data.jstree.type && t[m[dpc[i]].data.jstree.type]) { + c = m[dpc[i]].data.jstree.type; + } + m[dpc[i]].type = c; + if(m[dpc[i]].icon === true && t[c].icon !== undefined) { + m[dpc[i]].icon = t[c].icon; + } + if(t[c].li_attr !== undefined && typeof t[c].li_attr === 'object') { + for (k in t[c].li_attr) { + if (t[c].li_attr.hasOwnProperty(k)) { + if (k === 'id') { + continue; + } + else if (m[dpc[i]].li_attr[k] === undefined) { + m[dpc[i]].li_attr[k] = t[c].li_attr[k]; + } + else if (k === 'class') { + m[dpc[i]].li_attr['class'] = t[c].li_attr['class'] + ' ' + m[dpc[i]].li_attr['class']; + } + } + } + } + if(t[c].a_attr !== undefined && typeof t[c].a_attr === 'object') { + for (k in t[c].a_attr) { + if (t[c].a_attr.hasOwnProperty(k)) { + if (k === 'id') { + continue; + } + else if (m[dpc[i]].a_attr[k] === undefined) { + m[dpc[i]].a_attr[k] = t[c].a_attr[k]; + } + else if (k === 'href' && m[dpc[i]].a_attr[k] === '#') { + m[dpc[i]].a_attr['href'] = t[c].a_attr['href']; + } + else if (k === 'class') { + m[dpc[i]].a_attr['class'] = t[c].a_attr['class'] + ' ' + m[dpc[i]].a_attr['class']; + } + } + } + } + } + m[$.jstree.root].type = $.jstree.root; + }, this)); + parent.bind.call(this); + }; + this.get_json = function (obj, options, flat) { + var i, j, + m = this._model.data, + opt = options ? $.extend(true, {}, options, {no_id:false}) : {}, + tmp = parent.get_json.call(this, obj, opt, flat); + if(tmp === false) { return false; } + if($.isArray(tmp)) { + for(i = 0, j = tmp.length; i < j; i++) { + tmp[i].type = tmp[i].id && m[tmp[i].id] && m[tmp[i].id].type ? m[tmp[i].id].type : "default"; + if(options && options.no_id) { + delete tmp[i].id; + if(tmp[i].li_attr && tmp[i].li_attr.id) { + delete tmp[i].li_attr.id; + } + if(tmp[i].a_attr && tmp[i].a_attr.id) { + delete tmp[i].a_attr.id; + } + } + } + } + else { + tmp.type = tmp.id && m[tmp.id] && m[tmp.id].type ? m[tmp.id].type : "default"; + if(options && options.no_id) { + tmp = this._delete_ids(tmp); + } + } + return tmp; + }; + this._delete_ids = function (tmp) { + if($.isArray(tmp)) { + for(var i = 0, j = tmp.length; i < j; i++) { + tmp[i] = this._delete_ids(tmp[i]); + } + return tmp; + } + delete tmp.id; + if(tmp.li_attr && tmp.li_attr.id) { + delete tmp.li_attr.id; + } + if(tmp.a_attr && tmp.a_attr.id) { + delete tmp.a_attr.id; + } + if(tmp.children && $.isArray(tmp.children)) { + tmp.children = this._delete_ids(tmp.children); + } + return tmp; + }; + this.check = function (chk, obj, par, pos, more) { + if(parent.check.call(this, chk, obj, par, pos, more) === false) { return false; } + obj = obj && obj.id ? obj : this.get_node(obj); + par = par && par.id ? par : this.get_node(par); + var m = obj && obj.id ? (more && more.origin ? more.origin : $.jstree.reference(obj.id)) : null, tmp, d, i, j; + m = m && m._model && m._model.data ? m._model.data : null; + switch(chk) { + case "create_node": + case "move_node": + case "copy_node": + if(chk !== 'move_node' || $.inArray(obj.id, par.children) === -1) { + tmp = this.get_rules(par); + if(tmp.max_children !== undefined && tmp.max_children !== -1 && tmp.max_children === par.children.length) { + this._data.core.last_error = { 'error' : 'check', 'plugin' : 'types', 'id' : 'types_01', 'reason' : 'max_children prevents function: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) }; + return false; + } + if(tmp.valid_children !== undefined && tmp.valid_children !== -1 && $.inArray((obj.type || 'default'), tmp.valid_children) === -1) { + this._data.core.last_error = { 'error' : 'check', 'plugin' : 'types', 'id' : 'types_02', 'reason' : 'valid_children prevents function: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) }; + return false; + } + if(m && obj.children_d && obj.parents) { + d = 0; + for(i = 0, j = obj.children_d.length; i < j; i++) { + d = Math.max(d, m[obj.children_d[i]].parents.length); + } + d = d - obj.parents.length + 1; + } + if(d <= 0 || d === undefined) { d = 1; } + do { + if(tmp.max_depth !== undefined && tmp.max_depth !== -1 && tmp.max_depth < d) { + this._data.core.last_error = { 'error' : 'check', 'plugin' : 'types', 'id' : 'types_03', 'reason' : 'max_depth prevents function: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) }; + return false; + } + par = this.get_node(par.parent); + tmp = this.get_rules(par); + d++; + } while(par); + } + break; + } + return true; + }; + /** + * used to retrieve the type settings object for a node + * @name get_rules(obj) + * @param {mixed} obj the node to find the rules for + * @return {Object} + * @plugin types + */ + this.get_rules = function (obj) { + obj = this.get_node(obj); + if(!obj) { return false; } + var tmp = this.get_type(obj, true); + if(tmp.max_depth === undefined) { tmp.max_depth = -1; } + if(tmp.max_children === undefined) { tmp.max_children = -1; } + if(tmp.valid_children === undefined) { tmp.valid_children = -1; } + return tmp; + }; + /** + * used to retrieve the type string or settings object for a node + * @name get_type(obj [, rules]) + * @param {mixed} obj the node to find the rules for + * @param {Boolean} rules if set to `true` instead of a string the settings object will be returned + * @return {String|Object} + * @plugin types + */ + this.get_type = function (obj, rules) { + obj = this.get_node(obj); + return (!obj) ? false : ( rules ? $.extend({ 'type' : obj.type }, this.settings.types[obj.type]) : obj.type); + }; + /** + * used to change a node's type + * @name set_type(obj, type) + * @param {mixed} obj the node to change + * @param {String} type the new type + * @plugin types + */ + this.set_type = function (obj, type) { + var m = this._model.data, t, t1, t2, old_type, old_icon, k, d, a; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.set_type(obj[t1], type); + } + return true; + } + t = this.settings.types; + obj = this.get_node(obj); + if(!t[type] || !obj) { return false; } + d = this.get_node(obj, true); + if (d && d.length) { + a = d.children('.jstree-anchor'); + } + old_type = obj.type; + old_icon = this.get_icon(obj); + obj.type = type; + if(old_icon === true || !t[old_type] || (t[old_type].icon !== undefined && old_icon === t[old_type].icon)) { + this.set_icon(obj, t[type].icon !== undefined ? t[type].icon : true); + } + + // remove old type props + if(t[old_type] && t[old_type].li_attr !== undefined && typeof t[old_type].li_attr === 'object') { + for (k in t[old_type].li_attr) { + if (t[old_type].li_attr.hasOwnProperty(k)) { + if (k === 'id') { + continue; + } + else if (k === 'class') { + m[obj.id].li_attr['class'] = (m[obj.id].li_attr['class'] || '').replace(t[old_type].li_attr[k], ''); + if (d) { d.removeClass(t[old_type].li_attr[k]); } + } + else if (m[obj.id].li_attr[k] === t[old_type].li_attr[k]) { + m[obj.id].li_attr[k] = null; + if (d) { d.removeAttr(k); } + } + } + } + } + if(t[old_type] && t[old_type].a_attr !== undefined && typeof t[old_type].a_attr === 'object') { + for (k in t[old_type].a_attr) { + if (t[old_type].a_attr.hasOwnProperty(k)) { + if (k === 'id') { + continue; + } + else if (k === 'class') { + m[obj.id].a_attr['class'] = (m[obj.id].a_attr['class'] || '').replace(t[old_type].a_attr[k], ''); + if (a) { a.removeClass(t[old_type].a_attr[k]); } + } + else if (m[obj.id].a_attr[k] === t[old_type].a_attr[k]) { + if (k === 'href') { + m[obj.id].a_attr[k] = '#'; + if (a) { a.attr('href', '#'); } + } + else { + delete m[obj.id].a_attr[k]; + if (a) { a.removeAttr(k); } + } + } + } + } + } + + // add new props + if(t[type].li_attr !== undefined && typeof t[type].li_attr === 'object') { + for (k in t[type].li_attr) { + if (t[type].li_attr.hasOwnProperty(k)) { + if (k === 'id') { + continue; + } + else if (m[obj.id].li_attr[k] === undefined) { + m[obj.id].li_attr[k] = t[type].li_attr[k]; + if (d) { + if (k === 'class') { + d.addClass(t[type].li_attr[k]); + } + else { + d.attr(k, t[type].li_attr[k]); + } + } + } + else if (k === 'class') { + m[obj.id].li_attr['class'] = t[type].li_attr[k] + ' ' + m[obj.id].li_attr['class']; + if (d) { d.addClass(t[type].li_attr[k]); } + } + } + } + } + if(t[type].a_attr !== undefined && typeof t[type].a_attr === 'object') { + for (k in t[type].a_attr) { + if (t[type].a_attr.hasOwnProperty(k)) { + if (k === 'id') { + continue; + } + else if (m[obj.id].a_attr[k] === undefined) { + m[obj.id].a_attr[k] = t[type].a_attr[k]; + if (a) { + if (k === 'class') { + a.addClass(t[type].a_attr[k]); + } + else { + a.attr(k, t[type].a_attr[k]); + } + } + } + else if (k === 'href' && m[obj.id].a_attr[k] === '#') { + m[obj.id].a_attr['href'] = t[type].a_attr['href']; + if (a) { a.attr('href', t[type].a_attr['href']); } + } + else if (k === 'class') { + m[obj.id].a_attr['class'] = t[type].a_attr['class'] + ' ' + m[obj.id].a_attr['class']; + if (a) { a.addClass(t[type].a_attr[k]); } + } + } + } + } + + return true; + }; + }; + // include the types plugin by default + // $.jstree.defaults.plugins.push("types"); + + +/** + * ### Unique plugin + * + * Enforces that no nodes with the same name can coexist as siblings. + */ + + /** + * stores all defaults for the unique plugin + * @name $.jstree.defaults.unique + * @plugin unique + */ + $.jstree.defaults.unique = { + /** + * Indicates if the comparison should be case sensitive. Default is `false`. + * @name $.jstree.defaults.unique.case_sensitive + * @plugin unique + */ + case_sensitive : false, + /** + * A callback executed in the instance's scope when a new node is created and the name is already taken, the two arguments are the conflicting name and the counter. The default will produce results like `New node (2)`. + * @name $.jstree.defaults.unique.duplicate + * @plugin unique + */ + duplicate : function (name, counter) { + return name + ' (' + counter + ')'; + } + }; + + $.jstree.plugins.unique = function (options, parent) { + this.check = function (chk, obj, par, pos, more) { + if(parent.check.call(this, chk, obj, par, pos, more) === false) { return false; } + obj = obj && obj.id ? obj : this.get_node(obj); + par = par && par.id ? par : this.get_node(par); + if(!par || !par.children) { return true; } + var n = chk === "rename_node" ? pos : obj.text, + c = [], + s = this.settings.unique.case_sensitive, + m = this._model.data, i, j; + for(i = 0, j = par.children.length; i < j; i++) { + c.push(s ? m[par.children[i]].text : m[par.children[i]].text.toLowerCase()); + } + if(!s) { n = n.toLowerCase(); } + switch(chk) { + case "delete_node": + return true; + case "rename_node": + i = ($.inArray(n, c) === -1 || (obj.text && obj.text[ s ? 'toString' : 'toLowerCase']() === n)); + if(!i) { + this._data.core.last_error = { 'error' : 'check', 'plugin' : 'unique', 'id' : 'unique_01', 'reason' : 'Child with name ' + n + ' already exists. Preventing: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) }; + } + return i; + case "create_node": + i = ($.inArray(n, c) === -1); + if(!i) { + this._data.core.last_error = { 'error' : 'check', 'plugin' : 'unique', 'id' : 'unique_04', 'reason' : 'Child with name ' + n + ' already exists. Preventing: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) }; + } + return i; + case "copy_node": + i = ($.inArray(n, c) === -1); + if(!i) { + this._data.core.last_error = { 'error' : 'check', 'plugin' : 'unique', 'id' : 'unique_02', 'reason' : 'Child with name ' + n + ' already exists. Preventing: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) }; + } + return i; + case "move_node": + i = ( (obj.parent === par.id && (!more || !more.is_multi)) || $.inArray(n, c) === -1); + if(!i) { + this._data.core.last_error = { 'error' : 'check', 'plugin' : 'unique', 'id' : 'unique_03', 'reason' : 'Child with name ' + n + ' already exists. Preventing: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) }; + } + return i; + } + return true; + }; + this.create_node = function (par, node, pos, callback, is_loaded) { + if(!node || node.text === undefined) { + if(par === null) { + par = $.jstree.root; + } + par = this.get_node(par); + if(!par) { + return parent.create_node.call(this, par, node, pos, callback, is_loaded); + } + pos = pos === undefined ? "last" : pos; + if(!pos.toString().match(/^(before|after)$/) && !is_loaded && !this.is_loaded(par)) { + return parent.create_node.call(this, par, node, pos, callback, is_loaded); + } + if(!node) { node = {}; } + var tmp, n, dpc, i, j, m = this._model.data, s = this.settings.unique.case_sensitive, cb = this.settings.unique.duplicate; + n = tmp = this.get_string('New node'); + dpc = []; + for(i = 0, j = par.children.length; i < j; i++) { + dpc.push(s ? m[par.children[i]].text : m[par.children[i]].text.toLowerCase()); + } + i = 1; + while($.inArray(s ? n : n.toLowerCase(), dpc) !== -1) { + n = cb.call(this, tmp, (++i)).toString(); + } + node.text = n; + } + return parent.create_node.call(this, par, node, pos, callback, is_loaded); + }; + }; + + // include the unique plugin by default + // $.jstree.defaults.plugins.push("unique"); + + +/** + * ### Wholerow plugin + * + * Makes each node appear block level. Making selection easier. May cause slow down for large trees in old browsers. + */ + + var div = document.createElement('DIV'); + div.setAttribute('unselectable','on'); + div.setAttribute('role','presentation'); + div.className = 'jstree-wholerow'; + div.innerHTML = ' '; + $.jstree.plugins.wholerow = function (options, parent) { + this.bind = function () { + parent.bind.call(this); + + this.element + .on('ready.jstree set_state.jstree', $.proxy(function () { + this.hide_dots(); + }, this)) + .on("init.jstree loading.jstree ready.jstree", $.proxy(function () { + //div.style.height = this._data.core.li_height + 'px'; + this.get_container_ul().addClass('jstree-wholerow-ul'); + }, this)) + .on("deselect_all.jstree", $.proxy(function (e, data) { + this.element.find('.jstree-wholerow-clicked').removeClass('jstree-wholerow-clicked'); + }, this)) + .on("changed.jstree", $.proxy(function (e, data) { + this.element.find('.jstree-wholerow-clicked').removeClass('jstree-wholerow-clicked'); + var tmp = false, i, j; + for(i = 0, j = data.selected.length; i < j; i++) { + tmp = this.get_node(data.selected[i], true); + if(tmp && tmp.length) { + tmp.children('.jstree-wholerow').addClass('jstree-wholerow-clicked'); + } + } + }, this)) + .on("open_node.jstree", $.proxy(function (e, data) { + this.get_node(data.node, true).find('.jstree-clicked').parent().children('.jstree-wholerow').addClass('jstree-wholerow-clicked'); + }, this)) + .on("hover_node.jstree dehover_node.jstree", $.proxy(function (e, data) { + if(e.type === "hover_node" && this.is_disabled(data.node)) { return; } + this.get_node(data.node, true).children('.jstree-wholerow')[e.type === "hover_node"?"addClass":"removeClass"]('jstree-wholerow-hovered'); + }, this)) + .on("contextmenu.jstree", ".jstree-wholerow", $.proxy(function (e) { + if (this._data.contextmenu) { + e.preventDefault(); + var tmp = $.Event('contextmenu', { metaKey : e.metaKey, ctrlKey : e.ctrlKey, altKey : e.altKey, shiftKey : e.shiftKey, pageX : e.pageX, pageY : e.pageY }); + $(e.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(tmp); + } + }, this)) + /*! + .on("mousedown.jstree touchstart.jstree", ".jstree-wholerow", function (e) { + if(e.target === e.currentTarget) { + var a = $(e.currentTarget).closest(".jstree-node").children(".jstree-anchor"); + e.target = a[0]; + a.trigger(e); + } + }) + */ + .on("click.jstree", ".jstree-wholerow", function (e) { + e.stopImmediatePropagation(); + var tmp = $.Event('click', { metaKey : e.metaKey, ctrlKey : e.ctrlKey, altKey : e.altKey, shiftKey : e.shiftKey }); + $(e.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(tmp).focus(); + }) + .on("dblclick.jstree", ".jstree-wholerow", function (e) { + e.stopImmediatePropagation(); + var tmp = $.Event('dblclick', { metaKey : e.metaKey, ctrlKey : e.ctrlKey, altKey : e.altKey, shiftKey : e.shiftKey }); + $(e.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(tmp).focus(); + }) + .on("click.jstree", ".jstree-leaf > .jstree-ocl", $.proxy(function (e) { + e.stopImmediatePropagation(); + var tmp = $.Event('click', { metaKey : e.metaKey, ctrlKey : e.ctrlKey, altKey : e.altKey, shiftKey : e.shiftKey }); + $(e.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(tmp).focus(); + }, this)) + .on("mouseover.jstree", ".jstree-wholerow, .jstree-icon", $.proxy(function (e) { + e.stopImmediatePropagation(); + if(!this.is_disabled(e.currentTarget)) { + this.hover_node(e.currentTarget); + } + return false; + }, this)) + .on("mouseleave.jstree", ".jstree-node", $.proxy(function (e) { + this.dehover_node(e.currentTarget); + }, this)); + }; + this.teardown = function () { + if(this.settings.wholerow) { + this.element.find(".jstree-wholerow").remove(); + } + parent.teardown.call(this); + }; + this.redraw_node = function(obj, deep, callback, force_render) { + obj = parent.redraw_node.apply(this, arguments); + if(obj) { + var tmp = div.cloneNode(true); + //tmp.style.height = this._data.core.li_height + 'px'; + if($.inArray(obj.id, this._data.core.selected) !== -1) { tmp.className += ' jstree-wholerow-clicked'; } + if(this._data.core.focused && this._data.core.focused === obj.id) { tmp.className += ' jstree-wholerow-hovered'; } + obj.insertBefore(tmp, obj.childNodes[0]); + } + return obj; + }; + }; + // include the wholerow plugin by default + // $.jstree.defaults.plugins.push("wholerow"); + if(document.registerElement && Object && Object.create) { + var proto = Object.create(HTMLElement.prototype); + proto.createdCallback = function () { + var c = { core : {}, plugins : [] }, i; + for(i in $.jstree.plugins) { + if($.jstree.plugins.hasOwnProperty(i) && this.attributes[i]) { + c.plugins.push(i); + if(this.getAttribute(i) && JSON.parse(this.getAttribute(i))) { + c[i] = JSON.parse(this.getAttribute(i)); + } + } + } + for(i in $.jstree.defaults.core) { + if($.jstree.defaults.core.hasOwnProperty(i) && this.attributes[i]) { + c.core[i] = JSON.parse(this.getAttribute(i)) || this.getAttribute(i); + } + } + $(this).jstree(c); + }; + // proto.attributeChangedCallback = function (name, previous, value) { }; + try { + document.registerElement("vakata-jstree", { prototype: proto }); + } catch(ignore) { } + } + +})); \ No newline at end of file diff --git a/civicrm/bower_components/jstree/dist/jstree.min.js b/civicrm/bower_components/jstree/dist/jstree.min.js new file mode 100644 index 0000000000..24c420489e --- /dev/null +++ b/civicrm/bower_components/jstree/dist/jstree.min.js @@ -0,0 +1,6 @@ +/*! jsTree - v3.3.3 - 2016-10-31 - (MIT) */ +!function(a){"use strict";"function"==typeof define&&define.amd?define(["jquery"],a):"undefined"!=typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a,b){"use strict";if(!a.jstree){var c=0,d=!1,e=!1,f=!1,g=[],h=a("script:last").attr("src"),i=window.document;a.jstree={version:"3.3.3",defaults:{plugins:[]},plugins:{},path:h&&-1!==h.indexOf("/")?h.replace(/\/[^\/]+$/,""):"",idregex:/[\\:&!^|()\[\]<>@*'+~#";.,=\- \/${}%?`]/g,root:"#"},a.jstree.create=function(b,d){var e=new a.jstree.core(++c),f=d;return d=a.extend(!0,{},a.jstree.defaults,d),f&&f.plugins&&(d.plugins=f.plugins),a.each(d.plugins,function(a,b){"core"!==a&&(e=e.plugin(b,d[b]))}),a(b).data("jstree",e),e.init(b,d),e},a.jstree.destroy=function(){a(".jstree:jstree").jstree("destroy"),a(i).off(".jstree")},a.jstree.core=function(a){this._id=a,this._cnt=0,this._wrk=null,this._data={core:{themes:{name:!1,dots:!1,icons:!1,ellipsis:!1},selected:[],last_error:{},working:!1,worker_queue:[],focused:null}}},a.jstree.reference=function(b){var c=null,d=null;if(!b||!b.id||b.tagName&&b.nodeType||(b=b.id),!d||!d.length)try{d=a(b)}catch(e){}if(!d||!d.length)try{d=a("#"+b.replace(a.jstree.idregex,"\\$&"))}catch(e){}return d&&d.length&&(d=d.closest(".jstree")).length&&(d=d.data("jstree"))?c=d:a(".jstree").each(function(){var d=a(this).data("jstree");return d&&d._model.data[b]?(c=d,!1):void 0}),c},a.fn.jstree=function(c){var d="string"==typeof c,e=Array.prototype.slice.call(arguments,1),f=null;return c!==!0||this.length?(this.each(function(){var g=a.jstree.reference(this),h=d&&g?g[c]:null;return f=d&&h?h.apply(g,e):null,g||d||c!==b&&!a.isPlainObject(c)||a.jstree.create(this,c),(g&&!d||c===!0)&&(f=g||!1),null!==f&&f!==b?!1:void 0}),null!==f&&f!==b?f:this):!1},a.expr.pseudos.jstree=a.expr.createPseudo(function(c){return function(c){return a(c).hasClass("jstree")&&a(c).data("jstree")!==b}}),a.jstree.defaults.core={data:!1,strings:!1,check_callback:!1,error:a.noop,animation:200,multiple:!0,themes:{name:!1,url:!1,dir:!1,dots:!0,icons:!0,ellipsis:!1,stripes:!1,variant:!1,responsive:!1},expand_selected_onload:!0,worker:!0,force_text:!1,dblclick_toggle:!0},a.jstree.core.prototype={plugin:function(b,c){var d=a.jstree.plugins[b];return d?(this._data[b]={},d.prototype=this,new d(c,this)):this},init:function(b,c){this._model={data:{},changed:[],force_full_redraw:!1,redraw_timeout:!1,default_state:{loaded:!0,opened:!1,selected:!1,disabled:!1}},this._model.data[a.jstree.root]={id:a.jstree.root,parent:null,parents:[],children:[],children_d:[],state:{loaded:!1}},this.element=a(b).addClass("jstree jstree-"+this._id),this.settings=c,this._data.core.ready=!1,this._data.core.loaded=!1,this._data.core.rtl="rtl"===this.element.css("direction"),this.element[this._data.core.rtl?"addClass":"removeClass"]("jstree-rtl"),this.element.attr("role","tree"),this.settings.core.multiple&&this.element.attr("aria-multiselectable",!0),this.element.attr("tabindex")||this.element.attr("tabindex","0"),this.bind(),this.trigger("init"),this._data.core.original_container_html=this.element.find(" > ul > li").clone(!0),this._data.core.original_container_html.find("li").addBack().contents().filter(function(){return 3===this.nodeType&&(!this.nodeValue||/^\s+$/.test(this.nodeValue))}).remove(),this.element.html("<ul class='jstree-container-ul jstree-children' role='group'><li id='j"+this._id+"_loading' class='jstree-initial-node jstree-loading jstree-leaf jstree-last' role='tree-item'><i class='jstree-icon jstree-ocl'></i><a class='jstree-anchor' href='#'><i class='jstree-icon jstree-themeicon-hidden'></i>"+this.get_string("Loading ...")+"</a></li></ul>"),this.element.attr("aria-activedescendant","j"+this._id+"_loading"),this._data.core.li_height=this.get_container_ul().children("li").first().height()||24,this._data.core.node=this._create_prototype_node(),this.trigger("loading"),this.load_node(a.jstree.root)},destroy:function(a){if(this._wrk)try{window.URL.revokeObjectURL(this._wrk),this._wrk=null}catch(b){}a||this.element.empty(),this.teardown()},_create_prototype_node:function(){var a=i.createElement("LI"),b,c;return a.setAttribute("role","treeitem"),b=i.createElement("I"),b.className="jstree-icon jstree-ocl",b.setAttribute("role","presentation"),a.appendChild(b),b=i.createElement("A"),b.className="jstree-anchor",b.setAttribute("href","#"),b.setAttribute("tabindex","-1"),c=i.createElement("I"),c.className="jstree-icon jstree-themeicon",c.setAttribute("role","presentation"),b.appendChild(c),a.appendChild(b),b=c=null,a},teardown:function(){this.unbind(),this.element.removeClass("jstree").removeData("jstree").find("[class^='jstree']").addBack().attr("class",function(){return this.className.replace(/jstree[^ ]*|$/gi,"")}),this.element=null},bind:function(){var b="",c=null,d=0;this.element.on("dblclick.jstree",function(a){if(a.target.tagName&&"input"===a.target.tagName.toLowerCase())return!0;if(i.selection&&i.selection.empty)i.selection.empty();else if(window.getSelection){var b=window.getSelection();try{b.removeAllRanges(),b.collapse()}catch(c){}}}).on("mousedown.jstree",a.proxy(function(a){a.target===this.element[0]&&(a.preventDefault(),d=+new Date)},this)).on("mousedown.jstree",".jstree-ocl",function(a){a.preventDefault()}).on("click.jstree",".jstree-ocl",a.proxy(function(a){this.toggle_node(a.target)},this)).on("dblclick.jstree",".jstree-anchor",a.proxy(function(a){return a.target.tagName&&"input"===a.target.tagName.toLowerCase()?!0:void(this.settings.core.dblclick_toggle&&this.toggle_node(a.target))},this)).on("click.jstree",".jstree-anchor",a.proxy(function(b){b.preventDefault(),b.currentTarget!==i.activeElement&&a(b.currentTarget).focus(),this.activate_node(b.currentTarget,b)},this)).on("keydown.jstree",".jstree-anchor",a.proxy(function(b){if(b.target.tagName&&"input"===b.target.tagName.toLowerCase())return!0;if(32!==b.which&&13!==b.which&&(b.shiftKey||b.ctrlKey||b.altKey||b.metaKey))return!0;var c=null;switch(this._data.core.rtl&&(37===b.which?b.which=39:39===b.which&&(b.which=37)),b.which){case 32:b.ctrlKey&&(b.type="click",a(b.currentTarget).trigger(b));break;case 13:b.type="click",a(b.currentTarget).trigger(b);break;case 37:b.preventDefault(),this.is_open(b.currentTarget)?this.close_node(b.currentTarget):(c=this.get_parent(b.currentTarget),c&&c.id!==a.jstree.root&&this.get_node(c,!0).children(".jstree-anchor").focus());break;case 38:b.preventDefault(),c=this.get_prev_dom(b.currentTarget),c&&c.length&&c.children(".jstree-anchor").focus();break;case 39:b.preventDefault(),this.is_closed(b.currentTarget)?this.open_node(b.currentTarget,function(a){this.get_node(a,!0).children(".jstree-anchor").focus()}):this.is_open(b.currentTarget)&&(c=this.get_node(b.currentTarget,!0).children(".jstree-children")[0],c&&a(this._firstChild(c)).children(".jstree-anchor").focus());break;case 40:b.preventDefault(),c=this.get_next_dom(b.currentTarget),c&&c.length&&c.children(".jstree-anchor").focus();break;case 106:this.open_all();break;case 36:b.preventDefault(),c=this._firstChild(this.get_container_ul()[0]),c&&a(c).children(".jstree-anchor").filter(":visible").focus();break;case 35:b.preventDefault(),this.element.find(".jstree-anchor").filter(":visible").last().focus();break;case 113:b.preventDefault(),this.edit(b.currentTarget)}},this)).on("load_node.jstree",a.proxy(function(b,c){c.status&&(c.node.id!==a.jstree.root||this._data.core.loaded||(this._data.core.loaded=!0,this._firstChild(this.get_container_ul()[0])&&this.element.attr("aria-activedescendant",this._firstChild(this.get_container_ul()[0]).id),this.trigger("loaded")),this._data.core.ready||setTimeout(a.proxy(function(){if(this.element&&!this.get_container_ul().find(".jstree-loading").length){if(this._data.core.ready=!0,this._data.core.selected.length){if(this.settings.core.expand_selected_onload){var b=[],c,d;for(c=0,d=this._data.core.selected.length;d>c;c++)b=b.concat(this._model.data[this._data.core.selected[c]].parents);for(b=a.vakata.array_unique(b),c=0,d=b.length;d>c;c++)this.open_node(b[c],!1,0)}this.trigger("changed",{action:"ready",selected:this._data.core.selected})}this.trigger("ready")}},this),0))},this)).on("keypress.jstree",a.proxy(function(d){if(d.target.tagName&&"input"===d.target.tagName.toLowerCase())return!0;c&&clearTimeout(c),c=setTimeout(function(){b=""},500);var e=String.fromCharCode(d.which).toLowerCase(),f=this.element.find(".jstree-anchor").filter(":visible"),g=f.index(i.activeElement)||0,h=!1;if(b+=e,b.length>1){if(f.slice(g).each(a.proxy(function(c,d){return 0===a(d).text().toLowerCase().indexOf(b)?(a(d).focus(),h=!0,!1):void 0},this)),h)return;if(f.slice(0,g).each(a.proxy(function(c,d){return 0===a(d).text().toLowerCase().indexOf(b)?(a(d).focus(),h=!0,!1):void 0},this)),h)return}if(new RegExp("^"+e.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")+"+$").test(b)){if(f.slice(g+1).each(a.proxy(function(b,c){return a(c).text().toLowerCase().charAt(0)===e?(a(c).focus(),h=!0,!1):void 0},this)),h)return;if(f.slice(0,g+1).each(a.proxy(function(b,c){return a(c).text().toLowerCase().charAt(0)===e?(a(c).focus(),h=!0,!1):void 0},this)),h)return}},this)).on("init.jstree",a.proxy(function(){var a=this.settings.core.themes;this._data.core.themes.dots=a.dots,this._data.core.themes.stripes=a.stripes,this._data.core.themes.icons=a.icons,this._data.core.themes.ellipsis=a.ellipsis,this.set_theme(a.name||"default",a.url),this.set_theme_variant(a.variant)},this)).on("loading.jstree",a.proxy(function(){this[this._data.core.themes.dots?"show_dots":"hide_dots"](),this[this._data.core.themes.icons?"show_icons":"hide_icons"](),this[this._data.core.themes.stripes?"show_stripes":"hide_stripes"](),this[this._data.core.themes.ellipsis?"show_ellipsis":"hide_ellipsis"]()},this)).on("blur.jstree",".jstree-anchor",a.proxy(function(b){this._data.core.focused=null,a(b.currentTarget).filter(".jstree-hovered").mouseleave(),this.element.attr("tabindex","0")},this)).on("focus.jstree",".jstree-anchor",a.proxy(function(b){var c=this.get_node(b.currentTarget);c&&c.id&&(this._data.core.focused=c.id),this.element.find(".jstree-hovered").not(b.currentTarget).mouseleave(),a(b.currentTarget).mouseenter(),this.element.attr("tabindex","-1")},this)).on("focus.jstree",a.proxy(function(){if(+new Date-d>500&&!this._data.core.focused){d=0;var a=this.get_node(this.element.attr("aria-activedescendant"),!0);a&&a.find("> .jstree-anchor").focus()}},this)).on("mouseenter.jstree",".jstree-anchor",a.proxy(function(a){this.hover_node(a.currentTarget)},this)).on("mouseleave.jstree",".jstree-anchor",a.proxy(function(a){this.dehover_node(a.currentTarget)},this))},unbind:function(){this.element.off(".jstree"),a(i).off(".jstree-"+this._id)},trigger:function(a,b){b||(b={}),b.instance=this,this.element.triggerHandler(a.replace(".jstree","")+".jstree",b)},get_container:function(){return this.element},get_container_ul:function(){return this.element.children(".jstree-children").first()},get_string:function(b){var c=this.settings.core.strings;return a.isFunction(c)?c.call(this,b):c&&c[b]?c[b]:b},_firstChild:function(a){a=a?a.firstChild:null;while(null!==a&&1!==a.nodeType)a=a.nextSibling;return a},_nextSibling:function(a){a=a?a.nextSibling:null;while(null!==a&&1!==a.nodeType)a=a.nextSibling;return a},_previousSibling:function(a){a=a?a.previousSibling:null;while(null!==a&&1!==a.nodeType)a=a.previousSibling;return a},get_node:function(b,c){b&&b.id&&(b=b.id);var d;try{if(this._model.data[b])b=this._model.data[b];else if("string"==typeof b&&this._model.data[b.replace(/^#/,"")])b=this._model.data[b.replace(/^#/,"")];else if("string"==typeof b&&(d=a("#"+b.replace(a.jstree.idregex,"\\$&"),this.element)).length&&this._model.data[d.closest(".jstree-node").attr("id")])b=this._model.data[d.closest(".jstree-node").attr("id")];else if((d=a(b,this.element)).length&&this._model.data[d.closest(".jstree-node").attr("id")])b=this._model.data[d.closest(".jstree-node").attr("id")];else{if(!(d=a(b,this.element)).length||!d.hasClass("jstree"))return!1;b=this._model.data[a.jstree.root]}return c&&(b=b.id===a.jstree.root?this.element:a("#"+b.id.replace(a.jstree.idregex,"\\$&"),this.element)),b}catch(e){return!1}},get_path:function(b,c,d){if(b=b.parents?b:this.get_node(b),!b||b.id===a.jstree.root||!b.parents)return!1;var e,f,g=[];for(g.push(d?b.id:b.text),e=0,f=b.parents.length;f>e;e++)g.push(d?b.parents[e]:this.get_text(b.parents[e]));return g=g.reverse().slice(1),c?g.join(c):g},get_next_dom:function(b,c){var d;if(b=this.get_node(b,!0),b[0]===this.element[0]){d=this._firstChild(this.get_container_ul()[0]);while(d&&0===d.offsetHeight)d=this._nextSibling(d);return d?a(d):!1}if(!b||!b.length)return!1;if(c){d=b[0];do d=this._nextSibling(d);while(d&&0===d.offsetHeight);return d?a(d):!1}if(b.hasClass("jstree-open")){d=this._firstChild(b.children(".jstree-children")[0]);while(d&&0===d.offsetHeight)d=this._nextSibling(d);if(null!==d)return a(d)}d=b[0];do d=this._nextSibling(d);while(d&&0===d.offsetHeight);return null!==d?a(d):b.parentsUntil(".jstree",".jstree-node").nextAll(".jstree-node:visible").first()},get_prev_dom:function(b,c){var d;if(b=this.get_node(b,!0),b[0]===this.element[0]){d=this.get_container_ul()[0].lastChild;while(d&&0===d.offsetHeight)d=this._previousSibling(d);return d?a(d):!1}if(!b||!b.length)return!1;if(c){d=b[0];do d=this._previousSibling(d);while(d&&0===d.offsetHeight);return d?a(d):!1}d=b[0];do d=this._previousSibling(d);while(d&&0===d.offsetHeight);if(null!==d){b=a(d);while(b.hasClass("jstree-open"))b=b.children(".jstree-children").first().children(".jstree-node:visible:last");return b}return d=b[0].parentNode.parentNode,d&&d.className&&-1!==d.className.indexOf("jstree-node")?a(d):!1},get_parent:function(b){return b=this.get_node(b),b&&b.id!==a.jstree.root?b.parent:!1},get_children_dom:function(a){return a=this.get_node(a,!0),a[0]===this.element[0]?this.get_container_ul().children(".jstree-node"):a&&a.length?a.children(".jstree-children").children(".jstree-node"):!1},is_parent:function(a){return a=this.get_node(a),a&&(a.state.loaded===!1||a.children.length>0)},is_loaded:function(a){return a=this.get_node(a),a&&a.state.loaded},is_loading:function(a){return a=this.get_node(a),a&&a.state&&a.state.loading},is_open:function(a){return a=this.get_node(a),a&&a.state.opened},is_closed:function(a){return a=this.get_node(a),a&&this.is_parent(a)&&!a.state.opened},is_leaf:function(a){return!this.is_parent(a)},load_node:function(b,c){var d,e,f,g,h;if(a.isArray(b))return this._load_nodes(b.slice(),c),!0;if(b=this.get_node(b),!b)return c&&c.call(this,b,!1),!1;if(b.state.loaded){for(b.state.loaded=!1,f=0,g=b.parents.length;g>f;f++)this._model.data[b.parents[f]].children_d=a.vakata.array_filter(this._model.data[b.parents[f]].children_d,function(c){return-1===a.inArray(c,b.children_d)});for(d=0,e=b.children_d.length;e>d;d++)this._model.data[b.children_d[d]].state.selected&&(h=!0),delete this._model.data[b.children_d[d]];h&&(this._data.core.selected=a.vakata.array_filter(this._data.core.selected,function(c){return-1===a.inArray(c,b.children_d)})),b.children=[],b.children_d=[],h&&this.trigger("changed",{action:"load_node",node:b,selected:this._data.core.selected})}return b.state.failed=!1,b.state.loading=!0,this.get_node(b,!0).addClass("jstree-loading").attr("aria-busy",!0),this._load_node(b,a.proxy(function(a){b=this._model.data[b.id],b.state.loading=!1,b.state.loaded=a,b.state.failed=!b.state.loaded;var d=this.get_node(b,!0),e=0,f=0,g=this._model.data,h=!1;for(e=0,f=b.children.length;f>e;e++)if(g[b.children[e]]&&!g[b.children[e]].state.hidden){h=!0;break}b.state.loaded&&d&&d.length&&(d.removeClass("jstree-closed jstree-open jstree-leaf"),h?"#"!==b.id&&d.addClass(b.state.opened?"jstree-open":"jstree-closed"):d.addClass("jstree-leaf")),d.removeClass("jstree-loading").attr("aria-busy",!1),this.trigger("load_node",{node:b,status:a}),c&&c.call(this,b,a)},this)),!0},_load_nodes:function(a,b,c,d){var e=!0,f=function(){this._load_nodes(a,b,!0)},g=this._model.data,h,i,j=[];for(h=0,i=a.length;i>h;h++)g[a[h]]&&(!g[a[h]].state.loaded&&!g[a[h]].state.failed||!c&&d)&&(this.is_loading(a[h])||this.load_node(a[h],f),e=!1);if(e){for(h=0,i=a.length;i>h;h++)g[a[h]]&&g[a[h]].state.loaded&&j.push(a[h]);b&&!b.done&&(b.call(this,j),b.done=!0)}},load_all:function(b,c){if(b||(b=a.jstree.root),b=this.get_node(b),!b)return!1;var d=[],e=this._model.data,f=e[b.id].children_d,g,h;for(b.state&&!b.state.loaded&&d.push(b.id),g=0,h=f.length;h>g;g++)e[f[g]]&&e[f[g]].state&&!e[f[g]].state.loaded&&d.push(f[g]);d.length?this._load_nodes(d,function(){this.load_all(b,c)}):(c&&c.call(this,b),this.trigger("load_all",{node:b}))},_load_node:function(b,c){var d=this.settings.core.data,e,f=function g(){return 3!==this.nodeType&&8!==this.nodeType};return d?a.isFunction(d)?d.call(this,b,a.proxy(function(d){d===!1?c.call(this,!1):this["string"==typeof d?"_append_html_data":"_append_json_data"](b,"string"==typeof d?a(a.parseHTML(d)).filter(f):d,function(a){c.call(this,a)})},this)):"object"==typeof d?d.url?(d=a.extend(!0,{},d),a.isFunction(d.url)&&(d.url=d.url.call(this,b)),a.isFunction(d.data)&&(d.data=d.data.call(this,b)),a.ajax(d).done(a.proxy(function(d,e,g){var h=g.getResponseHeader("Content-Type");return h&&-1!==h.indexOf("json")||"object"==typeof d?this._append_json_data(b,d,function(a){c.call(this,a)}):h&&-1!==h.indexOf("html")||"string"==typeof d?this._append_html_data(b,a(a.parseHTML(d)).filter(f),function(a){c.call(this,a)}):(this._data.core.last_error={error:"ajax",plugin:"core",id:"core_04",reason:"Could not load node",data:JSON.stringify({id:b.id,xhr:g})},this.settings.core.error.call(this,this._data.core.last_error),c.call(this,!1))},this)).fail(a.proxy(function(a){c.call(this,!1),this._data.core.last_error={error:"ajax",plugin:"core",id:"core_04",reason:"Could not load node",data:JSON.stringify({id:b.id,xhr:a})},this.settings.core.error.call(this,this._data.core.last_error)},this))):(e=a.isArray(d)||a.isPlainObject(d)?JSON.parse(JSON.stringify(d)):d,b.id===a.jstree.root?this._append_json_data(b,e,function(a){c.call(this,a)}):(this._data.core.last_error={error:"nodata",plugin:"core",id:"core_05",reason:"Could not load node",data:JSON.stringify({id:b.id})},this.settings.core.error.call(this,this._data.core.last_error),c.call(this,!1))):"string"==typeof d?b.id===a.jstree.root?this._append_html_data(b,a(a.parseHTML(d)).filter(f),function(a){c.call(this,a)}):(this._data.core.last_error={error:"nodata",plugin:"core",id:"core_06",reason:"Could not load node",data:JSON.stringify({id:b.id})},this.settings.core.error.call(this,this._data.core.last_error),c.call(this,!1)):c.call(this,!1):b.id===a.jstree.root?this._append_html_data(b,this._data.core.original_container_html.clone(!0),function(a){c.call(this,a)}):c.call(this,!1)},_node_changed:function(a){a=this.get_node(a),a&&this._model.changed.push(a.id)},_append_html_data:function(b,c,d){b=this.get_node(b),b.children=[],b.children_d=[];var e=c.is("ul")?c.children():c,f=b.id,g=[],h=[],i=this._model.data,j=i[f],k=this._data.core.selected.length,l,m,n;for(e.each(a.proxy(function(b,c){l=this._parse_model_from_html(a(c),f,j.parents.concat()),l&&(g.push(l),h.push(l),i[l].children_d.length&&(h=h.concat(i[l].children_d)))},this)),j.children=g,j.children_d=h,m=0,n=j.parents.length;n>m;m++)i[j.parents[m]].children_d=i[j.parents[m]].children_d.concat(h);this.trigger("model",{nodes:h,parent:f}),f!==a.jstree.root?(this._node_changed(f),this.redraw()):(this.get_container_ul().children(".jstree-initial-node").remove(),this.redraw(!0)),this._data.core.selected.length!==k&&this.trigger("changed",{action:"model",selected:this._data.core.selected}),d.call(this,!0)},_append_json_data:function(b,c,d,e){if(null!==this.element){b=this.get_node(b),b.children=[],b.children_d=[],c.d&&(c=c.d,"string"==typeof c&&(c=JSON.parse(c))),a.isArray(c)||(c=[c]);var f=null,g={df:this._model.default_state,dat:c,par:b.id,m:this._model.data,t_id:this._id,t_cnt:this._cnt,sel:this._data.core.selected},h=function(a,b){a.data&&(a=a.data);var c=a.dat,d=a.par,e=[],f=[],g=[],h=a.df,i=a.t_id,j=a.t_cnt,k=a.m,l=k[d],m=a.sel,n,o,p,q,r=function(a,c,d){d=d?d.concat():[],c&&d.unshift(c);var e=a.id.toString(),f,i,j,l,m={id:e,text:a.text||"",icon:a.icon!==b?a.icon:!0,parent:c,parents:d,children:a.children||[],children_d:a.children_d||[],data:a.data,state:{},li_attr:{id:!1},a_attr:{href:"#"},original:!1};for(f in h)h.hasOwnProperty(f)&&(m.state[f]=h[f]);if(a&&a.data&&a.data.jstree&&a.data.jstree.icon&&(m.icon=a.data.jstree.icon),(m.icon===b||null===m.icon||""===m.icon)&&(m.icon=!0),a&&a.data&&(m.data=a.data,a.data.jstree))for(f in a.data.jstree)a.data.jstree.hasOwnProperty(f)&&(m.state[f]=a.data.jstree[f]);if(a&&"object"==typeof a.state)for(f in a.state)a.state.hasOwnProperty(f)&&(m.state[f]=a.state[f]);if(a&&"object"==typeof a.li_attr)for(f in a.li_attr)a.li_attr.hasOwnProperty(f)&&(m.li_attr[f]=a.li_attr[f]);if(m.li_attr.id||(m.li_attr.id=e),a&&"object"==typeof a.a_attr)for(f in a.a_attr)a.a_attr.hasOwnProperty(f)&&(m.a_attr[f]=a.a_attr[f]);for(a&&a.children&&a.children===!0&&(m.state.loaded=!1,m.children=[],m.children_d=[]),k[m.id]=m,f=0,i=m.children.length;i>f;f++)j=r(k[m.children[f]],m.id,d),l=k[j],m.children_d.push(j),l.children_d.length&&(m.children_d=m.children_d.concat(l.children_d));return delete a.data,delete a.children,k[m.id].original=a,m.state.selected&&g.push(m.id),m.id},s=function(a,c,d){d=d?d.concat():[],c&&d.unshift(c);var e=!1,f,l,m,n,o;do e="j"+i+"_"+ ++j;while(k[e]);o={id:!1,text:"string"==typeof a?a:"",icon:"object"==typeof a&&a.icon!==b?a.icon:!0,parent:c,parents:d,children:[],children_d:[],data:null,state:{},li_attr:{id:!1},a_attr:{href:"#"},original:!1};for(f in h)h.hasOwnProperty(f)&&(o.state[f]=h[f]);if(a&&a.id&&(o.id=a.id.toString()),a&&a.text&&(o.text=a.text),a&&a.data&&a.data.jstree&&a.data.jstree.icon&&(o.icon=a.data.jstree.icon),(o.icon===b||null===o.icon||""===o.icon)&&(o.icon=!0),a&&a.data&&(o.data=a.data,a.data.jstree))for(f in a.data.jstree)a.data.jstree.hasOwnProperty(f)&&(o.state[f]=a.data.jstree[f]);if(a&&"object"==typeof a.state)for(f in a.state)a.state.hasOwnProperty(f)&&(o.state[f]=a.state[f]);if(a&&"object"==typeof a.li_attr)for(f in a.li_attr)a.li_attr.hasOwnProperty(f)&&(o.li_attr[f]=a.li_attr[f]);if(o.li_attr.id&&!o.id&&(o.id=o.li_attr.id.toString()),o.id||(o.id=e),o.li_attr.id||(o.li_attr.id=o.id),a&&"object"==typeof a.a_attr)for(f in a.a_attr)a.a_attr.hasOwnProperty(f)&&(o.a_attr[f]=a.a_attr[f]);if(a&&a.children&&a.children.length){for(f=0,l=a.children.length;l>f;f++)m=s(a.children[f],o.id,d),n=k[m],o.children.push(m),n.children_d.length&&(o.children_d=o.children_d.concat(n.children_d));o.children_d=o.children_d.concat(o.children)}return a&&a.children&&a.children===!0&&(o.state.loaded=!1,o.children=[],o.children_d=[]),delete a.data,delete a.children,o.original=a,k[o.id]=o,o.state.selected&&g.push(o.id),o.id};if(c.length&&c[0].id!==b&&c[0].parent!==b){for(o=0,p=c.length;p>o;o++)c[o].children||(c[o].children=[]),k[c[o].id.toString()]=c[o];for(o=0,p=c.length;p>o;o++)k[c[o].parent.toString()].children.push(c[o].id.toString()),l.children_d.push(c[o].id.toString());for(o=0,p=l.children.length;p>o;o++)n=r(k[l.children[o]],d,l.parents.concat()),f.push(n),k[n].children_d.length&&(f=f.concat(k[n].children_d));for(o=0,p=l.parents.length;p>o;o++)k[l.parents[o]].children_d=k[l.parents[o]].children_d.concat(f);q={cnt:j,mod:k,sel:m,par:d,dpc:f,add:g}}else{for(o=0,p=c.length;p>o;o++)n=s(c[o],d,l.parents.concat()),n&&(e.push(n),f.push(n),k[n].children_d.length&&(f=f.concat(k[n].children_d)));for(l.children=e,l.children_d=f,o=0,p=l.parents.length;p>o;o++)k[l.parents[o]].children_d=k[l.parents[o]].children_d.concat(f);q={cnt:j,mod:k,sel:m,par:d,dpc:f,add:g}}return"undefined"!=typeof window&&"undefined"!=typeof window.document?q:void postMessage(q)},i=function(b,c){if(null!==this.element){this._cnt=b.cnt;var e,f=this._model.data;for(e in f)f.hasOwnProperty(e)&&f[e].state&&f[e].state.loading&&b.mod[e]&&(b.mod[e].state.loading=!0);if(this._model.data=b.mod,c){var g,h=b.add,i=b.sel,j=this._data.core.selected.slice();if(f=this._model.data,i.length!==j.length||a.vakata.array_unique(i.concat(j)).length!==i.length){for(e=0,g=i.length;g>e;e++)-1===a.inArray(i[e],h)&&-1===a.inArray(i[e],j)&&(f[i[e]].state.selected=!1);for(e=0,g=j.length;g>e;e++)-1===a.inArray(j[e],i)&&(f[j[e]].state.selected=!0)}}b.add.length&&(this._data.core.selected=this._data.core.selected.concat(b.add)),this.trigger("model",{nodes:b.dpc,parent:b.par}),b.par!==a.jstree.root?(this._node_changed(b.par),this.redraw()):this.redraw(!0),b.add.length&&this.trigger("changed",{action:"model",selected:this._data.core.selected}),d.call(this,!0)}};if(this.settings.core.worker&&window.Blob&&window.URL&&window.Worker)try{null===this._wrk&&(this._wrk=window.URL.createObjectURL(new window.Blob(["self.onmessage = "+h.toString()],{type:"text/javascript"}))),!this._data.core.working||e?(this._data.core.working=!0,f=new window.Worker(this._wrk),f.onmessage=a.proxy(function(a){i.call(this,a.data,!0);try{f.terminate(),f=null}catch(b){}this._data.core.worker_queue.length?this._append_json_data.apply(this,this._data.core.worker_queue.shift()):this._data.core.working=!1},this),g.par?f.postMessage(g):this._data.core.worker_queue.length?this._append_json_data.apply(this,this._data.core.worker_queue.shift()):this._data.core.working=!1):this._data.core.worker_queue.push([b,c,d,!0])}catch(j){i.call(this,h(g),!1),this._data.core.worker_queue.length?this._append_json_data.apply(this,this._data.core.worker_queue.shift()):this._data.core.working=!1}else i.call(this,h(g),!1)}},_parse_model_from_html:function(c,d,e){e=e?[].concat(e):[],d&&e.unshift(d);var f,g,h=this._model.data,i={id:!1,text:!1,icon:!0,parent:d,parents:e,children:[],children_d:[],data:null,state:{},li_attr:{id:!1},a_attr:{href:"#"},original:!1},j,k,l;for(j in this._model.default_state)this._model.default_state.hasOwnProperty(j)&&(i.state[j]=this._model.default_state[j]);if(k=a.vakata.attributes(c,!0),a.each(k,function(b,c){return c=a.trim(c),c.length?(i.li_attr[b]=c,void("id"===b&&(i.id=c.toString()))):!0}),k=c.children("a").first(),k.length&&(k=a.vakata.attributes(k,!0),a.each(k,function(b,c){c=a.trim(c),c.length&&(i.a_attr[b]=c)})),k=c.children("a").first().length?c.children("a").first().clone():c.clone(),k.children("ins, i, ul").remove(),k=k.html(),k=a("<div />").html(k),i.text=this.settings.core.force_text?k.text():k.html(),k=c.data(),i.data=k?a.extend(!0,{},k):null,i.state.opened=c.hasClass("jstree-open"),i.state.selected=c.children("a").hasClass("jstree-clicked"),i.state.disabled=c.children("a").hasClass("jstree-disabled"),i.data&&i.data.jstree)for(j in i.data.jstree)i.data.jstree.hasOwnProperty(j)&&(i.state[j]=i.data.jstree[j]);k=c.children("a").children(".jstree-themeicon"),k.length&&(i.icon=k.hasClass("jstree-themeicon-hidden")?!1:k.attr("rel")),i.state.icon!==b&&(i.icon=i.state.icon),(i.icon===b||null===i.icon||""===i.icon)&&(i.icon=!0),k=c.children("ul").children("li");do l="j"+this._id+"_"+ ++this._cnt;while(h[l]);return i.id=i.li_attr.id?i.li_attr.id.toString():l,k.length?(k.each(a.proxy(function(b,c){f=this._parse_model_from_html(a(c),i.id,e),g=this._model.data[f],i.children.push(f),g.children_d.length&&(i.children_d=i.children_d.concat(g.children_d))},this)),i.children_d=i.children_d.concat(i.children)):c.hasClass("jstree-closed")&&(i.state.loaded=!1),i.li_attr["class"]&&(i.li_attr["class"]=i.li_attr["class"].replace("jstree-closed","").replace("jstree-open","")),i.a_attr["class"]&&(i.a_attr["class"]=i.a_attr["class"].replace("jstree-clicked","").replace("jstree-disabled","")),h[i.id]=i,i.state.selected&&this._data.core.selected.push(i.id),i.id},_parse_model_from_flat_json:function(a,c,d){d=d?d.concat():[],c&&d.unshift(c);var e=a.id.toString(),f=this._model.data,g=this._model.default_state,h,i,j,k,l={id:e,text:a.text||"",icon:a.icon!==b?a.icon:!0,parent:c,parents:d,children:a.children||[],children_d:a.children_d||[],data:a.data,state:{},li_attr:{id:!1},a_attr:{href:"#"},original:!1};for(h in g)g.hasOwnProperty(h)&&(l.state[h]=g[h]);if(a&&a.data&&a.data.jstree&&a.data.jstree.icon&&(l.icon=a.data.jstree.icon),(l.icon===b||null===l.icon||""===l.icon)&&(l.icon=!0),a&&a.data&&(l.data=a.data,a.data.jstree))for(h in a.data.jstree)a.data.jstree.hasOwnProperty(h)&&(l.state[h]=a.data.jstree[h]);if(a&&"object"==typeof a.state)for(h in a.state)a.state.hasOwnProperty(h)&&(l.state[h]=a.state[h]);if(a&&"object"==typeof a.li_attr)for(h in a.li_attr)a.li_attr.hasOwnProperty(h)&&(l.li_attr[h]=a.li_attr[h]);if(l.li_attr.id||(l.li_attr.id=e),a&&"object"==typeof a.a_attr)for(h in a.a_attr)a.a_attr.hasOwnProperty(h)&&(l.a_attr[h]=a.a_attr[h]);for(a&&a.children&&a.children===!0&&(l.state.loaded=!1,l.children=[],l.children_d=[]),f[l.id]=l,h=0,i=l.children.length;i>h;h++)j=this._parse_model_from_flat_json(f[l.children[h]],l.id,d),k=f[j],l.children_d.push(j),k.children_d.length&&(l.children_d=l.children_d.concat(k.children_d));return delete a.data,delete a.children,f[l.id].original=a,l.state.selected&&this._data.core.selected.push(l.id),l.id},_parse_model_from_json:function(a,c,d){d=d?d.concat():[],c&&d.unshift(c);var e=!1,f,g,h,i,j=this._model.data,k=this._model.default_state,l;do e="j"+this._id+"_"+ ++this._cnt;while(j[e]);l={id:!1,text:"string"==typeof a?a:"",icon:"object"==typeof a&&a.icon!==b?a.icon:!0,parent:c,parents:d,children:[],children_d:[],data:null,state:{},li_attr:{id:!1},a_attr:{href:"#"},original:!1};for(f in k)k.hasOwnProperty(f)&&(l.state[f]=k[f]);if(a&&a.id&&(l.id=a.id.toString()),a&&a.text&&(l.text=a.text),a&&a.data&&a.data.jstree&&a.data.jstree.icon&&(l.icon=a.data.jstree.icon),(l.icon===b||null===l.icon||""===l.icon)&&(l.icon=!0),a&&a.data&&(l.data=a.data,a.data.jstree))for(f in a.data.jstree)a.data.jstree.hasOwnProperty(f)&&(l.state[f]=a.data.jstree[f]);if(a&&"object"==typeof a.state)for(f in a.state)a.state.hasOwnProperty(f)&&(l.state[f]=a.state[f]);if(a&&"object"==typeof a.li_attr)for(f in a.li_attr)a.li_attr.hasOwnProperty(f)&&(l.li_attr[f]=a.li_attr[f]);if(l.li_attr.id&&!l.id&&(l.id=l.li_attr.id.toString()),l.id||(l.id=e),l.li_attr.id||(l.li_attr.id=l.id),a&&"object"==typeof a.a_attr)for(f in a.a_attr)a.a_attr.hasOwnProperty(f)&&(l.a_attr[f]=a.a_attr[f]);if(a&&a.children&&a.children.length){for(f=0,g=a.children.length;g>f;f++)h=this._parse_model_from_json(a.children[f],l.id,d),i=j[h],l.children.push(h),i.children_d.length&&(l.children_d=l.children_d.concat(i.children_d));l.children_d=l.children_d.concat(l.children)}return a&&a.children&&a.children===!0&&(l.state.loaded=!1,l.children=[],l.children_d=[]),delete a.data,delete a.children,l.original=a,j[l.id]=l,l.state.selected&&this._data.core.selected.push(l.id),l.id},_redraw:function(){var b=this._model.force_full_redraw?this._model.data[a.jstree.root].children.concat([]):this._model.changed.concat([]),c=i.createElement("UL"),d,e,f,g=this._data.core.focused;for(e=0,f=b.length;f>e;e++)d=this.redraw_node(b[e],!0,this._model.force_full_redraw),d&&this._model.force_full_redraw&&c.appendChild(d);this._model.force_full_redraw&&(c.className=this.get_container_ul()[0].className,c.setAttribute("role","group"),this.element.empty().append(c)),null!==g&&(d=this.get_node(g,!0),d&&d.length&&d.children(".jstree-anchor")[0]!==i.activeElement?d.children(".jstree-anchor").focus():this._data.core.focused=null),this._model.force_full_redraw=!1,this._model.changed=[],this.trigger("redraw",{nodes:b})},redraw:function(a){a&&(this._model.force_full_redraw=!0),this._redraw()},draw_children:function(b){var c=this.get_node(b),d=!1,e=!1,f=!1,g=i;if(!c)return!1;if(c.id===a.jstree.root)return this.redraw(!0);if(b=this.get_node(b,!0),!b||!b.length)return!1;if(b.children(".jstree-children").remove(),b=b[0],c.children.length&&c.state.loaded){for(f=g.createElement("UL"),f.setAttribute("role","group"),f.className="jstree-children",d=0,e=c.children.length;e>d;d++)f.appendChild(this.redraw_node(c.children[d],!0,!0));b.appendChild(f)}},redraw_node:function(b,c,d,e){var f=this.get_node(b),g=!1,h=!1,j=!1,k=!1,l=!1,m=!1,n="",o=i,p=this._model.data,q=!1,r=!1,s=null,t=0,u=0,v=!1,w=!1; +if(!f)return!1;if(f.id===a.jstree.root)return this.redraw(!0);if(c=c||0===f.children.length,b=i.querySelector?this.element[0].querySelector("#"+(-1!=="0123456789".indexOf(f.id[0])?"\\3"+f.id[0]+" "+f.id.substr(1).replace(a.jstree.idregex,"\\$&"):f.id.replace(a.jstree.idregex,"\\$&"))):i.getElementById(f.id))b=a(b),d||(g=b.parent().parent()[0],g===this.element[0]&&(g=null),h=b.index()),c||!f.children.length||b.children(".jstree-children").length||(c=!0),c||(j=b.children(".jstree-children")[0]),q=b.children(".jstree-anchor")[0]===i.activeElement,b.remove();else if(c=!0,!d){if(g=f.parent!==a.jstree.root?a("#"+f.parent.replace(a.jstree.idregex,"\\$&"),this.element)[0]:null,!(null===g||g&&p[f.parent].state.opened))return!1;h=a.inArray(f.id,null===g?p[a.jstree.root].children:p[f.parent].children)}b=this._data.core.node.cloneNode(!0),n="jstree-node ";for(k in f.li_attr)if(f.li_attr.hasOwnProperty(k)){if("id"===k)continue;"class"!==k?b.setAttribute(k,f.li_attr[k]):n+=f.li_attr[k]}for(f.a_attr.id||(f.a_attr.id=f.id+"_anchor"),b.setAttribute("aria-selected",!!f.state.selected),b.setAttribute("aria-level",f.parents.length),b.setAttribute("aria-labelledby",f.a_attr.id),f.state.disabled&&b.setAttribute("aria-disabled",!0),k=0,l=f.children.length;l>k;k++)if(!p[f.children[k]].state.hidden){v=!0;break}if(null!==f.parent&&p[f.parent]&&!f.state.hidden&&(k=a.inArray(f.id,p[f.parent].children),w=f.id,-1!==k))for(k++,l=p[f.parent].children.length;l>k;k++)if(p[p[f.parent].children[k]].state.hidden||(w=p[f.parent].children[k]),w!==f.id)break;f.state.hidden&&(n+=" jstree-hidden"),f.state.loaded&&!v?n+=" jstree-leaf":(n+=f.state.opened&&f.state.loaded?" jstree-open":" jstree-closed",b.setAttribute("aria-expanded",f.state.opened&&f.state.loaded)),w===f.id&&(n+=" jstree-last"),b.id=f.id,b.className=n,n=(f.state.selected?" jstree-clicked":"")+(f.state.disabled?" jstree-disabled":"");for(l in f.a_attr)if(f.a_attr.hasOwnProperty(l)){if("href"===l&&"#"===f.a_attr[l])continue;"class"!==l?b.childNodes[1].setAttribute(l,f.a_attr[l]):n+=" "+f.a_attr[l]}if(n.length&&(b.childNodes[1].className="jstree-anchor "+n),(f.icon&&f.icon!==!0||f.icon===!1)&&(f.icon===!1?b.childNodes[1].childNodes[0].className+=" jstree-themeicon-hidden":-1===f.icon.indexOf("/")&&-1===f.icon.indexOf(".")?b.childNodes[1].childNodes[0].className+=" "+f.icon+" jstree-themeicon-custom":(b.childNodes[1].childNodes[0].style.backgroundImage='url("'+f.icon+'")',b.childNodes[1].childNodes[0].style.backgroundPosition="center center",b.childNodes[1].childNodes[0].style.backgroundSize="auto",b.childNodes[1].childNodes[0].className+=" jstree-themeicon-custom")),this.settings.core.force_text?b.childNodes[1].appendChild(o.createTextNode(f.text)):b.childNodes[1].innerHTML+=f.text,c&&f.children.length&&(f.state.opened||e)&&f.state.loaded){for(m=o.createElement("UL"),m.setAttribute("role","group"),m.className="jstree-children",k=0,l=f.children.length;l>k;k++)m.appendChild(this.redraw_node(f.children[k],c,!0));b.appendChild(m)}if(j&&b.appendChild(j),!d){for(g||(g=this.element[0]),k=0,l=g.childNodes.length;l>k;k++)if(g.childNodes[k]&&g.childNodes[k].className&&-1!==g.childNodes[k].className.indexOf("jstree-children")){s=g.childNodes[k];break}s||(s=o.createElement("UL"),s.setAttribute("role","group"),s.className="jstree-children",g.appendChild(s)),g=s,h<g.childNodes.length?g.insertBefore(b,g.childNodes[h]):g.appendChild(b),q&&(t=this.element[0].scrollTop,u=this.element[0].scrollLeft,b.childNodes[1].focus(),this.element[0].scrollTop=t,this.element[0].scrollLeft=u)}return f.state.opened&&!f.state.loaded&&(f.state.opened=!1,setTimeout(a.proxy(function(){this.open_node(f.id,!1,0)},this),0)),b},open_node:function(c,d,e){var f,g,h,i;if(a.isArray(c)){for(c=c.slice(),f=0,g=c.length;g>f;f++)this.open_node(c[f],d,e);return!0}return c=this.get_node(c),c&&c.id!==a.jstree.root?(e=e===b?this.settings.core.animation:e,this.is_closed(c)?this.is_loaded(c)?(h=this.get_node(c,!0),i=this,h.length&&(e&&h.children(".jstree-children").length&&h.children(".jstree-children").stop(!0,!0),c.children.length&&!this._firstChild(h.children(".jstree-children")[0])&&this.draw_children(c),e?(this.trigger("before_open",{node:c}),h.children(".jstree-children").css("display","none").end().removeClass("jstree-closed").addClass("jstree-open").attr("aria-expanded",!0).children(".jstree-children").stop(!0,!0).slideDown(e,function(){this.style.display="",i.element&&i.trigger("after_open",{node:c})})):(this.trigger("before_open",{node:c}),h[0].className=h[0].className.replace("jstree-closed","jstree-open"),h[0].setAttribute("aria-expanded",!0))),c.state.opened=!0,d&&d.call(this,c,!0),h.length||this.trigger("before_open",{node:c}),this.trigger("open_node",{node:c}),e&&h.length||this.trigger("after_open",{node:c}),!0):this.is_loading(c)?setTimeout(a.proxy(function(){this.open_node(c,d,e)},this),500):void this.load_node(c,function(a,b){return b?this.open_node(a,d,e):d?d.call(this,a,!1):!1}):(d&&d.call(this,c,!1),!1)):!1},_open_to:function(b){if(b=this.get_node(b),!b||b.id===a.jstree.root)return!1;var c,d,e=b.parents;for(c=0,d=e.length;d>c;c+=1)c!==a.jstree.root&&this.open_node(e[c],!1,0);return a("#"+b.id.replace(a.jstree.idregex,"\\$&"),this.element)},close_node:function(c,d){var e,f,g,h;if(a.isArray(c)){for(c=c.slice(),e=0,f=c.length;f>e;e++)this.close_node(c[e],d);return!0}return c=this.get_node(c),c&&c.id!==a.jstree.root?this.is_closed(c)?!1:(d=d===b?this.settings.core.animation:d,g=this,h=this.get_node(c,!0),c.state.opened=!1,this.trigger("close_node",{node:c}),void(h.length?d?h.children(".jstree-children").attr("style","display:block !important").end().removeClass("jstree-open").addClass("jstree-closed").attr("aria-expanded",!1).children(".jstree-children").stop(!0,!0).slideUp(d,function(){this.style.display="",h.children(".jstree-children").remove(),g.element&&g.trigger("after_close",{node:c})}):(h[0].className=h[0].className.replace("jstree-open","jstree-closed"),h.attr("aria-expanded",!1).children(".jstree-children").remove(),this.trigger("after_close",{node:c})):this.trigger("after_close",{node:c}))):!1},toggle_node:function(b){var c,d;if(a.isArray(b)){for(b=b.slice(),c=0,d=b.length;d>c;c++)this.toggle_node(b[c]);return!0}return this.is_closed(b)?this.open_node(b):this.is_open(b)?this.close_node(b):void 0},open_all:function(b,c,d){if(b||(b=a.jstree.root),b=this.get_node(b),!b)return!1;var e=b.id===a.jstree.root?this.get_container_ul():this.get_node(b,!0),f,g,h;if(!e.length){for(f=0,g=b.children_d.length;g>f;f++)this.is_closed(this._model.data[b.children_d[f]])&&(this._model.data[b.children_d[f]].state.opened=!0);return this.trigger("open_all",{node:b})}d=d||e,h=this,e=this.is_closed(b)?e.find(".jstree-closed").addBack():e.find(".jstree-closed"),e.each(function(){h.open_node(this,function(a,b){b&&this.is_parent(a)&&this.open_all(a,c,d)},c||0)}),0===d.find(".jstree-closed").length&&this.trigger("open_all",{node:this.get_node(d)})},close_all:function(b,c){if(b||(b=a.jstree.root),b=this.get_node(b),!b)return!1;var d=b.id===a.jstree.root?this.get_container_ul():this.get_node(b,!0),e=this,f,g;for(d.length&&(d=this.is_open(b)?d.find(".jstree-open").addBack():d.find(".jstree-open"),a(d.get().reverse()).each(function(){e.close_node(this,c||0)})),f=0,g=b.children_d.length;g>f;f++)this._model.data[b.children_d[f]].state.opened=!1;this.trigger("close_all",{node:b})},is_disabled:function(a){return a=this.get_node(a),a&&a.state&&a.state.disabled},enable_node:function(b){var c,d;if(a.isArray(b)){for(b=b.slice(),c=0,d=b.length;d>c;c++)this.enable_node(b[c]);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(b.state.disabled=!1,this.get_node(b,!0).children(".jstree-anchor").removeClass("jstree-disabled").attr("aria-disabled",!1),void this.trigger("enable_node",{node:b})):!1},disable_node:function(b){var c,d;if(a.isArray(b)){for(b=b.slice(),c=0,d=b.length;d>c;c++)this.disable_node(b[c]);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(b.state.disabled=!0,this.get_node(b,!0).children(".jstree-anchor").addClass("jstree-disabled").attr("aria-disabled",!0),void this.trigger("disable_node",{node:b})):!1},is_hidden:function(a){return a=this.get_node(a),a.state.hidden===!0},hide_node:function(b,c){var d,e;if(a.isArray(b)){for(b=b.slice(),d=0,e=b.length;e>d;d++)this.hide_node(b[d],!0);return c||this.redraw(),!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?void(b.state.hidden||(b.state.hidden=!0,this._node_changed(b.parent),c||this.redraw(),this.trigger("hide_node",{node:b}))):!1},show_node:function(b,c){var d,e;if(a.isArray(b)){for(b=b.slice(),d=0,e=b.length;e>d;d++)this.show_node(b[d],!0);return c||this.redraw(),!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?void(b.state.hidden&&(b.state.hidden=!1,this._node_changed(b.parent),c||this.redraw(),this.trigger("show_node",{node:b}))):!1},hide_all:function(b){var c,d=this._model.data,e=[];for(c in d)d.hasOwnProperty(c)&&c!==a.jstree.root&&!d[c].state.hidden&&(d[c].state.hidden=!0,e.push(c));return this._model.force_full_redraw=!0,b||this.redraw(),this.trigger("hide_all",{nodes:e}),e},show_all:function(b){var c,d=this._model.data,e=[];for(c in d)d.hasOwnProperty(c)&&c!==a.jstree.root&&d[c].state.hidden&&(d[c].state.hidden=!1,e.push(c));return this._model.force_full_redraw=!0,b||this.redraw(),this.trigger("show_all",{nodes:e}),e},activate_node:function(a,c){if(this.is_disabled(a))return!1;if(c&&"object"==typeof c||(c={}),this._data.core.last_clicked=this._data.core.last_clicked&&this._data.core.last_clicked.id!==b?this.get_node(this._data.core.last_clicked.id):null,this._data.core.last_clicked&&!this._data.core.last_clicked.state.selected&&(this._data.core.last_clicked=null),!this._data.core.last_clicked&&this._data.core.selected.length&&(this._data.core.last_clicked=this.get_node(this._data.core.selected[this._data.core.selected.length-1])),this.settings.core.multiple&&(c.metaKey||c.ctrlKey||c.shiftKey)&&(!c.shiftKey||this._data.core.last_clicked&&this.get_parent(a)&&this.get_parent(a)===this._data.core.last_clicked.parent))if(c.shiftKey){var d=this.get_node(a).id,e=this._data.core.last_clicked.id,f=this.get_node(this._data.core.last_clicked.parent).children,g=!1,h,i;for(h=0,i=f.length;i>h;h+=1)f[h]===d&&(g=!g),f[h]===e&&(g=!g),this.is_disabled(f[h])||!g&&f[h]!==d&&f[h]!==e?this.deselect_node(f[h],!0,c):this.is_hidden(f[h])||this.select_node(f[h],!0,!1,c);this.trigger("changed",{action:"select_node",node:this.get_node(a),selected:this._data.core.selected,event:c})}else this.is_selected(a)?this.deselect_node(a,!1,c):this.select_node(a,!1,!1,c);else!this.settings.core.multiple&&(c.metaKey||c.ctrlKey||c.shiftKey)&&this.is_selected(a)?this.deselect_node(a,!1,c):(this.deselect_all(!0),this.select_node(a,!1,!1,c),this._data.core.last_clicked=this.get_node(a));this.trigger("activate_node",{node:this.get_node(a),event:c})},hover_node:function(a){if(a=this.get_node(a,!0),!a||!a.length||a.children(".jstree-hovered").length)return!1;var b=this.element.find(".jstree-hovered"),c=this.element;b&&b.length&&this.dehover_node(b),a.children(".jstree-anchor").addClass("jstree-hovered"),this.trigger("hover_node",{node:this.get_node(a)}),setTimeout(function(){c.attr("aria-activedescendant",a[0].id)},0)},dehover_node:function(a){return a=this.get_node(a,!0),a&&a.length&&a.children(".jstree-hovered").length?(a.children(".jstree-anchor").removeClass("jstree-hovered"),void this.trigger("dehover_node",{node:this.get_node(a)})):!1},select_node:function(b,c,d,e){var f,g,h,i;if(a.isArray(b)){for(b=b.slice(),g=0,h=b.length;h>g;g++)this.select_node(b[g],c,d,e);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(f=this.get_node(b,!0),void(b.state.selected||(b.state.selected=!0,this._data.core.selected.push(b.id),d||(f=this._open_to(b)),f&&f.length&&f.attr("aria-selected",!0).children(".jstree-anchor").addClass("jstree-clicked"),this.trigger("select_node",{node:b,selected:this._data.core.selected,event:e}),c||this.trigger("changed",{action:"select_node",node:b,selected:this._data.core.selected,event:e})))):!1},deselect_node:function(b,c,d){var e,f,g;if(a.isArray(b)){for(b=b.slice(),e=0,f=b.length;f>e;e++)this.deselect_node(b[e],c,d);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(g=this.get_node(b,!0),void(b.state.selected&&(b.state.selected=!1,this._data.core.selected=a.vakata.array_remove_item(this._data.core.selected,b.id),g.length&&g.attr("aria-selected",!1).children(".jstree-anchor").removeClass("jstree-clicked"),this.trigger("deselect_node",{node:b,selected:this._data.core.selected,event:d}),c||this.trigger("changed",{action:"deselect_node",node:b,selected:this._data.core.selected,event:d})))):!1},select_all:function(b){var c=this._data.core.selected.concat([]),d,e;for(this._data.core.selected=this._model.data[a.jstree.root].children_d.concat(),d=0,e=this._data.core.selected.length;e>d;d++)this._model.data[this._data.core.selected[d]]&&(this._model.data[this._data.core.selected[d]].state.selected=!0);this.redraw(!0),this.trigger("select_all",{selected:this._data.core.selected}),b||this.trigger("changed",{action:"select_all",selected:this._data.core.selected,old_selection:c})},deselect_all:function(a){var b=this._data.core.selected.concat([]),c,d;for(c=0,d=this._data.core.selected.length;d>c;c++)this._model.data[this._data.core.selected[c]]&&(this._model.data[this._data.core.selected[c]].state.selected=!1);this._data.core.selected=[],this.element.find(".jstree-clicked").removeClass("jstree-clicked").parent().attr("aria-selected",!1),this.trigger("deselect_all",{selected:this._data.core.selected,node:b}),a||this.trigger("changed",{action:"deselect_all",selected:this._data.core.selected,old_selection:b})},is_selected:function(b){return b=this.get_node(b),b&&b.id!==a.jstree.root?b.state.selected:!1},get_selected:function(b){return b?a.map(this._data.core.selected,a.proxy(function(a){return this.get_node(a)},this)):this._data.core.selected.slice()},get_top_selected:function(b){var c=this.get_selected(!0),d={},e,f,g,h;for(e=0,f=c.length;f>e;e++)d[c[e].id]=c[e];for(e=0,f=c.length;f>e;e++)for(g=0,h=c[e].children_d.length;h>g;g++)d[c[e].children_d[g]]&&delete d[c[e].children_d[g]];c=[];for(e in d)d.hasOwnProperty(e)&&c.push(e);return b?a.map(c,a.proxy(function(a){return this.get_node(a)},this)):c},get_bottom_selected:function(b){var c=this.get_selected(!0),d=[],e,f;for(e=0,f=c.length;f>e;e++)c[e].children.length||d.push(c[e].id);return b?a.map(d,a.proxy(function(a){return this.get_node(a)},this)):d},get_state:function(){var b={core:{open:[],scroll:{left:this.element.scrollLeft(),top:this.element.scrollTop()},selected:[]}},c;for(c in this._model.data)this._model.data.hasOwnProperty(c)&&c!==a.jstree.root&&(this._model.data[c].state.opened&&b.core.open.push(c),this._model.data[c].state.selected&&b.core.selected.push(c));return b},set_state:function(c,d){if(c){if(c.core){var e,f,g,h,i;if(c.core.open)return a.isArray(c.core.open)&&c.core.open.length?this._load_nodes(c.core.open,function(a){this.open_node(a,!1,0),delete c.core.open,this.set_state(c,d)}):(delete c.core.open,this.set_state(c,d)),!1;if(c.core.scroll)return c.core.scroll&&c.core.scroll.left!==b&&this.element.scrollLeft(c.core.scroll.left),c.core.scroll&&c.core.scroll.top!==b&&this.element.scrollTop(c.core.scroll.top),delete c.core.scroll,this.set_state(c,d),!1;if(c.core.selected)return h=this,this.deselect_all(),a.each(c.core.selected,function(a,b){h.select_node(b,!1,!0)}),delete c.core.selected,this.set_state(c,d),!1;for(i in c)c.hasOwnProperty(i)&&"core"!==i&&-1===a.inArray(i,this.settings.plugins)&&delete c[i];if(a.isEmptyObject(c.core))return delete c.core,this.set_state(c,d),!1}return a.isEmptyObject(c)?(c=null,d&&d.call(this),this.trigger("set_state"),!1):!0}return!1},refresh:function(b,c){this._data.core.state=c===!0?{}:this.get_state(),c&&a.isFunction(c)&&(this._data.core.state=c.call(this,this._data.core.state)),this._cnt=0,this._model.data={},this._model.data[a.jstree.root]={id:a.jstree.root,parent:null,parents:[],children:[],children_d:[],state:{loaded:!1}},this._data.core.selected=[],this._data.core.last_clicked=null,this._data.core.focused=null;var d=this.get_container_ul()[0].className;b||(this.element.html("<ul class='"+d+"' role='group'><li class='jstree-initial-node jstree-loading jstree-leaf jstree-last' role='treeitem' id='j"+this._id+"_loading'><i class='jstree-icon jstree-ocl'></i><a class='jstree-anchor' href='#'><i class='jstree-icon jstree-themeicon-hidden'></i>"+this.get_string("Loading ...")+"</a></li></ul>"),this.element.attr("aria-activedescendant","j"+this._id+"_loading")),this.load_node(a.jstree.root,function(b,c){c&&(this.get_container_ul()[0].className=d,this._firstChild(this.get_container_ul()[0])&&this.element.attr("aria-activedescendant",this._firstChild(this.get_container_ul()[0]).id),this.set_state(a.extend(!0,{},this._data.core.state),function(){this.trigger("refresh")})),this._data.core.state=null})},refresh_node:function(b){if(b=this.get_node(b),!b||b.id===a.jstree.root)return!1;var c=[],d=[],e=this._data.core.selected.concat([]);d.push(b.id),b.state.opened===!0&&c.push(b.id),this.get_node(b,!0).find(".jstree-open").each(function(){d.push(this.id),c.push(this.id)}),this._load_nodes(d,a.proxy(function(a){this.open_node(c,!1,0),this.select_node(e),this.trigger("refresh_node",{node:b,nodes:a})},this),!1,!0)},set_id:function(b,c){if(b=this.get_node(b),!b||b.id===a.jstree.root)return!1;var d,e,f=this._model.data,g=b.id;for(c=c.toString(),f[b.parent].children[a.inArray(b.id,f[b.parent].children)]=c,d=0,e=b.parents.length;e>d;d++)f[b.parents[d]].children_d[a.inArray(b.id,f[b.parents[d]].children_d)]=c;for(d=0,e=b.children.length;e>d;d++)f[b.children[d]].parent=c;for(d=0,e=b.children_d.length;e>d;d++)f[b.children_d[d]].parents[a.inArray(b.id,f[b.children_d[d]].parents)]=c;return d=a.inArray(b.id,this._data.core.selected),-1!==d&&(this._data.core.selected[d]=c),d=this.get_node(b.id,!0),d&&(d.attr("id",c),this.element.attr("aria-activedescendant")===b.id&&this.element.attr("aria-activedescendant",c)),delete f[b.id],b.id=c,b.li_attr.id=c,f[c]=b,this.trigger("set_id",{node:b,"new":b.id,old:g}),!0},get_text:function(b){return b=this.get_node(b),b&&b.id!==a.jstree.root?b.text:!1},set_text:function(b,c){var d,e;if(a.isArray(b)){for(b=b.slice(),d=0,e=b.length;e>d;d++)this.set_text(b[d],c);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(b.text=c,this.get_node(b,!0).length&&this.redraw_node(b.id),this.trigger("set_text",{obj:b,text:c}),!0):!1},get_json:function(b,c,d){if(b=this.get_node(b||a.jstree.root),!b)return!1;c&&c.flat&&!d&&(d=[]);var e={id:b.id,text:b.text,icon:this.get_icon(b),li_attr:a.extend(!0,{},b.li_attr),a_attr:a.extend(!0,{},b.a_attr),state:{},data:c&&c.no_data?!1:a.extend(!0,{},b.data)},f,g;if(c&&c.flat?e.parent=b.parent:e.children=[],c&&c.no_state)delete e.state;else for(f in b.state)b.state.hasOwnProperty(f)&&(e.state[f]=b.state[f]);if(c&&c.no_li_attr&&delete e.li_attr,c&&c.no_a_attr&&delete e.a_attr,c&&c.no_id&&(delete e.id,e.li_attr&&e.li_attr.id&&delete e.li_attr.id,e.a_attr&&e.a_attr.id&&delete e.a_attr.id),c&&c.flat&&b.id!==a.jstree.root&&d.push(e),!c||!c.no_children)for(f=0,g=b.children.length;g>f;f++)c&&c.flat?this.get_json(b.children[f],c,d):e.children.push(this.get_json(b.children[f],c));return c&&c.flat?d:b.id===a.jstree.root?e.children:e},create_node:function(c,d,e,f,g){if(null===c&&(c=a.jstree.root),c=this.get_node(c),!c)return!1;if(e=e===b?"last":e,!e.toString().match(/^(before|after)$/)&&!g&&!this.is_loaded(c))return this.load_node(c,function(){this.create_node(c,d,e,f,!0)});d||(d={text:this.get_string("New node")}),"string"==typeof d&&(d={text:d}),d.text===b&&(d.text=this.get_string("New node"));var h,i,j,k;switch(c.id===a.jstree.root&&("before"===e&&(e="first"),"after"===e&&(e="last")),e){case"before":h=this.get_node(c.parent),e=a.inArray(c.id,h.children),c=h;break;case"after":h=this.get_node(c.parent),e=a.inArray(c.id,h.children)+1,c=h;break;case"inside":case"first":e=0;break;case"last":e=c.children.length;break;default:e||(e=0)}if(e>c.children.length&&(e=c.children.length),d.id||(d.id=!0),!this.check("create_node",d,c,e))return this.settings.core.error.call(this,this._data.core.last_error),!1;if(d.id===!0&&delete d.id,d=this._parse_model_from_json(d,c.id,c.parents.concat()),!d)return!1;for(h=this.get_node(d),i=[],i.push(d),i=i.concat(h.children_d),this.trigger("model",{nodes:i,parent:c.id}),c.children_d=c.children_d.concat(i),j=0,k=c.parents.length;k>j;j++)this._model.data[c.parents[j]].children_d=this._model.data[c.parents[j]].children_d.concat(i);for(d=h,h=[],j=0,k=c.children.length;k>j;j++)h[j>=e?j+1:j]=c.children[j];return h[e]=d.id,c.children=h,this.redraw_node(c,!0),f&&f.call(this,this.get_node(d)),this.trigger("create_node",{node:this.get_node(d),parent:c.id,position:e}),d.id},rename_node:function(b,c){var d,e,f;if(a.isArray(b)){for(b=b.slice(),d=0,e=b.length;e>d;d++)this.rename_node(b[d],c);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(f=b.text,this.check("rename_node",b,this.get_parent(b),c)?(this.set_text(b,c),this.trigger("rename_node",{node:b,text:c,old:f}),!0):(this.settings.core.error.call(this,this._data.core.last_error),!1)):!1},delete_node:function(b){var c,d,e,f,g,h,i,j,k,l,m,n;if(a.isArray(b)){for(b=b.slice(),c=0,d=b.length;d>c;c++)this.delete_node(b[c]);return!0}if(b=this.get_node(b),!b||b.id===a.jstree.root)return!1;if(e=this.get_node(b.parent),f=a.inArray(b.id,e.children),l=!1,!this.check("delete_node",b,e,f))return this.settings.core.error.call(this,this._data.core.last_error),!1;for(-1!==f&&(e.children=a.vakata.array_remove(e.children,f)),g=b.children_d.concat([]),g.push(b.id),h=0,i=b.parents.length;i>h;h++)this._model.data[b.parents[h]].children_d=a.vakata.array_filter(this._model.data[b.parents[h]].children_d,function(b){return-1===a.inArray(b,g)});for(j=0,k=g.length;k>j;j++)if(this._model.data[g[j]].state.selected){l=!0;break}for(l&&(this._data.core.selected=a.vakata.array_filter(this._data.core.selected,function(b){return-1===a.inArray(b,g)})),this.trigger("delete_node",{node:b,parent:e.id}),l&&this.trigger("changed",{action:"delete_node",node:b,selected:this._data.core.selected,parent:e.id}),j=0,k=g.length;k>j;j++)delete this._model.data[g[j]];return-1!==a.inArray(this._data.core.focused,g)&&(this._data.core.focused=null,m=this.element[0].scrollTop,n=this.element[0].scrollLeft,e.id===a.jstree.root?this._model.data[a.jstree.root].children[0]&&this.get_node(this._model.data[a.jstree.root].children[0],!0).children(".jstree-anchor").focus():this.get_node(e,!0).children(".jstree-anchor").focus(),this.element[0].scrollTop=m,this.element[0].scrollLeft=n),this.redraw_node(e,!0),!0},check:function(b,c,d,e,f){c=c&&c.id?c:this.get_node(c),d=d&&d.id?d:this.get_node(d);var g=b.match(/^move_node|copy_node|create_node$/i)?d:c,h=this.settings.core.check_callback;return"move_node"!==b&&"copy_node"!==b||f&&f.is_multi||c.id!==d.id&&("move_node"!==b||a.inArray(c.id,d.children)!==e)&&-1===a.inArray(d.id,c.children_d)?(g&&g.data&&(g=g.data),g&&g.functions&&(g.functions[b]===!1||g.functions[b]===!0)?(g.functions[b]===!1&&(this._data.core.last_error={error:"check",plugin:"core",id:"core_02",reason:"Node data prevents function: "+b,data:JSON.stringify({chk:b,pos:e,obj:c&&c.id?c.id:!1,par:d&&d.id?d.id:!1})}),g.functions[b]):h===!1||a.isFunction(h)&&h.call(this,b,c,d,e,f)===!1||h&&h[b]===!1?(this._data.core.last_error={error:"check",plugin:"core",id:"core_03",reason:"User config for core.check_callback prevents function: "+b,data:JSON.stringify({chk:b,pos:e,obj:c&&c.id?c.id:!1,par:d&&d.id?d.id:!1})},!1):!0):(this._data.core.last_error={error:"check",plugin:"core",id:"core_01",reason:"Moving parent inside child",data:JSON.stringify({chk:b,pos:e,obj:c&&c.id?c.id:!1,par:d&&d.id?d.id:!1})},!1)},last_error:function(){return this._data.core.last_error},move_node:function(c,d,e,f,g,h,i){var j,k,l,m,n,o,p,q,r,s,t,u,v,w;if(d=this.get_node(d),e=e===b?0:e,!d)return!1;if(!e.toString().match(/^(before|after)$/)&&!g&&!this.is_loaded(d))return this.load_node(d,function(){this.move_node(c,d,e,f,!0,!1,i)});if(a.isArray(c)){if(1!==c.length){for(j=0,k=c.length;k>j;j++)(r=this.move_node(c[j],d,e,f,g,!1,i))&&(d=r,e="after");return this.redraw(),!0}c=c[0]}if(c=c&&c.id?c:this.get_node(c),!c||c.id===a.jstree.root)return!1;if(l=(c.parent||a.jstree.root).toString(),n=e.toString().match(/^(before|after)$/)&&d.id!==a.jstree.root?this.get_node(d.parent):d,o=i?i:this._model.data[c.id]?this:a.jstree.reference(c.id),p=!o||!o._id||this._id!==o._id,m=o&&o._id&&l&&o._model.data[l]&&o._model.data[l].children?a.inArray(c.id,o._model.data[l].children):-1,o&&o._id&&(c=o._model.data[c.id]),p)return(r=this.copy_node(c,d,e,f,g,!1,i))?(o&&o.delete_node(c),r):!1;switch(d.id===a.jstree.root&&("before"===e&&(e="first"),"after"===e&&(e="last")),e){case"before":e=a.inArray(d.id,n.children);break;case"after":e=a.inArray(d.id,n.children)+1;break;case"inside":case"first":e=0;break;case"last":e=n.children.length;break;default:e||(e=0)}if(e>n.children.length&&(e=n.children.length),!this.check("move_node",c,n,e,{core:!0,origin:i,is_multi:o&&o._id&&o._id!==this._id,is_foreign:!o||!o._id}))return this.settings.core.error.call(this,this._data.core.last_error),!1;if(c.parent===n.id){for(q=n.children.concat(),r=a.inArray(c.id,q),-1!==r&&(q=a.vakata.array_remove(q,r),e>r&&e--),r=[],s=0,t=q.length;t>s;s++)r[s>=e?s+1:s]=q[s];r[e]=c.id,n.children=r,this._node_changed(n.id),this.redraw(n.id===a.jstree.root)}else{for(r=c.children_d.concat(),r.push(c.id),s=0,t=c.parents.length;t>s;s++){for(q=[],w=o._model.data[c.parents[s]].children_d,u=0,v=w.length;v>u;u++)-1===a.inArray(w[u],r)&&q.push(w[u]);o._model.data[c.parents[s]].children_d=q}for(o._model.data[l].children=a.vakata.array_remove_item(o._model.data[l].children,c.id),s=0,t=n.parents.length;t>s;s++)this._model.data[n.parents[s]].children_d=this._model.data[n.parents[s]].children_d.concat(r);for(q=[],s=0,t=n.children.length;t>s;s++)q[s>=e?s+1:s]=n.children[s];for(q[e]=c.id,n.children=q,n.children_d.push(c.id),n.children_d=n.children_d.concat(c.children_d),c.parent=n.id,r=n.parents.concat(),r.unshift(n.id),w=c.parents.length,c.parents=r,r=r.concat(),s=0,t=c.children_d.length;t>s;s++)this._model.data[c.children_d[s]].parents=this._model.data[c.children_d[s]].parents.slice(0,-1*w),Array.prototype.push.apply(this._model.data[c.children_d[s]].parents,r);(l===a.jstree.root||n.id===a.jstree.root)&&(this._model.force_full_redraw=!0),this._model.force_full_redraw||(this._node_changed(l),this._node_changed(n.id)),h||this.redraw()}return f&&f.call(this,c,n,e),this.trigger("move_node",{node:c,parent:n.id,position:e,old_parent:l,old_position:m,is_multi:o&&o._id&&o._id!==this._id,is_foreign:!o||!o._id,old_instance:o,new_instance:this}),c.id},copy_node:function(c,d,e,f,g,h,i){var j,k,l,m,n,o,p,q,r,s,t;if(d=this.get_node(d),e=e===b?0:e,!d)return!1;if(!e.toString().match(/^(before|after)$/)&&!g&&!this.is_loaded(d))return this.load_node(d,function(){this.copy_node(c,d,e,f,!0,!1,i)});if(a.isArray(c)){if(1!==c.length){for(j=0,k=c.length;k>j;j++)(m=this.copy_node(c[j],d,e,f,g,!0,i))&&(d=m,e="after");return this.redraw(),!0}c=c[0]}if(c=c&&c.id?c:this.get_node(c),!c||c.id===a.jstree.root)return!1;switch(q=(c.parent||a.jstree.root).toString(),r=e.toString().match(/^(before|after)$/)&&d.id!==a.jstree.root?this.get_node(d.parent):d,s=i?i:this._model.data[c.id]?this:a.jstree.reference(c.id),t=!s||!s._id||this._id!==s._id,s&&s._id&&(c=s._model.data[c.id]),d.id===a.jstree.root&&("before"===e&&(e="first"),"after"===e&&(e="last")),e){case"before":e=a.inArray(d.id,r.children);break;case"after":e=a.inArray(d.id,r.children)+1;break;case"inside":case"first":e=0;break;case"last":e=r.children.length;break;default:e||(e=0)}if(e>r.children.length&&(e=r.children.length),!this.check("copy_node",c,r,e,{core:!0,origin:i,is_multi:s&&s._id&&s._id!==this._id,is_foreign:!s||!s._id}))return this.settings.core.error.call(this,this._data.core.last_error),!1;if(p=s?s.get_json(c,{no_id:!0,no_data:!0,no_state:!0}):c,!p)return!1;if(p.id===!0&&delete p.id,p=this._parse_model_from_json(p,r.id,r.parents.concat()),!p)return!1;for(m=this.get_node(p),c&&c.state&&c.state.loaded===!1&&(m.state.loaded=!1),l=[],l.push(p),l=l.concat(m.children_d),this.trigger("model",{nodes:l,parent:r.id}),n=0,o=r.parents.length;o>n;n++)this._model.data[r.parents[n]].children_d=this._model.data[r.parents[n]].children_d.concat(l);for(l=[],n=0,o=r.children.length;o>n;n++)l[n>=e?n+1:n]=r.children[n];return l[e]=m.id,r.children=l,r.children_d.push(m.id),r.children_d=r.children_d.concat(m.children_d),r.id===a.jstree.root&&(this._model.force_full_redraw=!0),this._model.force_full_redraw||this._node_changed(r.id),h||this.redraw(r.id===a.jstree.root),f&&f.call(this,m,r,e),this.trigger("copy_node",{node:m,original:c,parent:r.id,position:e,old_parent:q,old_position:s&&s._id&&q&&s._model.data[q]&&s._model.data[q].children?a.inArray(c.id,s._model.data[q].children):-1,is_multi:s&&s._id&&s._id!==this._id,is_foreign:!s||!s._id,old_instance:s,new_instance:this}),m.id},cut:function(b){if(b||(b=this._data.core.selected.concat()),a.isArray(b)||(b=[b]),!b.length)return!1;var c=[],g,h,i;for(h=0,i=b.length;i>h;h++)g=this.get_node(b[h]),g&&g.id&&g.id!==a.jstree.root&&c.push(g);return c.length?(d=c,f=this,e="move_node",void this.trigger("cut",{node:b})):!1},copy:function(b){if(b||(b=this._data.core.selected.concat()),a.isArray(b)||(b=[b]),!b.length)return!1;var c=[],g,h,i;for(h=0,i=b.length;i>h;h++)g=this.get_node(b[h]),g&&g.id&&g.id!==a.jstree.root&&c.push(g);return c.length?(d=c,f=this,e="copy_node",void this.trigger("copy",{node:b})):!1},get_buffer:function(){return{mode:e,node:d,inst:f}},can_paste:function(){return e!==!1&&d!==!1},paste:function(a,b){return a=this.get_node(a),a&&e&&e.match(/^(copy_node|move_node)$/)&&d?(this[e](d,a,b,!1,!1,!1,f)&&this.trigger("paste",{parent:a.id,node:d,mode:e}),d=!1,e=!1,void(f=!1)):!1},clear_buffer:function(){d=!1,e=!1,f=!1,this.trigger("clear_buffer")},edit:function(b,c,d){var e,f,g,h,j,k,l,m,n,o=!1;return(b=this.get_node(b))?this.settings.core.check_callback===!1?(this._data.core.last_error={error:"check",plugin:"core",id:"core_07",reason:"Could not edit node because of check_callback"},this.settings.core.error.call(this,this._data.core.last_error),!1):(n=b,c="string"==typeof c?c:b.text,this.set_text(b,""),b=this._open_to(b),n.text=c,e=this._data.core.rtl,f=this.element.width(),this._data.core.focused=n.id,g=b.children(".jstree-anchor").focus(),h=a("<span>"),j=c,k=a("<div />",{css:{position:"absolute",top:"-200px",left:e?"0px":"-1000px",visibility:"hidden"}}).appendTo("body"),l=a("<input />",{value:j,"class":"jstree-rename-input",css:{padding:"0",border:"1px solid silver","box-sizing":"border-box",display:"inline-block",height:this._data.core.li_height+"px",lineHeight:this._data.core.li_height+"px",width:"150px"},blur:a.proxy(function(c){c.stopImmediatePropagation(),c.preventDefault();var e=h.children(".jstree-rename-input"),f=e.val(),i=this.settings.core.force_text,m;""===f&&(f=j),k.remove(),h.replaceWith(g),h.remove(),j=i?j:a("<div></div>").append(a.parseHTML(j)).html(),this.set_text(b,j),m=!!this.rename_node(b,i?a("<div></div>").text(f).text():a("<div></div>").append(a.parseHTML(f)).html()),m||this.set_text(b,j),this._data.core.focused=n.id,setTimeout(a.proxy(function(){var a=this.get_node(n.id,!0);a.length&&(this._data.core.focused=n.id,a.children(".jstree-anchor").focus())},this),0),d&&d.call(this,n,m,o),l=null},this),keydown:function(a){var b=a.which;27===b&&(o=!0,this.value=j),(27===b||13===b||37===b||38===b||39===b||40===b||32===b)&&a.stopImmediatePropagation(),(27===b||13===b)&&(a.preventDefault(),this.blur())},click:function(a){a.stopImmediatePropagation()},mousedown:function(a){a.stopImmediatePropagation()},keyup:function(a){l.width(Math.min(k.text("pW"+this.value).width(),f))},keypress:function(a){return 13===a.which?!1:void 0}}),m={fontFamily:g.css("fontFamily")||"",fontSize:g.css("fontSize")||"", +fontWeight:g.css("fontWeight")||"",fontStyle:g.css("fontStyle")||"",fontStretch:g.css("fontStretch")||"",fontVariant:g.css("fontVariant")||"",letterSpacing:g.css("letterSpacing")||"",wordSpacing:g.css("wordSpacing")||""},h.attr("class",g.attr("class")).append(g.contents().clone()).append(l),g.replaceWith(h),k.css(m),l.css(m).width(Math.min(k.text("pW"+l[0].value).width(),f))[0].select(),void a(i).one("mousedown.jstree touchstart.jstree dnd_start.vakata",function(b){l&&b.target!==l&&a(l).blur()})):!1},set_theme:function(b,c){if(!b)return!1;if(c===!0){var d=this.settings.core.themes.dir;d||(d=a.jstree.path+"/themes"),c=d+"/"+b+"/style.css"}c&&-1===a.inArray(c,g)&&(a("head").append('<link rel="stylesheet" href="'+c+'" type="text/css" />'),g.push(c)),this._data.core.themes.name&&this.element.removeClass("jstree-"+this._data.core.themes.name),this._data.core.themes.name=b,this.element.addClass("jstree-"+b),this.element[this.settings.core.themes.responsive?"addClass":"removeClass"]("jstree-"+b+"-responsive"),this.trigger("set_theme",{theme:b})},get_theme:function(){return this._data.core.themes.name},set_theme_variant:function(a){this._data.core.themes.variant&&this.element.removeClass("jstree-"+this._data.core.themes.name+"-"+this._data.core.themes.variant),this._data.core.themes.variant=a,a&&this.element.addClass("jstree-"+this._data.core.themes.name+"-"+this._data.core.themes.variant)},get_theme_variant:function(){return this._data.core.themes.variant},show_stripes:function(){this._data.core.themes.stripes=!0,this.get_container_ul().addClass("jstree-striped"),this.trigger("show_stripes")},hide_stripes:function(){this._data.core.themes.stripes=!1,this.get_container_ul().removeClass("jstree-striped"),this.trigger("hide_stripes")},toggle_stripes:function(){this._data.core.themes.stripes?this.hide_stripes():this.show_stripes()},show_dots:function(){this._data.core.themes.dots=!0,this.get_container_ul().removeClass("jstree-no-dots"),this.trigger("show_dots")},hide_dots:function(){this._data.core.themes.dots=!1,this.get_container_ul().addClass("jstree-no-dots"),this.trigger("hide_dots")},toggle_dots:function(){this._data.core.themes.dots?this.hide_dots():this.show_dots()},show_icons:function(){this._data.core.themes.icons=!0,this.get_container_ul().removeClass("jstree-no-icons"),this.trigger("show_icons")},hide_icons:function(){this._data.core.themes.icons=!1,this.get_container_ul().addClass("jstree-no-icons"),this.trigger("hide_icons")},toggle_icons:function(){this._data.core.themes.icons?this.hide_icons():this.show_icons()},show_ellipsis:function(){this._data.core.themes.ellipsis=!0,this.get_container_ul().addClass("jstree-ellipsis"),this.trigger("show_ellipsis")},hide_ellipsis:function(){this._data.core.themes.ellipsis=!1,this.get_container_ul().removeClass("jstree-ellipsis"),this.trigger("hide_ellipsis")},toggle_ellipsis:function(){this._data.core.themes.ellipsis?this.hide_ellipsis():this.show_ellipsis()},set_icon:function(c,d){var e,f,g,h;if(a.isArray(c)){for(c=c.slice(),e=0,f=c.length;f>e;e++)this.set_icon(c[e],d);return!0}return c=this.get_node(c),c&&c.id!==a.jstree.root?(h=c.icon,c.icon=d===!0||null===d||d===b||""===d?!0:d,g=this.get_node(c,!0).children(".jstree-anchor").children(".jstree-themeicon"),d===!1?this.hide_icon(c):d===!0||null===d||d===b||""===d?(g.removeClass("jstree-themeicon-custom "+h).css("background","").removeAttr("rel"),h===!1&&this.show_icon(c)):-1===d.indexOf("/")&&-1===d.indexOf(".")?(g.removeClass(h).css("background",""),g.addClass(d+" jstree-themeicon-custom").attr("rel",d),h===!1&&this.show_icon(c)):(g.removeClass(h).css("background",""),g.addClass("jstree-themeicon-custom").css("background","url('"+d+"') center center no-repeat").attr("rel",d),h===!1&&this.show_icon(c)),!0):!1},get_icon:function(b){return b=this.get_node(b),b&&b.id!==a.jstree.root?b.icon:!1},hide_icon:function(b){var c,d;if(a.isArray(b)){for(b=b.slice(),c=0,d=b.length;d>c;c++)this.hide_icon(b[c]);return!0}return b=this.get_node(b),b&&b!==a.jstree.root?(b.icon=!1,this.get_node(b,!0).children(".jstree-anchor").children(".jstree-themeicon").addClass("jstree-themeicon-hidden"),!0):!1},show_icon:function(b){var c,d,e;if(a.isArray(b)){for(b=b.slice(),c=0,d=b.length;d>c;c++)this.show_icon(b[c]);return!0}return b=this.get_node(b),b&&b!==a.jstree.root?(e=this.get_node(b,!0),b.icon=e.length?e.children(".jstree-anchor").children(".jstree-themeicon").attr("rel"):!0,b.icon||(b.icon=!0),e.children(".jstree-anchor").children(".jstree-themeicon").removeClass("jstree-themeicon-hidden"),!0):!1}},a.vakata={},a.vakata.attributes=function(b,c){b=a(b)[0];var d=c?{}:[];return b&&b.attributes&&a.each(b.attributes,function(b,e){-1===a.inArray(e.name.toLowerCase(),["style","contenteditable","hasfocus","tabindex"])&&null!==e.value&&""!==a.trim(e.value)&&(c?d[e.name]=e.value:d.push(e.name))}),d},a.vakata.array_unique=function(a){var c=[],d,e,f,g={};for(d=0,f=a.length;f>d;d++)g[a[d]]===b&&(c.push(a[d]),g[a[d]]=!0);return c},a.vakata.array_remove=function(a,b){return a.splice(b,1),a},a.vakata.array_remove_item=function(b,c){var d=a.inArray(c,b);return-1!==d?a.vakata.array_remove(b,d):b},a.vakata.array_filter=function(a,b,c,d,e){if(a.filter)return a.filter(b,c);d=[];for(e in a)~~e+""==e+""&&e>=0&&b.call(c,a[e],+e,a)&&d.push(a[e]);return d},a.jstree.plugins.changed=function(a,b){var c=[];this.trigger=function(a,d){var e,f;if(d||(d={}),"changed"===a.replace(".jstree","")){d.changed={selected:[],deselected:[]};var g={};for(e=0,f=c.length;f>e;e++)g[c[e]]=1;for(e=0,f=d.selected.length;f>e;e++)g[d.selected[e]]?g[d.selected[e]]=2:d.changed.selected.push(d.selected[e]);for(e=0,f=c.length;f>e;e++)1===g[c[e]]&&d.changed.deselected.push(c[e]);c=d.selected.slice()}b.trigger.call(this,a,d)},this.refresh=function(a,d){return c=[],b.refresh.apply(this,arguments)}};var j=i.createElement("I");j.className="jstree-icon jstree-checkbox",j.setAttribute("role","presentation"),a.jstree.defaults.checkbox={visible:!0,three_state:!0,whole_node:!0,keep_selected_style:!0,cascade:"",tie_selection:!0},a.jstree.plugins.checkbox=function(c,d){this.bind=function(){d.bind.call(this),this._data.checkbox.uto=!1,this._data.checkbox.selected=[],this.settings.checkbox.three_state&&(this.settings.checkbox.cascade="up+down+undetermined"),this.element.on("init.jstree",a.proxy(function(){this._data.checkbox.visible=this.settings.checkbox.visible,this.settings.checkbox.keep_selected_style||this.element.addClass("jstree-checkbox-no-clicked"),this.settings.checkbox.tie_selection&&this.element.addClass("jstree-checkbox-selection")},this)).on("loading.jstree",a.proxy(function(){this[this._data.checkbox.visible?"show_checkboxes":"hide_checkboxes"]()},this)),-1!==this.settings.checkbox.cascade.indexOf("undetermined")&&this.element.on("changed.jstree uncheck_node.jstree check_node.jstree uncheck_all.jstree check_all.jstree move_node.jstree copy_node.jstree redraw.jstree open_node.jstree",a.proxy(function(){this._data.checkbox.uto&&clearTimeout(this._data.checkbox.uto),this._data.checkbox.uto=setTimeout(a.proxy(this._undetermined,this),50)},this)),this.settings.checkbox.tie_selection||this.element.on("model.jstree",a.proxy(function(a,b){var c=this._model.data,d=c[b.parent],e=b.nodes,f,g;for(f=0,g=e.length;g>f;f++)c[e[f]].state.checked=c[e[f]].state.checked||c[e[f]].original&&c[e[f]].original.state&&c[e[f]].original.state.checked,c[e[f]].state.checked&&this._data.checkbox.selected.push(e[f])},this)),(-1!==this.settings.checkbox.cascade.indexOf("up")||-1!==this.settings.checkbox.cascade.indexOf("down"))&&this.element.on("model.jstree",a.proxy(function(b,c){var d=this._model.data,e=d[c.parent],f=c.nodes,g=[],h,i,j,k,l,m,n=this.settings.checkbox.cascade,o=this.settings.checkbox.tie_selection;if(-1!==n.indexOf("down"))if(e.state[o?"selected":"checked"]){for(i=0,j=f.length;j>i;i++)d[f[i]].state[o?"selected":"checked"]=!0;this._data[o?"core":"checkbox"].selected=this._data[o?"core":"checkbox"].selected.concat(f)}else for(i=0,j=f.length;j>i;i++)if(d[f[i]].state[o?"selected":"checked"]){for(k=0,l=d[f[i]].children_d.length;l>k;k++)d[d[f[i]].children_d[k]].state[o?"selected":"checked"]=!0;this._data[o?"core":"checkbox"].selected=this._data[o?"core":"checkbox"].selected.concat(d[f[i]].children_d)}if(-1!==n.indexOf("up")){for(i=0,j=e.children_d.length;j>i;i++)d[e.children_d[i]].children.length||g.push(d[e.children_d[i]].parent);for(g=a.vakata.array_unique(g),k=0,l=g.length;l>k;k++){e=d[g[k]];while(e&&e.id!==a.jstree.root){for(h=0,i=0,j=e.children.length;j>i;i++)h+=d[e.children[i]].state[o?"selected":"checked"];if(h!==j)break;e.state[o?"selected":"checked"]=!0,this._data[o?"core":"checkbox"].selected.push(e.id),m=this.get_node(e,!0),m&&m.length&&m.attr("aria-selected",!0).children(".jstree-anchor").addClass(o?"jstree-clicked":"jstree-checked"),e=this.get_node(e.parent)}}}this._data[o?"core":"checkbox"].selected=a.vakata.array_unique(this._data[o?"core":"checkbox"].selected)},this)).on(this.settings.checkbox.tie_selection?"select_node.jstree":"check_node.jstree",a.proxy(function(b,c){var d=c.node,e=this._model.data,f=this.get_node(d.parent),g=this.get_node(d,!0),h,i,j,k,l=this.settings.checkbox.cascade,m=this.settings.checkbox.tie_selection,n={},o=this._data[m?"core":"checkbox"].selected;for(h=0,i=o.length;i>h;h++)n[o[h]]=!0;if(-1!==l.indexOf("down"))for(h=0,i=d.children_d.length;i>h;h++)n[d.children_d[h]]=!0,k=e[d.children_d[h]],k.state[m?"selected":"checked"]=!0,k&&k.original&&k.original.state&&k.original.state.undetermined&&(k.original.state.undetermined=!1);if(-1!==l.indexOf("up"))while(f&&f.id!==a.jstree.root){for(j=0,h=0,i=f.children.length;i>h;h++)j+=e[f.children[h]].state[m?"selected":"checked"];if(j!==i)break;f.state[m?"selected":"checked"]=!0,n[f.id]=!0,k=this.get_node(f,!0),k&&k.length&&k.attr("aria-selected",!0).children(".jstree-anchor").addClass(m?"jstree-clicked":"jstree-checked"),f=this.get_node(f.parent)}o=[];for(h in n)n.hasOwnProperty(h)&&o.push(h);this._data[m?"core":"checkbox"].selected=o,-1!==l.indexOf("down")&&g.length&&g.find(".jstree-anchor").addClass(m?"jstree-clicked":"jstree-checked").parent().attr("aria-selected",!0)},this)).on(this.settings.checkbox.tie_selection?"deselect_all.jstree":"uncheck_all.jstree",a.proxy(function(b,c){var d=this.get_node(a.jstree.root),e=this._model.data,f,g,h;for(f=0,g=d.children_d.length;g>f;f++)h=e[d.children_d[f]],h&&h.original&&h.original.state&&h.original.state.undetermined&&(h.original.state.undetermined=!1)},this)).on(this.settings.checkbox.tie_selection?"deselect_node.jstree":"uncheck_node.jstree",a.proxy(function(b,c){var d=c.node,e=this.get_node(d,!0),f,g,h,i=this.settings.checkbox.cascade,j=this.settings.checkbox.tie_selection,k=this._data[j?"core":"checkbox"].selected,l={};if(d&&d.original&&d.original.state&&d.original.state.undetermined&&(d.original.state.undetermined=!1),-1!==i.indexOf("down"))for(f=0,g=d.children_d.length;g>f;f++)h=this._model.data[d.children_d[f]],h.state[j?"selected":"checked"]=!1,h&&h.original&&h.original.state&&h.original.state.undetermined&&(h.original.state.undetermined=!1);if(-1!==i.indexOf("up"))for(f=0,g=d.parents.length;g>f;f++)h=this._model.data[d.parents[f]],h.state[j?"selected":"checked"]=!1,h&&h.original&&h.original.state&&h.original.state.undetermined&&(h.original.state.undetermined=!1),h=this.get_node(d.parents[f],!0),h&&h.length&&h.attr("aria-selected",!1).children(".jstree-anchor").removeClass(j?"jstree-clicked":"jstree-checked");for(l={},f=0,g=k.length;g>f;f++)-1!==i.indexOf("down")&&-1!==a.inArray(k[f],d.children_d)||-1!==i.indexOf("up")&&-1!==a.inArray(k[f],d.parents)||(l[k[f]]=!0);k=[];for(f in l)l.hasOwnProperty(f)&&k.push(f);this._data[j?"core":"checkbox"].selected=k,-1!==i.indexOf("down")&&e.length&&e.find(".jstree-anchor").removeClass(j?"jstree-clicked":"jstree-checked").parent().attr("aria-selected",!1)},this)),-1!==this.settings.checkbox.cascade.indexOf("up")&&this.element.on("delete_node.jstree",a.proxy(function(b,c){var d=this.get_node(c.parent),e=this._model.data,f,g,h,i,j=this.settings.checkbox.tie_selection;while(d&&d.id!==a.jstree.root&&!d.state[j?"selected":"checked"]){for(h=0,f=0,g=d.children.length;g>f;f++)h+=e[d.children[f]].state[j?"selected":"checked"];if(!(g>0&&h===g))break;d.state[j?"selected":"checked"]=!0,this._data[j?"core":"checkbox"].selected.push(d.id),i=this.get_node(d,!0),i&&i.length&&i.attr("aria-selected",!0).children(".jstree-anchor").addClass(j?"jstree-clicked":"jstree-checked"),d=this.get_node(d.parent)}},this)).on("move_node.jstree",a.proxy(function(b,c){var d=c.is_multi,e=c.old_parent,f=this.get_node(c.parent),g=this._model.data,h,i,j,k,l,m=this.settings.checkbox.tie_selection;if(!d){h=this.get_node(e);while(h&&h.id!==a.jstree.root&&!h.state[m?"selected":"checked"]){for(i=0,j=0,k=h.children.length;k>j;j++)i+=g[h.children[j]].state[m?"selected":"checked"];if(!(k>0&&i===k))break;h.state[m?"selected":"checked"]=!0,this._data[m?"core":"checkbox"].selected.push(h.id),l=this.get_node(h,!0),l&&l.length&&l.attr("aria-selected",!0).children(".jstree-anchor").addClass(m?"jstree-clicked":"jstree-checked"),h=this.get_node(h.parent)}}h=f;while(h&&h.id!==a.jstree.root){for(i=0,j=0,k=h.children.length;k>j;j++)i+=g[h.children[j]].state[m?"selected":"checked"];if(i===k)h.state[m?"selected":"checked"]||(h.state[m?"selected":"checked"]=!0,this._data[m?"core":"checkbox"].selected.push(h.id),l=this.get_node(h,!0),l&&l.length&&l.attr("aria-selected",!0).children(".jstree-anchor").addClass(m?"jstree-clicked":"jstree-checked"));else{if(!h.state[m?"selected":"checked"])break;h.state[m?"selected":"checked"]=!1,this._data[m?"core":"checkbox"].selected=a.vakata.array_remove_item(this._data[m?"core":"checkbox"].selected,h.id),l=this.get_node(h,!0),l&&l.length&&l.attr("aria-selected",!1).children(".jstree-anchor").removeClass(m?"jstree-clicked":"jstree-checked")}h=this.get_node(h.parent)}},this))},this._undetermined=function(){if(null!==this.element){var c,d,e,f,g={},h=this._model.data,i=this.settings.checkbox.tie_selection,j=this._data[i?"core":"checkbox"].selected,k=[],l=this;for(c=0,d=j.length;d>c;c++)if(h[j[c]]&&h[j[c]].parents)for(e=0,f=h[j[c]].parents.length;f>e;e++){if(g[h[j[c]].parents[e]]!==b)break;h[j[c]].parents[e]!==a.jstree.root&&(g[h[j[c]].parents[e]]=!0,k.push(h[j[c]].parents[e]))}for(this.element.find(".jstree-closed").not(":has(.jstree-children)").each(function(){var i=l.get_node(this),j;if(i.state.loaded){for(c=0,d=i.children_d.length;d>c;c++)if(j=h[i.children_d[c]],!j.state.loaded&&j.original&&j.original.state&&j.original.state.undetermined&&j.original.state.undetermined===!0)for(g[j.id]===b&&j.id!==a.jstree.root&&(g[j.id]=!0,k.push(j.id)),e=0,f=j.parents.length;f>e;e++)g[j.parents[e]]===b&&j.parents[e]!==a.jstree.root&&(g[j.parents[e]]=!0,k.push(j.parents[e]))}else if(i.original&&i.original.state&&i.original.state.undetermined&&i.original.state.undetermined===!0)for(g[i.id]===b&&i.id!==a.jstree.root&&(g[i.id]=!0,k.push(i.id)),e=0,f=i.parents.length;f>e;e++)g[i.parents[e]]===b&&i.parents[e]!==a.jstree.root&&(g[i.parents[e]]=!0,k.push(i.parents[e]))}),this.element.find(".jstree-undetermined").removeClass("jstree-undetermined"),c=0,d=k.length;d>c;c++)h[k[c]].state[i?"selected":"checked"]||(j=this.get_node(k[c],!0),j&&j.length&&j.children(".jstree-anchor").children(".jstree-checkbox").addClass("jstree-undetermined"))}},this.redraw_node=function(b,c,e,f){if(b=d.redraw_node.apply(this,arguments)){var g,h,i=null,k=null;for(g=0,h=b.childNodes.length;h>g;g++)if(b.childNodes[g]&&b.childNodes[g].className&&-1!==b.childNodes[g].className.indexOf("jstree-anchor")){i=b.childNodes[g];break}i&&(!this.settings.checkbox.tie_selection&&this._model.data[b.id].state.checked&&(i.className+=" jstree-checked"),k=j.cloneNode(!1),this._model.data[b.id].state.checkbox_disabled&&(k.className+=" jstree-checkbox-disabled"),i.insertBefore(k,i.childNodes[0]))}return e||-1===this.settings.checkbox.cascade.indexOf("undetermined")||(this._data.checkbox.uto&&clearTimeout(this._data.checkbox.uto),this._data.checkbox.uto=setTimeout(a.proxy(this._undetermined,this),50)),b},this.show_checkboxes=function(){this._data.core.themes.checkboxes=!0,this.get_container_ul().removeClass("jstree-no-checkboxes")},this.hide_checkboxes=function(){this._data.core.themes.checkboxes=!1,this.get_container_ul().addClass("jstree-no-checkboxes")},this.toggle_checkboxes=function(){this._data.core.themes.checkboxes?this.hide_checkboxes():this.show_checkboxes()},this.is_undetermined=function(b){b=this.get_node(b);var c=this.settings.checkbox.cascade,d,e,f=this.settings.checkbox.tie_selection,g=this._data[f?"core":"checkbox"].selected,h=this._model.data;if(!b||b.state[f?"selected":"checked"]===!0||-1===c.indexOf("undetermined")||-1===c.indexOf("down")&&-1===c.indexOf("up"))return!1;if(!b.state.loaded&&b.original.state.undetermined===!0)return!0;for(d=0,e=b.children_d.length;e>d;d++)if(-1!==a.inArray(b.children_d[d],g)||!h[b.children_d[d]].state.loaded&&h[b.children_d[d]].original.state.undetermined)return!0;return!1},this.disable_checkbox=function(b){var c,d,e;if(a.isArray(b)){for(b=b.slice(),c=0,d=b.length;d>c;c++)this.disable_checkbox(b[c]);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(e=this.get_node(b,!0),void(b.state.checkbox_disabled||(b.state.checkbox_disabled=!0,e&&e.length&&e.children(".jstree-anchor").children(".jstree-checkbox").addClass("jstree-checkbox-disabled"),this.trigger("disable_checkbox",{node:b})))):!1},this.enable_checkbox=function(b){var c,d,e;if(a.isArray(b)){for(b=b.slice(),c=0,d=b.length;d>c;c++)this.enable_checkbox(b[c]);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(e=this.get_node(b,!0),void(b.state.checkbox_disabled&&(b.state.checkbox_disabled=!1,e&&e.length&&e.children(".jstree-anchor").children(".jstree-checkbox").removeClass("jstree-checkbox-disabled"),this.trigger("enable_checkbox",{node:b})))):!1},this.activate_node=function(b,c){return a(c.target).hasClass("jstree-checkbox-disabled")?!1:(this.settings.checkbox.tie_selection&&(this.settings.checkbox.whole_node||a(c.target).hasClass("jstree-checkbox"))&&(c.ctrlKey=!0),this.settings.checkbox.tie_selection||!this.settings.checkbox.whole_node&&!a(c.target).hasClass("jstree-checkbox")?d.activate_node.call(this,b,c):this.is_disabled(b)?!1:(this.is_checked(b)?this.uncheck_node(b,c):this.check_node(b,c),void this.trigger("activate_node",{node:this.get_node(b)})))},this.check_node=function(b,c){if(this.settings.checkbox.tie_selection)return this.select_node(b,!1,!0,c);var d,e,f,g;if(a.isArray(b)){for(b=b.slice(),e=0,f=b.length;f>e;e++)this.check_node(b[e],c);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(d=this.get_node(b,!0),void(b.state.checked||(b.state.checked=!0,this._data.checkbox.selected.push(b.id),d&&d.length&&d.children(".jstree-anchor").addClass("jstree-checked"),this.trigger("check_node",{node:b,selected:this._data.checkbox.selected,event:c})))):!1},this.uncheck_node=function(b,c){if(this.settings.checkbox.tie_selection)return this.deselect_node(b,!1,c);var d,e,f;if(a.isArray(b)){for(b=b.slice(),d=0,e=b.length;e>d;d++)this.uncheck_node(b[d],c);return!0}return b=this.get_node(b),b&&b.id!==a.jstree.root?(f=this.get_node(b,!0),void(b.state.checked&&(b.state.checked=!1,this._data.checkbox.selected=a.vakata.array_remove_item(this._data.checkbox.selected,b.id),f.length&&f.children(".jstree-anchor").removeClass("jstree-checked"),this.trigger("uncheck_node",{node:b,selected:this._data.checkbox.selected,event:c})))):!1},this.check_all=function(){if(this.settings.checkbox.tie_selection)return this.select_all();var b=this._data.checkbox.selected.concat([]),c,d;for(this._data.checkbox.selected=this._model.data[a.jstree.root].children_d.concat(),c=0,d=this._data.checkbox.selected.length;d>c;c++)this._model.data[this._data.checkbox.selected[c]]&&(this._model.data[this._data.checkbox.selected[c]].state.checked=!0);this.redraw(!0),this.trigger("check_all",{selected:this._data.checkbox.selected})},this.uncheck_all=function(){if(this.settings.checkbox.tie_selection)return this.deselect_all();var a=this._data.checkbox.selected.concat([]),b,c;for(b=0,c=this._data.checkbox.selected.length;c>b;b++)this._model.data[this._data.checkbox.selected[b]]&&(this._model.data[this._data.checkbox.selected[b]].state.checked=!1);this._data.checkbox.selected=[],this.element.find(".jstree-checked").removeClass("jstree-checked"),this.trigger("uncheck_all",{selected:this._data.checkbox.selected,node:a})},this.is_checked=function(b){return this.settings.checkbox.tie_selection?this.is_selected(b):(b=this.get_node(b),b&&b.id!==a.jstree.root?b.state.checked:!1)},this.get_checked=function(b){return this.settings.checkbox.tie_selection?this.get_selected(b):b?a.map(this._data.checkbox.selected,a.proxy(function(a){return this.get_node(a)},this)):this._data.checkbox.selected},this.get_top_checked=function(b){if(this.settings.checkbox.tie_selection)return this.get_top_selected(b);var c=this.get_checked(!0),d={},e,f,g,h;for(e=0,f=c.length;f>e;e++)d[c[e].id]=c[e];for(e=0,f=c.length;f>e;e++)for(g=0,h=c[e].children_d.length;h>g;g++)d[c[e].children_d[g]]&&delete d[c[e].children_d[g]];c=[];for(e in d)d.hasOwnProperty(e)&&c.push(e);return b?a.map(c,a.proxy(function(a){return this.get_node(a)},this)):c},this.get_bottom_checked=function(b){if(this.settings.checkbox.tie_selection)return this.get_bottom_selected(b);var c=this.get_checked(!0),d=[],e,f;for(e=0,f=c.length;f>e;e++)c[e].children.length||d.push(c[e].id);return b?a.map(d,a.proxy(function(a){return this.get_node(a)},this)):d},this.load_node=function(b,c){var e,f,g,h,i,j;if(!a.isArray(b)&&!this.settings.checkbox.tie_selection&&(j=this.get_node(b),j&&j.state.loaded))for(e=0,f=j.children_d.length;f>e;e++)this._model.data[j.children_d[e]].state.checked&&(i=!0,this._data.checkbox.selected=a.vakata.array_remove_item(this._data.checkbox.selected,j.children_d[e]));return d.load_node.apply(this,arguments)},this.get_state=function(){var a=d.get_state.apply(this,arguments);return this.settings.checkbox.tie_selection?a:(a.checkbox=this._data.checkbox.selected.slice(),a)},this.set_state=function(b,c){var e=d.set_state.apply(this,arguments);if(e&&b.checkbox){if(!this.settings.checkbox.tie_selection){this.uncheck_all();var f=this;a.each(b.checkbox,function(a,b){f.check_node(b)})}return delete b.checkbox,this.set_state(b,c),!1}return e},this.refresh=function(a,b){return this.settings.checkbox.tie_selection||(this._data.checkbox.selected=[]),d.refresh.apply(this,arguments)}},a.jstree.defaults.conditionalselect=function(){return!0},a.jstree.plugins.conditionalselect=function(a,b){this.activate_node=function(a,c){this.settings.conditionalselect.call(this,this.get_node(a),c)&&b.activate_node.call(this,a,c)}},a.jstree.defaults.contextmenu={select_node:!0,show_at_node:!0,items:function(b,c){return{create:{separator_before:!1,separator_after:!0,_disabled:!1,label:"Create",action:function(b){var c=a.jstree.reference(b.reference),d=c.get_node(b.reference);c.create_node(d,{},"last",function(a){setTimeout(function(){c.edit(a)},0)})}},rename:{separator_before:!1,separator_after:!1,_disabled:!1,label:"Rename",action:function(b){var c=a.jstree.reference(b.reference),d=c.get_node(b.reference);c.edit(d)}},remove:{separator_before:!1,icon:!1,separator_after:!1,_disabled:!1,label:"Delete",action:function(b){var c=a.jstree.reference(b.reference),d=c.get_node(b.reference);c.is_selected(d)?c.delete_node(c.get_selected()):c.delete_node(d)}},ccp:{separator_before:!0,icon:!1,separator_after:!1,label:"Edit",action:!1,submenu:{cut:{separator_before:!1,separator_after:!1,label:"Cut",action:function(b){var c=a.jstree.reference(b.reference),d=c.get_node(b.reference);c.is_selected(d)?c.cut(c.get_top_selected()):c.cut(d)}},copy:{separator_before:!1,icon:!1,separator_after:!1,label:"Copy",action:function(b){var c=a.jstree.reference(b.reference),d=c.get_node(b.reference);c.is_selected(d)?c.copy(c.get_top_selected()):c.copy(d)}},paste:{separator_before:!1,icon:!1,_disabled:function(b){return!a.jstree.reference(b.reference).can_paste()},separator_after:!1,label:"Paste",action:function(b){var c=a.jstree.reference(b.reference),d=c.get_node(b.reference);c.paste(d)}}}}}}},a.jstree.plugins.contextmenu=function(c,d){this.bind=function(){d.bind.call(this);var b=0,c=null,e,f;this.element.on("contextmenu.jstree",".jstree-anchor",a.proxy(function(a,d){"input"!==a.target.tagName.toLowerCase()&&(a.preventDefault(),b=a.ctrlKey?+new Date:0,(d||c)&&(b=+new Date+1e4),c&&clearTimeout(c),this.is_loading(a.currentTarget)||this.show_contextmenu(a.currentTarget,a.pageX,a.pageY,a))},this)).on("click.jstree",".jstree-anchor",a.proxy(function(c){this._data.contextmenu.visible&&(!b||+new Date-b>250)&&a.vakata.context.hide(),b=0},this)).on("touchstart.jstree",".jstree-anchor",function(b){b.originalEvent&&b.originalEvent.changedTouches&&b.originalEvent.changedTouches[0]&&(e=b.originalEvent.changedTouches[0].clientX,f=b.originalEvent.changedTouches[0].clientY,c=setTimeout(function(){a(b.currentTarget).trigger("contextmenu",!0)},750))}).on("touchmove.vakata.jstree",function(a){c&&a.originalEvent&&a.originalEvent.changedTouches&&a.originalEvent.changedTouches[0]&&(Math.abs(e-a.originalEvent.changedTouches[0].clientX)>50||Math.abs(f-a.originalEvent.changedTouches[0].clientY)>50)&&clearTimeout(c)}).on("touchend.vakata.jstree",function(a){c&&clearTimeout(c)}),a(i).on("context_hide.vakata.jstree",a.proxy(function(b,c){this._data.contextmenu.visible=!1,a(c.reference).removeClass("jstree-context")},this))},this.teardown=function(){this._data.contextmenu.visible&&a.vakata.context.hide(),d.teardown.call(this)},this.show_contextmenu=function(c,d,e,f){if(c=this.get_node(c),!c||c.id===a.jstree.root)return!1;var g=this.settings.contextmenu,h=this.get_node(c,!0),i=h.children(".jstree-anchor"),j=!1,k=!1;(g.show_at_node||d===b||e===b)&&(j=i.offset(),d=j.left,e=j.top+this._data.core.li_height),this.settings.contextmenu.select_node&&!this.is_selected(c)&&this.activate_node(c,f),k=g.items,a.isFunction(k)&&(k=k.call(this,c,a.proxy(function(a){this._show_contextmenu(c,d,e,a)},this))),a.isPlainObject(k)&&this._show_contextmenu(c,d,e,k)},this._show_contextmenu=function(b,c,d,e){var f=this.get_node(b,!0),g=f.children(".jstree-anchor");a(i).one("context_show.vakata.jstree",a.proxy(function(b,c){var d="jstree-contextmenu jstree-"+this.get_theme()+"-contextmenu";a(c.element).addClass(d),g.addClass("jstree-context")},this)),this._data.contextmenu.visible=!0,a.vakata.context.show(g,{x:c,y:d},e),this.trigger("show_contextmenu",{node:b,x:c,y:d})}},function(a){var b=!1,c={element:!1,reference:!1,position_x:0,position_y:0,items:[],html:"",is_visible:!1};a.vakata.context={settings:{hide_onmouseleave:0,icons:!0},_trigger:function(b){a(i).triggerHandler("context_"+b+".vakata",{reference:c.reference,element:c.element,position:{x:c.position_x,y:c.position_y}})},_execute:function(b){return b=c.items[b],b&&(!b._disabled||a.isFunction(b._disabled)&&!b._disabled({item:b,reference:c.reference,element:c.element}))&&b.action?b.action.call(null,{item:b,reference:c.reference,element:c.element,position:{x:c.position_x,y:c.position_y}}):!1},_parse:function(b,d){if(!b)return!1;d||(c.html="",c.items=[]);var e="",f=!1,g;return d&&(e+="<ul>"),a.each(b,function(b,d){return d?(c.items.push(d),!f&&d.separator_before&&(e+="<li class='vakata-context-separator'><a href='#' "+(a.vakata.context.settings.icons?"":'style="margin-left:0px;"')+"> </a></li>"),f=!1,e+="<li class='"+(d._class||"")+(d._disabled===!0||a.isFunction(d._disabled)&&d._disabled({item:d,reference:c.reference,element:c.element})?" vakata-contextmenu-disabled ":"")+"' "+(d.shortcut?" data-shortcut='"+d.shortcut+"' ":"")+">",e+="<a href='#' rel='"+(c.items.length-1)+"' "+(d.title?"title='"+d.title+"'":"")+">",a.vakata.context.settings.icons&&(e+="<i ",d.icon&&(e+=-1!==d.icon.indexOf("/")||-1!==d.icon.indexOf(".")?" style='background:url(\""+d.icon+"\") center center no-repeat' ":" class='"+d.icon+"' "),e+="></i><span class='vakata-contextmenu-sep'> </span>"),e+=(a.isFunction(d.label)?d.label({item:b,reference:c.reference,element:c.element}):d.label)+(d.shortcut?' <span class="vakata-contextmenu-shortcut vakata-contextmenu-shortcut-'+d.shortcut+'">'+(d.shortcut_label||"")+"</span>":"")+"</a>",d.submenu&&(g=a.vakata.context._parse(d.submenu,!0),g&&(e+=g)),e+="</li>",void(d.separator_after&&(e+="<li class='vakata-context-separator'><a href='#' "+(a.vakata.context.settings.icons?"":'style="margin-left:0px;"')+"> </a></li>",f=!0))):!0}),e=e.replace(/<li class\='vakata-context-separator'\><\/li\>$/,""),d&&(e+="</ul>"),d||(c.html=e,a.vakata.context._trigger("parse")),e.length>10?e:!1},_show_submenu:function(c){if(c=a(c),c.length&&c.children("ul").length){var d=c.children("ul"),e=c.offset().left,f=e+c.outerWidth(),g=c.offset().top,h=d.width(),i=d.height(),j=a(window).width()+a(window).scrollLeft(),k=a(window).height()+a(window).scrollTop();b?c[f-(h+10+c.outerWidth())<0?"addClass":"removeClass"]("vakata-context-left"):c[f+h>j&&e>j-f?"addClass":"removeClass"]("vakata-context-right"),g+i+10>k&&d.css("bottom","-1px"),c.hasClass("vakata-context-right")?h>e&&d.css("margin-right",e-h):h>j-f&&d.css("margin-left",j-f-h),d.show()}},show:function(d,e,f){var g,h,i,j,k,l,m,n,o=!0;switch(c.element&&c.element.length&&c.element.width(""),o){case!e&&!d:return!1;case!!e&&!!d:c.reference=d,c.position_x=e.x,c.position_y=e.y;break;case!e&&!!d:c.reference=d,g=d.offset(),c.position_x=g.left+d.outerHeight(),c.position_y=g.top;break;case!!e&&!d:c.position_x=e.x,c.position_y=e.y}d&&!f&&a(d).data("vakata_contextmenu")&&(f=a(d).data("vakata_contextmenu")),a.vakata.context._parse(f)&&c.element.html(c.html),c.items.length&&(c.element.appendTo("body"),h=c.element,i=c.position_x,j=c.position_y,k=h.width(),l=h.height(),m=a(window).width()+a(window).scrollLeft(),n=a(window).height()+a(window).scrollTop(),b&&(i-=h.outerWidth()-a(d).outerWidth(),i<a(window).scrollLeft()+20&&(i=a(window).scrollLeft()+20)),i+k+20>m&&(i=m-(k+20)),j+l+20>n&&(j=n-(l+20)),c.element.css({left:i,top:j}).show().find("a").first().focus().parent().addClass("vakata-context-hover"),c.is_visible=!0,a.vakata.context._trigger("show"))},hide:function(){c.is_visible&&(c.element.hide().find("ul").hide().end().find(":focus").blur().end().detach(),c.is_visible=!1,a.vakata.context._trigger("hide"))}},a(function(){b="rtl"===a("body").css("direction");var d=!1;c.element=a("<ul class='vakata-context'></ul>"),c.element.on("mouseenter","li",function(b){b.stopImmediatePropagation(),a.contains(this,b.relatedTarget)||(d&&clearTimeout(d),c.element.find(".vakata-context-hover").removeClass("vakata-context-hover").end(),a(this).siblings().find("ul").hide().end().end().parentsUntil(".vakata-context","li").addBack().addClass("vakata-context-hover"),a.vakata.context._show_submenu(this))}).on("mouseleave","li",function(b){a.contains(this,b.relatedTarget)||a(this).find(".vakata-context-hover").addBack().removeClass("vakata-context-hover")}).on("mouseleave",function(b){a(this).find(".vakata-context-hover").removeClass("vakata-context-hover"),a.vakata.context.settings.hide_onmouseleave&&(d=setTimeout(function(b){return function(){a.vakata.context.hide()}}(this),a.vakata.context.settings.hide_onmouseleave))}).on("click","a",function(b){b.preventDefault(),a(this).blur().parent().hasClass("vakata-context-disabled")||a.vakata.context._execute(a(this).attr("rel"))===!1||a.vakata.context.hide()}).on("keydown","a",function(b){var d=null;switch(b.which){case 13:case 32:b.type="click",b.preventDefault(),a(b.currentTarget).trigger(b);break;case 37:c.is_visible&&(c.element.find(".vakata-context-hover").last().closest("li").first().find("ul").hide().find(".vakata-context-hover").removeClass("vakata-context-hover").end().end().children("a").focus(),b.stopImmediatePropagation(),b.preventDefault());break;case 38:c.is_visible&&(d=c.element.find("ul:visible").addBack().last().children(".vakata-context-hover").removeClass("vakata-context-hover").prevAll("li:not(.vakata-context-separator)").first(), +d.length||(d=c.element.find("ul:visible").addBack().last().children("li:not(.vakata-context-separator)").last()),d.addClass("vakata-context-hover").children("a").focus(),b.stopImmediatePropagation(),b.preventDefault());break;case 39:c.is_visible&&(c.element.find(".vakata-context-hover").last().children("ul").show().children("li:not(.vakata-context-separator)").removeClass("vakata-context-hover").first().addClass("vakata-context-hover").children("a").focus(),b.stopImmediatePropagation(),b.preventDefault());break;case 40:c.is_visible&&(d=c.element.find("ul:visible").addBack().last().children(".vakata-context-hover").removeClass("vakata-context-hover").nextAll("li:not(.vakata-context-separator)").first(),d.length||(d=c.element.find("ul:visible").addBack().last().children("li:not(.vakata-context-separator)").first()),d.addClass("vakata-context-hover").children("a").focus(),b.stopImmediatePropagation(),b.preventDefault());break;case 27:a.vakata.context.hide(),b.preventDefault()}}).on("keydown",function(a){a.preventDefault();var b=c.element.find(".vakata-contextmenu-shortcut-"+a.which).parent();b.parent().not(".vakata-context-disabled")&&b.click()}),a(i).on("mousedown.vakata.jstree",function(b){c.is_visible&&!a.contains(c.element[0],b.target)&&a.vakata.context.hide()}).on("context_show.vakata.jstree",function(a,d){c.element.find("li:has(ul)").children("a").addClass("vakata-context-parent"),b&&c.element.addClass("vakata-context-rtl").css("direction","rtl"),c.element.find("ul").hide().end()})})}(a),a.jstree.defaults.dnd={copy:!0,open_timeout:500,is_draggable:!0,check_while_dragging:!0,always_copy:!1,inside_pos:0,drag_selection:!0,touch:!0,large_drop_target:!1,large_drag_target:!1,use_html5:!1};var k,l;a.jstree.plugins.dnd=function(b,c){this.init=function(a,b){c.init.call(this,a,b),this.settings.dnd.use_html5=this.settings.dnd.use_html5&&"draggable"in i.createElement("span")},this.bind=function(){c.bind.call(this),this.element.on(this.settings.dnd.use_html5?"dragstart.jstree":"mousedown.jstree touchstart.jstree",this.settings.dnd.large_drag_target?".jstree-node":".jstree-anchor",a.proxy(function(b){if(this.settings.dnd.large_drag_target&&a(b.target).closest(".jstree-node")[0]!==b.currentTarget)return!0;if("touchstart"===b.type&&(!this.settings.dnd.touch||"selected"===this.settings.dnd.touch&&!a(b.currentTarget).closest(".jstree-node").children(".jstree-anchor").hasClass("jstree-clicked")))return!0;var c=this.get_node(b.target),d=this.is_selected(c)&&this.settings.dnd.drag_selection?this.get_top_selected().length:1,e=d>1?d+" "+this.get_string("nodes"):this.get_text(b.currentTarget);if(this.settings.core.force_text&&(e=a.vakata.html.escape(e)),c&&c.id&&c.id!==a.jstree.root&&(1===b.which||"touchstart"===b.type||"dragstart"===b.type)&&(this.settings.dnd.is_draggable===!0||a.isFunction(this.settings.dnd.is_draggable)&&this.settings.dnd.is_draggable.call(this,d>1?this.get_top_selected(!0):[c],b))){if(k={jstree:!0,origin:this,obj:this.get_node(c,!0),nodes:d>1?this.get_top_selected():[c.id]},l=b.currentTarget,!this.settings.dnd.use_html5)return this.element.trigger("mousedown.jstree"),a.vakata.dnd.start(b,k,'<div id="jstree-dnd" class="jstree-'+this.get_theme()+" jstree-"+this.get_theme()+"-"+this.get_theme_variant()+" "+(this.settings.core.themes.responsive?" jstree-dnd-responsive":"")+'"><i class="jstree-icon jstree-er"></i>'+e+'<ins class="jstree-copy" style="display:none;">+</ins></div>');a.vakata.dnd._trigger("start",b,{helper:a(),element:l,data:k})}},this)),this.settings.dnd.use_html5&&this.element.on("dragover.jstree",function(b){return b.preventDefault(),a.vakata.dnd._trigger("move",b,{helper:a(),element:l,data:k}),!1}).on("drop.jstree",a.proxy(function(b){return b.preventDefault(),a.vakata.dnd._trigger("stop",b,{helper:a(),element:l,data:k}),!1},this))},this.redraw_node=function(a,b,d,e){if(a=c.redraw_node.apply(this,arguments),a&&this.settings.dnd.use_html5)if(this.settings.dnd.large_drag_target)a.setAttribute("draggable",!0);else{var f,g,h=null;for(f=0,g=a.childNodes.length;g>f;f++)if(a.childNodes[f]&&a.childNodes[f].className&&-1!==a.childNodes[f].className.indexOf("jstree-anchor")){h=a.childNodes[f];break}h&&h.setAttribute("draggable",!0)}return a}},a(function(){var c=!1,d=!1,e=!1,f=!1,g=a('<div id="jstree-marker"> </div>').hide();a(i).on("dnd_start.vakata.jstree",function(a,b){c=!1,e=!1,b&&b.data&&b.data.jstree&&g.appendTo("body")}).on("dnd_move.vakata.jstree",function(h,i){if(f&&(i.event&&"dragover"===i.event.type&&i.event.target===e.target||clearTimeout(f)),i&&i.data&&i.data.jstree&&(!i.event.target.id||"jstree-marker"!==i.event.target.id)){e=i.event;var j=a.jstree.reference(i.event.target),k=!1,l=!1,m=!1,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D;if(j&&j._data&&j._data.dnd)if(g.attr("class","jstree-"+j.get_theme()+(j.settings.core.themes.responsive?" jstree-dnd-responsive":"")),C=i.data.origin&&(i.data.origin.settings.dnd.always_copy||i.data.origin.settings.dnd.copy&&(i.event.metaKey||i.event.ctrlKey)),i.helper.children().attr("class","jstree-"+j.get_theme()+" jstree-"+j.get_theme()+"-"+j.get_theme_variant()+" "+(j.settings.core.themes.responsive?" jstree-dnd-responsive":"")).find(".jstree-copy").first()[C?"show":"hide"](),i.event.target!==j.element[0]&&i.event.target!==j.get_container_ul()[0]||0!==j.get_container_ul().children().length){if(k=j.settings.dnd.large_drop_target?a(i.event.target).closest(".jstree-node").children(".jstree-anchor"):a(i.event.target).closest(".jstree-anchor"),k&&k.length&&k.parent().is(".jstree-closed, .jstree-open, .jstree-leaf")&&(l=k.offset(),m=(i.event.pageY!==b?i.event.pageY:i.event.originalEvent.pageY)-l.top,q=k.outerHeight(),t=q/3>m?["b","i","a"]:m>q-q/3?["a","i","b"]:m>q/2?["i","a","b"]:["i","b","a"],a.each(t,function(b,e){switch(e){case"b":o=l.left-6,p=l.top,r=j.get_parent(k),s=k.parent().index();break;case"i":A=j.settings.dnd.inside_pos,B=j.get_node(k.parent()),o=l.left-2,p=l.top+q/2+1,r=B.id,s="first"===A?0:"last"===A?B.children.length:Math.min(A,B.children.length);break;case"a":o=l.left-6,p=l.top+q,r=j.get_parent(k),s=k.parent().index()+1}for(u=!0,v=0,w=i.data.nodes.length;w>v;v++)if(x=i.data.origin&&(i.data.origin.settings.dnd.always_copy||i.data.origin.settings.dnd.copy&&(i.event.metaKey||i.event.ctrlKey))?"copy_node":"move_node",y=s,"move_node"===x&&"a"===e&&i.data.origin&&i.data.origin===j&&r===j.get_parent(i.data.nodes[v])&&(z=j.get_node(r),y>a.inArray(i.data.nodes[v],z.children)&&(y-=1)),u=u&&(j&&j.settings&&j.settings.dnd&&j.settings.dnd.check_while_dragging===!1||j.check(x,i.data.origin&&i.data.origin!==j?i.data.origin.get_node(i.data.nodes[v]):i.data.nodes[v],r,y,{dnd:!0,ref:j.get_node(k.parent()),pos:e,origin:i.data.origin,is_multi:i.data.origin&&i.data.origin!==j,is_foreign:!i.data.origin})),!u){j&&j.last_error&&(d=j.last_error());break}return"i"===e&&k.parent().is(".jstree-closed")&&j.settings.dnd.open_timeout&&(f=setTimeout(function(a,b){return function(){a.open_node(b)}}(j,k),j.settings.dnd.open_timeout)),u?(D=j.get_node(r,!0),D.hasClass(".jstree-dnd-parent")||(a(".jstree-dnd-parent").removeClass("jstree-dnd-parent"),D.addClass("jstree-dnd-parent")),c={ins:j,par:r,pos:"i"!==e||"last"!==A||0!==s||j.is_loaded(B)?s:"last"},g.css({left:o+"px",top:p+"px"}).show(),i.helper.find(".jstree-icon").first().removeClass("jstree-er").addClass("jstree-ok"),i.event.originalEvent&&i.event.originalEvent.dataTransfer&&(i.event.originalEvent.dataTransfer.dropEffect=C?"copy":"move"),d={},t=!0,!1):void 0}),t===!0))return}else{for(u=!0,v=0,w=i.data.nodes.length;w>v;v++)if(u=u&&j.check(i.data.origin&&(i.data.origin.settings.dnd.always_copy||i.data.origin.settings.dnd.copy&&(i.event.metaKey||i.event.ctrlKey))?"copy_node":"move_node",i.data.origin&&i.data.origin!==j?i.data.origin.get_node(i.data.nodes[v]):i.data.nodes[v],a.jstree.root,"last",{dnd:!0,ref:j.get_node(a.jstree.root),pos:"i",origin:i.data.origin,is_multi:i.data.origin&&i.data.origin!==j,is_foreign:!i.data.origin}),!u)break;if(u)return c={ins:j,par:a.jstree.root,pos:"last"},g.hide(),i.helper.find(".jstree-icon").first().removeClass("jstree-er").addClass("jstree-ok"),void(i.event.originalEvent&&i.event.originalEvent.dataTransfer&&(i.event.originalEvent.dataTransfer.dropEffect=C?"copy":"move"))}a(".jstree-dnd-parent").removeClass("jstree-dnd-parent"),c=!1,i.helper.find(".jstree-icon").removeClass("jstree-ok").addClass("jstree-er"),i.event.originalEvent&&i.event.originalEvent.dataTransfer&&(i.event.originalEvent.dataTransfer.dropEffect="none"),g.hide()}}).on("dnd_scroll.vakata.jstree",function(a,b){b&&b.data&&b.data.jstree&&(g.hide(),c=!1,e=!1,b.helper.find(".jstree-icon").first().removeClass("jstree-ok").addClass("jstree-er"))}).on("dnd_stop.vakata.jstree",function(b,h){if(a(".jstree-dnd-parent").removeClass("jstree-dnd-parent"),f&&clearTimeout(f),h&&h.data&&h.data.jstree){g.hide().detach();var i,j,k=[];if(c){for(i=0,j=h.data.nodes.length;j>i;i++)k[i]=h.data.origin?h.data.origin.get_node(h.data.nodes[i]):h.data.nodes[i];c.ins[h.data.origin&&(h.data.origin.settings.dnd.always_copy||h.data.origin.settings.dnd.copy&&(h.event.metaKey||h.event.ctrlKey))?"copy_node":"move_node"](k,c.par,c.pos,!1,!1,!1,h.data.origin)}else i=a(h.event.target).closest(".jstree"),i.length&&d&&d.error&&"check"===d.error&&(i=i.jstree(!0),i&&i.settings.core.error.call(this,d));e=!1,c=!1}}).on("keyup.jstree keydown.jstree",function(b,h){h=a.vakata.dnd._get(),h&&h.data&&h.data.jstree&&("keyup"===b.type&&27===b.which?(f&&clearTimeout(f),c=!1,d=!1,e=!1,f=!1,g.hide().detach(),a.vakata.dnd._clean()):(h.helper.find(".jstree-copy").first()[h.data.origin&&(h.data.origin.settings.dnd.always_copy||h.data.origin.settings.dnd.copy&&(b.metaKey||b.ctrlKey))?"show":"hide"](),e&&(e.metaKey=b.metaKey,e.ctrlKey=b.ctrlKey,a.vakata.dnd._trigger("move",e))))})}),function(a){a.vakata.html={div:a("<div />"),escape:function(b){return a.vakata.html.div.text(b).html()},strip:function(b){return a.vakata.html.div.empty().append(a.parseHTML(b)).text()}};var c={element:!1,target:!1,is_down:!1,is_drag:!1,helper:!1,helper_w:0,data:!1,init_x:0,init_y:0,scroll_l:0,scroll_t:0,scroll_e:!1,scroll_i:!1,is_touch:!1};a.vakata.dnd={settings:{scroll_speed:10,scroll_proximity:20,helper_left:5,helper_top:10,threshold:5,threshold_touch:50},_trigger:function(c,d,e){e===b&&(e=a.vakata.dnd._get()),e.event=d,a(i).triggerHandler("dnd_"+c+".vakata",e)},_get:function(){return{data:c.data,element:c.element,helper:c.helper}},_clean:function(){c.helper&&c.helper.remove(),c.scroll_i&&(clearInterval(c.scroll_i),c.scroll_i=!1),c={element:!1,target:!1,is_down:!1,is_drag:!1,helper:!1,helper_w:0,data:!1,init_x:0,init_y:0,scroll_l:0,scroll_t:0,scroll_e:!1,scroll_i:!1,is_touch:!1},a(i).off("mousemove.vakata.jstree touchmove.vakata.jstree",a.vakata.dnd.drag),a(i).off("mouseup.vakata.jstree touchend.vakata.jstree",a.vakata.dnd.stop)},_scroll:function(b){if(!c.scroll_e||!c.scroll_l&&!c.scroll_t)return c.scroll_i&&(clearInterval(c.scroll_i),c.scroll_i=!1),!1;if(!c.scroll_i)return c.scroll_i=setInterval(a.vakata.dnd._scroll,100),!1;if(b===!0)return!1;var d=c.scroll_e.scrollTop(),e=c.scroll_e.scrollLeft();c.scroll_e.scrollTop(d+c.scroll_t*a.vakata.dnd.settings.scroll_speed),c.scroll_e.scrollLeft(e+c.scroll_l*a.vakata.dnd.settings.scroll_speed),(d!==c.scroll_e.scrollTop()||e!==c.scroll_e.scrollLeft())&&a.vakata.dnd._trigger("scroll",c.scroll_e)},start:function(b,d,e){"touchstart"===b.type&&b.originalEvent&&b.originalEvent.changedTouches&&b.originalEvent.changedTouches[0]&&(b.pageX=b.originalEvent.changedTouches[0].pageX,b.pageY=b.originalEvent.changedTouches[0].pageY,b.target=i.elementFromPoint(b.originalEvent.changedTouches[0].pageX-window.pageXOffset,b.originalEvent.changedTouches[0].pageY-window.pageYOffset)),c.is_drag&&a.vakata.dnd.stop({});try{b.currentTarget.unselectable="on",b.currentTarget.onselectstart=function(){return!1},b.currentTarget.style&&(b.currentTarget.style.touchAction="none",b.currentTarget.style.msTouchAction="none",b.currentTarget.style.MozUserSelect="none")}catch(f){}return c.init_x=b.pageX,c.init_y=b.pageY,c.data=d,c.is_down=!0,c.element=b.currentTarget,c.target=b.target,c.is_touch="touchstart"===b.type,e!==!1&&(c.helper=a("<div id='vakata-dnd'></div>").html(e).css({display:"block",margin:"0",padding:"0",position:"absolute",top:"-2000px",lineHeight:"16px",zIndex:"10000"})),a(i).on("mousemove.vakata.jstree touchmove.vakata.jstree",a.vakata.dnd.drag),a(i).on("mouseup.vakata.jstree touchend.vakata.jstree",a.vakata.dnd.stop),!1},drag:function(b){if("touchmove"===b.type&&b.originalEvent&&b.originalEvent.changedTouches&&b.originalEvent.changedTouches[0]&&(b.pageX=b.originalEvent.changedTouches[0].pageX,b.pageY=b.originalEvent.changedTouches[0].pageY,b.target=i.elementFromPoint(b.originalEvent.changedTouches[0].pageX-window.pageXOffset,b.originalEvent.changedTouches[0].pageY-window.pageYOffset)),c.is_down){if(!c.is_drag){if(!(Math.abs(b.pageX-c.init_x)>(c.is_touch?a.vakata.dnd.settings.threshold_touch:a.vakata.dnd.settings.threshold)||Math.abs(b.pageY-c.init_y)>(c.is_touch?a.vakata.dnd.settings.threshold_touch:a.vakata.dnd.settings.threshold)))return;c.helper&&(c.helper.appendTo("body"),c.helper_w=c.helper.outerWidth()),c.is_drag=!0,a(c.target).one("click.vakata",!1),a.vakata.dnd._trigger("start",b)}var d=!1,e=!1,f=!1,g=!1,h=!1,j=!1,k=!1,l=!1,m=!1,n=!1;return c.scroll_t=0,c.scroll_l=0,c.scroll_e=!1,a(a(b.target).parentsUntil("body").addBack().get().reverse()).filter(function(){return/^auto|scroll$/.test(a(this).css("overflow"))&&(this.scrollHeight>this.offsetHeight||this.scrollWidth>this.offsetWidth)}).each(function(){var d=a(this),e=d.offset();return this.scrollHeight>this.offsetHeight&&(e.top+d.height()-b.pageY<a.vakata.dnd.settings.scroll_proximity&&(c.scroll_t=1),b.pageY-e.top<a.vakata.dnd.settings.scroll_proximity&&(c.scroll_t=-1)),this.scrollWidth>this.offsetWidth&&(e.left+d.width()-b.pageX<a.vakata.dnd.settings.scroll_proximity&&(c.scroll_l=1),b.pageX-e.left<a.vakata.dnd.settings.scroll_proximity&&(c.scroll_l=-1)),c.scroll_t||c.scroll_l?(c.scroll_e=a(this),!1):void 0}),c.scroll_e||(d=a(i),e=a(window),f=d.height(),g=e.height(),h=d.width(),j=e.width(),k=d.scrollTop(),l=d.scrollLeft(),f>g&&b.pageY-k<a.vakata.dnd.settings.scroll_proximity&&(c.scroll_t=-1),f>g&&g-(b.pageY-k)<a.vakata.dnd.settings.scroll_proximity&&(c.scroll_t=1),h>j&&b.pageX-l<a.vakata.dnd.settings.scroll_proximity&&(c.scroll_l=-1),h>j&&j-(b.pageX-l)<a.vakata.dnd.settings.scroll_proximity&&(c.scroll_l=1),(c.scroll_t||c.scroll_l)&&(c.scroll_e=d)),c.scroll_e&&a.vakata.dnd._scroll(!0),c.helper&&(m=parseInt(b.pageY+a.vakata.dnd.settings.helper_top,10),n=parseInt(b.pageX+a.vakata.dnd.settings.helper_left,10),f&&m+25>f&&(m=f-50),h&&n+c.helper_w>h&&(n=h-(c.helper_w+2)),c.helper.css({left:n+"px",top:m+"px"})),a.vakata.dnd._trigger("move",b),!1}},stop:function(b){if("touchend"===b.type&&b.originalEvent&&b.originalEvent.changedTouches&&b.originalEvent.changedTouches[0]&&(b.pageX=b.originalEvent.changedTouches[0].pageX,b.pageY=b.originalEvent.changedTouches[0].pageY,b.target=i.elementFromPoint(b.originalEvent.changedTouches[0].pageX-window.pageXOffset,b.originalEvent.changedTouches[0].pageY-window.pageYOffset)),c.is_drag)b.target!==c.target&&a(c.target).off("click.vakata"),a.vakata.dnd._trigger("stop",b);else if("touchend"===b.type&&b.target===c.target){var d=setTimeout(function(){a(b.target).click()},100);a(b.target).one("click",function(){d&&clearTimeout(d)})}return a.vakata.dnd._clean(),!1}}}(a),a.jstree.defaults.massload=null,a.jstree.plugins.massload=function(b,c){this.init=function(a,b){this._data.massload={},c.init.call(this,a,b)},this._load_nodes=function(b,d,e,f){var g=this.settings.massload,h=JSON.stringify(b),i=[],j=this._model.data,k,l,m;if(!e){for(k=0,l=b.length;l>k;k++)(!j[b[k]]||!j[b[k]].state.loaded&&!j[b[k]].state.failed||f)&&(i.push(b[k]),m=this.get_node(b[k],!0),m&&m.length&&m.addClass("jstree-loading").attr("aria-busy",!0));if(this._data.massload={},i.length){if(a.isFunction(g))return g.call(this,i,a.proxy(function(a){var g,h;if(a)for(g in a)a.hasOwnProperty(g)&&(this._data.massload[g]=a[g]);for(g=0,h=b.length;h>g;g++)m=this.get_node(b[g],!0),m&&m.length&&m.removeClass("jstree-loading").attr("aria-busy",!1);c._load_nodes.call(this,b,d,e,f)},this));if("object"==typeof g&&g&&g.url)return g=a.extend(!0,{},g),a.isFunction(g.url)&&(g.url=g.url.call(this,i)),a.isFunction(g.data)&&(g.data=g.data.call(this,i)),a.ajax(g).done(a.proxy(function(a,g,h){var i,j;if(a)for(i in a)a.hasOwnProperty(i)&&(this._data.massload[i]=a[i]);for(i=0,j=b.length;j>i;i++)m=this.get_node(b[i],!0),m&&m.length&&m.removeClass("jstree-loading").attr("aria-busy",!1);c._load_nodes.call(this,b,d,e,f)},this)).fail(a.proxy(function(a){c._load_nodes.call(this,b,d,e,f)},this))}}return c._load_nodes.call(this,b,d,e,f)},this._load_node=function(b,d){var e=this._data.massload[b.id],f=null,g;return e?(f=this["string"==typeof e?"_append_html_data":"_append_json_data"](b,"string"==typeof e?a(a.parseHTML(e)).filter(function(){return 3!==this.nodeType}):e,function(a){d.call(this,a)}),g=this.get_node(b.id,!0),g&&g.length&&g.removeClass("jstree-loading").attr("aria-busy",!1),delete this._data.massload[b.id],f):c._load_node.call(this,b,d)}},a.jstree.defaults.search={ajax:!1,fuzzy:!1,case_sensitive:!1,show_only_matches:!1,show_only_matches_children:!1,close_opened_onclear:!0,search_leaves_only:!1,search_callback:!1},a.jstree.plugins.search=function(c,d){this.bind=function(){d.bind.call(this),this._data.search.str="",this._data.search.dom=a(),this._data.search.res=[],this._data.search.opn=[],this._data.search.som=!1,this._data.search.smc=!1,this._data.search.hdn=[],this.element.on("search.jstree",a.proxy(function(b,c){if(this._data.search.som&&c.res.length){var d=this._model.data,e,f,g=[],h,i;for(e=0,f=c.res.length;f>e;e++)if(d[c.res[e]]&&!d[c.res[e]].state.hidden&&(g.push(c.res[e]),g=g.concat(d[c.res[e]].parents),this._data.search.smc))for(h=0,i=d[c.res[e]].children_d.length;i>h;h++)d[d[c.res[e]].children_d[h]]&&!d[d[c.res[e]].children_d[h]].state.hidden&&g.push(d[c.res[e]].children_d[h]);g=a.vakata.array_remove_item(a.vakata.array_unique(g),a.jstree.root),this._data.search.hdn=this.hide_all(!0),this.show_node(g,!0),this.redraw(!0)}},this)).on("clear_search.jstree",a.proxy(function(a,b){this._data.search.som&&b.res.length&&(this.show_node(this._data.search.hdn,!0),this.redraw(!0))},this))},this.search=function(c,d,e,f,g,h){if(c===!1||""===a.trim(c.toString()))return this.clear_search();f=this.get_node(f),f=f&&f.id?f.id:null,c=c.toString();var i=this.settings.search,j=i.ajax?i.ajax:!1,k=this._model.data,l=null,m=[],n=[],o,p;if(this._data.search.res.length&&!g&&this.clear_search(),e===b&&(e=i.show_only_matches),h===b&&(h=i.show_only_matches_children),!d&&j!==!1)return a.isFunction(j)?j.call(this,c,a.proxy(function(b){b&&b.d&&(b=b.d),this._load_nodes(a.isArray(b)?a.vakata.array_unique(b):[],function(){this.search(c,!0,e,f,g,h)})},this),f):(j=a.extend({},j),j.data||(j.data={}),j.data.str=c,f&&(j.data.inside=f),this._data.search.lastRequest&&this._data.search.lastRequest.abort(),this._data.search.lastRequest=a.ajax(j).fail(a.proxy(function(){this._data.core.last_error={error:"ajax",plugin:"search",id:"search_01",reason:"Could not load search parents",data:JSON.stringify(j)},this.settings.core.error.call(this,this._data.core.last_error)},this)).done(a.proxy(function(b){b&&b.d&&(b=b.d),this._load_nodes(a.isArray(b)?a.vakata.array_unique(b):[],function(){this.search(c,!0,e,f,g,h)})},this)),this._data.search.lastRequest);if(g||(this._data.search.str=c,this._data.search.dom=a(),this._data.search.res=[],this._data.search.opn=[],this._data.search.som=e,this._data.search.smc=h),l=new a.vakata.search(c,!0,{caseSensitive:i.case_sensitive,fuzzy:i.fuzzy}),a.each(k[f?f:a.jstree.root].children_d,function(a,b){var d=k[b];d.text&&!d.state.hidden&&(!i.search_leaves_only||d.state.loaded&&0===d.children.length)&&(i.search_callback&&i.search_callback.call(this,c,d)||!i.search_callback&&l.search(d.text).isMatch)&&(m.push(b),n=n.concat(d.parents))}),m.length){for(n=a.vakata.array_unique(n),o=0,p=n.length;p>o;o++)n[o]!==a.jstree.root&&k[n[o]]&&this.open_node(n[o],null,0)===!0&&this._data.search.opn.push(n[o]);g?(this._data.search.dom=this._data.search.dom.add(a(this.element[0].querySelectorAll("#"+a.map(m,function(b){return-1!=="0123456789".indexOf(b[0])?"\\3"+b[0]+" "+b.substr(1).replace(a.jstree.idregex,"\\$&"):b.replace(a.jstree.idregex,"\\$&")}).join(", #")))),this._data.search.res=a.vakata.array_unique(this._data.search.res.concat(m))):(this._data.search.dom=a(this.element[0].querySelectorAll("#"+a.map(m,function(b){return-1!=="0123456789".indexOf(b[0])?"\\3"+b[0]+" "+b.substr(1).replace(a.jstree.idregex,"\\$&"):b.replace(a.jstree.idregex,"\\$&")}).join(", #"))),this._data.search.res=m),this._data.search.dom.children(".jstree-anchor").addClass("jstree-search")}this.trigger("search",{nodes:this._data.search.dom,str:c,res:this._data.search.res,show_only_matches:e})},this.clear_search=function(){this.settings.search.close_opened_onclear&&this.close_node(this._data.search.opn,0),this.trigger("clear_search",{nodes:this._data.search.dom,str:this._data.search.str,res:this._data.search.res}),this._data.search.res.length&&(this._data.search.dom=a(this.element[0].querySelectorAll("#"+a.map(this._data.search.res,function(b){return-1!=="0123456789".indexOf(b[0])?"\\3"+b[0]+" "+b.substr(1).replace(a.jstree.idregex,"\\$&"):b.replace(a.jstree.idregex,"\\$&")}).join(", #"))),this._data.search.dom.children(".jstree-anchor").removeClass("jstree-search")),this._data.search.str="",this._data.search.res=[],this._data.search.opn=[],this._data.search.dom=a()},this.redraw_node=function(b,c,e,f){if(b=d.redraw_node.apply(this,arguments),b&&-1!==a.inArray(b.id,this._data.search.res)){var g,h,i=null;for(g=0,h=b.childNodes.length;h>g;g++)if(b.childNodes[g]&&b.childNodes[g].className&&-1!==b.childNodes[g].className.indexOf("jstree-anchor")){i=b.childNodes[g];break}i&&(i.className+=" jstree-search")}return b}},function(a){a.vakata.search=function(b,c,d){d=d||{},d=a.extend({},a.vakata.search.defaults,d),d.fuzzy!==!1&&(d.fuzzy=!0),b=d.caseSensitive?b:b.toLowerCase();var e=d.location,f=d.distance,g=d.threshold,h=b.length,i,j,k,l;return h>32&&(d.fuzzy=!1),d.fuzzy&&(i=1<<h-1,j=function(){var a={},c=0;for(c=0;h>c;c++)a[b.charAt(c)]=0;for(c=0;h>c;c++)a[b.charAt(c)]|=1<<h-c-1;return a}(),k=function(a,b){var c=a/h,d=Math.abs(e-b);return f?c+d/f:d?1:c}),l=function(a){if(a=d.caseSensitive?a:a.toLowerCase(),b===a||-1!==a.indexOf(b))return{isMatch:!0,score:0};if(!d.fuzzy)return{isMatch:!1,score:1};var c,f,l=a.length,m=g,n=a.indexOf(b,e),o,p,q=h+l,r,s,t,u,v,w=1,x=[];for(-1!==n&&(m=Math.min(k(0,n),m),n=a.lastIndexOf(b,e+h),-1!==n&&(m=Math.min(k(0,n),m))),n=-1,c=0;h>c;c++){o=0,p=q;while(p>o)k(c,e+p)<=m?o=p:q=p,p=Math.floor((q-o)/2+o);for(q=p,s=Math.max(1,e-p+1),t=Math.min(e+p,l)+h,u=new Array(t+2),u[t+1]=(1<<c)-1,f=t;f>=s;f--)if(v=j[a.charAt(f-1)],0===c?u[f]=(u[f+1]<<1|1)&v:u[f]=(u[f+1]<<1|1)&v|((r[f+1]|r[f])<<1|1)|r[f+1],u[f]&i&&(w=k(c,f-1),m>=w)){if(m=w,n=f-1,x.push(n),!(n>e))break;s=Math.max(1,2*e-n)}if(k(c+1,e)>m)break;r=u}return{isMatch:n>=0,score:w}},c===!0?{search:l}:l(c)},a.vakata.search.defaults={location:0,distance:100,threshold:.6,fuzzy:!1,caseSensitive:!1}}(a),a.jstree.defaults.sort=function(a,b){return this.get_text(a)>this.get_text(b)?1:-1},a.jstree.plugins.sort=function(b,c){this.bind=function(){c.bind.call(this),this.element.on("model.jstree",a.proxy(function(a,b){this.sort(b.parent,!0)},this)).on("rename_node.jstree create_node.jstree",a.proxy(function(a,b){this.sort(b.parent||b.node.parent,!1),this.redraw_node(b.parent||b.node.parent,!0)},this)).on("move_node.jstree copy_node.jstree",a.proxy(function(a,b){this.sort(b.parent,!1),this.redraw_node(b.parent,!0)},this))},this.sort=function(b,c){var d,e;if(b=this.get_node(b),b&&b.children&&b.children.length&&(b.children.sort(a.proxy(this.settings.sort,this)),c))for(d=0,e=b.children_d.length;e>d;d++)this.sort(b.children_d[d],!1)}};var m=!1;a.jstree.defaults.state={key:"jstree",events:"changed.jstree open_node.jstree close_node.jstree check_node.jstree uncheck_node.jstree",ttl:!1,filter:!1},a.jstree.plugins.state=function(b,c){this.bind=function(){c.bind.call(this);var b=a.proxy(function(){this.element.on(this.settings.state.events,a.proxy(function(){m&&clearTimeout(m),m=setTimeout(a.proxy(function(){this.save_state()},this),100)},this)),this.trigger("state_ready")},this);this.element.on("ready.jstree",a.proxy(function(a,c){this.element.one("restore_state.jstree",b),this.restore_state()||b()},this))},this.save_state=function(){var b={state:this.get_state(),ttl:this.settings.state.ttl,sec:+new Date};a.vakata.storage.set(this.settings.state.key,JSON.stringify(b))},this.restore_state=function(){var b=a.vakata.storage.get(this.settings.state.key);if(b)try{b=JSON.parse(b)}catch(c){return!1}return b&&b.ttl&&b.sec&&+new Date-b.sec>b.ttl?!1:(b&&b.state&&(b=b.state),b&&a.isFunction(this.settings.state.filter)&&(b=this.settings.state.filter.call(this,b)),b?(this.element.one("set_state.jstree",function(c,d){d.instance.trigger("restore_state",{state:a.extend(!0,{},b)})}),this.set_state(b),!0):!1)},this.clear_state=function(){return a.vakata.storage.del(this.settings.state.key)}},function(a,b){a.vakata.storage={set:function(a,b){return window.localStorage.setItem(a,b)},get:function(a){return window.localStorage.getItem(a)},del:function(a){return window.localStorage.removeItem(a)}}}(a),a.jstree.defaults.types={"default":{}},a.jstree.defaults.types[a.jstree.root]={},a.jstree.plugins.types=function(c,d){this.init=function(c,e){var f,g;if(e&&e.types&&e.types["default"])for(f in e.types)if("default"!==f&&f!==a.jstree.root&&e.types.hasOwnProperty(f))for(g in e.types["default"])e.types["default"].hasOwnProperty(g)&&e.types[f][g]===b&&(e.types[f][g]=e.types["default"][g]);d.init.call(this,c,e),this._model.data[a.jstree.root].type=a.jstree.root},this.refresh=function(b,c){d.refresh.call(this,b,c),this._model.data[a.jstree.root].type=a.jstree.root},this.bind=function(){this.element.on("model.jstree",a.proxy(function(c,d){var e=this._model.data,f=d.nodes,g=this.settings.types,h,i,j="default",k;for(h=0,i=f.length;i>h;h++){if(j="default",e[f[h]].original&&e[f[h]].original.type&&g[e[f[h]].original.type]&&(j=e[f[h]].original.type),e[f[h]].data&&e[f[h]].data.jstree&&e[f[h]].data.jstree.type&&g[e[f[h]].data.jstree.type]&&(j=e[f[h]].data.jstree.type),e[f[h]].type=j,e[f[h]].icon===!0&&g[j].icon!==b&&(e[f[h]].icon=g[j].icon),g[j].li_attr!==b&&"object"==typeof g[j].li_attr)for(k in g[j].li_attr)if(g[j].li_attr.hasOwnProperty(k)){if("id"===k)continue;e[f[h]].li_attr[k]===b?e[f[h]].li_attr[k]=g[j].li_attr[k]:"class"===k&&(e[f[h]].li_attr["class"]=g[j].li_attr["class"]+" "+e[f[h]].li_attr["class"])}if(g[j].a_attr!==b&&"object"==typeof g[j].a_attr)for(k in g[j].a_attr)if(g[j].a_attr.hasOwnProperty(k)){if("id"===k)continue;e[f[h]].a_attr[k]===b?e[f[h]].a_attr[k]=g[j].a_attr[k]:"href"===k&&"#"===e[f[h]].a_attr[k]?e[f[h]].a_attr.href=g[j].a_attr.href:"class"===k&&(e[f[h]].a_attr["class"]=g[j].a_attr["class"]+" "+e[f[h]].a_attr["class"])}}e[a.jstree.root].type=a.jstree.root},this)),d.bind.call(this)},this.get_json=function(b,c,e){var f,g,h=this._model.data,i=c?a.extend(!0,{},c,{no_id:!1}):{},j=d.get_json.call(this,b,i,e);if(j===!1)return!1;if(a.isArray(j))for(f=0,g=j.length;g>f;f++)j[f].type=j[f].id&&h[j[f].id]&&h[j[f].id].type?h[j[f].id].type:"default",c&&c.no_id&&(delete j[f].id,j[f].li_attr&&j[f].li_attr.id&&delete j[f].li_attr.id,j[f].a_attr&&j[f].a_attr.id&&delete j[f].a_attr.id);else j.type=j.id&&h[j.id]&&h[j.id].type?h[j.id].type:"default",c&&c.no_id&&(j=this._delete_ids(j));return j},this._delete_ids=function(b){if(a.isArray(b)){for(var c=0,d=b.length;d>c;c++)b[c]=this._delete_ids(b[c]);return b}return delete b.id,b.li_attr&&b.li_attr.id&&delete b.li_attr.id,b.a_attr&&b.a_attr.id&&delete b.a_attr.id,b.children&&a.isArray(b.children)&&(b.children=this._delete_ids(b.children)),b},this.check=function(c,e,f,g,h){if(d.check.call(this,c,e,f,g,h)===!1)return!1;e=e&&e.id?e:this.get_node(e),f=f&&f.id?f:this.get_node(f);var i=e&&e.id?h&&h.origin?h.origin:a.jstree.reference(e.id):null,j,k,l,m;switch(i=i&&i._model&&i._model.data?i._model.data:null,c){case"create_node":case"move_node":case"copy_node":if("move_node"!==c||-1===a.inArray(e.id,f.children)){if(j=this.get_rules(f),j.max_children!==b&&-1!==j.max_children&&j.max_children===f.children.length)return this._data.core.last_error={error:"check",plugin:"types",id:"types_01",reason:"max_children prevents function: "+c,data:JSON.stringify({chk:c,pos:g,obj:e&&e.id?e.id:!1,par:f&&f.id?f.id:!1})},!1;if(j.valid_children!==b&&-1!==j.valid_children&&-1===a.inArray(e.type||"default",j.valid_children))return this._data.core.last_error={error:"check",plugin:"types",id:"types_02",reason:"valid_children prevents function: "+c,data:JSON.stringify({chk:c,pos:g,obj:e&&e.id?e.id:!1,par:f&&f.id?f.id:!1})},!1;if(i&&e.children_d&&e.parents){for(k=0,l=0,m=e.children_d.length;m>l;l++)k=Math.max(k,i[e.children_d[l]].parents.length);k=k-e.parents.length+1}(0>=k||k===b)&&(k=1);do{if(j.max_depth!==b&&-1!==j.max_depth&&j.max_depth<k)return this._data.core.last_error={error:"check",plugin:"types",id:"types_03",reason:"max_depth prevents function: "+c,data:JSON.stringify({chk:c,pos:g,obj:e&&e.id?e.id:!1,par:f&&f.id?f.id:!1})},!1;f=this.get_node(f.parent),j=this.get_rules(f),k++}while(f)}}return!0},this.get_rules=function(a){if(a=this.get_node(a),!a)return!1;var c=this.get_type(a,!0);return c.max_depth===b&&(c.max_depth=-1),c.max_children===b&&(c.max_children=-1),c.valid_children===b&&(c.valid_children=-1),c},this.get_type=function(b,c){return b=this.get_node(b),b?c?a.extend({type:b.type},this.settings.types[b.type]):b.type:!1},this.set_type=function(c,d){var e=this._model.data,f,g,h,i,j,k,l,m;if(a.isArray(c)){for(c=c.slice(),g=0,h=c.length;h>g;g++)this.set_type(c[g],d);return!0}if(f=this.settings.types,c=this.get_node(c),!f[d]||!c)return!1;if(l=this.get_node(c,!0),l&&l.length&&(m=l.children(".jstree-anchor")),i=c.type,j=this.get_icon(c),c.type=d,(j===!0||!f[i]||f[i].icon!==b&&j===f[i].icon)&&this.set_icon(c,f[d].icon!==b?f[d].icon:!0),f[i]&&f[i].li_attr!==b&&"object"==typeof f[i].li_attr)for(k in f[i].li_attr)if(f[i].li_attr.hasOwnProperty(k)){if("id"===k)continue;"class"===k?(e[c.id].li_attr["class"]=(e[c.id].li_attr["class"]||"").replace(f[i].li_attr[k],""),l&&l.removeClass(f[i].li_attr[k])):e[c.id].li_attr[k]===f[i].li_attr[k]&&(e[c.id].li_attr[k]=null,l&&l.removeAttr(k))}if(f[i]&&f[i].a_attr!==b&&"object"==typeof f[i].a_attr)for(k in f[i].a_attr)if(f[i].a_attr.hasOwnProperty(k)){if("id"===k)continue;"class"===k?(e[c.id].a_attr["class"]=(e[c.id].a_attr["class"]||"").replace(f[i].a_attr[k],""),m&&m.removeClass(f[i].a_attr[k])):e[c.id].a_attr[k]===f[i].a_attr[k]&&("href"===k?(e[c.id].a_attr[k]="#",m&&m.attr("href","#")):(delete e[c.id].a_attr[k],m&&m.removeAttr(k)))}if(f[d].li_attr!==b&&"object"==typeof f[d].li_attr)for(k in f[d].li_attr)if(f[d].li_attr.hasOwnProperty(k)){if("id"===k)continue;e[c.id].li_attr[k]===b?(e[c.id].li_attr[k]=f[d].li_attr[k],l&&("class"===k?l.addClass(f[d].li_attr[k]):l.attr(k,f[d].li_attr[k]))):"class"===k&&(e[c.id].li_attr["class"]=f[d].li_attr[k]+" "+e[c.id].li_attr["class"],l&&l.addClass(f[d].li_attr[k]))}if(f[d].a_attr!==b&&"object"==typeof f[d].a_attr)for(k in f[d].a_attr)if(f[d].a_attr.hasOwnProperty(k)){if("id"===k)continue;e[c.id].a_attr[k]===b?(e[c.id].a_attr[k]=f[d].a_attr[k],m&&("class"===k?m.addClass(f[d].a_attr[k]):m.attr(k,f[d].a_attr[k]))):"href"===k&&"#"===e[c.id].a_attr[k]?(e[c.id].a_attr.href=f[d].a_attr.href,m&&m.attr("href",f[d].a_attr.href)):"class"===k&&(e[c.id].a_attr["class"]=f[d].a_attr["class"]+" "+e[c.id].a_attr["class"],m&&m.addClass(f[d].a_attr[k]))}return!0}},a.jstree.defaults.unique={case_sensitive:!1,duplicate:function(a,b){return a+" ("+b+")"}},a.jstree.plugins.unique=function(c,d){this.check=function(b,c,e,f,g){if(d.check.call(this,b,c,e,f,g)===!1)return!1; +if(c=c&&c.id?c:this.get_node(c),e=e&&e.id?e:this.get_node(e),!e||!e.children)return!0;var h="rename_node"===b?f:c.text,i=[],j=this.settings.unique.case_sensitive,k=this._model.data,l,m;for(l=0,m=e.children.length;m>l;l++)i.push(j?k[e.children[l]].text:k[e.children[l]].text.toLowerCase());switch(j||(h=h.toLowerCase()),b){case"delete_node":return!0;case"rename_node":return l=-1===a.inArray(h,i)||c.text&&c.text[j?"toString":"toLowerCase"]()===h,l||(this._data.core.last_error={error:"check",plugin:"unique",id:"unique_01",reason:"Child with name "+h+" already exists. Preventing: "+b,data:JSON.stringify({chk:b,pos:f,obj:c&&c.id?c.id:!1,par:e&&e.id?e.id:!1})}),l;case"create_node":return l=-1===a.inArray(h,i),l||(this._data.core.last_error={error:"check",plugin:"unique",id:"unique_04",reason:"Child with name "+h+" already exists. Preventing: "+b,data:JSON.stringify({chk:b,pos:f,obj:c&&c.id?c.id:!1,par:e&&e.id?e.id:!1})}),l;case"copy_node":return l=-1===a.inArray(h,i),l||(this._data.core.last_error={error:"check",plugin:"unique",id:"unique_02",reason:"Child with name "+h+" already exists. Preventing: "+b,data:JSON.stringify({chk:b,pos:f,obj:c&&c.id?c.id:!1,par:e&&e.id?e.id:!1})}),l;case"move_node":return l=c.parent===e.id&&(!g||!g.is_multi)||-1===a.inArray(h,i),l||(this._data.core.last_error={error:"check",plugin:"unique",id:"unique_03",reason:"Child with name "+h+" already exists. Preventing: "+b,data:JSON.stringify({chk:b,pos:f,obj:c&&c.id?c.id:!1,par:e&&e.id?e.id:!1})}),l}return!0},this.create_node=function(c,e,f,g,h){if(!e||e.text===b){if(null===c&&(c=a.jstree.root),c=this.get_node(c),!c)return d.create_node.call(this,c,e,f,g,h);if(f=f===b?"last":f,!f.toString().match(/^(before|after)$/)&&!h&&!this.is_loaded(c))return d.create_node.call(this,c,e,f,g,h);e||(e={});var i,j,k,l,m,n=this._model.data,o=this.settings.unique.case_sensitive,p=this.settings.unique.duplicate;for(j=i=this.get_string("New node"),k=[],l=0,m=c.children.length;m>l;l++)k.push(o?n[c.children[l]].text:n[c.children[l]].text.toLowerCase());l=1;while(-1!==a.inArray(o?j:j.toLowerCase(),k))j=p.call(this,i,++l).toString();e.text=j}return d.create_node.call(this,c,e,f,g,h)}};var n=i.createElement("DIV");if(n.setAttribute("unselectable","on"),n.setAttribute("role","presentation"),n.className="jstree-wholerow",n.innerHTML=" ",a.jstree.plugins.wholerow=function(b,c){this.bind=function(){c.bind.call(this),this.element.on("ready.jstree set_state.jstree",a.proxy(function(){this.hide_dots()},this)).on("init.jstree loading.jstree ready.jstree",a.proxy(function(){this.get_container_ul().addClass("jstree-wholerow-ul")},this)).on("deselect_all.jstree",a.proxy(function(a,b){this.element.find(".jstree-wholerow-clicked").removeClass("jstree-wholerow-clicked")},this)).on("changed.jstree",a.proxy(function(a,b){this.element.find(".jstree-wholerow-clicked").removeClass("jstree-wholerow-clicked");var c=!1,d,e;for(d=0,e=b.selected.length;e>d;d++)c=this.get_node(b.selected[d],!0),c&&c.length&&c.children(".jstree-wholerow").addClass("jstree-wholerow-clicked")},this)).on("open_node.jstree",a.proxy(function(a,b){this.get_node(b.node,!0).find(".jstree-clicked").parent().children(".jstree-wholerow").addClass("jstree-wholerow-clicked")},this)).on("hover_node.jstree dehover_node.jstree",a.proxy(function(a,b){"hover_node"===a.type&&this.is_disabled(b.node)||this.get_node(b.node,!0).children(".jstree-wholerow")["hover_node"===a.type?"addClass":"removeClass"]("jstree-wholerow-hovered")},this)).on("contextmenu.jstree",".jstree-wholerow",a.proxy(function(b){if(this._data.contextmenu){b.preventDefault();var c=a.Event("contextmenu",{metaKey:b.metaKey,ctrlKey:b.ctrlKey,altKey:b.altKey,shiftKey:b.shiftKey,pageX:b.pageX,pageY:b.pageY});a(b.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(c)}},this)).on("click.jstree",".jstree-wholerow",function(b){b.stopImmediatePropagation();var c=a.Event("click",{metaKey:b.metaKey,ctrlKey:b.ctrlKey,altKey:b.altKey,shiftKey:b.shiftKey});a(b.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(c).focus()}).on("dblclick.jstree",".jstree-wholerow",function(b){b.stopImmediatePropagation();var c=a.Event("dblclick",{metaKey:b.metaKey,ctrlKey:b.ctrlKey,altKey:b.altKey,shiftKey:b.shiftKey});a(b.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(c).focus()}).on("click.jstree",".jstree-leaf > .jstree-ocl",a.proxy(function(b){b.stopImmediatePropagation();var c=a.Event("click",{metaKey:b.metaKey,ctrlKey:b.ctrlKey,altKey:b.altKey,shiftKey:b.shiftKey});a(b.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(c).focus()},this)).on("mouseover.jstree",".jstree-wholerow, .jstree-icon",a.proxy(function(a){return a.stopImmediatePropagation(),this.is_disabled(a.currentTarget)||this.hover_node(a.currentTarget),!1},this)).on("mouseleave.jstree",".jstree-node",a.proxy(function(a){this.dehover_node(a.currentTarget)},this))},this.teardown=function(){this.settings.wholerow&&this.element.find(".jstree-wholerow").remove(),c.teardown.call(this)},this.redraw_node=function(b,d,e,f){if(b=c.redraw_node.apply(this,arguments)){var g=n.cloneNode(!0);-1!==a.inArray(b.id,this._data.core.selected)&&(g.className+=" jstree-wholerow-clicked"),this._data.core.focused&&this._data.core.focused===b.id&&(g.className+=" jstree-wholerow-hovered"),b.insertBefore(g,b.childNodes[0])}return b}},i.registerElement&&Object&&Object.create){var o=Object.create(HTMLElement.prototype);o.createdCallback=function(){var b={core:{},plugins:[]},c;for(c in a.jstree.plugins)a.jstree.plugins.hasOwnProperty(c)&&this.attributes[c]&&(b.plugins.push(c),this.getAttribute(c)&&JSON.parse(this.getAttribute(c))&&(b[c]=JSON.parse(this.getAttribute(c))));for(c in a.jstree.defaults.core)a.jstree.defaults.core.hasOwnProperty(c)&&this.attributes[c]&&(b.core[c]=JSON.parse(this.getAttribute(c))||this.getAttribute(c));a(this).jstree(b)};try{i.registerElement("vakata-jstree",{prototype:o})}catch(p){}}}}); \ No newline at end of file diff --git a/civicrm/bower_components/jstree/dist/themes/default-dark/32px.png b/civicrm/bower_components/jstree/dist/themes/default-dark/32px.png new file mode 100644 index 0000000000000000000000000000000000000000..d6fd72114f8205ace7579894ec50cc37739b1471 GIT binary patch literal 1562 zcmZ8heKga182_1NL)y?Sx!97DWU52*G8;`HFB3{gC^fx#KelDfGF0oNTV6Y2ZdXn( zW?q&;2$$7yGo_jk?dL78m$BH`?oapJf9~_g^E}_rdCuo~&i8zt=LXs5u#T3Y761S` z9`2;00H8*M@^GX&<U?{o453g+_6l%=A{-7^S6{;+Q&Us>H~F9M=;#m#1Z8Dq5Z>6> z$mjF#-n~0GIQa47M*@KWf$i<>91aJI#ZoAgjEs!d)>f5DH9kIGP*5;GKd(?ICMG77 zO6APVj7%n*nwnZ#T3T3GSX^A}>+6GfKoAs(L}IbHv$Inu6lP^*QK{7Q%Q;&hYLmpH zKK_8EZ-l{ijlJvfy6TRlf7~;9DPVu?BhfnV*dK~6$QQ=l0)TZW50Xm&^~-c2Cs^XJ zG2LRnx7N-)T||;kWH254-Gre^cGMJXz<XQYvjIiD7d8@lTX&sU^}k;gWixTyH+S+> zIbn5~l}bdTk#HD`I8<!jmGrl-J@0b@gLG#%c3%K&-~yd@p>|A;99ehHfebTtaNb7o zGG3K;76(qcr3!~V^z!nRWo5aU&-H`AEDPT1G+30PS2S8u73QQ}EU)%_Ff^AV5?k+1 zM3Q=9yvY~Cu9z1rB_q)cA94?xD+WqIPvh>Y8jTwk4}SYJ7x;XDhSF61*rcj;P;F3? zbajJrz<1dK)~3=%Pol3!i&})y(x5z|zRCoajmUH&{JC+)Al#Bw6USa2^+xu{>`<{g zZZj?y70(;=YP0^@W~My$HkHU=N`a0Rxu=|Co@%A%{y4<3F|mV|yI(&@SvJpn`gpT) z_K5>-<ff$s=SnPkc3;u71b8|DV%<L+&>7wk&=XZjzOO-tYaC5tql=~NO7^5aWhm>& z!4?-=;8r!;7<D-JOi*C)@`)X?u4w5^dgntvx$QI__F({5{vd)^b5;_fuxW3@<YlnI z^MJwODL%6o6U5F*k{tHSjtTS2L*dM<YLLT)c19&+sr}hZKxZXR(<}6KK!2Kn{#K(l ztD~RRfm5d;>Ub&*w-E2Xfb`NE9F6<}appJs<#6A7k^%`KZWa^Yl*@~Qp%q;UGKbjq zZ1mjlEW1>2d3+(XqXhf6Z60<{k178{uvivcKZB&TzDojSp_`?u7tA*T!p(<3C~8F@ zA6v1*i_$dccr+Y-jYz~Ik#NQwj$Su)a{Zc2*4}E6S}NYsnL{GYny;7xiLmk?2-%|y zJ6v5uS+{2phdBUVf{;Vu{;E@XO6L&ebA|d9Fy@o!cv|$8YgYBw8)}!Dz9T3-7_mO9 z#hGHn-I^x<StO}=sj3h(Rb1M<WvOolHI?3+lA@#Df3@cGmT3&0*|*AiCA{?Asx7*m zR@(HWayvhO=`UA3YqDJB#7@f)GSbjvR)uqO12b!KA4L*VPvBRa=1vVgT|9)*Nhwh% zR@df|?dqg45Km~C+{UJ9WwX-2OE2W>p`ZOjZ|t$Dy3Z|I!w0K2DLvO(#^PglepW~D z%&$Y&;~KOuKfeGA?F|g(g2keH+{T#iQ!1HV{WqGwpV{ljSYKjSAe?+r<k($T$hk!@ zns&8G8heAPz0b|$+1<7?rQ(yz3>(Eu_i}J)&5spU+}>Ib+a~+cBQ~@br7nUmR?V}= z%^6Mofa6H*FYNwfUj?QK9`DXK<PtU!xuy=TP6fqAgVQHRcFy8)QQNca5`M(!@aIaw zISgrdC2-UnotV2kR4YyYQS0+f1NLTsg*&&r^2)y`in^2?9$S$!IHVcMc0pe>jZ08) zosVpzCY<*Tv8StD?y@1m2E6M)zqV>a<)h&U<8y`5lMOwdXhihh^bg^waQeGlk+;$( z>kXAxpC$Xn_nYZv<po=tR*DHPsZMRjBT(h8?VoI=$u=)Xojhk&bKLJt?l#+l>YWn~ zCkqiYlbw2Jl2$xi$2{Vju$1jrDY^!gky_Q1d`sO*G1W}x<F7QOq+}$eM3AlB3eLsK zwOUy`l9R-i<R9vlPYLrnFxz!7%}m78h_lyDeEpw3)mU8TMNFyVa8x>e!WufFfQOq8 JiRT)A?H?ng_znO7 literal 0 HcmV?d00001 diff --git a/civicrm/bower_components/jstree/dist/themes/default-dark/40px.png b/civicrm/bower_components/jstree/dist/themes/default-dark/40px.png new file mode 100644 index 0000000000000000000000000000000000000000..4fc88e41e66508e4657b3ec6e5ec185a6084b7a9 GIT binary patch literal 5717 zcmZu#cU)7;wx*+i1Ocf67MfH61(BvGa3J&+IuTH+(xjJAM5L-9Rf@Eu5FpeLN+{Bi zVvrVkk90x_O_H}g_uc!>J-;`9Oun`D%v#^K_RQY16Qi%IafyzLj*N`#lI9<e4T0ZX zGBWb{3zPsV6=8ZyMn<8ouWhUbnBLyrrlzI<_<vhiSlGY(Ha0c@aCdjt)z$r%heRTo zn3xzF8ygxL=H=z->+1u4IyyQdBO?Il>FL2>u$7e+YinyDJ_G_WFfed%Z~!jdzI_|$ zLqbA=f`WW}d|tkM>F4Jc5D;KxWo2n;X<=buZf<U7W(JILa&iKCpoNBp`uh3?2M1G8 zQ3VDDva+)J`}=EaYoDK=gTY{c#`N?wFE1|+hr{FX2L}hIr>7?;Cre99XJ=;shohsT z{r!Ccfv~l;wX?Icv9YnXwzjaaFgG_hGcz+eImyn>zPh>!BwAct1p0)81Wry)Kw5r& zK49|m^8>_+i;DpacmQtP+}wctjEoE-kqD$1A0IzHK5lDktFEpF2mmpGIEROa03RSD z8jb$>^CysNaBy&UcXwc5U}9pTr>6&?2aw#{-2D3W>+<q4Kzn|E9u9~9`0)ea{Oi{* z6bc1!1~d*25AW^m0XzXAU0q!Oc|gw8)D$3Oc6JsJTVG%Q{rmUw^78KP?uv>EK+E>_ z_WJsIdwV+qffyMX>F@7vZf-6qDFIZEj*eDURrU4t0j2o%?HdMz85<j`t*tFBEp2LQ z0xH?i(D3EUm&V4%y1F_*b!TU1OG^tDi*0Rf9U2<y=;)}asp;+Qt*oppD=R}Hk;^ic zEI?_TUmEHfkx^J_QZNfhF(}bcP~SEt*RbNaOb*=HBrA}N6{8geIZ#zA4M8v~#a|7u zjE$8wo|piZGQ}kdC!&)vQ4Of-KieZB6Hz!%*6cmEhE)Jn(tUZ|bkTccWGp6{j~^QQ zPj1b`*m5~%(s~5d)F)-@N@pJkPC=5^GL%0Ltzk2=vGRoGowMdNVJ_WU59%G%47MLd zgq3l|UvT#HNx;a?kg(0uCi+D_P5P3%in)3)3;37lBk&ddw3hgUOPVv>Y!|}F8K7j8 z9Ia$Dw|~RbOjK}y-G^3|A=~=BUmZWggmOrkre}Ax7s<)Sn<hGzBe`v?>=xU^B?YC{ zpqcD%(>-pt$Ek_&lo|>f+pWgzE;4~>;3F1g76QRJ!jd$2B?cRb(SZHOfwhyOX-}!g zbv8@(S7Qi$3@<V#jBx`jJ1Kt2FFrPy;0BU0q8GL0d`bpC3Vnvqr90dGMsNrP>c?Y9 zww#^~f~q1v=&_DT9RzOjZlRO@#T#ssYAgD{Zl;jiZjh7T-!s(dF4Q4NDpdTgOK_Hx zWHZm({n%@gNb7G8@r(EUTbFqngVo^Ko27g$F+*_+yB=Ooot<L~Qd3O@skgkWnx$h- zeGZOqX+rsJGQD*4qRm|bC-2tszhvJy?KAF+;zIVNWH#sy3R<&#{`#kx{+vl$`mHSH zW|j~hbm&4@u}OFZ{b!DLO~sVJz=yfjD3*9HORv)?XQ^n-@eE1mmQSN@*SI10>UYch z)zVy3bMKLS&>ID&W~t|Nliu=Rw3mF)_d6kxUtGZ=KK*uwY+oGUUn0g`Vq%m=J#RAg z*Y6v+qVog%BsfqHM`{I9Ecko`A9**Z4@4ymezE!0TgojM^fmJ^Xk%r_g2ng8rTlX7 z;t~0lhjnIJxu3Ms*nDVUx_xVXX|5mR-<G5ykmx4u-(l_>q>IY?4zA*ce6JSOtEx_3 zTuVC)KnyW~Mnzxj2JD}v#WWxb4K+mJjT$)_oI{vx7lD#g|K5e7{CfQiQTK7UBIH(j zoaAMn=bA->yb6gqn_EiqURNE90$lCl#y?Gor3{aXq{#ZvAXWsJ%f&Grvs=}lX=(L_ zkZ42nUC(@vCYPznnc}hS)aQq&`A|)wE103uQ%XiA+5C>yk!j~#ykOmP$BZ6>+8Y_! zEZLREI`s%~pIAAbL>;l&%!#X#Tc6%WeICuk_GG;(?cA{uyb#~<ELM66Z`vt$-i_?} zfkjgq2Z59t8{87bJPwmZ<Gxw41btJGq5T$Z8{&g%!g;>hlZ%-w>@KvW*kR_DlL4i* zpkSo9mFNte9i4pTnm~P)p_X;g?Cm)iVUtL7?mZGQumz);jgT2D8gEk_-A3T;Fe9)@ z@aTLxb}rYGqdf8JbFhzRV5o9Jw*p5Uug#&U$Sl0TYvYMd)_@I9_D3*$QErx_XewG` zhsHCD`tKX?Z+r2-AgUW0&whuNB3=gX!qjTUf-t5NDD#-by}lHG7q8_K{DAMbv#^Wy zfIMCfuXSBq`4b4L9RnHg+dgV&n=|rFIrbwcmD*qyV=Qx>s7HnB1eeL}wVFzZGZhug z+^R1@)sRB7eV@E}gsTI2bs4ABVz_yGDdm;xIjBSNqEDx(+B*xg(X8_ln|v09ah@>o z7*<ffU;<e2HlGEmgL1$26<E;>%CJaI31$aznN|7Ew;Fav(xwXYKB%~ZzZTIgIQz>J z!pb(sLq(OtYU~gOn|xmyHC!Wj5;3H?VmGjM<4JOJVp7G=hi1YTU85YelU51L_E`G9 z6pIFNQZyUgSG!fH&OYet@U*TDtv0>lH`a9B-b<+*kwx`e($t5(IYppMtGbn0{5!UY zq5zevViwbi-wYXE&!q*78`@E&u7(&%J-NFt=9=#mXgeE8TTE`235s}8{iCNk>zUs! zr8x*B&~59iTw$60A>7eG7jCV7J8@TZAX;8U%WBCyuTbSE&kZVufn<Vay1o-`3{5g} z&Qyitsen1Ey;{z+Lt5@a1$@0!>Nb9mO%qj*&6L%ftfe&yL)E@u&uVQbE4j&?bzNVJ zJcy(0!8$z%Jsi9_{+uVke+-j4NUGExPi?lWd95qWozNpXgkcQCtGx<#R`!(`RLNd3 z*Tb=ASA~0<&y?eyDB)cQ&K<s+?8$Em>o>r;+v5AB=pQvZ<yIdL27-GQuy7$8p8m}b zodOS>w*`6hKs)=T?Vl5ut+C2AF9O$MAnKkmkj%!E>PQWc|5!m}b)WS~bE*fwjq~;^ z>2ILW!D?PHM^!(EX?*KD|Dt-M3|mVQUrueatZn^GTzSz!hv-0dgicS;gemIgMqA`E zU=Q_Q?_OgVy6^L<UnTiySKnoEbVaTTtNKTGwQ7_bA>o^JM3IoqrD1CPYYy8*6L<O- zOnd~2zg{{2waowXBKo@*Ec}cr_28P=^!aWC=4Tg{cwgU5j1|)2DYhCkT)$)m0|k_w zymJ*1JAY?>-&_Qxumg9!R1m#ui^Uxz*I?%<_V@SraB4Pdi$NjyJsw=AP48mRIew2@ zh!0_mM=J-M#3$!M^3CYXu6Ilkzq4Tw1+05vCQDoHe-J{bULSou{5pd$*g6q0Z;g!; z{@SE^ddq=aRMH<!9Voe}F-7yiD@-!bH_t|ytLWglg(9k!TBOona=n`jJn?5|WQsMV z@vX_mh6uFSd56-Uu=x^$GUg2)MUNS??wDQ1t0?Evy$*lcOVhF?CizW~G=FZfCBBWD z+~KjR=sEutK2zAqJI+9cdha%R`hC5x$t6S+FJC;0(L1mYq%9YK<~hK}#)tXES?G0g z-C(!$L|z@SoTbl(yIwRC#+IO$DkCUrt;&SUkbY4^WR0gW!P+~mM#ALu0+u?pe&VA8 zkINoR+#MxIh~qh-ekz`C*LWtL#;zSoCBx5`MSMh>nCNNj=@*Qr6rxP)42@L`fC2Ze zidu+unxzw#Meb^isxCbFa}CK}mQ0pQUUkT_59Ef&7>;t>I!%U;EJQ&)u1^#4p%r$w zKe1x<Isno(73pZ3YK1QUz4iNlBId%BE)U??KG>c4C<?BYD|c00qrdk?x=7g3cqrJ* zfuV*V$4VYF;(8!tr-eCBe~Zz`W~D>W^-&_(7Cl8QH~qa%oynexx!>WS8~bD!tkPv4 zYc9fz8wV+vU9L9tzW>3^XO_%+Fm^k=s*5%KG;c(F=4wmmL|cg`{7H~cb&`^M*lHhP z9og20E96FmV*3Q=fUEX>O;0eshJ<WCi&2Pjr8w7~mi*}xT2Zf&#j!*k+_JLg_6XJ& z$yS`Dn)p{RSb(UE`=gClOT%vvZXbu-QqF%NA55QDM0T^XJ-T1zS(7|w5<Ihz+#D-` z_O7|C$t^|~00e}OJY(f0EXN2{RX^P*Da-!DXSRH>pR}hk3q&228-2FgOWd1O)&g&Q zK}Vj~uAB>H=zM<1t+-2QXH>s=M?(D>sKx)lE#zEAy$qoebkMor=714)2u7Vfp&cLV zRqO*>!gg112OaRCmf(s+=8@H?a?o#D@SVnY;(HFHT`8Hpb^HP``HeXL@%igUK3|VR zb!m4eA33k}JRzF^-J6Z@>xehpy&gyHjOBA8Kh-oFfCs>bw2do4@N3(@OI6_Oy#~GV zkAvjj_wWB5FaPqcmh#T#Ke&dfJArhB2W7+5xKOwg$gA+6T$mag3UmT_9Dep5rpAnt zJc00spC!T6m{2Mw5UTLAWB{h89(Gi^#@r;uUcIf;p5dIw@BXnX>2uNiX{ljSosRuQ z34^N0lzS2CWdAwXilS1U7j4E4ucu30o%cniB(W8$(T^A|_O#r%Fg=JYA@zt&GHCwJ zz>PJ%wXBuL$IhYl@wyZ#*7lHcx(Au5UhaHQkZn-IIlPCsV9}o7Cd$fF#PEr4CO&`Q zUFvUs@1IBI=X{|5sUcI~BvZIzdztFRvTfe-&8JM~J=!x5@*uUGN&AQk6molr&7LB? zV|vyCIwBQam*J!U&h|Z3InLJHMO50=AtC`gSyK1MV9O2K>HZc~j7BVVkn)Cuv8=o8 zgU|kZK#U%8xqZa1(PaO&8>b%mkbI8PoQ{3)|4zssRL}uy0>*{uo)!^ylwJpW-@o%- zUEv=uN_D_qmnX$u^H3m_T$R%|PBLJ9`X<eD8Q`!DCSK8;Z(g>&Ouel^ykb7D3_zOg z5aJc*`5c_>W!h~Y;+63EN`uDwmlbsX{$TjWeWp}-@DESbfqgx5;)&|LCs4JaM`9N! zMa@YRpw>qqQ){CHHnY6*<*^RoaLh97bc$V_PO<o$ASxNp?5`H5srUe@xcHF5{xXQw z>}&%O&tY~po-~dR3$G=Km?%0yx9VD?q?qS>#}Fi6SE|<df-V>*d4(1pJaD>03Vce{ z`o+d+q@#nrosqcA9dCHvT@guI$c4Q(C7tZJGb*5}iJ={>$t}0-=5rZ1{rB>@q;G?h zOf^c!b}q4}3uwl1!tWkVwNvMKMH$$!IZ}TupL>5nP*4xf=u6EO5x7k!K}CGP#o?z( zt=GLNPw%&~S*gM$;qkz|SEF9k9YY%P2xs>SsLpNdKbhuZWWSf*!xb|9v|ljP8`bLT z+Qx*Fc+_?()J`pNn%sSVn@->yrf3C?ld3`YSx;SG$^~XTO!>jMt(8`+!Y$!ZQ`Mj_ zWZei)nd6YC2pCMo&X>n;9Un#0Z_dr)6_+K31_?Wi>=X4|8P-eX*q-%V5If3a(LAW% z`Yh+bmVrHeGVs_xyOCGr<*yZw@JkA`L&~^vM_PpzS*v-iXD8oCE9H`DGO)W2uE%a$ z)ug4;To}?<*1>fmK-&BGO(Ub@Fig%tf!A{i!{En*U4+RPL)B#C_M+-VU-UoIjKyzu zURr!5^to*g^pD;CukXsgFAC6&<4$F9neX%OE!ztiLp?`Y)Bd12vZEK|3cmQ)vZAFd zH8gg&X1;$f(MqYyLAp(()-;YdFb0lDvpb8n$w-c&f}l<C0t;ZDI0eDv3*|u=VHm$% zv92f1fuc<ZVR|Miav3buX`S3lS%<a|C&7X;kgOqj+r1s(Yc@o?F2k)TGr?q<XMrcN z3aKs<9kLm>JwB)9qFjqlRZEk5Dg1(JCtcYk$9T-Giz@FJG0{BR-!pHgLv~JNUZ!E& zcxvqtoQ39m2*ubC)Z{bYQ>M<Z2nlYw#ysz#Ak;{(u^^Y)8bV?GmE==hH$bRRRL}w; z*qPy@*=%HV*TQzxj_u{>X!d}o<Z>WC$zM$kcV26X?OY5STPR=8AHsp{{X1OD_3$+s zqa3tHN0=fhF}tqD&pXf*uA*OMpHxZkgu=Ud<^!De_K1typ<71kaEnGg&Y&g4A!n%} zLQJQ~Py!-yx3(q%dU&zi^sZnWcb3+`&(WXVX6+#~1()+Kw0e-4_;X!S57AK?&HA1- z!8`97(Wr+Bti7*`={%=~XuM*^ufO+i<DmO>#!5}mWpO#c$?)DN@2n*KRu0{d%t|Ed zq|uFI3y~`?1Qu7kd_$NPw(1G5KJ}_`Pg_!;C5$RYORrRpV-CuiBjEN`1&<Y7%kocx zZ@llRgZZ#WJ~>@IO0Ae(fMRCc#>x|s=hOuT)CU*ga~q{8;~R$sB(9d@vWtx|c=CP9 zhuJy=U!2R%m|lFB%1=p-1kqJlg%Hh0jshXNz!5@`H`vl`j$iF0m^H=0`P?_R&B@`k zDLIyJNNVGruKfOK;?i85ny*qKq*wFN*^%#lb0lU0I3F0#S`~JF6@QWX$QU^h&_sGf zRN7iK)f?HIn3v%SdA&sV!1NS3K1r(Bf!?_vC)1pblt*T+R20=M>4L{k5_WdCIqq<0 z^1ugFqc)HIkxcn|GU<_{LdUwKHmBf=xe{oF+?WwjnU;@ZC(JWA?_);YJU^q4iPhS0 z&MRd(wef~!j=fp(vbXANu7fyY3SM{4^t}GeHn50&vnj!qFNQ;erbwdF5g!J1mHM9@ zIO4N%QbbPjBVc-^&^v72Kl!C)8vQ&xD&!Pc<S%Am2glLfjn)$8ea2H#nYFppI)fjQ z>erW#9LNhQk9`_*(6#Ld#&LpT<9(Hllink$rZDeO-*5fT1{{lZa^Nit(%~4htdAMk z_OrL!e1p$qvo~?}Es_;8dk|odSaORb3r9kc{-jwWX_GjqUfk+QJmGn=rF%3+(9IZV z5Nf%}&XLfWM%d)b?^od)KOy+Nsug`ID=lD)<00coUZEWCV#dDta1U+2Ll>Of|9nus zaR(384TUJ*=88M=Kb!a#qO@WizSaLsX3APIzSk=PV^)RTlplYa!!n(Ct}K4Kj9aEE z5M?6y+nA+)Z^PHK=-GH2&VAr&r(HEVr)nW)r3Z$1v<+{lk<rh+fL;P|AN!Djm^dDx km0jkg{{86Dp!h|);!ZS4OrTl<{?#MXRMUN2t_qF#A79W+tN;K2 literal 0 HcmV?d00001 diff --git a/civicrm/bower_components/jstree/dist/themes/default-dark/style.css b/civicrm/bower_components/jstree/dist/themes/default-dark/style.css new file mode 100644 index 0000000000..3af003f2d5 --- /dev/null +++ b/civicrm/bower_components/jstree/dist/themes/default-dark/style.css @@ -0,0 +1,1146 @@ +/* jsTree default dark theme */ +.jstree-node, +.jstree-children, +.jstree-container-ul { + display: block; + margin: 0; + padding: 0; + list-style-type: none; + list-style-image: none; +} +.jstree-node { + white-space: nowrap; +} +.jstree-anchor { + display: inline-block; + color: black; + white-space: nowrap; + padding: 0 4px 0 1px; + margin: 0; + vertical-align: top; +} +.jstree-anchor:focus { + outline: 0; +} +.jstree-anchor, +.jstree-anchor:link, +.jstree-anchor:visited, +.jstree-anchor:hover, +.jstree-anchor:active { + text-decoration: none; + color: inherit; +} +.jstree-icon { + display: inline-block; + text-decoration: none; + margin: 0; + padding: 0; + vertical-align: top; + text-align: center; +} +.jstree-icon:empty { + display: inline-block; + text-decoration: none; + margin: 0; + padding: 0; + vertical-align: top; + text-align: center; +} +.jstree-ocl { + cursor: pointer; +} +.jstree-leaf > .jstree-ocl { + cursor: default; +} +.jstree .jstree-open > .jstree-children { + display: block; +} +.jstree .jstree-closed > .jstree-children, +.jstree .jstree-leaf > .jstree-children { + display: none; +} +.jstree-anchor > .jstree-themeicon { + margin-right: 2px; +} +.jstree-no-icons .jstree-themeicon, +.jstree-anchor > .jstree-themeicon-hidden { + display: none; +} +.jstree-hidden, +.jstree-node.jstree-hidden { + display: none; +} +.jstree-rtl .jstree-anchor { + padding: 0 1px 0 4px; +} +.jstree-rtl .jstree-anchor > .jstree-themeicon { + margin-left: 2px; + margin-right: 0; +} +.jstree-rtl .jstree-node { + margin-left: 0; +} +.jstree-rtl .jstree-container-ul > .jstree-node { + margin-right: 0; +} +.jstree-wholerow-ul { + position: relative; + display: inline-block; + min-width: 100%; +} +.jstree-wholerow-ul .jstree-leaf > .jstree-ocl { + cursor: pointer; +} +.jstree-wholerow-ul .jstree-anchor, +.jstree-wholerow-ul .jstree-icon { + position: relative; +} +.jstree-wholerow-ul .jstree-wholerow { + width: 100%; + cursor: pointer; + position: absolute; + left: 0; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +.vakata-context { + display: none; +} +.vakata-context, +.vakata-context ul { + margin: 0; + padding: 2px; + position: absolute; + background: #f5f5f5; + border: 1px solid #979797; + box-shadow: 2px 2px 2px #999999; +} +.vakata-context ul { + list-style: none; + left: 100%; + margin-top: -2.7em; + margin-left: -4px; +} +.vakata-context .vakata-context-right ul { + left: auto; + right: 100%; + margin-left: auto; + margin-right: -4px; +} +.vakata-context li { + list-style: none; +} +.vakata-context li > a { + display: block; + padding: 0 2em 0 2em; + text-decoration: none; + width: auto; + color: black; + white-space: nowrap; + line-height: 2.4em; + text-shadow: 1px 1px 0 white; + border-radius: 1px; +} +.vakata-context li > a:hover { + position: relative; + background-color: #e8eff7; + box-shadow: 0 0 2px #0a6aa1; +} +.vakata-context li > a.vakata-context-parent { + background-image: url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAIORI4JlrqN1oMSnmmZDQUAOw=="); + background-position: right center; + background-repeat: no-repeat; +} +.vakata-context li > a:focus { + outline: 0; +} +.vakata-context .vakata-context-hover > a { + position: relative; + background-color: #e8eff7; + box-shadow: 0 0 2px #0a6aa1; +} +.vakata-context .vakata-context-separator > a, +.vakata-context .vakata-context-separator > a:hover { + background: white; + border: 0; + border-top: 1px solid #e2e3e3; + height: 1px; + min-height: 1px; + max-height: 1px; + padding: 0; + margin: 0 0 0 2.4em; + border-left: 1px solid #e0e0e0; + text-shadow: 0 0 0 transparent; + box-shadow: 0 0 0 transparent; + border-radius: 0; +} +.vakata-context .vakata-contextmenu-disabled a, +.vakata-context .vakata-contextmenu-disabled a:hover { + color: silver; + background-color: transparent; + border: 0; + box-shadow: 0 0 0; +} +.vakata-context li > a > i { + text-decoration: none; + display: inline-block; + width: 2.4em; + height: 2.4em; + background: transparent; + margin: 0 0 0 -2em; + vertical-align: top; + text-align: center; + line-height: 2.4em; +} +.vakata-context li > a > i:empty { + width: 2.4em; + line-height: 2.4em; +} +.vakata-context li > a .vakata-contextmenu-sep { + display: inline-block; + width: 1px; + height: 2.4em; + background: white; + margin: 0 0.5em 0 0; + border-left: 1px solid #e2e3e3; +} +.vakata-context .vakata-contextmenu-shortcut { + font-size: 0.8em; + color: silver; + opacity: 0.5; + display: none; +} +.vakata-context-rtl ul { + left: auto; + right: 100%; + margin-left: auto; + margin-right: -4px; +} +.vakata-context-rtl li > a.vakata-context-parent { + background-image: url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAINjI+AC7rWHIsPtmoxLAA7"); + background-position: left center; + background-repeat: no-repeat; +} +.vakata-context-rtl .vakata-context-separator > a { + margin: 0 2.4em 0 0; + border-left: 0; + border-right: 1px solid #e2e3e3; +} +.vakata-context-rtl .vakata-context-left ul { + right: auto; + left: 100%; + margin-left: -4px; + margin-right: auto; +} +.vakata-context-rtl li > a > i { + margin: 0 -2em 0 0; +} +.vakata-context-rtl li > a .vakata-contextmenu-sep { + margin: 0 0 0 0.5em; + border-left-color: white; + background: #e2e3e3; +} +#jstree-marker { + position: absolute; + top: 0; + left: 0; + margin: -5px 0 0 0; + padding: 0; + border-right: 0; + border-top: 5px solid transparent; + border-bottom: 5px solid transparent; + border-left: 5px solid; + width: 0; + height: 0; + font-size: 0; + line-height: 0; +} +#jstree-dnd { + line-height: 16px; + margin: 0; + padding: 4px; +} +#jstree-dnd .jstree-icon, +#jstree-dnd .jstree-copy { + display: inline-block; + text-decoration: none; + margin: 0 2px 0 0; + padding: 0; + width: 16px; + height: 16px; +} +#jstree-dnd .jstree-ok { + background: green; +} +#jstree-dnd .jstree-er { + background: red; +} +#jstree-dnd .jstree-copy { + margin: 0 2px 0 2px; +} +.jstree-default-dark .jstree-node, +.jstree-default-dark .jstree-icon { + background-repeat: no-repeat; + background-color: transparent; +} +.jstree-default-dark .jstree-anchor, +.jstree-default-dark .jstree-animated, +.jstree-default-dark .jstree-wholerow { + transition: background-color 0.15s, box-shadow 0.15s; +} +.jstree-default-dark .jstree-hovered { + background: #555555; + border-radius: 2px; + box-shadow: inset 0 0 1px #555555; +} +.jstree-default-dark .jstree-context { + background: #555555; + border-radius: 2px; + box-shadow: inset 0 0 1px #555555; +} +.jstree-default-dark .jstree-clicked { + background: #5fa2db; + border-radius: 2px; + box-shadow: inset 0 0 1px #666666; +} +.jstree-default-dark .jstree-no-icons .jstree-anchor > .jstree-themeicon { + display: none; +} +.jstree-default-dark .jstree-disabled { + background: transparent; + color: #666666; +} +.jstree-default-dark .jstree-disabled.jstree-hovered { + background: transparent; + box-shadow: none; +} +.jstree-default-dark .jstree-disabled.jstree-clicked { + background: #333333; +} +.jstree-default-dark .jstree-disabled > .jstree-icon { + opacity: 0.8; + filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'jstree-grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#jstree-grayscale"); + /* Firefox 10+ */ + filter: gray; + /* IE6-9 */ + -webkit-filter: grayscale(100%); + /* Chrome 19+ & Safari 6+ */ +} +.jstree-default-dark .jstree-search { + font-style: italic; + color: #ffffff; + font-weight: bold; +} +.jstree-default-dark .jstree-no-checkboxes .jstree-checkbox { + display: none !important; +} +.jstree-default-dark.jstree-checkbox-no-clicked .jstree-clicked { + background: transparent; + box-shadow: none; +} +.jstree-default-dark.jstree-checkbox-no-clicked .jstree-clicked.jstree-hovered { + background: #555555; +} +.jstree-default-dark.jstree-checkbox-no-clicked > .jstree-wholerow-ul .jstree-wholerow-clicked { + background: transparent; +} +.jstree-default-dark.jstree-checkbox-no-clicked > .jstree-wholerow-ul .jstree-wholerow-clicked.jstree-wholerow-hovered { + background: #555555; +} +.jstree-default-dark > .jstree-striped { + min-width: 100%; + display: inline-block; + background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAMAAAB/qqA+AAAABlBMVEUAAAAAAAClZ7nPAAAAAnRSTlMNAMM9s3UAAAAXSURBVHjajcEBAQAAAIKg/H/aCQZ70AUBjAATb6YPDgAAAABJRU5ErkJggg==") left top repeat; +} +.jstree-default-dark > .jstree-wholerow-ul .jstree-hovered, +.jstree-default-dark > .jstree-wholerow-ul .jstree-clicked { + background: transparent; + box-shadow: none; + border-radius: 0; +} +.jstree-default-dark .jstree-wholerow { + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} +.jstree-default-dark .jstree-wholerow-hovered { + background: #555555; +} +.jstree-default-dark .jstree-wholerow-clicked { + background: #5fa2db; + background: -webkit-linear-gradient(top, #5fa2db 0%, #5fa2db 100%); + background: linear-gradient(to bottom, #5fa2db 0%, #5fa2db 100%); +} +.jstree-default-dark .jstree-node { + min-height: 24px; + line-height: 24px; + margin-left: 24px; + min-width: 24px; +} +.jstree-default-dark .jstree-anchor { + line-height: 24px; + height: 24px; +} +.jstree-default-dark .jstree-icon { + width: 24px; + height: 24px; + line-height: 24px; +} +.jstree-default-dark .jstree-icon:empty { + width: 24px; + height: 24px; + line-height: 24px; +} +.jstree-default-dark.jstree-rtl .jstree-node { + margin-right: 24px; +} +.jstree-default-dark .jstree-wholerow { + height: 24px; +} +.jstree-default-dark .jstree-node, +.jstree-default-dark .jstree-icon { + background-image: url("32px.png"); +} +.jstree-default-dark .jstree-node { + background-position: -292px -4px; + background-repeat: repeat-y; +} +.jstree-default-dark .jstree-last { + background: transparent; +} +.jstree-default-dark .jstree-open > .jstree-ocl { + background-position: -132px -4px; +} +.jstree-default-dark .jstree-closed > .jstree-ocl { + background-position: -100px -4px; +} +.jstree-default-dark .jstree-leaf > .jstree-ocl { + background-position: -68px -4px; +} +.jstree-default-dark .jstree-themeicon { + background-position: -260px -4px; +} +.jstree-default-dark > .jstree-no-dots .jstree-node, +.jstree-default-dark > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-dark > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -36px -4px; +} +.jstree-default-dark > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: -4px -4px; +} +.jstree-default-dark .jstree-disabled { + background: transparent; +} +.jstree-default-dark .jstree-disabled.jstree-hovered { + background: transparent; +} +.jstree-default-dark .jstree-disabled.jstree-clicked { + background: #efefef; +} +.jstree-default-dark .jstree-checkbox { + background-position: -164px -4px; +} +.jstree-default-dark .jstree-checkbox:hover { + background-position: -164px -36px; +} +.jstree-default-dark.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, +.jstree-default-dark .jstree-checked > .jstree-checkbox { + background-position: -228px -4px; +} +.jstree-default-dark.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, +.jstree-default-dark .jstree-checked > .jstree-checkbox:hover { + background-position: -228px -36px; +} +.jstree-default-dark .jstree-anchor > .jstree-undetermined { + background-position: -196px -4px; +} +.jstree-default-dark .jstree-anchor > .jstree-undetermined:hover { + background-position: -196px -36px; +} +.jstree-default-dark .jstree-checkbox-disabled { + opacity: 0.8; + filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'jstree-grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#jstree-grayscale"); + /* Firefox 10+ */ + filter: gray; + /* IE6-9 */ + -webkit-filter: grayscale(100%); + /* Chrome 19+ & Safari 6+ */ +} +.jstree-default-dark > .jstree-striped { + background-size: auto 48px; +} +.jstree-default-dark.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); + background-position: 100% 1px; + background-repeat: repeat-y; +} +.jstree-default-dark.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-dark.jstree-rtl .jstree-open > .jstree-ocl { + background-position: -132px -36px; +} +.jstree-default-dark.jstree-rtl .jstree-closed > .jstree-ocl { + background-position: -100px -36px; +} +.jstree-default-dark.jstree-rtl .jstree-leaf > .jstree-ocl { + background-position: -68px -36px; +} +.jstree-default-dark.jstree-rtl > .jstree-no-dots .jstree-node, +.jstree-default-dark.jstree-rtl > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-dark.jstree-rtl > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -36px -36px; +} +.jstree-default-dark.jstree-rtl > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: -4px -36px; +} +.jstree-default-dark .jstree-themeicon-custom { + background-color: transparent; + background-image: none; + background-position: 0 0; +} +.jstree-default-dark > .jstree-container-ul .jstree-loading > .jstree-ocl { + background: url("throbber.gif") center center no-repeat; +} +.jstree-default-dark .jstree-file { + background: url("32px.png") -100px -68px no-repeat; +} +.jstree-default-dark .jstree-folder { + background: url("32px.png") -260px -4px no-repeat; +} +.jstree-default-dark > .jstree-container-ul > .jstree-node { + margin-left: 0; + margin-right: 0; +} +#jstree-dnd.jstree-default-dark { + line-height: 24px; + padding: 0 4px; +} +#jstree-dnd.jstree-default-dark .jstree-ok, +#jstree-dnd.jstree-default-dark .jstree-er { + background-image: url("32px.png"); + background-repeat: no-repeat; + background-color: transparent; +} +#jstree-dnd.jstree-default-dark i { + background: transparent; + width: 24px; + height: 24px; + line-height: 24px; +} +#jstree-dnd.jstree-default-dark .jstree-ok { + background-position: -4px -68px; +} +#jstree-dnd.jstree-default-dark .jstree-er { + background-position: -36px -68px; +} +.jstree-default-dark .jstree-ellipsis { + overflow: hidden; +} +.jstree-default-dark .jstree-ellipsis .jstree-anchor { + width: calc(100% - 29px); + text-overflow: ellipsis; + overflow: hidden; +} +.jstree-default-dark .jstree-ellipsis.jstree-no-icons .jstree-anchor { + width: calc(100% - 5px); +} +.jstree-default-dark.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); +} +.jstree-default-dark.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-dark-small .jstree-node { + min-height: 18px; + line-height: 18px; + margin-left: 18px; + min-width: 18px; +} +.jstree-default-dark-small .jstree-anchor { + line-height: 18px; + height: 18px; +} +.jstree-default-dark-small .jstree-icon { + width: 18px; + height: 18px; + line-height: 18px; +} +.jstree-default-dark-small .jstree-icon:empty { + width: 18px; + height: 18px; + line-height: 18px; +} +.jstree-default-dark-small.jstree-rtl .jstree-node { + margin-right: 18px; +} +.jstree-default-dark-small .jstree-wholerow { + height: 18px; +} +.jstree-default-dark-small .jstree-node, +.jstree-default-dark-small .jstree-icon { + background-image: url("32px.png"); +} +.jstree-default-dark-small .jstree-node { + background-position: -295px -7px; + background-repeat: repeat-y; +} +.jstree-default-dark-small .jstree-last { + background: transparent; +} +.jstree-default-dark-small .jstree-open > .jstree-ocl { + background-position: -135px -7px; +} +.jstree-default-dark-small .jstree-closed > .jstree-ocl { + background-position: -103px -7px; +} +.jstree-default-dark-small .jstree-leaf > .jstree-ocl { + background-position: -71px -7px; +} +.jstree-default-dark-small .jstree-themeicon { + background-position: -263px -7px; +} +.jstree-default-dark-small > .jstree-no-dots .jstree-node, +.jstree-default-dark-small > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-dark-small > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -39px -7px; +} +.jstree-default-dark-small > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: -7px -7px; +} +.jstree-default-dark-small .jstree-disabled { + background: transparent; +} +.jstree-default-dark-small .jstree-disabled.jstree-hovered { + background: transparent; +} +.jstree-default-dark-small .jstree-disabled.jstree-clicked { + background: #efefef; +} +.jstree-default-dark-small .jstree-checkbox { + background-position: -167px -7px; +} +.jstree-default-dark-small .jstree-checkbox:hover { + background-position: -167px -39px; +} +.jstree-default-dark-small.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, +.jstree-default-dark-small .jstree-checked > .jstree-checkbox { + background-position: -231px -7px; +} +.jstree-default-dark-small.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, +.jstree-default-dark-small .jstree-checked > .jstree-checkbox:hover { + background-position: -231px -39px; +} +.jstree-default-dark-small .jstree-anchor > .jstree-undetermined { + background-position: -199px -7px; +} +.jstree-default-dark-small .jstree-anchor > .jstree-undetermined:hover { + background-position: -199px -39px; +} +.jstree-default-dark-small .jstree-checkbox-disabled { + opacity: 0.8; + filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'jstree-grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#jstree-grayscale"); + /* Firefox 10+ */ + filter: gray; + /* IE6-9 */ + -webkit-filter: grayscale(100%); + /* Chrome 19+ & Safari 6+ */ +} +.jstree-default-dark-small > .jstree-striped { + background-size: auto 36px; +} +.jstree-default-dark-small.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); + background-position: 100% 1px; + background-repeat: repeat-y; +} +.jstree-default-dark-small.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-dark-small.jstree-rtl .jstree-open > .jstree-ocl { + background-position: -135px -39px; +} +.jstree-default-dark-small.jstree-rtl .jstree-closed > .jstree-ocl { + background-position: -103px -39px; +} +.jstree-default-dark-small.jstree-rtl .jstree-leaf > .jstree-ocl { + background-position: -71px -39px; +} +.jstree-default-dark-small.jstree-rtl > .jstree-no-dots .jstree-node, +.jstree-default-dark-small.jstree-rtl > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-dark-small.jstree-rtl > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -39px -39px; +} +.jstree-default-dark-small.jstree-rtl > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: -7px -39px; +} +.jstree-default-dark-small .jstree-themeicon-custom { + background-color: transparent; + background-image: none; + background-position: 0 0; +} +.jstree-default-dark-small > .jstree-container-ul .jstree-loading > .jstree-ocl { + background: url("throbber.gif") center center no-repeat; +} +.jstree-default-dark-small .jstree-file { + background: url("32px.png") -103px -71px no-repeat; +} +.jstree-default-dark-small .jstree-folder { + background: url("32px.png") -263px -7px no-repeat; +} +.jstree-default-dark-small > .jstree-container-ul > .jstree-node { + margin-left: 0; + margin-right: 0; +} +#jstree-dnd.jstree-default-dark-small { + line-height: 18px; + padding: 0 4px; +} +#jstree-dnd.jstree-default-dark-small .jstree-ok, +#jstree-dnd.jstree-default-dark-small .jstree-er { + background-image: url("32px.png"); + background-repeat: no-repeat; + background-color: transparent; +} +#jstree-dnd.jstree-default-dark-small i { + background: transparent; + width: 18px; + height: 18px; + line-height: 18px; +} +#jstree-dnd.jstree-default-dark-small .jstree-ok { + background-position: -7px -71px; +} +#jstree-dnd.jstree-default-dark-small .jstree-er { + background-position: -39px -71px; +} +.jstree-default-dark-small .jstree-ellipsis { + overflow: hidden; +} +.jstree-default-dark-small .jstree-ellipsis .jstree-anchor { + width: calc(100% - 23px); + text-overflow: ellipsis; + overflow: hidden; +} +.jstree-default-dark-small .jstree-ellipsis.jstree-no-icons .jstree-anchor { + width: calc(100% - 5px); +} +.jstree-default-dark-small.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg=="); +} +.jstree-default-dark-small.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-dark-large .jstree-node { + min-height: 32px; + line-height: 32px; + margin-left: 32px; + min-width: 32px; +} +.jstree-default-dark-large .jstree-anchor { + line-height: 32px; + height: 32px; +} +.jstree-default-dark-large .jstree-icon { + width: 32px; + height: 32px; + line-height: 32px; +} +.jstree-default-dark-large .jstree-icon:empty { + width: 32px; + height: 32px; + line-height: 32px; +} +.jstree-default-dark-large.jstree-rtl .jstree-node { + margin-right: 32px; +} +.jstree-default-dark-large .jstree-wholerow { + height: 32px; +} +.jstree-default-dark-large .jstree-node, +.jstree-default-dark-large .jstree-icon { + background-image: url("32px.png"); +} +.jstree-default-dark-large .jstree-node { + background-position: -288px 0px; + background-repeat: repeat-y; +} +.jstree-default-dark-large .jstree-last { + background: transparent; +} +.jstree-default-dark-large .jstree-open > .jstree-ocl { + background-position: -128px 0px; +} +.jstree-default-dark-large .jstree-closed > .jstree-ocl { + background-position: -96px 0px; +} +.jstree-default-dark-large .jstree-leaf > .jstree-ocl { + background-position: -64px 0px; +} +.jstree-default-dark-large .jstree-themeicon { + background-position: -256px 0px; +} +.jstree-default-dark-large > .jstree-no-dots .jstree-node, +.jstree-default-dark-large > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-dark-large > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -32px 0px; +} +.jstree-default-dark-large > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: 0px 0px; +} +.jstree-default-dark-large .jstree-disabled { + background: transparent; +} +.jstree-default-dark-large .jstree-disabled.jstree-hovered { + background: transparent; +} +.jstree-default-dark-large .jstree-disabled.jstree-clicked { + background: #efefef; +} +.jstree-default-dark-large .jstree-checkbox { + background-position: -160px 0px; +} +.jstree-default-dark-large .jstree-checkbox:hover { + background-position: -160px -32px; +} +.jstree-default-dark-large.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, +.jstree-default-dark-large .jstree-checked > .jstree-checkbox { + background-position: -224px 0px; +} +.jstree-default-dark-large.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, +.jstree-default-dark-large .jstree-checked > .jstree-checkbox:hover { + background-position: -224px -32px; +} +.jstree-default-dark-large .jstree-anchor > .jstree-undetermined { + background-position: -192px 0px; +} +.jstree-default-dark-large .jstree-anchor > .jstree-undetermined:hover { + background-position: -192px -32px; +} +.jstree-default-dark-large .jstree-checkbox-disabled { + opacity: 0.8; + filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'jstree-grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#jstree-grayscale"); + /* Firefox 10+ */ + filter: gray; + /* IE6-9 */ + -webkit-filter: grayscale(100%); + /* Chrome 19+ & Safari 6+ */ +} +.jstree-default-dark-large > .jstree-striped { + background-size: auto 64px; +} +.jstree-default-dark-large.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); + background-position: 100% 1px; + background-repeat: repeat-y; +} +.jstree-default-dark-large.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-dark-large.jstree-rtl .jstree-open > .jstree-ocl { + background-position: -128px -32px; +} +.jstree-default-dark-large.jstree-rtl .jstree-closed > .jstree-ocl { + background-position: -96px -32px; +} +.jstree-default-dark-large.jstree-rtl .jstree-leaf > .jstree-ocl { + background-position: -64px -32px; +} +.jstree-default-dark-large.jstree-rtl > .jstree-no-dots .jstree-node, +.jstree-default-dark-large.jstree-rtl > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-dark-large.jstree-rtl > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -32px -32px; +} +.jstree-default-dark-large.jstree-rtl > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: 0px -32px; +} +.jstree-default-dark-large .jstree-themeicon-custom { + background-color: transparent; + background-image: none; + background-position: 0 0; +} +.jstree-default-dark-large > .jstree-container-ul .jstree-loading > .jstree-ocl { + background: url("throbber.gif") center center no-repeat; +} +.jstree-default-dark-large .jstree-file { + background: url("32px.png") -96px -64px no-repeat; +} +.jstree-default-dark-large .jstree-folder { + background: url("32px.png") -256px 0px no-repeat; +} +.jstree-default-dark-large > .jstree-container-ul > .jstree-node { + margin-left: 0; + margin-right: 0; +} +#jstree-dnd.jstree-default-dark-large { + line-height: 32px; + padding: 0 4px; +} +#jstree-dnd.jstree-default-dark-large .jstree-ok, +#jstree-dnd.jstree-default-dark-large .jstree-er { + background-image: url("32px.png"); + background-repeat: no-repeat; + background-color: transparent; +} +#jstree-dnd.jstree-default-dark-large i { + background: transparent; + width: 32px; + height: 32px; + line-height: 32px; +} +#jstree-dnd.jstree-default-dark-large .jstree-ok { + background-position: 0px -64px; +} +#jstree-dnd.jstree-default-dark-large .jstree-er { + background-position: -32px -64px; +} +.jstree-default-dark-large .jstree-ellipsis { + overflow: hidden; +} +.jstree-default-dark-large .jstree-ellipsis .jstree-anchor { + width: calc(100% - 37px); + text-overflow: ellipsis; + overflow: hidden; +} +.jstree-default-dark-large .jstree-ellipsis.jstree-no-icons .jstree-anchor { + width: calc(100% - 5px); +} +.jstree-default-dark-large.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg=="); +} +.jstree-default-dark-large.jstree-rtl .jstree-last { + background: transparent; +} +@media (max-width: 768px) { + #jstree-dnd.jstree-dnd-responsive { + line-height: 40px; + font-weight: bold; + font-size: 1.1em; + text-shadow: 1px 1px white; + } + #jstree-dnd.jstree-dnd-responsive > i { + background: transparent; + width: 40px; + height: 40px; + } + #jstree-dnd.jstree-dnd-responsive > .jstree-ok { + background-image: url("40px.png"); + background-position: 0 -200px; + background-size: 120px 240px; + } + #jstree-dnd.jstree-dnd-responsive > .jstree-er { + background-image: url("40px.png"); + background-position: -40px -200px; + background-size: 120px 240px; + } + #jstree-marker.jstree-dnd-responsive { + border-left-width: 10px; + border-top-width: 10px; + border-bottom-width: 10px; + margin-top: -10px; + } +} +@media (max-width: 768px) { + .jstree-default-dark-responsive { + /* + .jstree-open > .jstree-ocl, + .jstree-closed > .jstree-ocl { border-radius:20px; background-color:white; } + */ + } + .jstree-default-dark-responsive .jstree-icon { + background-image: url("40px.png"); + } + .jstree-default-dark-responsive .jstree-node, + .jstree-default-dark-responsive .jstree-leaf > .jstree-ocl { + background: transparent; + } + .jstree-default-dark-responsive .jstree-node { + min-height: 40px; + line-height: 40px; + margin-left: 40px; + min-width: 40px; + white-space: nowrap; + } + .jstree-default-dark-responsive .jstree-anchor { + line-height: 40px; + height: 40px; + } + .jstree-default-dark-responsive .jstree-icon, + .jstree-default-dark-responsive .jstree-icon:empty { + width: 40px; + height: 40px; + line-height: 40px; + } + .jstree-default-dark-responsive > .jstree-container-ul > .jstree-node { + margin-left: 0; + } + .jstree-default-dark-responsive.jstree-rtl .jstree-node { + margin-left: 0; + margin-right: 40px; + background: transparent; + } + .jstree-default-dark-responsive.jstree-rtl .jstree-container-ul > .jstree-node { + margin-right: 0; + } + .jstree-default-dark-responsive .jstree-ocl, + .jstree-default-dark-responsive .jstree-themeicon, + .jstree-default-dark-responsive .jstree-checkbox { + background-size: 120px 240px; + } + .jstree-default-dark-responsive .jstree-leaf > .jstree-ocl, + .jstree-default-dark-responsive.jstree-rtl .jstree-leaf > .jstree-ocl { + background: transparent; + } + .jstree-default-dark-responsive .jstree-open > .jstree-ocl { + background-position: 0 0px !important; + } + .jstree-default-dark-responsive .jstree-closed > .jstree-ocl { + background-position: 0 -40px !important; + } + .jstree-default-dark-responsive.jstree-rtl .jstree-closed > .jstree-ocl { + background-position: -40px 0px !important; + } + .jstree-default-dark-responsive .jstree-themeicon { + background-position: -40px -40px; + } + .jstree-default-dark-responsive .jstree-checkbox, + .jstree-default-dark-responsive .jstree-checkbox:hover { + background-position: -40px -80px; + } + .jstree-default-dark-responsive.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, + .jstree-default-dark-responsive.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, + .jstree-default-dark-responsive .jstree-checked > .jstree-checkbox, + .jstree-default-dark-responsive .jstree-checked > .jstree-checkbox:hover { + background-position: 0 -80px; + } + .jstree-default-dark-responsive .jstree-anchor > .jstree-undetermined, + .jstree-default-dark-responsive .jstree-anchor > .jstree-undetermined:hover { + background-position: 0 -120px; + } + .jstree-default-dark-responsive .jstree-anchor { + font-weight: bold; + font-size: 1.1em; + text-shadow: 1px 1px white; + } + .jstree-default-dark-responsive > .jstree-striped { + background: transparent; + } + .jstree-default-dark-responsive .jstree-wholerow { + border-top: 1px solid #666666; + border-bottom: 1px solid #000000; + background: #333333; + height: 40px; + } + .jstree-default-dark-responsive .jstree-wholerow-hovered { + background: #555555; + } + .jstree-default-dark-responsive .jstree-wholerow-clicked { + background: #5fa2db; + } + .jstree-default-dark-responsive .jstree-children .jstree-last > .jstree-wholerow { + box-shadow: inset 0 -6px 3px -5px #111111; + } + .jstree-default-dark-responsive .jstree-children .jstree-open > .jstree-wholerow { + box-shadow: inset 0 6px 3px -5px #111111; + border-top: 0; + } + .jstree-default-dark-responsive .jstree-children .jstree-open + .jstree-open { + box-shadow: none; + } + .jstree-default-dark-responsive .jstree-node, + .jstree-default-dark-responsive .jstree-icon, + .jstree-default-dark-responsive .jstree-node > .jstree-ocl, + .jstree-default-dark-responsive .jstree-themeicon, + .jstree-default-dark-responsive .jstree-checkbox { + background-image: url("40px.png"); + background-size: 120px 240px; + } + .jstree-default-dark-responsive .jstree-node { + background-position: -80px 0; + background-repeat: repeat-y; + } + .jstree-default-dark-responsive .jstree-last { + background: transparent; + } + .jstree-default-dark-responsive .jstree-leaf > .jstree-ocl { + background-position: -40px -120px; + } + .jstree-default-dark-responsive .jstree-last > .jstree-ocl { + background-position: -40px -160px; + } + .jstree-default-dark-responsive .jstree-themeicon-custom { + background-color: transparent; + background-image: none; + background-position: 0 0; + } + .jstree-default-dark-responsive .jstree-file { + background: url("40px.png") 0 -160px no-repeat; + background-size: 120px 240px; + } + .jstree-default-dark-responsive .jstree-folder { + background: url("40px.png") -40px -40px no-repeat; + background-size: 120px 240px; + } + .jstree-default-dark-responsive > .jstree-container-ul > .jstree-node { + margin-left: 0; + margin-right: 0; + } +} +.jstree-default-dark { + background: #333; +} +.jstree-default-dark .jstree-anchor { + color: #999; + text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.5); +} +.jstree-default-dark .jstree-clicked, +.jstree-default-dark .jstree-checked { + color: white; +} +.jstree-default-dark .jstree-hovered { + color: white; +} +#jstree-marker.jstree-default-dark { + border-left-color: #999; + background: transparent; +} +.jstree-default-dark .jstree-anchor > .jstree-icon { + opacity: 0.75; +} +.jstree-default-dark .jstree-clicked > .jstree-icon, +.jstree-default-dark .jstree-hovered > .jstree-icon, +.jstree-default-dark .jstree-checked > .jstree-icon { + opacity: 1; +} +.jstree-default-dark.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAACZmZl+9SADAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); +} +.jstree-default-dark.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-dark-small.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAACZmZl+9SADAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg=="); +} +.jstree-default-dark-small.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-dark-large.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAACZmZl+9SADAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg=="); +} +.jstree-default-dark-large.jstree-rtl .jstree-last { + background: transparent; +} diff --git a/civicrm/bower_components/jstree/dist/themes/default-dark/style.min.css b/civicrm/bower_components/jstree/dist/themes/default-dark/style.min.css new file mode 100644 index 0000000000..d9084d403c --- /dev/null +++ b/civicrm/bower_components/jstree/dist/themes/default-dark/style.min.css @@ -0,0 +1 @@ +.jstree-node,.jstree-children,.jstree-container-ul{display:block;margin:0;padding:0;list-style-type:none;list-style-image:none}.jstree-node{white-space:nowrap}.jstree-anchor{display:inline-block;color:#000;white-space:nowrap;padding:0 4px 0 1px;margin:0;vertical-align:top}.jstree-anchor:focus{outline:0}.jstree-anchor,.jstree-anchor:link,.jstree-anchor:visited,.jstree-anchor:hover,.jstree-anchor:active{text-decoration:none;color:inherit}.jstree-icon{display:inline-block;text-decoration:none;margin:0;padding:0;vertical-align:top;text-align:center}.jstree-icon:empty{display:inline-block;text-decoration:none;margin:0;padding:0;vertical-align:top;text-align:center}.jstree-ocl{cursor:pointer}.jstree-leaf>.jstree-ocl{cursor:default}.jstree .jstree-open>.jstree-children{display:block}.jstree .jstree-closed>.jstree-children,.jstree .jstree-leaf>.jstree-children{display:none}.jstree-anchor>.jstree-themeicon{margin-right:2px}.jstree-no-icons .jstree-themeicon,.jstree-anchor>.jstree-themeicon-hidden{display:none}.jstree-hidden,.jstree-node.jstree-hidden{display:none}.jstree-rtl .jstree-anchor{padding:0 1px 0 4px}.jstree-rtl .jstree-anchor>.jstree-themeicon{margin-left:2px;margin-right:0}.jstree-rtl .jstree-node{margin-left:0}.jstree-rtl .jstree-container-ul>.jstree-node{margin-right:0}.jstree-wholerow-ul{position:relative;display:inline-block;min-width:100%}.jstree-wholerow-ul .jstree-leaf>.jstree-ocl{cursor:pointer}.jstree-wholerow-ul .jstree-anchor,.jstree-wholerow-ul .jstree-icon{position:relative}.jstree-wholerow-ul .jstree-wholerow{width:100%;cursor:pointer;position:absolute;left:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.vakata-context{display:none}.vakata-context,.vakata-context ul{margin:0;padding:2px;position:absolute;background:#f5f5f5;border:1px solid #979797;box-shadow:2px 2px 2px #999}.vakata-context ul{list-style:none;left:100%;margin-top:-2.7em;margin-left:-4px}.vakata-context .vakata-context-right ul{left:auto;right:100%;margin-left:auto;margin-right:-4px}.vakata-context li{list-style:none}.vakata-context li>a{display:block;padding:0 2em;text-decoration:none;width:auto;color:#000;white-space:nowrap;line-height:2.4em;text-shadow:1px 1px 0 #fff;border-radius:1px}.vakata-context li>a:hover{position:relative;background-color:#e8eff7;box-shadow:0 0 2px #0a6aa1}.vakata-context li>a.vakata-context-parent{background-image:url(data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAIORI4JlrqN1oMSnmmZDQUAOw==);background-position:right center;background-repeat:no-repeat}.vakata-context li>a:focus{outline:0}.vakata-context .vakata-context-hover>a{position:relative;background-color:#e8eff7;box-shadow:0 0 2px #0a6aa1}.vakata-context .vakata-context-separator>a,.vakata-context .vakata-context-separator>a:hover{background:#fff;border:0;border-top:1px solid #e2e3e3;height:1px;min-height:1px;max-height:1px;padding:0;margin:0 0 0 2.4em;border-left:1px solid #e0e0e0;text-shadow:0 0 0 transparent;box-shadow:0 0 0 transparent;border-radius:0}.vakata-context .vakata-contextmenu-disabled a,.vakata-context .vakata-contextmenu-disabled a:hover{color:silver;background-color:transparent;border:0;box-shadow:0 0 0}.vakata-context li>a>i{text-decoration:none;display:inline-block;width:2.4em;height:2.4em;background:0 0;margin:0 0 0 -2em;vertical-align:top;text-align:center;line-height:2.4em}.vakata-context li>a>i:empty{width:2.4em;line-height:2.4em}.vakata-context li>a .vakata-contextmenu-sep{display:inline-block;width:1px;height:2.4em;background:#fff;margin:0 .5em 0 0;border-left:1px solid #e2e3e3}.vakata-context .vakata-contextmenu-shortcut{font-size:.8em;color:silver;opacity:.5;display:none}.vakata-context-rtl ul{left:auto;right:100%;margin-left:auto;margin-right:-4px}.vakata-context-rtl li>a.vakata-context-parent{background-image:url(data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAINjI+AC7rWHIsPtmoxLAA7);background-position:left center;background-repeat:no-repeat}.vakata-context-rtl .vakata-context-separator>a{margin:0 2.4em 0 0;border-left:0;border-right:1px solid #e2e3e3}.vakata-context-rtl .vakata-context-left ul{right:auto;left:100%;margin-left:-4px;margin-right:auto}.vakata-context-rtl li>a>i{margin:0 -2em 0 0}.vakata-context-rtl li>a .vakata-contextmenu-sep{margin:0 0 0 .5em;border-left-color:#fff;background:#e2e3e3}#jstree-marker{position:absolute;top:0;left:0;margin:-5px 0 0 0;padding:0;border-right:0;border-top:5px solid transparent;border-bottom:5px solid transparent;border-left:5px solid;width:0;height:0;font-size:0;line-height:0}#jstree-dnd{line-height:16px;margin:0;padding:4px}#jstree-dnd .jstree-icon,#jstree-dnd .jstree-copy{display:inline-block;text-decoration:none;margin:0 2px 0 0;padding:0;width:16px;height:16px}#jstree-dnd .jstree-ok{background:green}#jstree-dnd .jstree-er{background:red}#jstree-dnd .jstree-copy{margin:0 2px}.jstree-default-dark .jstree-node,.jstree-default-dark .jstree-icon{background-repeat:no-repeat;background-color:transparent}.jstree-default-dark .jstree-anchor,.jstree-default-dark .jstree-animated,.jstree-default-dark .jstree-wholerow{transition:background-color .15s,box-shadow .15s}.jstree-default-dark .jstree-hovered{background:#555;border-radius:2px;box-shadow:inset 0 0 1px #555}.jstree-default-dark .jstree-context{background:#555;border-radius:2px;box-shadow:inset 0 0 1px #555}.jstree-default-dark .jstree-clicked{background:#5fa2db;border-radius:2px;box-shadow:inset 0 0 1px #666}.jstree-default-dark .jstree-no-icons .jstree-anchor>.jstree-themeicon{display:none}.jstree-default-dark .jstree-disabled{background:0 0;color:#666}.jstree-default-dark .jstree-disabled.jstree-hovered{background:0 0;box-shadow:none}.jstree-default-dark .jstree-disabled.jstree-clicked{background:#333}.jstree-default-dark .jstree-disabled>.jstree-icon{opacity:.8;filter:url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'jstree-grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default-dark .jstree-search{font-style:italic;color:#fff;font-weight:700}.jstree-default-dark .jstree-no-checkboxes .jstree-checkbox{display:none!important}.jstree-default-dark.jstree-checkbox-no-clicked .jstree-clicked{background:0 0;box-shadow:none}.jstree-default-dark.jstree-checkbox-no-clicked .jstree-clicked.jstree-hovered{background:#555}.jstree-default-dark.jstree-checkbox-no-clicked>.jstree-wholerow-ul .jstree-wholerow-clicked{background:0 0}.jstree-default-dark.jstree-checkbox-no-clicked>.jstree-wholerow-ul .jstree-wholerow-clicked.jstree-wholerow-hovered{background:#555}.jstree-default-dark>.jstree-striped{min-width:100%;display:inline-block;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAMAAAB/qqA+AAAABlBMVEUAAAAAAAClZ7nPAAAAAnRSTlMNAMM9s3UAAAAXSURBVHjajcEBAQAAAIKg/H/aCQZ70AUBjAATb6YPDgAAAABJRU5ErkJggg==) left top repeat}.jstree-default-dark>.jstree-wholerow-ul .jstree-hovered,.jstree-default-dark>.jstree-wholerow-ul .jstree-clicked{background:0 0;box-shadow:none;border-radius:0}.jstree-default-dark .jstree-wholerow{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.jstree-default-dark .jstree-wholerow-hovered{background:#555}.jstree-default-dark .jstree-wholerow-clicked{background:#5fa2db;background:-webkit-linear-gradient(top,#5fa2db 0,#5fa2db 100%);background:linear-gradient(to bottom,#5fa2db 0,#5fa2db 100%)}.jstree-default-dark .jstree-node{min-height:24px;line-height:24px;margin-left:24px;min-width:24px}.jstree-default-dark .jstree-anchor{line-height:24px;height:24px}.jstree-default-dark .jstree-icon{width:24px;height:24px;line-height:24px}.jstree-default-dark .jstree-icon:empty{width:24px;height:24px;line-height:24px}.jstree-default-dark.jstree-rtl .jstree-node{margin-right:24px}.jstree-default-dark .jstree-wholerow{height:24px}.jstree-default-dark .jstree-node,.jstree-default-dark .jstree-icon{background-image:url(32px.png)}.jstree-default-dark .jstree-node{background-position:-292px -4px;background-repeat:repeat-y}.jstree-default-dark .jstree-last{background:0 0}.jstree-default-dark .jstree-open>.jstree-ocl{background-position:-132px -4px}.jstree-default-dark .jstree-closed>.jstree-ocl{background-position:-100px -4px}.jstree-default-dark .jstree-leaf>.jstree-ocl{background-position:-68px -4px}.jstree-default-dark .jstree-themeicon{background-position:-260px -4px}.jstree-default-dark>.jstree-no-dots .jstree-node,.jstree-default-dark>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:0 0}.jstree-default-dark>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-36px -4px}.jstree-default-dark>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-4px -4px}.jstree-default-dark .jstree-disabled{background:0 0}.jstree-default-dark .jstree-disabled.jstree-hovered{background:0 0}.jstree-default-dark .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default-dark .jstree-checkbox{background-position:-164px -4px}.jstree-default-dark .jstree-checkbox:hover{background-position:-164px -36px}.jstree-default-dark.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-dark .jstree-checked>.jstree-checkbox{background-position:-228px -4px}.jstree-default-dark.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-dark .jstree-checked>.jstree-checkbox:hover{background-position:-228px -36px}.jstree-default-dark .jstree-anchor>.jstree-undetermined{background-position:-196px -4px}.jstree-default-dark .jstree-anchor>.jstree-undetermined:hover{background-position:-196px -36px}.jstree-default-dark .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'jstree-grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default-dark>.jstree-striped{background-size:auto 48px}.jstree-default-dark.jstree-rtl .jstree-node{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==);background-position:100% 1px;background-repeat:repeat-y}.jstree-default-dark.jstree-rtl .jstree-last{background:0 0}.jstree-default-dark.jstree-rtl .jstree-open>.jstree-ocl{background-position:-132px -36px}.jstree-default-dark.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-100px -36px}.jstree-default-dark.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-68px -36px}.jstree-default-dark.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default-dark.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:0 0}.jstree-default-dark.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-36px -36px}.jstree-default-dark.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-4px -36px}.jstree-default-dark .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-dark>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url(throbber.gif) center center no-repeat}.jstree-default-dark .jstree-file{background:url(32px.png) -100px -68px no-repeat}.jstree-default-dark .jstree-folder{background:url(32px.png) -260px -4px no-repeat}.jstree-default-dark>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-default-dark{line-height:24px;padding:0 4px}#jstree-dnd.jstree-default-dark .jstree-ok,#jstree-dnd.jstree-default-dark .jstree-er{background-image:url(32px.png);background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default-dark i{background:0 0;width:24px;height:24px;line-height:24px}#jstree-dnd.jstree-default-dark .jstree-ok{background-position:-4px -68px}#jstree-dnd.jstree-default-dark .jstree-er{background-position:-36px -68px}.jstree-default-dark .jstree-ellipsis{overflow:hidden}.jstree-default-dark .jstree-ellipsis .jstree-anchor{width:calc(100% - 29px);text-overflow:ellipsis;overflow:hidden}.jstree-default-dark .jstree-ellipsis.jstree-no-icons .jstree-anchor{width:calc(100% - 5px)}.jstree-default-dark.jstree-rtl .jstree-node{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==)}.jstree-default-dark.jstree-rtl .jstree-last{background:0 0}.jstree-default-dark-small .jstree-node{min-height:18px;line-height:18px;margin-left:18px;min-width:18px}.jstree-default-dark-small .jstree-anchor{line-height:18px;height:18px}.jstree-default-dark-small .jstree-icon{width:18px;height:18px;line-height:18px}.jstree-default-dark-small .jstree-icon:empty{width:18px;height:18px;line-height:18px}.jstree-default-dark-small.jstree-rtl .jstree-node{margin-right:18px}.jstree-default-dark-small .jstree-wholerow{height:18px}.jstree-default-dark-small .jstree-node,.jstree-default-dark-small .jstree-icon{background-image:url(32px.png)}.jstree-default-dark-small .jstree-node{background-position:-295px -7px;background-repeat:repeat-y}.jstree-default-dark-small .jstree-last{background:0 0}.jstree-default-dark-small .jstree-open>.jstree-ocl{background-position:-135px -7px}.jstree-default-dark-small .jstree-closed>.jstree-ocl{background-position:-103px -7px}.jstree-default-dark-small .jstree-leaf>.jstree-ocl{background-position:-71px -7px}.jstree-default-dark-small .jstree-themeicon{background-position:-263px -7px}.jstree-default-dark-small>.jstree-no-dots .jstree-node,.jstree-default-dark-small>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:0 0}.jstree-default-dark-small>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-39px -7px}.jstree-default-dark-small>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-7px -7px}.jstree-default-dark-small .jstree-disabled{background:0 0}.jstree-default-dark-small .jstree-disabled.jstree-hovered{background:0 0}.jstree-default-dark-small .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default-dark-small .jstree-checkbox{background-position:-167px -7px}.jstree-default-dark-small .jstree-checkbox:hover{background-position:-167px -39px}.jstree-default-dark-small.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-dark-small .jstree-checked>.jstree-checkbox{background-position:-231px -7px}.jstree-default-dark-small.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-dark-small .jstree-checked>.jstree-checkbox:hover{background-position:-231px -39px}.jstree-default-dark-small .jstree-anchor>.jstree-undetermined{background-position:-199px -7px}.jstree-default-dark-small .jstree-anchor>.jstree-undetermined:hover{background-position:-199px -39px}.jstree-default-dark-small .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'jstree-grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default-dark-small>.jstree-striped{background-size:auto 36px}.jstree-default-dark-small.jstree-rtl .jstree-node{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==);background-position:100% 1px;background-repeat:repeat-y}.jstree-default-dark-small.jstree-rtl .jstree-last{background:0 0}.jstree-default-dark-small.jstree-rtl .jstree-open>.jstree-ocl{background-position:-135px -39px}.jstree-default-dark-small.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-103px -39px}.jstree-default-dark-small.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-71px -39px}.jstree-default-dark-small.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default-dark-small.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:0 0}.jstree-default-dark-small.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-39px -39px}.jstree-default-dark-small.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-7px -39px}.jstree-default-dark-small .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-dark-small>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url(throbber.gif) center center no-repeat}.jstree-default-dark-small .jstree-file{background:url(32px.png) -103px -71px no-repeat}.jstree-default-dark-small .jstree-folder{background:url(32px.png) -263px -7px no-repeat}.jstree-default-dark-small>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-default-dark-small{line-height:18px;padding:0 4px}#jstree-dnd.jstree-default-dark-small .jstree-ok,#jstree-dnd.jstree-default-dark-small .jstree-er{background-image:url(32px.png);background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default-dark-small i{background:0 0;width:18px;height:18px;line-height:18px}#jstree-dnd.jstree-default-dark-small .jstree-ok{background-position:-7px -71px}#jstree-dnd.jstree-default-dark-small .jstree-er{background-position:-39px -71px}.jstree-default-dark-small .jstree-ellipsis{overflow:hidden}.jstree-default-dark-small .jstree-ellipsis .jstree-anchor{width:calc(100% - 23px);text-overflow:ellipsis;overflow:hidden}.jstree-default-dark-small .jstree-ellipsis.jstree-no-icons .jstree-anchor{width:calc(100% - 5px)}.jstree-default-dark-small.jstree-rtl .jstree-node{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg==)}.jstree-default-dark-small.jstree-rtl .jstree-last{background:0 0}.jstree-default-dark-large .jstree-node{min-height:32px;line-height:32px;margin-left:32px;min-width:32px}.jstree-default-dark-large .jstree-anchor{line-height:32px;height:32px}.jstree-default-dark-large .jstree-icon{width:32px;height:32px;line-height:32px}.jstree-default-dark-large .jstree-icon:empty{width:32px;height:32px;line-height:32px}.jstree-default-dark-large.jstree-rtl .jstree-node{margin-right:32px}.jstree-default-dark-large .jstree-wholerow{height:32px}.jstree-default-dark-large .jstree-node,.jstree-default-dark-large .jstree-icon{background-image:url(32px.png)}.jstree-default-dark-large .jstree-node{background-position:-288px 0;background-repeat:repeat-y}.jstree-default-dark-large .jstree-last{background:0 0}.jstree-default-dark-large .jstree-open>.jstree-ocl{background-position:-128px 0}.jstree-default-dark-large .jstree-closed>.jstree-ocl{background-position:-96px 0}.jstree-default-dark-large .jstree-leaf>.jstree-ocl{background-position:-64px 0}.jstree-default-dark-large .jstree-themeicon{background-position:-256px 0}.jstree-default-dark-large>.jstree-no-dots .jstree-node,.jstree-default-dark-large>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:0 0}.jstree-default-dark-large>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-32px 0}.jstree-default-dark-large>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:0 0}.jstree-default-dark-large .jstree-disabled{background:0 0}.jstree-default-dark-large .jstree-disabled.jstree-hovered{background:0 0}.jstree-default-dark-large .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default-dark-large .jstree-checkbox{background-position:-160px 0}.jstree-default-dark-large .jstree-checkbox:hover{background-position:-160px -32px}.jstree-default-dark-large.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-dark-large .jstree-checked>.jstree-checkbox{background-position:-224px 0}.jstree-default-dark-large.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-dark-large .jstree-checked>.jstree-checkbox:hover{background-position:-224px -32px}.jstree-default-dark-large .jstree-anchor>.jstree-undetermined{background-position:-192px 0}.jstree-default-dark-large .jstree-anchor>.jstree-undetermined:hover{background-position:-192px -32px}.jstree-default-dark-large .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'jstree-grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default-dark-large>.jstree-striped{background-size:auto 64px}.jstree-default-dark-large.jstree-rtl .jstree-node{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==);background-position:100% 1px;background-repeat:repeat-y}.jstree-default-dark-large.jstree-rtl .jstree-last{background:0 0}.jstree-default-dark-large.jstree-rtl .jstree-open>.jstree-ocl{background-position:-128px -32px}.jstree-default-dark-large.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-96px -32px}.jstree-default-dark-large.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-64px -32px}.jstree-default-dark-large.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default-dark-large.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:0 0}.jstree-default-dark-large.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-32px -32px}.jstree-default-dark-large.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:0 -32px}.jstree-default-dark-large .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-dark-large>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url(throbber.gif) center center no-repeat}.jstree-default-dark-large .jstree-file{background:url(32px.png) -96px -64px no-repeat}.jstree-default-dark-large .jstree-folder{background:url(32px.png) -256px 0 no-repeat}.jstree-default-dark-large>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-default-dark-large{line-height:32px;padding:0 4px}#jstree-dnd.jstree-default-dark-large .jstree-ok,#jstree-dnd.jstree-default-dark-large .jstree-er{background-image:url(32px.png);background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default-dark-large i{background:0 0;width:32px;height:32px;line-height:32px}#jstree-dnd.jstree-default-dark-large .jstree-ok{background-position:0 -64px}#jstree-dnd.jstree-default-dark-large .jstree-er{background-position:-32px -64px}.jstree-default-dark-large .jstree-ellipsis{overflow:hidden}.jstree-default-dark-large .jstree-ellipsis .jstree-anchor{width:calc(100% - 37px);text-overflow:ellipsis;overflow:hidden}.jstree-default-dark-large .jstree-ellipsis.jstree-no-icons .jstree-anchor{width:calc(100% - 5px)}.jstree-default-dark-large.jstree-rtl .jstree-node{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg==)}.jstree-default-dark-large.jstree-rtl .jstree-last{background:0 0}@media (max-width:768px){#jstree-dnd.jstree-dnd-responsive{line-height:40px;font-weight:700;font-size:1.1em;text-shadow:1px 1px #fff}#jstree-dnd.jstree-dnd-responsive>i{background:0 0;width:40px;height:40px}#jstree-dnd.jstree-dnd-responsive>.jstree-ok{background-image:url(40px.png);background-position:0 -200px;background-size:120px 240px}#jstree-dnd.jstree-dnd-responsive>.jstree-er{background-image:url(40px.png);background-position:-40px -200px;background-size:120px 240px}#jstree-marker.jstree-dnd-responsive{border-left-width:10px;border-top-width:10px;border-bottom-width:10px;margin-top:-10px}}@media (max-width:768px){.jstree-default-dark-responsive .jstree-icon{background-image:url(40px.png)}.jstree-default-dark-responsive .jstree-node,.jstree-default-dark-responsive .jstree-leaf>.jstree-ocl{background:0 0}.jstree-default-dark-responsive .jstree-node{min-height:40px;line-height:40px;margin-left:40px;min-width:40px;white-space:nowrap}.jstree-default-dark-responsive .jstree-anchor{line-height:40px;height:40px}.jstree-default-dark-responsive .jstree-icon,.jstree-default-dark-responsive .jstree-icon:empty{width:40px;height:40px;line-height:40px}.jstree-default-dark-responsive>.jstree-container-ul>.jstree-node{margin-left:0}.jstree-default-dark-responsive.jstree-rtl .jstree-node{margin-left:0;margin-right:40px;background:0 0}.jstree-default-dark-responsive.jstree-rtl .jstree-container-ul>.jstree-node{margin-right:0}.jstree-default-dark-responsive .jstree-ocl,.jstree-default-dark-responsive .jstree-themeicon,.jstree-default-dark-responsive .jstree-checkbox{background-size:120px 240px}.jstree-default-dark-responsive .jstree-leaf>.jstree-ocl,.jstree-default-dark-responsive.jstree-rtl .jstree-leaf>.jstree-ocl{background:0 0}.jstree-default-dark-responsive .jstree-open>.jstree-ocl{background-position:0 0!important}.jstree-default-dark-responsive .jstree-closed>.jstree-ocl{background-position:0 -40px!important}.jstree-default-dark-responsive.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-40px 0!important}.jstree-default-dark-responsive .jstree-themeicon{background-position:-40px -40px}.jstree-default-dark-responsive .jstree-checkbox,.jstree-default-dark-responsive .jstree-checkbox:hover{background-position:-40px -80px}.jstree-default-dark-responsive.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-dark-responsive.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-dark-responsive .jstree-checked>.jstree-checkbox,.jstree-default-dark-responsive .jstree-checked>.jstree-checkbox:hover{background-position:0 -80px}.jstree-default-dark-responsive .jstree-anchor>.jstree-undetermined,.jstree-default-dark-responsive .jstree-anchor>.jstree-undetermined:hover{background-position:0 -120px}.jstree-default-dark-responsive .jstree-anchor{font-weight:700;font-size:1.1em;text-shadow:1px 1px #fff}.jstree-default-dark-responsive>.jstree-striped{background:0 0}.jstree-default-dark-responsive .jstree-wholerow{border-top:1px solid #666;border-bottom:1px solid #000;background:#333;height:40px}.jstree-default-dark-responsive .jstree-wholerow-hovered{background:#555}.jstree-default-dark-responsive .jstree-wholerow-clicked{background:#5fa2db}.jstree-default-dark-responsive .jstree-children .jstree-last>.jstree-wholerow{box-shadow:inset 0 -6px 3px -5px #111}.jstree-default-dark-responsive .jstree-children .jstree-open>.jstree-wholerow{box-shadow:inset 0 6px 3px -5px #111;border-top:0}.jstree-default-dark-responsive .jstree-children .jstree-open+.jstree-open{box-shadow:none}.jstree-default-dark-responsive .jstree-node,.jstree-default-dark-responsive .jstree-icon,.jstree-default-dark-responsive .jstree-node>.jstree-ocl,.jstree-default-dark-responsive .jstree-themeicon,.jstree-default-dark-responsive .jstree-checkbox{background-image:url(40px.png);background-size:120px 240px}.jstree-default-dark-responsive .jstree-node{background-position:-80px 0;background-repeat:repeat-y}.jstree-default-dark-responsive .jstree-last{background:0 0}.jstree-default-dark-responsive .jstree-leaf>.jstree-ocl{background-position:-40px -120px}.jstree-default-dark-responsive .jstree-last>.jstree-ocl{background-position:-40px -160px}.jstree-default-dark-responsive .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-dark-responsive .jstree-file{background:url(40px.png) 0 -160px no-repeat;background-size:120px 240px}.jstree-default-dark-responsive .jstree-folder{background:url(40px.png) -40px -40px no-repeat;background-size:120px 240px}.jstree-default-dark-responsive>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}}.jstree-default-dark{background:#333}.jstree-default-dark .jstree-anchor{color:#999;text-shadow:1px 1px 0 rgba(0,0,0,.5)}.jstree-default-dark .jstree-clicked,.jstree-default-dark .jstree-checked{color:#fff}.jstree-default-dark .jstree-hovered{color:#fff}#jstree-marker.jstree-default-dark{border-left-color:#999;background:0 0}.jstree-default-dark .jstree-anchor>.jstree-icon{opacity:.75}.jstree-default-dark .jstree-clicked>.jstree-icon,.jstree-default-dark .jstree-hovered>.jstree-icon,.jstree-default-dark .jstree-checked>.jstree-icon{opacity:1}.jstree-default-dark.jstree-rtl .jstree-node{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAACZmZl+9SADAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==)}.jstree-default-dark.jstree-rtl .jstree-last{background:0 0}.jstree-default-dark-small.jstree-rtl .jstree-node{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAACZmZl+9SADAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg==)}.jstree-default-dark-small.jstree-rtl .jstree-last{background:0 0}.jstree-default-dark-large.jstree-rtl .jstree-node{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAACZmZl+9SADAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg==)}.jstree-default-dark-large.jstree-rtl .jstree-last{background:0 0} \ No newline at end of file diff --git a/civicrm/bower_components/jstree/dist/themes/default-dark/throbber.gif b/civicrm/bower_components/jstree/dist/themes/default-dark/throbber.gif new file mode 100644 index 0000000000000000000000000000000000000000..cd75035ce8086b233c62c3775de4696007ba7950 GIT binary patch literal 1720 zcmZ|OYfMvT7zgm4p2O+ea@rnBg#%t_w^9y@rd%z;T+7W;EEIuRP@n~of>p{*LD94n zD#dD%>4eQ7(f}2w1Jp&gxD-%9@q$L8PU8@DI@}hSaq0)%%HqfF!~5+?{=fX6_gR&k zB#zeL6rA#kLJ1EKkB*MkYPAxH#A31N_4>ZPK7+x~*4Cy{sgz1(XJ@Bct?upZwb^Vn zH8uQyJW~@hGvcMn#IR)|7@|-p{15)|6-An=q7A%lB~@CUrc_g-E7NRPR<dPd8HN82 zp)*`lA+G0>Y{9GBtGW2#F<6Tlp*{3e2sO*9QTn07T-ayS_ZHC-#O>$xhqqdcpZ ztmi!vPe)MeZRuUe$#kkQ=ZCx#&BIF_bl`&&kBftO#70Qh(%BzvH^%Q*V^7k&A({sT z%Y^lTu*avnIgG+U1|!SMokH(YXlu`0j~)X}p;*dbvgwiG8ou~G0H`U%D%A}cX`Z7O z)ni(eb`a})TPHM1hAVH$IJP)wYgYnn9eF%-V%K@toW*&nV8eM+!Cp9L>Vhol^Gh@~ z%&1Z5Vm+|c!un0R(q?jRP)d+nM1>1Mdb<!00m4C22b1F~4bvL(K24Ow5uy;LR~``5 zOQu8^f<FFpK#ZYe4kw9DF7mew^V&!=_Pit^m3#em=(!cL4S{wAZ`L^mhtchw{eR!7 z@ef;-7EoITVWKo{ZN-+Dg7Toy0{4u$F33U`Lk?)O3$F;7`+QMbdTM|(MD8Hik;>t4 zq+z&G4Mf-;dC=>aU>rU4#Qsu;p3RpG$pl+_MhkB8a)~L$l9^5fWiX2+H!!5_T5s^9 z4>JK<{X^Fo%S_uDF%5Ow6`@;%!WN<1E;i0BB-n*W1?E{l7sBj|dY;=Uk(#XoO1L_N z@qGP~b}*65jDQozoGo?S4(63|3?uFyzC7?Gm+`Y=Q}V!~<?@+(&6BbN{6Aic9m8Wq z51v(;f10WNVvBcuty$P$@^%|t<BE2yIdk1_4TzhaHzM?C3<A706_YQq7yTg9kGxC? zJ5*n|o40{WwF*UIV!?MeoTunG5%8O{m?~n?>eW9^>IiUQTB_L<1=H*gdQy5&m_IYV z%Li4Uo_>Bi7os#uY}WcRfHHEkH&b8~%gsue?-o<(!aOHjm`s4Z3LOy|RiA_<T+TA# z4tT%HCu)iBtEz@0jc=lvi}sjacsq4e8&cVKPq4^l(v?yLfVIkaD<l=AmCRNiV{uW_ zMA*_;9CZxszpVB_sc2zY+6n_)vn*{j6ZK^-&kds0aos!qJJUIbUMa@~Bf_1;+s^{m zGWp_I#=+|8>cGTpV7aX)L(k3WdLrb3z#~FKmqZa8IsfA0m#1pKiYPj1TEN53e>tkg z0RTNlJq#uQVrLpQqdM5r6JnuD=hIQXX(5PA4}{kHxmV1!p*>qQvt#tEygNOAs@+Oz zdfw4ZMdhbk+u}+OPG5|*-o?V{NXcn0HBbAn)h^Y1-B04pOzSBDfelR>`teLE(^ROI zh&b$euUUs^kZN*1k{J%gadZHxgJ?{nH{AjOmJrF77iSdv|L<1j9OLgC{;#V|RJlr& zcSW6j{0-Aeuhh1H@4Gt=_&ggRSH>Bn1;_M62O`)zlyTGNWU^sE&gnQmJ~HG$aPw$; zKX(DOIsRy?o{m{z>42;$0!CTTcF2R3?au%K2(p-Mna`zCH@bI}ee7d=$K>rPkFF?8 zv$nvf0d|7yp7!sKocJY+u<ZT)F9{LAbEZmTB7FA5RkY(44su(dd`hxUK1h5i%cQd6 z`4X|n&z5aWKME1f;le4<y4n+QF|h26Y=});nZql_s{Gua%g3FRp1JhC4JBQlsv`<> zY6SVs9!-4A?3JGvc^gfN8$7Nen2o=3aWO!QO@le}aMdx8^`2yXn=H9`9ATLE&9>s? q)n(GDbX6ch9<^Oe2Q%ytegccF@POz|8L)A;FQ!??rHkeqG5-P<(jCG8 literal 0 HcmV?d00001 diff --git a/civicrm/bower_components/jstree/dist/themes/default/32px.png b/civicrm/bower_components/jstree/dist/themes/default/32px.png new file mode 100644 index 0000000000000000000000000000000000000000..15327152481789306eadef88393cd1c748dc31a7 GIT binary patch literal 3121 zcmd7U`8U-69tZG`S&Ttp2wAdCqGXM%-z>#gDk)iGP*Pd5FU3%4q{tQ_Lo{TYq8P+T z5f#GN%GeTPjAdk><<7nLm-{E&_xqgZdpqwR-se2d>%6h{=dAYeOYs8$u+JKG+5rG~ zOu2J3ADEkN*=|w*00!*sE}h{nU5gzdXvqoyFfcHHKp@<m``4`C007|!%~ajGd-rZx z*{ia$GNPoUTZtpD_rccyP>!$I+1Y6afnM?O0B%x~Mb|(c2l@8#hDXMUCqv2rKqy4I z6@l2QsK7&^+`G<=>TiUFIV{dwI6NXUP9q(8;688n@#F0Z3P+RG9BWO&y3Wd_@m4~i zfQ#s{=Yr)R(0o!-H6PzfW~NXatPBR*Sl{p>ntc@%+{n!IZL)@WiKq143Tt=C{~6=) z#wLv%lr|8&bp85}we>p*iFp^7MIWDf2;?yUERGkpN=p-*^qJcXSy}1Q($eY58ypU2 zX^F0^tjuPzD1|<|%hQfdZrn#9^MUR8Vb&(u-6wc+W0SQ_Ut_FIPEJu57WNp_sV|SW z=$*NFxy7lDy0rjEkH9@092{C5XjuQ%{CA?0I`X2sF1DfgdM_zs;v3#Fz#<_LySlof zSHrtCH&jL}+g+Yoq|u)Lx!yb5F+DRA77=^=C7@ji>@gOud^)P}3b-?ZYFJC{+pKl1 zF=y`W4FJFb0MM4`1M{5*1m5}i`OVq>SpcB(@Kk&)F>QeAK9f!yJzKZ(@O+y%d5Fx~ zqSe;U+I$e&S{!@3@bojOP%#G*HDo?FH^=zPn4nOG$iqE6JRgU;aFm3n!@+*vv^=UU zkGufTU1~}x2=XAAlbbsRg>FvutN{Sq*O#@uwD;)IQLJp>N88449|~pzhqs%SR+eJB zTzA%g*Z#_T@--l`)itEqDL%fD@cG^F@EE7QegXhkk&)ZV%4@?-t0pEiVc`p(#IAih znLOb2aL^k|Mwd^fRINq@_3C%`H4?s8Z_z35#l*ac7MogHly4QB%F3jiWL#6}g_nlk z$gPk1{7XiYAG8LZDv_zobIhLgC?Lm{P=nfjyfb=o;=@|D)?-y-OU|=5MQT|h4y}hc z6bh%in-do|(OW_2c>i^*qoKfMAv`=hH=>}xKI&<FX-nnnrC0*-NqNmf|E*zfu6TNw z!?}w9OI^m*OqmBR&Prf&+}OH`Y&P57YR5o=MXfqxw^_{E3*@kvV`EkK&=d60`h(QU ziGtm+q}_$}U9uvTOsie!XY@Pm?F=ApW<pt9WZcI7@9_VYJMVl`F985--TJiIrKoXw zLA3LruS}N!bUa30CA61#R(WxMt?Y8^%B+yvN58KZUewsT*tn4{D3+_}Tbf}X^1qP3 z*iSqgk}^^N^T=NgYx-#rX*6+XawWgs?$BLp7xN>XTi_GMefcdn{)x+M3EIZkkl&>W z+}@+UYHm9PvX;jn)BoFXpCC6I`x5++Z98xoB9S;IbW{@)ac9Nj&6^J~RG(PdMnt)+ z=%ZngTU%Z*R@n~9y88kev~gJoMlZf`S*U(cJZ;|KUYAdCdqi#8E1%>Ig6T`G$LG-z zPZ)@DjZ#(q?mA~R4*?ZF#`|ua>%9f32~Y>gafc7yUo$+-FsiDZaChLamHi|(9B~zC zH;IMt|E<La<hH-nA(%_qIeRYFJs;>2@%*PX;K9MstygLL>rm*8p2NpHJfnFCkKB=g zAiRc>g*Ry94~dQVU5c{gyxF&urRuLBp=ghu-n1?n$;!zY9`e_KY_7A1libqmFKr~} zd&bU@9gA_K)U018s?Iy3ao|$WHO+S9F^u+ZS^&Yd`l8e!Oa2=|D#2YX=Z`4p_5Hjs z+F%hn^x1YYw_y#n(Rswy#)Ca|=YX0f7_Vtz3Hp#_LR!nadf48Q<2<E(Rrr4T1B9RY zuN_HWYUX4W2(o{>G2%zTvmS~^R$iV#1Dt8#s}wR82k3O#nwV<jAGsUHBRa|kFM2i> zuE+&ifu5~c^5O|<a~SAwj`0--2P6FL17ZA}e<UjMFB$}l*Avg4P}A(_hKDJ3!VY8L zGVQiFKTgc>V(^m31F^Sa1*Er3W=~HKlgZRxRenpOQ3vto3k}09L>o;Q^S!ryec}Tf zV&e!k80}<5?cI^O{mDM;n_}k21o%sLk%teP+;7e3Q9;SG$U2ST9m>J6)klwjv7y)T zjT2NV)j`znGSmr|$~M4^Dl|PKfh;oO?vX&Uo+cMP+or9eVhh!~u%C#bpP&)#`t~`d z+3uLiXSFX@2p_?7SOtYU{Z^<i>cO~x5Pi0ONSr963q)^Pm5Gc942(Hv6Vvn;5<$!3 zyEbi>sbw$x^}Oz?sYt=1i_3eji=vO-fbg2)5BcO*1v_g_`s~g~V3MJ}av6t|{ggUG zRrD|%i5AP5=@TXaioz%m9EpK&t?!6HD+-b6rU;Zg90^CJLl7vC5pG%@4zc!!^#^K7 z#suSnAmcw#VwCew4K#E$`bt|M%1!<Onh8Ksz@7H>hcnR6H}t?m%e6wrF;(O8Ox~r6 z=>3_hju^O_rlNmi;!r*>T<s4H9D+e>sq}w|OrU||lQz?PytEZCeyXg(6c$6TSOB3y zX$uA&^wG|ACmFa4!PQnrV1Z+o0XTE!Wu~CEio0B{RN9(Dw7}UlbCIRfpzkHHTzMmF z#NG%}yIXKphmSvQ&`HkOwN4hX-OZ&;OYJnA-X#rfTWPL&gN&Y@`oYM)mp~4fO&n_b z^ULL%D^in)Bl#WUg={)6RSGdfDd$Y(J>{I8x<+8^stgrPG>D$%#01VVv{i`lYW;K1 z?;ntQ3<5o4Y+&A9>wE(GNrthn+Cx<_(N!n=c_Q@9*D^?(bbAi|y?})L&E6}tm>*PE zBLQg$<YtT-W#{|g!|@(F6mBsyo(4{Pb?}@UXzntf&9dC#{_Hs&XFz%NyW@^b9>KK3 z%k$3EFAGbze#Gb<TgX$>>z6O*3{r1v*=a?IQfD=SlAz=485&qfD>dEpMTtD+elvh& zy=)E^hw1r&leGds7HEu1{Om5tu*JkU{SPd$;*5Z3zin_Q=1PVc7JNgQHW3*=CDUYz zd5?7uk*^WDR}=E!1b+QDb~fBk?GtIlH2Xjj^SHn6m@2gQ^niGkXM$;_R<QC%N!F+& zO5SiIPh-DVe5&o$qt|Z+9KRW$o9Aeww3dbE!6FWchi!U&RF6aCJJ5ee%NHA&|A!S9 z6(3hyhAD_!S^q699r8lgn50pU#0*H@c0_ud_6RQ~@w?vpvf1=P#w(>kCVYMl*XBu) zek5q=@t1yvU{<ZJXnw?7Gj*@J@;<#{74m@c{u&$|jM~Alj{7Jn1^ud<HyXw1C6;_t zs-NK&9Hmygc2Z<J{bcA)Gq|RxxvAy#45=w6Cr9@d<!9)@sFVj6ML!EN;H9$l4S0m8 zKKggNTNjQwkw}}j3@a}hEQe(~T{3QtpKM)m8+Ly!F1%fyYvzG_7NIXQ&EK**y-UpR zy!YhOMra3S*W&SR4<lu)uayuu(P~SUQoxMj`oq&DB<IUi4eg@gGQrTABIytlZXAHt zl(e>`=tMQRPN_eFDkh1PfI|2_*tCdlwSDwFb@Hf~$83T0=55}Ulq{81g|>EmsIu@u z<D%N4W~2?t(=J*^Pk*m)Pth^soYy(DyG+c5Kh6ZsPUGEWL@{$;fWKN$AjR#1)?Q)k z%F{5>wN8`Y8zp@@&Qpy5FO60!@}+2Tyun-QtF%>`dhKgNf@hDWrRZ=U2d}<nQ~3Dr zDJ|nm3#;U$$rLP6+c3u7$8nu}(;7^rsj)d|d_Uy%32@21pF>H>`^{&DlDv64I&u>( z8uW=uGK=c7Psu$Hv@8;>zTt+7$`u~2m9z0|)7cfv+3PCBtFeuy&wye3rS%AWA~lN4 q$a=%VWn+k|UtiDv&>%>!2^rk(<mU}sN#*`~0P8d7PS=>D6aNK_^-%!; literal 0 HcmV?d00001 diff --git a/civicrm/bower_components/jstree/dist/themes/default/40px.png b/civicrm/bower_components/jstree/dist/themes/default/40px.png new file mode 100644 index 0000000000000000000000000000000000000000..1959347aea041d75a58d0584ea7ec51714797983 GIT binary patch literal 1880 zcmZ`)do<fw9*<}e@1Q2_D)Bn4dY2-m9$9UbNQ(-Cs6<n0F-g-_Oim3EEY)_HF~y9G z)y~u--ik^|h*GAbm`0I$#INeHCDEW2(qOY^dv<o(v-h9R_k8a?-}||r`~BRT8x-KH ztzoDE0)ezKekX&KC<TF305w%*RBNr9uLN|^=@1_!9{pqp1cKe&-A~dV5)z5zKaq!r zM+znSqO!!^q~HJ?NM{Fn4!mumqEL%4HZ#zOf(9+)csn2vv=wvGJA^(VnO-iKI;5L@ zo@7~cB}so{r@<xXw__KUvw#yxBM!T#@N9a5Gq@!COngBBt`WTdNHjlPMHQ;G{|LbD z9?;k1&T&tIcO`|n&HEbsf10NI%!>PK^x}L8xo#<I*1cfr5N*+#3%-n?=ZD5ER&yn@ zwNfN|XejhrPUg(=W!co>OE#OkB~$LGr;}=FbpxeWUvbGmLn1DXa;HsQK~D7_{^sq2 z^fni3chvJ5$YKUAlPB<%YYsGqZ3*PyX7OjPSmNI*c<p)p5sq_(G&>$WG!up*Jd*}3 zyaNUJH)Q(CkAGRYx9(QF6|av~uGv)1Y;;XvzcpOJ6RwjX&Aq_Aw}!?@ks55jzGfWq zHi2b^qzQ-8bl-&6a#)X#NWKfdin__%Ol?}CAS&@2z3m-#8{JmeH=J<Bz4_RtZNZYA z&bMp24(x-3iC}JT3!R;_T7Z334!3bX^+BrtYW8u!VcTMDrRIddSYxi=`1u&}0u9#a z+H_cEkcfL&tV3vWv*DG*_^n5umB)34LNi>{JF%S+MQ5YWYP20_w8qRF6(+-b#Trf> zo_2Ahj>H8mS@~xq^k9LXSkqS5UA65dkI8zx!mlGSfKyE;s4Src2P4*>GKW637{uPZ zn41TS!b0I%aCMOGtR7_5i0R^u?Z1kp6{@2~AH^7slz&0Qj|5)78I0s6dlVU{)cQrP zeNGP#HlU^~-R%ecwQ5d4f89gT`1oM|(<dLMHs@Rg472*KGDNM&w5q4*gg@0=azER~ zY|)bY)zS+x(Mpf=G?Fl!=N^yYmx~0~lBeBIgY0ERqs{A-_(8y3RB$bM#v}k@Z?3k2 zGE}sLnIqCeMFrz5vUHkQN~6AZSgAm@?F=54O4_PVP-!W11`7GzpGT8mY1<(qSSd7Z zJABmU3N-ED*gNoaMq&z&VDfs2&^c24#dcL+T=R3?=T}~=x)~Y_PqcoiG5b)AHGz08 z7<)MHu`A6h+F*<yg~MwyTPXcKDQ_fdDj@z!_u3uS`>Ofc=m=oyYg2-k3n{hQ$7?G# z&FPF6FFv(B1kEI;9zR$1bF}BYcUcz6lkHP>F~*Z@^?L7<Tb32ZW6uQJbJ1wXAD;TZ zGP>Dwi265tsN>ESDZo%}%mSZ>gVZrQEHe#NWr4C*NSf*0NrTPY+o|6J6YC;=zHNu2 z8bz_U4ETk(5(4ZKzU=r-bX5C~YoQu69_!<yls;DOxd_V9oc+7@NS}Id4l5xS^&^7P z?kvipb8qL+F?OqhqF_#MOVU{DPY7`(=-=M|h^M$N<4>Kg_;tIz@|bcZeUDp?>LM|N ziJp5yVxnWe6Y7OqZ0sqz9>rV_e8%6p;7r{y(w<VdZ;a@46%#Yxw$v&Pysw19(cI$v zE=N3AY@}G1HO$M<m9WIF%M1YijE@FGwcMPQ4#f|r<616#LPkqyx`}g^#!Py&+x&^u zN4z~V#{2Epv;xvEFvIxC{F-lA%EHQLO$sO~Y9n3YLt7@R_{%Tm&wmdv*5NahafvB; zb-4%8y&HS3vo5qa%E(o%{<M=PXKAu$gI^fm3JW9auvEwGpU-q9qzDZ;PBb}CUE0&f zFMKi!3zHZ>fYhJK>k?%R9^#}q@<oO3ziQq?iBJS_Lvzijlcan>xkWO6(y$(5^<ZpO z$bMOpMM{hs;3*T9NDsPD;o)NE_e9WO1`KLq#xl-1&<?1GLXMAR+*>YBRpql1{)zuK zbrtwwtit>e;@%w>h7p&2<37Z3Q~Of2IoVshosA0BYcm}a31kTD@b5Y^cq1>Lz~v#* z=I3$&3b7mLgtwj%M~`+Qvt=#z{qJiwXm0kiXWM^#JaGk!bF6zb=stF+fn62*;^IMV z;8jniInrmfUG6KNlUC^lV!pmFFQ+Bb!%x?kA|oelOOeQZy&ZYzuw;)RIQ$l#&^K8* z0OFJoe{kr3Me>S$Wc!cxtzZ7K-m>EtO!YQ<*Jwhovtf3=v?o4fP-T|cmxOL~h!|$H iV&_@$q2+YC87j9T{b5}<wiwF)4TSLtI9Y!@I^$o<n_Kw+ literal 0 HcmV?d00001 diff --git a/civicrm/bower_components/jstree/dist/themes/default/style.css b/civicrm/bower_components/jstree/dist/themes/default/style.css new file mode 100644 index 0000000000..616be241be --- /dev/null +++ b/civicrm/bower_components/jstree/dist/themes/default/style.css @@ -0,0 +1,1102 @@ +/* jsTree default theme */ +.jstree-node, +.jstree-children, +.jstree-container-ul { + display: block; + margin: 0; + padding: 0; + list-style-type: none; + list-style-image: none; +} +.jstree-node { + white-space: nowrap; +} +.jstree-anchor { + display: inline-block; + color: black; + white-space: nowrap; + padding: 0 4px 0 1px; + margin: 0; + vertical-align: top; +} +.jstree-anchor:focus { + outline: 0; +} +.jstree-anchor, +.jstree-anchor:link, +.jstree-anchor:visited, +.jstree-anchor:hover, +.jstree-anchor:active { + text-decoration: none; + color: inherit; +} +.jstree-icon { + display: inline-block; + text-decoration: none; + margin: 0; + padding: 0; + vertical-align: top; + text-align: center; +} +.jstree-icon:empty { + display: inline-block; + text-decoration: none; + margin: 0; + padding: 0; + vertical-align: top; + text-align: center; +} +.jstree-ocl { + cursor: pointer; +} +.jstree-leaf > .jstree-ocl { + cursor: default; +} +.jstree .jstree-open > .jstree-children { + display: block; +} +.jstree .jstree-closed > .jstree-children, +.jstree .jstree-leaf > .jstree-children { + display: none; +} +.jstree-anchor > .jstree-themeicon { + margin-right: 2px; +} +.jstree-no-icons .jstree-themeicon, +.jstree-anchor > .jstree-themeicon-hidden { + display: none; +} +.jstree-hidden, +.jstree-node.jstree-hidden { + display: none; +} +.jstree-rtl .jstree-anchor { + padding: 0 1px 0 4px; +} +.jstree-rtl .jstree-anchor > .jstree-themeicon { + margin-left: 2px; + margin-right: 0; +} +.jstree-rtl .jstree-node { + margin-left: 0; +} +.jstree-rtl .jstree-container-ul > .jstree-node { + margin-right: 0; +} +.jstree-wholerow-ul { + position: relative; + display: inline-block; + min-width: 100%; +} +.jstree-wholerow-ul .jstree-leaf > .jstree-ocl { + cursor: pointer; +} +.jstree-wholerow-ul .jstree-anchor, +.jstree-wholerow-ul .jstree-icon { + position: relative; +} +.jstree-wholerow-ul .jstree-wholerow { + width: 100%; + cursor: pointer; + position: absolute; + left: 0; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +.vakata-context { + display: none; +} +.vakata-context, +.vakata-context ul { + margin: 0; + padding: 2px; + position: absolute; + background: #f5f5f5; + border: 1px solid #979797; + box-shadow: 2px 2px 2px #999999; +} +.vakata-context ul { + list-style: none; + left: 100%; + margin-top: -2.7em; + margin-left: -4px; +} +.vakata-context .vakata-context-right ul { + left: auto; + right: 100%; + margin-left: auto; + margin-right: -4px; +} +.vakata-context li { + list-style: none; +} +.vakata-context li > a { + display: block; + padding: 0 2em 0 2em; + text-decoration: none; + width: auto; + color: black; + white-space: nowrap; + line-height: 2.4em; + text-shadow: 1px 1px 0 white; + border-radius: 1px; +} +.vakata-context li > a:hover { + position: relative; + background-color: #e8eff7; + box-shadow: 0 0 2px #0a6aa1; +} +.vakata-context li > a.vakata-context-parent { + background-image: url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAIORI4JlrqN1oMSnmmZDQUAOw=="); + background-position: right center; + background-repeat: no-repeat; +} +.vakata-context li > a:focus { + outline: 0; +} +.vakata-context .vakata-context-hover > a { + position: relative; + background-color: #e8eff7; + box-shadow: 0 0 2px #0a6aa1; +} +.vakata-context .vakata-context-separator > a, +.vakata-context .vakata-context-separator > a:hover { + background: white; + border: 0; + border-top: 1px solid #e2e3e3; + height: 1px; + min-height: 1px; + max-height: 1px; + padding: 0; + margin: 0 0 0 2.4em; + border-left: 1px solid #e0e0e0; + text-shadow: 0 0 0 transparent; + box-shadow: 0 0 0 transparent; + border-radius: 0; +} +.vakata-context .vakata-contextmenu-disabled a, +.vakata-context .vakata-contextmenu-disabled a:hover { + color: silver; + background-color: transparent; + border: 0; + box-shadow: 0 0 0; +} +.vakata-context li > a > i { + text-decoration: none; + display: inline-block; + width: 2.4em; + height: 2.4em; + background: transparent; + margin: 0 0 0 -2em; + vertical-align: top; + text-align: center; + line-height: 2.4em; +} +.vakata-context li > a > i:empty { + width: 2.4em; + line-height: 2.4em; +} +.vakata-context li > a .vakata-contextmenu-sep { + display: inline-block; + width: 1px; + height: 2.4em; + background: white; + margin: 0 0.5em 0 0; + border-left: 1px solid #e2e3e3; +} +.vakata-context .vakata-contextmenu-shortcut { + font-size: 0.8em; + color: silver; + opacity: 0.5; + display: none; +} +.vakata-context-rtl ul { + left: auto; + right: 100%; + margin-left: auto; + margin-right: -4px; +} +.vakata-context-rtl li > a.vakata-context-parent { + background-image: url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAINjI+AC7rWHIsPtmoxLAA7"); + background-position: left center; + background-repeat: no-repeat; +} +.vakata-context-rtl .vakata-context-separator > a { + margin: 0 2.4em 0 0; + border-left: 0; + border-right: 1px solid #e2e3e3; +} +.vakata-context-rtl .vakata-context-left ul { + right: auto; + left: 100%; + margin-left: -4px; + margin-right: auto; +} +.vakata-context-rtl li > a > i { + margin: 0 -2em 0 0; +} +.vakata-context-rtl li > a .vakata-contextmenu-sep { + margin: 0 0 0 0.5em; + border-left-color: white; + background: #e2e3e3; +} +#jstree-marker { + position: absolute; + top: 0; + left: 0; + margin: -5px 0 0 0; + padding: 0; + border-right: 0; + border-top: 5px solid transparent; + border-bottom: 5px solid transparent; + border-left: 5px solid; + width: 0; + height: 0; + font-size: 0; + line-height: 0; +} +#jstree-dnd { + line-height: 16px; + margin: 0; + padding: 4px; +} +#jstree-dnd .jstree-icon, +#jstree-dnd .jstree-copy { + display: inline-block; + text-decoration: none; + margin: 0 2px 0 0; + padding: 0; + width: 16px; + height: 16px; +} +#jstree-dnd .jstree-ok { + background: green; +} +#jstree-dnd .jstree-er { + background: red; +} +#jstree-dnd .jstree-copy { + margin: 0 2px 0 2px; +} +.jstree-default .jstree-node, +.jstree-default .jstree-icon { + background-repeat: no-repeat; + background-color: transparent; +} +.jstree-default .jstree-anchor, +.jstree-default .jstree-animated, +.jstree-default .jstree-wholerow { + transition: background-color 0.15s, box-shadow 0.15s; +} +.jstree-default .jstree-hovered { + background: #e7f4f9; + border-radius: 2px; + box-shadow: inset 0 0 1px #cccccc; +} +.jstree-default .jstree-context { + background: #e7f4f9; + border-radius: 2px; + box-shadow: inset 0 0 1px #cccccc; +} +.jstree-default .jstree-clicked { + background: #beebff; + border-radius: 2px; + box-shadow: inset 0 0 1px #999999; +} +.jstree-default .jstree-no-icons .jstree-anchor > .jstree-themeicon { + display: none; +} +.jstree-default .jstree-disabled { + background: transparent; + color: #666666; +} +.jstree-default .jstree-disabled.jstree-hovered { + background: transparent; + box-shadow: none; +} +.jstree-default .jstree-disabled.jstree-clicked { + background: #efefef; +} +.jstree-default .jstree-disabled > .jstree-icon { + opacity: 0.8; + filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'jstree-grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#jstree-grayscale"); + /* Firefox 10+ */ + filter: gray; + /* IE6-9 */ + -webkit-filter: grayscale(100%); + /* Chrome 19+ & Safari 6+ */ +} +.jstree-default .jstree-search { + font-style: italic; + color: #8b0000; + font-weight: bold; +} +.jstree-default .jstree-no-checkboxes .jstree-checkbox { + display: none !important; +} +.jstree-default.jstree-checkbox-no-clicked .jstree-clicked { + background: transparent; + box-shadow: none; +} +.jstree-default.jstree-checkbox-no-clicked .jstree-clicked.jstree-hovered { + background: #e7f4f9; +} +.jstree-default.jstree-checkbox-no-clicked > .jstree-wholerow-ul .jstree-wholerow-clicked { + background: transparent; +} +.jstree-default.jstree-checkbox-no-clicked > .jstree-wholerow-ul .jstree-wholerow-clicked.jstree-wholerow-hovered { + background: #e7f4f9; +} +.jstree-default > .jstree-striped { + min-width: 100%; + display: inline-block; + background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAMAAAB/qqA+AAAABlBMVEUAAAAAAAClZ7nPAAAAAnRSTlMNAMM9s3UAAAAXSURBVHjajcEBAQAAAIKg/H/aCQZ70AUBjAATb6YPDgAAAABJRU5ErkJggg==") left top repeat; +} +.jstree-default > .jstree-wholerow-ul .jstree-hovered, +.jstree-default > .jstree-wholerow-ul .jstree-clicked { + background: transparent; + box-shadow: none; + border-radius: 0; +} +.jstree-default .jstree-wholerow { + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} +.jstree-default .jstree-wholerow-hovered { + background: #e7f4f9; +} +.jstree-default .jstree-wholerow-clicked { + background: #beebff; + background: -webkit-linear-gradient(top, #beebff 0%, #a8e4ff 100%); + background: linear-gradient(to bottom, #beebff 0%, #a8e4ff 100%); +} +.jstree-default .jstree-node { + min-height: 24px; + line-height: 24px; + margin-left: 24px; + min-width: 24px; +} +.jstree-default .jstree-anchor { + line-height: 24px; + height: 24px; +} +.jstree-default .jstree-icon { + width: 24px; + height: 24px; + line-height: 24px; +} +.jstree-default .jstree-icon:empty { + width: 24px; + height: 24px; + line-height: 24px; +} +.jstree-default.jstree-rtl .jstree-node { + margin-right: 24px; +} +.jstree-default .jstree-wholerow { + height: 24px; +} +.jstree-default .jstree-node, +.jstree-default .jstree-icon { + background-image: url("32px.png"); +} +.jstree-default .jstree-node { + background-position: -292px -4px; + background-repeat: repeat-y; +} +.jstree-default .jstree-last { + background: transparent; +} +.jstree-default .jstree-open > .jstree-ocl { + background-position: -132px -4px; +} +.jstree-default .jstree-closed > .jstree-ocl { + background-position: -100px -4px; +} +.jstree-default .jstree-leaf > .jstree-ocl { + background-position: -68px -4px; +} +.jstree-default .jstree-themeicon { + background-position: -260px -4px; +} +.jstree-default > .jstree-no-dots .jstree-node, +.jstree-default > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -36px -4px; +} +.jstree-default > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: -4px -4px; +} +.jstree-default .jstree-disabled { + background: transparent; +} +.jstree-default .jstree-disabled.jstree-hovered { + background: transparent; +} +.jstree-default .jstree-disabled.jstree-clicked { + background: #efefef; +} +.jstree-default .jstree-checkbox { + background-position: -164px -4px; +} +.jstree-default .jstree-checkbox:hover { + background-position: -164px -36px; +} +.jstree-default.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, +.jstree-default .jstree-checked > .jstree-checkbox { + background-position: -228px -4px; +} +.jstree-default.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, +.jstree-default .jstree-checked > .jstree-checkbox:hover { + background-position: -228px -36px; +} +.jstree-default .jstree-anchor > .jstree-undetermined { + background-position: -196px -4px; +} +.jstree-default .jstree-anchor > .jstree-undetermined:hover { + background-position: -196px -36px; +} +.jstree-default .jstree-checkbox-disabled { + opacity: 0.8; + filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'jstree-grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#jstree-grayscale"); + /* Firefox 10+ */ + filter: gray; + /* IE6-9 */ + -webkit-filter: grayscale(100%); + /* Chrome 19+ & Safari 6+ */ +} +.jstree-default > .jstree-striped { + background-size: auto 48px; +} +.jstree-default.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); + background-position: 100% 1px; + background-repeat: repeat-y; +} +.jstree-default.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default.jstree-rtl .jstree-open > .jstree-ocl { + background-position: -132px -36px; +} +.jstree-default.jstree-rtl .jstree-closed > .jstree-ocl { + background-position: -100px -36px; +} +.jstree-default.jstree-rtl .jstree-leaf > .jstree-ocl { + background-position: -68px -36px; +} +.jstree-default.jstree-rtl > .jstree-no-dots .jstree-node, +.jstree-default.jstree-rtl > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default.jstree-rtl > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -36px -36px; +} +.jstree-default.jstree-rtl > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: -4px -36px; +} +.jstree-default .jstree-themeicon-custom { + background-color: transparent; + background-image: none; + background-position: 0 0; +} +.jstree-default > .jstree-container-ul .jstree-loading > .jstree-ocl { + background: url("throbber.gif") center center no-repeat; +} +.jstree-default .jstree-file { + background: url("32px.png") -100px -68px no-repeat; +} +.jstree-default .jstree-folder { + background: url("32px.png") -260px -4px no-repeat; +} +.jstree-default > .jstree-container-ul > .jstree-node { + margin-left: 0; + margin-right: 0; +} +#jstree-dnd.jstree-default { + line-height: 24px; + padding: 0 4px; +} +#jstree-dnd.jstree-default .jstree-ok, +#jstree-dnd.jstree-default .jstree-er { + background-image: url("32px.png"); + background-repeat: no-repeat; + background-color: transparent; +} +#jstree-dnd.jstree-default i { + background: transparent; + width: 24px; + height: 24px; + line-height: 24px; +} +#jstree-dnd.jstree-default .jstree-ok { + background-position: -4px -68px; +} +#jstree-dnd.jstree-default .jstree-er { + background-position: -36px -68px; +} +.jstree-default .jstree-ellipsis { + overflow: hidden; +} +.jstree-default .jstree-ellipsis .jstree-anchor { + width: calc(100% - 29px); + text-overflow: ellipsis; + overflow: hidden; +} +.jstree-default .jstree-ellipsis.jstree-no-icons .jstree-anchor { + width: calc(100% - 5px); +} +.jstree-default.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); +} +.jstree-default.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-small .jstree-node { + min-height: 18px; + line-height: 18px; + margin-left: 18px; + min-width: 18px; +} +.jstree-default-small .jstree-anchor { + line-height: 18px; + height: 18px; +} +.jstree-default-small .jstree-icon { + width: 18px; + height: 18px; + line-height: 18px; +} +.jstree-default-small .jstree-icon:empty { + width: 18px; + height: 18px; + line-height: 18px; +} +.jstree-default-small.jstree-rtl .jstree-node { + margin-right: 18px; +} +.jstree-default-small .jstree-wholerow { + height: 18px; +} +.jstree-default-small .jstree-node, +.jstree-default-small .jstree-icon { + background-image: url("32px.png"); +} +.jstree-default-small .jstree-node { + background-position: -295px -7px; + background-repeat: repeat-y; +} +.jstree-default-small .jstree-last { + background: transparent; +} +.jstree-default-small .jstree-open > .jstree-ocl { + background-position: -135px -7px; +} +.jstree-default-small .jstree-closed > .jstree-ocl { + background-position: -103px -7px; +} +.jstree-default-small .jstree-leaf > .jstree-ocl { + background-position: -71px -7px; +} +.jstree-default-small .jstree-themeicon { + background-position: -263px -7px; +} +.jstree-default-small > .jstree-no-dots .jstree-node, +.jstree-default-small > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-small > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -39px -7px; +} +.jstree-default-small > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: -7px -7px; +} +.jstree-default-small .jstree-disabled { + background: transparent; +} +.jstree-default-small .jstree-disabled.jstree-hovered { + background: transparent; +} +.jstree-default-small .jstree-disabled.jstree-clicked { + background: #efefef; +} +.jstree-default-small .jstree-checkbox { + background-position: -167px -7px; +} +.jstree-default-small .jstree-checkbox:hover { + background-position: -167px -39px; +} +.jstree-default-small.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, +.jstree-default-small .jstree-checked > .jstree-checkbox { + background-position: -231px -7px; +} +.jstree-default-small.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, +.jstree-default-small .jstree-checked > .jstree-checkbox:hover { + background-position: -231px -39px; +} +.jstree-default-small .jstree-anchor > .jstree-undetermined { + background-position: -199px -7px; +} +.jstree-default-small .jstree-anchor > .jstree-undetermined:hover { + background-position: -199px -39px; +} +.jstree-default-small .jstree-checkbox-disabled { + opacity: 0.8; + filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'jstree-grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#jstree-grayscale"); + /* Firefox 10+ */ + filter: gray; + /* IE6-9 */ + -webkit-filter: grayscale(100%); + /* Chrome 19+ & Safari 6+ */ +} +.jstree-default-small > .jstree-striped { + background-size: auto 36px; +} +.jstree-default-small.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); + background-position: 100% 1px; + background-repeat: repeat-y; +} +.jstree-default-small.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-small.jstree-rtl .jstree-open > .jstree-ocl { + background-position: -135px -39px; +} +.jstree-default-small.jstree-rtl .jstree-closed > .jstree-ocl { + background-position: -103px -39px; +} +.jstree-default-small.jstree-rtl .jstree-leaf > .jstree-ocl { + background-position: -71px -39px; +} +.jstree-default-small.jstree-rtl > .jstree-no-dots .jstree-node, +.jstree-default-small.jstree-rtl > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-small.jstree-rtl > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -39px -39px; +} +.jstree-default-small.jstree-rtl > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: -7px -39px; +} +.jstree-default-small .jstree-themeicon-custom { + background-color: transparent; + background-image: none; + background-position: 0 0; +} +.jstree-default-small > .jstree-container-ul .jstree-loading > .jstree-ocl { + background: url("throbber.gif") center center no-repeat; +} +.jstree-default-small .jstree-file { + background: url("32px.png") -103px -71px no-repeat; +} +.jstree-default-small .jstree-folder { + background: url("32px.png") -263px -7px no-repeat; +} +.jstree-default-small > .jstree-container-ul > .jstree-node { + margin-left: 0; + margin-right: 0; +} +#jstree-dnd.jstree-default-small { + line-height: 18px; + padding: 0 4px; +} +#jstree-dnd.jstree-default-small .jstree-ok, +#jstree-dnd.jstree-default-small .jstree-er { + background-image: url("32px.png"); + background-repeat: no-repeat; + background-color: transparent; +} +#jstree-dnd.jstree-default-small i { + background: transparent; + width: 18px; + height: 18px; + line-height: 18px; +} +#jstree-dnd.jstree-default-small .jstree-ok { + background-position: -7px -71px; +} +#jstree-dnd.jstree-default-small .jstree-er { + background-position: -39px -71px; +} +.jstree-default-small .jstree-ellipsis { + overflow: hidden; +} +.jstree-default-small .jstree-ellipsis .jstree-anchor { + width: calc(100% - 23px); + text-overflow: ellipsis; + overflow: hidden; +} +.jstree-default-small .jstree-ellipsis.jstree-no-icons .jstree-anchor { + width: calc(100% - 5px); +} +.jstree-default-small.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg=="); +} +.jstree-default-small.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-large .jstree-node { + min-height: 32px; + line-height: 32px; + margin-left: 32px; + min-width: 32px; +} +.jstree-default-large .jstree-anchor { + line-height: 32px; + height: 32px; +} +.jstree-default-large .jstree-icon { + width: 32px; + height: 32px; + line-height: 32px; +} +.jstree-default-large .jstree-icon:empty { + width: 32px; + height: 32px; + line-height: 32px; +} +.jstree-default-large.jstree-rtl .jstree-node { + margin-right: 32px; +} +.jstree-default-large .jstree-wholerow { + height: 32px; +} +.jstree-default-large .jstree-node, +.jstree-default-large .jstree-icon { + background-image: url("32px.png"); +} +.jstree-default-large .jstree-node { + background-position: -288px 0px; + background-repeat: repeat-y; +} +.jstree-default-large .jstree-last { + background: transparent; +} +.jstree-default-large .jstree-open > .jstree-ocl { + background-position: -128px 0px; +} +.jstree-default-large .jstree-closed > .jstree-ocl { + background-position: -96px 0px; +} +.jstree-default-large .jstree-leaf > .jstree-ocl { + background-position: -64px 0px; +} +.jstree-default-large .jstree-themeicon { + background-position: -256px 0px; +} +.jstree-default-large > .jstree-no-dots .jstree-node, +.jstree-default-large > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-large > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -32px 0px; +} +.jstree-default-large > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: 0px 0px; +} +.jstree-default-large .jstree-disabled { + background: transparent; +} +.jstree-default-large .jstree-disabled.jstree-hovered { + background: transparent; +} +.jstree-default-large .jstree-disabled.jstree-clicked { + background: #efefef; +} +.jstree-default-large .jstree-checkbox { + background-position: -160px 0px; +} +.jstree-default-large .jstree-checkbox:hover { + background-position: -160px -32px; +} +.jstree-default-large.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, +.jstree-default-large .jstree-checked > .jstree-checkbox { + background-position: -224px 0px; +} +.jstree-default-large.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, +.jstree-default-large .jstree-checked > .jstree-checkbox:hover { + background-position: -224px -32px; +} +.jstree-default-large .jstree-anchor > .jstree-undetermined { + background-position: -192px 0px; +} +.jstree-default-large .jstree-anchor > .jstree-undetermined:hover { + background-position: -192px -32px; +} +.jstree-default-large .jstree-checkbox-disabled { + opacity: 0.8; + filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'jstree-grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#jstree-grayscale"); + /* Firefox 10+ */ + filter: gray; + /* IE6-9 */ + -webkit-filter: grayscale(100%); + /* Chrome 19+ & Safari 6+ */ +} +.jstree-default-large > .jstree-striped { + background-size: auto 64px; +} +.jstree-default-large.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); + background-position: 100% 1px; + background-repeat: repeat-y; +} +.jstree-default-large.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-large.jstree-rtl .jstree-open > .jstree-ocl { + background-position: -128px -32px; +} +.jstree-default-large.jstree-rtl .jstree-closed > .jstree-ocl { + background-position: -96px -32px; +} +.jstree-default-large.jstree-rtl .jstree-leaf > .jstree-ocl { + background-position: -64px -32px; +} +.jstree-default-large.jstree-rtl > .jstree-no-dots .jstree-node, +.jstree-default-large.jstree-rtl > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-large.jstree-rtl > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -32px -32px; +} +.jstree-default-large.jstree-rtl > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: 0px -32px; +} +.jstree-default-large .jstree-themeicon-custom { + background-color: transparent; + background-image: none; + background-position: 0 0; +} +.jstree-default-large > .jstree-container-ul .jstree-loading > .jstree-ocl { + background: url("throbber.gif") center center no-repeat; +} +.jstree-default-large .jstree-file { + background: url("32px.png") -96px -64px no-repeat; +} +.jstree-default-large .jstree-folder { + background: url("32px.png") -256px 0px no-repeat; +} +.jstree-default-large > .jstree-container-ul > .jstree-node { + margin-left: 0; + margin-right: 0; +} +#jstree-dnd.jstree-default-large { + line-height: 32px; + padding: 0 4px; +} +#jstree-dnd.jstree-default-large .jstree-ok, +#jstree-dnd.jstree-default-large .jstree-er { + background-image: url("32px.png"); + background-repeat: no-repeat; + background-color: transparent; +} +#jstree-dnd.jstree-default-large i { + background: transparent; + width: 32px; + height: 32px; + line-height: 32px; +} +#jstree-dnd.jstree-default-large .jstree-ok { + background-position: 0px -64px; +} +#jstree-dnd.jstree-default-large .jstree-er { + background-position: -32px -64px; +} +.jstree-default-large .jstree-ellipsis { + overflow: hidden; +} +.jstree-default-large .jstree-ellipsis .jstree-anchor { + width: calc(100% - 37px); + text-overflow: ellipsis; + overflow: hidden; +} +.jstree-default-large .jstree-ellipsis.jstree-no-icons .jstree-anchor { + width: calc(100% - 5px); +} +.jstree-default-large.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg=="); +} +.jstree-default-large.jstree-rtl .jstree-last { + background: transparent; +} +@media (max-width: 768px) { + #jstree-dnd.jstree-dnd-responsive { + line-height: 40px; + font-weight: bold; + font-size: 1.1em; + text-shadow: 1px 1px white; + } + #jstree-dnd.jstree-dnd-responsive > i { + background: transparent; + width: 40px; + height: 40px; + } + #jstree-dnd.jstree-dnd-responsive > .jstree-ok { + background-image: url("40px.png"); + background-position: 0 -200px; + background-size: 120px 240px; + } + #jstree-dnd.jstree-dnd-responsive > .jstree-er { + background-image: url("40px.png"); + background-position: -40px -200px; + background-size: 120px 240px; + } + #jstree-marker.jstree-dnd-responsive { + border-left-width: 10px; + border-top-width: 10px; + border-bottom-width: 10px; + margin-top: -10px; + } +} +@media (max-width: 768px) { + .jstree-default-responsive { + /* + .jstree-open > .jstree-ocl, + .jstree-closed > .jstree-ocl { border-radius:20px; background-color:white; } + */ + } + .jstree-default-responsive .jstree-icon { + background-image: url("40px.png"); + } + .jstree-default-responsive .jstree-node, + .jstree-default-responsive .jstree-leaf > .jstree-ocl { + background: transparent; + } + .jstree-default-responsive .jstree-node { + min-height: 40px; + line-height: 40px; + margin-left: 40px; + min-width: 40px; + white-space: nowrap; + } + .jstree-default-responsive .jstree-anchor { + line-height: 40px; + height: 40px; + } + .jstree-default-responsive .jstree-icon, + .jstree-default-responsive .jstree-icon:empty { + width: 40px; + height: 40px; + line-height: 40px; + } + .jstree-default-responsive > .jstree-container-ul > .jstree-node { + margin-left: 0; + } + .jstree-default-responsive.jstree-rtl .jstree-node { + margin-left: 0; + margin-right: 40px; + background: transparent; + } + .jstree-default-responsive.jstree-rtl .jstree-container-ul > .jstree-node { + margin-right: 0; + } + .jstree-default-responsive .jstree-ocl, + .jstree-default-responsive .jstree-themeicon, + .jstree-default-responsive .jstree-checkbox { + background-size: 120px 240px; + } + .jstree-default-responsive .jstree-leaf > .jstree-ocl, + .jstree-default-responsive.jstree-rtl .jstree-leaf > .jstree-ocl { + background: transparent; + } + .jstree-default-responsive .jstree-open > .jstree-ocl { + background-position: 0 0px !important; + } + .jstree-default-responsive .jstree-closed > .jstree-ocl { + background-position: 0 -40px !important; + } + .jstree-default-responsive.jstree-rtl .jstree-closed > .jstree-ocl { + background-position: -40px 0px !important; + } + .jstree-default-responsive .jstree-themeicon { + background-position: -40px -40px; + } + .jstree-default-responsive .jstree-checkbox, + .jstree-default-responsive .jstree-checkbox:hover { + background-position: -40px -80px; + } + .jstree-default-responsive.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, + .jstree-default-responsive.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, + .jstree-default-responsive .jstree-checked > .jstree-checkbox, + .jstree-default-responsive .jstree-checked > .jstree-checkbox:hover { + background-position: 0 -80px; + } + .jstree-default-responsive .jstree-anchor > .jstree-undetermined, + .jstree-default-responsive .jstree-anchor > .jstree-undetermined:hover { + background-position: 0 -120px; + } + .jstree-default-responsive .jstree-anchor { + font-weight: bold; + font-size: 1.1em; + text-shadow: 1px 1px white; + } + .jstree-default-responsive > .jstree-striped { + background: transparent; + } + .jstree-default-responsive .jstree-wholerow { + border-top: 1px solid rgba(255, 255, 255, 0.7); + border-bottom: 1px solid rgba(64, 64, 64, 0.2); + background: #ebebeb; + height: 40px; + } + .jstree-default-responsive .jstree-wholerow-hovered { + background: #e7f4f9; + } + .jstree-default-responsive .jstree-wholerow-clicked { + background: #beebff; + } + .jstree-default-responsive .jstree-children .jstree-last > .jstree-wholerow { + box-shadow: inset 0 -6px 3px -5px #666666; + } + .jstree-default-responsive .jstree-children .jstree-open > .jstree-wholerow { + box-shadow: inset 0 6px 3px -5px #666666; + border-top: 0; + } + .jstree-default-responsive .jstree-children .jstree-open + .jstree-open { + box-shadow: none; + } + .jstree-default-responsive .jstree-node, + .jstree-default-responsive .jstree-icon, + .jstree-default-responsive .jstree-node > .jstree-ocl, + .jstree-default-responsive .jstree-themeicon, + .jstree-default-responsive .jstree-checkbox { + background-image: url("40px.png"); + background-size: 120px 240px; + } + .jstree-default-responsive .jstree-node { + background-position: -80px 0; + background-repeat: repeat-y; + } + .jstree-default-responsive .jstree-last { + background: transparent; + } + .jstree-default-responsive .jstree-leaf > .jstree-ocl { + background-position: -40px -120px; + } + .jstree-default-responsive .jstree-last > .jstree-ocl { + background-position: -40px -160px; + } + .jstree-default-responsive .jstree-themeicon-custom { + background-color: transparent; + background-image: none; + background-position: 0 0; + } + .jstree-default-responsive .jstree-file { + background: url("40px.png") 0 -160px no-repeat; + background-size: 120px 240px; + } + .jstree-default-responsive .jstree-folder { + background: url("40px.png") -40px -40px no-repeat; + background-size: 120px 240px; + } + .jstree-default-responsive > .jstree-container-ul > .jstree-node { + margin-left: 0; + margin-right: 0; + } +} diff --git a/civicrm/bower_components/jstree/dist/themes/default/style.min.css b/civicrm/bower_components/jstree/dist/themes/default/style.min.css new file mode 100644 index 0000000000..a76f15c094 --- /dev/null +++ b/civicrm/bower_components/jstree/dist/themes/default/style.min.css @@ -0,0 +1 @@ +.jstree-node,.jstree-children,.jstree-container-ul{display:block;margin:0;padding:0;list-style-type:none;list-style-image:none}.jstree-node{white-space:nowrap}.jstree-anchor{display:inline-block;color:#000;white-space:nowrap;padding:0 4px 0 1px;margin:0;vertical-align:top}.jstree-anchor:focus{outline:0}.jstree-anchor,.jstree-anchor:link,.jstree-anchor:visited,.jstree-anchor:hover,.jstree-anchor:active{text-decoration:none;color:inherit}.jstree-icon{display:inline-block;text-decoration:none;margin:0;padding:0;vertical-align:top;text-align:center}.jstree-icon:empty{display:inline-block;text-decoration:none;margin:0;padding:0;vertical-align:top;text-align:center}.jstree-ocl{cursor:pointer}.jstree-leaf>.jstree-ocl{cursor:default}.jstree .jstree-open>.jstree-children{display:block}.jstree .jstree-closed>.jstree-children,.jstree .jstree-leaf>.jstree-children{display:none}.jstree-anchor>.jstree-themeicon{margin-right:2px}.jstree-no-icons .jstree-themeicon,.jstree-anchor>.jstree-themeicon-hidden{display:none}.jstree-hidden,.jstree-node.jstree-hidden{display:none}.jstree-rtl .jstree-anchor{padding:0 1px 0 4px}.jstree-rtl .jstree-anchor>.jstree-themeicon{margin-left:2px;margin-right:0}.jstree-rtl .jstree-node{margin-left:0}.jstree-rtl .jstree-container-ul>.jstree-node{margin-right:0}.jstree-wholerow-ul{position:relative;display:inline-block;min-width:100%}.jstree-wholerow-ul .jstree-leaf>.jstree-ocl{cursor:pointer}.jstree-wholerow-ul .jstree-anchor,.jstree-wholerow-ul .jstree-icon{position:relative}.jstree-wholerow-ul .jstree-wholerow{width:100%;cursor:pointer;position:absolute;left:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.vakata-context{display:none}.vakata-context,.vakata-context ul{margin:0;padding:2px;position:absolute;background:#f5f5f5;border:1px solid #979797;box-shadow:2px 2px 2px #999}.vakata-context ul{list-style:none;left:100%;margin-top:-2.7em;margin-left:-4px}.vakata-context .vakata-context-right ul{left:auto;right:100%;margin-left:auto;margin-right:-4px}.vakata-context li{list-style:none}.vakata-context li>a{display:block;padding:0 2em;text-decoration:none;width:auto;color:#000;white-space:nowrap;line-height:2.4em;text-shadow:1px 1px 0 #fff;border-radius:1px}.vakata-context li>a:hover{position:relative;background-color:#e8eff7;box-shadow:0 0 2px #0a6aa1}.vakata-context li>a.vakata-context-parent{background-image:url(data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAIORI4JlrqN1oMSnmmZDQUAOw==);background-position:right center;background-repeat:no-repeat}.vakata-context li>a:focus{outline:0}.vakata-context .vakata-context-hover>a{position:relative;background-color:#e8eff7;box-shadow:0 0 2px #0a6aa1}.vakata-context .vakata-context-separator>a,.vakata-context .vakata-context-separator>a:hover{background:#fff;border:0;border-top:1px solid #e2e3e3;height:1px;min-height:1px;max-height:1px;padding:0;margin:0 0 0 2.4em;border-left:1px solid #e0e0e0;text-shadow:0 0 0 transparent;box-shadow:0 0 0 transparent;border-radius:0}.vakata-context .vakata-contextmenu-disabled a,.vakata-context .vakata-contextmenu-disabled a:hover{color:silver;background-color:transparent;border:0;box-shadow:0 0 0}.vakata-context li>a>i{text-decoration:none;display:inline-block;width:2.4em;height:2.4em;background:0 0;margin:0 0 0 -2em;vertical-align:top;text-align:center;line-height:2.4em}.vakata-context li>a>i:empty{width:2.4em;line-height:2.4em}.vakata-context li>a .vakata-contextmenu-sep{display:inline-block;width:1px;height:2.4em;background:#fff;margin:0 .5em 0 0;border-left:1px solid #e2e3e3}.vakata-context .vakata-contextmenu-shortcut{font-size:.8em;color:silver;opacity:.5;display:none}.vakata-context-rtl ul{left:auto;right:100%;margin-left:auto;margin-right:-4px}.vakata-context-rtl li>a.vakata-context-parent{background-image:url(data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAINjI+AC7rWHIsPtmoxLAA7);background-position:left center;background-repeat:no-repeat}.vakata-context-rtl .vakata-context-separator>a{margin:0 2.4em 0 0;border-left:0;border-right:1px solid #e2e3e3}.vakata-context-rtl .vakata-context-left ul{right:auto;left:100%;margin-left:-4px;margin-right:auto}.vakata-context-rtl li>a>i{margin:0 -2em 0 0}.vakata-context-rtl li>a .vakata-contextmenu-sep{margin:0 0 0 .5em;border-left-color:#fff;background:#e2e3e3}#jstree-marker{position:absolute;top:0;left:0;margin:-5px 0 0 0;padding:0;border-right:0;border-top:5px solid transparent;border-bottom:5px solid transparent;border-left:5px solid;width:0;height:0;font-size:0;line-height:0}#jstree-dnd{line-height:16px;margin:0;padding:4px}#jstree-dnd .jstree-icon,#jstree-dnd .jstree-copy{display:inline-block;text-decoration:none;margin:0 2px 0 0;padding:0;width:16px;height:16px}#jstree-dnd .jstree-ok{background:green}#jstree-dnd .jstree-er{background:red}#jstree-dnd .jstree-copy{margin:0 2px}.jstree-default .jstree-node,.jstree-default .jstree-icon{background-repeat:no-repeat;background-color:transparent}.jstree-default .jstree-anchor,.jstree-default .jstree-animated,.jstree-default .jstree-wholerow{transition:background-color .15s,box-shadow .15s}.jstree-default .jstree-hovered{background:#e7f4f9;border-radius:2px;box-shadow:inset 0 0 1px #ccc}.jstree-default .jstree-context{background:#e7f4f9;border-radius:2px;box-shadow:inset 0 0 1px #ccc}.jstree-default .jstree-clicked{background:#beebff;border-radius:2px;box-shadow:inset 0 0 1px #999}.jstree-default .jstree-no-icons .jstree-anchor>.jstree-themeicon{display:none}.jstree-default .jstree-disabled{background:0 0;color:#666}.jstree-default .jstree-disabled.jstree-hovered{background:0 0;box-shadow:none}.jstree-default .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default .jstree-disabled>.jstree-icon{opacity:.8;filter:url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'jstree-grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default .jstree-search{font-style:italic;color:#8b0000;font-weight:700}.jstree-default .jstree-no-checkboxes .jstree-checkbox{display:none!important}.jstree-default.jstree-checkbox-no-clicked .jstree-clicked{background:0 0;box-shadow:none}.jstree-default.jstree-checkbox-no-clicked .jstree-clicked.jstree-hovered{background:#e7f4f9}.jstree-default.jstree-checkbox-no-clicked>.jstree-wholerow-ul .jstree-wholerow-clicked{background:0 0}.jstree-default.jstree-checkbox-no-clicked>.jstree-wholerow-ul .jstree-wholerow-clicked.jstree-wholerow-hovered{background:#e7f4f9}.jstree-default>.jstree-striped{min-width:100%;display:inline-block;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAMAAAB/qqA+AAAABlBMVEUAAAAAAAClZ7nPAAAAAnRSTlMNAMM9s3UAAAAXSURBVHjajcEBAQAAAIKg/H/aCQZ70AUBjAATb6YPDgAAAABJRU5ErkJggg==) left top repeat}.jstree-default>.jstree-wholerow-ul .jstree-hovered,.jstree-default>.jstree-wholerow-ul .jstree-clicked{background:0 0;box-shadow:none;border-radius:0}.jstree-default .jstree-wholerow{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.jstree-default .jstree-wholerow-hovered{background:#e7f4f9}.jstree-default .jstree-wholerow-clicked{background:#beebff;background:-webkit-linear-gradient(top,#beebff 0,#a8e4ff 100%);background:linear-gradient(to bottom,#beebff 0,#a8e4ff 100%)}.jstree-default .jstree-node{min-height:24px;line-height:24px;margin-left:24px;min-width:24px}.jstree-default .jstree-anchor{line-height:24px;height:24px}.jstree-default .jstree-icon{width:24px;height:24px;line-height:24px}.jstree-default .jstree-icon:empty{width:24px;height:24px;line-height:24px}.jstree-default.jstree-rtl .jstree-node{margin-right:24px}.jstree-default .jstree-wholerow{height:24px}.jstree-default .jstree-node,.jstree-default .jstree-icon{background-image:url(32px.png)}.jstree-default .jstree-node{background-position:-292px -4px;background-repeat:repeat-y}.jstree-default .jstree-last{background:0 0}.jstree-default .jstree-open>.jstree-ocl{background-position:-132px -4px}.jstree-default .jstree-closed>.jstree-ocl{background-position:-100px -4px}.jstree-default .jstree-leaf>.jstree-ocl{background-position:-68px -4px}.jstree-default .jstree-themeicon{background-position:-260px -4px}.jstree-default>.jstree-no-dots .jstree-node,.jstree-default>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:0 0}.jstree-default>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-36px -4px}.jstree-default>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-4px -4px}.jstree-default .jstree-disabled{background:0 0}.jstree-default .jstree-disabled.jstree-hovered{background:0 0}.jstree-default .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default .jstree-checkbox{background-position:-164px -4px}.jstree-default .jstree-checkbox:hover{background-position:-164px -36px}.jstree-default.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default .jstree-checked>.jstree-checkbox{background-position:-228px -4px}.jstree-default.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default .jstree-checked>.jstree-checkbox:hover{background-position:-228px -36px}.jstree-default .jstree-anchor>.jstree-undetermined{background-position:-196px -4px}.jstree-default .jstree-anchor>.jstree-undetermined:hover{background-position:-196px -36px}.jstree-default .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'jstree-grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default>.jstree-striped{background-size:auto 48px}.jstree-default.jstree-rtl .jstree-node{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==);background-position:100% 1px;background-repeat:repeat-y}.jstree-default.jstree-rtl .jstree-last{background:0 0}.jstree-default.jstree-rtl .jstree-open>.jstree-ocl{background-position:-132px -36px}.jstree-default.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-100px -36px}.jstree-default.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-68px -36px}.jstree-default.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:0 0}.jstree-default.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-36px -36px}.jstree-default.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-4px -36px}.jstree-default .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url(throbber.gif) center center no-repeat}.jstree-default .jstree-file{background:url(32px.png) -100px -68px no-repeat}.jstree-default .jstree-folder{background:url(32px.png) -260px -4px no-repeat}.jstree-default>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-default{line-height:24px;padding:0 4px}#jstree-dnd.jstree-default .jstree-ok,#jstree-dnd.jstree-default .jstree-er{background-image:url(32px.png);background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default i{background:0 0;width:24px;height:24px;line-height:24px}#jstree-dnd.jstree-default .jstree-ok{background-position:-4px -68px}#jstree-dnd.jstree-default .jstree-er{background-position:-36px -68px}.jstree-default .jstree-ellipsis{overflow:hidden}.jstree-default .jstree-ellipsis .jstree-anchor{width:calc(100% - 29px);text-overflow:ellipsis;overflow:hidden}.jstree-default .jstree-ellipsis.jstree-no-icons .jstree-anchor{width:calc(100% - 5px)}.jstree-default.jstree-rtl .jstree-node{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==)}.jstree-default.jstree-rtl .jstree-last{background:0 0}.jstree-default-small .jstree-node{min-height:18px;line-height:18px;margin-left:18px;min-width:18px}.jstree-default-small .jstree-anchor{line-height:18px;height:18px}.jstree-default-small .jstree-icon{width:18px;height:18px;line-height:18px}.jstree-default-small .jstree-icon:empty{width:18px;height:18px;line-height:18px}.jstree-default-small.jstree-rtl .jstree-node{margin-right:18px}.jstree-default-small .jstree-wholerow{height:18px}.jstree-default-small .jstree-node,.jstree-default-small .jstree-icon{background-image:url(32px.png)}.jstree-default-small .jstree-node{background-position:-295px -7px;background-repeat:repeat-y}.jstree-default-small .jstree-last{background:0 0}.jstree-default-small .jstree-open>.jstree-ocl{background-position:-135px -7px}.jstree-default-small .jstree-closed>.jstree-ocl{background-position:-103px -7px}.jstree-default-small .jstree-leaf>.jstree-ocl{background-position:-71px -7px}.jstree-default-small .jstree-themeicon{background-position:-263px -7px}.jstree-default-small>.jstree-no-dots .jstree-node,.jstree-default-small>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:0 0}.jstree-default-small>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-39px -7px}.jstree-default-small>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-7px -7px}.jstree-default-small .jstree-disabled{background:0 0}.jstree-default-small .jstree-disabled.jstree-hovered{background:0 0}.jstree-default-small .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default-small .jstree-checkbox{background-position:-167px -7px}.jstree-default-small .jstree-checkbox:hover{background-position:-167px -39px}.jstree-default-small.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-small .jstree-checked>.jstree-checkbox{background-position:-231px -7px}.jstree-default-small.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-small .jstree-checked>.jstree-checkbox:hover{background-position:-231px -39px}.jstree-default-small .jstree-anchor>.jstree-undetermined{background-position:-199px -7px}.jstree-default-small .jstree-anchor>.jstree-undetermined:hover{background-position:-199px -39px}.jstree-default-small .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'jstree-grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default-small>.jstree-striped{background-size:auto 36px}.jstree-default-small.jstree-rtl .jstree-node{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==);background-position:100% 1px;background-repeat:repeat-y}.jstree-default-small.jstree-rtl .jstree-last{background:0 0}.jstree-default-small.jstree-rtl .jstree-open>.jstree-ocl{background-position:-135px -39px}.jstree-default-small.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-103px -39px}.jstree-default-small.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-71px -39px}.jstree-default-small.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default-small.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:0 0}.jstree-default-small.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-39px -39px}.jstree-default-small.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-7px -39px}.jstree-default-small .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-small>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url(throbber.gif) center center no-repeat}.jstree-default-small .jstree-file{background:url(32px.png) -103px -71px no-repeat}.jstree-default-small .jstree-folder{background:url(32px.png) -263px -7px no-repeat}.jstree-default-small>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-default-small{line-height:18px;padding:0 4px}#jstree-dnd.jstree-default-small .jstree-ok,#jstree-dnd.jstree-default-small .jstree-er{background-image:url(32px.png);background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default-small i{background:0 0;width:18px;height:18px;line-height:18px}#jstree-dnd.jstree-default-small .jstree-ok{background-position:-7px -71px}#jstree-dnd.jstree-default-small .jstree-er{background-position:-39px -71px}.jstree-default-small .jstree-ellipsis{overflow:hidden}.jstree-default-small .jstree-ellipsis .jstree-anchor{width:calc(100% - 23px);text-overflow:ellipsis;overflow:hidden}.jstree-default-small .jstree-ellipsis.jstree-no-icons .jstree-anchor{width:calc(100% - 5px)}.jstree-default-small.jstree-rtl .jstree-node{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg==)}.jstree-default-small.jstree-rtl .jstree-last{background:0 0}.jstree-default-large .jstree-node{min-height:32px;line-height:32px;margin-left:32px;min-width:32px}.jstree-default-large .jstree-anchor{line-height:32px;height:32px}.jstree-default-large .jstree-icon{width:32px;height:32px;line-height:32px}.jstree-default-large .jstree-icon:empty{width:32px;height:32px;line-height:32px}.jstree-default-large.jstree-rtl .jstree-node{margin-right:32px}.jstree-default-large .jstree-wholerow{height:32px}.jstree-default-large .jstree-node,.jstree-default-large .jstree-icon{background-image:url(32px.png)}.jstree-default-large .jstree-node{background-position:-288px 0;background-repeat:repeat-y}.jstree-default-large .jstree-last{background:0 0}.jstree-default-large .jstree-open>.jstree-ocl{background-position:-128px 0}.jstree-default-large .jstree-closed>.jstree-ocl{background-position:-96px 0}.jstree-default-large .jstree-leaf>.jstree-ocl{background-position:-64px 0}.jstree-default-large .jstree-themeicon{background-position:-256px 0}.jstree-default-large>.jstree-no-dots .jstree-node,.jstree-default-large>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:0 0}.jstree-default-large>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-32px 0}.jstree-default-large>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:0 0}.jstree-default-large .jstree-disabled{background:0 0}.jstree-default-large .jstree-disabled.jstree-hovered{background:0 0}.jstree-default-large .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default-large .jstree-checkbox{background-position:-160px 0}.jstree-default-large .jstree-checkbox:hover{background-position:-160px -32px}.jstree-default-large.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-large .jstree-checked>.jstree-checkbox{background-position:-224px 0}.jstree-default-large.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-large .jstree-checked>.jstree-checkbox:hover{background-position:-224px -32px}.jstree-default-large .jstree-anchor>.jstree-undetermined{background-position:-192px 0}.jstree-default-large .jstree-anchor>.jstree-undetermined:hover{background-position:-192px -32px}.jstree-default-large .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'jstree-grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default-large>.jstree-striped{background-size:auto 64px}.jstree-default-large.jstree-rtl .jstree-node{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==);background-position:100% 1px;background-repeat:repeat-y}.jstree-default-large.jstree-rtl .jstree-last{background:0 0}.jstree-default-large.jstree-rtl .jstree-open>.jstree-ocl{background-position:-128px -32px}.jstree-default-large.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-96px -32px}.jstree-default-large.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-64px -32px}.jstree-default-large.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default-large.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:0 0}.jstree-default-large.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-32px -32px}.jstree-default-large.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:0 -32px}.jstree-default-large .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-large>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url(throbber.gif) center center no-repeat}.jstree-default-large .jstree-file{background:url(32px.png) -96px -64px no-repeat}.jstree-default-large .jstree-folder{background:url(32px.png) -256px 0 no-repeat}.jstree-default-large>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-default-large{line-height:32px;padding:0 4px}#jstree-dnd.jstree-default-large .jstree-ok,#jstree-dnd.jstree-default-large .jstree-er{background-image:url(32px.png);background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default-large i{background:0 0;width:32px;height:32px;line-height:32px}#jstree-dnd.jstree-default-large .jstree-ok{background-position:0 -64px}#jstree-dnd.jstree-default-large .jstree-er{background-position:-32px -64px}.jstree-default-large .jstree-ellipsis{overflow:hidden}.jstree-default-large .jstree-ellipsis .jstree-anchor{width:calc(100% - 37px);text-overflow:ellipsis;overflow:hidden}.jstree-default-large .jstree-ellipsis.jstree-no-icons .jstree-anchor{width:calc(100% - 5px)}.jstree-default-large.jstree-rtl .jstree-node{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg==)}.jstree-default-large.jstree-rtl .jstree-last{background:0 0}@media (max-width:768px){#jstree-dnd.jstree-dnd-responsive{line-height:40px;font-weight:700;font-size:1.1em;text-shadow:1px 1px #fff}#jstree-dnd.jstree-dnd-responsive>i{background:0 0;width:40px;height:40px}#jstree-dnd.jstree-dnd-responsive>.jstree-ok{background-image:url(40px.png);background-position:0 -200px;background-size:120px 240px}#jstree-dnd.jstree-dnd-responsive>.jstree-er{background-image:url(40px.png);background-position:-40px -200px;background-size:120px 240px}#jstree-marker.jstree-dnd-responsive{border-left-width:10px;border-top-width:10px;border-bottom-width:10px;margin-top:-10px}}@media (max-width:768px){.jstree-default-responsive .jstree-icon{background-image:url(40px.png)}.jstree-default-responsive .jstree-node,.jstree-default-responsive .jstree-leaf>.jstree-ocl{background:0 0}.jstree-default-responsive .jstree-node{min-height:40px;line-height:40px;margin-left:40px;min-width:40px;white-space:nowrap}.jstree-default-responsive .jstree-anchor{line-height:40px;height:40px}.jstree-default-responsive .jstree-icon,.jstree-default-responsive .jstree-icon:empty{width:40px;height:40px;line-height:40px}.jstree-default-responsive>.jstree-container-ul>.jstree-node{margin-left:0}.jstree-default-responsive.jstree-rtl .jstree-node{margin-left:0;margin-right:40px;background:0 0}.jstree-default-responsive.jstree-rtl .jstree-container-ul>.jstree-node{margin-right:0}.jstree-default-responsive .jstree-ocl,.jstree-default-responsive .jstree-themeicon,.jstree-default-responsive .jstree-checkbox{background-size:120px 240px}.jstree-default-responsive .jstree-leaf>.jstree-ocl,.jstree-default-responsive.jstree-rtl .jstree-leaf>.jstree-ocl{background:0 0}.jstree-default-responsive .jstree-open>.jstree-ocl{background-position:0 0!important}.jstree-default-responsive .jstree-closed>.jstree-ocl{background-position:0 -40px!important}.jstree-default-responsive.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-40px 0!important}.jstree-default-responsive .jstree-themeicon{background-position:-40px -40px}.jstree-default-responsive .jstree-checkbox,.jstree-default-responsive .jstree-checkbox:hover{background-position:-40px -80px}.jstree-default-responsive.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-responsive.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-responsive .jstree-checked>.jstree-checkbox,.jstree-default-responsive .jstree-checked>.jstree-checkbox:hover{background-position:0 -80px}.jstree-default-responsive .jstree-anchor>.jstree-undetermined,.jstree-default-responsive .jstree-anchor>.jstree-undetermined:hover{background-position:0 -120px}.jstree-default-responsive .jstree-anchor{font-weight:700;font-size:1.1em;text-shadow:1px 1px #fff}.jstree-default-responsive>.jstree-striped{background:0 0}.jstree-default-responsive .jstree-wholerow{border-top:1px solid rgba(255,255,255,.7);border-bottom:1px solid rgba(64,64,64,.2);background:#ebebeb;height:40px}.jstree-default-responsive .jstree-wholerow-hovered{background:#e7f4f9}.jstree-default-responsive .jstree-wholerow-clicked{background:#beebff}.jstree-default-responsive .jstree-children .jstree-last>.jstree-wholerow{box-shadow:inset 0 -6px 3px -5px #666}.jstree-default-responsive .jstree-children .jstree-open>.jstree-wholerow{box-shadow:inset 0 6px 3px -5px #666;border-top:0}.jstree-default-responsive .jstree-children .jstree-open+.jstree-open{box-shadow:none}.jstree-default-responsive .jstree-node,.jstree-default-responsive .jstree-icon,.jstree-default-responsive .jstree-node>.jstree-ocl,.jstree-default-responsive .jstree-themeicon,.jstree-default-responsive .jstree-checkbox{background-image:url(40px.png);background-size:120px 240px}.jstree-default-responsive .jstree-node{background-position:-80px 0;background-repeat:repeat-y}.jstree-default-responsive .jstree-last{background:0 0}.jstree-default-responsive .jstree-leaf>.jstree-ocl{background-position:-40px -120px}.jstree-default-responsive .jstree-last>.jstree-ocl{background-position:-40px -160px}.jstree-default-responsive .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-responsive .jstree-file{background:url(40px.png) 0 -160px no-repeat;background-size:120px 240px}.jstree-default-responsive .jstree-folder{background:url(40px.png) -40px -40px no-repeat;background-size:120px 240px}.jstree-default-responsive>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}} \ No newline at end of file diff --git a/civicrm/bower_components/jstree/dist/themes/default/throbber.gif b/civicrm/bower_components/jstree/dist/themes/default/throbber.gif new file mode 100644 index 0000000000000000000000000000000000000000..1b5b2fde42f8ea14e6981339196a9d62b681d79e GIT binary patch literal 1720 zcmZ|OYfMvT7zgm4p2O+ea@rnBg#)OxTPX)YQxLES+gfgxVz~&+f}$;m6s%Hi3W%nq zP@z^qrV}=TNF%FL8K5q@MN>cp#S0pVI*qHSli{|&j8i`-D~lhy5AU}p`Tz2N-e*-( zqBu&8Q*g>F3T19?Zf0i2Y&JU_j>N>onwlC4g`!j{1p>jzlP51;yvXHpJ32ZL1c{7{ z)MzyPIro%=%#1i`T0+<|5ezw}`5%1a$_msK1)F#~iYhcbb+NiiTcX~ytZ3Wj5(@tv zLT5OqLY&VTiBl*@DK5jOqAQC<<G>V}_H8&J8*d!6F|8^P+>r!@8gG==_FR|TOFO5N ztmi!uPli+Ln$x?H-gK%V=cf&)%tK3Ubl`;)j){YK#AZm_($yDbHN+iIVb4-MA(|Tn z%Y=0Su-m75IE?%N1|!SEl|tuKXsXZNj2Z=vp;+=jlJSZD2EODW0H`s<BGnEWXznAI zRihe|b_nZwTPrk3hRW~AIL)!p_U?GtGW>M#)b0zgDU0)5!G<?Df;@1J<B}}$iz_rX z%&1amW8ARS!n!TmVl%lfFgegAqRfdPJ)MZh0O24h14(h^`bjnUkS0px2vG>rr5zO1 zNgN^!L7)EBFUC+Zhm%Mr7yC91@!CieHdPd#!o7Jn^!!TMrU0vgH)|h-!|2wozJKmj z`G&1Z^{+00Fi|SEx@=o?UTI)xo@>T@7i7MZAqTYCMc0JP{oZJEdWye2L~bM45otrq zk@}$q6%b*2<$<rGgK+flGwX~NJ-1OZC=+b&8OgiN%OxC&;OQ;|WiSgRw=ksb#&<za zK1};>_YGZVC^6PBqU&pG6rtOM!WN;+E;i3EB*=+K0j60WC&J{7x}V=Ak(w<1X>er- zV`_bHI~Y%5hQkS?_Lf?1C-Yh<h7tEWuJ%96W&EPplGML=g?##fc|vxO|L1G5ZD_RM z(Tj4^#p&uVw|Ul8n}qd7PnXeE&S=}3vp0R#fY{ju!$P-)K)_p5HZg;}>;suT<W)-8 z;kx`iyiHuHMJN&z3xBv}KTXF8|KII}R1u3-r}}w9OMpw0QuXdgm}Y&{liY*C{OPgX zUZ?_f_wm`a2&GYCveuUXl#!dgl>(z!ZdS6NOH8>FGetNtnE-ngIxI9OKM9M!nq|ao z@ByV)WU%+EiuxlBZ=#rs_ZnY%+O^bXr2P8_g2l~7Z822<SgQ<oLQ+s#(QNr~78f;+ zhb@i4QQP2wt12&)isqN3uGGU-%TiY}QE%po+(23_*R|unGo5$n(&V^cSh$OL`&qzR zCSM%GI8-@V8IZ68tZ44Z&~bCRp9y&&;D}J)Em6co_+5TFbGrKL@Pc0BLLPSEs}U6r z0O&F3U@#64D^tG})xz%X5DQ)EM@RX_MIa(Q09x<kS~1^-=3K?}&XIHSW9b_m?G{qq z^NwyTC_U5K7F&F1@^XyjKDL~W6rJ%<@idQHty1+jeI#yXT22cHY;Z!~hi6im#(b4T z#9`NY%-Tc)RHOZgOn*3*qXkecL}MB}=}iz|36X4hVMd|v|88a8G4{^p`?}Idl`BOX zuBoz5ykT1C<(d}o<FU?zUN8E|&tvt{yyH5e6A|ni%((5<o22iTb2=}K4G-E7+%(eO z$6ZJ@#~p3e(J>1w?Uyx%!zc@?f!tWxz6{`xAWPUyeq1Vbvuj7m$3Dh(PTY04bw^_A zwRr|LuoC34N#A1;<G*GRP5b`%TSEBr>?zXdaId|wW$kzq2e~Uqdrq=@A0^DlGO4UM zzC<kYY0fsJAB70}P`(4Su69S93@ke%8)DNw&*2qf6+W)d<>O9@&t7@ohLX-t)ftJ| z)q;&?w?;l@^4Pc`;x3vPJ8(itFdKg3;$nap8V7O~;L775>pjUjnIyS=0%4f;&$i;^ q^<`2=x-x(uk2YUU2h;2jemsk<aD(WL8L(lGH>O_4rHker(f<M+QXWPC literal 0 HcmV?d00001 diff --git a/civicrm/bower_components/jstree/src/intro.js b/civicrm/bower_components/jstree/src/intro.js new file mode 100644 index 0000000000..5c95a5cdfb --- /dev/null +++ b/civicrm/bower_components/jstree/src/intro.js @@ -0,0 +1,14 @@ +/*globals jQuery, define, module, exports, require, window, document, postMessage */ +(function (factory) { + "use strict"; + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } + else if(typeof module !== 'undefined' && module.exports) { + module.exports = factory(require('jquery')); + } + else { + factory(jQuery); + } +}(function ($, undefined) { + "use strict"; diff --git a/civicrm/bower_components/jstree/src/jstree.changed.js b/civicrm/bower_components/jstree/src/jstree.changed.js new file mode 100644 index 0000000000..be8cfd7d12 --- /dev/null +++ b/civicrm/bower_components/jstree/src/jstree.changed.js @@ -0,0 +1,69 @@ +/** + * ### Changed plugin + * + * This plugin adds more information to the `changed.jstree` event. The new data is contained in the `changed` event data property, and contains a lists of `selected` and `deselected` nodes. + */ +/*globals jQuery, define, exports, require, document */ +(function (factory) { + "use strict"; + if (typeof define === 'function' && define.amd) { + define('jstree.changed', ['jquery','jstree'], factory); + } + else if(typeof exports === 'object') { + factory(require('jquery'), require('jstree')); + } + else { + factory(jQuery, jQuery.jstree); + } +}(function ($, jstree, undefined) { + "use strict"; + + if($.jstree.plugins.changed) { return; } + + $.jstree.plugins.changed = function (options, parent) { + var last = []; + this.trigger = function (ev, data) { + var i, j; + if(!data) { + data = {}; + } + if(ev.replace('.jstree','') === 'changed') { + data.changed = { selected : [], deselected : [] }; + var tmp = {}; + for(i = 0, j = last.length; i < j; i++) { + tmp[last[i]] = 1; + } + for(i = 0, j = data.selected.length; i < j; i++) { + if(!tmp[data.selected[i]]) { + data.changed.selected.push(data.selected[i]); + } + else { + tmp[data.selected[i]] = 2; + } + } + for(i = 0, j = last.length; i < j; i++) { + if(tmp[last[i]] === 1) { + data.changed.deselected.push(last[i]); + } + } + last = data.selected.slice(); + } + /** + * triggered when selection changes (the "changed" plugin enhances the original event with more data) + * @event + * @name changed.jstree + * @param {Object} node + * @param {Object} action the action that caused the selection to change + * @param {Array} selected the current selection + * @param {Object} changed an object containing two properties `selected` and `deselected` - both arrays of node IDs, which were selected or deselected since the last changed event + * @param {Object} event the event (if any) that triggered this changed event + * @plugin changed + */ + parent.trigger.call(this, ev, data); + }; + this.refresh = function (skip_loading, forget_state) { + last = []; + return parent.refresh.apply(this, arguments); + }; + }; +})); \ No newline at end of file diff --git a/civicrm/bower_components/jstree/src/jstree.checkbox.js b/civicrm/bower_components/jstree/src/jstree.checkbox.js new file mode 100644 index 0000000000..5dd9837d75 --- /dev/null +++ b/civicrm/bower_components/jstree/src/jstree.checkbox.js @@ -0,0 +1,871 @@ +/** + * ### Checkbox plugin + * + * This plugin renders checkbox icons in front of each node, making multiple selection much easier. + * It also supports tri-state behavior, meaning that if a node has a few of its children checked it will be rendered as undetermined, and state will be propagated up. + */ +/*globals jQuery, define, exports, require, document */ +(function (factory) { + "use strict"; + if (typeof define === 'function' && define.amd) { + define('jstree.checkbox', ['jquery','jstree'], factory); + } + else if(typeof exports === 'object') { + factory(require('jquery'), require('jstree')); + } + else { + factory(jQuery, jQuery.jstree); + } +}(function ($, jstree, undefined) { + "use strict"; + + if($.jstree.plugins.checkbox) { return; } + + var _i = document.createElement('I'); + _i.className = 'jstree-icon jstree-checkbox'; + _i.setAttribute('role', 'presentation'); + /** + * stores all defaults for the checkbox plugin + * @name $.jstree.defaults.checkbox + * @plugin checkbox + */ + $.jstree.defaults.checkbox = { + /** + * a boolean indicating if checkboxes should be visible (can be changed at a later time using `show_checkboxes()` and `hide_checkboxes`). Defaults to `true`. + * @name $.jstree.defaults.checkbox.visible + * @plugin checkbox + */ + visible : true, + /** + * a boolean indicating if checkboxes should cascade down and have an undetermined state. Defaults to `true`. + * @name $.jstree.defaults.checkbox.three_state + * @plugin checkbox + */ + three_state : true, + /** + * a boolean indicating if clicking anywhere on the node should act as clicking on the checkbox. Defaults to `true`. + * @name $.jstree.defaults.checkbox.whole_node + * @plugin checkbox + */ + whole_node : true, + /** + * a boolean indicating if the selected style of a node should be kept, or removed. Defaults to `true`. + * @name $.jstree.defaults.checkbox.keep_selected_style + * @plugin checkbox + */ + keep_selected_style : true, + /** + * This setting controls how cascading and undetermined nodes are applied. + * If 'up' is in the string - cascading up is enabled, if 'down' is in the string - cascading down is enabled, if 'undetermined' is in the string - undetermined nodes will be used. + * If `three_state` is set to `true` this setting is automatically set to 'up+down+undetermined'. Defaults to ''. + * @name $.jstree.defaults.checkbox.cascade + * @plugin checkbox + */ + cascade : '', + /** + * This setting controls if checkbox are bound to the general tree selection or to an internal array maintained by the checkbox plugin. Defaults to `true`, only set to `false` if you know exactly what you are doing. + * @name $.jstree.defaults.checkbox.tie_selection + * @plugin checkbox + */ + tie_selection : true + }; + $.jstree.plugins.checkbox = function (options, parent) { + this.bind = function () { + parent.bind.call(this); + this._data.checkbox.uto = false; + this._data.checkbox.selected = []; + if(this.settings.checkbox.three_state) { + this.settings.checkbox.cascade = 'up+down+undetermined'; + } + this.element + .on("init.jstree", $.proxy(function () { + this._data.checkbox.visible = this.settings.checkbox.visible; + if(!this.settings.checkbox.keep_selected_style) { + this.element.addClass('jstree-checkbox-no-clicked'); + } + if(this.settings.checkbox.tie_selection) { + this.element.addClass('jstree-checkbox-selection'); + } + }, this)) + .on("loading.jstree", $.proxy(function () { + this[ this._data.checkbox.visible ? 'show_checkboxes' : 'hide_checkboxes' ](); + }, this)); + if(this.settings.checkbox.cascade.indexOf('undetermined') !== -1) { + this.element + .on('changed.jstree uncheck_node.jstree check_node.jstree uncheck_all.jstree check_all.jstree move_node.jstree copy_node.jstree redraw.jstree open_node.jstree', $.proxy(function () { + // only if undetermined is in setting + if(this._data.checkbox.uto) { clearTimeout(this._data.checkbox.uto); } + this._data.checkbox.uto = setTimeout($.proxy(this._undetermined, this), 50); + }, this)); + } + if(!this.settings.checkbox.tie_selection) { + this.element + .on('model.jstree', $.proxy(function (e, data) { + var m = this._model.data, + p = m[data.parent], + dpc = data.nodes, + i, j; + for(i = 0, j = dpc.length; i < j; i++) { + m[dpc[i]].state.checked = m[dpc[i]].state.checked || (m[dpc[i]].original && m[dpc[i]].original.state && m[dpc[i]].original.state.checked); + if(m[dpc[i]].state.checked) { + this._data.checkbox.selected.push(dpc[i]); + } + } + }, this)); + } + if(this.settings.checkbox.cascade.indexOf('up') !== -1 || this.settings.checkbox.cascade.indexOf('down') !== -1) { + this.element + .on('model.jstree', $.proxy(function (e, data) { + var m = this._model.data, + p = m[data.parent], + dpc = data.nodes, + chd = [], + c, i, j, k, l, tmp, s = this.settings.checkbox.cascade, t = this.settings.checkbox.tie_selection; + + if(s.indexOf('down') !== -1) { + // apply down + if(p.state[ t ? 'selected' : 'checked' ]) { + for(i = 0, j = dpc.length; i < j; i++) { + m[dpc[i]].state[ t ? 'selected' : 'checked' ] = true; + } + this._data[ t ? 'core' : 'checkbox' ].selected = this._data[ t ? 'core' : 'checkbox' ].selected.concat(dpc); + } + else { + for(i = 0, j = dpc.length; i < j; i++) { + if(m[dpc[i]].state[ t ? 'selected' : 'checked' ]) { + for(k = 0, l = m[dpc[i]].children_d.length; k < l; k++) { + m[m[dpc[i]].children_d[k]].state[ t ? 'selected' : 'checked' ] = true; + } + this._data[ t ? 'core' : 'checkbox' ].selected = this._data[ t ? 'core' : 'checkbox' ].selected.concat(m[dpc[i]].children_d); + } + } + } + } + + if(s.indexOf('up') !== -1) { + // apply up + for(i = 0, j = p.children_d.length; i < j; i++) { + if(!m[p.children_d[i]].children.length) { + chd.push(m[p.children_d[i]].parent); + } + } + chd = $.vakata.array_unique(chd); + for(k = 0, l = chd.length; k < l; k++) { + p = m[chd[k]]; + while(p && p.id !== $.jstree.root) { + c = 0; + for(i = 0, j = p.children.length; i < j; i++) { + c += m[p.children[i]].state[ t ? 'selected' : 'checked' ]; + } + if(c === j) { + p.state[ t ? 'selected' : 'checked' ] = true; + this._data[ t ? 'core' : 'checkbox' ].selected.push(p.id); + tmp = this.get_node(p, true); + if(tmp && tmp.length) { + tmp.attr('aria-selected', true).children('.jstree-anchor').addClass( t ? 'jstree-clicked' : 'jstree-checked'); + } + } + else { + break; + } + p = this.get_node(p.parent); + } + } + } + + this._data[ t ? 'core' : 'checkbox' ].selected = $.vakata.array_unique(this._data[ t ? 'core' : 'checkbox' ].selected); + }, this)) + .on(this.settings.checkbox.tie_selection ? 'select_node.jstree' : 'check_node.jstree', $.proxy(function (e, data) { + var obj = data.node, + m = this._model.data, + par = this.get_node(obj.parent), + dom = this.get_node(obj, true), + i, j, c, tmp, s = this.settings.checkbox.cascade, t = this.settings.checkbox.tie_selection, + sel = {}, cur = this._data[ t ? 'core' : 'checkbox' ].selected; + + for (i = 0, j = cur.length; i < j; i++) { + sel[cur[i]] = true; + } + // apply down + if(s.indexOf('down') !== -1) { + //this._data[ t ? 'core' : 'checkbox' ].selected = $.vakata.array_unique(this._data[ t ? 'core' : 'checkbox' ].selected.concat(obj.children_d)); + for(i = 0, j = obj.children_d.length; i < j; i++) { + sel[obj.children_d[i]] = true; + tmp = m[obj.children_d[i]]; + tmp.state[ t ? 'selected' : 'checked' ] = true; + if(tmp && tmp.original && tmp.original.state && tmp.original.state.undetermined) { + tmp.original.state.undetermined = false; + } + } + } + + // apply up + if(s.indexOf('up') !== -1) { + while(par && par.id !== $.jstree.root) { + c = 0; + for(i = 0, j = par.children.length; i < j; i++) { + c += m[par.children[i]].state[ t ? 'selected' : 'checked' ]; + } + if(c === j) { + par.state[ t ? 'selected' : 'checked' ] = true; + sel[par.id] = true; + //this._data[ t ? 'core' : 'checkbox' ].selected.push(par.id); + tmp = this.get_node(par, true); + if(tmp && tmp.length) { + tmp.attr('aria-selected', true).children('.jstree-anchor').addClass(t ? 'jstree-clicked' : 'jstree-checked'); + } + } + else { + break; + } + par = this.get_node(par.parent); + } + } + + cur = []; + for (i in sel) { + if (sel.hasOwnProperty(i)) { + cur.push(i); + } + } + this._data[ t ? 'core' : 'checkbox' ].selected = cur; + + // apply down (process .children separately?) + if(s.indexOf('down') !== -1 && dom.length) { + dom.find('.jstree-anchor').addClass(t ? 'jstree-clicked' : 'jstree-checked').parent().attr('aria-selected', true); + } + }, this)) + .on(this.settings.checkbox.tie_selection ? 'deselect_all.jstree' : 'uncheck_all.jstree', $.proxy(function (e, data) { + var obj = this.get_node($.jstree.root), + m = this._model.data, + i, j, tmp; + for(i = 0, j = obj.children_d.length; i < j; i++) { + tmp = m[obj.children_d[i]]; + if(tmp && tmp.original && tmp.original.state && tmp.original.state.undetermined) { + tmp.original.state.undetermined = false; + } + } + }, this)) + .on(this.settings.checkbox.tie_selection ? 'deselect_node.jstree' : 'uncheck_node.jstree', $.proxy(function (e, data) { + var obj = data.node, + dom = this.get_node(obj, true), + i, j, tmp, s = this.settings.checkbox.cascade, t = this.settings.checkbox.tie_selection, + cur = this._data[ t ? 'core' : 'checkbox' ].selected, sel = {}; + if(obj && obj.original && obj.original.state && obj.original.state.undetermined) { + obj.original.state.undetermined = false; + } + + // apply down + if(s.indexOf('down') !== -1) { + for(i = 0, j = obj.children_d.length; i < j; i++) { + tmp = this._model.data[obj.children_d[i]]; + tmp.state[ t ? 'selected' : 'checked' ] = false; + if(tmp && tmp.original && tmp.original.state && tmp.original.state.undetermined) { + tmp.original.state.undetermined = false; + } + } + } + + // apply up + if(s.indexOf('up') !== -1) { + for(i = 0, j = obj.parents.length; i < j; i++) { + tmp = this._model.data[obj.parents[i]]; + tmp.state[ t ? 'selected' : 'checked' ] = false; + if(tmp && tmp.original && tmp.original.state && tmp.original.state.undetermined) { + tmp.original.state.undetermined = false; + } + tmp = this.get_node(obj.parents[i], true); + if(tmp && tmp.length) { + tmp.attr('aria-selected', false).children('.jstree-anchor').removeClass(t ? 'jstree-clicked' : 'jstree-checked'); + } + } + } + sel = {}; + for(i = 0, j = cur.length; i < j; i++) { + // apply down + apply up + if( + (s.indexOf('down') === -1 || $.inArray(cur[i], obj.children_d) === -1) && + (s.indexOf('up') === -1 || $.inArray(cur[i], obj.parents) === -1) + ) { + sel[cur[i]] = true; + } + } + cur = []; + for (i in sel) { + if (sel.hasOwnProperty(i)) { + cur.push(i); + } + } + this._data[ t ? 'core' : 'checkbox' ].selected = cur; + + // apply down (process .children separately?) + if(s.indexOf('down') !== -1 && dom.length) { + dom.find('.jstree-anchor').removeClass(t ? 'jstree-clicked' : 'jstree-checked').parent().attr('aria-selected', false); + } + }, this)); + } + if(this.settings.checkbox.cascade.indexOf('up') !== -1) { + this.element + .on('delete_node.jstree', $.proxy(function (e, data) { + // apply up (whole handler) + var p = this.get_node(data.parent), + m = this._model.data, + i, j, c, tmp, t = this.settings.checkbox.tie_selection; + while(p && p.id !== $.jstree.root && !p.state[ t ? 'selected' : 'checked' ]) { + c = 0; + for(i = 0, j = p.children.length; i < j; i++) { + c += m[p.children[i]].state[ t ? 'selected' : 'checked' ]; + } + if(j > 0 && c === j) { + p.state[ t ? 'selected' : 'checked' ] = true; + this._data[ t ? 'core' : 'checkbox' ].selected.push(p.id); + tmp = this.get_node(p, true); + if(tmp && tmp.length) { + tmp.attr('aria-selected', true).children('.jstree-anchor').addClass(t ? 'jstree-clicked' : 'jstree-checked'); + } + } + else { + break; + } + p = this.get_node(p.parent); + } + }, this)) + .on('move_node.jstree', $.proxy(function (e, data) { + // apply up (whole handler) + var is_multi = data.is_multi, + old_par = data.old_parent, + new_par = this.get_node(data.parent), + m = this._model.data, + p, c, i, j, tmp, t = this.settings.checkbox.tie_selection; + if(!is_multi) { + p = this.get_node(old_par); + while(p && p.id !== $.jstree.root && !p.state[ t ? 'selected' : 'checked' ]) { + c = 0; + for(i = 0, j = p.children.length; i < j; i++) { + c += m[p.children[i]].state[ t ? 'selected' : 'checked' ]; + } + if(j > 0 && c === j) { + p.state[ t ? 'selected' : 'checked' ] = true; + this._data[ t ? 'core' : 'checkbox' ].selected.push(p.id); + tmp = this.get_node(p, true); + if(tmp && tmp.length) { + tmp.attr('aria-selected', true).children('.jstree-anchor').addClass(t ? 'jstree-clicked' : 'jstree-checked'); + } + } + else { + break; + } + p = this.get_node(p.parent); + } + } + p = new_par; + while(p && p.id !== $.jstree.root) { + c = 0; + for(i = 0, j = p.children.length; i < j; i++) { + c += m[p.children[i]].state[ t ? 'selected' : 'checked' ]; + } + if(c === j) { + if(!p.state[ t ? 'selected' : 'checked' ]) { + p.state[ t ? 'selected' : 'checked' ] = true; + this._data[ t ? 'core' : 'checkbox' ].selected.push(p.id); + tmp = this.get_node(p, true); + if(tmp && tmp.length) { + tmp.attr('aria-selected', true).children('.jstree-anchor').addClass(t ? 'jstree-clicked' : 'jstree-checked'); + } + } + } + else { + if(p.state[ t ? 'selected' : 'checked' ]) { + p.state[ t ? 'selected' : 'checked' ] = false; + this._data[ t ? 'core' : 'checkbox' ].selected = $.vakata.array_remove_item(this._data[ t ? 'core' : 'checkbox' ].selected, p.id); + tmp = this.get_node(p, true); + if(tmp && tmp.length) { + tmp.attr('aria-selected', false).children('.jstree-anchor').removeClass(t ? 'jstree-clicked' : 'jstree-checked'); + } + } + else { + break; + } + } + p = this.get_node(p.parent); + } + }, this)); + } + }; + /** + * set the undetermined state where and if necessary. Used internally. + * @private + * @name _undetermined() + * @plugin checkbox + */ + this._undetermined = function () { + if(this.element === null) { return; } + var i, j, k, l, o = {}, m = this._model.data, t = this.settings.checkbox.tie_selection, s = this._data[ t ? 'core' : 'checkbox' ].selected, p = [], tt = this; + for(i = 0, j = s.length; i < j; i++) { + if(m[s[i]] && m[s[i]].parents) { + for(k = 0, l = m[s[i]].parents.length; k < l; k++) { + if(o[m[s[i]].parents[k]] !== undefined) { + break; + } + if(m[s[i]].parents[k] !== $.jstree.root) { + o[m[s[i]].parents[k]] = true; + p.push(m[s[i]].parents[k]); + } + } + } + } + // attempt for server side undetermined state + this.element.find('.jstree-closed').not(':has(.jstree-children)') + .each(function () { + var tmp = tt.get_node(this), tmp2; + if(!tmp.state.loaded) { + if(tmp.original && tmp.original.state && tmp.original.state.undetermined && tmp.original.state.undetermined === true) { + if(o[tmp.id] === undefined && tmp.id !== $.jstree.root) { + o[tmp.id] = true; + p.push(tmp.id); + } + for(k = 0, l = tmp.parents.length; k < l; k++) { + if(o[tmp.parents[k]] === undefined && tmp.parents[k] !== $.jstree.root) { + o[tmp.parents[k]] = true; + p.push(tmp.parents[k]); + } + } + } + } + else { + for(i = 0, j = tmp.children_d.length; i < j; i++) { + tmp2 = m[tmp.children_d[i]]; + if(!tmp2.state.loaded && tmp2.original && tmp2.original.state && tmp2.original.state.undetermined && tmp2.original.state.undetermined === true) { + if(o[tmp2.id] === undefined && tmp2.id !== $.jstree.root) { + o[tmp2.id] = true; + p.push(tmp2.id); + } + for(k = 0, l = tmp2.parents.length; k < l; k++) { + if(o[tmp2.parents[k]] === undefined && tmp2.parents[k] !== $.jstree.root) { + o[tmp2.parents[k]] = true; + p.push(tmp2.parents[k]); + } + } + } + } + } + }); + + this.element.find('.jstree-undetermined').removeClass('jstree-undetermined'); + for(i = 0, j = p.length; i < j; i++) { + if(!m[p[i]].state[ t ? 'selected' : 'checked' ]) { + s = this.get_node(p[i], true); + if(s && s.length) { + s.children('.jstree-anchor').children('.jstree-checkbox').addClass('jstree-undetermined'); + } + } + } + }; + this.redraw_node = function(obj, deep, is_callback, force_render) { + obj = parent.redraw_node.apply(this, arguments); + if(obj) { + var i, j, tmp = null, icon = null; + for(i = 0, j = obj.childNodes.length; i < j; i++) { + if(obj.childNodes[i] && obj.childNodes[i].className && obj.childNodes[i].className.indexOf("jstree-anchor") !== -1) { + tmp = obj.childNodes[i]; + break; + } + } + if(tmp) { + if(!this.settings.checkbox.tie_selection && this._model.data[obj.id].state.checked) { tmp.className += ' jstree-checked'; } + icon = _i.cloneNode(false); + if(this._model.data[obj.id].state.checkbox_disabled) { icon.className += ' jstree-checkbox-disabled'; } + tmp.insertBefore(icon, tmp.childNodes[0]); + } + } + if(!is_callback && this.settings.checkbox.cascade.indexOf('undetermined') !== -1) { + if(this._data.checkbox.uto) { clearTimeout(this._data.checkbox.uto); } + this._data.checkbox.uto = setTimeout($.proxy(this._undetermined, this), 50); + } + return obj; + }; + /** + * show the node checkbox icons + * @name show_checkboxes() + * @plugin checkbox + */ + this.show_checkboxes = function () { this._data.core.themes.checkboxes = true; this.get_container_ul().removeClass("jstree-no-checkboxes"); }; + /** + * hide the node checkbox icons + * @name hide_checkboxes() + * @plugin checkbox + */ + this.hide_checkboxes = function () { this._data.core.themes.checkboxes = false; this.get_container_ul().addClass("jstree-no-checkboxes"); }; + /** + * toggle the node icons + * @name toggle_checkboxes() + * @plugin checkbox + */ + this.toggle_checkboxes = function () { if(this._data.core.themes.checkboxes) { this.hide_checkboxes(); } else { this.show_checkboxes(); } }; + /** + * checks if a node is in an undetermined state + * @name is_undetermined(obj) + * @param {mixed} obj + * @return {Boolean} + */ + this.is_undetermined = function (obj) { + obj = this.get_node(obj); + var s = this.settings.checkbox.cascade, i, j, t = this.settings.checkbox.tie_selection, d = this._data[ t ? 'core' : 'checkbox' ].selected, m = this._model.data; + if(!obj || obj.state[ t ? 'selected' : 'checked' ] === true || s.indexOf('undetermined') === -1 || (s.indexOf('down') === -1 && s.indexOf('up') === -1)) { + return false; + } + if(!obj.state.loaded && obj.original.state.undetermined === true) { + return true; + } + for(i = 0, j = obj.children_d.length; i < j; i++) { + if($.inArray(obj.children_d[i], d) !== -1 || (!m[obj.children_d[i]].state.loaded && m[obj.children_d[i]].original.state.undetermined)) { + return true; + } + } + return false; + }; + /** + * disable a node's checkbox + * @name disable_checkbox(obj) + * @param {mixed} obj an array can be used too + * @trigger disable_checkbox.jstree + * @plugin checkbox + */ + this.disable_checkbox = function (obj) { + var t1, t2, dom; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.disable_checkbox(obj[t1]); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { + return false; + } + dom = this.get_node(obj, true); + if(!obj.state.checkbox_disabled) { + obj.state.checkbox_disabled = true; + if(dom && dom.length) { + dom.children('.jstree-anchor').children('.jstree-checkbox').addClass('jstree-checkbox-disabled'); + } + /** + * triggered when an node's checkbox is disabled + * @event + * @name disable_checkbox.jstree + * @param {Object} node + * @plugin checkbox + */ + this.trigger('disable_checkbox', { 'node' : obj }); + } + }; + /** + * enable a node's checkbox + * @name disable_checkbox(obj) + * @param {mixed} obj an array can be used too + * @trigger enable_checkbox.jstree + * @plugin checkbox + */ + this.enable_checkbox = function (obj) { + var t1, t2, dom; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.enable_checkbox(obj[t1]); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { + return false; + } + dom = this.get_node(obj, true); + if(obj.state.checkbox_disabled) { + obj.state.checkbox_disabled = false; + if(dom && dom.length) { + dom.children('.jstree-anchor').children('.jstree-checkbox').removeClass('jstree-checkbox-disabled'); + } + /** + * triggered when an node's checkbox is enabled + * @event + * @name enable_checkbox.jstree + * @param {Object} node + * @plugin checkbox + */ + this.trigger('enable_checkbox', { 'node' : obj }); + } + }; + + this.activate_node = function (obj, e) { + if($(e.target).hasClass('jstree-checkbox-disabled')) { + return false; + } + if(this.settings.checkbox.tie_selection && (this.settings.checkbox.whole_node || $(e.target).hasClass('jstree-checkbox'))) { + e.ctrlKey = true; + } + if(this.settings.checkbox.tie_selection || (!this.settings.checkbox.whole_node && !$(e.target).hasClass('jstree-checkbox'))) { + return parent.activate_node.call(this, obj, e); + } + if(this.is_disabled(obj)) { + return false; + } + if(this.is_checked(obj)) { + this.uncheck_node(obj, e); + } + else { + this.check_node(obj, e); + } + this.trigger('activate_node', { 'node' : this.get_node(obj) }); + }; + + /** + * check a node (only if tie_selection in checkbox settings is false, otherwise select_node will be called internally) + * @name check_node(obj) + * @param {mixed} obj an array can be used to check multiple nodes + * @trigger check_node.jstree + * @plugin checkbox + */ + this.check_node = function (obj, e) { + if(this.settings.checkbox.tie_selection) { return this.select_node(obj, false, true, e); } + var dom, t1, t2, th; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.check_node(obj[t1], e); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { + return false; + } + dom = this.get_node(obj, true); + if(!obj.state.checked) { + obj.state.checked = true; + this._data.checkbox.selected.push(obj.id); + if(dom && dom.length) { + dom.children('.jstree-anchor').addClass('jstree-checked'); + } + /** + * triggered when an node is checked (only if tie_selection in checkbox settings is false) + * @event + * @name check_node.jstree + * @param {Object} node + * @param {Array} selected the current selection + * @param {Object} event the event (if any) that triggered this check_node + * @plugin checkbox + */ + this.trigger('check_node', { 'node' : obj, 'selected' : this._data.checkbox.selected, 'event' : e }); + } + }; + /** + * uncheck a node (only if tie_selection in checkbox settings is false, otherwise deselect_node will be called internally) + * @name uncheck_node(obj) + * @param {mixed} obj an array can be used to uncheck multiple nodes + * @trigger uncheck_node.jstree + * @plugin checkbox + */ + this.uncheck_node = function (obj, e) { + if(this.settings.checkbox.tie_selection) { return this.deselect_node(obj, false, e); } + var t1, t2, dom; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.uncheck_node(obj[t1], e); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { + return false; + } + dom = this.get_node(obj, true); + if(obj.state.checked) { + obj.state.checked = false; + this._data.checkbox.selected = $.vakata.array_remove_item(this._data.checkbox.selected, obj.id); + if(dom.length) { + dom.children('.jstree-anchor').removeClass('jstree-checked'); + } + /** + * triggered when an node is unchecked (only if tie_selection in checkbox settings is false) + * @event + * @name uncheck_node.jstree + * @param {Object} node + * @param {Array} selected the current selection + * @param {Object} event the event (if any) that triggered this uncheck_node + * @plugin checkbox + */ + this.trigger('uncheck_node', { 'node' : obj, 'selected' : this._data.checkbox.selected, 'event' : e }); + } + }; + /** + * checks all nodes in the tree (only if tie_selection in checkbox settings is false, otherwise select_all will be called internally) + * @name check_all() + * @trigger check_all.jstree, changed.jstree + * @plugin checkbox + */ + this.check_all = function () { + if(this.settings.checkbox.tie_selection) { return this.select_all(); } + var tmp = this._data.checkbox.selected.concat([]), i, j; + this._data.checkbox.selected = this._model.data[$.jstree.root].children_d.concat(); + for(i = 0, j = this._data.checkbox.selected.length; i < j; i++) { + if(this._model.data[this._data.checkbox.selected[i]]) { + this._model.data[this._data.checkbox.selected[i]].state.checked = true; + } + } + this.redraw(true); + /** + * triggered when all nodes are checked (only if tie_selection in checkbox settings is false) + * @event + * @name check_all.jstree + * @param {Array} selected the current selection + * @plugin checkbox + */ + this.trigger('check_all', { 'selected' : this._data.checkbox.selected }); + }; + /** + * uncheck all checked nodes (only if tie_selection in checkbox settings is false, otherwise deselect_all will be called internally) + * @name uncheck_all() + * @trigger uncheck_all.jstree + * @plugin checkbox + */ + this.uncheck_all = function () { + if(this.settings.checkbox.tie_selection) { return this.deselect_all(); } + var tmp = this._data.checkbox.selected.concat([]), i, j; + for(i = 0, j = this._data.checkbox.selected.length; i < j; i++) { + if(this._model.data[this._data.checkbox.selected[i]]) { + this._model.data[this._data.checkbox.selected[i]].state.checked = false; + } + } + this._data.checkbox.selected = []; + this.element.find('.jstree-checked').removeClass('jstree-checked'); + /** + * triggered when all nodes are unchecked (only if tie_selection in checkbox settings is false) + * @event + * @name uncheck_all.jstree + * @param {Object} node the previous selection + * @param {Array} selected the current selection + * @plugin checkbox + */ + this.trigger('uncheck_all', { 'selected' : this._data.checkbox.selected, 'node' : tmp }); + }; + /** + * checks if a node is checked (if tie_selection is on in the settings this function will return the same as is_selected) + * @name is_checked(obj) + * @param {mixed} obj + * @return {Boolean} + * @plugin checkbox + */ + this.is_checked = function (obj) { + if(this.settings.checkbox.tie_selection) { return this.is_selected(obj); } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { return false; } + return obj.state.checked; + }; + /** + * get an array of all checked nodes (if tie_selection is on in the settings this function will return the same as get_selected) + * @name get_checked([full]) + * @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned + * @return {Array} + * @plugin checkbox + */ + this.get_checked = function (full) { + if(this.settings.checkbox.tie_selection) { return this.get_selected(full); } + return full ? $.map(this._data.checkbox.selected, $.proxy(function (i) { return this.get_node(i); }, this)) : this._data.checkbox.selected; + }; + /** + * get an array of all top level checked nodes (ignoring children of checked nodes) (if tie_selection is on in the settings this function will return the same as get_top_selected) + * @name get_top_checked([full]) + * @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned + * @return {Array} + * @plugin checkbox + */ + this.get_top_checked = function (full) { + if(this.settings.checkbox.tie_selection) { return this.get_top_selected(full); } + var tmp = this.get_checked(true), + obj = {}, i, j, k, l; + for(i = 0, j = tmp.length; i < j; i++) { + obj[tmp[i].id] = tmp[i]; + } + for(i = 0, j = tmp.length; i < j; i++) { + for(k = 0, l = tmp[i].children_d.length; k < l; k++) { + if(obj[tmp[i].children_d[k]]) { + delete obj[tmp[i].children_d[k]]; + } + } + } + tmp = []; + for(i in obj) { + if(obj.hasOwnProperty(i)) { + tmp.push(i); + } + } + return full ? $.map(tmp, $.proxy(function (i) { return this.get_node(i); }, this)) : tmp; + }; + /** + * get an array of all bottom level checked nodes (ignoring selected parents) (if tie_selection is on in the settings this function will return the same as get_bottom_selected) + * @name get_bottom_checked([full]) + * @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned + * @return {Array} + * @plugin checkbox + */ + this.get_bottom_checked = function (full) { + if(this.settings.checkbox.tie_selection) { return this.get_bottom_selected(full); } + var tmp = this.get_checked(true), + obj = [], i, j; + for(i = 0, j = tmp.length; i < j; i++) { + if(!tmp[i].children.length) { + obj.push(tmp[i].id); + } + } + return full ? $.map(obj, $.proxy(function (i) { return this.get_node(i); }, this)) : obj; + }; + this.load_node = function (obj, callback) { + var k, l, i, j, c, tmp; + if(!$.isArray(obj) && !this.settings.checkbox.tie_selection) { + tmp = this.get_node(obj); + if(tmp && tmp.state.loaded) { + for(k = 0, l = tmp.children_d.length; k < l; k++) { + if(this._model.data[tmp.children_d[k]].state.checked) { + c = true; + this._data.checkbox.selected = $.vakata.array_remove_item(this._data.checkbox.selected, tmp.children_d[k]); + } + } + } + } + return parent.load_node.apply(this, arguments); + }; + this.get_state = function () { + var state = parent.get_state.apply(this, arguments); + if(this.settings.checkbox.tie_selection) { return state; } + state.checkbox = this._data.checkbox.selected.slice(); + return state; + }; + this.set_state = function (state, callback) { + var res = parent.set_state.apply(this, arguments); + if(res && state.checkbox) { + if(!this.settings.checkbox.tie_selection) { + this.uncheck_all(); + var _this = this; + $.each(state.checkbox, function (i, v) { + _this.check_node(v); + }); + } + delete state.checkbox; + this.set_state(state, callback); + return false; + } + return res; + }; + this.refresh = function (skip_loading, forget_state) { + if(!this.settings.checkbox.tie_selection) { + this._data.checkbox.selected = []; + } + return parent.refresh.apply(this, arguments); + }; + }; + + // include the checkbox plugin by default + // $.jstree.defaults.plugins.push("checkbox"); +})); \ No newline at end of file diff --git a/civicrm/bower_components/jstree/src/jstree.conditionalselect.js b/civicrm/bower_components/jstree/src/jstree.conditionalselect.js new file mode 100644 index 0000000000..012562ec10 --- /dev/null +++ b/civicrm/bower_components/jstree/src/jstree.conditionalselect.js @@ -0,0 +1,38 @@ +/** + * ### Conditionalselect plugin + * + * This plugin allows defining a callback to allow or deny node selection by user input (activate node method). + */ +/*globals jQuery, define, exports, require, document */ +(function (factory) { + "use strict"; + if (typeof define === 'function' && define.amd) { + define('jstree.conditionalselect', ['jquery','jstree'], factory); + } + else if(typeof exports === 'object') { + factory(require('jquery'), require('jstree')); + } + else { + factory(jQuery, jQuery.jstree); + } +}(function ($, jstree, undefined) { + "use strict"; + + if($.jstree.plugins.conditionalselect) { return; } + + /** + * a callback (function) which is invoked in the instance's scope and receives two arguments - the node and the event that triggered the `activate_node` call. Returning false prevents working with the node, returning true allows invoking activate_node. Defaults to returning `true`. + * @name $.jstree.defaults.checkbox.visible + * @plugin checkbox + */ + $.jstree.defaults.conditionalselect = function () { return true; }; + $.jstree.plugins.conditionalselect = function (options, parent) { + // own function + this.activate_node = function (obj, e) { + if(this.settings.conditionalselect.call(this, this.get_node(obj), e)) { + parent.activate_node.call(this, obj, e); + } + }; + }; + +})); \ No newline at end of file diff --git a/civicrm/bower_components/jstree/src/jstree.contextmenu.js b/civicrm/bower_components/jstree/src/jstree.contextmenu.js new file mode 100644 index 0000000000..00f4517510 --- /dev/null +++ b/civicrm/bower_components/jstree/src/jstree.contextmenu.js @@ -0,0 +1,653 @@ +/** + * ### Contextmenu plugin + * + * Shows a context menu when a node is right-clicked. + */ +/*globals jQuery, define, exports, require, document */ +(function (factory) { + "use strict"; + if (typeof define === 'function' && define.amd) { + define('jstree.contextmenu', ['jquery','jstree'], factory); + } + else if(typeof exports === 'object') { + factory(require('jquery'), require('jstree')); + } + else { + factory(jQuery, jQuery.jstree); + } +}(function ($, jstree, undefined) { + "use strict"; + + if($.jstree.plugins.contextmenu) { return; } + + /** + * stores all defaults for the contextmenu plugin + * @name $.jstree.defaults.contextmenu + * @plugin contextmenu + */ + $.jstree.defaults.contextmenu = { + /** + * a boolean indicating if the node should be selected when the context menu is invoked on it. Defaults to `true`. + * @name $.jstree.defaults.contextmenu.select_node + * @plugin contextmenu + */ + select_node : true, + /** + * a boolean indicating if the menu should be shown aligned with the node. Defaults to `true`, otherwise the mouse coordinates are used. + * @name $.jstree.defaults.contextmenu.show_at_node + * @plugin contextmenu + */ + show_at_node : true, + /** + * an object of actions, or a function that accepts a node and a callback function and calls the callback function with an object of actions available for that node (you can also return the items too). + * + * Each action consists of a key (a unique name) and a value which is an object with the following properties (only label and action are required). Once a menu item is activated the `action` function will be invoked with an object containing the following keys: item - the contextmenu item definition as seen below, reference - the DOM node that was used (the tree node), element - the contextmenu DOM element, position - an object with x/y properties indicating the position of the menu. + * + * * `separator_before` - a boolean indicating if there should be a separator before this item + * * `separator_after` - a boolean indicating if there should be a separator after this item + * * `_disabled` - a boolean indicating if this action should be disabled + * * `label` - a string - the name of the action (could be a function returning a string) + * * `title` - a string - an optional tooltip for the item + * * `action` - a function to be executed if this item is chosen, the function will receive + * * `icon` - a string, can be a path to an icon or a className, if using an image that is in the current directory use a `./` prefix, otherwise it will be detected as a class + * * `shortcut` - keyCode which will trigger the action if the menu is open (for example `113` for rename, which equals F2) + * * `shortcut_label` - shortcut label (like for example `F2` for rename) + * * `submenu` - an object with the same structure as $.jstree.defaults.contextmenu.items which can be used to create a submenu - each key will be rendered as a separate option in a submenu that will appear once the current item is hovered + * + * @name $.jstree.defaults.contextmenu.items + * @plugin contextmenu + */ + items : function (o, cb) { // Could be an object directly + return { + "create" : { + "separator_before" : false, + "separator_after" : true, + "_disabled" : false, //(this.check("create_node", data.reference, {}, "last")), + "label" : "Create", + "action" : function (data) { + var inst = $.jstree.reference(data.reference), + obj = inst.get_node(data.reference); + inst.create_node(obj, {}, "last", function (new_node) { + setTimeout(function () { inst.edit(new_node); },0); + }); + } + }, + "rename" : { + "separator_before" : false, + "separator_after" : false, + "_disabled" : false, //(this.check("rename_node", data.reference, this.get_parent(data.reference), "")), + "label" : "Rename", + /*! + "shortcut" : 113, + "shortcut_label" : 'F2', + "icon" : "glyphicon glyphicon-leaf", + */ + "action" : function (data) { + var inst = $.jstree.reference(data.reference), + obj = inst.get_node(data.reference); + inst.edit(obj); + } + }, + "remove" : { + "separator_before" : false, + "icon" : false, + "separator_after" : false, + "_disabled" : false, //(this.check("delete_node", data.reference, this.get_parent(data.reference), "")), + "label" : "Delete", + "action" : function (data) { + var inst = $.jstree.reference(data.reference), + obj = inst.get_node(data.reference); + if(inst.is_selected(obj)) { + inst.delete_node(inst.get_selected()); + } + else { + inst.delete_node(obj); + } + } + }, + "ccp" : { + "separator_before" : true, + "icon" : false, + "separator_after" : false, + "label" : "Edit", + "action" : false, + "submenu" : { + "cut" : { + "separator_before" : false, + "separator_after" : false, + "label" : "Cut", + "action" : function (data) { + var inst = $.jstree.reference(data.reference), + obj = inst.get_node(data.reference); + if(inst.is_selected(obj)) { + inst.cut(inst.get_top_selected()); + } + else { + inst.cut(obj); + } + } + }, + "copy" : { + "separator_before" : false, + "icon" : false, + "separator_after" : false, + "label" : "Copy", + "action" : function (data) { + var inst = $.jstree.reference(data.reference), + obj = inst.get_node(data.reference); + if(inst.is_selected(obj)) { + inst.copy(inst.get_top_selected()); + } + else { + inst.copy(obj); + } + } + }, + "paste" : { + "separator_before" : false, + "icon" : false, + "_disabled" : function (data) { + return !$.jstree.reference(data.reference).can_paste(); + }, + "separator_after" : false, + "label" : "Paste", + "action" : function (data) { + var inst = $.jstree.reference(data.reference), + obj = inst.get_node(data.reference); + inst.paste(obj); + } + } + } + } + }; + } + }; + + $.jstree.plugins.contextmenu = function (options, parent) { + this.bind = function () { + parent.bind.call(this); + + var last_ts = 0, cto = null, ex, ey; + this.element + .on("contextmenu.jstree", ".jstree-anchor", $.proxy(function (e, data) { + if (e.target.tagName.toLowerCase() === 'input') { + return; + } + e.preventDefault(); + last_ts = e.ctrlKey ? +new Date() : 0; + if(data || cto) { + last_ts = (+new Date()) + 10000; + } + if(cto) { + clearTimeout(cto); + } + if(!this.is_loading(e.currentTarget)) { + this.show_contextmenu(e.currentTarget, e.pageX, e.pageY, e); + } + }, this)) + .on("click.jstree", ".jstree-anchor", $.proxy(function (e) { + if(this._data.contextmenu.visible && (!last_ts || (+new Date()) - last_ts > 250)) { // work around safari & macOS ctrl+click + $.vakata.context.hide(); + } + last_ts = 0; + }, this)) + .on("touchstart.jstree", ".jstree-anchor", function (e) { + if(!e.originalEvent || !e.originalEvent.changedTouches || !e.originalEvent.changedTouches[0]) { + return; + } + ex = e.originalEvent.changedTouches[0].clientX; + ey = e.originalEvent.changedTouches[0].clientY; + cto = setTimeout(function () { + $(e.currentTarget).trigger('contextmenu', true); + }, 750); + }) + .on('touchmove.vakata.jstree', function (e) { + if(cto && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0] && (Math.abs(ex - e.originalEvent.changedTouches[0].clientX) > 50 || Math.abs(ey - e.originalEvent.changedTouches[0].clientY) > 50)) { + clearTimeout(cto); + } + }) + .on('touchend.vakata.jstree', function (e) { + if(cto) { + clearTimeout(cto); + } + }); + + /*! + if(!('oncontextmenu' in document.body) && ('ontouchstart' in document.body)) { + var el = null, tm = null; + this.element + .on("touchstart", ".jstree-anchor", function (e) { + el = e.currentTarget; + tm = +new Date(); + $(document).one("touchend", function (e) { + e.target = document.elementFromPoint(e.originalEvent.targetTouches[0].pageX - window.pageXOffset, e.originalEvent.targetTouches[0].pageY - window.pageYOffset); + e.currentTarget = e.target; + tm = ((+(new Date())) - tm); + if(e.target === el && tm > 600 && tm < 1000) { + e.preventDefault(); + $(el).trigger('contextmenu', e); + } + el = null; + tm = null; + }); + }); + } + */ + $(document).on("context_hide.vakata.jstree", $.proxy(function (e, data) { + this._data.contextmenu.visible = false; + $(data.reference).removeClass('jstree-context'); + }, this)); + }; + this.teardown = function () { + if(this._data.contextmenu.visible) { + $.vakata.context.hide(); + } + parent.teardown.call(this); + }; + + /** + * prepare and show the context menu for a node + * @name show_contextmenu(obj [, x, y]) + * @param {mixed} obj the node + * @param {Number} x the x-coordinate relative to the document to show the menu at + * @param {Number} y the y-coordinate relative to the document to show the menu at + * @param {Object} e the event if available that triggered the contextmenu + * @plugin contextmenu + * @trigger show_contextmenu.jstree + */ + this.show_contextmenu = function (obj, x, y, e) { + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { return false; } + var s = this.settings.contextmenu, + d = this.get_node(obj, true), + a = d.children(".jstree-anchor"), + o = false, + i = false; + if(s.show_at_node || x === undefined || y === undefined) { + o = a.offset(); + x = o.left; + y = o.top + this._data.core.li_height; + } + if(this.settings.contextmenu.select_node && !this.is_selected(obj)) { + this.activate_node(obj, e); + } + + i = s.items; + if($.isFunction(i)) { + i = i.call(this, obj, $.proxy(function (i) { + this._show_contextmenu(obj, x, y, i); + }, this)); + } + if($.isPlainObject(i)) { + this._show_contextmenu(obj, x, y, i); + } + }; + /** + * show the prepared context menu for a node + * @name _show_contextmenu(obj, x, y, i) + * @param {mixed} obj the node + * @param {Number} x the x-coordinate relative to the document to show the menu at + * @param {Number} y the y-coordinate relative to the document to show the menu at + * @param {Number} i the object of items to show + * @plugin contextmenu + * @trigger show_contextmenu.jstree + * @private + */ + this._show_contextmenu = function (obj, x, y, i) { + var d = this.get_node(obj, true), + a = d.children(".jstree-anchor"); + $(document).one("context_show.vakata.jstree", $.proxy(function (e, data) { + var cls = 'jstree-contextmenu jstree-' + this.get_theme() + '-contextmenu'; + $(data.element).addClass(cls); + a.addClass('jstree-context'); + }, this)); + this._data.contextmenu.visible = true; + $.vakata.context.show(a, { 'x' : x, 'y' : y }, i); + /** + * triggered when the contextmenu is shown for a node + * @event + * @name show_contextmenu.jstree + * @param {Object} node the node + * @param {Number} x the x-coordinate of the menu relative to the document + * @param {Number} y the y-coordinate of the menu relative to the document + * @plugin contextmenu + */ + this.trigger('show_contextmenu', { "node" : obj, "x" : x, "y" : y }); + }; + }; + + // contextmenu helper + (function ($) { + var right_to_left = false, + vakata_context = { + element : false, + reference : false, + position_x : 0, + position_y : 0, + items : [], + html : "", + is_visible : false + }; + + $.vakata.context = { + settings : { + hide_onmouseleave : 0, + icons : true + }, + _trigger : function (event_name) { + $(document).triggerHandler("context_" + event_name + ".vakata", { + "reference" : vakata_context.reference, + "element" : vakata_context.element, + "position" : { + "x" : vakata_context.position_x, + "y" : vakata_context.position_y + } + }); + }, + _execute : function (i) { + i = vakata_context.items[i]; + return i && (!i._disabled || ($.isFunction(i._disabled) && !i._disabled({ "item" : i, "reference" : vakata_context.reference, "element" : vakata_context.element }))) && i.action ? i.action.call(null, { + "item" : i, + "reference" : vakata_context.reference, + "element" : vakata_context.element, + "position" : { + "x" : vakata_context.position_x, + "y" : vakata_context.position_y + } + }) : false; + }, + _parse : function (o, is_callback) { + if(!o) { return false; } + if(!is_callback) { + vakata_context.html = ""; + vakata_context.items = []; + } + var str = "", + sep = false, + tmp; + + if(is_callback) { str += "<"+"ul>"; } + $.each(o, function (i, val) { + if(!val) { return true; } + vakata_context.items.push(val); + if(!sep && val.separator_before) { + str += "<"+"li class='vakata-context-separator'><"+"a href='#' " + ($.vakata.context.settings.icons ? '' : 'style="margin-left:0px;"') + "> <"+"/a><"+"/li>"; + } + sep = false; + str += "<"+"li class='" + (val._class || "") + (val._disabled === true || ($.isFunction(val._disabled) && val._disabled({ "item" : val, "reference" : vakata_context.reference, "element" : vakata_context.element })) ? " vakata-contextmenu-disabled " : "") + "' "+(val.shortcut?" data-shortcut='"+val.shortcut+"' ":'')+">"; + str += "<"+"a href='#' rel='" + (vakata_context.items.length - 1) + "' " + (val.title ? "title='" + val.title + "'" : "") + ">"; + if($.vakata.context.settings.icons) { + str += "<"+"i "; + if(val.icon) { + if(val.icon.indexOf("/") !== -1 || val.icon.indexOf(".") !== -1) { str += " style='background:url(\"" + val.icon + "\") center center no-repeat' "; } + else { str += " class='" + val.icon + "' "; } + } + str += "><"+"/i><"+"span class='vakata-contextmenu-sep'> <"+"/span>"; + } + str += ($.isFunction(val.label) ? val.label({ "item" : i, "reference" : vakata_context.reference, "element" : vakata_context.element }) : val.label) + (val.shortcut?' <span class="vakata-contextmenu-shortcut vakata-contextmenu-shortcut-'+val.shortcut+'">'+ (val.shortcut_label || '') +'</span>':'') + "<"+"/a>"; + if(val.submenu) { + tmp = $.vakata.context._parse(val.submenu, true); + if(tmp) { str += tmp; } + } + str += "<"+"/li>"; + if(val.separator_after) { + str += "<"+"li class='vakata-context-separator'><"+"a href='#' " + ($.vakata.context.settings.icons ? '' : 'style="margin-left:0px;"') + "> <"+"/a><"+"/li>"; + sep = true; + } + }); + str = str.replace(/<li class\='vakata-context-separator'\><\/li\>$/,""); + if(is_callback) { str += "</ul>"; } + /** + * triggered on the document when the contextmenu is parsed (HTML is built) + * @event + * @plugin contextmenu + * @name context_parse.vakata + * @param {jQuery} reference the element that was right clicked + * @param {jQuery} element the DOM element of the menu itself + * @param {Object} position the x & y coordinates of the menu + */ + if(!is_callback) { vakata_context.html = str; $.vakata.context._trigger("parse"); } + return str.length > 10 ? str : false; + }, + _show_submenu : function (o) { + o = $(o); + if(!o.length || !o.children("ul").length) { return; } + var e = o.children("ul"), + xl = o.offset().left, + x = xl + o.outerWidth(), + y = o.offset().top, + w = e.width(), + h = e.height(), + dw = $(window).width() + $(window).scrollLeft(), + dh = $(window).height() + $(window).scrollTop(); + // може да Ñе ÑпеÑти е една проверка - дали нÑма нÑкой от клаÑовете вече нагоре + if(right_to_left) { + o[x - (w + 10 + o.outerWidth()) < 0 ? "addClass" : "removeClass"]("vakata-context-left"); + } + else { + o[x + w > dw && xl > dw - x ? "addClass" : "removeClass"]("vakata-context-right"); + } + if(y + h + 10 > dh) { + e.css("bottom","-1px"); + } + + //if does not fit - stick it to the side + if (o.hasClass('vakata-context-right')) { + if (xl < w) { + e.css("margin-right", xl - w); + } + } else { + if (dw - x < w) { + e.css("margin-left", dw - x - w); + } + } + + e.show(); + }, + show : function (reference, position, data) { + var o, e, x, y, w, h, dw, dh, cond = true; + if(vakata_context.element && vakata_context.element.length) { + vakata_context.element.width(''); + } + switch(cond) { + case (!position && !reference): + return false; + case (!!position && !!reference): + vakata_context.reference = reference; + vakata_context.position_x = position.x; + vakata_context.position_y = position.y; + break; + case (!position && !!reference): + vakata_context.reference = reference; + o = reference.offset(); + vakata_context.position_x = o.left + reference.outerHeight(); + vakata_context.position_y = o.top; + break; + case (!!position && !reference): + vakata_context.position_x = position.x; + vakata_context.position_y = position.y; + break; + } + if(!!reference && !data && $(reference).data('vakata_contextmenu')) { + data = $(reference).data('vakata_contextmenu'); + } + if($.vakata.context._parse(data)) { + vakata_context.element.html(vakata_context.html); + } + if(vakata_context.items.length) { + vakata_context.element.appendTo("body"); + e = vakata_context.element; + x = vakata_context.position_x; + y = vakata_context.position_y; + w = e.width(); + h = e.height(); + dw = $(window).width() + $(window).scrollLeft(); + dh = $(window).height() + $(window).scrollTop(); + if(right_to_left) { + x -= (e.outerWidth() - $(reference).outerWidth()); + if(x < $(window).scrollLeft() + 20) { + x = $(window).scrollLeft() + 20; + } + } + if(x + w + 20 > dw) { + x = dw - (w + 20); + } + if(y + h + 20 > dh) { + y = dh - (h + 20); + } + + vakata_context.element + .css({ "left" : x, "top" : y }) + .show() + .find('a').first().focus().parent().addClass("vakata-context-hover"); + vakata_context.is_visible = true; + /** + * triggered on the document when the contextmenu is shown + * @event + * @plugin contextmenu + * @name context_show.vakata + * @param {jQuery} reference the element that was right clicked + * @param {jQuery} element the DOM element of the menu itself + * @param {Object} position the x & y coordinates of the menu + */ + $.vakata.context._trigger("show"); + } + }, + hide : function () { + if(vakata_context.is_visible) { + vakata_context.element.hide().find("ul").hide().end().find(':focus').blur().end().detach(); + vakata_context.is_visible = false; + /** + * triggered on the document when the contextmenu is hidden + * @event + * @plugin contextmenu + * @name context_hide.vakata + * @param {jQuery} reference the element that was right clicked + * @param {jQuery} element the DOM element of the menu itself + * @param {Object} position the x & y coordinates of the menu + */ + $.vakata.context._trigger("hide"); + } + } + }; + $(function () { + right_to_left = $("body").css("direction") === "rtl"; + var to = false; + + vakata_context.element = $("<ul class='vakata-context'></ul>"); + vakata_context.element + .on("mouseenter", "li", function (e) { + e.stopImmediatePropagation(); + + if($.contains(this, e.relatedTarget)) { + // премахнато заради delegate mouseleave по-долу + // $(this).find(".vakata-context-hover").removeClass("vakata-context-hover"); + return; + } + + if(to) { clearTimeout(to); } + vakata_context.element.find(".vakata-context-hover").removeClass("vakata-context-hover").end(); + + $(this) + .siblings().find("ul").hide().end().end() + .parentsUntil(".vakata-context", "li").addBack().addClass("vakata-context-hover"); + $.vakata.context._show_submenu(this); + }) + // теÑтово - дали не натоварва? + .on("mouseleave", "li", function (e) { + if($.contains(this, e.relatedTarget)) { return; } + $(this).find(".vakata-context-hover").addBack().removeClass("vakata-context-hover"); + }) + .on("mouseleave", function (e) { + $(this).find(".vakata-context-hover").removeClass("vakata-context-hover"); + if($.vakata.context.settings.hide_onmouseleave) { + to = setTimeout( + (function (t) { + return function () { $.vakata.context.hide(); }; + }(this)), $.vakata.context.settings.hide_onmouseleave); + } + }) + .on("click", "a", function (e) { + e.preventDefault(); + //}) + //.on("mouseup", "a", function (e) { + if(!$(this).blur().parent().hasClass("vakata-context-disabled") && $.vakata.context._execute($(this).attr("rel")) !== false) { + $.vakata.context.hide(); + } + }) + .on('keydown', 'a', function (e) { + var o = null; + switch(e.which) { + case 13: + case 32: + e.type = "click"; + e.preventDefault(); + $(e.currentTarget).trigger(e); + break; + case 37: + if(vakata_context.is_visible) { + vakata_context.element.find(".vakata-context-hover").last().closest("li").first().find("ul").hide().find(".vakata-context-hover").removeClass("vakata-context-hover").end().end().children('a').focus(); + e.stopImmediatePropagation(); + e.preventDefault(); + } + break; + case 38: + if(vakata_context.is_visible) { + o = vakata_context.element.find("ul:visible").addBack().last().children(".vakata-context-hover").removeClass("vakata-context-hover").prevAll("li:not(.vakata-context-separator)").first(); + if(!o.length) { o = vakata_context.element.find("ul:visible").addBack().last().children("li:not(.vakata-context-separator)").last(); } + o.addClass("vakata-context-hover").children('a').focus(); + e.stopImmediatePropagation(); + e.preventDefault(); + } + break; + case 39: + if(vakata_context.is_visible) { + vakata_context.element.find(".vakata-context-hover").last().children("ul").show().children("li:not(.vakata-context-separator)").removeClass("vakata-context-hover").first().addClass("vakata-context-hover").children('a').focus(); + e.stopImmediatePropagation(); + e.preventDefault(); + } + break; + case 40: + if(vakata_context.is_visible) { + o = vakata_context.element.find("ul:visible").addBack().last().children(".vakata-context-hover").removeClass("vakata-context-hover").nextAll("li:not(.vakata-context-separator)").first(); + if(!o.length) { o = vakata_context.element.find("ul:visible").addBack().last().children("li:not(.vakata-context-separator)").first(); } + o.addClass("vakata-context-hover").children('a').focus(); + e.stopImmediatePropagation(); + e.preventDefault(); + } + break; + case 27: + $.vakata.context.hide(); + e.preventDefault(); + break; + default: + //console.log(e.which); + break; + } + }) + .on('keydown', function (e) { + e.preventDefault(); + var a = vakata_context.element.find('.vakata-contextmenu-shortcut-' + e.which).parent(); + if(a.parent().not('.vakata-context-disabled')) { + a.click(); + } + }); + + $(document) + .on("mousedown.vakata.jstree", function (e) { + if(vakata_context.is_visible && !$.contains(vakata_context.element[0], e.target)) { + $.vakata.context.hide(); + } + }) + .on("context_show.vakata.jstree", function (e, data) { + vakata_context.element.find("li:has(ul)").children("a").addClass("vakata-context-parent"); + if(right_to_left) { + vakata_context.element.addClass("vakata-context-rtl").css("direction", "rtl"); + } + // also apply a RTL class? + vakata_context.element.find("ul").hide().end(); + }); + }); + }($)); + // $.jstree.defaults.plugins.push("contextmenu"); +})); diff --git a/civicrm/bower_components/jstree/src/jstree.dnd.js b/civicrm/bower_components/jstree/src/jstree.dnd.js new file mode 100644 index 0000000000..a8a4cec2ec --- /dev/null +++ b/civicrm/bower_components/jstree/src/jstree.dnd.js @@ -0,0 +1,653 @@ +/** + * ### Drag'n'drop plugin + * + * Enables dragging and dropping of nodes in the tree, resulting in a move or copy operations. + */ +/*globals jQuery, define, exports, require, document */ +(function (factory) { + "use strict"; + if (typeof define === 'function' && define.amd) { + define('jstree.dnd', ['jquery','jstree'], factory); + } + else if(typeof exports === 'object') { + factory(require('jquery'), require('jstree')); + } + else { + factory(jQuery, jQuery.jstree); + } +}(function ($, jstree, undefined) { + "use strict"; + + if($.jstree.plugins.dnd) { return; } + + /** + * stores all defaults for the drag'n'drop plugin + * @name $.jstree.defaults.dnd + * @plugin dnd + */ + $.jstree.defaults.dnd = { + /** + * a boolean indicating if a copy should be possible while dragging (by pressint the meta key or Ctrl). Defaults to `true`. + * @name $.jstree.defaults.dnd.copy + * @plugin dnd + */ + copy : true, + /** + * a number indicating how long a node should remain hovered while dragging to be opened. Defaults to `500`. + * @name $.jstree.defaults.dnd.open_timeout + * @plugin dnd + */ + open_timeout : 500, + /** + * a function invoked each time a node is about to be dragged, invoked in the tree's scope and receives the nodes about to be dragged as an argument (array) and the event that started the drag - return `false` to prevent dragging + * @name $.jstree.defaults.dnd.is_draggable + * @plugin dnd + */ + is_draggable : true, + /** + * a boolean indicating if checks should constantly be made while the user is dragging the node (as opposed to checking only on drop), default is `true` + * @name $.jstree.defaults.dnd.check_while_dragging + * @plugin dnd + */ + check_while_dragging : true, + /** + * a boolean indicating if nodes from this tree should only be copied with dnd (as opposed to moved), default is `false` + * @name $.jstree.defaults.dnd.always_copy + * @plugin dnd + */ + always_copy : false, + /** + * when dropping a node "inside", this setting indicates the position the node should go to - it can be an integer or a string: "first" (same as 0) or "last", default is `0` + * @name $.jstree.defaults.dnd.inside_pos + * @plugin dnd + */ + inside_pos : 0, + /** + * when starting the drag on a node that is selected this setting controls if all selected nodes are dragged or only the single node, default is `true`, which means all selected nodes are dragged when the drag is started on a selected node + * @name $.jstree.defaults.dnd.drag_selection + * @plugin dnd + */ + drag_selection : true, + /** + * controls whether dnd works on touch devices. If left as boolean true dnd will work the same as in desktop browsers, which in some cases may impair scrolling. If set to boolean false dnd will not work on touch devices. There is a special third option - string "selected" which means only selected nodes can be dragged on touch devices. + * @name $.jstree.defaults.dnd.touch + * @plugin dnd + */ + touch : true, + /** + * controls whether items can be dropped anywhere on the node, not just on the anchor, by default only the node anchor is a valid drop target. Works best with the wholerow plugin. If enabled on mobile depending on the interface it might be hard for the user to cancel the drop, since the whole tree container will be a valid drop target. + * @name $.jstree.defaults.dnd.large_drop_target + * @plugin dnd + */ + large_drop_target : false, + /** + * controls whether a drag can be initiated from any part of the node and not just the text/icon part, works best with the wholerow plugin. Keep in mind it can cause problems with tree scrolling on mobile depending on the interface - in that case set the touch option to "selected". + * @name $.jstree.defaults.dnd.large_drag_target + * @plugin dnd + */ + large_drag_target : false, + /** + * controls whether use HTML5 dnd api instead of classical. That will allow better integration of dnd events with other HTML5 controls. + * @reference http://caniuse.com/#feat=dragndrop + * @name $.jstree.defaults.dnd.use_html5 + * @plugin dnd + */ + use_html5: false + }; + var drg, elm; + // TODO: now check works by checking for each node individually, how about max_children, unique, etc? + $.jstree.plugins.dnd = function (options, parent) { + this.init = function (el, options) { + parent.init.call(this, el, options); + this.settings.dnd.use_html5 = this.settings.dnd.use_html5 && ('draggable' in document.createElement('span')); + }; + this.bind = function () { + parent.bind.call(this); + + this.element + .on(this.settings.dnd.use_html5 ? 'dragstart.jstree' : 'mousedown.jstree touchstart.jstree', this.settings.dnd.large_drag_target ? '.jstree-node' : '.jstree-anchor', $.proxy(function (e) { + if(this.settings.dnd.large_drag_target && $(e.target).closest('.jstree-node')[0] !== e.currentTarget) { + return true; + } + if(e.type === "touchstart" && (!this.settings.dnd.touch || (this.settings.dnd.touch === 'selected' && !$(e.currentTarget).closest('.jstree-node').children('.jstree-anchor').hasClass('jstree-clicked')))) { + return true; + } + var obj = this.get_node(e.target), + mlt = this.is_selected(obj) && this.settings.dnd.drag_selection ? this.get_top_selected().length : 1, + txt = (mlt > 1 ? mlt + ' ' + this.get_string('nodes') : this.get_text(e.currentTarget)); + if(this.settings.core.force_text) { + txt = $.vakata.html.escape(txt); + } + if(obj && obj.id && obj.id !== $.jstree.root && (e.which === 1 || e.type === "touchstart" || e.type === "dragstart") && + (this.settings.dnd.is_draggable === true || ($.isFunction(this.settings.dnd.is_draggable) && this.settings.dnd.is_draggable.call(this, (mlt > 1 ? this.get_top_selected(true) : [obj]), e))) + ) { + drg = { 'jstree' : true, 'origin' : this, 'obj' : this.get_node(obj,true), 'nodes' : mlt > 1 ? this.get_top_selected() : [obj.id] }; + elm = e.currentTarget; + if (this.settings.dnd.use_html5) { + $.vakata.dnd._trigger('start', e, { 'helper': $(), 'element': elm, 'data': drg }); + } else { + this.element.trigger('mousedown.jstree'); + return $.vakata.dnd.start(e, drg, '<div id="jstree-dnd" class="jstree-' + this.get_theme() + ' jstree-' + this.get_theme() + '-' + this.get_theme_variant() + ' ' + ( this.settings.core.themes.responsive ? ' jstree-dnd-responsive' : '' ) + '"><i class="jstree-icon jstree-er"></i>' + txt + '<ins class="jstree-copy" style="display:none;">+</ins></div>'); + } + } + }, this)); + if (this.settings.dnd.use_html5) { + this.element + .on('dragover.jstree', function (e) { + e.preventDefault(); + $.vakata.dnd._trigger('move', e, { 'helper': $(), 'element': elm, 'data': drg }); + return false; + }) + //.on('dragenter.jstree', this.settings.dnd.large_drop_target ? '.jstree-node' : '.jstree-anchor', $.proxy(function (e) { + // e.preventDefault(); + // $.vakata.dnd._trigger('move', e, { 'helper': $(), 'element': elm, 'data': drg }); + // return false; + // }, this)) + .on('drop.jstree', $.proxy(function (e) { + e.preventDefault(); + $.vakata.dnd._trigger('stop', e, { 'helper': $(), 'element': elm, 'data': drg }); + return false; + }, this)); + } + }; + this.redraw_node = function(obj, deep, callback, force_render) { + obj = parent.redraw_node.apply(this, arguments); + if (obj && this.settings.dnd.use_html5) { + if (this.settings.dnd.large_drag_target) { + obj.setAttribute('draggable', true); + } else { + var i, j, tmp = null; + for(i = 0, j = obj.childNodes.length; i < j; i++) { + if(obj.childNodes[i] && obj.childNodes[i].className && obj.childNodes[i].className.indexOf("jstree-anchor") !== -1) { + tmp = obj.childNodes[i]; + break; + } + } + if(tmp) { + tmp.setAttribute('draggable', true); + } + } + } + return obj; + }; + }; + + $(function() { + // bind only once for all instances + var lastmv = false, + laster = false, + lastev = false, + opento = false, + marker = $('<div id="jstree-marker"> </div>').hide(); //.appendTo('body'); + + $(document) + .on('dnd_start.vakata.jstree', function (e, data) { + lastmv = false; + lastev = false; + if(!data || !data.data || !data.data.jstree) { return; } + marker.appendTo('body'); //.show(); + }) + .on('dnd_move.vakata.jstree', function (e, data) { + if(opento) { + if (!data.event || data.event.type !== 'dragover' || data.event.target !== lastev.target) { + clearTimeout(opento); + } + } + if(!data || !data.data || !data.data.jstree) { return; } + + // if we are hovering the marker image do nothing (can happen on "inside" drags) + if(data.event.target.id && data.event.target.id === 'jstree-marker') { + return; + } + lastev = data.event; + + var ins = $.jstree.reference(data.event.target), + ref = false, + off = false, + rel = false, + tmp, l, t, h, p, i, o, ok, t1, t2, op, ps, pr, ip, tm, is_copy, pn; + // if we are over an instance + if(ins && ins._data && ins._data.dnd) { + marker.attr('class', 'jstree-' + ins.get_theme() + ( ins.settings.core.themes.responsive ? ' jstree-dnd-responsive' : '' )); + is_copy = data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (data.event.metaKey || data.event.ctrlKey))); + data.helper + .children().attr('class', 'jstree-' + ins.get_theme() + ' jstree-' + ins.get_theme() + '-' + ins.get_theme_variant() + ' ' + ( ins.settings.core.themes.responsive ? ' jstree-dnd-responsive' : '' )) + .find('.jstree-copy').first()[ is_copy ? 'show' : 'hide' ](); + + // if are hovering the container itself add a new root node + //console.log(data.event); + if( (data.event.target === ins.element[0] || data.event.target === ins.get_container_ul()[0]) && ins.get_container_ul().children().length === 0) { + ok = true; + for(t1 = 0, t2 = data.data.nodes.length; t1 < t2; t1++) { + ok = ok && ins.check( (data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (data.event.metaKey || data.event.ctrlKey)) ) ? "copy_node" : "move_node"), (data.data.origin && data.data.origin !== ins ? data.data.origin.get_node(data.data.nodes[t1]) : data.data.nodes[t1]), $.jstree.root, 'last', { 'dnd' : true, 'ref' : ins.get_node($.jstree.root), 'pos' : 'i', 'origin' : data.data.origin, 'is_multi' : (data.data.origin && data.data.origin !== ins), 'is_foreign' : (!data.data.origin) }); + if(!ok) { break; } + } + if(ok) { + lastmv = { 'ins' : ins, 'par' : $.jstree.root, 'pos' : 'last' }; + marker.hide(); + data.helper.find('.jstree-icon').first().removeClass('jstree-er').addClass('jstree-ok'); + if (data.event.originalEvent && data.event.originalEvent.dataTransfer) { + data.event.originalEvent.dataTransfer.dropEffect = is_copy ? 'copy' : 'move'; + } + return; + } + } + else { + // if we are hovering a tree node + ref = ins.settings.dnd.large_drop_target ? $(data.event.target).closest('.jstree-node').children('.jstree-anchor') : $(data.event.target).closest('.jstree-anchor'); + if(ref && ref.length && ref.parent().is('.jstree-closed, .jstree-open, .jstree-leaf')) { + off = ref.offset(); + rel = (data.event.pageY !== undefined ? data.event.pageY : data.event.originalEvent.pageY) - off.top; + h = ref.outerHeight(); + if(rel < h / 3) { + o = ['b', 'i', 'a']; + } + else if(rel > h - h / 3) { + o = ['a', 'i', 'b']; + } + else { + o = rel > h / 2 ? ['i', 'a', 'b'] : ['i', 'b', 'a']; + } + $.each(o, function (j, v) { + switch(v) { + case 'b': + l = off.left - 6; + t = off.top; + p = ins.get_parent(ref); + i = ref.parent().index(); + break; + case 'i': + ip = ins.settings.dnd.inside_pos; + tm = ins.get_node(ref.parent()); + l = off.left - 2; + t = off.top + h / 2 + 1; + p = tm.id; + i = ip === 'first' ? 0 : (ip === 'last' ? tm.children.length : Math.min(ip, tm.children.length)); + break; + case 'a': + l = off.left - 6; + t = off.top + h; + p = ins.get_parent(ref); + i = ref.parent().index() + 1; + break; + } + ok = true; + for(t1 = 0, t2 = data.data.nodes.length; t1 < t2; t1++) { + op = data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (data.event.metaKey || data.event.ctrlKey))) ? "copy_node" : "move_node"; + ps = i; + if(op === "move_node" && v === 'a' && (data.data.origin && data.data.origin === ins) && p === ins.get_parent(data.data.nodes[t1])) { + pr = ins.get_node(p); + if(ps > $.inArray(data.data.nodes[t1], pr.children)) { + ps -= 1; + } + } + ok = ok && ( (ins && ins.settings && ins.settings.dnd && ins.settings.dnd.check_while_dragging === false) || ins.check(op, (data.data.origin && data.data.origin !== ins ? data.data.origin.get_node(data.data.nodes[t1]) : data.data.nodes[t1]), p, ps, { 'dnd' : true, 'ref' : ins.get_node(ref.parent()), 'pos' : v, 'origin' : data.data.origin, 'is_multi' : (data.data.origin && data.data.origin !== ins), 'is_foreign' : (!data.data.origin) }) ); + if(!ok) { + if(ins && ins.last_error) { laster = ins.last_error(); } + break; + } + } + if(v === 'i' && ref.parent().is('.jstree-closed') && ins.settings.dnd.open_timeout) { + opento = setTimeout((function (x, z) { return function () { x.open_node(z); }; }(ins, ref)), ins.settings.dnd.open_timeout); + } + if(ok) { + pn = ins.get_node(p, true); + if (!pn.hasClass('.jstree-dnd-parent')) { + $('.jstree-dnd-parent').removeClass('jstree-dnd-parent'); + pn.addClass('jstree-dnd-parent'); + } + lastmv = { 'ins' : ins, 'par' : p, 'pos' : v === 'i' && ip === 'last' && i === 0 && !ins.is_loaded(tm) ? 'last' : i }; + marker.css({ 'left' : l + 'px', 'top' : t + 'px' }).show(); + data.helper.find('.jstree-icon').first().removeClass('jstree-er').addClass('jstree-ok'); + if (data.event.originalEvent && data.event.originalEvent.dataTransfer) { + data.event.originalEvent.dataTransfer.dropEffect = is_copy ? 'copy' : 'move'; + } + laster = {}; + o = true; + return false; + } + }); + if(o === true) { return; } + } + } + } + $('.jstree-dnd-parent').removeClass('jstree-dnd-parent'); + lastmv = false; + data.helper.find('.jstree-icon').removeClass('jstree-ok').addClass('jstree-er'); + if (data.event.originalEvent && data.event.originalEvent.dataTransfer) { + data.event.originalEvent.dataTransfer.dropEffect = 'none'; + } + marker.hide(); + }) + .on('dnd_scroll.vakata.jstree', function (e, data) { + if(!data || !data.data || !data.data.jstree) { return; } + marker.hide(); + lastmv = false; + lastev = false; + data.helper.find('.jstree-icon').first().removeClass('jstree-ok').addClass('jstree-er'); + }) + .on('dnd_stop.vakata.jstree', function (e, data) { + $('.jstree-dnd-parent').removeClass('jstree-dnd-parent'); + if(opento) { clearTimeout(opento); } + if(!data || !data.data || !data.data.jstree) { return; } + marker.hide().detach(); + var i, j, nodes = []; + if(lastmv) { + for(i = 0, j = data.data.nodes.length; i < j; i++) { + nodes[i] = data.data.origin ? data.data.origin.get_node(data.data.nodes[i]) : data.data.nodes[i]; + } + lastmv.ins[ data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (data.event.metaKey || data.event.ctrlKey))) ? 'copy_node' : 'move_node' ](nodes, lastmv.par, lastmv.pos, false, false, false, data.data.origin); + } + else { + i = $(data.event.target).closest('.jstree'); + if(i.length && laster && laster.error && laster.error === 'check') { + i = i.jstree(true); + if(i) { + i.settings.core.error.call(this, laster); + } + } + } + lastev = false; + lastmv = false; + }) + .on('keyup.jstree keydown.jstree', function (e, data) { + data = $.vakata.dnd._get(); + if(data && data.data && data.data.jstree) { + if (e.type === "keyup" && e.which === 27) { + if (opento) { clearTimeout(opento); } + lastmv = false; + laster = false; + lastev = false; + opento = false; + marker.hide().detach(); + $.vakata.dnd._clean(); + } else { + data.helper.find('.jstree-copy').first()[ data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (e.metaKey || e.ctrlKey))) ? 'show' : 'hide' ](); + if(lastev) { + lastev.metaKey = e.metaKey; + lastev.ctrlKey = e.ctrlKey; + $.vakata.dnd._trigger('move', lastev); + } + } + } + }); + }); + + // helpers + (function ($) { + $.vakata.html = { + div : $('<div />'), + escape : function (str) { + return $.vakata.html.div.text(str).html(); + }, + strip : function (str) { + return $.vakata.html.div.empty().append($.parseHTML(str)).text(); + } + }; + // private variable + var vakata_dnd = { + element : false, + target : false, + is_down : false, + is_drag : false, + helper : false, + helper_w: 0, + data : false, + init_x : 0, + init_y : 0, + scroll_l: 0, + scroll_t: 0, + scroll_e: false, + scroll_i: false, + is_touch: false + }; + $.vakata.dnd = { + settings : { + scroll_speed : 10, + scroll_proximity : 20, + helper_left : 5, + helper_top : 10, + threshold : 5, + threshold_touch : 50 + }, + _trigger : function (event_name, e, data) { + if (data === undefined) { + data = $.vakata.dnd._get(); + } + data.event = e; + $(document).triggerHandler("dnd_" + event_name + ".vakata", data); + }, + _get : function () { + return { + "data" : vakata_dnd.data, + "element" : vakata_dnd.element, + "helper" : vakata_dnd.helper + }; + }, + _clean : function () { + if(vakata_dnd.helper) { vakata_dnd.helper.remove(); } + if(vakata_dnd.scroll_i) { clearInterval(vakata_dnd.scroll_i); vakata_dnd.scroll_i = false; } + vakata_dnd = { + element : false, + target : false, + is_down : false, + is_drag : false, + helper : false, + helper_w: 0, + data : false, + init_x : 0, + init_y : 0, + scroll_l: 0, + scroll_t: 0, + scroll_e: false, + scroll_i: false, + is_touch: false + }; + $(document).off("mousemove.vakata.jstree touchmove.vakata.jstree", $.vakata.dnd.drag); + $(document).off("mouseup.vakata.jstree touchend.vakata.jstree", $.vakata.dnd.stop); + }, + _scroll : function (init_only) { + if(!vakata_dnd.scroll_e || (!vakata_dnd.scroll_l && !vakata_dnd.scroll_t)) { + if(vakata_dnd.scroll_i) { clearInterval(vakata_dnd.scroll_i); vakata_dnd.scroll_i = false; } + return false; + } + if(!vakata_dnd.scroll_i) { + vakata_dnd.scroll_i = setInterval($.vakata.dnd._scroll, 100); + return false; + } + if(init_only === true) { return false; } + + var i = vakata_dnd.scroll_e.scrollTop(), + j = vakata_dnd.scroll_e.scrollLeft(); + vakata_dnd.scroll_e.scrollTop(i + vakata_dnd.scroll_t * $.vakata.dnd.settings.scroll_speed); + vakata_dnd.scroll_e.scrollLeft(j + vakata_dnd.scroll_l * $.vakata.dnd.settings.scroll_speed); + if(i !== vakata_dnd.scroll_e.scrollTop() || j !== vakata_dnd.scroll_e.scrollLeft()) { + /** + * triggered on the document when a drag causes an element to scroll + * @event + * @plugin dnd + * @name dnd_scroll.vakata + * @param {Mixed} data any data supplied with the call to $.vakata.dnd.start + * @param {DOM} element the DOM element being dragged + * @param {jQuery} helper the helper shown next to the mouse + * @param {jQuery} event the element that is scrolling + */ + $.vakata.dnd._trigger("scroll", vakata_dnd.scroll_e); + } + }, + start : function (e, data, html) { + if(e.type === "touchstart" && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0]) { + e.pageX = e.originalEvent.changedTouches[0].pageX; + e.pageY = e.originalEvent.changedTouches[0].pageY; + e.target = document.elementFromPoint(e.originalEvent.changedTouches[0].pageX - window.pageXOffset, e.originalEvent.changedTouches[0].pageY - window.pageYOffset); + } + if(vakata_dnd.is_drag) { $.vakata.dnd.stop({}); } + try { + e.currentTarget.unselectable = "on"; + e.currentTarget.onselectstart = function() { return false; }; + if(e.currentTarget.style) { + e.currentTarget.style.touchAction = "none"; + e.currentTarget.style.msTouchAction = "none"; + e.currentTarget.style.MozUserSelect = "none"; + } + } catch(ignore) { } + vakata_dnd.init_x = e.pageX; + vakata_dnd.init_y = e.pageY; + vakata_dnd.data = data; + vakata_dnd.is_down = true; + vakata_dnd.element = e.currentTarget; + vakata_dnd.target = e.target; + vakata_dnd.is_touch = e.type === "touchstart"; + if(html !== false) { + vakata_dnd.helper = $("<div id='vakata-dnd'></div>").html(html).css({ + "display" : "block", + "margin" : "0", + "padding" : "0", + "position" : "absolute", + "top" : "-2000px", + "lineHeight" : "16px", + "zIndex" : "10000" + }); + } + $(document).on("mousemove.vakata.jstree touchmove.vakata.jstree", $.vakata.dnd.drag); + $(document).on("mouseup.vakata.jstree touchend.vakata.jstree", $.vakata.dnd.stop); + return false; + }, + drag : function (e) { + if(e.type === "touchmove" && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0]) { + e.pageX = e.originalEvent.changedTouches[0].pageX; + e.pageY = e.originalEvent.changedTouches[0].pageY; + e.target = document.elementFromPoint(e.originalEvent.changedTouches[0].pageX - window.pageXOffset, e.originalEvent.changedTouches[0].pageY - window.pageYOffset); + } + if(!vakata_dnd.is_down) { return; } + if(!vakata_dnd.is_drag) { + if( + Math.abs(e.pageX - vakata_dnd.init_x) > (vakata_dnd.is_touch ? $.vakata.dnd.settings.threshold_touch : $.vakata.dnd.settings.threshold) || + Math.abs(e.pageY - vakata_dnd.init_y) > (vakata_dnd.is_touch ? $.vakata.dnd.settings.threshold_touch : $.vakata.dnd.settings.threshold) + ) { + if(vakata_dnd.helper) { + vakata_dnd.helper.appendTo("body"); + vakata_dnd.helper_w = vakata_dnd.helper.outerWidth(); + } + vakata_dnd.is_drag = true; + $(vakata_dnd.target).one('click.vakata', false); + /** + * triggered on the document when a drag starts + * @event + * @plugin dnd + * @name dnd_start.vakata + * @param {Mixed} data any data supplied with the call to $.vakata.dnd.start + * @param {DOM} element the DOM element being dragged + * @param {jQuery} helper the helper shown next to the mouse + * @param {Object} event the event that caused the start (probably mousemove) + */ + $.vakata.dnd._trigger("start", e); + } + else { return; } + } + + var d = false, w = false, + dh = false, wh = false, + dw = false, ww = false, + dt = false, dl = false, + ht = false, hl = false; + + vakata_dnd.scroll_t = 0; + vakata_dnd.scroll_l = 0; + vakata_dnd.scroll_e = false; + $($(e.target).parentsUntil("body").addBack().get().reverse()) + .filter(function () { + return (/^auto|scroll$/).test($(this).css("overflow")) && + (this.scrollHeight > this.offsetHeight || this.scrollWidth > this.offsetWidth); + }) + .each(function () { + var t = $(this), o = t.offset(); + if(this.scrollHeight > this.offsetHeight) { + if(o.top + t.height() - e.pageY < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_t = 1; } + if(e.pageY - o.top < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_t = -1; } + } + if(this.scrollWidth > this.offsetWidth) { + if(o.left + t.width() - e.pageX < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_l = 1; } + if(e.pageX - o.left < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_l = -1; } + } + if(vakata_dnd.scroll_t || vakata_dnd.scroll_l) { + vakata_dnd.scroll_e = $(this); + return false; + } + }); + + if(!vakata_dnd.scroll_e) { + d = $(document); w = $(window); + dh = d.height(); wh = w.height(); + dw = d.width(); ww = w.width(); + dt = d.scrollTop(); dl = d.scrollLeft(); + if(dh > wh && e.pageY - dt < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_t = -1; } + if(dh > wh && wh - (e.pageY - dt) < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_t = 1; } + if(dw > ww && e.pageX - dl < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_l = -1; } + if(dw > ww && ww - (e.pageX - dl) < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_l = 1; } + if(vakata_dnd.scroll_t || vakata_dnd.scroll_l) { + vakata_dnd.scroll_e = d; + } + } + if(vakata_dnd.scroll_e) { $.vakata.dnd._scroll(true); } + + if(vakata_dnd.helper) { + ht = parseInt(e.pageY + $.vakata.dnd.settings.helper_top, 10); + hl = parseInt(e.pageX + $.vakata.dnd.settings.helper_left, 10); + if(dh && ht + 25 > dh) { ht = dh - 50; } + if(dw && hl + vakata_dnd.helper_w > dw) { hl = dw - (vakata_dnd.helper_w + 2); } + vakata_dnd.helper.css({ + left : hl + "px", + top : ht + "px" + }); + } + /** + * triggered on the document when a drag is in progress + * @event + * @plugin dnd + * @name dnd_move.vakata + * @param {Mixed} data any data supplied with the call to $.vakata.dnd.start + * @param {DOM} element the DOM element being dragged + * @param {jQuery} helper the helper shown next to the mouse + * @param {Object} event the event that caused this to trigger (most likely mousemove) + */ + $.vakata.dnd._trigger("move", e); + return false; + }, + stop : function (e) { + if(e.type === "touchend" && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0]) { + e.pageX = e.originalEvent.changedTouches[0].pageX; + e.pageY = e.originalEvent.changedTouches[0].pageY; + e.target = document.elementFromPoint(e.originalEvent.changedTouches[0].pageX - window.pageXOffset, e.originalEvent.changedTouches[0].pageY - window.pageYOffset); + } + if(vakata_dnd.is_drag) { + /** + * triggered on the document when a drag stops (the dragged element is dropped) + * @event + * @plugin dnd + * @name dnd_stop.vakata + * @param {Mixed} data any data supplied with the call to $.vakata.dnd.start + * @param {DOM} element the DOM element being dragged + * @param {jQuery} helper the helper shown next to the mouse + * @param {Object} event the event that caused the stop + */ + if (e.target !== vakata_dnd.target) { + $(vakata_dnd.target).off('click.vakata'); + } + $.vakata.dnd._trigger("stop", e); + } + else { + if(e.type === "touchend" && e.target === vakata_dnd.target) { + var to = setTimeout(function () { $(e.target).click(); }, 100); + $(e.target).one('click', function() { if(to) { clearTimeout(to); } }); + } + } + $.vakata.dnd._clean(); + return false; + } + }; + }($)); + + // include the dnd plugin by default + // $.jstree.defaults.plugins.push("dnd"); +})); diff --git a/civicrm/bower_components/jstree/src/jstree.js b/civicrm/bower_components/jstree/src/jstree.js new file mode 100644 index 0000000000..a867704590 --- /dev/null +++ b/civicrm/bower_components/jstree/src/jstree.js @@ -0,0 +1,4810 @@ +/*! + * jsTree {{VERSION}} + * http://jstree.com/ + * + * Copyright (c) 2014 Ivan Bozhanov (http://vakata.com) + * + * Licensed same as jquery - under the terms of the MIT License + * http://www.opensource.org/licenses/mit-license.php + */ +/*! + * if using jslint please allow for the jQuery global and use following options: + * jslint: loopfunc: true, browser: true, ass: true, bitwise: true, continue: true, nomen: true, plusplus: true, regexp: true, unparam: true, todo: true, white: true + */ +/*jshint -W083 */ +/*globals jQuery, define, module, exports, require, window, document, postMessage */ +(function (factory) { + "use strict"; + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } + else if(typeof module !== 'undefined' && module.exports) { + module.exports = factory(require('jquery')); + } + else { + factory(jQuery); + } +}(function ($, undefined) { + "use strict"; + + // prevent another load? maybe there is a better way? + if($.jstree) { + return; + } + + /** + * ### jsTree core functionality + */ + + // internal variables + var instance_counter = 0, + ccp_node = false, + ccp_mode = false, + ccp_inst = false, + themes_loaded = [], + src = $('script:last').attr('src'), + document = window.document; // local variable is always faster to access then a global + + /** + * holds all jstree related functions and variables, including the actual class and methods to create, access and manipulate instances. + * @name $.jstree + */ + $.jstree = { + /** + * specifies the jstree version in use + * @name $.jstree.version + */ + version : '{{VERSION}}', + /** + * holds all the default options used when creating new instances + * @name $.jstree.defaults + */ + defaults : { + /** + * configure which plugins will be active on an instance. Should be an array of strings, where each element is a plugin name. The default is `[]` + * @name $.jstree.defaults.plugins + */ + plugins : [] + }, + /** + * stores all loaded jstree plugins (used internally) + * @name $.jstree.plugins + */ + plugins : {}, + path : src && src.indexOf('/') !== -1 ? src.replace(/\/[^\/]+$/,'') : '', + idregex : /[\\:&!^|()\[\]<>@*'+~#";.,=\- \/${}%?`]/g, + root : '#' + }; + + /** + * creates a jstree instance + * @name $.jstree.create(el [, options]) + * @param {DOMElement|jQuery|String} el the element to create the instance on, can be jQuery extended or a selector + * @param {Object} options options for this instance (extends `$.jstree.defaults`) + * @return {jsTree} the new instance + */ + $.jstree.create = function (el, options) { + var tmp = new $.jstree.core(++instance_counter), + opt = options; + options = $.extend(true, {}, $.jstree.defaults, options); + if(opt && opt.plugins) { + options.plugins = opt.plugins; + } + $.each(options.plugins, function (i, k) { + if(i !== 'core') { + tmp = tmp.plugin(k, options[k]); + } + }); + $(el).data('jstree', tmp); + tmp.init(el, options); + return tmp; + }; + /** + * remove all traces of jstree from the DOM and destroy all instances + * @name $.jstree.destroy() + */ + $.jstree.destroy = function () { + $('.jstree:jstree').jstree('destroy'); + $(document).off('.jstree'); + }; + /** + * the jstree class constructor, used only internally + * @private + * @name $.jstree.core(id) + * @param {Number} id this instance's index + */ + $.jstree.core = function (id) { + this._id = id; + this._cnt = 0; + this._wrk = null; + this._data = { + core : { + themes : { + name : false, + dots : false, + icons : false, + ellipsis : false + }, + selected : [], + last_error : {}, + working : false, + worker_queue : [], + focused : null + } + }; + }; + /** + * get a reference to an existing instance + * + * __Examples__ + * + * // provided a container with an ID of "tree", and a nested node with an ID of "branch" + * // all of there will return the same instance + * $.jstree.reference('tree'); + * $.jstree.reference('#tree'); + * $.jstree.reference($('#tree')); + * $.jstree.reference(document.getElementByID('tree')); + * $.jstree.reference('branch'); + * $.jstree.reference('#branch'); + * $.jstree.reference($('#branch')); + * $.jstree.reference(document.getElementByID('branch')); + * + * @name $.jstree.reference(needle) + * @param {DOMElement|jQuery|String} needle + * @return {jsTree|null} the instance or `null` if not found + */ + $.jstree.reference = function (needle) { + var tmp = null, + obj = null; + if(needle && needle.id && (!needle.tagName || !needle.nodeType)) { needle = needle.id; } + + if(!obj || !obj.length) { + try { obj = $(needle); } catch (ignore) { } + } + if(!obj || !obj.length) { + try { obj = $('#' + needle.replace($.jstree.idregex,'\\$&')); } catch (ignore) { } + } + if(obj && obj.length && (obj = obj.closest('.jstree')).length && (obj = obj.data('jstree'))) { + tmp = obj; + } + else { + $('.jstree').each(function () { + var inst = $(this).data('jstree'); + if(inst && inst._model.data[needle]) { + tmp = inst; + return false; + } + }); + } + return tmp; + }; + /** + * Create an instance, get an instance or invoke a command on a instance. + * + * If there is no instance associated with the current node a new one is created and `arg` is used to extend `$.jstree.defaults` for this new instance. There would be no return value (chaining is not broken). + * + * If there is an existing instance and `arg` is a string the command specified by `arg` is executed on the instance, with any additional arguments passed to the function. If the function returns a value it will be returned (chaining could break depending on function). + * + * If there is an existing instance and `arg` is not a string the instance itself is returned (similar to `$.jstree.reference`). + * + * In any other case - nothing is returned and chaining is not broken. + * + * __Examples__ + * + * $('#tree1').jstree(); // creates an instance + * $('#tree2').jstree({ plugins : [] }); // create an instance with some options + * $('#tree1').jstree('open_node', '#branch_1'); // call a method on an existing instance, passing additional arguments + * $('#tree2').jstree(); // get an existing instance (or create an instance) + * $('#tree2').jstree(true); // get an existing instance (will not create new instance) + * $('#branch_1').jstree().select_node('#branch_1'); // get an instance (using a nested element and call a method) + * + * @name $().jstree([arg]) + * @param {String|Object} arg + * @return {Mixed} + */ + $.fn.jstree = function (arg) { + // check for string argument + var is_method = (typeof arg === 'string'), + args = Array.prototype.slice.call(arguments, 1), + result = null; + if(arg === true && !this.length) { return false; } + this.each(function () { + // get the instance (if there is one) and method (if it exists) + var instance = $.jstree.reference(this), + method = is_method && instance ? instance[arg] : null; + // if calling a method, and method is available - execute on the instance + result = is_method && method ? + method.apply(instance, args) : + null; + // if there is no instance and no method is being called - create one + if(!instance && !is_method && (arg === undefined || $.isPlainObject(arg))) { + $.jstree.create(this, arg); + } + // if there is an instance and no method is called - return the instance + if( (instance && !is_method) || arg === true ) { + result = instance || false; + } + // if there was a method call which returned a result - break and return the value + if(result !== null && result !== undefined) { + return false; + } + }); + // if there was a method call with a valid return value - return that, otherwise continue the chain + return result !== null && result !== undefined ? + result : this; + }; + /** + * used to find elements containing an instance + * + * __Examples__ + * + * $('div:jstree').each(function () { + * $(this).jstree('destroy'); + * }); + * + * @name $(':jstree') + * @return {jQuery} + */ + $.expr.pseudos.jstree = $.expr.createPseudo(function(search) { + return function(a) { + return $(a).hasClass('jstree') && + $(a).data('jstree') !== undefined; + }; + }); + + /** + * stores all defaults for the core + * @name $.jstree.defaults.core + */ + $.jstree.defaults.core = { + /** + * data configuration + * + * If left as `false` the HTML inside the jstree container element is used to populate the tree (that should be an unordered list with list items). + * + * You can also pass in a HTML string or a JSON array here. + * + * It is possible to pass in a standard jQuery-like AJAX config and jstree will automatically determine if the response is JSON or HTML and use that to populate the tree. + * In addition to the standard jQuery ajax options here you can suppy functions for `data` and `url`, the functions will be run in the current instance's scope and a param will be passed indicating which node is being loaded, the return value of those functions will be used. + * + * The last option is to specify a function, that function will receive the node being loaded as argument and a second param which is a function which should be called with the result. + * + * __Examples__ + * + * // AJAX + * $('#tree').jstree({ + * 'core' : { + * 'data' : { + * 'url' : '/get/children/', + * 'data' : function (node) { + * return { 'id' : node.id }; + * } + * } + * }); + * + * // direct data + * $('#tree').jstree({ + * 'core' : { + * 'data' : [ + * 'Simple root node', + * { + * 'id' : 'node_2', + * 'text' : 'Root node with options', + * 'state' : { 'opened' : true, 'selected' : true }, + * 'children' : [ { 'text' : 'Child 1' }, 'Child 2'] + * } + * ] + * } + * }); + * + * // function + * $('#tree').jstree({ + * 'core' : { + * 'data' : function (obj, callback) { + * callback.call(this, ['Root 1', 'Root 2']); + * } + * }); + * + * @name $.jstree.defaults.core.data + */ + data : false, + /** + * configure the various strings used throughout the tree + * + * You can use an object where the key is the string you need to replace and the value is your replacement. + * Another option is to specify a function which will be called with an argument of the needed string and should return the replacement. + * If left as `false` no replacement is made. + * + * __Examples__ + * + * $('#tree').jstree({ + * 'core' : { + * 'strings' : { + * 'Loading ...' : 'Please wait ...' + * } + * } + * }); + * + * @name $.jstree.defaults.core.strings + */ + strings : false, + /** + * determines what happens when a user tries to modify the structure of the tree + * If left as `false` all operations like create, rename, delete, move or copy are prevented. + * You can set this to `true` to allow all interactions or use a function to have better control. + * + * __Examples__ + * + * $('#tree').jstree({ + * 'core' : { + * 'check_callback' : function (operation, node, node_parent, node_position, more) { + * // operation can be 'create_node', 'rename_node', 'delete_node', 'move_node' or 'copy_node' + * // in case of 'rename_node' node_position is filled with the new node name + * return operation === 'rename_node' ? true : false; + * } + * } + * }); + * + * @name $.jstree.defaults.core.check_callback + */ + check_callback : false, + /** + * a callback called with a single object parameter in the instance's scope when something goes wrong (operation prevented, ajax failed, etc) + * @name $.jstree.defaults.core.error + */ + error : $.noop, + /** + * the open / close animation duration in milliseconds - set this to `false` to disable the animation (default is `200`) + * @name $.jstree.defaults.core.animation + */ + animation : 200, + /** + * a boolean indicating if multiple nodes can be selected + * @name $.jstree.defaults.core.multiple + */ + multiple : true, + /** + * theme configuration object + * @name $.jstree.defaults.core.themes + */ + themes : { + /** + * the name of the theme to use (if left as `false` the default theme is used) + * @name $.jstree.defaults.core.themes.name + */ + name : false, + /** + * the URL of the theme's CSS file, leave this as `false` if you have manually included the theme CSS (recommended). You can set this to `true` too which will try to autoload the theme. + * @name $.jstree.defaults.core.themes.url + */ + url : false, + /** + * the location of all jstree themes - only used if `url` is set to `true` + * @name $.jstree.defaults.core.themes.dir + */ + dir : false, + /** + * a boolean indicating if connecting dots are shown + * @name $.jstree.defaults.core.themes.dots + */ + dots : true, + /** + * a boolean indicating if node icons are shown + * @name $.jstree.defaults.core.themes.icons + */ + icons : true, + /** + * a boolean indicating if node ellipsis should be shown - this only works with a fixed with on the container + * @name $.jstree.defaults.core.themes.ellipsis + */ + ellipsis : false, + /** + * a boolean indicating if the tree background is striped + * @name $.jstree.defaults.core.themes.stripes + */ + stripes : false, + /** + * a string (or boolean `false`) specifying the theme variant to use (if the theme supports variants) + * @name $.jstree.defaults.core.themes.variant + */ + variant : false, + /** + * a boolean specifying if a reponsive version of the theme should kick in on smaller screens (if the theme supports it). Defaults to `false`. + * @name $.jstree.defaults.core.themes.responsive + */ + responsive : false + }, + /** + * if left as `true` all parents of all selected nodes will be opened once the tree loads (so that all selected nodes are visible to the user) + * @name $.jstree.defaults.core.expand_selected_onload + */ + expand_selected_onload : true, + /** + * if left as `true` web workers will be used to parse incoming JSON data where possible, so that the UI will not be blocked by large requests. Workers are however about 30% slower. Defaults to `true` + * @name $.jstree.defaults.core.worker + */ + worker : true, + /** + * Force node text to plain text (and escape HTML). Defaults to `false` + * @name $.jstree.defaults.core.force_text + */ + force_text : false, + /** + * Should the node should be toggled if the text is double clicked . Defaults to `true` + * @name $.jstree.defaults.core.dblclick_toggle + */ + dblclick_toggle : true + }; + $.jstree.core.prototype = { + /** + * used to decorate an instance with a plugin. Used internally. + * @private + * @name plugin(deco [, opts]) + * @param {String} deco the plugin to decorate with + * @param {Object} opts options for the plugin + * @return {jsTree} + */ + plugin : function (deco, opts) { + var Child = $.jstree.plugins[deco]; + if(Child) { + this._data[deco] = {}; + Child.prototype = this; + return new Child(opts, this); + } + return this; + }, + /** + * initialize the instance. Used internally. + * @private + * @name init(el, optons) + * @param {DOMElement|jQuery|String} el the element we are transforming + * @param {Object} options options for this instance + * @trigger init.jstree, loading.jstree, loaded.jstree, ready.jstree, changed.jstree + */ + init : function (el, options) { + this._model = { + data : {}, + changed : [], + force_full_redraw : false, + redraw_timeout : false, + default_state : { + loaded : true, + opened : false, + selected : false, + disabled : false + } + }; + this._model.data[$.jstree.root] = { + id : $.jstree.root, + parent : null, + parents : [], + children : [], + children_d : [], + state : { loaded : false } + }; + + this.element = $(el).addClass('jstree jstree-' + this._id); + this.settings = options; + + this._data.core.ready = false; + this._data.core.loaded = false; + this._data.core.rtl = (this.element.css("direction") === "rtl"); + this.element[this._data.core.rtl ? 'addClass' : 'removeClass']("jstree-rtl"); + this.element.attr('role','tree'); + if(this.settings.core.multiple) { + this.element.attr('aria-multiselectable', true); + } + if(!this.element.attr('tabindex')) { + this.element.attr('tabindex','0'); + } + + this.bind(); + /** + * triggered after all events are bound + * @event + * @name init.jstree + */ + this.trigger("init"); + + this._data.core.original_container_html = this.element.find(" > ul > li").clone(true); + this._data.core.original_container_html + .find("li").addBack() + .contents().filter(function() { + return this.nodeType === 3 && (!this.nodeValue || /^\s+$/.test(this.nodeValue)); + }) + .remove(); + this.element.html("<"+"ul class='jstree-container-ul jstree-children' role='group'><"+"li id='j"+this._id+"_loading' class='jstree-initial-node jstree-loading jstree-leaf jstree-last' role='tree-item'><i class='jstree-icon jstree-ocl'></i><"+"a class='jstree-anchor' href='#'><i class='jstree-icon jstree-themeicon-hidden'></i>" + this.get_string("Loading ...") + "</a></li></ul>"); + this.element.attr('aria-activedescendant','j' + this._id + '_loading'); + this._data.core.li_height = this.get_container_ul().children("li").first().height() || 24; + this._data.core.node = this._create_prototype_node(); + /** + * triggered after the loading text is shown and before loading starts + * @event + * @name loading.jstree + */ + this.trigger("loading"); + this.load_node($.jstree.root); + }, + /** + * destroy an instance + * @name destroy() + * @param {Boolean} keep_html if not set to `true` the container will be emptied, otherwise the current DOM elements will be kept intact + */ + destroy : function (keep_html) { + if(this._wrk) { + try { + window.URL.revokeObjectURL(this._wrk); + this._wrk = null; + } + catch (ignore) { } + } + if(!keep_html) { this.element.empty(); } + this.teardown(); + }, + /** + * Create prototype node + */ + _create_prototype_node : function () { + var _node = document.createElement('LI'), _temp1, _temp2; + _node.setAttribute('role', 'treeitem'); + _temp1 = document.createElement('I'); + _temp1.className = 'jstree-icon jstree-ocl'; + _temp1.setAttribute('role', 'presentation'); + _node.appendChild(_temp1); + _temp1 = document.createElement('A'); + _temp1.className = 'jstree-anchor'; + _temp1.setAttribute('href','#'); + _temp1.setAttribute('tabindex','-1'); + _temp2 = document.createElement('I'); + _temp2.className = 'jstree-icon jstree-themeicon'; + _temp2.setAttribute('role', 'presentation'); + _temp1.appendChild(_temp2); + _node.appendChild(_temp1); + _temp1 = _temp2 = null; + + return _node; + }, + /** + * part of the destroying of an instance. Used internally. + * @private + * @name teardown() + */ + teardown : function () { + this.unbind(); + this.element + .removeClass('jstree') + .removeData('jstree') + .find("[class^='jstree']") + .addBack() + .attr("class", function () { return this.className.replace(/jstree[^ ]*|$/ig,''); }); + this.element = null; + }, + /** + * bind all events. Used internally. + * @private + * @name bind() + */ + bind : function () { + var word = '', + tout = null, + was_click = 0; + this.element + .on("dblclick.jstree", function (e) { + if(e.target.tagName && e.target.tagName.toLowerCase() === "input") { return true; } + if(document.selection && document.selection.empty) { + document.selection.empty(); + } + else { + if(window.getSelection) { + var sel = window.getSelection(); + try { + sel.removeAllRanges(); + sel.collapse(); + } catch (ignore) { } + } + } + }) + .on("mousedown.jstree", $.proxy(function (e) { + if(e.target === this.element[0]) { + e.preventDefault(); // prevent losing focus when clicking scroll arrows (FF, Chrome) + was_click = +(new Date()); // ie does not allow to prevent losing focus + } + }, this)) + .on("mousedown.jstree", ".jstree-ocl", function (e) { + e.preventDefault(); // prevent any node inside from losing focus when clicking the open/close icon + }) + .on("click.jstree", ".jstree-ocl", $.proxy(function (e) { + this.toggle_node(e.target); + }, this)) + .on("dblclick.jstree", ".jstree-anchor", $.proxy(function (e) { + if(e.target.tagName && e.target.tagName.toLowerCase() === "input") { return true; } + if(this.settings.core.dblclick_toggle) { + this.toggle_node(e.target); + } + }, this)) + .on("click.jstree", ".jstree-anchor", $.proxy(function (e) { + e.preventDefault(); + if(e.currentTarget !== document.activeElement) { $(e.currentTarget).focus(); } + this.activate_node(e.currentTarget, e); + }, this)) + .on('keydown.jstree', '.jstree-anchor', $.proxy(function (e) { + if(e.target.tagName && e.target.tagName.toLowerCase() === "input") { return true; } + if(e.which !== 32 && e.which !== 13 && (e.shiftKey || e.ctrlKey || e.altKey || e.metaKey)) { return true; } + var o = null; + if(this._data.core.rtl) { + if(e.which === 37) { e.which = 39; } + else if(e.which === 39) { e.which = 37; } + } + switch(e.which) { + case 32: // aria defines space only with Ctrl + if(e.ctrlKey) { + e.type = "click"; + $(e.currentTarget).trigger(e); + } + break; + case 13: // enter + e.type = "click"; + $(e.currentTarget).trigger(e); + break; + case 37: // left + e.preventDefault(); + if(this.is_open(e.currentTarget)) { + this.close_node(e.currentTarget); + } + else { + o = this.get_parent(e.currentTarget); + if(o && o.id !== $.jstree.root) { this.get_node(o, true).children('.jstree-anchor').focus(); } + } + break; + case 38: // up + e.preventDefault(); + o = this.get_prev_dom(e.currentTarget); + if(o && o.length) { o.children('.jstree-anchor').focus(); } + break; + case 39: // right + e.preventDefault(); + if(this.is_closed(e.currentTarget)) { + this.open_node(e.currentTarget, function (o) { this.get_node(o, true).children('.jstree-anchor').focus(); }); + } + else if (this.is_open(e.currentTarget)) { + o = this.get_node(e.currentTarget, true).children('.jstree-children')[0]; + if(o) { $(this._firstChild(o)).children('.jstree-anchor').focus(); } + } + break; + case 40: // down + e.preventDefault(); + o = this.get_next_dom(e.currentTarget); + if(o && o.length) { o.children('.jstree-anchor').focus(); } + break; + case 106: // aria defines * on numpad as open_all - not very common + this.open_all(); + break; + case 36: // home + e.preventDefault(); + o = this._firstChild(this.get_container_ul()[0]); + if(o) { $(o).children('.jstree-anchor').filter(':visible').focus(); } + break; + case 35: // end + e.preventDefault(); + this.element.find('.jstree-anchor').filter(':visible').last().focus(); + break; + case 113: // f2 - safe to include - if check_callback is false it will fail + e.preventDefault(); + this.edit(e.currentTarget); + break; + default: + break; + /*! + // delete + case 46: + e.preventDefault(); + o = this.get_node(e.currentTarget); + if(o && o.id && o.id !== $.jstree.root) { + o = this.is_selected(o) ? this.get_selected() : o; + this.delete_node(o); + } + break; + + */ + } + }, this)) + .on("load_node.jstree", $.proxy(function (e, data) { + if(data.status) { + if(data.node.id === $.jstree.root && !this._data.core.loaded) { + this._data.core.loaded = true; + if(this._firstChild(this.get_container_ul()[0])) { + this.element.attr('aria-activedescendant',this._firstChild(this.get_container_ul()[0]).id); + } + /** + * triggered after the root node is loaded for the first time + * @event + * @name loaded.jstree + */ + this.trigger("loaded"); + } + if(!this._data.core.ready) { + setTimeout($.proxy(function() { + if(this.element && !this.get_container_ul().find('.jstree-loading').length) { + this._data.core.ready = true; + if(this._data.core.selected.length) { + if(this.settings.core.expand_selected_onload) { + var tmp = [], i, j; + for(i = 0, j = this._data.core.selected.length; i < j; i++) { + tmp = tmp.concat(this._model.data[this._data.core.selected[i]].parents); + } + tmp = $.vakata.array_unique(tmp); + for(i = 0, j = tmp.length; i < j; i++) { + this.open_node(tmp[i], false, 0); + } + } + this.trigger('changed', { 'action' : 'ready', 'selected' : this._data.core.selected }); + } + /** + * triggered after all nodes are finished loading + * @event + * @name ready.jstree + */ + this.trigger("ready"); + } + }, this), 0); + } + } + }, this)) + // quick searching when the tree is focused + .on('keypress.jstree', $.proxy(function (e) { + if(e.target.tagName && e.target.tagName.toLowerCase() === "input") { return true; } + if(tout) { clearTimeout(tout); } + tout = setTimeout(function () { + word = ''; + }, 500); + + var chr = String.fromCharCode(e.which).toLowerCase(), + col = this.element.find('.jstree-anchor').filter(':visible'), + ind = col.index(document.activeElement) || 0, + end = false; + word += chr; + + // match for whole word from current node down (including the current node) + if(word.length > 1) { + col.slice(ind).each($.proxy(function (i, v) { + if($(v).text().toLowerCase().indexOf(word) === 0) { + $(v).focus(); + end = true; + return false; + } + }, this)); + if(end) { return; } + + // match for whole word from the beginning of the tree + col.slice(0, ind).each($.proxy(function (i, v) { + if($(v).text().toLowerCase().indexOf(word) === 0) { + $(v).focus(); + end = true; + return false; + } + }, this)); + if(end) { return; } + } + // list nodes that start with that letter (only if word consists of a single char) + if(new RegExp('^' + chr.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') + '+$').test(word)) { + // search for the next node starting with that letter + col.slice(ind + 1).each($.proxy(function (i, v) { + if($(v).text().toLowerCase().charAt(0) === chr) { + $(v).focus(); + end = true; + return false; + } + }, this)); + if(end) { return; } + + // search from the beginning + col.slice(0, ind + 1).each($.proxy(function (i, v) { + if($(v).text().toLowerCase().charAt(0) === chr) { + $(v).focus(); + end = true; + return false; + } + }, this)); + if(end) { return; } + } + }, this)) + // THEME RELATED + .on("init.jstree", $.proxy(function () { + var s = this.settings.core.themes; + this._data.core.themes.dots = s.dots; + this._data.core.themes.stripes = s.stripes; + this._data.core.themes.icons = s.icons; + this._data.core.themes.ellipsis = s.ellipsis; + this.set_theme(s.name || "default", s.url); + this.set_theme_variant(s.variant); + }, this)) + .on("loading.jstree", $.proxy(function () { + this[ this._data.core.themes.dots ? "show_dots" : "hide_dots" ](); + this[ this._data.core.themes.icons ? "show_icons" : "hide_icons" ](); + this[ this._data.core.themes.stripes ? "show_stripes" : "hide_stripes" ](); + this[ this._data.core.themes.ellipsis ? "show_ellipsis" : "hide_ellipsis" ](); + }, this)) + .on('blur.jstree', '.jstree-anchor', $.proxy(function (e) { + this._data.core.focused = null; + $(e.currentTarget).filter('.jstree-hovered').mouseleave(); + this.element.attr('tabindex', '0'); + }, this)) + .on('focus.jstree', '.jstree-anchor', $.proxy(function (e) { + var tmp = this.get_node(e.currentTarget); + if(tmp && tmp.id) { + this._data.core.focused = tmp.id; + } + this.element.find('.jstree-hovered').not(e.currentTarget).mouseleave(); + $(e.currentTarget).mouseenter(); + this.element.attr('tabindex', '-1'); + }, this)) + .on('focus.jstree', $.proxy(function () { + if(+(new Date()) - was_click > 500 && !this._data.core.focused) { + was_click = 0; + var act = this.get_node(this.element.attr('aria-activedescendant'), true); + if(act) { + act.find('> .jstree-anchor').focus(); + } + } + }, this)) + .on('mouseenter.jstree', '.jstree-anchor', $.proxy(function (e) { + this.hover_node(e.currentTarget); + }, this)) + .on('mouseleave.jstree', '.jstree-anchor', $.proxy(function (e) { + this.dehover_node(e.currentTarget); + }, this)); + }, + /** + * part of the destroying of an instance. Used internally. + * @private + * @name unbind() + */ + unbind : function () { + this.element.off('.jstree'); + $(document).off('.jstree-' + this._id); + }, + /** + * trigger an event. Used internally. + * @private + * @name trigger(ev [, data]) + * @param {String} ev the name of the event to trigger + * @param {Object} data additional data to pass with the event + */ + trigger : function (ev, data) { + if(!data) { + data = {}; + } + data.instance = this; + this.element.triggerHandler(ev.replace('.jstree','') + '.jstree', data); + }, + /** + * returns the jQuery extended instance container + * @name get_container() + * @return {jQuery} + */ + get_container : function () { + return this.element; + }, + /** + * returns the jQuery extended main UL node inside the instance container. Used internally. + * @private + * @name get_container_ul() + * @return {jQuery} + */ + get_container_ul : function () { + return this.element.children(".jstree-children").first(); + }, + /** + * gets string replacements (localization). Used internally. + * @private + * @name get_string(key) + * @param {String} key + * @return {String} + */ + get_string : function (key) { + var a = this.settings.core.strings; + if($.isFunction(a)) { return a.call(this, key); } + if(a && a[key]) { return a[key]; } + return key; + }, + /** + * gets the first child of a DOM node. Used internally. + * @private + * @name _firstChild(dom) + * @param {DOMElement} dom + * @return {DOMElement} + */ + _firstChild : function (dom) { + dom = dom ? dom.firstChild : null; + while(dom !== null && dom.nodeType !== 1) { + dom = dom.nextSibling; + } + return dom; + }, + /** + * gets the next sibling of a DOM node. Used internally. + * @private + * @name _nextSibling(dom) + * @param {DOMElement} dom + * @return {DOMElement} + */ + _nextSibling : function (dom) { + dom = dom ? dom.nextSibling : null; + while(dom !== null && dom.nodeType !== 1) { + dom = dom.nextSibling; + } + return dom; + }, + /** + * gets the previous sibling of a DOM node. Used internally. + * @private + * @name _previousSibling(dom) + * @param {DOMElement} dom + * @return {DOMElement} + */ + _previousSibling : function (dom) { + dom = dom ? dom.previousSibling : null; + while(dom !== null && dom.nodeType !== 1) { + dom = dom.previousSibling; + } + return dom; + }, + /** + * get the JSON representation of a node (or the actual jQuery extended DOM node) by using any input (child DOM element, ID string, selector, etc) + * @name get_node(obj [, as_dom]) + * @param {mixed} obj + * @param {Boolean} as_dom + * @return {Object|jQuery} + */ + get_node : function (obj, as_dom) { + if(obj && obj.id) { + obj = obj.id; + } + var dom; + try { + if(this._model.data[obj]) { + obj = this._model.data[obj]; + } + else if(typeof obj === "string" && this._model.data[obj.replace(/^#/, '')]) { + obj = this._model.data[obj.replace(/^#/, '')]; + } + else if(typeof obj === "string" && (dom = $('#' + obj.replace($.jstree.idregex,'\\$&'), this.element)).length && this._model.data[dom.closest('.jstree-node').attr('id')]) { + obj = this._model.data[dom.closest('.jstree-node').attr('id')]; + } + else if((dom = $(obj, this.element)).length && this._model.data[dom.closest('.jstree-node').attr('id')]) { + obj = this._model.data[dom.closest('.jstree-node').attr('id')]; + } + else if((dom = $(obj, this.element)).length && dom.hasClass('jstree')) { + obj = this._model.data[$.jstree.root]; + } + else { + return false; + } + + if(as_dom) { + obj = obj.id === $.jstree.root ? this.element : $('#' + obj.id.replace($.jstree.idregex,'\\$&'), this.element); + } + return obj; + } catch (ex) { return false; } + }, + /** + * get the path to a node, either consisting of node texts, or of node IDs, optionally glued together (otherwise an array) + * @name get_path(obj [, glue, ids]) + * @param {mixed} obj the node + * @param {String} glue if you want the path as a string - pass the glue here (for example '/'), if a falsy value is supplied here, an array is returned + * @param {Boolean} ids if set to true build the path using ID, otherwise node text is used + * @return {mixed} + */ + get_path : function (obj, glue, ids) { + obj = obj.parents ? obj : this.get_node(obj); + if(!obj || obj.id === $.jstree.root || !obj.parents) { + return false; + } + var i, j, p = []; + p.push(ids ? obj.id : obj.text); + for(i = 0, j = obj.parents.length; i < j; i++) { + p.push(ids ? obj.parents[i] : this.get_text(obj.parents[i])); + } + p = p.reverse().slice(1); + return glue ? p.join(glue) : p; + }, + /** + * get the next visible node that is below the `obj` node. If `strict` is set to `true` only sibling nodes are returned. + * @name get_next_dom(obj [, strict]) + * @param {mixed} obj + * @param {Boolean} strict + * @return {jQuery} + */ + get_next_dom : function (obj, strict) { + var tmp; + obj = this.get_node(obj, true); + if(obj[0] === this.element[0]) { + tmp = this._firstChild(this.get_container_ul()[0]); + while (tmp && tmp.offsetHeight === 0) { + tmp = this._nextSibling(tmp); + } + return tmp ? $(tmp) : false; + } + if(!obj || !obj.length) { + return false; + } + if(strict) { + tmp = obj[0]; + do { + tmp = this._nextSibling(tmp); + } while (tmp && tmp.offsetHeight === 0); + return tmp ? $(tmp) : false; + } + if(obj.hasClass("jstree-open")) { + tmp = this._firstChild(obj.children('.jstree-children')[0]); + while (tmp && tmp.offsetHeight === 0) { + tmp = this._nextSibling(tmp); + } + if(tmp !== null) { + return $(tmp); + } + } + tmp = obj[0]; + do { + tmp = this._nextSibling(tmp); + } while (tmp && tmp.offsetHeight === 0); + if(tmp !== null) { + return $(tmp); + } + return obj.parentsUntil(".jstree",".jstree-node").nextAll(".jstree-node:visible").first(); + }, + /** + * get the previous visible node that is above the `obj` node. If `strict` is set to `true` only sibling nodes are returned. + * @name get_prev_dom(obj [, strict]) + * @param {mixed} obj + * @param {Boolean} strict + * @return {jQuery} + */ + get_prev_dom : function (obj, strict) { + var tmp; + obj = this.get_node(obj, true); + if(obj[0] === this.element[0]) { + tmp = this.get_container_ul()[0].lastChild; + while (tmp && tmp.offsetHeight === 0) { + tmp = this._previousSibling(tmp); + } + return tmp ? $(tmp) : false; + } + if(!obj || !obj.length) { + return false; + } + if(strict) { + tmp = obj[0]; + do { + tmp = this._previousSibling(tmp); + } while (tmp && tmp.offsetHeight === 0); + return tmp ? $(tmp) : false; + } + tmp = obj[0]; + do { + tmp = this._previousSibling(tmp); + } while (tmp && tmp.offsetHeight === 0); + if(tmp !== null) { + obj = $(tmp); + while(obj.hasClass("jstree-open")) { + obj = obj.children(".jstree-children").first().children(".jstree-node:visible:last"); + } + return obj; + } + tmp = obj[0].parentNode.parentNode; + return tmp && tmp.className && tmp.className.indexOf('jstree-node') !== -1 ? $(tmp) : false; + }, + /** + * get the parent ID of a node + * @name get_parent(obj) + * @param {mixed} obj + * @return {String} + */ + get_parent : function (obj) { + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { + return false; + } + return obj.parent; + }, + /** + * get a jQuery collection of all the children of a node (node must be rendered) + * @name get_children_dom(obj) + * @param {mixed} obj + * @return {jQuery} + */ + get_children_dom : function (obj) { + obj = this.get_node(obj, true); + if(obj[0] === this.element[0]) { + return this.get_container_ul().children(".jstree-node"); + } + if(!obj || !obj.length) { + return false; + } + return obj.children(".jstree-children").children(".jstree-node"); + }, + /** + * checks if a node has children + * @name is_parent(obj) + * @param {mixed} obj + * @return {Boolean} + */ + is_parent : function (obj) { + obj = this.get_node(obj); + return obj && (obj.state.loaded === false || obj.children.length > 0); + }, + /** + * checks if a node is loaded (its children are available) + * @name is_loaded(obj) + * @param {mixed} obj + * @return {Boolean} + */ + is_loaded : function (obj) { + obj = this.get_node(obj); + return obj && obj.state.loaded; + }, + /** + * check if a node is currently loading (fetching children) + * @name is_loading(obj) + * @param {mixed} obj + * @return {Boolean} + */ + is_loading : function (obj) { + obj = this.get_node(obj); + return obj && obj.state && obj.state.loading; + }, + /** + * check if a node is opened + * @name is_open(obj) + * @param {mixed} obj + * @return {Boolean} + */ + is_open : function (obj) { + obj = this.get_node(obj); + return obj && obj.state.opened; + }, + /** + * check if a node is in a closed state + * @name is_closed(obj) + * @param {mixed} obj + * @return {Boolean} + */ + is_closed : function (obj) { + obj = this.get_node(obj); + return obj && this.is_parent(obj) && !obj.state.opened; + }, + /** + * check if a node has no children + * @name is_leaf(obj) + * @param {mixed} obj + * @return {Boolean} + */ + is_leaf : function (obj) { + return !this.is_parent(obj); + }, + /** + * loads a node (fetches its children using the `core.data` setting). Multiple nodes can be passed to by using an array. + * @name load_node(obj [, callback]) + * @param {mixed} obj + * @param {function} callback a function to be executed once loading is complete, the function is executed in the instance's scope and receives two arguments - the node and a boolean status + * @return {Boolean} + * @trigger load_node.jstree + */ + load_node : function (obj, callback) { + var k, l, i, j, c; + if($.isArray(obj)) { + this._load_nodes(obj.slice(), callback); + return true; + } + obj = this.get_node(obj); + if(!obj) { + if(callback) { callback.call(this, obj, false); } + return false; + } + // if(obj.state.loading) { } // the node is already loading - just wait for it to load and invoke callback? but if called implicitly it should be loaded again? + if(obj.state.loaded) { + obj.state.loaded = false; + for(i = 0, j = obj.parents.length; i < j; i++) { + this._model.data[obj.parents[i]].children_d = $.vakata.array_filter(this._model.data[obj.parents[i]].children_d, function (v) { + return $.inArray(v, obj.children_d) === -1; + }); + } + for(k = 0, l = obj.children_d.length; k < l; k++) { + if(this._model.data[obj.children_d[k]].state.selected) { + c = true; + } + delete this._model.data[obj.children_d[k]]; + } + if (c) { + this._data.core.selected = $.vakata.array_filter(this._data.core.selected, function (v) { + return $.inArray(v, obj.children_d) === -1; + }); + } + obj.children = []; + obj.children_d = []; + if(c) { + this.trigger('changed', { 'action' : 'load_node', 'node' : obj, 'selected' : this._data.core.selected }); + } + } + obj.state.failed = false; + obj.state.loading = true; + this.get_node(obj, true).addClass("jstree-loading").attr('aria-busy',true); + this._load_node(obj, $.proxy(function (status) { + obj = this._model.data[obj.id]; + obj.state.loading = false; + obj.state.loaded = status; + obj.state.failed = !obj.state.loaded; + var dom = this.get_node(obj, true), i = 0, j = 0, m = this._model.data, has_children = false; + for(i = 0, j = obj.children.length; i < j; i++) { + if(m[obj.children[i]] && !m[obj.children[i]].state.hidden) { + has_children = true; + break; + } + } + if(obj.state.loaded && dom && dom.length) { + dom.removeClass('jstree-closed jstree-open jstree-leaf'); + if (!has_children) { + dom.addClass('jstree-leaf'); + } + else { + if (obj.id !== '#') { + dom.addClass(obj.state.opened ? 'jstree-open' : 'jstree-closed'); + } + } + } + dom.removeClass("jstree-loading").attr('aria-busy',false); + /** + * triggered after a node is loaded + * @event + * @name load_node.jstree + * @param {Object} node the node that was loading + * @param {Boolean} status was the node loaded successfully + */ + this.trigger('load_node', { "node" : obj, "status" : status }); + if(callback) { + callback.call(this, obj, status); + } + }, this)); + return true; + }, + /** + * load an array of nodes (will also load unavailable nodes as soon as the appear in the structure). Used internally. + * @private + * @name _load_nodes(nodes [, callback]) + * @param {array} nodes + * @param {function} callback a function to be executed once loading is complete, the function is executed in the instance's scope and receives one argument - the array passed to _load_nodes + */ + _load_nodes : function (nodes, callback, is_callback, force_reload) { + var r = true, + c = function () { this._load_nodes(nodes, callback, true); }, + m = this._model.data, i, j, tmp = []; + for(i = 0, j = nodes.length; i < j; i++) { + if(m[nodes[i]] && ( (!m[nodes[i]].state.loaded && !m[nodes[i]].state.failed) || (!is_callback && force_reload) )) { + if(!this.is_loading(nodes[i])) { + this.load_node(nodes[i], c); + } + r = false; + } + } + if(r) { + for(i = 0, j = nodes.length; i < j; i++) { + if(m[nodes[i]] && m[nodes[i]].state.loaded) { + tmp.push(nodes[i]); + } + } + if(callback && !callback.done) { + callback.call(this, tmp); + callback.done = true; + } + } + }, + /** + * loads all unloaded nodes + * @name load_all([obj, callback]) + * @param {mixed} obj the node to load recursively, omit to load all nodes in the tree + * @param {function} callback a function to be executed once loading all the nodes is complete, + * @trigger load_all.jstree + */ + load_all : function (obj, callback) { + if(!obj) { obj = $.jstree.root; } + obj = this.get_node(obj); + if(!obj) { return false; } + var to_load = [], + m = this._model.data, + c = m[obj.id].children_d, + i, j; + if(obj.state && !obj.state.loaded) { + to_load.push(obj.id); + } + for(i = 0, j = c.length; i < j; i++) { + if(m[c[i]] && m[c[i]].state && !m[c[i]].state.loaded) { + to_load.push(c[i]); + } + } + if(to_load.length) { + this._load_nodes(to_load, function () { + this.load_all(obj, callback); + }); + } + else { + /** + * triggered after a load_all call completes + * @event + * @name load_all.jstree + * @param {Object} node the recursively loaded node + */ + if(callback) { callback.call(this, obj); } + this.trigger('load_all', { "node" : obj }); + } + }, + /** + * handles the actual loading of a node. Used only internally. + * @private + * @name _load_node(obj [, callback]) + * @param {mixed} obj + * @param {function} callback a function to be executed once loading is complete, the function is executed in the instance's scope and receives one argument - a boolean status + * @return {Boolean} + */ + _load_node : function (obj, callback) { + var s = this.settings.core.data, t; + var notTextOrCommentNode = function notTextOrCommentNode () { + return this.nodeType !== 3 && this.nodeType !== 8; + }; + // use original HTML + if(!s) { + if(obj.id === $.jstree.root) { + return this._append_html_data(obj, this._data.core.original_container_html.clone(true), function (status) { + callback.call(this, status); + }); + } + else { + return callback.call(this, false); + } + // return callback.call(this, obj.id === $.jstree.root ? this._append_html_data(obj, this._data.core.original_container_html.clone(true)) : false); + } + if($.isFunction(s)) { + return s.call(this, obj, $.proxy(function (d) { + if(d === false) { + callback.call(this, false); + } + else { + this[typeof d === 'string' ? '_append_html_data' : '_append_json_data'](obj, typeof d === 'string' ? $($.parseHTML(d)).filter(notTextOrCommentNode) : d, function (status) { + callback.call(this, status); + }); + } + // return d === false ? callback.call(this, false) : callback.call(this, this[typeof d === 'string' ? '_append_html_data' : '_append_json_data'](obj, typeof d === 'string' ? $(d) : d)); + }, this)); + } + if(typeof s === 'object') { + if(s.url) { + s = $.extend(true, {}, s); + if($.isFunction(s.url)) { + s.url = s.url.call(this, obj); + } + if($.isFunction(s.data)) { + s.data = s.data.call(this, obj); + } + return $.ajax(s) + .done($.proxy(function (d,t,x) { + var type = x.getResponseHeader('Content-Type'); + if((type && type.indexOf('json') !== -1) || typeof d === "object") { + return this._append_json_data(obj, d, function (status) { callback.call(this, status); }); + //return callback.call(this, this._append_json_data(obj, d)); + } + if((type && type.indexOf('html') !== -1) || typeof d === "string") { + return this._append_html_data(obj, $($.parseHTML(d)).filter(notTextOrCommentNode), function (status) { callback.call(this, status); }); + // return callback.call(this, this._append_html_data(obj, $(d))); + } + this._data.core.last_error = { 'error' : 'ajax', 'plugin' : 'core', 'id' : 'core_04', 'reason' : 'Could not load node', 'data' : JSON.stringify({ 'id' : obj.id, 'xhr' : x }) }; + this.settings.core.error.call(this, this._data.core.last_error); + return callback.call(this, false); + }, this)) + .fail($.proxy(function (f) { + callback.call(this, false); + this._data.core.last_error = { 'error' : 'ajax', 'plugin' : 'core', 'id' : 'core_04', 'reason' : 'Could not load node', 'data' : JSON.stringify({ 'id' : obj.id, 'xhr' : f }) }; + this.settings.core.error.call(this, this._data.core.last_error); + }, this)); + } + t = ($.isArray(s) || $.isPlainObject(s)) ? JSON.parse(JSON.stringify(s)) : s; + if(obj.id === $.jstree.root) { + return this._append_json_data(obj, t, function (status) { + callback.call(this, status); + }); + } + else { + this._data.core.last_error = { 'error' : 'nodata', 'plugin' : 'core', 'id' : 'core_05', 'reason' : 'Could not load node', 'data' : JSON.stringify({ 'id' : obj.id }) }; + this.settings.core.error.call(this, this._data.core.last_error); + return callback.call(this, false); + } + //return callback.call(this, (obj.id === $.jstree.root ? this._append_json_data(obj, t) : false) ); + } + if(typeof s === 'string') { + if(obj.id === $.jstree.root) { + return this._append_html_data(obj, $($.parseHTML(s)).filter(notTextOrCommentNode), function (status) { + callback.call(this, status); + }); + } + else { + this._data.core.last_error = { 'error' : 'nodata', 'plugin' : 'core', 'id' : 'core_06', 'reason' : 'Could not load node', 'data' : JSON.stringify({ 'id' : obj.id }) }; + this.settings.core.error.call(this, this._data.core.last_error); + return callback.call(this, false); + } + //return callback.call(this, (obj.id === $.jstree.root ? this._append_html_data(obj, $(s)) : false) ); + } + return callback.call(this, false); + }, + /** + * adds a node to the list of nodes to redraw. Used only internally. + * @private + * @name _node_changed(obj [, callback]) + * @param {mixed} obj + */ + _node_changed : function (obj) { + obj = this.get_node(obj); + if(obj) { + this._model.changed.push(obj.id); + } + }, + /** + * appends HTML content to the tree. Used internally. + * @private + * @name _append_html_data(obj, data) + * @param {mixed} obj the node to append to + * @param {String} data the HTML string to parse and append + * @trigger model.jstree, changed.jstree + */ + _append_html_data : function (dom, data, cb) { + dom = this.get_node(dom); + dom.children = []; + dom.children_d = []; + var dat = data.is('ul') ? data.children() : data, + par = dom.id, + chd = [], + dpc = [], + m = this._model.data, + p = m[par], + s = this._data.core.selected.length, + tmp, i, j; + dat.each($.proxy(function (i, v) { + tmp = this._parse_model_from_html($(v), par, p.parents.concat()); + if(tmp) { + chd.push(tmp); + dpc.push(tmp); + if(m[tmp].children_d.length) { + dpc = dpc.concat(m[tmp].children_d); + } + } + }, this)); + p.children = chd; + p.children_d = dpc; + for(i = 0, j = p.parents.length; i < j; i++) { + m[p.parents[i]].children_d = m[p.parents[i]].children_d.concat(dpc); + } + /** + * triggered when new data is inserted to the tree model + * @event + * @name model.jstree + * @param {Array} nodes an array of node IDs + * @param {String} parent the parent ID of the nodes + */ + this.trigger('model', { "nodes" : dpc, 'parent' : par }); + if(par !== $.jstree.root) { + this._node_changed(par); + this.redraw(); + } + else { + this.get_container_ul().children('.jstree-initial-node').remove(); + this.redraw(true); + } + if(this._data.core.selected.length !== s) { + this.trigger('changed', { 'action' : 'model', 'selected' : this._data.core.selected }); + } + cb.call(this, true); + }, + /** + * appends JSON content to the tree. Used internally. + * @private + * @name _append_json_data(obj, data) + * @param {mixed} obj the node to append to + * @param {String} data the JSON object to parse and append + * @param {Boolean} force_processing internal param - do not set + * @trigger model.jstree, changed.jstree + */ + _append_json_data : function (dom, data, cb, force_processing) { + if(this.element === null) { return; } + dom = this.get_node(dom); + dom.children = []; + dom.children_d = []; + // *%$@!!! + if(data.d) { + data = data.d; + if(typeof data === "string") { + data = JSON.parse(data); + } + } + if(!$.isArray(data)) { data = [data]; } + var w = null, + args = { + 'df' : this._model.default_state, + 'dat' : data, + 'par' : dom.id, + 'm' : this._model.data, + 't_id' : this._id, + 't_cnt' : this._cnt, + 'sel' : this._data.core.selected + }, + func = function (data, undefined) { + if(data.data) { data = data.data; } + var dat = data.dat, + par = data.par, + chd = [], + dpc = [], + add = [], + df = data.df, + t_id = data.t_id, + t_cnt = data.t_cnt, + m = data.m, + p = m[par], + sel = data.sel, + tmp, i, j, rslt, + parse_flat = function (d, p, ps) { + if(!ps) { ps = []; } + else { ps = ps.concat(); } + if(p) { ps.unshift(p); } + var tid = d.id.toString(), + i, j, c, e, + tmp = { + id : tid, + text : d.text || '', + icon : d.icon !== undefined ? d.icon : true, + parent : p, + parents : ps, + children : d.children || [], + children_d : d.children_d || [], + data : d.data, + state : { }, + li_attr : { id : false }, + a_attr : { href : '#' }, + original : false + }; + for(i in df) { + if(df.hasOwnProperty(i)) { + tmp.state[i] = df[i]; + } + } + if(d && d.data && d.data.jstree && d.data.jstree.icon) { + tmp.icon = d.data.jstree.icon; + } + if(tmp.icon === undefined || tmp.icon === null || tmp.icon === "") { + tmp.icon = true; + } + if(d && d.data) { + tmp.data = d.data; + if(d.data.jstree) { + for(i in d.data.jstree) { + if(d.data.jstree.hasOwnProperty(i)) { + tmp.state[i] = d.data.jstree[i]; + } + } + } + } + if(d && typeof d.state === 'object') { + for (i in d.state) { + if(d.state.hasOwnProperty(i)) { + tmp.state[i] = d.state[i]; + } + } + } + if(d && typeof d.li_attr === 'object') { + for (i in d.li_attr) { + if(d.li_attr.hasOwnProperty(i)) { + tmp.li_attr[i] = d.li_attr[i]; + } + } + } + if(!tmp.li_attr.id) { + tmp.li_attr.id = tid; + } + if(d && typeof d.a_attr === 'object') { + for (i in d.a_attr) { + if(d.a_attr.hasOwnProperty(i)) { + tmp.a_attr[i] = d.a_attr[i]; + } + } + } + if(d && d.children && d.children === true) { + tmp.state.loaded = false; + tmp.children = []; + tmp.children_d = []; + } + m[tmp.id] = tmp; + for(i = 0, j = tmp.children.length; i < j; i++) { + c = parse_flat(m[tmp.children[i]], tmp.id, ps); + e = m[c]; + tmp.children_d.push(c); + if(e.children_d.length) { + tmp.children_d = tmp.children_d.concat(e.children_d); + } + } + delete d.data; + delete d.children; + m[tmp.id].original = d; + if(tmp.state.selected) { + add.push(tmp.id); + } + return tmp.id; + }, + parse_nest = function (d, p, ps) { + if(!ps) { ps = []; } + else { ps = ps.concat(); } + if(p) { ps.unshift(p); } + var tid = false, i, j, c, e, tmp; + do { + tid = 'j' + t_id + '_' + (++t_cnt); + } while(m[tid]); + + tmp = { + id : false, + text : typeof d === 'string' ? d : '', + icon : typeof d === 'object' && d.icon !== undefined ? d.icon : true, + parent : p, + parents : ps, + children : [], + children_d : [], + data : null, + state : { }, + li_attr : { id : false }, + a_attr : { href : '#' }, + original : false + }; + for(i in df) { + if(df.hasOwnProperty(i)) { + tmp.state[i] = df[i]; + } + } + if(d && d.id) { tmp.id = d.id.toString(); } + if(d && d.text) { tmp.text = d.text; } + if(d && d.data && d.data.jstree && d.data.jstree.icon) { + tmp.icon = d.data.jstree.icon; + } + if(tmp.icon === undefined || tmp.icon === null || tmp.icon === "") { + tmp.icon = true; + } + if(d && d.data) { + tmp.data = d.data; + if(d.data.jstree) { + for(i in d.data.jstree) { + if(d.data.jstree.hasOwnProperty(i)) { + tmp.state[i] = d.data.jstree[i]; + } + } + } + } + if(d && typeof d.state === 'object') { + for (i in d.state) { + if(d.state.hasOwnProperty(i)) { + tmp.state[i] = d.state[i]; + } + } + } + if(d && typeof d.li_attr === 'object') { + for (i in d.li_attr) { + if(d.li_attr.hasOwnProperty(i)) { + tmp.li_attr[i] = d.li_attr[i]; + } + } + } + if(tmp.li_attr.id && !tmp.id) { + tmp.id = tmp.li_attr.id.toString(); + } + if(!tmp.id) { + tmp.id = tid; + } + if(!tmp.li_attr.id) { + tmp.li_attr.id = tmp.id; + } + if(d && typeof d.a_attr === 'object') { + for (i in d.a_attr) { + if(d.a_attr.hasOwnProperty(i)) { + tmp.a_attr[i] = d.a_attr[i]; + } + } + } + if(d && d.children && d.children.length) { + for(i = 0, j = d.children.length; i < j; i++) { + c = parse_nest(d.children[i], tmp.id, ps); + e = m[c]; + tmp.children.push(c); + if(e.children_d.length) { + tmp.children_d = tmp.children_d.concat(e.children_d); + } + } + tmp.children_d = tmp.children_d.concat(tmp.children); + } + if(d && d.children && d.children === true) { + tmp.state.loaded = false; + tmp.children = []; + tmp.children_d = []; + } + delete d.data; + delete d.children; + tmp.original = d; + m[tmp.id] = tmp; + if(tmp.state.selected) { + add.push(tmp.id); + } + return tmp.id; + }; + + if(dat.length && dat[0].id !== undefined && dat[0].parent !== undefined) { + // Flat JSON support (for easy import from DB): + // 1) convert to object (foreach) + for(i = 0, j = dat.length; i < j; i++) { + if(!dat[i].children) { + dat[i].children = []; + } + m[dat[i].id.toString()] = dat[i]; + } + // 2) populate children (foreach) + for(i = 0, j = dat.length; i < j; i++) { + m[dat[i].parent.toString()].children.push(dat[i].id.toString()); + // populate parent.children_d + p.children_d.push(dat[i].id.toString()); + } + // 3) normalize && populate parents and children_d with recursion + for(i = 0, j = p.children.length; i < j; i++) { + tmp = parse_flat(m[p.children[i]], par, p.parents.concat()); + dpc.push(tmp); + if(m[tmp].children_d.length) { + dpc = dpc.concat(m[tmp].children_d); + } + } + for(i = 0, j = p.parents.length; i < j; i++) { + m[p.parents[i]].children_d = m[p.parents[i]].children_d.concat(dpc); + } + // ?) three_state selection - p.state.selected && t - (if three_state foreach(dat => ch) -> foreach(parents) if(parent.selected) child.selected = true; + rslt = { + 'cnt' : t_cnt, + 'mod' : m, + 'sel' : sel, + 'par' : par, + 'dpc' : dpc, + 'add' : add + }; + } + else { + for(i = 0, j = dat.length; i < j; i++) { + tmp = parse_nest(dat[i], par, p.parents.concat()); + if(tmp) { + chd.push(tmp); + dpc.push(tmp); + if(m[tmp].children_d.length) { + dpc = dpc.concat(m[tmp].children_d); + } + } + } + p.children = chd; + p.children_d = dpc; + for(i = 0, j = p.parents.length; i < j; i++) { + m[p.parents[i]].children_d = m[p.parents[i]].children_d.concat(dpc); + } + rslt = { + 'cnt' : t_cnt, + 'mod' : m, + 'sel' : sel, + 'par' : par, + 'dpc' : dpc, + 'add' : add + }; + } + if(typeof window === 'undefined' || typeof window.document === 'undefined') { + postMessage(rslt); + } + else { + return rslt; + } + }, + rslt = function (rslt, worker) { + if(this.element === null) { return; } + this._cnt = rslt.cnt; + var i, m = this._model.data; + for (i in m) { + if (m.hasOwnProperty(i) && m[i].state && m[i].state.loading && rslt.mod[i]) { + rslt.mod[i].state.loading = true; + } + } + this._model.data = rslt.mod; // breaks the reference in load_node - careful + + if(worker) { + var j, a = rslt.add, r = rslt.sel, s = this._data.core.selected.slice(); + m = this._model.data; + // if selection was changed while calculating in worker + if(r.length !== s.length || $.vakata.array_unique(r.concat(s)).length !== r.length) { + // deselect nodes that are no longer selected + for(i = 0, j = r.length; i < j; i++) { + if($.inArray(r[i], a) === -1 && $.inArray(r[i], s) === -1) { + m[r[i]].state.selected = false; + } + } + // select nodes that were selected in the mean time + for(i = 0, j = s.length; i < j; i++) { + if($.inArray(s[i], r) === -1) { + m[s[i]].state.selected = true; + } + } + } + } + if(rslt.add.length) { + this._data.core.selected = this._data.core.selected.concat(rslt.add); + } + + this.trigger('model', { "nodes" : rslt.dpc, 'parent' : rslt.par }); + + if(rslt.par !== $.jstree.root) { + this._node_changed(rslt.par); + this.redraw(); + } + else { + // this.get_container_ul().children('.jstree-initial-node').remove(); + this.redraw(true); + } + if(rslt.add.length) { + this.trigger('changed', { 'action' : 'model', 'selected' : this._data.core.selected }); + } + cb.call(this, true); + }; + if(this.settings.core.worker && window.Blob && window.URL && window.Worker) { + try { + if(this._wrk === null) { + this._wrk = window.URL.createObjectURL( + new window.Blob( + ['self.onmessage = ' + func.toString()], + {type:"text/javascript"} + ) + ); + } + if(!this._data.core.working || force_processing) { + this._data.core.working = true; + w = new window.Worker(this._wrk); + w.onmessage = $.proxy(function (e) { + rslt.call(this, e.data, true); + try { w.terminate(); w = null; } catch(ignore) { } + if(this._data.core.worker_queue.length) { + this._append_json_data.apply(this, this._data.core.worker_queue.shift()); + } + else { + this._data.core.working = false; + } + }, this); + if(!args.par) { + if(this._data.core.worker_queue.length) { + this._append_json_data.apply(this, this._data.core.worker_queue.shift()); + } + else { + this._data.core.working = false; + } + } + else { + w.postMessage(args); + } + } + else { + this._data.core.worker_queue.push([dom, data, cb, true]); + } + } + catch(e) { + rslt.call(this, func(args), false); + if(this._data.core.worker_queue.length) { + this._append_json_data.apply(this, this._data.core.worker_queue.shift()); + } + else { + this._data.core.working = false; + } + } + } + else { + rslt.call(this, func(args), false); + } + }, + /** + * parses a node from a jQuery object and appends them to the in memory tree model. Used internally. + * @private + * @name _parse_model_from_html(d [, p, ps]) + * @param {jQuery} d the jQuery object to parse + * @param {String} p the parent ID + * @param {Array} ps list of all parents + * @return {String} the ID of the object added to the model + */ + _parse_model_from_html : function (d, p, ps) { + if(!ps) { ps = []; } + else { ps = [].concat(ps); } + if(p) { ps.unshift(p); } + var c, e, m = this._model.data, + data = { + id : false, + text : false, + icon : true, + parent : p, + parents : ps, + children : [], + children_d : [], + data : null, + state : { }, + li_attr : { id : false }, + a_attr : { href : '#' }, + original : false + }, i, tmp, tid; + for(i in this._model.default_state) { + if(this._model.default_state.hasOwnProperty(i)) { + data.state[i] = this._model.default_state[i]; + } + } + tmp = $.vakata.attributes(d, true); + $.each(tmp, function (i, v) { + v = $.trim(v); + if(!v.length) { return true; } + data.li_attr[i] = v; + if(i === 'id') { + data.id = v.toString(); + } + }); + tmp = d.children('a').first(); + if(tmp.length) { + tmp = $.vakata.attributes(tmp, true); + $.each(tmp, function (i, v) { + v = $.trim(v); + if(v.length) { + data.a_attr[i] = v; + } + }); + } + tmp = d.children("a").first().length ? d.children("a").first().clone() : d.clone(); + tmp.children("ins, i, ul").remove(); + tmp = tmp.html(); + tmp = $('<div />').html(tmp); + data.text = this.settings.core.force_text ? tmp.text() : tmp.html(); + tmp = d.data(); + data.data = tmp ? $.extend(true, {}, tmp) : null; + data.state.opened = d.hasClass('jstree-open'); + data.state.selected = d.children('a').hasClass('jstree-clicked'); + data.state.disabled = d.children('a').hasClass('jstree-disabled'); + if(data.data && data.data.jstree) { + for(i in data.data.jstree) { + if(data.data.jstree.hasOwnProperty(i)) { + data.state[i] = data.data.jstree[i]; + } + } + } + tmp = d.children("a").children(".jstree-themeicon"); + if(tmp.length) { + data.icon = tmp.hasClass('jstree-themeicon-hidden') ? false : tmp.attr('rel'); + } + if(data.state.icon !== undefined) { + data.icon = data.state.icon; + } + if(data.icon === undefined || data.icon === null || data.icon === "") { + data.icon = true; + } + tmp = d.children("ul").children("li"); + do { + tid = 'j' + this._id + '_' + (++this._cnt); + } while(m[tid]); + data.id = data.li_attr.id ? data.li_attr.id.toString() : tid; + if(tmp.length) { + tmp.each($.proxy(function (i, v) { + c = this._parse_model_from_html($(v), data.id, ps); + e = this._model.data[c]; + data.children.push(c); + if(e.children_d.length) { + data.children_d = data.children_d.concat(e.children_d); + } + }, this)); + data.children_d = data.children_d.concat(data.children); + } + else { + if(d.hasClass('jstree-closed')) { + data.state.loaded = false; + } + } + if(data.li_attr['class']) { + data.li_attr['class'] = data.li_attr['class'].replace('jstree-closed','').replace('jstree-open',''); + } + if(data.a_attr['class']) { + data.a_attr['class'] = data.a_attr['class'].replace('jstree-clicked','').replace('jstree-disabled',''); + } + m[data.id] = data; + if(data.state.selected) { + this._data.core.selected.push(data.id); + } + return data.id; + }, + /** + * parses a node from a JSON object (used when dealing with flat data, which has no nesting of children, but has id and parent properties) and appends it to the in memory tree model. Used internally. + * @private + * @name _parse_model_from_flat_json(d [, p, ps]) + * @param {Object} d the JSON object to parse + * @param {String} p the parent ID + * @param {Array} ps list of all parents + * @return {String} the ID of the object added to the model + */ + _parse_model_from_flat_json : function (d, p, ps) { + if(!ps) { ps = []; } + else { ps = ps.concat(); } + if(p) { ps.unshift(p); } + var tid = d.id.toString(), + m = this._model.data, + df = this._model.default_state, + i, j, c, e, + tmp = { + id : tid, + text : d.text || '', + icon : d.icon !== undefined ? d.icon : true, + parent : p, + parents : ps, + children : d.children || [], + children_d : d.children_d || [], + data : d.data, + state : { }, + li_attr : { id : false }, + a_attr : { href : '#' }, + original : false + }; + for(i in df) { + if(df.hasOwnProperty(i)) { + tmp.state[i] = df[i]; + } + } + if(d && d.data && d.data.jstree && d.data.jstree.icon) { + tmp.icon = d.data.jstree.icon; + } + if(tmp.icon === undefined || tmp.icon === null || tmp.icon === "") { + tmp.icon = true; + } + if(d && d.data) { + tmp.data = d.data; + if(d.data.jstree) { + for(i in d.data.jstree) { + if(d.data.jstree.hasOwnProperty(i)) { + tmp.state[i] = d.data.jstree[i]; + } + } + } + } + if(d && typeof d.state === 'object') { + for (i in d.state) { + if(d.state.hasOwnProperty(i)) { + tmp.state[i] = d.state[i]; + } + } + } + if(d && typeof d.li_attr === 'object') { + for (i in d.li_attr) { + if(d.li_attr.hasOwnProperty(i)) { + tmp.li_attr[i] = d.li_attr[i]; + } + } + } + if(!tmp.li_attr.id) { + tmp.li_attr.id = tid; + } + if(d && typeof d.a_attr === 'object') { + for (i in d.a_attr) { + if(d.a_attr.hasOwnProperty(i)) { + tmp.a_attr[i] = d.a_attr[i]; + } + } + } + if(d && d.children && d.children === true) { + tmp.state.loaded = false; + tmp.children = []; + tmp.children_d = []; + } + m[tmp.id] = tmp; + for(i = 0, j = tmp.children.length; i < j; i++) { + c = this._parse_model_from_flat_json(m[tmp.children[i]], tmp.id, ps); + e = m[c]; + tmp.children_d.push(c); + if(e.children_d.length) { + tmp.children_d = tmp.children_d.concat(e.children_d); + } + } + delete d.data; + delete d.children; + m[tmp.id].original = d; + if(tmp.state.selected) { + this._data.core.selected.push(tmp.id); + } + return tmp.id; + }, + /** + * parses a node from a JSON object and appends it to the in memory tree model. Used internally. + * @private + * @name _parse_model_from_json(d [, p, ps]) + * @param {Object} d the JSON object to parse + * @param {String} p the parent ID + * @param {Array} ps list of all parents + * @return {String} the ID of the object added to the model + */ + _parse_model_from_json : function (d, p, ps) { + if(!ps) { ps = []; } + else { ps = ps.concat(); } + if(p) { ps.unshift(p); } + var tid = false, i, j, c, e, m = this._model.data, df = this._model.default_state, tmp; + do { + tid = 'j' + this._id + '_' + (++this._cnt); + } while(m[tid]); + + tmp = { + id : false, + text : typeof d === 'string' ? d : '', + icon : typeof d === 'object' && d.icon !== undefined ? d.icon : true, + parent : p, + parents : ps, + children : [], + children_d : [], + data : null, + state : { }, + li_attr : { id : false }, + a_attr : { href : '#' }, + original : false + }; + for(i in df) { + if(df.hasOwnProperty(i)) { + tmp.state[i] = df[i]; + } + } + if(d && d.id) { tmp.id = d.id.toString(); } + if(d && d.text) { tmp.text = d.text; } + if(d && d.data && d.data.jstree && d.data.jstree.icon) { + tmp.icon = d.data.jstree.icon; + } + if(tmp.icon === undefined || tmp.icon === null || tmp.icon === "") { + tmp.icon = true; + } + if(d && d.data) { + tmp.data = d.data; + if(d.data.jstree) { + for(i in d.data.jstree) { + if(d.data.jstree.hasOwnProperty(i)) { + tmp.state[i] = d.data.jstree[i]; + } + } + } + } + if(d && typeof d.state === 'object') { + for (i in d.state) { + if(d.state.hasOwnProperty(i)) { + tmp.state[i] = d.state[i]; + } + } + } + if(d && typeof d.li_attr === 'object') { + for (i in d.li_attr) { + if(d.li_attr.hasOwnProperty(i)) { + tmp.li_attr[i] = d.li_attr[i]; + } + } + } + if(tmp.li_attr.id && !tmp.id) { + tmp.id = tmp.li_attr.id.toString(); + } + if(!tmp.id) { + tmp.id = tid; + } + if(!tmp.li_attr.id) { + tmp.li_attr.id = tmp.id; + } + if(d && typeof d.a_attr === 'object') { + for (i in d.a_attr) { + if(d.a_attr.hasOwnProperty(i)) { + tmp.a_attr[i] = d.a_attr[i]; + } + } + } + if(d && d.children && d.children.length) { + for(i = 0, j = d.children.length; i < j; i++) { + c = this._parse_model_from_json(d.children[i], tmp.id, ps); + e = m[c]; + tmp.children.push(c); + if(e.children_d.length) { + tmp.children_d = tmp.children_d.concat(e.children_d); + } + } + tmp.children_d = tmp.children_d.concat(tmp.children); + } + if(d && d.children && d.children === true) { + tmp.state.loaded = false; + tmp.children = []; + tmp.children_d = []; + } + delete d.data; + delete d.children; + tmp.original = d; + m[tmp.id] = tmp; + if(tmp.state.selected) { + this._data.core.selected.push(tmp.id); + } + return tmp.id; + }, + /** + * redraws all nodes that need to be redrawn. Used internally. + * @private + * @name _redraw() + * @trigger redraw.jstree + */ + _redraw : function () { + var nodes = this._model.force_full_redraw ? this._model.data[$.jstree.root].children.concat([]) : this._model.changed.concat([]), + f = document.createElement('UL'), tmp, i, j, fe = this._data.core.focused; + for(i = 0, j = nodes.length; i < j; i++) { + tmp = this.redraw_node(nodes[i], true, this._model.force_full_redraw); + if(tmp && this._model.force_full_redraw) { + f.appendChild(tmp); + } + } + if(this._model.force_full_redraw) { + f.className = this.get_container_ul()[0].className; + f.setAttribute('role','group'); + this.element.empty().append(f); + //this.get_container_ul()[0].appendChild(f); + } + if(fe !== null) { + tmp = this.get_node(fe, true); + if(tmp && tmp.length && tmp.children('.jstree-anchor')[0] !== document.activeElement) { + tmp.children('.jstree-anchor').focus(); + } + else { + this._data.core.focused = null; + } + } + this._model.force_full_redraw = false; + this._model.changed = []; + /** + * triggered after nodes are redrawn + * @event + * @name redraw.jstree + * @param {array} nodes the redrawn nodes + */ + this.trigger('redraw', { "nodes" : nodes }); + }, + /** + * redraws all nodes that need to be redrawn or optionally - the whole tree + * @name redraw([full]) + * @param {Boolean} full if set to `true` all nodes are redrawn. + */ + redraw : function (full) { + if(full) { + this._model.force_full_redraw = true; + } + //if(this._model.redraw_timeout) { + // clearTimeout(this._model.redraw_timeout); + //} + //this._model.redraw_timeout = setTimeout($.proxy(this._redraw, this),0); + this._redraw(); + }, + /** + * redraws a single node's children. Used internally. + * @private + * @name draw_children(node) + * @param {mixed} node the node whose children will be redrawn + */ + draw_children : function (node) { + var obj = this.get_node(node), + i = false, + j = false, + k = false, + d = document; + if(!obj) { return false; } + if(obj.id === $.jstree.root) { return this.redraw(true); } + node = this.get_node(node, true); + if(!node || !node.length) { return false; } // TODO: quick toggle + + node.children('.jstree-children').remove(); + node = node[0]; + if(obj.children.length && obj.state.loaded) { + k = d.createElement('UL'); + k.setAttribute('role', 'group'); + k.className = 'jstree-children'; + for(i = 0, j = obj.children.length; i < j; i++) { + k.appendChild(this.redraw_node(obj.children[i], true, true)); + } + node.appendChild(k); + } + }, + /** + * redraws a single node. Used internally. + * @private + * @name redraw_node(node, deep, is_callback, force_render) + * @param {mixed} node the node to redraw + * @param {Boolean} deep should child nodes be redrawn too + * @param {Boolean} is_callback is this a recursion call + * @param {Boolean} force_render should children of closed parents be drawn anyway + */ + redraw_node : function (node, deep, is_callback, force_render) { + var obj = this.get_node(node), + par = false, + ind = false, + old = false, + i = false, + j = false, + k = false, + c = '', + d = document, + m = this._model.data, + f = false, + s = false, + tmp = null, + t = 0, + l = 0, + has_children = false, + last_sibling = false; + if(!obj) { return false; } + if(obj.id === $.jstree.root) { return this.redraw(true); } + deep = deep || obj.children.length === 0; + node = !document.querySelector ? document.getElementById(obj.id) : this.element[0].querySelector('#' + ("0123456789".indexOf(obj.id[0]) !== -1 ? '\\3' + obj.id[0] + ' ' + obj.id.substr(1).replace($.jstree.idregex,'\\$&') : obj.id.replace($.jstree.idregex,'\\$&')) ); //, this.element); + if(!node) { + deep = true; + //node = d.createElement('LI'); + if(!is_callback) { + par = obj.parent !== $.jstree.root ? $('#' + obj.parent.replace($.jstree.idregex,'\\$&'), this.element)[0] : null; + if(par !== null && (!par || !m[obj.parent].state.opened)) { + return false; + } + ind = $.inArray(obj.id, par === null ? m[$.jstree.root].children : m[obj.parent].children); + } + } + else { + node = $(node); + if(!is_callback) { + par = node.parent().parent()[0]; + if(par === this.element[0]) { + par = null; + } + ind = node.index(); + } + // m[obj.id].data = node.data(); // use only node's data, no need to touch jquery storage + if(!deep && obj.children.length && !node.children('.jstree-children').length) { + deep = true; + } + if(!deep) { + old = node.children('.jstree-children')[0]; + } + f = node.children('.jstree-anchor')[0] === document.activeElement; + node.remove(); + //node = d.createElement('LI'); + //node = node[0]; + } + node = this._data.core.node.cloneNode(true); + // node is DOM, deep is boolean + + c = 'jstree-node '; + for(i in obj.li_attr) { + if(obj.li_attr.hasOwnProperty(i)) { + if(i === 'id') { continue; } + if(i !== 'class') { + node.setAttribute(i, obj.li_attr[i]); + } + else { + c += obj.li_attr[i]; + } + } + } + if(!obj.a_attr.id) { + obj.a_attr.id = obj.id + '_anchor'; + } + node.setAttribute('aria-selected', !!obj.state.selected); + node.setAttribute('aria-level', obj.parents.length); + node.setAttribute('aria-labelledby', obj.a_attr.id); + if(obj.state.disabled) { + node.setAttribute('aria-disabled', true); + } + + for(i = 0, j = obj.children.length; i < j; i++) { + if(!m[obj.children[i]].state.hidden) { + has_children = true; + break; + } + } + if(obj.parent !== null && m[obj.parent] && !obj.state.hidden) { + i = $.inArray(obj.id, m[obj.parent].children); + last_sibling = obj.id; + if(i !== -1) { + i++; + for(j = m[obj.parent].children.length; i < j; i++) { + if(!m[m[obj.parent].children[i]].state.hidden) { + last_sibling = m[obj.parent].children[i]; + } + if(last_sibling !== obj.id) { + break; + } + } + } + } + + if(obj.state.hidden) { + c += ' jstree-hidden'; + } + if(obj.state.loaded && !has_children) { + c += ' jstree-leaf'; + } + else { + c += obj.state.opened && obj.state.loaded ? ' jstree-open' : ' jstree-closed'; + node.setAttribute('aria-expanded', (obj.state.opened && obj.state.loaded) ); + } + if(last_sibling === obj.id) { + c += ' jstree-last'; + } + node.id = obj.id; + node.className = c; + c = ( obj.state.selected ? ' jstree-clicked' : '') + ( obj.state.disabled ? ' jstree-disabled' : ''); + for(j in obj.a_attr) { + if(obj.a_attr.hasOwnProperty(j)) { + if(j === 'href' && obj.a_attr[j] === '#') { continue; } + if(j !== 'class') { + node.childNodes[1].setAttribute(j, obj.a_attr[j]); + } + else { + c += ' ' + obj.a_attr[j]; + } + } + } + if(c.length) { + node.childNodes[1].className = 'jstree-anchor ' + c; + } + if((obj.icon && obj.icon !== true) || obj.icon === false) { + if(obj.icon === false) { + node.childNodes[1].childNodes[0].className += ' jstree-themeicon-hidden'; + } + else if(obj.icon.indexOf('/') === -1 && obj.icon.indexOf('.') === -1) { + node.childNodes[1].childNodes[0].className += ' ' + obj.icon + ' jstree-themeicon-custom'; + } + else { + node.childNodes[1].childNodes[0].style.backgroundImage = 'url("'+obj.icon+'")'; + node.childNodes[1].childNodes[0].style.backgroundPosition = 'center center'; + node.childNodes[1].childNodes[0].style.backgroundSize = 'auto'; + node.childNodes[1].childNodes[0].className += ' jstree-themeicon-custom'; + } + } + + if(this.settings.core.force_text) { + node.childNodes[1].appendChild(d.createTextNode(obj.text)); + } + else { + node.childNodes[1].innerHTML += obj.text; + } + + + if(deep && obj.children.length && (obj.state.opened || force_render) && obj.state.loaded) { + k = d.createElement('UL'); + k.setAttribute('role', 'group'); + k.className = 'jstree-children'; + for(i = 0, j = obj.children.length; i < j; i++) { + k.appendChild(this.redraw_node(obj.children[i], deep, true)); + } + node.appendChild(k); + } + if(old) { + node.appendChild(old); + } + if(!is_callback) { + // append back using par / ind + if(!par) { + par = this.element[0]; + } + for(i = 0, j = par.childNodes.length; i < j; i++) { + if(par.childNodes[i] && par.childNodes[i].className && par.childNodes[i].className.indexOf('jstree-children') !== -1) { + tmp = par.childNodes[i]; + break; + } + } + if(!tmp) { + tmp = d.createElement('UL'); + tmp.setAttribute('role', 'group'); + tmp.className = 'jstree-children'; + par.appendChild(tmp); + } + par = tmp; + + if(ind < par.childNodes.length) { + par.insertBefore(node, par.childNodes[ind]); + } + else { + par.appendChild(node); + } + if(f) { + t = this.element[0].scrollTop; + l = this.element[0].scrollLeft; + node.childNodes[1].focus(); + this.element[0].scrollTop = t; + this.element[0].scrollLeft = l; + } + } + if(obj.state.opened && !obj.state.loaded) { + obj.state.opened = false; + setTimeout($.proxy(function () { + this.open_node(obj.id, false, 0); + }, this), 0); + } + return node; + }, + /** + * opens a node, revaling its children. If the node is not loaded it will be loaded and opened once ready. + * @name open_node(obj [, callback, animation]) + * @param {mixed} obj the node to open + * @param {Function} callback a function to execute once the node is opened + * @param {Number} animation the animation duration in milliseconds when opening the node (overrides the `core.animation` setting). Use `false` for no animation. + * @trigger open_node.jstree, after_open.jstree, before_open.jstree + */ + open_node : function (obj, callback, animation) { + var t1, t2, d, t; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.open_node(obj[t1], callback, animation); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { + return false; + } + animation = animation === undefined ? this.settings.core.animation : animation; + if(!this.is_closed(obj)) { + if(callback) { + callback.call(this, obj, false); + } + return false; + } + if(!this.is_loaded(obj)) { + if(this.is_loading(obj)) { + return setTimeout($.proxy(function () { + this.open_node(obj, callback, animation); + }, this), 500); + } + this.load_node(obj, function (o, ok) { + return ok ? this.open_node(o, callback, animation) : (callback ? callback.call(this, o, false) : false); + }); + } + else { + d = this.get_node(obj, true); + t = this; + if(d.length) { + if(animation && d.children(".jstree-children").length) { + d.children(".jstree-children").stop(true, true); + } + if(obj.children.length && !this._firstChild(d.children('.jstree-children')[0])) { + this.draw_children(obj); + //d = this.get_node(obj, true); + } + if(!animation) { + this.trigger('before_open', { "node" : obj }); + d[0].className = d[0].className.replace('jstree-closed', 'jstree-open'); + d[0].setAttribute("aria-expanded", true); + } + else { + this.trigger('before_open', { "node" : obj }); + d + .children(".jstree-children").css("display","none").end() + .removeClass("jstree-closed").addClass("jstree-open").attr("aria-expanded", true) + .children(".jstree-children").stop(true, true) + .slideDown(animation, function () { + this.style.display = ""; + if (t.element) { + t.trigger("after_open", { "node" : obj }); + } + }); + } + } + obj.state.opened = true; + if(callback) { + callback.call(this, obj, true); + } + if(!d.length) { + /** + * triggered when a node is about to be opened (if the node is supposed to be in the DOM, it will be, but it won't be visible yet) + * @event + * @name before_open.jstree + * @param {Object} node the opened node + */ + this.trigger('before_open', { "node" : obj }); + } + /** + * triggered when a node is opened (if there is an animation it will not be completed yet) + * @event + * @name open_node.jstree + * @param {Object} node the opened node + */ + this.trigger('open_node', { "node" : obj }); + if(!animation || !d.length) { + /** + * triggered when a node is opened and the animation is complete + * @event + * @name after_open.jstree + * @param {Object} node the opened node + */ + this.trigger("after_open", { "node" : obj }); + } + return true; + } + }, + /** + * opens every parent of a node (node should be loaded) + * @name _open_to(obj) + * @param {mixed} obj the node to reveal + * @private + */ + _open_to : function (obj) { + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { + return false; + } + var i, j, p = obj.parents; + for(i = 0, j = p.length; i < j; i+=1) { + if(i !== $.jstree.root) { + this.open_node(p[i], false, 0); + } + } + return $('#' + obj.id.replace($.jstree.idregex,'\\$&'), this.element); + }, + /** + * closes a node, hiding its children + * @name close_node(obj [, animation]) + * @param {mixed} obj the node to close + * @param {Number} animation the animation duration in milliseconds when closing the node (overrides the `core.animation` setting). Use `false` for no animation. + * @trigger close_node.jstree, after_close.jstree + */ + close_node : function (obj, animation) { + var t1, t2, t, d; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.close_node(obj[t1], animation); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { + return false; + } + if(this.is_closed(obj)) { + return false; + } + animation = animation === undefined ? this.settings.core.animation : animation; + t = this; + d = this.get_node(obj, true); + + obj.state.opened = false; + /** + * triggered when a node is closed (if there is an animation it will not be complete yet) + * @event + * @name close_node.jstree + * @param {Object} node the closed node + */ + this.trigger('close_node',{ "node" : obj }); + if(!d.length) { + /** + * triggered when a node is closed and the animation is complete + * @event + * @name after_close.jstree + * @param {Object} node the closed node + */ + this.trigger("after_close", { "node" : obj }); + } + else { + if(!animation) { + d[0].className = d[0].className.replace('jstree-open', 'jstree-closed'); + d.attr("aria-expanded", false).children('.jstree-children').remove(); + this.trigger("after_close", { "node" : obj }); + } + else { + d + .children(".jstree-children").attr("style","display:block !important").end() + .removeClass("jstree-open").addClass("jstree-closed").attr("aria-expanded", false) + .children(".jstree-children").stop(true, true).slideUp(animation, function () { + this.style.display = ""; + d.children('.jstree-children').remove(); + if (t.element) { + t.trigger("after_close", { "node" : obj }); + } + }); + } + } + }, + /** + * toggles a node - closing it if it is open, opening it if it is closed + * @name toggle_node(obj) + * @param {mixed} obj the node to toggle + */ + toggle_node : function (obj) { + var t1, t2; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.toggle_node(obj[t1]); + } + return true; + } + if(this.is_closed(obj)) { + return this.open_node(obj); + } + if(this.is_open(obj)) { + return this.close_node(obj); + } + }, + /** + * opens all nodes within a node (or the tree), revaling their children. If the node is not loaded it will be loaded and opened once ready. + * @name open_all([obj, animation, original_obj]) + * @param {mixed} obj the node to open recursively, omit to open all nodes in the tree + * @param {Number} animation the animation duration in milliseconds when opening the nodes, the default is no animation + * @param {jQuery} reference to the node that started the process (internal use) + * @trigger open_all.jstree + */ + open_all : function (obj, animation, original_obj) { + if(!obj) { obj = $.jstree.root; } + obj = this.get_node(obj); + if(!obj) { return false; } + var dom = obj.id === $.jstree.root ? this.get_container_ul() : this.get_node(obj, true), i, j, _this; + if(!dom.length) { + for(i = 0, j = obj.children_d.length; i < j; i++) { + if(this.is_closed(this._model.data[obj.children_d[i]])) { + this._model.data[obj.children_d[i]].state.opened = true; + } + } + return this.trigger('open_all', { "node" : obj }); + } + original_obj = original_obj || dom; + _this = this; + dom = this.is_closed(obj) ? dom.find('.jstree-closed').addBack() : dom.find('.jstree-closed'); + dom.each(function () { + _this.open_node( + this, + function(node, status) { if(status && this.is_parent(node)) { this.open_all(node, animation, original_obj); } }, + animation || 0 + ); + }); + if(original_obj.find('.jstree-closed').length === 0) { + /** + * triggered when an `open_all` call completes + * @event + * @name open_all.jstree + * @param {Object} node the opened node + */ + this.trigger('open_all', { "node" : this.get_node(original_obj) }); + } + }, + /** + * closes all nodes within a node (or the tree), revaling their children + * @name close_all([obj, animation]) + * @param {mixed} obj the node to close recursively, omit to close all nodes in the tree + * @param {Number} animation the animation duration in milliseconds when closing the nodes, the default is no animation + * @trigger close_all.jstree + */ + close_all : function (obj, animation) { + if(!obj) { obj = $.jstree.root; } + obj = this.get_node(obj); + if(!obj) { return false; } + var dom = obj.id === $.jstree.root ? this.get_container_ul() : this.get_node(obj, true), + _this = this, i, j; + if(dom.length) { + dom = this.is_open(obj) ? dom.find('.jstree-open').addBack() : dom.find('.jstree-open'); + $(dom.get().reverse()).each(function () { _this.close_node(this, animation || 0); }); + } + for(i = 0, j = obj.children_d.length; i < j; i++) { + this._model.data[obj.children_d[i]].state.opened = false; + } + /** + * triggered when an `close_all` call completes + * @event + * @name close_all.jstree + * @param {Object} node the closed node + */ + this.trigger('close_all', { "node" : obj }); + }, + /** + * checks if a node is disabled (not selectable) + * @name is_disabled(obj) + * @param {mixed} obj + * @return {Boolean} + */ + is_disabled : function (obj) { + obj = this.get_node(obj); + return obj && obj.state && obj.state.disabled; + }, + /** + * enables a node - so that it can be selected + * @name enable_node(obj) + * @param {mixed} obj the node to enable + * @trigger enable_node.jstree + */ + enable_node : function (obj) { + var t1, t2; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.enable_node(obj[t1]); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { + return false; + } + obj.state.disabled = false; + this.get_node(obj,true).children('.jstree-anchor').removeClass('jstree-disabled').attr('aria-disabled', false); + /** + * triggered when an node is enabled + * @event + * @name enable_node.jstree + * @param {Object} node the enabled node + */ + this.trigger('enable_node', { 'node' : obj }); + }, + /** + * disables a node - so that it can not be selected + * @name disable_node(obj) + * @param {mixed} obj the node to disable + * @trigger disable_node.jstree + */ + disable_node : function (obj) { + var t1, t2; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.disable_node(obj[t1]); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { + return false; + } + obj.state.disabled = true; + this.get_node(obj,true).children('.jstree-anchor').addClass('jstree-disabled').attr('aria-disabled', true); + /** + * triggered when an node is disabled + * @event + * @name disable_node.jstree + * @param {Object} node the disabled node + */ + this.trigger('disable_node', { 'node' : obj }); + }, + /** + * determines if a node is hidden + * @name is_hidden(obj) + * @param {mixed} obj the node + */ + is_hidden : function (obj) { + obj = this.get_node(obj); + return obj.state.hidden === true; + }, + /** + * hides a node - it is still in the structure but will not be visible + * @name hide_node(obj) + * @param {mixed} obj the node to hide + * @param {Boolean} skip_redraw internal parameter controlling if redraw is called + * @trigger hide_node.jstree + */ + hide_node : function (obj, skip_redraw) { + var t1, t2; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.hide_node(obj[t1], true); + } + if (!skip_redraw) { + this.redraw(); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { + return false; + } + if(!obj.state.hidden) { + obj.state.hidden = true; + this._node_changed(obj.parent); + if(!skip_redraw) { + this.redraw(); + } + /** + * triggered when an node is hidden + * @event + * @name hide_node.jstree + * @param {Object} node the hidden node + */ + this.trigger('hide_node', { 'node' : obj }); + } + }, + /** + * shows a node + * @name show_node(obj) + * @param {mixed} obj the node to show + * @param {Boolean} skip_redraw internal parameter controlling if redraw is called + * @trigger show_node.jstree + */ + show_node : function (obj, skip_redraw) { + var t1, t2; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.show_node(obj[t1], true); + } + if (!skip_redraw) { + this.redraw(); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { + return false; + } + if(obj.state.hidden) { + obj.state.hidden = false; + this._node_changed(obj.parent); + if(!skip_redraw) { + this.redraw(); + } + /** + * triggered when an node is shown + * @event + * @name show_node.jstree + * @param {Object} node the shown node + */ + this.trigger('show_node', { 'node' : obj }); + } + }, + /** + * hides all nodes + * @name hide_all() + * @trigger hide_all.jstree + */ + hide_all : function (skip_redraw) { + var i, m = this._model.data, ids = []; + for(i in m) { + if(m.hasOwnProperty(i) && i !== $.jstree.root && !m[i].state.hidden) { + m[i].state.hidden = true; + ids.push(i); + } + } + this._model.force_full_redraw = true; + if(!skip_redraw) { + this.redraw(); + } + /** + * triggered when all nodes are hidden + * @event + * @name hide_all.jstree + * @param {Array} nodes the IDs of all hidden nodes + */ + this.trigger('hide_all', { 'nodes' : ids }); + return ids; + }, + /** + * shows all nodes + * @name show_all() + * @trigger show_all.jstree + */ + show_all : function (skip_redraw) { + var i, m = this._model.data, ids = []; + for(i in m) { + if(m.hasOwnProperty(i) && i !== $.jstree.root && m[i].state.hidden) { + m[i].state.hidden = false; + ids.push(i); + } + } + this._model.force_full_redraw = true; + if(!skip_redraw) { + this.redraw(); + } + /** + * triggered when all nodes are shown + * @event + * @name show_all.jstree + * @param {Array} nodes the IDs of all shown nodes + */ + this.trigger('show_all', { 'nodes' : ids }); + return ids; + }, + /** + * called when a node is selected by the user. Used internally. + * @private + * @name activate_node(obj, e) + * @param {mixed} obj the node + * @param {Object} e the related event + * @trigger activate_node.jstree, changed.jstree + */ + activate_node : function (obj, e) { + if(this.is_disabled(obj)) { + return false; + } + if(!e || typeof e !== 'object') { + e = {}; + } + + // ensure last_clicked is still in the DOM, make it fresh (maybe it was moved?) and make sure it is still selected, if not - make last_clicked the last selected node + this._data.core.last_clicked = this._data.core.last_clicked && this._data.core.last_clicked.id !== undefined ? this.get_node(this._data.core.last_clicked.id) : null; + if(this._data.core.last_clicked && !this._data.core.last_clicked.state.selected) { this._data.core.last_clicked = null; } + if(!this._data.core.last_clicked && this._data.core.selected.length) { this._data.core.last_clicked = this.get_node(this._data.core.selected[this._data.core.selected.length - 1]); } + + if(!this.settings.core.multiple || (!e.metaKey && !e.ctrlKey && !e.shiftKey) || (e.shiftKey && (!this._data.core.last_clicked || !this.get_parent(obj) || this.get_parent(obj) !== this._data.core.last_clicked.parent ) )) { + if(!this.settings.core.multiple && (e.metaKey || e.ctrlKey || e.shiftKey) && this.is_selected(obj)) { + this.deselect_node(obj, false, e); + } + else { + this.deselect_all(true); + this.select_node(obj, false, false, e); + this._data.core.last_clicked = this.get_node(obj); + } + } + else { + if(e.shiftKey) { + var o = this.get_node(obj).id, + l = this._data.core.last_clicked.id, + p = this.get_node(this._data.core.last_clicked.parent).children, + c = false, + i, j; + for(i = 0, j = p.length; i < j; i += 1) { + // separate IFs work whem o and l are the same + if(p[i] === o) { + c = !c; + } + if(p[i] === l) { + c = !c; + } + if(!this.is_disabled(p[i]) && (c || p[i] === o || p[i] === l)) { + if (!this.is_hidden(p[i])) { + this.select_node(p[i], true, false, e); + } + } + else { + this.deselect_node(p[i], true, e); + } + } + this.trigger('changed', { 'action' : 'select_node', 'node' : this.get_node(obj), 'selected' : this._data.core.selected, 'event' : e }); + } + else { + if(!this.is_selected(obj)) { + this.select_node(obj, false, false, e); + } + else { + this.deselect_node(obj, false, e); + } + } + } + /** + * triggered when an node is clicked or intercated with by the user + * @event + * @name activate_node.jstree + * @param {Object} node + * @param {Object} event the ooriginal event (if any) which triggered the call (may be an empty object) + */ + this.trigger('activate_node', { 'node' : this.get_node(obj), 'event' : e }); + }, + /** + * applies the hover state on a node, called when a node is hovered by the user. Used internally. + * @private + * @name hover_node(obj) + * @param {mixed} obj + * @trigger hover_node.jstree + */ + hover_node : function (obj) { + obj = this.get_node(obj, true); + if(!obj || !obj.length || obj.children('.jstree-hovered').length) { + return false; + } + var o = this.element.find('.jstree-hovered'), t = this.element; + if(o && o.length) { this.dehover_node(o); } + + obj.children('.jstree-anchor').addClass('jstree-hovered'); + /** + * triggered when an node is hovered + * @event + * @name hover_node.jstree + * @param {Object} node + */ + this.trigger('hover_node', { 'node' : this.get_node(obj) }); + setTimeout(function () { t.attr('aria-activedescendant', obj[0].id); }, 0); + }, + /** + * removes the hover state from a nodecalled when a node is no longer hovered by the user. Used internally. + * @private + * @name dehover_node(obj) + * @param {mixed} obj + * @trigger dehover_node.jstree + */ + dehover_node : function (obj) { + obj = this.get_node(obj, true); + if(!obj || !obj.length || !obj.children('.jstree-hovered').length) { + return false; + } + obj.children('.jstree-anchor').removeClass('jstree-hovered'); + /** + * triggered when an node is no longer hovered + * @event + * @name dehover_node.jstree + * @param {Object} node + */ + this.trigger('dehover_node', { 'node' : this.get_node(obj) }); + }, + /** + * select a node + * @name select_node(obj [, supress_event, prevent_open]) + * @param {mixed} obj an array can be used to select multiple nodes + * @param {Boolean} supress_event if set to `true` the `changed.jstree` event won't be triggered + * @param {Boolean} prevent_open if set to `true` parents of the selected node won't be opened + * @trigger select_node.jstree, changed.jstree + */ + select_node : function (obj, supress_event, prevent_open, e) { + var dom, t1, t2, th; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.select_node(obj[t1], supress_event, prevent_open, e); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { + return false; + } + dom = this.get_node(obj, true); + if(!obj.state.selected) { + obj.state.selected = true; + this._data.core.selected.push(obj.id); + if(!prevent_open) { + dom = this._open_to(obj); + } + if(dom && dom.length) { + dom.attr('aria-selected', true).children('.jstree-anchor').addClass('jstree-clicked'); + } + /** + * triggered when an node is selected + * @event + * @name select_node.jstree + * @param {Object} node + * @param {Array} selected the current selection + * @param {Object} event the event (if any) that triggered this select_node + */ + this.trigger('select_node', { 'node' : obj, 'selected' : this._data.core.selected, 'event' : e }); + if(!supress_event) { + /** + * triggered when selection changes + * @event + * @name changed.jstree + * @param {Object} node + * @param {Object} action the action that caused the selection to change + * @param {Array} selected the current selection + * @param {Object} event the event (if any) that triggered this changed event + */ + this.trigger('changed', { 'action' : 'select_node', 'node' : obj, 'selected' : this._data.core.selected, 'event' : e }); + } + } + }, + /** + * deselect a node + * @name deselect_node(obj [, supress_event]) + * @param {mixed} obj an array can be used to deselect multiple nodes + * @param {Boolean} supress_event if set to `true` the `changed.jstree` event won't be triggered + * @trigger deselect_node.jstree, changed.jstree + */ + deselect_node : function (obj, supress_event, e) { + var t1, t2, dom; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.deselect_node(obj[t1], supress_event, e); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { + return false; + } + dom = this.get_node(obj, true); + if(obj.state.selected) { + obj.state.selected = false; + this._data.core.selected = $.vakata.array_remove_item(this._data.core.selected, obj.id); + if(dom.length) { + dom.attr('aria-selected', false).children('.jstree-anchor').removeClass('jstree-clicked'); + } + /** + * triggered when an node is deselected + * @event + * @name deselect_node.jstree + * @param {Object} node + * @param {Array} selected the current selection + * @param {Object} event the event (if any) that triggered this deselect_node + */ + this.trigger('deselect_node', { 'node' : obj, 'selected' : this._data.core.selected, 'event' : e }); + if(!supress_event) { + this.trigger('changed', { 'action' : 'deselect_node', 'node' : obj, 'selected' : this._data.core.selected, 'event' : e }); + } + } + }, + /** + * select all nodes in the tree + * @name select_all([supress_event]) + * @param {Boolean} supress_event if set to `true` the `changed.jstree` event won't be triggered + * @trigger select_all.jstree, changed.jstree + */ + select_all : function (supress_event) { + var tmp = this._data.core.selected.concat([]), i, j; + this._data.core.selected = this._model.data[$.jstree.root].children_d.concat(); + for(i = 0, j = this._data.core.selected.length; i < j; i++) { + if(this._model.data[this._data.core.selected[i]]) { + this._model.data[this._data.core.selected[i]].state.selected = true; + } + } + this.redraw(true); + /** + * triggered when all nodes are selected + * @event + * @name select_all.jstree + * @param {Array} selected the current selection + */ + this.trigger('select_all', { 'selected' : this._data.core.selected }); + if(!supress_event) { + this.trigger('changed', { 'action' : 'select_all', 'selected' : this._data.core.selected, 'old_selection' : tmp }); + } + }, + /** + * deselect all selected nodes + * @name deselect_all([supress_event]) + * @param {Boolean} supress_event if set to `true` the `changed.jstree` event won't be triggered + * @trigger deselect_all.jstree, changed.jstree + */ + deselect_all : function (supress_event) { + var tmp = this._data.core.selected.concat([]), i, j; + for(i = 0, j = this._data.core.selected.length; i < j; i++) { + if(this._model.data[this._data.core.selected[i]]) { + this._model.data[this._data.core.selected[i]].state.selected = false; + } + } + this._data.core.selected = []; + this.element.find('.jstree-clicked').removeClass('jstree-clicked').parent().attr('aria-selected', false); + /** + * triggered when all nodes are deselected + * @event + * @name deselect_all.jstree + * @param {Object} node the previous selection + * @param {Array} selected the current selection + */ + this.trigger('deselect_all', { 'selected' : this._data.core.selected, 'node' : tmp }); + if(!supress_event) { + this.trigger('changed', { 'action' : 'deselect_all', 'selected' : this._data.core.selected, 'old_selection' : tmp }); + } + }, + /** + * checks if a node is selected + * @name is_selected(obj) + * @param {mixed} obj + * @return {Boolean} + */ + is_selected : function (obj) { + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { + return false; + } + return obj.state.selected; + }, + /** + * get an array of all selected nodes + * @name get_selected([full]) + * @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned + * @return {Array} + */ + get_selected : function (full) { + return full ? $.map(this._data.core.selected, $.proxy(function (i) { return this.get_node(i); }, this)) : this._data.core.selected.slice(); + }, + /** + * get an array of all top level selected nodes (ignoring children of selected nodes) + * @name get_top_selected([full]) + * @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned + * @return {Array} + */ + get_top_selected : function (full) { + var tmp = this.get_selected(true), + obj = {}, i, j, k, l; + for(i = 0, j = tmp.length; i < j; i++) { + obj[tmp[i].id] = tmp[i]; + } + for(i = 0, j = tmp.length; i < j; i++) { + for(k = 0, l = tmp[i].children_d.length; k < l; k++) { + if(obj[tmp[i].children_d[k]]) { + delete obj[tmp[i].children_d[k]]; + } + } + } + tmp = []; + for(i in obj) { + if(obj.hasOwnProperty(i)) { + tmp.push(i); + } + } + return full ? $.map(tmp, $.proxy(function (i) { return this.get_node(i); }, this)) : tmp; + }, + /** + * get an array of all bottom level selected nodes (ignoring selected parents) + * @name get_bottom_selected([full]) + * @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned + * @return {Array} + */ + get_bottom_selected : function (full) { + var tmp = this.get_selected(true), + obj = [], i, j; + for(i = 0, j = tmp.length; i < j; i++) { + if(!tmp[i].children.length) { + obj.push(tmp[i].id); + } + } + return full ? $.map(obj, $.proxy(function (i) { return this.get_node(i); }, this)) : obj; + }, + /** + * gets the current state of the tree so that it can be restored later with `set_state(state)`. Used internally. + * @name get_state() + * @private + * @return {Object} + */ + get_state : function () { + var state = { + 'core' : { + 'open' : [], + 'scroll' : { + 'left' : this.element.scrollLeft(), + 'top' : this.element.scrollTop() + }, + /*! + 'themes' : { + 'name' : this.get_theme(), + 'icons' : this._data.core.themes.icons, + 'dots' : this._data.core.themes.dots + }, + */ + 'selected' : [] + } + }, i; + for(i in this._model.data) { + if(this._model.data.hasOwnProperty(i)) { + if(i !== $.jstree.root) { + if(this._model.data[i].state.opened) { + state.core.open.push(i); + } + if(this._model.data[i].state.selected) { + state.core.selected.push(i); + } + } + } + } + return state; + }, + /** + * sets the state of the tree. Used internally. + * @name set_state(state [, callback]) + * @private + * @param {Object} state the state to restore. Keep in mind this object is passed by reference and jstree will modify it. + * @param {Function} callback an optional function to execute once the state is restored. + * @trigger set_state.jstree + */ + set_state : function (state, callback) { + if(state) { + if(state.core) { + var res, n, t, _this, i; + if(state.core.open) { + if(!$.isArray(state.core.open) || !state.core.open.length) { + delete state.core.open; + this.set_state(state, callback); + } + else { + this._load_nodes(state.core.open, function (nodes) { + this.open_node(nodes, false, 0); + delete state.core.open; + this.set_state(state, callback); + }); + } + return false; + } + if(state.core.scroll) { + if(state.core.scroll && state.core.scroll.left !== undefined) { + this.element.scrollLeft(state.core.scroll.left); + } + if(state.core.scroll && state.core.scroll.top !== undefined) { + this.element.scrollTop(state.core.scroll.top); + } + delete state.core.scroll; + this.set_state(state, callback); + return false; + } + if(state.core.selected) { + _this = this; + this.deselect_all(); + $.each(state.core.selected, function (i, v) { + _this.select_node(v, false, true); + }); + delete state.core.selected; + this.set_state(state, callback); + return false; + } + for(i in state) { + if(state.hasOwnProperty(i) && i !== "core" && $.inArray(i, this.settings.plugins) === -1) { + delete state[i]; + } + } + if($.isEmptyObject(state.core)) { + delete state.core; + this.set_state(state, callback); + return false; + } + } + if($.isEmptyObject(state)) { + state = null; + if(callback) { callback.call(this); } + /** + * triggered when a `set_state` call completes + * @event + * @name set_state.jstree + */ + this.trigger('set_state'); + return false; + } + return true; + } + return false; + }, + /** + * refreshes the tree - all nodes are reloaded with calls to `load_node`. + * @name refresh() + * @param {Boolean} skip_loading an option to skip showing the loading indicator + * @param {Mixed} forget_state if set to `true` state will not be reapplied, if set to a function (receiving the current state as argument) the result of that function will be used as state + * @trigger refresh.jstree + */ + refresh : function (skip_loading, forget_state) { + this._data.core.state = forget_state === true ? {} : this.get_state(); + if(forget_state && $.isFunction(forget_state)) { this._data.core.state = forget_state.call(this, this._data.core.state); } + this._cnt = 0; + this._model.data = {}; + this._model.data[$.jstree.root] = { + id : $.jstree.root, + parent : null, + parents : [], + children : [], + children_d : [], + state : { loaded : false } + }; + this._data.core.selected = []; + this._data.core.last_clicked = null; + this._data.core.focused = null; + + var c = this.get_container_ul()[0].className; + if(!skip_loading) { + this.element.html("<"+"ul class='"+c+"' role='group'><"+"li class='jstree-initial-node jstree-loading jstree-leaf jstree-last' role='treeitem' id='j"+this._id+"_loading'><i class='jstree-icon jstree-ocl'></i><"+"a class='jstree-anchor' href='#'><i class='jstree-icon jstree-themeicon-hidden'></i>" + this.get_string("Loading ...") + "</a></li></ul>"); + this.element.attr('aria-activedescendant','j'+this._id+'_loading'); + } + this.load_node($.jstree.root, function (o, s) { + if(s) { + this.get_container_ul()[0].className = c; + if(this._firstChild(this.get_container_ul()[0])) { + this.element.attr('aria-activedescendant',this._firstChild(this.get_container_ul()[0]).id); + } + this.set_state($.extend(true, {}, this._data.core.state), function () { + /** + * triggered when a `refresh` call completes + * @event + * @name refresh.jstree + */ + this.trigger('refresh'); + }); + } + this._data.core.state = null; + }); + }, + /** + * refreshes a node in the tree (reload its children) all opened nodes inside that node are reloaded with calls to `load_node`. + * @name refresh_node(obj) + * @param {mixed} obj the node + * @trigger refresh_node.jstree + */ + refresh_node : function (obj) { + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { return false; } + var opened = [], to_load = [], s = this._data.core.selected.concat([]); + to_load.push(obj.id); + if(obj.state.opened === true) { opened.push(obj.id); } + this.get_node(obj, true).find('.jstree-open').each(function() { to_load.push(this.id); opened.push(this.id); }); + this._load_nodes(to_load, $.proxy(function (nodes) { + this.open_node(opened, false, 0); + this.select_node(s); + /** + * triggered when a node is refreshed + * @event + * @name refresh_node.jstree + * @param {Object} node - the refreshed node + * @param {Array} nodes - an array of the IDs of the nodes that were reloaded + */ + this.trigger('refresh_node', { 'node' : obj, 'nodes' : nodes }); + }, this), false, true); + }, + /** + * set (change) the ID of a node + * @name set_id(obj, id) + * @param {mixed} obj the node + * @param {String} id the new ID + * @return {Boolean} + * @trigger set_id.jstree + */ + set_id : function (obj, id) { + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { return false; } + var i, j, m = this._model.data, old = obj.id; + id = id.toString(); + // update parents (replace current ID with new one in children and children_d) + m[obj.parent].children[$.inArray(obj.id, m[obj.parent].children)] = id; + for(i = 0, j = obj.parents.length; i < j; i++) { + m[obj.parents[i]].children_d[$.inArray(obj.id, m[obj.parents[i]].children_d)] = id; + } + // update children (replace current ID with new one in parent and parents) + for(i = 0, j = obj.children.length; i < j; i++) { + m[obj.children[i]].parent = id; + } + for(i = 0, j = obj.children_d.length; i < j; i++) { + m[obj.children_d[i]].parents[$.inArray(obj.id, m[obj.children_d[i]].parents)] = id; + } + i = $.inArray(obj.id, this._data.core.selected); + if(i !== -1) { this._data.core.selected[i] = id; } + // update model and obj itself (obj.id, this._model.data[KEY]) + i = this.get_node(obj.id, true); + if(i) { + i.attr('id', id); //.children('.jstree-anchor').attr('id', id + '_anchor').end().attr('aria-labelledby', id + '_anchor'); + if(this.element.attr('aria-activedescendant') === obj.id) { + this.element.attr('aria-activedescendant', id); + } + } + delete m[obj.id]; + obj.id = id; + obj.li_attr.id = id; + m[id] = obj; + /** + * triggered when a node id value is changed + * @event + * @name set_id.jstree + * @param {Object} node + * @param {String} old the old id + */ + this.trigger('set_id',{ "node" : obj, "new" : obj.id, "old" : old }); + return true; + }, + /** + * get the text value of a node + * @name get_text(obj) + * @param {mixed} obj the node + * @return {String} + */ + get_text : function (obj) { + obj = this.get_node(obj); + return (!obj || obj.id === $.jstree.root) ? false : obj.text; + }, + /** + * set the text value of a node. Used internally, please use `rename_node(obj, val)`. + * @private + * @name set_text(obj, val) + * @param {mixed} obj the node, you can pass an array to set the text on multiple nodes + * @param {String} val the new text value + * @return {Boolean} + * @trigger set_text.jstree + */ + set_text : function (obj, val) { + var t1, t2; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.set_text(obj[t1], val); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { return false; } + obj.text = val; + if(this.get_node(obj, true).length) { + this.redraw_node(obj.id); + } + /** + * triggered when a node text value is changed + * @event + * @name set_text.jstree + * @param {Object} obj + * @param {String} text the new value + */ + this.trigger('set_text',{ "obj" : obj, "text" : val }); + return true; + }, + /** + * gets a JSON representation of a node (or the whole tree) + * @name get_json([obj, options]) + * @param {mixed} obj + * @param {Object} options + * @param {Boolean} options.no_state do not return state information + * @param {Boolean} options.no_id do not return ID + * @param {Boolean} options.no_children do not include children + * @param {Boolean} options.no_data do not include node data + * @param {Boolean} options.no_li_attr do not include LI attributes + * @param {Boolean} options.no_a_attr do not include A attributes + * @param {Boolean} options.flat return flat JSON instead of nested + * @return {Object} + */ + get_json : function (obj, options, flat) { + obj = this.get_node(obj || $.jstree.root); + if(!obj) { return false; } + if(options && options.flat && !flat) { flat = []; } + var tmp = { + 'id' : obj.id, + 'text' : obj.text, + 'icon' : this.get_icon(obj), + 'li_attr' : $.extend(true, {}, obj.li_attr), + 'a_attr' : $.extend(true, {}, obj.a_attr), + 'state' : {}, + 'data' : options && options.no_data ? false : $.extend(true, {}, obj.data) + //( this.get_node(obj, true).length ? this.get_node(obj, true).data() : obj.data ), + }, i, j; + if(options && options.flat) { + tmp.parent = obj.parent; + } + else { + tmp.children = []; + } + if(!options || !options.no_state) { + for(i in obj.state) { + if(obj.state.hasOwnProperty(i)) { + tmp.state[i] = obj.state[i]; + } + } + } else { + delete tmp.state; + } + if(options && options.no_li_attr) { + delete tmp.li_attr; + } + if(options && options.no_a_attr) { + delete tmp.a_attr; + } + if(options && options.no_id) { + delete tmp.id; + if(tmp.li_attr && tmp.li_attr.id) { + delete tmp.li_attr.id; + } + if(tmp.a_attr && tmp.a_attr.id) { + delete tmp.a_attr.id; + } + } + if(options && options.flat && obj.id !== $.jstree.root) { + flat.push(tmp); + } + if(!options || !options.no_children) { + for(i = 0, j = obj.children.length; i < j; i++) { + if(options && options.flat) { + this.get_json(obj.children[i], options, flat); + } + else { + tmp.children.push(this.get_json(obj.children[i], options)); + } + } + } + return options && options.flat ? flat : (obj.id === $.jstree.root ? tmp.children : tmp); + }, + /** + * create a new node (do not confuse with load_node) + * @name create_node([par, node, pos, callback, is_loaded]) + * @param {mixed} par the parent node (to create a root node use either "#" (string) or `null`) + * @param {mixed} node the data for the new node (a valid JSON object, or a simple string with the name) + * @param {mixed} pos the index at which to insert the node, "first" and "last" are also supported, default is "last" + * @param {Function} callback a function to be called once the node is created + * @param {Boolean} is_loaded internal argument indicating if the parent node was succesfully loaded + * @return {String} the ID of the newly create node + * @trigger model.jstree, create_node.jstree + */ + create_node : function (par, node, pos, callback, is_loaded) { + if(par === null) { par = $.jstree.root; } + par = this.get_node(par); + if(!par) { return false; } + pos = pos === undefined ? "last" : pos; + if(!pos.toString().match(/^(before|after)$/) && !is_loaded && !this.is_loaded(par)) { + return this.load_node(par, function () { this.create_node(par, node, pos, callback, true); }); + } + if(!node) { node = { "text" : this.get_string('New node') }; } + if(typeof node === "string") { node = { "text" : node }; } + if(node.text === undefined) { node.text = this.get_string('New node'); } + var tmp, dpc, i, j; + + if(par.id === $.jstree.root) { + if(pos === "before") { pos = "first"; } + if(pos === "after") { pos = "last"; } + } + switch(pos) { + case "before": + tmp = this.get_node(par.parent); + pos = $.inArray(par.id, tmp.children); + par = tmp; + break; + case "after" : + tmp = this.get_node(par.parent); + pos = $.inArray(par.id, tmp.children) + 1; + par = tmp; + break; + case "inside": + case "first": + pos = 0; + break; + case "last": + pos = par.children.length; + break; + default: + if(!pos) { pos = 0; } + break; + } + if(pos > par.children.length) { pos = par.children.length; } + if(!node.id) { node.id = true; } + if(!this.check("create_node", node, par, pos)) { + this.settings.core.error.call(this, this._data.core.last_error); + return false; + } + if(node.id === true) { delete node.id; } + node = this._parse_model_from_json(node, par.id, par.parents.concat()); + if(!node) { return false; } + tmp = this.get_node(node); + dpc = []; + dpc.push(node); + dpc = dpc.concat(tmp.children_d); + this.trigger('model', { "nodes" : dpc, "parent" : par.id }); + + par.children_d = par.children_d.concat(dpc); + for(i = 0, j = par.parents.length; i < j; i++) { + this._model.data[par.parents[i]].children_d = this._model.data[par.parents[i]].children_d.concat(dpc); + } + node = tmp; + tmp = []; + for(i = 0, j = par.children.length; i < j; i++) { + tmp[i >= pos ? i+1 : i] = par.children[i]; + } + tmp[pos] = node.id; + par.children = tmp; + + this.redraw_node(par, true); + if(callback) { callback.call(this, this.get_node(node)); } + /** + * triggered when a node is created + * @event + * @name create_node.jstree + * @param {Object} node + * @param {String} parent the parent's ID + * @param {Number} position the position of the new node among the parent's children + */ + this.trigger('create_node', { "node" : this.get_node(node), "parent" : par.id, "position" : pos }); + return node.id; + }, + /** + * set the text value of a node + * @name rename_node(obj, val) + * @param {mixed} obj the node, you can pass an array to rename multiple nodes to the same name + * @param {String} val the new text value + * @return {Boolean} + * @trigger rename_node.jstree + */ + rename_node : function (obj, val) { + var t1, t2, old; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.rename_node(obj[t1], val); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { return false; } + old = obj.text; + if(!this.check("rename_node", obj, this.get_parent(obj), val)) { + this.settings.core.error.call(this, this._data.core.last_error); + return false; + } + this.set_text(obj, val); // .apply(this, Array.prototype.slice.call(arguments)) + /** + * triggered when a node is renamed + * @event + * @name rename_node.jstree + * @param {Object} node + * @param {String} text the new value + * @param {String} old the old value + */ + this.trigger('rename_node', { "node" : obj, "text" : val, "old" : old }); + return true; + }, + /** + * remove a node + * @name delete_node(obj) + * @param {mixed} obj the node, you can pass an array to delete multiple nodes + * @return {Boolean} + * @trigger delete_node.jstree, changed.jstree + */ + delete_node : function (obj) { + var t1, t2, par, pos, tmp, i, j, k, l, c, top, lft; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.delete_node(obj[t1]); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { return false; } + par = this.get_node(obj.parent); + pos = $.inArray(obj.id, par.children); + c = false; + if(!this.check("delete_node", obj, par, pos)) { + this.settings.core.error.call(this, this._data.core.last_error); + return false; + } + if(pos !== -1) { + par.children = $.vakata.array_remove(par.children, pos); + } + tmp = obj.children_d.concat([]); + tmp.push(obj.id); + for(i = 0, j = obj.parents.length; i < j; i++) { + this._model.data[obj.parents[i]].children_d = $.vakata.array_filter(this._model.data[obj.parents[i]].children_d, function (v) { + return $.inArray(v, tmp) === -1; + }); + } + for(k = 0, l = tmp.length; k < l; k++) { + if(this._model.data[tmp[k]].state.selected) { + c = true; + break; + } + } + if (c) { + this._data.core.selected = $.vakata.array_filter(this._data.core.selected, function (v) { + return $.inArray(v, tmp) === -1; + }); + } + /** + * triggered when a node is deleted + * @event + * @name delete_node.jstree + * @param {Object} node + * @param {String} parent the parent's ID + */ + this.trigger('delete_node', { "node" : obj, "parent" : par.id }); + if(c) { + this.trigger('changed', { 'action' : 'delete_node', 'node' : obj, 'selected' : this._data.core.selected, 'parent' : par.id }); + } + for(k = 0, l = tmp.length; k < l; k++) { + delete this._model.data[tmp[k]]; + } + if($.inArray(this._data.core.focused, tmp) !== -1) { + this._data.core.focused = null; + top = this.element[0].scrollTop; + lft = this.element[0].scrollLeft; + if(par.id === $.jstree.root) { + if (this._model.data[$.jstree.root].children[0]) { + this.get_node(this._model.data[$.jstree.root].children[0], true).children('.jstree-anchor').focus(); + } + } + else { + this.get_node(par, true).children('.jstree-anchor').focus(); + } + this.element[0].scrollTop = top; + this.element[0].scrollLeft = lft; + } + this.redraw_node(par, true); + return true; + }, + /** + * check if an operation is premitted on the tree. Used internally. + * @private + * @name check(chk, obj, par, pos) + * @param {String} chk the operation to check, can be "create_node", "rename_node", "delete_node", "copy_node" or "move_node" + * @param {mixed} obj the node + * @param {mixed} par the parent + * @param {mixed} pos the position to insert at, or if "rename_node" - the new name + * @param {mixed} more some various additional information, for example if a "move_node" operations is triggered by DND this will be the hovered node + * @return {Boolean} + */ + check : function (chk, obj, par, pos, more) { + obj = obj && obj.id ? obj : this.get_node(obj); + par = par && par.id ? par : this.get_node(par); + var tmp = chk.match(/^move_node|copy_node|create_node$/i) ? par : obj, + chc = this.settings.core.check_callback; + if(chk === "move_node" || chk === "copy_node") { + if((!more || !more.is_multi) && (obj.id === par.id || (chk === "move_node" && $.inArray(obj.id, par.children) === pos) || $.inArray(par.id, obj.children_d) !== -1)) { + this._data.core.last_error = { 'error' : 'check', 'plugin' : 'core', 'id' : 'core_01', 'reason' : 'Moving parent inside child', 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) }; + return false; + } + } + if(tmp && tmp.data) { tmp = tmp.data; } + if(tmp && tmp.functions && (tmp.functions[chk] === false || tmp.functions[chk] === true)) { + if(tmp.functions[chk] === false) { + this._data.core.last_error = { 'error' : 'check', 'plugin' : 'core', 'id' : 'core_02', 'reason' : 'Node data prevents function: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) }; + } + return tmp.functions[chk]; + } + if(chc === false || ($.isFunction(chc) && chc.call(this, chk, obj, par, pos, more) === false) || (chc && chc[chk] === false)) { + this._data.core.last_error = { 'error' : 'check', 'plugin' : 'core', 'id' : 'core_03', 'reason' : 'User config for core.check_callback prevents function: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) }; + return false; + } + return true; + }, + /** + * get the last error + * @name last_error() + * @return {Object} + */ + last_error : function () { + return this._data.core.last_error; + }, + /** + * move a node to a new parent + * @name move_node(obj, par [, pos, callback, is_loaded]) + * @param {mixed} obj the node to move, pass an array to move multiple nodes + * @param {mixed} par the new parent + * @param {mixed} pos the position to insert at (besides integer values, "first" and "last" are supported, as well as "before" and "after"), defaults to integer `0` + * @param {function} callback a function to call once the move is completed, receives 3 arguments - the node, the new parent and the position + * @param {Boolean} is_loaded internal parameter indicating if the parent node has been loaded + * @param {Boolean} skip_redraw internal parameter indicating if the tree should be redrawn + * @param {Boolean} instance internal parameter indicating if the node comes from another instance + * @trigger move_node.jstree + */ + move_node : function (obj, par, pos, callback, is_loaded, skip_redraw, origin) { + var t1, t2, old_par, old_pos, new_par, old_ins, is_multi, dpc, tmp, i, j, k, l, p; + + par = this.get_node(par); + pos = pos === undefined ? 0 : pos; + if(!par) { return false; } + if(!pos.toString().match(/^(before|after)$/) && !is_loaded && !this.is_loaded(par)) { + return this.load_node(par, function () { this.move_node(obj, par, pos, callback, true, false, origin); }); + } + + if($.isArray(obj)) { + if(obj.length === 1) { + obj = obj[0]; + } + else { + //obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + if((tmp = this.move_node(obj[t1], par, pos, callback, is_loaded, false, origin))) { + par = tmp; + pos = "after"; + } + } + this.redraw(); + return true; + } + } + obj = obj && obj.id ? obj : this.get_node(obj); + + if(!obj || obj.id === $.jstree.root) { return false; } + + old_par = (obj.parent || $.jstree.root).toString(); + new_par = (!pos.toString().match(/^(before|after)$/) || par.id === $.jstree.root) ? par : this.get_node(par.parent); + old_ins = origin ? origin : (this._model.data[obj.id] ? this : $.jstree.reference(obj.id)); + is_multi = !old_ins || !old_ins._id || (this._id !== old_ins._id); + old_pos = old_ins && old_ins._id && old_par && old_ins._model.data[old_par] && old_ins._model.data[old_par].children ? $.inArray(obj.id, old_ins._model.data[old_par].children) : -1; + if(old_ins && old_ins._id) { + obj = old_ins._model.data[obj.id]; + } + + if(is_multi) { + if((tmp = this.copy_node(obj, par, pos, callback, is_loaded, false, origin))) { + if(old_ins) { old_ins.delete_node(obj); } + return tmp; + } + return false; + } + //var m = this._model.data; + if(par.id === $.jstree.root) { + if(pos === "before") { pos = "first"; } + if(pos === "after") { pos = "last"; } + } + switch(pos) { + case "before": + pos = $.inArray(par.id, new_par.children); + break; + case "after" : + pos = $.inArray(par.id, new_par.children) + 1; + break; + case "inside": + case "first": + pos = 0; + break; + case "last": + pos = new_par.children.length; + break; + default: + if(!pos) { pos = 0; } + break; + } + if(pos > new_par.children.length) { pos = new_par.children.length; } + if(!this.check("move_node", obj, new_par, pos, { 'core' : true, 'origin' : origin, 'is_multi' : (old_ins && old_ins._id && old_ins._id !== this._id), 'is_foreign' : (!old_ins || !old_ins._id) })) { + this.settings.core.error.call(this, this._data.core.last_error); + return false; + } + if(obj.parent === new_par.id) { + dpc = new_par.children.concat(); + tmp = $.inArray(obj.id, dpc); + if(tmp !== -1) { + dpc = $.vakata.array_remove(dpc, tmp); + if(pos > tmp) { pos--; } + } + tmp = []; + for(i = 0, j = dpc.length; i < j; i++) { + tmp[i >= pos ? i+1 : i] = dpc[i]; + } + tmp[pos] = obj.id; + new_par.children = tmp; + this._node_changed(new_par.id); + this.redraw(new_par.id === $.jstree.root); + } + else { + // clean old parent and up + tmp = obj.children_d.concat(); + tmp.push(obj.id); + for(i = 0, j = obj.parents.length; i < j; i++) { + dpc = []; + p = old_ins._model.data[obj.parents[i]].children_d; + for(k = 0, l = p.length; k < l; k++) { + if($.inArray(p[k], tmp) === -1) { + dpc.push(p[k]); + } + } + old_ins._model.data[obj.parents[i]].children_d = dpc; + } + old_ins._model.data[old_par].children = $.vakata.array_remove_item(old_ins._model.data[old_par].children, obj.id); + + // insert into new parent and up + for(i = 0, j = new_par.parents.length; i < j; i++) { + this._model.data[new_par.parents[i]].children_d = this._model.data[new_par.parents[i]].children_d.concat(tmp); + } + dpc = []; + for(i = 0, j = new_par.children.length; i < j; i++) { + dpc[i >= pos ? i+1 : i] = new_par.children[i]; + } + dpc[pos] = obj.id; + new_par.children = dpc; + new_par.children_d.push(obj.id); + new_par.children_d = new_par.children_d.concat(obj.children_d); + + // update object + obj.parent = new_par.id; + tmp = new_par.parents.concat(); + tmp.unshift(new_par.id); + p = obj.parents.length; + obj.parents = tmp; + + // update object children + tmp = tmp.concat(); + for(i = 0, j = obj.children_d.length; i < j; i++) { + this._model.data[obj.children_d[i]].parents = this._model.data[obj.children_d[i]].parents.slice(0,p*-1); + Array.prototype.push.apply(this._model.data[obj.children_d[i]].parents, tmp); + } + + if(old_par === $.jstree.root || new_par.id === $.jstree.root) { + this._model.force_full_redraw = true; + } + if(!this._model.force_full_redraw) { + this._node_changed(old_par); + this._node_changed(new_par.id); + } + if(!skip_redraw) { + this.redraw(); + } + } + if(callback) { callback.call(this, obj, new_par, pos); } + /** + * triggered when a node is moved + * @event + * @name move_node.jstree + * @param {Object} node + * @param {String} parent the parent's ID + * @param {Number} position the position of the node among the parent's children + * @param {String} old_parent the old parent of the node + * @param {Number} old_position the old position of the node + * @param {Boolean} is_multi do the node and new parent belong to different instances + * @param {jsTree} old_instance the instance the node came from + * @param {jsTree} new_instance the instance of the new parent + */ + this.trigger('move_node', { "node" : obj, "parent" : new_par.id, "position" : pos, "old_parent" : old_par, "old_position" : old_pos, 'is_multi' : (old_ins && old_ins._id && old_ins._id !== this._id), 'is_foreign' : (!old_ins || !old_ins._id), 'old_instance' : old_ins, 'new_instance' : this }); + return obj.id; + }, + /** + * copy a node to a new parent + * @name copy_node(obj, par [, pos, callback, is_loaded]) + * @param {mixed} obj the node to copy, pass an array to copy multiple nodes + * @param {mixed} par the new parent + * @param {mixed} pos the position to insert at (besides integer values, "first" and "last" are supported, as well as "before" and "after"), defaults to integer `0` + * @param {function} callback a function to call once the move is completed, receives 3 arguments - the node, the new parent and the position + * @param {Boolean} is_loaded internal parameter indicating if the parent node has been loaded + * @param {Boolean} skip_redraw internal parameter indicating if the tree should be redrawn + * @param {Boolean} instance internal parameter indicating if the node comes from another instance + * @trigger model.jstree copy_node.jstree + */ + copy_node : function (obj, par, pos, callback, is_loaded, skip_redraw, origin) { + var t1, t2, dpc, tmp, i, j, node, old_par, new_par, old_ins, is_multi; + + par = this.get_node(par); + pos = pos === undefined ? 0 : pos; + if(!par) { return false; } + if(!pos.toString().match(/^(before|after)$/) && !is_loaded && !this.is_loaded(par)) { + return this.load_node(par, function () { this.copy_node(obj, par, pos, callback, true, false, origin); }); + } + + if($.isArray(obj)) { + if(obj.length === 1) { + obj = obj[0]; + } + else { + //obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + if((tmp = this.copy_node(obj[t1], par, pos, callback, is_loaded, true, origin))) { + par = tmp; + pos = "after"; + } + } + this.redraw(); + return true; + } + } + obj = obj && obj.id ? obj : this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { return false; } + + old_par = (obj.parent || $.jstree.root).toString(); + new_par = (!pos.toString().match(/^(before|after)$/) || par.id === $.jstree.root) ? par : this.get_node(par.parent); + old_ins = origin ? origin : (this._model.data[obj.id] ? this : $.jstree.reference(obj.id)); + is_multi = !old_ins || !old_ins._id || (this._id !== old_ins._id); + + if(old_ins && old_ins._id) { + obj = old_ins._model.data[obj.id]; + } + + if(par.id === $.jstree.root) { + if(pos === "before") { pos = "first"; } + if(pos === "after") { pos = "last"; } + } + switch(pos) { + case "before": + pos = $.inArray(par.id, new_par.children); + break; + case "after" : + pos = $.inArray(par.id, new_par.children) + 1; + break; + case "inside": + case "first": + pos = 0; + break; + case "last": + pos = new_par.children.length; + break; + default: + if(!pos) { pos = 0; } + break; + } + if(pos > new_par.children.length) { pos = new_par.children.length; } + if(!this.check("copy_node", obj, new_par, pos, { 'core' : true, 'origin' : origin, 'is_multi' : (old_ins && old_ins._id && old_ins._id !== this._id), 'is_foreign' : (!old_ins || !old_ins._id) })) { + this.settings.core.error.call(this, this._data.core.last_error); + return false; + } + node = old_ins ? old_ins.get_json(obj, { no_id : true, no_data : true, no_state : true }) : obj; + if(!node) { return false; } + if(node.id === true) { delete node.id; } + node = this._parse_model_from_json(node, new_par.id, new_par.parents.concat()); + if(!node) { return false; } + tmp = this.get_node(node); + if(obj && obj.state && obj.state.loaded === false) { tmp.state.loaded = false; } + dpc = []; + dpc.push(node); + dpc = dpc.concat(tmp.children_d); + this.trigger('model', { "nodes" : dpc, "parent" : new_par.id }); + + // insert into new parent and up + for(i = 0, j = new_par.parents.length; i < j; i++) { + this._model.data[new_par.parents[i]].children_d = this._model.data[new_par.parents[i]].children_d.concat(dpc); + } + dpc = []; + for(i = 0, j = new_par.children.length; i < j; i++) { + dpc[i >= pos ? i+1 : i] = new_par.children[i]; + } + dpc[pos] = tmp.id; + new_par.children = dpc; + new_par.children_d.push(tmp.id); + new_par.children_d = new_par.children_d.concat(tmp.children_d); + + if(new_par.id === $.jstree.root) { + this._model.force_full_redraw = true; + } + if(!this._model.force_full_redraw) { + this._node_changed(new_par.id); + } + if(!skip_redraw) { + this.redraw(new_par.id === $.jstree.root); + } + if(callback) { callback.call(this, tmp, new_par, pos); } + /** + * triggered when a node is copied + * @event + * @name copy_node.jstree + * @param {Object} node the copied node + * @param {Object} original the original node + * @param {String} parent the parent's ID + * @param {Number} position the position of the node among the parent's children + * @param {String} old_parent the old parent of the node + * @param {Number} old_position the position of the original node + * @param {Boolean} is_multi do the node and new parent belong to different instances + * @param {jsTree} old_instance the instance the node came from + * @param {jsTree} new_instance the instance of the new parent + */ + this.trigger('copy_node', { "node" : tmp, "original" : obj, "parent" : new_par.id, "position" : pos, "old_parent" : old_par, "old_position" : old_ins && old_ins._id && old_par && old_ins._model.data[old_par] && old_ins._model.data[old_par].children ? $.inArray(obj.id, old_ins._model.data[old_par].children) : -1,'is_multi' : (old_ins && old_ins._id && old_ins._id !== this._id), 'is_foreign' : (!old_ins || !old_ins._id), 'old_instance' : old_ins, 'new_instance' : this }); + return tmp.id; + }, + /** + * cut a node (a later call to `paste(obj)` would move the node) + * @name cut(obj) + * @param {mixed} obj multiple objects can be passed using an array + * @trigger cut.jstree + */ + cut : function (obj) { + if(!obj) { obj = this._data.core.selected.concat(); } + if(!$.isArray(obj)) { obj = [obj]; } + if(!obj.length) { return false; } + var tmp = [], o, t1, t2; + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + o = this.get_node(obj[t1]); + if(o && o.id && o.id !== $.jstree.root) { tmp.push(o); } + } + if(!tmp.length) { return false; } + ccp_node = tmp; + ccp_inst = this; + ccp_mode = 'move_node'; + /** + * triggered when nodes are added to the buffer for moving + * @event + * @name cut.jstree + * @param {Array} node + */ + this.trigger('cut', { "node" : obj }); + }, + /** + * copy a node (a later call to `paste(obj)` would copy the node) + * @name copy(obj) + * @param {mixed} obj multiple objects can be passed using an array + * @trigger copy.jstree + */ + copy : function (obj) { + if(!obj) { obj = this._data.core.selected.concat(); } + if(!$.isArray(obj)) { obj = [obj]; } + if(!obj.length) { return false; } + var tmp = [], o, t1, t2; + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + o = this.get_node(obj[t1]); + if(o && o.id && o.id !== $.jstree.root) { tmp.push(o); } + } + if(!tmp.length) { return false; } + ccp_node = tmp; + ccp_inst = this; + ccp_mode = 'copy_node'; + /** + * triggered when nodes are added to the buffer for copying + * @event + * @name copy.jstree + * @param {Array} node + */ + this.trigger('copy', { "node" : obj }); + }, + /** + * get the current buffer (any nodes that are waiting for a paste operation) + * @name get_buffer() + * @return {Object} an object consisting of `mode` ("copy_node" or "move_node"), `node` (an array of objects) and `inst` (the instance) + */ + get_buffer : function () { + return { 'mode' : ccp_mode, 'node' : ccp_node, 'inst' : ccp_inst }; + }, + /** + * check if there is something in the buffer to paste + * @name can_paste() + * @return {Boolean} + */ + can_paste : function () { + return ccp_mode !== false && ccp_node !== false; // && ccp_inst._model.data[ccp_node]; + }, + /** + * copy or move the previously cut or copied nodes to a new parent + * @name paste(obj [, pos]) + * @param {mixed} obj the new parent + * @param {mixed} pos the position to insert at (besides integer, "first" and "last" are supported), defaults to integer `0` + * @trigger paste.jstree + */ + paste : function (obj, pos) { + obj = this.get_node(obj); + if(!obj || !ccp_mode || !ccp_mode.match(/^(copy_node|move_node)$/) || !ccp_node) { return false; } + if(this[ccp_mode](ccp_node, obj, pos, false, false, false, ccp_inst)) { + /** + * triggered when paste is invoked + * @event + * @name paste.jstree + * @param {String} parent the ID of the receiving node + * @param {Array} node the nodes in the buffer + * @param {String} mode the performed operation - "copy_node" or "move_node" + */ + this.trigger('paste', { "parent" : obj.id, "node" : ccp_node, "mode" : ccp_mode }); + } + ccp_node = false; + ccp_mode = false; + ccp_inst = false; + }, + /** + * clear the buffer of previously copied or cut nodes + * @name clear_buffer() + * @trigger clear_buffer.jstree + */ + clear_buffer : function () { + ccp_node = false; + ccp_mode = false; + ccp_inst = false; + /** + * triggered when the copy / cut buffer is cleared + * @event + * @name clear_buffer.jstree + */ + this.trigger('clear_buffer'); + }, + /** + * put a node in edit mode (input field to rename the node) + * @name edit(obj [, default_text, callback]) + * @param {mixed} obj + * @param {String} default_text the text to populate the input with (if omitted or set to a non-string value the node's text value is used) + * @param {Function} callback a function to be called once the text box is blurred, it is called in the instance's scope and receives the node, a status parameter (true if the rename is successful, false otherwise) and a boolean indicating if the user cancelled the edit. You can access the node's title using .text + */ + edit : function (obj, default_text, callback) { + var rtl, w, a, s, t, h1, h2, fn, tmp, cancel = false; + obj = this.get_node(obj); + if(!obj) { return false; } + if(this.settings.core.check_callback === false) { + this._data.core.last_error = { 'error' : 'check', 'plugin' : 'core', 'id' : 'core_07', 'reason' : 'Could not edit node because of check_callback' }; + this.settings.core.error.call(this, this._data.core.last_error); + return false; + } + tmp = obj; + default_text = typeof default_text === 'string' ? default_text : obj.text; + this.set_text(obj, ""); + obj = this._open_to(obj); + tmp.text = default_text; + + rtl = this._data.core.rtl; + w = this.element.width(); + this._data.core.focused = tmp.id; + a = obj.children('.jstree-anchor').focus(); + s = $('<span>'); + /*! + oi = obj.children("i:visible"), + ai = a.children("i:visible"), + w1 = oi.width() * oi.length, + w2 = ai.width() * ai.length, + */ + t = default_text; + h1 = $("<"+"div />", { css : { "position" : "absolute", "top" : "-200px", "left" : (rtl ? "0px" : "-1000px"), "visibility" : "hidden" } }).appendTo("body"); + h2 = $("<"+"input />", { + "value" : t, + "class" : "jstree-rename-input", + // "size" : t.length, + "css" : { + "padding" : "0", + "border" : "1px solid silver", + "box-sizing" : "border-box", + "display" : "inline-block", + "height" : (this._data.core.li_height) + "px", + "lineHeight" : (this._data.core.li_height) + "px", + "width" : "150px" // will be set a bit further down + }, + "blur" : $.proxy(function (e) { + e.stopImmediatePropagation(); + e.preventDefault(); + var i = s.children(".jstree-rename-input"), + v = i.val(), + f = this.settings.core.force_text, + nv; + if(v === "") { v = t; } + h1.remove(); + s.replaceWith(a); + s.remove(); + t = f ? t : $('<div></div>').append($.parseHTML(t)).html(); + this.set_text(obj, t); + nv = !!this.rename_node(obj, f ? $('<div></div>').text(v).text() : $('<div></div>').append($.parseHTML(v)).html()); + if(!nv) { + this.set_text(obj, t); // move this up? and fix #483 + } + this._data.core.focused = tmp.id; + setTimeout($.proxy(function () { + var node = this.get_node(tmp.id, true); + if(node.length) { + this._data.core.focused = tmp.id; + node.children('.jstree-anchor').focus(); + } + }, this), 0); + if(callback) { + callback.call(this, tmp, nv, cancel); + } + h2 = null; + }, this), + "keydown" : function (e) { + var key = e.which; + if(key === 27) { + cancel = true; + this.value = t; + } + if(key === 27 || key === 13 || key === 37 || key === 38 || key === 39 || key === 40 || key === 32) { + e.stopImmediatePropagation(); + } + if(key === 27 || key === 13) { + e.preventDefault(); + this.blur(); + } + }, + "click" : function (e) { e.stopImmediatePropagation(); }, + "mousedown" : function (e) { e.stopImmediatePropagation(); }, + "keyup" : function (e) { + h2.width(Math.min(h1.text("pW" + this.value).width(),w)); + }, + "keypress" : function(e) { + if(e.which === 13) { return false; } + } + }); + fn = { + fontFamily : a.css('fontFamily') || '', + fontSize : a.css('fontSize') || '', + fontWeight : a.css('fontWeight') || '', + fontStyle : a.css('fontStyle') || '', + fontStretch : a.css('fontStretch') || '', + fontVariant : a.css('fontVariant') || '', + letterSpacing : a.css('letterSpacing') || '', + wordSpacing : a.css('wordSpacing') || '' + }; + s.attr('class', a.attr('class')).append(a.contents().clone()).append(h2); + a.replaceWith(s); + h1.css(fn); + h2.css(fn).width(Math.min(h1.text("pW" + h2[0].value).width(),w))[0].select(); + $(document).one('mousedown.jstree touchstart.jstree dnd_start.vakata', function (e) { + if (h2 && e.target !== h2) { + $(h2).blur(); + } + }); + }, + + + /** + * changes the theme + * @name set_theme(theme_name [, theme_url]) + * @param {String} theme_name the name of the new theme to apply + * @param {mixed} theme_url the location of the CSS file for this theme. Omit or set to `false` if you manually included the file. Set to `true` to autoload from the `core.themes.dir` directory. + * @trigger set_theme.jstree + */ + set_theme : function (theme_name, theme_url) { + if(!theme_name) { return false; } + if(theme_url === true) { + var dir = this.settings.core.themes.dir; + if(!dir) { dir = $.jstree.path + '/themes'; } + theme_url = dir + '/' + theme_name + '/style.css'; + } + if(theme_url && $.inArray(theme_url, themes_loaded) === -1) { + $('head').append('<'+'link rel="stylesheet" href="' + theme_url + '" type="text/css" />'); + themes_loaded.push(theme_url); + } + if(this._data.core.themes.name) { + this.element.removeClass('jstree-' + this._data.core.themes.name); + } + this._data.core.themes.name = theme_name; + this.element.addClass('jstree-' + theme_name); + this.element[this.settings.core.themes.responsive ? 'addClass' : 'removeClass' ]('jstree-' + theme_name + '-responsive'); + /** + * triggered when a theme is set + * @event + * @name set_theme.jstree + * @param {String} theme the new theme + */ + this.trigger('set_theme', { 'theme' : theme_name }); + }, + /** + * gets the name of the currently applied theme name + * @name get_theme() + * @return {String} + */ + get_theme : function () { return this._data.core.themes.name; }, + /** + * changes the theme variant (if the theme has variants) + * @name set_theme_variant(variant_name) + * @param {String|Boolean} variant_name the variant to apply (if `false` is used the current variant is removed) + */ + set_theme_variant : function (variant_name) { + if(this._data.core.themes.variant) { + this.element.removeClass('jstree-' + this._data.core.themes.name + '-' + this._data.core.themes.variant); + } + this._data.core.themes.variant = variant_name; + if(variant_name) { + this.element.addClass('jstree-' + this._data.core.themes.name + '-' + this._data.core.themes.variant); + } + }, + /** + * gets the name of the currently applied theme variant + * @name get_theme() + * @return {String} + */ + get_theme_variant : function () { return this._data.core.themes.variant; }, + /** + * shows a striped background on the container (if the theme supports it) + * @name show_stripes() + */ + show_stripes : function () { + this._data.core.themes.stripes = true; + this.get_container_ul().addClass("jstree-striped"); + /** + * triggered when stripes are shown + * @event + * @name show_stripes.jstree + */ + this.trigger('show_stripes'); + }, + /** + * hides the striped background on the container + * @name hide_stripes() + */ + hide_stripes : function () { + this._data.core.themes.stripes = false; + this.get_container_ul().removeClass("jstree-striped"); + /** + * triggered when stripes are hidden + * @event + * @name hide_stripes.jstree + */ + this.trigger('hide_stripes'); + }, + /** + * toggles the striped background on the container + * @name toggle_stripes() + */ + toggle_stripes : function () { if(this._data.core.themes.stripes) { this.hide_stripes(); } else { this.show_stripes(); } }, + /** + * shows the connecting dots (if the theme supports it) + * @name show_dots() + */ + show_dots : function () { + this._data.core.themes.dots = true; + this.get_container_ul().removeClass("jstree-no-dots"); + /** + * triggered when dots are shown + * @event + * @name show_dots.jstree + */ + this.trigger('show_dots'); + }, + /** + * hides the connecting dots + * @name hide_dots() + */ + hide_dots : function () { + this._data.core.themes.dots = false; + this.get_container_ul().addClass("jstree-no-dots"); + /** + * triggered when dots are hidden + * @event + * @name hide_dots.jstree + */ + this.trigger('hide_dots'); + }, + /** + * toggles the connecting dots + * @name toggle_dots() + */ + toggle_dots : function () { if(this._data.core.themes.dots) { this.hide_dots(); } else { this.show_dots(); } }, + /** + * show the node icons + * @name show_icons() + */ + show_icons : function () { + this._data.core.themes.icons = true; + this.get_container_ul().removeClass("jstree-no-icons"); + /** + * triggered when icons are shown + * @event + * @name show_icons.jstree + */ + this.trigger('show_icons'); + }, + /** + * hide the node icons + * @name hide_icons() + */ + hide_icons : function () { + this._data.core.themes.icons = false; + this.get_container_ul().addClass("jstree-no-icons"); + /** + * triggered when icons are hidden + * @event + * @name hide_icons.jstree + */ + this.trigger('hide_icons'); + }, + /** + * toggle the node icons + * @name toggle_icons() + */ + toggle_icons : function () { if(this._data.core.themes.icons) { this.hide_icons(); } else { this.show_icons(); } }, + /** + * show the node ellipsis + * @name show_icons() + */ + show_ellipsis : function () { + this._data.core.themes.ellipsis = true; + this.get_container_ul().addClass("jstree-ellipsis"); + /** + * triggered when ellisis is shown + * @event + * @name show_ellipsis.jstree + */ + this.trigger('show_ellipsis'); + }, + /** + * hide the node ellipsis + * @name hide_ellipsis() + */ + hide_ellipsis : function () { + this._data.core.themes.ellipsis = false; + this.get_container_ul().removeClass("jstree-ellipsis"); + /** + * triggered when ellisis is hidden + * @event + * @name hide_ellipsis.jstree + */ + this.trigger('hide_ellipsis'); + }, + /** + * toggle the node ellipsis + * @name toggle_icons() + */ + toggle_ellipsis : function () { if(this._data.core.themes.ellipsis) { this.hide_ellipsis(); } else { this.show_ellipsis(); } }, + /** + * set the node icon for a node + * @name set_icon(obj, icon) + * @param {mixed} obj + * @param {String} icon the new icon - can be a path to an icon or a className, if using an image that is in the current directory use a `./` prefix, otherwise it will be detected as a class + */ + set_icon : function (obj, icon) { + var t1, t2, dom, old; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.set_icon(obj[t1], icon); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { return false; } + old = obj.icon; + obj.icon = icon === true || icon === null || icon === undefined || icon === '' ? true : icon; + dom = this.get_node(obj, true).children(".jstree-anchor").children(".jstree-themeicon"); + if(icon === false) { + this.hide_icon(obj); + } + else if(icon === true || icon === null || icon === undefined || icon === '') { + dom.removeClass('jstree-themeicon-custom ' + old).css("background","").removeAttr("rel"); + if(old === false) { this.show_icon(obj); } + } + else if(icon.indexOf("/") === -1 && icon.indexOf(".") === -1) { + dom.removeClass(old).css("background",""); + dom.addClass(icon + ' jstree-themeicon-custom').attr("rel",icon); + if(old === false) { this.show_icon(obj); } + } + else { + dom.removeClass(old).css("background",""); + dom.addClass('jstree-themeicon-custom').css("background", "url('" + icon + "') center center no-repeat").attr("rel",icon); + if(old === false) { this.show_icon(obj); } + } + return true; + }, + /** + * get the node icon for a node + * @name get_icon(obj) + * @param {mixed} obj + * @return {String} + */ + get_icon : function (obj) { + obj = this.get_node(obj); + return (!obj || obj.id === $.jstree.root) ? false : obj.icon; + }, + /** + * hide the icon on an individual node + * @name hide_icon(obj) + * @param {mixed} obj + */ + hide_icon : function (obj) { + var t1, t2; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.hide_icon(obj[t1]); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj === $.jstree.root) { return false; } + obj.icon = false; + this.get_node(obj, true).children(".jstree-anchor").children(".jstree-themeicon").addClass('jstree-themeicon-hidden'); + return true; + }, + /** + * show the icon on an individual node + * @name show_icon(obj) + * @param {mixed} obj + */ + show_icon : function (obj) { + var t1, t2, dom; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.show_icon(obj[t1]); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj === $.jstree.root) { return false; } + dom = this.get_node(obj, true); + obj.icon = dom.length ? dom.children(".jstree-anchor").children(".jstree-themeicon").attr('rel') : true; + if(!obj.icon) { obj.icon = true; } + dom.children(".jstree-anchor").children(".jstree-themeicon").removeClass('jstree-themeicon-hidden'); + return true; + } + }; + + // helpers + $.vakata = {}; + // collect attributes + $.vakata.attributes = function(node, with_values) { + node = $(node)[0]; + var attr = with_values ? {} : []; + if(node && node.attributes) { + $.each(node.attributes, function (i, v) { + if($.inArray(v.name.toLowerCase(),['style','contenteditable','hasfocus','tabindex']) !== -1) { return; } + if(v.value !== null && $.trim(v.value) !== '') { + if(with_values) { attr[v.name] = v.value; } + else { attr.push(v.name); } + } + }); + } + return attr; + }; + $.vakata.array_unique = function(array) { + var a = [], i, j, l, o = {}; + for(i = 0, l = array.length; i < l; i++) { + if(o[array[i]] === undefined) { + a.push(array[i]); + o[array[i]] = true; + } + } + return a; + }; + // remove item from array + $.vakata.array_remove = function(array, from) { + array.splice(from, 1); + return array; + //var rest = array.slice((to || from) + 1 || array.length); + //array.length = from < 0 ? array.length + from : from; + //array.push.apply(array, rest); + //return array; + }; + // remove item from array + $.vakata.array_remove_item = function(array, item) { + var tmp = $.inArray(item, array); + return tmp !== -1 ? $.vakata.array_remove(array, tmp) : array; + }; + $.vakata.array_filter = function(c,a,b,d,e) { + if (c.filter) { + return c.filter(a, b); + } + d=[]; + for (e in c) { + if (~~e+''===e+'' && e>=0 && a.call(b,c[e],+e,c)) { + d.push(c[e]); + } + } + return d; + }; +})); diff --git a/civicrm/bower_components/jstree/src/jstree.massload.js b/civicrm/bower_components/jstree/src/jstree.massload.js new file mode 100644 index 0000000000..d202a3eca5 --- /dev/null +++ b/civicrm/bower_components/jstree/src/jstree.massload.js @@ -0,0 +1,137 @@ +/** + * ### Massload plugin + * + * Adds massload functionality to jsTree, so that multiple nodes can be loaded in a single request (only useful with lazy loading). + */ +/*globals jQuery, define, exports, require, document */ +(function (factory) { + "use strict"; + if (typeof define === 'function' && define.amd) { + define('jstree.massload', ['jquery','jstree'], factory); + } + else if(typeof exports === 'object') { + factory(require('jquery'), require('jstree')); + } + else { + factory(jQuery, jQuery.jstree); + } +}(function ($, jstree, undefined) { + "use strict"; + + if($.jstree.plugins.massload) { return; } + + /** + * massload configuration + * + * It is possible to set this to a standard jQuery-like AJAX config. + * In addition to the standard jQuery ajax options here you can supply functions for `data` and `url`, the functions will be run in the current instance's scope and a param will be passed indicating which node IDs need to be loaded, the return value of those functions will be used. + * + * You can also set this to a function, that function will receive the node IDs being loaded as argument and a second param which is a function (callback) which should be called with the result. + * + * Both the AJAX and the function approach rely on the same return value - an object where the keys are the node IDs, and the value is the children of that node as an array. + * + * { + * "id1" : [{ "text" : "Child of ID1", "id" : "c1" }, { "text" : "Another child of ID1", "id" : "c2" }], + * "id2" : [{ "text" : "Child of ID2", "id" : "c3" }] + * } + * + * @name $.jstree.defaults.massload + * @plugin massload + */ + $.jstree.defaults.massload = null; + $.jstree.plugins.massload = function (options, parent) { + this.init = function (el, options) { + this._data.massload = {}; + parent.init.call(this, el, options); + }; + this._load_nodes = function (nodes, callback, is_callback, force_reload) { + var s = this.settings.massload, + nodesString = JSON.stringify(nodes), + toLoad = [], + m = this._model.data, + i, j, dom; + if (!is_callback) { + for(i = 0, j = nodes.length; i < j; i++) { + if(!m[nodes[i]] || ( (!m[nodes[i]].state.loaded && !m[nodes[i]].state.failed) || force_reload) ) { + toLoad.push(nodes[i]); + dom = this.get_node(nodes[i], true); + if (dom && dom.length) { + dom.addClass("jstree-loading").attr('aria-busy',true); + } + } + } + this._data.massload = {}; + if (toLoad.length) { + if($.isFunction(s)) { + return s.call(this, toLoad, $.proxy(function (data) { + var i, j; + if(data) { + for(i in data) { + if(data.hasOwnProperty(i)) { + this._data.massload[i] = data[i]; + } + } + } + for(i = 0, j = nodes.length; i < j; i++) { + dom = this.get_node(nodes[i], true); + if (dom && dom.length) { + dom.removeClass("jstree-loading").attr('aria-busy',false); + } + } + parent._load_nodes.call(this, nodes, callback, is_callback, force_reload); + }, this)); + } + if(typeof s === 'object' && s && s.url) { + s = $.extend(true, {}, s); + if($.isFunction(s.url)) { + s.url = s.url.call(this, toLoad); + } + if($.isFunction(s.data)) { + s.data = s.data.call(this, toLoad); + } + return $.ajax(s) + .done($.proxy(function (data,t,x) { + var i, j; + if(data) { + for(i in data) { + if(data.hasOwnProperty(i)) { + this._data.massload[i] = data[i]; + } + } + } + for(i = 0, j = nodes.length; i < j; i++) { + dom = this.get_node(nodes[i], true); + if (dom && dom.length) { + dom.removeClass("jstree-loading").attr('aria-busy',false); + } + } + parent._load_nodes.call(this, nodes, callback, is_callback, force_reload); + }, this)) + .fail($.proxy(function (f) { + parent._load_nodes.call(this, nodes, callback, is_callback, force_reload); + }, this)); + } + } + } + return parent._load_nodes.call(this, nodes, callback, is_callback, force_reload); + }; + this._load_node = function (obj, callback) { + var data = this._data.massload[obj.id], + rslt = null, dom; + if(data) { + rslt = this[typeof data === 'string' ? '_append_html_data' : '_append_json_data']( + obj, + typeof data === 'string' ? $($.parseHTML(data)).filter(function () { return this.nodeType !== 3; }) : data, + function (status) { callback.call(this, status); } + ); + dom = this.get_node(obj.id, true); + if (dom && dom.length) { + dom.removeClass("jstree-loading").attr('aria-busy',false); + } + delete this._data.massload[obj.id]; + return rslt; + } + return parent._load_node.call(this, obj, callback); + }; + }; +})); \ No newline at end of file diff --git a/civicrm/bower_components/jstree/src/jstree.search.js b/civicrm/bower_components/jstree/src/jstree.search.js new file mode 100644 index 0000000000..21c3e7923a --- /dev/null +++ b/civicrm/bower_components/jstree/src/jstree.search.js @@ -0,0 +1,421 @@ +/** + * ### Search plugin + * + * Adds search functionality to jsTree. + */ +/*globals jQuery, define, exports, require, document */ +(function (factory) { + "use strict"; + if (typeof define === 'function' && define.amd) { + define('jstree.search', ['jquery','jstree'], factory); + } + else if(typeof exports === 'object') { + factory(require('jquery'), require('jstree')); + } + else { + factory(jQuery, jQuery.jstree); + } +}(function ($, jstree, undefined) { + "use strict"; + + if($.jstree.plugins.search) { return; } + + /** + * stores all defaults for the search plugin + * @name $.jstree.defaults.search + * @plugin search + */ + $.jstree.defaults.search = { + /** + * a jQuery-like AJAX config, which jstree uses if a server should be queried for results. + * + * A `str` (which is the search string) parameter will be added with the request, an optional `inside` parameter will be added if the search is limited to a node id. The expected result is a JSON array with nodes that need to be opened so that matching nodes will be revealed. + * Leave this setting as `false` to not query the server. You can also set this to a function, which will be invoked in the instance's scope and receive 3 parameters - the search string, the callback to call with the array of nodes to load, and the optional node ID to limit the search to + * @name $.jstree.defaults.search.ajax + * @plugin search + */ + ajax : false, + /** + * Indicates if the search should be fuzzy or not (should `chnd3` match `child node 3`). Default is `false`. + * @name $.jstree.defaults.search.fuzzy + * @plugin search + */ + fuzzy : false, + /** + * Indicates if the search should be case sensitive. Default is `false`. + * @name $.jstree.defaults.search.case_sensitive + * @plugin search + */ + case_sensitive : false, + /** + * Indicates if the tree should be filtered (by default) to show only matching nodes (keep in mind this can be a heavy on large trees in old browsers). + * This setting can be changed at runtime when calling the search method. Default is `false`. + * @name $.jstree.defaults.search.show_only_matches + * @plugin search + */ + show_only_matches : false, + /** + * Indicates if the children of matched element are shown (when show_only_matches is true) + * This setting can be changed at runtime when calling the search method. Default is `false`. + * @name $.jstree.defaults.search.show_only_matches_children + * @plugin search + */ + show_only_matches_children : false, + /** + * Indicates if all nodes opened to reveal the search result, should be closed when the search is cleared or a new search is performed. Default is `true`. + * @name $.jstree.defaults.search.close_opened_onclear + * @plugin search + */ + close_opened_onclear : true, + /** + * Indicates if only leaf nodes should be included in search results. Default is `false`. + * @name $.jstree.defaults.search.search_leaves_only + * @plugin search + */ + search_leaves_only : false, + /** + * If set to a function it wil be called in the instance's scope with two arguments - search string and node (where node will be every node in the structure, so use with caution). + * If the function returns a truthy value the node will be considered a match (it might not be displayed if search_only_leaves is set to true and the node is not a leaf). Default is `false`. + * @name $.jstree.defaults.search.search_callback + * @plugin search + */ + search_callback : false + }; + + $.jstree.plugins.search = function (options, parent) { + this.bind = function () { + parent.bind.call(this); + + this._data.search.str = ""; + this._data.search.dom = $(); + this._data.search.res = []; + this._data.search.opn = []; + this._data.search.som = false; + this._data.search.smc = false; + this._data.search.hdn = []; + + this.element + .on("search.jstree", $.proxy(function (e, data) { + if(this._data.search.som && data.res.length) { + var m = this._model.data, i, j, p = [], k, l; + for(i = 0, j = data.res.length; i < j; i++) { + if(m[data.res[i]] && !m[data.res[i]].state.hidden) { + p.push(data.res[i]); + p = p.concat(m[data.res[i]].parents); + if(this._data.search.smc) { + for (k = 0, l = m[data.res[i]].children_d.length; k < l; k++) { + if (m[m[data.res[i]].children_d[k]] && !m[m[data.res[i]].children_d[k]].state.hidden) { + p.push(m[data.res[i]].children_d[k]); + } + } + } + } + } + p = $.vakata.array_remove_item($.vakata.array_unique(p), $.jstree.root); + this._data.search.hdn = this.hide_all(true); + this.show_node(p, true); + this.redraw(true); + } + }, this)) + .on("clear_search.jstree", $.proxy(function (e, data) { + if(this._data.search.som && data.res.length) { + this.show_node(this._data.search.hdn, true); + this.redraw(true); + } + }, this)); + }; + /** + * used to search the tree nodes for a given string + * @name search(str [, skip_async]) + * @param {String} str the search string + * @param {Boolean} skip_async if set to true server will not be queried even if configured + * @param {Boolean} show_only_matches if set to true only matching nodes will be shown (keep in mind this can be very slow on large trees or old browsers) + * @param {mixed} inside an optional node to whose children to limit the search + * @param {Boolean} append if set to true the results of this search are appended to the previous search + * @plugin search + * @trigger search.jstree + */ + this.search = function (str, skip_async, show_only_matches, inside, append, show_only_matches_children) { + if(str === false || $.trim(str.toString()) === "") { + return this.clear_search(); + } + inside = this.get_node(inside); + inside = inside && inside.id ? inside.id : null; + str = str.toString(); + var s = this.settings.search, + a = s.ajax ? s.ajax : false, + m = this._model.data, + f = null, + r = [], + p = [], i, j; + if(this._data.search.res.length && !append) { + this.clear_search(); + } + if(show_only_matches === undefined) { + show_only_matches = s.show_only_matches; + } + if(show_only_matches_children === undefined) { + show_only_matches_children = s.show_only_matches_children; + } + if(!skip_async && a !== false) { + if($.isFunction(a)) { + return a.call(this, str, $.proxy(function (d) { + if(d && d.d) { d = d.d; } + this._load_nodes(!$.isArray(d) ? [] : $.vakata.array_unique(d), function () { + this.search(str, true, show_only_matches, inside, append, show_only_matches_children); + }); + }, this), inside); + } + else { + a = $.extend({}, a); + if(!a.data) { a.data = {}; } + a.data.str = str; + if(inside) { + a.data.inside = inside; + } + if (this._data.search.lastRequest) { + this._data.search.lastRequest.abort(); + } + this._data.search.lastRequest = $.ajax(a) + .fail($.proxy(function () { + this._data.core.last_error = { 'error' : 'ajax', 'plugin' : 'search', 'id' : 'search_01', 'reason' : 'Could not load search parents', 'data' : JSON.stringify(a) }; + this.settings.core.error.call(this, this._data.core.last_error); + }, this)) + .done($.proxy(function (d) { + if(d && d.d) { d = d.d; } + this._load_nodes(!$.isArray(d) ? [] : $.vakata.array_unique(d), function () { + this.search(str, true, show_only_matches, inside, append, show_only_matches_children); + }); + }, this)); + return this._data.search.lastRequest; + } + } + if(!append) { + this._data.search.str = str; + this._data.search.dom = $(); + this._data.search.res = []; + this._data.search.opn = []; + this._data.search.som = show_only_matches; + this._data.search.smc = show_only_matches_children; + } + + f = new $.vakata.search(str, true, { caseSensitive : s.case_sensitive, fuzzy : s.fuzzy }); + $.each(m[inside ? inside : $.jstree.root].children_d, function (ii, i) { + var v = m[i]; + if(v.text && !v.state.hidden && (!s.search_leaves_only || (v.state.loaded && v.children.length === 0)) && ( (s.search_callback && s.search_callback.call(this, str, v)) || (!s.search_callback && f.search(v.text).isMatch) ) ) { + r.push(i); + p = p.concat(v.parents); + } + }); + if(r.length) { + p = $.vakata.array_unique(p); + for(i = 0, j = p.length; i < j; i++) { + if(p[i] !== $.jstree.root && m[p[i]] && this.open_node(p[i], null, 0) === true) { + this._data.search.opn.push(p[i]); + } + } + if(!append) { + this._data.search.dom = $(this.element[0].querySelectorAll('#' + $.map(r, function (v) { return "0123456789".indexOf(v[0]) !== -1 ? '\\3' + v[0] + ' ' + v.substr(1).replace($.jstree.idregex,'\\$&') : v.replace($.jstree.idregex,'\\$&'); }).join(', #'))); + this._data.search.res = r; + } + else { + this._data.search.dom = this._data.search.dom.add($(this.element[0].querySelectorAll('#' + $.map(r, function (v) { return "0123456789".indexOf(v[0]) !== -1 ? '\\3' + v[0] + ' ' + v.substr(1).replace($.jstree.idregex,'\\$&') : v.replace($.jstree.idregex,'\\$&'); }).join(', #')))); + this._data.search.res = $.vakata.array_unique(this._data.search.res.concat(r)); + } + this._data.search.dom.children(".jstree-anchor").addClass('jstree-search'); + } + /** + * triggered after search is complete + * @event + * @name search.jstree + * @param {jQuery} nodes a jQuery collection of matching nodes + * @param {String} str the search string + * @param {Array} res a collection of objects represeing the matching nodes + * @plugin search + */ + this.trigger('search', { nodes : this._data.search.dom, str : str, res : this._data.search.res, show_only_matches : show_only_matches }); + }; + /** + * used to clear the last search (removes classes and shows all nodes if filtering is on) + * @name clear_search() + * @plugin search + * @trigger clear_search.jstree + */ + this.clear_search = function () { + if(this.settings.search.close_opened_onclear) { + this.close_node(this._data.search.opn, 0); + } + /** + * triggered after search is complete + * @event + * @name clear_search.jstree + * @param {jQuery} nodes a jQuery collection of matching nodes (the result from the last search) + * @param {String} str the search string (the last search string) + * @param {Array} res a collection of objects represeing the matching nodes (the result from the last search) + * @plugin search + */ + this.trigger('clear_search', { 'nodes' : this._data.search.dom, str : this._data.search.str, res : this._data.search.res }); + if(this._data.search.res.length) { + this._data.search.dom = $(this.element[0].querySelectorAll('#' + $.map(this._data.search.res, function (v) { + return "0123456789".indexOf(v[0]) !== -1 ? '\\3' + v[0] + ' ' + v.substr(1).replace($.jstree.idregex,'\\$&') : v.replace($.jstree.idregex,'\\$&'); + }).join(', #'))); + this._data.search.dom.children(".jstree-anchor").removeClass("jstree-search"); + } + this._data.search.str = ""; + this._data.search.res = []; + this._data.search.opn = []; + this._data.search.dom = $(); + }; + + this.redraw_node = function(obj, deep, callback, force_render) { + obj = parent.redraw_node.apply(this, arguments); + if(obj) { + if($.inArray(obj.id, this._data.search.res) !== -1) { + var i, j, tmp = null; + for(i = 0, j = obj.childNodes.length; i < j; i++) { + if(obj.childNodes[i] && obj.childNodes[i].className && obj.childNodes[i].className.indexOf("jstree-anchor") !== -1) { + tmp = obj.childNodes[i]; + break; + } + } + if(tmp) { + tmp.className += ' jstree-search'; + } + } + } + return obj; + }; + }; + + // helpers + (function ($) { + // from http://kiro.me/projects/fuse.html + $.vakata.search = function(pattern, txt, options) { + options = options || {}; + options = $.extend({}, $.vakata.search.defaults, options); + if(options.fuzzy !== false) { + options.fuzzy = true; + } + pattern = options.caseSensitive ? pattern : pattern.toLowerCase(); + var MATCH_LOCATION = options.location, + MATCH_DISTANCE = options.distance, + MATCH_THRESHOLD = options.threshold, + patternLen = pattern.length, + matchmask, pattern_alphabet, match_bitapScore, search; + if(patternLen > 32) { + options.fuzzy = false; + } + if(options.fuzzy) { + matchmask = 1 << (patternLen - 1); + pattern_alphabet = (function () { + var mask = {}, + i = 0; + for (i = 0; i < patternLen; i++) { + mask[pattern.charAt(i)] = 0; + } + for (i = 0; i < patternLen; i++) { + mask[pattern.charAt(i)] |= 1 << (patternLen - i - 1); + } + return mask; + }()); + match_bitapScore = function (e, x) { + var accuracy = e / patternLen, + proximity = Math.abs(MATCH_LOCATION - x); + if(!MATCH_DISTANCE) { + return proximity ? 1.0 : accuracy; + } + return accuracy + (proximity / MATCH_DISTANCE); + }; + } + search = function (text) { + text = options.caseSensitive ? text : text.toLowerCase(); + if(pattern === text || text.indexOf(pattern) !== -1) { + return { + isMatch: true, + score: 0 + }; + } + if(!options.fuzzy) { + return { + isMatch: false, + score: 1 + }; + } + var i, j, + textLen = text.length, + scoreThreshold = MATCH_THRESHOLD, + bestLoc = text.indexOf(pattern, MATCH_LOCATION), + binMin, binMid, + binMax = patternLen + textLen, + lastRd, start, finish, rd, charMatch, + score = 1, + locations = []; + if (bestLoc !== -1) { + scoreThreshold = Math.min(match_bitapScore(0, bestLoc), scoreThreshold); + bestLoc = text.lastIndexOf(pattern, MATCH_LOCATION + patternLen); + if (bestLoc !== -1) { + scoreThreshold = Math.min(match_bitapScore(0, bestLoc), scoreThreshold); + } + } + bestLoc = -1; + for (i = 0; i < patternLen; i++) { + binMin = 0; + binMid = binMax; + while (binMin < binMid) { + if (match_bitapScore(i, MATCH_LOCATION + binMid) <= scoreThreshold) { + binMin = binMid; + } else { + binMax = binMid; + } + binMid = Math.floor((binMax - binMin) / 2 + binMin); + } + binMax = binMid; + start = Math.max(1, MATCH_LOCATION - binMid + 1); + finish = Math.min(MATCH_LOCATION + binMid, textLen) + patternLen; + rd = new Array(finish + 2); + rd[finish + 1] = (1 << i) - 1; + for (j = finish; j >= start; j--) { + charMatch = pattern_alphabet[text.charAt(j - 1)]; + if (i === 0) { + rd[j] = ((rd[j + 1] << 1) | 1) & charMatch; + } else { + rd[j] = ((rd[j + 1] << 1) | 1) & charMatch | (((lastRd[j + 1] | lastRd[j]) << 1) | 1) | lastRd[j + 1]; + } + if (rd[j] & matchmask) { + score = match_bitapScore(i, j - 1); + if (score <= scoreThreshold) { + scoreThreshold = score; + bestLoc = j - 1; + locations.push(bestLoc); + if (bestLoc > MATCH_LOCATION) { + start = Math.max(1, 2 * MATCH_LOCATION - bestLoc); + } else { + break; + } + } + } + } + if (match_bitapScore(i + 1, MATCH_LOCATION) > scoreThreshold) { + break; + } + lastRd = rd; + } + return { + isMatch: bestLoc >= 0, + score: score + }; + }; + return txt === true ? { 'search' : search } : search(txt); + }; + $.vakata.search.defaults = { + location : 0, + distance : 100, + threshold : 0.6, + fuzzy : false, + caseSensitive : false + }; + }($)); + + // include the search plugin by default + // $.jstree.defaults.plugins.push("search"); +})); diff --git a/civicrm/bower_components/jstree/src/jstree.sort.js b/civicrm/bower_components/jstree/src/jstree.sort.js new file mode 100644 index 0000000000..94f8b39014 --- /dev/null +++ b/civicrm/bower_components/jstree/src/jstree.sort.js @@ -0,0 +1,74 @@ +/** + * ### Sort plugin + * + * Automatically sorts all siblings in the tree according to a sorting function. + */ +/*globals jQuery, define, exports, require */ +(function (factory) { + "use strict"; + if (typeof define === 'function' && define.amd) { + define('jstree.sort', ['jquery','jstree'], factory); + } + else if(typeof exports === 'object') { + factory(require('jquery'), require('jstree')); + } + else { + factory(jQuery, jQuery.jstree); + } +}(function ($, jstree, undefined) { + "use strict"; + + if($.jstree.plugins.sort) { return; } + + /** + * the settings function used to sort the nodes. + * It is executed in the tree's context, accepts two nodes as arguments and should return `1` or `-1`. + * @name $.jstree.defaults.sort + * @plugin sort + */ + $.jstree.defaults.sort = function (a, b) { + //return this.get_type(a) === this.get_type(b) ? (this.get_text(a) > this.get_text(b) ? 1 : -1) : this.get_type(a) >= this.get_type(b); + return this.get_text(a) > this.get_text(b) ? 1 : -1; + }; + $.jstree.plugins.sort = function (options, parent) { + this.bind = function () { + parent.bind.call(this); + this.element + .on("model.jstree", $.proxy(function (e, data) { + this.sort(data.parent, true); + }, this)) + .on("rename_node.jstree create_node.jstree", $.proxy(function (e, data) { + this.sort(data.parent || data.node.parent, false); + this.redraw_node(data.parent || data.node.parent, true); + }, this)) + .on("move_node.jstree copy_node.jstree", $.proxy(function (e, data) { + this.sort(data.parent, false); + this.redraw_node(data.parent, true); + }, this)); + }; + /** + * used to sort a node's children + * @private + * @name sort(obj [, deep]) + * @param {mixed} obj the node + * @param {Boolean} deep if set to `true` nodes are sorted recursively. + * @plugin sort + * @trigger search.jstree + */ + this.sort = function (obj, deep) { + var i, j; + obj = this.get_node(obj); + if(obj && obj.children && obj.children.length) { + obj.children.sort($.proxy(this.settings.sort, this)); + if(deep) { + for(i = 0, j = obj.children_d.length; i < j; i++) { + this.sort(obj.children_d[i], false); + } + } + } + }; + }; + + // include the sort plugin by default + // $.jstree.defaults.plugins.push("sort"); +})); \ No newline at end of file diff --git a/civicrm/bower_components/jstree/src/jstree.state.js b/civicrm/bower_components/jstree/src/jstree.state.js new file mode 100644 index 0000000000..f87cf4fb64 --- /dev/null +++ b/civicrm/bower_components/jstree/src/jstree.state.js @@ -0,0 +1,125 @@ +/** + * ### State plugin + * + * Saves the state of the tree (selected nodes, opened nodes) on the user's computer using available options (localStorage, cookies, etc) + */ +/*globals jQuery, define, exports, require */ +(function (factory) { + "use strict"; + if (typeof define === 'function' && define.amd) { + define('jstree.state', ['jquery','jstree'], factory); + } + else if(typeof exports === 'object') { + factory(require('jquery'), require('jstree')); + } + else { + factory(jQuery, jQuery.jstree); + } +}(function ($, jstree, undefined) { + "use strict"; + + if($.jstree.plugins.state) { return; } + + var to = false; + /** + * stores all defaults for the state plugin + * @name $.jstree.defaults.state + * @plugin state + */ + $.jstree.defaults.state = { + /** + * A string for the key to use when saving the current tree (change if using multiple trees in your project). Defaults to `jstree`. + * @name $.jstree.defaults.state.key + * @plugin state + */ + key : 'jstree', + /** + * A space separated list of events that trigger a state save. Defaults to `changed.jstree open_node.jstree close_node.jstree`. + * @name $.jstree.defaults.state.events + * @plugin state + */ + events : 'changed.jstree open_node.jstree close_node.jstree check_node.jstree uncheck_node.jstree', + /** + * Time in milliseconds after which the state will expire. Defaults to 'false' meaning - no expire. + * @name $.jstree.defaults.state.ttl + * @plugin state + */ + ttl : false, + /** + * A function that will be executed prior to restoring state with one argument - the state object. Can be used to clear unwanted parts of the state. + * @name $.jstree.defaults.state.filter + * @plugin state + */ + filter : false + }; + $.jstree.plugins.state = function (options, parent) { + this.bind = function () { + parent.bind.call(this); + var bind = $.proxy(function () { + this.element.on(this.settings.state.events, $.proxy(function () { + if(to) { clearTimeout(to); } + to = setTimeout($.proxy(function () { this.save_state(); }, this), 100); + }, this)); + /** + * triggered when the state plugin is finished restoring the state (and immediately after ready if there is no state to restore). + * @event + * @name state_ready.jstree + * @plugin state + */ + this.trigger('state_ready'); + }, this); + this.element + .on("ready.jstree", $.proxy(function (e, data) { + this.element.one("restore_state.jstree", bind); + if(!this.restore_state()) { bind(); } + }, this)); + }; + /** + * save the state + * @name save_state() + * @plugin state + */ + this.save_state = function () { + var st = { 'state' : this.get_state(), 'ttl' : this.settings.state.ttl, 'sec' : +(new Date()) }; + $.vakata.storage.set(this.settings.state.key, JSON.stringify(st)); + }; + /** + * restore the state from the user's computer + * @name restore_state() + * @plugin state + */ + this.restore_state = function () { + var k = $.vakata.storage.get(this.settings.state.key); + if(!!k) { try { k = JSON.parse(k); } catch(ex) { return false; } } + if(!!k && k.ttl && k.sec && +(new Date()) - k.sec > k.ttl) { return false; } + if(!!k && k.state) { k = k.state; } + if(!!k && $.isFunction(this.settings.state.filter)) { k = this.settings.state.filter.call(this, k); } + if(!!k) { + this.element.one("set_state.jstree", function (e, data) { data.instance.trigger('restore_state', { 'state' : $.extend(true, {}, k) }); }); + this.set_state(k); + return true; + } + return false; + }; + /** + * clear the state on the user's computer + * @name clear_state() + * @plugin state + */ + this.clear_state = function () { + return $.vakata.storage.del(this.settings.state.key); + }; + }; + + (function ($, undefined) { + $.vakata.storage = { + // simply specifying the functions in FF throws an error + set : function (key, val) { return window.localStorage.setItem(key, val); }, + get : function (key) { return window.localStorage.getItem(key); }, + del : function (key) { return window.localStorage.removeItem(key); } + }; + }($)); + + // include the state plugin by default + // $.jstree.defaults.plugins.push("state"); +})); \ No newline at end of file diff --git a/civicrm/bower_components/jstree/src/jstree.types.js b/civicrm/bower_components/jstree/src/jstree.types.js new file mode 100644 index 0000000000..706829a9d0 --- /dev/null +++ b/civicrm/bower_components/jstree/src/jstree.types.js @@ -0,0 +1,372 @@ +/** + * ### Types plugin + * + * Makes it possible to add predefined types for groups of nodes, which make it possible to easily control nesting rules and icon for each group. + */ +/*globals jQuery, define, exports, require */ +(function (factory) { + "use strict"; + if (typeof define === 'function' && define.amd) { + define('jstree.types', ['jquery','jstree'], factory); + } + else if(typeof exports === 'object') { + factory(require('jquery'), require('jstree')); + } + else { + factory(jQuery, jQuery.jstree); + } +}(function ($, jstree, undefined) { + "use strict"; + + if($.jstree.plugins.types) { return; } + + /** + * An object storing all types as key value pairs, where the key is the type name and the value is an object that could contain following keys (all optional). + * + * * `max_children` the maximum number of immediate children this node type can have. Do not specify or set to `-1` for unlimited. + * * `max_depth` the maximum number of nesting this node type can have. A value of `1` would mean that the node can have children, but no grandchildren. Do not specify or set to `-1` for unlimited. + * * `valid_children` an array of node type strings, that nodes of this type can have as children. Do not specify or set to `-1` for no limits. + * * `icon` a string - can be a path to an icon or a className, if using an image that is in the current directory use a `./` prefix, otherwise it will be detected as a class. Omit to use the default icon from your theme. + * * `li_attr` an object of values which will be used to add HTML attributes on the resulting LI DOM node (merged with the node's own data) + * * `a_attr` an object of values which will be used to add HTML attributes on the resulting A DOM node (merged with the node's own data) + * + * There are two predefined types: + * + * * `#` represents the root of the tree, for example `max_children` would control the maximum number of root nodes. + * * `default` represents the default node - any settings here will be applied to all nodes that do not have a type specified. + * + * @name $.jstree.defaults.types + * @plugin types + */ + $.jstree.defaults.types = { + 'default' : {} + }; + $.jstree.defaults.types[$.jstree.root] = {}; + + $.jstree.plugins.types = function (options, parent) { + this.init = function (el, options) { + var i, j; + if(options && options.types && options.types['default']) { + for(i in options.types) { + if(i !== "default" && i !== $.jstree.root && options.types.hasOwnProperty(i)) { + for(j in options.types['default']) { + if(options.types['default'].hasOwnProperty(j) && options.types[i][j] === undefined) { + options.types[i][j] = options.types['default'][j]; + } + } + } + } + } + parent.init.call(this, el, options); + this._model.data[$.jstree.root].type = $.jstree.root; + }; + this.refresh = function (skip_loading, forget_state) { + parent.refresh.call(this, skip_loading, forget_state); + this._model.data[$.jstree.root].type = $.jstree.root; + }; + this.bind = function () { + this.element + .on('model.jstree', $.proxy(function (e, data) { + var m = this._model.data, + dpc = data.nodes, + t = this.settings.types, + i, j, c = 'default', k; + for(i = 0, j = dpc.length; i < j; i++) { + c = 'default'; + if(m[dpc[i]].original && m[dpc[i]].original.type && t[m[dpc[i]].original.type]) { + c = m[dpc[i]].original.type; + } + if(m[dpc[i]].data && m[dpc[i]].data.jstree && m[dpc[i]].data.jstree.type && t[m[dpc[i]].data.jstree.type]) { + c = m[dpc[i]].data.jstree.type; + } + m[dpc[i]].type = c; + if(m[dpc[i]].icon === true && t[c].icon !== undefined) { + m[dpc[i]].icon = t[c].icon; + } + if(t[c].li_attr !== undefined && typeof t[c].li_attr === 'object') { + for (k in t[c].li_attr) { + if (t[c].li_attr.hasOwnProperty(k)) { + if (k === 'id') { + continue; + } + else if (m[dpc[i]].li_attr[k] === undefined) { + m[dpc[i]].li_attr[k] = t[c].li_attr[k]; + } + else if (k === 'class') { + m[dpc[i]].li_attr['class'] = t[c].li_attr['class'] + ' ' + m[dpc[i]].li_attr['class']; + } + } + } + } + if(t[c].a_attr !== undefined && typeof t[c].a_attr === 'object') { + for (k in t[c].a_attr) { + if (t[c].a_attr.hasOwnProperty(k)) { + if (k === 'id') { + continue; + } + else if (m[dpc[i]].a_attr[k] === undefined) { + m[dpc[i]].a_attr[k] = t[c].a_attr[k]; + } + else if (k === 'href' && m[dpc[i]].a_attr[k] === '#') { + m[dpc[i]].a_attr['href'] = t[c].a_attr['href']; + } + else if (k === 'class') { + m[dpc[i]].a_attr['class'] = t[c].a_attr['class'] + ' ' + m[dpc[i]].a_attr['class']; + } + } + } + } + } + m[$.jstree.root].type = $.jstree.root; + }, this)); + parent.bind.call(this); + }; + this.get_json = function (obj, options, flat) { + var i, j, + m = this._model.data, + opt = options ? $.extend(true, {}, options, {no_id:false}) : {}, + tmp = parent.get_json.call(this, obj, opt, flat); + if(tmp === false) { return false; } + if($.isArray(tmp)) { + for(i = 0, j = tmp.length; i < j; i++) { + tmp[i].type = tmp[i].id && m[tmp[i].id] && m[tmp[i].id].type ? m[tmp[i].id].type : "default"; + if(options && options.no_id) { + delete tmp[i].id; + if(tmp[i].li_attr && tmp[i].li_attr.id) { + delete tmp[i].li_attr.id; + } + if(tmp[i].a_attr && tmp[i].a_attr.id) { + delete tmp[i].a_attr.id; + } + } + } + } + else { + tmp.type = tmp.id && m[tmp.id] && m[tmp.id].type ? m[tmp.id].type : "default"; + if(options && options.no_id) { + tmp = this._delete_ids(tmp); + } + } + return tmp; + }; + this._delete_ids = function (tmp) { + if($.isArray(tmp)) { + for(var i = 0, j = tmp.length; i < j; i++) { + tmp[i] = this._delete_ids(tmp[i]); + } + return tmp; + } + delete tmp.id; + if(tmp.li_attr && tmp.li_attr.id) { + delete tmp.li_attr.id; + } + if(tmp.a_attr && tmp.a_attr.id) { + delete tmp.a_attr.id; + } + if(tmp.children && $.isArray(tmp.children)) { + tmp.children = this._delete_ids(tmp.children); + } + return tmp; + }; + this.check = function (chk, obj, par, pos, more) { + if(parent.check.call(this, chk, obj, par, pos, more) === false) { return false; } + obj = obj && obj.id ? obj : this.get_node(obj); + par = par && par.id ? par : this.get_node(par); + var m = obj && obj.id ? (more && more.origin ? more.origin : $.jstree.reference(obj.id)) : null, tmp, d, i, j; + m = m && m._model && m._model.data ? m._model.data : null; + switch(chk) { + case "create_node": + case "move_node": + case "copy_node": + if(chk !== 'move_node' || $.inArray(obj.id, par.children) === -1) { + tmp = this.get_rules(par); + if(tmp.max_children !== undefined && tmp.max_children !== -1 && tmp.max_children === par.children.length) { + this._data.core.last_error = { 'error' : 'check', 'plugin' : 'types', 'id' : 'types_01', 'reason' : 'max_children prevents function: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) }; + return false; + } + if(tmp.valid_children !== undefined && tmp.valid_children !== -1 && $.inArray((obj.type || 'default'), tmp.valid_children) === -1) { + this._data.core.last_error = { 'error' : 'check', 'plugin' : 'types', 'id' : 'types_02', 'reason' : 'valid_children prevents function: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) }; + return false; + } + if(m && obj.children_d && obj.parents) { + d = 0; + for(i = 0, j = obj.children_d.length; i < j; i++) { + d = Math.max(d, m[obj.children_d[i]].parents.length); + } + d = d - obj.parents.length + 1; + } + if(d <= 0 || d === undefined) { d = 1; } + do { + if(tmp.max_depth !== undefined && tmp.max_depth !== -1 && tmp.max_depth < d) { + this._data.core.last_error = { 'error' : 'check', 'plugin' : 'types', 'id' : 'types_03', 'reason' : 'max_depth prevents function: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) }; + return false; + } + par = this.get_node(par.parent); + tmp = this.get_rules(par); + d++; + } while(par); + } + break; + } + return true; + }; + /** + * used to retrieve the type settings object for a node + * @name get_rules(obj) + * @param {mixed} obj the node to find the rules for + * @return {Object} + * @plugin types + */ + this.get_rules = function (obj) { + obj = this.get_node(obj); + if(!obj) { return false; } + var tmp = this.get_type(obj, true); + if(tmp.max_depth === undefined) { tmp.max_depth = -1; } + if(tmp.max_children === undefined) { tmp.max_children = -1; } + if(tmp.valid_children === undefined) { tmp.valid_children = -1; } + return tmp; + }; + /** + * used to retrieve the type string or settings object for a node + * @name get_type(obj [, rules]) + * @param {mixed} obj the node to find the rules for + * @param {Boolean} rules if set to `true` instead of a string the settings object will be returned + * @return {String|Object} + * @plugin types + */ + this.get_type = function (obj, rules) { + obj = this.get_node(obj); + return (!obj) ? false : ( rules ? $.extend({ 'type' : obj.type }, this.settings.types[obj.type]) : obj.type); + }; + /** + * used to change a node's type + * @name set_type(obj, type) + * @param {mixed} obj the node to change + * @param {String} type the new type + * @plugin types + */ + this.set_type = function (obj, type) { + var m = this._model.data, t, t1, t2, old_type, old_icon, k, d, a; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.set_type(obj[t1], type); + } + return true; + } + t = this.settings.types; + obj = this.get_node(obj); + if(!t[type] || !obj) { return false; } + d = this.get_node(obj, true); + if (d && d.length) { + a = d.children('.jstree-anchor'); + } + old_type = obj.type; + old_icon = this.get_icon(obj); + obj.type = type; + if(old_icon === true || !t[old_type] || (t[old_type].icon !== undefined && old_icon === t[old_type].icon)) { + this.set_icon(obj, t[type].icon !== undefined ? t[type].icon : true); + } + + // remove old type props + if(t[old_type] && t[old_type].li_attr !== undefined && typeof t[old_type].li_attr === 'object') { + for (k in t[old_type].li_attr) { + if (t[old_type].li_attr.hasOwnProperty(k)) { + if (k === 'id') { + continue; + } + else if (k === 'class') { + m[obj.id].li_attr['class'] = (m[obj.id].li_attr['class'] || '').replace(t[old_type].li_attr[k], ''); + if (d) { d.removeClass(t[old_type].li_attr[k]); } + } + else if (m[obj.id].li_attr[k] === t[old_type].li_attr[k]) { + m[obj.id].li_attr[k] = null; + if (d) { d.removeAttr(k); } + } + } + } + } + if(t[old_type] && t[old_type].a_attr !== undefined && typeof t[old_type].a_attr === 'object') { + for (k in t[old_type].a_attr) { + if (t[old_type].a_attr.hasOwnProperty(k)) { + if (k === 'id') { + continue; + } + else if (k === 'class') { + m[obj.id].a_attr['class'] = (m[obj.id].a_attr['class'] || '').replace(t[old_type].a_attr[k], ''); + if (a) { a.removeClass(t[old_type].a_attr[k]); } + } + else if (m[obj.id].a_attr[k] === t[old_type].a_attr[k]) { + if (k === 'href') { + m[obj.id].a_attr[k] = '#'; + if (a) { a.attr('href', '#'); } + } + else { + delete m[obj.id].a_attr[k]; + if (a) { a.removeAttr(k); } + } + } + } + } + } + + // add new props + if(t[type].li_attr !== undefined && typeof t[type].li_attr === 'object') { + for (k in t[type].li_attr) { + if (t[type].li_attr.hasOwnProperty(k)) { + if (k === 'id') { + continue; + } + else if (m[obj.id].li_attr[k] === undefined) { + m[obj.id].li_attr[k] = t[type].li_attr[k]; + if (d) { + if (k === 'class') { + d.addClass(t[type].li_attr[k]); + } + else { + d.attr(k, t[type].li_attr[k]); + } + } + } + else if (k === 'class') { + m[obj.id].li_attr['class'] = t[type].li_attr[k] + ' ' + m[obj.id].li_attr['class']; + if (d) { d.addClass(t[type].li_attr[k]); } + } + } + } + } + if(t[type].a_attr !== undefined && typeof t[type].a_attr === 'object') { + for (k in t[type].a_attr) { + if (t[type].a_attr.hasOwnProperty(k)) { + if (k === 'id') { + continue; + } + else if (m[obj.id].a_attr[k] === undefined) { + m[obj.id].a_attr[k] = t[type].a_attr[k]; + if (a) { + if (k === 'class') { + a.addClass(t[type].a_attr[k]); + } + else { + a.attr(k, t[type].a_attr[k]); + } + } + } + else if (k === 'href' && m[obj.id].a_attr[k] === '#') { + m[obj.id].a_attr['href'] = t[type].a_attr['href']; + if (a) { a.attr('href', t[type].a_attr['href']); } + } + else if (k === 'class') { + m[obj.id].a_attr['class'] = t[type].a_attr['class'] + ' ' + m[obj.id].a_attr['class']; + if (a) { a.addClass(t[type].a_attr[k]); } + } + } + } + } + + return true; + }; + }; + // include the types plugin by default + // $.jstree.defaults.plugins.push("types"); +})); diff --git a/civicrm/bower_components/jstree/src/jstree.unique.js b/civicrm/bower_components/jstree/src/jstree.unique.js new file mode 100644 index 0000000000..bfe2f1b8f8 --- /dev/null +++ b/civicrm/bower_components/jstree/src/jstree.unique.js @@ -0,0 +1,121 @@ +/** + * ### Unique plugin + * + * Enforces that no nodes with the same name can coexist as siblings. + */ +/*globals jQuery, define, exports, require */ +(function (factory) { + "use strict"; + if (typeof define === 'function' && define.amd) { + define('jstree.unique', ['jquery','jstree'], factory); + } + else if(typeof exports === 'object') { + factory(require('jquery'), require('jstree')); + } + else { + factory(jQuery, jQuery.jstree); + } +}(function ($, jstree, undefined) { + "use strict"; + + if($.jstree.plugins.unique) { return; } + + /** + * stores all defaults for the unique plugin + * @name $.jstree.defaults.unique + * @plugin unique + */ + $.jstree.defaults.unique = { + /** + * Indicates if the comparison should be case sensitive. Default is `false`. + * @name $.jstree.defaults.unique.case_sensitive + * @plugin unique + */ + case_sensitive : false, + /** + * A callback executed in the instance's scope when a new node is created and the name is already taken, the two arguments are the conflicting name and the counter. The default will produce results like `New node (2)`. + * @name $.jstree.defaults.unique.duplicate + * @plugin unique + */ + duplicate : function (name, counter) { + return name + ' (' + counter + ')'; + } + }; + + $.jstree.plugins.unique = function (options, parent) { + this.check = function (chk, obj, par, pos, more) { + if(parent.check.call(this, chk, obj, par, pos, more) === false) { return false; } + obj = obj && obj.id ? obj : this.get_node(obj); + par = par && par.id ? par : this.get_node(par); + if(!par || !par.children) { return true; } + var n = chk === "rename_node" ? pos : obj.text, + c = [], + s = this.settings.unique.case_sensitive, + m = this._model.data, i, j; + for(i = 0, j = par.children.length; i < j; i++) { + c.push(s ? m[par.children[i]].text : m[par.children[i]].text.toLowerCase()); + } + if(!s) { n = n.toLowerCase(); } + switch(chk) { + case "delete_node": + return true; + case "rename_node": + i = ($.inArray(n, c) === -1 || (obj.text && obj.text[ s ? 'toString' : 'toLowerCase']() === n)); + if(!i) { + this._data.core.last_error = { 'error' : 'check', 'plugin' : 'unique', 'id' : 'unique_01', 'reason' : 'Child with name ' + n + ' already exists. Preventing: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) }; + } + return i; + case "create_node": + i = ($.inArray(n, c) === -1); + if(!i) { + this._data.core.last_error = { 'error' : 'check', 'plugin' : 'unique', 'id' : 'unique_04', 'reason' : 'Child with name ' + n + ' already exists. Preventing: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) }; + } + return i; + case "copy_node": + i = ($.inArray(n, c) === -1); + if(!i) { + this._data.core.last_error = { 'error' : 'check', 'plugin' : 'unique', 'id' : 'unique_02', 'reason' : 'Child with name ' + n + ' already exists. Preventing: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) }; + } + return i; + case "move_node": + i = ( (obj.parent === par.id && (!more || !more.is_multi)) || $.inArray(n, c) === -1); + if(!i) { + this._data.core.last_error = { 'error' : 'check', 'plugin' : 'unique', 'id' : 'unique_03', 'reason' : 'Child with name ' + n + ' already exists. Preventing: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) }; + } + return i; + } + return true; + }; + this.create_node = function (par, node, pos, callback, is_loaded) { + if(!node || node.text === undefined) { + if(par === null) { + par = $.jstree.root; + } + par = this.get_node(par); + if(!par) { + return parent.create_node.call(this, par, node, pos, callback, is_loaded); + } + pos = pos === undefined ? "last" : pos; + if(!pos.toString().match(/^(before|after)$/) && !is_loaded && !this.is_loaded(par)) { + return parent.create_node.call(this, par, node, pos, callback, is_loaded); + } + if(!node) { node = {}; } + var tmp, n, dpc, i, j, m = this._model.data, s = this.settings.unique.case_sensitive, cb = this.settings.unique.duplicate; + n = tmp = this.get_string('New node'); + dpc = []; + for(i = 0, j = par.children.length; i < j; i++) { + dpc.push(s ? m[par.children[i]].text : m[par.children[i]].text.toLowerCase()); + } + i = 1; + while($.inArray(s ? n : n.toLowerCase(), dpc) !== -1) { + n = cb.call(this, tmp, (++i)).toString(); + } + node.text = n; + } + return parent.create_node.call(this, par, node, pos, callback, is_loaded); + }; + }; + + // include the unique plugin by default + // $.jstree.defaults.plugins.push("unique"); +})); diff --git a/civicrm/bower_components/jstree/src/jstree.wholerow.js b/civicrm/bower_components/jstree/src/jstree.wholerow.js new file mode 100644 index 0000000000..e8fe3e6d54 --- /dev/null +++ b/civicrm/bower_components/jstree/src/jstree.wholerow.js @@ -0,0 +1,122 @@ +/** + * ### Wholerow plugin + * + * Makes each node appear block level. Making selection easier. May cause slow down for large trees in old browsers. + */ +/*globals jQuery, define, exports, require */ +(function (factory) { + "use strict"; + if (typeof define === 'function' && define.amd) { + define('jstree.wholerow', ['jquery','jstree'], factory); + } + else if(typeof exports === 'object') { + factory(require('jquery'), require('jstree')); + } + else { + factory(jQuery, jQuery.jstree); + } +}(function ($, jstree, undefined) { + "use strict"; + + if($.jstree.plugins.wholerow) { return; } + + var div = document.createElement('DIV'); + div.setAttribute('unselectable','on'); + div.setAttribute('role','presentation'); + div.className = 'jstree-wholerow'; + div.innerHTML = ' '; + $.jstree.plugins.wholerow = function (options, parent) { + this.bind = function () { + parent.bind.call(this); + + this.element + .on('ready.jstree set_state.jstree', $.proxy(function () { + this.hide_dots(); + }, this)) + .on("init.jstree loading.jstree ready.jstree", $.proxy(function () { + //div.style.height = this._data.core.li_height + 'px'; + this.get_container_ul().addClass('jstree-wholerow-ul'); + }, this)) + .on("deselect_all.jstree", $.proxy(function (e, data) { + this.element.find('.jstree-wholerow-clicked').removeClass('jstree-wholerow-clicked'); + }, this)) + .on("changed.jstree", $.proxy(function (e, data) { + this.element.find('.jstree-wholerow-clicked').removeClass('jstree-wholerow-clicked'); + var tmp = false, i, j; + for(i = 0, j = data.selected.length; i < j; i++) { + tmp = this.get_node(data.selected[i], true); + if(tmp && tmp.length) { + tmp.children('.jstree-wholerow').addClass('jstree-wholerow-clicked'); + } + } + }, this)) + .on("open_node.jstree", $.proxy(function (e, data) { + this.get_node(data.node, true).find('.jstree-clicked').parent().children('.jstree-wholerow').addClass('jstree-wholerow-clicked'); + }, this)) + .on("hover_node.jstree dehover_node.jstree", $.proxy(function (e, data) { + if(e.type === "hover_node" && this.is_disabled(data.node)) { return; } + this.get_node(data.node, true).children('.jstree-wholerow')[e.type === "hover_node"?"addClass":"removeClass"]('jstree-wholerow-hovered'); + }, this)) + .on("contextmenu.jstree", ".jstree-wholerow", $.proxy(function (e) { + if (this._data.contextmenu) { + e.preventDefault(); + var tmp = $.Event('contextmenu', { metaKey : e.metaKey, ctrlKey : e.ctrlKey, altKey : e.altKey, shiftKey : e.shiftKey, pageX : e.pageX, pageY : e.pageY }); + $(e.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(tmp); + } + }, this)) + /*! + .on("mousedown.jstree touchstart.jstree", ".jstree-wholerow", function (e) { + if(e.target === e.currentTarget) { + var a = $(e.currentTarget).closest(".jstree-node").children(".jstree-anchor"); + e.target = a[0]; + a.trigger(e); + } + }) + */ + .on("click.jstree", ".jstree-wholerow", function (e) { + e.stopImmediatePropagation(); + var tmp = $.Event('click', { metaKey : e.metaKey, ctrlKey : e.ctrlKey, altKey : e.altKey, shiftKey : e.shiftKey }); + $(e.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(tmp).focus(); + }) + .on("dblclick.jstree", ".jstree-wholerow", function (e) { + e.stopImmediatePropagation(); + var tmp = $.Event('dblclick', { metaKey : e.metaKey, ctrlKey : e.ctrlKey, altKey : e.altKey, shiftKey : e.shiftKey }); + $(e.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(tmp).focus(); + }) + .on("click.jstree", ".jstree-leaf > .jstree-ocl", $.proxy(function (e) { + e.stopImmediatePropagation(); + var tmp = $.Event('click', { metaKey : e.metaKey, ctrlKey : e.ctrlKey, altKey : e.altKey, shiftKey : e.shiftKey }); + $(e.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(tmp).focus(); + }, this)) + .on("mouseover.jstree", ".jstree-wholerow, .jstree-icon", $.proxy(function (e) { + e.stopImmediatePropagation(); + if(!this.is_disabled(e.currentTarget)) { + this.hover_node(e.currentTarget); + } + return false; + }, this)) + .on("mouseleave.jstree", ".jstree-node", $.proxy(function (e) { + this.dehover_node(e.currentTarget); + }, this)); + }; + this.teardown = function () { + if(this.settings.wholerow) { + this.element.find(".jstree-wholerow").remove(); + } + parent.teardown.call(this); + }; + this.redraw_node = function(obj, deep, callback, force_render) { + obj = parent.redraw_node.apply(this, arguments); + if(obj) { + var tmp = div.cloneNode(true); + //tmp.style.height = this._data.core.li_height + 'px'; + if($.inArray(obj.id, this._data.core.selected) !== -1) { tmp.className += ' jstree-wholerow-clicked'; } + if(this._data.core.focused && this._data.core.focused === obj.id) { tmp.className += ' jstree-wholerow-hovered'; } + obj.insertBefore(tmp, obj.childNodes[0]); + } + return obj; + }; + }; + // include the wholerow plugin by default + // $.jstree.defaults.plugins.push("wholerow"); +})); diff --git a/civicrm/bower_components/jstree/src/misc.js b/civicrm/bower_components/jstree/src/misc.js new file mode 100644 index 0000000000..d2d789b1f3 --- /dev/null +++ b/civicrm/bower_components/jstree/src/misc.js @@ -0,0 +1,601 @@ +/* global jQuery */ + +// disable all events +(function ($, undefined) { + "use strict"; + $.jstree.plugins.trigger = function (options, parent) { + this.init = function (el, options) { + // do not forget parent + parent.init.call(this, el, options); + this._data.trigger.disabled = false; + }; + this.trigger = function (ev, data) { + if(!this._data.trigger.disabled) { + parent.trigger.call(this, ev, data); + } + }; + this.disable_events = function () { this._data.trigger.disabled = true; }; + this.enable_events = function () { this._data.trigger.disabled = false; }; + }; +})(jQuery); + +// mapping +(function ($, undefined) { + "use strict"; + // use this if you need any options + $.jstree.defaults.mapper = { + option_key : "option_value" + }; + $.jstree.plugins.mapper = function () { + this._parse_model_from_json = function (d, p, ps) { + // d is the node from the server, it will be called recursively for children, + // so you do not need to process at once + /* // for example + for(var i in d) { + if(d.hasOwnProperty(i)) { + d[i.toLowerCase()] = d[i]; + } + } + */ + return parent._parse_model_from_json.call(this, d, p, ps); + }; + }; +})(jQuery); + +// no hover +(function ($, undefined) { + "use strict"; + $.jstree.plugins.nohover = function () { + this.hover_node = $.noop; + }; +})(jQuery); + +// force multiple select +(function ($, undefined) { + "use strict"; + $.jstree.defaults.multiselect = {}; + $.jstree.plugins.multiselect = function (options, parent) { + this.activate_node = function (obj, e) { + e.ctrlKey = true; + parent.activate_node.call(this, obj, e); + }; + }; +})(jQuery); + +// real checkboxes +(function ($, undefined) { + "use strict"; + + var inp = document.createElement("INPUT"); + inp.type = "checkbox"; + inp.className = "jstree-checkbox jstree-realcheckbox"; + + $.jstree.defaults.realcheckboxes = {}; + + $.jstree.plugins.realcheckboxes = function (options, parent) { + this.bind = function () { + parent.bind.call(this); + this._data.realcheckboxes.uto = false; + this.element + .on('changed.jstree uncheck_node.jstree check_node.jstree uncheck_all.jstree check_all.jstree move_node.jstree copy_node.jstree redraw.jstree open_node.jstree ready.jstree loaded.jstree', $.proxy(function () { + // only if undetermined is in setting + if(this._data.realcheckboxes.uto) { clearTimeout(this._data.realcheckboxes.uto); } + this._data.realcheckboxes.uto = setTimeout($.proxy(this._realcheckboxes, this), 50); + }, this)); + }; + this.redraw_node = function(obj, deep, callback, force_draw) { + obj = parent.redraw_node.call(this, obj, deep, callback, force_draw); + if(obj) { + var i, j, tmp = null, chk = inp.cloneNode(true); + for(i = 0, j = obj.childNodes.length; i < j; i++) { + if(obj.childNodes[i] && obj.childNodes[i].className && obj.childNodes[i].className.indexOf("jstree-anchor") !== -1) { + tmp = obj.childNodes[i]; + break; + } + } + if(tmp) { + for(i = 0, j = tmp.childNodes.length; i < j; i++) { + if(tmp.childNodes[i] && tmp.childNodes[i].className && tmp.childNodes[i].className.indexOf("jstree-checkbox") !== -1) { + tmp = tmp.childNodes[i]; + break; + } + } + } + if(tmp && tmp.tagName === "I") { + tmp.style.backgroundColor = "transparent"; + tmp.style.backgroundImage = "none"; + tmp.appendChild(chk); + } + } + return obj; + }; + this._realcheckboxes = function () { + var ts = this.settings.checkbox.tie_selection; + console.log(ts); + $('.jstree-realcheckbox').each(function () { + this.checked = (!ts && this.parentNode.parentNode.className.indexOf("jstree-checked") !== -1) || (ts && this.parentNode.parentNode.className.indexOf('jstree-clicked') !== -1); + this.indeterminate = this.parentNode.className.indexOf("jstree-undetermined") !== -1; + this.disabled = this.parentNode.parentNode.className.indexOf("disabled") !== -1; + }); + }; + }; +})(jQuery); + +// no state +(function ($, undefined) { + "use strict"; + $.jstree.plugins.nostate = function () { + this.set_state = function (state, callback) { + if(callback) { callback.call(this); } + this.trigger('set_state'); + }; + }; +})(jQuery); + +// no selected in state +(function ($, undefined) { + "use strict"; + $.jstree.plugins.noselectedstate = function (options, parent) { + this.get_state = function () { + var state = parent.get_state.call(this); + delete state.core.selected; + return state; + }; + }; +})(jQuery); + +// additional icon on node (outside of anchor) +(function ($, undefined) { + "use strict"; + var img = document.createElement('IMG'); + //img.src = "http://www.dpcd.vic.gov.au/__data/assets/image/0004/30667/help.gif"; + img.className = "jstree-questionmark"; + + $.jstree.defaults.questionmark = $.noop; + $.jstree.plugins.questionmark = function (options, parent) { + this.bind = function () { + parent.bind.call(this); + this.element + .on("click.jstree", ".jstree-questionmark", $.proxy(function (e) { + e.stopImmediatePropagation(); + this.settings.questionmark.call(this, this.get_node(e.target)); + }, this)); + }; + this.teardown = function () { + if(this.settings.questionmark) { + this.element.find(".jstree-questionmark").remove(); + } + parent.teardown.call(this); + }; + this.redraw_node = function(obj, deep, callback, force_draw) { + obj = parent.redraw_node.call(this, obj, deep, callback, force_draw); + if(obj) { + var tmp = img.cloneNode(true); + obj.insertBefore(tmp, obj.childNodes[2]); + } + return obj; + }; + }; +})(jQuery); + +// auto numbering +(function ($, undefined) { + "use strict"; + var span = document.createElement('SPAN'); + span.className = "jstree-numbering"; + + $.jstree.defaults.numbering = {}; + $.jstree.plugins.numbering = function (options, parent) { + this.teardown = function () { + if(this.settings.questionmark) { + this.element.find(".jstree-numbering").remove(); + } + parent.teardown.call(this); + }; + this.get_number = function (obj) { + obj = this.get_node(obj); + var ind = $.inArray(obj.id, this.get_node(obj.parent).children) + 1; + return obj.parent === '#' ? ind : this.get_number(obj.parent) + '.' + ind; + }; + this.redraw_node = function(obj, deep, callback, force_draw) { + var i, j, tmp = null, elm = null, org = this.get_number(obj); + obj = parent.redraw_node.call(this, obj, deep, callback, force_draw); + if(obj) { + for(i = 0, j = obj.childNodes.length; i < j; i++) { + if(obj.childNodes[i] && obj.childNodes[i].className && obj.childNodes[i].className.indexOf("jstree-anchor") !== -1) { + tmp = obj.childNodes[i]; + break; + } + } + if(tmp) { + elm = span.cloneNode(true); + elm.innerHTML = org + '. '; + tmp.insertBefore(elm, tmp.childNodes[tmp.childNodes.length - 1]); + } + } + return obj; + }; + }; +})(jQuery); + +// additional icon on node (inside anchor) +(function ($, undefined) { + "use strict"; + var _s = document.createElement('SPAN'); + _s.className = 'fa-stack jstree-stackedicon'; + var _i = document.createElement('I'); + _i.className = 'jstree-icon'; + _i.setAttribute('role', 'presentation'); + + $.jstree.plugins.stackedicon = function (options, parent) { + this.teardown = function () { + this.element.find(".jstree-stackedicon").remove(); + parent.teardown.call(this); + }; + this.redraw_node = function(obj, deep, is_callback, force_render) { + obj = parent.redraw_node.apply(this, arguments); + if(obj) { + var i, j, tmp = null, icon = null, temp = null; + for(i = 0, j = obj.childNodes.length; i < j; i++) { + if(obj.childNodes[i] && obj.childNodes[i].className && obj.childNodes[i].className.indexOf("jstree-anchor") !== -1) { + tmp = obj.childNodes[i]; + break; + } + } + if(tmp) { + if(this._model.data[obj.id].state.icons && this._model.data[obj.id].state.icons.length) { + icon = _s.cloneNode(false); + for(i = 0, j = this._model.data[obj.id].state.icons.length; i < j; i++) { + temp = _i.cloneNode(false); + temp.className += ' ' + this._model.data[obj.id].state.icons[i]; + icon.appendChild(temp); + } + tmp.insertBefore(icon, tmp.childNodes[0]); + } + } + } + return obj; + }; + }; +})(jQuery); + +// selecting a node opens it +(function ($, undefined) { + "use strict"; + $.jstree.plugins.selectopens = function (options, parent) { + this.bind = function () { + parent.bind.call(this); + this.element.on('select_node.jstree', function (e, data) { data.instance.open_node(data.node); }); + }; + }; +})(jQuery); + +// object as data +(function ($, undefined) { + "use strict"; + $.jstree.defaults.datamodel = {}; + $.jstree.plugins.datamodel = function (options, parent) { + this.init = function (el, options) { + this._data.datamodel = {}; + parent.init.call(this, el, options); + }; + this._datamodel = function (id, nodes, callback) { + var i = 0, j = nodes.length, tmp = [], obj = null; + for(; i < j; i++) { + this._data.datamodel[nodes[i].getID()] = nodes[i]; + obj = { + id : nodes[i].getID(), + text : nodes[i].getText(), + children : nodes[i].hasChildren() + }; + if(nodes[i].getExtra) { + obj = nodes[i].getExtra(obj); // icon, type + } + tmp.push(obj); + } + return this._append_json_data(id, tmp, $.proxy(function (status) { + callback.call(this, status); + }, this)); + }; + this._load_node = function (obj, callback) { + var id = obj.id; + var nd = obj.id === "#" ? this.settings.core.data : this._data.datamodel[obj.id].getChildren($.proxy(function (nodes) { + this._datamodel(id, nodes, callback); + }, this)); + if($.isArray(nd)) { + this._datamodel(id, nd, callback); + } + }; + }; +})(jQuery); +/* + demo of the above + function treeNode(val) { + var id = ++treeNode.counter; + this.getID = function () { + return id; + }; + this.getText = function () { + return val.toString(); + }; + this.getExtra = function (obj) { + obj.icon = false; + return obj; + }; + this.hasChildren = function () { + return true; + }; + this.getChildren = function () { + return [ + new treeNode(Math.pow(val, 2)), + new treeNode(Math.sqrt(val)), + ]; + }; + } + treeNode.counter = 0; + + $('#jstree').jstree({ + 'core': { + 'data': [ + new treeNode(2), + new treeNode(3), + new treeNode(4), + new treeNode(5) + ] + }, + plugins : ['datamodel'] + }); +*/ + +// untested sample plugin to keep all nodes in the DOM +(function ($, undefined) { + "use strict"; + $.jstree.plugins.dom = function (options, parent) { + this.redraw_node = function (node, deep, is_callback, force_render) { + return parent.redraw_node.call(this, node, deep, is_callback, true); + }; + this.close_node = function (obj, animation) { + var t1, t2, t, d; + if($.isArray(obj)) { + obj = obj.slice(); + for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { + this.close_node(obj[t1], animation); + } + return true; + } + obj = this.get_node(obj); + if(!obj || obj.id === $.jstree.root) { + return false; + } + if(this.is_closed(obj)) { + return false; + } + animation = animation === undefined ? this.settings.core.animation : animation; + t = this; + d = this.get_node(obj, true); + if(d.length) { + if(!animation) { + d[0].className = d[0].className.replace('jstree-open', 'jstree-closed'); + d.attr("aria-expanded", false); + } + else { + d + .children(".jstree-children").attr("style","display:block !important").end() + .removeClass("jstree-open").addClass("jstree-closed").attr("aria-expanded", false) + .children(".jstree-children").stop(true, true).slideUp(animation, function () { + this.style.display = ""; + t.trigger("after_close", { "node" : obj }); + }); + } + } + obj.state.opened = false; + this.trigger('close_node',{ "node" : obj }); + if(!animation || !d.length) { + this.trigger("after_close", { "node" : obj }); + } + }; + }; +})(jQuery); + +// customize plugin by @Lusito +// https://github.com/Lusito/jstree/blob/node-customize/src/jstree-node-customize.js +/** + * ### Node Customize plugin + * + * Allows to customize nodes when they are drawn. + */ +(function (factory) { + "use strict"; + if (typeof define === 'function' && define.amd) { + define('jstree.node_customize', ['jquery','jstree'], factory); + } + else if(typeof exports === 'object') { + factory(require('jquery'), require('jstree')); + } + else { + factory(jQuery, jQuery.jstree); + } +}(function ($, jstree, undefined) { + "use strict"; + + if($.jstree.plugins.node_customize) { return; } + + /** + * the settings object. + * key is the attribute name to select the customizer function from switch. + * switch is a key => function(el, node) map. + * default: function(el, node) will be called if the type could not be mapped + * @name $.jstree.defaults.node_customize + * @plugin node_customize + */ + $.jstree.defaults.node_customize = { + "key": "type", + "switch": {}, + "default": null + }; + + $.jstree.plugins.node_customize = function (options, parent) { + this.redraw_node = function (obj, deep, callback, force_draw) { + var node_id = obj; + var el = parent.redraw_node.apply(this, arguments); + if (el) { + var node = this._model.data[node_id]; + var cfg = this.settings.node_customize; + var key = cfg.key; + var type = (node && node.original && node.original[key]); + var customizer = (type && cfg.switch[type]) || cfg.default; + if(customizer) + customizer(el, node); + } + return el; + }; + } +})); + + +// parentsload plugin by @ashl1 +/** + * ### Parentsload plugin + * + * Change load_node() functionality in jsTree, to possible load not yes downloaded node with all it parent in a single request (only useful with lazy loading). + * + * version 1.0.0 (Alexey Shildyakov - ashl1future@gmail.com) + * 2015: Compatible with jsTree-3.2.1 + */ +/*globals jQuery, define, exports, require, document */ +(function (factory) { + "use strict"; + if (typeof define === 'function' && define.amd) { + define('jstree.parentsload', ['jquery','jstree'], factory); + } + else if(typeof exports === 'object') { + factory(require('jquery'), require('jstree')); + } + else { + factory(jQuery, jQuery.jstree); + } +}(function ($, jstree, undefined) { + "use strict"; + + if($.jstree.plugins.parentsload) { return; } + + /** + * parentsload configuration + * + * The configuration syntax is almost the same as for core.data option. You must set parenstload.data the following: + * + * parentsload: { + * data: function(){} // this function overwrites core data.data options + * } + * + * OR + * + * parentsload: { + * data: { + * url: function(node){} OR string, + * data: function(node){} OR associative array as json{data} jQuery parameter + * } + * } + * + * In last case at least on of 'url' or 'data' must be presented. + * + * At first, the plugin load_node() detects if the node already downloaded. If is - uses the core.data settings, if not - uses parentsload.data settings + * to fetch in one query the specified node and all its parent. The data must be in the first mentioned JSON format with set nested children[]. + * Each node level should consist of all nodes on the level to properly work with the tree in the future. Otherwise, you must manually call load_node + * on every parent node to fetch all children nodes on that level. + * + * @name $.jstree.defaults.parentsload + * @plugin parentsload + */ + $.jstree.defaults.parentsload = null; + $.jstree.plugins.parentsload = function (options, parent) { + this.init = function (el, options) { + parent.init.call(this, el, options); + this.patch_data() + }; + this.patch_data = function(){ + var parentsloadSettings = this.settings.parentsload; + var jsTreeDataSettings = this.settings.core.data; + var self = this; + + var callError = function(number, message) { + self._data.core.last_error = { 'error' : 'configuration', 'plugin' : 'parentsload', 'id' : 'parentsload_' + number, 'reason' : message, 'data' : JSON.stringify({config: parentsloadSettings}) }; + self.settings.core.error.call(self, self._data.core.last_error); + } + + if(!parentsloadSettings) { + callError('01', 'The configuration must be presented') + return + } + parentsloadSettings = parentsloadSettings.data; + + var patchSettingsProperty = function (propertyName) { + var property = parentsloadSettings[propertyName], + coreProperty = jsTreeDataSettings[propertyName]; + if (property) { + jsTreeDataSettings[propertyName] = function(node) { + if (this.get_node(node).parentsload_required) { + if ($.isFunction(property)) { + return property.call(this, node) + } else {// (typeof property === 'string') + return property + } + } else { + if ($.isFunction(coreProperty)) { + return coreProperty.call(this, node) + } else { // (typeof coreProperty === 'string') + return coreProperty + } + } + } + } /* else { + use jstree the same data[propertyName] settings + }*/ + } + + if($.isFunction(parentsloadSettings)) { + this.settings.data = parentsloadSettings + } else if (typeof parentsloadSettings === 'object') { + if (! (parentsloadSettings.url || parentsloadSettings.data)) { + callError('02', 'The "data.url" or "data.data" must be presented in configuration') + return + } + patchSettingsProperty('url') + patchSettingsProperty('data') + + } else { + callError('03', 'The appropriate "data.url" or "data.data" must be presented in configuration') + } + } + + this.load_node = function (obj, callback) { + if($.isArray(obj)) { + // FIXME: _load_nodes will not load nodes not presented in the tree + this._load_nodes(obj.slice(), callback); + return true; + } + var foundObj = this.get_node(obj); + if (foundObj) { + return parent.load_node.apply(this, arguments) + } else { + // node hasn't been loaded + var id = obj.id? obj.id: obj; + this._model.data[id] = { + id : id, + parent : '#', + parents : [], + children : [], + children_d : [], + state : { loaded : false }, + li_attr : {}, + a_attr : {}, + parentsload_required : true, + }; + return parent.load_node.call(this, obj, function(obj, status){ + obj.parentsload_required = !status + callback.call(this, obj, status) + }) + } + } + }; +})); diff --git a/civicrm/bower_components/jstree/src/outro.js b/civicrm/bower_components/jstree/src/outro.js new file mode 100644 index 0000000000..57d3e4820a --- /dev/null +++ b/civicrm/bower_components/jstree/src/outro.js @@ -0,0 +1 @@ +})); \ No newline at end of file diff --git a/civicrm/bower_components/jstree/src/sample.js b/civicrm/bower_components/jstree/src/sample.js new file mode 100644 index 0000000000..2811e75ca0 --- /dev/null +++ b/civicrm/bower_components/jstree/src/sample.js @@ -0,0 +1,93 @@ +/*global jQuery */ +// wrap in IIFE and pass jQuery as $ +(function ($, undefined) { + "use strict"; + + // some private plugin stuff if needed + var private_var = null; + + // extending the defaults + $.jstree.defaults.sample = { + sample_option : 'sample_val' + }; + + // the actual plugin code + $.jstree.plugins.sample = function (options, parent) { + // own function + this.sample_function = function (arg) { + // you can chain this method if needed and available + if(parent.sample_function) { parent.sample_function.call(this, arg); } + }; + + // *SPECIAL* FUNCTIONS + this.init = function (el, options) { + // do not forget parent + parent.init.call(this, el, options); + }; + // bind events if needed + this.bind = function () { + // call parent function first + parent.bind.call(this); + // do(stuff); + }; + // unbind events if needed (all in jquery namespace are taken care of by the core) + this.unbind = function () { + // do(stuff); + // call parent function last + parent.unbind.call(this); + }; + this.teardown = function () { + // do not forget parent + parent.teardown.call(this); + }; + // state management - get and restore + this.get_state = function () { + // always get state from parent first + var state = parent.get_state.call(this); + // add own stuff to state + state.sample = { 'var' : 'val' }; + return state; + }; + this.set_state = function (state, callback) { + // only process your part if parent returns true + // there will be multiple times with false + if(parent.set_state.call(this, state, callback)) { + // check the key you set above + if(state.sample) { + // do(stuff); // like calling this.sample_function(state.sample.var); + // remove your part of the state, call again and RETURN FALSE, the next cycle will be TRUE + delete state.sample; + this.set_state(state, callback); + return false; + } + // return true if your state is gone (cleared in the previous step) + return true; + } + // parent was false - return false too + return false; + }; + // node transportation + this.get_json = function (obj, options, flat) { + // get the node from the parent + var tmp = parent.get_json.call(this, obj, options, flat), i, j; + if($.isArray(tmp)) { + for(i = 0, j = tmp.length; i < j; i++) { + tmp[i].sample = 'value'; + } + } + else { + tmp.sample = 'value'; + } + // return the original / modified node + return tmp; + }; + }; + + // attach to document ready if needed + $(function () { + // do(stuff); + }); + + // you can include the sample plugin in all instances by default + $.jstree.defaults.plugins.push("sample"); +})(jQuery); \ No newline at end of file diff --git a/civicrm/bower_components/jstree/src/themes/base.less b/civicrm/bower_components/jstree/src/themes/base.less new file mode 100644 index 0000000000..097e9997a8 --- /dev/null +++ b/civicrm/bower_components/jstree/src/themes/base.less @@ -0,0 +1,88 @@ +// base jstree +.jstree-node, .jstree-children, .jstree-container-ul { display:block; margin:0; padding:0; list-style-type:none; list-style-image:none; } +.jstree-node { white-space:nowrap; } +.jstree-anchor { display:inline-block; color:black; white-space:nowrap; padding:0 4px 0 1px; margin:0; vertical-align:top; } +.jstree-anchor:focus { outline:0; } +.jstree-anchor, .jstree-anchor:link, .jstree-anchor:visited, .jstree-anchor:hover, .jstree-anchor:active { text-decoration:none; color:inherit; } +.jstree-icon { display:inline-block; text-decoration:none; margin:0; padding:0; vertical-align:top; text-align:center; } +.jstree-icon:empty { display:inline-block; text-decoration:none; margin:0; padding:0; vertical-align:top; text-align:center; } +.jstree-ocl { cursor:pointer; } +.jstree-leaf > .jstree-ocl { cursor:default; } +.jstree .jstree-open > .jstree-children { display:block; } +.jstree .jstree-closed > .jstree-children, +.jstree .jstree-leaf > .jstree-children { display:none; } +.jstree-anchor > .jstree-themeicon { margin-right:2px; } +.jstree-no-icons .jstree-themeicon, +.jstree-anchor > .jstree-themeicon-hidden { display:none; } +.jstree-hidden, .jstree-node.jstree-hidden { display:none; } + +// base jstree rtl +.jstree-rtl { + .jstree-anchor { padding:0 1px 0 4px; } + .jstree-anchor > .jstree-themeicon { margin-left:2px; margin-right:0; } + .jstree-node { margin-left:0; } + .jstree-container-ul > .jstree-node { margin-right:0; } +} + +// base jstree wholerow +.jstree-wholerow-ul { + position:relative; + display:inline-block; + min-width:100%; + .jstree-leaf > .jstree-ocl { cursor:pointer; } + .jstree-anchor, .jstree-icon { position:relative; } + .jstree-wholerow { width:100%; cursor:pointer; position:absolute; left:0; -webkit-user-select:none; -moz-user-select:none; -ms-user-select:none; user-select:none; } +} + +// base contextmenu +.vakata-context { + display:none; + &, ul { margin:0; padding:2px; position:absolute; background:#f5f5f5; border:1px solid #979797; box-shadow:2px 2px 2px #999999; } + ul { list-style:none; left:100%; margin-top:-2.7em; margin-left:-4px; } + .vakata-context-right ul { left:auto; right:100%; margin-left:auto; margin-right:-4px; } + li { + list-style:none; + > a { + display:block; padding:0 2em 0 2em; text-decoration:none; width:auto; color:black; white-space:nowrap; line-height:2.4em; text-shadow:1px 1px 0 white; border-radius:1px; + &:hover { position:relative; background-color:#e8eff7; box-shadow:0 0 2px #0a6aa1; } + &.vakata-context-parent { background-image:url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAIORI4JlrqN1oMSnmmZDQUAOw=="); background-position:right center; background-repeat:no-repeat; } + } + > a:focus { outline:0; } + } + .vakata-context-hover > a { position:relative; background-color:#e8eff7; box-shadow:0 0 2px #0a6aa1; } + .vakata-context-separator { + > a, > a:hover { background:white; border:0; border-top:1px solid #e2e3e3; height:1px; min-height:1px; max-height:1px; padding:0; margin:0 0 0 2.4em; border-left:1px solid #e0e0e0; text-shadow:0 0 0 transparent; box-shadow:0 0 0 transparent; border-radius:0; } + } + .vakata-contextmenu-disabled { + a, a:hover { color:silver; background-color:transparent; border:0; box-shadow:0 0 0; } + } + li > a { + > i { text-decoration:none; display:inline-block; width:2.4em; height:2.4em; background:transparent; margin:0 0 0 -2em; vertical-align:top; text-align:center; line-height:2.4em; } + > i:empty { width:2.4em; line-height:2.4em; } + .vakata-contextmenu-sep { display:inline-block; width:1px; height:2.4em; background:white; margin:0 0.5em 0 0; border-left:1px solid #e2e3e3; } + } + .vakata-contextmenu-shortcut { font-size:0.8em; color:silver; opacity:0.5; display:none; } +} +.vakata-context-rtl { + ul { left:auto; right:100%; margin-left:auto; margin-right:-4px; } + li > a.vakata-context-parent { background-image:url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAINjI+AC7rWHIsPtmoxLAA7"); background-position:left center; background-repeat:no-repeat; } + .vakata-context-separator > a { margin:0 2.4em 0 0; border-left:0; border-right:1px solid #e2e3e3;} + .vakata-context-left ul { right:auto; left:100%; margin-left:-4px; margin-right:auto; } + li > a { + > i { margin:0 -2em 0 0; } + .vakata-contextmenu-sep { margin:0 0 0 0.5em; border-left-color:white; background:#e2e3e3; } + } +} + +// base drag'n'drop +#jstree-marker { position: absolute; top:0; left:0; margin:-5px 0 0 0; padding:0; border-right:0; border-top:5px solid transparent; border-bottom:5px solid transparent; border-left:5px solid; width:0; height:0; font-size:0; line-height:0; } +#jstree-dnd { + line-height:16px; + margin:0; + padding:4px; + .jstree-icon, + .jstree-copy { display:inline-block; text-decoration:none; margin:0 2px 0 0; padding:0; width:16px; height:16px; } + .jstree-ok { background:green; } + .jstree-er { background:red; } + .jstree-copy { margin:0 2px 0 2px; } +} diff --git a/civicrm/bower_components/jstree/src/themes/default-dark/32px.png b/civicrm/bower_components/jstree/src/themes/default-dark/32px.png new file mode 100644 index 0000000000000000000000000000000000000000..60395729ef6cfda914b211d5a45c9d2c083b3175 GIT binary patch literal 1525 zcmV<R1q%9!P)<h;3K|Lk000e1NJLTq00BS%003YJ0{{R3Ta{ZH0001-P)t-s00000 z0000000000000010RaRA1ONa40|Ns9000000LRD200000006bMwWp`2zP`Qy00000 z0N>x=)z#Iou&|Pnl0QE`#>U2ri;Ey2AZTc4hK7d2!^8jo|LExGnVFgL^78xp`|9fI z{{H^%?(X*X_U!EJ`1ttr^z`-h_21v$+uPgY<Kx)a*wE0>%*@Ql$jFb6k9c@^bbCf0 z0000UbW%=J05J?b7$qwPPhmTy5d)-?xp^Mm+qHy5%#b-oX_@#U>G}Ww1nNmdK~#9! z?VAfz;xH72Nz$||!ongb>TW_>N?RW4>i_?5dkfnECVkjIX4-l`ADw#akseRQ#%u4! zEU(s^P17GAf(=CKfepk4b_;A^Q}G;^oNyiQraC}50XXf|q%93}?!-BF&P{cI9|d>R z(FVGrPfqlOYpxI20Q7<YdG89SL$Cd$WyPVD4J`5}f?V$DI_2aDr@4CeD41XaO{b*) z1L(8N!lZ#*Fj|=(Gx#PM_!|VsMFuYk5WavAeN8_dd_@z95Cd9yeu9`b5d1$Y{6A8E z!vKlMAi4S}Khe+8FCiukB*KS|RODA4;Pw9Y0;CT8pC20-2B@Q(Fj{_o1`Rauw-Dff z3FaL0qr_GN%g>OqRZ3Za*8Hyzun*QhRscKzVy}UKQ+R&yMyVt&ZQ$iguK&kL&-MSz z(+T9N?OlF^`0GuglFiyDd3xXX<9HqWjOHGniWzb2n>El+VYDber6MUKRTiK%f8vwN zJzXbBB=_6Bj1rQk4_J~Yl`xur{91)UMyS?i4U9LNxbO;d0zkqW*ERe8WKAyjbe)89 zyL;VjWk_;$%EB;YwBY#k;0&-ZYoJo9<R=u@e#g|Y=1&y4+|zX~C4{hr_dHjJj!Q<1 zj*qslZyB%K$gF`;#LUvM?@vN<xu@ypcOtp^*<DnQ9_-%U{~mdN+XY4q<nrqLtogga z#l3Fe-dHCAH1PchG%z5h_rhk__ji8EbACEE*144X-RqIvUP|7z)fn6Bfs~VsMyv~V zmG(9e=?2(9q!!pfq+?(M8&Aha6B_>T5Nse)7i=Iluv=gQ8_Mn10~?Bk2HKeq{B8}j zJ0EEK4;Q**-mr52?0Eb0fwme5_WX+ZJ`4V~<^%0O2cp=Ui0TBF75<+U{vSQS{(PXV z27<j`dV&TWH1oGVA83Q4Ju#l|1C|#2?aT)nv8>9k`~+7i1|2l;w?7|f0Y_AvV4NtG z%~w^91nT-n=3k(HYX0`-11&YsPbm)YIKQV1I%wc;dp^(xl%*4Vh2H!yzy~<C{q4^O zT6-2&N)Zbaf(HJ!=L79PSrnalH^<+?e4wp65y^X2IQchmKCst_A-*sAH*r3&^Q$r6 zW<9Xuw6}psH^2rWwZH}<9RnMP)B+obbPQ}DQVVP#(lM}sEr#+A{6F)T8aNtGhohd3 zHynED#(|9iT%5ss-DTvAqu-96pvUhPuGgbvHU_mmM4Ul-?PU3t{2qLfJPh^x#zIW^ z@cCZ&pc)1E>&Jm#?G5lt`K_QK_m1`>Y%G9ze<pw_Hc)3osh8#_fcr<PHSlF3fIt9a z=eq`2`qc6Ahf}zIbMphJI}ry~<Ei&uFX55~(#Nfs3?5clemWjGB<Mdue%L^bY2f?* zB7}GM&on<`vhY*pu33PqGuj$pNduilyisAOl7jw?=<{ryD5W;*iBW>YkF!fS_S+g@ z37$I-rIf+!v7mpyXPYqEFQQPbCq_>qYZV>=hqeZ|EK88j11V?EG+!RxDHTRfYz_%3 zZW5ph<bE&Hw?MTuK%g{13H>W<=s1d=rj*ZNW7NP<W|y!G+Zy1qBEj(sEm41trygu3 z<EhcDToCN{+rw)Rv^BsAJnCuD=!*&I#sDtQXzOA^?e#!h&O$oVKm@@CA~nGVA{_%8 bcx(OvDHqR+L@oF300000NkvXXu0mjf0vg<X literal 0 HcmV?d00001 diff --git a/civicrm/bower_components/jstree/src/themes/default-dark/40px.png b/civicrm/bower_components/jstree/src/themes/default-dark/40px.png new file mode 100644 index 0000000000000000000000000000000000000000..002af360d04324dd30ef3c19116c738da7e06105 GIT binary patch literal 11488 zcmaKS2Ut_f);5N!bVO+)kt)4+5l}i(r1#!yfKWn@*h23pRl0yQ=@1|)C`CF1lq%9& zqzME9|HgCAx%Yd%@BTdVkiFNQwPyCr?02nq%^-BORmrb0Uc<w~BUe{b(gS{f;o)6b zARz*-vJMv7fgc8_vI$h*+X)(I>+6W8=-_SV2v+yBb#~Nqv~_^_^g7<d!^3BFH86pi zXg!j#_x2R9y{sb;<Ou<^@$l}+2SIG@-5sG|J4a_%FF96BTPG{n)j^KcSX@g;3-Zv> z#Z@iX*HJ%M+rU29-Co*(RsKHsUXTo6z|#?G3l8%1@bZ%hl4Jd2R|dGg6brI~|5Smx z%d!5|DHAPS@I!B3N3ghnD8IdsurOFcLO@tdTtY&a4=f@iEFvfb6bXJ|F&S|Q84*eF zzy4T()_fhDWb~9&{?!(6C&%gng+gQm1p@;E1p-9{ynUSog{7sXFKvj3@B=mY{a{{D z+aP`~KeoRuC^`Ds`?^A)uHIhYON+L4-u_TIR-mVUy@Ds?AG2P5{~9J>zyyPAA%emJ zLYJ@fcSS9&|9@3a&wpzBLG>K}-QWMyu%7`8;wY%+=;!V4YY$AE6We7|5SfR*j<!&5 zUjuJ%kH1Gz*Toy^?dReR0YB820N*us^>XkI^yB_hUrS3y-OCSZ>t*k#t|Z3_SP*b^ zb&!#iRuWSZQxp{!6BQK}Ru+4pC@CZ*EukzTAuXyRtt9ogu9COCzo(-Y^lx2<f9s0< zSKZ5{;0Xa*R&w-p4RCZ&@%8ou|9NE@*Z<xZ;s0vyU%C$ey)PpFRaX$`jNs+O{>McB zEdo~0<>f!i7P$Fm;X8T(tKAn^){!9ydptaD19c@ugP`wQInxQZCfYI6etEmGUnH*F zv$xkJ$es-1UCS<H!`|ER$YZB@s+lVE81#|VLhQ*IA*}EE71gJ4ac~qK*NmVHqbD=7 zC-*+INGY>PDf)5Oz)tOl-;p5#zk{59V{aaAwwKI|O>XRzZw#rLZJ7I88dd7x!rcuG zkKzXg25yNB#WTxhV#70!9@b6gIsi9~u%(`)E-xF(jVncT1Vjopcz+cFBD}u~AW$O- zGf;f5_Q?@p5v~cyS%t)W7Iw(<s@vWxrh$cuz&ZZhtxL0Va&lo=RxEPC2SYoy)Cg+& z<oQmDrS{d_5DIzR!I)@pweH<V?I$Z)b!v}T==E4JOx{Rgd(39b+?aDcF~M`%-k2^D zGVTmIgnm4cA|wB}YN-FnT4?#Z6s4KXE~IyzidbcbzWSn<3-R-Cy;25MGfOI|LXae@ zcO?xQ<ml?XjXr)`2G57>l1L;U$xJM=K`j<F%TYtnI?MPx_f)UDLvfm~8ttjphVtn# z*RmtnxeagXG0<K#>NAh&GNqByhQ+O~uSW#zZ>cUgq#MOcXp}tky5r}_m@_9!>nzi5 z|0TY>pR{y+W5mg3xFns;`<t4HjzcWl9{N3!PietO$x3f+M=RewnOgvnWoh-D(5nea zlI;oKOfEA;{4}xZBlKzm1eS27<g&+zpJrCkggY+*ffhU~xy%aj)5_`^;m)f+0&heG z^#o*2;wG$pc{W)DF3Teb3LJ7RQeoO_EDhz!;n|=u^DSSS3&AYsE(plS(YhPVIMp{h z_N%EA>;x@wfJ9$TytVO6lKcSTQn4af5z}igz{O}(6ogzO&`w2?e0_F{nZuFJmtEV6 zU?)C{fri^hz%oOx(PB<zk_q1S)2m2H9XY#RMnF1KEerR+NlHj$3d~=eAF=rE<I;O$ zQ0sKfY4W`0P{;5u@yxKvpp~<n*^L~p2%Q4ewA|cWB)Yp&RoIh!u)0p=SuOTgXa9Vm z!z$9QYJx@+>>j$gxmoPH+?Qq&BaazH?C4q@SqVGJlh#+USWZftRhG&gdvKpOqV*1P zj^-mStT7#@JD7Eg_Z1np*|p`jk8O_>7CSmR&X)T#R?k%EOO>qZ$)j_Rj*f`;swyjQ zG$2#+Z&-zHRyIN5-Q%0po%hGquJlwh4XEyqg@%NLv_SCT?ioQgHsH?IRvBmN?u691 zXpcDkZt<Q`KYq=AC~=%!G~2*UgmuVv!)q0a$dRb56?>Z1X6!ZiW>S!g%iT^S@}Bb^ z&!MLn<0<)=^07CTV5cQL-?1f1nUM|CNYjRW9eg-p?EH?>oz-}A%#3A<03GObD|3F@ zyECqf#3HYYjg9RjhE8zM^wa*S>tWF|x7eHhm2kH?v(J5f8p035kP3^sjb+AGFpk9L zT$fvMA7vJv?JL?5R9P?9*4CaGTZf64l6cUZjx^tdO^{S}R;*^0uC&+Jr#|a3f4rDs z9S-~4dM8fJV}2|&kserZL7}1dBF@iFJUQYeKD+e2TdP>b;c(Ien)}csxtKjGj@r?A z`LiFCqT#<66SxghO#Gea!`6#4o<OlVfpeD)>nyg19IbR7FUBY=HZ(N6x$~X-PNy)I zTxZX0oSB}!$Mtq*M$DRNdSFafzK6bG$FUu_cAmK`y?aV=SRPk$;t~#gj{cgV+YOT| zL)p@zTyR0_j$2|1a*~M3k(0u&$$`MYmSWs)(+OCt5y7gHO_KJX(OJFP9g3J_tKAss z2wChxfN45UciPmlX=K75UbOhFf)Lf6=h(BJ9yKorM99VDL7WC_)>jGLVpjkw3ISsy zq|9#ot{Eop<$j^?_4|~z@SNGkZ`xK;6fTbzYqm^GOw8=<`Rb;pr~3}cUz~jfUbeTB zmKEapwl?f!IRoC6l9F<gBO6GRG%@O+S%`aE@t5U*U6%SZ_V8aHh)bb1b#S@O>sjym zJkD5Qhj-z|Mn)i*VRX0M&hhR~;HAYIQ9?Aiav>6l$0#`d2{3=z%J#}PZ^X1>AC0+~ zg_Vx<WWh;p)igJoBp>%AvFXd8Ty=Furry8WW~~*hV?h|ErqBC)VFpZ1u+`j{q@-ZK zAN0#69GKEXe<)P!ZgADn!RwNddSP6iUipYb^LYe#Hw4ozc{==%Qj46Da`h~=RZoUF zZ7SNz-KKv4BO!^gGO(p`pC;MTze^i^{rYuy*Um{cV~VbW4~BTpEmMH8rktln3Rp0o z=h{Q?5#m&br}Gyb(A+8Q0nfn9UZVOZ(_<eMD}x2fudx0~_r)HpgK0EPiU)Z(tMA90 zu#oEu)};BZ4iY9E<BsO@!j_U$OA3BoU1qIqZ^SRKoGro3L|owXhvbfC^3o86*QlHM zfN`D<bHF!mGJ~K)Zj@j)NIXJ;31FJXqMJa7+5WP5+)kkAvX}gU&d@hh26j*a{pK7h zMXAk24QEoJ$s^NDnl<borQvrT%H>yH{Bk?QL&KgVSr2EYnTG2ZJj}g6CYEV5!UUtH zml-F#N=$%{kUw6C`UW6=nPpo*n#%7RuG>%O<u}|IwJI=RLC`~DLL*ZXlPT6(mE9Y* z;u@75wb8koa$(PrmS|$9R1sL%!rf;NZ0+sr>~=p<%9CNcbmR`lV~NVnM#6FmLe6%- zlzwzgY%(W!4y8&v{^p#Qvr8C${NqJZ1}$T9`U6$%0mAiqrL>xj{c^A%H9bxCgVSso ze>eM!a~!;D(lRh7JV#_T_k!WF!%wfjpQ|QFI_^STzqs9DrD_Ejt%cVgz^~xJuSC+y zutB_-U!w3x$o?sjD7-{6skl_CEtZ>C{?{YmDNz1rbwEHRKch`AdRFd$gk*70(*w5O zkm{|872PXpQ6M0S+)`d3q5!x5*snUy>i42gz4K|E0?vWi0fun;U~z4v@B@ohTTUmO z3a|I3RN_%?$d2^c!I;j_THJ$tp~ICd??IV6o9WG(^!|>lq3>Q4luL#_<tvf(NoQQ1 z-CSz-7JULl0-2njmm5N}aEEUL!`!o*irT~K6b~#13e%=%%dy*HfVY|UP;T!w{4V#> zFdFHN-2MFM;9+~|kXT$y7g<f%m~tZW#mr!)`y#j!bNkvVAwvNd_a5tR<0COPZ>7bn z<tg_e{Y!@&0hE>_Toi?N#U0xN!U8+8!YZ~{wB;!AT;q^=oEf%@dk4S5>a%69cL{A} zNHe+I0le-TaTV`gfT_%^tehNfen$IPKbrD9VpL-3eBa`}!&}OkRHP+%H=dMEAhtM+ z?W5;{LnslU(bJYn2AHV8?g{_^0wsUsqZP4~cFT*2Qug@fo2m)7aTir*bVs4i8cnvn zX`(IO0#VOm$?e4N1sM*ZjG~Ea%^C%^`6{cdiE3peUlx<JynPA7v>$1AGa#gO$cA%i zTiF5dmco7-ftu|P74HjhGKYSiQC!246%Et*Swgr>n~H}$wMzA0Jvh?Q(Ye@n>Kl=8 zF;~m43*(3OkF8r^!?PpD)TlHWGalOE5vbTj#*)T%;c?T^Bd+KP2+`mdS=g`>skNY5 zeq}lV7lkNl#KktT{P73DpRITbG%w`Mv(`=x>!8eH^%))PVsmSoadC0)^Cq5zbIE9R z-l+6!*nSj4Yt(thDG4HuYiw$gY(BZzX~Ue)0lxXX8vS<DbvV3G4_HRMxZ^MKxxs+v zK8V^yAZG^}Ym>IO>rqBulokc(rc#b-QUX=tTIPs6$@?;-QYCjKWv70ZDBD?EDJ&!- ztJ{Bn|C+{Yyy5jVJnH>kO5Pd!jXg73D{E^?jZA_7Vjw&dpaT|WRojlty`LuL=A?|Z zS1l@aT;jeIH5{>H0Oy>;2y3Y1teI!gevdMmFB+cZg{aQ~Uf6MEZ@IrExWHR1ZmiI1 zK5#y)ENN0FpQE~Qz5p^xXmmi{CQm>943x2S={4|SxHa<x<nOo759;!8eExgb^*RD0 z^(d5?s$9vB$S4$l;*qL6cH~EfRj{j*zrT3mWWxQ19$s61e+k$;Y&FN=T;>IZ8E3WQ z9re$cs)NHrTV1-V7Rg85bk^CXrl!578y1=uLkW%O#PP`R^ZmS1BdbnI590S?B)86J zo`yVnn8ysaPdyrx#oP-8yyolW<>l<+L9~l|(qsY(@cS*+XNz?DKv?CK8A0c+$zpPt zluq(4%6WA12HZaV=wvl7&(zGU&$1QDO*Ms$xEa@naF62XK;q-$w-DbB0w3-HA<a@l zZ6v!rLn1*5Wp)@`bMLl%cxZ_U-^w^94HdpLt8FE}$Fo>ILPkNcay#_bhw=V4O9Jgy zl$kXXiWTH+zMwECyVLyh7pWjp$ZvPCJ6q40skvOt<wm>IC%u*Y{QQ|DHq{a!!fjWu z`to^awoTvs1Whaf<L6ZmCO~(T6>s9N-)uh0e{s8YTe9<HAeObNt3l6o^|b8$jpDDL zK7Epw>`X=i!NgS0gP*&q`C~Nj2Axr%h36<?6$W{&8EqSDtKxp1=vE*UYq37x%h1Pk zUW9`&C;O|Scf4EnQ9SC_&a!?AEK<{;YWbrXzX&T6lUI5dlY_I^$6s{vn^FQ-2Xk6f zZ^Me%F+eCH@qXN;k9j6ppoZLr8eYc_fuw}rof{V&x_8~e-*Gh@|5H0#vn9O^cU{5G z+M3JGh$;(z@9A=ewU@*8OUw~`j9rKu8dx;UftZcYlL<api_H_kN@AuX(*!a0333vL zABb59_5c(KU~?z`+&G``QJrpz0(tJgnfT*=jry%<sl!XKJr10|%Ssw2vPqk?G~3{A z>=hi`%8q$0>MZg8yY3mO!4@nNP4`~#*G<F?L|*Vl8N>BaM);E9I5P_i<r41KCrW&n zB}*_{zbcHmIo03g)bpw22s!6Hx@v!P>%%}2i)1NU(L|Ft!_u^;MDIR-{_L9|e;%Yh z_aHyf71rQMqev_e0lC}jlDD3ki#FZVzBVfdvgX*W8@ez1lk^NQ@0}$1)4y~5eOwHU zg2>(S^-vfi0lJk3>o(g!{{5!G2AS;Q{U_+D7o=6A*dLS;LB}ntxuoX@=5(&Fkfl0# zRi<;jy}i#_t+#G4cm+1VLJqH=eQ4r+eHw+4+H4xL2Vo-?*i_@$18fTPC86o8yZ)1w zM{?~yayKX0=yY;q8b&x=UvDf_)Zi6qEF^bvX=fiF{c7<25{ElIsx!vZ1J|g3od5{? zjpj|8@tccJMR)O(Y*@+g0B=Zj=@2h{qCbR@+v)hreJ}_g4}=dE!uzNE5&Wmj;CU8< z*`ub52UjHnss3mKR{kn~?k>#*WVR-<^>eLH`&>~;-$>{jzXQTokY$5hk8Ks9zW-Tq zB<;cR6uEB1Z~z>q(lk_TQ72ql2s;wOteC&s4{=Rxym1&fCC3LA1$j^Y@``U8QO4T% zRZ(jjxCQO(k3hnr52JJOe9SE)>Zo7KKXAaJ+(KVi{5%ffWy+(2SM*l+KQ6pS+o2tW z^epRq`_-%@o!LH<g8TXu<Ge+MWPurWt5?=}M23*2sq&o1QCw{%2gGGGmnt?G-yhQj z;N#-5R?yE!u}HO<Fi@$=+*66cE`Z3-a{N-tT#6GLWEcC2VDDopE4^B;PT`ZQl8h%g z3C_#$_DEg0=V-APO#D<kPr%g}XIPNF-*2X>E$FDbfN+zYXD#jA|A~CwconvKeHbjO z7m-A2s?rdvaaigP9h=$6%~i_tC>|~pSBg(ZB>Tc-ts<-fL|FtXe)vB-xO&TC&e$=N za7oJvmzLCQ7TrOKr~^7ATTL6SIY(fr{jC=3{uE-#@U>5uB}hz#q0*MN{AxNiY%DXG z1}=&wj^|B2pRM{-2`#gKzC@_jgj#lZ2W=PG1F<VDXo#ez(8I1Ivq20Q!VpPxHoQ6K zfgdvkn901+^0)5iDO*K4kXVQw<~k`_fuDKFJ=3jkKAq?xRazh_SPFRHd32)<D%gB3 z5x*Jij@0K)>WrCC!1+&L6-Wu^rl#(0Lqh7AEnQ!<VQz#32LqAszQW>KD9_bRgn6>@ zKHrgLQ??D&qkf+uZ~rm&l_zH^o7IN$Z|Byq3L1oH?Z%uP4CDrvW;dp?x|$B)x~sEL z*b$O_H-I&R+PI%&X#&|N?k0JmV3pNb07*XAdh;5qIf_;2BmA8((^%(@02^0XaQ{9$ z9FQH^b9Z<5TV~W{Hxw8!pHD(&s<sequQ2s&-k(n{;d;EFvMI>DiO;Q_ZwckyJ`i#w z4+yU$A4ZsOVK8}t91$mb%hK{`F)CNMJb%4)<*4p3uM%z>!iV|m4r9L^rEo%S9cDZ| zgwv9~TP&DKXWl8WUias})W1bf|0<9JpyuWKo#q9R1I8G4#@-4{s(a7QzJk@jm#Y?T zp~><H(3i&%IaVxcFak8ir2Q1e<1J<2`e^au!otGY@UU*UqhoQZwmF;Lh;y>>SbElr z({ONg2Zmt&y|((J{GabSwW}zLnkjG1{up^_tb-4IT(`!a!*csJ1#9j6%STpP`a7pU zb8~>_l;&#I+kd0zW+~P#jw(8Y1G-WGWGPL4DG+iH1DUhchgSpy6{l8=I%}gA0V+y` z;IO~z46eRk@oV;~R&~!NsRwlzV_34@2cvOo3u=>YY&%-;dF<6K4D_nKTBZ{gqN%Cb z4Uo)1*(7iBd7ia)o_VH;;A7DA`}+G0xz0POT|Q`Q3lJ$&Lgdy}i+Z;D?VuR2TV(nZ z@$Yys@!3bbFB?KtY1FLL->sqp8=t>AUD0?~wDlq#ZO!%ySuV@eE(xnVA1>YR5@&o& z&%`8qD~>h!i$*b9*bK)l65bn?G4h#=Rql5bM~dtZo0!kvYc0Cq@^zlG*6@<v{NaJu zrNZ|~k@A$|lN~Qx&+&24FVcjYVTNaZ89!tMLV+{~A{wP$)(K%a4Tbejuuw~xQ%ku# zb#n=48y~c`v>d2>_ipL_>6Yj$MbJdV=5dCWg!uy)rK>4`G@ke-=;H?r(aTl8HtM@_ z-gb)Yp$#J5rnD=*`v?$E$~=G&p|wMfT{9T_zpzBy3mnsu^gMA-oNWvI(js>{BjO}z zg`^j|AJgF$WL64?!?V%Cw(EX8o0R_VxoYD3SjfrA(*io8b5zF*tuD5`BeJ$Jn4y!A z5>viqgL)GS3%=s;fDN^N##^_>x$kP7j{tr=TAc~5t&am-I5&h!xvFI)Gc;fKRh^0r zxsEcqe%uE}>umCxnP<dqp>A7lp+N8;U1`3PHJ_!uajvF}%hw7Zr0^Qfd-bZPEqpvX z!Z9faz3YADz?;t{)fXot?je3J?Z=NFGe88Oy;<acx)>uEef6f)?xE_zKqIPHCFm2m z<kDrjbhN$w{MnTe*;vLKJi*pAhZ6?0;^V&pw!f#1wYuaC=E`L`z^+?I^h`5@G8lh+ zh$4<sTbx&Q!?n6ReAh&+;<X}pI3YG%0M&`}4h=<)9}i|rrx3xen*$n_Aa4Zw##ou{ z+qW#vbjC^;$x6CSVr-Z=dHvg6AaqX~?RfU=nOJXDGxp)!4($|XY+Yt03&@V_e*-=T z{x~6Q1?8a<m3w6PPyGWa$U>yHzf1ji1MUIiveqNq9q&L=k2u{)VLFRXx(~^!4j$Xr zLu+0Wxwu+St!-V)|F}L@8Z&S}d7aZ|dXv(JI;idWU6uCF^pnUYu~xvhzuT^8M6-Y) zm2uQ><z1-4nFs+V3HIlP5)r+WxpqjbWb;pM8o2l;WvyTn8H<|#+CYC!#su))|Dd;j zk=?)k|1Zk>PrdDevb^!$(V^~Ns`i&;_dscZ^AAyt#mCu)-3cX7Sh%U#HdOqs&S!9@ zc>l%hCy)p}s7Yle>u0*e=!=}Vo-=Aze2}Cd<__1Sg{)+sLjddQ?5BG)4~^D)Gm+Fu z4O<U|e>YrdeXwxpI3rP)iS8?KeE~rle9+{e63ud)+Px26FWynD-mPby9+=?V8=P!> zVm2t~&Me(dKw`m(9W+WhDj$;>u!_3Xay!JJ|7|Lv3-hd4Q)?;LH(VsjoDI^@<Gz<( z)fc_~oaADo0>)p__u*-{5E!ELGR&~V^w&~c*c)D&*^1(|(~pPXxaS7fC&6eX<_z^l zhc^|uSIRFvB8b2X%;D*X%}hPSQ%n0ZkpGO)pV3R?w!^9CY*)Dp1hzQLbbhiJ5_x|R zf{sMh*3{NMrulqZEA_3=a*3zWj9Gf^Y(1W(U=6#lYpAV3aBy(B_H-<&LBPJv^$L{~ z?dOEh>0Y}rab6#eJB9tfCQGwef7RN5p*hVHR*k>)O;IBC4Q+5(SUY=MBH!{->|eT{ ztn<9w#FC#n#iPWpzPn5!^M3>gQrdPNc1(g7!VlQ_VucTeurI39%SF%4&FN*DyMA{f zsPbnx$3pd4UeVrwyYJwuKC6X_^E@)BQei77?h58>A{&rzy?^uB6{_agRL&A|ZS_}g z-<(Gpi-M-F6j(6su&^8O(TLaGi~M?ROS7)A(I{BQwL)1zzH(nvbp1!b{w^gakA&PF z2xP4_LLh?R2Wc*-^_j&|aEkNP4w!R1%8%(l(HIk7mpfV}&-j9|y#jhc3q;Qpf_!{m zv1RqqUCA!z^@W9nCjcW3uIlXUEK}sTZZbc4&u{)r#4)m~J@mv^w_ZCF4R{{x7zi3h z5a9Shss0LkiYV>W1xL>bki(kIjKKt!o#myGhu;}nO6xgqnTIgby+lO<gdJ({yF5nh z{>f6xH(=Xk<YIkt;l%_U9bJ~$8bGaZ86R}eZl-`6y3B|!DA;W-#VN1}f+1pYb8Uf` zANr-*17>|5Y#p4t^5?q=E#48Q)8^-99IQ5VTYf-PVQFg0t!&*7A|fL4HB%jRR#@0` z-BNw{@S);T9W8qBQ~BDV^#yj)^e_zP*EC?!^FuY{>LwOlJpK*a5#1UU6(wDng-#+N zBSC7>cC2K&?*WOmLH1-6XI<BC)wrLntbLsxBEidP6gQIt9URz8{n@Y}ka7ISeIRvt zGIamcW3cnPhKO}5biEv~Z?)lET5(o@AJt{ZaQilz#9w<eHRi0A5f9|ewo5KKlXw9T zrPW6~7kzKnJf9Af44->Gi*5y&AWh(8m8EngDKL$b+`E4;b!+~GJ8to9&!NVaD&)Fx zSqo8ls(|L)?yk=gA%T|!O@$6$t-&~@5s#;_+R4!-I_9tt*HJ}O&W@RyqIVSqLmq|M zS=RgPujWPEZ$l!H%8M%A8%;g#ILj2{ks}}-EMr(SvH}8HloYHL_<mQac59;|Ecx5$ zx)VWTy>u$Ns^)<O06hpk6}i_xGbKkspg;vDJOCH1Z~O}vXCe|n07>~jQ4!d!`@8%b zDHpsJr)ur9W}4zqiFWZU^4c8#5E$U%e{z`m<f)4s-HYigqGlu&fUAj>BwP9NnB1Q3 zeXhAPxTHcBVJ^gVW8VJJfVcm?>}zx?GuV^+z~$pAF#sEh1GKG<&Gj&`*dAqUw*rAS z%Z9bP?q;3^16K+jfi|6D#FYA3Y1>ZgruEF2<+ZO{+6oJ_`7y$CKnmyrmxBpijcCrW zS0f|I7J+x4ot<6y(9FkQVkaR0ok;*6ljXmhrVIDG!g!$4I2~YpUsy%p4x5(gbBGAE zxkyP#FEBvj@f=e$252oW^`>0h{EY})ZJxrXk}@6l<x0kO$>Y{_F6hGS6c(0r-x=EM zZd6ncE;VOe6;ZR+m~4A<8l|eD5@47G8OoKzZ<-Hpd(_#p0~p84%F2pHaecaLAxtJH zD2O@!$#Ov-8aGQ$G9&#tyCQ_~Y$ubqqRPTH10NI^$(0wn2Y0V-4;WFNZ`Hoatw2dZ zadW5rXl`}3U+~*<B#L<f!IgV#Dmots>U@Dp6mMOeaS56nrD|iMlF9*zMiLecYbnX& zsb!&<n3y==vUlF+*e-%WBr`S#;s{v|h>i{=2yj0<kW%(^<eB@Yh@EI)zmmhNIR2LO z`>3$gUzboS7j!VT9-un!<;DI7LCIBZu6ob}K3D*7@(mssf=@kFP@~aCnBF{_tC3Q` z3K`?BXL&aLte~0&0U)CyyxO9LCN+T6181%0qOib8U}bK;`3e>6vFdw8gsn#Y<%Ac! z@?v^toEcolU7y=Tn$lQZO$omO&$?ma3T-3g1iDyiVsjWlO;6Q)6~PzQI4UrHVI)rv zRI!gn<xn-xMmgh=+)6<)0y!dl&=)YIP2Yvw#`HkhMqz=Tz=+ms^E36Oz3WmuJ^)AN z@+!dViA9a@*2-`QT^dzHKn2hd9vR4U-xj8;RLxfaNO~e7CPu6DAz<#t`20KzUm&nk zWI~KbP!+fm7S=K{GBV1Y6Hqd2Huvin#0yC2eDDLFB@}d}DMUZ1sHpI4Pt_ZBYsp9U z&1Ou^Mxq+@Uu9<_#WP~%(dhZ4o0p<Pb-!dDA{S<|ArSBZIj}xkDdz%q$uIK)e}7H? znH2aBnFDP&9}j0UDR0&-`S9$&qm#d472v<+wbCRSrMC04%IlEKxId2-u8}*6*f>Tr zXlS{A&*dw{DcPv`H>L6PxDf213kC3n6$qYtNew3%vk4WYU4kx2_7bg(rfYF4el&f& zljPGg#+N81vi}U7UXB`O=<NWIFfRA#sURt^uDi)RGc<&EJl&R&a1smehxe8kf6N;m z+zS=toi=<Kl4U0C4F*Y$Qmt;u$pvCoXUAa1=|4>d13OP=`KvGXGCJ#n#~M8{JX3i0 z2UPl9a=QQ2=cpE}y&tmj+Bu*EGS=sn;i)e=;@c(@V?PH34?UZbecj#N5A&(Y(j_TI z$|o3rO?|s1aWoozUgWCJ>Z3J1@zSLM{g*gSqR)xlD=@DK?OCo|AH2yIj|CCLE6=5> z%?t-ju=*7GKkp*RriWb@@X?<(R9|%3BtuY33Gb;eI_i^)I3c()XRCZ^z8E_HIN}<< z3YQh|mXgn5@!GI(KFEg9{Njjj8^nXBuwz0+K}`yC51Orf)I-}ezWN&}l>Q!jfkb3T z(p3#1(SjucA3b7E->l0-3B;n*GnxqTO*s(P>nRiI;Ie|=5fK*`kJKMNitXx&K_L)G zz?Ew2Kiq2W;uMq=hbEzZ^sE9W7PO*~ZZ8w=W7qWhew%+`SD6!_m5LAXNts&RmOvym z0cn99tC?VSuQVis%S%rn_t2)hV7Aj;$tk>N#5oh6t`UpuEv~-4hov#bro9mBn|>~v z+^6wQCU*0l@LoU?YWdu(xU`gu%G=)Fe(-*Rw(|w#t?SGIu;mA<&4rB*AD{VOV=PFg z&e6%dxcwPzIlbJtTQt3LI=fGoHOo1XlLhR&t@rx+8+m6%rjpD|Pcyx2>gc$?8W8#m zW}t9gGl3@)9VUoj{E7^*n(?~bAVHQ@ePh6U&uz}s-J(&>HfQ!SN~4<%KpR?5Pvosk zOiq^K^bBV6H9zaSTp!v#mhPlZbAR->7ntf5?CI&g*KMu|s>9ar_Zr=U&fTr&jEtSQ zMx8t7`X@|9L8`y|@6kBx+9<322-r(kDJmG++V_p?Wkkq+Bu?Pv<@EzHzejCf=w?Ho zV3Z1j8dOSQWz9qx`Ui<fFDqs9gm=ZEoS4gl12gbCgH<0A5C1Y4B^en3O@)AZe%<Q_ z32v%c(2lO@ZQYo3&YHeS>j=x_$rZ!0$H)7+wX1HB<jG3?iF)a7a)HDnU<cW+yv~dw z^Dvg#B*!h>?DN8c%^dUFC>iAifT*X6eIMySO<?WAzi*ayhIh7n58TGHiPI+6+H3Xa zc4`(T+~aZgnTAbV5sg>mt1x#I%?x~XXL&Z9V&i6*2>Y*%4L2Vb7Z<BNK0(3F16^*$ zan{<4nY^k@q?^ULpSVzO#bH?kb*b*2!d!82v4T}hM+1eGY1rg<{>Sa*F4k_ZWdnD< zw&8A#3sXz6h1vY*;*XDw{o0n?8MM2Y-RnYQtWmldM{$#Z54+LAn7%X-Y_PFkg8V?Z zR~~MuM7Cr&-;}<iAvRVf-e22__BE*A0(P#E6jLoC8GvVy(O<(0d@3N5w9*jOiQT9G z=b*JGp+0K2v|dltSakB0E~{Jd%Wt~YZ5ZzHU^5LSmKx4I>a*;Kr_4I$Cnt@~($Th| zq1oow>Np|83<0t6@q_Nf*3A&xK}J)9#b71g$$4>D<sH|SxSlMUANVjJR$aAto-d%u zjrB6l3(q-;();~=D3)iN4wI^<Zl_i4{|z{wU`TTvuAlkfG!%C@*$srm1DJ1hToF4n zEeqqx>K0`qhAGA$ftO9*e6cJRAr9uR&aIbr1QGAGdS?4Es0`8przvnUWBULN{gk<K zus&9Yj;Lz1F4(VYMa#6{kji!h+AsnMi%di4h|hVZdsT15ZZ{nVLb)<Z;9MbEnNl1) zdC}+E;U;CK{h4XtsUEsNLy&k8yYAOA-lUgf34|t`SxSR>(tagS^qcSD!tiasEbmv^ z^BbJf2t5V_>bYiqjDW`A<-rq0dtn5ButBnv%(Ze6A)z-(E7>ch&)=R%GQ!4E_fFWb zBQgh*5p6O|3=G`86*6P>-vxt**n!@jK`ln^1<$>vZN-U&$=V+1eeqpBJK6uh@9oCt zrlt`#f%nd~eB|xjk0!N8?|e-9wj`AXn$nkzdAMC6g#I@Sh)2#VtOF0xrgEp<xmoq- zQuKkXWJx57;f6`~VN}#-5n<t^`4&It#6i>fuS89JpeZn7ZgMsKd_4r)u~K*<&g&h` zXr>z&a<ntRdnz<?*1E4hAH4A{9Y>SX#7ti=V8*3VpwCxRtlK~foMm9_KgXT!1Jp+m zzvi<YcXotX7h^%m*a0@TqxxjLZbpMcnc6<aC4BZ|GFDR0Iqi3U!2WMavd1t4iXj$d z1Y|;(#L}6(n(xR<NZc$6+$c14bCH!t=1L!1jJXDf>C7jv?UnF7n`5oD4!jxnDN9m= z+ppc<$g6W)1aphd7n*_MaURUR%Ge(#IroYM*acyHTKqg2Ju2E>JtUq}GI_L^Dp^dv zUEZoMmTD60Q8L)Ko#D2xlAoIJK$7Rf$Bz$u<~zdnC1;`f=RXtVbL%?Nux39TlN9Yo zR^9kAI}AS->n<sXO$<2ag_X2Ded6_EL+8+Gq&7)r|46fNpA!@aM|~J}%h!eC-oB{~ zJwI9XV^r8>>WAYKKlxm+?m|0VI#v~~(HZ548+F?F`dgECg`7bxA9s1?;>{fmqhgnk z-&<Gp#8Zs(zT`-hHd7+EQR$5z2x1BcJvt4tB&nNY*lK(>#>*CgVP56p;_~(<cTAA| zXsrt#J{5bOxv3pdV;NgF2)J~$mndP$u7qsl@62>P)!Ah;=<UX|{pSuO$e&G}xb1i; zqZQ*$tl>J$V*j20>m47>z(pWtoq`h6Qm`g^!au3xwmd&yO3^`wf&1;`@VLdq(p%A~ z-<n-zT64qE1SDksP7>M&+SSg|Wg$~h+wkb;8kV3QJAxGh5FWLZyT^OE`8U*|nfPHg zE;W>yiRZHa?3k?Ke`*wJrTm-ZM5gbtfXMJB_VjPFn{=sOo;g-m)>f)|VDsev0ThVb Az5oCK literal 0 HcmV?d00001 diff --git a/civicrm/bower_components/jstree/src/themes/default-dark/style.css b/civicrm/bower_components/jstree/src/themes/default-dark/style.css new file mode 100644 index 0000000000..3af003f2d5 --- /dev/null +++ b/civicrm/bower_components/jstree/src/themes/default-dark/style.css @@ -0,0 +1,1146 @@ +/* jsTree default dark theme */ +.jstree-node, +.jstree-children, +.jstree-container-ul { + display: block; + margin: 0; + padding: 0; + list-style-type: none; + list-style-image: none; +} +.jstree-node { + white-space: nowrap; +} +.jstree-anchor { + display: inline-block; + color: black; + white-space: nowrap; + padding: 0 4px 0 1px; + margin: 0; + vertical-align: top; +} +.jstree-anchor:focus { + outline: 0; +} +.jstree-anchor, +.jstree-anchor:link, +.jstree-anchor:visited, +.jstree-anchor:hover, +.jstree-anchor:active { + text-decoration: none; + color: inherit; +} +.jstree-icon { + display: inline-block; + text-decoration: none; + margin: 0; + padding: 0; + vertical-align: top; + text-align: center; +} +.jstree-icon:empty { + display: inline-block; + text-decoration: none; + margin: 0; + padding: 0; + vertical-align: top; + text-align: center; +} +.jstree-ocl { + cursor: pointer; +} +.jstree-leaf > .jstree-ocl { + cursor: default; +} +.jstree .jstree-open > .jstree-children { + display: block; +} +.jstree .jstree-closed > .jstree-children, +.jstree .jstree-leaf > .jstree-children { + display: none; +} +.jstree-anchor > .jstree-themeicon { + margin-right: 2px; +} +.jstree-no-icons .jstree-themeicon, +.jstree-anchor > .jstree-themeicon-hidden { + display: none; +} +.jstree-hidden, +.jstree-node.jstree-hidden { + display: none; +} +.jstree-rtl .jstree-anchor { + padding: 0 1px 0 4px; +} +.jstree-rtl .jstree-anchor > .jstree-themeicon { + margin-left: 2px; + margin-right: 0; +} +.jstree-rtl .jstree-node { + margin-left: 0; +} +.jstree-rtl .jstree-container-ul > .jstree-node { + margin-right: 0; +} +.jstree-wholerow-ul { + position: relative; + display: inline-block; + min-width: 100%; +} +.jstree-wholerow-ul .jstree-leaf > .jstree-ocl { + cursor: pointer; +} +.jstree-wholerow-ul .jstree-anchor, +.jstree-wholerow-ul .jstree-icon { + position: relative; +} +.jstree-wholerow-ul .jstree-wholerow { + width: 100%; + cursor: pointer; + position: absolute; + left: 0; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +.vakata-context { + display: none; +} +.vakata-context, +.vakata-context ul { + margin: 0; + padding: 2px; + position: absolute; + background: #f5f5f5; + border: 1px solid #979797; + box-shadow: 2px 2px 2px #999999; +} +.vakata-context ul { + list-style: none; + left: 100%; + margin-top: -2.7em; + margin-left: -4px; +} +.vakata-context .vakata-context-right ul { + left: auto; + right: 100%; + margin-left: auto; + margin-right: -4px; +} +.vakata-context li { + list-style: none; +} +.vakata-context li > a { + display: block; + padding: 0 2em 0 2em; + text-decoration: none; + width: auto; + color: black; + white-space: nowrap; + line-height: 2.4em; + text-shadow: 1px 1px 0 white; + border-radius: 1px; +} +.vakata-context li > a:hover { + position: relative; + background-color: #e8eff7; + box-shadow: 0 0 2px #0a6aa1; +} +.vakata-context li > a.vakata-context-parent { + background-image: url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAIORI4JlrqN1oMSnmmZDQUAOw=="); + background-position: right center; + background-repeat: no-repeat; +} +.vakata-context li > a:focus { + outline: 0; +} +.vakata-context .vakata-context-hover > a { + position: relative; + background-color: #e8eff7; + box-shadow: 0 0 2px #0a6aa1; +} +.vakata-context .vakata-context-separator > a, +.vakata-context .vakata-context-separator > a:hover { + background: white; + border: 0; + border-top: 1px solid #e2e3e3; + height: 1px; + min-height: 1px; + max-height: 1px; + padding: 0; + margin: 0 0 0 2.4em; + border-left: 1px solid #e0e0e0; + text-shadow: 0 0 0 transparent; + box-shadow: 0 0 0 transparent; + border-radius: 0; +} +.vakata-context .vakata-contextmenu-disabled a, +.vakata-context .vakata-contextmenu-disabled a:hover { + color: silver; + background-color: transparent; + border: 0; + box-shadow: 0 0 0; +} +.vakata-context li > a > i { + text-decoration: none; + display: inline-block; + width: 2.4em; + height: 2.4em; + background: transparent; + margin: 0 0 0 -2em; + vertical-align: top; + text-align: center; + line-height: 2.4em; +} +.vakata-context li > a > i:empty { + width: 2.4em; + line-height: 2.4em; +} +.vakata-context li > a .vakata-contextmenu-sep { + display: inline-block; + width: 1px; + height: 2.4em; + background: white; + margin: 0 0.5em 0 0; + border-left: 1px solid #e2e3e3; +} +.vakata-context .vakata-contextmenu-shortcut { + font-size: 0.8em; + color: silver; + opacity: 0.5; + display: none; +} +.vakata-context-rtl ul { + left: auto; + right: 100%; + margin-left: auto; + margin-right: -4px; +} +.vakata-context-rtl li > a.vakata-context-parent { + background-image: url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAINjI+AC7rWHIsPtmoxLAA7"); + background-position: left center; + background-repeat: no-repeat; +} +.vakata-context-rtl .vakata-context-separator > a { + margin: 0 2.4em 0 0; + border-left: 0; + border-right: 1px solid #e2e3e3; +} +.vakata-context-rtl .vakata-context-left ul { + right: auto; + left: 100%; + margin-left: -4px; + margin-right: auto; +} +.vakata-context-rtl li > a > i { + margin: 0 -2em 0 0; +} +.vakata-context-rtl li > a .vakata-contextmenu-sep { + margin: 0 0 0 0.5em; + border-left-color: white; + background: #e2e3e3; +} +#jstree-marker { + position: absolute; + top: 0; + left: 0; + margin: -5px 0 0 0; + padding: 0; + border-right: 0; + border-top: 5px solid transparent; + border-bottom: 5px solid transparent; + border-left: 5px solid; + width: 0; + height: 0; + font-size: 0; + line-height: 0; +} +#jstree-dnd { + line-height: 16px; + margin: 0; + padding: 4px; +} +#jstree-dnd .jstree-icon, +#jstree-dnd .jstree-copy { + display: inline-block; + text-decoration: none; + margin: 0 2px 0 0; + padding: 0; + width: 16px; + height: 16px; +} +#jstree-dnd .jstree-ok { + background: green; +} +#jstree-dnd .jstree-er { + background: red; +} +#jstree-dnd .jstree-copy { + margin: 0 2px 0 2px; +} +.jstree-default-dark .jstree-node, +.jstree-default-dark .jstree-icon { + background-repeat: no-repeat; + background-color: transparent; +} +.jstree-default-dark .jstree-anchor, +.jstree-default-dark .jstree-animated, +.jstree-default-dark .jstree-wholerow { + transition: background-color 0.15s, box-shadow 0.15s; +} +.jstree-default-dark .jstree-hovered { + background: #555555; + border-radius: 2px; + box-shadow: inset 0 0 1px #555555; +} +.jstree-default-dark .jstree-context { + background: #555555; + border-radius: 2px; + box-shadow: inset 0 0 1px #555555; +} +.jstree-default-dark .jstree-clicked { + background: #5fa2db; + border-radius: 2px; + box-shadow: inset 0 0 1px #666666; +} +.jstree-default-dark .jstree-no-icons .jstree-anchor > .jstree-themeicon { + display: none; +} +.jstree-default-dark .jstree-disabled { + background: transparent; + color: #666666; +} +.jstree-default-dark .jstree-disabled.jstree-hovered { + background: transparent; + box-shadow: none; +} +.jstree-default-dark .jstree-disabled.jstree-clicked { + background: #333333; +} +.jstree-default-dark .jstree-disabled > .jstree-icon { + opacity: 0.8; + filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'jstree-grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#jstree-grayscale"); + /* Firefox 10+ */ + filter: gray; + /* IE6-9 */ + -webkit-filter: grayscale(100%); + /* Chrome 19+ & Safari 6+ */ +} +.jstree-default-dark .jstree-search { + font-style: italic; + color: #ffffff; + font-weight: bold; +} +.jstree-default-dark .jstree-no-checkboxes .jstree-checkbox { + display: none !important; +} +.jstree-default-dark.jstree-checkbox-no-clicked .jstree-clicked { + background: transparent; + box-shadow: none; +} +.jstree-default-dark.jstree-checkbox-no-clicked .jstree-clicked.jstree-hovered { + background: #555555; +} +.jstree-default-dark.jstree-checkbox-no-clicked > .jstree-wholerow-ul .jstree-wholerow-clicked { + background: transparent; +} +.jstree-default-dark.jstree-checkbox-no-clicked > .jstree-wholerow-ul .jstree-wholerow-clicked.jstree-wholerow-hovered { + background: #555555; +} +.jstree-default-dark > .jstree-striped { + min-width: 100%; + display: inline-block; + background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAMAAAB/qqA+AAAABlBMVEUAAAAAAAClZ7nPAAAAAnRSTlMNAMM9s3UAAAAXSURBVHjajcEBAQAAAIKg/H/aCQZ70AUBjAATb6YPDgAAAABJRU5ErkJggg==") left top repeat; +} +.jstree-default-dark > .jstree-wholerow-ul .jstree-hovered, +.jstree-default-dark > .jstree-wholerow-ul .jstree-clicked { + background: transparent; + box-shadow: none; + border-radius: 0; +} +.jstree-default-dark .jstree-wholerow { + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} +.jstree-default-dark .jstree-wholerow-hovered { + background: #555555; +} +.jstree-default-dark .jstree-wholerow-clicked { + background: #5fa2db; + background: -webkit-linear-gradient(top, #5fa2db 0%, #5fa2db 100%); + background: linear-gradient(to bottom, #5fa2db 0%, #5fa2db 100%); +} +.jstree-default-dark .jstree-node { + min-height: 24px; + line-height: 24px; + margin-left: 24px; + min-width: 24px; +} +.jstree-default-dark .jstree-anchor { + line-height: 24px; + height: 24px; +} +.jstree-default-dark .jstree-icon { + width: 24px; + height: 24px; + line-height: 24px; +} +.jstree-default-dark .jstree-icon:empty { + width: 24px; + height: 24px; + line-height: 24px; +} +.jstree-default-dark.jstree-rtl .jstree-node { + margin-right: 24px; +} +.jstree-default-dark .jstree-wholerow { + height: 24px; +} +.jstree-default-dark .jstree-node, +.jstree-default-dark .jstree-icon { + background-image: url("32px.png"); +} +.jstree-default-dark .jstree-node { + background-position: -292px -4px; + background-repeat: repeat-y; +} +.jstree-default-dark .jstree-last { + background: transparent; +} +.jstree-default-dark .jstree-open > .jstree-ocl { + background-position: -132px -4px; +} +.jstree-default-dark .jstree-closed > .jstree-ocl { + background-position: -100px -4px; +} +.jstree-default-dark .jstree-leaf > .jstree-ocl { + background-position: -68px -4px; +} +.jstree-default-dark .jstree-themeicon { + background-position: -260px -4px; +} +.jstree-default-dark > .jstree-no-dots .jstree-node, +.jstree-default-dark > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-dark > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -36px -4px; +} +.jstree-default-dark > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: -4px -4px; +} +.jstree-default-dark .jstree-disabled { + background: transparent; +} +.jstree-default-dark .jstree-disabled.jstree-hovered { + background: transparent; +} +.jstree-default-dark .jstree-disabled.jstree-clicked { + background: #efefef; +} +.jstree-default-dark .jstree-checkbox { + background-position: -164px -4px; +} +.jstree-default-dark .jstree-checkbox:hover { + background-position: -164px -36px; +} +.jstree-default-dark.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, +.jstree-default-dark .jstree-checked > .jstree-checkbox { + background-position: -228px -4px; +} +.jstree-default-dark.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, +.jstree-default-dark .jstree-checked > .jstree-checkbox:hover { + background-position: -228px -36px; +} +.jstree-default-dark .jstree-anchor > .jstree-undetermined { + background-position: -196px -4px; +} +.jstree-default-dark .jstree-anchor > .jstree-undetermined:hover { + background-position: -196px -36px; +} +.jstree-default-dark .jstree-checkbox-disabled { + opacity: 0.8; + filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'jstree-grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#jstree-grayscale"); + /* Firefox 10+ */ + filter: gray; + /* IE6-9 */ + -webkit-filter: grayscale(100%); + /* Chrome 19+ & Safari 6+ */ +} +.jstree-default-dark > .jstree-striped { + background-size: auto 48px; +} +.jstree-default-dark.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); + background-position: 100% 1px; + background-repeat: repeat-y; +} +.jstree-default-dark.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-dark.jstree-rtl .jstree-open > .jstree-ocl { + background-position: -132px -36px; +} +.jstree-default-dark.jstree-rtl .jstree-closed > .jstree-ocl { + background-position: -100px -36px; +} +.jstree-default-dark.jstree-rtl .jstree-leaf > .jstree-ocl { + background-position: -68px -36px; +} +.jstree-default-dark.jstree-rtl > .jstree-no-dots .jstree-node, +.jstree-default-dark.jstree-rtl > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-dark.jstree-rtl > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -36px -36px; +} +.jstree-default-dark.jstree-rtl > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: -4px -36px; +} +.jstree-default-dark .jstree-themeicon-custom { + background-color: transparent; + background-image: none; + background-position: 0 0; +} +.jstree-default-dark > .jstree-container-ul .jstree-loading > .jstree-ocl { + background: url("throbber.gif") center center no-repeat; +} +.jstree-default-dark .jstree-file { + background: url("32px.png") -100px -68px no-repeat; +} +.jstree-default-dark .jstree-folder { + background: url("32px.png") -260px -4px no-repeat; +} +.jstree-default-dark > .jstree-container-ul > .jstree-node { + margin-left: 0; + margin-right: 0; +} +#jstree-dnd.jstree-default-dark { + line-height: 24px; + padding: 0 4px; +} +#jstree-dnd.jstree-default-dark .jstree-ok, +#jstree-dnd.jstree-default-dark .jstree-er { + background-image: url("32px.png"); + background-repeat: no-repeat; + background-color: transparent; +} +#jstree-dnd.jstree-default-dark i { + background: transparent; + width: 24px; + height: 24px; + line-height: 24px; +} +#jstree-dnd.jstree-default-dark .jstree-ok { + background-position: -4px -68px; +} +#jstree-dnd.jstree-default-dark .jstree-er { + background-position: -36px -68px; +} +.jstree-default-dark .jstree-ellipsis { + overflow: hidden; +} +.jstree-default-dark .jstree-ellipsis .jstree-anchor { + width: calc(100% - 29px); + text-overflow: ellipsis; + overflow: hidden; +} +.jstree-default-dark .jstree-ellipsis.jstree-no-icons .jstree-anchor { + width: calc(100% - 5px); +} +.jstree-default-dark.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); +} +.jstree-default-dark.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-dark-small .jstree-node { + min-height: 18px; + line-height: 18px; + margin-left: 18px; + min-width: 18px; +} +.jstree-default-dark-small .jstree-anchor { + line-height: 18px; + height: 18px; +} +.jstree-default-dark-small .jstree-icon { + width: 18px; + height: 18px; + line-height: 18px; +} +.jstree-default-dark-small .jstree-icon:empty { + width: 18px; + height: 18px; + line-height: 18px; +} +.jstree-default-dark-small.jstree-rtl .jstree-node { + margin-right: 18px; +} +.jstree-default-dark-small .jstree-wholerow { + height: 18px; +} +.jstree-default-dark-small .jstree-node, +.jstree-default-dark-small .jstree-icon { + background-image: url("32px.png"); +} +.jstree-default-dark-small .jstree-node { + background-position: -295px -7px; + background-repeat: repeat-y; +} +.jstree-default-dark-small .jstree-last { + background: transparent; +} +.jstree-default-dark-small .jstree-open > .jstree-ocl { + background-position: -135px -7px; +} +.jstree-default-dark-small .jstree-closed > .jstree-ocl { + background-position: -103px -7px; +} +.jstree-default-dark-small .jstree-leaf > .jstree-ocl { + background-position: -71px -7px; +} +.jstree-default-dark-small .jstree-themeicon { + background-position: -263px -7px; +} +.jstree-default-dark-small > .jstree-no-dots .jstree-node, +.jstree-default-dark-small > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-dark-small > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -39px -7px; +} +.jstree-default-dark-small > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: -7px -7px; +} +.jstree-default-dark-small .jstree-disabled { + background: transparent; +} +.jstree-default-dark-small .jstree-disabled.jstree-hovered { + background: transparent; +} +.jstree-default-dark-small .jstree-disabled.jstree-clicked { + background: #efefef; +} +.jstree-default-dark-small .jstree-checkbox { + background-position: -167px -7px; +} +.jstree-default-dark-small .jstree-checkbox:hover { + background-position: -167px -39px; +} +.jstree-default-dark-small.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, +.jstree-default-dark-small .jstree-checked > .jstree-checkbox { + background-position: -231px -7px; +} +.jstree-default-dark-small.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, +.jstree-default-dark-small .jstree-checked > .jstree-checkbox:hover { + background-position: -231px -39px; +} +.jstree-default-dark-small .jstree-anchor > .jstree-undetermined { + background-position: -199px -7px; +} +.jstree-default-dark-small .jstree-anchor > .jstree-undetermined:hover { + background-position: -199px -39px; +} +.jstree-default-dark-small .jstree-checkbox-disabled { + opacity: 0.8; + filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'jstree-grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#jstree-grayscale"); + /* Firefox 10+ */ + filter: gray; + /* IE6-9 */ + -webkit-filter: grayscale(100%); + /* Chrome 19+ & Safari 6+ */ +} +.jstree-default-dark-small > .jstree-striped { + background-size: auto 36px; +} +.jstree-default-dark-small.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); + background-position: 100% 1px; + background-repeat: repeat-y; +} +.jstree-default-dark-small.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-dark-small.jstree-rtl .jstree-open > .jstree-ocl { + background-position: -135px -39px; +} +.jstree-default-dark-small.jstree-rtl .jstree-closed > .jstree-ocl { + background-position: -103px -39px; +} +.jstree-default-dark-small.jstree-rtl .jstree-leaf > .jstree-ocl { + background-position: -71px -39px; +} +.jstree-default-dark-small.jstree-rtl > .jstree-no-dots .jstree-node, +.jstree-default-dark-small.jstree-rtl > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-dark-small.jstree-rtl > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -39px -39px; +} +.jstree-default-dark-small.jstree-rtl > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: -7px -39px; +} +.jstree-default-dark-small .jstree-themeicon-custom { + background-color: transparent; + background-image: none; + background-position: 0 0; +} +.jstree-default-dark-small > .jstree-container-ul .jstree-loading > .jstree-ocl { + background: url("throbber.gif") center center no-repeat; +} +.jstree-default-dark-small .jstree-file { + background: url("32px.png") -103px -71px no-repeat; +} +.jstree-default-dark-small .jstree-folder { + background: url("32px.png") -263px -7px no-repeat; +} +.jstree-default-dark-small > .jstree-container-ul > .jstree-node { + margin-left: 0; + margin-right: 0; +} +#jstree-dnd.jstree-default-dark-small { + line-height: 18px; + padding: 0 4px; +} +#jstree-dnd.jstree-default-dark-small .jstree-ok, +#jstree-dnd.jstree-default-dark-small .jstree-er { + background-image: url("32px.png"); + background-repeat: no-repeat; + background-color: transparent; +} +#jstree-dnd.jstree-default-dark-small i { + background: transparent; + width: 18px; + height: 18px; + line-height: 18px; +} +#jstree-dnd.jstree-default-dark-small .jstree-ok { + background-position: -7px -71px; +} +#jstree-dnd.jstree-default-dark-small .jstree-er { + background-position: -39px -71px; +} +.jstree-default-dark-small .jstree-ellipsis { + overflow: hidden; +} +.jstree-default-dark-small .jstree-ellipsis .jstree-anchor { + width: calc(100% - 23px); + text-overflow: ellipsis; + overflow: hidden; +} +.jstree-default-dark-small .jstree-ellipsis.jstree-no-icons .jstree-anchor { + width: calc(100% - 5px); +} +.jstree-default-dark-small.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg=="); +} +.jstree-default-dark-small.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-dark-large .jstree-node { + min-height: 32px; + line-height: 32px; + margin-left: 32px; + min-width: 32px; +} +.jstree-default-dark-large .jstree-anchor { + line-height: 32px; + height: 32px; +} +.jstree-default-dark-large .jstree-icon { + width: 32px; + height: 32px; + line-height: 32px; +} +.jstree-default-dark-large .jstree-icon:empty { + width: 32px; + height: 32px; + line-height: 32px; +} +.jstree-default-dark-large.jstree-rtl .jstree-node { + margin-right: 32px; +} +.jstree-default-dark-large .jstree-wholerow { + height: 32px; +} +.jstree-default-dark-large .jstree-node, +.jstree-default-dark-large .jstree-icon { + background-image: url("32px.png"); +} +.jstree-default-dark-large .jstree-node { + background-position: -288px 0px; + background-repeat: repeat-y; +} +.jstree-default-dark-large .jstree-last { + background: transparent; +} +.jstree-default-dark-large .jstree-open > .jstree-ocl { + background-position: -128px 0px; +} +.jstree-default-dark-large .jstree-closed > .jstree-ocl { + background-position: -96px 0px; +} +.jstree-default-dark-large .jstree-leaf > .jstree-ocl { + background-position: -64px 0px; +} +.jstree-default-dark-large .jstree-themeicon { + background-position: -256px 0px; +} +.jstree-default-dark-large > .jstree-no-dots .jstree-node, +.jstree-default-dark-large > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-dark-large > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -32px 0px; +} +.jstree-default-dark-large > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: 0px 0px; +} +.jstree-default-dark-large .jstree-disabled { + background: transparent; +} +.jstree-default-dark-large .jstree-disabled.jstree-hovered { + background: transparent; +} +.jstree-default-dark-large .jstree-disabled.jstree-clicked { + background: #efefef; +} +.jstree-default-dark-large .jstree-checkbox { + background-position: -160px 0px; +} +.jstree-default-dark-large .jstree-checkbox:hover { + background-position: -160px -32px; +} +.jstree-default-dark-large.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, +.jstree-default-dark-large .jstree-checked > .jstree-checkbox { + background-position: -224px 0px; +} +.jstree-default-dark-large.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, +.jstree-default-dark-large .jstree-checked > .jstree-checkbox:hover { + background-position: -224px -32px; +} +.jstree-default-dark-large .jstree-anchor > .jstree-undetermined { + background-position: -192px 0px; +} +.jstree-default-dark-large .jstree-anchor > .jstree-undetermined:hover { + background-position: -192px -32px; +} +.jstree-default-dark-large .jstree-checkbox-disabled { + opacity: 0.8; + filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'jstree-grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#jstree-grayscale"); + /* Firefox 10+ */ + filter: gray; + /* IE6-9 */ + -webkit-filter: grayscale(100%); + /* Chrome 19+ & Safari 6+ */ +} +.jstree-default-dark-large > .jstree-striped { + background-size: auto 64px; +} +.jstree-default-dark-large.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); + background-position: 100% 1px; + background-repeat: repeat-y; +} +.jstree-default-dark-large.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-dark-large.jstree-rtl .jstree-open > .jstree-ocl { + background-position: -128px -32px; +} +.jstree-default-dark-large.jstree-rtl .jstree-closed > .jstree-ocl { + background-position: -96px -32px; +} +.jstree-default-dark-large.jstree-rtl .jstree-leaf > .jstree-ocl { + background-position: -64px -32px; +} +.jstree-default-dark-large.jstree-rtl > .jstree-no-dots .jstree-node, +.jstree-default-dark-large.jstree-rtl > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-dark-large.jstree-rtl > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -32px -32px; +} +.jstree-default-dark-large.jstree-rtl > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: 0px -32px; +} +.jstree-default-dark-large .jstree-themeicon-custom { + background-color: transparent; + background-image: none; + background-position: 0 0; +} +.jstree-default-dark-large > .jstree-container-ul .jstree-loading > .jstree-ocl { + background: url("throbber.gif") center center no-repeat; +} +.jstree-default-dark-large .jstree-file { + background: url("32px.png") -96px -64px no-repeat; +} +.jstree-default-dark-large .jstree-folder { + background: url("32px.png") -256px 0px no-repeat; +} +.jstree-default-dark-large > .jstree-container-ul > .jstree-node { + margin-left: 0; + margin-right: 0; +} +#jstree-dnd.jstree-default-dark-large { + line-height: 32px; + padding: 0 4px; +} +#jstree-dnd.jstree-default-dark-large .jstree-ok, +#jstree-dnd.jstree-default-dark-large .jstree-er { + background-image: url("32px.png"); + background-repeat: no-repeat; + background-color: transparent; +} +#jstree-dnd.jstree-default-dark-large i { + background: transparent; + width: 32px; + height: 32px; + line-height: 32px; +} +#jstree-dnd.jstree-default-dark-large .jstree-ok { + background-position: 0px -64px; +} +#jstree-dnd.jstree-default-dark-large .jstree-er { + background-position: -32px -64px; +} +.jstree-default-dark-large .jstree-ellipsis { + overflow: hidden; +} +.jstree-default-dark-large .jstree-ellipsis .jstree-anchor { + width: calc(100% - 37px); + text-overflow: ellipsis; + overflow: hidden; +} +.jstree-default-dark-large .jstree-ellipsis.jstree-no-icons .jstree-anchor { + width: calc(100% - 5px); +} +.jstree-default-dark-large.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg=="); +} +.jstree-default-dark-large.jstree-rtl .jstree-last { + background: transparent; +} +@media (max-width: 768px) { + #jstree-dnd.jstree-dnd-responsive { + line-height: 40px; + font-weight: bold; + font-size: 1.1em; + text-shadow: 1px 1px white; + } + #jstree-dnd.jstree-dnd-responsive > i { + background: transparent; + width: 40px; + height: 40px; + } + #jstree-dnd.jstree-dnd-responsive > .jstree-ok { + background-image: url("40px.png"); + background-position: 0 -200px; + background-size: 120px 240px; + } + #jstree-dnd.jstree-dnd-responsive > .jstree-er { + background-image: url("40px.png"); + background-position: -40px -200px; + background-size: 120px 240px; + } + #jstree-marker.jstree-dnd-responsive { + border-left-width: 10px; + border-top-width: 10px; + border-bottom-width: 10px; + margin-top: -10px; + } +} +@media (max-width: 768px) { + .jstree-default-dark-responsive { + /* + .jstree-open > .jstree-ocl, + .jstree-closed > .jstree-ocl { border-radius:20px; background-color:white; } + */ + } + .jstree-default-dark-responsive .jstree-icon { + background-image: url("40px.png"); + } + .jstree-default-dark-responsive .jstree-node, + .jstree-default-dark-responsive .jstree-leaf > .jstree-ocl { + background: transparent; + } + .jstree-default-dark-responsive .jstree-node { + min-height: 40px; + line-height: 40px; + margin-left: 40px; + min-width: 40px; + white-space: nowrap; + } + .jstree-default-dark-responsive .jstree-anchor { + line-height: 40px; + height: 40px; + } + .jstree-default-dark-responsive .jstree-icon, + .jstree-default-dark-responsive .jstree-icon:empty { + width: 40px; + height: 40px; + line-height: 40px; + } + .jstree-default-dark-responsive > .jstree-container-ul > .jstree-node { + margin-left: 0; + } + .jstree-default-dark-responsive.jstree-rtl .jstree-node { + margin-left: 0; + margin-right: 40px; + background: transparent; + } + .jstree-default-dark-responsive.jstree-rtl .jstree-container-ul > .jstree-node { + margin-right: 0; + } + .jstree-default-dark-responsive .jstree-ocl, + .jstree-default-dark-responsive .jstree-themeicon, + .jstree-default-dark-responsive .jstree-checkbox { + background-size: 120px 240px; + } + .jstree-default-dark-responsive .jstree-leaf > .jstree-ocl, + .jstree-default-dark-responsive.jstree-rtl .jstree-leaf > .jstree-ocl { + background: transparent; + } + .jstree-default-dark-responsive .jstree-open > .jstree-ocl { + background-position: 0 0px !important; + } + .jstree-default-dark-responsive .jstree-closed > .jstree-ocl { + background-position: 0 -40px !important; + } + .jstree-default-dark-responsive.jstree-rtl .jstree-closed > .jstree-ocl { + background-position: -40px 0px !important; + } + .jstree-default-dark-responsive .jstree-themeicon { + background-position: -40px -40px; + } + .jstree-default-dark-responsive .jstree-checkbox, + .jstree-default-dark-responsive .jstree-checkbox:hover { + background-position: -40px -80px; + } + .jstree-default-dark-responsive.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, + .jstree-default-dark-responsive.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, + .jstree-default-dark-responsive .jstree-checked > .jstree-checkbox, + .jstree-default-dark-responsive .jstree-checked > .jstree-checkbox:hover { + background-position: 0 -80px; + } + .jstree-default-dark-responsive .jstree-anchor > .jstree-undetermined, + .jstree-default-dark-responsive .jstree-anchor > .jstree-undetermined:hover { + background-position: 0 -120px; + } + .jstree-default-dark-responsive .jstree-anchor { + font-weight: bold; + font-size: 1.1em; + text-shadow: 1px 1px white; + } + .jstree-default-dark-responsive > .jstree-striped { + background: transparent; + } + .jstree-default-dark-responsive .jstree-wholerow { + border-top: 1px solid #666666; + border-bottom: 1px solid #000000; + background: #333333; + height: 40px; + } + .jstree-default-dark-responsive .jstree-wholerow-hovered { + background: #555555; + } + .jstree-default-dark-responsive .jstree-wholerow-clicked { + background: #5fa2db; + } + .jstree-default-dark-responsive .jstree-children .jstree-last > .jstree-wholerow { + box-shadow: inset 0 -6px 3px -5px #111111; + } + .jstree-default-dark-responsive .jstree-children .jstree-open > .jstree-wholerow { + box-shadow: inset 0 6px 3px -5px #111111; + border-top: 0; + } + .jstree-default-dark-responsive .jstree-children .jstree-open + .jstree-open { + box-shadow: none; + } + .jstree-default-dark-responsive .jstree-node, + .jstree-default-dark-responsive .jstree-icon, + .jstree-default-dark-responsive .jstree-node > .jstree-ocl, + .jstree-default-dark-responsive .jstree-themeicon, + .jstree-default-dark-responsive .jstree-checkbox { + background-image: url("40px.png"); + background-size: 120px 240px; + } + .jstree-default-dark-responsive .jstree-node { + background-position: -80px 0; + background-repeat: repeat-y; + } + .jstree-default-dark-responsive .jstree-last { + background: transparent; + } + .jstree-default-dark-responsive .jstree-leaf > .jstree-ocl { + background-position: -40px -120px; + } + .jstree-default-dark-responsive .jstree-last > .jstree-ocl { + background-position: -40px -160px; + } + .jstree-default-dark-responsive .jstree-themeicon-custom { + background-color: transparent; + background-image: none; + background-position: 0 0; + } + .jstree-default-dark-responsive .jstree-file { + background: url("40px.png") 0 -160px no-repeat; + background-size: 120px 240px; + } + .jstree-default-dark-responsive .jstree-folder { + background: url("40px.png") -40px -40px no-repeat; + background-size: 120px 240px; + } + .jstree-default-dark-responsive > .jstree-container-ul > .jstree-node { + margin-left: 0; + margin-right: 0; + } +} +.jstree-default-dark { + background: #333; +} +.jstree-default-dark .jstree-anchor { + color: #999; + text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.5); +} +.jstree-default-dark .jstree-clicked, +.jstree-default-dark .jstree-checked { + color: white; +} +.jstree-default-dark .jstree-hovered { + color: white; +} +#jstree-marker.jstree-default-dark { + border-left-color: #999; + background: transparent; +} +.jstree-default-dark .jstree-anchor > .jstree-icon { + opacity: 0.75; +} +.jstree-default-dark .jstree-clicked > .jstree-icon, +.jstree-default-dark .jstree-hovered > .jstree-icon, +.jstree-default-dark .jstree-checked > .jstree-icon { + opacity: 1; +} +.jstree-default-dark.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAACZmZl+9SADAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); +} +.jstree-default-dark.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-dark-small.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAACZmZl+9SADAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg=="); +} +.jstree-default-dark-small.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-dark-large.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAACZmZl+9SADAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg=="); +} +.jstree-default-dark-large.jstree-rtl .jstree-last { + background: transparent; +} diff --git a/civicrm/bower_components/jstree/src/themes/default-dark/style.less b/civicrm/bower_components/jstree/src/themes/default-dark/style.less new file mode 100644 index 0000000000..6cab4e672e --- /dev/null +++ b/civicrm/bower_components/jstree/src/themes/default-dark/style.less @@ -0,0 +1,50 @@ +/* jsTree default dark theme */ +@theme-name: default-dark; +@hovered-bg-color: #555; +@hovered-shadow-color: #555; +@disabled-color: #666666; +@disabled-bg-color: #333333; +@clicked-bg-color: #5fa2db; +@clicked-shadow-color: #666666; +@clicked-gradient-color-1: #5fa2db; +@clicked-gradient-color-2: #5fa2db; +@search-result-color: #ffffff; +@mobile-wholerow-bg-color: #333333; +@mobile-wholerow-shadow: #111111; +@mobile-wholerow-bordert: #666; +@mobile-wholerow-borderb: #000; +@responsive: true; +@image-path: ""; +@base-height: 40px; + +@import "../mixins.less"; +@import "../base.less"; +@import "../main.less"; + +.jstree-@{theme-name} { + background:#333; + .jstree-anchor { color:#999; text-shadow:1px 1px 0 rgba(0,0,0,0.5); } + .jstree-clicked, .jstree-checked { color:white; } + .jstree-hovered { color:white; } + #jstree-marker& { + border-left-color:#999; + background:transparent; + } + .jstree-anchor > .jstree-icon { opacity:0.75; } + .jstree-clicked > .jstree-icon, + .jstree-hovered > .jstree-icon, + .jstree-checked > .jstree-icon { opacity:1; } +} +// theme variants +.jstree-@{theme-name} { + &.jstree-rtl .jstree-node { background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAACZmZl+9SADAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); } + &.jstree-rtl .jstree-last { background:transparent; } +} +.jstree-@{theme-name}-small { + &.jstree-rtl .jstree-node { background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAACZmZl+9SADAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg=="); } + &.jstree-rtl .jstree-last { background:transparent; } +} +.jstree-@{theme-name}-large { + &.jstree-rtl .jstree-node { background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAACZmZl+9SADAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg=="); } + &.jstree-rtl .jstree-last { background:transparent; } +} \ No newline at end of file diff --git a/civicrm/bower_components/jstree/src/themes/default-dark/throbber.gif b/civicrm/bower_components/jstree/src/themes/default-dark/throbber.gif new file mode 100644 index 0000000000000000000000000000000000000000..2e310e8be219965cda00a2e1e9f3077838152c73 GIT binary patch literal 1849 zcmb8wdr(tX9tZI2z31lM+(&YVNJFGf2tkvOm_Q%|vGyi_Ah2wp3Y14l#IS@y4OAp; z5y=A~$Wy6`)ru`G2-*TZrrRxukr{0}wleGNPItF6+F^IJb-S=_r#jPD!XN!B{iDA> z&zv*oGvD9&&B@-e-I!*B2t>X`5WQYMF)@*rmR4I^%W<6F?{_+#!Ik#*_7f*gl$MrS zES8ax5v$cYHa6DZ-|up{kl$0WKhp(SJD<rgS+bHg>##M!v#~!(GMenRefB-l7RSC? zsjbfDs^4qdv)S=N&0Zw-G2m0dUFy&+AtZvgNTn#skNx*JnrS9)m<A?uV*Gb+2F{Bv zUb9VMZ)bV}@IRdNxhs*T2c?e&ETi1Yd$L_#&&9$x{wMd$?uzs?x9IDM6Cy^8@BMU3 zl3cPM;{YXZRqKI}rdZ&qibF{r!tMd>DS)RxE~8&ep=o<;ILrQ!#lhLr`Z7)AhbGuF z)4i}VFNn}iMq8b=a&d2lEuNF&JvSaWbIy_EX*lJY-Hy5g&CmEFp?8fdt^;QQ2yDLk zx$n@kku`l0ARn!gVL0Wa^k#2~8$dvJRkr5y*b2juS6W{_X*``;o*I_o3Q;~|f)tQR zX35C@nQotVKB-AP`NT-0Wg)T?ZAT)-b(aFxWh3MfUx@-7B#pbHaztvWYVix5So1c! z+_1ew{Pj}WY`$eQOP_#JP~kz%GL}cz^uE%iGM7|o{RdH&tCIUYZFx=ZR8v!U%xW&5 zB?mFSSTbit_OVLTzn;Eb*stZh(_I<?6uFbzA;7PnbHZdnPf^16A816xnfsTW7s#7q z)<uirn1S@(8#ygm-lhFP$|q@+8u*j|QzU3BW%YmT&>m8mo*z7Tw42Tw>gldDwHXW} zhOoKRueL}W%0))rSlJMybgrkF**OH${LQG#0V2<I`%?w!XPMg{MeOutJ-iKPquyEf zb>liHxj*{fY5VKUm%H}nB~_J_{r~fxV*jPYx<8cwJGZYnN2_hIKHcH3X^T7JKV}#@ z8W$GO76SZP9Rzq}q<2NKprQ_?GtQ!m@u+VqPRAQPX+0~Qmu$LTJ**gw!iI7=E@s2k zC$3!<MM|`Z*Bn?f><U<Ci!Vt005g9vR}6$~^8uf%njmmnfkVp>l?0<y_G$<c$+y=Z z<P&s*;{XB(w!vPW5SH{(h_nL+NdX!8hi?oEs=&A`HS5+fpPS28DDpSnaW>X*WgTPw z$L~i-8Q=fnxeEZ|E$7RWQs{HmV+yLj(|zYcA4xWT*Q{C_MG!?Bt9g)5SP7w0sbC0< zc=2FW?f~f8R#hP&HVLvDQpp~9c+KiSuWC@0`mj{7pqf+sU`{C)C5qR~NZ%@(`Rfi_ zZ7eVQ_=MdhetG6$uCB{|)i596id%P0;$S8D{VSObGad1A!L8T6a*7#>UqRs62<GDR z*#iid09paVphDuQ1d2#Js^MqZQqX#3c*|-s%2P|@uWvG)$~$-D-MjzjRljlNM*%qM z&#F+=drzI)n4Ti-y$e%Bnf`_7cHR9A7xf<7d7Vadc-_EdO^jgi$+Pp~A<%c->&!`x zgm^I@#<LELz=T4|SzaV-<)b|)DHx2ShEcxIfIG@ss#{dQ-KSNJI&Vnz_{su$cwBde zww+A>`{CPDYo0Z_cUzMmyfC_f4vd?3Bc9!VamCEx>gj8DBBJL8N2WiHn!B}jX;Hx! z5jSV2o|FQb<i%6lFoGp<nxT?ZfDoeHC{O56(R?kAZ-K)JatzxaUeg?UHLIHX@(KAp zY9<#pmcJQjWc0(<!tzIgl(p_hTcQQsuP%cfrLnsCCR3(S%w+7J9QZI2|5uKs#t|{M z<Uk6CK)=^y;hgJX29J%;L|6+C0%2jYfx&|q)=}+1Az4tTYhiuL@FVqWmo_tvbK{gc z8>QdLg-Da)-I&|~BSUs(EH9}dx;qb<FR6zmeH~wJ6mO+E+&!2687-=vW=h&L@Pk3? zqMFZi9{X-otbVu+Lm@AnVvR)wTh%ny0k<aZ6v9d#N}Z?%gU2_qjnB&|E~H5heMGDE E3$pnT2><{9 literal 0 HcmV?d00001 diff --git a/civicrm/bower_components/jstree/src/themes/default/32px.png b/civicrm/bower_components/jstree/src/themes/default/32px.png new file mode 100644 index 0000000000000000000000000000000000000000..ac74418d2843d0233fc67c04a59462caa82bd860 GIT binary patch literal 8740 zcma)gWl&vB(B|Qy7k3Cwkl-GIySqb>aDgBJf(Mt2y9L)k2myjau;6aN-Q6{~^WEgF zt=g*H+S(s8JvC?gOi#~DKTl7%nu;t2DhVn802uOeQW^jNCkAUnP>^7?tzt0)On@Ea z-Z}#S8s6Um2c%~b0|2V(2T4gaH7k1;duJ<q2P%0<Nh${?dy5aY<^bS6pQUN3rMX8a ze7$@jp%?~DRJ7M1K%vr*h=k(D(=$<nu@%CobLR-u+i|3&5lH)T!r)_Kpiu<sEa(xa zv&fs&Ut<FE!XgIl*Szv<rkk#}hn{L?M0QHfv#Ljs+fdMx<+#;fL(z*QC~#H-d%Jqp zHrd4dQE43jY?SKv)XtAIaKMePkP!3BHslrn&V2$61!z;wXyYIYea70CNHc_k2Enzt z#PcblK=A=F&lrjCfS3#%G%J-}6UadTAcJP68-N-s0D0xNJpn+oZqmHq0E0wo0=S%b zfC|q%ObW0P1WHD9BBTL54glXmv5Oy=Wd%6obuHw8iaMZe7#pn$KtTsM)Wd=q0R%4q z(nmw%4g{qE_%dg@LVuXcuy>eXo=U3{YM|wp_BTLbbwt+HWussimM3Dy=QRPDq>Hh2 zc%;4H^5?-?J^u{=Iq?Lr)t*1P4`Y@M5A(*<Vj8pVw<0~iG&S9L+8QZ#fNk8Gi|^PI z3wt#QR1gXJ@#!nwF@n`Qw46`Zkrq{0Vl_a{-n{O)!(ZP>=f*Y6&24RN&MI_C7?=#` z`aD^77`N#@+TQvKJzQU|wye|oa~b)|BHXNY{Jv1iCmZ<;4l-Tbj+K3=LwkN8pLp3N zZ`z>8gukJV>lh=I9(B%@|1w<SGh;X1`1AYq6_$H=k(Jj#g|!HrS3GN>ks17z;wx-D zm$vn5061&3Z=Ym9frnZJu8p`opNKxn=FkC93;EBE0Ps$VmQ8D*TC^7h0HkvKnJUCd zFWQM&+K|ZF5f|Ih9w59y60}_%64(-`@1bN)5XO=K35JlN3UVe0`=l5-Pn)_`NP+_< zTZeW%rmzFnoe4^IJ42H{7(u)b1<!<fJ`Bz@LXRc}g(xlfhPqu20XLGCsy_^0{iS03 zYdKDh2rVjYIr1}MClG(Aq0Fy%!9IX1;31?*mNU`6N?mvoy+*R3@C`|j%vZG0_b#02 zv4lApqfS3bgrj(KcSeh?u;yb$Bzrm9c8QU>yKFhwdO9U4`B=aSW`mV4OVEpZNGfzn z;2Xm)%|<HS5ODpa+rYdCZW2@`6ykDvN_r}@a)nf6v^+TT;5T6SAoY${FB1wCf71WL zx$Po0<>Cz0lVhQo#*M{e$My=7?0Q3s8!pN9sv!;}U-?aI9Cuu1+)jgLkEJMsM~;Lh zp@06pO%*bKA`2CBU+`wuX6GjNCg~>inE`5+shH!p8_jhFjR9+g7hBj{JX=WSsa)dP zdFdKUg}GWduVeKkN^@&9%GE;)@pwL^^A80Q$}8rVeodMnu_Cg%{!qT_@(X7vi9#i1 zRCj!EPj)wD7yiNx9V3Jwus6(-;Y9{9GO^_gH{$YCrSC5$B46}salGL?NZm=pO0(D2 zW2$BHCWs$EO;SjrPa<Vv*DCt){m1eTH0^WkL9N)LcbYzBGTPjl8%5yB<YMg~S!xHG zq?(pRf`y?!EDP<mM8EmIeGEr>+o{y4D)~)4r_y+%sfP;9>_xRZ3$+bKamXkC*Io3L zLv!A)OpU3J<c*QSKZ<hsCAk&2b*nYb6D>rMH&PvMGF?=_I}8OW=e`lk_$Q3(jHKUr zlo~kA4Q+lTrzGnY%N45^%N{iImK_yjeQ%a-e0%SYDc-B_%J7w}W$Z9w){f?!=28J_ z0im+6z-1ZR51V|_+(s$4R=a}Z)a;gb&}=39f@P29ojWog_D8M9k9P%^vgmq9)#$WH z3+ThdLfx+&?S;tMdl&wwOB!{GN#>g*nWU@*#W#!z<xR;%%V0%)=rP=&-T2t^u_uon ziJqEXQF&kaI9)@z;XC7ZK_x+@-l5+^Ux%jCUS|k%&T#Ey>}1SjtkgmD-St^&3v27m z<*PRJzrQ`MZL$m2=YN~8r>$>PEmN9RN;lnD+E{>7(4dl_Qk*?)*;(<Yw!gNh?nTAc zEYd<*?Z;Xl6H8Mf%ewBe&f|pU1fO3%(T~E&7@>2R#pL?rzRo|L@C9@PmeYqbk41gD zFOv7zE%ipQM`pP<YVigcyFO%TW=zOh5?MAl2cCyThARdPvZaWyWsvqP^)+uQxLi6K zt$B`LW@S`obQ~2flppgRe>e_Z{PLUU3uE?MZs*a?KFL+}tuaxwFG(CWD<!_FlB)ie zH9IuyX6*60r85<E`EEb1O-_hJu0))^Y=~?Ky;<g3erx>uO<P@G-JoixeYSD%iliUS z^ZRGd=P{rFN(W~NAMP*iZveW#@${x{jS&@CFu$srI}(q|X%Ht6j}0gd*lI7Ow(2{K zE2X~PNga+K{(u>*=DRyRifpoN64~jC{wg>$ST{s8#vx3PWQ;TAwcFUDr1Of@om8^a za)u?RDt|ev!fPgxA8gh_^KX9f{1WY9vv~V^N-s-K-d2%}pN*-E*Uq+O<>BZ&bUkYw zZNrNwmA%i%!6SFL<080#u!s$pMIc#BDNKbg@l+g}sgN*=?hMb3E(X=3gS^A?CHolf zSlFzjArpnlnH-a{=jX%trq>>{-Q4*sTMa?4isG7-FqD=u1hNU!U8z2D2@5oH27Zo@ zbCmc&t(;J6xo^2`;W}7i9$fX*Z5LU`PLYJ%Z&Mvtg7}sdwN~Q$u9iN-3=?vdrMa#} z>rnUre{yj)^U%@n>Vbv0H<>42o{w-laMwQ9=7%WivXbj<H<wuRR|z?KETC=>ATo#O zAe9K!N7OQXoKh`5(oHGzZKn5Bw()=0J`m7e17~x9rj5E4>~pX<b7Z8d$NqMu#^f#} zi&TUlJfaMLfhdK*Z<b-veTy{IexNmNG4W?naaY6p5sPt)z3pYzYy-^XA1T`@n06R* z^FJ|GbbcOPUP&*orwlPHGzQj6HsrMm)i;?J^bZdSifVn+y3o4Q;yoT;sxg_lu^T%k z^=i7}Ih<NBXu5tB>2F!khSOG_vY0Zzm%p#R7A*_^v3HYv|Iw&a<)h<KFZ?+CBQgzU z?M%bu6#2NYmPYI}^MNd8FJ;S9)`=S{1}}zobY{;wjf0fO=H4}U<(dLRVBR&#t7Hv% zg3^`TlAPUIBK<5~CPOp*-oVu0m+EhkvFZI~&j;BBN~}yCp|>6i=UV+A=Jx_75-iU~ zqOy{*e0<q%7a<E@YrS^NhF7ey>`#7SyR3~%KS%BeHVF<Jp4GdYRV{4c>DKF}mkStw z+;`a*dP<m3?QP6#OfPFNv}ri@Y_9RLxZWepelxsu(d_Yu@OgSFn_qaT`P|d~y8HTa zg>cE&>DA-#VB?(ItK-rp)h6Q$u_N(0$)(UKQG=(&*^@;->o&KX^RY$QYoy@7k*D~} zSS(4z*tFQe5R8z6Y(5cw{&i8O$GwLF$&vRX^w~sDU!MlchzQwzZ>A1rhR0IJa#PMy z5?Vic=RfYZ9lR)C=;`R8Xz6$7=6rXdbAQzCw&+HFlDC4Ty6H{j$M9@*TY0HDT5zB6 zA|c@!0Y3Ho!Hk=A0me6}%;Yqb0l<?E0HA>YaQh6CdjRl>0|53R03eVG07Ukmjk{%F zQdM3`T+4m_Fw4tb^YXE`^#eTO_dc>jxClIjspt$t{nb}|j?U{3N9`;21oC3)VhD4P zr+PjU=%G3bN2)vXx7GRV#N}NKt6YdUBSD<kXPs{!)5o`eDv#5$%Fk!go~%$d%t|;; zWc@U{zZDue;8*TA_jYdS_xK~Sa&nu^0UX{-Y?a=hP$F4>iTH8e;wRc={LxSb^zG}{ zJ5^R(Dmo4Ys8%8%57pB8ClcEj;55`hw6IG3p8(|{$Vr3aV3qVg0X`J1c>MN_R^H3c zEqLGh<dvSbudnF*#(KXI+%Sb<=$-u)+g}wriSDBq_+Cefe2qPIr+&M94MvB41)>5a zSLURCikOWy#w6G$Fs$K7w(i<1zIpZN&KKi+zZ|=8O@RPYQqgguFh5;*PQk8zoIZ1Y zlhH!jh-BA@bPHA#kiyS;Db^85{0y&t|4bIMp_V(<VOrB>%h_pbCl=TMhk;?C$AVFz zS6ZPzRKcTfQlsB~F2olTn0jPDT3WGiSdlu!VL$@0<>;{DZ5xF^`%R&9i$LTQC}RlI zCQtk4)eAHKE2DtZEN^xFprG;<$@yCz2QnfaH~~@@2j1OPJKiNuxNPBiwq4xAp9pf; z<ltUMJIQ7o!eRoMJg`gx*rFIwr?{K>JH6l`FFRX1xN(RA0Z!jR+zmC&+{+>N&e?EX zbwlA3=j0u`qr7p@;2V{V@#vR^lUb<gK(x%n$D8iVJ8j(c@^abm4L+w^tO@};We0>^ zMfYJOay!MKmKgyqMArzQ`@tz({QY}cPYuxdwV$p$wEgfIwm0FQHx}>GNr<ClPKB_t zcT6~Lq^#_qQ`W&XV<d6@sUT3B##Mnw6cWw4;`D}Erw-YN8$q_&amTsjXvH_x4r|+R znHAmv#X}8!zgmz(Jn>+o!<pLhevF)6^(XPU^TP{`)Zyfu{Vtf*K0|UkaHUdje8D(h z>fZVu@vfZgEHSmJ!QDxhv>g$_J@SU^yD6Vi_tG0UC$iAQ$D&=PvjY}5SJRjK>W}4{ ziO1>b)~B8n0$G^a+S;QB9>nOE93;^k=}H`FN)<PVRs;snqU<|Qc-Kth7~!e%mz8#O zPOK*{SE?{>r$6>_+jmntvp7W=oIW*(<_<%!kIqe^D(ggjkq<_O#6z}}o3t-pKB>1M zBBWj=;V!VT%6d<sc3Bfb2B%W~WbYI7X=EcAV2jWbgIrQ0)@p4W{%n@<f-WM<^AKi> zz@t_?xzz~}n14;T`^NC_AgcR*`JbJ&XSDJ(bit*yxJgL@yFcv2%4hP*Y6+17abSB- zZ~U@~Ctdm|WAd>mTObh526b!JP=J(Dr#Wb8Dl(_=EhyL*d^On=a+5B)T25D8dB^=? z|6o79N_2`wW??)yFz;QTAHI!tYga_1X2orWWyN6^i??T@<Uj*$llp~VldFl)W`WFF zK6{UuqdJdo3J>{-HyQIUZ+)~;6Q-Wh@KN?2ig>^%0LU8)s$X*4{T*1&jX0YIu6T9X zs!`;kt2>jUVGxd5O1MR!Z&i~ts=b#}UIsUEUigN%sUS$lh69&se;?zf)r_k|Q#kq) zovN8xKZ`9xR&Z<L1Cot4cjd*R)Pw!nNClM_;r@O%9#w{@%l<{sTB?sJcDArDy9Hs; zdc#-$xGj+w-58PZx4~{^PMDpWEFtn~=<1D>Vvc*d;%Nx{UJgd2?YES5DNnHTL2Dbk z*8(0DJ?}af;{6ySZAtEJL=E>edeq9?W^mt{H{YuHj9l!K|M`6P((|v;iB>s`4Ix!$ zs9IJvg_C<~MHAv92kHg~<fPSlzgPK&X}$vo7%;Ra44ey={Ik9{rl%%E!k+bnxJ@J) zH1{fG{ZF81$IlYq)Ras7eT>Vm*`U_jCmE$#ZsM^yboICI=7#tt(I%WEI5-1MOi4O} zctZLqqoo}C8`_AiI1qL@2=a<ba*W`3lL&rN&w>u)VYY9(Fed_y_Rr2_J7ecUOh5Gt zCrJvmt*v;B^O{P?wg?E8Crq<2o3gQ#(8ID}cl`IDH?AgECwA5x=|t7NslE=S(%@lW zA$)GC3l+Y4S~Hd4DJ{B8ULk0c4>Qg3?DQPVFF;n4xQC8AN}DTci@1lDGfKsjxcXeg z+qI~0=m}ZU_f!5oq~&wy_bSj&l_1}}sib4H(Na8!E^**~drI&{;nNNursq4XBz=se zfk^#Qf0=w4`Tm(ghHC{igCh8m^9o*lDWaS)s{kR+9$}4k?A$miQ}#|tFFIm^5e|)Z z4z6tKmm&zxSighDtZ<E>(=yDiJM@svD}Q%)%FaSz5q$Jm+s79%UqoSdW4!Kp9jrE> zXWT<PsH%sH4Y7H^y$~%EI<Etk1mIkg-u7iPwPjB}llA)V+(IAp^K^=Grwem0qtUEu zlEm?HSg3o*b0Ng}DAGX^0r3%PQ5r#15;&k%VskL(F$AoZud&g2*z67&q>6gbi@>3j z=iJXij`Lw+uQ*wLBvOYyN_6DI$~j(g4s5HUSN9dJsYOlX3&3$@@Q3Z7!w>fh`cUf? zoxE|ed^VUT{AEf*6!JgN0F}A{46#hqieZj}xMqvzxTcF$T{}x>QYSje*c-`oUG>fp znBkt(wZ>4_4B?9B#Xl}ei=0TBu2LHge=2#;HatW|TdY8d3SatQ%a-$gBA`sNd?JLc z|Iep;7*b?84xAVtnKXU~ef*B`=HqhdkVT-PLkArSHUc#Rv-m?n@=<9|{U`H~RK-6J zpo_ui9S_)<Clhfa3r<l*%(jWvF<{(hJS_#;DqEt)O@r`+LC-?~EI`+W?o97Iyn)AV zd^~Z-`Z$kialf)-fnvH;-}MHQIITh$=|~(LM-|2<FFTplCFd4Mjq-H?t%CbRRvtu) z^0jxlF#%>C0-YExl{ofaLVzHy2BQJE2;eweDwv`i^uJEfHv~Bl{$n<DQbhc38~fh? zIx*`nRB#%wKLsGj{ne;ZjRP2A+W*FY<K|!e)dvUs9RpK3a`XAQS1$jz*u7^<TI@4q z`XfsJPk*dvwh>ztfpcLdpZzfzesJ+u)E1jjkCSB*k+|FHr&u<hwBBd?fcd9ZXzOE4 zp|;I5wYeV?ENXN&1v6KEaAx@%Kz@_)KhmSXj50=t<4Gcrv?^&NKR6oUzaUXZ{HAD( znp=r^Y(bMr&#G@X-8QEeXkkN;PHNva*CkmoBVIAxal|2RRT9YN!`P+Z@br%eWHPf# zjnACCJb#I7bT^I}>F3zE0b18AnhZ;$k%djS&1xv$3YNe&MH!t_16u}`VZ38Zn_tC6 zsLxOq$A+-7?W#~0*kZA1`^6OBO{o1bmKY-1`0>QUw!#;Trd{xt8AzCYR6}q-c&a-N zoGky0?dKz`K-L>S=m)*Infp3ux!jRth1Ghhk5+McAp8=}^}>EiMn)z8ceU=wP3PH7 z4Rpb0t@W3jtiE>GeQh<Jl9Qi{tK#g%#S_6Qrm7f7h<YhNW*sKoV*ZM4mfN8}IdJgG z(9m@=r|lOS-Eb$L!y^qJDU&o2B$u9YA%?ZLzXNM+)Mj2z&0|~hkjVqS;geuo;ZhX- zkxr9w73fhH(?h`)u2z>#96Dyz@qMVWZ{U}ID!&te;)#051s;8NhLZaLt^{CL-lc}; znh5F75k8TNF(d?Jces4klkYA__^e-Baeioi$+2QZCmxTOS~<DFp$*w-5H)oh!lj*l z#A!%&i?d$}@jl?)d|O97@{0hOwQ|<eHEkF4JLXH^<<2%$=NbJnlP8X`Z;K#R>w1Uq ztm_B<^<o_=ooc|KtR?DNs~n;}fCoYA=tYo(QmfC^!R2%!&eGxLJj)gfZU9kfG$$@# zS69&C@#6`>s%b&<J{OtiYg+<KlXCTT^*sN;nVg1Nd=<^$Yy7#A^Jui`2$nW;yT(5P zPlgP=3;ET5)Gxie_K3uDjX{X52&le{<535vu6y>CUstak(!20-T-H_@ZsQ&Gitp%j z3^N0UR)hl0Us>edyeEqgS%`iU;Tt-`78Uw1$<TDs?asm$A)}<hbGEUAw1r>K46c~K zgDf8N5l1gOrVI-JjR6RPk=diq`rTi#j|$3p7hH%;iW?#_wk#d0*A-{&4gK@(m|*6o z+bFKCDvp^>w$G^%kin6ZnH*ViJ-odneaOFHw0*eyV0+_9$eZ|tWdFf8nr?@Fb*@7^ zjxrToAphzeC=-U}zq?HSf6#nlJ!HMurXYX|ECH?{$l&b_*tu;(*RrI5nvw-QJuCa} z>XgvlmfLk7Kc6hL%sxJogV0NFT;!{p&xGuf{lGSRoIFO)=*n9KCKK7g&GQ-P<bRKb zV$+8IJ2=m-U)$wOK4}Z@{4k1RnxW5(O_XR6vKvX<W~XOqWA1x{#;dJpoj6%bqzP3L z)G)Bj#1K$d^-rRFrbyU8q87-YW*TH}d=cttqOXENZ^5CYWR@D&!*Q9nR-bc+er%x` ziw%iYg~Ebjh1X@PP9?*)^@;AGtAR)>CguR`PY8sU>O4k*A>XUmA;m)QvX|zw#ZwNa zBz($A*d<L?pbM1%7UzZNt<*2)JYTu*shEnfzQ4Z`chNDHGQaBi27~d$7Xk8Vxv3e{ zEx@NeMaNS^!X95fAoe>)l%fT3@q6My&M0|P;;b%?KPQq7+fL#Ti7;Hq8%lUuPnl;M zf=CIbD^|P8mHMFX2fZdO=~(AU-g;UdR!zR>$}_PW79O1G10(LQWG+ZhqH79g8|5bD z<1F$B&vAF$Wf&!}b0J}B98povu7VnC=5{^5b5PW*N+hqw$la~(0imW?lSv9n)DXvo z<KDURhSDq1dQg*QseW~gg@1T9C)%PvDADSg&1u0#OXQY3<aWS>$FM)}R)OO84<Q~O zXY^?Ef-x-}GHmGV3|uXbmPGbVlb{4n07@_dP6W18*L`h-Jt6}PL6H@q+sqzv{oYtO z2EI}8l!~0|G>pD~j(zw%xNwxsyFXru>Jdq-?CH08py?tZ5Wjdax6S_xGj2DIcGibI z=-sB{?rRR?e%bC@e637X>Dz9t)TvtzV_{JBewb>Ehd%*LyB_$f(2pRNHIF(NX<=22 zf}ytQ;#m-J-QO;j_Itj9T{Q^0iW1zf3}x8PifO)ubBgVuw(cGIa}xvRGfE_r^YsmQ zjnqeMrvH)7F2ClXs>%+s(L)1^>!E&OAvyurK`6}Pi<o$enDC23GAGk^r*`B>^_d{U z0B$R0al7W58<m@s^>9`(zhBO~uPbH>9nT)bGn+LWG9Ji0G13Pj1YH;nVF<x%ClnA( z8Vi|9|K#6lw%rG#{56)eVgV>uL)i1iH?1X0q;M`t88{a~8PuEj<iC!zW<{Tf>I7r{ z0<w!BivkRh|2Iti4|m0}X~q7ZAJqQC=>HSeVPpUX-hZ`WHvEI`|FC}5F9@(NZRK=5 z$r3Q5G4ts<B>VUIkc$%X6o$j>lEJIJ^LSBkZg&*L9)gi!KVK#7Y}y933}h5zH1jc- zi1(pBBEoGk=?qam;xr$?e?fi<V-@j;H$MBzqDw?I=lcVLcy+3VwDY7F+O8`tekDfD zBz=8iouQNh=N+9}Pcx{Y=<y2)30Z}OP+{Tby;Riz@p$9bIENlRS~C`nd3M?+8oJ$t z#gFE7bFj3Y*LJod9MdxZ7xD_FV&zPH1Ak_PE0HgTCgmBxvWrQ5l?+S}8<b&UAc{hO z->pxt4Hs(LAD-@qA5Kpj5ZBh6KT>+HO4+f+Wnp9rqsdzD58(wOi;|+larL~6mcfgX z!TYAMhZj}Z7xNk71#$s{U_Dw)uYouOumZFld$qZk;$bS1f8>2|GnvSG?Pi^+-i69g z#Qfqfa=A%6nFv?rW%jrJPt2i0bUn!RUn*7ExI##y#7BsK!y`-R)nnHlEv&g;8$otd zRs*r1&0hYKTC06HnO?iOtnGY=NecO@#L@IHN-Ag=a0DKOZ=1IY*3S>A8ADB>`e%YE zYQ;#gWI>s*;KFAU54>WLFU2Nj{*n*&>#~ZW(Mz6tm%na)5QI&!v?Uj_ZwOB@yR#it zI@MBnN1;&W&_-9T^+%Z-nxhMu6<VSb_N;mza=K5K_*)+7LmoY;cnObHMcQ>Ydd$CZ z@(QJby!WwGUF#7}Tu=|4P+|E(u10aLhDSWi$T$E+0s8zM$VWq#?It5%`l)lNSW?f2 zn9=HiR8IJNyn@J=>mqxG!rjGu%>LkABL~HqX5Q&I(MDxG1IffX&1)rItEMnB=x3gu zkOGe6GSlChgTzr$?E}Q=l)l7e-I4w?#<GL+HQDU4u_~%&wtQwvxVCW1Ozn_Z@EyW# z11q8@AnwpHZWRnmU|`-!$ERk1i--qyu(C*!`1*M6yQqY`9^U<CLFsmuhNl+f%RAi4 zQ=J@UY9dW=CZ@OKR2q0sTv>emiJp>6{7@ddhgi|Vc9**7!n#HZl+Bsyjq4Ic4A*qW zG+Aw7q+(%fRbk=3fCsSwBMBm^WC>_5X9HvV@+nkpTljKN*nuDGfld85HR2jPEoI3q zW$t1AW<!l#X%O7rg&q?A0Ud9g_;`Why9qlwDf2$5Eo<Am=53!(Ge*h;QMnPEHwihx zoIIjuC{c>ZJhd%S-|xW=>F9Q`XwM}=RB*V7fOHmOGS>akqhS80{|lsSHosfpm^%&s zN;<Er(6jl<^V)8VBSfP|?KlI!$Q&K1XS9u&439p?cda8iP%@-XPytHrfhy$F<I>Q3 zg!2$S5_=t6+YSp5Y9Rc3F5=s`0;Fc<QlI~o=3Tdt>kPb?>_y(f;OhA-DX~qFEEmKb zwI*a%KR{f@8Di7ywed>|)NJq6g-sZevC$j&MNpSd$o(|)m>0}t)`Q-#aOB#7QE$Xn zkJuhLh?ue(pok56@ozr#o=?#8P?7tMI<Kji|57{0k-G{T+hZSfac&+nr5A)(Gfn>R zf28G5B3^V#_c(~Kpd;U138!|<<}yd+&ZnRp++QP8l1D$7bn+r<LdjWMcXzG&FZL$3 zhLe*CQ>etSGaUq)|3+|?0=EZM?A6@A>qK7<9<9o4^?ZLIH&N&&lf1-u8_pmmPh!@I z+u8Bt=)Nk39~`p&UJga$+xP`f4~3H1p*Wq{9+CG(fbq&FBBzsv9m)?;7zcJl5~^QB zjO=Wx_>Xu64_zs17aYMLIx$#$!qyFtOSSFutI0mXumHV}lE311_0!PPlh}sBsd2fs zxfMnF<@cS^_F!g0(9>|`JA8YNu?EaJvYPOZD|;yt-j)#RnrYI^J5=LL_sHmFl)x^a zN!=VQ&4Rr=%nf1Fw*0&{B{9Q^;_PQFm%e%D1>=ftjW0STi!{wuEF&8m8W1r<;axK@ zFdN~AVk}TtRZs%(*xKb2s1WGd>^uco<e8uLY?h7&S&|gK=+#(cd0oz59#7fKG)_0& z63wL792gbPl)07bS1(t44hf9>czsY|JtUwHmVmi08ECvy`82~G@QmMN|Gd05?n}Mq zb9YU#Sl~CiD&qF9ank;`7p`d|>A%P39D6hZg1^v2026I&tYS<|Og|_xfTF^}!oSbZ rf1jXX57l4yU&0bll&^xP&+x!8qx_8*`OXvU86J?AR*@=`fCT&x-wZUe literal 0 HcmV?d00001 diff --git a/civicrm/bower_components/jstree/src/themes/default/40px.png b/civicrm/bower_components/jstree/src/themes/default/40px.png new file mode 100644 index 0000000000000000000000000000000000000000..29273260075f1654bb86a9e3f42c3f32ab5a2d23 GIT binary patch literal 6055 zcmai12Q*x5w?1P;?=^Z0K`=xYy|)l8h+c;XMo3K5(Fq|UdQCy1muN8<j1pzEh%kDM zh!$id+MRsm-tYeZf7d<h?6u$Xp1t0+&VKgu?0ph$8R<}xv62A*K&hvzX^QuI003Gf zA;Pb64;S0;jufVA?GFIt^uG-R<m6oj05W4w4UJp3JbVLu{XKkP+<F=s+_3w;?w<GD z002IdZw56t+hkJ0%^#{8#3P;?_?j}3aGR<pA{bHygn3A5^y7J6Of#Bv(rRfDvh^3m zgOigHNsJ~U6pzV16R+~TOpbaL|9IeJDfpGwCnRot_`G3Cd86VWzkY-mMM9CGD`_H) zpm?j!NxK-;hwfck6;q8My8;7fNa|gA{LlD6z;T$O;x%3raXSElPmq%UsGGScarU?i z>aXhAwje|_2o;bjXF!5r091pL)k^?XZ4e?qOTY{$A_N=<U7S~dTcUvD)$sKR0Fi&3 z9Sj0&p7St*ic$e?dbfB@z~cr`F>?E{7GNa~Ft{6_<$=$lfViHeyDm`E1fVc9<aGcE z1t4w`A0q@11_O@$e0*>qIvZfn{%)zbf31pULl~c_>^jAkEAm<qHYB2c#Fmy~oProV z=4%WxP6SRls$yM_vRST2NKr2y3;{q<DkJ`D56<8iswxadCb^NyLG)_}(FL!w^UC?! zNI6Uu0G0y6#?D0`^{j{+L<sNmm;5_~9`@u#4{(X@b=0a2K+)!m<pJz>ZnR!JZJC~4 zTV4IEk5;#F8n6sKhjuxjEYI%!3{yPC9WAymUx~PG7okIVyx28#XjsfX@{Bavd3HTT z=d_9Z;*?{87p>>qVkOM5VnXMateKN^aJ`r}LH(If5C8au>+*ug30QeS8mPIe3<^#a zePibW{$X&H#wq}{j01r0t-hTf1xdgNkEo@Qz>8g#Go2!S0O79p%ntzUHLr-757evl zkpO^ZQG{@f8rxy#Wf2q+d*`LuPV!SnnP~MZ=q_~{buw23`+Y~Dib!?A*x?!uVMoYE zRSqeXiAQW2j7qG_qM1qwM*Yi)q@Ys}89_>@)=xt3#4{5Qa(-;ZmrTN(9dpdnsY^(g zc!m2zJc9|ZL8`Q_gy~~*ZVO$G?@IRx<l}6$->2T_2d+n+#v*kjo=4P~D1D@8&}exh z%Nniyl6=%PKq4oFsVH~!{ySEsB$*c*qvamdGbzd%ed4Gumx(3O_r%3|yVYyuL`c(I z25WgMD9U?TYi?J7TN934Mrs2I=_0gHq%wqo>fBD8YPwd2Rz{z7-*B^Ek)oX;l_dp7 zn{-{}O?zYTPT)Q5PxNKy>k@HRx*~j^=u+q*G{Ny2XxS@t2^!b0wmc=!t9@-gPB*SS z?qkZgDe^W~N|%){?Zb?#R~@nZa}n-q{V}WgtKF-Tt8A-0-)+e9omKr_ADb-;nhxC6 zXIZ0JlUgHk%et;+@hZo3?#&BxTIrNK>Xk1VO{-1f-q1@u$dMn8V$w4xu6&t3!Ro>6 zf%B~X67ZgOE}hdTbJTKta8u_?<`?i`AO&SCV^m)}RFEb2GVx_7OW@_|EW;9(iA0t@ zb8%UTt*nh~>TF*NE8#}r5XRI2vUL4)fpj)ui22*HlCt?Sa*G3tLGzTi_GY0~+7^;# zD{o0ZW|Ui$<=@&eV>5%kz40cl4En~`T;+9`^;rUub+=)+vBqnYqFRR)WG^?l3rjs* zgvX1rJoZ6^G+Ll`csk^vaBJ2XM{A-|+1nTL8j|{wmi49w&)rpsSF-$$^8$=WHv~&F z55gYLGwcd23$c|*8Ma8c*?N^_WM){E>z138>uj~jRBe~$m$YfMTAxHvsrBh!wY{nX zO~G8s-!Pjtn=2(NWxA=Pa8xB$=2gu0qE$1n!>4p7tDxN;QDEp>I{&C`;}?4<<jnlc z`&a3a4uus_J;fCwECuGWVvn?+uObJe54&%oVb`syQS6lNl(`h0+A^m2YEt`&Hg%F` zukFf}74Kf}-d6%d0z3i+H^1K8$uYgzQX*7x!|;Y--|*1z%i&Mi(z!|!Q`a|gH*%+P z7n&UJ!0(7OzG-ZB)2my(Q)0c-i1dlMBX3=7WpT%@Ub`~ClK)d{Wos#IX^T;sQF*~9 zXm`zi<A=t#O)NEQpNX(ljoyu+PEcoNXj4yB_fA?{TIl=GCud5;lyTEk<s5f7!u;Re zXHdAUFrS0T+ffPaIn3CEK&?h-Mm|ffG|~?Wp*{1>awl}4%+MD9sDt>#1cS&yu}o#L zT(;i1{<c;9fFnP<rJ(Vn{M`E7uI)G2>K&OK&z-p0!Xc?bp#p13|IzM#jYX5SF%|N{ zbaAhRiZEjh;|OTO1|P%)l4@BwRnt@)ScY@jWmf*7e7|r-c|}on{`$PN!;mbhslRE^ zxZAhDA!b1%obST*BIsfaC`Istpx}fEwFn!6ljEQeo{nS{1+3eTy6J7Tq@orzMzxg4 z%E-0ON*<5?Z%-?Ea2r{eRE#H8%&o95pGJwD)}0c&!zixC#Kl;~swBhWtysq-GNl8@ zW;Og5G=FJkXwK(CC5+{(MfIhHmCMBLD$dBhmwK<#E9P!JG-;J@rFYMOU0zJMO2+42 z`@-q=LELiwGWkj{a~7oE4)*8;rt2`Kl<BP)orpq)s$sm5-19v(8sRrgN&MgG1NoE5 z9(8eaL3tr#GGp<dHEe}BjlSy&-wb;8Efp#K=t_@dvB+9W^wqadk%p9pbGZryOgRs^ zy{{`Nv`IugOMU96UdD4Xtr7Yay6*mPu)-~-?!3n*u?fPNPW-{E{%OS}Yf-XB^^z~< zcLb+|iR++lmhK(H2?O#O<ptM<w}<Knuuo<4b_*}I>AL8ao;4Q78d!>QSgp5J+?B6W z^m~LQTVcF(E%r81g<|vLMq%$s<MM6G%&M?9fuNgS5%!$}k(~`7uPt&5vbC7dt=Xw< zJ7X(|^+JQwuh@JxWyXZZRSa0>Ovdofg0t{7wm9E`j_ldz@7|W9TU<xn$K5yA=S2%_ zs4~hj*E6YnD5q!MQ7+tmw|(?O3k%5{7R0tjHEOiH>QHP(x|M#w4Bt>Oe{Ftf{>xlu zXMC=~Y3kT#Y=<ov`9td4B-RFrJ5&D9j<o<;+?;fubUV>IsmG~QC6sL*XPkK3RT_Ew zZTEr4!DqyLRE<+DA167+mCQ|3K3&_=q3YvmKhNI{6s44*w0M%&yUYjEe6+fWBVE98 zQYy?mObV`8BA(!S$N}Ym+*Qx{o}-;>mUCj`Z1diDNO|nj*ZH7R9V{1ho|K~XBmD#O z51uodkrQdq?;}b1>G`2yVn1gcu`e5gH(W3acd31M-_ryvjcZ*bZrniLz}S9o4)|V& zU8A>bw#=zkaPa;b@Ky0VZNj*(HLo?Ns>Rl;WhbbuA=n+a$yOkXnLBKIw9j<$X|h0G zX|C-c$QRdxJ6d3x3%h^y3^Uj|9e8!85^0QdI8@zMo7R|%n^dtmpZ&Z$8-5oRSadKp ztAitoi5fXiJxZb0xRjEeG8ju4yHy~kEHA&Ta{p}ev{Ylnbwr?m`TXViU==eHB<y%{ zYYH=#HTEL&duCdPcS!NsSJW0uHMX~_m$Ur?TvEdR@b<}eXW(og$L^~IYU9-q?r^~i zkDs+iW}~GiX)I}J7lh!fgHsntQ7nGm<aW_Dy$Jw8`~ZN60)U?vc)tk%55xiBt0Mp? zWB~xP?=y!UZ2+Jc*V9xphtGVQQ}W^az=Bx%Dp6a*eoPeG%j`I=*gf0HW86DbyP^cn z-UE7*T&|LL(;z$F(fi%LrppjsR<>0h#;IEK>9X{Pogj-z*EH4=Pknic?x#hvD{@9B zXYJFSXCHVXn+YihhzKc2F8?+fac;-ori%J)(SC}YTq%7kuas!917cS0NbL5Htpi-) z)Yg$~a1VuH4ctuMvvn>^nw~rhvH#c#MVMlVCJ=xld6~pJR~Ty%q@309mrkqv*h}%Z zy>E3UTuWq8)+K1`#NMa6>Gwl`SkW_+$@Vt;6)hCBTZq<T8@r`6Kj*U{Tv<#Mq9-o@ zsw^~kxfqM6Cgs;LZ}2rn2C(gkM$FRV1L+}iMC?LnPF^NR;hlKdu5lZr$U1v-fVn}t zss@sQ^cW^bA<c_n@x`2o*msSfiustT;X=r0F~(YWk3q5j;w){VCDNRtdGZ$enmve^ zQX9F<2pfg*_LAQuR18#2U9qd4T6owxw_%GtIJXDIk-d$}wnR(O!nTWo?#Lu&2@q5< z-cH#-@|GkZ42VA+(BJ-J71J0E&DAob2W?RK=s_40@NpQ%c{+y;Mv0q*A-)KMc3lm$ z)IsdIje0;#di<r?r(Tf^)$yKtd=JD(&G4s<AymlB@qQn%KyHCN;?qW1^D_CK#kYl9 z{k7`3<`}6hVh^I1a^5G)D#CvUitvdQl0d)%y-ay8r$od7{Tn-DuB=`4CkMTLdH1DF zm%Y|#MEwPnIa3Oa7qEPOr0`B!EIB3u1OgKf{kH#H1PBBO6ot3{BZ%7v)wi-g=8zDF ztyoVE#8*S;`FXvH0;L*37>lpIkarWdnpfGEy>Bz4@CG|oR2!7kPGsJa*2V~$gqtta zLNWJTTdo7)i>GIWQNk9QRifCD73b7Xw`<Tk=R>=JHi7o>=h>vJ$Zg|J+_|9XEXNt} zOmTXAUH0`GVEx#yUMt3c+okOXJ+tH&gYjqNH9fws6C9F%{Iiy#lPl_RP<{lyV4LQA zaPt0Wcjq?`s6?De*lXfn<lU_Xmp<Rst4#Y+O}{bE<^ScZA*dRhoA4q9p+(UNW|APJ zwnEb=I?`(F{rg4)3e@_ME|N&Zo`kgq&f|evjwu2qGXMV@3i8BE5JGafsgvLya>-#7 z4i9A3BhpYW^m2?gCZZaT<LE8al%|NihxnoazPP2>_gdn6$Sre9ga)TXllxXy<dP@k zlG9Sci?#4fZebPLZ^-fAsF>RF#Y1th8QguTsy^q0ii9~bAN(6O?4{pqMj+Ji_75Qc zM4U$aPul-U`F{)gtqVhL(o>Xp1lDHfmtdDO0v5lilo96zkG9P}+>NR^Jg2Wmlv5+U zi0#m$Uf(*Je2n`s5xI$h$=tj>*a7beRg`Ein<uOh#-)WEMc5?Eb}io9Y)^nYfpp@V z);c$pC2UZs%hK2cx%XeI!Bau*2RWTgo711haTc%13nEk$j+ec|FG2&@2pmxIHSm?4 z4v!Np6vw8ty&&h_tU>vg{rAn$Js6a`J>l%Fq$xrnyk9g7(#u-bLQz7ZMlK24dt6!c z(qM#0(d{)Dxb1iO-Zt6!(g3lGXO@Ir;#a4K5Kyt!!f9cn@%|mdG=#Q7&ilNJcvdlk zi1BEU$l+OqKk5ea8#oUNOS(X2fuy;zIMw->IgEbYRG-;Hb(H0@AbX85{N05(7%WO; zd!Sd$S%|8;5afiB7k*tBaEPn9c=O^{{b*P#He3oBovhg1lCqC0MBGpsEm&i$MnrM$ z#pAn@%O`}5{9Y<?;aOh=XhaDJx*YO@Yop>WRrH;aq8~DQ-&EWwk1HcmgT=+1MyJDv zSZhEo7qs8l|3$d}!P)<;?tjDl7qR~i%JBIo(CkKp?1D46Mp1V{_A9ggO;=s>z{H77 z>DbskP!rA5cv{#VOfv})Ma<_+$gaphJCTcrFEh;D>UCBGd5_tOTYid<#v(~`XLeu} zHd0IUg~4$2%N`0_p?<o-&n>=O@9ow9P@R8Op3#DIyV0hM>XRQt3?M!_1CQUe`<DoL z6Nd~BGV<HcWS#tQqN;DB65%Cz7hUy8>#1?RChC&=B&$=y-V{#}mjB%}EvvnHlVW#v zC?42b=tM*m5uZIFyA=CxY(WW`^ObjF&9_)QmUtJtoPM65Xha-4)oT3z!IXc=&fiS= zvq8Ep`kIjbk@x?|oI30DS@?Qj7X|KgZwUr_C-Iw!_&g^MT)oM?xQGka7dq>4(nR@z z&n@*gN2vG-l3SC`wa_GTGPHb-v{8tS<l_`7QG(<xq2j}|?nK1OF9-ciV=4*!P6sA| z7S<~EC~h1gRNSHPkwnfNg^x0h%i*ky>^s@)>hoZEf?zv5iwr;T(%)R5lFk@KupDcL z8wi~(^%nmKH`Tv@HPh~eoEI$Rv533?e_szLWd9r($NFa*NNlPj|CRX@;_B)z$Bw+t z?WpNYO8L*>;QuHeD^ry6Z6Z)`-e|^4uDcuHNz@SG-*d(P7MXvvlqJ^_&1BD<Z#Uo9 zPv0B*AEf`gCpDLJx~QYxp^s|u2~1j(#lOfE&4cj%HKZUAnb7*_(_@7**$`JZ=8x1z zd1ql4trsypM5jg~6W!e!K|w*RRSBzWjYcX>)A#CP9}YI!EA<K$OFfSdub(#DjLO8G zj?==%rnes<O7Yj>-k!L(Ozx7@p8dr)n~Q}lwO`*CkWEkW_QUp$jjA;+;I^5w>oEpL zn`;n~X*uG8?p?8Wa#|s~6xlAHKGZzfjJoi7fF(IDQG-7~Z}7HWMG@?;Q&g@t((c(s z?dhO%hu2To11lVn^6J-Gyfeb6Le^Ta#TO5oW%~^r&fn7PDy4XpHH?UZH}ZIP3M|A( z>z$EJ=e*_bM`&PU#VZY+jA8O_!pHs-6enyTD3{?xn?yU#e@djDT(Qx!#G7xiEXt!f zP~c2(oCT7er@t+m8UBfRU9Z9bGTzVV`y?WyJKa{Jm$7$rCd{Qp64ng&{fQf?-5_%d zYFDgFU?d-;lnX{SQK6fvGR58<-t%mfJRpP5!*M5P-%fb&Quu%><iHUle?WzsUtk~X zV;M>4@gjPNX)VgOLK@^nI4F8v&$Gse$;@+0*204+kGpW?1?^lrv)Y;aGMu$=W(9CZ z;64hrA*0@Fv$vM<j5aaw1t>h==lrNXl0}(uWmyjLlON{tg`bycR~_7bNbsw(?q?kw za>_4x#nOtjSslrxB{GlQ(b-A)NW0%fP;i~%Iq&|wWc}K#cIUy$+tGanzbIvCy4|fp zyVdX2V{or~x!ME;tgM2|_?a|HJMAd!x$*@iU3GjgwcG)A4vqD>#k+IN4#&jfXAv!H z#$?aCJoDNG96LhunYhmS2@VXZ0lF+6B{)$rKmH9Wup_s~>L=<=<gp$)%DWRxYUd&! zI;O>1DUxf9MIM0x{g7CT-a)a_VRy-6+lq7dMN>()FWG^;DUKW!&iKhPz>cDsMLE<Z z%M%+wR}*pF0o^@>ElERAKL15a{p4QmP@PJ`(R|uvUy5<BLdDIXB8F3ve48IOAG{~- zqZ)|yjYoo*;^Bhud+63h{zGZ7lL>h3ooS1+wGzXuZ<GtKBe)o2XnVJVGC6_&P}HE& zhj>6K-2ZrJC}bvFqtk_NzL@AVXtZ6DCay62{AVe|q5X8`pv7l1-7q<YILO6fQMjCm z`dF$ZNqYE1Hul>@qcODPENtQ1fJ^$O>I2E(Hr~7M9n{%Y-Ti`8h~3A^*$9!ksnCFq z5aDB2W^Q%7h&0X~WzmQ)Gym}`@wZxZ-#-fnL@7s79cLCl;{SvIJuM^6Ds{)m{{lji B1Y7_B literal 0 HcmV?d00001 diff --git a/civicrm/bower_components/jstree/src/themes/default/style.css b/civicrm/bower_components/jstree/src/themes/default/style.css new file mode 100644 index 0000000000..616be241be --- /dev/null +++ b/civicrm/bower_components/jstree/src/themes/default/style.css @@ -0,0 +1,1102 @@ +/* jsTree default theme */ +.jstree-node, +.jstree-children, +.jstree-container-ul { + display: block; + margin: 0; + padding: 0; + list-style-type: none; + list-style-image: none; +} +.jstree-node { + white-space: nowrap; +} +.jstree-anchor { + display: inline-block; + color: black; + white-space: nowrap; + padding: 0 4px 0 1px; + margin: 0; + vertical-align: top; +} +.jstree-anchor:focus { + outline: 0; +} +.jstree-anchor, +.jstree-anchor:link, +.jstree-anchor:visited, +.jstree-anchor:hover, +.jstree-anchor:active { + text-decoration: none; + color: inherit; +} +.jstree-icon { + display: inline-block; + text-decoration: none; + margin: 0; + padding: 0; + vertical-align: top; + text-align: center; +} +.jstree-icon:empty { + display: inline-block; + text-decoration: none; + margin: 0; + padding: 0; + vertical-align: top; + text-align: center; +} +.jstree-ocl { + cursor: pointer; +} +.jstree-leaf > .jstree-ocl { + cursor: default; +} +.jstree .jstree-open > .jstree-children { + display: block; +} +.jstree .jstree-closed > .jstree-children, +.jstree .jstree-leaf > .jstree-children { + display: none; +} +.jstree-anchor > .jstree-themeicon { + margin-right: 2px; +} +.jstree-no-icons .jstree-themeicon, +.jstree-anchor > .jstree-themeicon-hidden { + display: none; +} +.jstree-hidden, +.jstree-node.jstree-hidden { + display: none; +} +.jstree-rtl .jstree-anchor { + padding: 0 1px 0 4px; +} +.jstree-rtl .jstree-anchor > .jstree-themeicon { + margin-left: 2px; + margin-right: 0; +} +.jstree-rtl .jstree-node { + margin-left: 0; +} +.jstree-rtl .jstree-container-ul > .jstree-node { + margin-right: 0; +} +.jstree-wholerow-ul { + position: relative; + display: inline-block; + min-width: 100%; +} +.jstree-wholerow-ul .jstree-leaf > .jstree-ocl { + cursor: pointer; +} +.jstree-wholerow-ul .jstree-anchor, +.jstree-wholerow-ul .jstree-icon { + position: relative; +} +.jstree-wholerow-ul .jstree-wholerow { + width: 100%; + cursor: pointer; + position: absolute; + left: 0; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +.vakata-context { + display: none; +} +.vakata-context, +.vakata-context ul { + margin: 0; + padding: 2px; + position: absolute; + background: #f5f5f5; + border: 1px solid #979797; + box-shadow: 2px 2px 2px #999999; +} +.vakata-context ul { + list-style: none; + left: 100%; + margin-top: -2.7em; + margin-left: -4px; +} +.vakata-context .vakata-context-right ul { + left: auto; + right: 100%; + margin-left: auto; + margin-right: -4px; +} +.vakata-context li { + list-style: none; +} +.vakata-context li > a { + display: block; + padding: 0 2em 0 2em; + text-decoration: none; + width: auto; + color: black; + white-space: nowrap; + line-height: 2.4em; + text-shadow: 1px 1px 0 white; + border-radius: 1px; +} +.vakata-context li > a:hover { + position: relative; + background-color: #e8eff7; + box-shadow: 0 0 2px #0a6aa1; +} +.vakata-context li > a.vakata-context-parent { + background-image: url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAIORI4JlrqN1oMSnmmZDQUAOw=="); + background-position: right center; + background-repeat: no-repeat; +} +.vakata-context li > a:focus { + outline: 0; +} +.vakata-context .vakata-context-hover > a { + position: relative; + background-color: #e8eff7; + box-shadow: 0 0 2px #0a6aa1; +} +.vakata-context .vakata-context-separator > a, +.vakata-context .vakata-context-separator > a:hover { + background: white; + border: 0; + border-top: 1px solid #e2e3e3; + height: 1px; + min-height: 1px; + max-height: 1px; + padding: 0; + margin: 0 0 0 2.4em; + border-left: 1px solid #e0e0e0; + text-shadow: 0 0 0 transparent; + box-shadow: 0 0 0 transparent; + border-radius: 0; +} +.vakata-context .vakata-contextmenu-disabled a, +.vakata-context .vakata-contextmenu-disabled a:hover { + color: silver; + background-color: transparent; + border: 0; + box-shadow: 0 0 0; +} +.vakata-context li > a > i { + text-decoration: none; + display: inline-block; + width: 2.4em; + height: 2.4em; + background: transparent; + margin: 0 0 0 -2em; + vertical-align: top; + text-align: center; + line-height: 2.4em; +} +.vakata-context li > a > i:empty { + width: 2.4em; + line-height: 2.4em; +} +.vakata-context li > a .vakata-contextmenu-sep { + display: inline-block; + width: 1px; + height: 2.4em; + background: white; + margin: 0 0.5em 0 0; + border-left: 1px solid #e2e3e3; +} +.vakata-context .vakata-contextmenu-shortcut { + font-size: 0.8em; + color: silver; + opacity: 0.5; + display: none; +} +.vakata-context-rtl ul { + left: auto; + right: 100%; + margin-left: auto; + margin-right: -4px; +} +.vakata-context-rtl li > a.vakata-context-parent { + background-image: url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAINjI+AC7rWHIsPtmoxLAA7"); + background-position: left center; + background-repeat: no-repeat; +} +.vakata-context-rtl .vakata-context-separator > a { + margin: 0 2.4em 0 0; + border-left: 0; + border-right: 1px solid #e2e3e3; +} +.vakata-context-rtl .vakata-context-left ul { + right: auto; + left: 100%; + margin-left: -4px; + margin-right: auto; +} +.vakata-context-rtl li > a > i { + margin: 0 -2em 0 0; +} +.vakata-context-rtl li > a .vakata-contextmenu-sep { + margin: 0 0 0 0.5em; + border-left-color: white; + background: #e2e3e3; +} +#jstree-marker { + position: absolute; + top: 0; + left: 0; + margin: -5px 0 0 0; + padding: 0; + border-right: 0; + border-top: 5px solid transparent; + border-bottom: 5px solid transparent; + border-left: 5px solid; + width: 0; + height: 0; + font-size: 0; + line-height: 0; +} +#jstree-dnd { + line-height: 16px; + margin: 0; + padding: 4px; +} +#jstree-dnd .jstree-icon, +#jstree-dnd .jstree-copy { + display: inline-block; + text-decoration: none; + margin: 0 2px 0 0; + padding: 0; + width: 16px; + height: 16px; +} +#jstree-dnd .jstree-ok { + background: green; +} +#jstree-dnd .jstree-er { + background: red; +} +#jstree-dnd .jstree-copy { + margin: 0 2px 0 2px; +} +.jstree-default .jstree-node, +.jstree-default .jstree-icon { + background-repeat: no-repeat; + background-color: transparent; +} +.jstree-default .jstree-anchor, +.jstree-default .jstree-animated, +.jstree-default .jstree-wholerow { + transition: background-color 0.15s, box-shadow 0.15s; +} +.jstree-default .jstree-hovered { + background: #e7f4f9; + border-radius: 2px; + box-shadow: inset 0 0 1px #cccccc; +} +.jstree-default .jstree-context { + background: #e7f4f9; + border-radius: 2px; + box-shadow: inset 0 0 1px #cccccc; +} +.jstree-default .jstree-clicked { + background: #beebff; + border-radius: 2px; + box-shadow: inset 0 0 1px #999999; +} +.jstree-default .jstree-no-icons .jstree-anchor > .jstree-themeicon { + display: none; +} +.jstree-default .jstree-disabled { + background: transparent; + color: #666666; +} +.jstree-default .jstree-disabled.jstree-hovered { + background: transparent; + box-shadow: none; +} +.jstree-default .jstree-disabled.jstree-clicked { + background: #efefef; +} +.jstree-default .jstree-disabled > .jstree-icon { + opacity: 0.8; + filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'jstree-grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#jstree-grayscale"); + /* Firefox 10+ */ + filter: gray; + /* IE6-9 */ + -webkit-filter: grayscale(100%); + /* Chrome 19+ & Safari 6+ */ +} +.jstree-default .jstree-search { + font-style: italic; + color: #8b0000; + font-weight: bold; +} +.jstree-default .jstree-no-checkboxes .jstree-checkbox { + display: none !important; +} +.jstree-default.jstree-checkbox-no-clicked .jstree-clicked { + background: transparent; + box-shadow: none; +} +.jstree-default.jstree-checkbox-no-clicked .jstree-clicked.jstree-hovered { + background: #e7f4f9; +} +.jstree-default.jstree-checkbox-no-clicked > .jstree-wholerow-ul .jstree-wholerow-clicked { + background: transparent; +} +.jstree-default.jstree-checkbox-no-clicked > .jstree-wholerow-ul .jstree-wholerow-clicked.jstree-wholerow-hovered { + background: #e7f4f9; +} +.jstree-default > .jstree-striped { + min-width: 100%; + display: inline-block; + background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAMAAAB/qqA+AAAABlBMVEUAAAAAAAClZ7nPAAAAAnRSTlMNAMM9s3UAAAAXSURBVHjajcEBAQAAAIKg/H/aCQZ70AUBjAATb6YPDgAAAABJRU5ErkJggg==") left top repeat; +} +.jstree-default > .jstree-wholerow-ul .jstree-hovered, +.jstree-default > .jstree-wholerow-ul .jstree-clicked { + background: transparent; + box-shadow: none; + border-radius: 0; +} +.jstree-default .jstree-wholerow { + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} +.jstree-default .jstree-wholerow-hovered { + background: #e7f4f9; +} +.jstree-default .jstree-wholerow-clicked { + background: #beebff; + background: -webkit-linear-gradient(top, #beebff 0%, #a8e4ff 100%); + background: linear-gradient(to bottom, #beebff 0%, #a8e4ff 100%); +} +.jstree-default .jstree-node { + min-height: 24px; + line-height: 24px; + margin-left: 24px; + min-width: 24px; +} +.jstree-default .jstree-anchor { + line-height: 24px; + height: 24px; +} +.jstree-default .jstree-icon { + width: 24px; + height: 24px; + line-height: 24px; +} +.jstree-default .jstree-icon:empty { + width: 24px; + height: 24px; + line-height: 24px; +} +.jstree-default.jstree-rtl .jstree-node { + margin-right: 24px; +} +.jstree-default .jstree-wholerow { + height: 24px; +} +.jstree-default .jstree-node, +.jstree-default .jstree-icon { + background-image: url("32px.png"); +} +.jstree-default .jstree-node { + background-position: -292px -4px; + background-repeat: repeat-y; +} +.jstree-default .jstree-last { + background: transparent; +} +.jstree-default .jstree-open > .jstree-ocl { + background-position: -132px -4px; +} +.jstree-default .jstree-closed > .jstree-ocl { + background-position: -100px -4px; +} +.jstree-default .jstree-leaf > .jstree-ocl { + background-position: -68px -4px; +} +.jstree-default .jstree-themeicon { + background-position: -260px -4px; +} +.jstree-default > .jstree-no-dots .jstree-node, +.jstree-default > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -36px -4px; +} +.jstree-default > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: -4px -4px; +} +.jstree-default .jstree-disabled { + background: transparent; +} +.jstree-default .jstree-disabled.jstree-hovered { + background: transparent; +} +.jstree-default .jstree-disabled.jstree-clicked { + background: #efefef; +} +.jstree-default .jstree-checkbox { + background-position: -164px -4px; +} +.jstree-default .jstree-checkbox:hover { + background-position: -164px -36px; +} +.jstree-default.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, +.jstree-default .jstree-checked > .jstree-checkbox { + background-position: -228px -4px; +} +.jstree-default.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, +.jstree-default .jstree-checked > .jstree-checkbox:hover { + background-position: -228px -36px; +} +.jstree-default .jstree-anchor > .jstree-undetermined { + background-position: -196px -4px; +} +.jstree-default .jstree-anchor > .jstree-undetermined:hover { + background-position: -196px -36px; +} +.jstree-default .jstree-checkbox-disabled { + opacity: 0.8; + filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'jstree-grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#jstree-grayscale"); + /* Firefox 10+ */ + filter: gray; + /* IE6-9 */ + -webkit-filter: grayscale(100%); + /* Chrome 19+ & Safari 6+ */ +} +.jstree-default > .jstree-striped { + background-size: auto 48px; +} +.jstree-default.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); + background-position: 100% 1px; + background-repeat: repeat-y; +} +.jstree-default.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default.jstree-rtl .jstree-open > .jstree-ocl { + background-position: -132px -36px; +} +.jstree-default.jstree-rtl .jstree-closed > .jstree-ocl { + background-position: -100px -36px; +} +.jstree-default.jstree-rtl .jstree-leaf > .jstree-ocl { + background-position: -68px -36px; +} +.jstree-default.jstree-rtl > .jstree-no-dots .jstree-node, +.jstree-default.jstree-rtl > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default.jstree-rtl > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -36px -36px; +} +.jstree-default.jstree-rtl > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: -4px -36px; +} +.jstree-default .jstree-themeicon-custom { + background-color: transparent; + background-image: none; + background-position: 0 0; +} +.jstree-default > .jstree-container-ul .jstree-loading > .jstree-ocl { + background: url("throbber.gif") center center no-repeat; +} +.jstree-default .jstree-file { + background: url("32px.png") -100px -68px no-repeat; +} +.jstree-default .jstree-folder { + background: url("32px.png") -260px -4px no-repeat; +} +.jstree-default > .jstree-container-ul > .jstree-node { + margin-left: 0; + margin-right: 0; +} +#jstree-dnd.jstree-default { + line-height: 24px; + padding: 0 4px; +} +#jstree-dnd.jstree-default .jstree-ok, +#jstree-dnd.jstree-default .jstree-er { + background-image: url("32px.png"); + background-repeat: no-repeat; + background-color: transparent; +} +#jstree-dnd.jstree-default i { + background: transparent; + width: 24px; + height: 24px; + line-height: 24px; +} +#jstree-dnd.jstree-default .jstree-ok { + background-position: -4px -68px; +} +#jstree-dnd.jstree-default .jstree-er { + background-position: -36px -68px; +} +.jstree-default .jstree-ellipsis { + overflow: hidden; +} +.jstree-default .jstree-ellipsis .jstree-anchor { + width: calc(100% - 29px); + text-overflow: ellipsis; + overflow: hidden; +} +.jstree-default .jstree-ellipsis.jstree-no-icons .jstree-anchor { + width: calc(100% - 5px); +} +.jstree-default.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); +} +.jstree-default.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-small .jstree-node { + min-height: 18px; + line-height: 18px; + margin-left: 18px; + min-width: 18px; +} +.jstree-default-small .jstree-anchor { + line-height: 18px; + height: 18px; +} +.jstree-default-small .jstree-icon { + width: 18px; + height: 18px; + line-height: 18px; +} +.jstree-default-small .jstree-icon:empty { + width: 18px; + height: 18px; + line-height: 18px; +} +.jstree-default-small.jstree-rtl .jstree-node { + margin-right: 18px; +} +.jstree-default-small .jstree-wholerow { + height: 18px; +} +.jstree-default-small .jstree-node, +.jstree-default-small .jstree-icon { + background-image: url("32px.png"); +} +.jstree-default-small .jstree-node { + background-position: -295px -7px; + background-repeat: repeat-y; +} +.jstree-default-small .jstree-last { + background: transparent; +} +.jstree-default-small .jstree-open > .jstree-ocl { + background-position: -135px -7px; +} +.jstree-default-small .jstree-closed > .jstree-ocl { + background-position: -103px -7px; +} +.jstree-default-small .jstree-leaf > .jstree-ocl { + background-position: -71px -7px; +} +.jstree-default-small .jstree-themeicon { + background-position: -263px -7px; +} +.jstree-default-small > .jstree-no-dots .jstree-node, +.jstree-default-small > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-small > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -39px -7px; +} +.jstree-default-small > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: -7px -7px; +} +.jstree-default-small .jstree-disabled { + background: transparent; +} +.jstree-default-small .jstree-disabled.jstree-hovered { + background: transparent; +} +.jstree-default-small .jstree-disabled.jstree-clicked { + background: #efefef; +} +.jstree-default-small .jstree-checkbox { + background-position: -167px -7px; +} +.jstree-default-small .jstree-checkbox:hover { + background-position: -167px -39px; +} +.jstree-default-small.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, +.jstree-default-small .jstree-checked > .jstree-checkbox { + background-position: -231px -7px; +} +.jstree-default-small.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, +.jstree-default-small .jstree-checked > .jstree-checkbox:hover { + background-position: -231px -39px; +} +.jstree-default-small .jstree-anchor > .jstree-undetermined { + background-position: -199px -7px; +} +.jstree-default-small .jstree-anchor > .jstree-undetermined:hover { + background-position: -199px -39px; +} +.jstree-default-small .jstree-checkbox-disabled { + opacity: 0.8; + filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'jstree-grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#jstree-grayscale"); + /* Firefox 10+ */ + filter: gray; + /* IE6-9 */ + -webkit-filter: grayscale(100%); + /* Chrome 19+ & Safari 6+ */ +} +.jstree-default-small > .jstree-striped { + background-size: auto 36px; +} +.jstree-default-small.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); + background-position: 100% 1px; + background-repeat: repeat-y; +} +.jstree-default-small.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-small.jstree-rtl .jstree-open > .jstree-ocl { + background-position: -135px -39px; +} +.jstree-default-small.jstree-rtl .jstree-closed > .jstree-ocl { + background-position: -103px -39px; +} +.jstree-default-small.jstree-rtl .jstree-leaf > .jstree-ocl { + background-position: -71px -39px; +} +.jstree-default-small.jstree-rtl > .jstree-no-dots .jstree-node, +.jstree-default-small.jstree-rtl > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-small.jstree-rtl > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -39px -39px; +} +.jstree-default-small.jstree-rtl > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: -7px -39px; +} +.jstree-default-small .jstree-themeicon-custom { + background-color: transparent; + background-image: none; + background-position: 0 0; +} +.jstree-default-small > .jstree-container-ul .jstree-loading > .jstree-ocl { + background: url("throbber.gif") center center no-repeat; +} +.jstree-default-small .jstree-file { + background: url("32px.png") -103px -71px no-repeat; +} +.jstree-default-small .jstree-folder { + background: url("32px.png") -263px -7px no-repeat; +} +.jstree-default-small > .jstree-container-ul > .jstree-node { + margin-left: 0; + margin-right: 0; +} +#jstree-dnd.jstree-default-small { + line-height: 18px; + padding: 0 4px; +} +#jstree-dnd.jstree-default-small .jstree-ok, +#jstree-dnd.jstree-default-small .jstree-er { + background-image: url("32px.png"); + background-repeat: no-repeat; + background-color: transparent; +} +#jstree-dnd.jstree-default-small i { + background: transparent; + width: 18px; + height: 18px; + line-height: 18px; +} +#jstree-dnd.jstree-default-small .jstree-ok { + background-position: -7px -71px; +} +#jstree-dnd.jstree-default-small .jstree-er { + background-position: -39px -71px; +} +.jstree-default-small .jstree-ellipsis { + overflow: hidden; +} +.jstree-default-small .jstree-ellipsis .jstree-anchor { + width: calc(100% - 23px); + text-overflow: ellipsis; + overflow: hidden; +} +.jstree-default-small .jstree-ellipsis.jstree-no-icons .jstree-anchor { + width: calc(100% - 5px); +} +.jstree-default-small.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg=="); +} +.jstree-default-small.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-large .jstree-node { + min-height: 32px; + line-height: 32px; + margin-left: 32px; + min-width: 32px; +} +.jstree-default-large .jstree-anchor { + line-height: 32px; + height: 32px; +} +.jstree-default-large .jstree-icon { + width: 32px; + height: 32px; + line-height: 32px; +} +.jstree-default-large .jstree-icon:empty { + width: 32px; + height: 32px; + line-height: 32px; +} +.jstree-default-large.jstree-rtl .jstree-node { + margin-right: 32px; +} +.jstree-default-large .jstree-wholerow { + height: 32px; +} +.jstree-default-large .jstree-node, +.jstree-default-large .jstree-icon { + background-image: url("32px.png"); +} +.jstree-default-large .jstree-node { + background-position: -288px 0px; + background-repeat: repeat-y; +} +.jstree-default-large .jstree-last { + background: transparent; +} +.jstree-default-large .jstree-open > .jstree-ocl { + background-position: -128px 0px; +} +.jstree-default-large .jstree-closed > .jstree-ocl { + background-position: -96px 0px; +} +.jstree-default-large .jstree-leaf > .jstree-ocl { + background-position: -64px 0px; +} +.jstree-default-large .jstree-themeicon { + background-position: -256px 0px; +} +.jstree-default-large > .jstree-no-dots .jstree-node, +.jstree-default-large > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-large > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -32px 0px; +} +.jstree-default-large > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: 0px 0px; +} +.jstree-default-large .jstree-disabled { + background: transparent; +} +.jstree-default-large .jstree-disabled.jstree-hovered { + background: transparent; +} +.jstree-default-large .jstree-disabled.jstree-clicked { + background: #efefef; +} +.jstree-default-large .jstree-checkbox { + background-position: -160px 0px; +} +.jstree-default-large .jstree-checkbox:hover { + background-position: -160px -32px; +} +.jstree-default-large.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, +.jstree-default-large .jstree-checked > .jstree-checkbox { + background-position: -224px 0px; +} +.jstree-default-large.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, +.jstree-default-large .jstree-checked > .jstree-checkbox:hover { + background-position: -224px -32px; +} +.jstree-default-large .jstree-anchor > .jstree-undetermined { + background-position: -192px 0px; +} +.jstree-default-large .jstree-anchor > .jstree-undetermined:hover { + background-position: -192px -32px; +} +.jstree-default-large .jstree-checkbox-disabled { + opacity: 0.8; + filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'jstree-grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#jstree-grayscale"); + /* Firefox 10+ */ + filter: gray; + /* IE6-9 */ + -webkit-filter: grayscale(100%); + /* Chrome 19+ & Safari 6+ */ +} +.jstree-default-large > .jstree-striped { + background-size: auto 64px; +} +.jstree-default-large.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); + background-position: 100% 1px; + background-repeat: repeat-y; +} +.jstree-default-large.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-large.jstree-rtl .jstree-open > .jstree-ocl { + background-position: -128px -32px; +} +.jstree-default-large.jstree-rtl .jstree-closed > .jstree-ocl { + background-position: -96px -32px; +} +.jstree-default-large.jstree-rtl .jstree-leaf > .jstree-ocl { + background-position: -64px -32px; +} +.jstree-default-large.jstree-rtl > .jstree-no-dots .jstree-node, +.jstree-default-large.jstree-rtl > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-large.jstree-rtl > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -32px -32px; +} +.jstree-default-large.jstree-rtl > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: 0px -32px; +} +.jstree-default-large .jstree-themeicon-custom { + background-color: transparent; + background-image: none; + background-position: 0 0; +} +.jstree-default-large > .jstree-container-ul .jstree-loading > .jstree-ocl { + background: url("throbber.gif") center center no-repeat; +} +.jstree-default-large .jstree-file { + background: url("32px.png") -96px -64px no-repeat; +} +.jstree-default-large .jstree-folder { + background: url("32px.png") -256px 0px no-repeat; +} +.jstree-default-large > .jstree-container-ul > .jstree-node { + margin-left: 0; + margin-right: 0; +} +#jstree-dnd.jstree-default-large { + line-height: 32px; + padding: 0 4px; +} +#jstree-dnd.jstree-default-large .jstree-ok, +#jstree-dnd.jstree-default-large .jstree-er { + background-image: url("32px.png"); + background-repeat: no-repeat; + background-color: transparent; +} +#jstree-dnd.jstree-default-large i { + background: transparent; + width: 32px; + height: 32px; + line-height: 32px; +} +#jstree-dnd.jstree-default-large .jstree-ok { + background-position: 0px -64px; +} +#jstree-dnd.jstree-default-large .jstree-er { + background-position: -32px -64px; +} +.jstree-default-large .jstree-ellipsis { + overflow: hidden; +} +.jstree-default-large .jstree-ellipsis .jstree-anchor { + width: calc(100% - 37px); + text-overflow: ellipsis; + overflow: hidden; +} +.jstree-default-large .jstree-ellipsis.jstree-no-icons .jstree-anchor { + width: calc(100% - 5px); +} +.jstree-default-large.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg=="); +} +.jstree-default-large.jstree-rtl .jstree-last { + background: transparent; +} +@media (max-width: 768px) { + #jstree-dnd.jstree-dnd-responsive { + line-height: 40px; + font-weight: bold; + font-size: 1.1em; + text-shadow: 1px 1px white; + } + #jstree-dnd.jstree-dnd-responsive > i { + background: transparent; + width: 40px; + height: 40px; + } + #jstree-dnd.jstree-dnd-responsive > .jstree-ok { + background-image: url("40px.png"); + background-position: 0 -200px; + background-size: 120px 240px; + } + #jstree-dnd.jstree-dnd-responsive > .jstree-er { + background-image: url("40px.png"); + background-position: -40px -200px; + background-size: 120px 240px; + } + #jstree-marker.jstree-dnd-responsive { + border-left-width: 10px; + border-top-width: 10px; + border-bottom-width: 10px; + margin-top: -10px; + } +} +@media (max-width: 768px) { + .jstree-default-responsive { + /* + .jstree-open > .jstree-ocl, + .jstree-closed > .jstree-ocl { border-radius:20px; background-color:white; } + */ + } + .jstree-default-responsive .jstree-icon { + background-image: url("40px.png"); + } + .jstree-default-responsive .jstree-node, + .jstree-default-responsive .jstree-leaf > .jstree-ocl { + background: transparent; + } + .jstree-default-responsive .jstree-node { + min-height: 40px; + line-height: 40px; + margin-left: 40px; + min-width: 40px; + white-space: nowrap; + } + .jstree-default-responsive .jstree-anchor { + line-height: 40px; + height: 40px; + } + .jstree-default-responsive .jstree-icon, + .jstree-default-responsive .jstree-icon:empty { + width: 40px; + height: 40px; + line-height: 40px; + } + .jstree-default-responsive > .jstree-container-ul > .jstree-node { + margin-left: 0; + } + .jstree-default-responsive.jstree-rtl .jstree-node { + margin-left: 0; + margin-right: 40px; + background: transparent; + } + .jstree-default-responsive.jstree-rtl .jstree-container-ul > .jstree-node { + margin-right: 0; + } + .jstree-default-responsive .jstree-ocl, + .jstree-default-responsive .jstree-themeicon, + .jstree-default-responsive .jstree-checkbox { + background-size: 120px 240px; + } + .jstree-default-responsive .jstree-leaf > .jstree-ocl, + .jstree-default-responsive.jstree-rtl .jstree-leaf > .jstree-ocl { + background: transparent; + } + .jstree-default-responsive .jstree-open > .jstree-ocl { + background-position: 0 0px !important; + } + .jstree-default-responsive .jstree-closed > .jstree-ocl { + background-position: 0 -40px !important; + } + .jstree-default-responsive.jstree-rtl .jstree-closed > .jstree-ocl { + background-position: -40px 0px !important; + } + .jstree-default-responsive .jstree-themeicon { + background-position: -40px -40px; + } + .jstree-default-responsive .jstree-checkbox, + .jstree-default-responsive .jstree-checkbox:hover { + background-position: -40px -80px; + } + .jstree-default-responsive.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, + .jstree-default-responsive.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, + .jstree-default-responsive .jstree-checked > .jstree-checkbox, + .jstree-default-responsive .jstree-checked > .jstree-checkbox:hover { + background-position: 0 -80px; + } + .jstree-default-responsive .jstree-anchor > .jstree-undetermined, + .jstree-default-responsive .jstree-anchor > .jstree-undetermined:hover { + background-position: 0 -120px; + } + .jstree-default-responsive .jstree-anchor { + font-weight: bold; + font-size: 1.1em; + text-shadow: 1px 1px white; + } + .jstree-default-responsive > .jstree-striped { + background: transparent; + } + .jstree-default-responsive .jstree-wholerow { + border-top: 1px solid rgba(255, 255, 255, 0.7); + border-bottom: 1px solid rgba(64, 64, 64, 0.2); + background: #ebebeb; + height: 40px; + } + .jstree-default-responsive .jstree-wholerow-hovered { + background: #e7f4f9; + } + .jstree-default-responsive .jstree-wholerow-clicked { + background: #beebff; + } + .jstree-default-responsive .jstree-children .jstree-last > .jstree-wholerow { + box-shadow: inset 0 -6px 3px -5px #666666; + } + .jstree-default-responsive .jstree-children .jstree-open > .jstree-wholerow { + box-shadow: inset 0 6px 3px -5px #666666; + border-top: 0; + } + .jstree-default-responsive .jstree-children .jstree-open + .jstree-open { + box-shadow: none; + } + .jstree-default-responsive .jstree-node, + .jstree-default-responsive .jstree-icon, + .jstree-default-responsive .jstree-node > .jstree-ocl, + .jstree-default-responsive .jstree-themeicon, + .jstree-default-responsive .jstree-checkbox { + background-image: url("40px.png"); + background-size: 120px 240px; + } + .jstree-default-responsive .jstree-node { + background-position: -80px 0; + background-repeat: repeat-y; + } + .jstree-default-responsive .jstree-last { + background: transparent; + } + .jstree-default-responsive .jstree-leaf > .jstree-ocl { + background-position: -40px -120px; + } + .jstree-default-responsive .jstree-last > .jstree-ocl { + background-position: -40px -160px; + } + .jstree-default-responsive .jstree-themeicon-custom { + background-color: transparent; + background-image: none; + background-position: 0 0; + } + .jstree-default-responsive .jstree-file { + background: url("40px.png") 0 -160px no-repeat; + background-size: 120px 240px; + } + .jstree-default-responsive .jstree-folder { + background: url("40px.png") -40px -40px no-repeat; + background-size: 120px 240px; + } + .jstree-default-responsive > .jstree-container-ul > .jstree-node { + margin-left: 0; + margin-right: 0; + } +} diff --git a/civicrm/bower_components/jstree/src/themes/default/style.less b/civicrm/bower_components/jstree/src/themes/default/style.less new file mode 100644 index 0000000000..88b6cab279 --- /dev/null +++ b/civicrm/bower_components/jstree/src/themes/default/style.less @@ -0,0 +1,22 @@ +/* jsTree default theme */ +@theme-name: default; +@hovered-bg-color: #e7f4f9; +@hovered-shadow-color: #cccccc; +@disabled-color: #666666; +@disabled-bg-color: #efefef; +@clicked-bg-color: #beebff; +@clicked-shadow-color: #999999; +@clicked-gradient-color-1: #beebff; +@clicked-gradient-color-2: #a8e4ff; +@search-result-color: #8b0000; +@mobile-wholerow-bg-color: #ebebeb; +@mobile-wholerow-shadow: #666666; +@mobile-wholerow-bordert: rgba(255,255,255,0.7); +@mobile-wholerow-borderb: rgba(64,64,64,0.2); +@responsive: true; +@image-path: ""; +@base-height: 40px; + +@import "../mixins.less"; +@import "../base.less"; +@import "../main.less"; \ No newline at end of file diff --git a/civicrm/bower_components/jstree/src/themes/default/throbber.gif b/civicrm/bower_components/jstree/src/themes/default/throbber.gif new file mode 100644 index 0000000000000000000000000000000000000000..5b33f7e54f4e55b6b8774d86d96895db9af044b4 GIT binary patch literal 1849 zcma*odr(tX9tZI2z31lM+(&YVk%mZ}5P~KlG2s=WSbGzm0!x7^P##Mnh7t-jP!X0Q zk_SQ}Po-L1tlDK;6l?(>v)e5ZBQx4|Y-Q?nr@Px3?9h(3ZWr3^tj=`TP57gKr87N$ zp2wWee1GRRCwo_xahnw)5cxNPJbCg2L6DV|6`#+yw6v6!mDS$f9-JvFD^n;GQ&UrZ zzh5jCkByB101O60U0q#p_1BM>Cv-vP?&s4@g_((4_1L=L$(a91)0=J91Gas#R{McE znYG^9*0A5YZ>#;~+Wkn(W5B0^yELIYLP!K}mB~<)AM@1&nqekynuaEGqP<JE0#l+( z*R9joTN$nZ{F;;f_Nv(QpzP65;W)SYC;1+?>rzoH|KodRXJy)%+w_fu3nE5>@Bd_b zqC$EQ;{c`T&?EsNO|igL9gC7Ygxv?aQUEXMq?~>wg{EyW;VcJ37CUF#HjrT=KQO_* zS>M9yydXk18D(+QDJ1>r);Lav_uYKp$T?4vr{Q$lTo&pKv^?(>L-)G2*lwH!Ah7k? z7oH<8h-(KTKt5V6$8gF)C7Io&P5=SjTh)=zV=E2EUhQZ<Wjvi)ks6lL7NUI41Suec z%#@RZvp$b|KCxLd`PA8_!Ub^;+J%TE^_K&d6(i&k---epB#nC`b3_`MdhtuWMEe%I z(wJ2$`EGgJTz=trW>P##L8S{d%UK>>+y82>+FV+#^BzW7u3F)Bb>=lYQ%%j`F>ASe zo*cw@V#u6T`A2He;70mR(V&iV&-7{qP~=SRf&jm9-T{*ZeZ}$rd0#6c&fLG^xJcf5 z+p<`wJYgW+_s*V{uI$nMB;%8`S_3>PfGOj3Rq}@Cx^+j?rk92fANSFDBYnOqQ>Vdj z)(|$AhP4t&Lb=Gvo2#3Gl%9<=Gv`Mz?Po@P4iLF!x}GUWJICDlFk-hS^Whyh7x~VH z@0vD1>HYD4&e+~yzS*-sFR{9`{QEEZO1zg7>R&7cHts-6j!xHVdA8eI+ZlVzd%`es zJT@$#GX(gvCJ1oJN%yLBK}{V=V;seo;!w|Yte!W1%5qLNFWqvZW>h&IiH+oPT=b@E zPhGzv5=(Un*X>v`><w7vN-j#h05gB-F9AZf<&Z~SLlC&Nz^-G6DuPj|`n3d!<l7n! z^9j1qeh2{s+i0tZ4@>%8h_nj^NdY<en;#4d>cE6NHS_ifkCV$*D)Tqrbu`s;<=t<4 zAHNqNV?6(g<1PY-w@#I-WYFViz?9TrkMr)u0g`O`u|>T;k|2sV*YF^pun<C(O34ry z@yg-q+#%4rv$|41Y!PHPrjmV%@S3%TUelmz%~6?hLG4%mWKO9NB}mrI%KlhB`{^!g zT?{Y#<ON%sq<!{buD;iH%`hL}N;>vT;$SuTy{j3Gv)yqD!R_CF>yR)MzmmYS5v+~R zXAdD<Jm>%ng9?df;wd8GxR#%3O+gz};Vo;)sK%Bj-q>Oq%R7JU-KD?vYu>#2UjaDo z&8$>5xW~?KPD_#XFToU1hIb*VOMidUr6iYiO0N|i-7s`T8!cFT`rN!^1Pt78J93i6 z5HI1wIM$94m{3SLDvISDe6$ZG1;eq_D9RTaaC>=cO{@Bs>$IlP<c+8wUtK_tPUz3j z)>CPJJ$h$)-3vzNUQ6<Wm&Z5JfeG_o#I^S?ZP9*QGjsiJM3jH{?94}z{@d%97nOVw zacge+X&InNUL3U(BUlor87ff?2qEf2c|yCI=Id~LI~<KyVA#R%nwHS3S<^IBTu|Jj zW^-Xv#UBDqOwy>OsN#_zWxey!_9%hxwH2_dEJi=yY|1c7nDm2_Lm!Cof8-R_+9UkS zcBE(o47yE)oMR(Q=dp1a2wTX5Kv<M)VDKP@wb$5DNEX!VTUn1Pd`taYrL9bpe}d9v zqx3tu5NTGv8=X63WXPWMm1T8=ujh#QvSw5|(EZJ3$quU9*?0NxQKGsTrnFNF-ygOt zYWPggi66%$nuj|v6!Ow2)>vGyLqlWTa7V&!A*|w|)ax~1_~aJ0=_Lilg*0iQk7#ZD EAHN$8j{pDw literal 0 HcmV?d00001 diff --git a/civicrm/bower_components/jstree/src/themes/main.less b/civicrm/bower_components/jstree/src/themes/main.less new file mode 100644 index 0000000000..8616cc039f --- /dev/null +++ b/civicrm/bower_components/jstree/src/themes/main.less @@ -0,0 +1,77 @@ +.jstree-@{theme-name} { + .jstree-node, + .jstree-icon { background-repeat:no-repeat; background-color:transparent; } + .jstree-anchor, + .jstree-animated, + .jstree-wholerow { transition:background-color 0.15s, box-shadow 0.15s; } + .jstree-hovered { background:@hovered-bg-color; border-radius:2px; box-shadow:inset 0 0 1px @hovered-shadow-color; } + .jstree-context { background:@hovered-bg-color; border-radius:2px; box-shadow:inset 0 0 1px @hovered-shadow-color; } + .jstree-clicked { background:@clicked-bg-color; border-radius:2px; box-shadow:inset 0 0 1px @clicked-shadow-color; } + .jstree-no-icons .jstree-anchor > .jstree-themeicon { display:none; } + .jstree-disabled { + background:transparent; color:@disabled-color; + &.jstree-hovered { background:transparent; box-shadow:none; } + &.jstree-clicked { background:@disabled-bg-color; } + > .jstree-icon { opacity:0.8; filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'jstree-grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#jstree-grayscale"); /* Firefox 10+ */ filter: gray; /* IE6-9 */ -webkit-filter: grayscale(100%); /* Chrome 19+ & Safari 6+ */ } + } + // search + .jstree-search { font-style:italic; color:@search-result-color; font-weight:bold; } + // checkboxes + .jstree-no-checkboxes .jstree-checkbox { display:none !important; } + &.jstree-checkbox-no-clicked { + .jstree-clicked { + background:transparent; + box-shadow:none; + &.jstree-hovered { background:@hovered-bg-color; } + } + > .jstree-wholerow-ul .jstree-wholerow-clicked { + background:transparent; + &.jstree-wholerow-hovered { background:@hovered-bg-color; } + } + } + // stripes + > .jstree-striped { min-width:100%; display:inline-block; background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAMAAAB/qqA+AAAABlBMVEUAAAAAAAClZ7nPAAAAAnRSTlMNAMM9s3UAAAAXSURBVHjajcEBAQAAAIKg/H/aCQZ70AUBjAATb6YPDgAAAABJRU5ErkJggg==") left top repeat; } + // wholerow + > .jstree-wholerow-ul .jstree-hovered, + > .jstree-wholerow-ul .jstree-clicked { background:transparent; box-shadow:none; border-radius:0; } + .jstree-wholerow { -moz-box-sizing:border-box; -webkit-box-sizing:border-box; box-sizing:border-box; } + .jstree-wholerow-hovered { background:@hovered-bg-color; } + .jstree-wholerow-clicked { .gradient(@clicked-gradient-color-1, @clicked-gradient-color-2); } +} + +// theme variants +.jstree-@{theme-name} { + .jstree-theme(24px, "@{image-path}32px.png", 32px); + &.jstree-rtl .jstree-node { background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); } + &.jstree-rtl .jstree-last { background:transparent; } +} +.jstree-@{theme-name}-small { + .jstree-theme(18px, "@{image-path}32px.png", 32px); + &.jstree-rtl .jstree-node { background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg=="); } + &.jstree-rtl .jstree-last { background:transparent; } +} +.jstree-@{theme-name}-large { + .jstree-theme(32px, "@{image-path}32px.png", 32px); + &.jstree-rtl .jstree-node { background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg=="); } + &.jstree-rtl .jstree-last { background:transparent; } +} + +// mobile theme attempt +@media (max-width: 768px) { + #jstree-dnd.jstree-dnd-responsive when (@responsive = true) { + line-height:@base-height; font-weight:bold; font-size:1.1em; text-shadow:1px 1px white; + > i { background:transparent; width:@base-height; height:@base-height; } + > .jstree-ok { background-image:url("@{image-path}@{base-height}.png"); background-position:0 -(@base-height * 5); background-size:(@base-height * 3) (@base-height * 6); } + > .jstree-er { background-image:url("@{image-path}@{base-height}.png"); background-position:-(@base-height * 1) -(@base-height * 5); background-size:(@base-height * 3) (@base-height * 6); } + } + #jstree-marker.jstree-dnd-responsive when (@responsive = true) { + border-left-width:10px; + border-top-width:10px; + border-bottom-width:10px; + margin-top:-10px; + } +} + +.jstree-@{theme-name}-responsive when (@responsive = true) { + @import "responsive.less"; +} diff --git a/civicrm/bower_components/jstree/src/themes/mixins.less b/civicrm/bower_components/jstree/src/themes/mixins.less new file mode 100644 index 0000000000..3018623b26 --- /dev/null +++ b/civicrm/bower_components/jstree/src/themes/mixins.less @@ -0,0 +1,105 @@ +.gradient (@color1; @color2) { + background:@color1; + background: -webkit-linear-gradient(top, @color1 0%,@color2 100%); + background: linear-gradient(to bottom, @color1 0%,@color2 100%); +} + +.jstree-theme (@base-height, @image, @image-height) { + @correction: (@image-height - @base-height) / 2; + + .jstree-node { min-height:@base-height; line-height:@base-height; margin-left:@base-height; min-width:@base-height; } + .jstree-anchor { line-height:@base-height; height:@base-height; } + .jstree-icon { width:@base-height; height:@base-height; line-height:@base-height; } + .jstree-icon:empty { width:@base-height; height:@base-height; line-height:@base-height; } + &.jstree-rtl .jstree-node { margin-right:@base-height; } + .jstree-wholerow { height:@base-height; } + + .jstree-node, + .jstree-icon { background-image:url("@{image}"); } + .jstree-node { background-position:-(@image-height * 9 + @correction) -@correction; background-repeat:repeat-y; } + .jstree-last { background:transparent; } + + .jstree-open > .jstree-ocl { background-position:-(@image-height * 4 + @correction) -@correction; } + .jstree-closed > .jstree-ocl { background-position:-(@image-height * 3 + @correction) -@correction; } + .jstree-leaf > .jstree-ocl { background-position:-(@image-height * 2 + @correction) -@correction; } + + .jstree-themeicon { background-position:-(@image-height * 8 + @correction) -@correction; } + + > .jstree-no-dots { + .jstree-node, + .jstree-leaf > .jstree-ocl { background:transparent; } + .jstree-open > .jstree-ocl { background-position:-(@image-height * 1 + @correction) -@correction; } + .jstree-closed > .jstree-ocl { background-position:-@correction -@correction; } + } + + .jstree-disabled { + background:transparent; + &.jstree-hovered { + background:transparent; + } + &.jstree-clicked { + background:#efefef; + } + } + + .jstree-checkbox { + background-position:-(@image-height * 5 + @correction) -@correction; + &:hover { background-position:-(@image-height * 5 + @correction) -(@image-height * 1 + @correction); } + } + + &.jstree-checkbox-selection .jstree-clicked, .jstree-checked { + > .jstree-checkbox { + background-position:-(@image-height * 7 + @correction) -@correction; + &:hover { background-position:-(@image-height * 7 + @correction) -(@image-height * 1 + @correction); } + } + } + .jstree-anchor { + > .jstree-undetermined { + background-position:-(@image-height * 6 + @correction) -@correction; + &:hover { + background-position:-(@image-height * 6 + @correction) -(@image-height * 1 + @correction); + } + } + } + .jstree-checkbox-disabled { opacity:0.8; filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'jstree-grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#jstree-grayscale"); /* Firefox 10+ */ filter: gray; /* IE6-9 */ -webkit-filter: grayscale(100%); /* Chrome 19+ & Safari 6+ */ } + + > .jstree-striped { background-size:auto (@base-height * 2); } + + &.jstree-rtl { + .jstree-node { background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); background-position: 100% 1px; background-repeat:repeat-y; } + .jstree-last { background:transparent; } + .jstree-open > .jstree-ocl { background-position:-(@image-height * 4 + @correction) -(@image-height * 1 + @correction); } + .jstree-closed > .jstree-ocl { background-position:-(@image-height * 3 + @correction) -(@image-height * 1 + @correction); } + .jstree-leaf > .jstree-ocl { background-position:-(@image-height * 2 + @correction) -(@image-height * 1 + @correction); } + > .jstree-no-dots { + .jstree-node, + .jstree-leaf > .jstree-ocl { background:transparent; } + .jstree-open > .jstree-ocl { background-position:-(@image-height * 1 + @correction) -(@image-height * 1 + @correction); } + .jstree-closed > .jstree-ocl { background-position:-@correction -(@image-height * 1 + @correction); } + } + } + .jstree-themeicon-custom { background-color:transparent; background-image:none; background-position:0 0; } + + > .jstree-container-ul .jstree-loading > .jstree-ocl { background:url("@{image-path}throbber.gif") center center no-repeat; } + + .jstree-file { background:url("@{image}") -(@image-height * 3 + @correction) -(@image-height * 2 + @correction) no-repeat; } + .jstree-folder { background:url("@{image}") -(@image-height * 8 + @correction) -(@correction) no-repeat; } + + > .jstree-container-ul > .jstree-node { margin-left:0; margin-right:0; } + + // drag'n'drop + #jstree-dnd& { + line-height:@base-height; padding:0 4px; + .jstree-ok, + .jstree-er { background-image:url("@{image-path}32px.png"); background-repeat:no-repeat; background-color:transparent; } + i { background:transparent; width:@base-height; height:@base-height; line-height:@base-height; } + .jstree-ok { background-position: -(@correction) -(@image-height * 2 + @correction); } + .jstree-er { background-position: -(@image-height * 1 + @correction) -(@image-height * 2 + @correction); } + } + + // ellipsis + .jstree-ellipsis { overflow: hidden; } + // base height + PADDINGS! + .jstree-ellipsis .jstree-anchor { width: calc(100% ~"-" (@base-height + 5px)); text-overflow: ellipsis; overflow: hidden; } + .jstree-ellipsis.jstree-no-icons .jstree-anchor { width: calc(100% ~"-" 5px); } +} diff --git a/civicrm/bower_components/jstree/src/themes/responsive.less b/civicrm/bower_components/jstree/src/themes/responsive.less new file mode 100644 index 0000000000..46ffa97e06 --- /dev/null +++ b/civicrm/bower_components/jstree/src/themes/responsive.less @@ -0,0 +1,67 @@ +@media (max-width: 768px) { + // background image + .jstree-icon { background-image:url("@{image-path}@{base-height}.png"); } + + .jstree-node, + .jstree-leaf > .jstree-ocl { background:transparent; } + + .jstree-node { min-height:@base-height; line-height:@base-height; margin-left:@base-height; min-width:@base-height; white-space:nowrap; } + .jstree-anchor { line-height:@base-height; height:@base-height; } + .jstree-icon, .jstree-icon:empty { width:@base-height; height:@base-height; line-height:@base-height; } + + > .jstree-container-ul > .jstree-node { margin-left:0; } + &.jstree-rtl .jstree-node { margin-left:0; margin-right:@base-height; background:transparent; } + &.jstree-rtl .jstree-container-ul > .jstree-node { margin-right:0; } + + .jstree-ocl, + .jstree-themeicon, + .jstree-checkbox { background-size:(@base-height * 3) (@base-height * 6); } + .jstree-leaf > .jstree-ocl, + &.jstree-rtl .jstree-leaf > .jstree-ocl { background:transparent; } + .jstree-open > .jstree-ocl { background-position:0 0px !important; } + .jstree-closed > .jstree-ocl { background-position:0 -(@base-height * 1) !important; } + &.jstree-rtl .jstree-closed > .jstree-ocl { background-position:-(@base-height * 1) 0px !important; } + + .jstree-themeicon { background-position:-(@base-height * 1) -(@base-height * 1); } + + .jstree-checkbox, .jstree-checkbox:hover { background-position:-(@base-height * 1) -(@base-height * 2); } + &.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, + &.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, + .jstree-checked > .jstree-checkbox, + .jstree-checked > .jstree-checkbox:hover { background-position:0 -(@base-height * 2); } + .jstree-anchor > .jstree-undetermined, .jstree-anchor > .jstree-undetermined:hover { background-position:0 -(@base-height * 3); } + + .jstree-anchor { font-weight:bold; font-size:1.1em; text-shadow:1px 1px white; } + + > .jstree-striped { background:transparent; } + .jstree-wholerow { border-top:1px solid @mobile-wholerow-bordert; border-bottom:1px solid @mobile-wholerow-borderb; background:@mobile-wholerow-bg-color; height:@base-height; } + .jstree-wholerow-hovered { background:@hovered-bg-color; } + .jstree-wholerow-clicked { background:@clicked-bg-color; } + + // thanks to PHOTONUI + .jstree-children .jstree-last > .jstree-wholerow { box-shadow: inset 0 -6px 3px -5px @mobile-wholerow-shadow; } + .jstree-children .jstree-open > .jstree-wholerow { box-shadow: inset 0 6px 3px -5px @mobile-wholerow-shadow; border-top:0; } + .jstree-children .jstree-open + .jstree-open { box-shadow:none; } + + // experiment + .jstree-node, + .jstree-icon, + .jstree-node > .jstree-ocl, + .jstree-themeicon, + .jstree-checkbox { background-image:url("@{image-path}@{base-height}.png"); background-size:(@base-height * 3) (@base-height * 6); } + + .jstree-node { background-position:-(@base-height * 2) 0; background-repeat:repeat-y; } + .jstree-last { background:transparent; } + .jstree-leaf > .jstree-ocl { background-position:-(@base-height * 1) -(@base-height * 3); } + .jstree-last > .jstree-ocl { background-position:-(@base-height * 1) -(@base-height * 4); } + /* + .jstree-open > .jstree-ocl, + .jstree-closed > .jstree-ocl { border-radius:20px; background-color:white; } + */ + + .jstree-themeicon-custom { background-color:transparent; background-image:none; background-position:0 0; } + .jstree-file { background:url("@{image-path}@{base-height}.png") 0 -(@base-height * 4) no-repeat; background-size:(@base-height * 3) (@base-height * 6); } + .jstree-folder { background:url("@{image-path}@{base-height}.png") -(@base-height * 1) -(@base-height * 1) no-repeat; background-size:(@base-height * 3) (@base-height * 6); } + + > .jstree-container-ul > .jstree-node { margin-left:0; margin-right:0; } +} \ No newline at end of file diff --git a/civicrm/bower_components/jstree/src/vakata-jstree.js b/civicrm/bower_components/jstree/src/vakata-jstree.js new file mode 100644 index 0000000000..9838885177 --- /dev/null +++ b/civicrm/bower_components/jstree/src/vakata-jstree.js @@ -0,0 +1,38 @@ +(function (factory) { + "use strict"; + if (typeof define === 'function' && define.amd) { + define('jstree.checkbox', ['jquery','jstree'], factory); + } + else if(typeof exports === 'object') { + factory(require('jquery'), require('jstree')); + } + else { + factory(jQuery); + } +}(function ($, undefined) { + "use strict"; + if(document.registerElement && Object && Object.create) { + var proto = Object.create(HTMLElement.prototype); + proto.createdCallback = function () { + var c = { core : {}, plugins : [] }, i; + for(i in $.jstree.plugins) { + if($.jstree.plugins.hasOwnProperty(i) && this.attributes[i]) { + c.plugins.push(i); + if(this.getAttribute(i) && JSON.parse(this.getAttribute(i))) { + c[i] = JSON.parse(this.getAttribute(i)); + } + } + } + for(i in $.jstree.defaults.core) { + if($.jstree.defaults.core.hasOwnProperty(i) && this.attributes[i]) { + c.core[i] = JSON.parse(this.getAttribute(i)) || this.getAttribute(i); + } + } + $(this).jstree(c); + }; + // proto.attributeChangedCallback = function (name, previous, value) { }; + try { + document.registerElement("vakata-jstree", { prototype: proto }); + } catch(ignore) { } + } +})); diff --git a/civicrm/civicrm-version.php b/civicrm/civicrm-version.php index a182d86e8c..9b670cabc5 100644 --- a/civicrm/civicrm-version.php +++ b/civicrm/civicrm-version.php @@ -1,7 +1,7 @@ <?php function civicrmVersion( ) { - return array( 'version' => '4.7.16', + return array( 'version' => '4.7.17', 'cms' => 'Wordpress', - 'revision' => '49b3bee36e' ); + 'revision' => 'e0ebb075af' ); } diff --git a/civicrm/css/contactSummary.css b/civicrm/css/contactSummary.css index a0b14924a9..6a957989da 100644 --- a/civicrm/css/contactSummary.css +++ b/civicrm/css/contactSummary.css @@ -345,6 +345,30 @@ div#crm-contact-thumbnail { width: 100%; } +#tagtree { + max-height: 500px; + overflow: auto; +} +#tagtree, +#tagtree li.highlighted ul { + background-color: white; +} +#tagtree li.highlighted, +#tagtree li.highlighted-child.jstree-closed { + background-color: #fefcb0; +} +#tagtree li { + margin-top: 5px; +} +#tagtree ins.jstree-icon { + cursor: pointer; + position: relative; + top: -3px; +} +#tagtree input { + margin: 0; +} + #tagGroup table .label { color: #FFF; } diff --git a/civicrm/js/Common.js b/civicrm/js/Common.js index 86f21fb46e..4600589652 100644 --- a/civicrm/js/Common.js +++ b/civicrm/js/Common.js @@ -1522,10 +1522,13 @@ if (!CRM.vars) CRM.vars = {}; $(this).siblings('input:text').val('').trigger('change', ['crmClear']); return false; }) - .on('change', 'input.crm-form-radio:checked, input[allowclear=1]', function(e, context) { + .on('change keyup', 'input.crm-form-radio:checked, input[allowclear=1]', function(e, context) { if (context !== 'crmClear' && ($(this).is(':checked') || ($(this).is('[allowclear=1]') && $(this).val()))) { $(this).siblings('.crm-clear-link').css({visibility: ''}); } + if (context !== 'crmClear' && $(this).is('[allowclear=1]') && $(this).val() === '') { + $(this).siblings('.crm-clear-link').css({visibility: 'hidden'}); + } }) // Allow normal clicking of links within accordions @@ -1658,8 +1661,11 @@ if (!CRM.vars) CRM.vars = {}; return input; case 'string': - // convert iso format - return $.datepicker.parseDate('yy-mm-dd', input.substr(0, 10)); + // convert iso format with or without dashes + if (input.indexOf('-') > 0) { + return $.datepicker.parseDate('yy-mm-dd', input.substr(0, 10)); + } + return $.datepicker.parseDate('yymmdd', input.substr(0, 8)); case 'number': // convert unix timestamp diff --git a/civicrm/js/crm.ajax.js b/civicrm/js/crm.ajax.js index b01e814bf0..262227ea89 100644 --- a/civicrm/js/crm.ajax.js +++ b/civicrm/js/crm.ajax.js @@ -496,7 +496,7 @@ url = $el.attr('href'), popup = $el.data('popup-type') === 'page' ? CRM.loadPage : CRM.loadForm, settings = $el.data('popup-settings') || {}, - formSuccess = false; + formData = false; settings.dialog = settings.dialog || {}; if (e.isDefaultPrevented() || !CRM.config.ajaxPopupsEnabled || !url || $el.is(exclude)) { return; @@ -513,12 +513,12 @@ // Trigger events from the dialog on the original link element $el.trigger('crmPopupOpen', [dialog]); // Listen for success events and buffer them so we only trigger once - dialog.on('crmFormSuccess.crmPopup crmPopupFormSuccess.crmPopup', function() { - formSuccess = true; + dialog.on('crmFormSuccess.crmPopup crmPopupFormSuccess.crmPopup', function(e, data) { + formData = data; }); dialog.on('dialogclose.crmPopup', function(e, data) { - if (formSuccess) { - $el.trigger('crmPopupFormSuccess', [dialog, data]); + if (formData) { + $el.trigger('crmPopupFormSuccess', [dialog, formData]); } $el.trigger('crmPopupClose', [dialog, data]); }); diff --git a/civicrm/js/crm.drupal.js b/civicrm/js/crm.drupal.js index 2f14c49921..7ed33666e2 100644 --- a/civicrm/js/crm.drupal.js +++ b/civicrm/js/crm.drupal.js @@ -10,5 +10,13 @@ CRM.$(function($) { // D7 hack, restore toolbar position (CRM-15341) $('#toolbar').css('z-index', ''); } - }); + }) + // d8 Hack to hide title when it should be (CRM-19960) + .ready(function() { + var pageTitle = $('.page-title'); + var title = $('.page-title').text(); + if ('<span id="crm-remove-title" style="display:none">CiviCRM</span>' == title) { + pageTitle.hide(); + } + }); }); diff --git a/civicrm/packages/DB/DataObject.php b/civicrm/packages/DB/DataObject.php index ca3f70bbee..9636b9a5fc 100644 --- a/civicrm/packages/DB/DataObject.php +++ b/civicrm/packages/DB/DataObject.php @@ -3645,7 +3645,7 @@ class DB_DataObject extends DB_DataObject_Overload * @return array of key => value for row */ - function toArray($format = '%s', $hideEmpty = false) + function toArray($format = null, $hideEmpty = false) { global $_DB_DATAOBJECT; $ret = array(); @@ -3659,24 +3659,35 @@ class DB_DataObject extends DB_DataObject_Overload if (!isset($this->$k)) { if (!$hideEmpty) { - $ret[sprintf($format,$k)] = ''; + if ($format === null) + $ret[$k] = ''; + else + $ret[sprintf($format,$k)] = ''; } continue; } // call the overloaded getXXXX() method. - except getLink and getLinks if (method_exists($this,'get'.$k) && !in_array(strtolower($k),array('links','link'))) { - $ret[sprintf($format,$k)] = $this->{'get'.$k}(); + if ($format === null) + $ret[$k] = $this->{'get'.$k}(); + else + $ret[sprintf($format,$k)] = $this->{'get'.$k}(); continue; } // should this call toValue() ??? - $ret[sprintf($format,$k)] = $this->$k; + if ($format === null) + $ret[$k] = $this->$k; + else + $ret[sprintf($format,$k)] = $this->$k; } if (!$this->_link_loaded) { return $ret; } foreach($this->_link_loaded as $k) { - $ret[sprintf($format,$k)] = $this->$k->toArray(); - + if ($format === null) + $ret[$k] = $this->$k->toArray(); + else + $ret[sprintf($format,$k)] = $this->$k->toArray(); } return $ret; diff --git a/civicrm/release-notes.md b/civicrm/release-notes.md index c21ab0bee1..9c4d6a3c35 100644 --- a/civicrm/release-notes.md +++ b/civicrm/release-notes.md @@ -14,6 +14,15 @@ Other resources for identifying changes are: * https://github.com/civicrm/civicrm-joomla * https://github.com/civicrm/civicrm-wordpress +## CiviCRM 4.7.17 + +Released March 8, 2017 + +- **[Features](release-notes/4.7.17.md#features)** +- **[Bugs resolved](release-notes/4.7.17.md#bugs)** +- **[Miscellany](release-notes/4.7.17.md#misc)** +- **[Credits](release-notes/4.7.17.md#credits)** + ## CiviCRM 4.7.16 Released February 8, 2017 diff --git a/civicrm/release-notes/4.7.17.md b/civicrm/release-notes/4.7.17.md new file mode 100644 index 0000000000..0d95f91bae --- /dev/null +++ b/civicrm/release-notes/4.7.17.md @@ -0,0 +1,556 @@ +# CiviCRM 4.7.17 + +Released March 8, 2017 + +- **[Features](#features)** +- **[Bugs resolved](#bugs)** +- **[Miscellany](#misc)** +- **[Credits](#credits)** + +## <a name="features"></a>Features + +### Core CiviCRM + +- **[CRM-19815](https://issues.civicrm.org/jira/browse/CRM-19815) Make + pseudoconstant code generic in advanced search + ([9908](https://github.com/civicrm/civicrm-core/pull/9908), + [9885](https://github.com/civicrm/civicrm-core/pull/9885), and + [9799](https://github.com/civicrm/civicrm-core/pull/9799))** + + This modifies handling of pseudoconstants (site-wide lists of options) from + specific hard-coded situations to metadata-based fields. This results in + removing slow joins and improves speed. + +- **[CRM-19492](https://issues.civicrm.org/jira/browse/CRM-19492) When merging: + require row to be taken across before changing row settings + ([9902](https://github.com/civicrm/civicrm-core/pull/9902))** + + The interface for merging contacts is clarified so that merge options such as + location type on a field are not available unless the field is marked to be + merged from the contact which is to be deleted. + +- **[CRM-20175](https://issues.civicrm.org/jira/browse/CRM-20175) Increase pager + support to 9999 pages + ([9894](https://github.com/civicrm/civicrm-core/pull/9894))** + + The page number box on search results now allows four-digit page numbers. + +- **[CRM-19934](https://issues.civicrm.org/jira/browse/CRM-19934) Performance + improvement on civicrm_acl_contact_cache + ([9807](https://github.com/civicrm/civicrm-core/pull/9807)) (Partial work)** + + The query for building an ACL cache is simplified to avoid a taxing `OR` + clause. + +- **[CRM-19816](https://issues.civicrm.org/jira/browse/CRM-19816) Improve + activity search filters + ([9841](https://github.com/civicrm/civicrm-core/pull/9841))** + + Using the API to search for activities involving a specific contact is + simplified and standardized across the assignee, source, and target, plus the + generic `contact_id` parameter. + +- **[CRM-19883](https://issues.civicrm.org/jira/browse/CRM-19883) Activity + Priority Field is Not Included in Advanced Search or Activity Reports + ([9816](https://github.com/civicrm/civicrm-core/pull/9816) and + [9800](https://github.com/civicrm/civicrm-core/pull/9800))** + + The Priority field is now available in the Activity Detail and Activity + Summary reports. + +- **[CRM-19938](https://issues.civicrm.org/jira/browse/CRM-19938) Make Civi to + CMS email sync optional + ([9765](https://github.com/civicrm/civicrm-core/pull/9765))** + + There is now an option to disable synchronization of a contact's email address + with their CMS user account. + +- **[CRM-19930](https://issues.civicrm.org/jira/browse/CRM-19930) Patch + DB_DataObject::toArray() to sprintf only as needed + ([9735](https://github.com/civicrm/civicrm-core/pull/9735) and + [177](https://github.com/civicrm/civicrm-packages/pull/177))** + + Database query performance is improved by only running strings through + `sprintf()` when actually necessary. + +- **Extension.download API - Allow downloading without installing + ([9898](https://github.com/civicrm/civicrm-core/pull/9898))** + + The Extension.download API still defaults to downloading and installing an + extension, but a new parameter `install` can be set to `FALSE` in order to + download without installing. + +- **[CRM-20034](https://issues.civicrm.org/jira/browse/CRM-20034) Support "OR" + params in api get + ([9844](https://github.com/civicrm/civicrm-core/pull/9844))** + + Many entities can now be queried with sets of `OR` parameters, returning rows + that meet one of several criteria. The API Explorer displays the `AND`/`OR` + option when it is available. + + Separately, the Activity.get API now allows for searching by the ID of + attached files and allows for joining on EntityTag. + +- **[CRM-19943](https://issues.civicrm.org/jira/browse/CRM-19943) Improve tag + management UI ([9918](https://github.com/civicrm/civicrm-core/pull/9918) and + [9787](https://github.com/civicrm/civicrm-core/pull/9787))** + + A new drag-and-drop interface allows for editing, nesting, and coloring tags. + +- **[CRM-20061](https://issues.civicrm.org/jira/browse/CRM-20061) Allow 'tables' + as a parameter on the revert api + ([9862](https://github.com/civicrm/civicrm-core/pull/9862))** + + This adds the opportunity to specify which tables to revert for a logged + change. + +### CiviContribute + +- **[CRM-20158](https://issues.civicrm.org/jira/browse/CRM-20158) Store card + type and last 4 digits of credit card + ([9876](https://github.com/civicrm/civicrm-core/pull/9876)) (Preliminary + work)** + + The `civicrm_financial_trxn` table now contains fields to store credit card + type (e.g. Visa, MasterCard, etc.) and the last four digits of the card + number, if available. The fields are not yet used by any functions. + +- **[CRM-20022](https://issues.civicrm.org/jira/browse/CRM-20022) Add Batch + Title to Columns, Grouping tabs on Contribution Summary report + ([9838](https://github.com/civicrm/civicrm-core/pull/9838))** + + The Contribution Summary report now has an option to display the title of the + corresponding financial transaction batch. + +### CiviEvent + +- **[CRM-19999](https://issues.civicrm.org/jira/browse/CRM-19999) Soften error + message when registration is closed for an event + ([9823](https://github.com/civicrm/civicrm-core/pull/9823))** + + CiviCRM now says "Sorry" when you attempt to register for an event where + registration is closed. + +### CiviMail + +- **[CRM-20196](https://issues.civicrm.org/jira/browse/CRM-20196) Add a useful + message when the user didn't setup bounce processing properly + ([9906](https://github.com/civicrm/civicrm-core/pull/9906))** + + If you fail to set a domain in the Mail Accounts and send a message through + CiviMail, a log message will note the situation. + +### Backdrop Integration + +- **Add a default layout for CiviCRM admin and ability to configure/set to + default. + ([15](https://github.com/civicrm/civicrm-backdrop/issues/15) and + [20](https://github.com/civicrm/civicrm-backdrop/pull/20))** + + CiviCRM for Backdrop now has a default layout for administration pages. + +## <a name="bugs"></a>Bugs resolved + +### Core CiviCRM + +- **[CRM-19929](https://issues.civicrm.org/jira/browse/CRM-19929) Implement pre + hook for entityTag + ([9733](https://github.com/civicrm/civicrm-core/pull/9733))** + + Updates to `civicrm_entity_tag`--tagging or untagging a contact or + activity--now invoke `hook_civicrm_pre()`. + +- **[CRM-20201](https://issues.civicrm.org/jira/browse/CRM-20201) Manage Tags + page does not work if a tag set does not have created by set + ([9919](https://github.com/civicrm/civicrm-core/pull/9919) and + [9913](https://github.com/civicrm/civicrm-core/pull/9913))** + +- **(Regression) CRM_Mailing_ActionTokens - Degrade gracefully + ([9874](https://github.com/civicrm/civicrm-core/pull/9874))** + + This fixes an issue where scheduled reminders and other non-CiviMail messages + would fail if they inadvertently use CiviMail action tokens. + +- **[CRM-19453](https://issues.civicrm.org/jira/browse/CRM-19453) In Windows + System->Directories fails to display under Joomla + ([9890](https://github.com/civicrm/civicrm-core/pull/9890))** + + This allows Joomla users on Windows to view the Directories settings page + without errors. + +- **[CRM-20144](https://issues.civicrm.org/jira/browse/CRM-20144) API + contact.get group='x' yields ""DB Error: no such field"" + ([9884](https://github.com/civicrm/civicrm-core/pull/9884) and + [9867](https://github.com/civicrm/civicrm-core/pull/9867))** + + This reinstates the feature allowing for contacts to be searched by group + (including smart group) using the API. + +- **Display error message for activity processing + ([9882](https://github.com/civicrm/civicrm-core/pull/9882))** + + The activity processor scheduled job now records the actual error message that + occurred rather than a generic failure message. + +- **ApiExplorer - Fix js error + ([9883](https://github.com/civicrm/civicrm-core/pull/9883))** + +- **[CRM-19693](https://issues.civicrm.org/jira/browse/CRM-19693) Don't show + options for disabled components + ([9459](https://github.com/civicrm/civicrm-core/pull/9459))** + +- **[CRM-19657](https://issues.civicrm.org/jira/browse/CRM-19657) recurring + contribution receipt comes from logged in user + ([9856](https://github.com/civicrm/civicrm-core/pull/9856) and + [9842](https://github.com/civicrm/civicrm-core/pull/9842))** + + This fixes a bug where receipts triggered by an administrator's actions or a + scheduled job now come from system-wide information or the default email + rather than the contact associated with the user who is triggering them. + +- **[CRM-19972](https://issues.civicrm.org/jira/browse/CRM-19972) Add in Post + upgrade message for addition of manage tags permission + ([9808](https://github.com/civicrm/civicrm-core/pull/9808))** + + The "manage tags" permission was added in 4.7.13, but site administrators were + not alerted about it when upgrading. + +- **[CRM-19184](https://issues.civicrm.org/jira/browse/CRM-19184) Activities + target contact list does not truncate + ([9846](https://github.com/civicrm/civicrm-core/pull/9846))** + + When viewing activities, the list of contacts the activity is with should be + limited to the first several. This fixes a regression that listed all the + contacts. + +- **[CRM-18811](https://issues.civicrm.org/jira/browse/CRM-18811) MySQL table + and column aliases can contain spaces + ([8548](https://github.com/civicrm/civicrm-core/pull/8548))** + + This fixes a problem displaying profiles that have location details for a + location type that contains a space. + +- **[CRM-20015](https://issues.civicrm.org/jira/browse/CRM-20015) token values + with ampersand cause error when generating docx letter + ([9834](https://github.com/civicrm/civicrm-core/pull/9834))** + +- **[CRM-19950](https://issues.civicrm.org/jira/browse/CRM-19950) Wrong param + passed to checkPermission function + ([9832](https://github.com/civicrm/civicrm-core/pull/9832) and + [9810](https://github.com/civicrm/civicrm-core/pull/9810))** + +- **[CRM-18464](https://issues.civicrm.org/jira/browse/CRM-18464) Database Error + upgrading to Civicrm 4.7 + ([9679](https://github.com/civicrm/civicrm-core/pull/9679))** + + Some legacy sites had a foreign key from `civicrm_action_schedule` to + `mapping_id` set as an index rather than a proper foreign key. Dropping that + key as part of the upgrade to 4.7.alpha1 resulted in a failed upgrade. The + key is now dropped more safely. + +- **[CRM-19979](https://issues.civicrm.org/jira/browse/CRM-19979) + GroupContact.delete does not work for contacts with status of Pending + ([9797](https://github.com/civicrm/civicrm-core/pull/9797))** + +- **[CRM-19957](https://issues.civicrm.org/jira/browse/CRM-19957) DB Syntax + Error on all Search Form submission + ([9767](https://github.com/civicrm/civicrm-core/pull/9767))** + +- **[CRM-19955](https://issues.civicrm.org/jira/browse/CRM-19955) custom field + image display in contact record retrieve incorrectly + ([9758](https://github.com/civicrm/civicrm-core/pull/9758))** + + This fixes a problem where files uploaded to custom fields were retrieved + according to the ID of the entity they're attached to, not the ID of the files + themselves. + +- **[CRM-19926](https://issues.civicrm.org/jira/browse/CRM-19926) Constituent + Summary Report Filtered by Groups ignores children groups + ([9732](https://github.com/civicrm/civicrm-core/pull/9732))** + +- **[CRM-18427](https://issues.civicrm.org/jira/browse/CRM-18427) Submitted + custom data values not reloaded on form when validation fails + ([9752](https://github.com/civicrm/civicrm-core/pull/9752))** + +- **[CRM-19927](https://issues.civicrm.org/jira/browse/CRM-19927) Error message + when "Add to Group" is pressed with no group selected + ([9731](https://github.com/civicrm/civicrm-core/pull/9731))** + +- **[CRM-19864](https://issues.civicrm.org/jira/browse/CRM-19864) Incorrect URL + in CiviCRM Resources dashlet on Joomla + ([9668](https://github.com/civicrm/civicrm-core/pull/9668))** + + The Configuration Checklist link in the Resources menu was a frontend link in + WordPress and Joomla. + +- **[CRM-20180](https://issues.civicrm.org/jira/browse/CRM-20180) Several + documentation links are malformed + ([9897](https://github.com/civicrm/civicrm-core/pull/9897))** + +- **Handle date formats through metadata (see + [CRM-19490](https://issues.civicrm.org/jira/browse/CRM-19490), + [CRM-18387](https://issues.civicrm.org/jira/browse/CRM-18387), + [CRM-20012](https://issues.civicrm.org/jira/browse/CRM-20012), + [CRM-20011](https://issues.civicrm.org/jira/browse/CRM-20011), + [CRM-15948](https://issues.civicrm.org/jira/browse/CRM-15948), and + [CRM-19911](https://issues.civicrm.org/jira/browse/CRM-19911)) + (([9888](https://github.com/civicrm/civicrm-core/pull/9888), + [9845](https://github.com/civicrm/civicrm-core/pull/9845), + [9843](https://github.com/civicrm/civicrm-core/pull/9843), and + [9830](https://github.com/civicrm/civicrm-core/pull/9830))) (Preliminary work)** + + A variety of problems periodically emerge with date fields, mainly due to the + practically-unique ways of defining and handling each date field. The goal of + this work is to define all date fields through metadata. Changes so far + define the metadata for date fields, but the fields are still generated the + old way. + +- **[CRM-19887](https://issues.civicrm.org/jira/browse/CRM-19887) Activity + Summary report gives DB error on sort by email + ([9690](https://github.com/civicrm/civicrm-core/pull/9690))** + +- **[CRM-19982](https://issues.civicrm.org/jira/browse/CRM-19982) Can't enter + dates in 4.7.16. Can only enter characters in word "birth" + ([9831](https://github.com/civicrm/civicrm-core/pull/9831))** + +- **[CRM-19947](https://issues.civicrm.org/jira/browse/CRM-19947) custom multi + profile: file upload display issue + ([9754](https://github.com/civicrm/civicrm-core/pull/9754))** + + On profiles including fields from multi-record custom data sets, files + uploaded in one record were appearing in other records on the same contact. + +### CiviCase + +- **[CRM-19956](https://issues.civicrm.org/jira/browse/CRM-19956) Moving/Copying + activities between Cases + ([9766](https://github.com/civicrm/civicrm-core/pull/9766))** + + This fixes an issue preventing the selection of a destination case when moving + or copying activities. + +### CiviContribute + +- **[CRM-19830](https://issues.civicrm.org/jira/browse/CRM-19830) Cleanup + contribution search by making non-exportable fields exportable + ([9718](https://github.com/civicrm/civicrm-core/pull/9718))** + +- **[CRM-19793](https://issues.civicrm.org/jira/browse/CRM-19793) Redirect + payment processors that fail result in ugly fatal - be prettier + ([9762](https://github.com/civicrm/civicrm-core/pull/9762))** + +- **[CRM-19949](https://issues.civicrm.org/jira/browse/CRM-19949) Notice appear + when setup profiles contain common field with contribution page + ([9753](https://github.com/civicrm/civicrm-core/pull/9753))** + +- **[CRM-19881](https://issues.civicrm.org/jira/browse/CRM-19881): Time + clobbered in receive_date and trxn_date for api contribution repeattransaction + and completetransaction + ([9680](https://github.com/civicrm/civicrm-core/pull/9680))** + + The API spec for the contribution `gettransaction` and `repeattransaction` + actions did not contain time, so the receive date and transaction dates were + set to midnight. + +- **[CRM-20145](https://issues.civicrm.org/jira/browse/CRM-20145) line_item with + $0 amount may error when creating civicrm_entity_financial_trxn + ([9866](https://github.com/civicrm/civicrm-core/pull/9866))** + +- **[CRM-20048](https://issues.civicrm.org/jira/browse/CRM-20048) PayPal IPNs + not processed if "receiver_email" != "business" + ([9858](https://github.com/civicrm/civicrm-core/pull/9858))** + + This resolves problems if a site's PayPal account has a `receiver_email` that + is different from the main email address for their business account. CiviCRM + now looks for the `business` email. + +- **[CRM-19908](https://issues.civicrm.org/jira/browse/CRM-19908) Fundamental + Fixes for Tax Math Calculations. + ([9711](https://github.com/civicrm/civicrm-core/pull/9711))** + + This change defers rounding of tax amounts until after being multiplied by an + item's quantity and avoids deriving a tax rate from the amount of tax on a + line item. + +- **[CRM-19517](https://issues.civicrm.org/jira/browse/CRM-19517) Show price + field Options that use disabled Financial Types so they can be edited. + ([9763](https://github.com/civicrm/civicrm-core/pull/9763))** + +- **[CRM-19802](https://issues.civicrm.org/jira/browse/CRM-19802) Contribution + page : missing translation + ([9587](https://github.com/civicrm/civicrm-core/pull/9587))** + + This fixes the wrapping of translatable strings in Javascript within page + templates. + +- **[CRM-19873](https://issues.civicrm.org/jira/browse/CRM-19873) + contribute.repeattransaction fails when contribution_recur_id is a test + recurring contribtuion + ([9674](https://github.com/civicrm/civicrm-core/pull/9674))** + +### CiviEvent + +- **[CRM-20004](https://issues.civicrm.org/jira/browse/CRM-20004) Event payment + receipt sent twice + ([9933](https://github.com/civicrm/civicrm-core/pull/9933))** + +- **[CRM-19964](https://issues.civicrm.org/jira/browse/CRM-19964) Event + registration creates contribution without line item + ([9774](https://github.com/civicrm/civicrm-core/pull/9774))** + + This situation occurred if a price set was enabled, no price field was + required, and a user registered for the event without any of the price fields + having a value. + +- **[CRM-19918](https://issues.civicrm.org/jira/browse/CRM-19918) Price field + "Active on" date ignored in Edit Event Registration > "Change Selections" + ([9764](https://github.com/civicrm/civicrm-core/pull/9764))** + +- **[CRM-20170](https://issues.civicrm.org/jira/browse/CRM-20170) Fix attendee + count on event summary report for free events + ([9887](https://github.com/civicrm/civicrm-core/pull/9887))** + +- **[CRM-20013](https://issues.civicrm.org/jira/browse/CRM-20013) Localization + for participant status on Event Income Report (Summary) + ([9833](https://github.com/civicrm/civicrm-core/pull/9833))** + + The participant status was showing the field name rather than the translated + label. + +### CiviMail + +- **[CRM-20016](https://issues.civicrm.org/jira/browse/CRM-20016) Fatal error + processing bounces when email_id IS NULL + ([9837](https://github.com/civicrm/civicrm-core/pull/9837))** + +- **[CRM-19924](https://issues.civicrm.org/jira/browse/CRM-19924) Unsubscribe + from a mailing sent to a parent group silently fails + ([9730](https://github.com/civicrm/civicrm-core/pull/9730))** + +### CiviMember + +- **[CRM-19871](https://issues.civicrm.org/jira/browse/CRM-19871) Default + Membership Type not selected - Contribution Form + ([9704](https://github.com/civicrm/civicrm-core/pull/9704))** + + The membership type on contribution pages was defaulting according to weight + rather than the type marked as default. + +- **[CRM-19936](https://issues.civicrm.org/jira/browse/CRM-19936) Membership + line items are duplicated when a membership is created or renewed with + priceset containing multiple memberships + ([9744](https://github.com/civicrm/civicrm-core/pull/9744)) (Partially + fixed)** + + Bug was as described. The cause has been repaired, but the issue is still + pending an action to repair the duplicate line items. + +- **[CRM-20010](https://issues.civicrm.org/jira/browse/CRM-20010) Membership + period_type is required in frontend but not in API. + ([9829](https://github.com/civicrm/civicrm-core/pull/9829))** + +- **[CRM-19945](https://issues.civicrm.org/jira/browse/CRM-19945) + api.contribute.repeattransaction fails to renew membership under certain + conditions ([9792](https://github.com/civicrm/civicrm-core/pull/9792))** + +### Drupal Integration Modules + +- **[CRM-19910](https://issues.civicrm.org/jira/browse/CRM-19910) Drupal view + contact sub type IN query + ([424](https://github.com/civicrm/civicrm-drupal/pull/424))** + + Views was attempting to filter contact subtype as a single-value field rather + than a delimited multi-value field. + +- **[CRM-20051](https://issues.civicrm.org/jira/browse/CRM-20051) Drupal 8 user + view page, Profile information not displaying + ([428](https://github.com/civicrm/civicrm-drupal/pull/428))** + + CiviCRM's implementation of `hook_user_view()` needed to reflect a change to + the hook function signature. + +- **[CRM-19960](https://issues.civicrm.org/jira/browse/CRM-19960) Drupal 8 + Standard Page title does not immediately disappear on contact record screen + ([9770](https://github.com/civicrm/civicrm-core/pull/9770))** + +- **[CRM-19545](https://issues.civicrm.org/jira/browse/CRM-19545) Custom field + groups which do not directly extend the base 'Contact' disappear from Drupal + view after applying patch CRM-18776 + ([417](https://github.com/civicrm/civicrm-drupal/pull/417))** + + This reverts a change for + [CRM-18776](https://issues.civicrm.org/jira/browse/CRM-18776), which in turn + was attempting to fix a bug with custom fields that apply to only certain + types of an entity (e.g. activity types or financial types). That original + issue is still outstanding. + +## <a name="misc"></a>Miscellany + +- **[CRM-20154](https://issues.civicrm.org/jira/browse/CRM-20154) dedupe code + improvement, remove unused autoflip parameter + ([9893](https://github.com/civicrm/civicrm-core/pull/9893) and + [9873](https://github.com/civicrm/civicrm-core/pull/9873))** + + This cleans up code and removes a parameter called `autoFlip` that was never + fully implemented in the merging of duplicate contacts. + +- **[CRM-20181](https://issues.civicrm.org/jira/browse/CRM-20181) Deprecate + CRM_Core_Error::fatal() + ([9900](https://github.com/civicrm/civicrm-core/pull/9900))** + +- **MailingGroup API - Tighten up deprecations + ([9892](https://github.com/civicrm/civicrm-core/pull/9892))** + +- **More test output on intermittant error + ([9871](https://github.com/civicrm/civicrm-core/pull/9871))** + + A test of reverting tables now sleeps for a second. + +- **Remove mispelt param. + ([9853](https://github.com/civicrm/civicrm-core/pull/9853))** + +- **remove markdown files in /docs + ([9771](https://github.com/civicrm/civicrm-core/pull/9771))** + +- **civicrm_webtest.install - Restore access to edit message templates and tags + ([9785](https://github.com/civicrm/civicrm-core/pull/9785))** + +- **Update Test generated examples + ([9798](https://github.com/civicrm/civicrm-core/pull/9798))** + +- **[CRM-20007](https://issues.civicrm.org/jira/browse/CRM-20007) + RepeatTransaction API does not use the Payment Processor's payment Instrument + to determine Payment Instrument + ([9826](https://github.com/civicrm/civicrm-core/pull/9826))** + +## <a name="credits"></a>Credits + +This release was developed by the following code authors: + +AGH Strategies - Andrew Hunt; Australian Greens - Seamus Lee; Chanun +Chirattikanon; CiviCRM - Coleman Watts, Kurund Jalmi, Monish Deb, Tim Otten; +Francesc Bassas i Bullich; Freeform Solutions - Herb van den Dool; Fuzion - +Chris Burgess, Eileen McNaughton; Hartmann Computer Consulting - Peter Hartmann; +JMA Consulting - Edsel Lopez, Pradeep Nayak; John Kingsnorth; Lighthouse Design +and Consulting - Brian Shaughnessy; Matthew Wire; MongoDB - A. Jesse Jiryu +Davis; Sean Madsen; Semper IT - Karin Gerritsen; Skvare - Mark Hanna; Stephen +Palmstrom; Wikimedia Foundation - Eileen McNaughton + +Most authors also reviewed code for this release; in addition, the following +reviewers contributed their comments: + +Agileware - Agileware Team; Andrew Cormick-Dockery; Andrew McNaughton; Andrew +Thompson; Blackfly Solutions - Alan Dixon; Borislav Zlatanov; Circle Interactive - +Dave Jenkins; City of Winnipeg, Manitoba - Matt Allard; CiviCoop - Jaap Jansma; +CiviCRM - Jitendra Purohit, Yashodha Chaku; CiviDesk - Nicolas Ganivet, Steve +Kessler, Sunil Pawar; CompuCorp - Alessandro Verdura, Guanhuan Chen; Coop +SymbioTIC - Mathieu Lutfy, Stéphane Lussier; Davi Alexandre; Erich Schulz; +Jesper Angelo; JMA Consulting - Joe Murray, Jon Goldberg; Joinery - Allen Shaw; +Klangsoft - David Reedy Jr; Korlon - Stuart Gaston; MC3 - Graham Mitchell; +Monadnock Developmental Services - Charlie Wilder; Oxfam Germany - Thomas +Schüttler; Palante Technology Cooperative - Joseph Lacey; Progressive Technology +Project - Jamie McClelland; Skylark Technology - Owen Pearson; Spry Digital - +Ellen Hendricks; Squiffle Consulting - Aidan Saunders; Systopia - Björn Endres; +Tadpole Collective - Kevin Cristiano; Third Sector Design - Michael McAndrew; +Upleaf - Osvaldo Gomez; Vakees K; Valéry Gouleau; Veda Consulting - Kajakaran +Balakrishnan; diff --git a/civicrm/settings/Core.setting.php b/civicrm/settings/Core.setting.php index 0b35e75822..eaa0fe10fb 100644 --- a/civicrm/settings/Core.setting.php +++ b/civicrm/settings/Core.setting.php @@ -918,4 +918,18 @@ return array( 'description' => ts('Default to only loading matches against this number of contacts'), 'help_text' => ts('Deduping larger databases can crash the server. By configuring a limit other than 0 here the dedupe query will only search for matches against a limited number of contacts.'), ), + 'syncCMSEmail' => array( + 'group_name' => 'CiviCRM Preferences', + 'group' => 'core', + 'name' => 'syncCMSEmail', + 'type' => 'Boolean', + 'quick_form_type' => 'YesNo', + 'default' => 1, + 'add' => '4.7', + 'title' => 'Sync CMS Email', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => 'If enabled, then CMS email id will be syncronised with CiviCRM contacts\'s primary email.', + 'help_text' => NULL, + ), ); diff --git a/civicrm/sql/civicrm.mysql b/civicrm/sql/civicrm.mysql index 34e3ef590f..f1d3a1be5a 100644 --- a/civicrm/sql/civicrm.mysql +++ b/civicrm/sql/civicrm.mysql @@ -4130,7 +4130,9 @@ CREATE TABLE `civicrm_financial_trxn` ( `status_id` int unsigned COMMENT 'pseudo FK to civicrm_option_value of contribution_status_id option_group', `payment_processor_id` int unsigned COMMENT 'Payment Processor for this financial transaction', `payment_instrument_id` int unsigned COMMENT 'FK to payment_instrument option group values', - `check_number` varchar(255) COMMENT 'Check number' + `card_type` int unsigned COMMENT 'FK to accept_creditcard option group values', + `check_number` varchar(255) COMMENT 'Check number', + `pan_truncation` int unsigned COMMENT 'Last 4 digits of credit card' , PRIMARY KEY ( `id` ) diff --git a/civicrm/sql/civicrm_data.mysql b/civicrm/sql/civicrm_data.mysql index ea344dffd9..af17d54251 100644 --- a/civicrm/sql/civicrm_data.mysql +++ b/civicrm/sql/civicrm_data.mysql @@ -6290,7 +6290,7 @@ INSERT INTO civicrm_uf_field ( 10, 'receive_date', 1, 1, 4, 'User and User Admin Only', 0, 0, NULL, 'Received', 'Contribution', NULL, NULL ), ( 10, 'contribution_source', 0, 0, 5, 'User and User Admin Only', 0, 0, NULL, 'Source', 'Contribution', NULL, NULL ), ( 10, 'payment_instrument', 0, 0, 6, 'User and User Admin Only', 0, 0, NULL, 'Payment Method', 'Contribution', NULL, NULL ), - ( 10, 'check_number', 0, 0, 7, 'User and User Admin Only', 0, 0, NULL, 'Check Number', 'Contribution', NULL, NULL ), + ( 10, 'contribution_check_number', 0, 0, 7, 'User and User Admin Only', 0, 0, NULL, 'Check Number', 'Contribution', NULL, NULL ), ( 10, 'send_receipt', 0, 0, 8, 'User and User Admin Only', 0, 0, NULL, 'Send Receipt', 'Contribution', NULL, NULL ), ( 10, 'invoice_id', 0, 0, 9, 'User and User Admin Only', 0, 0, NULL, 'Invoice ID', 'Contribution', NULL, NULL ), ( 10, 'soft_credit', 0, 0, 10, 'User and User Admin Only', 0, 0, NULL, 'Soft Credit', 'Contribution', NULL, NULL ), @@ -6305,7 +6305,7 @@ INSERT INTO civicrm_uf_field ( 11, 'total_amount', 0, 1, 8, 'User and User Admin Only', 0, 0, NULL, 'Amount', 'Membership', NULL, NULL ), ( 11, 'receive_date', 1, 1, 9, 'User and User Admin Only', 0, 0, NULL, 'Received', 'Membership', NULL, NULL ), ( 11, 'payment_instrument', 0, 0, 10, 'User and User Admin Only', 0, 0, NULL, 'Payment Method', 'Membership', NULL, NULL ), - ( 11, 'check_number', 0, 0, 11, 'User and User Admin Only', 0, 0, NULL, 'Check Number', 'Membership', NULL, NULL ), + ( 11, 'contribution_check_number', 0, 0, 11, 'User and User Admin Only', 0, 0, NULL, 'Check Number', 'Membership', NULL, NULL ), ( 11, 'contribution_status_id', 1, 1, 12, 'User and User Admin Only', 0, 0, NULL, 'Payment Status', 'Membership', NULL, NULL ), ( 11, 'soft_credit', 0, 0, 13, 'User and User Admin Only', 0, 0, NULL, 'Soft Credit', 'Membership', NULL, NULL ), ( 11, 'soft_credit_type', 0, 0, 14, 'User and User Admin Only', 0, 0, NULL, 'Soft Credit Type', 'Membership', NULL, NULL ), @@ -23854,4 +23854,4 @@ INSERT INTO `civicrm_report_instance` VALUES ( @domainID, 'Survey Details', 'survey/detail', 'Detailed report for canvassing, phone-banking, walk lists or other surveys.', 'access CiviReport', 'a:39:{s:6:"fields";a:2:{s:9:"sort_name";s:1:"1";s:6:"result";s:1:"1";}s:22:"assignee_contact_id_op";s:2:"eq";s:25:"assignee_contact_id_value";s:0:"";s:12:"sort_name_op";s:3:"has";s:15:"sort_name_value";s:0:"";s:17:"street_number_min";s:0:"";s:17:"street_number_max";s:0:"";s:16:"street_number_op";s:3:"lte";s:19:"street_number_value";s:0:"";s:14:"street_name_op";s:3:"has";s:17:"street_name_value";s:0:"";s:15:"postal_code_min";s:0:"";s:15:"postal_code_max";s:0:"";s:14:"postal_code_op";s:3:"lte";s:17:"postal_code_value";s:0:"";s:7:"city_op";s:3:"has";s:10:"city_value";s:0:"";s:20:"state_province_id_op";s:2:"in";s:23:"state_province_id_value";a:0:{}s:13:"country_id_op";s:2:"in";s:16:"country_id_value";a:0:{}s:12:"survey_id_op";s:2:"in";s:15:"survey_id_value";a:0:{}s:12:"status_id_op";s:2:"eq";s:15:"status_id_value";s:1:"1";s:11:"custom_1_op";s:2:"in";s:14:"custom_1_value";a:0:{}s:11:"custom_2_op";s:2:"in";s:14:"custom_2_value";a:0:{}s:17:"custom_3_relative";s:1:"0";s:13:"custom_3_from";s:0:"";s:11:"custom_3_to";s:0:"";s:11:"description";s:75:"Detailed report for canvassing, phone-banking, walk lists or other surveys.";s:13:"email_subject";s:0:"";s:8:"email_to";s:0:"";s:8:"email_cc";s:0:"";s:10:"permission";s:17:"access CiviReport";s:6:"groups";s:0:"";s:9:"domain_id";i:1;}'); -UPDATE civicrm_domain SET version = '4.7.16'; +UPDATE civicrm_domain SET version = '4.7.17'; diff --git a/civicrm/sql/civicrm_generated.mysql b/civicrm/sql/civicrm_generated.mysql index 7ccbdf26e1..8e692636fb 100644 --- a/civicrm/sql/civicrm_generated.mysql +++ b/civicrm/sql/civicrm_generated.mysql @@ -399,7 +399,7 @@ UNLOCK TABLES; LOCK TABLES `civicrm_domain` WRITE; /*!40000 ALTER TABLE `civicrm_domain` DISABLE KEYS */; -INSERT INTO `civicrm_domain` (`id`, `name`, `description`, `config_backend`, `version`, `contact_id`, `locales`, `locale_custom_strings`) VALUES (1,'Default Domain Name',NULL,NULL,'4.7.16',1,NULL,'a:1:{s:5:\"en_US\";a:0:{}}'); +INSERT INTO `civicrm_domain` (`id`, `name`, `description`, `config_backend`, `version`, `contact_id`, `locales`, `locale_custom_strings`) VALUES (1,'Default Domain Name',NULL,NULL,'4.7.17',1,NULL,'a:1:{s:5:\"en_US\";a:0:{}}'); /*!40000 ALTER TABLE `civicrm_domain` ENABLE KEYS */; UNLOCK TABLES; @@ -1402,7 +1402,7 @@ UNLOCK TABLES; LOCK TABLES `civicrm_uf_field` WRITE; /*!40000 ALTER TABLE `civicrm_uf_field` DISABLE KEYS */; -INSERT INTO `civicrm_uf_field` (`id`, `uf_group_id`, `field_name`, `is_active`, `is_view`, `is_required`, `weight`, `help_post`, `help_pre`, `visibility`, `in_selector`, `is_searchable`, `location_type_id`, `phone_type_id`, `website_type_id`, `label`, `field_type`, `is_reserved`, `is_multi_summary`) VALUES (1,1,'first_name',1,0,1,1,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'First Name','Individual',0,0),(2,1,'last_name',1,0,1,2,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Last Name','Individual',0,0),(3,1,'street_address',1,0,0,3,NULL,NULL,'User and User Admin Only',0,0,1,NULL,NULL,'Street Address (Home)','Contact',0,0),(4,1,'city',1,0,0,4,NULL,NULL,'User and User Admin Only',0,0,1,NULL,NULL,'City (Home)','Contact',0,0),(5,1,'postal_code',1,0,0,5,NULL,NULL,'User and User Admin Only',0,0,1,NULL,NULL,'Postal Code (Home)','Contact',0,0),(6,1,'country',1,0,0,6,NULL,NULL,'User and User Admin Only',0,0,1,NULL,NULL,'Country (Home)','Contact',0,0),(7,1,'state_province',1,0,0,7,NULL,NULL,'User and User Admin Only',0,0,1,NULL,NULL,'State (Home)','Contact',0,0),(8,2,'first_name',1,0,1,1,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'First Name','Individual',0,0),(9,2,'last_name',1,0,1,2,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Last Name','Individual',0,0),(10,2,'email',1,0,1,3,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Email Address','Contact',0,0),(11,3,'participant_status',1,0,1,1,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Participant Status','Participant',1,0),(12,4,'first_name',1,0,1,1,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'First Name','Individual',0,0),(13,4,'last_name',1,0,1,2,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Last Name','Individual',0,0),(14,4,'email',1,0,0,3,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Email Address','Contact',0,0),(15,5,'organization_name',1,0,1,2,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Organization Name','Organization',0,0),(16,5,'email',1,0,0,3,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Email Address','Contact',0,0),(17,6,'household_name',1,0,1,2,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Household Name','Household',0,0),(18,6,'email',1,0,0,3,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Email Address','Contact',0,0),(19,7,'phone',1,0,1,1,NULL,NULL,'User and User Admin Only',0,0,1,1,NULL,'Home Phone','Contact',0,0),(20,7,'phone',1,0,1,2,NULL,NULL,'User and User Admin Only',0,0,1,2,NULL,'Home Mobile','Contact',0,0),(21,7,'street_address',1,0,1,3,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Primary Address','Contact',0,0),(22,7,'city',1,0,1,4,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'City','Contact',0,0),(23,7,'state_province',1,0,1,5,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'State','Contact',0,0),(24,7,'postal_code',1,0,1,6,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Postal Code','Contact',0,0),(25,7,'email',1,0,1,7,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Primary Email','Contact',0,0),(26,7,'group',1,0,1,8,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Groups','Contact',0,0),(27,7,'tag',1,0,1,9,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Tags','Contact',0,0),(28,7,'gender_id',1,0,1,10,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Gender','Individual',0,0),(29,7,'birth_date',1,0,1,11,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Date of Birth','Individual',0,0),(30,8,'street_address',1,0,1,1,NULL,NULL,'User and User Admin Only',0,0,1,NULL,NULL,'Street Address (Home)','Contact',1,0),(31,8,'city',1,0,1,2,NULL,NULL,'User and User Admin Only',0,0,1,NULL,NULL,'City (Home)','Contact',1,0),(32,8,'postal_code',1,0,0,3,NULL,NULL,'User and User Admin Only',0,0,1,NULL,NULL,'Postal Code (Home)','Contact',0,0),(33,8,'country',1,0,0,4,NULL,NULL,'User and User Admin Only',0,0,1,NULL,NULL,'Country (Home)','Contact',0,0),(34,8,'state_province',1,0,0,5,NULL,NULL,'User and User Admin Only',0,0,1,NULL,NULL,'State (Home)','Contact',0,0),(35,9,'organization_name',1,0,1,1,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Organization Name','Organization',0,0),(36,9,'phone',1,0,1,2,NULL,NULL,'User and User Admin Only',0,0,3,1,NULL,'Phone (Main) ','Contact',0,0),(37,9,'email',1,0,1,3,NULL,NULL,'User and User Admin Only',0,0,3,NULL,NULL,'Email (Main) ','Contact',0,0),(38,9,'street_address',1,0,1,4,NULL,NULL,'User and User Admin Only',0,0,3,NULL,NULL,'Street Address','Contact',0,0),(39,9,'city',1,0,1,5,NULL,NULL,'User and User Admin Only',0,0,3,NULL,NULL,'City','Contact',0,0),(40,9,'postal_code',1,0,1,6,NULL,NULL,'User and User Admin Only',0,0,3,NULL,NULL,'Postal Code','Contact',0,0),(41,9,'country',1,0,1,7,NULL,NULL,'User and User Admin Only',0,0,3,NULL,NULL,'Country','Contact',0,0),(42,9,'state_province',1,0,1,8,NULL,NULL,'User and User Admin Only',0,0,3,NULL,NULL,'State/Province','Contact',0,0),(43,10,'financial_type',1,0,0,1,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Financial Type','Contribution',1,0),(44,10,'total_amount',1,0,0,2,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Amount','Contribution',1,0),(45,10,'contribution_status_id',1,0,1,3,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Status','Contribution',1,0),(46,10,'receive_date',1,0,1,4,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Received','Contribution',1,0),(47,10,'contribution_source',1,0,0,5,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Source','Contribution',0,0),(48,10,'payment_instrument',1,0,0,6,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Payment Method','Contribution',0,0),(49,10,'check_number',1,0,0,7,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Check Number','Contribution',0,0),(50,10,'send_receipt',1,0,0,8,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Send Receipt','Contribution',0,0),(51,10,'invoice_id',1,0,0,9,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Invoice ID','Contribution',0,0),(52,10,'soft_credit',1,0,0,10,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Soft Credit','Contribution',0,0),(53,10,'soft_credit_type',1,0,0,11,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Soft Credit Type','Contribution',0,0),(54,11,'membership_type',1,0,1,1,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Membership Type','Membership',1,0),(55,11,'join_date',1,0,1,2,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Member Since','Membership',1,0),(56,11,'membership_start_date',1,0,0,3,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Start Date','Membership',1,0),(57,11,'membership_end_date',1,0,0,4,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'End Date','Membership',1,0),(58,11,'membership_source',1,0,0,5,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Source','Membership',0,0),(59,11,'send_receipt',1,0,0,6,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Send Receipt','Membership',0,0),(60,11,'financial_type',1,0,0,7,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Financial Type','Membership',1,0),(61,11,'total_amount',1,0,0,8,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Amount','Membership',1,0),(62,11,'receive_date',1,0,1,9,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Received','Membership',1,0),(63,11,'payment_instrument',1,0,0,10,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Payment Method','Membership',0,0),(64,11,'check_number',1,0,0,11,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Check Number','Membership',0,0),(65,11,'contribution_status_id',1,0,1,12,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Payment Status','Membership',1,0),(66,11,'soft_credit',1,0,0,13,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Soft Credit','Membership',0,0),(67,11,'soft_credit_type',1,0,0,14,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Soft Credit Type','Membership',0,0),(68,12,'first_name',1,0,1,1,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'First Name','Individual',0,0),(69,12,'last_name',1,0,1,2,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Last Name','Individual',0,0),(70,12,'email',1,0,1,3,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Email Address','Contact',0,0),(71,13,'prefix_id',1,0,0,1,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Individual Prefix','Individual',1,0),(72,13,'first_name',1,0,1,2,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'First Name','Individual',1,0),(73,13,'last_name',1,0,1,3,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Last Name','Individual',1,0),(74,13,'email',1,0,0,4,NULL,NULL,'User and User Admin Only',0,0,1,NULL,NULL,'Email Address','Contact',1,0); +INSERT INTO `civicrm_uf_field` (`id`, `uf_group_id`, `field_name`, `is_active`, `is_view`, `is_required`, `weight`, `help_post`, `help_pre`, `visibility`, `in_selector`, `is_searchable`, `location_type_id`, `phone_type_id`, `website_type_id`, `label`, `field_type`, `is_reserved`, `is_multi_summary`) VALUES (1,1,'first_name',1,0,1,1,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'First Name','Individual',0,0),(2,1,'last_name',1,0,1,2,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Last Name','Individual',0,0),(3,1,'street_address',1,0,0,3,NULL,NULL,'User and User Admin Only',0,0,1,NULL,NULL,'Street Address (Home)','Contact',0,0),(4,1,'city',1,0,0,4,NULL,NULL,'User and User Admin Only',0,0,1,NULL,NULL,'City (Home)','Contact',0,0),(5,1,'postal_code',1,0,0,5,NULL,NULL,'User and User Admin Only',0,0,1,NULL,NULL,'Postal Code (Home)','Contact',0,0),(6,1,'country',1,0,0,6,NULL,NULL,'User and User Admin Only',0,0,1,NULL,NULL,'Country (Home)','Contact',0,0),(7,1,'state_province',1,0,0,7,NULL,NULL,'User and User Admin Only',0,0,1,NULL,NULL,'State (Home)','Contact',0,0),(8,2,'first_name',1,0,1,1,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'First Name','Individual',0,0),(9,2,'last_name',1,0,1,2,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Last Name','Individual',0,0),(10,2,'email',1,0,1,3,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Email Address','Contact',0,0),(11,3,'participant_status',1,0,1,1,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Participant Status','Participant',1,0),(12,4,'first_name',1,0,1,1,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'First Name','Individual',0,0),(13,4,'last_name',1,0,1,2,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Last Name','Individual',0,0),(14,4,'email',1,0,0,3,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Email Address','Contact',0,0),(15,5,'organization_name',1,0,1,2,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Organization Name','Organization',0,0),(16,5,'email',1,0,0,3,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Email Address','Contact',0,0),(17,6,'household_name',1,0,1,2,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Household Name','Household',0,0),(18,6,'email',1,0,0,3,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Email Address','Contact',0,0),(19,7,'phone',1,0,1,1,NULL,NULL,'User and User Admin Only',0,0,1,1,NULL,'Home Phone','Contact',0,0),(20,7,'phone',1,0,1,2,NULL,NULL,'User and User Admin Only',0,0,1,2,NULL,'Home Mobile','Contact',0,0),(21,7,'street_address',1,0,1,3,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Primary Address','Contact',0,0),(22,7,'city',1,0,1,4,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'City','Contact',0,0),(23,7,'state_province',1,0,1,5,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'State','Contact',0,0),(24,7,'postal_code',1,0,1,6,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Postal Code','Contact',0,0),(25,7,'email',1,0,1,7,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Primary Email','Contact',0,0),(26,7,'group',1,0,1,8,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Groups','Contact',0,0),(27,7,'tag',1,0,1,9,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Tags','Contact',0,0),(28,7,'gender_id',1,0,1,10,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Gender','Individual',0,0),(29,7,'birth_date',1,0,1,11,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Date of Birth','Individual',0,0),(30,8,'street_address',1,0,1,1,NULL,NULL,'User and User Admin Only',0,0,1,NULL,NULL,'Street Address (Home)','Contact',1,0),(31,8,'city',1,0,1,2,NULL,NULL,'User and User Admin Only',0,0,1,NULL,NULL,'City (Home)','Contact',1,0),(32,8,'postal_code',1,0,0,3,NULL,NULL,'User and User Admin Only',0,0,1,NULL,NULL,'Postal Code (Home)','Contact',0,0),(33,8,'country',1,0,0,4,NULL,NULL,'User and User Admin Only',0,0,1,NULL,NULL,'Country (Home)','Contact',0,0),(34,8,'state_province',1,0,0,5,NULL,NULL,'User and User Admin Only',0,0,1,NULL,NULL,'State (Home)','Contact',0,0),(35,9,'organization_name',1,0,1,1,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Organization Name','Organization',0,0),(36,9,'phone',1,0,1,2,NULL,NULL,'User and User Admin Only',0,0,3,1,NULL,'Phone (Main) ','Contact',0,0),(37,9,'email',1,0,1,3,NULL,NULL,'User and User Admin Only',0,0,3,NULL,NULL,'Email (Main) ','Contact',0,0),(38,9,'street_address',1,0,1,4,NULL,NULL,'User and User Admin Only',0,0,3,NULL,NULL,'Street Address','Contact',0,0),(39,9,'city',1,0,1,5,NULL,NULL,'User and User Admin Only',0,0,3,NULL,NULL,'City','Contact',0,0),(40,9,'postal_code',1,0,1,6,NULL,NULL,'User and User Admin Only',0,0,3,NULL,NULL,'Postal Code','Contact',0,0),(41,9,'country',1,0,1,7,NULL,NULL,'User and User Admin Only',0,0,3,NULL,NULL,'Country','Contact',0,0),(42,9,'state_province',1,0,1,8,NULL,NULL,'User and User Admin Only',0,0,3,NULL,NULL,'State/Province','Contact',0,0),(43,10,'financial_type',1,0,0,1,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Financial Type','Contribution',1,0),(44,10,'total_amount',1,0,0,2,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Amount','Contribution',1,0),(45,10,'contribution_status_id',1,0,1,3,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Status','Contribution',1,0),(46,10,'receive_date',1,0,1,4,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Received','Contribution',1,0),(47,10,'contribution_source',1,0,0,5,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Source','Contribution',0,0),(48,10,'payment_instrument',1,0,0,6,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Payment Method','Contribution',0,0),(49,10,'contribution_check_number',1,0,0,7,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Check Number','Contribution',0,0),(50,10,'send_receipt',1,0,0,8,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Send Receipt','Contribution',0,0),(51,10,'invoice_id',1,0,0,9,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Invoice ID','Contribution',0,0),(52,10,'soft_credit',1,0,0,10,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Soft Credit','Contribution',0,0),(53,10,'soft_credit_type',1,0,0,11,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Soft Credit Type','Contribution',0,0),(54,11,'membership_type',1,0,1,1,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Membership Type','Membership',1,0),(55,11,'join_date',1,0,1,2,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Member Since','Membership',1,0),(56,11,'membership_start_date',1,0,0,3,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Start Date','Membership',1,0),(57,11,'membership_end_date',1,0,0,4,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'End Date','Membership',1,0),(58,11,'membership_source',1,0,0,5,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Source','Membership',0,0),(59,11,'send_receipt',1,0,0,6,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Send Receipt','Membership',0,0),(60,11,'financial_type',1,0,0,7,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Financial Type','Membership',1,0),(61,11,'total_amount',1,0,0,8,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Amount','Membership',1,0),(62,11,'receive_date',1,0,1,9,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Received','Membership',1,0),(63,11,'payment_instrument',1,0,0,10,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Payment Method','Membership',0,0),(64,11,'contribution_check_number',1,0,0,11,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Check Number','Membership',0,0),(65,11,'contribution_status_id',1,0,1,12,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Payment Status','Membership',1,0),(66,11,'soft_credit',1,0,0,13,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Soft Credit','Membership',0,0),(67,11,'soft_credit_type',1,0,0,14,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Soft Credit Type','Membership',0,0),(68,12,'first_name',1,0,1,1,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'First Name','Individual',0,0),(69,12,'last_name',1,0,1,2,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Last Name','Individual',0,0),(70,12,'email',1,0,1,3,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Email Address','Contact',0,0),(71,13,'prefix_id',1,0,0,1,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Individual Prefix','Individual',1,0),(72,13,'first_name',1,0,1,2,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'First Name','Individual',1,0),(73,13,'last_name',1,0,1,3,NULL,NULL,'User and User Admin Only',0,0,NULL,NULL,NULL,'Last Name','Individual',1,0),(74,13,'email',1,0,0,4,NULL,NULL,'User and User Admin Only',0,0,1,NULL,NULL,'Email Address','Contact',1,0); /*!40000 ALTER TABLE `civicrm_uf_field` ENABLE KEYS */; UNLOCK TABLES; diff --git a/civicrm/templates/CRM/Admin/Form/Setting/UF.tpl b/civicrm/templates/CRM/Admin/Form/Setting/UF.tpl index 77f245749b..a38feec15b 100644 --- a/civicrm/templates/CRM/Admin/Form/Setting/UF.tpl +++ b/civicrm/templates/CRM/Admin/Form/Setting/UF.tpl @@ -41,6 +41,10 @@ </td> </tr> {/if} + <tr class="crm-uf-form-block-syncCMSEmail"> + <td class="label">{$form.syncCMSEmail.label}</td> + <td>{$form.syncCMSEmail.html}</td> + </tr> </table> <div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl" location="bottom"}</div> <div class="spacer"></div> diff --git a/civicrm/templates/CRM/Admin/Page/APIExplorer.js b/civicrm/templates/CRM/Admin/Page/APIExplorer.js index bbcc726095..aa871e7683 100644 --- a/civicrm/templates/CRM/Admin/Page/APIExplorer.js +++ b/civicrm/templates/CRM/Admin/Page/APIExplorer.js @@ -20,8 +20,7 @@ docCodeTpl = _.template($('#doc-code-tpl').html()), joinTpl = _.template($('#join-tpl').html()), - // The following apis do not support the syntax for joins - // FIXME: the solution is to convert these apis to use _civicrm_api3_basic_get + // The following apis do not use Api3SelectQuery so do not support advanced features like joins or OR NO_JOINS = ['Contact', 'Contribution', 'Pledge', 'Participant'], // These types of entityRef don't require any input to open @@ -134,9 +133,10 @@ function addJoinInfo(field, name) { if (field.name === 'entity_id') { - var entityTableParam = name.slice(0, -2) + 'table'; - if (params[entityTableParam]) { - field.FKApiName = getField(entityTableParam).options[params[entityTableParam]]; + var entityTableParam = name.slice(0, -2) + 'table', + entityField = params[entityTableParam] ? getField(entityTableParam) : {}; + if (entityField.options) { + field.FKApiName = entityField.options[params[entityTableParam]]; } } if (field.pseudoconstant && field.pseudoconstant.optionGroupName) { @@ -660,6 +660,7 @@ } }); if (entity && action) { + handleAndOr(); formatQuery(); } } @@ -879,14 +880,14 @@ */ function renderJoinSelector() { $('#api-join').hide(); - if (!_.includes(NO_JOINS, entity) && _.includes(['get', 'getsingle'], action)) { + if (!_.includes(NO_JOINS, entity) && _.includes(['get', 'getsingle', 'getcount'], action)) { var joinable = {}; (function recurse(fields, joinable, prefix, depth, entities) { _.each(fields, function(field) { var name = prefix + field.name; addJoinInfo(field, name); var entity = field.FKApiName; - if (entity) { + if (entity && (field.is_core_field || field.supports_joins)) { joinable[name] = { title: field.title + ' (' + field.FKApiName + ')', entity: entity, @@ -938,6 +939,40 @@ } } + function handleAndOr() { + if (!_.includes(NO_JOINS, entity) && _.includes(['get', 'getsingle', 'getcount'], action)) { + var or = []; + $('tr.api-param-row').each(function() { + if ($(this).next().is('tr.api-param-row') && $('input.api-param-name', this).val()) { + $('.api-and-or', this).show(); + } else { + $(this).removeClass('or').find('.api-and-or').hide(); + } + }); + $('tr.api-param-row.or').each(function() { + var val = $(this).next().find('input.api-param-name').val(); + if (val) { + if ($(this).prev().is('.or')) { + or[or.length - 1].push(val); + } else { + or.push([$('input.api-param-name', this).val(), val]); + } + } + }); + if (or.length) { + params.options = params.options || {}; + params.options.or = or; + } + } else { + $('.api-and-or').hide(); + } + } + + function toggleAndOr() { + $(this).closest('tr').toggleClass('or'); + buildParams(); + } + $(document).ready(function() { // Set up tabs - bind active tab to document hash because... it's cool? document.location.hash = document.location.hash || 'explorer'; @@ -996,7 +1031,13 @@ $(this).closest('tr').remove(); buildParams(); }) - .on('change', 'select.api-chain-entity', getChainedAction); + .on('click', '.api-and-or > span', toggleAndOr) + .on('change', 'select.api-chain-entity', getChainedAction) + .on('sortupdate', buildParams) + .sortable({ + handle: '.api-sort-handle', + items: '.api-chain-row, .api-param-row' + }); $('#api-join').on('change', 'input', onSelectJoin); $('#example-entity').on('change', getExamples); $('#example-action').on('change', getExample); diff --git a/civicrm/templates/CRM/Admin/Page/APIExplorer.tpl b/civicrm/templates/CRM/Admin/Page/APIExplorer.tpl index fea4a10bcd..b2b22bbc87 100644 --- a/civicrm/templates/CRM/Admin/Page/APIExplorer.tpl +++ b/civicrm/templates/CRM/Admin/Page/APIExplorer.tpl @@ -50,6 +50,9 @@ margin-top: 1em; overflow: auto; } + #api-params tr td { + padding-top: 13px; + } #api-params-table th:first-child, #api-params-table td:first-child { width: 35%; @@ -69,6 +72,61 @@ #api-params-table th:first-child + th + th { width: 65% } + #api-params .api-sort-handle { + margin-right: 10px; + cursor: move; + } + #api-params tr td > .crm-i, + #api-params tr td > a .crm-i { + color: lightgrey; + } + #api-params tr:hover td > .crm-i, + #api-params tr:hover td > a .crm-i { + color: grey; + } + #api-params .api-and-or { + margin-left: 1.2em; + font-size: .8em; + position: relative; + top: 5px; + width: 10em; + margin-bottom: -9px; + } + #api-params .api-and-or > span { + padding: 0 1em; + background: white; + cursor: pointer; + } + #api-params .api-or, + #api-params tr.or .api-and { + color: lightgrey; + } + #api-params tr.or .api-or { + color: inherit; + } + #api-params .api-and-or .crm-i { + transform: rotate(180deg); + } + #api-params tr.or .api-and-or .crm-i { + transform: initial; + } + #api-params .api-and-or:hover .crm-i { + color: #2786c2; + } + #api-params tr.or { + border-top: 3px solid lightgrey; + border-left: 3px solid lightgrey; + border-right: 3px solid lightgrey; + } + #api-params tr.or + tr { + border-left: 3px solid lightgrey; + border-right: 3px solid lightgrey; + border-bottom: 3px solid lightgrey; + } + #api-params tr.or + tr.or { + border-top: none; + border-bottom: none; + } #api-generated td:first-child { width: 60px; } @@ -171,13 +229,13 @@ <div id="mainTabContainer"> <ul> <li class="ui-corner-all" title="GUI to build and execute API calls"> - <a href="#explorer-tab">{ts}Explorer{/ts}</a> + <a href="#explorer-tab"><i class="crm-i fa-search"></i> {ts}Explorer{/ts}</a> </li> <li class="ui-corner-all" title="Auto-generated examples from the test suite"> - <a href="#examples-tab">{ts}Examples{/ts}</a> + <a href="#examples-tab"><i class="crm-i fa-book"></i> {ts}Examples{/ts}</a> </li> <li class="ui-corner-all" title="API source-code and code-level documentation"> - <a href="#docs-tab">{ts}Code Docs{/ts}</a> + <a href="#docs-tab"><i class="crm-i fa-code"></i> {ts}Code Docs{/ts}</a> </li> </ul> @@ -303,7 +361,11 @@ {strip} <script type="text/template" id="api-param-tpl"> <tr class="api-param-row"> - <td><input style="width: 100%;" class="crm-form-text api-param-name api-input" value="<%= name %>" placeholder="{ts}Parameter{/ts}" /></td> + <td> + <i class="crm-i api-sort-handle fa-arrows"></i> + <input style="width: 90%;" class="crm-form-text api-param-name api-input" value="<%= name %>" placeholder="{ts}Parameter{/ts}" /> + <div class="api-and-or"><span><span class="api-and">{ts}AND{/ts}</span> <i class="crm-i fa-toggle-on"></i> <span class="api-or">{ts}OR{/ts}</span></span></div> + </td> <td> {literal} <% if (noOps) { %> @@ -357,7 +419,8 @@ <script type="text/template" id="api-chain-tpl"> <tr class="api-chain-row"> <td> - <select style="width: 100%;" class="crm-form-select api-chain-entity"> + <i class="crm-i api-sort-handle fa-arrows"></i> + <select style="width: 90%;" class="crm-form-select api-chain-entity"> <option value=""></option> {foreach from=$entities.values item=entity} <option value="{$entity}" {if !empty($entities.deprecated) && in_array($entity, $entities.deprecated)}class="strikethrough"{/if}> diff --git a/civicrm/templates/CRM/Batch/Form/Entry.js b/civicrm/templates/CRM/Batch/Form/Entry.js index 23bf05aef9..89fcda8db4 100644 --- a/civicrm/templates/CRM/Batch/Form/Entry.js +++ b/civicrm/templates/CRM/Batch/Form/Entry.js @@ -171,6 +171,7 @@ function checkColumns(parentRow) { parentRow.find('div .required').each(function () { //special case to handle contact autocomplete select + // @todo WHY OH WHY is this duplicated on the tpl file? var fieldId = cj(this).attr('id'); if (fieldId.substring(0, 16) == 'primary_contact_') { // if display value is set then make sure we also check if contact id is set diff --git a/civicrm/templates/CRM/Campaign/Form/Task/Interview.tpl b/civicrm/templates/CRM/Campaign/Form/Task/Interview.tpl index 289058760b..e42247fa94 100644 --- a/civicrm/templates/CRM/Campaign/Form/Task/Interview.tpl +++ b/civicrm/templates/CRM/Campaign/Form/Task/Interview.tpl @@ -328,7 +328,7 @@ var surveyActivityIds = {/literal}{$surveyActivityIds}{literal}; if (interview.errors[error]) errorList = errorList + '<li>' + interview.errors[error] + '</li>'; } if ( errorList ) { - var allErrors = '<i class="crm-i fa-exclamation-triangle crm-i-red"></i> ' + ts('Please correct the following errors in the survey fields below:') + '<ul>' + errorList + '</ul>'; + var allErrors = '<i class="crm-i fa-exclamation-triangle crm-i-red"></i> {/literal}{ts}Please correct the following errors in the survey fields below:{/ts}{literal}<ul>' + errorList + '</ul>'; CRM.$('#responseErrors').show( ).html(allErrors); } } diff --git a/civicrm/templates/CRM/Contact/Form/Merge.tpl b/civicrm/templates/CRM/Contact/Form/Merge.tpl index 4541877abf..ca2de4c87a 100644 --- a/civicrm/templates/CRM/Contact/Form/Merge.tpl +++ b/civicrm/templates/CRM/Contact/Form/Merge.tpl @@ -130,9 +130,22 @@ $row.title|substr:0:5 == "Phone"} <td> - {* @TODO check if this is ever an array or a fileName? *} - {* This is on one long line for address formatting *} - {if $row.title|substr:0:7 == "Address"}<span style="white-space: pre" id="main_{$blockName}_{$blockId}">{else}<span id="main_{$blockName}_{$blockId}">{/if}{if !is_array($row.main)}{$row.main}{elseif $row.main.fileName}{$row.main.fileName}{else}{', '|implode:$row.main}{/if}</span> + {strip} + {if $row.title|substr:0:7 == "Address"} + <span style="white-space: pre" id="main_{$blockName}_{$blockId}"> + {else} + <span id="main_{$blockName}_{$blockId}"> + {/if} + {* @TODO check if this is ever an array or a fileName? *} + {if !is_array($row.main)} + {$row.main} + {elseif $row.main.fileName} + {$row.main.fileName} + {else} + {', '|implode:$row.main} + {/if} + </span> + {/strip} </td> <td> @@ -220,10 +233,6 @@ {/if} {/foreach} </table> - <div class='form-item'> - <!--<p>{$form.moveBelongings.html} {$form.moveBelongings.label}</p>--> - <!--<p>{$form.deleteOther.html} {$form.deleteOther.label}</p>--> - </div> <div class="crm-submit-buttons"> {include file="CRM/common/formButtons.tpl" location="bottom"} @@ -239,7 +248,7 @@ /** * Triggered when a 'location' or 'type' destination is changed, and when * the operation or 'set primary' checkboxes are changed. - * + * * Check to see if the 'main' contact record has a corresponding location * block when the destination of a field is changed. Allow existing location * fields to be overwritten with data from the 'other' contact. @@ -388,29 +397,26 @@ } } - CRM.$(function($) { - - $('table td input.form-checkbox').each(function() { - var ele = null; - var element = $(this).attr('id').split('_',3); + /** + * Toggle the location type and the is_primary on & off depending on whether the merge box is ticked. + * + * @param element + */ + function toggleRelatedLocationFields(element) { + relatedElements = CRM.$(element).parent().siblings('td').find('input,select,label,hidden'); + if (CRM.$(element).is(':checked')) { + relatedElements.removeClass('disabled').attr('disabled', false); - switch ( element['1'] ) { - case 'addressee': - ele = '#' + element['0'] + '_' + element['1']; - break; + } + else { + relatedElements.addClass('disabled').attr('disabled', true); + } - case 'email': - case 'postal': - ele = '#' + element['0'] + '_' + element['1'] + '_' + element['2']; - break; - } + } - if( ele ) { - $(this).on('click', function() { - var val = $(this).prop('checked'); - $('input' + ele + ', input' + ele + '_custom').prop('checked', val); - }); - } + CRM.$(function($) { + $('input.crm-form-checkbox[data-is_location]').on('click', function(){ + toggleRelatedLocationFields(this) }); // Show/hide matching data rows @@ -419,6 +425,8 @@ }); // Call mergeBlock whenever a location type is changed + // (This is applied to the body because the inputs can be added dynamically + // to the form, and we need to catch when they change.) $('body').on('change', 'select[id$="locTypeId"],select[id$="typeTypeId"],input[id$="[operation]"],input[id$="[set_other_primary]"]', function(event){ // All the information we need is held in the id, separated by underscores diff --git a/civicrm/templates/CRM/Event/Form/EventFees.tpl b/civicrm/templates/CRM/Event/Form/EventFees.tpl index e481c82a84..002f24e41b 100644 --- a/civicrm/templates/CRM/Event/Form/EventFees.tpl +++ b/civicrm/templates/CRM/Event/Form/EventFees.tpl @@ -24,13 +24,6 @@ +--------------------------------------------------------------------+ *} {assign var=isRecordPayment value=1 } -{if $isFTPermissionDenied} - <script> - {literal} - CRM.alert(ts('You do not have all the permissions needed for this page.'), 'Permission Denied', 'error'); - {/literal} - </script> -{/if} {if $paid} {* We retrieve this tpl when event is selected - keep it empty if event is not paid *} <table class="form-layout"> {if $priceSet} diff --git a/civicrm/templates/CRM/Event/Form/SelfSvcUpdate.tpl b/civicrm/templates/CRM/Event/Form/SelfSvcUpdate.tpl index 746a65f7a8..6792392148 100644 --- a/civicrm/templates/CRM/Event/Form/SelfSvcUpdate.tpl +++ b/civicrm/templates/CRM/Event/Form/SelfSvcUpdate.tpl @@ -56,7 +56,7 @@ $('#action').on('change', function() { selected = $(this).find("option:selected").text(); if (selected == 'Cancel' && contributionID) { - CRM.alert(ts('Cancellations are not refundable.'), 'Warning', 'alert'); + CRM.alert('{/literal}{ts}Cancellations are not refundable.{/ts}{literal}', 'Warning', 'alert'); } }); }); diff --git a/civicrm/templates/CRM/Price/Page/LineItem.tpl b/civicrm/templates/CRM/Price/Page/LineItem.tpl index 9c0c0f365c..d0ab3de21c 100644 --- a/civicrm/templates/CRM/Price/Page/LineItem.tpl +++ b/civicrm/templates/CRM/Price/Page/LineItem.tpl @@ -78,7 +78,7 @@ {if $getTaxDetails} <td class="right">{$line.line_total|crmMoney}</td> {if $line.tax_rate != "" || $line.tax_amount != ""} - <td class="right">{$taxTerm} ({$line.tax_rate|string_format:"%.2f"}%)</td> + <td class="right">{$taxTerm} ({$line.tax_rate|string_format:"%.3f"}%)</td> <td class="right">{$line.tax_amount|crmMoney}</td> {else} <td></td> diff --git a/civicrm/templates/CRM/Tag/Form/Edit.tpl b/civicrm/templates/CRM/Tag/Form/Edit.tpl index 646dd7c519..0f78e0f839 100644 --- a/civicrm/templates/CRM/Tag/Form/Edit.tpl +++ b/civicrm/templates/CRM/Tag/Form/Edit.tpl @@ -42,6 +42,7 @@ <td>{$form.parent_id.html}</td> </tr> {/if} + {if $form.used_for} <tr class="crm-tag-form-block-used_for"> <td class="label">{$form.used_for.label}</td> <td>{$form.used_for.html} <br /> @@ -52,6 +53,7 @@ </span> </td> </tr> + {/if} {if $form.color.html} <tr class="crm-tag-form-block-color"> <td class="label">{$form.color.label}</td> @@ -81,7 +83,7 @@ </table><br /> {/if} {else} - <div class="status">{ts 1=$delName}Are you sure you want to delete <b>%1</b> Tag?{/ts}<br />{ts}This tag will be removed from any currently tagged contacts, and users will no longer be able to assign contacts to this tag.{/ts}</div> + <div class="status">{ts 1=$delName}Are you sure you want to delete <b>%1</b>?{/ts}<br />{ts}This tag will be removed from any currently tagged contacts, and users will no longer be able to assign contacts to this tag.{/ts}</div> {/if} <div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl" location="bottom"}</div> </div> @@ -90,8 +92,9 @@ CRM.$(function($) { var $form = $('form.{/literal}{$form.formClass}{literal}'); function toggleUsedFor() { - $('.crm-tag-form-block-used_for', $form).toggle(!$(this).val()); - if ($(this).val()) { + var value = $(this).val() && $(this).val() !== '0'; + $('.crm-tag-form-block-used_for', $form).toggle(!value); + if (value) { $('select#used_for', $form).val('').change(); } } diff --git a/civicrm/templates/CRM/Tag/Form/Merge.tpl b/civicrm/templates/CRM/Tag/Form/Merge.tpl new file mode 100644 index 0000000000..a62e200a16 --- /dev/null +++ b/civicrm/templates/CRM/Tag/Form/Merge.tpl @@ -0,0 +1,39 @@ +{* + +--------------------------------------------------------------------+ + | CiviCRM version 4.7 | + +--------------------------------------------------------------------+ + | Copyright CiviCRM LLC (c) 2004-2017 | + +--------------------------------------------------------------------+ + | This file is a part of CiviCRM. | + | | + | CiviCRM is free software; you can copy, modify, and distribute it | + | under the terms of the GNU Affero General Public License | + | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. | + | | + | CiviCRM 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 Affero General Public License for more details. | + | | + | You should have received a copy of the GNU Affero General Public | + | License and the CiviCRM Licensing Exception along | + | with this program; if not, contact CiviCRM LLC | + | at info[AT]civicrm[DOT]org. If you have questions about the | + | GNU Affero General Public License or the licensing of CiviCRM, | + | see the CiviCRM license FAQ at http://civicrm.org/licensing | + +--------------------------------------------------------------------+ +*} +{* this template is used for merging tags (admin) *} +<div class="crm-block crm-form-block crm-tag-form-block"> + <div class="status"> + {ts 1=$tags|@count}You are about to combine the following %1 tags into a single tag:{/ts}<br /> + {', '|implode:$tags} + </div> + <table class="form-layout-compressed"> + <tr class="crm-tag-form-block-label"> + <td class="label">{$form.name.label}</td> + <td>{$form.name.html}</td> + </tr> + </table> + <div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl" location="bottom"}</div> +</div> \ No newline at end of file diff --git a/civicrm/templates/CRM/Tag/Form/Tag.tpl b/civicrm/templates/CRM/Tag/Form/Tag.tpl index 817fdddba8..b83dffad9c 100644 --- a/civicrm/templates/CRM/Tag/Form/Tag.tpl +++ b/civicrm/templates/CRM/Tag/Form/Tag.tpl @@ -25,19 +25,6 @@ *} {* this template is used for adding/editing tags *} {literal} -<style> - #tagtree, - #tagtree li.highlighted ul { - background-color: white; - } - #tagtree li.highlighted, - #tagtree li.highlighted-child.jstree-closed { - background-color: #fefcb0; - } - #tagtree ins.jstree-icon { - cursor: pointer; - } -</style> <script type="text/javascript"> (function($, _){{/literal} var entityID={$entityID}, @@ -46,7 +33,7 @@ {literal} CRM.updateContactSummaryTags = function() { var tags = []; - $('#tagtree input:checkbox:checked+span label').each(function() { + $('#tagtree input:checkbox:checked+a label').each(function() { tags.push('<span class="crm-tag-item" style="' + $(this).attr('style') + '" title="' + ($(this).attr('title') || '') + '">' + $(this).text() + '</span>'); }); $('input.crm-contact-tagset').each(function() { @@ -83,8 +70,12 @@ if (childTag) { //load js tree. $("#tagtree").jstree({ - plugins : ["themes", "html_data"], + plugins : ["themes", "html_data", "search"], core: {animation: 100}, + 'search': { + 'case_insensitive' : true, + 'show_only_matches': true + }, themes: { "theme": 'classic', "dots": false, @@ -102,15 +93,37 @@ {literal} $(document).on('change', 'input.crm-contact-tagset', CRM.updateContactSummaryTags); + + $('input[name=filter_tag_tree]', '#Tag').on('keyup change', function() { + $("#tagtree").jstree('search', $(this).val()); + }); }); })(CRM.$, CRM._); {/literal} </script> <div id="Tag" class="view-content"> - <h3>{if !$hideContext}{ts}Tags{/ts}{/if}</h3> - <div id="tagtree"> - {include file="CRM/Tag/Form/Tagtree.tpl" level=1} - </div> - <br /> -{include file="CRM/common/Tagset.tpl"} + <table class=""> + <thead> + <tr> + <th>{ts}Tag Tree{/ts}</th> + {if $tagsetInfo.contact}<th>{ts}Tag Sets{/ts}</th>{/if} + </tr> + </thead> + <tbody> + <tr> + <td> + <input class="crm-form-text big" name="filter_tag_tree" placeholder="{ts}Filter List{/ts}" allowclear="1"/> + <a class="crm-hover-button crm-clear-link" style="visibility:hidden;" title="{ts}Clear{/ts}"><i class="crm-i fa-times"></i></a> + <div id="tagtree"> + {include file="CRM/Tag/Form/Tagtree.tpl" level=1} + </div> + </td> + {if $tagsetInfo.contact} + <td> + {include file="CRM/common/Tagset.tpl"} + </td> + {/if} + </tr> + </tbody> + </table> </div> diff --git a/civicrm/templates/CRM/Tag/Form/Tagtree.tpl b/civicrm/templates/CRM/Tag/Form/Tagtree.tpl index 8102dabb92..5c27022c2a 100644 --- a/civicrm/templates/CRM/Tag/Form/Tagtree.tpl +++ b/civicrm/templates/CRM/Tag/Form/Tagtree.tpl @@ -28,11 +28,11 @@ {foreach from=$tree item="node" key="id"} <li id="tag_{$id}"> <input name="tagList[{$id}]" id="check_{$id}" type="checkbox" {if $node.is_selectable EQ 0}disabled=""{/if} {if $tagged[$id]}checked="checked"{/if}/> - <span> + <a> <label for="check_{$id}" id="tagLabel_{$id}" class="crm-tag-item" {if !empty($allTags.$id.color)}style="background-color: {$allTags.$id.color}; color: {$allTags.$id.color|colorContrast};"{/if} title="{$node.description}"> {$node.name} </label> - </span> + </a> {if $node.children} {* Recurse... *} {include file="CRM/Tag/Form/Tagtree.tpl" tree=$node.children level=$level+1} diff --git a/civicrm/templates/CRM/Tag/Page/Tag.tpl b/civicrm/templates/CRM/Tag/Page/Tag.tpl index dd292d70b9..a5fc9c91d8 100644 --- a/civicrm/templates/CRM/Tag/Page/Tag.tpl +++ b/civicrm/templates/CRM/Tag/Page/Tag.tpl @@ -23,204 +23,510 @@ | see the CiviCRM license FAQ at http://civicrm.org/licensing | +--------------------------------------------------------------------+ *} +<div class="crm-content-block"> + <div class="help"> + {ts 1=', '|implode:$usedFor}Tags are a convenient way to categorize data (%1).{/ts} + {if call_user_func(array('CRM_Core_Permission','check'), 'administer Tagsets')} + <br /> + {ts}Create predefined tags in the main tree, or click the <strong>+</strong> to add a set for free tagging.{/ts} + {/if} + {docURL page="user/organising-your-data/groups-and-tags"} + </div> -{capture assign=docLink}{docURL page="user/organising-your-data/groups-and-tags"}{/capture} - -{if $action eq 1 or $action eq 2 or $action eq 8} - {include file="CRM/Tag/Form/Edit.tpl"} -{else} - <div class="crm-content-block"> - <div class="help"> - {ts 1=$docLink}Tags can be assigned to any contact record, and are a convenient way to find contacts. You can create as many tags as needed to organize and segment your records.{/ts} {$docLink} - </div> - - {if $rows} - <div id="mainTabContainer"> - <ul> - <li class="ui-corner-all crm-tab-button"> - <a href="#tags">{ts}Tags{/ts}</a> - </li> - <li class="ui-corner-all crm-tab-button"> - <a href="#tagsets">{ts}Tag Sets{/ts}</a> - </li> - </ul> - <div id="tags"> - {if !($action eq 1 and $action eq 2)} - <div class="crm-submit-buttons"> - <div class="action-link"> - {crmButton q="action=add&reset=1" id="newTag" icon="plus-circle"}{ts}Add Tag{/ts}{/crmButton} - </div> - </div> - {/if} - {strip} - <table id="tags_table" class="display"> - <thead> - <tr> - <th>{ts}Tag{/ts}</th> - <th>{ts}ID{/ts}</th> - <th id="nosort">{ts}Description{/ts}</th> - <th>{ts}Parent (ID){/ts}</th> - <th>{ts}Used For{/ts}</th> - <th>{ts}Reserved?{/ts}</th> - <th></th> - </tr> - </thead> - {foreach from=$rows item=row key=id } - {if !$row.is_tagset && !$row.is_tagset_child} - <tr class="{if $row.parent_id}child-row{/if} {if $row.grandparent_id}grandchild-row{/if} crm-tag crm-entity" id="tag-{$row.id}"> - <td class="crm-tag-name crm-editable crmf-name" {if $row.color}style="background-color: {$row.color}; color: {$row.color|colorContrast};"{/if}> - {$row.name} - </td> - <td class="crm-tag-id">{$row.id}</td> - <td class="crm-tag-description crm-editable crmf-description">{$row.description} </td> - <td class="crm-tag-parent">{$row.parent}{if $row.parent_id} ({$row.parent_id}){/if}</td> - <td class="crm-tag-used_for">{$row.used_for}</td> - <td class="crm-tag-is_reserved">{if $row.is_reserved}<img src="{$config->resourceBase}i/check.gif" alt="{ts}Reserved{/ts}" />{/if}</td> - <td>{$row.action|replace:'xx':$row.id}</td> - </tr> - {/if} - {/foreach} - </table> - {/strip} - </div> - <div id="tagsets"> - {if !($action eq 1 and $action eq 2) && $adminTagSet} - <div class="crm-submit-buttons"> - <div class="action-link"> - {crmButton q="action=add&reset=1&tagset=1" id="newTagSet" icon="plus-circle"}{ts}Add Tag Set{/ts}{/crmButton} - </div> - </div> - {/if} - {strip} - <table id="tagsets_table" class="display"> - <thead> - <tr> - <th>{ts}Tag{/ts}</th> - <th>{ts}ID{/ts}</th> - <th id="nosort">{ts}Description{/ts}</th> - <th>{ts}Parent (ID){/ts}</th> - <th>{ts}Used For{/ts}</th> - <th>{ts}Reserved?{/ts}</th> - <th></th> - </tr> - </thead> - {foreach from=$rows item=row key=id} - {if $row.is_tagset || $row.is_tagset_child} - <tr class="{if $row.parent_id}child-row{/if} crm-tag crm-entity" id="tag-{$row.id}"> - <td class="crm-tag-name crm-editable crmf-name" {if $row.color}style="background-color: {$row.color}; color: {$row.color|colorContrast};"{/if}> - {$row.name} - </td> - <td class="crm-tag-id">{$row.id}</td> - <td class="crm-tag-description crm-editable crmf-description">{$row.description} </td> - <td class="crm-tag-parent">{$row.parent}{if $row.parent_id} ({$row.parent_id}){/if}</td> - <td class="crm-tag-used_for">{$row.used_for}</td> - <td class="crm-tag-is_reserved">{if $row.is_reserved}<img src="{$config->resourceBase}i/check.gif" alt="{ts}Reserved{/ts}" />{/if}</td> - <td>{$row.action|replace:'xx':$row.id}</td> - </tr> - {/if} - {/foreach} - </table> - {/strip} - </div> - </div> - {if !($action eq 1 and $action eq 2)} - <div class="crm-submit-buttons"> - <div class="action-link"> - {crmButton q="action=add&reset=1" id="newTag" icon="plus-circle"}{ts}Add Tag{/ts}{/crmButton} - {if $adminTagSet} - {crmButton q="action=add&reset=1&tagset=1" id="newTagSet" icon="plus-circle"}{ts}Add Tag Set{/ts}{/crmButton} - {/if} - </div> - </div> + <div id="mainTabContainer"> + <ul> + <li class="ui-corner-all crm-tab-button" title="{ts}Main Tag List{/ts}"> + <a href="#tree"><i class="crm-i fa-tags"></i> {ts}Tag Tree{/ts}</a> + </li> + {foreach from=$tagsets item=set} + <li class="ui-corner-all crm-tab-button {if ($set.is_reserved)}is-reserved{/if}" title="{ts 1=', '|implode:$set.used_for_label}Tag Set for %1{/ts}"> + <a href="#tagset-{$set.id}">{$set.name}</a> + </li> + {/foreach} + {if call_user_func(array('CRM_Core_Permission','check'), 'administer Tagsets')} + <li class="ui-corner-all crm-tab-button" title="{ts}Add Tag Set{/ts}"> + <a href="#new-tagset"><i class="crm-i fa-plus"></i></a> + </li> {/if} - <div id="merge_tag_status"></div> - {include file="CRM/common/jsortable.tpl"} - {else} - <div class="messages status no-popup"> - <div class="icon inform-icon"></div> - {capture assign=crmURL}{crmURL p='civicrm/tag' q="action=add&reset=1"}{/capture} - {ts 1=$crmURL}There are no Tags present. You can <a href='%1'>add one</a>.{/ts} + </ul> + <div id="tree"> + <div class="help"> + {ts}Organize the tag hierarchy by clicking and dragging. Shift-click to select multiple tags to merge/move/delete.{/ts} </div> - {/if} - + </div> + {foreach from=$tagsets item=set} + <div id="tagset-{$set.id}"> + </div> + {/foreach} + <div id="new-tagset"> + </div> </div> - +</div> +{crmAPI entity="Contact" action="getsingle" var="user" return='display_name' id="user_contact_id"} {literal} - <script type="text/javascript"> - CRM.$(function($) { - var tag; - $('#mainTabContainer').tabs(); - $('.merge_tag').click(function(e) { - tag = $(this).crmEditableEntity(); - mergeTagDialog(); - e.preventDefault(); - }); +<script type="text/javascript"> + (function($, _) { + $(function($) { + var $window = $(window), + renderedTabs = ['tree'], + tagSets = {/literal}{$tagsets|@json_encode}{literal}, + user = {/literal}{$user|@json_encode}{literal}, + usedFor = {/literal}{$usedFor|@json_encode}{literal}, + menuHeight = $('#civicrm-menu').height() + 15, + noneSelectedTpl = _.template($('#noneSelectedTpl').html()), + oneSelectedTpl = _.template($('#oneSelectedTpl').html()), + moreSelectedTpl = _.template($('#moreSelectedTpl').html()), + tagsetHelpTpl = _.template($('#tagsetHelpTpl').html()); - function mergeTagDialog() { - var tagUrl = {/literal}"{crmURL p='civicrm/ajax/mergeTagList' h=0}"{literal}; - var title = {/literal}'{ts escape="js" 1="%1"}Merge tag %1 into:{/ts}'{literal}; - CRM.confirm({ - title: ts(title, {1: tag.name}), - message: '<input name="select_merge_tag" class="big" />', - open: function() { - var dialog = this; - $('input[name=select_merge_tag]', dialog) - .crmSelect2({ - placeholder: {/literal}'{ts escape="js"}- select tag -{/ts}'{literal}, - minimumInputLength: 1, - ajax: { - url: tagUrl, - data: function(term) { - return {term: term, fromId: tag.id}; - }, - results: function(response) { - return {results: response}; - } - } - }) - .change(function() { - $('.messages', dialog).remove(); - if ($(this).val() && $(this).select2('data').warning) { - $(dialog).append('<div class="messages status">{/literal}{ts escape='js'}Note: the selected tag is used by additional entities.{/ts}{literal}</div>'); - } - }); - } + function formatTagSet(info) { + info.date = CRM.utils.formatDate(info.created_date); + info.used_for_label = []; + if (undefined !== info.used_for) { + _.each(info.used_for.split(','), function(item) { + info.used_for_label.push(usedFor[item]); + }); + } + } + + _.each(tagSets, formatTagSet); + + function renderTree($panel) { + var plugins, + selected = [], + tagset = $panel.attr('id').split('-')[1] || 0; + + function hasChildren(id) { + var $node = $('.tag-tree', $panel).jstree(true).get_node(id, true); + return !$node.hasClass('jstree-leaf'); + } + + function changeColor() { + var color = $(this).val().toLowerCase(), + id = $(this).closest('.crm-entity').data('id'), + node = $('.tag-tree', $panel).jstree(true).get_node(id); + if (color === '#ffffff') { + node.a_attr.style = ''; + } else { + node.a_attr.style = 'background-color: ' + color + '; color: ' + CRM.utils.colorContrast(color) + ';'; + } + node.data.color = color; + $('.tag-tree', $panel).jstree(true).redraw(true); + CRM.api3('Tag', 'create', {id: id, color: color}, true); + } + + function changeSelection(e, data) { + var tplParams = { + tagset: tagset, + tagsetCount: _.keys(tagSets).length, + adminReserved: CRM.checkPerm('administer reserved tags') + }, + tree = $('.tag-tree', $panel).jstree(true), + $infoBox = $('.tag-info', $panel); + selected = data.selected; + if (!data.selected || !data.selected.length) { + tplParams.is_reserved = tagset ? tagSets[tagset].is_reserved == 1 : false; + tplParams.length = $('.tag-tree li', $panel).length; + tplParams.adminTagsets = CRM.checkPerm('administer Tagsets'); + $infoBox.html(noneSelectedTpl(tplParams)); + } else if (data.selected.length === 1) { + tplParams.usedFor = usedFor; + tplParams.hasChildren = hasChildren(data.node.id); + $infoBox.html(oneSelectedTpl($.extend({}, data.node, tplParams))); + } else { + tplParams.items = data.selected; + tplParams.hasChildren = tplParams.reserved = tplParams.usages = 0; + _.each(data.selected, function(id) { + var node = tree.get_node(id); + tplParams.usages += node.data.usages; + tplParams.reserved += node.data.is_reserved; + tplParams.hasChildren += hasChildren(id) ? 1 : 0; + }); + $infoBox.html(moreSelectedTpl(tplParams)); + } + $infoBox.trigger('crmLoad'); + } + + function clearSelection(e) { + e.preventDefault(); + $('.tag-tree', $panel).jstree(true).deselect_all(); + } + + function changeUsedFor() { + var vals = $('input[name=used_for]:checked', $panel).map(function(i, el) { + return $(el).val(); + }).get(), + id = $(this).closest('.crm-entity').data('id'); + if (vals.length) { + CRM.api3('Tag', 'create', {id: id, used_for: vals}, true); + var node = $('.tag-tree', $panel).jstree(true).get_node(id); + node.data.used_for = vals; + } + } + + function moveTag(e, data) { + if (data.parent != data.old_parent) { + CRM.api3('Tag', 'create', {id: data.node.id, parent_id: data.parent.replace('#', '')}, true); + } + } + + function deleteTagset() { + $('#mainTabContainer').tabs('option', 'active', 0); + $panel.off().remove(); + $("a[href='#tagset-" + tagset + "']").parent().remove(); + $('#mainTabContainer').tabs('refresh'); + } + + function updateTagset(info) { + tagSets[tagset].description = info.description; + tagSets[tagset].name = info.name; + tagSets[tagset].used_for = info.used_for; + tagSets[tagset].is_reserved = info.is_reserved; + formatTagSet(tagSets[tagset]); + $('.help', $panel).remove(); + addHelp(); + } + + function addHelp() { + $panel.prepend(tagsetHelpTpl(tagSets[tagset])); + $("a[href='#tagset-" + tagset + "']").text(tagSets[tagset].name) + .parent().toggleClass('is-reserved', tagSets[tagset].is_reserved == 1) + .attr('title', ts('{/literal}{ts escape='js' 1='%1'}Tag Set for %1{/ts}{literal}', {'1': tagSets[tagset].used_for_label.join(', ')})); + } + + if (tagset) { + addHelp(); + } + + function moveTagDialog(e) { + e.preventDefault(); + var sets = [{key: '0', value: '{/literal}{ts escape='js'}Main Tag Tree{/ts}{literal}'}]; + _.each(tagSets, function(tagSet) { + sets.push({key: tagSet.id, value: tagSet.name}); + }); + CRM.confirm({ + title: '{/literal}{ts escape='js'}Move to Tagset{/ts}{literal}', + message: '<label for="select-tagset">{/literal}{ts escape='js'}Select Tagset{/ts}{literal}: ' + + '<select id="select-tagset" class="crm-select2 big">' + + CRM.utils.renderOptions(sets, tagset) + + '</select>' }) - .on('dialogclose', function() { - $('input[name=select_merge_tag]', this).select2('destroy'); + .on('crmConfirm:yes', function() { + var chosen = parseInt($('#select-tagset').val()); + if (parseInt(tagset) !== chosen) { + var apiCalls = []; + _.each(selected, function(id) { + apiCalls.push(['Tag', 'create', {id: id, parent_id: chosen || ''}]); + }); + $('#mainTabContainer').block(); + CRM.api3(apiCalls, true) + .done(function() { + $('.tag-tree', $panel).jstree(true).refresh(); + $('#mainTabContainer').unblock(); + var $otherPanel = $(chosen ? '#tagset-' + chosen : '#tree'); + if ($('.tag-tree', $otherPanel).length) { + $('.tag-tree', $otherPanel).jstree(true).refresh(); + } + }); + } + }); + } + + $panel + .append('<div class="tag-tree-wrapper"><div class="tag-tree"></div><div class="tag-info"></div></div>') + .on('change', 'input[type=color]', changeColor) + .on('change', 'input[name=used_for]', changeUsedFor) + .on('click', '.clear-tag-selection', clearSelection) + .on('click', '.move-tag-button', moveTagDialog) + .on('click', '.used-for-toggle', function() { + $(this).attr('style', 'display: none !important;').next().show(); }) - .on('crmConfirm:yes', function() { - var toId = $("input[name=select_merge_tag]", this).val(); - if (!toId) { - $("input[name=select_merge_tag]", this).crmError('{/literal}{ts escape='js'}Select a tag{/ts}{literal}'); - return false; + .on('crmPopupFormSuccess crmFormSuccess', function(e, cts, data) { + if ($(e.target).hasClass('tagset-action-delete')) { + deleteTagset(); + } else if ($(e.target).hasClass('tagset-action-update')) { + updateTagset(data.tag); + } else { + $('.tag-tree', $panel).jstree(true).refresh(); } - var postUrl = {/literal}"{crmURL p='civicrm/ajax/mergeTags' h=0 }"{literal}; - var data = {fromId: tag.id, toId: toId, key:{/literal}"{crmKey name='civicrm/ajax/mergeTags'}"{literal}}; - $.ajax({ - type: "POST", - url: postUrl, - data: data, - dataType: "json", - success: function(values) { - if ( values.status == true ) { - $('#tag-' + toId).children('td.crm-tag-used_for').text(values.tagB_used_for); - $('#tag-' + tag.id).html('<td colspan="8"><div class="status message"><div class="icon inform-icon"></div>' + values.message + '</div></td>'); + }); + + plugins = ['wholerow', 'changed']; + if (!tagset) { + // Allow drag-n-drop nesting of the tag tree + plugins.push('dnd'); + } + + $('.tag-tree', $panel) + .on('changed.jstree loaded.jstree', changeSelection) + .on('move_node.jstree', moveTag) + .jstree({ + core: { + data: { + url: CRM.url('civicrm/ajax/tagTree'), + data: function(node) { + return {parent_id: node.id === '#' ? tagset : node.id}; } - } - }); + }, + check_callback: true + }, + plugins: plugins, + dnd: { + copy: false + }, + themes: { + stripes: true, + dots: false + } + }); + } + + function newTagset() { + CRM.loadForm(CRM.url('civicrm/tag/edit', {action: 'add', tagset: 1})) + .on('crmFormSuccess', function(e, data) { + tagSets[data.tag.id] = data.tag; + tagSets[data.tag.id].display_name = user.display_name; + formatTagSet(tagSets[data.tag.id]); + $("#new-tagset").before('<div id="tagset-' + data.tag.id + '">'); + $("a[href='#new-tagset']").parent().before('<li class="ui-corner-all crm-tab-button"><a href="#tagset-' + data.tag.id + '">' + data.tag.name + '</a></li>'); + $('#mainTabContainer').tabs('refresh'); + $('#mainTabContainer').tabs('option', 'active', -2); }); } + + $('#mainTabContainer') + .tabs() + .on("tabsbeforeactivate", function (event, ui) { + var id = $(ui.newPanel).attr('id'); + if (id === 'new-tagset') { + event.preventDefault(); + newTagset(); + return false; + } + if ($.inArray(id, renderedTabs) < 0) { + renderedTabs.push(id); + renderTree(ui.newPanel); + } + }); + + renderTree($('#tree')); + + // Prevent the info box from scrolling offscreen + $window.on('scroll resize', function () { + var $wrapper = $('.tag-tree-wrapper:visible'), + pos = $wrapper.offset(), + $box = $('.tag-info:visible'); + if ($window.scrollTop() + menuHeight > pos.top) { + $box.css({ + position: 'fixed', + top: menuHeight, + right: parseInt($window.width() - (pos.left + $wrapper.width())), + width: parseInt($wrapper.width() * .40) + }); + } else { + $box.removeAttr('style'); + } + }); + }); - </script> - <style type="text/css"> - .crm-container tr.child-row td:first-child { - padding-left: 2em; - } - .crm-container tr.grandchild-row td:first-child { - padding-left: 3em; - } - </style> + })(CRM.$, CRM._); +</script> +<style type="text/css"> + div.tag-tree-wrapper { + position: relative; + min-height: 250px; + } + div.tag-tree { + width: 59%; + } + div.tag-info { + width: 40%; + position: absolute; + top: 5px; + right: 0; + min-height: 100px; + border: 1px solid #aaa; + border-radius: 4px; + box-shadow: 0 0 4px #e3e3e3; + padding: 1em; + box-sizing: border-box; + background: white; + } + div.tag-info .clear-tag-selection { + position: absolute; + top: 10px; + right: 12px; + color: inherit; + opacity: .5; + } + div.tag-info .clear-tag-selection:hover, + div.tag-info .clear-tag-selection:active { + opacity: 1; + } + .tag-tree-wrapper .tag-tree a.crm-tag-item { + border-radius: 3px; + margin: 2px 0; + height: 20px; + line-height: 20px; + font-size: 12px; + padding: 0 3px; + } + #tree a.crm-tag-item { + cursor: move; + } + li.is-reserved > a:after { + content: ' *'; + } + .tag-tree-wrapper ul { + margin: 0; + padding: 0; + } + div.tag-info h4 .crm-editable { + min-width: 60%; + padding: .2em; + } + div.tag-info .crm-editable-enabled { + min-width: 5em; + } + div.tag-info .crm-editable-enabled[data-field=description] { + min-width: 60%; + } + div.tag-info input[type=color] { + cursor: pointer; + } + div.tag-info .tdl { + font-weight: bold; + color: #999; + } + div.tag-info hr { + margin: .2em 0; + } + div.tag-info .crm-submit-buttons { + margin: 10px 0 0; + } +</style> {/literal} -{/if} +<script type="text/template" id="noneSelectedTpl"> + <% if (length) {ldelim} %> + <h4>{ts}None Selected{/ts}</h4> + <hr /> + <p>{ts}Select one or more tags for details.{/ts}</p> + <% {rdelim} else {ldelim} %> + <h4>{ts}Empty Tag Set{/ts}</h4> + <hr /> + <p>{ts}No tags have been created in this set.{/ts}</p> + <% {rdelim} %> + <div class="crm-submit-buttons"> + <a href="{crmURL p="civicrm/tag/edit" q="action=add&parent_id="}<%= tagset || '' %>" class="button crm-popup"> + <span><i class="crm-i fa-plus"></i> {ts}Add Tag{/ts}</span> + </a> + <% if(tagset && adminTagsets) {ldelim} %> + <a href="{crmURL p="civicrm/tag/edit" q="action=update&id="}<%= tagset %>" class="button crm-popup tagset-action-update"> + <span><i class="crm-i fa-pencil"></i> {ts}Edit Set{/ts}</span> + </a> + <% {rdelim} %> + <% if(tagset && !length && adminTagsets && (!is_reserved || adminReserved)) {ldelim} %> + <a href="{crmURL p="civicrm/tag/edit" q="action=delete&id="}<%= tagset %>" class="button crm-popup small-popup tagset-action-delete"> + <span><i class="crm-i fa-trash"></i> {ts}Delete Set{/ts}</span> + </a> + <% {rdelim} %> + </div> +</script> + +<script type="text/template" id="oneSelectedTpl"> + <div class="crm-entity" data-entity="Tag" data-id="<%= id %>"> + <h4> + <input type="color" value="<%= data.color %>" title="{ts}Select color{/ts}"/> + <span class="crm-editable" data-field="name"><%- text %></span> + </h4> + <hr /> + <div><span class="tdl">{ts}Description:{/ts}</span> + <span class="crm-editable" data-field="description"><%- data.description %></span> + </div> + <div><span class="tdl">{ts}Selectable:{/ts}</span> + <span class="crm-editable" data-field="is_selectable" data-type="select"><% if (data.is_selectable) {ldelim} %> {ts}Yes{/ts} <% {rdelim} else {ldelim} %> {ts}No{/ts} <% {rdelim} %></span> + </div> + <div><span class="tdl">{ts}Reserved:{/ts}</span> + <span class="<% if (adminReserved) {ldelim} %>crm-editable<% {rdelim} %>" data-field="is_reserved" data-type="select"><% if (data.is_reserved) {ldelim} %> {ts}Yes{/ts} <% {rdelim} else {ldelim} %> {ts}No{/ts} <% {rdelim} %></span> + </div> + <% if (parent === '#' && !tagset) {ldelim} %> + <div> + <span class="tdl">{ts}Used For:{/ts}</span> + {literal} + <span class="crm-editable-enabled used-for-toggle"> + <% if (!data.used_for.length) { %><i class="crm-i fa-pencil crm-editable-placeholder"></i><% } %> + <% _.forEach(data.used_for, function(key, i) { %><%- (i ? ', ' : '') + usedFor[key] %><% }) %> + </span> + <span style="display: none"> + <% _.forEach(usedFor, function(label, key) { %> + <span style="white-space: nowrap"> + <input type="checkbox" name="used_for" value="<%= key %>" id="<%= id + '_used_for_' + key %>" <% if (data.used_for.indexOf(key) > -1) { %>checked<% } %> /> + <label for="<%= id + '_used_for_' + key %>"><%- label %></label> + </span> + <% }) %> + </span> + {/literal} + </div> + <% {rdelim} %> + <div><span class="tdl">{ts}Usage Count:{/ts}</span> <%= data.usages %></div> + <a class="clear-tag-selection" href="#" title="{ts}Clear selection{/ts}"><i class="crm-i fa-ban"></i></a> + </div> + <div class="crm-submit-buttons"> + <% if(!tagset) {ldelim} %> + <a href="{crmURL p="civicrm/tag/edit" q="action=add&parent_id="}<%= id %>" class="button crm-popup" title="{ts}Create new tag under this one{/ts}"> + <span><i class="crm-i fa-plus"></i> {ts}Add Child{/ts}</span> + </a> + <% {rdelim} %> + <a href="{crmURL p="civicrm/tag/edit" q="action=add&clone_from="}<%= id %>" class="button crm-popup" title="{ts}Duplicate ths tag{/ts}"> + <span><i class="crm-i fa-copy"></i> {ts}Clone Tag{/ts}</span> + </a> + <% if(!data.is_reserved || adminReserved) {ldelim} %> + <% if(tagsetCount) {ldelim} %> + <a href="#move" class="button move-tag-button" title="{ts}Move to a different tagset{/ts}"> + <span><i class="crm-i fa-share-square-o"></i> {ts}Move Tag{/ts}</span> + </a> + <% {rdelim} %> + <% if(!hasChildren) {ldelim} %> + <a href="{crmURL p="civicrm/tag/edit" q="action=delete&id="}<%= id %>" class="button crm-popup small-popup"> + <span><i class="crm-i fa-trash"></i> {ts}Delete{/ts}</span> + </a> + <% {rdelim} %> + <% {rdelim} %> + </div> +</script> + +<script type="text/template" id="moreSelectedTpl"> + <h4>{ts 1="<%= items.length %>"}%1 Tags Selected{/ts}</h4> + <hr /> + <% if (reserved) {ldelim} %> + <p>* {ts 1="<%= reserved %>"}%1 reserved.{/ts}</p> + <% {rdelim} %> + <p><span class="tdl">{ts}Total Usage:{/ts}</span> <%= usages %></p> + <a class="clear-tag-selection" href="#" title="{ts}Clear selection{/ts}"><i class="crm-i fa-ban"></i></a> + <div class="crm-submit-buttons"> + <% if(!reserved || adminReserved) {ldelim} %> + <a href="{crmURL p="civicrm/tag/merge" q="id="}<%= items.join() %>" class="button crm-popup small-popup" title="{ts}Combine tags into one{/ts}"> + <span><i class="crm-i fa-compress"></i> {ts}Merge Tags{/ts}</span> + </a> + <% if(tagsetCount) {ldelim} %> + <a href="#move" class="button move-tag-button" title="{ts}Move to a different tagset{/ts}"> + <span><i class="crm-i fa-share-square-o"></i> {ts}Move Tags{/ts}</span> + </a> + <% {rdelim} %> + <% if(!hasChildren) {ldelim} %> + <a href="{crmURL p="civicrm/tag/edit" q="action=delete&id="}<%= items.join() %>" class="button crm-popup small-popup"> + <span><i class="crm-i fa-trash"></i> {ts}Delete All{/ts}</span> + </a> + <% {rdelim} %> + <% {rdelim} %> + </div> +</script> + +<script type="text/template" id="tagsetHelpTpl"> + <div class="help"> + <% if(is_reserved == 1) {ldelim} %><strong>{ts}Reserved{/ts}</strong><% {rdelim} %> + <% if(undefined === display_name) {ldelim} var display_name = null; {rdelim} %> + {ts 1="<%= used_for_label.join(', ') %>" 2="<%= date %>" 3="<%= display_name %>"}Tag Set for %1 (created %2 by %3).{/ts} + <% if(typeof description === 'string' && description.length) {ldelim} %><p><em><%- description %></em></p><% {rdelim} %> + </div> +</script> diff --git a/civicrm/templates/CRM/UF/Form/Block.tpl b/civicrm/templates/CRM/UF/Form/Block.tpl index ffdd708d35..da77dda5d1 100644 --- a/civicrm/templates/CRM/UF/Form/Block.tpl +++ b/civicrm/templates/CRM/UF/Form/Block.tpl @@ -29,148 +29,7 @@ {if $help_pre && $action neq 4}<div class="messages help">{$help_pre}</div>{/if} {assign var=zeroField value="Initial Non Existent Fieldset"} {assign var=fieldset value=$zeroField} - {foreach from=$fields item=field key=fieldName} - {if $field.skipDisplay} - {continue} - {/if} - {if $field.groupTitle != $fieldset} - {if $fieldset != $zeroField} - {if $groupHelpPost && $action neq 4} - <div class="messages help">{$groupHelpPost}</div> - {/if} - {if $mode ne 8} - </fieldset> - {/if} - {/if} - - {if $mode ne 8 && $action ne 1028 && $action ne 4 && !$hideFieldset} - <fieldset class="crm-profile crm-profile-id-{$field.group_id} crm-profile-name-{$field.groupName}"><legend>{$field.groupTitle}</legend> - {/if} - - {if ($form.formName eq 'Confirm' OR $form.formName eq 'ThankYou') AND $prefix neq 'honor'} - <div class="header-dark">{$field.groupTitle} </div> - {/if} - {assign var=fieldset value=`$field.groupTitle`} - {assign var=groupHelpPost value=`$field.groupHelpPost`} - {if $field.groupHelpPre && $action neq 4 && $action neq 1028} - <div class="messages help">{$field.groupHelpPre}</div> - {/if} - {/if} - - {assign var=n value=$field.name} - - {if $field.field_type eq "Formatting"} - {if $action neq 4 && $action neq 1028} - {$field.help_pre} - {/if} - {elseif $n} - {* Show explanatory text for field if not in 'view' or 'preview' modes *} - {if $field.help_pre && $action neq 4 && $action neq 1028} - <div class="crm-section helprow-{$n}-section helprow-pre" id="helprow-{$n}"> - <div class="content description">{$field.help_pre}</div> - </div> - {/if} - {if $field.options_per_line != 0} - <div class="crm-section editrow_{$n}-section form-item" id="editrow-{$n}"> - <div class="label option-label">{if $prefix}{$form.$prefix.$n.label}{else}{$form.$n.label}{/if}</div> - <div class="content 3"> - {assign var="count" value="1"} - {strip} - <table class="form-layout-compressed"> - <tr> - {* sort by fails for option per line. Added a variable to iterate through the element array*} - {assign var="index" value="1"} - {if $prefix} - {assign var="formElement" value=$form.$prefix.$n} - {else} - {assign var="formElement" value=$form.$n} - {/if} - {foreach name=outer key=key item=item from=$formElement} - {if $index < 10} - {assign var="index" value=`$index+1`} - {else} - <td class="labels font-light">{$formElement.$key.html}</td> - {if $count == $field.options_per_line} - </tr> - <tr> - {assign var="count" value="1"} - {else} - {assign var="count" value=`$count+1`} - {/if} - {/if} - {/foreach} - </tr> - </table> - {/strip} - </div> - <div class="clear"></div> - </div> - {else} - <div class="crm-section editrow_{$n}-section form-item" id="editrow-{$n}"> - <div class="label"> - {if $prefix}{$form.$prefix.$n.label}{else}{$form.$n.label}{/if} - </div> - <div class="content"> - {if $n|substr:0:3 eq 'im-'} - {assign var="provider" value=$n|cat:"-provider_id"} - {$form.$provider.html} - {/if} - - {if $n eq 'email_greeting' or $n eq 'postal_greeting' or $n eq 'addressee'} - {include file="CRM/Profile/Form/GreetingType.tpl"} - {elseif ($n eq 'group' && $form.group) || ($n eq 'tag' && $form.tag)} - {include file="CRM/Contact/Form/Edit/TagsAndGroups.tpl" type=$n title=null context="profile"} - {elseif ( $n|substr:-5:5 eq '_date' ) AND - ( $form.formName neq 'Confirm' ) AND - ( $form.formName neq 'ThankYou' ) } - {include file="CRM/common/jcalendar.tpl" elementName=$n} - {elseif ( $n|substr:-5:5 eq '_date' ) } - {assign var="date_value" value=$form.$n.value} - <span class="crm-frozen-field"> - {$date_value|date_format:"%Y-%m-%d"|crmDate:$config->dateformatshortdate} - <input type="hidden" name="{$form.$n.name}" value="{$form.$n.value}" id="{$form.$n.name}"> - </span> - {elseif $n|substr:0:5 eq 'phone'} - {assign var="phone_ext_field" value=$n|replace:'phone':'phone_ext'} - {if $prefix}{$form.$prefix.$n.html}{else}{$form.$n.html}{/if} - {if $form.$phone_ext_field.html} - {$form.$phone_ext_field.html} - {/if} - {else} - {if $prefix} - {if $n eq 'organization_name' && !empty($form.onbehalfof_id)} - {$form.onbehalfof_id.html} - {/if} - {if $field.html_type eq 'File' && $viewOnlyPrefixFileValues} - {$viewOnlyPrefixFileValues.$prefix.$n} - {else} - {$form.$prefix.$n.html} - {/if} - {elseif $field.html_type eq 'File' && $viewOnlyFileValues} - {$viewOnlyFileValues.$n} - {else} - {$form.$n.html} - {/if} - {/if} - - {*CRM-4564*} - {if $field.html_type eq 'Autocomplete-Select'} - {if $field.data_type eq 'ContactReference'} - {include file="CRM/Custom/Form/ContactReference.tpl" element_name = $n} - {/if} - {/if} - </div> - <div class="clear"></div> - </div> - {/if} - {* Show explanatory text for field if not in 'view' or 'preview' modes *} - {if $field.help_post && $action neq 4 && $action neq 1028} - <div class="crm-section helprow-{$n}-section helprow-post" id="helprow-{$n}"> - <div class="content description">{$field.help_post}</div> - </div> - {/if} - {/if} - {/foreach} + {include file="CRM/UF/Form/Fields.tpl"} {if $field.groupHelpPost && $action neq 4 && $action neq 1028} <div class="messages help">{$field.groupHelpPost}</div> diff --git a/civicrm/templates/CRM/UF/Form/Fields.tpl b/civicrm/templates/CRM/UF/Form/Fields.tpl new file mode 100644 index 0000000000..4fbe9a4e7e --- /dev/null +++ b/civicrm/templates/CRM/UF/Form/Fields.tpl @@ -0,0 +1,143 @@ +{foreach from=$fields item=field key=fieldName} + {if $field.skipDisplay} + {continue} + {/if} + {if $field.groupTitle != $fieldset} + {if $fieldset != $zeroField} + {if $groupHelpPost && $action neq 4} + <div class="messages help">{$groupHelpPost}</div> + {/if} + {if $mode ne 8} + </fieldset> + {/if} + {/if} + + {if $mode ne 8 && $action ne 1028 && $action ne 4 && !$hideFieldset} + <fieldset class="crm-profile crm-profile-id-{$field.group_id} crm-profile-name-{$field.groupName}"><legend>{$field.groupTitle}</legend> + {/if} + + {if ($form.formName eq 'Confirm' OR $form.formName eq 'ThankYou') AND $prefix neq 'honor'} + <div class="header-dark">{$field.groupTitle} </div> + {/if} + {assign var=fieldset value=`$field.groupTitle`} + {assign var=groupHelpPost value=`$field.groupHelpPost`} + {if $field.groupHelpPre && $action neq 4 && $action neq 1028} + <div class="messages help">{$field.groupHelpPre}</div> + {/if} + {/if} + + {assign var=profileFieldName value=$field.name} + + {if $field.field_type eq "Formatting"} + {if $action neq 4 && $action neq 1028} + {$field.help_pre} + {/if} + {elseif $profileFieldName} + {* Show explanatory text for field if not in 'view' or 'preview' modes *} + {if $field.help_pre && $action neq 4 && $action neq 1028} + <div class="crm-section helprow-{$profileFieldName}-section helprow-pre" id="helprow-{$profileFieldName}"> + <div class="content description">{$field.help_pre}</div> + </div> + {/if} + {if $field.options_per_line != 0} + <div class="crm-section editrow_{$profileFieldName}-section form-item" id="editrow-{$profileFieldName}"> + <div class="label option-label">{if $prefix}{$form.$prefix.$profileFieldName.label}{else}{$form.$profileFieldName.label}{/if}</div> + <div class="content 3"> + {assign var="count" value="1"} + {strip} + <table class="form-layout-compressed"> + <tr> + {* sort by fails for option per line. Added a variable to iterate through the element array*} + {assign var="index" value="1"} + {if $prefix} + {assign var="formElement" value=$form.$prefix.$profileFieldName} + {else} + {assign var="formElement" value=$form.$profileFieldName} + {/if} + {foreach name=outer key=key item=item from=$formElement} + {if $index < 10} + {assign var="index" value=`$index+1`} + {else} + <td class="labels font-light">{$formElement.$key.html}</td> + {if $count == $field.options_per_line} + </tr> + <tr> + {assign var="count" value="1"} + {else} + {assign var="count" value=`$count+1`} + {/if} + {/if} + {/foreach} + </tr> + </table> + {/strip} + </div> + <div class="clear"></div> + </div> + {else} + <div class="crm-section editrow_{$profileFieldName}-section form-item" id="editrow-{$profileFieldName}"> + <div class="label"> + {if $prefix}{$form.$prefix.$profileFieldName.label}{else}{$form.$profileFieldName.label}{/if} + </div> + <div class="content"> + {if $profileFieldName|substr:0:3 eq 'im-'} + {assign var="provider" value=profileFieldNamen|cat:"-provider_id"} + {$form.$provider.html} + {/if} + + {if $profileFieldName eq 'email_greeting' or $profileFieldName eq 'postal_greeting' or $profileFieldName eq 'addressee'} + {include file="CRM/Profile/Form/GreetingType.tpl"} + {elseif ($profileFieldName eq 'group' && $form.group) || ($profileFieldName eq 'tag' && $form.tag)} + {include file="CRM/Contact/Form/Edit/TagsAndGroups.tpl" type=$profileFieldName title=null context="profile"} + {elseif $field.is_datetime_field && $action & 4} + {assign var="date_value" value=$form.$profileFieldName.value} + <span class="crm-frozen-field"> + {$date_value|date_format:"%Y-%m-%d"|crmDate:$config->dateformatshortdate} + <input type="hidden" + name="{$form.$profileFieldName.name}" + value="{$form.$profileFieldName.value}" id="{$form.$profileFieldName.name}" + > + </span> + {elseif $field.is_legacy_date} + {include file="CRM/common/jcalendar.tpl" elementName=$profileFieldName} + {elseif $profileFieldName|substr:0:5 eq 'phone'} + {assign var="phone_ext_field" value=$profileFieldName|replace:'phone':'phone_ext'} + {if $prefix}{$form.$prefix.$profileFieldName.html}{else}{$form.$profileFieldName.html}{/if} + {if $form.$phone_ext_field.html} + {$form.$phone_ext_field.html} + {/if} + {else} + {if $prefix} + {if $profileFieldName eq 'organization_name' && !empty($form.onbehalfof_id)} + {$form.onbehalfof_id.html} + {/if} + {if $field.html_type eq 'File' && $viewOnlyPrefixFileValues} + {$viewOnlyPrefixFileValues.$prefix.$profileFieldName} + {else} + {$form.$prefix.$profileFieldName.html} + {/if} + {elseif $field.html_type eq 'File' && $viewOnlyFileValues} + {$viewOnlyFileValues.$profileFieldName} + {else} + {$form.$profileFieldName.html} + {/if} + {/if} + + {*CRM-4564*} + {if $field.html_type eq 'Autocomplete-Select'} + {if $field.data_type eq 'ContactReference'} + {include file="CRM/Custom/Form/ContactReference.tpl" element_name = $profileFieldName} + {/if} + {/if} + </div> + <div class="clear"></div> + </div> + {/if} + {* Show explanatory text for field if not in 'view' or 'preview' modes *} + {if $field.help_post && $action neq 4 && $action neq 1028} + <div class="crm-section helprow-{$profileFieldName}-section helprow-post" id="helprow-{$profileFieldName}"> + <div class="content description">{$field.help_post}</div> + </div> + {/if} + {/if} +{/foreach} diff --git a/civicrm/templates/CRM/UF/Form/Preview.tpl b/civicrm/templates/CRM/UF/Form/Preview.tpl index 6bede7d17b..cc4b5cf7d9 100644 --- a/civicrm/templates/CRM/UF/Form/Preview.tpl +++ b/civicrm/templates/CRM/UF/Form/Preview.tpl @@ -40,109 +40,10 @@ {if $help_pre && $action neq 4}<div class="messages help">{$help_pre}</div>{/if} {assign var=zeroField value="Initial Non Existent Fieldset"} {assign var=fieldset value=$zeroField} - {foreach from=$fields item=field key=fieldName} - {if $field.skipDisplay} - {continue} - {/if} - {if $field.groupTitle != $fieldset} - {if $fieldset != $zeroField} - </table> - {if $groupHelpPost} - <div class="messages help">{$groupHelpPost}</div> - {/if} - {if $mode ne 8} - </fieldset> - {/if} - {/if} - {if $mode ne 8} - <h3>{$field.groupTitle}</h3> - {/if} - {assign var=fieldset value=`$field.groupTitle`} - {assign var=groupHelpPost value=`$field.groupHelpPost`} - {if $field.groupHelpPre} - <div class="messages help">{$field.groupHelpPre}</div> - {/if} - <table class="form-layout-compressed" id="table-1"> - {/if} - {* Show explanatory text for field if not in 'view' mode *} - {if $field.help_pre && $action neq 4 && $field.field_type neq "Formatting"} - <tr><td> </td><td class="description">{$field.help_pre}</td></tr> - {/if} - {assign var=n value=$field.name} - {if $field.field_type eq "Formatting"} - <tr><td colspan="2">{$field.help_pre}</td></tr> - {elseif $field.options_per_line } - <tr> - <td class="option-label">{$form.$n.label}</td> - <td> - {assign var="count" value="1"} - {strip} - <table class="form-layout-compressed"> - <tr> - {* sort by fails for option per line. Added a variable to iterate through the element array*} - {assign var="index" value="1"} - {foreach name=outer key=key item=item from=$form.$n} - {if $index < 10} - {assign var="index" value=`$index+1`} - {else} - <td class="labels font-light">{$form.$n.$key.html}</td> - {if $count == $field.options_per_line} - </tr> - {assign var="count" value="1"} - {else} - {assign var="count" value=`$count+1`} - {/if} - {/if} - {/foreach} - </table> - {/strip} - </td> - </tr> - {else} - <tr> - <td class="label"> - {$form.$n.label} - </td> - <td> - {if $n eq 'group' && $form.group || ( $n eq 'tag' && $form.tag )} - {include file="CRM/Contact/Form/Edit/TagsAndGroups.tpl" type=$n} - {elseif $n eq 'email_greeting' or $n eq 'postal_greeting' or $n eq 'addressee'} - {include file="CRM/Profile/Form/GreetingType.tpl"} - {elseif ( $n|substr:-5:5 eq '_date' ) or ( $field.name eq 'activity_date_time' ) } - {include file="CRM/common/jcalendar.tpl" elementName=$form.$n.name} - {elseif $n|substr:0:5 eq 'phone'} - {assign var="phone_ext_field" value=$n|replace:'phone':'phone_ext'} - {$form.$n.html} - {if $form.$phone_ext_field.html} - {$form.$phone_ext_field.html} - {/if} - {else} - {if $n|substr:0:3 eq 'im-'} - {assign var="provider" value=$n|cat:"-provider_id"} - {$form.$provider.html} - {/if} - {$form.$n.html} - {if $field.is_view eq 0} - {if $field.html_type eq 'Autocomplete-Select'} - {if $field.data_type eq 'ContactReference'} - {include file="CRM/Custom/Form/ContactReference.tpl" element_name = $n} - {/if} - {/if} - {/if} - {/if} - </td> - </tr> - {/if} - {* Show explanatory text for field if not in 'view' mode *} - {if $field.help_post && $action neq 4} - <tr><td> </td><td class="description">{$field.help_post}</td></tr> - {/if} - {/foreach} - + {include file="CRM/UF/Form/Fields.tpl"} {if $addCAPTCHA } {include file='CRM/common/ReCAPTCHA.tpl'} {/if} - </table> {if $field.groupHelpPost} <div class="messages help">{$field.groupHelpPost}</div> {/if} diff --git a/civicrm/templates/CRM/common/version.tpl b/civicrm/templates/CRM/common/version.tpl index 8df56acc47..bf0a93eb38 100644 --- a/civicrm/templates/CRM/common/version.tpl +++ b/civicrm/templates/CRM/common/version.tpl @@ -1 +1 @@ -4.7.16 \ No newline at end of file +4.7.17 \ No newline at end of file diff --git a/civicrm/vendor/autoload.php b/civicrm/vendor/autoload.php index 57466a2567..6d9fa7f9d9 100644 --- a/civicrm/vendor/autoload.php +++ b/civicrm/vendor/autoload.php @@ -4,4 +4,4 @@ require_once __DIR__ . '/composer' . '/autoload_real.php'; -return ComposerAutoloaderInitfc6c36efd254e0839a09e449fe249ca5::getLoader(); +return ComposerAutoloaderInit08ca5e7ba3199d8cc11629f471bf7947::getLoader(); diff --git a/civicrm/vendor/composer/autoload_real.php b/civicrm/vendor/composer/autoload_real.php index 19e0916714..ad08ffd85b 100644 --- a/civicrm/vendor/composer/autoload_real.php +++ b/civicrm/vendor/composer/autoload_real.php @@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInitfc6c36efd254e0839a09e449fe249ca5 +class ComposerAutoloaderInit08ca5e7ba3199d8cc11629f471bf7947 { private static $loader; @@ -19,9 +19,9 @@ class ComposerAutoloaderInitfc6c36efd254e0839a09e449fe249ca5 return self::$loader; } - spl_autoload_register(array('ComposerAutoloaderInitfc6c36efd254e0839a09e449fe249ca5', 'loadClassLoader'), true, true); + spl_autoload_register(array('ComposerAutoloaderInit08ca5e7ba3199d8cc11629f471bf7947', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(); - spl_autoload_unregister(array('ComposerAutoloaderInitfc6c36efd254e0839a09e449fe249ca5', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInit08ca5e7ba3199d8cc11629f471bf7947', 'loadClassLoader')); $includePaths = require __DIR__ . '/include_paths.php'; array_push($includePaths, get_include_path()); @@ -46,14 +46,14 @@ class ComposerAutoloaderInitfc6c36efd254e0839a09e449fe249ca5 $includeFiles = require __DIR__ . '/autoload_files.php'; foreach ($includeFiles as $file) { - composerRequirefc6c36efd254e0839a09e449fe249ca5($file); + composerRequire08ca5e7ba3199d8cc11629f471bf7947($file); } return $loader; } } -function composerRequirefc6c36efd254e0839a09e449fe249ca5($file) +function composerRequire08ca5e7ba3199d8cc11629f471bf7947($file) { require $file; } -- GitLab