From 6cc0d28cf66074adebc261e981eb35811601f813 Mon Sep 17 00:00:00 2001 From: magento packaging service Date: Thu, 5 Oct 2023 19:20:49 +0000 Subject: [PATCH] Magento Release 2.4.6-p3 --- app/code/Magento/AdminAnalytics/composer.json | 24 +- .../Magento/AdminNotification/composer.json | 24 +- .../AdvancedPricingImportExport/composer.json | 30 +- app/code/Magento/AdvancedSearch/composer.json | 28 +- app/code/Magento/Amqp/composer.json | 18 +- app/code/Magento/Analytics/composer.json | 18 +- .../AsynchronousOperations/composer.json | 26 +- app/code/Magento/Authorization/composer.json | 16 +- app/code/Magento/AwsS3/composer.json | 14 +- app/code/Magento/Backend/composer.json | 50 +- app/code/Magento/Backup/composer.json | 20 +- ...ProductWithZeroPriceToShoppingCartTest.xml | 1 + app/code/Magento/Bundle/composer.json | 52 +- .../view/type/bundle/option/radio.phtml | 50 +- app/code/Magento/BundleGraphQl/composer.json | 28 +- .../Magento/BundleImportExport/composer.json | 26 +- .../Magento/CacheInvalidate/composer.json | 16 +- ...aLoginOnCheckoutWithEnabledCaptchaTest.xml | 1 + ...ontCaptchaOnOnepageCheckoutPyamentTest.xml | 2 + app/code/Magento/Captcha/composer.json | 26 +- .../Magento/CardinalCommerce/composer.json | 20 +- .../Adminhtml/Product/NewAction.php | 25 +- .../Section/StorefrontProductPageSection.xml | 1 + .../AdminCreateTwoSimpleProductTest.xml | 1 + ...teVirtualProductWithoutManageStockTest.xml | 3 + .../Test/Mftf/Test/EndToEndB2CAdminTest.xml | 5 +- ...torefrontCategorySidebarMobileMenuTest.xml | 2 + .../Adminhtml/Product/NewActionTest.php | 90 +- .../Unit/Pricing/Render/FinalPriceBoxTest.php | 33 + app/code/Magento/Catalog/composer.json | 70 +- app/code/Magento/Catalog/i18n/en_US.csv | 1 + .../view/adminhtml/web/js/category-tree.js | 5 +- .../Magento/CatalogAnalytics/composer.json | 14 +- .../Magento/CatalogCmsGraphQl/composer.json | 22 +- .../CatalogCustomerGraphQl/composer.json | 16 +- app/code/Magento/CatalogGraphQl/composer.json | 36 +- .../Model/Import/Product.php | 9 +- .../Magento/CatalogImportExport/composer.json | 34 +- ...abledInventoryCheckOnePageCheckoutTest.xml | 1 + .../Magento/CatalogInventory/composer.json | 28 +- .../CatalogInventoryGraphQl/composer.json | 18 +- ...ogPriceRuleEntityFromSimpleProductTest.xml | 1 + ...ForSimpleProductsWithCustomOptionsTest.xml | 1 + app/code/Magento/CatalogRule/composer.json | 32 +- .../CatalogRuleConfigurable/composer.json | 22 +- .../Magento/CatalogRuleGraphQl/composer.json | 14 +- app/code/Magento/CatalogSearch/composer.json | 38 +- .../Magento/CatalogUrlRewrite/composer.json | 32 +- .../CatalogUrlRewriteGraphQl/composer.json | 26 +- app/code/Magento/CatalogWidget/composer.json | 32 +- .../Model/ShippingInformationManagement.php | 34 +- .../AdminDisableGuestCheckoutActionGroup.xml | 18 + .../AdminEnableGuestCheckoutActionGroup.xml | 18 + ...ShippingTotalInOrderSummaryActionGroup.xml | 1 + ...orefrontOrderCannotBePlacedActionGroup.xml | 1 + ...ldShouldNotAcceptJustIntegerValuesTest.xml | 1 + ...sNotAffectedStartedCheckoutProcessTest.xml | 1 + ...oSubtotalOrderIsInProcessingStatusTest.xml | 1 + ...CheckZeroSubtotalOrderWithCustomStatus.xml | 1 + ...oSubtotalOrderWithGeneratedInvoiceTest.xml | 1 + .../CheckCheckoutSuccessPageAsGuestTest.xml | 1 + ...outDifferentDefaultCountryPerStoreTest.xml | 1 + ...ckoutAsCustomerUsingDefaultAddressTest.xml | 4 +- ...eCheckoutAsCustomerUsingNewAddressTest.xml | 1 + ...utAsCustomerUsingNonDefaultAddressTest.xml | 3 + ...ageCheckoutCancelEditingBillingAddress.xml | 1 + .../OnePageCheckoutUsingSignInLinkTest.xml | 1 + ...WithSignInLinkForEmailVerificationTest.xml | 1 + ...UKCustomerRemainOptionAfterRefreshTest.xml | 1 + ...efrontApplyPromoCodeDuringCheckoutTest.xml | 1 + ...rtItemsCountDisplayItemsQuantitiesTest.xml | 1 + ...ntCartItemsCountDisplayUniqueItemsTest.xml | 1 + ...isplayWithDefaultDisplayLimitationTest.xml | 1 + ...tomerInfoOnOrderPageCreatedByGuestTest.xml | 1 + ...rtItemDisplayWithDefaultLimitationTest.xml | 1 + ...playWithCustomDisplayConfigurationTest.xml | 1 + ...ressAndCreateCustomerAfterCheckoutTest.xml | 1 + ...ingAddressAndProductWithTierPricesTest.xml | 1 + ...thPurchaseOrderNumberPressKeyEnterTest.xml | 1 + ...ontCheckoutWithPurchaseOrderNumberTest.xml | 1 + ...ntCheckoutWithSpecialPriceProductsTest.xml | 3 + ...refrontCustomerLoginDuringCheckoutTest.xml | 4 +- ...StorefrontGuestCheckoutDataPersistTest.xml | 1 + ...tGuestCheckoutForSpecificCountriesTest.xml | 1 + ...tSummaryItemsInCartLabelPluralizedTest.xml | 1 + ...orefrontGuestCheckoutAddNewAddressTest.xml | 1 + .../StorefrontGuestCheckoutTest.xml | 1 + ...tWithRestrictedCountriesForPaymentTest.xml | 1 + ...ntGuestCheckoutWithSidebarDisabledTest.xml | 1 + ...tCheckoutWithCouponAndZeroSubtotalTest.xml | 1 + ...sWithRestrictedCountriesForPaymentTest.xml | 1 + ...ippingMethodInReviewAndPaymentStepTest.xml | 1 + ...ntOnePageCheckoutDataWhenChangeQtyTest.xml | 1 + ...aForGuestCustomerWithPhysicalQuoteTest.xml | 1 + ...tOnCheckoutPageDifferentStoreViewsTest.xml | 1 + ...ngesInBackendAfterCustomerCheckoutTest.xml | 1 + ...rontRefreshPageDuringGuestCheckoutTest.xml | 1 + ...uctQuantityEqualsToOrderedQuantityTest.xml | 1 + ...CouponAndBankTransferPaymentMethodTest.xml | 1 + ...riceInShoppingCartAfterProductSaveTest.xml | 1 + .../StorefrontValidateEmailOnCheckoutTest.xml | 1 + ...tCheckoutUsingFreeShippingAndTaxesTest.xml | 1 + ...ontVerifySecureURLRedirectCheckoutTest.xml | 1 + ...ieldForUnregisteredEmailOnCheckoutTest.xml | 1 + ...ateOptionApplicableForCheckoutFlowTest.xml | 1 + app/code/Magento/Checkout/composer.json | 56 +- .../Magento/Checkout/etc/adminhtml/system.xml | 7 +- app/code/Magento/Checkout/etc/config.xml | 1 + .../AdminCreateActiveHtmlTermEntityTest.xml | 1 + .../AdminCreateActiveTextTermEntityTest.xml | 1 + .../AdminCreateDisabledTextTermEntityTest.xml | 1 + .../AdminDeleteActiveTextTermEntityTest.xml | 1 + .../AdminUpdateDisabledHtmlTermEntityTest.xml | 1 + .../AdminUpdateDisabledTextTermEntityTest.xml | 1 + .../AdminUpdateEnabledTextTermEntityTest.xml | 1 + .../Magento/CheckoutAgreements/composer.json | 22 +- .../CheckoutAgreementsGraphQl/composer.json | 18 +- .../AdminCmsPageGridUrlFilterApplierTest.xml | 1 + app/code/Magento/Cms/composer.json | 34 +- app/code/Magento/CmsGraphQl/composer.json | 24 +- app/code/Magento/CmsUrlRewrite/composer.json | 20 +- .../CmsUrlRewriteGraphQl/composer.json | 24 +- .../Magento/CompareListGraphQl/composer.json | 14 +- app/code/Magento/Config/composer.json | 28 +- .../ConfigurableImportExport/composer.json | 26 +- .../Magento/ConfigurableProduct/composer.json | 50 +- .../ConfigurableProductGraphQl/composer.json | 24 +- .../ConfigurableProductSales/composer.json | 22 +- app/code/Magento/Contact/composer.json | 22 +- app/code/Magento/Cookie/composer.json | 18 +- app/code/Magento/Cron/composer.json | 18 +- app/code/Magento/Csp/composer.json | 16 +- ...kCurrencyConverterApiConfigurationTest.xml | 2 + ...ayWhenChooseThreeAllowedCurrenciesTest.xml | 1 + .../AdminOrderRateDisplayedInOneLineTest.xml | 1 + app/code/Magento/CurrencySymbol/composer.json | 24 +- .../Api/AccountManagementInterface.php | 3 +- .../Customer/Model/AccountManagement.php | 24 +- .../Controller/Rest/ValidateCustomerData.php | 7 +- ...stomerOnStorefrontSignupNewsletterTest.xml | 1 + ...tomerSubscribeNewsletterPerWebsiteTest.xml | 1 + .../Mftf/Test/EndToEndB2CLoggedInUserTest.xml | 3 + ...scribeToNewsletterAndVerifyInAdminTest.xml | 1 + ...frontCustomerSubscribeToNewsletterTest.xml | 1 + .../StorefrontRetainLocalCacheStorageTest.xml | 4 + .../Rest/ValidateCustomerDataTest.php | 34 +- app/code/Magento/Customer/composer.json | 56 +- .../Magento/CustomerAnalytics/composer.json | 14 +- .../CustomerDownloadableGraphQl/composer.json | 18 +- .../Magento/CustomerGraphQl/composer.json | 30 +- .../CustomerImportExport/composer.json | 26 +- app/code/Magento/Deploy/composer.json | 22 +- app/code/Magento/Developer/composer.json | 18 +- app/code/Magento/Dhl/composer.json | 34 +- app/code/Magento/Directory/composer.json | 20 +- .../Magento/DirectoryGraphQl/composer.json | 16 +- ...oveDefaultImageDownloadableProductTest.xml | 3 +- ...loadableProductFromGuestToCustomerTest.xml | 1 + app/code/Magento/Downloadable/composer.json | 48 +- .../Magento/DownloadableGraphQl/composer.json | 28 +- .../DownloadableImportExport/composer.json | 26 +- app/code/Magento/Eav/composer.json | 24 +- app/code/Magento/EavGraphQl/composer.json | 16 +- app/code/Magento/Elasticsearch/composer.json | 32 +- app/code/Magento/Elasticsearch7/composer.json | 24 +- .../Magento/Email/Model/Template/Filter.php | 16 + app/code/Magento/Email/composer.json | 34 +- app/code/Magento/EncryptionKey/composer.json | 18 +- .../Fedex/Model/Config/Backend/FedexUrl.php | 76 + .../Model/Config/Backend/FedexUrlTest.php | 131 + app/code/Magento/Fedex/composer.json | 30 +- .../Magento/Fedex/etc/adminhtml/system.xml | 2 + app/code/Magento/Fedex/i18n/en_US.csv | 1 + app/code/Magento/GiftMessage/composer.json | 34 +- .../Magento/GiftMessageGraphQl/composer.json | 16 +- app/code/Magento/GoogleAdwords/composer.json | 18 +- .../Magento/GoogleAnalytics/composer.json | 22 +- app/code/Magento/GoogleGtag/composer.json | 22 +- .../Magento/GoogleOptimizer/composer.json | 28 +- app/code/Magento/GraphQl/composer.json | 22 +- app/code/Magento/GraphQlCache/composer.json | 18 +- .../GroupedCatalogInventory/composer.json | 20 +- .../Magento/GroupedImportExport/composer.json | 24 +- app/code/Magento/GroupedProduct/composer.json | 42 +- .../GroupedProductGraphQl/composer.json | 16 +- app/code/Magento/ImportExport/composer.json | 26 +- app/code/Magento/Indexer/composer.json | 16 +- .../Magento/InstantPurchase/composer.json | 18 +- app/code/Magento/Integration/composer.json | 28 +- .../Magento/JwtFrameworkAdapter/composer.json | 14 +- app/code/Magento/JwtUserToken/composer.json | 18 +- .../Magento/LayeredNavigation/composer.json | 18 +- ...ginAsCustomerSubscribeToNewsletterTest.xml | 1 + .../Magento/LoginAsCustomer/composer.json | 22 +- .../LoginAsCustomerAdminUi/composer.json | 29 +- .../Magento/LoginAsCustomerApi/composer.json | 10 +- .../LoginAsCustomerAssistance/composer.json | 29 +- .../LoginAsCustomerFrontendUi/composer.json | 17 +- .../LoginAsCustomerGraphQl/composer.json | 26 +- .../Magento/LoginAsCustomerLog/composer.json | 27 +- .../LoginAsCustomerPageCache/composer.json | 21 +- .../LoginAsCustomerQuote/composer.json | 23 +- .../LoginAsCustomerSales/composer.json | 23 +- app/code/Magento/Marketplace/composer.json | 16 +- .../view/adminhtml/templates/index.phtml | 6 +- app/code/Magento/MediaContent/composer.json | 14 +- .../Magento/MediaContentApi/composer.json | 12 +- .../Magento/MediaContentCatalog/composer.json | 18 +- .../Magento/MediaContentCms/composer.json | 14 +- .../MediaContentSynchronization/composer.json | 24 +- .../composer.json | 12 +- .../composer.json | 16 +- .../composer.json | 16 +- app/code/Magento/MediaGallery/composer.json | 14 +- .../Magento/MediaGalleryApi/composer.json | 10 +- .../Magento/MediaGalleryCatalog/composer.json | 14 +- .../composer.json | 24 +- .../MediaGalleryCatalogUi/composer.json | 20 +- .../Magento/MediaGalleryCmsUi/composer.json | 14 +- .../MediaGalleryIntegration/composer.json | 32 +- .../MediaGalleryMetadata/composer.json | 12 +- .../MediaGalleryMetadataApi/composer.json | 10 +- .../MediaGalleryRenditions/composer.json | 24 +- .../MediaGalleryRenditionsApi/composer.json | 10 +- .../MediaGallerySynchronization/composer.json | 16 +- .../composer.json | 12 +- .../composer.json | 16 +- app/code/Magento/MediaGalleryUi/composer.json | 32 +- .../Magento/MediaGalleryUiApi/composer.json | 16 +- app/code/Magento/MediaStorage/composer.json | 30 +- app/code/Magento/MessageQueue/composer.json | 16 +- app/code/Magento/Msrp/composer.json | 28 +- .../MsrpConfigurableProduct/composer.json | 20 +- .../Magento/MsrpGroupedProduct/composer.json | 20 +- app/code/Magento/Multishipping/composer.json | 34 +- app/code/Magento/MysqlMq/composer.json | 18 +- .../Magento/NewRelicReporting/composer.json | 26 +- .../AdminDisableNewsletterActionGroup.xml | 17 + .../AdminEnableNewsletterActionGroup.xml | 17 + ...nMarketingCreateNewsletterTemplateTest.xml | 1 - ...nMarketingNewsletterTemplateUpdateTest.xml | 1 - .../Mftf/Test/AdminNameEmptyForGuestTest.xml | 1 + ...tVerifySecureURLRedirectNewsletterTest.xml | 2 + ...erifySubscribedNewsletterDisplayedTest.xml | 1 + app/code/Magento/Newsletter/composer.json | 32 +- .../Magento/NewsletterGraphQl/composer.json | 22 +- .../Magento/OfflinePayments/composer.json | 22 +- .../Magento/OfflineShipping/composer.json | 36 +- app/code/Magento/OpenSearch/composer.json | 22 +- .../Magento/PageCache/Controller/Block.php | 33 +- app/code/Magento/PageCache/composer.json | 22 +- .../PageCache/etc/adminhtml/system.xml | 4 + app/code/Magento/PageCache/etc/config.xml | 1 + app/code/Magento/PageCache/etc/di.xml | 1 + app/code/Magento/Payment/composer.json | 30 +- app/code/Magento/PaymentGraphQl/composer.json | 18 +- ...ckoutPaymentWorksWithPaypalExpressTest.xml | 1 + app/code/Magento/Paypal/composer.json | 50 +- app/code/Magento/PaypalCaptcha/composer.json | 22 +- app/code/Magento/PaypalGraphQl/composer.json | 34 +- ...GuestCheckoutWithEnabledPersistentTest.xml | 1 + ...CartPersistenceUnderLongTermCookieTest.xml | 1 + app/code/Magento/Persistent/composer.json | 26 +- app/code/Magento/ProductAlert/composer.json | 32 +- app/code/Magento/ProductVideo/composer.json | 30 +- .../Quote/Model/BillingAddressManagement.php | 18 +- .../Quote/Model/QuoteAddressValidator.php | 109 +- app/code/Magento/Quote/composer.json | 44 +- app/code/Magento/Quote/i18n/en_US.csv | 1 + app/code/Magento/QuoteAnalytics/composer.json | 14 +- .../Magento/QuoteBundleOptions/composer.json | 12 +- .../QuoteConfigurableOptions/composer.json | 12 +- .../QuoteDownloadableLinks/composer.json | 12 +- .../Model/Resolver/RemoveItemFromCart.php | 3 +- app/code/Magento/QuoteGraphQl/composer.json | 40 +- .../RelatedProductGraphQl/composer.json | 18 +- .../Magento/ReleaseNotification/composer.json | 22 +- app/code/Magento/RemoteStorage/composer.json | 36 +- ...rMultiWebsiteWithDifferentCurrencyTest.xml | 1 + .../ResourceModel/Order/CollectionTest.php | 4 + app/code/Magento/Reports/composer.json | 48 +- app/code/Magento/RequireJs/composer.json | 14 +- app/code/Magento/Review/composer.json | 34 +- .../Magento/ReviewAnalytics/composer.json | 14 +- app/code/Magento/ReviewGraphQl/composer.json | 22 +- app/code/Magento/Robots/composer.json | 18 +- app/code/Magento/Rss/composer.json | 20 +- app/code/Magento/Rule/composer.json | 22 +- .../Adminhtml/Order/Create/LoadBlock.php | 38 +- ...ewOrderPageExistingCustomerActionGroup.xml | 33 + ...teToNewOrderPageNewCustomerActionGroup.xml | 23 + ...ectStoreDuringOrderCreationActionGroup.xml | 25 + ...nStoreChoosingPaymentMethodActionGroup.xml | 4 +- ...ableProductToOrderFromShoppingCartTest.xml | 1 + ...ectnessInvoicedItemInBundleProductTest.xml | 1 + ...pliedToUncheckedNewlyCreatedOrdersTest.xml | 1 + ...SSVulnerabilityDuringOrderCreationTest.xml | 1 + ...loseOrderInCaseItRefundedPartiallyTest.xml | 3 + ...editMemoTotalAfterShippingDiscountTest.xml | 1 + .../Test/Mftf/Test/EndToEndB2CAdminTest.xml | 9 +- ...tCreateOrderWithDifferentAddressesTest.xml | 4 +- ...ntCreateOrdersWithMoveJSCodeBottomTest.xml | 1 + app/code/Magento/Sales/composer.json | 64 +- app/code/Magento/SalesAnalytics/composer.json | 14 +- app/code/Magento/SalesGraphQl/composer.json | 24 +- app/code/Magento/SalesInventory/composer.json | 22 +- ...StorefrontApplyDiscountCodeActionGroup.xml | 2 +- ...inCartRulesAppliedForProductInCartTest.xml | 1 + ...nCodeCheckTimesUsedAfterGuestOrderTest.xml | 1 + .../StorefrontAutoGeneratedCouponCodeTest.xml | 1 + ...ductWithDiscountUsingCartPriceRuleTest.xml | 1 + app/code/Magento/SalesRule/composer.json | 58 +- app/code/Magento/SalesSequence/composer.json | 14 +- app/code/Magento/SampleData/composer.json | 16 +- app/code/Magento/Search/composer.json | 24 +- app/code/Magento/Security/composer.json | 24 +- app/code/Magento/SendFriend/composer.json | 26 +- .../Magento/SendFriendGraphQl/composer.json | 16 +- ...ustomStoreShippingMethodTableRatesTest.xml | 6 +- ...PricesPresentAfterApplyingCartRuleTest.xml | 1 + app/code/Magento/Shipping/composer.json | 46 +- app/code/Magento/Sitemap/composer.json | 34 +- app/code/Magento/Store/composer.json | 32 +- app/code/Magento/StoreGraphQl/composer.json | 16 +- app/code/Magento/Swagger/composer.json | 14 +- app/code/Magento/SwaggerWebapi/composer.json | 16 +- .../Magento/SwaggerWebapiAsync/composer.json | 18 +- .../Renderer/Listing/ConfigurableTest.php | 34 +- app/code/Magento/Swatches/composer.json | 38 +- .../Magento/SwatchesGraphQl/composer.json | 20 +- .../SwatchesLayeredNavigation/composer.json | 14 +- ...refrontTaxQuoteCheckoutGuestSimpleTest.xml | 1 + ...efrontTaxQuoteCheckoutGuestVirtualTest.xml | 1 + app/code/Magento/Tax/composer.json | 44 +- app/code/Magento/TaxGraphQl/composer.json | 16 +- .../Magento/TaxImportExport/composer.json | 24 +- ...tCheckNotificationMessageContainerTest.xml | 1 + app/code/Magento/Theme/composer.json | 40 +- app/code/Magento/ThemeGraphQl/composer.json | 14 +- app/code/Magento/Translation/composer.json | 26 +- app/code/Magento/Ui/composer.json | 26 +- app/code/Magento/Ups/composer.json | 30 +- .../Test/Mftf/Data/UrlRewriteData.xml | 4 +- ...inUpdateCustomURLRewritesPermanentTest.xml | 1 + app/code/Magento/UrlRewrite/composer.json | 28 +- .../Magento/UrlRewriteGraphQl/composer.json | 16 +- app/code/Magento/User/composer.json | 28 +- app/code/Magento/Usps/Helper/Data.php | 12 +- app/code/Magento/Usps/Model/Carrier.php | 16 + .../Usps/Model/Config/Backend/UspsUrl.php | 76 + .../Setup/Patch/Data/UpdateAllowedMethods.php | 13 +- .../Usps/Test/Unit/Helper/DataTest.php | 8 + .../Usps/Test/Unit/Model/CarrierTest.php | 3 +- .../Unit/Model/Config/Backend/UspsUrlTest.php | 124 + app/code/Magento/Usps/composer.json | 30 +- .../Magento/Usps/etc/adminhtml/system.xml | 2 + app/code/Magento/Usps/etc/config.xml | 2 +- app/code/Magento/Usps/i18n/en_US.csv | 9 + app/code/Magento/Variable/composer.json | 22 +- app/code/Magento/Vault/composer.json | 29 +- app/code/Magento/VaultGraphQl/composer.json | 14 +- app/code/Magento/Version/composer.json | 14 +- app/code/Magento/Webapi/composer.json | 26 +- app/code/Magento/WebapiAsync/composer.json | 24 +- app/code/Magento/WebapiSecurity/composer.json | 16 +- app/code/Magento/Weee/composer.json | 40 +- app/code/Magento/WeeeGraphQl/composer.json | 20 +- app/code/Magento/Widget/composer.json | 32 +- app/code/Magento/Wishlist/composer.json | 48 +- .../Magento/WishlistAnalytics/composer.json | 14 +- .../Magento/WishlistGraphQl/composer.json | 22 +- .../adminhtml/Magento/backend/composer.json | 14 +- .../frontend/Magento/blank/composer.json | 14 +- .../frontend/Magento/luma/composer.json | 16 +- app/i18n/Magento/de_DE/composer.json | 6 +- app/i18n/Magento/en_US/composer.json | 6 +- app/i18n/Magento/es_ES/composer.json | 6 +- app/i18n/Magento/fr_FR/composer.json | 6 +- app/i18n/Magento/nl_NL/composer.json | 6 +- app/i18n/Magento/pt_BR/composer.json | 6 +- app/i18n/Magento/zh_Hans_CN/composer.json | 6 +- composer.json | 534 +- composer.lock | 2097 +- .../TestFramework/TestCase/WebapiAbstract.php | 3 + .../Customer/Api/AccountManagementTest.php | 35 +- .../GraphQl/Catalog/ProductSearchTest.php | 21 +- .../GraphQl/Customer/IsEmailAvailableTest.php | 35 +- .../SubscribeEmailToNewsletterTest.php | 23 +- .../Quote/Customer/RemoveItemFromCartTest.php | 55 +- .../Customer/Model/AccountManagementTest.php | 28 +- .../ConnectionFactoryTest.php | 3 +- .../ObjectManager/ObjectManagerTest.php | 17 +- .../Magento/Framework/ProfilerTest.php | 5 +- .../Magento/ImportExport/Model/ExportTest.php | 3 +- .../Controller/Subscriber/NewActionTest.php | 15 +- .../Magento/Ups/Model/CarrierTest.php | 75 +- .../Ups/_files/ups_rates_response_option9.xml | 299 + .../Ui/base/js/grid/data-storage.test.js | 3 +- .../constraint_modification.mariadb10427.php | 59 + .../constraint_modification.mariadb10611.php | 59 + .../rollback.mariadb10427.php | 27 + .../rollback.mariadb10611.php | 27 + .../table_removal.mariadb10427.php | 14 + .../table_removal.mariadb10611.php | 14 + .../table_rename.mariadb10427.php | 15 + .../table_rename.mariadb10611.php | 15 + .../fixture/dry_run_log.mariadb10611.php | 58 + .../fixture/shards.mariadb10427.php | 38 + .../fixture/shards.mariadb10611.php | 38 + .../disabling_tables.mariadb10427.php | 14 + .../disabling_tables.mariadb10611.php | 14 + .../Annotation/DataProviderFromFile.php | 4 +- .../TestFramework/TestCase/SetupTestCase.php | 6 + .../allowed_dependencies/ce.php | 1 + .../App/Action/AbstractActionTest.php | 20 + .../controllers_extending_abstract_action.php | 10 + .../Magento/Framework/Amqp/composer.json | 18 +- .../Framework/App/DeploymentConfig.php | 82 +- .../Magento/Framework/App/Http/Context.php | 28 +- .../App/Test/Unit/DeploymentConfigTest.php | 59 +- .../App/Test/Unit/Http/ContextTest.php | 39 +- .../Magento/Framework/Bulk/composer.json | 18 +- .../DB/Adapter/SqlVersionProvider.php | 38 + .../Framework/MessageQueue/composer.json | 18 +- .../Magento/Framework/Module/ModuleList.php | 7 +- .../Module/Test/Unit/ModuleListTest.php | 4 +- .../Magento/Framework/RegexValidator.php | 53 + .../Framework/Url/Test/Unit/ValidatorTest.php | 12 + .../Magento/Framework/Url/Validator.php | 11 +- .../Framework/View/Element/AbstractBlock.php | 39 +- .../Test/Unit/Element/AbstractBlockTest.php | 38 +- lib/internal/Magento/Framework/composer.json | 10 +- .../fileUploader/vendor/jquery.ui.widget.js | 1505 +- lib/web/jquery/jquery-ui.js | 28663 ++++++++-------- lib/web/jquery/jquery.validate.js | 35 +- lib/web/jquery/ui-modules/data.js | 44 +- .../jquery/ui-modules/disable-selection.js | 56 +- lib/web/jquery/ui-modules/effect.js | 1888 +- .../jquery/ui-modules/effects/effect-blind.js | 92 +- .../ui-modules/effects/effect-bounce.js | 146 +- .../jquery/ui-modules/effects/effect-clip.js | 82 +- .../jquery/ui-modules/effects/effect-drop.js | 92 +- .../ui-modules/effects/effect-explode.js | 182 +- .../jquery/ui-modules/effects/effect-fade.js | 58 +- .../jquery/ui-modules/effects/effect-fold.js | 142 +- .../ui-modules/effects/effect-highlight.js | 78 +- .../jquery/ui-modules/effects/effect-puff.js | 50 +- .../ui-modules/effects/effect-pulsate.js | 78 +- .../jquery/ui-modules/effects/effect-scale.js | 82 +- .../jquery/ui-modules/effects/effect-shake.js | 94 +- .../jquery/ui-modules/effects/effect-size.js | 350 +- .../jquery/ui-modules/effects/effect-slide.js | 104 +- .../ui-modules/effects/effect-transfer.js | 42 +- lib/web/jquery/ui-modules/focusable.js | 110 +- lib/web/jquery/ui-modules/form-reset-mixin.js | 106 +- lib/web/jquery/ui-modules/jquery-patch.js | 100 +- lib/web/jquery/ui-modules/keycode.js | 56 +- lib/web/jquery/ui-modules/labels.js | 76 +- lib/web/jquery/ui-modules/position.js | 976 +- lib/web/jquery/ui-modules/scroll-parent.js | 56 +- lib/web/jquery/ui-modules/tabbable.js | 34 +- lib/web/jquery/ui-modules/unique-id.js | 64 +- lib/web/jquery/ui-modules/version.js | 22 +- lib/web/jquery/ui-modules/widget.js | 1470 +- .../jquery/ui-modules/widgets/accordion.js | 1198 +- .../jquery/ui-modules/widgets/autocomplete.js | 1306 +- lib/web/jquery/ui-modules/widgets/button.js | 842 +- .../ui-modules/widgets/checkboxradio.js | 531 +- .../jquery/ui-modules/widgets/controlgroup.js | 558 +- .../jquery/ui-modules/widgets/datepicker.js | 4430 +-- lib/web/jquery/ui-modules/widgets/dialog.js | 1860 +- .../jquery/ui-modules/widgets/draggable.js | 2480 +- .../jquery/ui-modules/widgets/droppable.js | 964 +- lib/web/jquery/ui-modules/widgets/menu.js | 1384 +- lib/web/jquery/ui-modules/widgets/mouse.js | 440 +- .../jquery/ui-modules/widgets/progressbar.js | 302 +- .../jquery/ui-modules/widgets/resizable.js | 2340 +- .../jquery/ui-modules/widgets/selectable.js | 596 +- .../jquery/ui-modules/widgets/selectmenu.js | 1340 +- lib/web/jquery/ui-modules/widgets/slider.js | 1468 +- lib/web/jquery/ui-modules/widgets/sortable.js | 3192 +- lib/web/jquery/ui-modules/widgets/spinner.js | 1116 +- lib/web/jquery/ui-modules/widgets/tabs.js | 1802 +- lib/web/jquery/ui-modules/widgets/tooltip.js | 1006 +- lib/web/moment.js | 5 +- 485 files changed, 39695 insertions(+), 37139 deletions(-) mode change 100644 => 100755 app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/NewActionTest.php create mode 100644 app/code/Magento/Checkout/Test/Mftf/ActionGroup/AdminDisableGuestCheckoutActionGroup.xml create mode 100644 app/code/Magento/Checkout/Test/Mftf/ActionGroup/AdminEnableGuestCheckoutActionGroup.xml create mode 100644 app/code/Magento/Fedex/Model/Config/Backend/FedexUrl.php create mode 100644 app/code/Magento/Fedex/Test/Unit/Model/Config/Backend/FedexUrlTest.php create mode 100644 app/code/Magento/Newsletter/Test/Mftf/ActionGroup/AdminDisableNewsletterActionGroup.xml create mode 100644 app/code/Magento/Newsletter/Test/Mftf/ActionGroup/AdminEnableNewsletterActionGroup.xml create mode 100644 app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminNavigateToNewOrderPageExistingCustomerActionGroup.xml create mode 100644 app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminNavigateToNewOrderPageNewCustomerActionGroup.xml create mode 100644 app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminSelectStoreDuringOrderCreationActionGroup.xml create mode 100644 app/code/Magento/Usps/Model/Config/Backend/UspsUrl.php create mode 100644 app/code/Magento/Usps/Test/Unit/Model/Config/Backend/UspsUrlTest.php create mode 100644 dev/tests/integration/testsuite/Magento/Ups/_files/ups_rates_response_option9.xml create mode 100644 dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/constraint_modification.mariadb10427.php create mode 100644 dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/constraint_modification.mariadb10611.php create mode 100644 dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/rollback.mariadb10427.php create mode 100644 dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/rollback.mariadb10611.php create mode 100644 dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/table_removal.mariadb10427.php create mode 100644 dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/table_removal.mariadb10611.php create mode 100644 dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/table_rename.mariadb10427.php create mode 100644 dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/table_rename.mariadb10611.php create mode 100644 dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/dry_run_log.mariadb10611.php create mode 100644 dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule2/fixture/shards.mariadb10427.php create mode 100644 dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule2/fixture/shards.mariadb10611.php create mode 100644 dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule9/fixture/declarative_installer/disabling_tables.mariadb10427.php create mode 100644 dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule9/fixture/declarative_installer/disabling_tables.mariadb10611.php create mode 100644 dev/tests/static/testsuite/Magento/Test/Legacy/_files/blacklist/controller/controllers_extending_abstract_action.php create mode 100644 lib/internal/Magento/Framework/RegexValidator.php diff --git a/app/code/Magento/AdminAnalytics/composer.json b/app/code/Magento/AdminAnalytics/composer.json index e2f2bb182422d..72407e4f4c119 100644 --- a/app/code/Magento/AdminAnalytics/composer.json +++ b/app/code/Magento/AdminAnalytics/composer.json @@ -1,23 +1,24 @@ { "name": "magento/module-admin-analytics", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.5", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-config": "*", - "magento/module-store": "*", - "magento/module-ui": "*", - "magento/module-release-notification": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-config": "101.2.*", + "magento/module-store": "101.1.*", + "magento/module-ui": "101.2.*", + "magento/module-release-notification": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -27,3 +28,4 @@ } } } + diff --git a/app/code/Magento/AdminNotification/composer.json b/app/code/Magento/AdminNotification/composer.json index 1354cc202d7d2..a3f2d07f63b65 100644 --- a/app/code/Magento/AdminNotification/composer.json +++ b/app/code/Magento/AdminNotification/composer.json @@ -1,24 +1,25 @@ { "name": "magento/module-admin-notification", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.5", "require": { "php": "~8.1.0||~8.2.0", "lib-libxml": "*", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-media-storage": "*", - "magento/module-store": "*", - "magento/module-ui": "*", - "magento/module-config": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-media-storage": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-ui": "101.2.*", + "magento/module-config": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -28,3 +29,4 @@ } } } + diff --git a/app/code/Magento/AdvancedPricingImportExport/composer.json b/app/code/Magento/AdvancedPricingImportExport/composer.json index 9ba5c58657f4f..c52092b56c3d7 100644 --- a/app/code/Magento/AdvancedPricingImportExport/composer.json +++ b/app/code/Magento/AdvancedPricingImportExport/composer.json @@ -1,26 +1,27 @@ { "name": "magento/module-advanced-pricing-import-export", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.6", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-catalog": "*", - "magento/module-catalog-import-export": "*", - "magento/module-catalog-inventory": "*", - "magento/module-customer": "*", - "magento/module-eav": "*", - "magento/module-import-export": "*", - "magento/module-store": "*", - "magento/module-directory": "*" + "magento/framework": "103.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-import-export": "101.1.*", + "magento/module-catalog-inventory": "100.4.*", + "magento/module-customer": "103.0.*", + "magento/module-eav": "102.1.*", + "magento/module-import-export": "101.0.*", + "magento/module-store": "101.1.*", + "magento/module-directory": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -30,3 +31,4 @@ } } } + diff --git a/app/code/Magento/AdvancedSearch/composer.json b/app/code/Magento/AdvancedSearch/composer.json index 289207e2fa1c4..222f9c3da97cf 100644 --- a/app/code/Magento/AdvancedSearch/composer.json +++ b/app/code/Magento/AdvancedSearch/composer.json @@ -1,25 +1,26 @@ { "name": "magento/module-advanced-search", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-catalog-search": "*", - "magento/module-config": "*", - "magento/module-customer": "*", - "magento/module-search": "*", - "magento/module-store": "*", + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-search": "102.0.*", + "magento/module-config": "101.2.*", + "magento/module-customer": "103.0.*", + "magento/module-search": "101.1.*", + "magento/module-store": "101.1.*", "php": "~8.1.0||~8.2.0" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -29,3 +30,4 @@ } } } + diff --git a/app/code/Magento/Amqp/composer.json b/app/code/Magento/Amqp/composer.json index 2382864a4c4f5..61263c423890e 100644 --- a/app/code/Magento/Amqp/composer.json +++ b/app/code/Magento/Amqp/composer.json @@ -1,20 +1,21 @@ { "name": "magento/module-amqp", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.3", "require": { - "magento/framework": "*", - "magento/framework-amqp": "*", - "magento/framework-message-queue": "*", + "magento/framework": "103.0.*", + "magento/framework-amqp": "100.4.*", + "magento/framework-message-queue": "100.4.*", "php": "~8.1.0||~8.2.0" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -24,3 +25,4 @@ } } } + diff --git a/app/code/Magento/Analytics/composer.json b/app/code/Magento/Analytics/composer.json index d52a4dc2a98a4..8ee1b7d91960a 100644 --- a/app/code/Magento/Analytics/composer.json +++ b/app/code/Magento/Analytics/composer.json @@ -1,19 +1,20 @@ { "name": "magento/module-analytics", "description": "N/A", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/module-backend": "*", - "magento/module-config": "*", - "magento/module-integration": "*", - "magento/module-store": "*", - "magento/framework": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.6", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/module-backend": "102.0.*", + "magento/module-config": "101.2.*", + "magento/module-integration": "100.4.*", + "magento/module-store": "101.1.*", + "magento/framework": "103.0.*" + }, "autoload": { "files": [ "registration.php" @@ -23,3 +24,4 @@ } } } + diff --git a/app/code/Magento/AsynchronousOperations/composer.json b/app/code/Magento/AsynchronousOperations/composer.json index 7efcf27821405..d14d785f22d44 100644 --- a/app/code/Magento/AsynchronousOperations/composer.json +++ b/app/code/Magento/AsynchronousOperations/composer.json @@ -1,27 +1,28 @@ { "name": "magento/module-asynchronous-operations", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.6", "require": { - "magento/framework": "*", - "magento/framework-message-queue": "*", - "magento/framework-bulk": "*", - "magento/module-authorization": "*", - "magento/module-backend": "*", - "magento/module-ui": "*", + "magento/framework": "103.0.*", + "magento/framework-message-queue": "100.4.*", + "magento/framework-bulk": "101.0.*", + "magento/module-authorization": "100.4.*", + "magento/module-backend": "102.0.*", + "magento/module-ui": "101.2.*", "php": "~8.1.0||~8.2.0" }, "suggest": { - "magento/module-admin-notification": "*", + "magento/module-admin-notification": "100.4.*", "magento/module-logging": "*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -31,3 +32,4 @@ } } } + diff --git a/app/code/Magento/Authorization/composer.json b/app/code/Magento/Authorization/composer.json index 268db947994fe..3b3596bfa1ba8 100644 --- a/app/code/Magento/Authorization/composer.json +++ b/app/code/Magento/Authorization/composer.json @@ -1,19 +1,20 @@ { "name": "magento/module-authorization", "description": "Authorization module provides access to Magento ACL functionality.", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.6", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-backend": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -23,3 +24,4 @@ } } } + diff --git a/app/code/Magento/AwsS3/composer.json b/app/code/Magento/AwsS3/composer.json index 9b9d55c18140a..d97c11964c946 100644 --- a/app/code/Magento/AwsS3/composer.json +++ b/app/code/Magento/AwsS3/composer.json @@ -1,18 +1,19 @@ { "name": "magento/module-aws-s3", "description": "N/A", + "type": "magento2-module", + "license": [ + "proprietary" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-remote-storage": "*" + "magento/framework": "103.0.*", + "magento/module-remote-storage": "100.4.*" }, - "type": "magento2-module", - "license": [ - "proprietary" - ], "autoload": { "files": [ "registration.php" @@ -22,3 +23,4 @@ } } } + diff --git a/app/code/Magento/Backend/composer.json b/app/code/Magento/Backend/composer.json index a3d6c48757c9a..3ce10ba96ff3d 100644 --- a/app/code/Magento/Backend/composer.json +++ b/app/code/Magento/Backend/composer.json @@ -1,38 +1,39 @@ { "name": "magento/module-backend", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "102.0.6", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-backup": "*", - "magento/module-catalog": "*", - "magento/module-config": "*", - "magento/module-cms": "*", - "magento/module-customer": "*", - "magento/module-developer": "*", - "magento/module-directory": "*", - "magento/module-eav": "*", - "magento/module-quote": "*", - "magento/module-reports": "*", - "magento/module-require-js": "*", - "magento/module-sales": "*", - "magento/module-security": "*", - "magento/module-store": "*", - "magento/module-translation": "*", - "magento/module-ui": "*", - "magento/module-user": "*" + "magento/framework": "103.0.*", + "magento/module-backup": "100.4.*", + "magento/module-catalog": "104.0.*", + "magento/module-config": "101.2.*", + "magento/module-cms": "104.0.*", + "magento/module-customer": "103.0.*", + "magento/module-developer": "100.4.*", + "magento/module-directory": "100.4.*", + "magento/module-eav": "102.1.*", + "magento/module-quote": "101.2.*", + "magento/module-reports": "100.4.*", + "magento/module-require-js": "100.4.*", + "magento/module-sales": "103.0.*", + "magento/module-security": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-translation": "100.4.*", + "magento/module-ui": "101.2.*", + "magento/module-user": "101.2.*" }, "suggest": { - "magento/module-theme": "*" + "magento/module-theme": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php", @@ -43,3 +44,4 @@ } } } + diff --git a/app/code/Magento/Backup/composer.json b/app/code/Magento/Backup/composer.json index 2f7a82e9a5c82..c1f6610fe9852 100644 --- a/app/code/Magento/Backup/composer.json +++ b/app/code/Magento/Backup/composer.json @@ -1,21 +1,22 @@ { "name": "magento/module-backup", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.6", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-cron": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-cron": "100.4.*", + "magento/module-store": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -25,3 +26,4 @@ } } } + diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontAddBundleProductWithZeroPriceToShoppingCartTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontAddBundleProductWithZeroPriceToShoppingCartTest.xml index 88f992e698181..762f561491919 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontAddBundleProductWithZeroPriceToShoppingCartTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontAddBundleProductWithZeroPriceToShoppingCartTest.xml @@ -17,6 +17,7 @@ + diff --git a/app/code/Magento/Bundle/composer.json b/app/code/Magento/Bundle/composer.json index 35972c3ba10de..9257cbe61efd1 100644 --- a/app/code/Magento/Bundle/composer.json +++ b/app/code/Magento/Bundle/composer.json @@ -1,39 +1,40 @@ { "name": "magento/module-bundle", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "101.0.6-p2", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-catalog-inventory": "*", - "magento/module-catalog-rule": "*", - "magento/module-checkout": "*", - "magento/module-config": "*", - "magento/module-customer": "*", - "magento/module-eav": "*", - "magento/module-gift-message": "*", - "magento/module-media-storage": "*", - "magento/module-quote": "*", - "magento/module-sales": "*", - "magento/module-store": "*", - "magento/module-tax": "*", - "magento/module-ui": "*", - "magento/module-directory": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-inventory": "100.4.*", + "magento/module-catalog-rule": "101.2.*", + "magento/module-checkout": "100.4.*", + "magento/module-config": "101.2.*", + "magento/module-customer": "103.0.*", + "magento/module-eav": "102.1.*", + "magento/module-gift-message": "100.4.*", + "magento/module-media-storage": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-sales": "103.0.*", + "magento/module-store": "101.1.*", + "magento/module-tax": "100.4.*", + "magento/module-ui": "101.2.*", + "magento/module-directory": "100.4.*" }, "suggest": { - "magento/module-webapi": "*", - "magento/module-bundle-sample-data": "*", - "magento/module-sales-rule": "*" + "magento/module-webapi": "100.4.*", + "magento/module-bundle-sample-data": "Sample Data version: 100.4.*", + "magento/module-sales-rule": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -43,3 +44,4 @@ } } } + diff --git a/app/code/Magento/Bundle/view/frontend/templates/catalog/product/view/type/bundle/option/radio.phtml b/app/code/Magento/Bundle/view/frontend/templates/catalog/product/view/type/bundle/option/radio.phtml index 706b28049470e..5f3e219866ba6 100644 --- a/app/code/Magento/Bundle/view/frontend/templates/catalog/product/view/type/bundle/option/radio.phtml +++ b/app/code/Magento/Bundle/view/frontend/templates/catalog/product/view/type/bundle/option/radio.phtml @@ -4,6 +4,8 @@ * See COPYING.txt for license details. */ use Magento\Bundle\ViewModel\ValidateQuantity; + +// phpcs:disable Generic.Files.LineLength.TooLong ?> getOption(); ?> @@ -20,42 +22,45 @@ $viewModel = $block->getData('validateQuantityViewModel');
- showSingle()) : ?> + showSingle()): ?> getSelectionTitlePrice($_selections[0]) ?> getTierPriceRenderer()->renderTierPrice($_selections[0]) ?> - - getRequired()) : ?> + + getRequired()): ?>
isSalable())?'':' checked="checked" ' ?> + isSalable())?'':' checked="checked" ' ?> value=""/>
- +
getRequired()) { echo 'data-validate="{\'validate-one-required-by-name\':true}"'; }?> + getRequired()) { + echo 'data-validate="{\'validate-one-required-by-name\':true}"'; + } ?> name="bundle_option[escapeHtmlAttr($_option->getId()) ?>]" data-selector="bundle_option[escapeHtmlAttr($_option->getId()) ?>]" - isSelected($_selection)) { echo ' checked="checked"'; } ?> - isSaleable()) { echo ' disabled="disabled"'; } ?> - value="escapeHtmlAttr($_selection->getSelectionId()) ?>"/> + isSelected($_selection)) { echo ' checked="checked"'; } ?> + isSaleable()) { echo ' disabled="disabled"'; } ?> + value="escapeHtmlAttr($_selection->getSelectionId()) ?>" + data-errors-message-box="#validation-message-box-radio"/>
+
- id="bundle-option-escapeHtmlAttr($_option->getId()) ?>-qty-input" - class="input-text qty" - type="number" - min="0" - data-validate="escapeHtmlAttr($viewModel->getQuantityValidators()) ?>" - name="bundle_option_qty[escapeHtmlAttr($_option->getId()) ?>]" - data-selector="bundle_option_qty[escapeHtmlAttr($_option->getId()) ?>]" - value="escapeHtmlAttr($_defaultQty) ?>"/> + id="bundle-option-escapeHtmlAttr($_option->getId()) ?>-qty-input" + class="input-text qty" + type="number" + min="0" + data-validate="escapeHtmlAttr($viewModel->getQuantityValidators()) ?>" + name="bundle_option_qty[escapeHtmlAttr($_option->getId()) ?>]" + data-selector="bundle_option_qty[escapeHtmlAttr($_option->getId()) ?>]" + value="escapeHtmlAttr($_defaultQty) ?>"/>
diff --git a/app/code/Magento/BundleGraphQl/composer.json b/app/code/Magento/BundleGraphQl/composer.json index 7d29641125a37..22720d7f795aa 100644 --- a/app/code/Magento/BundleGraphQl/composer.json +++ b/app/code/Magento/BundleGraphQl/composer.json @@ -2,23 +2,24 @@ "name": "magento/module-bundle-graph-ql", "description": "N/A", "type": "magento2-module", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/module-catalog": "*", - "magento/module-bundle": "*", - "magento/module-graph-ql": "*", - "magento/module-catalog-graph-ql": "*", - "magento/module-quote": "*", - "magento/module-quote-graph-ql": "*", - "magento/module-store": "*", - "magento/module-sales": "*", - "magento/module-sales-graph-ql": "*", - "magento/framework": "*" - }, "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.6", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/module-catalog": "104.0.*", + "magento/module-bundle": "101.0.*", + "magento/module-graph-ql": "100.4.*", + "magento/module-catalog-graph-ql": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-quote-graph-ql": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-sales": "103.0.*", + "magento/module-sales-graph-ql": "100.4.*", + "magento/framework": "103.0.*" + }, "autoload": { "files": [ "registration.php" @@ -28,3 +29,4 @@ } } } + diff --git a/app/code/Magento/BundleImportExport/composer.json b/app/code/Magento/BundleImportExport/composer.json index d7a59a1795ff6..7a4855c5749f3 100644 --- a/app/code/Magento/BundleImportExport/composer.json +++ b/app/code/Magento/BundleImportExport/composer.json @@ -1,24 +1,25 @@ { "name": "magento/module-bundle-import-export", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.5", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-bundle": "*", - "magento/module-store": "*", - "magento/module-catalog": "*", - "magento/module-catalog-import-export": "*", - "magento/module-eav": "*", - "magento/module-import-export": "*" + "magento/framework": "103.0.*", + "magento/module-bundle": "101.0.*", + "magento/module-store": "101.1.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-import-export": "101.1.*", + "magento/module-eav": "102.1.*", + "magento/module-import-export": "101.0.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -28,3 +29,4 @@ } } } + diff --git a/app/code/Magento/CacheInvalidate/composer.json b/app/code/Magento/CacheInvalidate/composer.json index 6c635ea103b0c..eba6b087ca446 100644 --- a/app/code/Magento/CacheInvalidate/composer.json +++ b/app/code/Magento/CacheInvalidate/composer.json @@ -1,19 +1,20 @@ { "name": "magento/module-cache-invalidate", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-page-cache": "*" + "magento/framework": "103.0.*", + "magento/module-page-cache": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -23,3 +24,4 @@ } } } + diff --git a/app/code/Magento/Captcha/Test/Mftf/Test/StorefrontCaptchaLoginOnCheckoutWithEnabledCaptchaTest.xml b/app/code/Magento/Captcha/Test/Mftf/Test/StorefrontCaptchaLoginOnCheckoutWithEnabledCaptchaTest.xml index 89f937fa45592..4e16a98f56b2a 100644 --- a/app/code/Magento/Captcha/Test/Mftf/Test/StorefrontCaptchaLoginOnCheckoutWithEnabledCaptchaTest.xml +++ b/app/code/Magento/Captcha/Test/Mftf/Test/StorefrontCaptchaLoginOnCheckoutWithEnabledCaptchaTest.xml @@ -16,6 +16,7 @@ + diff --git a/app/code/Magento/Captcha/Test/Mftf/Test/StorefrontCaptchaOnOnepageCheckoutPyamentTest.xml b/app/code/Magento/Captcha/Test/Mftf/Test/StorefrontCaptchaOnOnepageCheckoutPyamentTest.xml index 912e637dc534e..4ab4ec7f055f9 100644 --- a/app/code/Magento/Captcha/Test/Mftf/Test/StorefrontCaptchaOnOnepageCheckoutPyamentTest.xml +++ b/app/code/Magento/Captcha/Test/Mftf/Test/StorefrontCaptchaOnOnepageCheckoutPyamentTest.xml @@ -21,6 +21,7 @@ + 20 @@ -62,6 +63,7 @@ + diff --git a/app/code/Magento/Captcha/composer.json b/app/code/Magento/Captcha/composer.json index 0c39d988ba740..592429ac13238 100644 --- a/app/code/Magento/Captcha/composer.json +++ b/app/code/Magento/Captcha/composer.json @@ -1,26 +1,27 @@ { "name": "magento/module-captcha", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.6-p2", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-checkout": "*", - "magento/module-customer": "*", - "magento/module-sales": "*", - "magento/module-store": "*", - "magento/module-authorization": "*", + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-checkout": "100.4.*", + "magento/module-customer": "103.0.*", + "magento/module-sales": "103.0.*", + "magento/module-store": "101.1.*", + "magento/module-authorization": "100.4.*", "laminas/laminas-captcha": "^2.12", "laminas/laminas-db": "^2.13.4" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -30,3 +31,4 @@ } } } + diff --git a/app/code/Magento/CardinalCommerce/composer.json b/app/code/Magento/CardinalCommerce/composer.json index a6bc6bd72afd6..d1c56d6e8bd10 100644 --- a/app/code/Magento/CardinalCommerce/composer.json +++ b/app/code/Magento/CardinalCommerce/composer.json @@ -1,21 +1,22 @@ { "name": "magento/module-cardinal-commerce", "description": "Provides a possibility to enable 3-D Secure 2.0 support for payment methods.", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-checkout": "*", - "magento/module-payment": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-checkout": "100.4.*", + "magento/module-payment": "100.4.*", + "magento/module-store": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -25,3 +26,4 @@ } } } + diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/NewAction.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/NewAction.php index 0b1ef98c386c4..ea14dbc1ce627 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/NewAction.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/NewAction.php @@ -4,18 +4,21 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Catalog\Controller\Adminhtml\Product; -use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface; -use Magento\Backend\App\Action; use Magento\Catalog\Controller\Adminhtml\Product; +use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface; use Magento\Framework\App\ObjectManager; +use Magento\Framework\RegexValidator; class NewAction extends \Magento\Catalog\Controller\Adminhtml\Product implements HttpGetActionInterface { /** * @var Initialization\StockDataFilter * @deprecated 101.0.0 + * @see Initialization\StockDataFilter */ protected $stockFilter; @@ -30,23 +33,32 @@ class NewAction extends \Magento\Catalog\Controller\Adminhtml\Product implements protected $resultForwardFactory; /** - * @param Action\Context $context + * @var RegexValidator + */ + private RegexValidator $regexValidator; + + /** + * @param Context $context * @param Builder $productBuilder * @param Initialization\StockDataFilter $stockFilter * @param \Magento\Framework\View\Result\PageFactory $resultPageFactory * @param \Magento\Backend\Model\View\Result\ForwardFactory $resultForwardFactory + * @param RegexValidator|null $regexValidator */ public function __construct( \Magento\Backend\App\Action\Context $context, Product\Builder $productBuilder, Initialization\StockDataFilter $stockFilter, \Magento\Framework\View\Result\PageFactory $resultPageFactory, - \Magento\Backend\Model\View\Result\ForwardFactory $resultForwardFactory + \Magento\Backend\Model\View\Result\ForwardFactory $resultForwardFactory, + RegexValidator $regexValidator = null ) { $this->stockFilter = $stockFilter; parent::__construct($context, $productBuilder); $this->resultPageFactory = $resultPageFactory; $this->resultForwardFactory = $resultForwardFactory; + $this->regexValidator = $regexValidator + ?: ObjectManager::getInstance()->get(RegexValidator::class); } /** @@ -56,6 +68,11 @@ public function __construct( */ public function execute() { + $typeId = $this->getRequest()->getParam('type'); + if (!$this->regexValidator->validateParamRegex($typeId)) { + return $this->resultForwardFactory->create()->forward('noroute'); + } + if (!$this->getRequest()->getParam('set')) { return $this->resultForwardFactory->create()->forward('noroute'); } diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontProductPageSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontProductPageSection.xml index 7be02126e3a0f..db0179e9d90ce 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontProductPageSection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontProductPageSection.xml @@ -26,5 +26,6 @@ + diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateSimpleProductTest/AdminCreateTwoSimpleProductTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateSimpleProductTest/AdminCreateTwoSimpleProductTest.xml index d74b15b01ea3b..b577865e9df1a 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateSimpleProductTest/AdminCreateTwoSimpleProductTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateSimpleProductTest/AdminCreateTwoSimpleProductTest.xml @@ -15,6 +15,7 @@ + diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateVirtualProductWithoutManageStockTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateVirtualProductWithoutManageStockTest.xml index 7aeb1a1397952..09b88a4358ec2 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateVirtualProductWithoutManageStockTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateVirtualProductWithoutManageStockTest.xml @@ -24,6 +24,9 @@ + + + diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/EndToEndB2CAdminTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/EndToEndB2CAdminTest.xml index 3b0fad592fed8..7a10c0e949e31 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/EndToEndB2CAdminTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/EndToEndB2CAdminTest.xml @@ -18,13 +18,16 @@ + + + + - diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontCategorySidebarMobileMenuTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontCategorySidebarMobileMenuTest.xml index f0058712c41a5..f67d887a3995b 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontCategorySidebarMobileMenuTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontCategorySidebarMobileMenuTest.xml @@ -38,7 +38,9 @@ + + diff --git a/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/NewActionTest.php b/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/NewActionTest.php old mode 100644 new mode 100755 index 974c85b2b5c98..cad43f39f0261 --- a/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/NewActionTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/NewActionTest.php @@ -16,6 +16,9 @@ use Magento\Catalog\Controller\Adminhtml\Product\NewAction; use Magento\Catalog\Model\Product; use Magento\Catalog\Test\Unit\Controller\Adminhtml\ProductTest; +use Magento\Framework\RegexValidator; +use Magento\Framework\Validator\Regex; +use Magento\Framework\Validator\RegexFactory; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use Magento\Framework\View\Result\PageFactory; use PHPUnit\Framework\MockObject\MockObject; @@ -42,6 +45,26 @@ class NewActionTest extends ProductTest */ protected $initializationHelper; + /** + * @var RegexValidator|MockObject + */ + private $regexValidator; + + /** + * @var RegexFactory + */ + private $regexValidatorFactoryMock; + + /** + * @var Regex|MockObject + */ + private $regexValidatorMock; + + /** + * @var ForwardFactory&MockObject|MockObject + */ + private $resultForwardFactory; + protected function setUp(): void { $this->productBuilder = $this->createPartialMock( @@ -63,37 +86,78 @@ protected function setUp(): void ->disableOriginalConstructor() ->setMethods(['create']) ->getMock(); - $resultPageFactory->expects($this->atLeastOnce()) - ->method('create') - ->willReturn($this->resultPage); $this->resultForward = $this->getMockBuilder(Forward::class) ->disableOriginalConstructor() ->getMock(); - $resultForwardFactory = $this->getMockBuilder(ForwardFactory::class) + $this->resultForwardFactory = $this->getMockBuilder(ForwardFactory::class) + ->disableOriginalConstructor() + ->onlyMethods(['create']) + ->getMock(); + + $this->regexValidatorFactoryMock = $this->getMockBuilder(RegexFactory::class) ->disableOriginalConstructor() ->setMethods(['create']) ->getMock(); - $resultForwardFactory->expects($this->any()) - ->method('create') - ->willReturn($this->resultForward); + $this->regexValidatorMock = $this->createMock(Regex::class); + $this->regexValidatorFactoryMock->method('create') + ->willReturn($this->regexValidatorMock); + $this->regexValidator = new regexValidator($this->regexValidatorFactoryMock); $this->action = (new ObjectManager($this))->getObject( NewAction::class, [ 'context' => $this->initContext(), 'productBuilder' => $this->productBuilder, 'resultPageFactory' => $resultPageFactory, - 'resultForwardFactory' => $resultForwardFactory, + 'resultForwardFactory' => $this->resultForwardFactory, + 'regexValidator' => $this->regexValidator, ] ); } - public function testExecute() + /** + * Test execute method input validation. + * + * @param string $value + * @param bool $exceptionThrown + * @dataProvider validationCases + */ + public function testExecute(string $value, bool $exceptionThrown): void + { + if ($exceptionThrown) { + $this->action->getRequest()->expects($this->any()) + ->method('getParam') + ->willReturn($value); + $this->resultForwardFactory->expects($this->any()) + ->method('create') + ->willReturn($this->resultForward); + $this->resultForward->expects($this->once()) + ->method('forward') + ->with('noroute') + ->willReturn(true); + $this->assertTrue($this->action->execute()); + } else { + $this->action->getRequest()->expects($this->any())->method('getParam')->willReturn($value); + $this->regexValidatorMock->expects($this->any()) + ->method('isValid') + ->with($value) + ->willReturn(true); + + $this->assertEquals(true, $this->regexValidator->validateParamRegex($value)); + } + } + + /** + * Validation cases. + * + * @return array + */ + public function validationCases(): array { - $this->action->getRequest()->expects($this->any())->method('getParam')->willReturn(true); - $this->action->getRequest()->expects($this->any())->method('getFullActionName') - ->willReturn('catalog_product_new'); - $this->action->execute(); + return [ + 'execute-with-exception' => ['simple\' and true()]|*[self%3a%3ahandle%20or%20self%3a%3alayout',true], + 'execute-without-exception' => ['catalog_product_new',false] + ]; } } diff --git a/app/code/Magento/Catalog/Test/Unit/Pricing/Render/FinalPriceBoxTest.php b/app/code/Magento/Catalog/Test/Unit/Pricing/Render/FinalPriceBoxTest.php index f3831e50ef3d9..a97c75d32da15 100644 --- a/app/code/Magento/Catalog/Test/Unit/Pricing/Render/FinalPriceBoxTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Pricing/Render/FinalPriceBoxTest.php @@ -15,8 +15,11 @@ use Magento\Catalog\Pricing\Render\FinalPriceBox; use Magento\Framework\App\Cache\StateInterface; use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\App\DeploymentConfig; use Magento\Framework\App\State; +use Magento\Framework\Config\ConfigOptionsListConstants; use Magento\Framework\Event\Test\Unit\ManagerStub; +use Magento\Framework\ObjectManagerInterface; use Magento\Framework\Pricing\Amount\AmountInterface; use Magento\Framework\Pricing\Price\PriceInterface; use Magento\Framework\Pricing\PriceInfoInterface; @@ -96,11 +99,27 @@ class FinalPriceBoxTest extends TestCase */ private $minimalPriceCalculator; + /** + * @var DeploymentConfig|MockObject + */ + private $deploymentConfig; + + /** + * @var ObjectManagerInterface|MockObject + */ + private $objectManagerMock; + /** * @inheritDoc + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ protected function setUp(): void { + $this->objectManagerMock = $this->getMockBuilder(ObjectManagerInterface::class) + ->disableOriginalConstructor() + ->onlyMethods(['get']) + ->getMockForAbstractClass(); + \Magento\Framework\App\ObjectManager::setInstance($this->objectManagerMock); $this->product = $this->getMockBuilder(Product::class) ->addMethods(['getCanShowPrice']) ->onlyMethods(['getPriceInfo', 'isSalable', 'getId']) @@ -183,6 +202,11 @@ protected function setUp(): void ->disableOriginalConstructor() ->getMockForAbstractClass(); + $this->deploymentConfig = $this->createPartialMock( + DeploymentConfig::class, + ['get'] + ); + $this->minimalPriceCalculator = $this->getMockForAbstractClass(MinimalPriceCalculatorInterface::class); $this->object = $objectManager->getObject( FinalPriceBox::class, @@ -455,6 +479,15 @@ public function testHidePrice(): void */ public function testGetCacheKey(): void { + $this->objectManagerMock->expects($this->any()) + ->method('get') + ->with(DeploymentConfig::class) + ->willReturn($this->deploymentConfig); + + $this->deploymentConfig->expects($this->any()) + ->method('get') + ->with(ConfigOptionsListConstants::CONFIG_PATH_CRYPT_KEY) + ->willReturn('448198e08af35844a42d3c93c1ef4e03'); $result = $this->object->getCacheKey(); $this->assertStringEndsWith('list-category-page', $result); } diff --git a/app/code/Magento/Catalog/composer.json b/app/code/Magento/Catalog/composer.json index 4421b2991266b..c54f8be886678 100644 --- a/app/code/Magento/Catalog/composer.json +++ b/app/code/Magento/Catalog/composer.json @@ -1,48 +1,49 @@ { "name": "magento/module-catalog", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "104.0.6-p3", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-authorization": "*", - "magento/module-asynchronous-operations": "*", - "magento/module-backend": "*", - "magento/module-catalog-inventory": "*", - "magento/module-catalog-rule": "*", - "magento/module-catalog-url-rewrite": "*", - "magento/module-checkout": "*", - "magento/module-cms": "*", - "magento/module-config": "*", - "magento/module-customer": "*", - "magento/module-directory": "*", - "magento/module-eav": "*", - "magento/module-indexer": "*", - "magento/module-media-storage": "*", - "magento/module-msrp": "*", - "magento/module-page-cache": "*", - "magento/module-product-alert": "*", - "magento/module-quote": "*", - "magento/module-store": "*", - "magento/module-tax": "*", - "magento/module-theme": "*", - "magento/module-ui": "*", - "magento/module-url-rewrite": "*", - "magento/module-widget": "*", - "magento/module-wishlist": "*" + "magento/framework": "103.0.*", + "magento/module-authorization": "100.4.*", + "magento/module-asynchronous-operations": "100.4.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog-inventory": "100.4.*", + "magento/module-catalog-rule": "101.2.*", + "magento/module-catalog-url-rewrite": "100.4.*", + "magento/module-checkout": "100.4.*", + "magento/module-cms": "104.0.*", + "magento/module-config": "101.2.*", + "magento/module-customer": "103.0.*", + "magento/module-directory": "100.4.*", + "magento/module-eav": "102.1.*", + "magento/module-indexer": "100.4.*", + "magento/module-media-storage": "100.4.*", + "magento/module-msrp": "100.4.*", + "magento/module-page-cache": "100.4.*", + "magento/module-product-alert": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-store": "101.1.*", + "magento/module-tax": "100.4.*", + "magento/module-theme": "101.1.*", + "magento/module-ui": "101.2.*", + "magento/module-url-rewrite": "102.0.*", + "magento/module-widget": "101.2.*", + "magento/module-wishlist": "101.2.*" }, "suggest": { - "magento/module-cookie": "*", - "magento/module-sales": "*", - "magento/module-catalog-sample-data": "*" + "magento/module-cookie": "100.4.*", + "magento/module-sales": "103.0.*", + "magento/module-catalog-sample-data": "Sample Data version: 100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -52,3 +53,4 @@ } } } + diff --git a/app/code/Magento/Catalog/i18n/en_US.csv b/app/code/Magento/Catalog/i18n/en_US.csv index defbf31a6b8f8..81e059adb3bb0 100644 --- a/app/code/Magento/Catalog/i18n/en_US.csv +++ b/app/code/Magento/Catalog/i18n/en_US.csv @@ -819,4 +819,5 @@ Details,Details "Failed to retrieve product links for ""%1""","Failed to retrieve product links for ""%1""" "The linked product SKU is invalid. Verify the data and try again.","The linked product SKU is invalid. Verify the data and try again." "The linked products data is invalid. Verify the data and try again.","The linked products data is invalid. Verify the data and try again." +"The url has invalid characters. Please correct and try again.","The url has invalid characters. Please correct and try again." diff --git a/app/code/Magento/Catalog/view/adminhtml/web/js/category-tree.js b/app/code/Magento/Catalog/view/adminhtml/web/js/category-tree.js index d292bd126593c..b4d4ed12d20ba 100644 --- a/app/code/Magento/Catalog/view/adminhtml/web/js/category-tree.js +++ b/app/code/Magento/Catalog/view/adminhtml/web/js/category-tree.js @@ -5,10 +5,9 @@ define([ 'jquery', - 'mageUtils', 'jquery/ui', 'jquery/jstree/jquery.jstree' -], function ($, utils) { +], function ($) { 'use strict'; $.widget('mage.categoryTree', { @@ -87,7 +86,7 @@ define([ // jscs:disable requireCamelCaseOrUpperCaseIdentifiers result = { id: node.id, - text: utils.unescape(node.name) + ' (' + node.product_count + ')', + text: node.name + ' (' + node.product_count + ')', li_attr: { class: node.cls + (!!node.disabled ? ' disabled' : '') //eslint-disable-line no-extra-boolean-cast }, diff --git a/app/code/Magento/CatalogAnalytics/composer.json b/app/code/Magento/CatalogAnalytics/composer.json index 2710625d0f08d..a1f7f80748319 100644 --- a/app/code/Magento/CatalogAnalytics/composer.json +++ b/app/code/Magento/CatalogAnalytics/composer.json @@ -1,17 +1,18 @@ { "name": "magento/module-catalog-analytics", "description": "N/A", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-catalog": "*", - "magento/module-analytics": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.3", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-analytics": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -21,3 +22,4 @@ } } } + diff --git a/app/code/Magento/CatalogCmsGraphQl/composer.json b/app/code/Magento/CatalogCmsGraphQl/composer.json index d1cff1a3e448f..7168091a40cfd 100644 --- a/app/code/Magento/CatalogCmsGraphQl/composer.json +++ b/app/code/Magento/CatalogCmsGraphQl/composer.json @@ -2,21 +2,22 @@ "name": "magento/module-catalog-cms-graph-ql", "description": "N/A", "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "100.4.2", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-catalog": "*", - "magento/module-cms-graph-ql": "*" + "magento/framework": "103.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-cms-graph-ql": "100.4.*" }, "suggest": { - "magento/module-graph-ql": "*", - "magento/module-cms": "*", - "magento/module-catalog-graph-ql": "*" + "magento/module-graph-ql": "100.4.*", + "magento/module-cms": "104.0.*", + "magento/module-catalog-graph-ql": "100.4.*" }, - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -26,3 +27,4 @@ } } } + diff --git a/app/code/Magento/CatalogCustomerGraphQl/composer.json b/app/code/Magento/CatalogCustomerGraphQl/composer.json index 5c4a301857c7e..d99751e54e243 100644 --- a/app/code/Magento/CatalogCustomerGraphQl/composer.json +++ b/app/code/Magento/CatalogCustomerGraphQl/composer.json @@ -2,17 +2,18 @@ "name": "magento/module-catalog-customer-graph-ql", "description": "N/A", "type": "magento2-module", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-catalog": "*", - "magento/module-customer": "*", - "magento/module-catalog-graph-ql": "*" - }, "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.5", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-customer": "103.0.*", + "magento/module-catalog-graph-ql": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -22,3 +23,4 @@ } } } + diff --git a/app/code/Magento/CatalogGraphQl/composer.json b/app/code/Magento/CatalogGraphQl/composer.json index fbc4172226c58..b863dec6df3a5 100644 --- a/app/code/Magento/CatalogGraphQl/composer.json +++ b/app/code/Magento/CatalogGraphQl/composer.json @@ -2,28 +2,29 @@ "name": "magento/module-catalog-graph-ql", "description": "N/A", "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "100.4.6", "require": { "php": "~8.1.0||~8.2.0", - "magento/module-eav": "*", - "magento/module-catalog": "*", - "magento/module-catalog-inventory": "*", - "magento/module-directory": "*", - "magento/module-search": "*", - "magento/module-store": "*", - "magento/module-eav-graph-ql": "*", - "magento/module-catalog-search": "*", - "magento/framework": "*", - "magento/module-graph-ql": "*", - "magento/module-advanced-search": "*" + "magento/module-eav": "102.1.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-inventory": "100.4.*", + "magento/module-directory": "100.4.*", + "magento/module-search": "101.1.*", + "magento/module-store": "101.1.*", + "magento/module-eav-graph-ql": "100.4.*", + "magento/module-catalog-search": "102.0.*", + "magento/framework": "103.0.*", + "magento/module-graph-ql": "100.4.*", + "magento/module-advanced-search": "100.4.*" }, "suggest": { - "magento/module-graph-ql-cache": "*", - "magento/module-store-graph-ql": "*" + "magento/module-graph-ql-cache": "100.4.*", + "magento/module-store-graph-ql": "100.4.*" }, - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -33,3 +34,4 @@ } } } + diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product.php b/app/code/Magento/CatalogImportExport/Model/Import/Product.php index e7c7ede1ca3db..bec6517e8fb05 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product.php @@ -48,6 +48,7 @@ */ class Product extends AbstractEntity { + private const COL_NAME_FORMAT = '/[\x00-\x1F\x7F]/'; private const DEFAULT_GLOBAL_MULTIPLE_VALUE_SEPARATOR = ','; public const CONFIG_KEY_PRODUCT_TYPES = 'global/importexport/import_product_types'; @@ -1624,6 +1625,12 @@ protected function _saveProducts() // the bunch of products will pass for the event with url_key column. $bunch[$rowNum][self::URL_KEY] = $rowData[self::URL_KEY] = $urlKey; } + + if (!empty($rowData[self::COL_NAME])) { + // remove null byte character + $rowData[self::COL_NAME] = preg_replace(self::COL_NAME_FORMAT, '', $rowData[self::COL_NAME]); + } + $rowSku = $rowData[self::COL_SKU]; if (null === $rowSku) { $this->getErrorAggregator()->addRowToSkip($rowNum); @@ -1660,7 +1667,7 @@ protected function _saveProducts() $prevAttributeSet, $attributes ); - // phpcs:ignore Magento2.CodeAnalysis.EmptyBlock.DetectedCatch + // phpcs:ignore Magento2.CodeAnalysis.EmptyBlock.DetectedCatch } catch (Skip $skip) { // Product is skipped. Go on to the next one. } diff --git a/app/code/Magento/CatalogImportExport/composer.json b/app/code/Magento/CatalogImportExport/composer.json index 41b2b5f72ce7b..4ef2e08aa8810 100644 --- a/app/code/Magento/CatalogImportExport/composer.json +++ b/app/code/Magento/CatalogImportExport/composer.json @@ -1,29 +1,30 @@ { "name": "magento/module-catalog-import-export", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "101.1.6-p1", "require": { "php": "~8.1.0||~8.2.0", "ext-ctype": "*", - "magento/framework": "*", - "magento/module-catalog": "*", - "magento/module-catalog-inventory": "*", - "magento/module-catalog-url-rewrite": "*", - "magento/module-customer": "*", - "magento/module-eav": "*", - "magento/module-import-export": "*", - "magento/module-media-storage": "*", - "magento/module-store": "*", - "magento/module-tax": "*", - "magento/module-authorization": "*" + "magento/framework": "103.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-inventory": "100.4.*", + "magento/module-catalog-url-rewrite": "100.4.*", + "magento/module-customer": "103.0.*", + "magento/module-eav": "102.1.*", + "magento/module-import-export": "101.0.*", + "magento/module-media-storage": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-tax": "100.4.*", + "magento/module-authorization": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -33,3 +34,4 @@ } } } + diff --git a/app/code/Magento/CatalogInventory/Test/Mftf/Test/DisabledInventoryCheckOnePageCheckoutTest.xml b/app/code/Magento/CatalogInventory/Test/Mftf/Test/DisabledInventoryCheckOnePageCheckoutTest.xml index 7d00422aa1f6e..6ed5c374caa49 100644 --- a/app/code/Magento/CatalogInventory/Test/Mftf/Test/DisabledInventoryCheckOnePageCheckoutTest.xml +++ b/app/code/Magento/CatalogInventory/Test/Mftf/Test/DisabledInventoryCheckOnePageCheckoutTest.xml @@ -16,6 +16,7 @@ + diff --git a/app/code/Magento/CatalogInventory/composer.json b/app/code/Magento/CatalogInventory/composer.json index 7ea00923ac715..3589cbe29c04b 100644 --- a/app/code/Magento/CatalogInventory/composer.json +++ b/app/code/Magento/CatalogInventory/composer.json @@ -1,25 +1,26 @@ { "name": "magento/module-catalog-inventory", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.6-p2", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-catalog": "*", - "magento/module-config": "*", - "magento/module-customer": "*", - "magento/module-eav": "*", - "magento/module-quote": "*", - "magento/module-store": "*", - "magento/module-ui": "*" + "magento/framework": "103.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-config": "101.2.*", + "magento/module-customer": "103.0.*", + "magento/module-eav": "102.1.*", + "magento/module-quote": "101.2.*", + "magento/module-store": "101.1.*", + "magento/module-ui": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -30,3 +31,4 @@ }, "abandoned": "magento/inventory-metapackage" } + diff --git a/app/code/Magento/CatalogInventoryGraphQl/composer.json b/app/code/Magento/CatalogInventoryGraphQl/composer.json index 58d567bc0706e..4c45fd6319edf 100644 --- a/app/code/Magento/CatalogInventoryGraphQl/composer.json +++ b/app/code/Magento/CatalogInventoryGraphQl/composer.json @@ -2,18 +2,19 @@ "name": "magento/module-catalog-inventory-graph-ql", "description": "N/A", "type": "magento2-module", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-store": "*", - "magento/module-catalog": "*", - "magento/module-catalog-inventory": "*", - "magento/module-graph-ql": "*" - }, "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.3", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*", + "magento/module-store": "101.1.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-inventory": "100.4.*", + "magento/module-graph-ql": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -23,3 +24,4 @@ } } } + diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminDeleteCatalogPriceRuleEntityTest/AdminDeleteCatalogPriceRuleEntityFromSimpleProductTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminDeleteCatalogPriceRuleEntityTest/AdminDeleteCatalogPriceRuleEntityFromSimpleProductTest.xml index c6452612f82a4..118091288db94 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminDeleteCatalogPriceRuleEntityTest/AdminDeleteCatalogPriceRuleEntityFromSimpleProductTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminDeleteCatalogPriceRuleEntityTest/AdminDeleteCatalogPriceRuleEntityFromSimpleProductTest.xml @@ -16,6 +16,7 @@ + diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontApplyCatalogRuleForSimpleProductsWithCustomOptionsTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontApplyCatalogRuleForSimpleProductsWithCustomOptionsTest.xml index a616a7ab172f1..09868a880d7a7 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontApplyCatalogRuleForSimpleProductsWithCustomOptionsTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontApplyCatalogRuleForSimpleProductsWithCustomOptionsTest.xml @@ -18,6 +18,7 @@ + diff --git a/app/code/Magento/CatalogRule/composer.json b/app/code/Magento/CatalogRule/composer.json index dc9c51dade87f..4466589e6d1c0 100644 --- a/app/code/Magento/CatalogRule/composer.json +++ b/app/code/Magento/CatalogRule/composer.json @@ -1,29 +1,30 @@ { "name": "magento/module-catalog-rule", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "101.2.6-p2", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-customer": "*", - "magento/module-eav": "*", - "magento/module-rule": "*", - "magento/module-store": "*", - "magento/module-ui": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-customer": "103.0.*", + "magento/module-eav": "102.1.*", + "magento/module-rule": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-ui": "101.2.*" }, "suggest": { - "magento/module-import-export": "*", - "magento/module-catalog-rule-sample-data": "*" + "magento/module-import-export": "101.0.*", + "magento/module-catalog-rule-sample-data": "Sample Data version: 100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -33,3 +34,4 @@ } } } + diff --git a/app/code/Magento/CatalogRuleConfigurable/composer.json b/app/code/Magento/CatalogRuleConfigurable/composer.json index 8b6569ba9fec4..02fa1e01e9831 100644 --- a/app/code/Magento/CatalogRuleConfigurable/composer.json +++ b/app/code/Magento/CatalogRuleConfigurable/composer.json @@ -1,25 +1,26 @@ { "name": "magento/module-catalog-rule-configurable", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.5", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", + "magento/framework": "103.0.*", "magento/magento-composer-installer": "*", - "magento/module-catalog": "*", - "magento/module-catalog-rule": "*", - "magento/module-configurable-product": "*" + "magento/module-catalog": "104.0.*", + "magento/module-catalog-rule": "101.2.*", + "magento/module-configurable-product": "100.4.*" }, "suggest": { - "magento/module-catalog-rule": "*" + "magento/module-catalog-rule": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -29,3 +30,4 @@ } } } + diff --git a/app/code/Magento/CatalogRuleGraphQl/composer.json b/app/code/Magento/CatalogRuleGraphQl/composer.json index c22ba277d57d9..d6af5d0916f72 100644 --- a/app/code/Magento/CatalogRuleGraphQl/composer.json +++ b/app/code/Magento/CatalogRuleGraphQl/composer.json @@ -2,17 +2,18 @@ "name": "magento/module-catalog-rule-graph-ql", "description": "N/A", "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "100.4.3", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*" + "magento/framework": "103.0.*" }, "suggest": { - "magento/module-catalog-rule": "*" + "magento/module-catalog-rule": "101.2.*" }, - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -22,3 +23,4 @@ } } } + diff --git a/app/code/Magento/CatalogSearch/composer.json b/app/code/Magento/CatalogSearch/composer.json index 7ccdb99d2c9d1..cb1a3c3c13928 100644 --- a/app/code/Magento/CatalogSearch/composer.json +++ b/app/code/Magento/CatalogSearch/composer.json @@ -1,32 +1,33 @@ { "name": "magento/module-catalog-search", "description": "Catalog search", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "102.0.6", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-indexer": "*", - "magento/module-catalog-inventory": "*", - "magento/module-customer": "*", - "magento/module-directory": "*", - "magento/module-eav": "*", - "magento/module-search": "*", - "magento/module-store": "*", - "magento/module-theme": "*", - "magento/module-ui": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-indexer": "100.4.*", + "magento/module-catalog-inventory": "100.4.*", + "magento/module-customer": "103.0.*", + "magento/module-directory": "100.4.*", + "magento/module-eav": "102.1.*", + "magento/module-search": "101.1.*", + "magento/module-store": "101.1.*", + "magento/module-theme": "101.1.*", + "magento/module-ui": "101.2.*" }, "suggest": { - "magento/module-config": "*" + "magento/module-config": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -36,3 +37,4 @@ } } } + diff --git a/app/code/Magento/CatalogUrlRewrite/composer.json b/app/code/Magento/CatalogUrlRewrite/composer.json index 6df0042d40648..fdf8b4df854c3 100644 --- a/app/code/Magento/CatalogUrlRewrite/composer.json +++ b/app/code/Magento/CatalogUrlRewrite/composer.json @@ -1,29 +1,30 @@ { "name": "magento/module-catalog-url-rewrite", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.6", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-catalog-import-export": "*", - "magento/module-eav": "*", - "magento/module-import-export": "*", - "magento/module-store": "*", - "magento/module-ui": "*", - "magento/module-url-rewrite": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-import-export": "101.1.*", + "magento/module-eav": "102.1.*", + "magento/module-import-export": "101.0.*", + "magento/module-store": "101.1.*", + "magento/module-ui": "101.2.*", + "magento/module-url-rewrite": "102.0.*" }, "suggest": { - "magento/module-webapi": "*" + "magento/module-webapi": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -33,3 +34,4 @@ } } } + diff --git a/app/code/Magento/CatalogUrlRewriteGraphQl/composer.json b/app/code/Magento/CatalogUrlRewriteGraphQl/composer.json index c3917a517a68d..3879b426cc935 100644 --- a/app/code/Magento/CatalogUrlRewriteGraphQl/composer.json +++ b/app/code/Magento/CatalogUrlRewriteGraphQl/composer.json @@ -2,23 +2,24 @@ "name": "magento/module-catalog-url-rewrite-graph-ql", "description": "N/A", "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "100.4.4", "require": { "php": "~8.1.0||~8.2.0", - "magento/module-store": "*", - "magento/module-catalog": "*", - "magento/module-catalog-graph-ql": "*", - "magento/module-url-rewrite-graph-ql": "*", - "magento/framework": "*" + "magento/module-store": "101.1.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-graph-ql": "100.4.*", + "magento/module-url-rewrite-graph-ql": "100.4.*", + "magento/framework": "103.0.*" }, "suggest": { - "magento/module-catalog-url-rewrite": "*", - "magento/module-catalog-graph-ql": "*", - "magento/module-url-rewrite-graph-ql": "*" + "magento/module-catalog-url-rewrite": "100.4.*", + "magento/module-catalog-graph-ql": "100.4.*", + "magento/module-url-rewrite-graph-ql": "100.4.*" }, - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -28,3 +29,4 @@ } } } + diff --git a/app/code/Magento/CatalogWidget/composer.json b/app/code/Magento/CatalogWidget/composer.json index b54b27474787b..9c51b4f00d30e 100644 --- a/app/code/Magento/CatalogWidget/composer.json +++ b/app/code/Magento/CatalogWidget/composer.json @@ -1,27 +1,28 @@ { "name": "magento/module-catalog-widget", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.6", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-customer": "*", - "magento/module-eav": "*", - "magento/module-rule": "*", - "magento/module-store": "*", - "magento/module-widget": "*", - "magento/module-wishlist": "*", - "magento/module-theme": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-customer": "103.0.*", + "magento/module-eav": "102.1.*", + "magento/module-rule": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-widget": "101.2.*", + "magento/module-wishlist": "101.2.*", + "magento/module-theme": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -31,3 +32,4 @@ } } } + diff --git a/app/code/Magento/Checkout/Model/ShippingInformationManagement.php b/app/code/Magento/Checkout/Model/ShippingInformationManagement.php index f397a8ddc9cf1..f08c48c55efa1 100644 --- a/app/code/Magento/Checkout/Model/ShippingInformationManagement.php +++ b/app/code/Magento/Checkout/Model/ShippingInformationManagement.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Checkout\Model; @@ -39,60 +40,62 @@ class ShippingInformationManagement implements ShippingInformationManagementInte /** * @var PaymentMethodManagementInterface */ - protected $paymentMethodManagement; + protected PaymentMethodManagementInterface $paymentMethodManagement; /** * @var PaymentDetailsFactory */ - protected $paymentDetailsFactory; + protected PaymentDetailsFactory $paymentDetailsFactory; /** * @var CartTotalRepositoryInterface */ - protected $cartTotalsRepository; + protected CartTotalRepositoryInterface $cartTotalsRepository; /** * @var CartRepositoryInterface */ - protected $quoteRepository; - + protected CartRepositoryInterface $quoteRepository; /** * @var Logger */ - protected $logger; + protected Logger $logger; /** * @var QuoteAddressValidator */ - protected $addressValidator; + protected QuoteAddressValidator $addressValidator; /** * @var AddressRepositoryInterface * @deprecated 100.2.0 + * @see AddressRepositoryInterface */ - protected $addressRepository; + protected AddressRepositoryInterface $addressRepository; /** * @var ScopeConfigInterface * @deprecated 100.2.0 + * @see ScopeConfigInterface */ - protected $scopeConfig; + protected ScopeConfigInterface $scopeConfig; /** * @var TotalsCollector * @deprecated 100.2.0 + * @see TotalsCollector */ - protected $totalsCollector; + protected TotalsCollector $totalsCollector; /** * @var CartExtensionFactory */ - private $cartExtensionFactory; + private CartExtensionFactory $cartExtensionFactory; /** * @var ShippingAssignmentFactory */ - protected $shippingAssignmentFactory; + protected ShippingAssignmentFactory $shippingAssignmentFactory; /** * @var ShippingFactory @@ -262,8 +265,11 @@ protected function validateQuote(Quote $quote): void * @param string $method * @return CartInterface */ - private function prepareShippingAssignment(CartInterface $quote, AddressInterface $address, $method): CartInterface - { + private function prepareShippingAssignment( + CartInterface $quote, + AddressInterface $address, + string $method + ): CartInterface { $cartExtension = $quote->getExtensionAttributes(); if ($cartExtension === null) { $cartExtension = $this->cartExtensionFactory->create(); diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/AdminDisableGuestCheckoutActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/AdminDisableGuestCheckoutActionGroup.xml new file mode 100644 index 0000000000000..435170e3b933c --- /dev/null +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/AdminDisableGuestCheckoutActionGroup.xml @@ -0,0 +1,18 @@ + + + + + + + Runs bin/magento command to disable guest checkout + + + + + diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/AdminEnableGuestCheckoutActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/AdminEnableGuestCheckoutActionGroup.xml new file mode 100644 index 0000000000000..1dce549999055 --- /dev/null +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/AdminEnableGuestCheckoutActionGroup.xml @@ -0,0 +1,18 @@ + + + + + + + Runs bin/magento command to enable guest checkout + + + + + diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/AssertStorefrontNotCalculatedValueInShippingTotalInOrderSummaryActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/AssertStorefrontNotCalculatedValueInShippingTotalInOrderSummaryActionGroup.xml index 1ec42033a782b..589d259f2ca7d 100644 --- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/AssertStorefrontNotCalculatedValueInShippingTotalInOrderSummaryActionGroup.xml +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/AssertStorefrontNotCalculatedValueInShippingTotalInOrderSummaryActionGroup.xml @@ -16,6 +16,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/AssertStorefrontOrderCannotBePlacedActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/AssertStorefrontOrderCannotBePlacedActionGroup.xml index 4f9555d84898d..fec0aa3cf218b 100644 --- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/AssertStorefrontOrderCannotBePlacedActionGroup.xml +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/AssertStorefrontOrderCannotBePlacedActionGroup.xml @@ -18,6 +18,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/AddressStateFieldShouldNotAcceptJustIntegerValuesTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/AddressStateFieldShouldNotAcceptJustIntegerValuesTest.xml index eddb7d430387c..ec39d428072fb 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/AddressStateFieldShouldNotAcceptJustIntegerValuesTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/AddressStateFieldShouldNotAcceptJustIntegerValuesTest.xml @@ -17,6 +17,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/AdminCheckConfigsChangesIsNotAffectedStartedCheckoutProcessTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/AdminCheckConfigsChangesIsNotAffectedStartedCheckoutProcessTest.xml index 1a7e2255db35c..359a1ec1ee173 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/AdminCheckConfigsChangesIsNotAffectedStartedCheckoutProcessTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/AdminCheckConfigsChangesIsNotAffectedStartedCheckoutProcessTest.xml @@ -17,6 +17,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/AdminCheckZeroSubtotalOrderIsInProcessingStatusTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/AdminCheckZeroSubtotalOrderIsInProcessingStatusTest.xml index 12a524d2d6ad8..586a979a5a55c 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/AdminCheckZeroSubtotalOrderIsInProcessingStatusTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/AdminCheckZeroSubtotalOrderIsInProcessingStatusTest.xml @@ -18,6 +18,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/AdminCheckZeroSubtotalOrderWithCustomStatus.xml b/app/code/Magento/Checkout/Test/Mftf/Test/AdminCheckZeroSubtotalOrderWithCustomStatus.xml index f08640d895b6b..7c9385dcaf039 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/AdminCheckZeroSubtotalOrderWithCustomStatus.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/AdminCheckZeroSubtotalOrderWithCustomStatus.xml @@ -18,6 +18,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/AdminCheckZeroSubtotalOrderWithGeneratedInvoiceTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/AdminCheckZeroSubtotalOrderWithGeneratedInvoiceTest.xml index 81de8664f98e2..b278ca681e9cd 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/AdminCheckZeroSubtotalOrderWithGeneratedInvoiceTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/AdminCheckZeroSubtotalOrderWithGeneratedInvoiceTest.xml @@ -18,6 +18,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/CheckCheckoutSuccessPageTest/CheckCheckoutSuccessPageAsGuestTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/CheckCheckoutSuccessPageTest/CheckCheckoutSuccessPageAsGuestTest.xml index 9a3a590952467..3409c61214abb 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/CheckCheckoutSuccessPageTest/CheckCheckoutSuccessPageAsGuestTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/CheckCheckoutSuccessPageTest/CheckCheckoutSuccessPageAsGuestTest.xml @@ -17,6 +17,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/CheckoutDifferentDefaultCountryPerStoreTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/CheckoutDifferentDefaultCountryPerStoreTest.xml index 13e8cba7003be..0f762e3fa15d7 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/CheckoutDifferentDefaultCountryPerStoreTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/CheckoutDifferentDefaultCountryPerStoreTest.xml @@ -18,6 +18,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutAsCustomerUsingDefaultAddressTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutAsCustomerUsingDefaultAddressTest.xml index 64f392d39edcb..75abc9324d6f3 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutAsCustomerUsingDefaultAddressTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutAsCustomerUsingDefaultAddressTest.xml @@ -18,13 +18,14 @@ + + 560 - @@ -40,6 +41,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutAsCustomerUsingNewAddressTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutAsCustomerUsingNewAddressTest.xml index 138fbe5055d61..303d4414cda0d 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutAsCustomerUsingNewAddressTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutAsCustomerUsingNewAddressTest.xml @@ -18,6 +18,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutAsCustomerUsingNonDefaultAddressTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutAsCustomerUsingNonDefaultAddressTest.xml index f6db22cbccaa8..41e643f273e2e 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutAsCustomerUsingNonDefaultAddressTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutAsCustomerUsingNonDefaultAddressTest.xml @@ -18,8 +18,10 @@ + + 560 @@ -40,6 +42,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutCancelEditingBillingAddress.xml b/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutCancelEditingBillingAddress.xml index 5dbe287d88d3a..23142d83e0584 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutCancelEditingBillingAddress.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutCancelEditingBillingAddress.xml @@ -16,6 +16,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutUsingSignInLinkTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutUsingSignInLinkTest.xml index b8b8155159d37..9ff8fb61c25d5 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutUsingSignInLinkTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutUsingSignInLinkTest.xml @@ -18,6 +18,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutWithSignInLinkForEmailVerificationTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutWithSignInLinkForEmailVerificationTest.xml index 2e1c8d5a27886..bb8a0edcdba8d 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutWithSignInLinkForEmailVerificationTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutWithSignInLinkForEmailVerificationTest.xml @@ -18,6 +18,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontAddressStateFieldForUKCustomerRemainOptionAfterRefreshTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontAddressStateFieldForUKCustomerRemainOptionAfterRefreshTest.xml index 6b9c1f8f9b009..2d144dc580f67 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontAddressStateFieldForUKCustomerRemainOptionAfterRefreshTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontAddressStateFieldForUKCustomerRemainOptionAfterRefreshTest.xml @@ -17,6 +17,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontApplyPromoCodeDuringCheckoutTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontApplyPromoCodeDuringCheckoutTest.xml index c68abb2f4ea8d..4c5db5d345ac8 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontApplyPromoCodeDuringCheckoutTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontApplyPromoCodeDuringCheckoutTest.xml @@ -18,6 +18,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckCartAndCheckoutItemsCountTest/StorefrontCartItemsCountDisplayItemsQuantitiesTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckCartAndCheckoutItemsCountTest/StorefrontCartItemsCountDisplayItemsQuantitiesTest.xml index 83ed32803654e..a575efb281d25 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckCartAndCheckoutItemsCountTest/StorefrontCartItemsCountDisplayItemsQuantitiesTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckCartAndCheckoutItemsCountTest/StorefrontCartItemsCountDisplayItemsQuantitiesTest.xml @@ -15,6 +15,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckCartAndCheckoutItemsCountTest/StorefrontCartItemsCountDisplayUniqueItemsTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckCartAndCheckoutItemsCountTest/StorefrontCartItemsCountDisplayUniqueItemsTest.xml index 9fa7f64d38aa1..910455cc6a69a 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckCartAndCheckoutItemsCountTest/StorefrontCartItemsCountDisplayUniqueItemsTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckCartAndCheckoutItemsCountTest/StorefrontCartItemsCountDisplayUniqueItemsTest.xml @@ -15,6 +15,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckCartAndSummaryBlockItemDisplayWithDefaultDisplayLimitationTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckCartAndSummaryBlockItemDisplayWithDefaultDisplayLimitationTest.xml index 6af6df2ea03f3..868459b9c9677 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckCartAndSummaryBlockItemDisplayWithDefaultDisplayLimitationTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckCartAndSummaryBlockItemDisplayWithDefaultDisplayLimitationTest.xml @@ -15,6 +15,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckCustomerInfoOnOrderPageCreatedByGuestTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckCustomerInfoOnOrderPageCreatedByGuestTest.xml index e769d9d37286d..bfe0558522029 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckCustomerInfoOnOrderPageCreatedByGuestTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckCustomerInfoOnOrderPageCreatedByGuestTest.xml @@ -18,6 +18,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckSimpleProductCartItemDisplayWithDefaultLimitationTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckSimpleProductCartItemDisplayWithDefaultLimitationTest.xml index ee32ce6d928a1..3f281d802ffe2 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckSimpleProductCartItemDisplayWithDefaultLimitationTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckSimpleProductCartItemDisplayWithDefaultLimitationTest.xml @@ -15,6 +15,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckVirtualProductCountDisplayWithCustomDisplayConfigurationTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckVirtualProductCountDisplayWithCustomDisplayConfigurationTest.xml index f20a21da14969..7772234e34c10 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckVirtualProductCountDisplayWithCustomDisplayConfigurationTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckVirtualProductCountDisplayWithCustomDisplayConfigurationTest.xml @@ -15,6 +15,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutWithDifferentShippingAndBillingAddressAndCreateCustomerAfterCheckoutTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutWithDifferentShippingAndBillingAddressAndCreateCustomerAfterCheckoutTest.xml index 1ea3f118f9f23..a18c7ed6c71e9 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutWithDifferentShippingAndBillingAddressAndCreateCustomerAfterCheckoutTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutWithDifferentShippingAndBillingAddressAndCreateCustomerAfterCheckoutTest.xml @@ -16,6 +16,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutWithDifferentShippingAndBillingAddressAndProductWithTierPricesTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutWithDifferentShippingAndBillingAddressAndProductWithTierPricesTest.xml index ef38a85c6c509..c25ae432c6d33 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutWithDifferentShippingAndBillingAddressAndProductWithTierPricesTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutWithDifferentShippingAndBillingAddressAndProductWithTierPricesTest.xml @@ -15,6 +15,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutWithPurchaseOrderNumberPressKeyEnterTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutWithPurchaseOrderNumberPressKeyEnterTest.xml index 1055ff25edaef..77d52fed2f0d6 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutWithPurchaseOrderNumberPressKeyEnterTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutWithPurchaseOrderNumberPressKeyEnterTest.xml @@ -17,6 +17,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutWithPurchaseOrderNumberTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutWithPurchaseOrderNumberTest.xml index c2dc47c006a1b..c289179864894 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutWithPurchaseOrderNumberTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutWithPurchaseOrderNumberTest.xml @@ -15,6 +15,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutWithSpecialPriceProductsTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutWithSpecialPriceProductsTest.xml index 1a85bb0bee1ee..0ee0e852ece05 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutWithSpecialPriceProductsTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutWithSpecialPriceProductsTest.xml @@ -15,9 +15,11 @@ + + @@ -105,6 +107,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerLoginDuringCheckoutTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerLoginDuringCheckoutTest.xml index eb76748a81c97..98a46c2a04903 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerLoginDuringCheckoutTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerLoginDuringCheckoutTest.xml @@ -17,8 +17,10 @@ + + @@ -39,9 +41,9 @@ - + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutDataPersistTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutDataPersistTest.xml index 45eb3443e4205..715d61294c180 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutDataPersistTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutDataPersistTest.xml @@ -17,6 +17,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutForSpecificCountriesTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutForSpecificCountriesTest.xml index f6a332a529dc9..fb8473e3422cc 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutForSpecificCountriesTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutForSpecificCountriesTest.xml @@ -17,6 +17,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest/StorefrontCheckoutSummaryItemsInCartLabelPluralizedTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest/StorefrontCheckoutSummaryItemsInCartLabelPluralizedTest.xml index e61ad766565d7..8810cbbf71e3a 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest/StorefrontCheckoutSummaryItemsInCartLabelPluralizedTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest/StorefrontCheckoutSummaryItemsInCartLabelPluralizedTest.xml @@ -14,6 +14,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest/StorefrontGuestCheckoutAddNewAddressTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest/StorefrontGuestCheckoutAddNewAddressTest.xml index cf21af3daed17..0206fbb3a9099 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest/StorefrontGuestCheckoutAddNewAddressTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest/StorefrontGuestCheckoutAddNewAddressTest.xml @@ -17,6 +17,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest/StorefrontGuestCheckoutTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest/StorefrontGuestCheckoutTest.xml index da4a1b93691b6..a639a094291a4 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest/StorefrontGuestCheckoutTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest/StorefrontGuestCheckoutTest.xml @@ -16,6 +16,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest/StorefrontGuestCheckoutTestWithRestrictedCountriesForPaymentTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest/StorefrontGuestCheckoutTestWithRestrictedCountriesForPaymentTest.xml index a393d6b42df48..472aa3e978e3f 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest/StorefrontGuestCheckoutTestWithRestrictedCountriesForPaymentTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest/StorefrontGuestCheckoutTestWithRestrictedCountriesForPaymentTest.xml @@ -16,6 +16,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest/StorefrontGuestCheckoutWithSidebarDisabledTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest/StorefrontGuestCheckoutWithSidebarDisabledTest.xml index 4a4d7bcabfb03..d4580f0927877 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest/StorefrontGuestCheckoutWithSidebarDisabledTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest/StorefrontGuestCheckoutWithSidebarDisabledTest.xml @@ -16,6 +16,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutWithCouponAndZeroSubtotalTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutWithCouponAndZeroSubtotalTest.xml index f81ee2fc19d5b..a7fde20c9543a 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutWithCouponAndZeroSubtotalTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutWithCouponAndZeroSubtotalTest.xml @@ -15,6 +15,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutWithDifferentShippingAndBillingAddressWithRestrictedCountriesForPaymentTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutWithDifferentShippingAndBillingAddressWithRestrictedCountriesForPaymentTest.xml index ad4dbd0ab8047..e6db1378efadb 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutWithDifferentShippingAndBillingAddressWithRestrictedCountriesForPaymentTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutWithDifferentShippingAndBillingAddressWithRestrictedCountriesForPaymentTest.xml @@ -18,6 +18,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontNotApplicableShippingMethodInReviewAndPaymentStepTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontNotApplicableShippingMethodInReviewAndPaymentStepTest.xml index d83550a82a87c..3401d053f38f2 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontNotApplicableShippingMethodInReviewAndPaymentStepTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontNotApplicableShippingMethodInReviewAndPaymentStepTest.xml @@ -17,6 +17,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontOnePageCheckoutDataWhenChangeQtyTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontOnePageCheckoutDataWhenChangeQtyTest.xml index 502a564a22ffd..468c0d248aeca 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontOnePageCheckoutDataWhenChangeQtyTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontOnePageCheckoutDataWhenChangeQtyTest.xml @@ -17,6 +17,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontPersistentDataForGuestCustomerWithPhysicalQuoteTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontPersistentDataForGuestCustomerWithPhysicalQuoteTest.xml index 3ab3a0b4ad3f7..5b90db5c6c6d2 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontPersistentDataForGuestCustomerWithPhysicalQuoteTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontPersistentDataForGuestCustomerWithPhysicalQuoteTest.xml @@ -17,6 +17,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontProductNameMinicartOnCheckoutPageDifferentStoreViewsTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontProductNameMinicartOnCheckoutPageDifferentStoreViewsTest.xml index 463a55f59c797..cc087f3f344e2 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontProductNameMinicartOnCheckoutPageDifferentStoreViewsTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontProductNameMinicartOnCheckoutPageDifferentStoreViewsTest.xml @@ -18,6 +18,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontProductQuantityChangesInBackendAfterCustomerCheckoutTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontProductQuantityChangesInBackendAfterCustomerCheckoutTest.xml index 50f906fa9d2ca..5cda02330bb2c 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontProductQuantityChangesInBackendAfterCustomerCheckoutTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontProductQuantityChangesInBackendAfterCustomerCheckoutTest.xml @@ -15,6 +15,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontRefreshPageDuringGuestCheckoutTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontRefreshPageDuringGuestCheckoutTest.xml index 87eba009f5e56..7c0a0af8a6840 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontRefreshPageDuringGuestCheckoutTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontRefreshPageDuringGuestCheckoutTest.xml @@ -17,6 +17,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUKGuestCheckoutWithConditionProductQuantityEqualsToOrderedQuantityTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUKGuestCheckoutWithConditionProductQuantityEqualsToOrderedQuantityTest.xml index dfb778bc2e027..04825729271ed 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUKGuestCheckoutWithConditionProductQuantityEqualsToOrderedQuantityTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUKGuestCheckoutWithConditionProductQuantityEqualsToOrderedQuantityTest.xml @@ -15,6 +15,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUSCustomerCheckoutWithCouponAndBankTransferPaymentMethodTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUSCustomerCheckoutWithCouponAndBankTransferPaymentMethodTest.xml index a17ce096a95f9..a5c9da0af6753 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUSCustomerCheckoutWithCouponAndBankTransferPaymentMethodTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUSCustomerCheckoutWithCouponAndBankTransferPaymentMethodTest.xml @@ -15,6 +15,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUpdatePriceInShoppingCartAfterProductSaveTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUpdatePriceInShoppingCartAfterProductSaveTest.xml index 05dff1ae58773..1eeaa6babe4a1 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUpdatePriceInShoppingCartAfterProductSaveTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUpdatePriceInShoppingCartAfterProductSaveTest.xml @@ -17,6 +17,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontValidateEmailOnCheckoutTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontValidateEmailOnCheckoutTest.xml index 65f5dd365b215..b147031e4923f 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontValidateEmailOnCheckoutTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontValidateEmailOnCheckoutTest.xml @@ -20,6 +20,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontVerifyGuestCheckoutUsingFreeShippingAndTaxesTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontVerifyGuestCheckoutUsingFreeShippingAndTaxesTest.xml index e7dd7a0db223f..40f18df576093 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontVerifyGuestCheckoutUsingFreeShippingAndTaxesTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontVerifyGuestCheckoutUsingFreeShippingAndTaxesTest.xml @@ -18,6 +18,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontVerifySecureURLRedirectCheckoutTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontVerifySecureURLRedirectCheckoutTest.xml index 901c5c3598dbf..35793fa14c0de 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontVerifySecureURLRedirectCheckoutTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontVerifySecureURLRedirectCheckoutTest.xml @@ -19,6 +19,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontVisiblePasswordFieldForUnregisteredEmailOnCheckoutTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontVisiblePasswordFieldForUnregisteredEmailOnCheckoutTest.xml index 41b5f734d0096..562b1013e722e 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontVisiblePasswordFieldForUnregisteredEmailOnCheckoutTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontVisiblePasswordFieldForUnregisteredEmailOnCheckoutTest.xml @@ -16,6 +16,7 @@ + diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/VerifyStateOptionApplicableForCheckoutFlowTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/VerifyStateOptionApplicableForCheckoutFlowTest.xml index 6016893ed3e28..7504496280d0d 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/VerifyStateOptionApplicableForCheckoutFlowTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/VerifyStateOptionApplicableForCheckoutFlowTest.xml @@ -17,6 +17,7 @@ + diff --git a/app/code/Magento/Checkout/composer.json b/app/code/Magento/Checkout/composer.json index 4d24d27e676ee..7030a9f7d3699 100644 --- a/app/code/Magento/Checkout/composer.json +++ b/app/code/Magento/Checkout/composer.json @@ -1,41 +1,42 @@ { "name": "magento/module-checkout", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.6-p3", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-captcha": "*", - "magento/module-catalog": "*", - "magento/module-catalog-inventory": "*", - "magento/module-config": "*", - "magento/module-customer": "*", - "magento/module-directory": "*", - "magento/module-eav": "*", - "magento/module-msrp": "*", - "magento/module-page-cache": "*", - "magento/module-payment": "*", - "magento/module-quote": "*", - "magento/module-sales": "*", - "magento/module-sales-rule": "*", - "magento/module-security": "*", - "magento/module-shipping": "*", - "magento/module-store": "*", - "magento/module-tax": "*", - "magento/module-theme": "*", - "magento/module-ui": "*", - "magento/module-authorization": "*" + "magento/framework": "103.0.*", + "magento/module-captcha": "100.4.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-inventory": "100.4.*", + "magento/module-config": "101.2.*", + "magento/module-customer": "103.0.*", + "magento/module-directory": "100.4.*", + "magento/module-eav": "102.1.*", + "magento/module-msrp": "100.4.*", + "magento/module-page-cache": "100.4.*", + "magento/module-payment": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-sales": "103.0.*", + "magento/module-sales-rule": "101.2.*", + "magento/module-security": "100.4.*", + "magento/module-shipping": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-tax": "100.4.*", + "magento/module-theme": "101.1.*", + "magento/module-ui": "101.2.*", + "magento/module-authorization": "100.4.*" }, "suggest": { - "magento/module-cookie": "*" + "magento/module-cookie": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -45,3 +46,4 @@ } } } + diff --git a/app/code/Magento/Checkout/etc/adminhtml/system.xml b/app/code/Magento/Checkout/etc/adminhtml/system.xml index b56566a043c3e..5bb0f37f3bc25 100644 --- a/app/code/Magento/Checkout/etc/adminhtml/system.xml +++ b/app/code/Magento/Checkout/etc/adminhtml/system.xml @@ -13,6 +13,11 @@ Magento_Checkout::checkout + + + Magento\Config\Model\Config\Source\Yesno + Enabling this setting will allow unauthenticated users to query if an e-mail address is already associated with a customer account. This can be used to enhance the checkout workflow for guests that do not realize they already have an account but comes at the cost of exposing information to unauthenticated users. + Magento\Config\Model\Config\Source\Yesno @@ -23,7 +28,7 @@ - \Magento\Checkout\Model\Adminhtml\BillingAddressDisplayOptions + Magento\Checkout\Model\Adminhtml\BillingAddressDisplayOptions diff --git a/app/code/Magento/Checkout/etc/config.xml b/app/code/Magento/Checkout/etc/config.xml index eac0bd849da35..c85d68b35f714 100644 --- a/app/code/Magento/Checkout/etc/config.xml +++ b/app/code/Magento/Checkout/etc/config.xml @@ -9,6 +9,7 @@ + 0 1 1 0 diff --git a/app/code/Magento/CheckoutAgreements/Test/Mftf/Test/AdminCreateActiveHtmlTermEntityTest.xml b/app/code/Magento/CheckoutAgreements/Test/Mftf/Test/AdminCreateActiveHtmlTermEntityTest.xml index c597d3d660dc8..b6c49b49d4a68 100644 --- a/app/code/Magento/CheckoutAgreements/Test/Mftf/Test/AdminCreateActiveHtmlTermEntityTest.xml +++ b/app/code/Magento/CheckoutAgreements/Test/Mftf/Test/AdminCreateActiveHtmlTermEntityTest.xml @@ -18,6 +18,7 @@ + diff --git a/app/code/Magento/CheckoutAgreements/Test/Mftf/Test/AdminCreateActiveTextTermEntityTest.xml b/app/code/Magento/CheckoutAgreements/Test/Mftf/Test/AdminCreateActiveTextTermEntityTest.xml index a90c3536ec744..94d0ddd95be19 100644 --- a/app/code/Magento/CheckoutAgreements/Test/Mftf/Test/AdminCreateActiveTextTermEntityTest.xml +++ b/app/code/Magento/CheckoutAgreements/Test/Mftf/Test/AdminCreateActiveTextTermEntityTest.xml @@ -18,6 +18,7 @@ + diff --git a/app/code/Magento/CheckoutAgreements/Test/Mftf/Test/AdminCreateDisabledTextTermEntityTest.xml b/app/code/Magento/CheckoutAgreements/Test/Mftf/Test/AdminCreateDisabledTextTermEntityTest.xml index e74235dba19db..2083414fa5b28 100644 --- a/app/code/Magento/CheckoutAgreements/Test/Mftf/Test/AdminCreateDisabledTextTermEntityTest.xml +++ b/app/code/Magento/CheckoutAgreements/Test/Mftf/Test/AdminCreateDisabledTextTermEntityTest.xml @@ -18,6 +18,7 @@ + diff --git a/app/code/Magento/CheckoutAgreements/Test/Mftf/Test/AdminDeleteActiveTextTermEntityTest.xml b/app/code/Magento/CheckoutAgreements/Test/Mftf/Test/AdminDeleteActiveTextTermEntityTest.xml index 175d5eb621501..ac782075ab30a 100644 --- a/app/code/Magento/CheckoutAgreements/Test/Mftf/Test/AdminDeleteActiveTextTermEntityTest.xml +++ b/app/code/Magento/CheckoutAgreements/Test/Mftf/Test/AdminDeleteActiveTextTermEntityTest.xml @@ -18,6 +18,7 @@ + diff --git a/app/code/Magento/CheckoutAgreements/Test/Mftf/Test/AdminUpdateDisabledHtmlTermEntityTest.xml b/app/code/Magento/CheckoutAgreements/Test/Mftf/Test/AdminUpdateDisabledHtmlTermEntityTest.xml index f9d60796d0424..2a4b4f0332d7b 100644 --- a/app/code/Magento/CheckoutAgreements/Test/Mftf/Test/AdminUpdateDisabledHtmlTermEntityTest.xml +++ b/app/code/Magento/CheckoutAgreements/Test/Mftf/Test/AdminUpdateDisabledHtmlTermEntityTest.xml @@ -18,6 +18,7 @@ + diff --git a/app/code/Magento/CheckoutAgreements/Test/Mftf/Test/AdminUpdateDisabledTextTermEntityTest.xml b/app/code/Magento/CheckoutAgreements/Test/Mftf/Test/AdminUpdateDisabledTextTermEntityTest.xml index 198a9fe3fc7b4..264fb517989aa 100644 --- a/app/code/Magento/CheckoutAgreements/Test/Mftf/Test/AdminUpdateDisabledTextTermEntityTest.xml +++ b/app/code/Magento/CheckoutAgreements/Test/Mftf/Test/AdminUpdateDisabledTextTermEntityTest.xml @@ -18,6 +18,7 @@ + diff --git a/app/code/Magento/CheckoutAgreements/Test/Mftf/Test/AdminUpdateEnabledTextTermEntityTest.xml b/app/code/Magento/CheckoutAgreements/Test/Mftf/Test/AdminUpdateEnabledTextTermEntityTest.xml index f82840bc07c7d..e900122647e69 100644 --- a/app/code/Magento/CheckoutAgreements/Test/Mftf/Test/AdminUpdateEnabledTextTermEntityTest.xml +++ b/app/code/Magento/CheckoutAgreements/Test/Mftf/Test/AdminUpdateEnabledTextTermEntityTest.xml @@ -18,6 +18,7 @@ + diff --git a/app/code/Magento/CheckoutAgreements/composer.json b/app/code/Magento/CheckoutAgreements/composer.json index 44d0e86bd78f2..6f1723e27bb3b 100644 --- a/app/code/Magento/CheckoutAgreements/composer.json +++ b/app/code/Magento/CheckoutAgreements/composer.json @@ -1,22 +1,23 @@ { "name": "magento/module-checkout-agreements", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.5-p2", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-checkout": "*", - "magento/module-quote": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-checkout": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-store": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -26,3 +27,4 @@ } } } + diff --git a/app/code/Magento/CheckoutAgreementsGraphQl/composer.json b/app/code/Magento/CheckoutAgreementsGraphQl/composer.json index c0c1853eb4324..9ece75204f615 100644 --- a/app/code/Magento/CheckoutAgreementsGraphQl/composer.json +++ b/app/code/Magento/CheckoutAgreementsGraphQl/composer.json @@ -2,19 +2,20 @@ "name": "magento/module-checkout-agreements-graph-ql", "description": "N/A", "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "100.4.2", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-store": "*", - "magento/module-checkout-agreements": "*" + "magento/framework": "103.0.*", + "magento/module-store": "101.1.*", + "magento/module-checkout-agreements": "100.4.*" }, "suggest": { - "magento/module-graph-ql": "*" + "magento/module-graph-ql": "100.4.*" }, - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -24,3 +25,4 @@ } } } + diff --git a/app/code/Magento/Cms/Test/Mftf/Test/AdminCmsPageGridUrlFilterApplierTest.xml b/app/code/Magento/Cms/Test/Mftf/Test/AdminCmsPageGridUrlFilterApplierTest.xml index cb79113fe591c..08cd5196f681e 100644 --- a/app/code/Magento/Cms/Test/Mftf/Test/AdminCmsPageGridUrlFilterApplierTest.xml +++ b/app/code/Magento/Cms/Test/Mftf/Test/AdminCmsPageGridUrlFilterApplierTest.xml @@ -32,6 +32,7 @@ + diff --git a/app/code/Magento/Cms/composer.json b/app/code/Magento/Cms/composer.json index aa972d0a711a7..1aebfad60a272 100644 --- a/app/code/Magento/Cms/composer.json +++ b/app/code/Magento/Cms/composer.json @@ -1,30 +1,31 @@ { "name": "magento/module-cms", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "104.0.6-p2", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-email": "*", - "magento/module-media-storage": "*", - "magento/module-store": "*", - "magento/module-theme": "*", - "magento/module-ui": "*", - "magento/module-variable": "*", - "magento/module-widget": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-email": "101.1.*", + "magento/module-media-storage": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-theme": "101.1.*", + "magento/module-ui": "101.2.*", + "magento/module-variable": "100.4.*", + "magento/module-widget": "101.2.*" }, "suggest": { - "magento/module-cms-sample-data": "*" + "magento/module-cms-sample-data": "Sample Data version: 100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -34,3 +35,4 @@ } } } + diff --git a/app/code/Magento/CmsGraphQl/composer.json b/app/code/Magento/CmsGraphQl/composer.json index 07b7261823d92..4786af8a02866 100644 --- a/app/code/Magento/CmsGraphQl/composer.json +++ b/app/code/Magento/CmsGraphQl/composer.json @@ -2,22 +2,23 @@ "name": "magento/module-cms-graph-ql", "description": "N/A", "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "100.4.3", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-cms": "*", - "magento/module-widget": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-cms": "104.0.*", + "magento/module-widget": "101.2.*", + "magento/module-store": "101.1.*" }, "suggest": { - "magento/module-graph-ql": "*", - "magento/module-graph-ql-cache": "*", - "magento/module-store-graph-ql": "*" + "magento/module-graph-ql": "100.4.*", + "magento/module-graph-ql-cache": "100.4.*", + "magento/module-store-graph-ql": "100.4.*" }, - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -27,3 +28,4 @@ } } } + diff --git a/app/code/Magento/CmsUrlRewrite/composer.json b/app/code/Magento/CmsUrlRewrite/composer.json index 0521f77f9bb7f..fa24885c1525b 100644 --- a/app/code/Magento/CmsUrlRewrite/composer.json +++ b/app/code/Magento/CmsUrlRewrite/composer.json @@ -1,21 +1,22 @@ { "name": "magento/module-cms-url-rewrite", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.5", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-cms": "*", - "magento/module-store": "*", - "magento/module-url-rewrite": "*" + "magento/framework": "103.0.*", + "magento/module-cms": "104.0.*", + "magento/module-store": "101.1.*", + "magento/module-url-rewrite": "102.0.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -25,3 +26,4 @@ } } } + diff --git a/app/code/Magento/CmsUrlRewriteGraphQl/composer.json b/app/code/Magento/CmsUrlRewriteGraphQl/composer.json index 2687ad032e000..c949f41846a07 100644 --- a/app/code/Magento/CmsUrlRewriteGraphQl/composer.json +++ b/app/code/Magento/CmsUrlRewriteGraphQl/composer.json @@ -2,22 +2,23 @@ "name": "magento/module-cms-url-rewrite-graph-ql", "description": "N/A", "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "100.4.4", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-cms": "*", - "magento/module-store": "*", - "magento/module-url-rewrite-graph-ql": "*", - "magento/module-cms-graph-ql": "*" + "magento/framework": "103.0.*", + "magento/module-cms": "104.0.*", + "magento/module-store": "101.1.*", + "magento/module-url-rewrite-graph-ql": "100.4.*", + "magento/module-cms-graph-ql": "100.4.*" }, "suggest": { - "magento/module-cms-url-rewrite": "*", - "magento/module-catalog-graph-ql": "*" + "magento/module-cms-url-rewrite": "100.4.*", + "magento/module-catalog-graph-ql": "100.4.*" }, - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -27,3 +28,4 @@ } } } + diff --git a/app/code/Magento/CompareListGraphQl/composer.json b/app/code/Magento/CompareListGraphQl/composer.json index 9193e30061619..2b56700b83293 100644 --- a/app/code/Magento/CompareListGraphQl/composer.json +++ b/app/code/Magento/CompareListGraphQl/composer.json @@ -2,16 +2,17 @@ "name": "magento/module-compare-list-graph-ql", "description": "N/A", "type": "magento2-module", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-catalog": "*", - "magento/module-customer": "*" - }, "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.2", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-customer": "103.0.*" + }, "autoload": { "files": [ "registration.php" @@ -21,3 +22,4 @@ } } } + diff --git a/app/code/Magento/Config/composer.json b/app/code/Magento/Config/composer.json index 8ad286bd667b5..603162f317bb3 100644 --- a/app/code/Magento/Config/composer.json +++ b/app/code/Magento/Config/composer.json @@ -1,25 +1,26 @@ { "name": "magento/module-config", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "101.2.6", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-cron": "*", - "magento/module-deploy": "*", - "magento/module-directory": "*", - "magento/module-email": "*", - "magento/module-media-storage": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-cron": "100.4.*", + "magento/module-deploy": "100.4.*", + "magento/module-directory": "100.4.*", + "magento/module-email": "101.1.*", + "magento/module-media-storage": "100.4.*", + "magento/module-store": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -29,3 +30,4 @@ } } } + diff --git a/app/code/Magento/ConfigurableImportExport/composer.json b/app/code/Magento/ConfigurableImportExport/composer.json index f56cfd6299ad2..31f941a4b1ce2 100644 --- a/app/code/Magento/ConfigurableImportExport/composer.json +++ b/app/code/Magento/ConfigurableImportExport/composer.json @@ -1,24 +1,25 @@ { "name": "magento/module-configurable-import-export", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-catalog": "*", - "magento/module-catalog-import-export": "*", - "magento/module-configurable-product": "*", - "magento/module-eav": "*", - "magento/module-import-export": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-import-export": "101.1.*", + "magento/module-configurable-product": "100.4.*", + "magento/module-eav": "102.1.*", + "magento/module-import-export": "101.0.*", + "magento/module-store": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -28,3 +29,4 @@ } } } + diff --git a/app/code/Magento/ConfigurableProduct/composer.json b/app/code/Magento/ConfigurableProduct/composer.json index 8a9e4e50ad194..2b773ff0b5309 100644 --- a/app/code/Magento/ConfigurableProduct/composer.json +++ b/app/code/Magento/ConfigurableProduct/composer.json @@ -1,38 +1,39 @@ { "name": "magento/module-configurable-product", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.6", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-catalog-inventory": "*", - "magento/module-checkout": "*", - "magento/module-customer": "*", - "magento/module-eav": "*", - "magento/module-media-storage": "*", - "magento/module-quote": "*", - "magento/module-store": "*", - "magento/module-ui": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-inventory": "100.4.*", + "magento/module-checkout": "100.4.*", + "magento/module-customer": "103.0.*", + "magento/module-eav": "102.1.*", + "magento/module-media-storage": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-store": "101.1.*", + "magento/module-ui": "101.2.*" }, "suggest": { - "magento/module-msrp": "*", - "magento/module-webapi": "*", - "magento/module-sales": "*", - "magento/module-sales-rule": "*", - "magento/module-product-video": "*", - "magento/module-configurable-sample-data": "*", - "magento/module-product-links-sample-data": "*", - "magento/module-tax": "*" + "magento/module-msrp": "100.4.*", + "magento/module-webapi": "100.4.*", + "magento/module-sales": "103.0.*", + "magento/module-sales-rule": "101.2.*", + "magento/module-product-video": "100.4.*", + "magento/module-configurable-sample-data": "Sample Data version: 100.4.*", + "magento/module-product-links-sample-data": "Sample Data version: 100.4.*", + "magento/module-tax": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -42,3 +43,4 @@ } } } + diff --git a/app/code/Magento/ConfigurableProductGraphQl/composer.json b/app/code/Magento/ConfigurableProductGraphQl/composer.json index 43c297de656c5..ab16ff4fc8e65 100644 --- a/app/code/Magento/ConfigurableProductGraphQl/composer.json +++ b/app/code/Magento/ConfigurableProductGraphQl/composer.json @@ -2,21 +2,22 @@ "name": "magento/module-configurable-product-graph-ql", "description": "N/A", "type": "magento2-module", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/module-catalog": "*", - "magento/module-configurable-product": "*", - "magento/module-graph-ql": "*", - "magento/module-catalog-graph-ql": "*", - "magento/module-quote": "*", - "magento/module-quote-graph-ql": "*", - "magento/module-catalog-inventory": "*", - "magento/framework": "*" - }, "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.6", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/module-catalog": "104.0.*", + "magento/module-configurable-product": "100.4.*", + "magento/module-graph-ql": "100.4.*", + "magento/module-catalog-graph-ql": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-quote-graph-ql": "100.4.*", + "magento/module-catalog-inventory": "100.4.*", + "magento/framework": "103.0.*" + }, "autoload": { "files": [ "registration.php" @@ -26,3 +27,4 @@ } } } + diff --git a/app/code/Magento/ConfigurableProductSales/composer.json b/app/code/Magento/ConfigurableProductSales/composer.json index 909c2ff967f41..50cbe3edf6696 100644 --- a/app/code/Magento/ConfigurableProductSales/composer.json +++ b/app/code/Magento/ConfigurableProductSales/composer.json @@ -1,22 +1,23 @@ { "name": "magento/module-configurable-product-sales", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.3", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-catalog": "*", - "magento/module-sales": "*", - "magento/module-store": "*", - "magento/module-configurable-product": "*" + "magento/framework": "103.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-sales": "103.0.*", + "magento/module-store": "101.1.*", + "magento/module-configurable-product": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -26,3 +27,4 @@ } } } + diff --git a/app/code/Magento/Contact/composer.json b/app/code/Magento/Contact/composer.json index 68b5bb4c9a6da..1d5dbc3ede6a2 100644 --- a/app/code/Magento/Contact/composer.json +++ b/app/code/Magento/Contact/composer.json @@ -1,22 +1,23 @@ { "name": "magento/module-contact", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.5", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-cms": "*", - "magento/module-config": "*", - "magento/module-customer": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-cms": "104.0.*", + "magento/module-config": "101.2.*", + "magento/module-customer": "103.0.*", + "magento/module-store": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -26,3 +27,4 @@ } } } + diff --git a/app/code/Magento/Cookie/composer.json b/app/code/Magento/Cookie/composer.json index d2f1a87594a3c..85ec34011ac33 100644 --- a/app/code/Magento/Cookie/composer.json +++ b/app/code/Magento/Cookie/composer.json @@ -1,22 +1,23 @@ { "name": "magento/module-cookie", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.6", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-store": "101.1.*" }, "suggest": { - "magento/module-backend": "*" + "magento/module-backend": "102.0.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -26,3 +27,4 @@ } } } + diff --git a/app/code/Magento/Cron/composer.json b/app/code/Magento/Cron/composer.json index 1696588920015..bd3a43dcb04b2 100644 --- a/app/code/Magento/Cron/composer.json +++ b/app/code/Magento/Cron/composer.json @@ -1,22 +1,23 @@ { "name": "magento/module-cron", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.6", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-store": "101.1.*" }, "suggest": { - "magento/module-config": "*" + "magento/module-config": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -26,3 +27,4 @@ } } } + diff --git a/app/code/Magento/Csp/composer.json b/app/code/Magento/Csp/composer.json index f2e69e7a7ec63..0cce60de63026 100644 --- a/app/code/Magento/Csp/composer.json +++ b/app/code/Magento/Csp/composer.json @@ -1,19 +1,20 @@ { "name": "magento/module-csp", "description": "CSP module enables Content Security Policies for Magento", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.5", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-store": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -23,3 +24,4 @@ } } } + diff --git a/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminCheckCurrencyConverterApiConfigurationTest.xml b/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminCheckCurrencyConverterApiConfigurationTest.xml index 91ae96e2656df..e6086c427a708 100644 --- a/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminCheckCurrencyConverterApiConfigurationTest.xml +++ b/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminCheckCurrencyConverterApiConfigurationTest.xml @@ -18,6 +18,8 @@ + + diff --git a/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminOrderRateDisplayWhenChooseThreeAllowedCurrenciesTest.xml b/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminOrderRateDisplayWhenChooseThreeAllowedCurrenciesTest.xml index be32919c79c83..4172c75198198 100644 --- a/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminOrderRateDisplayWhenChooseThreeAllowedCurrenciesTest.xml +++ b/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminOrderRateDisplayWhenChooseThreeAllowedCurrenciesTest.xml @@ -18,6 +18,7 @@ + diff --git a/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminOrderRateDisplayedInOneLineTest.xml b/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminOrderRateDisplayedInOneLineTest.xml index d3cf2c124c85c..08a631789cfa2 100644 --- a/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminOrderRateDisplayedInOneLineTest.xml +++ b/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminOrderRateDisplayedInOneLineTest.xml @@ -18,6 +18,7 @@ + diff --git a/app/code/Magento/CurrencySymbol/composer.json b/app/code/Magento/CurrencySymbol/composer.json index 8c2325b39d508..ed7a5ef7a533e 100644 --- a/app/code/Magento/CurrencySymbol/composer.json +++ b/app/code/Magento/CurrencySymbol/composer.json @@ -1,23 +1,24 @@ { "name": "magento/module-currency-symbol", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4-p3", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-config": "*", - "magento/module-directory": "*", - "magento/module-page-cache": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-config": "101.2.*", + "magento/module-directory": "100.4.*", + "magento/module-page-cache": "100.4.*", + "magento/module-store": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -27,3 +28,4 @@ } } } + diff --git a/app/code/Magento/Customer/Api/AccountManagementInterface.php b/app/code/Magento/Customer/Api/AccountManagementInterface.php index 9c607be9f217c..165233cc6a880 100644 --- a/app/code/Magento/Customer/Api/AccountManagementInterface.php +++ b/app/code/Magento/Customer/Api/AccountManagementInterface.php @@ -8,6 +8,7 @@ namespace Magento\Customer\Api; use Magento\Framework\Exception\InputException; +use Magento\Framework\Exception\LocalizedException; /** * Interface for managing customers accounts. @@ -194,7 +195,7 @@ public function resendConfirmation($email, $websiteId, $redirectUrl = ''); * Check if given email is associated with a customer account in given website. * * @param string $customerEmail - * @param int $websiteId If not set, will use the current websiteId + * @param int|null $websiteId If not set, will use the current websiteId * @return bool * @throws \Magento\Framework\Exception\LocalizedException */ diff --git a/app/code/Magento/Customer/Model/AccountManagement.php b/app/code/Magento/Customer/Model/AccountManagement.php index 08587deee2a76..702b6aeb68653 100644 --- a/app/code/Magento/Customer/Model/AccountManagement.php +++ b/app/code/Magento/Customer/Model/AccountManagement.php @@ -69,6 +69,11 @@ */ class AccountManagement implements AccountManagementInterface { + /** + * System Configuration Path for Enable/Disable Login at Guest Checkout + */ + public const GUEST_CHECKOUT_LOGIN_OPTION_SYS_CONFIG = 'checkout/options/enable_guest_checkout_login'; + /** * Configuration paths for create account email template * @@ -719,7 +724,7 @@ private function handleUnknownTemplate($template) throw new InputException( __( 'Invalid value of "%value" provided for the %fieldName field. ' - . 'Possible values: %template1 or %template2.', + . 'Possible values: %template1 or %template2.', [ 'value' => $template, 'fieldName' => 'template', @@ -1125,7 +1130,7 @@ public function validate(CustomerInterface $customer) $result = $this->eavValidator->isValid($customerModel); if ($result === false && is_array($this->eavValidator->getMessages())) { return $validationResults->setIsValid(false)->setMessages( - // phpcs:ignore Magento2.Functions.DiscouragedFunction + // phpcs:ignore Magento2.Functions.DiscouragedFunction call_user_func_array( 'array_merge', array_values($this->eavValidator->getMessages()) @@ -1137,9 +1142,24 @@ public function validate(CustomerInterface $customer) /** * @inheritdoc + * + * @param string $customerEmail + * @param int|null $websiteId + * @return bool + * @throws LocalizedException */ public function isEmailAvailable($customerEmail, $websiteId = null) { + $guestLoginConfig = $this->scopeConfig->getValue( + self::GUEST_CHECKOUT_LOGIN_OPTION_SYS_CONFIG, + ScopeInterface::SCOPE_WEBSITE, + $websiteId + ); + + if (!$guestLoginConfig) { + return true; + } + try { if ($websiteId === null) { $websiteId = $this->storeManager->getStore()->getWebsiteId(); diff --git a/app/code/Magento/Customer/Plugin/Webapi/Controller/Rest/ValidateCustomerData.php b/app/code/Magento/Customer/Plugin/Webapi/Controller/Rest/ValidateCustomerData.php index ad2d8ed1cf974..7d744cb4fe971 100644 --- a/app/code/Magento/Customer/Plugin/Webapi/Controller/Rest/ValidateCustomerData.php +++ b/app/code/Magento/Customer/Plugin/Webapi/Controller/Rest/ValidateCustomerData.php @@ -28,8 +28,8 @@ class ValidateCustomerData */ public function beforeOverride(ParamsOverrider $subject, array $inputData, array $parameters): array { - if (isset($inputData[self:: CUSTOMER_KEY])) { - $inputData[self:: CUSTOMER_KEY] = $this->validateInputData($inputData[self:: CUSTOMER_KEY]); + if (isset($inputData[self::CUSTOMER_KEY])) { + $inputData[self::CUSTOMER_KEY] = $this->validateInputData($inputData[self::CUSTOMER_KEY]); } return [$inputData, $parameters]; } @@ -43,9 +43,8 @@ public function beforeOverride(ParamsOverrider $subject, array $inputData, array private function validateInputData(array $inputData): array { $result = []; - $data = array_filter($inputData, function ($k) use (&$result) { - $key = is_string($k) ? strtolower($k) : $k; + $key = is_string($k) ? strtolower(str_replace('_', "", $k)) : $k; return !isset($result[$key]) && ($result[$key] = true); }, ARRAY_FILTER_USE_KEY); diff --git a/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateNewCustomerOnStorefrontSignupNewsletterTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateNewCustomerOnStorefrontSignupNewsletterTest.xml index 2cd231d0bf396..8a355070f1c1b 100644 --- a/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateNewCustomerOnStorefrontSignupNewsletterTest.xml +++ b/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateNewCustomerOnStorefrontSignupNewsletterTest.xml @@ -17,6 +17,7 @@ + diff --git a/app/code/Magento/Customer/Test/Mftf/Test/AdminCustomerSubscribeNewsletterPerWebsiteTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/AdminCustomerSubscribeNewsletterPerWebsiteTest.xml index d54977b2e2ab1..f93a2e9665641 100644 --- a/app/code/Magento/Customer/Test/Mftf/Test/AdminCustomerSubscribeNewsletterPerWebsiteTest.xml +++ b/app/code/Magento/Customer/Test/Mftf/Test/AdminCustomerSubscribeNewsletterPerWebsiteTest.xml @@ -17,6 +17,7 @@ + diff --git a/app/code/Magento/Customer/Test/Mftf/Test/EndToEndB2CLoggedInUserTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/EndToEndB2CLoggedInUserTest.xml index 368a5c8db7d3c..60e71d3afc718 100644 --- a/app/code/Magento/Customer/Test/Mftf/Test/EndToEndB2CLoggedInUserTest.xml +++ b/app/code/Magento/Customer/Test/Mftf/Test/EndToEndB2CLoggedInUserTest.xml @@ -18,8 +18,10 @@ + + @@ -29,6 +31,7 @@ + diff --git a/app/code/Magento/Customer/Test/Mftf/Test/StorefrontCustomerSubscribeToNewsletterAndVerifyInAdminTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/StorefrontCustomerSubscribeToNewsletterAndVerifyInAdminTest.xml index 2b0da367a9ec5..09c969af6381e 100644 --- a/app/code/Magento/Customer/Test/Mftf/Test/StorefrontCustomerSubscribeToNewsletterAndVerifyInAdminTest.xml +++ b/app/code/Magento/Customer/Test/Mftf/Test/StorefrontCustomerSubscribeToNewsletterAndVerifyInAdminTest.xml @@ -16,6 +16,7 @@ + diff --git a/app/code/Magento/Customer/Test/Mftf/Test/StorefrontCustomerSubscribeToNewsletterTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/StorefrontCustomerSubscribeToNewsletterTest.xml index 62bab5669307b..0dfc4d2ca5f57 100644 --- a/app/code/Magento/Customer/Test/Mftf/Test/StorefrontCustomerSubscribeToNewsletterTest.xml +++ b/app/code/Magento/Customer/Test/Mftf/Test/StorefrontCustomerSubscribeToNewsletterTest.xml @@ -15,6 +15,7 @@ <description value="Customer can be subscribed to Newsletter Subscription on StoreFront"/> <severity value="MAJOR"/> + <group value="newsletter"/> </annotations> <before> <createData entity="Simple_US_Customer" stepKey="createCustomer"/> diff --git a/app/code/Magento/Customer/Test/Mftf/Test/StorefrontRetainLocalCacheStorageTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/StorefrontRetainLocalCacheStorageTest.xml index 7661b1222fb57..e3fdba1ce3e57 100644 --- a/app/code/Magento/Customer/Test/Mftf/Test/StorefrontRetainLocalCacheStorageTest.xml +++ b/app/code/Magento/Customer/Test/Mftf/Test/StorefrontRetainLocalCacheStorageTest.xml @@ -17,6 +17,10 @@ <severity value="AVERAGE"/> <testCaseId value="AC-3635"/> <group value="customer"/> + <group value="guest_checkout"/> + <skip> + <issueId value="ACQE-4352"/> + </skip> </annotations> <before> <createData entity="Simple_US_Customer" stepKey="createCustomer"/> diff --git a/app/code/Magento/Customer/Test/Unit/Plugin/Webapi/Controller/Rest/ValidateCustomerDataTest.php b/app/code/Magento/Customer/Test/Unit/Plugin/Webapi/Controller/Rest/ValidateCustomerDataTest.php index cda66041ab3c5..72d5f36e2266f 100644 --- a/app/code/Magento/Customer/Test/Unit/Plugin/Webapi/Controller/Rest/ValidateCustomerDataTest.php +++ b/app/code/Magento/Customer/Test/Unit/Plugin/Webapi/Controller/Rest/ValidateCustomerDataTest.php @@ -8,8 +8,8 @@ namespace Magento\Customer\Test\Unit\Plugin\Webapi\Controller\Rest; use Exception; -use Magento\Framework\App\ObjectManager; use Magento\Customer\Plugin\Webapi\Controller\Rest\ValidateCustomerData; +use Magento\Framework\App\ObjectManager; use PHPUnit\Framework\TestCase; use ReflectionClass; @@ -75,40 +75,48 @@ public function dataProviderInputData(): array { return [ [ - ['customer' => - [ + ['customer' => [ 'id' => -1, 'Id' => 1, - 'name' => - [ + 'name' => [ 'firstName' => 'Test', 'LastName' => 'user' ], 'isHavingOwnHouse' => 1, - 'address' => - [ + 'address' => [ 'street' => '1st Street', 'Street' => '3rd Street', 'city' => 'London' ], ] ], - ['customer' => - [ + ['customer' => [ 'id' => -1, - 'name' => - [ + 'name' => [ 'firstName' => 'Test', 'LastName' => 'user' ], 'isHavingOwnHouse' => 1, - 'address' => - [ + 'address' => [ 'street' => '1st Street', 'city' => 'London' ], ] ], + ['customer' => [ + 'id' => -1, + '_Id' => 1, + 'name' => [ + 'firstName' => 'Test', + 'LastName' => 'user' + ], + 'isHavingOwnHouse' => 1, + 'address' => [ + 'street' => '1st Street', + 'city' => 'London' + ], + ] + ], ] ]; } diff --git a/app/code/Magento/Customer/composer.json b/app/code/Magento/Customer/composer.json index ef2047644759b..d096dee35f38e 100644 --- a/app/code/Magento/Customer/composer.json +++ b/app/code/Magento/Customer/composer.json @@ -1,41 +1,42 @@ { "name": "magento/module-customer", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "103.0.6-p3", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-authorization": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-checkout": "*", - "magento/module-config": "*", - "magento/module-directory": "*", - "magento/module-eav": "*", - "magento/module-integration": "*", - "magento/module-media-storage": "*", - "magento/module-newsletter": "*", - "magento/module-page-cache": "*", - "magento/module-quote": "*", - "magento/module-sales": "*", - "magento/module-store": "*", - "magento/module-tax": "*", - "magento/module-theme": "*", - "magento/module-ui": "*", - "magento/module-wishlist": "*" + "magento/framework": "103.0.*", + "magento/module-authorization": "100.4.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-checkout": "100.4.*", + "magento/module-config": "101.2.*", + "magento/module-directory": "100.4.*", + "magento/module-eav": "102.1.*", + "magento/module-integration": "100.4.*", + "magento/module-media-storage": "100.4.*", + "magento/module-newsletter": "100.4.*", + "magento/module-page-cache": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-sales": "103.0.*", + "magento/module-store": "101.1.*", + "magento/module-tax": "100.4.*", + "magento/module-theme": "101.1.*", + "magento/module-ui": "101.2.*", + "magento/module-wishlist": "101.2.*" }, "suggest": { - "magento/module-cookie": "*", - "magento/module-customer-sample-data": "*", - "magento/module-webapi": "*" + "magento/module-cookie": "100.4.*", + "magento/module-customer-sample-data": "Sample Data version: 100.4.*", + "magento/module-webapi": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -45,3 +46,4 @@ } } } + diff --git a/app/code/Magento/CustomerAnalytics/composer.json b/app/code/Magento/CustomerAnalytics/composer.json index d02051d5148cd..802a1fa00ebd1 100644 --- a/app/code/Magento/CustomerAnalytics/composer.json +++ b/app/code/Magento/CustomerAnalytics/composer.json @@ -1,17 +1,18 @@ { "name": "magento/module-customer-analytics", "description": "N/A", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-customer": "*", - "magento/module-analytics": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.3", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*", + "magento/module-customer": "103.0.*", + "magento/module-analytics": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -21,3 +22,4 @@ } } } + diff --git a/app/code/Magento/CustomerDownloadableGraphQl/composer.json b/app/code/Magento/CustomerDownloadableGraphQl/composer.json index 99e2f94da4081..219a8b479ac92 100644 --- a/app/code/Magento/CustomerDownloadableGraphQl/composer.json +++ b/app/code/Magento/CustomerDownloadableGraphQl/composer.json @@ -2,19 +2,20 @@ "name": "magento/module-customer-downloadable-graph-ql", "description": "N/A", "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "100.4.2", "require": { "php": "~8.1.0||~8.2.0", - "magento/module-downloadable-graph-ql": "*", - "magento/module-graph-ql": "*", - "magento/framework": "*" + "magento/module-downloadable-graph-ql": "100.4.*", + "magento/module-graph-ql": "100.4.*", + "magento/framework": "103.0.*" }, "suggest": { - "magento/module-catalog-graph-ql": "*" + "magento/module-catalog-graph-ql": "100.4.*" }, - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -24,3 +25,4 @@ } } } + diff --git a/app/code/Magento/CustomerGraphQl/composer.json b/app/code/Magento/CustomerGraphQl/composer.json index 5967d2e9f8ac7..bfabb6edb885b 100644 --- a/app/code/Magento/CustomerGraphQl/composer.json +++ b/app/code/Magento/CustomerGraphQl/composer.json @@ -2,24 +2,25 @@ "name": "magento/module-customer-graph-ql", "description": "N/A", "type": "magento2-module", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/module-authorization": "*", - "magento/module-customer": "*", - "magento/module-eav": "*", - "magento/module-graph-ql": "*", - "magento/module-newsletter": "*", - "magento/module-integration": "*", - "magento/module-store": "*", - "magento/framework": "*", - "magento/module-directory": "*", - "magento/module-tax": "*", - "magento/module-graph-ql-cache": "*" - }, "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.6", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/module-authorization": "100.4.*", + "magento/module-customer": "103.0.*", + "magento/module-eav": "102.1.*", + "magento/module-graph-ql": "100.4.*", + "magento/module-newsletter": "100.4.*", + "magento/module-integration": "100.4.*", + "magento/module-store": "101.1.*", + "magento/framework": "103.0.*", + "magento/module-directory": "100.4.*", + "magento/module-tax": "100.4.*", + "magento/module-graph-ql-cache": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -29,3 +30,4 @@ } } } + diff --git a/app/code/Magento/CustomerImportExport/composer.json b/app/code/Magento/CustomerImportExport/composer.json index 09eb16c1d8a01..d08647f46ea02 100644 --- a/app/code/Magento/CustomerImportExport/composer.json +++ b/app/code/Magento/CustomerImportExport/composer.json @@ -1,24 +1,25 @@ { "name": "magento/module-customer-import-export", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.6", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-customer": "*", - "magento/module-directory": "*", - "magento/module-eav": "*", - "magento/module-import-export": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-customer": "103.0.*", + "magento/module-directory": "100.4.*", + "magento/module-eav": "102.1.*", + "magento/module-import-export": "101.0.*", + "magento/module-store": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -28,3 +29,4 @@ } } } + diff --git a/app/code/Magento/Deploy/composer.json b/app/code/Magento/Deploy/composer.json index c90a64299e8e5..68f2aa0acce2e 100644 --- a/app/code/Magento/Deploy/composer.json +++ b/app/code/Magento/Deploy/composer.json @@ -1,22 +1,23 @@ { "name": "magento/module-deploy", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.6", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-config": "*", - "magento/module-require-js": "*", - "magento/module-store": "*", - "magento/module-user": "*" + "magento/framework": "103.0.*", + "magento/module-config": "101.2.*", + "magento/module-require-js": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-user": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "cli_commands.php", @@ -27,3 +28,4 @@ } } } + diff --git a/app/code/Magento/Developer/composer.json b/app/code/Magento/Developer/composer.json index 3f75c5bef7d44..06333f6a17873 100644 --- a/app/code/Magento/Developer/composer.json +++ b/app/code/Magento/Developer/composer.json @@ -1,20 +1,21 @@ { "name": "magento/module-developer", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.6", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-config": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-config": "101.2.*", + "magento/module-store": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -24,3 +25,4 @@ } } } + diff --git a/app/code/Magento/Dhl/composer.json b/app/code/Magento/Dhl/composer.json index 26b8546164965..3a07467a8823b 100644 --- a/app/code/Magento/Dhl/composer.json +++ b/app/code/Magento/Dhl/composer.json @@ -1,31 +1,32 @@ { "name": "magento/module-dhl", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.5", "require": { "php": "~8.1.0||~8.2.0", "lib-libxml": "*", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-catalog-inventory": "*", - "magento/module-config": "*", - "magento/module-directory": "*", - "magento/module-quote": "*", - "magento/module-sales": "*", - "magento/module-shipping": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-inventory": "100.4.*", + "magento/module-config": "101.2.*", + "magento/module-directory": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-sales": "103.0.*", + "magento/module-shipping": "100.4.*", + "magento/module-store": "101.1.*" }, "suggest": { - "magento/module-checkout": "*" + "magento/module-checkout": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -35,3 +36,4 @@ } } } + diff --git a/app/code/Magento/Directory/composer.json b/app/code/Magento/Directory/composer.json index a2538a6378d5b..8aba070e1ca81 100644 --- a/app/code/Magento/Directory/composer.json +++ b/app/code/Magento/Directory/composer.json @@ -1,22 +1,23 @@ { "name": "magento/module-directory", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.6", "require": { "php": "~8.1.0||~8.2.0", "lib-libxml": "*", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-config": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-config": "101.2.*", + "magento/module-store": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -26,3 +27,4 @@ } } } + diff --git a/app/code/Magento/DirectoryGraphQl/composer.json b/app/code/Magento/DirectoryGraphQl/composer.json index 082fa8ae742c1..bc7d04030135e 100644 --- a/app/code/Magento/DirectoryGraphQl/composer.json +++ b/app/code/Magento/DirectoryGraphQl/composer.json @@ -2,17 +2,18 @@ "name": "magento/module-directory-graph-ql", "description": "N/A", "type": "magento2-module", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/module-directory": "*", - "magento/module-store": "*", - "magento/module-graph-ql": "*", - "magento/framework": "*" - }, "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.4", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/module-directory": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-graph-ql": "100.4.*", + "magento/framework": "103.0.*" + }, "autoload": { "files": [ "registration.php" @@ -22,3 +23,4 @@ } } } + diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminRemoveDefaultImageDownloadableProductTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminRemoveDefaultImageDownloadableProductTest.xml index a2b418e510482..f7beed1e3f9c1 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminRemoveDefaultImageDownloadableProductTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminRemoveDefaultImageDownloadableProductTest.xml @@ -56,7 +56,8 @@ <!--Save product--> <actionGroup ref="SaveProductFormActionGroup" stepKey="saveProduct"/> - + <!-- Reindex invalidated indices after product attribute has been created/deleted --> + <magentoCron groups="index" stepKey="reindexInvalidatedIndices"/> <!-- Remove image from product --> <actionGroup ref="RemoveProductImageActionGroup" stepKey="removeProductImage"/> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/LinkDownloadableProductFromGuestToCustomerTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/LinkDownloadableProductFromGuestToCustomerTest.xml index 3dbb6830e331c..3bad1d73c753e 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/LinkDownloadableProductFromGuestToCustomerTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/LinkDownloadableProductFromGuestToCustomerTest.xml @@ -16,6 +16,7 @@ <severity value="AVERAGE"/> <useCaseId value="MAGETWO-98656"/> <testCaseId value="MC-16011"/> + <group value="guest_checkout"/> </annotations> <before> <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add example.com static.magento.com"/> diff --git a/app/code/Magento/Downloadable/composer.json b/app/code/Magento/Downloadable/composer.json index abd6479f10e2d..89e7383e04a2d 100644 --- a/app/code/Magento/Downloadable/composer.json +++ b/app/code/Magento/Downloadable/composer.json @@ -1,37 +1,38 @@ { "name": "magento/module-downloadable", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.6-p3", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-catalog-inventory": "*", - "magento/module-checkout": "*", - "magento/module-config": "*", - "magento/module-customer": "*", - "magento/module-directory": "*", - "magento/module-eav": "*", - "magento/module-gift-message": "*", - "magento/module-media-storage": "*", - "magento/module-quote": "*", - "magento/module-sales": "*", - "magento/module-store": "*", - "magento/module-tax": "*", - "magento/module-theme": "*", - "magento/module-ui": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-inventory": "100.4.*", + "magento/module-checkout": "100.4.*", + "magento/module-config": "101.2.*", + "magento/module-customer": "103.0.*", + "magento/module-directory": "100.4.*", + "magento/module-eav": "102.1.*", + "magento/module-gift-message": "100.4.*", + "magento/module-media-storage": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-sales": "103.0.*", + "magento/module-store": "101.1.*", + "magento/module-tax": "100.4.*", + "magento/module-theme": "101.1.*", + "magento/module-ui": "101.2.*" }, "suggest": { - "magento/module-downloadable-sample-data": "*" + "magento/module-downloadable-sample-data": "Sample Data version: 100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -41,3 +42,4 @@ } } } + diff --git a/app/code/Magento/DownloadableGraphQl/composer.json b/app/code/Magento/DownloadableGraphQl/composer.json index c286438b49356..6875fa9572c27 100644 --- a/app/code/Magento/DownloadableGraphQl/composer.json +++ b/app/code/Magento/DownloadableGraphQl/composer.json @@ -2,24 +2,25 @@ "name": "magento/module-downloadable-graph-ql", "description": "N/A", "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "100.4.6", "require": { "php": "~8.1.0||~8.2.0", - "magento/module-store": "*", - "magento/module-catalog": "*", - "magento/module-downloadable": "*", - "magento/module-quote": "*", - "magento/module-sales": "*", - "magento/module-quote-graph-ql": "*", - "magento/framework": "*" + "magento/module-store": "101.1.*", + "magento/module-catalog": "104.0.*", + "magento/module-downloadable": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-sales": "103.0.*", + "magento/module-quote-graph-ql": "100.4.*", + "magento/framework": "103.0.*" }, "suggest": { - "magento/module-catalog-graph-ql": "*", - "magento/module-sales-graph-ql": "*" + "magento/module-catalog-graph-ql": "100.4.*", + "magento/module-sales-graph-ql": "100.4.*" }, - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -29,3 +30,4 @@ } } } + diff --git a/app/code/Magento/DownloadableImportExport/composer.json b/app/code/Magento/DownloadableImportExport/composer.json index bc35e44944c91..1d9d0935cb3ef 100644 --- a/app/code/Magento/DownloadableImportExport/composer.json +++ b/app/code/Magento/DownloadableImportExport/composer.json @@ -1,24 +1,25 @@ { "name": "magento/module-downloadable-import-export", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.5", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-catalog": "*", - "magento/module-catalog-import-export": "*", - "magento/module-downloadable": "*", - "magento/module-eav": "*", - "magento/module-import-export": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-import-export": "101.1.*", + "magento/module-downloadable": "100.4.*", + "magento/module-eav": "102.1.*", + "magento/module-import-export": "101.0.*", + "magento/module-store": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -28,3 +29,4 @@ } } } + diff --git a/app/code/Magento/Eav/composer.json b/app/code/Magento/Eav/composer.json index 40d249ba472b9..a65b0a0ea5ca5 100644 --- a/app/code/Magento/Eav/composer.json +++ b/app/code/Magento/Eav/composer.json @@ -1,23 +1,24 @@ { "name": "magento/module-eav", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "102.1.6", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-config": "*", - "magento/module-media-storage": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-config": "101.2.*", + "magento/module-media-storage": "100.4.*", + "magento/module-store": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -27,3 +28,4 @@ } } } + diff --git a/app/code/Magento/EavGraphQl/composer.json b/app/code/Magento/EavGraphQl/composer.json index a19a8bc3d5109..5e187295d726b 100644 --- a/app/code/Magento/EavGraphQl/composer.json +++ b/app/code/Magento/EavGraphQl/composer.json @@ -2,18 +2,19 @@ "name": "magento/module-eav-graph-ql", "description": "N/A", "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "100.4.3", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-eav": "*" + "magento/framework": "103.0.*", + "magento/module-eav": "102.1.*" }, "suggest": { - "magento/module-graph-ql": "*" + "magento/module-graph-ql": "100.4.*" }, - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -23,3 +24,4 @@ } } } + diff --git a/app/code/Magento/Elasticsearch/composer.json b/app/code/Magento/Elasticsearch/composer.json index 714890fd5f452..bb4a095808871 100644 --- a/app/code/Magento/Elasticsearch/composer.json +++ b/app/code/Magento/Elasticsearch/composer.json @@ -1,27 +1,28 @@ { "name": "magento/module-elasticsearch", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "101.0.6", "require": { "php": "~8.1.0||~8.2.0", - "magento/module-advanced-search": "*", - "magento/module-catalog": "*", - "magento/module-catalog-search": "*", - "magento/module-customer": "*", - "magento/module-eav": "*", - "magento/module-search": "*", - "magento/module-store": "*", - "magento/module-catalog-inventory": "*", - "magento/framework": "*", + "magento/module-advanced-search": "100.4.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-search": "102.0.*", + "magento/module-customer": "103.0.*", + "magento/module-eav": "102.1.*", + "magento/module-search": "101.1.*", + "magento/module-store": "101.1.*", + "magento/module-catalog-inventory": "100.4.*", + "magento/framework": "103.0.*", "elasticsearch/elasticsearch": "~7.17.0 || ~8.5.0" }, "suggest": { - "magento/module-config": "*" + "magento/module-config": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -31,3 +32,4 @@ } } } + diff --git a/app/code/Magento/Elasticsearch7/composer.json b/app/code/Magento/Elasticsearch7/composer.json index 89f41bf14b0dc..3c793b31575d6 100644 --- a/app/code/Magento/Elasticsearch7/composer.json +++ b/app/code/Magento/Elasticsearch7/composer.json @@ -1,23 +1,24 @@ { "name": "magento/module-elasticsearch-7", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "100.4.6", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-elasticsearch": "*", + "magento/framework": "103.0.*", + "magento/module-elasticsearch": "101.0.*", "elasticsearch/elasticsearch": "^7.17", - "magento/module-advanced-search": "*", - "magento/module-catalog-search": "*", - "magento/module-search": "*" + "magento/module-advanced-search": "100.4.*", + "magento/module-catalog-search": "102.0.*", + "magento/module-search": "101.1.*" }, "suggest": { - "magento/module-config": "*" + "magento/module-config": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -27,3 +28,4 @@ } } } + diff --git a/app/code/Magento/Email/Model/Template/Filter.php b/app/code/Magento/Email/Model/Template/Filter.php index 40320b9ffc845..57478f76765b1 100644 --- a/app/code/Magento/Email/Model/Template/Filter.php +++ b/app/code/Magento/Email/Model/Template/Filter.php @@ -69,15 +69,22 @@ class Filter extends Template /** * @var bool * @deprecated SID is not being used as query parameter anymore. + * @see Session ID's in URL */ protected $_useSessionInUrl = false; /** * @var array * @deprecated 101.0.4 Use the new Directive Processor interfaces + * @see Directive Processor interfaces */ protected $_modifiers = ['nl2br' => '']; + /** + * @var string + */ + private const CACHE_KEY_PREFIX = "EMAIL_FILTER_"; + /** * @var bool */ @@ -281,6 +288,7 @@ public function setUseAbsoluteLinks($flag) * @return $this * @SuppressWarnings(PHPMD.UnusedFormalParameter) * @deprecated SID query parameter is not used in URLs anymore. + * @see SessionId's in URL */ public function setUseSessionInUrl($flag) { @@ -404,6 +412,11 @@ public function blockDirective($construction) { $skipParams = ['class', 'id', 'output']; $blockParameters = $this->getParameters($construction[2]); + + if (isset($blockParameters['cache_key'])) { + $blockParameters['cache_key'] = self::CACHE_KEY_PREFIX . $blockParameters['cache_key']; + } + $block = null; if (isset($blockParameters['class'])) { @@ -688,6 +701,7 @@ public function varDirective($construction) * @param string $default assumed modifier if none present * @return array * @deprecated 101.0.4 Use the new FilterApplier or Directive Processor interfaces + * @see Directive Processor Interfaces */ protected function explodeModifiers($value, $default = null) { @@ -707,6 +721,7 @@ protected function explodeModifiers($value, $default = null) * @param string $modifiers * @return string * @deprecated 101.0.4 Use the new FilterApplier or Directive Processor interfaces + * @see Directive Processor Interfaces */ protected function applyModifiers($value, $modifiers) { @@ -736,6 +751,7 @@ protected function applyModifiers($value, $modifiers) * @param string $type * @return string * @deprecated 101.0.4 Use the new FilterApplier or Directive Processor interfaces + * @see Directive Processor Interfacees */ public function modifierEscape($value, $type = 'html') { diff --git a/app/code/Magento/Email/composer.json b/app/code/Magento/Email/composer.json index 27b33acfe00db..393beafba5806 100644 --- a/app/code/Magento/Email/composer.json +++ b/app/code/Magento/Email/composer.json @@ -1,30 +1,31 @@ { "name": "magento/module-email", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "101.1.6-p1", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-cms": "*", - "magento/module-config": "*", - "magento/module-store": "*", - "magento/module-theme": "*", - "magento/module-require-js": "*", - "magento/module-media-storage": "*", - "magento/module-variable": "*", - "magento/module-ui": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-cms": "104.0.*", + "magento/module-config": "101.2.*", + "magento/module-store": "101.1.*", + "magento/module-theme": "101.1.*", + "magento/module-require-js": "100.4.*", + "magento/module-media-storage": "100.4.*", + "magento/module-variable": "100.4.*", + "magento/module-ui": "101.2.*" }, "suggest": { - "magento/module-theme": "*" + "magento/module-theme": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -34,3 +35,4 @@ } } } + diff --git a/app/code/Magento/EncryptionKey/composer.json b/app/code/Magento/EncryptionKey/composer.json index 43a61d210ed74..8cfa6778ae68f 100644 --- a/app/code/Magento/EncryptionKey/composer.json +++ b/app/code/Magento/EncryptionKey/composer.json @@ -1,20 +1,21 @@ { "name": "magento/module-encryption-key", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-config": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-config": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -24,3 +25,4 @@ } } } + diff --git a/app/code/Magento/Fedex/Model/Config/Backend/FedexUrl.php b/app/code/Magento/Fedex/Model/Config/Backend/FedexUrl.php new file mode 100644 index 0000000000000..33cd6f64de9cf --- /dev/null +++ b/app/code/Magento/Fedex/Model/Config/Backend/FedexUrl.php @@ -0,0 +1,76 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\Fedex\Model\Config\Backend; + +use Magento\Framework\App\Cache\TypeListInterface; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\App\Config\Value; +use Magento\Framework\Data\Collection\AbstractDb; +use Magento\Framework\Exception\ValidatorException; +use Magento\Framework\Model\AbstractModel; +use Magento\Framework\Model\Context; +use Magento\Framework\Model\ResourceModel\AbstractResource; +use Magento\Framework\Registry; +use Magento\Framework\Validator\Url; + +/** + * Represents a config URL that may point to a Fedex endpoint + */ +class FedexUrl extends Value +{ + /** + * @var Url + */ + private Url $url; + /** + * @param Context $context + * @param Registry $registry + * @param ScopeConfigInterface $config + * @param TypeListInterface $cacheTypeList + * @param AbstractResource|null $resource + * @param AbstractDb|null $resourceCollection + * @param Url $url + * @param array $data + */ + public function __construct( + Context $context, + Registry $registry, + ScopeConfigInterface $config, + TypeListInterface $cacheTypeList, + AbstractResource $resource = null, + AbstractDb $resourceCollection = null, + Url $url, + array $data = [] + ) { + parent::__construct($context, $registry, $config, $cacheTypeList, $resource, $resourceCollection, $data); + $this->url = $url; + } + + /** + * @inheritDoc + * + * @return AbstractModel + * @throws ValidatorException + */ + public function beforeSave(): AbstractModel + { + $isValid = $this->url->isValid($this->getValue(), ['http', 'https']); + + if ($isValid) { + // phpcs:ignore Magento2.Functions.DiscouragedFunction + $host = parse_url((string)$this->getValue(), \PHP_URL_HOST); + + if (!empty($host) && !preg_match('/(?:.+\.|^)fedex\.com$/i', $host)) { + throw new ValidatorException(__('Fedex API endpoint URL\'s must use fedex.com')); + } + } + + return parent::beforeSave(); + } +} diff --git a/app/code/Magento/Fedex/Test/Unit/Model/Config/Backend/FedexUrlTest.php b/app/code/Magento/Fedex/Test/Unit/Model/Config/Backend/FedexUrlTest.php new file mode 100644 index 0000000000000..56626222312bf --- /dev/null +++ b/app/code/Magento/Fedex/Test/Unit/Model/Config/Backend/FedexUrlTest.php @@ -0,0 +1,131 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\Fedex\Test\Unit\Model\Config\Backend; + +use Magento\Fedex\Model\Config\Backend\FedexUrl; +use Magento\Framework\App\Cache\TypeListInterface; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\Data\Collection\AbstractDb; +use Magento\Framework\Event\ManagerInterface; +use Magento\Framework\Exception\ValidatorException; +use Magento\Framework\Model\Context; +use Magento\Framework\Registry; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\Framework\Validator\Url; +use Magento\Rule\Model\ResourceModel\AbstractResource; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; + +/** + * Verify behavior of FedexUrl backend type + */ +class FedexUrlTest extends TestCase +{ + + /** + * @var FedexUrl + */ + private $urlConfig; + + /** + * @var Url + */ + private $url; + + /** + * @var Context|MockObject + */ + private $contextMock; + + protected function setUp(): void + { + $objectManager = new ObjectManager($this); + $this->contextMock = $this->createMock(Context::class); + $registry = $this->createMock(Registry::class); + $config = $this->createMock(ScopeConfigInterface::class); + $cacheTypeList = $this->createMock(TypeListInterface::class); + $this->url = $this->createMock(Url::class); + $resource = $this->createMock(AbstractResource::class); + $resourceCollection = $this->createMock(AbstractDb::class); + $eventManagerMock = $this->getMockForAbstractClass(ManagerInterface::class); + $eventManagerMock->expects($this->any())->method('dispatch'); + $this->contextMock->expects($this->any())->method('getEventDispatcher')->willReturn($eventManagerMock); + + $this->urlConfig = $objectManager->getObject( + FedexUrl::class, + [ + 'url' => $this->url, + 'context' => $this->contextMock, + 'registry' => $registry, + 'config' => $config, + 'cacheTypeList' => $cacheTypeList, + 'resource' => $resource, + 'resourceCollection' => $resourceCollection, + ] + ); + } + + /** + * @dataProvider validDataProvider + * @param string|null $data The valid data + * @throws ValidatorException + */ + public function testBeforeSave(string $data = null): void + { + $this->url->expects($this->any())->method('isValid')->willReturn(true); + $this->urlConfig->setValue($data); + $this->urlConfig->beforeSave(); + $this->assertTrue($this->url->isValid($data)); + } + + /** + * @dataProvider invalidDataProvider + * @param string $data The invalid data + */ + public function testBeforeSaveErrors(string $data): void + { + $this->url->expects($this->any())->method('isValid')->willReturn(true); + $this->expectException('Magento\Framework\Exception\ValidatorException'); + $this->expectExceptionMessage('Fedex API endpoint URL\'s must use fedex.com'); + $this->urlConfig->setValue($data); + $this->urlConfig->beforeSave(); + } + + /** + * Validator Data Provider + * + * @return array + */ + public function validDataProvider(): array + { + return [ + [], + [null], + [''], + ['http://fedex.com'], + ['https://foo.fedex.com'], + ['http://foo.fedex.com/foo/bar?baz=bash&fizz=buzz'], + ]; + } + + /** + * @return \string[][] + */ + public function invalidDataProvider(): array + { + return [ + ['http://fedexfoo.com'], + ['https://foofedex.com'], + ['https://fedex.com.fake.com'], + ['https://fedex.info'], + ['http://fedex.com.foo.com/foo/bar?baz=bash&fizz=buzz'], + ['http://foofedex.com/foo/bar?baz=bash&fizz=buzz'], + ]; + } +} diff --git a/app/code/Magento/Fedex/composer.json b/app/code/Magento/Fedex/composer.json index c3e879ac31177..d791577a587d6 100644 --- a/app/code/Magento/Fedex/composer.json +++ b/app/code/Magento/Fedex/composer.json @@ -1,27 +1,28 @@ { "name": "magento/module-fedex", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4-p1", "require": { "php": "~8.1.0||~8.2.0", "lib-libxml": "*", - "magento/framework": "*", - "magento/module-catalog": "*", - "magento/module-catalog-inventory": "*", - "magento/module-config": "*", - "magento/module-directory": "*", - "magento/module-quote": "*", - "magento/module-sales": "*", - "magento/module-shipping": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-inventory": "100.4.*", + "magento/module-config": "101.2.*", + "magento/module-directory": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-sales": "103.0.*", + "magento/module-shipping": "100.4.*", + "magento/module-store": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -31,3 +32,4 @@ } } } + diff --git a/app/code/Magento/Fedex/etc/adminhtml/system.xml b/app/code/Magento/Fedex/etc/adminhtml/system.xml index f164a8e21e0ae..a200b5bda7199 100644 --- a/app/code/Magento/Fedex/etc/adminhtml/system.xml +++ b/app/code/Magento/Fedex/etc/adminhtml/system.xml @@ -40,12 +40,14 @@ </field> <field id="production_webservices_url" translate="label" type="text" sortOrder="90" showInDefault="1" showInWebsite="1" canRestore="1"> <label>Web-Services URL (Production)</label> + <backend_model>Magento\Fedex\Model\Config\Backend\FedexUrl</backend_model> <depends> <field id="sandbox_mode">0</field> </depends> </field> <field id="sandbox_webservices_url" translate="label" type="text" sortOrder="100" showInDefault="1" showInWebsite="1" canRestore="1"> <label>Web-Services URL (Sandbox)</label> + <backend_model>Magento\Fedex\Model\Config\Backend\FedexUrl</backend_model> <depends> <field id="sandbox_mode">1</field> </depends> diff --git a/app/code/Magento/Fedex/i18n/en_US.csv b/app/code/Magento/Fedex/i18n/en_US.csv index d1509d42730bc..2911ebe793f23 100644 --- a/app/code/Magento/Fedex/i18n/en_US.csv +++ b/app/code/Magento/Fedex/i18n/en_US.csv @@ -78,3 +78,4 @@ Debug,Debug "Show Method if Not Applicable","Show Method if Not Applicable" "Sort Order","Sort Order" "Can't convert a shipping cost from ""%1-%2"" for FedEx carrier.","Can't convert a shipping cost from ""%1-%2"" for FedEx carrier." +"Fedex API endpoint URL\'s must use fedex.com","Fedex API endpoint URL\'s must use fedex.com" diff --git a/app/code/Magento/GiftMessage/composer.json b/app/code/Magento/GiftMessage/composer.json index be0cdbbe22911..07aca6fb886b3 100644 --- a/app/code/Magento/GiftMessage/composer.json +++ b/app/code/Magento/GiftMessage/composer.json @@ -1,30 +1,31 @@ { "name": "magento/module-gift-message", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.5", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-checkout": "*", - "magento/module-customer": "*", - "magento/module-quote": "*", - "magento/module-sales": "*", - "magento/module-store": "*", - "magento/module-ui": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-checkout": "100.4.*", + "magento/module-customer": "103.0.*", + "magento/module-quote": "101.2.*", + "magento/module-sales": "103.0.*", + "magento/module-store": "101.1.*", + "magento/module-ui": "101.2.*" }, "suggest": { - "magento/module-eav": "*", - "magento/module-multishipping": "*" + "magento/module-eav": "102.1.*", + "magento/module-multishipping": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -34,3 +35,4 @@ } } } + diff --git a/app/code/Magento/GiftMessageGraphQl/composer.json b/app/code/Magento/GiftMessageGraphQl/composer.json index 143b02439966f..fd0a85478e9bc 100644 --- a/app/code/Magento/GiftMessageGraphQl/composer.json +++ b/app/code/Magento/GiftMessageGraphQl/composer.json @@ -2,18 +2,19 @@ "name": "magento/module-gift-message-graph-ql", "description": "N/A", "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "100.4.4", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-gift-message": "*" + "magento/framework": "103.0.*", + "magento/module-gift-message": "100.4.*" }, "suggest": { - "magento/module-graph-ql": "*" + "magento/module-graph-ql": "100.4.*" }, - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -23,3 +24,4 @@ } } } + diff --git a/app/code/Magento/GoogleAdwords/composer.json b/app/code/Magento/GoogleAdwords/composer.json index a9d5b9178bb85..b9774878989a7 100644 --- a/app/code/Magento/GoogleAdwords/composer.json +++ b/app/code/Magento/GoogleAdwords/composer.json @@ -1,20 +1,21 @@ { "name": "magento/module-google-adwords", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.3", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-sales": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-sales": "103.0.*", + "magento/module-store": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -24,3 +25,4 @@ } } } + diff --git a/app/code/Magento/GoogleAnalytics/composer.json b/app/code/Magento/GoogleAnalytics/composer.json index 09d9cadf97658..f36a7de32d535 100644 --- a/app/code/Magento/GoogleAnalytics/composer.json +++ b/app/code/Magento/GoogleAnalytics/composer.json @@ -1,24 +1,25 @@ { "name": "magento/module-google-analytics", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.2", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-cookie": "*", - "magento/module-sales": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-cookie": "100.4.*", + "magento/module-sales": "103.0.*", + "magento/module-store": "101.1.*" }, "suggest": { - "magento/module-config": "*" + "magento/module-config": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -28,3 +29,4 @@ } } } + diff --git a/app/code/Magento/GoogleGtag/composer.json b/app/code/Magento/GoogleGtag/composer.json index ed6e245b4e955..d4213065f39f6 100644 --- a/app/code/Magento/GoogleGtag/composer.json +++ b/app/code/Magento/GoogleGtag/composer.json @@ -1,24 +1,25 @@ { "name": "magento/module-google-gtag", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.1", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-cookie": "*", - "magento/module-sales": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-cookie": "100.4.*", + "magento/module-sales": "103.0.*", + "magento/module-store": "101.1.*" }, "suggest": { - "magento/module-config": "*" + "magento/module-config": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -28,3 +29,4 @@ } } } + diff --git a/app/code/Magento/GoogleOptimizer/composer.json b/app/code/Magento/GoogleOptimizer/composer.json index 0192f363b61c2..eaad1a005eaa3 100644 --- a/app/code/Magento/GoogleOptimizer/composer.json +++ b/app/code/Magento/GoogleOptimizer/composer.json @@ -1,25 +1,26 @@ { "name": "magento/module-google-optimizer", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.5", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-cms": "*", - "magento/module-google-analytics": "*", - "magento/module-google-gtag": "*", - "magento/module-store": "*", - "magento/module-ui": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-cms": "104.0.*", + "magento/module-google-analytics": "100.4.*", + "magento/module-google-gtag": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-ui": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -29,3 +30,4 @@ } } } + diff --git a/app/code/Magento/GraphQl/composer.json b/app/code/Magento/GraphQl/composer.json index af1fe042c6df5..2e02286e3af94 100644 --- a/app/code/Magento/GraphQl/composer.json +++ b/app/code/Magento/GraphQl/composer.json @@ -2,22 +2,23 @@ "name": "magento/module-graph-ql", "description": "N/A", "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "100.4.6", "require": { "php": "~8.1.0||~8.2.0", - "magento/module-eav": "*", - "magento/framework": "*", - "magento/module-webapi": "*", - "magento/module-new-relic-reporting": "*", - "magento/module-authorization": "*", + "magento/module-eav": "102.1.*", + "magento/framework": "103.0.*", + "magento/module-webapi": "100.4.*", + "magento/module-new-relic-reporting": "100.4.*", + "magento/module-authorization": "100.4.*", "webonyx/graphql-php": "^15.0" }, "suggest": { - "magento/module-graph-ql-cache": "*" + "magento/module-graph-ql-cache": "100.4.*" }, - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -27,3 +28,4 @@ } } } + diff --git a/app/code/Magento/GraphQlCache/composer.json b/app/code/Magento/GraphQlCache/composer.json index 082534290d139..34db5ffafcfb2 100644 --- a/app/code/Magento/GraphQlCache/composer.json +++ b/app/code/Magento/GraphQlCache/composer.json @@ -2,18 +2,19 @@ "name": "magento/module-graph-ql-cache", "description": "N/A", "type": "magento2-module", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-page-cache": "*", - "magento/module-graph-ql": "*", - "magento/module-authorization": "*", - "magento/module-integration": "*" - }, "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.3", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*", + "magento/module-page-cache": "100.4.*", + "magento/module-graph-ql": "100.4.*", + "magento/module-authorization": "100.4.*", + "magento/module-integration": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -23,3 +24,4 @@ } } } + diff --git a/app/code/Magento/GroupedCatalogInventory/composer.json b/app/code/Magento/GroupedCatalogInventory/composer.json index 487fdfe0cc828..9ded78d413e21 100644 --- a/app/code/Magento/GroupedCatalogInventory/composer.json +++ b/app/code/Magento/GroupedCatalogInventory/composer.json @@ -1,21 +1,22 @@ { "name": "magento/module-grouped-catalog-inventory", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.3", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-catalog": "*", - "magento/module-catalog-inventory": "*", - "magento/module-grouped-product": "*" + "magento/framework": "103.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-inventory": "100.4.*", + "magento/module-grouped-product": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -25,3 +26,4 @@ } } } + diff --git a/app/code/Magento/GroupedImportExport/composer.json b/app/code/Magento/GroupedImportExport/composer.json index 21805741bca44..f6b1613b79a70 100644 --- a/app/code/Magento/GroupedImportExport/composer.json +++ b/app/code/Magento/GroupedImportExport/composer.json @@ -1,23 +1,24 @@ { "name": "magento/module-grouped-import-export", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-catalog": "*", - "magento/module-catalog-import-export": "*", - "magento/module-eav": "*", - "magento/module-grouped-product": "*", - "magento/module-import-export": "*" + "magento/framework": "103.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-import-export": "101.1.*", + "magento/module-eav": "102.1.*", + "magento/module-grouped-product": "100.4.*", + "magento/module-import-export": "101.0.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -27,3 +28,4 @@ } } } + diff --git a/app/code/Magento/GroupedProduct/composer.json b/app/code/Magento/GroupedProduct/composer.json index 8277efc44f06b..90c014b878640 100644 --- a/app/code/Magento/GroupedProduct/composer.json +++ b/app/code/Magento/GroupedProduct/composer.json @@ -1,34 +1,35 @@ { "name": "magento/module-grouped-product", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.6", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-catalog-inventory": "*", - "magento/module-checkout": "*", - "magento/module-customer": "*", - "magento/module-eav": "*", - "magento/module-media-storage": "*", - "magento/module-msrp": "*", - "magento/module-quote": "*", - "magento/module-sales": "*", - "magento/module-store": "*", - "magento/module-ui": "*", - "magento/module-wishlist": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-inventory": "100.4.*", + "magento/module-checkout": "100.4.*", + "magento/module-customer": "103.0.*", + "magento/module-eav": "102.1.*", + "magento/module-media-storage": "100.4.*", + "magento/module-msrp": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-sales": "103.0.*", + "magento/module-store": "101.1.*", + "magento/module-ui": "101.2.*", + "magento/module-wishlist": "101.2.*" }, "suggest": { - "magento/module-grouped-product-sample-data": "*" + "magento/module-grouped-product-sample-data": "Sample Data version: 100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -38,3 +39,4 @@ } } } + diff --git a/app/code/Magento/GroupedProductGraphQl/composer.json b/app/code/Magento/GroupedProductGraphQl/composer.json index 41254569da53b..c506dff0dc317 100644 --- a/app/code/Magento/GroupedProductGraphQl/composer.json +++ b/app/code/Magento/GroupedProductGraphQl/composer.json @@ -2,17 +2,18 @@ "name": "magento/module-grouped-product-graph-ql", "description": "N/A", "type": "magento2-module", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/module-grouped-product": "*", - "magento/module-catalog": "*", - "magento/module-catalog-graph-ql": "*", - "magento/framework": "*" - }, "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.6", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/module-grouped-product": "100.4.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-graph-ql": "100.4.*", + "magento/framework": "103.0.*" + }, "autoload": { "files": [ "registration.php" @@ -22,3 +23,4 @@ } } } + diff --git a/app/code/Magento/ImportExport/composer.json b/app/code/Magento/ImportExport/composer.json index 8ea56d1011582..81f0ad7fca8ed 100644 --- a/app/code/Magento/ImportExport/composer.json +++ b/app/code/Magento/ImportExport/composer.json @@ -1,25 +1,26 @@ { "name": "magento/module-import-export", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "101.0.6", "require": { "php": "~8.1.0||~8.2.0", "ext-ctype": "*", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-eav": "*", - "magento/module-media-storage": "*", - "magento/module-store": "*", - "magento/module-ui": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-eav": "102.1.*", + "magento/module-media-storage": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-ui": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -29,3 +30,4 @@ } } } + diff --git a/app/code/Magento/Indexer/composer.json b/app/code/Magento/Indexer/composer.json index 8cee48610c7ea..52d9a5591a41b 100644 --- a/app/code/Magento/Indexer/composer.json +++ b/app/code/Magento/Indexer/composer.json @@ -1,19 +1,20 @@ { "name": "magento/module-indexer", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.6", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-backend": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -23,3 +24,4 @@ } } } + diff --git a/app/code/Magento/InstantPurchase/composer.json b/app/code/Magento/InstantPurchase/composer.json index d64f757adfd3b..d78743c07689d 100644 --- a/app/code/Magento/InstantPurchase/composer.json +++ b/app/code/Magento/InstantPurchase/composer.json @@ -6,16 +6,17 @@ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.5", "require": { "php": "~8.1.0||~8.2.0", - "magento/module-store": "*", - "magento/module-catalog": "*", - "magento/module-customer": "*", - "magento/module-sales": "*", - "magento/module-shipping": "*", - "magento/module-quote": "*", - "magento/module-vault": "*", - "magento/framework": "*" + "magento/module-store": "101.1.*", + "magento/module-catalog": "104.0.*", + "magento/module-customer": "103.0.*", + "magento/module-sales": "103.0.*", + "magento/module-shipping": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-vault": "101.2.*", + "magento/framework": "103.0.*" }, "autoload": { "files": [ @@ -26,3 +27,4 @@ } } } + diff --git a/app/code/Magento/Integration/composer.json b/app/code/Magento/Integration/composer.json index a6eea5321de74..907ad94b4bd91 100644 --- a/app/code/Magento/Integration/composer.json +++ b/app/code/Magento/Integration/composer.json @@ -1,25 +1,26 @@ { "name": "magento/module-integration", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.6", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-authorization": "*", - "magento/module-backend": "*", - "magento/module-customer": "*", - "magento/module-security": "*", - "magento/module-store": "*", - "magento/module-user": "*", - "magento/module-ui": "*" + "magento/framework": "103.0.*", + "magento/module-authorization": "100.4.*", + "magento/module-backend": "102.0.*", + "magento/module-customer": "103.0.*", + "magento/module-security": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-user": "101.2.*", + "magento/module-ui": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -29,3 +30,4 @@ } } } + diff --git a/app/code/Magento/JwtFrameworkAdapter/composer.json b/app/code/Magento/JwtFrameworkAdapter/composer.json index d3bb5db7439fb..dcbdc89cfb718 100644 --- a/app/code/Magento/JwtFrameworkAdapter/composer.json +++ b/app/code/Magento/JwtFrameworkAdapter/composer.json @@ -1,19 +1,20 @@ { "name": "magento/module-jwt-framework-adapter", "description": "JWT Manager implementation based on jwt-framework", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.2", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", + "magento/framework": "103.0.*", "web-token/jwt-framework": "^3.1.2" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -23,3 +24,4 @@ } } } + diff --git a/app/code/Magento/JwtUserToken/composer.json b/app/code/Magento/JwtUserToken/composer.json index ff1ae2bda5261..25fe8834cd471 100644 --- a/app/code/Magento/JwtUserToken/composer.json +++ b/app/code/Magento/JwtUserToken/composer.json @@ -1,20 +1,21 @@ { "name": "magento/module-jwt-user-token", "description": "Introduces JWT token support for web API authentication", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.1", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-integration": "*", - "magento/module-authorization": "*" + "magento/framework": "103.0.*", + "magento/module-integration": "100.4.*", + "magento/module-authorization": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -24,3 +25,4 @@ } } } + diff --git a/app/code/Magento/LayeredNavigation/composer.json b/app/code/Magento/LayeredNavigation/composer.json index c40f906eac3a0..daec6732a0664 100644 --- a/app/code/Magento/LayeredNavigation/composer.json +++ b/app/code/Magento/LayeredNavigation/composer.json @@ -1,20 +1,21 @@ { "name": "magento/module-layered-navigation", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.6", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-catalog": "*", - "magento/module-config": "*" + "magento/framework": "103.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-config": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -24,3 +25,4 @@ } } } + diff --git a/app/code/Magento/LoginAsCustomer/Test/Mftf/Test/AdminLoginAsCustomerSubscribeToNewsletterTest.xml b/app/code/Magento/LoginAsCustomer/Test/Mftf/Test/AdminLoginAsCustomerSubscribeToNewsletterTest.xml index 1c3ae6e790089..a1eb8609fb4ae 100644 --- a/app/code/Magento/LoginAsCustomer/Test/Mftf/Test/AdminLoginAsCustomerSubscribeToNewsletterTest.xml +++ b/app/code/Magento/LoginAsCustomer/Test/Mftf/Test/AdminLoginAsCustomerSubscribeToNewsletterTest.xml @@ -17,6 +17,7 @@ value="Verify that Admin can subscribe to newsletter using Login as Customer functionality"/> <severity value="AVERAGE"/> <group value="login_as_customer"/> + <group value="newsletter"/> </annotations> <before> <magentoCLI command="config:set {{LoginAsCustomerConfigDataEnabled.path}} 1" diff --git a/app/code/Magento/LoginAsCustomer/composer.json b/app/code/Magento/LoginAsCustomer/composer.json index 6b2cbf7c1f3f7..fc5fee8fa04f1 100755 --- a/app/code/Magento/LoginAsCustomer/composer.json +++ b/app/code/Magento/LoginAsCustomer/composer.json @@ -1,21 +1,22 @@ { "name": "magento/module-login-as-customer", "description": "Allow for admin to enter a customer account", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-customer": "*", - "magento/module-login-as-customer-api": "*" - }, - "suggest": { - "magento/module-backend": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.6-p2", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-customer": "103.0.*", + "magento/module-login-as-customer-api": "100.4.*" + }, + "suggest": { + "magento/module-backend": "102.0.*" + }, "autoload": { "files": [ "registration.php" @@ -25,3 +26,4 @@ } } } + diff --git a/app/code/Magento/LoginAsCustomerAdminUi/composer.json b/app/code/Magento/LoginAsCustomerAdminUi/composer.json index 2a42d814be498..77602ffdedc2c 100644 --- a/app/code/Magento/LoginAsCustomerAdminUi/composer.json +++ b/app/code/Magento/LoginAsCustomerAdminUi/composer.json @@ -1,24 +1,24 @@ { "name": "magento/module-login-as-customer-admin-ui", - "description": "", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-login-as-customer-api": "*", - "magento/module-login-as-customer-frontend-ui": "*", - "magento/module-backend": "*", - "magento/module-customer": "*", - "magento/module-sales": "*", - "magento/module-store": "*" - }, - "suggest": { - "magento/module-login-as-customer": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.6", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*", + "magento/module-login-as-customer-api": "100.4.*", + "magento/module-login-as-customer-frontend-ui": "100.4.*", + "magento/module-backend": "102.0.*", + "magento/module-customer": "103.0.*", + "magento/module-sales": "103.0.*", + "magento/module-store": "101.1.*" + }, + "suggest": { + "magento/module-login-as-customer": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -28,3 +28,4 @@ } } } + diff --git a/app/code/Magento/LoginAsCustomerApi/composer.json b/app/code/Magento/LoginAsCustomerApi/composer.json index fed3ab5390597..63253d6b4bded 100644 --- a/app/code/Magento/LoginAsCustomerApi/composer.json +++ b/app/code/Magento/LoginAsCustomerApi/composer.json @@ -1,15 +1,16 @@ { "name": "magento/module-login-as-customer-api", "description": "Allow for admin to enter a customer account", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.5", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*" + }, "autoload": { "files": [ "registration.php" @@ -19,3 +20,4 @@ } } } + diff --git a/app/code/Magento/LoginAsCustomerAssistance/composer.json b/app/code/Magento/LoginAsCustomerAssistance/composer.json index 32e351bee5115..16ed3e854c6bf 100644 --- a/app/code/Magento/LoginAsCustomerAssistance/composer.json +++ b/app/code/Magento/LoginAsCustomerAssistance/composer.json @@ -1,24 +1,24 @@ { "name": "magento/module-login-as-customer-assistance", - "description": "", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-authorization": "*", - "magento/module-backend": "*", - "magento/module-customer": "*", - "magento/module-store": "*", - "magento/module-login-as-customer": "*", - "magento/module-login-as-customer-api": "*" - }, - "suggest": { - "magento/module-login-as-customer-admin-ui": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.5", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*", + "magento/module-authorization": "100.4.*", + "magento/module-backend": "102.0.*", + "magento/module-customer": "103.0.*", + "magento/module-store": "101.1.*", + "magento/module-login-as-customer": "100.4.*", + "magento/module-login-as-customer-api": "100.4.*" + }, + "suggest": { + "magento/module-login-as-customer-admin-ui": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -28,3 +28,4 @@ } } } + diff --git a/app/code/Magento/LoginAsCustomerFrontendUi/composer.json b/app/code/Magento/LoginAsCustomerFrontendUi/composer.json index 7c7767e23c27a..95517fd0a48c9 100644 --- a/app/code/Magento/LoginAsCustomerFrontendUi/composer.json +++ b/app/code/Magento/LoginAsCustomerFrontendUi/composer.json @@ -1,18 +1,18 @@ { "name": "magento/module-login-as-customer-frontend-ui", - "description": "", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-login-as-customer-api": "*", - "magento/module-customer": "*", - "magento/module-store": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.5", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*", + "magento/module-login-as-customer-api": "100.4.*", + "magento/module-customer": "103.0.*", + "magento/module-store": "101.1.*" + }, "autoload": { "files": [ "registration.php" @@ -22,3 +22,4 @@ } } } + diff --git a/app/code/Magento/LoginAsCustomerGraphQl/composer.json b/app/code/Magento/LoginAsCustomerGraphQl/composer.json index ee97cd320115e..6e08392b27273 100755 --- a/app/code/Magento/LoginAsCustomerGraphQl/composer.json +++ b/app/code/Magento/LoginAsCustomerGraphQl/composer.json @@ -1,23 +1,24 @@ { "name": "magento/module-login-as-customer-graph-ql", "description": "Flexible login as a customer so a merchant or merchant admin can log into an end customer's account to assist them with their account.", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-login-as-customer-api": "*", - "magento/module-login-as-customer-assistance": "*", - "magento/module-integration": "*", - "magento/module-store": "*", - "magento/module-customer": "*" - }, - "suggest": { - "magento/module-login-as-customer": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.3", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*", + "magento/module-login-as-customer-api": "100.4.*", + "magento/module-login-as-customer-assistance": "100.4.*", + "magento/module-integration": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-customer": "103.0.*" + }, + "suggest": { + "magento/module-login-as-customer": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -27,3 +28,4 @@ } } } + diff --git a/app/code/Magento/LoginAsCustomerLog/composer.json b/app/code/Magento/LoginAsCustomerLog/composer.json index 7e39d22d23ef6..370a4d90c51d8 100644 --- a/app/code/Magento/LoginAsCustomerLog/composer.json +++ b/app/code/Magento/LoginAsCustomerLog/composer.json @@ -1,23 +1,23 @@ { "name": "magento/module-login-as-customer-log", - "description": "", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-customer": "*", - "magento/module-login-as-customer-api": "*", - "magento/module-ui": "*", - "magento/module-user": "*" - }, - "suggest": { - "magento/module-login-as-customer": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.4", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-customer": "103.0.*", + "magento/module-login-as-customer-api": "100.4.*", + "magento/module-ui": "101.2.*", + "magento/module-user": "101.2.*" + }, + "suggest": { + "magento/module-login-as-customer": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -27,3 +27,4 @@ } } } + diff --git a/app/code/Magento/LoginAsCustomerPageCache/composer.json b/app/code/Magento/LoginAsCustomerPageCache/composer.json index 39b8217c89969..010b5c8624eae 100644 --- a/app/code/Magento/LoginAsCustomerPageCache/composer.json +++ b/app/code/Magento/LoginAsCustomerPageCache/composer.json @@ -1,20 +1,20 @@ { "name": "magento/module-login-as-customer-page-cache", - "description": "", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-store": "*", - "magento/module-login-as-customer-api": "*" - }, - "suggest": { - "magento/module-page-cache": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.5", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*", + "magento/module-store": "101.1.*", + "magento/module-login-as-customer-api": "100.4.*" + }, + "suggest": { + "magento/module-page-cache": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -24,3 +24,4 @@ } } } + diff --git a/app/code/Magento/LoginAsCustomerQuote/composer.json b/app/code/Magento/LoginAsCustomerQuote/composer.json index 0ce4d008d1fd8..e2008d68abf76 100644 --- a/app/code/Magento/LoginAsCustomerQuote/composer.json +++ b/app/code/Magento/LoginAsCustomerQuote/composer.json @@ -1,21 +1,21 @@ { "name": "magento/module-login-as-customer-quote", - "description": "", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-checkout": "*", - "magento/module-customer": "*", - "magento/module-quote": "*" - }, - "suggest": { - "magento/module-login-as-customer-api": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.4", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*", + "magento/module-checkout": "100.4.*", + "magento/module-customer": "103.0.*", + "magento/module-quote": "101.2.*" + }, + "suggest": { + "magento/module-login-as-customer-api": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -25,3 +25,4 @@ } } } + diff --git a/app/code/Magento/LoginAsCustomerSales/composer.json b/app/code/Magento/LoginAsCustomerSales/composer.json index 74f74eb34432e..612142f813453 100644 --- a/app/code/Magento/LoginAsCustomerSales/composer.json +++ b/app/code/Magento/LoginAsCustomerSales/composer.json @@ -1,21 +1,21 @@ { "name": "magento/module-login-as-customer-sales", - "description": "", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-user": "*", - "magento/module-login-as-customer-api": "*" - }, - "suggest": { - "magento/module-sales": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.5", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-user": "101.2.*", + "magento/module-login-as-customer-api": "100.4.*" + }, + "suggest": { + "magento/module-sales": "103.0.*" + }, "autoload": { "files": [ "registration.php" @@ -25,3 +25,4 @@ } } } + diff --git a/app/code/Magento/Marketplace/composer.json b/app/code/Magento/Marketplace/composer.json index 1827499160587..8bb89f869ab56 100644 --- a/app/code/Magento/Marketplace/composer.json +++ b/app/code/Magento/Marketplace/composer.json @@ -1,19 +1,20 @@ { "name": "magento/module-marketplace", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4-p2", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-backend": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -23,3 +24,4 @@ } } } + diff --git a/app/code/Magento/Marketplace/view/adminhtml/templates/index.phtml b/app/code/Magento/Marketplace/view/adminhtml/templates/index.phtml index ac39d72388e6c..fc58db1bed373 100644 --- a/app/code/Magento/Marketplace/view/adminhtml/templates/index.phtml +++ b/app/code/Magento/Marketplace/view/adminhtml/templates/index.phtml @@ -32,8 +32,8 @@ <h2 class="page-sub-title"><?= $block->escapeHtml(__('Partner search')) ?></h2> <p> <?= $block->escapeHtml(__( - 'Magento has a thriving ecosystem of technology partners to help merchants and brands deliver ' . - 'the best possible customer experiences. They are recognized as experts in eCommerce, ' . + 'Magento has a thriving ecosystem of technology partners to help merchants and brands deliver ' + . 'the best possible customer experiences. They are recognized as experts in eCommerce, ' . 'search, email marketing, payments, tax, fraud, optimization and analytics, fulfillment, ' . 'and more. Visit the Magento Partner Directory to see all of our trusted partners.' )); ?> @@ -61,7 +61,7 @@ )); ?> </p> <a class="action-secondary" target="_blank" - href="https://marketplace.magento.com/"> + href="https://commercemarketplace.adobe.com/"> <?= $block->escapeHtml(__('Visit Magento Marketplaces')) ?> </a> </div> diff --git a/app/code/Magento/MediaContent/composer.json b/app/code/Magento/MediaContent/composer.json index 4e7fd39b9d0ae..4a78525082875 100644 --- a/app/code/Magento/MediaContent/composer.json +++ b/app/code/Magento/MediaContent/composer.json @@ -1,17 +1,18 @@ { "name": "magento/module-media-content", "description": "Magento module provides the implementation for managing relations between content and media files used in that content", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-media-content-api": "*", - "magento/module-media-gallery-api": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.4", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*", + "magento/module-media-content-api": "100.4.*", + "magento/module-media-gallery-api": "101.0.*" + }, "autoload": { "files": [ "registration.php" @@ -21,3 +22,4 @@ } } } + diff --git a/app/code/Magento/MediaContentApi/composer.json b/app/code/Magento/MediaContentApi/composer.json index f7583a1f61a08..0ef247d0ccd37 100644 --- a/app/code/Magento/MediaContentApi/composer.json +++ b/app/code/Magento/MediaContentApi/composer.json @@ -1,16 +1,17 @@ { "name": "magento/module-media-content-api", "description": "Magento module provides the API interfaces for managing relations between content and media files used in that content", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/module-media-gallery-api": "*", - "magento/framework": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.5", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/module-media-gallery-api": "101.0.*", + "magento/framework": "103.0.*" + }, "autoload": { "files": [ "registration.php" @@ -20,3 +21,4 @@ } } } + diff --git a/app/code/Magento/MediaContentCatalog/composer.json b/app/code/Magento/MediaContentCatalog/composer.json index 948cc9f05d3cd..2c352d9987c5b 100644 --- a/app/code/Magento/MediaContentCatalog/composer.json +++ b/app/code/Magento/MediaContentCatalog/composer.json @@ -1,19 +1,20 @@ { "name": "magento/module-media-content-catalog", "description": "Magento module provides the implementation of MediaContent functionality for Magento_Catalog module", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/module-media-content-api": "*", - "magento/module-catalog": "*", - "magento/module-eav": "*", - "magento/module-store": "*", - "magento/framework": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.4", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/module-media-content-api": "100.4.*", + "magento/module-catalog": "104.0.*", + "magento/module-eav": "102.1.*", + "magento/module-store": "101.1.*", + "magento/framework": "103.0.*" + }, "autoload": { "files": [ "registration.php" @@ -23,3 +24,4 @@ } } } + diff --git a/app/code/Magento/MediaContentCms/composer.json b/app/code/Magento/MediaContentCms/composer.json index a0a6098993900..2071dc0c3868b 100644 --- a/app/code/Magento/MediaContentCms/composer.json +++ b/app/code/Magento/MediaContentCms/composer.json @@ -1,17 +1,18 @@ { "name": "magento/module-media-content-cms", "description": "Magento module provides the implementation of MediaContent functionality for Magento_Cms module", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/module-media-content-api": "*", - "magento/module-cms": "*", - "magento/framework": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.4", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/module-media-content-api": "100.4.*", + "magento/module-cms": "104.0.*", + "magento/framework": "103.0.*" + }, "autoload": { "files": [ "registration.php" @@ -21,3 +22,4 @@ } } } + diff --git a/app/code/Magento/MediaContentSynchronization/composer.json b/app/code/Magento/MediaContentSynchronization/composer.json index 4520f1302a03f..0532ddaddfaa2 100644 --- a/app/code/Magento/MediaContentSynchronization/composer.json +++ b/app/code/Magento/MediaContentSynchronization/composer.json @@ -1,22 +1,23 @@ { "name": "magento/module-media-content-synchronization", "description": "Magento module provides implementation of the media content data synchronization.", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/framework-bulk": "*", - "magento/module-media-content-synchronization-api": "*", - "magento/module-media-content-api": "*", - "magento/module-asynchronous-operations": "*" - }, - "suggest": { - "magento/module-media-gallery-synchronization": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.5", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*", + "magento/framework-bulk": "101.0.*", + "magento/module-media-content-synchronization-api": "100.4.*", + "magento/module-media-content-api": "100.4.*", + "magento/module-asynchronous-operations": "100.4.*" + }, + "suggest": { + "magento/module-media-gallery-synchronization": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -26,3 +27,4 @@ } } } + diff --git a/app/code/Magento/MediaContentSynchronizationApi/composer.json b/app/code/Magento/MediaContentSynchronizationApi/composer.json index 1e44b8079e29b..84a80b90a6e25 100644 --- a/app/code/Magento/MediaContentSynchronizationApi/composer.json +++ b/app/code/Magento/MediaContentSynchronizationApi/composer.json @@ -1,16 +1,17 @@ { "name": "magento/module-media-content-synchronization-api", "description": "Magento module responsible for the media content synchronization implementation API", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-media-content-api": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.4", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*", + "magento/module-media-content-api": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -20,3 +21,4 @@ } } } + diff --git a/app/code/Magento/MediaContentSynchronizationCatalog/composer.json b/app/code/Magento/MediaContentSynchronizationCatalog/composer.json index f3a2bbb4baeb1..444dcd3a95e9f 100644 --- a/app/code/Magento/MediaContentSynchronizationCatalog/composer.json +++ b/app/code/Magento/MediaContentSynchronizationCatalog/composer.json @@ -1,18 +1,19 @@ { "name": "magento/module-media-content-synchronization-catalog", "description": "Magento module provides the implementation of MediaContentSynchronization functionality for Magento_Catalog module", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-media-content-synchronization-api": "*", - "magento/module-media-gallery-synchronization-api": "*", - "magento/module-media-content-api": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.3", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*", + "magento/module-media-content-synchronization-api": "100.4.*", + "magento/module-media-gallery-synchronization-api": "100.4.*", + "magento/module-media-content-api": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -22,3 +23,4 @@ } } } + diff --git a/app/code/Magento/MediaContentSynchronizationCms/composer.json b/app/code/Magento/MediaContentSynchronizationCms/composer.json index 9925cc9ae5387..0f68ec4a4a02b 100644 --- a/app/code/Magento/MediaContentSynchronizationCms/composer.json +++ b/app/code/Magento/MediaContentSynchronizationCms/composer.json @@ -1,18 +1,19 @@ { "name": "magento/module-media-content-synchronization-cms", "description": "Magento module provides the implementation of MediaContentSynchronization functionality for Magento_Cms module", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-media-content-synchronization-api": "*", - "magento/module-media-gallery-synchronization-api": "*", - "magento/module-media-content-api": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.3", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*", + "magento/module-media-content-synchronization-api": "100.4.*", + "magento/module-media-gallery-synchronization-api": "100.4.*", + "magento/module-media-content-api": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -22,3 +23,4 @@ } } } + diff --git a/app/code/Magento/MediaGallery/composer.json b/app/code/Magento/MediaGallery/composer.json index 0076013351e22..2019f89a6d43d 100644 --- a/app/code/Magento/MediaGallery/composer.json +++ b/app/code/Magento/MediaGallery/composer.json @@ -1,17 +1,18 @@ { "name": "magento/module-media-gallery", "description": "Magento module responsible for media handling", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-media-gallery-api": "*", - "magento/module-cms": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.5", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*", + "magento/module-media-gallery-api": "101.0.*", + "magento/module-cms": "104.0.*" + }, "autoload": { "files": [ "registration.php" @@ -21,3 +22,4 @@ } } } + diff --git a/app/code/Magento/MediaGalleryApi/composer.json b/app/code/Magento/MediaGalleryApi/composer.json index 48ef4dbf076f3..3d20fc5770ab5 100644 --- a/app/code/Magento/MediaGalleryApi/composer.json +++ b/app/code/Magento/MediaGalleryApi/composer.json @@ -1,15 +1,16 @@ { "name": "magento/module-media-gallery-api", "description": "Magento module responsible for media gallery asset attributes storage and management", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "101.0.5", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*" + }, "autoload": { "files": [ "registration.php" @@ -19,3 +20,4 @@ } } } + diff --git a/app/code/Magento/MediaGalleryCatalog/composer.json b/app/code/Magento/MediaGalleryCatalog/composer.json index 7feea28221df4..d1d90aa5db83a 100644 --- a/app/code/Magento/MediaGalleryCatalog/composer.json +++ b/app/code/Magento/MediaGalleryCatalog/composer.json @@ -1,17 +1,18 @@ { "name": "magento/module-media-gallery-catalog", "description": "Magento module responsible for catalog gallery processor delete operation handling", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-media-gallery-api": "*", - "magento/module-catalog": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.3", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*", + "magento/module-media-gallery-api": "101.0.*", + "magento/module-catalog": "104.0.*" + }, "autoload": { "files": [ "registration.php" @@ -21,3 +22,4 @@ } } } + diff --git a/app/code/Magento/MediaGalleryCatalogIntegration/composer.json b/app/code/Magento/MediaGalleryCatalogIntegration/composer.json index 267c37e88b44e..532ca881b2efe 100644 --- a/app/code/Magento/MediaGalleryCatalogIntegration/composer.json +++ b/app/code/Magento/MediaGalleryCatalogIntegration/composer.json @@ -1,22 +1,23 @@ { "name": "magento/module-media-gallery-catalog-integration", "description": "Magento module responsible for extending catalog image uploader functionality", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-cms": "*", - "magento/module-media-gallery-api": "*", - "magento/module-media-gallery-synchronization-api": "*", - "magento/module-media-gallery-ui-api": "*" - }, - "suggest": { - "magento/module-catalog": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.3", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*", + "magento/module-cms": "104.0.*", + "magento/module-media-gallery-api": "101.0.*", + "magento/module-media-gallery-synchronization-api": "100.4.*", + "magento/module-media-gallery-ui-api": "100.4.*" + }, + "suggest": { + "magento/module-catalog": "104.0.*" + }, "autoload": { "files": [ "registration.php" @@ -26,3 +27,4 @@ } } } + diff --git a/app/code/Magento/MediaGalleryCatalogUi/composer.json b/app/code/Magento/MediaGalleryCatalogUi/composer.json index 46f0de7c6a51b..4c4619171cc3a 100644 --- a/app/code/Magento/MediaGalleryCatalogUi/composer.json +++ b/app/code/Magento/MediaGalleryCatalogUi/composer.json @@ -1,20 +1,21 @@ { "name": "magento/module-media-gallery-catalog-ui", "description": "Magento module that implement category grid for media gallery.", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-cms": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-store": "*", - "magento/module-ui": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.3", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*", + "magento/module-cms": "104.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-store": "101.1.*", + "magento/module-ui": "101.2.*" + }, "autoload": { "files": [ "registration.php" @@ -24,3 +25,4 @@ } } } + diff --git a/app/code/Magento/MediaGalleryCmsUi/composer.json b/app/code/Magento/MediaGalleryCmsUi/composer.json index 04e7f24199775..9ab26ba78468e 100644 --- a/app/code/Magento/MediaGalleryCmsUi/composer.json +++ b/app/code/Magento/MediaGalleryCmsUi/composer.json @@ -1,17 +1,18 @@ { "name": "magento/module-media-gallery-cms-ui", "description": "Cms related UI elements in the magento media gallery", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-cms": "*", - "magento/module-backend": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.3", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*", + "magento/module-cms": "104.0.*", + "magento/module-backend": "102.0.*" + }, "autoload": { "files": [ "registration.php" @@ -21,3 +22,4 @@ } } } + diff --git a/app/code/Magento/MediaGalleryIntegration/composer.json b/app/code/Magento/MediaGalleryIntegration/composer.json index 3c0fd77facb76..781da96b1cf94 100644 --- a/app/code/Magento/MediaGalleryIntegration/composer.json +++ b/app/code/Magento/MediaGalleryIntegration/composer.json @@ -1,26 +1,24 @@ { "name": "magento/module-media-gallery-integration", "description": "Magento module responsible for integration of enhanced media gallery", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-media-gallery-ui-api": "*", - "magento/module-media-gallery-api": "*", - "magento/module-media-gallery-synchronization-api": "*", - "magento/module-ui": "*" - }, - "require-dev": { - "magento/module-cms": "*" - }, - "suggest": { - "magento/module-catalog": "*", - "magento/module-cms": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.5", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*", + "magento/module-media-gallery-ui-api": "100.4.*", + "magento/module-media-gallery-api": "101.0.*", + "magento/module-media-gallery-synchronization-api": "100.4.*", + "magento/module-ui": "101.2.*" + }, + "suggest": { + "magento/module-catalog": "104.0.*", + "magento/module-cms": "104.0.*" + }, "autoload": { "files": [ "registration.php" @@ -28,5 +26,9 @@ "psr-4": { "Magento\\MediaGalleryIntegration\\": "" } + }, + "require-dev": { + "magento/module-cms": "*" } } + diff --git a/app/code/Magento/MediaGalleryMetadata/composer.json b/app/code/Magento/MediaGalleryMetadata/composer.json index aede5537f058b..f41f7c39d9629 100644 --- a/app/code/Magento/MediaGalleryMetadata/composer.json +++ b/app/code/Magento/MediaGalleryMetadata/composer.json @@ -1,16 +1,17 @@ { "name": "magento/module-media-gallery-metadata", "description": "Magento module responsible for images metadata processing", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-media-gallery-metadata-api": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.4", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*", + "magento/module-media-gallery-metadata-api": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -20,3 +21,4 @@ } } } + diff --git a/app/code/Magento/MediaGalleryMetadataApi/composer.json b/app/code/Magento/MediaGalleryMetadataApi/composer.json index 41de71aeb5265..d7f33e6ec76f4 100644 --- a/app/code/Magento/MediaGalleryMetadataApi/composer.json +++ b/app/code/Magento/MediaGalleryMetadataApi/composer.json @@ -1,15 +1,16 @@ { "name": "magento/module-media-gallery-metadata-api", "description": "Magento module responsible for media gallery metadata implementation API", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.3", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*" + }, "autoload": { "files": [ "registration.php" @@ -19,3 +20,4 @@ } } } + diff --git a/app/code/Magento/MediaGalleryRenditions/composer.json b/app/code/Magento/MediaGalleryRenditions/composer.json index ca05a594554a6..4709b2c8b0729 100644 --- a/app/code/Magento/MediaGalleryRenditions/composer.json +++ b/app/code/Magento/MediaGalleryRenditions/composer.json @@ -1,22 +1,23 @@ { "name": "magento/module-media-gallery-renditions", "description": "Magento module that implements height and width fields for for media gallery items.", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-media-gallery-renditions-api": "*", - "magento/module-media-gallery-api": "*", - "magento/framework-message-queue": "*", - "magento/module-cms": "*" - }, - "suggest": { - "magento/module-media-content-api": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.4", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*", + "magento/module-media-gallery-renditions-api": "100.4.*", + "magento/module-media-gallery-api": "101.0.*", + "magento/framework-message-queue": "100.4.*", + "magento/module-cms": "104.0.*" + }, + "suggest": { + "magento/module-media-content-api": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -26,3 +27,4 @@ } } } + diff --git a/app/code/Magento/MediaGalleryRenditionsApi/composer.json b/app/code/Magento/MediaGalleryRenditionsApi/composer.json index e6f9cf747690f..990171e9696e1 100644 --- a/app/code/Magento/MediaGalleryRenditionsApi/composer.json +++ b/app/code/Magento/MediaGalleryRenditionsApi/composer.json @@ -1,15 +1,16 @@ { "name": "magento/module-media-gallery-renditions-api", "description": "Magento module that is responsible for the API implementation of Media Gallery Renditions.", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.3", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*" + }, "autoload": { "files": [ "registration.php" @@ -19,3 +20,4 @@ } } } + diff --git a/app/code/Magento/MediaGallerySynchronization/composer.json b/app/code/Magento/MediaGallerySynchronization/composer.json index ee7b9b5be5b89..0f7598adde956 100644 --- a/app/code/Magento/MediaGallerySynchronization/composer.json +++ b/app/code/Magento/MediaGallerySynchronization/composer.json @@ -1,18 +1,19 @@ { "name": "magento/module-media-gallery-synchronization", "description": "Magento module provides implementation of the media gallery data synchronization.", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-media-gallery-api": "*", - "magento/module-media-gallery-synchronization-api": "*", - "magento/framework-message-queue": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.5", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*", + "magento/module-media-gallery-api": "101.0.*", + "magento/module-media-gallery-synchronization-api": "100.4.*", + "magento/framework-message-queue": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -22,3 +23,4 @@ } } } + diff --git a/app/code/Magento/MediaGallerySynchronizationApi/composer.json b/app/code/Magento/MediaGallerySynchronizationApi/composer.json index 7b62a0d7c680f..c746823cc40fa 100644 --- a/app/code/Magento/MediaGallerySynchronizationApi/composer.json +++ b/app/code/Magento/MediaGallerySynchronizationApi/composer.json @@ -1,16 +1,17 @@ { "name": "magento/module-media-gallery-synchronization-api", "description": "Magento module responsible for the media gallery synchronization implementation API", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-media-gallery-api": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.4", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*", + "magento/module-media-gallery-api": "101.0.*" + }, "autoload": { "files": [ "registration.php" @@ -20,3 +21,4 @@ } } } + diff --git a/app/code/Magento/MediaGallerySynchronizationMetadata/composer.json b/app/code/Magento/MediaGallerySynchronizationMetadata/composer.json index ba4cec8bd6da9..466080c2fb1dd 100644 --- a/app/code/Magento/MediaGallerySynchronizationMetadata/composer.json +++ b/app/code/Magento/MediaGallerySynchronizationMetadata/composer.json @@ -1,18 +1,19 @@ { "name": "magento/module-media-gallery-synchronization-metadata", "description": "Magento module responsible for images metadata synchronization", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-media-gallery-api": "*", - "magento/module-media-gallery-metadata-api": "*", - "magento/module-media-gallery-synchronization-api": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.2", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*", + "magento/module-media-gallery-api": "101.0.*", + "magento/module-media-gallery-metadata-api": "100.4.*", + "magento/module-media-gallery-synchronization-api": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -22,3 +23,4 @@ } } } + diff --git a/app/code/Magento/MediaGalleryUi/composer.json b/app/code/Magento/MediaGalleryUi/composer.json index d5caac3ff409e..6911017121adb 100644 --- a/app/code/Magento/MediaGalleryUi/composer.json +++ b/app/code/Magento/MediaGalleryUi/composer.json @@ -1,26 +1,27 @@ { "name": "magento/module-media-gallery-ui", "description": "Magento module responsible for the media gallery UI implementation", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-ui": "*", - "magento/module-store": "*", - "magento/module-media-gallery-ui-api": "*", - "magento/module-media-gallery-api": "*", - "magento/module-media-gallery-metadata-api": "*", - "magento/module-media-gallery-synchronization-api": "*", - "magento/module-media-content-api": "*", - "magento/module-cms": "*", - "magento/module-directory": "*", - "magento/module-authorization": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.5", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-ui": "101.2.*", + "magento/module-store": "101.1.*", + "magento/module-media-gallery-ui-api": "100.4.*", + "magento/module-media-gallery-api": "101.0.*", + "magento/module-media-gallery-metadata-api": "100.4.*", + "magento/module-media-gallery-synchronization-api": "100.4.*", + "magento/module-media-content-api": "100.4.*", + "magento/module-cms": "104.0.*", + "magento/module-directory": "100.4.*", + "magento/module-authorization": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -30,3 +31,4 @@ } } } + diff --git a/app/code/Magento/MediaGalleryUiApi/composer.json b/app/code/Magento/MediaGalleryUiApi/composer.json index 9c6aa225fa058..e6b0795d5b066 100644 --- a/app/code/Magento/MediaGalleryUiApi/composer.json +++ b/app/code/Magento/MediaGalleryUiApi/composer.json @@ -1,18 +1,19 @@ { "name": "magento/module-media-gallery-ui-api", "description": "Magento module responsible for the media gallery UI implementation API", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*" - }, - "suggest": { - "magento/module-cms": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.4", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*" + }, + "suggest": { + "magento/module-cms": "104.0.*" + }, "autoload": { "files": [ "registration.php" @@ -22,3 +23,4 @@ } } } + diff --git a/app/code/Magento/MediaStorage/composer.json b/app/code/Magento/MediaStorage/composer.json index f58c5d9b808c3..14e38db53967d 100644 --- a/app/code/Magento/MediaStorage/composer.json +++ b/app/code/Magento/MediaStorage/composer.json @@ -1,26 +1,27 @@ { "name": "magento/module-media-storage", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.5", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/framework-bulk": "*", - "magento/module-backend": "*", - "magento/module-config": "*", - "magento/module-store": "*", - "magento/module-catalog": "*", - "magento/module-theme": "*", - "magento/module-asynchronous-operations": "*", - "magento/module-authorization": "*" + "magento/framework": "103.0.*", + "magento/framework-bulk": "101.0.*", + "magento/module-backend": "102.0.*", + "magento/module-config": "101.2.*", + "magento/module-store": "101.1.*", + "magento/module-catalog": "104.0.*", + "magento/module-theme": "101.1.*", + "magento/module-asynchronous-operations": "100.4.*", + "magento/module-authorization": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -30,3 +31,4 @@ } } } + diff --git a/app/code/Magento/MessageQueue/composer.json b/app/code/Magento/MessageQueue/composer.json index 7a297574ec8b2..55745d6d28450 100644 --- a/app/code/Magento/MessageQueue/composer.json +++ b/app/code/Magento/MessageQueue/composer.json @@ -1,20 +1,21 @@ { "name": "magento/module-message-queue", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.6", "require": { - "magento/framework": "*", - "magento/framework-message-queue": "*", + "magento/framework": "103.0.*", + "magento/framework-message-queue": "100.4.*", "magento/magento-composer-installer": "*", "php": "~8.1.0||~8.2.0" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -24,3 +25,4 @@ } } } + diff --git a/app/code/Magento/Msrp/composer.json b/app/code/Magento/Msrp/composer.json index 1614f33d6c20c..5a50521cb99b3 100644 --- a/app/code/Magento/Msrp/composer.json +++ b/app/code/Magento/Msrp/composer.json @@ -1,27 +1,28 @@ { "name": "magento/module-msrp", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.5", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-catalog": "*", - "magento/module-downloadable": "*", - "magento/module-eav": "*", - "magento/module-store": "*", - "magento/module-tax": "*" + "magento/framework": "103.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-downloadable": "100.4.*", + "magento/module-eav": "102.1.*", + "magento/module-store": "101.1.*", + "magento/module-tax": "100.4.*" }, "suggest": { - "magento/module-bundle": "*", - "magento/module-msrp-sample-data": "*" + "magento/module-bundle": "101.0.*", + "magento/module-msrp-sample-data": "Sample Data version: 100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -31,3 +32,4 @@ } } } + diff --git a/app/code/Magento/MsrpConfigurableProduct/composer.json b/app/code/Magento/MsrpConfigurableProduct/composer.json index c58e77c047b2d..548f9c97db545 100644 --- a/app/code/Magento/MsrpConfigurableProduct/composer.json +++ b/app/code/Magento/MsrpConfigurableProduct/composer.json @@ -1,21 +1,22 @@ { "name": "magento/module-msrp-configurable-product", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.3", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-catalog": "*", - "magento/module-msrp": "*", - "magento/module-configurable-product": "*" + "magento/framework": "103.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-msrp": "100.4.*", + "magento/module-configurable-product": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -25,3 +26,4 @@ } } } + diff --git a/app/code/Magento/MsrpGroupedProduct/composer.json b/app/code/Magento/MsrpGroupedProduct/composer.json index 1dea4b9949058..2926d4333b409 100644 --- a/app/code/Magento/MsrpGroupedProduct/composer.json +++ b/app/code/Magento/MsrpGroupedProduct/composer.json @@ -1,21 +1,22 @@ { "name": "magento/module-msrp-grouped-product", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.3", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-catalog": "*", - "magento/module-msrp": "*", - "magento/module-grouped-product": "*" + "magento/framework": "103.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-msrp": "100.4.*", + "magento/module-grouped-product": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -25,3 +26,4 @@ } } } + diff --git a/app/code/Magento/Multishipping/composer.json b/app/code/Magento/Multishipping/composer.json index 3ea9380da0809..b301b3721a8f9 100644 --- a/app/code/Magento/Multishipping/composer.json +++ b/app/code/Magento/Multishipping/composer.json @@ -1,28 +1,29 @@ { "name": "magento/module-multishipping", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.6", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-checkout": "*", - "magento/module-customer": "*", - "magento/module-directory": "*", - "magento/module-payment": "*", - "magento/module-quote": "*", - "magento/module-sales": "*", - "magento/module-store": "*", - "magento/module-tax": "*", - "magento/module-theme": "*", - "magento/module-captcha": "*" + "magento/framework": "103.0.*", + "magento/module-checkout": "100.4.*", + "magento/module-customer": "103.0.*", + "magento/module-directory": "100.4.*", + "magento/module-payment": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-sales": "103.0.*", + "magento/module-store": "101.1.*", + "magento/module-tax": "100.4.*", + "magento/module-theme": "101.1.*", + "magento/module-captcha": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -32,3 +33,4 @@ } } } + diff --git a/app/code/Magento/MysqlMq/composer.json b/app/code/Magento/MysqlMq/composer.json index b164a3b63aad4..f417cd6a2159a 100644 --- a/app/code/Magento/MysqlMq/composer.json +++ b/app/code/Magento/MysqlMq/composer.json @@ -1,21 +1,22 @@ { "name": "magento/module-mysql-mq", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { - "magento/framework": "*", - "magento/framework-message-queue": "*", + "magento/framework": "103.0.*", + "magento/framework-message-queue": "100.4.*", "magento/magento-composer-installer": "*", - "magento/module-store": "*", + "magento/module-store": "101.1.*", "php": "~8.1.0||~8.2.0" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -25,3 +26,4 @@ } } } + diff --git a/app/code/Magento/NewRelicReporting/composer.json b/app/code/Magento/NewRelicReporting/composer.json index e98f914082fab..5dd88e8932c2a 100644 --- a/app/code/Magento/NewRelicReporting/composer.json +++ b/app/code/Magento/NewRelicReporting/composer.json @@ -1,25 +1,26 @@ { "name": "magento/module-new-relic-reporting", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", + "magento/framework": "103.0.*", "magento/magento-composer-installer": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-config": "*", - "magento/module-configurable-product": "*", - "magento/module-customer": "*", - "magento/module-store": "*" + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-config": "101.2.*", + "magento/module-configurable-product": "100.4.*", + "magento/module-customer": "103.0.*", + "magento/module-store": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -29,3 +30,4 @@ } } } + diff --git a/app/code/Magento/Newsletter/Test/Mftf/ActionGroup/AdminDisableNewsletterActionGroup.xml b/app/code/Magento/Newsletter/Test/Mftf/ActionGroup/AdminDisableNewsletterActionGroup.xml new file mode 100644 index 0000000000000..930a40765d72b --- /dev/null +++ b/app/code/Magento/Newsletter/Test/Mftf/ActionGroup/AdminDisableNewsletterActionGroup.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AdminDisableNewsletterActionGroup"> + <annotations> + <description>Runs bin/magento command to inactive newsletter subscription</description> + </annotations> + <magentoCLI command="config:set newsletter/general/active 0" stepKey="disableNewsletter"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Newsletter/Test/Mftf/ActionGroup/AdminEnableNewsletterActionGroup.xml b/app/code/Magento/Newsletter/Test/Mftf/ActionGroup/AdminEnableNewsletterActionGroup.xml new file mode 100644 index 0000000000000..8b84a66a14e35 --- /dev/null +++ b/app/code/Magento/Newsletter/Test/Mftf/ActionGroup/AdminEnableNewsletterActionGroup.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AdminEnableNewsletterActionGroup"> + <annotations> + <description>Runs bin/magento command to active newsletter subscription</description> + </annotations> + <magentoCLI command="config:set newsletter/general/active 1" stepKey="enableNewsletter"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Newsletter/Test/Mftf/Test/AdminMarketingCreateNewsletterTemplateTest.xml b/app/code/Magento/Newsletter/Test/Mftf/Test/AdminMarketingCreateNewsletterTemplateTest.xml index d3ebe3cbc30de..7f022d744a4ee 100644 --- a/app/code/Magento/Newsletter/Test/Mftf/Test/AdminMarketingCreateNewsletterTemplateTest.xml +++ b/app/code/Magento/Newsletter/Test/Mftf/Test/AdminMarketingCreateNewsletterTemplateTest.xml @@ -14,7 +14,6 @@ <stories value="Admin Creates Newsletter Template"/> <title value="Newsletter Template Creation"/> <description value="Newsletter Template Successfully Created"/> - <group value="newsletter"/> <group value="mtf_migrated"/> <severity value="CRITICAL"/> <testCaseId value="MC-29809"/> diff --git a/app/code/Magento/Newsletter/Test/Mftf/Test/AdminMarketingNewsletterTemplateUpdateTest.xml b/app/code/Magento/Newsletter/Test/Mftf/Test/AdminMarketingNewsletterTemplateUpdateTest.xml index 1d8565d7b2b78..1824c4ce2a02c 100644 --- a/app/code/Magento/Newsletter/Test/Mftf/Test/AdminMarketingNewsletterTemplateUpdateTest.xml +++ b/app/code/Magento/Newsletter/Test/Mftf/Test/AdminMarketingNewsletterTemplateUpdateTest.xml @@ -17,7 +17,6 @@ <severity value="MAJOR"/> <testCaseId value="MC-39506"/> <useCaseId value="MAGETWO-69597"/> - <group value="newsletter"/> <group value="reports"/> <group value="mtf_migrated"/> <group value="WYSIWYGDisabled"/> diff --git a/app/code/Magento/Newsletter/Test/Mftf/Test/AdminNameEmptyForGuestTest.xml b/app/code/Magento/Newsletter/Test/Mftf/Test/AdminNameEmptyForGuestTest.xml index 5e35f5aab60cd..10a12fcad5ca4 100644 --- a/app/code/Magento/Newsletter/Test/Mftf/Test/AdminNameEmptyForGuestTest.xml +++ b/app/code/Magento/Newsletter/Test/Mftf/Test/AdminNameEmptyForGuestTest.xml @@ -16,6 +16,7 @@ <title value="Empty name for Guest Customer"/> <description value="'Customer First Name' and 'Customer Last Name' should be empty for Guest Customer in Newsletter Subscribers Grid"/> <severity value="MINOR"/> + <group value="newsletter"/> </annotations> <before> diff --git a/app/code/Magento/Newsletter/Test/Mftf/Test/StorefrontVerifySecureURLRedirectNewsletterTest.xml b/app/code/Magento/Newsletter/Test/Mftf/Test/StorefrontVerifySecureURLRedirectNewsletterTest.xml index 7ec1fb62fc00f..b7441c97c716c 100644 --- a/app/code/Magento/Newsletter/Test/Mftf/Test/StorefrontVerifySecureURLRedirectNewsletterTest.xml +++ b/app/code/Magento/Newsletter/Test/Mftf/Test/StorefrontVerifySecureURLRedirectNewsletterTest.xml @@ -21,6 +21,7 @@ <group value="secure_storefront_url"/> </annotations> <before> + <actionGroup ref="AdminEnableNewsletterActionGroup" stepKey="enableNewsletter" /> <createData entity="Simple_US_Customer" stepKey="customer"/> <actionGroup ref="LoginToStorefrontActionGroup" stepKey="loginToStorefront"> <argument name="Customer" value="$$customer$$"/> @@ -34,6 +35,7 @@ <magentoCLI command="config:set web/secure/use_in_frontend 0" stepKey="dontUseSecureURLsOnStorefront"/> <comment userInput="Adding the comment to replace CliCacheFlushActionGroup action group ('cache:flush' command) for preserving Backward Compatibility" stepKey="flushCache"/> <deleteData createDataKey="customer" stepKey="deleteCustomer"/> + <actionGroup ref="AdminDisableNewsletterActionGroup" stepKey="disableNewsletter" /> </after> <executeJS function="return window.location.host" stepKey="hostname"/> <amOnUrl url="http://{$hostname}/newsletter/manage" stepKey="goToUnsecureNewsletterManageURL"/> diff --git a/app/code/Magento/Newsletter/Test/Mftf/Test/VerifySubscribedNewsletterDisplayedTest.xml b/app/code/Magento/Newsletter/Test/Mftf/Test/VerifySubscribedNewsletterDisplayedTest.xml index 1b56f12049973..fa9f193d8b970 100644 --- a/app/code/Magento/Newsletter/Test/Mftf/Test/VerifySubscribedNewsletterDisplayedTest.xml +++ b/app/code/Magento/Newsletter/Test/Mftf/Test/VerifySubscribedNewsletterDisplayedTest.xml @@ -17,6 +17,7 @@ <description value="Newsletter subscription when user is registered on 2 stores"/> <severity value="MAJOR"/> <testCaseId value="MC-25840"/> + <group value="newsletter"/> </annotations> <before> diff --git a/app/code/Magento/Newsletter/composer.json b/app/code/Magento/Newsletter/composer.json index c477f8ecb64e3..72d91014fd19e 100644 --- a/app/code/Magento/Newsletter/composer.json +++ b/app/code/Magento/Newsletter/composer.json @@ -1,27 +1,28 @@ { "name": "magento/module-newsletter", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.6-p2", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-cms": "*", - "magento/module-customer": "*", - "magento/module-eav": "*", - "magento/module-email": "*", - "magento/module-require-js": "*", - "magento/module-store": "*", - "magento/module-widget": "*", - "magento/module-ui": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-cms": "104.0.*", + "magento/module-customer": "103.0.*", + "magento/module-eav": "102.1.*", + "magento/module-email": "101.1.*", + "magento/module-require-js": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-widget": "101.2.*", + "magento/module-ui": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -31,3 +32,4 @@ } } } + diff --git a/app/code/Magento/NewsletterGraphQl/composer.json b/app/code/Magento/NewsletterGraphQl/composer.json index 3fe7f7aaf289a..aa6f167e0d730 100644 --- a/app/code/Magento/NewsletterGraphQl/composer.json +++ b/app/code/Magento/NewsletterGraphQl/composer.json @@ -1,24 +1,25 @@ { "name": "magento/module-newsletter-graph-ql", "description": "Provides GraphQl functionality for the newsletter subscriptions.", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, - "type": "magento2-module", + "version": "100.4.3", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-customer": "*", - "magento/module-newsletter": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-customer": "103.0.*", + "magento/module-newsletter": "100.4.*", + "magento/module-store": "101.1.*" }, "suggest": { - "magento/module-graph-ql": "*" + "magento/module-graph-ql": "100.4.*" }, - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -28,3 +29,4 @@ } } } + diff --git a/app/code/Magento/OfflinePayments/composer.json b/app/code/Magento/OfflinePayments/composer.json index 09de8b66996ad..b21419adb01e7 100644 --- a/app/code/Magento/OfflinePayments/composer.json +++ b/app/code/Magento/OfflinePayments/composer.json @@ -1,24 +1,25 @@ { "name": "magento/module-offline-payments", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-checkout": "*", - "magento/module-payment": "*", - "magento/module-quote": "*" + "magento/framework": "103.0.*", + "magento/module-checkout": "100.4.*", + "magento/module-payment": "100.4.*", + "magento/module-quote": "101.2.*" }, "suggest": { - "magento/module-config": "*" + "magento/module-config": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -28,3 +29,4 @@ } } } + diff --git a/app/code/Magento/OfflineShipping/composer.json b/app/code/Magento/OfflineShipping/composer.json index 9e75d64075f84..55e6cead59ad9 100644 --- a/app/code/Magento/OfflineShipping/composer.json +++ b/app/code/Magento/OfflineShipping/composer.json @@ -1,31 +1,32 @@ { "name": "magento/module-offline-shipping", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.5", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-config": "*", - "magento/module-directory": "*", - "magento/module-quote": "*", - "magento/module-sales": "*", - "magento/module-sales-rule": "*", - "magento/module-shipping": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-config": "101.2.*", + "magento/module-directory": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-sales": "103.0.*", + "magento/module-sales-rule": "101.2.*", + "magento/module-shipping": "100.4.*", + "magento/module-store": "101.1.*" }, "suggest": { - "magento/module-checkout": "*", - "magento/module-offline-shipping-sample-data": "*" + "magento/module-checkout": "100.4.*", + "magento/module-offline-shipping-sample-data": "Sample Data version: 100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -35,3 +36,4 @@ } } } + diff --git a/app/code/Magento/OpenSearch/composer.json b/app/code/Magento/OpenSearch/composer.json index 1b9e006b9e9b1..5ebdea5086f99 100644 --- a/app/code/Magento/OpenSearch/composer.json +++ b/app/code/Magento/OpenSearch/composer.json @@ -1,21 +1,22 @@ { "name": "magento/module-open-search", "description": "N/A", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-advanced-search": "*", - "magento/module-catalog-search": "*", - "magento/module-elasticsearch": "*", - "magento/module-search": "*", - "magento/module-config": "*", - "opensearch-project/opensearch-php": "^1.0 || ^2.0" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.0", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*", + "magento/module-advanced-search": "100.4.*", + "magento/module-catalog-search": "102.0.*", + "magento/module-elasticsearch": "101.0.*", + "magento/module-search": "101.1.*", + "magento/module-config": "101.2.*", + "opensearch-project/opensearch-php": "^1.0 || ^2.0" + }, "autoload": { "files": [ "registration.php" @@ -25,3 +26,4 @@ } } } + diff --git a/app/code/Magento/PageCache/Controller/Block.php b/app/code/Magento/PageCache/Controller/Block.php index b32866524d9d9..d09384d974a99 100644 --- a/app/code/Magento/PageCache/Controller/Block.php +++ b/app/code/Magento/PageCache/Controller/Block.php @@ -4,12 +4,15 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\PageCache\Controller; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\App\ObjectManager; use Magento\Framework\Serialize\Serializer\Base64Json; use Magento\Framework\Serialize\Serializer\Json; use Magento\Framework\Validator\RegexFactory; -use Magento\Framework\App\ObjectManager; use Magento\Framework\View\Layout\LayoutCacheKeyInterface; abstract class Block extends \Magento\Framework\App\Action\Action @@ -51,13 +54,24 @@ abstract class Block extends \Magento\Framework\App\Action\Action */ private const VALIDATION_RULE_PATTERN = '/^[a-z0-9]+[a-z0-9_]*$/i'; + /** + * @var ScopeConfigInterface + */ + private $config; + + /** + * Handle size system name + */ + private const XML_HANDLES_SIZE = 'system/full_page_cache/handles_size'; + /** * @param \Magento\Framework\App\Action\Context $context * @param \Magento\Framework\Translate\InlineInterface $translateInline - * @param Json $jsonSerializer - * @param Base64Json $base64jsonSerializer - * @param LayoutCacheKeyInterface $layoutCacheKey + * @param Json|null $jsonSerializer + * @param Base64Json|null $base64jsonSerializer + * @param LayoutCacheKeyInterface|null $layoutCacheKey * @param RegexFactory|null $regexValidatorFactory + * @param ScopeConfigInterface|null $scopeConfig */ public function __construct( \Magento\Framework\App\Action\Context $context, @@ -65,7 +79,8 @@ public function __construct( Json $jsonSerializer = null, Base64Json $base64jsonSerializer = null, LayoutCacheKeyInterface $layoutCacheKey = null, - ?RegexFactory $regexValidatorFactory = null + ?RegexFactory $regexValidatorFactory = null, + ScopeConfigInterface $scopeConfig = null ) { parent::__construct($context); $this->translateInline = $translateInline; @@ -77,6 +92,8 @@ public function __construct( ?: ObjectManager::getInstance()->get(LayoutCacheKeyInterface::class); $this->regexValidatorFactory = $regexValidatorFactory ?: ObjectManager::getInstance()->get(RegexFactory::class); + $this->config = $scopeConfig + ?: ObjectManager::getInstance()->get(ScopeConfigInterface::class); } /** @@ -94,6 +111,12 @@ protected function _getBlocks() } $blocks = $this->jsonSerializer->unserialize($blocks); $handles = $this->base64jsonSerializer->unserialize($handles); + + $handlesSize = (int) $this->config->getValue(self::XML_HANDLES_SIZE); + + $handles = ($handlesSize && count($handles) > $handlesSize) + ? array_splice($handles, 0, $handlesSize) : $handles; + if (!$this->validateHandleParam($handles)) { return []; } diff --git a/app/code/Magento/PageCache/composer.json b/app/code/Magento/PageCache/composer.json index 494b5918004d8..8c72e88ed1c63 100644 --- a/app/code/Magento/PageCache/composer.json +++ b/app/code/Magento/PageCache/composer.json @@ -1,22 +1,23 @@ { "name": "magento/module-page-cache", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.6-p3", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-config": "*", - "magento/module-store": "*", - "magento/module-catalog": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-config": "101.2.*", + "magento/module-store": "101.1.*", + "magento/module-catalog": "104.0.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -26,3 +27,4 @@ } } } + diff --git a/app/code/Magento/PageCache/etc/adminhtml/system.xml b/app/code/Magento/PageCache/etc/adminhtml/system.xml index 4ffc20958748d..73c8c913ba63c 100644 --- a/app/code/Magento/PageCache/etc/adminhtml/system.xml +++ b/app/code/Magento/PageCache/etc/adminhtml/system.xml @@ -78,6 +78,10 @@ <comment>Public content cache lifetime in seconds. If field is empty default value 86400 will be saved. </comment> <backend_model>Magento\PageCache\Model\System\Config\Backend\Ttl</backend_model> </field> + <field id="handles_size" type="text" translate="label comment" sortOrder="5" showInDefault="1" canRestore="1"> + <label>Handles params size</label> + <comment>Handles params size. For better performance use handles parameter size between 50 and 100. </comment> + </field> </group> </section> </system> diff --git a/app/code/Magento/PageCache/etc/config.xml b/app/code/Magento/PageCache/etc/config.xml index 8a2412030c6aa..7ec052cb065ea 100644 --- a/app/code/Magento/PageCache/etc/config.xml +++ b/app/code/Magento/PageCache/etc/config.xml @@ -24,6 +24,7 @@ <path>varnish4.vcl</path> </varnish4> <ttl>86400</ttl> + <handles_size>100</handles_size> <caching_application>1</caching_application> <default> <access_list>localhost</access_list> diff --git a/app/code/Magento/PageCache/etc/di.xml b/app/code/Magento/PageCache/etc/di.xml index f70a561342763..acaee4b373b0f 100644 --- a/app/code/Magento/PageCache/etc/di.xml +++ b/app/code/Magento/PageCache/etc/di.xml @@ -35,6 +35,7 @@ <type name="Magento\PageCache\Controller\Block"> <arguments> <argument name="layoutCacheKey" xsi:type="object">Magento\Framework\View\Layout\LayoutCacheKeyInterface</argument> + <argument name="scopeConfig" xsi:type="object">Magento\Framework\App\Config\ScopeConfigInterface\Proxy</argument> </arguments> </type> <type name="Magento\Framework\App\Cache\RuntimeStaleCacheStateModifier"> diff --git a/app/code/Magento/Payment/composer.json b/app/code/Magento/Payment/composer.json index 36cd77ea50d47..99e6bb36489b9 100644 --- a/app/code/Magento/Payment/composer.json +++ b/app/code/Magento/Payment/composer.json @@ -1,26 +1,27 @@ { "name": "magento/module-payment", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.6", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-checkout": "*", - "magento/module-config": "*", - "magento/module-directory": "*", - "magento/module-quote": "*", - "magento/module-sales": "*", - "magento/module-store": "*", - "magento/module-ui": "*", - "magento/module-vault": "*" + "magento/framework": "103.0.*", + "magento/module-checkout": "100.4.*", + "magento/module-config": "101.2.*", + "magento/module-directory": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-sales": "103.0.*", + "magento/module-store": "101.1.*", + "magento/module-ui": "101.2.*", + "magento/module-vault": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -30,3 +31,4 @@ } } } + diff --git a/app/code/Magento/PaymentGraphQl/composer.json b/app/code/Magento/PaymentGraphQl/composer.json index e6ab6fc747768..0315acfc5c734 100644 --- a/app/code/Magento/PaymentGraphQl/composer.json +++ b/app/code/Magento/PaymentGraphQl/composer.json @@ -2,19 +2,20 @@ "name": "magento/module-payment-graph-ql", "description": "N/A", "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "100.4.1", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-payment": "*", - "magento/module-graph-ql": "*" + "magento/framework": "103.0.*", + "magento/module-payment": "100.4.*", + "magento/module-graph-ql": "100.4.*" }, "suggest": { - "magento/module-store-graph-ql": "*" + "magento/module-store-graph-ql": "100.4.*" }, - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -24,3 +25,4 @@ } } } + diff --git a/app/code/Magento/Paypal/Test/Mftf/Test/AdminEnablePaypalExpressCheckoutAndValidateTheGuestCheckoutPaymentWorksWithPaypalExpressTest.xml b/app/code/Magento/Paypal/Test/Mftf/Test/AdminEnablePaypalExpressCheckoutAndValidateTheGuestCheckoutPaymentWorksWithPaypalExpressTest.xml index 33ef8968137b7..e9976a9a566f1 100644 --- a/app/code/Magento/Paypal/Test/Mftf/Test/AdminEnablePaypalExpressCheckoutAndValidateTheGuestCheckoutPaymentWorksWithPaypalExpressTest.xml +++ b/app/code/Magento/Paypal/Test/Mftf/Test/AdminEnablePaypalExpressCheckoutAndValidateTheGuestCheckoutPaymentWorksWithPaypalExpressTest.xml @@ -16,6 +16,7 @@ <severity value="MAJOR"/> <testCaseId value="AC-5662"/> <group value="paypal"/> + <group value="guest_checkout"/> </annotations> <before> <createData entity="SimpleSubCategory" stepKey="simpleCategory"/> diff --git a/app/code/Magento/Paypal/composer.json b/app/code/Magento/Paypal/composer.json index 23ebf05f2f2bc..90e85270d71fd 100644 --- a/app/code/Magento/Paypal/composer.json +++ b/app/code/Magento/Paypal/composer.json @@ -1,39 +1,40 @@ { "name": "magento/module-paypal", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "101.0.6-p2", "require": { "php": "~8.1.0||~8.2.0", "lib-libxml": "*", - "magento/framework": "*", - "magento/module-authorization": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-checkout": "*", - "magento/module-config": "*", - "magento/module-customer": "*", - "magento/module-directory": "*", - "magento/module-eav": "*", - "magento/module-instant-purchase": "*", - "magento/module-payment": "*", - "magento/module-quote": "*", - "magento/module-sales": "*", - "magento/module-store": "*", - "magento/module-tax": "*", - "magento/module-theme": "*", - "magento/module-ui": "*", - "magento/module-vault": "*" + "magento/framework": "103.0.*", + "magento/module-authorization": "100.4.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-checkout": "100.4.*", + "magento/module-config": "101.2.*", + "magento/module-customer": "103.0.*", + "magento/module-directory": "100.4.*", + "magento/module-eav": "102.1.*", + "magento/module-instant-purchase": "100.4.*", + "magento/module-payment": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-sales": "103.0.*", + "magento/module-store": "101.1.*", + "magento/module-tax": "100.4.*", + "magento/module-theme": "101.1.*", + "magento/module-ui": "101.2.*", + "magento/module-vault": "101.2.*" }, "suggest": { - "magento/module-checkout-agreements": "*" + "magento/module-checkout-agreements": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -43,3 +44,4 @@ } } } + diff --git a/app/code/Magento/PaypalCaptcha/composer.json b/app/code/Magento/PaypalCaptcha/composer.json index 8c9feff31e823..f661efcb75bd1 100644 --- a/app/code/Magento/PaypalCaptcha/composer.json +++ b/app/code/Magento/PaypalCaptcha/composer.json @@ -1,24 +1,25 @@ { "name": "magento/module-paypal-captcha", "description": "Provides CAPTCHA validation for PayPal Payflow Pro", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.3", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-captcha": "*", - "magento/module-checkout": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-captcha": "100.4.*", + "magento/module-checkout": "100.4.*", + "magento/module-store": "101.1.*" }, "suggest": { - "magento/module-paypal": "*" + "magento/module-paypal": "101.0.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -28,3 +29,4 @@ } } } + diff --git a/app/code/Magento/PaypalGraphQl/composer.json b/app/code/Magento/PaypalGraphQl/composer.json index ce916276dac97..0104492e2742b 100644 --- a/app/code/Magento/PaypalGraphQl/composer.json +++ b/app/code/Magento/PaypalGraphQl/composer.json @@ -1,30 +1,31 @@ { "name": "magento/module-paypal-graph-ql", "description": "GraphQl support for Paypal", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-quote": "*", - "magento/module-checkout": "*", - "magento/module-paypal": "*", - "magento/module-quote-graph-ql": "*", - "magento/module-sales": "*", - "magento/module-payment": "*", - "magento/module-store": "*", - "magento/module-vault": "*" + "magento/framework": "103.0.*", + "magento/module-quote": "101.2.*", + "magento/module-checkout": "100.4.*", + "magento/module-paypal": "101.0.*", + "magento/module-quote-graph-ql": "100.4.*", + "magento/module-sales": "103.0.*", + "magento/module-payment": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-vault": "101.2.*" }, "suggest": { - "magento/module-graph-ql": "*", - "magento/module-store-graph-ql": "*" + "magento/module-graph-ql": "100.4.*", + "magento/module-store-graph-ql": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -34,3 +35,4 @@ } } } + diff --git a/app/code/Magento/Persistent/Test/Mftf/Test/GuestCheckoutWithEnabledPersistentTest.xml b/app/code/Magento/Persistent/Test/Mftf/Test/GuestCheckoutWithEnabledPersistentTest.xml index 1f944432ac1d1..72c035f24e2d0 100644 --- a/app/code/Magento/Persistent/Test/Mftf/Test/GuestCheckoutWithEnabledPersistentTest.xml +++ b/app/code/Magento/Persistent/Test/Mftf/Test/GuestCheckoutWithEnabledPersistentTest.xml @@ -17,6 +17,7 @@ <severity value="CRITICAL"/> <testCaseId value="MAGETWO-92453"/> <group value="persistent"/> + <group value="guest_checkout"/> </annotations> <before> <createData entity="PersistentConfigEnabled" stepKey="enablePersistent"/> diff --git a/app/code/Magento/Persistent/Test/Mftf/Test/StorefrontVerifyShoppingCartPersistenceUnderLongTermCookieTest.xml b/app/code/Magento/Persistent/Test/Mftf/Test/StorefrontVerifyShoppingCartPersistenceUnderLongTermCookieTest.xml index 159b5b6b9e79b..83814d4900818 100644 --- a/app/code/Magento/Persistent/Test/Mftf/Test/StorefrontVerifyShoppingCartPersistenceUnderLongTermCookieTest.xml +++ b/app/code/Magento/Persistent/Test/Mftf/Test/StorefrontVerifyShoppingCartPersistenceUnderLongTermCookieTest.xml @@ -152,6 +152,7 @@ <actionGroup ref="AssertStorefrontCustomerLogoutSuccessPageActionGroup" stepKey="seeLogoutSuccessPageUrlAfterLogOutJohnSmithCustomerSecondTime"/> <waitForPageLoad stepKey="waitForHomePageLoadAfter5Seconds"/> <waitForText selector="{{StorefrontCMSPageSection.mainContent}}" userInput="CMS homepage content goes here." stepKey="waitForLoadMainContentMessageOnHomePage"/> + <waitForElementVisible selector="{{StorefrontPanelHeaderSection.notYouLink}}" stepKey="waitForNotYouLink"/> <click selector="{{StorefrontPanelHeaderSection.notYouLink}}" stepKey="clickOnNotYouLink" /> <waitForPageLoad stepKey="waitForCustomerLoginPageLoad"/> <actionGroup ref="AssertMiniCartEmptyActionGroup" stepKey="assertMiniCartEmptyAfterJohnDoeSignOut" /> diff --git a/app/code/Magento/Persistent/composer.json b/app/code/Magento/Persistent/composer.json index 5a8ff5d7f3d5f..811cb71d76c2d 100644 --- a/app/code/Magento/Persistent/composer.json +++ b/app/code/Magento/Persistent/composer.json @@ -1,24 +1,25 @@ { "name": "magento/module-persistent", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.6-p3", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-checkout": "*", - "magento/module-cron": "*", - "magento/module-customer": "*", - "magento/module-page-cache": "*", - "magento/module-quote": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-checkout": "100.4.*", + "magento/module-cron": "100.4.*", + "magento/module-customer": "103.0.*", + "magento/module-page-cache": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-store": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -28,3 +29,4 @@ } } } + diff --git a/app/code/Magento/ProductAlert/composer.json b/app/code/Magento/ProductAlert/composer.json index aee755e6a00b0..5ae5834286fc8 100644 --- a/app/code/Magento/ProductAlert/composer.json +++ b/app/code/Magento/ProductAlert/composer.json @@ -1,29 +1,30 @@ { "name": "magento/module-product-alert", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.5", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/framework-bulk": "*", - "magento/module-asynchronous-operations": "*", - "magento/module-authorization": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-customer": "*", - "magento/module-store": "*", - "magento/module-theme": "*" + "magento/framework": "103.0.*", + "magento/framework-bulk": "101.0.*", + "magento/module-asynchronous-operations": "100.4.*", + "magento/module-authorization": "100.4.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-customer": "103.0.*", + "magento/module-store": "101.1.*", + "magento/module-theme": "101.1.*" }, "suggest": { - "magento/module-config": "*" + "magento/module-config": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -33,3 +34,4 @@ } } } + diff --git a/app/code/Magento/ProductVideo/composer.json b/app/code/Magento/ProductVideo/composer.json index 55b8cb5efa14b..2476d5beeb45c 100644 --- a/app/code/Magento/ProductVideo/composer.json +++ b/app/code/Magento/ProductVideo/composer.json @@ -1,29 +1,30 @@ { "name": "magento/module-product-video", "description": "Add Video to Products", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.6", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", + "magento/framework": "103.0.*", "magento/magento-composer-installer": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-eav": "*", - "magento/module-media-storage": "*", - "magento/module-store": "*" + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-eav": "102.1.*", + "magento/module-media-storage": "100.4.*", + "magento/module-store": "101.1.*" }, "suggest": { - "magento/module-customer": "*", - "magento/module-config": "*", - "magento/module-theme": "*" + "magento/module-customer": "103.0.*", + "magento/module-config": "101.2.*", + "magento/module-theme": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -33,3 +34,4 @@ } } } + diff --git a/app/code/Magento/Quote/Model/BillingAddressManagement.php b/app/code/Magento/Quote/Model/BillingAddressManagement.php index 6f8a44dff464c..9762a2a695262 100644 --- a/app/code/Magento/Quote/Model/BillingAddressManagement.php +++ b/app/code/Magento/Quote/Model/BillingAddressManagement.php @@ -3,14 +3,15 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Quote\Model; +use Magento\Framework\App\ObjectManager; use Magento\Framework\Exception\InputException; -use Magento\Quote\Model\Quote\Address\BillingAddressPersister; -use Psr\Log\LoggerInterface as Logger; use Magento\Quote\Api\BillingAddressManagementInterface; -use Magento\Framework\App\ObjectManager; +use Magento\Quote\Api\Data\AddressInterface; +use Psr\Log\LoggerInterface as Logger; /** * Quote billing address write service object. @@ -25,14 +26,14 @@ class BillingAddressManagement implements BillingAddressManagementInterface protected $addressValidator; /** - * Logger. + * Logger object. * * @var Logger */ protected $logger; /** - * Quote repository. + * Quote repository object. * * @var \Magento\Quote\Api\CartRepositoryInterface */ @@ -72,10 +73,14 @@ public function __construct( * @inheritdoc * @SuppressWarnings(PHPMD.NPathComplexity) */ - public function assign($cartId, \Magento\Quote\Api\Data\AddressInterface $address, $useForShipping = false) + public function assign($cartId, AddressInterface $address, $useForShipping = false) { /** @var \Magento\Quote\Model\Quote $quote */ $quote = $this->quoteRepository->getActive($cartId); + + // validate the address + $this->addressValidator->validateWithExistingAddress($quote, $address); + $address->setCustomerId($quote->getCustomerId()); $quote->removeAddress($quote->getBillingAddress()->getId()); $quote->setBillingAddress($address); @@ -104,6 +109,7 @@ public function get($cartId) * * @return \Magento\Quote\Model\ShippingAddressAssignment * @deprecated 101.0.0 + * @see \Magento\Quote\Model\Quote\Address */ private function getShippingAddressAssignment() { diff --git a/app/code/Magento/Quote/Model/QuoteAddressValidator.php b/app/code/Magento/Quote/Model/QuoteAddressValidator.php index f0bc12f7b3a36..5b100d5f48ab2 100644 --- a/app/code/Magento/Quote/Model/QuoteAddressValidator.php +++ b/app/code/Magento/Quote/Model/QuoteAddressValidator.php @@ -3,8 +3,15 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Quote\Model; +use Magento\Customer\Api\AddressRepositoryInterface; +use Magento\Customer\Api\CustomerRepositoryInterface; +use Magento\Customer\Model\Session; +use Magento\Framework\Exception\InputException; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Quote\Api\Data\AddressInterface; use Magento\Quote\Api\Data\CartInterface; @@ -17,35 +24,33 @@ class QuoteAddressValidator { /** - * Address factory. - * - * @var \Magento\Customer\Api\AddressRepositoryInterface + * @var AddressRepositoryInterface */ - protected $addressRepository; + protected AddressRepositoryInterface $addressRepository; /** - * Customer repository. - * - * @var \Magento\Customer\Api\CustomerRepositoryInterface + * @var CustomerRepositoryInterface */ - protected $customerRepository; + protected CustomerRepositoryInterface $customerRepository; /** + * @var Session * @deprecated 101.1.1 This class is not a part of HTML presentation layer and should not use sessions. + * @see Session */ - protected $customerSession; + protected Session $customerSession; /** * Constructs a quote shipping address validator service object. * - * @param \Magento\Customer\Api\AddressRepositoryInterface $addressRepository - * @param \Magento\Customer\Api\CustomerRepositoryInterface $customerRepository Customer repository. - * @param \Magento\Customer\Model\Session $customerSession + * @param AddressRepositoryInterface $addressRepository + * @param CustomerRepositoryInterface $customerRepository Customer repository. + * @param Session $customerSession */ public function __construct( - \Magento\Customer\Api\AddressRepositoryInterface $addressRepository, - \Magento\Customer\Api\CustomerRepositoryInterface $customerRepository, - \Magento\Customer\Model\Session $customerSession + AddressRepositoryInterface $addressRepository, + CustomerRepositoryInterface $customerRepository, + Session $customerSession ) { $this->addressRepository = $addressRepository; $this->customerRepository = $customerRepository; @@ -56,10 +61,10 @@ public function __construct( * Validate address. * * @param AddressInterface $address - * @param int|null $customerId Cart belongs to + * @param int|null $customerId * @return void - * @throws \Magento\Framework\Exception\InputException The specified address belongs to another customer. - * @throws \Magento\Framework\Exception\NoSuchEntityException The specified customer ID or address ID is not valid. + * @throws LocalizedException The specified customer ID or address ID is not valid. + * @throws NoSuchEntityException The specified customer ID or address ID is not valid. */ private function doValidate(AddressInterface $address, ?int $customerId): void { @@ -67,7 +72,7 @@ private function doValidate(AddressInterface $address, ?int $customerId): void if ($customerId) { $customer = $this->customerRepository->getById($customerId); if (!$customer->getId()) { - throw new \Magento\Framework\Exception\NoSuchEntityException( + throw new NoSuchEntityException( __('Invalid customer id %1', $customerId) ); } @@ -76,7 +81,7 @@ private function doValidate(AddressInterface $address, ?int $customerId): void if ($address->getCustomerAddressId()) { //Existing address cannot belong to a guest if (!$customerId) { - throw new \Magento\Framework\Exception\NoSuchEntityException( + throw new NoSuchEntityException( __('Invalid customer address id %1', $address->getCustomerAddressId()) ); } @@ -84,7 +89,7 @@ private function doValidate(AddressInterface $address, ?int $customerId): void try { $this->addressRepository->getById($address->getCustomerAddressId()); } catch (NoSuchEntityException $e) { - throw new \Magento\Framework\Exception\NoSuchEntityException( + throw new NoSuchEntityException( __('Invalid address id %1', $address->getId()) ); } @@ -94,7 +99,7 @@ private function doValidate(AddressInterface $address, ?int $customerId): void return $address->getId(); }, $this->customerRepository->getById($customerId)->getAddresses()); if (!in_array($address->getCustomerAddressId(), $applicableAddressIds)) { - throw new \Magento\Framework\Exception\NoSuchEntityException( + throw new NoSuchEntityException( __('Invalid customer address id %1', $address->getCustomerAddressId()) ); } @@ -104,29 +109,75 @@ private function doValidate(AddressInterface $address, ?int $customerId): void /** * Validates the fields in a specified address data object. * - * @param \Magento\Quote\Api\Data\AddressInterface $addressData The address data object. + * @param AddressInterface $addressData The address data object. * @return bool - * @throws \Magento\Framework\Exception\InputException The specified address belongs to another customer. - * @throws \Magento\Framework\Exception\NoSuchEntityException The specified customer ID or address ID is not valid. + * @throws InputException The specified address belongs to another customer. + * @throws NoSuchEntityException|LocalizedException The specified customer ID or address ID is not valid. */ - public function validate(AddressInterface $addressData) + public function validate(AddressInterface $addressData): bool { $this->doValidate($addressData, $addressData->getCustomerId()); return true; } + /** + * Validate Quest Address for guest user + * + * @param AddressInterface $address + * @param CartInterface $cart + * @return void + * @throws NoSuchEntityException + */ + private function doValidateForGuestQuoteAddress(AddressInterface $address, CartInterface $cart): void + { + //validate guest cart address + if ($address->getId() !== null) { + $old = $cart->getAddressById($address->getId()); + + if ($old === false) { + throw new NoSuchEntityException( + __('Invalid quote address id %1', $address->getId()) + ); + } + } + } + /** * Validate address to be used for cart. * * @param CartInterface $cart * @param AddressInterface $address * @return void - * @throws \Magento\Framework\Exception\InputException The specified address belongs to another customer. - * @throws \Magento\Framework\Exception\NoSuchEntityException The specified customer ID or address ID is not valid. + * @throws InputException The specified address belongs to another customer. + * @throws NoSuchEntityException|LocalizedException The specified customer ID or address ID is not valid. */ public function validateForCart(CartInterface $cart, AddressInterface $address): void { - $this->doValidate($address, $cart->getCustomerIsGuest() ? null : $cart->getCustomer()->getId()); + if ($cart->getCustomerIsGuest()) { + $this->doValidateForGuestQuoteAddress($address, $cart); + } + $this->doValidate($address, $cart->getCustomerIsGuest() ? null : (int) $cart->getCustomer()->getId()); + } + + /** + * Validate address id to be used for cart. + * + * @param CartInterface $cart + * @param AddressInterface $address + * @return void + * @throws NoSuchEntityException The specified customer ID or address ID is not valid. + */ + public function validateWithExistingAddress(CartInterface $cart, AddressInterface $address): void + { + // check if address belongs to quote. + if ($address->getId() !== null) { + $old = $cart->getAddressesCollection()->getItemById($address->getId()); + if ($old === null) { + throw new NoSuchEntityException( + __('Invalid quote address id %1', $address->getId()) + ); + } + } } } diff --git a/app/code/Magento/Quote/composer.json b/app/code/Magento/Quote/composer.json index 1552e71351af7..ee59c631e5982 100644 --- a/app/code/Magento/Quote/composer.json +++ b/app/code/Magento/Quote/composer.json @@ -1,35 +1,36 @@ { "name": "magento/module-quote", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "101.2.6-p1", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-authorization": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-catalog-inventory": "*", - "magento/module-checkout": "*", - "magento/module-customer": "*", - "magento/module-directory": "*", - "magento/module-eav": "*", - "magento/module-payment": "*", - "magento/module-sales": "*", - "magento/module-sales-sequence": "*", - "magento/module-shipping": "*", - "magento/module-store": "*", - "magento/module-tax": "*" + "magento/framework": "103.0.*", + "magento/module-authorization": "100.4.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-inventory": "100.4.*", + "magento/module-checkout": "100.4.*", + "magento/module-customer": "103.0.*", + "magento/module-directory": "100.4.*", + "magento/module-eav": "102.1.*", + "magento/module-payment": "100.4.*", + "magento/module-sales": "103.0.*", + "magento/module-sales-sequence": "100.4.*", + "magento/module-shipping": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-tax": "100.4.*" }, "suggest": { - "magento/module-webapi": "*" + "magento/module-webapi": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -39,3 +40,4 @@ } } } + diff --git a/app/code/Magento/Quote/i18n/en_US.csv b/app/code/Magento/Quote/i18n/en_US.csv index d96c88b7795f7..c8da332f729c8 100644 --- a/app/code/Magento/Quote/i18n/en_US.csv +++ b/app/code/Magento/Quote/i18n/en_US.csv @@ -69,3 +69,4 @@ Carts,Carts "Validated Country Code","Validated Country Code" "Validated Vat Number","Validated Vat Number" "Invalid Quote Item id %1","Invalid Quote Item id %1" +"Invalid quote address id %1","Invalid quote address id %1" diff --git a/app/code/Magento/QuoteAnalytics/composer.json b/app/code/Magento/QuoteAnalytics/composer.json index c9e9254aa7968..6f9a31399dd9e 100644 --- a/app/code/Magento/QuoteAnalytics/composer.json +++ b/app/code/Magento/QuoteAnalytics/composer.json @@ -1,17 +1,18 @@ { "name": "magento/module-quote-analytics", "description": "N/A", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-quote": "*", - "magento/module-analytics": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.5", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*", + "magento/module-quote": "101.2.*", + "magento/module-analytics": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -21,3 +22,4 @@ } } } + diff --git a/app/code/Magento/QuoteBundleOptions/composer.json b/app/code/Magento/QuoteBundleOptions/composer.json index 2412e9d23b329..6beb274f8883c 100644 --- a/app/code/Magento/QuoteBundleOptions/composer.json +++ b/app/code/Magento/QuoteBundleOptions/composer.json @@ -1,16 +1,17 @@ { "name": "magento/module-quote-bundle-options", "description": "Magento module provides data provider for creating buy request for bundle products", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-quote": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.2", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*", + "magento/module-quote": "101.2.*" + }, "autoload": { "files": [ "registration.php" @@ -20,3 +21,4 @@ } } } + diff --git a/app/code/Magento/QuoteConfigurableOptions/composer.json b/app/code/Magento/QuoteConfigurableOptions/composer.json index 35dee93c0b12a..f5e853208c6e6 100644 --- a/app/code/Magento/QuoteConfigurableOptions/composer.json +++ b/app/code/Magento/QuoteConfigurableOptions/composer.json @@ -1,16 +1,17 @@ { "name": "magento/module-quote-configurable-options", "description": "Magento module provides data provider for creating buy request for configurable products", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-quote": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.2", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*", + "magento/module-quote": "101.2.*" + }, "autoload": { "files": [ "registration.php" @@ -20,3 +21,4 @@ } } } + diff --git a/app/code/Magento/QuoteDownloadableLinks/composer.json b/app/code/Magento/QuoteDownloadableLinks/composer.json index 47030735c6081..2224d2b663370 100644 --- a/app/code/Magento/QuoteDownloadableLinks/composer.json +++ b/app/code/Magento/QuoteDownloadableLinks/composer.json @@ -1,16 +1,17 @@ { "name": "magento/module-quote-downloadable-links", "description": "Magento module provides data provider for creating buy request for links of downloadable products", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-quote": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.2", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*", + "magento/module-quote": "101.2.*" + }, "autoload": { "files": [ "registration.php" @@ -20,3 +21,4 @@ } } } + diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/RemoveItemFromCart.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/RemoveItemFromCart.php index 09ef1ad581876..307087391b89d 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/RemoveItemFromCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/RemoveItemFromCart.php @@ -86,6 +86,8 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value $itemId = $processedArgs['input']['cart_item_id']; $storeId = (int)$context->getExtensionAttributes()->getStore()->getId(); + /** Check if the current user is allowed to perform actions with the cart */ + $cart = $this->getCartForUser->execute($maskedCartId, $context->getUserId(), $storeId); try { $this->cartItemRepository->deleteById($cartId, $itemId); @@ -95,7 +97,6 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value throw new GraphQlInputException(__($e->getMessage()), $e); } - $cart = $this->getCartForUser->execute($maskedCartId, $context->getUserId(), $storeId); return [ 'cart' => [ 'model' => $cart, diff --git a/app/code/Magento/QuoteGraphQl/composer.json b/app/code/Magento/QuoteGraphQl/composer.json index 24cb1382634c2..d267c5ec3c219 100644 --- a/app/code/Magento/QuoteGraphQl/composer.json +++ b/app/code/Magento/QuoteGraphQl/composer.json @@ -2,30 +2,31 @@ "name": "magento/module-quote-graph-ql", "description": "N/A", "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "100.4.6-p1", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-quote": "*", - "magento/module-checkout": "*", - "magento/module-catalog": "*", - "magento/module-store": "*", - "magento/module-customer": "*", - "magento/module-customer-graph-ql": "*", - "magento/module-sales": "*", - "magento/module-directory": "*", - "magento/module-graph-ql": "*", - "magento/module-gift-message": "*", - "magento/module-catalog-inventory": "*" + "magento/framework": "103.0.*", + "magento/module-quote": "101.2.*", + "magento/module-checkout": "100.4.*", + "magento/module-catalog": "104.0.*", + "magento/module-store": "101.1.*", + "magento/module-customer": "103.0.*", + "magento/module-customer-graph-ql": "100.4.*", + "magento/module-sales": "103.0.*", + "magento/module-directory": "100.4.*", + "magento/module-graph-ql": "100.4.*", + "magento/module-gift-message": "100.4.*", + "magento/module-catalog-inventory": "100.4.*" }, "suggest": { - "magento/module-graph-ql-cache": "*", - "magento/module-catalog-inventory-graph-ql": "*", - "magento/module-payment-graph-ql": "*" + "magento/module-graph-ql-cache": "100.4.*", + "magento/module-catalog-inventory-graph-ql": "100.4.*", + "magento/module-payment-graph-ql": "100.4.*" }, - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -35,3 +36,4 @@ } } } + diff --git a/app/code/Magento/RelatedProductGraphQl/composer.json b/app/code/Magento/RelatedProductGraphQl/composer.json index 9c03a5b18f644..bce199f696105 100644 --- a/app/code/Magento/RelatedProductGraphQl/composer.json +++ b/app/code/Magento/RelatedProductGraphQl/composer.json @@ -2,19 +2,20 @@ "name": "magento/module-related-product-graph-ql", "description": "N/A", "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "100.4.3", "require": { "php": "~8.1.0||~8.2.0", - "magento/module-catalog": "*", - "magento/module-catalog-graph-ql": "*", - "magento/framework": "*" + "magento/module-catalog": "104.0.*", + "magento/module-catalog-graph-ql": "100.4.*", + "magento/framework": "103.0.*" }, "suggest": { - "magento/module-graph-ql": "*" + "magento/module-graph-ql": "100.4.*" }, - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -24,3 +25,4 @@ } } } + diff --git a/app/code/Magento/ReleaseNotification/composer.json b/app/code/Magento/ReleaseNotification/composer.json index 4ddab4217f32e..a60f5f94535f0 100644 --- a/app/code/Magento/ReleaseNotification/composer.json +++ b/app/code/Magento/ReleaseNotification/composer.json @@ -1,21 +1,22 @@ { "name": "magento/module-release-notification", "description": "N/A", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/module-user": "*", - "magento/module-backend": "*", - "magento/module-ui": "*", - "magento/framework": "*" - }, - "suggest": { - "magento/module-config": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.4", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/module-user": "101.2.*", + "magento/module-backend": "102.0.*", + "magento/module-ui": "101.2.*", + "magento/framework": "103.0.*" + }, + "suggest": { + "magento/module-config": "101.2.*" + }, "autoload": { "files": [ "registration.php" @@ -25,3 +26,4 @@ } } } + diff --git a/app/code/Magento/RemoteStorage/composer.json b/app/code/Magento/RemoteStorage/composer.json index 107ddf6788fe2..2310aa5ce3d32 100644 --- a/app/code/Magento/RemoteStorage/composer.json +++ b/app/code/Magento/RemoteStorage/composer.json @@ -1,31 +1,32 @@ { "name": "magento/module-remote-storage", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "100.4.4", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", + "magento/framework": "103.0.*", "league/flysystem": "^2.4", "league/flysystem-aws-s3-v3": "^2.4" }, "suggest": { - "magento/module-backend": "*", - "magento/module-sitemap": "*", - "magento/module-cms": "*", - "magento/module-downloadable": "*", - "magento/module-catalog": "*", - "magento/module-media-storage": "*", - "magento/module-media-gallery-metadata": "*", - "magento/module-media-gallery-synchronization": "*", - "magento/module-import-export": "*", - "magento/module-catalog-import-export": "*", - "magento/module-downloadable-import-export": "*", + "magento/module-backend": "102.0.*", + "magento/module-sitemap": "100.4.*", + "magento/module-cms": "104.0.*", + "magento/module-downloadable": "100.4.*", + "magento/module-catalog": "104.0.*", + "magento/module-media-storage": "100.4.*", + "magento/module-media-gallery-metadata": "100.4.*", + "magento/module-media-gallery-synchronization": "100.4.*", + "magento/module-import-export": "101.0.*", + "magento/module-catalog-import-export": "101.1.*", + "magento/module-downloadable-import-export": "100.4.*", "predis/predis": "*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -35,3 +36,4 @@ } } } + diff --git a/app/code/Magento/Reports/Test/Mftf/Test/AdminSalesReportsForMultiWebsiteWithDifferentCurrencyTest.xml b/app/code/Magento/Reports/Test/Mftf/Test/AdminSalesReportsForMultiWebsiteWithDifferentCurrencyTest.xml index 1c6a6e1ccf819..c6105dbbb3a7a 100644 --- a/app/code/Magento/Reports/Test/Mftf/Test/AdminSalesReportsForMultiWebsiteWithDifferentCurrencyTest.xml +++ b/app/code/Magento/Reports/Test/Mftf/Test/AdminSalesReportsForMultiWebsiteWithDifferentCurrencyTest.xml @@ -17,6 +17,7 @@ <severity value="MAJOR"/> <testCaseId value="ACP2E-414"/> <group value="combinedReports"/> + <group value="guest_checkout"/> </annotations> <before> <magentoCLI command="config:set {{StorefrontEnableAddStoreCodeToUrls.path}} {{StorefrontEnableAddStoreCodeToUrls.value}}" stepKey="addStoreCodeToUrlEnable"/> diff --git a/app/code/Magento/Reports/Test/Unit/Model/ResourceModel/Order/CollectionTest.php b/app/code/Magento/Reports/Test/Unit/Model/ResourceModel/Order/CollectionTest.php index 9e4f39be6b7dc..50398d42a7019 100644 --- a/app/code/Magento/Reports/Test/Unit/Model/ResourceModel/Order/CollectionTest.php +++ b/app/code/Magento/Reports/Test/Unit/Model/ResourceModel/Order/CollectionTest.php @@ -138,6 +138,10 @@ protected function setUp(): void ->getMock(); $this->timezoneMock = $this->getMockBuilder(TimezoneInterface::class) ->getMock(); + $this->timezoneMock + ->expects($this->any()) + ->method('getConfigTimezone') + ->willReturn('America/Chicago'); $this->configMock = $this->getMockBuilder(Config::class) ->disableOriginalConstructor() ->getMock(); diff --git a/app/code/Magento/Reports/composer.json b/app/code/Magento/Reports/composer.json index 887a9bc1730e3..af0f770ef9548 100644 --- a/app/code/Magento/Reports/composer.json +++ b/app/code/Magento/Reports/composer.json @@ -1,35 +1,36 @@ { "name": "magento/module-reports", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.6-p2", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-catalog-inventory": "*", - "magento/module-cms": "*", - "magento/module-config": "*", - "magento/module-customer": "*", - "magento/module-downloadable": "*", - "magento/module-eav": "*", - "magento/module-quote": "*", - "magento/module-review": "*", - "magento/module-sales": "*", - "magento/module-sales-rule": "*", - "magento/module-store": "*", - "magento/module-tax": "*", - "magento/module-widget": "*", - "magento/module-wishlist": "*", - "magento/module-directory": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-inventory": "100.4.*", + "magento/module-cms": "104.0.*", + "magento/module-config": "101.2.*", + "magento/module-customer": "103.0.*", + "magento/module-downloadable": "100.4.*", + "magento/module-eav": "102.1.*", + "magento/module-quote": "101.2.*", + "magento/module-review": "100.4.*", + "magento/module-sales": "103.0.*", + "magento/module-sales-rule": "101.2.*", + "magento/module-store": "101.1.*", + "magento/module-tax": "100.4.*", + "magento/module-widget": "101.2.*", + "magento/module-wishlist": "101.2.*", + "magento/module-directory": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -39,3 +40,4 @@ } } } + diff --git a/app/code/Magento/RequireJs/composer.json b/app/code/Magento/RequireJs/composer.json index a8dec7db61404..ca3ae524cd9d0 100644 --- a/app/code/Magento/RequireJs/composer.json +++ b/app/code/Magento/RequireJs/composer.json @@ -1,18 +1,19 @@ { "name": "magento/module-require-js", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.2", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*" + "magento/framework": "103.0.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -22,3 +23,4 @@ } } } + diff --git a/app/code/Magento/Review/composer.json b/app/code/Magento/Review/composer.json index e6ef2f416962c..110b3a0509be5 100644 --- a/app/code/Magento/Review/composer.json +++ b/app/code/Magento/Review/composer.json @@ -1,30 +1,31 @@ { "name": "magento/module-review", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.6", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-customer": "*", - "magento/module-eav": "*", - "magento/module-newsletter": "*", - "magento/module-store": "*", - "magento/module-theme": "*", - "magento/module-ui": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-customer": "103.0.*", + "magento/module-eav": "102.1.*", + "magento/module-newsletter": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-theme": "101.1.*", + "magento/module-ui": "101.2.*" }, "suggest": { - "magento/module-cookie": "*", - "magento/module-review-sample-data": "*" + "magento/module-cookie": "100.4.*", + "magento/module-review-sample-data": "Sample Data version: 100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -34,3 +35,4 @@ } } } + diff --git a/app/code/Magento/ReviewAnalytics/composer.json b/app/code/Magento/ReviewAnalytics/composer.json index 7939e3e475668..559ee484e68a3 100644 --- a/app/code/Magento/ReviewAnalytics/composer.json +++ b/app/code/Magento/ReviewAnalytics/composer.json @@ -1,17 +1,18 @@ { "name": "magento/module-review-analytics", "description": "N/A", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-review": "*", - "magento/module-analytics": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.3", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*", + "magento/module-review": "100.4.*", + "magento/module-analytics": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -21,3 +22,4 @@ } } } + diff --git a/app/code/Magento/ReviewGraphQl/composer.json b/app/code/Magento/ReviewGraphQl/composer.json index e31bb53d3dafc..cf74e40853a6a 100644 --- a/app/code/Magento/ReviewGraphQl/composer.json +++ b/app/code/Magento/ReviewGraphQl/composer.json @@ -2,21 +2,22 @@ "name": "magento/module-review-graph-ql", "description": "N/A", "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "100.4.2", "require": { "php": "~8.1.0||~8.2.0", - "magento/module-catalog": "*", - "magento/module-review": "*", - "magento/module-store": "*", - "magento/framework": "*" + "magento/module-catalog": "104.0.*", + "magento/module-review": "100.4.*", + "magento/module-store": "101.1.*", + "magento/framework": "103.0.*" }, "suggest": { - "magento/module-graph-ql": "*", - "magento/module-graph-ql-cache": "*" + "magento/module-graph-ql": "100.4.*", + "magento/module-graph-ql-cache": "100.4.*" }, - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -26,3 +27,4 @@ } } } + diff --git a/app/code/Magento/Robots/composer.json b/app/code/Magento/Robots/composer.json index 37c984daa0089..eddc3169d79f5 100644 --- a/app/code/Magento/Robots/composer.json +++ b/app/code/Magento/Robots/composer.json @@ -1,22 +1,23 @@ { "name": "magento/module-robots", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "101.1.2", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-store": "101.1.*" }, "suggest": { - "magento/module-theme": "*" + "magento/module-theme": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -26,3 +27,4 @@ } } } + diff --git a/app/code/Magento/Rss/composer.json b/app/code/Magento/Rss/composer.json index 436c956a56313..20305590b5a32 100644 --- a/app/code/Magento/Rss/composer.json +++ b/app/code/Magento/Rss/composer.json @@ -1,21 +1,22 @@ { "name": "magento/module-rss", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-customer": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-customer": "103.0.*", + "magento/module-store": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -25,3 +26,4 @@ } } } + diff --git a/app/code/Magento/Rule/composer.json b/app/code/Magento/Rule/composer.json index c39cfa4aa88d6..6983fcca47d76 100644 --- a/app/code/Magento/Rule/composer.json +++ b/app/code/Magento/Rule/composer.json @@ -1,23 +1,24 @@ { "name": "magento/module-rule", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.5", "require": { "php": "~8.1.0||~8.2.0", "lib-libxml": "*", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-eav": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-eav": "102.1.*", + "magento/module-store": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -27,3 +28,4 @@ } } } + diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/LoadBlock.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/LoadBlock.php index 65ccb43879ac6..643ed5445231f 100644 --- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/LoadBlock.php +++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/LoadBlock.php @@ -3,18 +3,26 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Sales\Controller\Adminhtml\Order\Create; -use Magento\Framework\App\Action\HttpGetActionInterface; -use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface; use Magento\Backend\App\Action; +use Magento\Backend\App\Action\Context; use Magento\Backend\Model\View\Result\ForwardFactory; -use Magento\Framework\View\Result\PageFactory; +use Magento\Framework\App\Action\HttpGetActionInterface; +use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface; use Magento\Framework\App\ObjectManager; use Magento\Framework\Controller\Result\RawFactory; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\RegexValidator; +use Magento\Framework\View\Result\PageFactory; use Magento\Sales\Controller\Adminhtml\Order\Create as CreateAction; use Magento\Store\Model\StoreManagerInterface; +/** + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ class LoadBlock extends CreateAction implements HttpPostActionInterface, HttpGetActionInterface { /** @@ -28,13 +36,19 @@ class LoadBlock extends CreateAction implements HttpPostActionInterface, HttpGet private $storeManager; /** - * @param Action\Context $context - * @param \Magento\Catalog\Helper\Product $productHelper - * @param \Magento\Framework\Escaper $escaper + * @var RegexValidator + */ + private RegexValidator $regexValidator; + + /** + * @param Context $context + * @param Product $productHelper + * @param Escaper $escaper * @param PageFactory $resultPageFactory * @param ForwardFactory $resultForwardFactory * @param RawFactory $resultRawFactory * @param StoreManagerInterface|null $storeManager + * @param RegexValidator|null $regexValidator */ public function __construct( Action\Context $context, @@ -43,7 +57,8 @@ public function __construct( PageFactory $resultPageFactory, ForwardFactory $resultForwardFactory, RawFactory $resultRawFactory, - StoreManagerInterface $storeManager = null + StoreManagerInterface $storeManager = null, + RegexValidator $regexValidator = null ) { $this->resultRawFactory = $resultRawFactory; parent::__construct( @@ -55,6 +70,8 @@ public function __construct( ); $this->storeManager = $storeManager ?: ObjectManager::getInstance() ->get(StoreManagerInterface::class); + $this->regexValidator = $regexValidator + ?: ObjectManager::getInstance()->get(RegexValidator::class); } /** @@ -64,6 +81,7 @@ public function __construct( * * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) + * @throws LocalizedException */ public function execute() { @@ -84,6 +102,12 @@ public function execute() $asJson = $request->getParam('json'); $block = $request->getParam('block'); + if ($block && !$this->regexValidator->validateParamRegex($block)) { + throw new LocalizedException( + __('The url has invalid characters. Please correct and try again.') + ); + } + /** @var \Magento\Framework\View\Result\Page $resultPage */ $resultPage = $this->resultPageFactory->create(); if ($asJson) { diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminNavigateToNewOrderPageExistingCustomerActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminNavigateToNewOrderPageExistingCustomerActionGroup.xml new file mode 100644 index 0000000000000..2bb8b8950815a --- /dev/null +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminNavigateToNewOrderPageExistingCustomerActionGroup.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AdminNavigateToNewOrderPageExistingCustomerActionGroup"> + <annotations> + <description>Goes to the Admin Orders grid page. Clicks on 'Create New Order'. Filters the grid for the provided Customer. Clicks on the Customer. Validates that the Page Title is present and correct.</description> + </annotations> + <arguments> + <argument name="customer"/> + </arguments> + + <amOnPage url="{{AdminOrdersPage.url}}" stepKey="navigateToOrderIndexPage"/> + <waitForPageLoad stepKey="waitForIndexPageLoad"/> + <see selector="{{AdminHeaderSection.pageTitle}}" userInput="Orders" stepKey="seeIndexPageTitle"/> + <click selector="{{AdminOrdersGridSection.createNewOrder}}" stepKey="clickCreateNewOrder"/> + <waitForPageLoad stepKey="waitForCustomerGridLoad"/> + + <!--Clear grid filters--> + <conditionalClick selector="{{AdminOrderCustomersGridSection.resetButton}}" dependentSelector="{{AdminOrderCustomersGridSection.resetButton}}" visible="true" stepKey="clearExistingCustomerFilters"/> + <fillField userInput="{{customer.email}}" selector="{{AdminOrderCustomersGridSection.emailInput}}" stepKey="filterEmail"/> + <click selector="{{AdminOrderCustomersGridSection.apply}}" stepKey="applyFilter"/> + <waitForPageLoad stepKey="waitForFilteredCustomerGridLoad"/> + <click selector="{{AdminOrderCustomersGridSection.firstRow}}" stepKey="clickOnCustomer"/> + <waitForPageLoad stepKey="waitForCreateOrderPageLoad"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminNavigateToNewOrderPageNewCustomerActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminNavigateToNewOrderPageNewCustomerActionGroup.xml new file mode 100644 index 0000000000000..438407e2e3468 --- /dev/null +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminNavigateToNewOrderPageNewCustomerActionGroup.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <!--Navigate to create order page (New Order -> Create New Customer)--> + <actionGroup name="AdminNavigateToNewOrderPageNewCustomerActionGroup"> + <annotations> + <description>Goes to the Admin Orders grid page. Clicks on 'Create New Order'. Clicks on 'Create New Customer'.</description> + </annotations> + <amOnPage url="{{AdminOrdersPage.url}}" stepKey="navigateToOrderIndexPage"/> + <waitForPageLoad stepKey="waitForIndexPageLoad"/> + <see selector="{{AdminHeaderSection.pageTitle}}" userInput="Orders" stepKey="seeIndexPageTitle"/> + <click selector="{{AdminOrdersGridSection.createNewOrder}}" stepKey="clickCreateNewOrder"/> + <click selector="{{AdminOrderFormActionSection.CreateNewCustomer}}" stepKey="clickCreateCustomer"/> + <waitForPageLoad stepKey="waitForPageLoaded" /> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminSelectStoreDuringOrderCreationActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminSelectStoreDuringOrderCreationActionGroup.xml new file mode 100644 index 0000000000000..6f2e004b1cc18 --- /dev/null +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminSelectStoreDuringOrderCreationActionGroup.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AdminSelectStoreDuringOrderCreationActionGroup"> + <annotations> + <description>Selects provided Store View.</description> + </annotations> + <arguments> + <argument name="storeView" defaultValue="_defaultStore"/> + </arguments> + + <waitForElementClickable selector="{{AdminOrderStoreScopeTreeSection.storeOption(storeView.name)}}" stepKey="waitForStoreOption" /> + <selectOption selector="{{AdminOrderStoreScopeTreeSection.storeTree}}" userInput="{{storeView.name}}" stepKey="selectStoreView"/> + <waitForPageLoad stepKey="waitForLoad"/> + <see selector="{{AdminHeaderSection.pageTitle}}" userInput="Create New Order" stepKey="seeNewOrderPageTitle"/> + <waitForElementClickable selector="{{OrdersGridSection.addProducts}}" stepKey="waitForAddProductsButton" /> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/CreateOrderInStoreChoosingPaymentMethodActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/CreateOrderInStoreChoosingPaymentMethodActionGroup.xml index 7277a75c9bc73..a1b6c72eb5038 100644 --- a/app/code/Magento/Sales/Test/Mftf/ActionGroup/CreateOrderInStoreChoosingPaymentMethodActionGroup.xml +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/CreateOrderInStoreChoosingPaymentMethodActionGroup.xml @@ -21,7 +21,9 @@ <amOnPage stepKey="navigateToNewOrderPage" url="{{AdminOrderCreatePage.url}}"/> <click stepKey="chooseCustomer" selector="{{AdminOrdersGridSection.customerInOrdersSection(customer.firstname)}}"/> <waitForPageLoad stepKey="waitForStoresPageOpened"/> - <click stepKey="chooseStore" selector="{{AdminOrderStoreScopeTreeSection.storeForOrder(storeView.name)}}"/> + <waitForElementClickable selector="{{AdminOrderStoreScopeTreeSection.storeForOrder(storeView.name)}}" stepKey="waitForStoreClickable" /> + <selectOption selector="{{AdminOrderStoreScopeTreeSection.storeTree}}" userInput="{{storeView.name}}" stepKey="chooseStore"/> + <waitForPageLoad stepKey="waitForLoadAfterSelectingOption"/> <scrollToTopOfPage stepKey="scrollToTop"/> <click selector="{{OrdersGridSection.addProducts}}" stepKey="clickOnAddProducts"/> <waitForPageLoad stepKey="waitForProductsListForOrder"/> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AddConfigurableProductToOrderFromShoppingCartTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AddConfigurableProductToOrderFromShoppingCartTest.xml index 76b5e2ad81bd1..f27f80830d7e0 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AddConfigurableProductToOrderFromShoppingCartTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AddConfigurableProductToOrderFromShoppingCartTest.xml @@ -18,6 +18,7 @@ <testCaseId value="MC-16008"/> <group value="sales"/> <group value="mtf_migrated"/> + <group value="guest_checkout"/> </annotations> <before> <!-- Create customer --> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminCorrectnessInvoicedItemInBundleProductTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminCorrectnessInvoicedItemInBundleProductTest.xml index 3a87c5fe6338a..c1ef6c7915db6 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminCorrectnessInvoicedItemInBundleProductTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminCorrectnessInvoicedItemInBundleProductTest.xml @@ -18,6 +18,7 @@ <testCaseId value="MC-11059"/> <useCaseId value="MC-10969"/> <group value="sales"/> + <group value="guest_checkout"/> </annotations> <before> <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminOrdersMultiSelectActionAppliedToUncheckedNewlyCreatedOrdersTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminOrdersMultiSelectActionAppliedToUncheckedNewlyCreatedOrdersTest.xml index 2299a12546849..d1e2b8ab19aab 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminOrdersMultiSelectActionAppliedToUncheckedNewlyCreatedOrdersTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminOrdersMultiSelectActionAppliedToUncheckedNewlyCreatedOrdersTest.xml @@ -17,6 +17,7 @@ <severity value="MAJOR"/> <testCaseId value="MC-36889"/> <group value="multiselect"/> + <group value="guest_checkout"/> </annotations> <before> <!--Set default flat rate shipping method settings--> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/CheckXSSVulnerabilityDuringOrderCreationTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/CheckXSSVulnerabilityDuringOrderCreationTest.xml index 528b6b61f4842..9b75abf096a2c 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/CheckXSSVulnerabilityDuringOrderCreationTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/CheckXSSVulnerabilityDuringOrderCreationTest.xml @@ -17,6 +17,7 @@ <severity value="CRITICAL"/> <testCaseId value="MC-11438"/> <group value="sales"/> + <group value="guest_checkout"/> </annotations> <before> <!-- Create product --> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/CloseOrderInCaseItRefundedPartiallyTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/CloseOrderInCaseItRefundedPartiallyTest.xml index 337ef3889c12b..f6cf3bbb658d1 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/CloseOrderInCaseItRefundedPartiallyTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/CloseOrderInCaseItRefundedPartiallyTest.xml @@ -11,6 +11,7 @@ <test name="CloseOrderInCaseItRefundedPartiallyTest"> <annotations> <group value="Sales"/> + <group value="guest_checkout"/> <stories value="Close order"/> <title value="Close order in case it refunded partially"/> <description value="Place order, generate invoice and do partial credit memos, it refunded partially and sales status should be closed"/> @@ -30,6 +31,8 @@ <actionGroup ref="CreateConfigurableProductActionGroup" stepKey="createProduct"> <argument name="category" value="$$createCategory$$"/> </actionGroup> + <!--Enable flat rate shipping--> + <magentoCLI command="config:set {{EnableFlatRateConfigData.path}} {{EnableFlatRateConfigData.value}}" stepKey="enableFlatRate"/> </before> <!-- add simple product into cart --> <actionGroup ref="StorefrontOpenHomePageActionGroup" stepKey="goToFrontPage"/> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml index f1f83dd8be3a9..53fad2147ac44 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml @@ -17,6 +17,7 @@ <severity value="MAJOR"/> <testCaseId value="MAGETWO-92924"/> <group value="sales"/> + <group value="guest_checkout"/> </annotations> <before> <createData entity="_defaultCategory" stepKey="createCategory"/> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/EndToEndB2CAdminTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/EndToEndB2CAdminTest.xml index 31e833f0eab7a..c10e5be07faf4 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/EndToEndB2CAdminTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/EndToEndB2CAdminTest.xml @@ -31,13 +31,18 @@ <!--Prerequisites--> <!--Create store view to ensure multiple store views--> <comment userInput="Create prerequisite store view" stepKey="createStoreViewComment" before="createStoreView"/> - <actionGroup ref="AdminCreateStoreViewActionGroup" stepKey="createStoreView" before="navigateToNewOrderPage"/> + <actionGroup ref="AdminCreateStoreViewActionGroup" stepKey="createStoreView" before="navigateToNewOrderPage"> + <argument name="customStore" value="customStore"/> + </actionGroup> <!--Admin creates order--> <comment userInput="Admin creates order" stepKey="adminCreateOrderComment" before="navigateToNewOrderPage"/> <actionGroup ref="NavigateToNewOrderPageNewCustomerActionGroup" stepKey="navigateToNewOrderPage" after="deleteCategory"/> - <actionGroup ref="CheckRequiredFieldsNewOrderFormActionGroup" stepKey="checkRequiredFieldsNewOrder" after="navigateToNewOrderPage"/> + <actionGroup ref="AdminSelectStoreDuringOrderCreationActionGroup" stepKey="selectCustomStore" after="navigateToNewOrderPage"> + <argument name="storeView" value="customStore"/> + </actionGroup> + <actionGroup ref="CheckRequiredFieldsNewOrderFormActionGroup" stepKey="checkRequiredFieldsNewOrder" after="selectCustomStore"/> <scrollToTopOfPage stepKey="scrollToTopOfOrderFormPage" after="checkRequiredFieldsNewOrder"/> <actionGroup ref="AddSimpleProductToOrderActionGroup" stepKey="addSimpleProductToOrder" after="scrollToTopOfOrderFormPage"> <argument name="product" value="SimpleProduct"/> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/StorefrontCreateOrderWithDifferentAddressesTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/StorefrontCreateOrderWithDifferentAddressesTest.xml index bf45d3305dcfd..5959fd22469a6 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/StorefrontCreateOrderWithDifferentAddressesTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/StorefrontCreateOrderWithDifferentAddressesTest.xml @@ -13,17 +13,19 @@ <description value="Place order on Store Front with manually filled billing address state and selected shipping address state. Check that billing address show correct state on Admin Order View page"/> <severity value="MINOR"/> <group value="sales"/> + <group value="guest_checkout"/> </annotations> <before> + <magentoCLI command="config:set checkout/options/enable_guest_checkout_login 1" stepKey="EnablingGuestCheckoutLogin"/> <createData entity="SimpleProduct2" stepKey="createSimpleProduct"/> <createData entity="Customer_UK_US" stepKey="createCustomer"/> </before> <after> <deleteData createDataKey="createCustomer" stepKey="deleteCreateCustomer"/> <deleteData createDataKey="createSimpleProduct" stepKey="deleteSimpleProduct"/> - <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> <actionGroup ref="StorefrontCustomerLogoutActionGroup" stepKey="logoutCustomer"/> + <magentoCLI command="config:set checkout/options/enable_guest_checkout_login 0" stepKey="DisablingGuestCheckoutLogin"/> </after> <actionGroup ref="OpenStoreFrontProductPageActionGroup" stepKey="navigateToProductPage"> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/StorefrontCreateOrdersWithMoveJSCodeBottomTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/StorefrontCreateOrdersWithMoveJSCodeBottomTest.xml index 8fd659a5bd6ac..8e518f2b1e230 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/StorefrontCreateOrdersWithMoveJSCodeBottomTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/StorefrontCreateOrdersWithMoveJSCodeBottomTest.xml @@ -14,6 +14,7 @@ <title value="Create a product and orders with set 'Move Js code to the bottom' to 'Yes'."/> <description value="Create a product and orders with a set 'Move JS code to the bottom of the page' to 'Yes' for registered customers and guests."/> <severity value="MAJOR"/> + <group value="guest_checkout"/> </annotations> <before> <magentoCLI command="config:set {{StorefrontEnableMoveJsCodeBottom.path}} {{StorefrontEnableMoveJsCodeBottom.value}}" stepKey="moveJsCodeBottomEnable"/> diff --git a/app/code/Magento/Sales/composer.json b/app/code/Magento/Sales/composer.json index e0ea835d63087..c1f1064a94245 100644 --- a/app/code/Magento/Sales/composer.json +++ b/app/code/Magento/Sales/composer.json @@ -1,45 +1,46 @@ { "name": "magento/module-sales", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "103.0.6-p3", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-authorization": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-bundle": "*", - "magento/module-catalog-inventory": "*", - "magento/module-checkout": "*", - "magento/module-config": "*", - "magento/module-customer": "*", - "magento/module-directory": "*", - "magento/module-eav": "*", - "magento/module-gift-message": "*", - "magento/module-media-storage": "*", - "magento/module-payment": "*", - "magento/module-quote": "*", - "magento/module-reports": "*", - "magento/module-sales-rule": "*", - "magento/module-sales-sequence": "*", - "magento/module-shipping": "*", - "magento/module-store": "*", - "magento/module-tax": "*", - "magento/module-theme": "*", - "magento/module-ui": "*", - "magento/module-widget": "*", - "magento/module-wishlist": "*" + "magento/framework": "103.0.*", + "magento/module-authorization": "100.4.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-bundle": "101.0.*", + "magento/module-catalog-inventory": "100.4.*", + "magento/module-checkout": "100.4.*", + "magento/module-config": "101.2.*", + "magento/module-customer": "103.0.*", + "magento/module-directory": "100.4.*", + "magento/module-eav": "102.1.*", + "magento/module-gift-message": "100.4.*", + "magento/module-media-storage": "100.4.*", + "magento/module-payment": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-reports": "100.4.*", + "magento/module-sales-rule": "101.2.*", + "magento/module-sales-sequence": "100.4.*", + "magento/module-shipping": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-tax": "100.4.*", + "magento/module-theme": "101.1.*", + "magento/module-ui": "101.2.*", + "magento/module-widget": "101.2.*", + "magento/module-wishlist": "101.2.*" }, "suggest": { - "magento/module-sales-sample-data": "*" + "magento/module-sales-sample-data": "Sample Data version: 100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -49,3 +50,4 @@ } } } + diff --git a/app/code/Magento/SalesAnalytics/composer.json b/app/code/Magento/SalesAnalytics/composer.json index 943fbf3e7ef07..de43645eb649d 100644 --- a/app/code/Magento/SalesAnalytics/composer.json +++ b/app/code/Magento/SalesAnalytics/composer.json @@ -1,17 +1,18 @@ { "name": "magento/module-sales-analytics", "description": "N/A", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-sales": "*", - "magento/module-analytics": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.3", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*", + "magento/module-sales": "103.0.*", + "magento/module-analytics": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -21,3 +22,4 @@ } } } + diff --git a/app/code/Magento/SalesGraphQl/composer.json b/app/code/Magento/SalesGraphQl/composer.json index 7215c8fefa8eb..11a25c9d67a66 100644 --- a/app/code/Magento/SalesGraphQl/composer.json +++ b/app/code/Magento/SalesGraphQl/composer.json @@ -2,21 +2,22 @@ "name": "magento/module-sales-graph-ql", "description": "N/A", "type": "magento2-module", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-sales": "*", - "magento/module-store": "*", - "magento/module-catalog": "*", - "magento/module-tax": "*", - "magento/module-quote": "*", - "magento/module-graph-ql": "*", - "magento/module-shipping": "*" - }, "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.6", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*", + "magento/module-sales": "103.0.*", + "magento/module-store": "101.1.*", + "magento/module-catalog": "104.0.*", + "magento/module-tax": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-graph-ql": "100.4.*", + "magento/module-shipping": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -26,3 +27,4 @@ } } } + diff --git a/app/code/Magento/SalesInventory/composer.json b/app/code/Magento/SalesInventory/composer.json index ad11c308042fb..c5cd0f756f26f 100644 --- a/app/code/Magento/SalesInventory/composer.json +++ b/app/code/Magento/SalesInventory/composer.json @@ -1,22 +1,23 @@ { "name": "magento/module-sales-inventory", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.3", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-catalog": "*", - "magento/module-catalog-inventory": "*", - "magento/module-sales": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-inventory": "100.4.*", + "magento/module-sales": "103.0.*", + "magento/module-store": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -26,3 +27,4 @@ } } } + diff --git a/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/StorefrontApplyDiscountCodeActionGroup.xml b/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/StorefrontApplyDiscountCodeActionGroup.xml index 5607512c862b3..9d6630463e444 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/StorefrontApplyDiscountCodeActionGroup.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/StorefrontApplyDiscountCodeActionGroup.xml @@ -15,7 +15,7 @@ <conditionalClick selector="{{DiscountSection.DiscountTab}}" dependentSelector="{{DiscountSection.CouponInput}}" visible="false" stepKey="clickToAddDiscount"/> <fillField selector="{{DiscountSection.DiscountInput}}" userInput="{{discountCode}}" stepKey="fillFieldDiscountCode"/> <click selector="{{DiscountSection.ApplyCodeBtn}}" stepKey="clickToApplyDiscount"/> - <waitForElementVisible selector="{{DiscountSection.DiscountVerificationMsg}}" time="30" stepKey="waitForDiscountToBeAdded"/> + <waitForElementVisible selector="{{DiscountSection.DiscountVerificationMsg}}" stepKey="waitForDiscountToBeAdded"/> <see selector="{{DiscountSection.DiscountVerificationMsg}}" userInput="Your coupon was successfully applied" stepKey="assertDiscountApplyMessage"/> </actionGroup> </actionGroups> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCartRulesAppliedForProductInCartTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCartRulesAppliedForProductInCartTest.xml index 18b9636e62e2b..024ac0885de59 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCartRulesAppliedForProductInCartTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCartRulesAppliedForProductInCartTest.xml @@ -18,6 +18,7 @@ <testCaseId value="MAGETWO-96722"/> <useCaseId value="MAGETWO-96410"/> <group value="SalesRule"/> + <group value="guest_checkout"/> </annotations> <before> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCouponCodeCheckTimesUsedAfterGuestOrderTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCouponCodeCheckTimesUsedAfterGuestOrderTest.xml index 17420271d7775..92f2dc59b7ecd 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCouponCodeCheckTimesUsedAfterGuestOrderTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCouponCodeCheckTimesUsedAfterGuestOrderTest.xml @@ -18,6 +18,7 @@ <testCaseId value="AC-2843"/> <useCaseId value="ACP2E-690"/> <group value="salesRule"/> + <group value="guest_checkout"/> </annotations> <before> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontAutoGeneratedCouponCodeTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontAutoGeneratedCouponCodeTest.xml index 986aa6130eae6..b58fdea05bef6 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontAutoGeneratedCouponCodeTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontAutoGeneratedCouponCodeTest.xml @@ -18,6 +18,7 @@ <severity value="BLOCKER"/> <testCaseId value="MAGETWO-59323"/> <group value="salesRule"/> + <group value="guest_checkout"/> </annotations> <before> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontZeroPriceProductWithDiscountUsingCartPriceRuleTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontZeroPriceProductWithDiscountUsingCartPriceRuleTest.xml index 2a989f3d0e54c..94f714175d803 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontZeroPriceProductWithDiscountUsingCartPriceRuleTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontZeroPriceProductWithDiscountUsingCartPriceRuleTest.xml @@ -17,6 +17,7 @@ <testCaseId value="MC-42802"/> <useCaseId value="MC-42612"/> <group value="SalesRule"/> + <group value="guest_checkout"/> </annotations> <before> <magentoCLI command="config:set {{EnableFlatRateConfigData.path}} {{EnableFlatRateConfigData.value}}" stepKey="enableFlatRate"/> diff --git a/app/code/Magento/SalesRule/composer.json b/app/code/Magento/SalesRule/composer.json index 89fd6cb64b89b..f4204a1aecd8d 100644 --- a/app/code/Magento/SalesRule/composer.json +++ b/app/code/Magento/SalesRule/composer.json @@ -1,42 +1,43 @@ { "name": "magento/module-sales-rule", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "101.2.6-p2", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/framework-bulk": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-catalog-rule": "*", - "magento/module-config": "*", - "magento/module-customer": "*", - "magento/module-directory": "*", - "magento/module-eav": "*", - "magento/module-payment": "*", - "magento/module-quote": "*", - "magento/module-reports": "*", - "magento/module-rule": "*", - "magento/module-sales": "*", - "magento/module-shipping": "*", - "magento/module-store": "*", - "magento/module-ui": "*", - "magento/module-widget": "*", - "magento/module-captcha": "*", - "magento/module-checkout": "*", - "magento/module-authorization": "*", - "magento/module-asynchronous-operations": "*" + "magento/framework": "103.0.*", + "magento/framework-bulk": "101.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-rule": "101.2.*", + "magento/module-config": "101.2.*", + "magento/module-customer": "103.0.*", + "magento/module-directory": "100.4.*", + "magento/module-eav": "102.1.*", + "magento/module-payment": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-reports": "100.4.*", + "magento/module-rule": "100.4.*", + "magento/module-sales": "103.0.*", + "magento/module-shipping": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-ui": "101.2.*", + "magento/module-widget": "101.2.*", + "magento/module-captcha": "100.4.*", + "magento/module-checkout": "100.4.*", + "magento/module-authorization": "100.4.*", + "magento/module-asynchronous-operations": "100.4.*" }, "suggest": { - "magento/module-sales-rule-sample-data": "*" + "magento/module-sales-rule-sample-data": "Sample Data version: 100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -46,3 +47,4 @@ } } } + diff --git a/app/code/Magento/SalesSequence/composer.json b/app/code/Magento/SalesSequence/composer.json index c00dae5f5b62d..1e61a432fa3d0 100644 --- a/app/code/Magento/SalesSequence/composer.json +++ b/app/code/Magento/SalesSequence/composer.json @@ -1,18 +1,19 @@ { "name": "magento/module-sales-sequence", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.3", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*" + "magento/framework": "103.0.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -22,3 +23,4 @@ } } } + diff --git a/app/code/Magento/SampleData/composer.json b/app/code/Magento/SampleData/composer.json index bccca4714b922..66529ba4f1139 100644 --- a/app/code/Magento/SampleData/composer.json +++ b/app/code/Magento/SampleData/composer.json @@ -1,21 +1,22 @@ { "name": "magento/module-sample-data", "description": "Sample Data fixtures", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*" + "magento/framework": "103.0.*" }, "suggest": { - "magento/sample-data-media": "*" + "magento/sample-data-media": "Sample Data version: 100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "cli_commands.php", @@ -26,3 +27,4 @@ } } } + diff --git a/app/code/Magento/Search/composer.json b/app/code/Magento/Search/composer.json index ed0779d3d7698..0938f0653e1de 100644 --- a/app/code/Magento/Search/composer.json +++ b/app/code/Magento/Search/composer.json @@ -1,23 +1,24 @@ { "name": "magento/module-search", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "101.1.6", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog-search": "*", - "magento/module-reports": "*", - "magento/module-store": "*", - "magento/module-ui": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog-search": "102.0.*", + "magento/module-reports": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-ui": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -27,3 +28,4 @@ } } } + diff --git a/app/code/Magento/Security/composer.json b/app/code/Magento/Security/composer.json index 0a2910591517d..80347cfaaec8d 100644 --- a/app/code/Magento/Security/composer.json +++ b/app/code/Magento/Security/composer.json @@ -1,25 +1,26 @@ { "name": "magento/module-security", "description": "Security management module", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.6", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-config": "*", - "magento/module-backend": "*", - "magento/module-store": "*", - "magento/module-user": "*" + "magento/framework": "103.0.*", + "magento/module-config": "101.2.*", + "magento/module-backend": "102.0.*", + "magento/module-store": "101.1.*", + "magento/module-user": "101.2.*" }, "suggest": { - "magento/module-customer": "*" + "magento/module-customer": "103.0.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -29,3 +30,4 @@ } } } + diff --git a/app/code/Magento/SendFriend/composer.json b/app/code/Magento/SendFriend/composer.json index 7ffc4924f2495..fa1943b15df51 100644 --- a/app/code/Magento/SendFriend/composer.json +++ b/app/code/Magento/SendFriend/composer.json @@ -1,24 +1,25 @@ { "name": "magento/module-send-friend", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-catalog": "*", - "magento/module-customer": "*", - "magento/module-store": "*", - "magento/module-captcha": "*", - "magento/module-authorization": "*", - "magento/module-theme": "*" + "magento/framework": "103.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-customer": "103.0.*", + "magento/module-store": "101.1.*", + "magento/module-captcha": "100.4.*", + "magento/module-authorization": "100.4.*", + "magento/module-theme": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -28,3 +29,4 @@ } } } + diff --git a/app/code/Magento/SendFriendGraphQl/composer.json b/app/code/Magento/SendFriendGraphQl/composer.json index 6abc8d6baf202..51a6bb18e73af 100644 --- a/app/code/Magento/SendFriendGraphQl/composer.json +++ b/app/code/Magento/SendFriendGraphQl/composer.json @@ -2,17 +2,18 @@ "name": "magento/module-send-friend-graph-ql", "description": "N/A", "type": "magento2-module", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-catalog": "*", - "magento/module-send-friend": "*", - "magento/module-graph-ql": "*" - }, "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.2", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-send-friend": "100.4.*", + "magento/module-graph-ql": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -22,3 +23,4 @@ } } } + diff --git a/app/code/Magento/Shipping/Test/Mftf/Test/AdminCreateOrderCustomStoreShippingMethodTableRatesTest.xml b/app/code/Magento/Shipping/Test/Mftf/Test/AdminCreateOrderCustomStoreShippingMethodTableRatesTest.xml index acbe29dd14e76..aa2f8c20ce7a4 100644 --- a/app/code/Magento/Shipping/Test/Mftf/Test/AdminCreateOrderCustomStoreShippingMethodTableRatesTest.xml +++ b/app/code/Magento/Shipping/Test/Mftf/Test/AdminCreateOrderCustomStoreShippingMethodTableRatesTest.xml @@ -89,9 +89,11 @@ <argument name="website" value="{{customWebsite.name}}"/> </actionGroup> <actionGroup ref="SaveProductFormActionGroup" stepKey="saveProduct"/> - <!--Create order--> - <actionGroup ref="NavigateToNewOrderPageExistingCustomerActionGroup" stepKey="navigateToNewOrderWithExistingCustomer"> + <!--Create order--> + <actionGroup ref="AdminNavigateToNewOrderPageExistingCustomerActionGroup" stepKey="navigateToNewOrderWithExistingCustomer"> <argument name="customer" value="$$createCustomer$$"/> + </actionGroup> + <actionGroup ref="AdminSelectStoreDuringOrderCreationActionGroup" stepKey="selectCustomStore"> <argument name="storeView" value="customStore"/> </actionGroup> <actionGroup ref="AddSimpleProductToOrderActionGroup" stepKey="addSimpleProductToTheOrder"> diff --git a/app/code/Magento/Shipping/Test/Mftf/Test/StorefrontAssertShippingPricesPresentAfterApplyingCartRuleTest.xml b/app/code/Magento/Shipping/Test/Mftf/Test/StorefrontAssertShippingPricesPresentAfterApplyingCartRuleTest.xml index 53e91fbdb24c1..a6496c54b95c4 100644 --- a/app/code/Magento/Shipping/Test/Mftf/Test/StorefrontAssertShippingPricesPresentAfterApplyingCartRuleTest.xml +++ b/app/code/Magento/Shipping/Test/Mftf/Test/StorefrontAssertShippingPricesPresentAfterApplyingCartRuleTest.xml @@ -19,6 +19,7 @@ <useCaseId value="MC-24379"/> <group value="shipping"/> <group value="SalesRule"/> + <group value="guest_checkout"/> </annotations> <before> <createData entity="SimpleProduct2" stepKey="createProduct"/> diff --git a/app/code/Magento/Shipping/composer.json b/app/code/Magento/Shipping/composer.json index 0347a97e755d7..0de25c0382550 100644 --- a/app/code/Magento/Shipping/composer.json +++ b/app/code/Magento/Shipping/composer.json @@ -1,37 +1,38 @@ { "name": "magento/module-shipping", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.6-p3", "require": { "php": "~8.1.0||~8.2.0", "ext-gd": "*", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-catalog-inventory": "*", - "magento/module-contact": "*", - "magento/module-customer": "*", - "magento/module-directory": "*", - "magento/module-payment": "*", - "magento/module-quote": "*", - "magento/module-sales": "*", - "magento/module-store": "*", - "magento/module-tax": "*", - "magento/module-ui": "*", - "magento/module-user": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-inventory": "100.4.*", + "magento/module-contact": "100.4.*", + "magento/module-customer": "103.0.*", + "magento/module-directory": "100.4.*", + "magento/module-payment": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-sales": "103.0.*", + "magento/module-store": "101.1.*", + "magento/module-tax": "100.4.*", + "magento/module-ui": "101.2.*", + "magento/module-user": "101.2.*" }, "suggest": { - "magento/module-fedex": "*", - "magento/module-ups": "*", - "magento/module-config": "*" + "magento/module-fedex": "100.4.*", + "magento/module-ups": "100.4.*", + "magento/module-config": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -41,3 +42,4 @@ } } } + diff --git a/app/code/Magento/Sitemap/composer.json b/app/code/Magento/Sitemap/composer.json index 3323abebdebac..1eb477d18b991 100644 --- a/app/code/Magento/Sitemap/composer.json +++ b/app/code/Magento/Sitemap/composer.json @@ -1,30 +1,31 @@ { "name": "magento/module-sitemap", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.5", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-catalog-url-rewrite": "*", - "magento/module-cms": "*", - "magento/module-config": "*", - "magento/module-eav": "*", - "magento/module-media-storage": "*", - "magento/module-robots": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-url-rewrite": "100.4.*", + "magento/module-cms": "104.0.*", + "magento/module-config": "101.2.*", + "magento/module-eav": "102.1.*", + "magento/module-media-storage": "100.4.*", + "magento/module-robots": "101.1.*", + "magento/module-store": "101.1.*" }, "suggest": { - "magento/module-config": "*" + "magento/module-config": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -34,3 +35,4 @@ } } } + diff --git a/app/code/Magento/Store/composer.json b/app/code/Magento/Store/composer.json index c4c195e45c138..f9504158c6ff5 100644 --- a/app/code/Magento/Store/composer.json +++ b/app/code/Magento/Store/composer.json @@ -1,29 +1,30 @@ { "name": "magento/module-store", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "101.1.6", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-catalog": "*", - "magento/module-config": "*", - "magento/module-directory": "*", - "magento/module-media-storage": "*", - "magento/module-ui": "*", - "magento/module-customer": "*", - "magento/module-authorization": "*", - "magento/module-backend": "*" + "magento/framework": "103.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-config": "101.2.*", + "magento/module-directory": "100.4.*", + "magento/module-media-storage": "100.4.*", + "magento/module-ui": "101.2.*", + "magento/module-customer": "103.0.*", + "magento/module-authorization": "100.4.*", + "magento/module-backend": "102.0.*" }, "suggest": { - "magento/module-deploy": "*" + "magento/module-deploy": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -33,3 +34,4 @@ } } } + diff --git a/app/code/Magento/StoreGraphQl/composer.json b/app/code/Magento/StoreGraphQl/composer.json index f5fd98fdc4cae..7407ac0d5ce1e 100644 --- a/app/code/Magento/StoreGraphQl/composer.json +++ b/app/code/Magento/StoreGraphQl/composer.json @@ -2,17 +2,18 @@ "name": "magento/module-store-graph-ql", "description": "N/A", "type": "magento2-module", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-store": "*", - "magento/module-graph-ql": "*", - "magento/module-graph-ql-cache": "*" - }, "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.4", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*", + "magento/module-store": "101.1.*", + "magento/module-graph-ql": "100.4.*", + "magento/module-graph-ql-cache": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -22,3 +23,4 @@ } } } + diff --git a/app/code/Magento/Swagger/composer.json b/app/code/Magento/Swagger/composer.json index fb357a01e22c0..bd65f6fdc1cb7 100644 --- a/app/code/Magento/Swagger/composer.json +++ b/app/code/Magento/Swagger/composer.json @@ -1,18 +1,19 @@ { "name": "magento/module-swagger", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.5", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*" + "magento/framework": "103.0.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -22,3 +23,4 @@ } } } + diff --git a/app/code/Magento/SwaggerWebapi/composer.json b/app/code/Magento/SwaggerWebapi/composer.json index ea2b06ed681f9..d5f79df9c7356 100644 --- a/app/code/Magento/SwaggerWebapi/composer.json +++ b/app/code/Magento/SwaggerWebapi/composer.json @@ -1,19 +1,20 @@ { "name": "magento/module-swagger-webapi", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.2", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-swagger": "*" + "magento/framework": "103.0.*", + "magento/module-swagger": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -23,3 +24,4 @@ } } } + diff --git a/app/code/Magento/SwaggerWebapiAsync/composer.json b/app/code/Magento/SwaggerWebapiAsync/composer.json index b02a3e031b1ae..eeee8bbd4560b 100644 --- a/app/code/Magento/SwaggerWebapiAsync/composer.json +++ b/app/code/Magento/SwaggerWebapiAsync/composer.json @@ -1,22 +1,23 @@ { "name": "magento/module-swagger-webapi-async", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.2", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-swagger": "*" + "magento/framework": "103.0.*", + "magento/module-swagger": "100.4.*" }, "suggest": { - "magento/module-config": "*" + "magento/module-config": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -26,3 +27,4 @@ } } } + diff --git a/app/code/Magento/Swatches/Test/Unit/Block/Product/Renderer/Listing/ConfigurableTest.php b/app/code/Magento/Swatches/Test/Unit/Block/Product/Renderer/Listing/ConfigurableTest.php index 9e7e62e0a077f..7f58641d4d227 100644 --- a/app/code/Magento/Swatches/Test/Unit/Block/Product/Renderer/Listing/ConfigurableTest.php +++ b/app/code/Magento/Swatches/Test/Unit/Block/Product/Renderer/Listing/ConfigurableTest.php @@ -23,8 +23,11 @@ use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\App\Request\Http; use Magento\Framework\App\RequestInterface; +use Magento\Framework\App\DeploymentConfig; +use Magento\Framework\Config\ConfigOptionsListConstants; use Magento\Framework\Json\EncoderInterface; use Magento\Framework\Model\AbstractModel; +use Magento\Framework\ObjectManagerInterface; use Magento\Framework\Pricing\PriceCurrencyInterface; use Magento\Framework\Pricing\PriceInfo\Base; use Magento\Framework\Stdlib\ArrayUtils; @@ -95,8 +98,23 @@ class ConfigurableTest extends TestCase */ private $request; + /** + * @var ObjectManagerInterface|MockObject + */ + private $objectManagerMock; + + /** + * @var DeploymentConfig|MockObject + */ + private $deploymentConfig; + protected function setUp(): void { + $this->objectManagerMock = $this->getMockBuilder(ObjectManagerInterface::class) + ->disableOriginalConstructor() + ->onlyMethods(['get']) + ->getMockForAbstractClass(); + \Magento\Framework\App\ObjectManager::setInstance($this->objectManagerMock); $this->arrayUtils = $this->createMock(ArrayUtils::class); $this->jsonEncoder = $this->getMockForAbstractClass(EncoderInterface::class); $this->helper = $this->createMock(Data::class); @@ -127,6 +145,16 @@ protected function setUp(): void $context = $this->getContextMock(); $context->method('getRequest')->willReturn($this->request); + $this->deploymentConfig = $this->createPartialMock( + DeploymentConfig::class, + ['get'] + ); + + $this->deploymentConfig->expects($this->any()) + ->method('get') + ->with(ConfigOptionsListConstants::CONFIG_PATH_CRYPT_KEY) + ->willReturn('448198e08af35844a42d3c93c1ef4e03'); + $objectManagerHelper = new ObjectManager($this); $this->configurable = $objectManagerHelper->getObject( ConfigurableRenderer::class, @@ -146,7 +174,7 @@ protected function setUp(): void 'configurableAttributeData' => $this->configurableAttributeData, 'data' => [], 'variationPrices' => $this->variationPricesMock, - 'customerSession' => $customerSession, + 'customerSession' => $customerSession ] ); } @@ -308,6 +336,10 @@ public function testGetCacheKey() ->willReturn($configurableAttributes); $this->request->method('toArray')->willReturn($requestParams); + $this->objectManagerMock->expects($this->any()) + ->method('get') + ->with(DeploymentConfig::class) + ->willReturn($this->deploymentConfig); $this->assertStringContainsString( sha1(json_encode(['color' => 59, 'size' => 1])), $this->configurable->getCacheKey() diff --git a/app/code/Magento/Swatches/composer.json b/app/code/Magento/Swatches/composer.json index 91f3d59016f7a..1795321b5a38c 100644 --- a/app/code/Magento/Swatches/composer.json +++ b/app/code/Magento/Swatches/composer.json @@ -1,32 +1,33 @@ { "name": "magento/module-swatches", "description": "Add Swatches to Products", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.6-p1", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-config": "*", - "magento/module-configurable-product": "*", - "magento/module-customer": "*", - "magento/module-eav": "*", - "magento/module-page-cache": "*", - "magento/module-media-storage": "*", - "magento/module-store": "*", - "magento/module-theme": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-config": "101.2.*", + "magento/module-configurable-product": "100.4.*", + "magento/module-customer": "103.0.*", + "magento/module-eav": "102.1.*", + "magento/module-page-cache": "100.4.*", + "magento/module-media-storage": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-theme": "101.1.*" }, "suggest": { - "magento/module-layered-navigation": "*", - "magento/module-swatches-sample-data": "*" + "magento/module-layered-navigation": "100.4.*", + "magento/module-swatches-sample-data": "Sample Data version: 100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -36,3 +37,4 @@ } } } + diff --git a/app/code/Magento/SwatchesGraphQl/composer.json b/app/code/Magento/SwatchesGraphQl/composer.json index 744ed81435c34..04f891ccf2805 100644 --- a/app/code/Magento/SwatchesGraphQl/composer.json +++ b/app/code/Magento/SwatchesGraphQl/composer.json @@ -2,20 +2,21 @@ "name": "magento/module-swatches-graph-ql", "description": "N/A", "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "100.4.4", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-swatches": "*", - "magento/module-catalog": "*", - "magento/module-catalog-graph-ql": "*" + "magento/framework": "103.0.*", + "magento/module-swatches": "100.4.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-graph-ql": "100.4.*" }, "suggest": { - "magento/module-configurable-product-graph-ql": "*" + "magento/module-configurable-product-graph-ql": "100.4.*" }, - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -25,3 +26,4 @@ } } } + diff --git a/app/code/Magento/SwatchesLayeredNavigation/composer.json b/app/code/Magento/SwatchesLayeredNavigation/composer.json index ff8ea5715b944..caa4a3ec723e6 100644 --- a/app/code/Magento/SwatchesLayeredNavigation/composer.json +++ b/app/code/Magento/SwatchesLayeredNavigation/composer.json @@ -1,19 +1,20 @@ { "name": "magento/module-swatches-layered-navigation", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.2", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", + "magento/framework": "103.0.*", "magento/magento-composer-installer": "*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -23,3 +24,4 @@ } } } + diff --git a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCheckoutTest/StorefrontTaxQuoteCheckoutGuestSimpleTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCheckoutTest/StorefrontTaxQuoteCheckoutGuestSimpleTest.xml index e8daba77c9264..30726ef6ac696 100644 --- a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCheckoutTest/StorefrontTaxQuoteCheckoutGuestSimpleTest.xml +++ b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCheckoutTest/StorefrontTaxQuoteCheckoutGuestSimpleTest.xml @@ -16,6 +16,7 @@ <severity value="CRITICAL"/> <testCaseId value="MC-258"/> <group value="Tax"/> + <group value="guest_checkout"/> </annotations> <before> <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> diff --git a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCheckoutTest/StorefrontTaxQuoteCheckoutGuestVirtualTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCheckoutTest/StorefrontTaxQuoteCheckoutGuestVirtualTest.xml index 52acb40a5b023..02b66624315b2 100644 --- a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCheckoutTest/StorefrontTaxQuoteCheckoutGuestVirtualTest.xml +++ b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCheckoutTest/StorefrontTaxQuoteCheckoutGuestVirtualTest.xml @@ -17,6 +17,7 @@ <testCaseId value="MC-255"/> <group value="Tax"/> <group value="cloud_smoke"/> + <group value="guest_checkout"/> </annotations> <before> <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> diff --git a/app/code/Magento/Tax/composer.json b/app/code/Magento/Tax/composer.json index fd7a5a075998e..9e3df1a7479c8 100644 --- a/app/code/Magento/Tax/composer.json +++ b/app/code/Magento/Tax/composer.json @@ -1,35 +1,36 @@ { "name": "magento/module-tax", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.6-p2", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-checkout": "*", - "magento/module-config": "*", - "magento/module-customer": "*", - "magento/module-directory": "*", - "magento/module-eav": "*", - "magento/module-page-cache": "*", - "magento/module-quote": "*", - "magento/module-reports": "*", - "magento/module-sales": "*", - "magento/module-shipping": "*", - "magento/module-store": "*", - "magento/module-ui": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-checkout": "100.4.*", + "magento/module-config": "101.2.*", + "magento/module-customer": "103.0.*", + "magento/module-directory": "100.4.*", + "magento/module-eav": "102.1.*", + "magento/module-page-cache": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-reports": "100.4.*", + "magento/module-sales": "103.0.*", + "magento/module-shipping": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-ui": "101.2.*" }, "suggest": { - "magento/module-tax-sample-data": "*" + "magento/module-tax-sample-data": "Sample Data version: 100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -39,3 +40,4 @@ } } } + diff --git a/app/code/Magento/TaxGraphQl/composer.json b/app/code/Magento/TaxGraphQl/composer.json index fef2c01d039da..ed7fd41912bb3 100644 --- a/app/code/Magento/TaxGraphQl/composer.json +++ b/app/code/Magento/TaxGraphQl/composer.json @@ -2,18 +2,19 @@ "name": "magento/module-tax-graph-ql", "description": "N/A", "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "100.4.2", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*" + "magento/framework": "103.0.*" }, "suggest": { - "magento/module-tax": "*", - "magento/module-catalog-graph-ql": "*" + "magento/module-tax": "100.4.*", + "magento/module-catalog-graph-ql": "100.4.*" }, - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -23,3 +24,4 @@ } } } + diff --git a/app/code/Magento/TaxImportExport/composer.json b/app/code/Magento/TaxImportExport/composer.json index 2f7d6737e9596..216ee652d7a44 100644 --- a/app/code/Magento/TaxImportExport/composer.json +++ b/app/code/Magento/TaxImportExport/composer.json @@ -1,23 +1,24 @@ { "name": "magento/module-tax-import-export", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.5", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-directory": "*", - "magento/module-store": "*", - "magento/module-tax": "*", - "magento/module-ui": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-directory": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-tax": "100.4.*", + "magento/module-ui": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -27,3 +28,4 @@ } } } + diff --git a/app/code/Magento/Theme/Test/Mftf/Test/StoreFrontCheckNotificationMessageContainerTest.xml b/app/code/Magento/Theme/Test/Mftf/Test/StoreFrontCheckNotificationMessageContainerTest.xml index 76cfaa461dfaa..d4630b4d2b740 100644 --- a/app/code/Magento/Theme/Test/Mftf/Test/StoreFrontCheckNotificationMessageContainerTest.xml +++ b/app/code/Magento/Theme/Test/Mftf/Test/StoreFrontCheckNotificationMessageContainerTest.xml @@ -17,6 +17,7 @@ <severity value="AVERAGE"/> <testCaseId value="MC-37339"/> <group value="Theme"/> + <group value="guest_checkout"/> </annotations> <before> <magentoCLI command="config:set {{EnableFlatRateConfigData.path}} {{EnableFlatRateConfigData.value}}" stepKey="enableFlatRate"/> diff --git a/app/code/Magento/Theme/composer.json b/app/code/Magento/Theme/composer.json index 658a856db5fc2..0d48ba669ba5d 100644 --- a/app/code/Magento/Theme/composer.json +++ b/app/code/Magento/Theme/composer.json @@ -1,33 +1,34 @@ { "name": "magento/module-theme", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "101.1.6-p2", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-cms": "*", - "magento/module-config": "*", - "magento/module-customer": "*", - "magento/module-eav": "*", - "magento/module-media-storage": "*", - "magento/module-require-js": "*", - "magento/module-store": "*", - "magento/module-ui": "*", - "magento/module-widget": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-cms": "104.0.*", + "magento/module-config": "101.2.*", + "magento/module-customer": "103.0.*", + "magento/module-eav": "102.1.*", + "magento/module-media-storage": "100.4.*", + "magento/module-require-js": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-ui": "101.2.*", + "magento/module-widget": "101.2.*" }, "suggest": { - "magento/module-theme-sample-data": "*", - "magento/module-deploy": "*", - "magento/module-directory": "*" + "magento/module-theme-sample-data": "Sample Data version: 100.4.*", + "magento/module-deploy": "100.4.*", + "magento/module-directory": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -37,3 +38,4 @@ } } } + diff --git a/app/code/Magento/ThemeGraphQl/composer.json b/app/code/Magento/ThemeGraphQl/composer.json index 6b4ee27e2f11b..83579945c7993 100644 --- a/app/code/Magento/ThemeGraphQl/composer.json +++ b/app/code/Magento/ThemeGraphQl/composer.json @@ -2,17 +2,18 @@ "name": "magento/module-theme-graph-ql", "description": "N/A", "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "100.4.3", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*" + "magento/framework": "103.0.*" }, "suggest": { - "magento/module-store-graph-ql": "*" + "magento/module-store-graph-ql": "100.4.*" }, - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -22,3 +23,4 @@ } } } + diff --git a/app/code/Magento/Translation/composer.json b/app/code/Magento/Translation/composer.json index 791bfbd7b1a73..eefc79cab6449 100644 --- a/app/code/Magento/Translation/composer.json +++ b/app/code/Magento/Translation/composer.json @@ -1,26 +1,27 @@ { "name": "magento/module-translation", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.6", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-developer": "*", - "magento/module-store": "*", - "magento/module-theme": "*", - "magento/module-deploy": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-developer": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-theme": "101.1.*", + "magento/module-deploy": "100.4.*" }, "suggest": { - "magento/module-deploy": "*" + "magento/module-deploy": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -30,3 +31,4 @@ } } } + diff --git a/app/code/Magento/Ui/composer.json b/app/code/Magento/Ui/composer.json index d25e69071a791..09ca895acd3a5 100644 --- a/app/code/Magento/Ui/composer.json +++ b/app/code/Magento/Ui/composer.json @@ -1,26 +1,27 @@ { "name": "magento/module-ui", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "101.2.6", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-authorization": "*", - "magento/module-backend": "*", - "magento/module-eav": "*", - "magento/module-store": "*", - "magento/module-user": "*" + "magento/framework": "103.0.*", + "magento/module-authorization": "100.4.*", + "magento/module-backend": "102.0.*", + "magento/module-eav": "102.1.*", + "magento/module-store": "101.1.*", + "magento/module-user": "101.2.*" }, "suggest": { - "magento/module-config": "*" + "magento/module-config": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -30,3 +31,4 @@ } } } + diff --git a/app/code/Magento/Ups/composer.json b/app/code/Magento/Ups/composer.json index dc80330fa3828..6292a52d88b30 100644 --- a/app/code/Magento/Ups/composer.json +++ b/app/code/Magento/Ups/composer.json @@ -1,28 +1,29 @@ { "name": "magento/module-ups", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.6", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog-inventory": "*", - "magento/module-directory": "*", - "magento/module-quote": "*", - "magento/module-sales": "*", - "magento/module-shipping": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog-inventory": "100.4.*", + "magento/module-directory": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-sales": "103.0.*", + "magento/module-shipping": "100.4.*", + "magento/module-store": "101.1.*" }, "suggest": { - "magento/module-config": "*" + "magento/module-config": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -32,3 +33,4 @@ } } } + diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Data/UrlRewriteData.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Data/UrlRewriteData.xml index 3692e82072afc..404fcb52c91e9 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Data/UrlRewriteData.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Data/UrlRewriteData.xml @@ -28,7 +28,7 @@ </entity> <entity name="customPermanentUrlRewrite" type="urlRewrite"> <data key="request_path" unique="prefix">wishlist</data> - <data key="target_path">https://marketplace.magento.com/</data> + <data key="target_path">https://commercemarketplace.adobe.com/</data> <data key="redirect_type">301</data> <data key="redirect_type_label">Permanent (301)</data> <data key="store_id">1</data> @@ -37,7 +37,7 @@ </entity> <entity name="customTemporaryUrlRewrite" type="urlRewrite"> <data key="request_path" unique="prefix">wishlist</data> - <data key="target_path">https://marketplace.magento.com/</data> + <data key="target_path">https://commercemarketplace.adobe.com/</data> <data key="redirect_type">302</data> <data key="redirect_type_label">Temporary (302)</data> <data key="store_id">1</data> diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateCustomURLRewritesPermanentTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateCustomURLRewritesPermanentTest.xml index 16916426167b8..99f02c6df9440 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateCustomURLRewritesPermanentTest.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateCustomURLRewritesPermanentTest.xml @@ -16,6 +16,7 @@ <severity value="CRITICAL"/> <group value="urlRewrite"/> <group value="mtf_migrated"/> + <group value="cloud"/> </annotations> <before> diff --git a/app/code/Magento/UrlRewrite/composer.json b/app/code/Magento/UrlRewrite/composer.json index 7dafa8b8f4d07..9fd5a3d141d3c 100644 --- a/app/code/Magento/UrlRewrite/composer.json +++ b/app/code/Magento/UrlRewrite/composer.json @@ -1,25 +1,26 @@ { "name": "magento/module-url-rewrite", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "102.0.5-p3", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-catalog-url-rewrite": "*", - "magento/module-cms": "*", - "magento/module-cms-url-rewrite": "*", - "magento/module-store": "*", - "magento/module-ui": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-url-rewrite": "100.4.*", + "magento/module-cms": "104.0.*", + "magento/module-cms-url-rewrite": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-ui": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -29,3 +30,4 @@ } } } + diff --git a/app/code/Magento/UrlRewriteGraphQl/composer.json b/app/code/Magento/UrlRewriteGraphQl/composer.json index 5e19ae73f5781..8487448711b77 100644 --- a/app/code/Magento/UrlRewriteGraphQl/composer.json +++ b/app/code/Magento/UrlRewriteGraphQl/composer.json @@ -2,18 +2,19 @@ "name": "magento/module-url-rewrite-graph-ql", "description": "N/A", "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "100.4.5", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-url-rewrite": "*" + "magento/framework": "103.0.*", + "magento/module-url-rewrite": "102.0.*" }, "suggest": { - "magento/module-graph-ql": "*" + "magento/module-graph-ql": "100.4.*" }, - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -23,3 +24,4 @@ } } } + diff --git a/app/code/Magento/User/composer.json b/app/code/Magento/User/composer.json index 0fa7ec8250c94..46e20d0ca80f2 100644 --- a/app/code/Magento/User/composer.json +++ b/app/code/Magento/User/composer.json @@ -1,25 +1,26 @@ { "name": "magento/module-user", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "101.2.6", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-authorization": "*", - "magento/module-backend": "*", - "magento/module-email": "*", - "magento/module-integration": "*", - "magento/module-security": "*", - "magento/module-store": "*", - "magento/module-ui": "*" + "magento/framework": "103.0.*", + "magento/module-authorization": "100.4.*", + "magento/module-backend": "102.0.*", + "magento/module-email": "101.1.*", + "magento/module-integration": "100.4.*", + "magento/module-security": "100.4.*", + "magento/module-store": "101.1.*", + "magento/module-ui": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -29,3 +30,4 @@ } } } + diff --git a/app/code/Magento/Usps/Helper/Data.php b/app/code/Magento/Usps/Helper/Data.php index 4a03f2aa815f1..42a3266c5738a 100644 --- a/app/code/Magento/Usps/Helper/Data.php +++ b/app/code/Magento/Usps/Helper/Data.php @@ -8,12 +8,12 @@ use Magento\Framework\App\Helper\AbstractHelper; /** - * Usps data helper + * USPS Allowed shipping methods */ class Data extends AbstractHelper { /** - * Available shipping methods + * Shipping methods * * @var array */ @@ -36,6 +36,14 @@ class Data extends AbstractHelper 'usps_INT_14', // First-Class Mail International Large Envelope 'usps_INT_16', // Priority Mail International Small Flat Rate Box 'usps_INT_20', // Priority Mail International Small Flat Rate Envelope + '1058', // Ground Advantageâ„¢ + '4058', // Ground Advantageâ„¢ HAZMAT + '6058', // Ground Advantageâ„¢ Parcel locker + '2058', // Ground Advantageâ„¢ Hold for pickup + '4096', // Ground Advantageâ„¢ Cubic HAZMAT + '1096', // Ground Advantageâ„¢ Cubic + '2096', // Ground Advantageâ„¢ Cubic Hold for pickup + '6096', // Ground Advantageâ„¢ Cubic Parcel locker ]; /** diff --git a/app/code/Magento/Usps/Model/Carrier.php b/app/code/Magento/Usps/Model/Carrier.php index 5d56cb5bc96ee..7c51331b1bf25 100644 --- a/app/code/Magento/Usps/Model/Carrier.php +++ b/app/code/Magento/Usps/Model/Carrier.php @@ -815,6 +815,14 @@ public function getCode($type, $code = '') 'INT_24' => __('Priority Mail International DVD Flat Rate priced box'), 'INT_25' => __('Priority Mail International Large Video Flat Rate priced box'), 'INT_27' => __('Priority Mail Express International Padded Flat Rate Envelope'), + '1058' => __('Ground Advantageâ„¢'), + '4058' => __('Ground Advantageâ„¢ HAZMAT'), + '6058' => __('Ground Advantageâ„¢ Parcel locker'), + '2058' => __('Ground Advantageâ„¢ Hold for pickup'), + '4096' => __('Ground Advantageâ„¢ Cubic HAZMAT'), + '1096' => __('Ground Advantageâ„¢ Cubic'), + '2096' => __('Ground Advantageâ„¢ Cubic Hold for pickup'), + '6096' => __('Ground Advantageâ„¢ Cubic Parcel locker') ], 'service_to_code' => [ '0_FCLE' => 'First Class', @@ -891,6 +899,14 @@ public function getCode($type, $code = '') 'INT_24' => 'Priority', 'INT_25' => 'Priority', 'INT_27' => 'Priority Express', + '1058' => 'Ground Advantage', + '4058' => 'Ground Advantage', + '6058' => 'Ground Advantage', + '2058' => 'Ground Advantage', + '4096' => 'Ground Advantage', + '1096' => 'Ground Advantage', + '2096' => 'Ground Advantage', + '6096' => 'Ground Advantage', ], 'method_to_code' => [ 'First-Class Mail Large Envelope' => '0_FCLE', diff --git a/app/code/Magento/Usps/Model/Config/Backend/UspsUrl.php b/app/code/Magento/Usps/Model/Config/Backend/UspsUrl.php new file mode 100644 index 0000000000000..17cdcc83961bd --- /dev/null +++ b/app/code/Magento/Usps/Model/Config/Backend/UspsUrl.php @@ -0,0 +1,76 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\Usps\Model\Config\Backend; + +use Magento\Framework\App\Cache\TypeListInterface; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\App\Config\Value; +use Magento\Framework\Data\Collection\AbstractDb; +use Magento\Framework\Exception\ValidatorException; +use Magento\Framework\Model\Context; +use Magento\Framework\Model\ResourceModel\AbstractResource; +use Magento\Framework\Registry; +use Magento\Framework\Validator\Url; + +/** + * Represents a config URL that may point to a USPS endpoint + * + * @SuppressWarnings(PHPMD.Superglobals) + */ +class UspsUrl extends Value +{ + /** + * @var Url + */ + private Url $url; + + /** + * @param Context $context + * @param Registry $registry + * @param ScopeConfigInterface $config + * @param TypeListInterface $cacheTypeList + * @param Url $url + * @param AbstractResource|null $resource + * @param AbstractDb|null $resourceCollection + * @param array $data + */ + public function __construct( + Context $context, + Registry $registry, + ScopeConfigInterface $config, + TypeListInterface $cacheTypeList, + Url $url, + AbstractResource $resource = null, + AbstractDb $resourceCollection = null, + array $data = [] + ) { + $this->url = $url; + parent::__construct($context, $registry, $config, $cacheTypeList, $resource, $resourceCollection, $data); + } + + /** + * @inheritdoc + * + * @throws ValidatorException + */ + public function beforeSave() + { + $isValid = $this->url->isValid($this->getValue()); + if ($isValid) { + // phpcs:ignore Magento2.Functions.DiscouragedFunction + $host = parse_url((string)$this->getValue(), \PHP_URL_HOST); + + if (!empty($host) && !preg_match("/(?:.+\.|^)usps|shippingapis\.com$/i", $host)) { + throw new ValidatorException(__('USPS API endpoint URL\'s must use usps.com or shippingapis.com')); + } + } + + return parent::beforeSave(); + } +} diff --git a/app/code/Magento/Usps/Setup/Patch/Data/UpdateAllowedMethods.php b/app/code/Magento/Usps/Setup/Patch/Data/UpdateAllowedMethods.php index 913819a5c1ac4..7e3dd1b74e829 100644 --- a/app/code/Magento/Usps/Setup/Patch/Data/UpdateAllowedMethods.php +++ b/app/code/Magento/Usps/Setup/Patch/Data/UpdateAllowedMethods.php @@ -11,8 +11,7 @@ use Magento\Framework\Setup\Patch\PatchVersionInterface; /** - * Class UpdateAllowedMethods - * @package Magento\Usps\Setup\Patch + * Updates all methods on the configuration */ class UpdateAllowedMethods implements DataPatchInterface, PatchVersionInterface { @@ -23,6 +22,7 @@ class UpdateAllowedMethods implements DataPatchInterface, PatchVersionInterface /** * UpdateAllowedMethods constructor. + * * @param \Magento\Framework\Setup\ModuleDataSetupInterface $moduleDataSetup */ public function __construct( @@ -32,7 +32,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function apply() { @@ -113,10 +113,11 @@ public function apply() $connection->update($configDataTable, ['value' => $newValue], $whereConfigId); } } + return $this; } /** - * {@inheritdoc} + * @inheritdoc */ public static function getDependencies() { @@ -124,7 +125,7 @@ public static function getDependencies() } /** - * {@inheritdoc} + * @inheritdoc */ public static function getVersion() { @@ -132,7 +133,7 @@ public static function getVersion() } /** - * {@inheritdoc} + * @inheritdoc */ public function getAliases() { diff --git a/app/code/Magento/Usps/Test/Unit/Helper/DataTest.php b/app/code/Magento/Usps/Test/Unit/Helper/DataTest.php index 2581385f1812c..a0077864ad256 100644 --- a/app/code/Magento/Usps/Test/Unit/Helper/DataTest.php +++ b/app/code/Magento/Usps/Test/Unit/Helper/DataTest.php @@ -70,6 +70,14 @@ public function shippingMethodDataProvider() ['usps_INT_14'], // First-Class Mail International Large Envelope ['usps_INT_16'], // Priority Mail International Small Flat Rate Box ['usps_INT_20'], // Priority Mail International Small Flat Rate Envelope + ['1058'], // Ground Advantageâ„¢ + ['4058'], // Ground Advantageâ„¢ HAZMAT + ['6058'], // Ground Advantageâ„¢ Parcel locker + ['2058'], // Ground Advantageâ„¢ Hold for pickup + ['4096'], // Ground Advantageâ„¢ Cubic HAZMAT + ['1096'], // Ground Advantageâ„¢ Cubic + ['2096'], // Ground Advantageâ„¢ Cubic Hold for pickup + ['6096'], // Ground Advantageâ„¢ Cubic Parcel locker ]; } } diff --git a/app/code/Magento/Usps/Test/Unit/Model/CarrierTest.php b/app/code/Magento/Usps/Test/Unit/Model/CarrierTest.php index f3b7cfc8c8a8b..e6da5fc05605c 100644 --- a/app/code/Magento/Usps/Test/Unit/Model/CarrierTest.php +++ b/app/code/Magento/Usps/Test/Unit/Model/CarrierTest.php @@ -90,7 +90,8 @@ class CarrierTest extends TestCase private $config = [ 'carriers/usps/allowed_methods' => '0_FCLE,0_FCL,0_FCP,1,2,3,4,6,7,13,16,17,22,23,25,27,28,33,' . '34,35,36,37,42,43,53,55,56,57,61,INT_1,INT_2,INT_4,INT_6,INT_7,INT_8,INT_9,INT_10,INT_11,' . - 'INT_12,INT_13,INT_14,INT_15,INT_16,INT_20,INT_26', + 'INT_12,INT_13,INT_14,INT_15,INT_16,INT_20,INT_26,1058,4058,6058,2058,4096,' . + '1096,2096,6096', 'carriers/usps/showmethod' => 1, 'carriers/usps/debug' => 1, 'carriers/usps/userid' => 'test', diff --git a/app/code/Magento/Usps/Test/Unit/Model/Config/Backend/UspsUrlTest.php b/app/code/Magento/Usps/Test/Unit/Model/Config/Backend/UspsUrlTest.php new file mode 100644 index 0000000000000..da18923366c55 --- /dev/null +++ b/app/code/Magento/Usps/Test/Unit/Model/Config/Backend/UspsUrlTest.php @@ -0,0 +1,124 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\Usps\Test\Unit\Model\Config\Backend; + +use Magento\Framework\App\Cache\TypeListInterface; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\Data\Collection\AbstractDb; +use Magento\Framework\Event\ManagerInterface; +use Magento\Framework\Exception\ValidatorException; +use Magento\Framework\Model\Context; +use Magento\Framework\Model\ResourceModel\AbstractResource; +use Magento\Framework\Registry; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\Framework\Validator\Url; +use Magento\Usps\Model\Config\Backend\UspsUrl; +use PHPUnit\Framework\TestCase; + +/** + * Verify behavior of UspsUrl backend type + * + * @SuppressWarnings(PHPMD.Superglobals) + */ +class UspsUrlTest extends TestCase +{ + /** + * @var UspsUrl + */ + private $urlConfig; + + /** + * @var Url + */ + private $url; + + /** + * @var Context + */ + private $contextMock; + + protected function setUp(): void + { + $objectManager = new ObjectManager($this); + + $this->contextMock = $this->createMock(Context::class); + $registry = $this->createMock(Registry::class); + $config = $this->createMock(ScopeConfigInterface::class); + $cacheTypeList = $this->createMock(TypeListInterface::class); + $this->url = $this->createMock(Url::class); + $resource = $this->createMock(AbstractResource::class); + $resourceCollection = $this->createMock(AbstractDb::class); + $eventManagerMock = $this->getMockForAbstractClass(ManagerInterface::class); + + $eventManagerMock->expects($this->any())->method('dispatch'); + $this->contextMock->expects($this->any())->method('getEventDispatcher')->willReturn($eventManagerMock); + + $this->urlConfig = $objectManager->getObject( + UspsUrl::class, + [ + 'url' => $this->url, + 'context' => $this->contextMock, + 'registry' => $registry, + 'config' => $config, + 'cacheTypeList' => $cacheTypeList, + 'resource' => $resource, + 'resourceCollection' => $resourceCollection, + ] + ); + } + + /** + * @dataProvider validDataProvider + * @param string $data The valid data + * @throws ValidatorException + */ + public function testBeforeSave(string $data = ""): void + { + $this->url->expects($this->any())->method('isValid')->willReturn(true); + $this->urlConfig->setValue($data); + $this->urlConfig->beforeSave(); + $this->assertTrue($this->url->isValid($data)); + } + + /** + * @dataProvider invalidDataProvider + * @param string $data The invalid data + */ + public function testBeforeSaveErrors(string $data): void + { + $this->url->expects($this->any())->method('isValid')->willReturn(true); + $this->expectException('Magento\Framework\Exception\ValidatorException'); + $this->expectExceptionMessage('USPS API endpoint URL\'s must use usps.com or shippingapis.com'); + $this->urlConfig->setValue($data); + $this->urlConfig->beforeSave(); + } + + public function validDataProvider(): array + { + return [ + [], + [''], + ['http://usps.com'], + ['https://foo.usps.com'], + ['http://foo.usps.com/foo/bar?baz=bash&fizz=buzz'], + ]; + } + + /** + * @return string[][] + */ + public function invalidDataProvider(): array + { + return [ + ['https://shippingapis.com.fake.com'], + ['https://shippingapis.info'], + ['http://shippingapis.com.foo.com/foo/bar?baz=bash&fizz=buzz'], + ]; + } +} diff --git a/app/code/Magento/Usps/composer.json b/app/code/Magento/Usps/composer.json index 107d4755d92c4..2273c4f24c753 100644 --- a/app/code/Magento/Usps/composer.json +++ b/app/code/Magento/Usps/composer.json @@ -1,27 +1,28 @@ { "name": "magento/module-usps", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.5-p3", "require": { "php": "~8.1.0||~8.2.0", "lib-libxml": "*", - "magento/framework": "*", - "magento/module-catalog": "*", - "magento/module-catalog-inventory": "*", - "magento/module-config": "*", - "magento/module-directory": "*", - "magento/module-quote": "*", - "magento/module-sales": "*", - "magento/module-shipping": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-inventory": "100.4.*", + "magento/module-config": "101.2.*", + "magento/module-directory": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-sales": "103.0.*", + "magento/module-shipping": "100.4.*", + "magento/module-store": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -31,3 +32,4 @@ } } } + diff --git a/app/code/Magento/Usps/etc/adminhtml/system.xml b/app/code/Magento/Usps/etc/adminhtml/system.xml index b01f7be9a19f9..00c9632b99367 100644 --- a/app/code/Magento/Usps/etc/adminhtml/system.xml +++ b/app/code/Magento/Usps/etc/adminhtml/system.xml @@ -16,9 +16,11 @@ </field> <field id="gateway_url" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" canRestore="1"> <label>Gateway URL</label> + <backend_model>Magento\Usps\Model\Config\Backend\UspsUrl</backend_model> </field> <field id="gateway_secure_url" translate="label" type="text" sortOrder="30" showInDefault="1" showInWebsite="1" canRestore="1"> <label>Secure Gateway URL</label> + <backend_model>Magento\Usps\Model\Config\Backend\UspsUrl</backend_model> </field> <field id="title" translate="label" type="text" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1"> <label>Title</label> diff --git a/app/code/Magento/Usps/etc/config.xml b/app/code/Magento/Usps/etc/config.xml index 852fbe9652929..bd6ad73f03130 100644 --- a/app/code/Magento/Usps/etc/config.xml +++ b/app/code/Magento/Usps/etc/config.xml @@ -11,7 +11,7 @@ <usps> <active>0</active> <sallowspecific>0</sallowspecific> - <allowed_methods>0_FCLE,0_FCL,0_FCP,1,2,3,4,6,7,13,16,17,22,23,25,27,28,33,34,35,36,37,42,43,53,57,61,INT_1,INT_2,INT_4,INT_6,INT_7,INT_8,INT_9,INT_10,INT_11,INT_12,INT_13,INT_14,INT_15,INT_16,INT_20</allowed_methods> + <allowed_methods>0_FCLE,0_FCL,0_FCP,1,2,3,4,6,7,13,16,17,22,23,25,27,28,33,34,35,36,37,42,43,53,57,61,INT_1,INT_2,INT_4,INT_6,INT_7,INT_8,INT_9,INT_10,INT_11,INT_12,INT_13,INT_14,INT_15,INT_16,INT_20,1058,4058,6058,2058,4096,1096,2096,6096</allowed_methods> <container>VARIABLE</container> <cutoff_cost /> <free_method /> diff --git a/app/code/Magento/Usps/i18n/en_US.csv b/app/code/Magento/Usps/i18n/en_US.csv index ab1a11155fe04..1c14cbc2b00c3 100644 --- a/app/code/Magento/Usps/i18n/en_US.csv +++ b/app/code/Magento/Usps/i18n/en_US.csv @@ -72,6 +72,14 @@ "Priority Mail International DVD Flat Rate priced box","Priority Mail International DVD Flat Rate priced box" "Priority Mail International Large Video Flat Rate priced box","Priority Mail International Large Video Flat Rate priced box" "Priority Mail Express International Padded Flat Rate Envelope","Priority Mail Express International Padded Flat Rate Envelope" +"Ground Advantageâ„¢","Ground Advantageâ„¢" +"Ground Advantageâ„¢ HAZMAT","Ground Advantageâ„¢ HAZMAT" +"Ground Advantageâ„¢ Parcel locker","Ground Advantageâ„¢ Parcel locker" +"Ground Advantageâ„¢ Hold for pickup","Ground Advantageâ„¢ Hold for pickup" +"Ground Advantageâ„¢ Cubic HAZMAT","Ground Advantageâ„¢ Cubic HAZMAT" +"Ground Advantageâ„¢ Cubic","Ground Advantageâ„¢ Cubic" +"Ground Advantageâ„¢ Cubic Hold for pickup","Ground Advantageâ„¢ Cubic Hold for pickup" +"Ground Advantageâ„¢ Cubic Parcel locker","Ground Advantageâ„¢ Cubic Parcel locker" Letter,Letter Flat,Flat Parcel,Parcel @@ -137,3 +145,4 @@ Machinable,Machinable Debug,Debug "Show Method if Not Applicable","Show Method if Not Applicable" "Sort Order","Sort Order" +"USPS API endpoint URL\'s must use usps.com or shippingapis.com","USPS API endpoint URL\'s must use usps.com or shippingapis.com" diff --git a/app/code/Magento/Variable/composer.json b/app/code/Magento/Variable/composer.json index 2af748d990c35..20b3aaf5fafbe 100644 --- a/app/code/Magento/Variable/composer.json +++ b/app/code/Magento/Variable/composer.json @@ -1,22 +1,23 @@ { "name": "magento/module-variable", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-store": "*", - "magento/module-config": "*", - "magento/module-ui": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-store": "101.1.*", + "magento/module-config": "101.2.*", + "magento/module-ui": "101.2.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -26,3 +27,4 @@ } } } + diff --git a/app/code/Magento/Vault/composer.json b/app/code/Magento/Vault/composer.json index f671abff34d08..1b119f82795e5 100644 --- a/app/code/Magento/Vault/composer.json +++ b/app/code/Magento/Vault/composer.json @@ -1,25 +1,25 @@ { "name": "magento/module-vault", - "description": "", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "101.2.6", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-checkout": "*", - "magento/module-customer": "*", - "magento/module-payment": "*", - "magento/module-quote": "*", - "magento/module-sales": "*", - "magento/module-store": "*", - "magento/module-theme": "*" + "magento/framework": "103.0.*", + "magento/module-checkout": "100.4.*", + "magento/module-customer": "103.0.*", + "magento/module-payment": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-sales": "103.0.*", + "magento/module-store": "101.1.*", + "magento/module-theme": "101.1.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -29,3 +29,4 @@ } } } + diff --git a/app/code/Magento/VaultGraphQl/composer.json b/app/code/Magento/VaultGraphQl/composer.json index 4d8e565267a81..597f8c34b1022 100644 --- a/app/code/Magento/VaultGraphQl/composer.json +++ b/app/code/Magento/VaultGraphQl/composer.json @@ -2,16 +2,17 @@ "name": "magento/module-vault-graph-ql", "description": "N/A", "type": "magento2-module", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-vault": "*", - "magento/module-graph-ql": "*" - }, "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.2", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*", + "magento/module-vault": "101.2.*", + "magento/module-graph-ql": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -21,3 +22,4 @@ } } } + diff --git a/app/code/Magento/Version/composer.json b/app/code/Magento/Version/composer.json index 36503adfc841c..d7306eee34237 100644 --- a/app/code/Magento/Version/composer.json +++ b/app/code/Magento/Version/composer.json @@ -1,18 +1,19 @@ { "name": "magento/module-version", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.3", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*" + "magento/framework": "103.0.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -22,3 +23,4 @@ } } } + diff --git a/app/code/Magento/Webapi/composer.json b/app/code/Magento/Webapi/composer.json index d8c713391c4a0..8f4e9faff6bcf 100644 --- a/app/code/Magento/Webapi/composer.json +++ b/app/code/Magento/Webapi/composer.json @@ -1,26 +1,27 @@ { "name": "magento/module-webapi", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.5", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-authorization": "*", - "magento/module-backend": "*", - "magento/module-integration": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-authorization": "100.4.*", + "magento/module-backend": "102.0.*", + "magento/module-integration": "100.4.*", + "magento/module-store": "101.1.*" }, "suggest": { - "magento/module-user": "*", - "magento/module-customer": "*" + "magento/module-user": "101.2.*", + "magento/module-customer": "103.0.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -30,3 +31,4 @@ } } } + diff --git a/app/code/Magento/WebapiAsync/composer.json b/app/code/Magento/WebapiAsync/composer.json index 9bdd9d48f1cc7..9a029ab0ead9d 100644 --- a/app/code/Magento/WebapiAsync/composer.json +++ b/app/code/Magento/WebapiAsync/composer.json @@ -1,25 +1,26 @@ { "name": "magento/module-webapi-async", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.4", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-webapi": "*", - "magento/module-asynchronous-operations": "*", - "magento/module-store": "*" + "magento/framework": "103.0.*", + "magento/module-webapi": "100.4.*", + "magento/module-asynchronous-operations": "100.4.*", + "magento/module-store": "101.1.*" }, "suggest": { - "magento/module-user": "*", - "magento/module-customer": "*" + "magento/module-user": "101.2.*", + "magento/module-customer": "103.0.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -29,3 +30,4 @@ } } } + diff --git a/app/code/Magento/WebapiSecurity/composer.json b/app/code/Magento/WebapiSecurity/composer.json index 16851cad3d89f..9c7eb79d5ad09 100644 --- a/app/code/Magento/WebapiSecurity/composer.json +++ b/app/code/Magento/WebapiSecurity/composer.json @@ -1,19 +1,20 @@ { "name": "magento/module-webapi-security", "description": "WebapiSecurity module provides option to loosen security on some webapi resources.", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.3", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-webapi": "*" + "magento/framework": "103.0.*", + "magento/module-webapi": "100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -23,3 +24,4 @@ } } } + diff --git a/app/code/Magento/Weee/composer.json b/app/code/Magento/Weee/composer.json index 226f55ed11319..91665633d491d 100644 --- a/app/code/Magento/Weee/composer.json +++ b/app/code/Magento/Weee/composer.json @@ -1,33 +1,34 @@ { "name": "magento/module-weee", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.6", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-checkout": "*", - "magento/module-customer": "*", - "magento/module-directory": "*", - "magento/module-eav": "*", - "magento/module-page-cache": "*", - "magento/module-quote": "*", - "magento/module-sales": "*", - "magento/module-store": "*", - "magento/module-tax": "*", - "magento/module-ui": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-checkout": "100.4.*", + "magento/module-customer": "103.0.*", + "magento/module-directory": "100.4.*", + "magento/module-eav": "102.1.*", + "magento/module-page-cache": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-sales": "103.0.*", + "magento/module-store": "101.1.*", + "magento/module-tax": "100.4.*", + "magento/module-ui": "101.2.*" }, "suggest": { - "magento/module-bundle": "*" + "magento/module-bundle": "101.0.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -37,3 +38,4 @@ } } } + diff --git a/app/code/Magento/WeeeGraphQl/composer.json b/app/code/Magento/WeeeGraphQl/composer.json index aa4d28bcc7f73..c60000c8b68ba 100644 --- a/app/code/Magento/WeeeGraphQl/composer.json +++ b/app/code/Magento/WeeeGraphQl/composer.json @@ -2,20 +2,21 @@ "name": "magento/module-weee-graph-ql", "description": "N/A", "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "version": "100.4.3", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-store": "*", - "magento/module-tax": "*", - "magento/module-weee": "*" + "magento/framework": "103.0.*", + "magento/module-store": "101.1.*", + "magento/module-tax": "100.4.*", + "magento/module-weee": "100.4.*" }, "suggest": { - "magento/module-catalog-graph-ql": "*" + "magento/module-catalog-graph-ql": "100.4.*" }, - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -25,3 +26,4 @@ } } } + diff --git a/app/code/Magento/Widget/composer.json b/app/code/Magento/Widget/composer.json index e30a41ae1f95d..8427390aee5cb 100644 --- a/app/code/Magento/Widget/composer.json +++ b/app/code/Magento/Widget/composer.json @@ -1,29 +1,30 @@ { "name": "magento/module-widget", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "101.2.6", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-cms": "*", - "magento/module-email": "*", - "magento/module-store": "*", - "magento/module-theme": "*", - "magento/module-variable": "*", - "magento/module-ui": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-cms": "104.0.*", + "magento/module-email": "101.1.*", + "magento/module-store": "101.1.*", + "magento/module-theme": "101.1.*", + "magento/module-variable": "100.4.*", + "magento/module-ui": "101.2.*" }, "suggest": { - "magento/module-widget-sample-data": "*" + "magento/module-widget-sample-data": "Sample Data version: 100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -33,3 +34,4 @@ } } } + diff --git a/app/code/Magento/Wishlist/composer.json b/app/code/Magento/Wishlist/composer.json index 82063e9c1bfbc..94142e9f30389 100644 --- a/app/code/Magento/Wishlist/composer.json +++ b/app/code/Magento/Wishlist/composer.json @@ -1,37 +1,38 @@ { "name": "magento/module-wishlist", "description": "N/A", + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "101.2.6", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-catalog-inventory": "*", - "magento/module-checkout": "*", - "magento/module-customer": "*", - "magento/module-rss": "*", - "magento/module-sales": "*", - "magento/module-store": "*", - "magento/module-theme": "*", - "magento/module-ui": "*", - "magento/module-captcha": "*" + "magento/framework": "103.0.*", + "magento/module-backend": "102.0.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-inventory": "100.4.*", + "magento/module-checkout": "100.4.*", + "magento/module-customer": "103.0.*", + "magento/module-rss": "100.4.*", + "magento/module-sales": "103.0.*", + "magento/module-store": "101.1.*", + "magento/module-theme": "101.1.*", + "magento/module-ui": "101.2.*", + "magento/module-captcha": "100.4.*" }, "suggest": { - "magento/module-configurable-product": "*", - "magento/module-downloadable": "*", - "magento/module-bundle": "*", - "magento/module-cookie": "*", - "magento/module-grouped-product": "*", - "magento/module-wishlist-sample-data": "*" + "magento/module-configurable-product": "100.4.*", + "magento/module-downloadable": "100.4.*", + "magento/module-bundle": "101.0.*", + "magento/module-cookie": "100.4.*", + "magento/module-grouped-product": "100.4.*", + "magento/module-wishlist-sample-data": "Sample Data version: 100.4.*" }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" @@ -41,3 +42,4 @@ } } } + diff --git a/app/code/Magento/WishlistAnalytics/composer.json b/app/code/Magento/WishlistAnalytics/composer.json index d990be3af68b0..be58362c32039 100644 --- a/app/code/Magento/WishlistAnalytics/composer.json +++ b/app/code/Magento/WishlistAnalytics/composer.json @@ -1,17 +1,18 @@ { "name": "magento/module-wishlist-analytics", "description": "N/A", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-wishlist": "*", - "magento/module-analytics": "*" - }, "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.4", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*", + "magento/module-wishlist": "101.2.*", + "magento/module-analytics": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -21,3 +22,4 @@ } } } + diff --git a/app/code/Magento/WishlistGraphQl/composer.json b/app/code/Magento/WishlistGraphQl/composer.json index d5bb93fefa7ec..f0bd5758c3045 100755 --- a/app/code/Magento/WishlistGraphQl/composer.json +++ b/app/code/Magento/WishlistGraphQl/composer.json @@ -2,20 +2,21 @@ "name": "magento/module-wishlist-graph-ql", "description": "N/A", "type": "magento2-module", - "require": { - "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/module-wishlist": "*", - "magento/module-store": "*", - "magento/module-quote-graph-ql": "*", - "magento/module-quote": "*", - "magento/module-catalog": "*", - "magento/module-catalog-graph-ql": "*" - }, "license": [ "OSL-3.0", "AFL-3.0" ], + "version": "100.4.6", + "require": { + "php": "~8.1.0||~8.2.0", + "magento/framework": "103.0.*", + "magento/module-wishlist": "101.2.*", + "magento/module-store": "101.1.*", + "magento/module-quote-graph-ql": "100.4.*", + "magento/module-quote": "101.2.*", + "magento/module-catalog": "104.0.*", + "magento/module-catalog-graph-ql": "100.4.*" + }, "autoload": { "files": [ "registration.php" @@ -25,3 +26,4 @@ } } } + diff --git a/app/design/adminhtml/Magento/backend/composer.json b/app/design/adminhtml/Magento/backend/composer.json index d5cb290cc67b9..badcf6e8490e3 100644 --- a/app/design/adminhtml/Magento/backend/composer.json +++ b/app/design/adminhtml/Magento/backend/composer.json @@ -1,21 +1,23 @@ { "name": "magento/theme-adminhtml-backend", "description": "N/A", + "type": "magento2-theme", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.6", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*" + "magento/framework": "103.0.*" }, - "type": "magento2-theme", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" ] } } + diff --git a/app/design/frontend/Magento/blank/composer.json b/app/design/frontend/Magento/blank/composer.json index afb262619592a..4f1e04c72d152 100644 --- a/app/design/frontend/Magento/blank/composer.json +++ b/app/design/frontend/Magento/blank/composer.json @@ -1,21 +1,23 @@ { "name": "magento/theme-frontend-blank", "description": "N/A", + "type": "magento2-theme", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.6", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*" + "magento/framework": "103.0.*" }, - "type": "magento2-theme", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" ] } } + diff --git a/app/design/frontend/Magento/luma/composer.json b/app/design/frontend/Magento/luma/composer.json index f456c842cbdd4..e344b2309e683 100644 --- a/app/design/frontend/Magento/luma/composer.json +++ b/app/design/frontend/Magento/luma/composer.json @@ -1,22 +1,24 @@ { "name": "magento/theme-frontend-luma", "description": "N/A", + "type": "magento2-theme", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], "config": { "sort-packages": true }, + "version": "100.4.6", "require": { "php": "~8.1.0||~8.2.0", - "magento/framework": "*", - "magento/theme-frontend-blank": "*" + "magento/framework": "103.0.*", + "magento/theme-frontend-blank": "100.4.*" }, - "type": "magento2-theme", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], "autoload": { "files": [ "registration.php" ] } } + diff --git a/app/i18n/Magento/de_DE/composer.json b/app/i18n/Magento/de_DE/composer.json index 5a488a3e32c2b..fd23d037ba459 100644 --- a/app/i18n/Magento/de_DE/composer.json +++ b/app/i18n/Magento/de_DE/composer.json @@ -1,6 +1,7 @@ { "name": "magento/language-de_de", "description": "German (Germany) language", + "type": "magento2-language", "license": [ "OSL-3.0", "AFL-3.0" @@ -8,13 +9,14 @@ "config": { "sort-packages": true }, + "version": "100.4.0", "require": { - "magento/framework": "*" + "magento/framework": "103.0.*" }, - "type": "magento2-language", "autoload": { "files": [ "registration.php" ] } } + diff --git a/app/i18n/Magento/en_US/composer.json b/app/i18n/Magento/en_US/composer.json index 1108c70de28a6..194854d58bbe2 100644 --- a/app/i18n/Magento/en_US/composer.json +++ b/app/i18n/Magento/en_US/composer.json @@ -1,6 +1,7 @@ { "name": "magento/language-en_us", "description": "English (United States) language", + "type": "magento2-language", "license": [ "OSL-3.0", "AFL-3.0" @@ -8,13 +9,14 @@ "config": { "sort-packages": true }, + "version": "100.4.0", "require": { - "magento/framework": "*" + "magento/framework": "103.0.*" }, - "type": "magento2-language", "autoload": { "files": [ "registration.php" ] } } + diff --git a/app/i18n/Magento/es_ES/composer.json b/app/i18n/Magento/es_ES/composer.json index 5bc3cb5730adf..0b49475587d54 100644 --- a/app/i18n/Magento/es_ES/composer.json +++ b/app/i18n/Magento/es_ES/composer.json @@ -1,6 +1,7 @@ { "name": "magento/language-es_es", "description": "Spanish (Spain) language", + "type": "magento2-language", "license": [ "OSL-3.0", "AFL-3.0" @@ -8,13 +9,14 @@ "config": { "sort-packages": true }, + "version": "100.4.0", "require": { - "magento/framework": "*" + "magento/framework": "103.0.*" }, - "type": "magento2-language", "autoload": { "files": [ "registration.php" ] } } + diff --git a/app/i18n/Magento/fr_FR/composer.json b/app/i18n/Magento/fr_FR/composer.json index 50c541308673b..ada414e6a7a32 100644 --- a/app/i18n/Magento/fr_FR/composer.json +++ b/app/i18n/Magento/fr_FR/composer.json @@ -1,6 +1,7 @@ { "name": "magento/language-fr_fr", "description": "French (France) language", + "type": "magento2-language", "license": [ "OSL-3.0", "AFL-3.0" @@ -8,13 +9,14 @@ "config": { "sort-packages": true }, + "version": "100.4.0", "require": { - "magento/framework": "*" + "magento/framework": "103.0.*" }, - "type": "magento2-language", "autoload": { "files": [ "registration.php" ] } } + diff --git a/app/i18n/Magento/nl_NL/composer.json b/app/i18n/Magento/nl_NL/composer.json index a182e179d4103..a881eed112ea0 100644 --- a/app/i18n/Magento/nl_NL/composer.json +++ b/app/i18n/Magento/nl_NL/composer.json @@ -1,6 +1,7 @@ { "name": "magento/language-nl_nl", "description": "Dutch (Netherlands) language", + "type": "magento2-language", "license": [ "OSL-3.0", "AFL-3.0" @@ -8,13 +9,14 @@ "config": { "sort-packages": true }, + "version": "100.4.0", "require": { - "magento/framework": "*" + "magento/framework": "103.0.*" }, - "type": "magento2-language", "autoload": { "files": [ "registration.php" ] } } + diff --git a/app/i18n/Magento/pt_BR/composer.json b/app/i18n/Magento/pt_BR/composer.json index 46734cc09b363..6e10bc16f6a79 100644 --- a/app/i18n/Magento/pt_BR/composer.json +++ b/app/i18n/Magento/pt_BR/composer.json @@ -1,6 +1,7 @@ { "name": "magento/language-pt_br", "description": "Portuguese (Brazil) language", + "type": "magento2-language", "license": [ "OSL-3.0", "AFL-3.0" @@ -8,13 +9,14 @@ "config": { "sort-packages": true }, + "version": "100.4.0", "require": { - "magento/framework": "*" + "magento/framework": "103.0.*" }, - "type": "magento2-language", "autoload": { "files": [ "registration.php" ] } } + diff --git a/app/i18n/Magento/zh_Hans_CN/composer.json b/app/i18n/Magento/zh_Hans_CN/composer.json index ce214ce649f56..8491eced1389f 100644 --- a/app/i18n/Magento/zh_Hans_CN/composer.json +++ b/app/i18n/Magento/zh_Hans_CN/composer.json @@ -1,6 +1,7 @@ { "name": "magento/language-zh_hans_cn", "description": "Chinese (China) language", + "type": "magento2-language", "license": [ "OSL-3.0", "AFL-3.0" @@ -8,13 +9,14 @@ "config": { "sort-packages": true }, + "version": "100.4.0", "require": { - "magento/framework": "*" + "magento/framework": "103.0.*" }, - "type": "magento2-language", "autoload": { "files": [ "registration.php" ] } } + diff --git a/composer.json b/composer.json index 8d961b68fa205..9ca9e210f2951 100644 --- a/composer.json +++ b/composer.json @@ -16,6 +16,7 @@ "preferred-install": "dist", "sort-packages": true }, + "version": "2.4.6-p3", "require": { "php": "~8.1.0||~8.2.0", "ext-bcmath": "*", @@ -91,6 +92,30 @@ "webonyx/graphql-php": "^15.0", "wikimedia/less.php": "^3.2" }, + "suggest": { + "ext-pcntl": "Need for run processes in parallel mode" + }, + "autoload": { + "exclude-from-classmap": [ + "**/dev/**", + "**/update/**", + "**/Test/**" + ], + "files": [ + "app/etc/NonComposerComponentRegistration.php" + ], + "psr-0": { + "": [ + "app/code/", + "generated/code/" + ] + }, + "psr-4": { + "Magento\\": "app/code/Magento/", + "Magento\\Framework\\": "lib/internal/Magento/Framework/", + "Magento\\Setup\\": "setup/src/Magento/Setup/" + } + }, "require-dev": { "allure-framework/allure-phpunit": "^2", "dealerdirect/phpcodesniffer-composer-installer": "^0.7", @@ -98,298 +123,277 @@ "friendsofphp/php-cs-fixer": "^3.8", "lusitanian/oauth": "^0.8", "magento/magento-coding-standard": "*", - "magento/magento2-functional-testing-framework": "^4.2.1", + "magento/magento2-functional-testing-framework": "^4.3.1", "pdepend/pdepend": "^2.10", "phpmd/phpmd": "^2.12", "phpstan/phpstan": "^1.9", "phpunit/phpunit": "^9.5", + "sebastian/comparator": "<=4.0.6", "sebastian/phpcpd": "^6.0", - "symfony/finder": "^5.4" + "symfony/finder": "^5.4", + "symfony/process": "<=v5.4.23" }, - "suggest": { - "ext-pcntl": "Need for run processes in parallel mode" + "conflict": { + "gene/bluefoot": "*" }, "replace": { - "magento/module-marketplace": "*", - "magento/module-admin-analytics": "*", - "magento/module-admin-notification": "*", - "magento/module-advanced-pricing-import-export": "*", - "magento/module-amqp": "*", - "magento/module-analytics": "*", - "magento/module-asynchronous-operations": "*", - "magento/module-authorization": "*", - "magento/module-advanced-search": "*", - "magento/module-backend": "*", - "magento/module-backup": "*", - "magento/module-bundle": "*", - "magento/module-bundle-graph-ql": "*", - "magento/module-bundle-import-export": "*", - "magento/module-cache-invalidate": "*", - "magento/module-captcha": "*", - "magento/module-cardinal-commerce": "*", - "magento/module-catalog": "*", - "magento/module-catalog-customer-graph-ql": "*", - "magento/module-catalog-analytics": "*", - "magento/module-catalog-import-export": "*", - "magento/module-catalog-inventory": "*", - "magento/module-catalog-inventory-graph-ql": "*", - "magento/module-catalog-rule": "*", - "magento/module-catalog-rule-graph-ql": "*", - "magento/module-catalog-rule-configurable": "*", - "magento/module-catalog-search": "*", - "magento/module-catalog-url-rewrite": "*", - "magento/module-catalog-widget": "*", - "magento/module-checkout": "*", - "magento/module-checkout-agreements": "*", - "magento/module-checkout-agreements-graph-ql": "*", - "magento/module-cms": "*", - "magento/module-cms-url-rewrite": "*", - "magento/module-compare-list-graph-ql": "*", - "magento/module-config": "*", - "magento/module-configurable-import-export": "*", - "magento/module-configurable-product": "*", - "magento/module-configurable-product-sales": "*", - "magento/module-contact": "*", - "magento/module-cookie": "*", - "magento/module-cron": "*", - "magento/module-currency-symbol": "*", - "magento/module-customer": "*", - "magento/module-customer-analytics": "*", - "magento/module-customer-downloadable-graph-ql": "*", - "magento/module-customer-import-export": "*", - "magento/module-deploy": "*", - "magento/module-developer": "*", - "magento/module-dhl": "*", - "magento/module-directory": "*", - "magento/module-directory-graph-ql": "*", - "magento/module-downloadable": "*", - "magento/module-downloadable-graph-ql": "*", - "magento/module-downloadable-import-export": "*", - "magento/module-eav": "*", - "magento/module-open-search": "*", - "magento/module-elasticsearch": "*", - "magento/module-elasticsearch-7": "*", - "magento/module-email": "*", - "magento/module-encryption-key": "*", - "magento/module-fedex": "*", - "magento/module-gift-message": "*", - "magento/module-gift-message-graph-ql": "*", - "magento/module-google-adwords": "*", - "magento/module-google-analytics": "*", - "magento/module-google-optimizer": "*", - "magento/module-google-gtag": "*", - "magento/module-graph-ql": "*", - "magento/module-graph-ql-cache": "*", - "magento/module-catalog-graph-ql": "*", - "magento/module-catalog-cms-graph-ql": "*", - "magento/module-catalog-url-rewrite-graph-ql": "*", - "magento/module-configurable-product-graph-ql": "*", - "magento/module-customer-graph-ql": "*", - "magento/module-eav-graph-ql": "*", - "magento/module-swatches-graph-ql": "*", - "magento/module-tax-graph-ql": "*", - "magento/module-url-rewrite-graph-ql": "*", - "magento/module-cms-url-rewrite-graph-ql": "*", - "magento/module-weee-graph-ql": "*", - "magento/module-cms-graph-ql": "*", - "magento/module-grouped-import-export": "*", - "magento/module-grouped-product": "*", - "magento/module-grouped-catalog-inventory": "*", - "magento/module-grouped-product-graph-ql": "*", - "magento/module-import-export": "*", - "magento/module-indexer": "*", - "magento/module-instant-purchase": "*", - "magento/module-integration": "*", - "magento/module-layered-navigation": "*", - "magento/module-login-as-customer": "*", - "magento/module-login-as-customer-admin-ui": "*", - "magento/module-login-as-customer-api": "*", - "magento/module-login-as-customer-assistance": "*", - "magento/module-login-as-customer-frontend-ui": "*", - "magento/module-login-as-customer-graph-ql": "*", - "magento/module-login-as-customer-log": "*", - "magento/module-login-as-customer-quote": "*", - "magento/module-login-as-customer-page-cache": "*", - "magento/module-login-as-customer-sales": "*", - "magento/module-media-content": "*", - "magento/module-media-content-api": "*", - "magento/module-media-content-catalog": "*", - "magento/module-media-content-cms": "*", - "magento/module-media-gallery": "*", - "magento/module-media-gallery-api": "*", - "magento/module-media-gallery-ui": "*", - "magento/module-media-gallery-ui-api": "*", - "magento/module-media-gallery-integration": "*", - "magento/module-media-gallery-synchronization": "*", - "magento/module-media-gallery-synchronization-api": "*", - "magento/module-media-content-synchronization": "*", - "magento/module-media-content-synchronization-api": "*", - "magento/module-media-content-synchronization-catalog": "*", - "magento/module-media-content-synchronization-cms": "*", - "magento/module-media-gallery-synchronization-metadata": "*", - "magento/module-media-gallery-metadata": "*", - "magento/module-media-gallery-metadata-api": "*", - "magento/module-media-gallery-catalog-ui": "*", - "magento/module-media-gallery-cms-ui": "*", - "magento/module-media-gallery-catalog-integration": "*", - "magento/module-media-gallery-catalog": "*", - "magento/module-media-gallery-renditions": "*", - "magento/module-media-gallery-renditions-api": "*", - "magento/module-media-storage": "*", - "magento/module-message-queue": "*", - "magento/module-msrp": "*", - "magento/module-msrp-configurable-product": "*", - "magento/module-msrp-grouped-product": "*", - "magento/module-multishipping": "*", - "magento/module-mysql-mq": "*", - "magento/module-new-relic-reporting": "*", - "magento/module-newsletter": "*", - "magento/module-newsletter-graph-ql": "*", - "magento/module-offline-payments": "*", - "magento/module-offline-shipping": "*", - "magento/module-page-cache": "*", - "magento/module-payment": "*", - "magento/module-payment-graph-ql": "*", - "magento/module-paypal": "*", - "magento/module-paypal-captcha": "*", - "magento/module-paypal-graph-ql": "*", - "magento/module-persistent": "*", - "magento/module-product-alert": "*", - "magento/module-product-video": "*", - "magento/module-quote": "*", - "magento/module-quote-analytics": "*", - "magento/module-quote-bundle-options": "*", - "magento/module-quote-configurable-options": "*", - "magento/module-quote-downloadable-links": "*", - "magento/module-quote-graph-ql": "*", - "magento/module-related-product-graph-ql": "*", - "magento/module-release-notification": "*", - "magento/module-reports": "*", - "magento/module-require-js": "*", - "magento/module-review": "*", - "magento/module-review-graph-ql": "*", - "magento/module-review-analytics": "*", - "magento/module-robots": "*", - "magento/module-rss": "*", - "magento/module-rule": "*", - "magento/module-sales": "*", - "magento/module-sales-analytics": "*", - "magento/module-sales-graph-ql": "*", - "magento/module-sales-inventory": "*", - "magento/module-sales-rule": "*", - "magento/module-sales-sequence": "*", - "magento/module-sample-data": "*", - "magento/module-search": "*", - "magento/module-security": "*", - "magento/module-send-friend": "*", - "magento/module-send-friend-graph-ql": "*", - "magento/module-shipping": "*", - "magento/module-sitemap": "*", - "magento/module-store": "*", - "magento/module-store-graph-ql": "*", - "magento/module-swagger": "*", - "magento/module-swagger-webapi": "*", - "magento/module-swagger-webapi-async": "*", - "magento/module-swatches": "*", - "magento/module-swatches-layered-navigation": "*", - "magento/module-tax": "*", - "magento/module-tax-import-export": "*", - "magento/module-theme": "*", - "magento/module-theme-graph-ql": "*", - "magento/module-translation": "*", - "magento/module-ui": "*", - "magento/module-ups": "*", - "magento/module-url-rewrite": "*", - "magento/module-user": "*", - "magento/module-usps": "*", - "magento/module-variable": "*", - "magento/module-vault": "*", - "magento/module-vault-graph-ql": "*", - "magento/module-version": "*", - "magento/module-webapi": "*", - "magento/module-webapi-async": "*", - "magento/module-webapi-security": "*", - "magento/module-weee": "*", - "magento/module-widget": "*", - "magento/module-wishlist": "*", - "magento/module-wishlist-graph-ql": "*", - "magento/module-wishlist-analytics": "*", - "magento/theme-adminhtml-backend": "*", - "magento/theme-frontend-blank": "*", - "magento/theme-frontend-luma": "*", - "magento/language-de_de": "*", - "magento/language-en_us": "*", - "magento/language-es_es": "*", - "magento/language-fr_fr": "*", - "magento/language-nl_nl": "*", - "magento/language-pt_br": "*", - "magento/language-zh_hans_cn": "*", - "magento/framework": "*", - "magento/framework-amqp": "*", - "magento/framework-bulk": "*", - "magento/framework-message-queue": "*", + "magento/module-marketplace": "100.4.4-p2", + "magento/module-admin-analytics": "100.4.5", + "magento/module-admin-notification": "100.4.5", + "magento/module-advanced-pricing-import-export": "100.4.6", + "magento/module-amqp": "100.4.3", + "magento/module-analytics": "100.4.6", + "magento/module-asynchronous-operations": "100.4.6", + "magento/module-authorization": "100.4.6", + "magento/module-advanced-search": "100.4.4", + "magento/module-backend": "102.0.6", + "magento/module-backup": "100.4.6", + "magento/module-bundle": "101.0.6-p2", + "magento/module-bundle-graph-ql": "100.4.6", + "magento/module-bundle-import-export": "100.4.5", + "magento/module-cache-invalidate": "100.4.4", + "magento/module-captcha": "100.4.6-p2", + "magento/module-cardinal-commerce": "100.4.4", + "magento/module-catalog": "104.0.6-p3", + "magento/module-catalog-customer-graph-ql": "100.4.5", + "magento/module-catalog-analytics": "100.4.3", + "magento/module-catalog-import-export": "101.1.6-p1", + "magento/module-catalog-inventory": "100.4.6-p2", + "magento/module-catalog-inventory-graph-ql": "100.4.3", + "magento/module-catalog-rule": "101.2.6-p2", + "magento/module-catalog-rule-graph-ql": "100.4.3", + "magento/module-catalog-rule-configurable": "100.4.5", + "magento/module-catalog-search": "102.0.6", + "magento/module-catalog-url-rewrite": "100.4.6", + "magento/module-catalog-widget": "100.4.6", + "magento/module-checkout": "100.4.6-p3", + "magento/module-checkout-agreements": "100.4.5-p2", + "magento/module-checkout-agreements-graph-ql": "100.4.2", + "magento/module-cms": "104.0.6-p2", + "magento/module-cms-url-rewrite": "100.4.5", + "magento/module-compare-list-graph-ql": "100.4.2", + "magento/module-config": "101.2.6", + "magento/module-configurable-import-export": "100.4.4", + "magento/module-configurable-product": "100.4.6", + "magento/module-configurable-product-sales": "100.4.3", + "magento/module-contact": "100.4.5", + "magento/module-cookie": "100.4.6", + "magento/module-cron": "100.4.6", + "magento/module-currency-symbol": "100.4.4-p3", + "magento/module-customer": "103.0.6-p3", + "magento/module-customer-analytics": "100.4.3", + "magento/module-customer-downloadable-graph-ql": "100.4.2", + "magento/module-customer-import-export": "100.4.6", + "magento/module-deploy": "100.4.6", + "magento/module-developer": "100.4.6", + "magento/module-dhl": "100.4.5", + "magento/module-directory": "100.4.6", + "magento/module-directory-graph-ql": "100.4.4", + "magento/module-downloadable": "100.4.6-p3", + "magento/module-downloadable-graph-ql": "100.4.6", + "magento/module-downloadable-import-export": "100.4.5", + "magento/module-eav": "102.1.6", + "magento/module-open-search": "100.4.0", + "magento/module-elasticsearch": "101.0.6", + "magento/module-elasticsearch-7": "100.4.6", + "magento/module-email": "101.1.6-p1", + "magento/module-encryption-key": "100.4.4", + "magento/module-fedex": "100.4.4-p1", + "magento/module-gift-message": "100.4.5", + "magento/module-gift-message-graph-ql": "100.4.4", + "magento/module-google-adwords": "100.4.3", + "magento/module-google-analytics": "100.4.2", + "magento/module-google-optimizer": "100.4.5", + "magento/module-google-gtag": "100.4.1", + "magento/module-graph-ql": "100.4.6", + "magento/module-graph-ql-cache": "100.4.3", + "magento/module-catalog-graph-ql": "100.4.6", + "magento/module-catalog-cms-graph-ql": "100.4.2", + "magento/module-catalog-url-rewrite-graph-ql": "100.4.4", + "magento/module-configurable-product-graph-ql": "100.4.6", + "magento/module-customer-graph-ql": "100.4.6", + "magento/module-eav-graph-ql": "100.4.3", + "magento/module-swatches-graph-ql": "100.4.4", + "magento/module-tax-graph-ql": "100.4.2", + "magento/module-url-rewrite-graph-ql": "100.4.5", + "magento/module-cms-url-rewrite-graph-ql": "100.4.4", + "magento/module-weee-graph-ql": "100.4.3", + "magento/module-cms-graph-ql": "100.4.3", + "magento/module-grouped-import-export": "100.4.4", + "magento/module-grouped-product": "100.4.6", + "magento/module-grouped-catalog-inventory": "100.4.3", + "magento/module-grouped-product-graph-ql": "100.4.6", + "magento/module-import-export": "101.0.6", + "magento/module-indexer": "100.4.6", + "magento/module-instant-purchase": "100.4.5", + "magento/module-integration": "100.4.6", + "magento/module-layered-navigation": "100.4.6", + "magento/module-login-as-customer": "100.4.6-p2", + "magento/module-login-as-customer-admin-ui": "100.4.6", + "magento/module-login-as-customer-api": "100.4.5", + "magento/module-login-as-customer-assistance": "100.4.5", + "magento/module-login-as-customer-frontend-ui": "100.4.5", + "magento/module-login-as-customer-graph-ql": "100.4.3", + "magento/module-login-as-customer-log": "100.4.4", + "magento/module-login-as-customer-quote": "100.4.4", + "magento/module-login-as-customer-page-cache": "100.4.5", + "magento/module-login-as-customer-sales": "100.4.5", + "magento/module-media-content": "100.4.4", + "magento/module-media-content-api": "100.4.5", + "magento/module-media-content-catalog": "100.4.4", + "magento/module-media-content-cms": "100.4.4", + "magento/module-media-gallery": "100.4.5", + "magento/module-media-gallery-api": "101.0.5", + "magento/module-media-gallery-ui": "100.4.5", + "magento/module-media-gallery-ui-api": "100.4.4", + "magento/module-media-gallery-integration": "100.4.5", + "magento/module-media-gallery-synchronization": "100.4.5", + "magento/module-media-gallery-synchronization-api": "100.4.4", + "magento/module-media-content-synchronization": "100.4.5", + "magento/module-media-content-synchronization-api": "100.4.4", + "magento/module-media-content-synchronization-catalog": "100.4.3", + "magento/module-media-content-synchronization-cms": "100.4.3", + "magento/module-media-gallery-synchronization-metadata": "100.4.2", + "magento/module-media-gallery-metadata": "100.4.4", + "magento/module-media-gallery-metadata-api": "100.4.3", + "magento/module-media-gallery-catalog-ui": "100.4.3", + "magento/module-media-gallery-cms-ui": "100.4.3", + "magento/module-media-gallery-catalog-integration": "100.4.3", + "magento/module-media-gallery-catalog": "100.4.3", + "magento/module-media-gallery-renditions": "100.4.4", + "magento/module-media-gallery-renditions-api": "100.4.3", + "magento/module-media-storage": "100.4.5", + "magento/module-message-queue": "100.4.6", + "magento/module-msrp": "100.4.5", + "magento/module-msrp-configurable-product": "100.4.3", + "magento/module-msrp-grouped-product": "100.4.3", + "magento/module-multishipping": "100.4.6", + "magento/module-mysql-mq": "100.4.4", + "magento/module-new-relic-reporting": "100.4.4", + "magento/module-newsletter": "100.4.6-p2", + "magento/module-newsletter-graph-ql": "100.4.3", + "magento/module-offline-payments": "100.4.4", + "magento/module-offline-shipping": "100.4.5", + "magento/module-page-cache": "100.4.6-p3", + "magento/module-payment": "100.4.6", + "magento/module-payment-graph-ql": "100.4.1", + "magento/module-paypal": "101.0.6-p2", + "magento/module-paypal-captcha": "100.4.3", + "magento/module-paypal-graph-ql": "100.4.4", + "magento/module-persistent": "100.4.6-p3", + "magento/module-product-alert": "100.4.5", + "magento/module-product-video": "100.4.6", + "magento/module-quote": "101.2.6-p1", + "magento/module-quote-analytics": "100.4.5", + "magento/module-quote-bundle-options": "100.4.2", + "magento/module-quote-configurable-options": "100.4.2", + "magento/module-quote-downloadable-links": "100.4.2", + "magento/module-quote-graph-ql": "100.4.6-p1", + "magento/module-related-product-graph-ql": "100.4.3", + "magento/module-release-notification": "100.4.4", + "magento/module-reports": "100.4.6-p2", + "magento/module-require-js": "100.4.2", + "magento/module-review": "100.4.6", + "magento/module-review-graph-ql": "100.4.2", + "magento/module-review-analytics": "100.4.3", + "magento/module-robots": "101.1.2", + "magento/module-rss": "100.4.4", + "magento/module-rule": "100.4.5", + "magento/module-sales": "103.0.6-p3", + "magento/module-sales-analytics": "100.4.3", + "magento/module-sales-graph-ql": "100.4.6", + "magento/module-sales-inventory": "100.4.3", + "magento/module-sales-rule": "101.2.6-p2", + "magento/module-sales-sequence": "100.4.3", + "magento/module-sample-data": "100.4.4", + "magento/module-search": "101.1.6", + "magento/module-security": "100.4.6", + "magento/module-send-friend": "100.4.4", + "magento/module-send-friend-graph-ql": "100.4.2", + "magento/module-shipping": "100.4.6-p3", + "magento/module-sitemap": "100.4.5", + "magento/module-store": "101.1.6", + "magento/module-store-graph-ql": "100.4.4", + "magento/module-swagger": "100.4.5", + "magento/module-swagger-webapi": "100.4.2", + "magento/module-swagger-webapi-async": "100.4.2", + "magento/module-swatches": "100.4.6-p1", + "magento/module-swatches-layered-navigation": "100.4.2", + "magento/module-tax": "100.4.6-p2", + "magento/module-tax-import-export": "100.4.5", + "magento/module-theme": "101.1.6-p2", + "magento/module-theme-graph-ql": "100.4.3", + "magento/module-translation": "100.4.6", + "magento/module-ui": "101.2.6", + "magento/module-ups": "100.4.6", + "magento/module-url-rewrite": "102.0.5-p3", + "magento/module-user": "101.2.6", + "magento/module-usps": "100.4.5-p3", + "magento/module-variable": "100.4.4", + "magento/module-vault": "101.2.6", + "magento/module-vault-graph-ql": "100.4.2", + "magento/module-version": "100.4.3", + "magento/module-webapi": "100.4.5", + "magento/module-webapi-async": "100.4.4", + "magento/module-webapi-security": "100.4.3", + "magento/module-weee": "100.4.6", + "magento/module-widget": "101.2.6", + "magento/module-wishlist": "101.2.6", + "magento/module-wishlist-graph-ql": "100.4.6", + "magento/module-wishlist-analytics": "100.4.4", + "magento/theme-adminhtml-backend": "100.4.6", + "magento/theme-frontend-blank": "100.4.6", + "magento/theme-frontend-luma": "100.4.6", + "magento/language-de_de": "100.4.0", + "magento/language-en_us": "100.4.0", + "magento/language-es_es": "100.4.0", + "magento/language-fr_fr": "100.4.0", + "magento/language-nl_nl": "100.4.0", + "magento/language-pt_br": "100.4.0", + "magento/language-zh_hans_cn": "100.4.0", + "magento/framework": "103.0.6-p3", + "magento/framework-amqp": "100.4.4", + "magento/framework-bulk": "101.0.2", + "magento/framework-message-queue": "100.4.6", "trentrichardson/jquery-timepicker-addon": "1.4.3", "components/jquery": "1.11.0", "blueimp/jquery-file-upload": "5.6.14", "components/jqueryui": "1.10.4", "twbs/bootstrap": "3.1.0", "tinymce/tinymce": "3.4.7", - "magento/module-csp": "*", - "magento/module-aws-s3": "*", - "magento/module-remote-storage": "*", - "magento/module-jwt-framework-adapter": "*", - "magento/module-jwt-user-token": "*" + "magento/module-csp": "100.4.5", + "magento/module-aws-s3": "100.4.4", + "magento/module-remote-storage": "100.4.4", + "magento/module-jwt-framework-adapter": "100.4.2", + "magento/module-jwt-user-token": "100.4.1" }, - "conflict": { - "gene/bluefoot": "*" + "autoload-dev": { + "psr-4": { + "Magento\\PhpStan\\": "dev/tests/static/framework/Magento/PhpStan/", + "Magento\\Sniffs\\": "dev/tests/static/framework/Magento/Sniffs/", + "Magento\\TestFramework\\Inspection\\": "dev/tests/static/framework/Magento/TestFramework/Inspection/", + "Magento\\TestFramework\\Utility\\": "dev/tests/static/framework/Magento/TestFramework/Utility/", + "Magento\\Tools\\": "dev/tools/Magento/Tools/", + "Magento\\Tools\\Sanity\\": "dev/build/publication/sanity/Magento/Tools/Sanity/" + } }, + "prefer-stable": true, "extra": { "component_paths": { - "trentrichardson/jquery-timepicker-addon": "lib/web/jquery/jquery-ui-timepicker-addon.js", + "blueimp/jquery-file-upload": "lib/web/jquery/fileUploader", "components/jquery": [ "lib/web/jquery.js", "lib/web/jquery/jquery.min.js" ], - "blueimp/jquery-file-upload": "lib/web/jquery/fileUploader", "components/jqueryui": [ "lib/web/jquery/jquery-ui.js" ], + "tinymce/tinymce": "lib/web/tiny_mce_5", + "trentrichardson/jquery-timepicker-addon": "lib/web/jquery/jquery-ui-timepicker-addon.js", "twbs/bootstrap": [ "lib/web/jquery/jquery.tabs.js" - ], - "tinymce/tinymce": "lib/web/tiny_mce_5" - } - }, - "autoload": { - "psr-4": { - "Magento\\Framework\\": "lib/internal/Magento/Framework/", - "Magento\\Setup\\": "setup/src/Magento/Setup/", - "Magento\\": "app/code/Magento/" - }, - "psr-0": { - "": [ - "app/code/", - "generated/code/" ] - }, - "files": [ - "app/etc/NonComposerComponentRegistration.php" - ], - "exclude-from-classmap": [ - "**/dev/**", - "**/update/**", - "**/Test/**" - ] - }, - "autoload-dev": { - "psr-4": { - "Magento\\Sniffs\\": "dev/tests/static/framework/Magento/Sniffs/", - "Magento\\Tools\\": "dev/tools/Magento/Tools/", - "Magento\\Tools\\Sanity\\": "dev/build/publication/sanity/Magento/Tools/Sanity/", - "Magento\\TestFramework\\Inspection\\": "dev/tests/static/framework/Magento/TestFramework/Inspection/", - "Magento\\TestFramework\\Utility\\": "dev/tests/static/framework/Magento/TestFramework/Utility/", - "Magento\\PhpStan\\": "dev/tests/static/framework/Magento/PhpStan/" } - }, - "prefer-stable": true + } } + diff --git a/composer.lock b/composer.lock index ae048f0928223..112f6afd80e9c 100644 --- a/composer.lock +++ b/composer.lock @@ -4,27 +4,31 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "bd4b64caee2131de1c4337fb3f8211a5", + "content-hash": "4f16566a5cb530bea89d694abc385e23", "packages": [ { "name": "aws/aws-crt-php", - "version": "v1.0.2", + "version": "v1.2.1", "source": { "type": "git", "url": "https://github.com/awslabs/aws-crt-php.git", - "reference": "3942776a8c99209908ee0b287746263725685732" + "reference": "1926277fc71d253dfa820271ac5987bdb193ccf5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/awslabs/aws-crt-php/zipball/3942776a8c99209908ee0b287746263725685732", - "reference": "3942776a8c99209908ee0b287746263725685732", + "url": "https://api.github.com/repos/awslabs/aws-crt-php/zipball/1926277fc71d253dfa820271ac5987bdb193ccf5", + "reference": "1926277fc71d253dfa820271ac5987bdb193ccf5", "shasum": "" }, "require": { "php": ">=5.5" }, "require-dev": { - "phpunit/phpunit": "^4.8.35|^5.4.3" + "phpunit/phpunit": "^4.8.35||^5.6.3||^9.5", + "yoast/phpunit-polyfills": "^1.0" + }, + "suggest": { + "ext-awscrt": "Make sure you install awscrt native extension to use any of the functionality." }, "type": "library", "autoload": { @@ -43,7 +47,7 @@ } ], "description": "AWS Common Runtime for PHP", - "homepage": "http://aws.amazon.com/sdkforphp", + "homepage": "https://github.com/awslabs/aws-crt-php", "keywords": [ "amazon", "aws", @@ -52,34 +56,35 @@ ], "support": { "issues": "https://github.com/awslabs/aws-crt-php/issues", - "source": "https://github.com/awslabs/aws-crt-php/tree/v1.0.2" + "source": "https://github.com/awslabs/aws-crt-php/tree/v1.2.1" }, - "time": "2021-09-03T22:57:30+00:00" + "time": "2023-03-24T20:22:19+00:00" }, { "name": "aws/aws-sdk-php", - "version": "3.257.2", + "version": "3.273.1", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "2511f952db0717407df0c4220068c010ccaa2de2" + "reference": "615adf6a83800936de345193b5c869f96aab1132" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/2511f952db0717407df0c4220068c010ccaa2de2", - "reference": "2511f952db0717407df0c4220068c010ccaa2de2", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/615adf6a83800936de345193b5c869f96aab1132", + "reference": "615adf6a83800936de345193b5c869f96aab1132", "shasum": "" }, "require": { - "aws/aws-crt-php": "^1.0.2", + "aws/aws-crt-php": "^1.0.4", "ext-json": "*", "ext-pcre": "*", "ext-simplexml": "*", "guzzlehttp/guzzle": "^6.5.8 || ^7.4.5", "guzzlehttp/promises": "^1.4.0", - "guzzlehttp/psr7": "^1.8.5 || ^2.3", + "guzzlehttp/psr7": "^1.9.1 || ^2.4.5", "mtdowling/jmespath.php": "^2.6", - "php": ">=5.5" + "php": ">=5.5", + "psr/http-message": "^1.0" }, "require-dev": { "andrewsville/php-token-reflection": "^1.4", @@ -146,32 +151,32 @@ "support": { "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80", "issues": "https://github.com/aws/aws-sdk-php/issues", - "source": "https://github.com/aws/aws-sdk-php/tree/3.257.2" + "source": "https://github.com/aws/aws-sdk-php/tree/3.273.1" }, - "time": "2023-01-17T19:19:40+00:00" + "time": "2023-06-15T18:23:27+00:00" }, { "name": "brick/math", - "version": "0.9.3", + "version": "0.10.2", "source": { "type": "git", "url": "https://github.com/brick/math.git", - "reference": "ca57d18f028f84f777b2168cd1911b0dee2343ae" + "reference": "459f2781e1a08d52ee56b0b1444086e038561e3f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/brick/math/zipball/ca57d18f028f84f777b2168cd1911b0dee2343ae", - "reference": "ca57d18f028f84f777b2168cd1911b0dee2343ae", + "url": "https://api.github.com/repos/brick/math/zipball/459f2781e1a08d52ee56b0b1444086e038561e3f", + "reference": "459f2781e1a08d52ee56b0b1444086e038561e3f", "shasum": "" }, "require": { "ext-json": "*", - "php": "^7.1 || ^8.0" + "php": "^7.4 || ^8.0" }, "require-dev": { "php-coveralls/php-coveralls": "^2.2", - "phpunit/phpunit": "^7.5.15 || ^8.5 || ^9.0", - "vimeo/psalm": "4.9.2" + "phpunit/phpunit": "^9.0", + "vimeo/psalm": "4.25.0" }, "type": "library", "autoload": { @@ -196,19 +201,15 @@ ], "support": { "issues": "https://github.com/brick/math/issues", - "source": "https://github.com/brick/math/tree/0.9.3" + "source": "https://github.com/brick/math/tree/0.10.2" }, "funding": [ { "url": "https://github.com/BenMorel", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/brick/math", - "type": "tidelift" } ], - "time": "2021-08-15T20:50:18+00:00" + "time": "2022-08-10T22:54:19+00:00" }, { "name": "brick/varexporter", @@ -423,16 +424,16 @@ }, { "name": "composer/ca-bundle", - "version": "1.3.4", + "version": "1.3.6", "source": { "type": "git", "url": "https://github.com/composer/ca-bundle.git", - "reference": "69098eca243998b53eed7a48d82dedd28b447cd5" + "reference": "90d087e988ff194065333d16bc5cf649872d9cdb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/ca-bundle/zipball/69098eca243998b53eed7a48d82dedd28b447cd5", - "reference": "69098eca243998b53eed7a48d82dedd28b447cd5", + "url": "https://api.github.com/repos/composer/ca-bundle/zipball/90d087e988ff194065333d16bc5cf649872d9cdb", + "reference": "90d087e988ff194065333d16bc5cf649872d9cdb", "shasum": "" }, "require": { @@ -479,7 +480,80 @@ "support": { "irc": "irc://irc.freenode.org/composer", "issues": "https://github.com/composer/ca-bundle/issues", - "source": "https://github.com/composer/ca-bundle/tree/1.3.4" + "source": "https://github.com/composer/ca-bundle/tree/1.3.6" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2023-06-06T12:02:59+00:00" + }, + { + "name": "composer/class-map-generator", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/composer/class-map-generator.git", + "reference": "1e1cb2b791facb2dfe32932a7718cf2571187513" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/class-map-generator/zipball/1e1cb2b791facb2dfe32932a7718cf2571187513", + "reference": "1e1cb2b791facb2dfe32932a7718cf2571187513", + "shasum": "" + }, + "require": { + "composer/pcre": "^2 || ^3", + "php": "^7.2 || ^8.0", + "symfony/finder": "^4.4 || ^5.3 || ^6" + }, + "require-dev": { + "phpstan/phpstan": "^1.6", + "phpstan/phpstan-deprecation-rules": "^1", + "phpstan/phpstan-phpunit": "^1", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/filesystem": "^5.4 || ^6", + "symfony/phpunit-bridge": "^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\ClassMapGenerator\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "https://seld.be" + } + ], + "description": "Utilities to scan PHP code and generate class maps.", + "keywords": [ + "classmap" + ], + "support": { + "issues": "https://github.com/composer/class-map-generator/issues", + "source": "https://github.com/composer/class-map-generator/tree/1.0.0" }, "funding": [ { @@ -495,43 +569,52 @@ "type": "tidelift" } ], - "time": "2022-10-12T12:08:29+00:00" + "time": "2022-06-19T11:31:27+00:00" }, { "name": "composer/composer", - "version": "2.2.18", + "version": "2.5.8", "source": { "type": "git", "url": "https://github.com/composer/composer.git", - "reference": "84175907664ca8b73f73f4883e67e886dfefb9f5" + "reference": "4c516146167d1392c8b9b269bb7c24115d262164" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/composer/zipball/84175907664ca8b73f73f4883e67e886dfefb9f5", - "reference": "84175907664ca8b73f73f4883e67e886dfefb9f5", + "url": "https://api.github.com/repos/composer/composer/zipball/4c516146167d1392c8b9b269bb7c24115d262164", + "reference": "4c516146167d1392c8b9b269bb7c24115d262164", "shasum": "" }, "require": { "composer/ca-bundle": "^1.0", + "composer/class-map-generator": "^1.0", "composer/metadata-minifier": "^1.0", - "composer/pcre": "^1.0", + "composer/pcre": "^2.1 || ^3.1", "composer/semver": "^3.0", - "composer/spdx-licenses": "^1.2", - "composer/xdebug-handler": "^2.0 || ^3.0", + "composer/spdx-licenses": "^1.5.7", + "composer/xdebug-handler": "^2.0.2 || ^3.0.3", "justinrainbow/json-schema": "^5.2.11", - "php": "^5.3.2 || ^7.0 || ^8.0", - "psr/log": "^1.0 || ^2.0", - "react/promise": "^1.2 || ^2.7", + "php": "^7.2.5 || ^8.0", + "psr/log": "^1.0 || ^2.0 || ^3.0", + "react/promise": "^2.8", "seld/jsonlint": "^1.4", - "seld/phar-utils": "^1.0", - "symfony/console": "^2.8.52 || ^3.4.35 || ^4.4 || ^5.0", - "symfony/filesystem": "^2.8.52 || ^3.4.35 || ^4.4 || ^5.0 || ^6.0", - "symfony/finder": "^2.8.52 || ^3.4.35 || ^4.4 || ^5.0 || ^6.0", - "symfony/process": "^2.8.52 || ^3.4.35 || ^4.4 || ^5.0 || ^6.0" + "seld/phar-utils": "^1.2", + "seld/signal-handler": "^2.0", + "symfony/console": "^5.4.11 || ^6.0.11", + "symfony/filesystem": "^5.4 || ^6.0", + "symfony/finder": "^5.4 || ^6.0", + "symfony/polyfill-php73": "^1.24", + "symfony/polyfill-php80": "^1.24", + "symfony/polyfill-php81": "^1.24", + "symfony/process": "^5.4 || ^6.0" }, "require-dev": { - "phpspec/prophecy": "^1.10", - "symfony/phpunit-bridge": "^4.2 || ^5.0 || ^6.0" + "phpstan/phpstan": "^1.9.3", + "phpstan/phpstan-deprecation-rules": "^1", + "phpstan/phpstan-phpunit": "^1.0", + "phpstan/phpstan-strict-rules": "^1", + "phpstan/phpstan-symfony": "^1.2.10", + "symfony/phpunit-bridge": "^6.0" }, "suggest": { "ext-openssl": "Enabling the openssl extension allows you to access https URLs for repositories and packages", @@ -544,7 +627,12 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "2.2-dev" + "dev-main": "2.5-dev" + }, + "phpstan": { + "includes": [ + "phpstan/rules.neon" + ] } }, "autoload": { @@ -578,7 +666,7 @@ "support": { "irc": "ircs://irc.libera.chat:6697/composer", "issues": "https://github.com/composer/composer/issues", - "source": "https://github.com/composer/composer/tree/2.2.18" + "source": "https://github.com/composer/composer/tree/2.5.8" }, "funding": [ { @@ -594,7 +682,7 @@ "type": "tidelift" } ], - "time": "2022-08-20T09:33:38+00:00" + "time": "2023-06-09T15:13:21+00:00" }, { "name": "composer/metadata-minifier", @@ -667,30 +755,30 @@ }, { "name": "composer/pcre", - "version": "1.0.1", + "version": "3.1.0", "source": { "type": "git", "url": "https://github.com/composer/pcre.git", - "reference": "67a32d7d6f9f560b726ab25a061b38ff3a80c560" + "reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/pcre/zipball/67a32d7d6f9f560b726ab25a061b38ff3a80c560", - "reference": "67a32d7d6f9f560b726ab25a061b38ff3a80c560", + "url": "https://api.github.com/repos/composer/pcre/zipball/4bff79ddd77851fe3cdd11616ed3f92841ba5bd2", + "reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2", "shasum": "" }, "require": { - "php": "^5.3.2 || ^7.0 || ^8.0" + "php": "^7.4 || ^8.0" }, "require-dev": { "phpstan/phpstan": "^1.3", "phpstan/phpstan-strict-rules": "^1.1", - "symfony/phpunit-bridge": "^4.2 || ^5" + "symfony/phpunit-bridge": "^5" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "1.x-dev" + "dev-main": "3.x-dev" } }, "autoload": { @@ -718,7 +806,7 @@ ], "support": { "issues": "https://github.com/composer/pcre/issues", - "source": "https://github.com/composer/pcre/tree/1.0.1" + "source": "https://github.com/composer/pcre/tree/3.1.0" }, "funding": [ { @@ -734,7 +822,7 @@ "type": "tidelift" } ], - "time": "2022-01-21T20:24:37+00:00" + "time": "2022-11-17T09:50:14+00:00" }, { "name": "composer/semver", @@ -1427,22 +1515,22 @@ }, { "name": "guzzlehttp/guzzle", - "version": "7.5.0", + "version": "7.7.0", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "b50a2a1251152e43f6a37f0fa053e730a67d25ba" + "reference": "fb7566caccf22d74d1ab270de3551f72a58399f5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/b50a2a1251152e43f6a37f0fa053e730a67d25ba", - "reference": "b50a2a1251152e43f6a37f0fa053e730a67d25ba", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/fb7566caccf22d74d1ab270de3551f72a58399f5", + "reference": "fb7566caccf22d74d1ab270de3551f72a58399f5", "shasum": "" }, "require": { "ext-json": "*", - "guzzlehttp/promises": "^1.5", - "guzzlehttp/psr7": "^1.9 || ^2.4", + "guzzlehttp/promises": "^1.5.3 || ^2.0", + "guzzlehttp/psr7": "^1.9.1 || ^2.4.5", "php": "^7.2.5 || ^8.0", "psr/http-client": "^1.0", "symfony/deprecation-contracts": "^2.2 || ^3.0" @@ -1453,7 +1541,8 @@ "require-dev": { "bamarni/composer-bin-plugin": "^1.8.1", "ext-curl": "*", - "php-http/client-integration-tests": "^3.0", + "php-http/client-integration-tests": "dev-master#2c025848417c1135031fdf9c728ee53d0a7ceaee as 3.0.999", + "php-http/message-factory": "^1.1", "phpunit/phpunit": "^8.5.29 || ^9.5.23", "psr/log": "^1.1 || ^2.0 || ^3.0" }, @@ -1467,9 +1556,6 @@ "bamarni-bin": { "bin-links": true, "forward-command": false - }, - "branch-alias": { - "dev-master": "7.5-dev" } }, "autoload": { @@ -1535,7 +1621,7 @@ ], "support": { "issues": "https://github.com/guzzle/guzzle/issues", - "source": "https://github.com/guzzle/guzzle/tree/7.5.0" + "source": "https://github.com/guzzle/guzzle/tree/7.7.0" }, "funding": [ { @@ -1551,20 +1637,20 @@ "type": "tidelift" } ], - "time": "2022-08-28T15:39:27+00:00" + "time": "2023-05-21T14:04:53+00:00" }, { "name": "guzzlehttp/promises", - "version": "1.5.2", + "version": "1.5.3", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "b94b2807d85443f9719887892882d0329d1e2598" + "reference": "67ab6e18aaa14d753cc148911d273f6e6cb6721e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/b94b2807d85443f9719887892882d0329d1e2598", - "reference": "b94b2807d85443f9719887892882d0329d1e2598", + "url": "https://api.github.com/repos/guzzle/promises/zipball/67ab6e18aaa14d753cc148911d273f6e6cb6721e", + "reference": "67ab6e18aaa14d753cc148911d273f6e6cb6721e", "shasum": "" }, "require": { @@ -1574,11 +1660,6 @@ "symfony/phpunit-bridge": "^4.4 || ^5.1" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.5-dev" - } - }, "autoload": { "files": [ "src/functions_include.php" @@ -1619,7 +1700,7 @@ ], "support": { "issues": "https://github.com/guzzle/promises/issues", - "source": "https://github.com/guzzle/promises/tree/1.5.2" + "source": "https://github.com/guzzle/promises/tree/1.5.3" }, "funding": [ { @@ -1635,26 +1716,26 @@ "type": "tidelift" } ], - "time": "2022-08-28T14:55:35+00:00" + "time": "2023-05-21T12:31:43+00:00" }, { "name": "guzzlehttp/psr7", - "version": "2.4.3", + "version": "2.5.0", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "67c26b443f348a51926030c83481b85718457d3d" + "reference": "b635f279edd83fc275f822a1188157ffea568ff6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/67c26b443f348a51926030c83481b85718457d3d", - "reference": "67c26b443f348a51926030c83481b85718457d3d", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/b635f279edd83fc275f822a1188157ffea568ff6", + "reference": "b635f279edd83fc275f822a1188157ffea568ff6", "shasum": "" }, "require": { "php": "^7.2.5 || ^8.0", "psr/http-factory": "^1.0", - "psr/http-message": "^1.0", + "psr/http-message": "^1.1 || ^2.0", "ralouphie/getallheaders": "^3.0" }, "provide": { @@ -1674,9 +1755,6 @@ "bamarni-bin": { "bin-links": true, "forward-command": false - }, - "branch-alias": { - "dev-master": "2.4-dev" } }, "autoload": { @@ -1738,7 +1816,7 @@ ], "support": { "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/2.4.3" + "source": "https://github.com/guzzle/psr7/tree/2.5.0" }, "funding": [ { @@ -1754,7 +1832,7 @@ "type": "tidelift" } ], - "time": "2022-10-26T14:07:24+00:00" + "time": "2023-04-17T16:11:26+00:00" }, { "name": "justinrainbow/json-schema", @@ -4950,16 +5028,16 @@ }, { "name": "monolog/monolog", - "version": "2.8.0", + "version": "2.9.1", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "720488632c590286b88b80e62aa3d3d551ad4a50" + "reference": "f259e2b15fb95494c83f52d3caad003bbf5ffaa1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/720488632c590286b88b80e62aa3d3d551ad4a50", - "reference": "720488632c590286b88b80e62aa3d3d551ad4a50", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/f259e2b15fb95494c83f52d3caad003bbf5ffaa1", + "reference": "f259e2b15fb95494c83f52d3caad003bbf5ffaa1", "shasum": "" }, "require": { @@ -4974,7 +5052,7 @@ "doctrine/couchdb": "~1.0@dev", "elasticsearch/elasticsearch": "^7 || ^8", "ext-json": "*", - "graylog2/gelf-php": "^1.4.2", + "graylog2/gelf-php": "^1.4.2 || ^2@dev", "guzzlehttp/guzzle": "^7.4", "guzzlehttp/psr7": "^2.2", "mongodb/mongodb": "^1.8", @@ -5036,7 +5114,7 @@ ], "support": { "issues": "https://github.com/Seldaek/monolog/issues", - "source": "https://github.com/Seldaek/monolog/tree/2.8.0" + "source": "https://github.com/Seldaek/monolog/tree/2.9.1" }, "funding": [ { @@ -5048,7 +5126,7 @@ "type": "tidelift" } ], - "time": "2022-07-24T11:55:47+00:00" + "time": "2023-02-06T13:44:46+00:00" }, { "name": "mtdowling/jmespath.php", @@ -5113,16 +5191,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.14.0", + "version": "v4.15.5", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "34bea19b6e03d8153165d8f30bba4c3be86184c1" + "reference": "11e2663a5bc9db5d714eedb4277ee300403b4a9e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/34bea19b6e03d8153165d8f30bba4c3be86184c1", - "reference": "34bea19b6e03d8153165d8f30bba4c3be86184c1", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/11e2663a5bc9db5d714eedb4277ee300403b4a9e", + "reference": "11e2663a5bc9db5d714eedb4277ee300403b4a9e", "shasum": "" }, "require": { @@ -5163,9 +5241,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.14.0" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.5" }, - "time": "2022-05-31T20:59:12+00:00" + "time": "2023-05-19T20:20:00+00:00" }, { "name": "opensearch-project/opensearch-php", @@ -5233,16 +5311,16 @@ }, { "name": "paragonie/constant_time_encoding", - "version": "v2.5.0", + "version": "v2.6.3", "source": { "type": "git", "url": "https://github.com/paragonie/constant_time_encoding.git", - "reference": "9229e15f2e6ba772f0c55dd6986c563b937170a8" + "reference": "58c3f47f650c94ec05a151692652a868995d2938" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/9229e15f2e6ba772f0c55dd6986c563b937170a8", - "reference": "9229e15f2e6ba772f0c55dd6986c563b937170a8", + "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/58c3f47f650c94ec05a151692652a868995d2938", + "reference": "58c3f47f650c94ec05a151692652a868995d2938", "shasum": "" }, "require": { @@ -5296,7 +5374,7 @@ "issues": "https://github.com/paragonie/constant_time_encoding/issues", "source": "https://github.com/paragonie/constant_time_encoding" }, - "time": "2022-01-17T05:32:27+00:00" + "time": "2022-06-14T06:56:20+00:00" }, { "name": "paragonie/random_compat", @@ -5428,16 +5506,16 @@ }, { "name": "php-amqplib/php-amqplib", - "version": "v3.2.0", + "version": "v3.5.3", "source": { "type": "git", "url": "https://github.com/php-amqplib/php-amqplib.git", - "reference": "0bec5b392428e0ac3b3f34fbc4e02d706995833e" + "reference": "bccaaf8ef8bcf18b4ab41e645e92537752b887bd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-amqplib/php-amqplib/zipball/0bec5b392428e0ac3b3f34fbc4e02d706995833e", - "reference": "0bec5b392428e0ac3b3f34fbc4e02d706995833e", + "url": "https://api.github.com/repos/php-amqplib/php-amqplib/zipball/bccaaf8ef8bcf18b4ab41e645e92537752b887bd", + "reference": "bccaaf8ef8bcf18b4ab41e645e92537752b887bd", "shasum": "" }, "require": { @@ -5503,9 +5581,9 @@ ], "support": { "issues": "https://github.com/php-amqplib/php-amqplib/issues", - "source": "https://github.com/php-amqplib/php-amqplib/tree/v3.2.0" + "source": "https://github.com/php-amqplib/php-amqplib/tree/v3.5.3" }, - "time": "2022-03-10T19:16:00+00:00" + "time": "2023-04-03T18:25:49+00:00" }, { "name": "phpseclib/mcrypt_compat", @@ -5577,16 +5655,16 @@ }, { "name": "phpseclib/phpseclib", - "version": "3.0.18", + "version": "3.0.20", "source": { "type": "git", "url": "https://github.com/phpseclib/phpseclib.git", - "reference": "f28693d38ba21bb0d9f0c411ee5dae2b178201da" + "reference": "543a1da81111a0bfd6ae7bbc2865c5e89ed3fc67" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/f28693d38ba21bb0d9f0c411ee5dae2b178201da", - "reference": "f28693d38ba21bb0d9f0c411ee5dae2b178201da", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/543a1da81111a0bfd6ae7bbc2865c5e89ed3fc67", + "reference": "543a1da81111a0bfd6ae7bbc2865c5e89ed3fc67", "shasum": "" }, "require": { @@ -5667,7 +5745,7 @@ ], "support": { "issues": "https://github.com/phpseclib/phpseclib/issues", - "source": "https://github.com/phpseclib/phpseclib/tree/3.0.18" + "source": "https://github.com/phpseclib/phpseclib/tree/3.0.20" }, "funding": [ { @@ -5683,7 +5761,7 @@ "type": "tidelift" } ], - "time": "2022-12-17T18:26:50+00:00" + "time": "2023-06-13T06:30:34+00:00" }, { "name": "psr/cache", @@ -5834,21 +5912,21 @@ }, { "name": "psr/http-client", - "version": "1.0.1", + "version": "1.0.2", "source": { "type": "git", "url": "https://github.com/php-fig/http-client.git", - "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621" + "reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", - "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/0955afe48220520692d2d09f7ab7e0f93ffd6a31", + "reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31", "shasum": "" }, "require": { "php": "^7.0 || ^8.0", - "psr/http-message": "^1.0" + "psr/http-message": "^1.0 || ^2.0" }, "type": "library", "extra": { @@ -5868,7 +5946,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common interface for HTTP clients", @@ -5880,27 +5958,27 @@ "psr-18" ], "support": { - "source": "https://github.com/php-fig/http-client/tree/master" + "source": "https://github.com/php-fig/http-client/tree/1.0.2" }, - "time": "2020-06-29T06:28:15+00:00" + "time": "2023-04-10T20:12:12+00:00" }, { "name": "psr/http-factory", - "version": "1.0.1", + "version": "1.0.2", "source": { "type": "git", "url": "https://github.com/php-fig/http-factory.git", - "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be" + "reference": "e616d01114759c4c489f93b099585439f795fe35" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-factory/zipball/12ac7fcd07e5b077433f5f2bee95b3a771bf61be", - "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35", + "reference": "e616d01114759c4c489f93b099585439f795fe35", "shasum": "" }, "require": { "php": ">=7.0.0", - "psr/http-message": "^1.0" + "psr/http-message": "^1.0 || ^2.0" }, "type": "library", "extra": { @@ -5920,7 +5998,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common interfaces for PSR-7 HTTP message factories", @@ -5935,31 +6013,31 @@ "response" ], "support": { - "source": "https://github.com/php-fig/http-factory/tree/master" + "source": "https://github.com/php-fig/http-factory/tree/1.0.2" }, - "time": "2019-04-30T12:38:16+00:00" + "time": "2023-04-10T20:10:41+00:00" }, { "name": "psr/http-message", - "version": "1.0.1", + "version": "1.1", "source": { "type": "git", "url": "https://github.com/php-fig/http-message.git", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/cb6ce4845ce34a8ad9e68117c10ee90a29919eba", + "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": "^7.2 || ^8.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.1.x-dev" } }, "autoload": { @@ -5988,9 +6066,9 @@ "response" ], "support": { - "source": "https://github.com/php-fig/http-message/tree/master" + "source": "https://github.com/php-fig/http-message/tree/1.1" }, - "time": "2016-08-06T14:39:51+00:00" + "time": "2023-04-04T09:50:52+00:00" }, { "name": "psr/log", @@ -6088,42 +6166,52 @@ }, { "name": "ramsey/collection", - "version": "1.2.2", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/ramsey/collection.git", - "reference": "cccc74ee5e328031b15640b51056ee8d3bb66c0a" + "reference": "a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/collection/zipball/cccc74ee5e328031b15640b51056ee8d3bb66c0a", - "reference": "cccc74ee5e328031b15640b51056ee8d3bb66c0a", + "url": "https://api.github.com/repos/ramsey/collection/zipball/a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5", + "reference": "a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5", "shasum": "" }, "require": { - "php": "^7.3 || ^8", - "symfony/polyfill-php81": "^1.23" + "php": "^8.1" }, "require-dev": { - "captainhook/captainhook": "^5.3", - "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", - "ergebnis/composer-normalize": "^2.6", - "fakerphp/faker": "^1.5", - "hamcrest/hamcrest-php": "^2", - "jangregor/phpstan-prophecy": "^0.8", - "mockery/mockery": "^1.3", + "captainhook/plugin-composer": "^5.3", + "ergebnis/composer-normalize": "^2.28.3", + "fakerphp/faker": "^1.21", + "hamcrest/hamcrest-php": "^2.0", + "jangregor/phpstan-prophecy": "^1.0", + "mockery/mockery": "^1.5", + "php-parallel-lint/php-console-highlighter": "^1.0", + "php-parallel-lint/php-parallel-lint": "^1.3", + "phpcsstandards/phpcsutils": "^1.0.0-rc1", "phpspec/prophecy-phpunit": "^2.0", - "phpstan/extension-installer": "^1", - "phpstan/phpstan": "^0.12.32", - "phpstan/phpstan-mockery": "^0.12.5", - "phpstan/phpstan-phpunit": "^0.12.11", - "phpunit/phpunit": "^8.5 || ^9", - "psy/psysh": "^0.10.4", - "slevomat/coding-standard": "^6.3", - "squizlabs/php_codesniffer": "^3.5", - "vimeo/psalm": "^4.4" + "phpstan/extension-installer": "^1.2", + "phpstan/phpstan": "^1.9", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-phpunit": "^1.3", + "phpunit/phpunit": "^9.5", + "psalm/plugin-mockery": "^1.1", + "psalm/plugin-phpunit": "^0.18.4", + "ramsey/coding-standard": "^2.0.3", + "ramsey/conventional-commits": "^1.3", + "vimeo/psalm": "^5.4" }, "type": "library", + "extra": { + "captainhook": { + "force-install": true + }, + "ramsey/conventional-commits": { + "configFile": "conventional-commits.json" + } + }, "autoload": { "psr-4": { "Ramsey\\Collection\\": "src/" @@ -6151,7 +6239,7 @@ ], "support": { "issues": "https://github.com/ramsey/collection/issues", - "source": "https://github.com/ramsey/collection/tree/1.2.2" + "source": "https://github.com/ramsey/collection/tree/2.0.0" }, "funding": [ { @@ -6163,29 +6251,27 @@ "type": "tidelift" } ], - "time": "2021-10-10T03:01:02+00:00" + "time": "2022-12-31T21:50:55+00:00" }, { "name": "ramsey/uuid", - "version": "4.2.3", + "version": "4.7.4", "source": { "type": "git", "url": "https://github.com/ramsey/uuid.git", - "reference": "fc9bb7fb5388691fd7373cd44dcb4d63bbcf24df" + "reference": "60a4c63ab724854332900504274f6150ff26d286" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/uuid/zipball/fc9bb7fb5388691fd7373cd44dcb4d63bbcf24df", - "reference": "fc9bb7fb5388691fd7373cd44dcb4d63bbcf24df", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/60a4c63ab724854332900504274f6150ff26d286", + "reference": "60a4c63ab724854332900504274f6150ff26d286", "shasum": "" }, "require": { - "brick/math": "^0.8 || ^0.9", + "brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11", "ext-json": "*", - "php": "^7.2 || ^8.0", - "ramsey/collection": "^1.0", - "symfony/polyfill-ctype": "^1.8", - "symfony/polyfill-php80": "^1.14" + "php": "^8.0", + "ramsey/collection": "^1.2 || ^2.0" }, "replace": { "rhumsaa/uuid": "self.version" @@ -6197,24 +6283,23 @@ "doctrine/annotations": "^1.8", "ergebnis/composer-normalize": "^2.15", "mockery/mockery": "^1.3", - "moontoast/math": "^1.1", "paragonie/random-lib": "^2", "php-mock/php-mock": "^2.2", "php-mock/php-mock-mockery": "^1.3", "php-parallel-lint/php-parallel-lint": "^1.1", "phpbench/phpbench": "^1.0", - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^0.12", - "phpstan/phpstan-mockery": "^0.12", - "phpstan/phpstan-phpunit": "^0.12", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-phpunit": "^1.1", "phpunit/phpunit": "^8.5 || ^9", - "slevomat/coding-standard": "^7.0", + "ramsey/composer-repl": "^1.4", + "slevomat/coding-standard": "^8.4", "squizlabs/php_codesniffer": "^3.5", "vimeo/psalm": "^4.9" }, "suggest": { "ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.", - "ext-ctype": "Enables faster processing of character classification using ctype functions.", "ext-gmp": "Enables faster math with arbitrary-precision integers using GMP.", "ext-uuid": "Enables the use of PeclUuidTimeGenerator and PeclUuidRandomGenerator.", "paragonie/random-lib": "Provides RandomLib for use with the RandomLibAdapter", @@ -6222,9 +6307,6 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "4.x-dev" - }, "captainhook": { "force-install": true } @@ -6249,7 +6331,7 @@ ], "support": { "issues": "https://github.com/ramsey/uuid/issues", - "source": "https://github.com/ramsey/uuid/tree/4.2.3" + "source": "https://github.com/ramsey/uuid/tree/4.7.4" }, "funding": [ { @@ -6261,27 +6343,27 @@ "type": "tidelift" } ], - "time": "2021-09-25T23:10:38+00:00" + "time": "2023-04-15T23:01:58+00:00" }, { "name": "react/promise", - "version": "v2.9.0", + "version": "v2.10.0", "source": { "type": "git", "url": "https://github.com/reactphp/promise.git", - "reference": "234f8fd1023c9158e2314fa9d7d0e6a83db42910" + "reference": "f913fb8cceba1e6644b7b90c4bfb678ed8a3ef38" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/reactphp/promise/zipball/234f8fd1023c9158e2314fa9d7d0e6a83db42910", - "reference": "234f8fd1023c9158e2314fa9d7d0e6a83db42910", + "url": "https://api.github.com/repos/reactphp/promise/zipball/f913fb8cceba1e6644b7b90c4bfb678ed8a3ef38", + "reference": "f913fb8cceba1e6644b7b90c4bfb678ed8a3ef38", "shasum": "" }, "require": { "php": ">=5.4.0" }, "require-dev": { - "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.36" + "phpunit/phpunit": "^9.5 || ^5.7 || ^4.8.36" }, "type": "library", "autoload": { @@ -6325,19 +6407,15 @@ ], "support": { "issues": "https://github.com/reactphp/promise/issues", - "source": "https://github.com/reactphp/promise/tree/v2.9.0" + "source": "https://github.com/reactphp/promise/tree/v2.10.0" }, "funding": [ { - "url": "https://github.com/WyriHaximus", - "type": "github" - }, - { - "url": "https://github.com/clue", - "type": "github" + "url": "https://opencollective.com/reactphp", + "type": "open_collective" } ], - "time": "2022-02-11T10:27:51+00:00" + "time": "2023-05-02T15:15:43+00:00" }, { "name": "sabberworm/php-css-parser", @@ -6394,16 +6472,16 @@ }, { "name": "seld/jsonlint", - "version": "1.9.0", + "version": "1.10.0", "source": { "type": "git", "url": "https://github.com/Seldaek/jsonlint.git", - "reference": "4211420d25eba80712bff236a98960ef68b866b7" + "reference": "594fd6462aad8ecee0b45ca5045acea4776667f1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/4211420d25eba80712bff236a98960ef68b866b7", - "reference": "4211420d25eba80712bff236a98960ef68b866b7", + "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/594fd6462aad8ecee0b45ca5045acea4776667f1", + "reference": "594fd6462aad8ecee0b45ca5045acea4776667f1", "shasum": "" }, "require": { @@ -6442,7 +6520,7 @@ ], "support": { "issues": "https://github.com/Seldaek/jsonlint/issues", - "source": "https://github.com/Seldaek/jsonlint/tree/1.9.0" + "source": "https://github.com/Seldaek/jsonlint/tree/1.10.0" }, "funding": [ { @@ -6454,7 +6532,7 @@ "type": "tidelift" } ], - "time": "2022-04-01T13:37:23+00:00" + "time": "2023-05-11T13:16:46+00:00" }, { "name": "seld/phar-utils", @@ -6504,6 +6582,67 @@ }, "time": "2022-08-31T10:31:18+00:00" }, + { + "name": "seld/signal-handler", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/signal-handler.git", + "reference": "f69d119511dc0360440cdbdaa71829c149b7be75" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/signal-handler/zipball/f69d119511dc0360440cdbdaa71829c149b7be75", + "reference": "f69d119511dc0360440cdbdaa71829c149b7be75", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "require-dev": { + "phpstan/phpstan": "^1", + "phpstan/phpstan-deprecation-rules": "^1.0", + "phpstan/phpstan-phpunit": "^1", + "phpstan/phpstan-strict-rules": "^1.3", + "phpunit/phpunit": "^7.5.20 || ^8.5.23", + "psr/log": "^1 || ^2 || ^3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Seld\\Signal\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Simple unix signal handler that silently fails where signals are not supported for easy cross-platform development", + "keywords": [ + "posix", + "sigint", + "signal", + "sigterm", + "unix" + ], + "support": { + "issues": "https://github.com/Seldaek/signal-handler/issues", + "source": "https://github.com/Seldaek/signal-handler/tree/2.0.1" + }, + "time": "2022-07-20T18:31:45+00:00" + }, { "name": "spomky-labs/aes-key-wrap", "version": "v7.0.0", @@ -6661,16 +6800,16 @@ }, { "name": "symfony/console", - "version": "v5.4.16", + "version": "v5.4.24", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "8e9b9c8dfb33af6057c94e1b44846bee700dc5ef" + "reference": "560fc3ed7a43e6d30ea94a07d77f9a60b8ed0fb8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/8e9b9c8dfb33af6057c94e1b44846bee700dc5ef", - "reference": "8e9b9c8dfb33af6057c94e1b44846bee700dc5ef", + "url": "https://api.github.com/repos/symfony/console/zipball/560fc3ed7a43e6d30ea94a07d77f9a60b8ed0fb8", + "reference": "560fc3ed7a43e6d30ea94a07d77f9a60b8ed0fb8", "shasum": "" }, "require": { @@ -6735,12 +6874,12 @@ "homepage": "https://symfony.com", "keywords": [ "cli", - "command line", + "command-line", "console", "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v5.4.16" + "source": "https://github.com/symfony/console/tree/v5.4.24" }, "funding": [ { @@ -6756,25 +6895,24 @@ "type": "tidelift" } ], - "time": "2022-11-25T14:09:27+00:00" + "time": "2023-05-26T05:13:16+00:00" }, { "name": "symfony/css-selector", - "version": "v5.4.3", + "version": "v6.3.0", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "b0a190285cd95cb019237851205b8140ef6e368e" + "reference": "88453e64cd86c5b60e8d2fb2c6f953bbc353ffbf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/b0a190285cd95cb019237851205b8140ef6e368e", - "reference": "b0a190285cd95cb019237851205b8140ef6e368e", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/88453e64cd86c5b60e8d2fb2c6f953bbc353ffbf", + "reference": "88453e64cd86c5b60e8d2fb2c6f953bbc353ffbf", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/polyfill-php80": "^1.16" + "php": ">=8.1" }, "type": "library", "autoload": { @@ -6806,7 +6944,7 @@ "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/css-selector/tree/v5.4.3" + "source": "https://github.com/symfony/css-selector/tree/v6.3.0" }, "funding": [ { @@ -6822,7 +6960,7 @@ "type": "tidelift" } ], - "time": "2022-01-02T09:53:40+00:00" + "time": "2023-03-20T16:43:42+00:00" }, { "name": "symfony/dependency-injection", @@ -6915,25 +7053,25 @@ }, { "name": "symfony/deprecation-contracts", - "version": "v2.5.2", + "version": "v3.3.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66" + "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e8b495ea28c1d97b5e0c121748d6f9b53d075c66", - "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf", + "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=8.1" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "2.5-dev" + "dev-main": "3.4-dev" }, "thanks": { "name": "symfony/contracts", @@ -6962,7 +7100,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.2" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.3.0" }, "funding": [ { @@ -6978,7 +7116,7 @@ "type": "tidelift" } ], - "time": "2022-01-02T09:53:40+00:00" + "time": "2023-05-23T14:45:45+00:00" }, { "name": "symfony/error-handler", @@ -7053,44 +7191,39 @@ }, { "name": "symfony/event-dispatcher", - "version": "v5.4.9", + "version": "v6.3.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "8e6ce1cc0279e3ff3c8ff0f43813bc88d21ca1bc" + "reference": "3af8ac1a3f98f6dbc55e10ae59c9e44bfc38dfaa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/8e6ce1cc0279e3ff3c8ff0f43813bc88d21ca1bc", - "reference": "8e6ce1cc0279e3ff3c8ff0f43813bc88d21ca1bc", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/3af8ac1a3f98f6dbc55e10ae59c9e44bfc38dfaa", + "reference": "3af8ac1a3f98f6dbc55e10ae59c9e44bfc38dfaa", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/event-dispatcher-contracts": "^2|^3", - "symfony/polyfill-php80": "^1.16" + "php": ">=8.1", + "symfony/event-dispatcher-contracts": "^2.5|^3" }, "conflict": { - "symfony/dependency-injection": "<4.4" + "symfony/dependency-injection": "<5.4", + "symfony/service-contracts": "<2.5" }, "provide": { "psr/event-dispatcher-implementation": "1.0", - "symfony/event-dispatcher-implementation": "2.0" + "symfony/event-dispatcher-implementation": "2.0|3.0" }, "require-dev": { "psr/log": "^1|^2|^3", - "symfony/config": "^4.4|^5.0|^6.0", - "symfony/dependency-injection": "^4.4|^5.0|^6.0", - "symfony/error-handler": "^4.4|^5.0|^6.0", - "symfony/expression-language": "^4.4|^5.0|^6.0", - "symfony/http-foundation": "^4.4|^5.0|^6.0", - "symfony/service-contracts": "^1.1|^2|^3", - "symfony/stopwatch": "^4.4|^5.0|^6.0" - }, - "suggest": { - "symfony/dependency-injection": "", - "symfony/http-kernel": "" + "symfony/config": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/error-handler": "^5.4|^6.0", + "symfony/expression-language": "^5.4|^6.0", + "symfony/http-foundation": "^5.4|^6.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/stopwatch": "^5.4|^6.0" }, "type": "library", "autoload": { @@ -7118,7 +7251,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v5.4.9" + "source": "https://github.com/symfony/event-dispatcher/tree/v6.3.0" }, "funding": [ { @@ -7134,33 +7267,30 @@ "type": "tidelift" } ], - "time": "2022-05-05T16:45:39+00:00" + "time": "2023-04-21T14:41:17+00:00" }, { "name": "symfony/event-dispatcher-contracts", - "version": "v3.1.1", + "version": "v3.3.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "02ff5eea2f453731cfbc6bc215e456b781480448" + "reference": "a76aed96a42d2b521153fb382d418e30d18b59df" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/02ff5eea2f453731cfbc6bc215e456b781480448", - "reference": "02ff5eea2f453731cfbc6bc215e456b781480448", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/a76aed96a42d2b521153fb382d418e30d18b59df", + "reference": "a76aed96a42d2b521153fb382d418e30d18b59df", "shasum": "" }, "require": { "php": ">=8.1", "psr/event-dispatcher": "^1" }, - "suggest": { - "symfony/event-dispatcher-implementation": "" - }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.1-dev" + "dev-main": "3.4-dev" }, "thanks": { "name": "symfony/contracts", @@ -7197,7 +7327,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.1.1" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.3.0" }, "funding": [ { @@ -7213,27 +7343,26 @@ "type": "tidelift" } ], - "time": "2022-02-25T11:15:52+00:00" + "time": "2023-05-23T14:45:45+00:00" }, { "name": "symfony/filesystem", - "version": "v5.4.13", + "version": "v6.3.0", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "ac09569844a9109a5966b9438fc29113ce77cf51" + "reference": "97b698e1d77d356304def77a8d0cd73090b359ea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/ac09569844a9109a5966b9438fc29113ce77cf51", - "reference": "ac09569844a9109a5966b9438fc29113ce77cf51", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/97b698e1d77d356304def77a8d0cd73090b359ea", + "reference": "97b698e1d77d356304def77a8d0cd73090b359ea", "shasum": "" }, "require": { - "php": ">=7.2.5", + "php": ">=8.1", "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-mbstring": "~1.8", - "symfony/polyfill-php80": "^1.16" + "symfony/polyfill-mbstring": "~1.8" }, "type": "library", "autoload": { @@ -7261,7 +7390,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v5.4.13" + "source": "https://github.com/symfony/filesystem/tree/v6.3.0" }, "funding": [ { @@ -7277,20 +7406,20 @@ "type": "tidelift" } ], - "time": "2022-09-21T19:53:16+00:00" + "time": "2023-05-30T17:12:32+00:00" }, { "name": "symfony/finder", - "version": "v5.4.11", + "version": "v5.4.21", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "7872a66f57caffa2916a584db1aa7f12adc76f8c" + "reference": "078e9a5e1871fcfe6a5ce421b539344c21afef19" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/7872a66f57caffa2916a584db1aa7f12adc76f8c", - "reference": "7872a66f57caffa2916a584db1aa7f12adc76f8c", + "url": "https://api.github.com/repos/symfony/finder/zipball/078e9a5e1871fcfe6a5ce421b539344c21afef19", + "reference": "078e9a5e1871fcfe6a5ce421b539344c21afef19", "shasum": "" }, "require": { @@ -7324,7 +7453,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v5.4.11" + "source": "https://github.com/symfony/finder/tree/v5.4.21" }, "funding": [ { @@ -7340,20 +7469,20 @@ "type": "tidelift" } ], - "time": "2022-07-29T07:37:50+00:00" + "time": "2023-02-16T09:33:00+00:00" }, { "name": "symfony/http-foundation", - "version": "v5.4.10", + "version": "v5.4.24", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "e7793b7906f72a8cc51054fbca9dcff7a8af1c1e" + "reference": "3c59f97f6249ce552a44f01b93bfcbd786a954f5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/e7793b7906f72a8cc51054fbca9dcff7a8af1c1e", - "reference": "e7793b7906f72a8cc51054fbca9dcff7a8af1c1e", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/3c59f97f6249ce552a44f01b93bfcbd786a954f5", + "reference": "3c59f97f6249ce552a44f01b93bfcbd786a954f5", "shasum": "" }, "require": { @@ -7365,8 +7494,11 @@ "require-dev": { "predis/predis": "~1.0", "symfony/cache": "^4.4|^5.0|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", "symfony/expression-language": "^4.4|^5.0|^6.0", - "symfony/mime": "^4.4|^5.0|^6.0" + "symfony/http-kernel": "^5.4.12|^6.0.12|^6.1.4", + "symfony/mime": "^4.4|^5.0|^6.0", + "symfony/rate-limiter": "^5.2|^6.0" }, "suggest": { "symfony/mime": "To use the file extension guesser" @@ -7397,7 +7529,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v5.4.10" + "source": "https://github.com/symfony/http-foundation/tree/v5.4.24" }, "funding": [ { @@ -7413,7 +7545,7 @@ "type": "tidelift" } ], - "time": "2022-06-19T13:13:40+00:00" + "time": "2023-05-19T07:21:23+00:00" }, { "name": "symfony/http-kernel", @@ -7780,16 +7912,16 @@ }, { "name": "symfony/polyfill-intl-idn", - "version": "v1.26.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "59a8d271f00dd0e4c2e518104cc7963f655a1aa8" + "reference": "639084e360537a19f9ee352433b84ce831f3d2da" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/59a8d271f00dd0e4c2e518104cc7963f655a1aa8", - "reference": "59a8d271f00dd0e4c2e518104cc7963f655a1aa8", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/639084e360537a19f9ee352433b84ce831f3d2da", + "reference": "639084e360537a19f9ee352433b84ce831f3d2da", "shasum": "" }, "require": { @@ -7803,7 +7935,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -7847,7 +7979,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.27.0" }, "funding": [ { @@ -7863,7 +7995,7 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "symfony/polyfill-intl-normalizer", @@ -8034,16 +8166,16 @@ }, { "name": "symfony/polyfill-php72", - "version": "v1.26.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "bf44a9fd41feaac72b074de600314a93e2ae78e2" + "reference": "869329b1e9894268a8a61dabb69153029b7a8c97" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/bf44a9fd41feaac72b074de600314a93e2ae78e2", - "reference": "bf44a9fd41feaac72b074de600314a93e2ae78e2", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/869329b1e9894268a8a61dabb69153029b7a8c97", + "reference": "869329b1e9894268a8a61dabb69153029b7a8c97", "shasum": "" }, "require": { @@ -8052,7 +8184,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -8090,7 +8222,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php72/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-php72/tree/v1.27.0" }, "funding": [ { @@ -8106,7 +8238,7 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "symfony/polyfill-php73", @@ -8272,16 +8404,16 @@ }, { "name": "symfony/polyfill-php81", - "version": "v1.26.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php81.git", - "reference": "13f6d1271c663dc5ae9fb843a8f16521db7687a1" + "reference": "707403074c8ea6e2edaf8794b0157a0bfa52157a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/13f6d1271c663dc5ae9fb843a8f16521db7687a1", - "reference": "13f6d1271c663dc5ae9fb843a8f16521db7687a1", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/707403074c8ea6e2edaf8794b0157a0bfa52157a", + "reference": "707403074c8ea6e2edaf8794b0157a0bfa52157a", "shasum": "" }, "require": { @@ -8290,7 +8422,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -8331,7 +8463,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php81/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-php81/tree/v1.27.0" }, "funding": [ { @@ -8347,20 +8479,20 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "symfony/process", - "version": "v5.4.11", + "version": "v5.4.23", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "6e75fe6874cbc7e4773d049616ab450eff537bf1" + "reference": "4b842fc4b61609e0a155a114082bd94e31e98287" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/6e75fe6874cbc7e4773d049616ab450eff537bf1", - "reference": "6e75fe6874cbc7e4773d049616ab450eff537bf1", + "url": "https://api.github.com/repos/symfony/process/zipball/4b842fc4b61609e0a155a114082bd94e31e98287", + "reference": "4b842fc4b61609e0a155a114082bd94e31e98287", "shasum": "" }, "require": { @@ -8393,7 +8525,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v5.4.11" + "source": "https://github.com/symfony/process/tree/v5.4.23" }, "funding": [ { @@ -8409,7 +8541,7 @@ "type": "tidelift" } ], - "time": "2022-06-27T16:58:25+00:00" + "time": "2023-04-18T13:50:24+00:00" }, { "name": "symfony/service-contracts", @@ -8496,16 +8628,16 @@ }, { "name": "symfony/string", - "version": "v5.4.15", + "version": "v5.4.22", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "571334ce9f687e3e6af72db4d3b2a9431e4fd9ed" + "reference": "8036a4c76c0dd29e60b6a7cafcacc50cf088ea62" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/571334ce9f687e3e6af72db4d3b2a9431e4fd9ed", - "reference": "571334ce9f687e3e6af72db4d3b2a9431e4fd9ed", + "url": "https://api.github.com/repos/symfony/string/zipball/8036a4c76c0dd29e60b6a7cafcacc50cf088ea62", + "reference": "8036a4c76c0dd29e60b6a7cafcacc50cf088ea62", "shasum": "" }, "require": { @@ -8562,7 +8694,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v5.4.15" + "source": "https://github.com/symfony/string/tree/v5.4.22" }, "funding": [ { @@ -8578,43 +8710,36 @@ "type": "tidelift" } ], - "time": "2022-10-05T15:16:54+00:00" + "time": "2023-03-14T06:11:53+00:00" }, { "name": "symfony/var-dumper", - "version": "v5.4.9", + "version": "v6.3.0", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "af52239a330fafd192c773795520dc2dd62b5657" + "reference": "6acdcd5c122074ee9f7b051e4fb177025c277a0e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/af52239a330fafd192c773795520dc2dd62b5657", - "reference": "af52239a330fafd192c773795520dc2dd62b5657", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/6acdcd5c122074ee9f7b051e4fb177025c277a0e", + "reference": "6acdcd5c122074ee9f7b051e4fb177025c277a0e", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php80": "^1.16" + "php": ">=8.1", + "symfony/polyfill-mbstring": "~1.0" }, "conflict": { - "phpunit/phpunit": "<5.4.3", - "symfony/console": "<4.4" + "symfony/console": "<5.4" }, "require-dev": { "ext-iconv": "*", - "symfony/console": "^4.4|^5.0|^6.0", - "symfony/process": "^4.4|^5.0|^6.0", - "symfony/uid": "^5.1|^6.0", + "symfony/console": "^5.4|^6.0", + "symfony/process": "^5.4|^6.0", + "symfony/uid": "^5.4|^6.0", "twig/twig": "^2.13|^3.0.4" }, - "suggest": { - "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).", - "ext-intl": "To show region name in time zone dump", - "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script" - }, "bin": [ "Resources/bin/var-dump-server" ], @@ -8651,7 +8776,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v5.4.9" + "source": "https://github.com/symfony/var-dumper/tree/v6.3.0" }, "funding": [ { @@ -8667,7 +8792,7 @@ "type": "tidelift" } ], - "time": "2022-05-21T10:24:18+00:00" + "time": "2023-05-25T13:09:35+00:00" }, { "name": "tedivm/jshrink", @@ -9229,34 +9354,35 @@ "packages-dev": [ { "name": "allure-framework/allure-codeception", - "version": "1.5.2", + "version": "v2.3.0", "source": { "type": "git", "url": "https://github.com/allure-framework/allure-codeception.git", - "reference": "a6156aef942a4e4de0add34a73d066a9458cefc6" + "reference": "d28f6ba7139406974b977e5611bc65b59c492a55" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/allure-framework/allure-codeception/zipball/a6156aef942a4e4de0add34a73d066a9458cefc6", - "reference": "a6156aef942a4e4de0add34a73d066a9458cefc6", + "url": "https://api.github.com/repos/allure-framework/allure-codeception/zipball/d28f6ba7139406974b977e5611bc65b59c492a55", + "reference": "d28f6ba7139406974b977e5611bc65b59c492a55", "shasum": "" }, "require": { - "allure-framework/allure-php-api": "^1.3", - "codeception/codeception": "^2.5 | ^3 | ^4", + "allure-framework/allure-php-commons": "^2.3.1", + "codeception/codeception": "^5.0.3", "ext-json": "*", - "php": ">=7.1.3", - "symfony/filesystem": "^2.7 | ^3 | ^4 | ^5", - "symfony/finder": "^2.7 | ^3 | ^4 | ^5" + "php": "^8" }, "require-dev": { - "ext-dom": "*", - "phpunit/phpunit": "^7.2 | ^8 | ^9" + "psalm/plugin-phpunit": "^0.18.4", + "remorhaz/php-json-data": "^0.5.3", + "remorhaz/php-json-path": "^0.7.7", + "squizlabs/php_codesniffer": "^3.7.2", + "vimeo/psalm": "^5.12" }, "type": "library", "autoload": { - "psr-0": { - "Yandex": "src/" + "psr-4": { + "Qameta\\Allure\\Codeception\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -9268,6 +9394,11 @@ "name": "Ivan Krutov", "email": "vania-pooh@aerokube.com", "role": "Developer" + }, + { + "name": "Edward Surov", + "email": "zoohie@gmail.com", + "role": "Developer" } ], "description": "Allure Codeception integration", @@ -9286,38 +9417,44 @@ "issues": "https://github.com/allure-framework/allure-codeception/issues", "source": "https://github.com/allure-framework/allure-codeception" }, - "time": "2021-06-04T13:24:36+00:00" + "time": "2023-05-31T14:10:46+00:00" }, { - "name": "allure-framework/allure-php-api", - "version": "1.4.0", + "name": "allure-framework/allure-php-commons", + "version": "v2.3.1", "source": { "type": "git", - "url": "https://github.com/allure-framework/allure-php-api.git", - "reference": "50507f482d490f114054f2281cca487db47fa2bd" + "url": "https://github.com/allure-framework/allure-php-commons2.git", + "reference": "5d7ed5ab510339652163ca1473eb499d4b7ec488" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/allure-framework/allure-php-api/zipball/50507f482d490f114054f2281cca487db47fa2bd", - "reference": "50507f482d490f114054f2281cca487db47fa2bd", + "url": "https://api.github.com/repos/allure-framework/allure-php-commons2/zipball/5d7ed5ab510339652163ca1473eb499d4b7ec488", + "reference": "5d7ed5ab510339652163ca1473eb499d4b7ec488", "shasum": "" }, "require": { - "jms/serializer": "^1 | ^2 | ^3", - "php": ">=7.1.3", - "ramsey/uuid": "^3 | ^4", - "symfony/mime": "^4.3 | ^5" + "doctrine/annotations": "^1.12 || ^2", + "ext-json": "*", + "php": "^8", + "psr/log": "^1 || ^2 || ^3", + "ramsey/uuid": "^3 || ^4" + }, + "conflict": { + "amphp/byte-stream": "<1.5.1" }, "require-dev": { - "phpunit/phpunit": "^7 | ^8 | ^9" + "jetbrains/phpstorm-attributes": "^1", + "phpunit/phpunit": "^9.6.8", + "psalm/plugin-phpunit": "^0.18.4", + "squizlabs/php_codesniffer": "^3.7.2", + "vimeo/psalm": "^5.12" }, "type": "library", "autoload": { - "psr-0": { - "Yandex": [ - "src/", - "test/" - ] + "psr-4": { + "Qameta\\Allure\\": "src", + "Yandex\\Allure\\Adapter\\": "src/Legacy" } }, "notification-url": "https://packagist.org/downloads/", @@ -9326,72 +9463,8 @@ ], "authors": [ { - "name": "Ivan Krutov", - "email": "vania-pooh@yandex-team.ru", - "role": "Developer" - } - ], - "description": "Allure PHP commons", - "homepage": "http://allure.qatools.ru/", - "keywords": [ - "allure", - "api", - "php", - "report" - ], - "support": { - "email": "allure@qameta.io", - "issues": "https://github.com/allure-framework/allure-php-api/issues", - "source": "https://github.com/allure-framework/allure-php-api" - }, - "time": "2021-11-15T13:15:20+00:00" - }, - { - "name": "allure-framework/allure-php-commons", - "version": "v2.0.0", - "source": { - "type": "git", - "url": "https://github.com/allure-framework/allure-php-commons2.git", - "reference": "946e375e90cce9e43d1622890fb5a312ec8086bb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/allure-framework/allure-php-commons2/zipball/946e375e90cce9e43d1622890fb5a312ec8086bb", - "reference": "946e375e90cce9e43d1622890fb5a312ec8086bb", - "shasum": "" - }, - "require": { - "doctrine/annotations": "^1.12", - "ext-json": "*", - "php": "^8", - "psr/log": "^1 || ^2 || ^3", - "ramsey/uuid": "^3 || ^4" - }, - "conflict": { - "amphp/byte-stream": "<1.5.1" - }, - "require-dev": { - "jetbrains/phpstorm-attributes": "^1", - "phpunit/phpunit": "^9.5.10", - "psalm/plugin-phpunit": "^0.16.1", - "squizlabs/php_codesniffer": "^3.6.2", - "vimeo/psalm": "^4.15" - }, - "type": "library", - "autoload": { - "psr-4": { - "Qameta\\Allure\\": "src", - "Yandex\\Allure\\Adapter\\": "src/Legacy" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache-2.0" - ], - "authors": [ - { - "name": "Dmitry Baev", - "email": "baev.dm@gmail.com", + "name": "Dmitry Baev", + "email": "baev.dm@gmail.com", "role": "Developer" }, { @@ -9414,20 +9487,20 @@ "issues": "https://github.com/allure-framework/allure-php-commons2/issues", "source": "https://github.com/allure-framework/allure-php-commons" }, - "time": "2021-12-28T12:03:10+00:00" + "time": "2023-05-30T10:55:43+00:00" }, { "name": "allure-framework/allure-phpunit", - "version": "v2.0.0", + "version": "v2.1.0", "source": { "type": "git", "url": "https://github.com/allure-framework/allure-phpunit.git", - "reference": "3884842467bcba9607db9d7aa69b82dcf0424218" + "reference": "a08e0092cdddfc8ead1953cf5bddf80b48595109" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/allure-framework/allure-phpunit/zipball/3884842467bcba9607db9d7aa69b82dcf0424218", - "reference": "3884842467bcba9607db9d7aa69b82dcf0424218", + "url": "https://api.github.com/repos/allure-framework/allure-phpunit/zipball/a08e0092cdddfc8ead1953cf5bddf80b48595109", + "reference": "a08e0092cdddfc8ead1953cf5bddf80b48595109", "shasum": "" }, "require": { @@ -9439,10 +9512,10 @@ "amphp/byte-stream": "<1.5.1" }, "require-dev": { - "brianium/paratest": "^6.4.1", - "psalm/plugin-phpunit": "^0.16.1", - "squizlabs/php_codesniffer": "^3.6.2", - "vimeo/psalm": "^4.16.1" + "brianium/paratest": "^6.8", + "psalm/plugin-phpunit": "^0.18.4", + "squizlabs/php_codesniffer": "^3.7.1", + "vimeo/psalm": "^5.4" }, "type": "library", "autoload": { @@ -9482,7 +9555,7 @@ "issues": "https://github.com/allure-framework/allure-phpunit/issues", "source": "https://github.com/allure-framework/allure-phpunit" }, - "time": "2021-12-29T11:34:16+00:00" + "time": "2023-01-12T14:27:20+00:00" }, { "name": "beberlei/assert", @@ -9616,61 +9689,76 @@ }, { "name": "codeception/codeception", - "version": "4.1.31", + "version": "5.0.10", "source": { "type": "git", "url": "https://github.com/Codeception/Codeception.git", - "reference": "15524571ae0686a7facc2eb1f40f600e5bbce9e5" + "reference": "ed4af7fd4103cdd035916fbb8f35124edd2d018b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Codeception/Codeception/zipball/15524571ae0686a7facc2eb1f40f600e5bbce9e5", - "reference": "15524571ae0686a7facc2eb1f40f600e5bbce9e5", + "url": "https://api.github.com/repos/Codeception/Codeception/zipball/ed4af7fd4103cdd035916fbb8f35124edd2d018b", + "reference": "ed4af7fd4103cdd035916fbb8f35124edd2d018b", "shasum": "" }, "require": { - "behat/gherkin": "^4.4.0", - "codeception/lib-asserts": "^1.0 | 2.0.*@dev", - "codeception/phpunit-wrapper": ">6.0.15 <6.1.0 | ^6.6.1 | ^7.7.1 | ^8.1.1 | ^9.0", - "codeception/stub": "^2.0 | ^3.0 | ^4.0", + "behat/gherkin": "^4.6.2", + "codeception/lib-asserts": "^2.0", + "codeception/stub": "^4.1", "ext-curl": "*", "ext-json": "*", "ext-mbstring": "*", - "guzzlehttp/psr7": "^1.4 | ^2.0", - "php": ">=5.6.0 <9.0", - "symfony/console": ">=2.7 <6.0", - "symfony/css-selector": ">=2.7 <6.0", - "symfony/event-dispatcher": ">=2.7 <6.0", - "symfony/finder": ">=2.7 <6.0", - "symfony/yaml": ">=2.7 <6.0" - }, - "require-dev": { - "codeception/module-asserts": "^1.0 | 2.0.*@dev", - "codeception/module-cli": "^1.0 | 2.0.*@dev", - "codeception/module-db": "^1.0 | 2.0.*@dev", - "codeception/module-filesystem": "^1.0 | 2.0.*@dev", - "codeception/module-phpbrowser": "^1.0 | 2.0.*@dev", - "codeception/specify": "~0.3", + "php": "^8.0", + "phpunit/php-code-coverage": "^9.2 || ^10.0", + "phpunit/php-text-template": "^2.0 || ^3.0", + "phpunit/php-timer": "^5.0.3 || ^6.0", + "phpunit/phpunit": "^9.5.20 || ^10.0", + "psy/psysh": "^0.11.2", + "sebastian/comparator": "^4.0.5 || ^5.0", + "sebastian/diff": "^4.0.3 || ^5.0", + "symfony/console": ">=4.4.24 <7.0", + "symfony/css-selector": ">=4.4.24 <7.0", + "symfony/event-dispatcher": ">=4.4.24 <7.0", + "symfony/finder": ">=4.4.24 <7.0", + "symfony/var-dumper": ">=4.4.24 < 7.0", + "symfony/yaml": ">=4.4.24 <7.0" + }, + "conflict": { + "codeception/lib-innerbrowser": "<3.1.3", + "codeception/module-filesystem": "<3.0", + "codeception/module-phpbrowser": "<2.5" + }, + "replace": { + "codeception/phpunit-wrapper": "*" + }, + "require-dev": { + "codeception/lib-innerbrowser": "*@dev", + "codeception/lib-web": "^1.0", + "codeception/module-asserts": "*@dev", + "codeception/module-cli": "*@dev", + "codeception/module-db": "*@dev", + "codeception/module-filesystem": "*@dev", + "codeception/module-phpbrowser": "*@dev", "codeception/util-universalframework": "*@dev", - "monolog/monolog": "~1.8", - "squizlabs/php_codesniffer": "~2.0", - "symfony/process": ">=2.7 <6.0", - "vlucas/phpdotenv": "^2.0 | ^3.0 | ^4.0 | ^5.0" + "ext-simplexml": "*", + "jetbrains/phpstorm-attributes": "^1.0", + "symfony/dotenv": ">=4.4.24 <7.0", + "symfony/process": ">=4.4.24 <7.0", + "vlucas/phpdotenv": "^5.1" }, "suggest": { "codeception/specify": "BDD-style code blocks", "codeception/verify": "BDD-style assertions", - "hoa/console": "For interactive console functionality", + "ext-simplexml": "For loading params from XML files", "stecman/symfony-console-completion": "For BASH autocompletion", - "symfony/phpunit-bridge": "For phpunit-bridge support" + "symfony/dotenv": "For loading params from .env files", + "symfony/phpunit-bridge": "For phpunit-bridge support", + "vlucas/phpdotenv": "For loading params from .env files" }, "bin": [ "codecept" ], "type": "library", - "extra": { - "branch-alias": [] - }, "autoload": { "files": [ "functions.php" @@ -9678,7 +9766,10 @@ "psr-4": { "Codeception\\": "src/Codeception", "Codeception\\Extension\\": "ext" - } + }, + "classmap": [ + "src/PHPUnit/TestCase.php" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -9687,12 +9778,12 @@ "authors": [ { "name": "Michael Bodnarchuk", - "email": "davert@mail.ua", - "homepage": "http://codegyre.com" + "email": "davert.ua@gmail.com", + "homepage": "https://codeception.com" } ], "description": "BDD-style testing framework", - "homepage": "http://codeception.com/", + "homepage": "https://codeception.com/", "keywords": [ "BDD", "TDD", @@ -9702,7 +9793,7 @@ ], "support": { "issues": "https://github.com/Codeception/Codeception/issues", - "source": "https://github.com/Codeception/Codeception/tree/4.1.31" + "source": "https://github.com/Codeception/Codeception/tree/5.0.10" }, "funding": [ { @@ -9710,26 +9801,26 @@ "type": "open_collective" } ], - "time": "2022-03-13T17:07:08+00:00" + "time": "2023-03-14T07:21:10+00:00" }, { "name": "codeception/lib-asserts", - "version": "1.13.2", + "version": "2.1.0", "source": { "type": "git", "url": "https://github.com/Codeception/lib-asserts.git", - "reference": "184231d5eab66bc69afd6b9429344d80c67a33b6" + "reference": "b8c7dff552249e560879c682ba44a4b963af91bc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Codeception/lib-asserts/zipball/184231d5eab66bc69afd6b9429344d80c67a33b6", - "reference": "184231d5eab66bc69afd6b9429344d80c67a33b6", + "url": "https://api.github.com/repos/Codeception/lib-asserts/zipball/b8c7dff552249e560879c682ba44a4b963af91bc", + "reference": "b8c7dff552249e560879c682ba44a4b963af91bc", "shasum": "" }, "require": { - "codeception/phpunit-wrapper": ">6.0.15 <6.1.0 | ^6.6.1 | ^7.7.1 | ^8.0.3 | ^9.0", + "codeception/phpunit-wrapper": "^7.7.1 | ^8.0.3 | ^9.0", "ext-dom": "*", - "php": ">=5.6.0 <9.0" + "php": "^7.4 | ^8.0" }, "type": "library", "autoload": { @@ -9762,31 +9853,84 @@ ], "support": { "issues": "https://github.com/Codeception/lib-asserts/issues", - "source": "https://github.com/Codeception/lib-asserts/tree/1.13.2" + "source": "https://github.com/Codeception/lib-asserts/tree/2.1.0" }, - "time": "2020-10-21T16:26:20+00:00" + "time": "2023-02-10T18:36:23+00:00" + }, + { + "name": "codeception/lib-web", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/Codeception/lib-web.git", + "reference": "f488ff9bc08c8985d43796db28da0bd18813bcae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Codeception/lib-web/zipball/f488ff9bc08c8985d43796db28da0bd18813bcae", + "reference": "f488ff9bc08c8985d43796db28da0bd18813bcae", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "guzzlehttp/psr7": "^2.0", + "php": "^8.0", + "symfony/css-selector": ">=4.4.24 <7.0" + }, + "conflict": { + "codeception/codeception": "<5.0.0-alpha3" + }, + "require-dev": { + "php-webdriver/webdriver": "^1.12", + "phpunit/phpunit": "^9.5 | ^10.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gintautas Miselis" + } + ], + "description": "Library containing files used by module-webdriver and lib-innerbrowser or module-phpbrowser", + "homepage": "https://codeception.com/", + "keywords": [ + "codeception" + ], + "support": { + "issues": "https://github.com/Codeception/lib-web/issues", + "source": "https://github.com/Codeception/lib-web/tree/1.0.2" + }, + "time": "2023-04-18T20:32:51+00:00" }, { "name": "codeception/module-asserts", - "version": "1.3.1", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/Codeception/module-asserts.git", - "reference": "59374f2fef0cabb9e8ddb53277e85cdca74328de" + "reference": "1b6b150b30586c3614e7e5761b31834ed7968603" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Codeception/module-asserts/zipball/59374f2fef0cabb9e8ddb53277e85cdca74328de", - "reference": "59374f2fef0cabb9e8ddb53277e85cdca74328de", + "url": "https://api.github.com/repos/Codeception/module-asserts/zipball/1b6b150b30586c3614e7e5761b31834ed7968603", + "reference": "1b6b150b30586c3614e7e5761b31834ed7968603", "shasum": "" }, "require": { "codeception/codeception": "*@dev", - "codeception/lib-asserts": "^1.13.1", - "php": ">=5.6.0 <9.0" + "codeception/lib-asserts": "^2.0", + "php": "^8.0" }, "conflict": { - "codeception/codeception": "<4.0" + "codeception/codeception": "<5.0" }, "type": "library", "autoload": { @@ -9819,30 +9963,33 @@ ], "support": { "issues": "https://github.com/Codeception/module-asserts/issues", - "source": "https://github.com/Codeception/module-asserts/tree/1.3.1" + "source": "https://github.com/Codeception/module-asserts/tree/3.0.0" }, - "time": "2020-10-21T16:48:15+00:00" + "time": "2022-02-16T19:48:08+00:00" }, { "name": "codeception/module-sequence", - "version": "1.0.1", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/Codeception/module-sequence.git", - "reference": "b75be26681ae90824cde8f8df785981f293667e1" + "reference": "9738e2eb06035a0975171a0aa3fce00d284b4dfb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Codeception/module-sequence/zipball/b75be26681ae90824cde8f8df785981f293667e1", - "reference": "b75be26681ae90824cde8f8df785981f293667e1", + "url": "https://api.github.com/repos/Codeception/module-sequence/zipball/9738e2eb06035a0975171a0aa3fce00d284b4dfb", + "reference": "9738e2eb06035a0975171a0aa3fce00d284b4dfb", "shasum": "" }, "require": { - "codeception/codeception": "^4.0", - "php": ">=5.6.0 <9.0" + "codeception/codeception": "^5.0", + "php": "^8.0" }, "type": "library", "autoload": { + "files": [ + "src/Codeception/Util/sq.php" + ], "classmap": [ "src/" ] @@ -9857,34 +10004,39 @@ } ], "description": "Sequence module for Codeception", - "homepage": "http://codeception.com/", + "homepage": "https://codeception.com/", "keywords": [ "codeception" ], "support": { "issues": "https://github.com/Codeception/module-sequence/issues", - "source": "https://github.com/Codeception/module-sequence/tree/1.0.1" + "source": "https://github.com/Codeception/module-sequence/tree/3.0.0" }, - "time": "2020-10-31T18:36:26+00:00" + "time": "2022-05-31T05:45:36+00:00" }, { "name": "codeception/module-webdriver", - "version": "1.4.0", + "version": "3.2.1", "source": { "type": "git", "url": "https://github.com/Codeception/module-webdriver.git", - "reference": "baa18b7bf70aa024012f967b5ce5021e1faa9151" + "reference": "59b6fe426dddbe889c23593f8698c52e08bba6e9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Codeception/module-webdriver/zipball/baa18b7bf70aa024012f967b5ce5021e1faa9151", - "reference": "baa18b7bf70aa024012f967b5ce5021e1faa9151", + "url": "https://api.github.com/repos/Codeception/module-webdriver/zipball/59b6fe426dddbe889c23593f8698c52e08bba6e9", + "reference": "59b6fe426dddbe889c23593f8698c52e08bba6e9", "shasum": "" }, "require": { - "codeception/codeception": "^4.0", - "php": ">=5.6.0 <9.0", - "php-webdriver/webdriver": "^1.8.0" + "codeception/codeception": "^5.0.0-RC2", + "codeception/lib-web": "^1.0.1", + "codeception/stub": "^4.0", + "ext-json": "*", + "ext-mbstring": "*", + "php": "^8.0", + "php-webdriver/webdriver": "^1.8.0", + "phpunit/phpunit": "^9.5" }, "suggest": { "codeception/phpbuiltinserver": "Start and stop PHP built-in web server for your tests" @@ -9911,7 +10063,7 @@ } ], "description": "WebDriver module for Codeception", - "homepage": "http://codeception.com/", + "homepage": "https://codeception.com/", "keywords": [ "acceptance-testing", "browser-testing", @@ -9919,77 +10071,31 @@ ], "support": { "issues": "https://github.com/Codeception/module-webdriver/issues", - "source": "https://github.com/Codeception/module-webdriver/tree/1.4.0" - }, - "time": "2021-09-02T12:01:02+00:00" - }, - { - "name": "codeception/phpunit-wrapper", - "version": "9.0.9", - "source": { - "type": "git", - "url": "https://github.com/Codeception/phpunit-wrapper.git", - "reference": "7439a53ae367986e9c22b2ac00f9d7376bb2f8cf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Codeception/phpunit-wrapper/zipball/7439a53ae367986e9c22b2ac00f9d7376bb2f8cf", - "reference": "7439a53ae367986e9c22b2ac00f9d7376bb2f8cf", - "shasum": "" + "source": "https://github.com/Codeception/module-webdriver/tree/3.2.1" }, - "require": { - "php": ">=7.2", - "phpunit/phpunit": "^9.0" - }, - "require-dev": { - "codeception/specify": "*", - "consolidation/robo": "^3.0.0-alpha3", - "vlucas/phpdotenv": "^3.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Codeception\\PHPUnit\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Davert", - "email": "davert.php@resend.cc" - }, - { - "name": "Naktibalda" - } - ], - "description": "PHPUnit classes used by Codeception", - "support": { - "issues": "https://github.com/Codeception/phpunit-wrapper/issues", - "source": "https://github.com/Codeception/phpunit-wrapper/tree/9.0.9" - }, - "time": "2022-05-23T06:24:11+00:00" + "time": "2023-02-03T21:46:32+00:00" }, { "name": "codeception/stub", - "version": "4.0.2", + "version": "4.1.0", "source": { "type": "git", "url": "https://github.com/Codeception/Stub.git", - "reference": "18a148dacd293fc7b044042f5aa63a82b08bff5d" + "reference": "58751aed08a68ae960a952fd3fe74ee9a56cdb1b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Codeception/Stub/zipball/18a148dacd293fc7b044042f5aa63a82b08bff5d", - "reference": "18a148dacd293fc7b044042f5aa63a82b08bff5d", + "url": "https://api.github.com/repos/Codeception/Stub/zipball/58751aed08a68ae960a952fd3fe74ee9a56cdb1b", + "reference": "58751aed08a68ae960a952fd3fe74ee9a56cdb1b", "shasum": "" }, "require": { "php": "^7.4 | ^8.0", "phpunit/phpunit": "^8.4 | ^9.0 | ^10.0 | 10.0.x-dev" }, + "conflict": { + "codeception/codeception": "<5.0.6" + }, "require-dev": { "consolidation/robo": "^3.0" }, @@ -10006,9 +10112,9 @@ "description": "Flexible Stub wrapper for PHPUnit's Mock Builder", "support": { "issues": "https://github.com/Codeception/Stub/issues", - "source": "https://github.com/Codeception/Stub/tree/4.0.2" + "source": "https://github.com/Codeception/Stub/tree/4.1.0" }, - "time": "2022-01-31T19:25:15+00:00" + "time": "2022-12-27T18:41:43+00:00" }, { "name": "csharpru/vault-php", @@ -10202,30 +10308,30 @@ }, { "name": "doctrine/instantiator", - "version": "1.4.1", + "version": "1.5.0", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc" + "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/0a0fa9780f5d4e507415a065172d26a98d02047b", + "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^9", + "doctrine/coding-standard": "^9 || ^11", "ext-pdo": "*", "ext-phar": "*", "phpbench/phpbench": "^0.16 || ^1", "phpstan/phpstan": "^1.4", "phpstan/phpstan-phpunit": "^1", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "vimeo/psalm": "^4.22" + "vimeo/psalm": "^4.30 || ^5.4" }, "type": "library", "autoload": { @@ -10252,7 +10358,7 @@ ], "support": { "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/1.4.1" + "source": "https://github.com/doctrine/instantiator/tree/1.5.0" }, "funding": [ { @@ -10268,7 +10374,7 @@ "type": "tidelift" } ], - "time": "2022-03-03T08:28:38+00:00" + "time": "2022-12-30T00:15:36+00:00" }, { "name": "friendsofphp/php-cs-fixer", @@ -10359,184 +10465,24 @@ ], "time": "2022-03-18T17:20:59+00:00" }, - { - "name": "jms/metadata", - "version": "2.6.1", - "source": { - "type": "git", - "url": "https://github.com/schmittjoh/metadata.git", - "reference": "c3a3214354b5a765a19875f7b7c5ebcd94e462e5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/schmittjoh/metadata/zipball/c3a3214354b5a765a19875f7b7c5ebcd94e462e5", - "reference": "c3a3214354b5a765a19875f7b7c5ebcd94e462e5", - "shasum": "" - }, - "require": { - "php": "^7.2|^8.0" - }, - "require-dev": { - "doctrine/cache": "^1.0", - "doctrine/coding-standard": "^8.0", - "mikey179/vfsstream": "^1.6.7", - "phpunit/phpunit": "^8.5|^9.0", - "psr/container": "^1.0", - "symfony/cache": "^3.1|^4.0|^5.0", - "symfony/dependency-injection": "^3.1|^4.0|^5.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - } - }, - "autoload": { - "psr-4": { - "Metadata\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Johannes M. Schmitt", - "email": "schmittjoh@gmail.com" - }, - { - "name": "Asmir Mustafic", - "email": "goetas@gmail.com" - } - ], - "description": "Class/method/property metadata management in PHP", - "keywords": [ - "annotations", - "metadata", - "xml", - "yaml" - ], - "support": { - "issues": "https://github.com/schmittjoh/metadata/issues", - "source": "https://github.com/schmittjoh/metadata/tree/2.6.1" - }, - "time": "2021-11-22T12:27:42+00:00" - }, - { - "name": "jms/serializer", - "version": "3.18.1", - "source": { - "type": "git", - "url": "https://github.com/schmittjoh/serializer.git", - "reference": "32956d3e3e1938f8130523a94297399d2b26fea7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/schmittjoh/serializer/zipball/32956d3e3e1938f8130523a94297399d2b26fea7", - "reference": "32956d3e3e1938f8130523a94297399d2b26fea7", - "shasum": "" - }, - "require": { - "doctrine/annotations": "^1.13", - "doctrine/instantiator": "^1.0.3", - "doctrine/lexer": "^1.1", - "jms/metadata": "^2.6", - "php": "^7.2||^8.0", - "phpstan/phpdoc-parser": "^0.4 || ^0.5 || ^1.0" - }, - "require-dev": { - "doctrine/coding-standard": "^8.1", - "doctrine/orm": "~2.1", - "doctrine/persistence": "^1.3.3|^2.0|^3.0", - "doctrine/phpcr-odm": "^1.3|^2.0", - "ext-pdo_sqlite": "*", - "jackalope/jackalope-doctrine-dbal": "^1.1.5", - "ocramius/proxy-manager": "^1.0|^2.0", - "phpbench/phpbench": "^1.0", - "phpstan/phpstan": "^1.0.2", - "phpunit/phpunit": "^8.5.21||^9.0", - "psr/container": "^1.0", - "symfony/dependency-injection": "^3.0|^4.0|^5.0|^6.0", - "symfony/expression-language": "^3.2|^4.0|^5.0|^6.0", - "symfony/filesystem": "^3.0|^4.0|^5.0|^6.0", - "symfony/form": "^3.0|^4.0|^5.0|^6.0", - "symfony/translation": "^3.0|^4.0|^5.0|^6.0", - "symfony/uid": "^5.1|^6.0", - "symfony/validator": "^3.1.9|^4.0|^5.0|^6.0", - "symfony/yaml": "^3.3|^4.0|^5.0|^6.0", - "twig/twig": "~1.34|~2.4|^3.0" - }, - "suggest": { - "doctrine/collections": "Required if you like to use doctrine collection types as ArrayCollection.", - "symfony/cache": "Required if you like to use cache functionality.", - "symfony/uid": "Required if you'd like to serialize UID objects.", - "symfony/yaml": "Required if you'd like to use the YAML metadata format." - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } - }, - "autoload": { - "psr-4": { - "JMS\\Serializer\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Johannes M. Schmitt", - "email": "schmittjoh@gmail.com" - }, - { - "name": "Asmir Mustafic", - "email": "goetas@gmail.com" - } - ], - "description": "Library for (de-)serializing data of any complexity; supports XML, JSON, and YAML.", - "homepage": "http://jmsyst.com/libs/serializer", - "keywords": [ - "deserialization", - "jaxb", - "json", - "serialization", - "xml" - ], - "support": { - "issues": "https://github.com/schmittjoh/serializer/issues", - "source": "https://github.com/schmittjoh/serializer/tree/3.18.1" - }, - "funding": [ - { - "url": "https://github.com/goetas", - "type": "github" - } - ], - "time": "2022-08-24T15:26:21+00:00" - }, { "name": "laminas/laminas-diactoros", - "version": "2.23.0", + "version": "2.25.2", "source": { "type": "git", "url": "https://github.com/laminas/laminas-diactoros.git", - "reference": "a738cecb420e3bcff34c33177f1ce9f68902695c" + "reference": "9f3f4bf5b99c9538b6f1dbcc20f6fec357914f9e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-diactoros/zipball/a738cecb420e3bcff34c33177f1ce9f68902695c", - "reference": "a738cecb420e3bcff34c33177f1ce9f68902695c", + "url": "https://api.github.com/repos/laminas/laminas-diactoros/zipball/9f3f4bf5b99c9538b6f1dbcc20f6fec357914f9e", + "reference": "9f3f4bf5b99c9538b6f1dbcc20f6fec357914f9e", "shasum": "" }, "require": { "php": "~8.0.0 || ~8.1.0 || ~8.2.0", "psr/http-factory": "^1.0", - "psr/http-message": "^1.0" + "psr/http-message": "^1.1" }, "conflict": { "zendframework/zend-diactoros": "*" @@ -10551,11 +10497,11 @@ "ext-gd": "*", "ext-libxml": "*", "http-interop/http-factory-tests": "^0.9.0", - "laminas/laminas-coding-standard": "^2.4.0", + "laminas/laminas-coding-standard": "^2.5", "php-http/psr7-integration-tests": "^1.2", - "phpunit/phpunit": "^9.5.26", - "psalm/plugin-phpunit": "^0.18.0", - "vimeo/psalm": "^5.0.0" + "phpunit/phpunit": "^9.5.28", + "psalm/plugin-phpunit": "^0.18.4", + "vimeo/psalm": "^5.6" }, "type": "library", "extra": { @@ -10614,7 +10560,7 @@ "type": "community_bridge" } ], - "time": "2022-12-14T22:31:50+00:00" + "time": "2023-04-17T15:44:17+00:00" }, { "name": "lusitanian/oauth", @@ -10737,26 +10683,26 @@ }, { "name": "magento/magento2-functional-testing-framework", - "version": "4.2.1", + "version": "4.3.1", "source": { "type": "git", "url": "https://github.com/magento/magento2-functional-testing-framework.git", - "reference": "9ba3321df1dbfebd4bf2e502f76880d05fa38a57" + "reference": "4b4214e6b1542f92ec9e1a9a66e38ed597becefe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/magento/magento2-functional-testing-framework/zipball/9ba3321df1dbfebd4bf2e502f76880d05fa38a57", - "reference": "9ba3321df1dbfebd4bf2e502f76880d05fa38a57", + "url": "https://api.github.com/repos/magento/magento2-functional-testing-framework/zipball/4b4214e6b1542f92ec9e1a9a66e38ed597becefe", + "reference": "4b4214e6b1542f92ec9e1a9a66e38ed597becefe", "shasum": "" }, "require": { - "allure-framework/allure-codeception": "^1.5", + "allure-framework/allure-codeception": "^2.1", "allure-framework/allure-phpunit": "^2", "aws/aws-sdk-php": "^3.132", - "codeception/codeception": "^4.1", - "codeception/module-asserts": "^1.1", - "codeception/module-sequence": "^1.0", - "codeception/module-webdriver": "^1.0", + "codeception/codeception": "^5.0", + "codeception/module-asserts": "^3.0", + "codeception/module-sequence": "^3.0", + "codeception/module-webdriver": "^3.0", "composer/composer": "^1.9 || ^2.0, !=2.2.16", "csharpru/vault-php": "^4.2.1", "doctrine/annotations": "^1.13", @@ -10788,7 +10734,7 @@ "codacy/coverage": "^1.4", "php-coveralls/php-coveralls": "^1.0||^2.2", "phpmd/phpmd": "^2.8.0", - "phpunit/phpunit": "^9.0", + "phpunit/phpunit": "<=9.5.20", "sebastian/phpcpd": "~6.0.0", "squizlabs/php_codesniffer": "~3.6.0" }, @@ -10826,22 +10772,22 @@ ], "support": { "issues": "https://github.com/magento/magento2-functional-testing-framework/issues", - "source": "https://github.com/magento/magento2-functional-testing-framework/tree/4.2.1" + "source": "https://github.com/magento/magento2-functional-testing-framework/tree/4.3.1" }, - "time": "2023-02-22T18:01:48+00:00" + "time": "2023-06-01T03:46:02+00:00" }, { "name": "mustache/mustache", - "version": "v2.14.1", + "version": "v2.14.2", "source": { "type": "git", "url": "https://github.com/bobthecow/mustache.php.git", - "reference": "579ffa5c96e1d292c060b3dd62811ff01ad8c24e" + "reference": "e62b7c3849d22ec55f3ec425507bf7968193a6cb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bobthecow/mustache.php/zipball/579ffa5c96e1d292c060b3dd62811ff01ad8c24e", - "reference": "579ffa5c96e1d292c060b3dd62811ff01ad8c24e", + "url": "https://api.github.com/repos/bobthecow/mustache.php/zipball/e62b7c3849d22ec55f3ec425507bf7968193a6cb", + "reference": "e62b7c3849d22ec55f3ec425507bf7968193a6cb", "shasum": "" }, "require": { @@ -10876,22 +10822,22 @@ ], "support": { "issues": "https://github.com/bobthecow/mustache.php/issues", - "source": "https://github.com/bobthecow/mustache.php/tree/v2.14.1" + "source": "https://github.com/bobthecow/mustache.php/tree/v2.14.2" }, - "time": "2022-01-21T06:08:36+00:00" + "time": "2022-08-23T13:07:01+00:00" }, { "name": "myclabs/deep-copy", - "version": "1.11.0", + "version": "1.11.1", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614" + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", "shasum": "" }, "require": { @@ -10929,7 +10875,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.11.0" + "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1" }, "funding": [ { @@ -10937,7 +10883,7 @@ "type": "tidelift" } ], - "time": "2022-03-03T13:19:32+00:00" + "time": "2023-03-08T13:26:56+00:00" }, { "name": "pdepend/pdepend", @@ -11162,16 +11108,16 @@ }, { "name": "php-webdriver/webdriver", - "version": "1.12.1", + "version": "1.13.1", "source": { "type": "git", "url": "https://github.com/php-webdriver/php-webdriver.git", - "reference": "b27ddf458d273c7d4602106fcaf978aa0b7fe15a" + "reference": "6dfe5f814b796c1b5748850aa19f781b9274c36c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-webdriver/php-webdriver/zipball/b27ddf458d273c7d4602106fcaf978aa0b7fe15a", - "reference": "b27ddf458d273c7d4602106fcaf978aa0b7fe15a", + "url": "https://api.github.com/repos/php-webdriver/php-webdriver/zipball/6dfe5f814b796c1b5748850aa19f781b9274c36c", + "reference": "6dfe5f814b796c1b5748850aa19f781b9274c36c", "shasum": "" }, "require": { @@ -11221,9 +11167,9 @@ ], "support": { "issues": "https://github.com/php-webdriver/php-webdriver/issues", - "source": "https://github.com/php-webdriver/php-webdriver/tree/1.12.1" + "source": "https://github.com/php-webdriver/php-webdriver/tree/1.13.1" }, - "time": "2022-05-03T12:16:34+00:00" + "time": "2022-10-11T11:49:44+00:00" }, { "name": "phpcompatibility/php-compatibility", @@ -11287,166 +11233,6 @@ }, "time": "2019-12-27T09:44:58+00:00" }, - { - "name": "phpdocumentor/reflection-common", - "version": "2.2.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-2.x": "2.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" - } - ], - "description": "Common reflection classes used by phpdocumentor to reflect the code structure", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "FQSEN", - "phpDocumentor", - "phpdoc", - "reflection", - "static analysis" - ], - "support": { - "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", - "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" - }, - "time": "2020-06-27T09:03:43+00:00" - }, - { - "name": "phpdocumentor/reflection-docblock", - "version": "5.3.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", - "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", - "shasum": "" - }, - "require": { - "ext-filter": "*", - "php": "^7.2 || ^8.0", - "phpdocumentor/reflection-common": "^2.2", - "phpdocumentor/type-resolver": "^1.3", - "webmozart/assert": "^1.9.1" - }, - "require-dev": { - "mockery/mockery": "~1.3.2", - "psalm/phar": "^4.8" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - }, - { - "name": "Jaap van Otterdijk", - "email": "account@ijaap.nl" - } - ], - "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "support": { - "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0" - }, - "time": "2021-10-19T17:43:47+00:00" - }, - { - "name": "phpdocumentor/type-resolver", - "version": "1.6.1", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "77a32518733312af16a44300404e945338981de3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/77a32518733312af16a44300404e945338981de3", - "reference": "77a32518733312af16a44300404e945338981de3", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0", - "phpdocumentor/reflection-common": "^2.0" - }, - "require-dev": { - "ext-tokenizer": "*", - "psalm/phar": "^4.8" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-1.x": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - } - ], - "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", - "support": { - "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.1" - }, - "time": "2022-03-15T21:29:03+00:00" - }, { "name": "phpmd/phpmd", "version": "2.13.0", @@ -11530,117 +11316,6 @@ ], "time": "2022-09-10T08:44:15+00:00" }, - { - "name": "phpspec/prophecy", - "version": "v1.16.0", - "source": { - "type": "git", - "url": "https://github.com/phpspec/prophecy.git", - "reference": "be8cac52a0827776ff9ccda8c381ac5b71aeb359" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/be8cac52a0827776ff9ccda8c381ac5b71aeb359", - "reference": "be8cac52a0827776ff9ccda8c381ac5b71aeb359", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.2", - "php": "^7.2 || 8.0.* || 8.1.* || 8.2.*", - "phpdocumentor/reflection-docblock": "^5.2", - "sebastian/comparator": "^3.0 || ^4.0", - "sebastian/recursion-context": "^3.0 || ^4.0" - }, - "require-dev": { - "phpspec/phpspec": "^6.0 || ^7.0", - "phpunit/phpunit": "^8.0 || ^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Prophecy\\": "src/Prophecy" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - }, - { - "name": "Marcello Duarte", - "email": "marcello.duarte@gmail.com" - } - ], - "description": "Highly opinionated mocking framework for PHP 5.3+", - "homepage": "https://github.com/phpspec/prophecy", - "keywords": [ - "Double", - "Dummy", - "fake", - "mock", - "spy", - "stub" - ], - "support": { - "issues": "https://github.com/phpspec/prophecy/issues", - "source": "https://github.com/phpspec/prophecy/tree/v1.16.0" - }, - "time": "2022-11-29T15:06:56+00:00" - }, - { - "name": "phpstan/phpdoc-parser", - "version": "1.5.1", - "source": { - "type": "git", - "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "981cc368a216c988e862a75e526b6076987d1b50" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/981cc368a216c988e862a75e526b6076987d1b50", - "reference": "981cc368a216c988e862a75e526b6076987d1b50", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "require-dev": { - "php-parallel-lint/php-parallel-lint": "^1.2", - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^1.5", - "phpstan/phpstan-strict-rules": "^1.0", - "phpunit/phpunit": "^9.5", - "symfony/process": "^5.2" - }, - "type": "library", - "autoload": { - "psr-4": { - "PHPStan\\PhpDocParser\\": [ - "src/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "PHPDoc parser with support for nullable, intersection and generic types", - "support": { - "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.5.1" - }, - "time": "2022-05-05T11:32:40+00:00" - }, { "name": "phpstan/phpstan", "version": "1.9.14", @@ -11702,23 +11377,23 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.2.15", + "version": "9.2.26", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "2e9da11878c4202f97915c1cb4bb1ca318a63f5f" + "reference": "443bc6912c9bd5b409254a40f4b0f4ced7c80ea1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2e9da11878c4202f97915c1cb4bb1ca318a63f5f", - "reference": "2e9da11878c4202f97915c1cb4bb1ca318a63f5f", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/443bc6912c9bd5b409254a40f4b0f4ced7c80ea1", + "reference": "443bc6912c9bd5b409254a40f4b0f4ced7c80ea1", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.13.0", + "nikic/php-parser": "^4.15", "php": ">=7.3", "phpunit/php-file-iterator": "^3.0.3", "phpunit/php-text-template": "^2.0.2", @@ -11733,8 +11408,8 @@ "phpunit/phpunit": "^9.3" }, "suggest": { - "ext-pcov": "*", - "ext-xdebug": "*" + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" }, "type": "library", "extra": { @@ -11767,7 +11442,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.15" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.26" }, "funding": [ { @@ -11775,7 +11450,7 @@ "type": "github" } ], - "time": "2022-03-07T09:28:20+00:00" + "time": "2023-03-06T12:58:08+00:00" }, { "name": "phpunit/php-file-iterator", @@ -12020,16 +11695,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.5.20", + "version": "9.5.24", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "12bc8879fb65aef2138b26fc633cb1e3620cffba" + "reference": "d0aa6097bef9fd42458a9b3c49da32c6ce6129c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/12bc8879fb65aef2138b26fc633cb1e3620cffba", - "reference": "12bc8879fb65aef2138b26fc633cb1e3620cffba", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d0aa6097bef9fd42458a9b3c49da32c6ce6129c5", + "reference": "d0aa6097bef9fd42458a9b3c49da32c6ce6129c5", "shasum": "" }, "require": { @@ -12044,7 +11719,6 @@ "phar-io/manifest": "^2.0.3", "phar-io/version": "^3.0.2", "php": ">=7.3", - "phpspec/prophecy": "^1.12.1", "phpunit/php-code-coverage": "^9.2.13", "phpunit/php-file-iterator": "^3.0.5", "phpunit/php-invoker": "^3.1.1", @@ -12059,13 +11733,9 @@ "sebastian/global-state": "^5.0.1", "sebastian/object-enumerator": "^4.0.3", "sebastian/resource-operations": "^3.0.3", - "sebastian/type": "^3.0", + "sebastian/type": "^3.1", "sebastian/version": "^3.0.2" }, - "require-dev": { - "ext-pdo": "*", - "phpspec/prophecy-phpunit": "^2.0.1" - }, "suggest": { "ext-soap": "*", "ext-xdebug": "*" @@ -12107,7 +11777,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.20" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.24" }, "funding": [ { @@ -12119,7 +11789,83 @@ "type": "github" } ], - "time": "2022-04-01T12:37:26+00:00" + "time": "2022-08-30T07:42:16+00:00" + }, + { + "name": "psy/psysh", + "version": "v0.11.18", + "source": { + "type": "git", + "url": "https://github.com/bobthecow/psysh.git", + "reference": "4f00ee9e236fa6a48f4560d1300b9c961a70a7ec" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/4f00ee9e236fa6a48f4560d1300b9c961a70a7ec", + "reference": "4f00ee9e236fa6a48f4560d1300b9c961a70a7ec", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-tokenizer": "*", + "nikic/php-parser": "^4.0 || ^3.1", + "php": "^8.0 || ^7.0.8", + "symfony/console": "^6.0 || ^5.0 || ^4.0 || ^3.4", + "symfony/var-dumper": "^6.0 || ^5.0 || ^4.0 || ^3.4" + }, + "conflict": { + "symfony/console": "4.4.37 || 5.3.14 || 5.3.15 || 5.4.3 || 5.4.4 || 6.0.3 || 6.0.4" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.2" + }, + "suggest": { + "ext-pcntl": "Enabling the PCNTL extension makes PsySH a lot happier :)", + "ext-pdo-sqlite": "The doc command requires SQLite to work.", + "ext-posix": "If you have PCNTL, you'll want the POSIX extension as well.", + "ext-readline": "Enables support for arrow-key history navigation, and showing and manipulating command history." + }, + "bin": [ + "bin/psysh" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "0.11.x-dev" + } + }, + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Psy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Justin Hileman", + "email": "justin@justinhileman.info", + "homepage": "http://justinhileman.com" + } + ], + "description": "An interactive shell for modern PHP.", + "homepage": "http://psysh.org", + "keywords": [ + "REPL", + "console", + "interactive", + "shell" + ], + "support": { + "issues": "https://github.com/bobthecow/psysh/issues", + "source": "https://github.com/bobthecow/psysh/tree/v0.11.18" + }, + "time": "2023-05-23T02:31:11+00:00" }, { "name": "rector/rector", @@ -12477,16 +12223,16 @@ }, { "name": "sebastian/diff", - "version": "4.0.4", + "version": "4.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" + "reference": "74be17022044ebaaecfdf0c5cd504fc9cd5a7131" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/74be17022044ebaaecfdf0c5cd504fc9cd5a7131", + "reference": "74be17022044ebaaecfdf0c5cd504fc9cd5a7131", "shasum": "" }, "require": { @@ -12531,7 +12277,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", - "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" + "source": "https://github.com/sebastianbergmann/diff/tree/4.0.5" }, "funding": [ { @@ -12539,20 +12285,20 @@ "type": "github" } ], - "time": "2020-10-26T13:10:38+00:00" + "time": "2023-05-07T05:35:17+00:00" }, { "name": "sebastian/environment", - "version": "5.1.4", + "version": "5.1.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7" + "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/1b5dff7bb151a4db11d49d90e5408e4e938270f7", - "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", + "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", "shasum": "" }, "require": { @@ -12594,7 +12340,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/5.1.4" + "source": "https://github.com/sebastianbergmann/environment/tree/5.1.5" }, "funding": [ { @@ -12602,20 +12348,20 @@ "type": "github" } ], - "time": "2022-04-03T09:37:03+00:00" + "time": "2023-02-03T06:03:51+00:00" }, { "name": "sebastian/exporter", - "version": "4.0.4", + "version": "4.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9" + "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/65e8b7db476c5dd267e65eea9cab77584d3cfff9", - "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", + "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", "shasum": "" }, "require": { @@ -12671,7 +12417,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.4" + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5" }, "funding": [ { @@ -12679,7 +12425,7 @@ "type": "github" } ], - "time": "2021-11-11T14:18:36+00:00" + "time": "2022-09-14T06:03:37+00:00" }, { "name": "sebastian/global-state", @@ -12977,16 +12723,16 @@ }, { "name": "sebastian/recursion-context", - "version": "4.0.4", + "version": "4.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172" + "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", + "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", "shasum": "" }, "require": { @@ -13025,10 +12771,10 @@ } ], "description": "Provides functionality to recursively process PHP variables", - "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "homepage": "https://github.com/sebastianbergmann/recursion-context", "support": { "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" + "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.5" }, "funding": [ { @@ -13036,7 +12782,7 @@ "type": "github" } ], - "time": "2020-10-26T13:17:30+00:00" + "time": "2023-02-03T06:07:39+00:00" }, { "name": "sebastian/resource-operations", @@ -13095,16 +12841,16 @@ }, { "name": "sebastian/type", - "version": "3.0.0", + "version": "3.2.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad" + "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b233b84bc4465aff7b57cf1c4bc75c86d00d6dad", - "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", + "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", "shasum": "" }, "require": { @@ -13116,7 +12862,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -13139,7 +12885,7 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/3.0.0" + "source": "https://github.com/sebastianbergmann/type/tree/3.2.1" }, "funding": [ { @@ -13147,7 +12893,7 @@ "type": "github" } ], - "time": "2022-03-15T09:54:48+00:00" + "time": "2023-02-03T06:13:03+00:00" }, { "name": "sebastian/version", @@ -13335,16 +13081,16 @@ }, { "name": "symfony/dotenv", - "version": "v5.4.5", + "version": "v5.4.22", "source": { "type": "git", "url": "https://github.com/symfony/dotenv.git", - "reference": "83a2310904a4f5d4f42526227b5a578ac82232a9" + "reference": "77b7660bfcb85e8f28287d557d7af0046bcd2ca3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dotenv/zipball/83a2310904a4f5d4f42526227b5a578ac82232a9", - "reference": "83a2310904a4f5d4f42526227b5a578ac82232a9", + "url": "https://api.github.com/repos/symfony/dotenv/zipball/77b7660bfcb85e8f28287d557d7af0046bcd2ca3", + "reference": "77b7660bfcb85e8f28287d557d7af0046bcd2ca3", "shasum": "" }, "require": { @@ -13386,7 +13132,7 @@ "environment" ], "support": { - "source": "https://github.com/symfony/dotenv/tree/v5.4.5" + "source": "https://github.com/symfony/dotenv/tree/v5.4.22" }, "funding": [ { @@ -13402,20 +13148,20 @@ "type": "tidelift" } ], - "time": "2022-02-15T17:04:12+00:00" + "time": "2023-03-09T20:36:58+00:00" }, { "name": "symfony/mime", - "version": "v5.4.10", + "version": "v5.4.23", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "02265e1e5111c3cd7480387af25e82378b7ab9cc" + "reference": "ae0a1032a450a3abf305ee44fc55ed423fbf16e3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/02265e1e5111c3cd7480387af25e82378b7ab9cc", - "reference": "02265e1e5111c3cd7480387af25e82378b7ab9cc", + "url": "https://api.github.com/repos/symfony/mime/zipball/ae0a1032a450a3abf305ee44fc55ed423fbf16e3", + "reference": "ae0a1032a450a3abf305ee44fc55ed423fbf16e3", "shasum": "" }, "require": { @@ -13429,15 +13175,16 @@ "egulias/email-validator": "~3.0.0", "phpdocumentor/reflection-docblock": "<3.2.2", "phpdocumentor/type-resolver": "<1.4.0", - "symfony/mailer": "<4.4" + "symfony/mailer": "<4.4", + "symfony/serializer": "<5.4.14|>=6.0,<6.0.14|>=6.1,<6.1.6" }, "require-dev": { - "egulias/email-validator": "^2.1.10|^3.1", + "egulias/email-validator": "^2.1.10|^3.1|^4", "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", "symfony/dependency-injection": "^4.4|^5.0|^6.0", "symfony/property-access": "^4.4|^5.1|^6.0", "symfony/property-info": "^4.4|^5.1|^6.0", - "symfony/serializer": "^5.2|^6.0" + "symfony/serializer": "^5.4.14|~6.0.14|^6.1.6" }, "type": "library", "autoload": { @@ -13469,7 +13216,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v5.4.10" + "source": "https://github.com/symfony/mime/tree/v5.4.23" }, "funding": [ { @@ -13485,27 +13232,25 @@ "type": "tidelift" } ], - "time": "2022-06-09T12:22:40+00:00" + "time": "2023-04-19T09:49:13+00:00" }, { "name": "symfony/options-resolver", - "version": "v5.4.3", + "version": "v6.3.0", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "cc1147cb11af1b43f503ac18f31aa3bec213aba8" + "reference": "a10f19f5198d589d5c33333cffe98dc9820332dd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/cc1147cb11af1b43f503ac18f31aa3bec213aba8", - "reference": "cc1147cb11af1b43f503ac18f31aa3bec213aba8", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/a10f19f5198d589d5c33333cffe98dc9820332dd", + "reference": "a10f19f5198d589d5c33333cffe98dc9820332dd", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/polyfill-php73": "~1.0", - "symfony/polyfill-php80": "^1.16" + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3" }, "type": "library", "autoload": { @@ -13538,7 +13283,7 @@ "options" ], "support": { - "source": "https://github.com/symfony/options-resolver/tree/v5.4.3" + "source": "https://github.com/symfony/options-resolver/tree/v6.3.0" }, "funding": [ { @@ -13554,7 +13299,7 @@ "type": "tidelift" } ], - "time": "2022-01-02T09:53:40+00:00" + "time": "2023-05-12T14:21:09+00:00" }, { "name": "symfony/stopwatch", @@ -13620,31 +13365,27 @@ }, { "name": "symfony/yaml", - "version": "v5.3.14", + "version": "v6.3.0", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "c441e9d2e340642ac8b951b753dea962d55b669d" + "reference": "a9a8337aa641ef2aa39c3e028f9107ec391e5927" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/c441e9d2e340642ac8b951b753dea962d55b669d", - "reference": "c441e9d2e340642ac8b951b753dea962d55b669d", + "url": "https://api.github.com/repos/symfony/yaml/zipball/a9a8337aa641ef2aa39c3e028f9107ec391e5927", + "reference": "a9a8337aa641ef2aa39c3e028f9107ec391e5927", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1", - "symfony/polyfill-ctype": "~1.8" + "php": ">=8.1", + "symfony/polyfill-ctype": "^1.8" }, "conflict": { - "symfony/console": "<4.4" + "symfony/console": "<5.4" }, "require-dev": { - "symfony/console": "^4.4|^5.0" - }, - "suggest": { - "symfony/console": "For validating YAML files using the lint command" + "symfony/console": "^5.4|^6.0" }, "bin": [ "Resources/bin/yaml-lint" @@ -13675,7 +13416,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v5.3.14" + "source": "https://github.com/symfony/yaml/tree/v6.3.0" }, "funding": [ { @@ -13691,43 +13432,50 @@ "type": "tidelift" } ], - "time": "2022-01-26T16:05:39+00:00" + "time": "2023-04-28T13:28:14+00:00" }, { "name": "thecodingmachine/safe", - "version": "v1.3.3", + "version": "v2.5.0", "source": { "type": "git", "url": "https://github.com/thecodingmachine/safe.git", - "reference": "a8ab0876305a4cdaef31b2350fcb9811b5608dbc" + "reference": "3115ecd6b4391662b4931daac4eba6b07a2ac1f0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thecodingmachine/safe/zipball/a8ab0876305a4cdaef31b2350fcb9811b5608dbc", - "reference": "a8ab0876305a4cdaef31b2350fcb9811b5608dbc", + "url": "https://api.github.com/repos/thecodingmachine/safe/zipball/3115ecd6b4391662b4931daac4eba6b07a2ac1f0", + "reference": "3115ecd6b4391662b4931daac4eba6b07a2ac1f0", "shasum": "" }, "require": { - "php": ">=7.2" + "php": "^8.0" }, "require-dev": { - "phpstan/phpstan": "^0.12", + "phpstan/phpstan": "^1.5", + "phpunit/phpunit": "^9.5", "squizlabs/php_codesniffer": "^3.2", - "thecodingmachine/phpstan-strict-rules": "^0.12" + "thecodingmachine/phpstan-strict-rules": "^1.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "0.1-dev" + "dev-master": "2.2.x-dev" } }, "autoload": { "files": [ "deprecated/apc.php", + "deprecated/array.php", + "deprecated/datetime.php", "deprecated/libevent.php", + "deprecated/misc.php", + "deprecated/password.php", "deprecated/mssql.php", "deprecated/stats.php", + "deprecated/strings.php", "lib/special_cases.php", + "deprecated/mysqli.php", "generated/apache.php", "generated/apcu.php", "generated/array.php", @@ -13748,6 +13496,7 @@ "generated/fpm.php", "generated/ftp.php", "generated/funchand.php", + "generated/gettext.php", "generated/gmp.php", "generated/gnupg.php", "generated/hash.php", @@ -13757,7 +13506,6 @@ "generated/image.php", "generated/imap.php", "generated/info.php", - "generated/ingres-ii.php", "generated/inotify.php", "generated/json.php", "generated/ldap.php", @@ -13766,20 +13514,14 @@ "generated/mailparse.php", "generated/mbstring.php", "generated/misc.php", - "generated/msql.php", "generated/mysql.php", - "generated/mysqli.php", - "generated/mysqlndMs.php", - "generated/mysqlndQc.php", "generated/network.php", "generated/oci8.php", "generated/opcache.php", "generated/openssl.php", "generated/outcontrol.php", - "generated/password.php", "generated/pcntl.php", "generated/pcre.php", - "generated/pdf.php", "generated/pgsql.php", "generated/posix.php", "generated/ps.php", @@ -13790,7 +13532,6 @@ "generated/sem.php", "generated/session.php", "generated/shmop.php", - "generated/simplexml.php", "generated/sockets.php", "generated/sodium.php", "generated/solr.php", @@ -13813,13 +13554,13 @@ "generated/zip.php", "generated/zlib.php" ], - "psr-4": { - "Safe\\": [ - "lib/", - "deprecated/", - "generated/" - ] - } + "classmap": [ + "lib/DateTime.php", + "lib/DateTimeImmutable.php", + "lib/Exceptions/", + "deprecated/Exceptions/", + "generated/Exceptions/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -13828,9 +13569,9 @@ "description": "PHP core functions that throw exceptions instead of returning FALSE on error", "support": { "issues": "https://github.com/thecodingmachine/safe/issues", - "source": "https://github.com/thecodingmachine/safe/tree/v1.3.3" + "source": "https://github.com/thecodingmachine/safe/tree/v2.5.0" }, - "time": "2020-10-28T17:51:34+00:00" + "time": "2023-04-05T11:54:14+00:00" }, { "name": "theseer/tokenizer", diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/WebapiAbstract.php b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/WebapiAbstract.php index 2dd022cc211f5..e6ba15d25a342 100644 --- a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/WebapiAbstract.php +++ b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/WebapiAbstract.php @@ -8,6 +8,7 @@ use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\Filesystem; use Magento\Framework\Webapi\Exception as WebapiException; +use Magento\TestFramework\SkippableTrait; use Magento\Webapi\Model\Soap\Fault; use Magento\TestFramework\Helper\Bootstrap; @@ -19,6 +20,8 @@ */ abstract class WebapiAbstract extends \PHPUnit\Framework\TestCase { + use SkippableTrait; + /** TODO: Reconsider implementation of fixture-management methods after implementing several tests */ /**#@+ * Auto tear down options in setFixture diff --git a/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementTest.php b/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementTest.php index 63f6814897863..a9954d29053cd 100644 --- a/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementTest.php @@ -8,10 +8,13 @@ use Magento\Customer\Api\Data\CustomerInterface as Customer; use Magento\Customer\Model\AccountManagement; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\App\ObjectManager; use Magento\Framework\Exception\InputException; use Magento\Framework\Webapi\Exception as HTTPExceptionCodes; use Magento\Newsletter\Model\Subscriber; use Magento\Security\Model\Config; +use Magento\Store\Model\ScopeInterface; use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\Helper\Customer as CustomerHelper; use Magento\TestFramework\TestCase\WebapiAbstract; @@ -23,15 +26,20 @@ */ class AccountManagementTest extends WebapiAbstract { - const SERVICE_VERSION = 'V1'; - const SERVICE_NAME = 'customerAccountManagementV1'; - const RESOURCE_PATH = '/V1/customers'; + public const SERVICE_VERSION = 'V1'; + public const SERVICE_NAME = 'customerAccountManagementV1'; + public const RESOURCE_PATH = '/V1/customers'; /** * Sample values for testing */ - const ATTRIBUTE_CODE = 'attribute_code'; - const ATTRIBUTE_VALUE = 'attribute_value'; + public const ATTRIBUTE_CODE = 'attribute_code'; + public const ATTRIBUTE_VALUE = 'attribute_value'; + + /** + * @var ObjectManager + */ + private $objectManager; /** * @var AccountManagementInterface @@ -86,6 +94,8 @@ class AccountManagementTest extends WebapiAbstract */ protected function setUp(): void { + $this->objectManager = Bootstrap::getObjectManager(); + $this->accountManagement = Bootstrap::getObjectManager()->get( \Magento\Customer\Api\AccountManagementInterface::class ); @@ -645,6 +655,8 @@ public function testIsReadonly() public function testEmailAvailable() { + $config = $this->objectManager->get(ScopeConfigInterface::class); + $customerData = $this->_createCustomer(); $serviceInfo = [ @@ -662,7 +674,18 @@ public function testEmailAvailable() 'customerEmail' => $customerData[Customer::EMAIL], 'websiteId' => $customerData[Customer::WEBSITE_ID], ]; - $this->assertFalse($this->_webApiCall($serviceInfo, $requestData)); + + $emailSetting = $config->getValue( + AccountManagement::GUEST_CHECKOUT_LOGIN_OPTION_SYS_CONFIG, + ScopeInterface::SCOPE_WEBSITE, + $customerData[Customer::WEBSITE_ID] + ); + + if (!$emailSetting) { + $this->assertTrue($this->_webApiCall($serviceInfo, $requestData)); + } else { + $this->assertFalse($this->_webApiCall($serviceInfo, $requestData)); + } } public function testEmailAvailableInvalidEmail() diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductSearchTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductSearchTest.php index 79d55ea4ed08a..84438e03bc149 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductSearchTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductSearchTest.php @@ -1744,7 +1744,7 @@ public function testFilteringForProductsFromMultipleCategories() * @return void * @dataProvider filterProductsBySingleCategoryIdDataProvider */ - public function testFilterProductsBySingleCategoryId(string $fieldName, string $queryCategoryId) + public function testFilterProductsBySingleCategoryId(string $fieldName, string $queryCategoryId): void { CacheCleaner::clean(['config']); if (is_numeric($queryCategoryId)) { @@ -1800,21 +1800,18 @@ public function testFilterProductsBySingleCategoryId(string $fieldName, string $ $product = $this->productRepository->get($links[$itemIndex]->getSku()); $this->assertEquals($response['products']['items'][$itemIndex]['name'], $product->getName()); $this->assertEquals($response['products']['items'][$itemIndex]['type_id'], $product->getTypeId()); - $categoryIds = $product->getCategoryIds(); - foreach ($categoryIds as $index => $value) { - $categoryIds[$index] = (int)$value; - } - $categoryInResponse = array_map( - null, - $categoryIds, + $categoryIds = array_map('intval', $product->getCategoryIds()); + $this->assertCount(count($categoryIds), $response['products']['items'][$itemIndex]['categories']); + $categoryInResponse = array_combine( + array_column($response['products']['items'][$itemIndex]['categories'], 'id'), $response['products']['items'][$itemIndex]['categories'] ); - foreach ($categoryInResponse as $key => $categoryData) { - $this->assertNotEmpty($categoryData); + foreach ($categoryIds as $categoryId) { + $this->assertArrayHasKey($categoryId, $categoryInResponse); /** @var CategoryInterface | Category $category */ - $category = $this->categoryRepository->get($categoryInResponse[$key][0]); + $category = $this->categoryRepository->get($categoryId); $this->assertResponseFields( - $categoryInResponse[$key][1], + $categoryInResponse[$categoryId], [ 'name' => $category->getName(), 'id' => $category->getId(), diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/IsEmailAvailableTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/IsEmailAvailableTest.php index f0bd7dc1e854a..b683b4bd521d6 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/IsEmailAvailableTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/IsEmailAvailableTest.php @@ -7,6 +7,11 @@ namespace Magento\GraphQl\Customer; +use Magento\Customer\Model\AccountManagement; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Store\Api\StoreResolverInterface; +use Magento\Store\Model\ScopeInterface; +use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\TestCase\GraphQlAbstract; /** @@ -14,6 +19,25 @@ */ class IsEmailAvailableTest extends GraphQlAbstract { + /** + * @var ScopeConfigInterface|null + */ + private ?ScopeConfigInterface $scopeConfig; + + /** + * @var string|null + */ + private ?string $storeId; + + public function setUp(): void + { + $objectManager = Bootstrap::getObjectManager(); + $this->scopeConfig = $objectManager->get(ScopeConfigInterface::class); + /* @var StoreResolverInterface $storeResolver */ + $storeResolver = $objectManager->get(StoreResolverInterface::class); + $this->storeId = $storeResolver->getCurrentStoreId(); + } + /** * @magentoApiDataFixture Magento/Customer/_files/customer.php */ @@ -31,7 +55,16 @@ public function testEmailNotAvailable() self::assertArrayHasKey('isEmailAvailable', $response); self::assertArrayHasKey('is_email_available', $response['isEmailAvailable']); - self::assertFalse($response['isEmailAvailable']['is_email_available']); + $emailConfig = $this->scopeConfig->getValue( + AccountManagement::GUEST_CHECKOUT_LOGIN_OPTION_SYS_CONFIG, + ScopeInterface::SCOPE_STORE, + $this->storeId + ); + if (!$emailConfig) { + self::assertTrue($response['isEmailAvailable']['is_email_available']); + } else { + self::assertFalse($response['isEmailAvailable']['is_email_available']); + } } /** diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Newsletter/Customer/SubscribeEmailToNewsletterTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Newsletter/Customer/SubscribeEmailToNewsletterTest.php index ec0e49cc55153..17c18521f2a2c 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Newsletter/Customer/SubscribeEmailToNewsletterTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Newsletter/Customer/SubscribeEmailToNewsletterTest.php @@ -8,11 +8,14 @@ namespace Magento\GraphQl\Newsletter\Customer; use Exception; +use Magento\Customer\Model\AccountManagement; use Magento\Customer\Model\CustomerAuthUpdate; use Magento\Customer\Model\CustomerRegistry; +use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\Exception\AuthenticationException; use Magento\Integration\Api\CustomerTokenServiceInterface; use Magento\Newsletter\Model\ResourceModel\Subscriber as SubscriberResourceModel; +use Magento\Store\Model\ScopeInterface; use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\TestCase\GraphQlAbstract; @@ -40,6 +43,10 @@ class SubscribeEmailToNewsletterTest extends GraphQlAbstract * @var SubscriberResourceModel */ private $subscriberResource; + /** + * @var ScopeConfigInterface + */ + private $scopeConfig; /** * @inheritDoc @@ -47,6 +54,7 @@ class SubscribeEmailToNewsletterTest extends GraphQlAbstract protected function setUp(): void { $objectManager = Bootstrap::getObjectManager(); + $this->scopeConfig = $objectManager->get(ScopeConfigInterface::class); $this->customerAuthUpdate = Bootstrap::getObjectManager()->get(CustomerAuthUpdate::class); $this->customerRegistry = Bootstrap::getObjectManager()->get(CustomerRegistry::class); $this->customerTokenService = $objectManager->get(CustomerTokenServiceInterface::class); @@ -146,10 +154,17 @@ public function testNewsletterSubscriptionWithAnotherCustomerEmail() { $query = $this->getQuery('customer2@search.example.com'); - $this->expectException(Exception::class); - $this->expectExceptionMessage('Cannot create a newsletter subscription.' . "\n"); - - $this->graphQlMutation($query, [], '', $this->getHeaderMap('customer@search.example.com')); + $guestLoginConfig = $this->scopeConfig->getValue( + AccountManagement::GUEST_CHECKOUT_LOGIN_OPTION_SYS_CONFIG, + ScopeInterface::SCOPE_WEBSITE, + 1 + ); + + if ($guestLoginConfig) { + $this->expectException(Exception::class); + $this->expectExceptionMessage('Cannot create a newsletter subscription.' . "\n"); + $this->graphQlMutation($query, [], '', $this->getHeaderMap('customer@search.example.com')); + } } /** diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/RemoveItemFromCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/RemoveItemFromCartTest.php index 2f64d0898c301..08c0237bf8dd5 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/RemoveItemFromCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/RemoveItemFromCartTest.php @@ -11,6 +11,7 @@ use Magento\GraphQl\Quote\GetQuoteItemIdByReservedQuoteIdAndSku; use Magento\Integration\Api\CustomerTokenServiceInterface; use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\TestCase\GraphQl\ResponseContainsErrorsException; use Magento\TestFramework\TestCase\GraphQlAbstract; /** @@ -148,12 +149,56 @@ public function testRemoveItemFromAnotherCustomerCart() 'simple_product' ); - $this->expectExceptionMessage( - "The current user cannot perform operations on cart \"$anotherCustomerQuoteMaskedId\"" - ); - $query = $this->getQuery($anotherCustomerQuoteMaskedId, $anotherCustomerQuoteItemId); - $this->graphQlMutation($query, [], '', $this->getHeaderMap('customer2@search.example.com')); + + try { + $this->graphQlMutation( + $query, + [], + '', + $this->getHeaderMap('customer2@search.example.com') + ); + $this->fail('ResponseContainsErrorsException was not thrown'); + } catch (ResponseContainsErrorsException $e) { + $this->assertStringContainsString( + "The current user cannot perform operations on cart \"$anotherCustomerQuoteMaskedId\"", + $e->getMessage() + ); + $cartQuery = $this->getCartQuery($anotherCustomerQuoteMaskedId); + $cart = $this->graphQlQuery( + $cartQuery, + [], + '', + $this->getHeaderMap('customer@search.example.com') + ); + $this->assertTrue(count($cart['cart']['items']) > 0, 'The cart is empty'); + $this->assertTrue( + $cart['cart']['items'][0]['product']['sku'] === 'simple_product', + 'The cart doesn\'t contain product' + ); + } + } + + /** + * @param string $maskedQuoteId + * @return string + */ + private function getCartQuery(string $maskedQuoteId): string + { + return <<<QUERY +{ + cart(cart_id: "{$maskedQuoteId}") { + id + items { + id + quantity + product { + sku + } + } + } +} +QUERY; } /** diff --git a/dev/tests/integration/testsuite/Magento/Customer/Model/AccountManagementTest.php b/dev/tests/integration/testsuite/Magento/Customer/Model/AccountManagementTest.php index f671cf1e69b63..c9196a581f542 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Model/AccountManagementTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Model/AccountManagementTest.php @@ -9,6 +9,7 @@ use Magento\Customer\Api\AccountManagementInterface; use Magento\Customer\Api\AddressRepositoryInterface; use Magento\Customer\Api\Data\AddressInterface; +use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\Exception\InputException; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Exception\State\ExpiredException; @@ -16,6 +17,7 @@ use Magento\Framework\Session\SessionManagerInterface; use Magento\Framework\Stdlib\DateTime; use Magento\Framework\Url as UrlBuilder; +use Magento\Store\Model\ScopeInterface; use Magento\Store\Model\StoreManagerInterface; use Magento\TestFramework\Helper\Bootstrap; @@ -604,7 +606,18 @@ public function testResendConfirmationNotNeeded() */ public function testIsEmailAvailable() { - $this->assertFalse($this->accountManagement->isEmailAvailable('customer@example.com', 1)); + $scopeConfig = $this->objectManager->get(ScopeConfigInterface::class); + $guestLoginConfig = $scopeConfig->getValue( + AccountManagement::GUEST_CHECKOUT_LOGIN_OPTION_SYS_CONFIG, + ScopeInterface::SCOPE_WEBSITE, + 1 + ); + + if (!$guestLoginConfig) { + $this->assertTrue($this->accountManagement->isEmailAvailable('customer@example.com', 1)); + } else { + $this->assertFalse($this->accountManagement->isEmailAvailable('customer@example.com', 1)); + } } /** @@ -612,7 +625,18 @@ public function testIsEmailAvailable() */ public function testIsEmailAvailableNoWebsiteSpecified() { - $this->assertFalse($this->accountManagement->isEmailAvailable('customer@example.com')); + $scopeConfig = $this->objectManager->get(ScopeConfigInterface::class); + $guestLoginConfig = $scopeConfig->getValue( + AccountManagement::GUEST_CHECKOUT_LOGIN_OPTION_SYS_CONFIG, + ScopeInterface::SCOPE_WEBSITE, + 1 + ); + + if (!$guestLoginConfig) { + $this->assertTrue($this->accountManagement->isEmailAvailable('customer@example.com')); + } else { + $this->assertFalse($this->accountManagement->isEmailAvailable('customer@example.com')); + } } /** diff --git a/dev/tests/integration/testsuite/Magento/Framework/App/ResourceConnection/ConnectionFactoryTest.php b/dev/tests/integration/testsuite/Magento/Framework/App/ResourceConnection/ConnectionFactoryTest.php index 93ed3d84c8452..72ba459997c32 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/App/ResourceConnection/ConnectionFactoryTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/App/ResourceConnection/ConnectionFactoryTest.php @@ -36,7 +36,8 @@ public function testCreate() ]; $connection = $this->model->create($dbConfig); $this->assertInstanceOf(\Magento\Framework\DB\Adapter\AdapterInterface::class, $connection); - $this->assertClassHasAttribute('logger', get_class($connection)); + $this->assertIsObject($connection); + $this->assertTrue(property_exists($connection, 'logger')); $object = new ReflectionClass(get_class($connection)); $attribute = $object->getProperty('logger'); $attribute->setAccessible(true); diff --git a/dev/tests/integration/testsuite/Magento/Framework/ObjectManager/ObjectManagerTest.php b/dev/tests/integration/testsuite/Magento/Framework/ObjectManager/ObjectManagerTest.php index 9b5ea2f361ba9..03de1a5ac09ab 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/ObjectManager/ObjectManagerTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/ObjectManager/ObjectManagerTest.php @@ -12,25 +12,27 @@ class ObjectManagerTest extends \PHPUnit\Framework\TestCase /**#@+ * Test class with type error */ - const TEST_CLASS_WITH_TYPE_ERROR = \Magento\Framework\ObjectManager\TestAsset\ConstructorWithTypeError::class; + public const TEST_CLASS_WITH_TYPE_ERROR = + \Magento\Framework\ObjectManager\TestAsset\ConstructorWithTypeError::class; /**#@+ * Test classes for basic instantiation */ - const TEST_CLASS = \Magento\Framework\ObjectManager\TestAsset\Basic::class; + public const TEST_CLASS = \Magento\Framework\ObjectManager\TestAsset\Basic::class; - const TEST_CLASS_INJECTION = \Magento\Framework\ObjectManager\TestAsset\BasicInjection::class; + public const TEST_CLASS_INJECTION = \Magento\Framework\ObjectManager\TestAsset\BasicInjection::class; /**#@-*/ /**#@+ * Test classes and interface to test preferences */ - const TEST_INTERFACE = \Magento\Framework\ObjectManager\TestAsset\TestAssetInterface::class; + public const TEST_INTERFACE = \Magento\Framework\ObjectManager\TestAsset\TestAssetInterface::class; - const TEST_INTERFACE_IMPLEMENTATION = \Magento\Framework\ObjectManager\TestAsset\InterfaceImplementation::class; + public const TEST_INTERFACE_IMPLEMENTATION = + \Magento\Framework\ObjectManager\TestAsset\InterfaceImplementation::class; - const TEST_CLASS_WITH_INTERFACE = \Magento\Framework\ObjectManager\TestAsset\InterfaceInjection::class; + public const TEST_CLASS_WITH_INTERFACE = \Magento\Framework\ObjectManager\TestAsset\InterfaceInjection::class; /**#@-*/ @@ -141,7 +143,8 @@ public function testNewInstance($actualClassName, array $properties = [], $expec $object = new ReflectionClass($actualClassName); if ($properties) { foreach ($properties as $propertyName => $propertyClass) { - $this->assertClassHasAttribute($propertyName, $actualClassName); + $this->assertIsObject($testObject); + $this->assertTrue(property_exists($testObject, $propertyName)); $attribute = $object->getProperty($propertyName); $attribute->setAccessible(true); $propertyObject = $attribute->getValue($testObject); diff --git a/dev/tests/integration/testsuite/Magento/Framework/ProfilerTest.php b/dev/tests/integration/testsuite/Magento/Framework/ProfilerTest.php index 4a6c542a110bf..df400561e2ffa 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/ProfilerTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/ProfilerTest.php @@ -1,7 +1,5 @@ <?php /** - * Test case for \Magento\Framework\Profiler - * * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ @@ -25,7 +23,8 @@ public function testApplyConfigWithDrivers(array $config, array $expectedDrivers { $profiler = new \Magento\Framework\Profiler(); $profiler::applyConfig($config, ''); - $this->assertClassHasAttribute('_drivers', \Magento\Framework\Profiler::class); + $this->assertIsObject($profiler); + $this->assertTrue(property_exists($profiler, '_drivers')); $object = new ReflectionClass(\Magento\Framework\Profiler::class); $attribute = $object->getProperty('_drivers'); $attribute->setAccessible(true); diff --git a/dev/tests/integration/testsuite/Magento/ImportExport/Model/ExportTest.php b/dev/tests/integration/testsuite/Magento/ImportExport/Model/ExportTest.php index 50972ef0325a6..73aa382baafb3 100644 --- a/dev/tests/integration/testsuite/Magento/ImportExport/Model/ExportTest.php +++ b/dev/tests/integration/testsuite/Magento/ImportExport/Model/ExportTest.php @@ -35,7 +35,8 @@ public function testGetEntityAdapterWithValidEntity($entity, $expectedEntityType { $this->_model->setData(['entity' => $entity]); $this->_model->getEntityAttributeCollection(); - $this->assertClassHasAttribute('_entityAdapter', get_class($this->_model)); + $this->assertIsObject($this->_model); + $this->assertTrue(property_exists($this->_model, '_entityAdapter')); $object = new ReflectionClass(get_class($this->_model)); $attribute = $object->getProperty('_entityAdapter'); $attribute->setAccessible(true); diff --git a/dev/tests/integration/testsuite/Magento/Newsletter/Controller/Subscriber/NewActionTest.php b/dev/tests/integration/testsuite/Magento/Newsletter/Controller/Subscriber/NewActionTest.php index 63670e9cb458d..f0c5ce25911f4 100644 --- a/dev/tests/integration/testsuite/Magento/Newsletter/Controller/Subscriber/NewActionTest.php +++ b/dev/tests/integration/testsuite/Magento/Newsletter/Controller/Subscriber/NewActionTest.php @@ -8,12 +8,15 @@ namespace Magento\Newsletter\Controller\Subscriber; use Magento\Customer\Api\CustomerRepositoryInterface; +use Magento\Customer\Model\AccountManagement; use Magento\Customer\Model\Session; use Magento\Customer\Model\Url; +use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\App\Request\Http as HttpRequest; use Magento\Newsletter\Model\ResourceModel\Subscriber as SubscriberResource; use Magento\Newsletter\Model\ResourceModel\Subscriber\CollectionFactory; use Magento\Newsletter\Model\ResourceModel\Subscriber\Grid\Collection as GridCollection; +use Magento\Store\Model\ScopeInterface; use Magento\TestFramework\TestCase\AbstractController; use Laminas\Stdlib\Parameters; @@ -222,8 +225,18 @@ public function testWithEmailAssignedToAnotherCustomer(): void $this->session->loginById(1); $this->prepareRequest('customer2@search.example.com'); $this->dispatch('newsletter/subscriber/new'); + $scopeConfig = $this->_objectManager->get(ScopeConfigInterface::class); + $guestLoginConfig = $scopeConfig->getValue( + AccountManagement::GUEST_CHECKOUT_LOGIN_OPTION_SYS_CONFIG, + ScopeInterface::SCOPE_WEBSITE, + 1 + ); - $this->performAsserts('This email address is already assigned to another user.'); + if ($guestLoginConfig) { + $this->performAsserts('This email address is already assigned to another user.'); + } else { + $this->performAsserts('This email address is already subscribed.'); + } } /** diff --git a/dev/tests/integration/testsuite/Magento/Ups/Model/CarrierTest.php b/dev/tests/integration/testsuite/Magento/Ups/Model/CarrierTest.php index ce271e5102099..0e20b6723b6e0 100644 --- a/dev/tests/integration/testsuite/Magento/Ups/Model/CarrierTest.php +++ b/dev/tests/integration/testsuite/Magento/Ups/Model/CarrierTest.php @@ -14,13 +14,13 @@ use Magento\Framework\HTTP\AsyncClient\Response; use Magento\Framework\HTTP\AsyncClientInterface; use Magento\Quote\Model\Quote\Address\RateRequest; +use Magento\Quote\Model\Quote\Address\RateRequestFactory; use Magento\Quote\Model\Quote\Address\RateResult\Error; +use Magento\Shipping\Model\Shipment\Request; use Magento\TestFramework\Helper\Bootstrap; -use Magento\Quote\Model\Quote\Address\RateRequestFactory; use Magento\TestFramework\HTTP\AsyncClientInterfaceMock; -use PHPUnit\Framework\TestCase; use PHPUnit\Framework\MockObject\MockObject; -use Magento\Shipping\Model\Shipment\Request; +use PHPUnit\Framework\TestCase; use Psr\Log\LoggerInterface; /** @@ -113,29 +113,54 @@ public function testGetShipConfirmUrlLive() } /** - * Collect free rates. + * Collect rates for UPS Ground method. * * @magentoConfigFixture current_store carriers/ups/active 1 - * @magentoConfigFixture current_store carriers/ups/type UPS - * @magentoConfigFixture current_store carriers/ups/allowed_methods 1DA,GND - * @magentoConfigFixture current_store carriers/ups/free_method GND + * @magentoConfigFixture current_store carriers/ups/type UPS_XML + * @magentoConfigFixture current_store carriers/ups/allowed_methods 03 + * @magentoConfigFixture current_store carriers/ups/free_method 03 + * @magentoConfigFixture default_store carriers/ups/shipper_number 12345 + * @magentoConfigFixture default_store carriers/ups/origin_shipment Shipments Originating in the United States + * @magentoConfigFixture default_store carriers/ups/username user + * @magentoConfigFixture default_store carriers/ups/password pass + * @magentoConfigFixture default_store carriers/ups/access_license_number acn + * @magentoConfigFixture default_store carriers/ups/debug 1 + * @magentoConfigFixture default_store currency/options/allow USD,EUR + * @magentoConfigFixture default_store currency/options/base USD */ public function testCollectFreeRates() { - $rateRequest = Bootstrap::getObjectManager()->get(RateRequestFactory::class)->create(); - $rateRequest->setDestCountryId('US'); - $rateRequest->setDestRegionId('CA'); - $rateRequest->setDestPostcode('90001'); - $rateRequest->setPackageQty(1); - $rateRequest->setPackageWeight(1); - $rateRequest->setFreeMethodWeight(0); - $rateRequest->setLimitCarrier($this->carrier::CODE); - $rateRequest->setFreeShipping(true); - $rateResult = $this->carrier->collectRates($rateRequest); - $result = $rateResult->asArray(); - $methods = $result[$this->carrier::CODE]['methods']; - $this->assertEquals(0, $methods['GND']['price']); - $this->assertNotEquals(0, $methods['1DA']['price']); + $request = Bootstrap::getObjectManager()->create( + RateRequest::class, + [ + 'data' => [ + 'dest_country' => 'US', + 'dest_postal' => '90001', + 'package_weight' => '1', + 'package_qty' => '1', + 'free_method_weight' => '5', + 'product' => '11', + 'action' => 'Rate', + 'unit_measure' => 'KGS', + 'free_shipping' => '1', + 'base_currency' => new DataObject(['code' => 'USD']) + ] + ] + ); + //phpcs:disable Magento2.Functions.DiscouragedFunction + $this->httpClient->nextResponses( + [ + new Response( + 200, + [], + file_get_contents(__DIR__ . "/../_files/ups_rates_response_option9.xml") + ) + ] + ); + + $rates = $this->carrier->collectRates($request)->getAllRates(); + $this->assertEquals('19.19', $rates[0]->getPrice()); + $this->assertEquals('03', $rates[0]->getMethod()); } /** @@ -181,7 +206,7 @@ public function testCollectRates(int $negotiable, int $tax, int $responseId, str new Response( 200, [], - file_get_contents(__DIR__ ."/../_files/ups_rates_response_option$responseId.xml") + file_get_contents(__DIR__ . "/../_files/ups_rates_response_option$responseId.xml") ) ] ); @@ -283,9 +308,9 @@ public function collectRatesDataProvider() public function testRequestToShipment(): void { //phpcs:disable Magento2.Functions.DiscouragedFunction - $expectedShipmentRequest = file_get_contents(__DIR__ .'/../_files/ShipmentConfirmRequest.xml'); - $shipmentResponse = file_get_contents(__DIR__ .'/../_files/ShipmentConfirmResponse.xml'); - $acceptResponse = file_get_contents(__DIR__ .'/../_files/ShipmentAcceptResponse.xml'); + $expectedShipmentRequest = file_get_contents(__DIR__ . '/../_files/ShipmentConfirmRequest.xml'); + $shipmentResponse = file_get_contents(__DIR__ . '/../_files/ShipmentConfirmResponse.xml'); + $acceptResponse = file_get_contents(__DIR__ . '/../_files/ShipmentAcceptResponse.xml'); //phpcs:enable Magento2.Functions.DiscouragedFunction $this->httpClient->nextResponses( [ diff --git a/dev/tests/integration/testsuite/Magento/Ups/_files/ups_rates_response_option9.xml b/dev/tests/integration/testsuite/Magento/Ups/_files/ups_rates_response_option9.xml new file mode 100644 index 0000000000000..2e5c4bc0ddbfd --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Ups/_files/ups_rates_response_option9.xml @@ -0,0 +1,299 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<RatingServiceSelectionResponse> + <Response> + <TransactionReference> + <CustomerContext>Rating and Service</CustomerContext> + <XpciVersion>1.0</XpciVersion> + </TransactionReference> + <ResponseStatusCode>1</ResponseStatusCode> + <ResponseStatusDescription>Success</ResponseStatusDescription> + </Response> + <RatedShipment> + <Service> + <Code>12</Code> + </Service> + <RatedShipmentWarning>Your invoice may vary from the displayed reference rates</RatedShipmentWarning> + <BillingWeight> + <UnitOfMeasurement> + <Code>LBS</Code> + </UnitOfMeasurement> + <Weight>20.0</Weight> + </BillingWeight> + <TransportationCharges> + <CurrencyCode>USD</CurrencyCode> + <MonetaryValue>43.19</MonetaryValue> + </TransportationCharges> + <ServiceOptionsCharges> + <CurrencyCode>USD</CurrencyCode> + <MonetaryValue>0.00</MonetaryValue> + </ServiceOptionsCharges> + <TotalCharges> + <CurrencyCode>USD</CurrencyCode> + <MonetaryValue>43.19</MonetaryValue> + </TotalCharges> + <GuaranteedDaysToDelivery>3</GuaranteedDaysToDelivery> + <ScheduledDeliveryTime /> + <RatedPackage> + <TransportationCharges> + <CurrencyCode>USD</CurrencyCode> + <MonetaryValue>43.19</MonetaryValue> + </TransportationCharges> + <ServiceOptionsCharges> + <CurrencyCode>USD</CurrencyCode> + <MonetaryValue>0.00</MonetaryValue> + </ServiceOptionsCharges> + <TotalCharges> + <CurrencyCode>USD</CurrencyCode> + <MonetaryValue>43.19</MonetaryValue> + </TotalCharges> + <Weight>20.0</Weight> + <BillingWeight> + <UnitOfMeasurement> + <Code>LBS</Code> + </UnitOfMeasurement> + <Weight>20.0</Weight> + </BillingWeight> + </RatedPackage> + </RatedShipment> + <RatedShipment> + <Service> + <Code>14</Code> + </Service> + <RatedShipmentWarning>Your invoice may vary from the displayed reference rates</RatedShipmentWarning> + <BillingWeight> + <UnitOfMeasurement> + <Code>LBS</Code> + </UnitOfMeasurement> + <Weight>20.0</Weight> + </BillingWeight> + <TransportationCharges> + <CurrencyCode>USD</CurrencyCode> + <MonetaryValue>122.34</MonetaryValue> + </TransportationCharges> + <ServiceOptionsCharges> + <CurrencyCode>USD</CurrencyCode> + <MonetaryValue>0.00</MonetaryValue> + </ServiceOptionsCharges> + <TotalCharges> + <CurrencyCode>USD</CurrencyCode> + <MonetaryValue>122.34</MonetaryValue> + </TotalCharges> + <GuaranteedDaysToDelivery>1</GuaranteedDaysToDelivery> + <ScheduledDeliveryTime>8:00 A.M.</ScheduledDeliveryTime> + <RatedPackage> + <TransportationCharges> + <CurrencyCode>USD</CurrencyCode> + <MonetaryValue>122.34</MonetaryValue> + </TransportationCharges> + <ServiceOptionsCharges> + <CurrencyCode>USD</CurrencyCode> + <MonetaryValue>0.00</MonetaryValue> + </ServiceOptionsCharges> + <TotalCharges> + <CurrencyCode>USD</CurrencyCode> + <MonetaryValue>122.34</MonetaryValue> + </TotalCharges> + <Weight>20.0</Weight> + <BillingWeight> + <UnitOfMeasurement> + <Code>LBS</Code> + </UnitOfMeasurement> + <Weight>20.0</Weight> + </BillingWeight> + </RatedPackage> + </RatedShipment> + <RatedShipment> + <Service> + <Code>03</Code> + </Service> + <RatedShipmentWarning>Your invoice may vary from the displayed reference rates</RatedShipmentWarning> + <BillingWeight> + <UnitOfMeasurement> + <Code>LBS</Code> + </UnitOfMeasurement> + <Weight>20.0</Weight> + </BillingWeight> + <TransportationCharges> + <CurrencyCode>USD</CurrencyCode> + <MonetaryValue>19.19</MonetaryValue> + </TransportationCharges> + <ServiceOptionsCharges> + <CurrencyCode>USD</CurrencyCode> + <MonetaryValue>0.00</MonetaryValue> + </ServiceOptionsCharges> + <TotalCharges> + <CurrencyCode>USD</CurrencyCode> + <MonetaryValue>19.19</MonetaryValue> + </TotalCharges> + <GuaranteedDaysToDelivery /> + <ScheduledDeliveryTime /> + <RatedPackage> + <TransportationCharges> + <CurrencyCode>USD</CurrencyCode> + <MonetaryValue>19.19</MonetaryValue> + </TransportationCharges> + <ServiceOptionsCharges> + <CurrencyCode>USD</CurrencyCode> + <MonetaryValue>0.00</MonetaryValue> + </ServiceOptionsCharges> + <TotalCharges> + <CurrencyCode>USD</CurrencyCode> + <MonetaryValue>19.19</MonetaryValue> + </TotalCharges> + <Weight>20.0</Weight> + <BillingWeight> + <UnitOfMeasurement> + <Code>LBS</Code> + </UnitOfMeasurement> + <Weight>20.0</Weight> + </BillingWeight> + </RatedPackage> + </RatedShipment> + <RatedShipment> + <Service> + <Code>13</Code> + </Service> + <RatedShipmentWarning>Your invoice may vary from the displayed reference rates</RatedShipmentWarning> + <BillingWeight> + <UnitOfMeasurement> + <Code>LBS</Code> + </UnitOfMeasurement> + <Weight>20.0</Weight> + </BillingWeight> + <TransportationCharges> + <CurrencyCode>USD</CurrencyCode> + <MonetaryValue>82.24</MonetaryValue> + </TransportationCharges> + <ServiceOptionsCharges> + <CurrencyCode>USD</CurrencyCode> + <MonetaryValue>0.00</MonetaryValue> + </ServiceOptionsCharges> + <TotalCharges> + <CurrencyCode>USD</CurrencyCode> + <MonetaryValue>82.24</MonetaryValue> + </TotalCharges> + <GuaranteedDaysToDelivery>1</GuaranteedDaysToDelivery> + <ScheduledDeliveryTime /> + <RatedPackage> + <TransportationCharges> + <CurrencyCode>USD</CurrencyCode> + <MonetaryValue>82.24</MonetaryValue> + </TransportationCharges> + <ServiceOptionsCharges> + <CurrencyCode>USD</CurrencyCode> + <MonetaryValue>0.00</MonetaryValue> + </ServiceOptionsCharges> + <TotalCharges> + <CurrencyCode>USD</CurrencyCode> + <MonetaryValue>82.24</MonetaryValue> + </TotalCharges> + <Weight>20.0</Weight> + <BillingWeight> + <UnitOfMeasurement> + <Code>LBS</Code> + </UnitOfMeasurement> + <Weight>20.0</Weight> + </BillingWeight> + </RatedPackage> + </RatedShipment> + <RatedShipment> + <Service> + <Code>01</Code> + </Service> + <RatedShipmentWarning>Your invoice may vary from the displayed reference rates</RatedShipmentWarning> + <BillingWeight> + <UnitOfMeasurement> + <Code>LBS</Code> + </UnitOfMeasurement> + <Weight>20.0</Weight> + </BillingWeight> + <TransportationCharges> + <CurrencyCode>USD</CurrencyCode> + <MonetaryValue>88.14</MonetaryValue> + </TransportationCharges> + <ServiceOptionsCharges> + <CurrencyCode>USD</CurrencyCode> + <MonetaryValue>0.00</MonetaryValue> + </ServiceOptionsCharges> + <TotalCharges> + <CurrencyCode>USD</CurrencyCode> + <MonetaryValue>88.14</MonetaryValue> + </TotalCharges> + <GuaranteedDaysToDelivery>1</GuaranteedDaysToDelivery> + <ScheduledDeliveryTime>10:30 A.M.</ScheduledDeliveryTime> + <RatedPackage> + <TransportationCharges> + <CurrencyCode>USD</CurrencyCode> + <MonetaryValue>88.14</MonetaryValue> + </TransportationCharges> + <ServiceOptionsCharges> + <CurrencyCode>USD</CurrencyCode> + <MonetaryValue>0.00</MonetaryValue> + </ServiceOptionsCharges> + <TotalCharges> + <CurrencyCode>USD</CurrencyCode> + <MonetaryValue>88.14</MonetaryValue> + </TotalCharges> + <Weight>20.0</Weight> + <BillingWeight> + <UnitOfMeasurement> + <Code>LBS</Code> + </UnitOfMeasurement> + <Weight>20.0</Weight> + </BillingWeight> + </RatedPackage> + </RatedShipment> + <RatedShipment> + <Service> + <Code>02</Code> + </Service> + <RatedShipmentWarning>Your invoice may vary from the displayed reference rates</RatedShipmentWarning> + <BillingWeight> + <UnitOfMeasurement> + <Code>LBS</Code> + </UnitOfMeasurement> + <Weight>20.0</Weight> + </BillingWeight> + <TransportationCharges> + <CurrencyCode>USD</CurrencyCode> + <MonetaryValue>57.11</MonetaryValue> + </TransportationCharges> + <ServiceOptionsCharges> + <CurrencyCode>USD</CurrencyCode> + <MonetaryValue>0.00</MonetaryValue> + </ServiceOptionsCharges> + <TotalCharges> + <CurrencyCode>USD</CurrencyCode> + <MonetaryValue>57.11</MonetaryValue> + </TotalCharges> + <GuaranteedDaysToDelivery>2</GuaranteedDaysToDelivery> + <ScheduledDeliveryTime /> + <RatedPackage> + <TransportationCharges> + <CurrencyCode>USD</CurrencyCode> + <MonetaryValue>57.11</MonetaryValue> + </TransportationCharges> + <ServiceOptionsCharges> + <CurrencyCode>USD</CurrencyCode> + <MonetaryValue>0.00</MonetaryValue> + </ServiceOptionsCharges> + <TotalCharges> + <CurrencyCode>USD</CurrencyCode> + <MonetaryValue>57.11</MonetaryValue> + </TotalCharges> + <Weight>20.0</Weight> + <BillingWeight> + <UnitOfMeasurement> + <Code>LBS</Code> + </UnitOfMeasurement> + <Weight>20.0</Weight> + </BillingWeight> + </RatedPackage> + </RatedShipment> +</RatingServiceSelectionResponse> diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/data-storage.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/data-storage.test.js index 7a6da6dcae57e..f95a5397b1168 100644 --- a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/data-storage.test.js +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/data-storage.test.js @@ -295,7 +295,8 @@ define([ result = { items: items, totalRecords: 2, - errorMessage: '' + errorMessage: '', + showTotalRecords: true }, model = new DataStorage({ cachedRequestDelay: 0 diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/constraint_modification.mariadb10427.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/constraint_modification.mariadb10427.php new file mode 100644 index 0000000000000..f00c9a1eb08c4 --- /dev/null +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/constraint_modification.mariadb10427.php @@ -0,0 +1,59 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +// @codingStandardsIgnoreFile +return [ + 'auto_increment_test' => 'CREATE TABLE `auto_increment_test` ( + `int_auto_increment_with_nullable` int(10) unsigned NOT NULL AUTO_INCREMENT, + `int_disabled_auto_increment` smallint(5) unsigned DEFAULT 0, + UNIQUE KEY `AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE` (`int_auto_increment_with_nullable`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci', + 'reference_table' => 'CREATE TABLE `reference_table` ( + `tinyint_ref` tinyint(4) NOT NULL AUTO_INCREMENT, + `tinyint_without_padding` tinyint(4) NOT NULL DEFAULT 0, + `bigint_without_padding` bigint(20) NOT NULL DEFAULT 0, + `smallint_without_padding` smallint(6) NOT NULL DEFAULT 0, + `integer_without_padding` int(11) NOT NULL DEFAULT 0, + `smallint_with_big_padding` smallint(6) NOT NULL DEFAULT 0, + `smallint_without_default` smallint(6) DEFAULT NULL, + `int_without_unsigned` int(11) DEFAULT NULL, + `int_unsigned` int(10) unsigned DEFAULT NULL, + `bigint_default_nullable` bigint(20) unsigned DEFAULT 1, + `bigint_not_default_not_nullable` bigint(20) unsigned NOT NULL, + `smallint_ref` smallint(6) NOT NULL DEFAULT 0, + PRIMARY KEY (`tinyint_ref`,`smallint_ref`), + UNIQUE KEY `REFERENCE_TABLE_SMALLINT_REF` (`smallint_ref`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci', + 'test_table' => 'CREATE TABLE `test_table` ( + `smallint` smallint(6) DEFAULT NULL, + `tinyint` tinyint(4) DEFAULT NULL, + `bigint` bigint(20) DEFAULT 0, + `float` float(12,10) DEFAULT 0.0000000000, + `double` double(245,10) DEFAULT 11111111.1111110000, + `decimal` decimal(15,4) DEFAULT 0.0000, + `date` date DEFAULT NULL, + `timestamp` timestamp NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(), + `datetime` datetime DEFAULT \'0000-00-00 00:00:00\', + `longtext` longtext DEFAULT NULL, + `mediumtext` mediumtext DEFAULT NULL, + `varchar` varchar(254) DEFAULT NULL, + `char` char(255) DEFAULT NULL, + `mediumblob` mediumblob DEFAULT NULL, + `blob` blob DEFAULT NULL, + `boolean` tinyint(1) DEFAULT NULL, + `integer_main` int(10) unsigned DEFAULT NULL, + `smallint_main` smallint(6) NOT NULL DEFAULT 0, + UNIQUE KEY `TEST_TABLE_SMALLINT_FLOAT` (`smallint`,`float`), + UNIQUE KEY `TEST_TABLE_DOUBLE` (`double`), + KEY `TEST_TABLE_TINYINT_BIGINT` (`tinyint`,`bigint`), + KEY `TEST_TABLE_SMALLINT_MAIN_REFERENCE_TABLE_SMALLINT_REF` (`smallint_main`), + KEY `FK_FB77604C299EB8612D01E4AF8D9931F2` (`integer_main`), + CONSTRAINT `FK_FB77604C299EB8612D01E4AF8D9931F2` FOREIGN KEY (`integer_main`) REFERENCES `auto_increment_test` (`int_auto_increment_with_nullable`) ON DELETE CASCADE, + CONSTRAINT `TEST_TABLE_SMALLINT_MAIN_REFERENCE_TABLE_SMALLINT_REF` FOREIGN KEY (`smallint_main`) REFERENCES `reference_table` (`smallint_ref`) ON DELETE CASCADE, + CONSTRAINT `TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF` FOREIGN KEY (`tinyint`) REFERENCES `reference_table` (`tinyint_ref`) ON DELETE SET NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci', +]; diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/constraint_modification.mariadb10611.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/constraint_modification.mariadb10611.php new file mode 100644 index 0000000000000..b6d4eca91d6a0 --- /dev/null +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/constraint_modification.mariadb10611.php @@ -0,0 +1,59 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +// @codingStandardsIgnoreFile +return [ + 'auto_increment_test' => 'CREATE TABLE `auto_increment_test` ( + `int_auto_increment_with_nullable` int(10) unsigned NOT NULL AUTO_INCREMENT, + `int_disabled_auto_increment` smallint(5) unsigned DEFAULT 0, + UNIQUE KEY `AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE` (`int_auto_increment_with_nullable`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci', + 'reference_table' => 'CREATE TABLE `reference_table` ( + `tinyint_ref` tinyint(4) NOT NULL AUTO_INCREMENT, + `tinyint_without_padding` tinyint(4) NOT NULL DEFAULT 0, + `bigint_without_padding` bigint(20) NOT NULL DEFAULT 0, + `smallint_without_padding` smallint(6) NOT NULL DEFAULT 0, + `integer_without_padding` int(11) NOT NULL DEFAULT 0, + `smallint_with_big_padding` smallint(6) NOT NULL DEFAULT 0, + `smallint_without_default` smallint(6) DEFAULT NULL, + `int_without_unsigned` int(11) DEFAULT NULL, + `int_unsigned` int(10) unsigned DEFAULT NULL, + `bigint_default_nullable` bigint(20) unsigned DEFAULT 1, + `bigint_not_default_not_nullable` bigint(20) unsigned NOT NULL, + `smallint_ref` smallint(6) NOT NULL DEFAULT 0, + PRIMARY KEY (`tinyint_ref`,`smallint_ref`), + UNIQUE KEY `REFERENCE_TABLE_SMALLINT_REF` (`smallint_ref`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci', + 'test_table' => 'CREATE TABLE `test_table` ( + `smallint` smallint(6) DEFAULT NULL, + `tinyint` tinyint(4) DEFAULT NULL, + `bigint` bigint(20) DEFAULT 0, + `float` float(12,10) DEFAULT 0.0000000000, + `double` double(245,10) DEFAULT 11111111.1111110000, + `decimal` decimal(15,4) DEFAULT 0.0000, + `date` date DEFAULT NULL, + `timestamp` timestamp NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(), + `datetime` datetime DEFAULT \'0000-00-00 00:00:00\', + `longtext` longtext DEFAULT NULL, + `mediumtext` mediumtext DEFAULT NULL, + `varchar` varchar(254) DEFAULT NULL, + `char` char(255) DEFAULT NULL, + `mediumblob` mediumblob DEFAULT NULL, + `blob` blob DEFAULT NULL, + `boolean` tinyint(1) DEFAULT NULL, + `integer_main` int(10) unsigned DEFAULT NULL, + `smallint_main` smallint(6) NOT NULL DEFAULT 0, + UNIQUE KEY `TEST_TABLE_SMALLINT_FLOAT` (`smallint`,`float`), + UNIQUE KEY `TEST_TABLE_DOUBLE` (`double`), + KEY `TEST_TABLE_TINYINT_BIGINT` (`tinyint`,`bigint`), + KEY `TEST_TABLE_SMALLINT_MAIN_REFERENCE_TABLE_SMALLINT_REF` (`smallint_main`), + KEY `FK_FB77604C299EB8612D01E4AF8D9931F2` (`integer_main`), + CONSTRAINT `FK_FB77604C299EB8612D01E4AF8D9931F2` FOREIGN KEY (`integer_main`) REFERENCES `auto_increment_test` (`int_auto_increment_with_nullable`) ON DELETE CASCADE, + CONSTRAINT `TEST_TABLE_SMALLINT_MAIN_REFERENCE_TABLE_SMALLINT_REF` FOREIGN KEY (`smallint_main`) REFERENCES `reference_table` (`smallint_ref`) ON DELETE CASCADE, + CONSTRAINT `TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF` FOREIGN KEY (`tinyint`) REFERENCES `reference_table` (`tinyint_ref`) ON DELETE SET NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci', +]; diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/rollback.mariadb10427.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/rollback.mariadb10427.php new file mode 100644 index 0000000000000..45cb5f6938b41 --- /dev/null +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/rollback.mariadb10427.php @@ -0,0 +1,27 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +// @codingStandardsIgnoreFile +return [ + 'before' => [ + 'store' => 'CREATE TABLE `store` ( + `store_owner_id` smallint(6) DEFAULT NULL COMMENT \'Store Owner Reference\', + KEY `STORE_STORE_OWNER_ID_STORE_OWNER_OWNER_ID` (`store_owner_id`), + CONSTRAINT `STORE_STORE_OWNER_ID_STORE_OWNER_OWNER_ID` FOREIGN KEY (`store_owner_id`) REFERENCES `store_owner` (`owner_id`) ON DELETE SET NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci', + 'store_owner' => 'CREATE TABLE `store_owner` ( + `owner_id` smallint(6) NOT NULL AUTO_INCREMENT, + `store_owner_name` varchar(255) DEFAULT NULL COMMENT \'Store Owner Name\', + PRIMARY KEY (`owner_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT=\'Store owner information\'' + ], + 'after' => [ + 'store' => 'CREATE TABLE `store` ( + `store_owner` varchar(255) DEFAULT NULL COMMENT \'Store Owner Name\' +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci' + ] +]; diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/rollback.mariadb10611.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/rollback.mariadb10611.php new file mode 100644 index 0000000000000..c4c9f12fbaeee --- /dev/null +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/rollback.mariadb10611.php @@ -0,0 +1,27 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +// @codingStandardsIgnoreFile +return [ + 'before' => [ + 'store' => 'CREATE TABLE `store` ( + `store_owner_id` smallint(6) DEFAULT NULL COMMENT \'Store Owner Reference\', + KEY `STORE_STORE_OWNER_ID_STORE_OWNER_OWNER_ID` (`store_owner_id`), + CONSTRAINT `STORE_STORE_OWNER_ID_STORE_OWNER_OWNER_ID` FOREIGN KEY (`store_owner_id`) REFERENCES `store_owner` (`owner_id`) ON DELETE SET NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci', + 'store_owner' => 'CREATE TABLE `store_owner` ( + `owner_id` smallint(6) NOT NULL AUTO_INCREMENT, + `store_owner_name` varchar(255) DEFAULT NULL COMMENT \'Store Owner Name\', + PRIMARY KEY (`owner_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci COMMENT=\'Store owner information\'' + ], + 'after' => [ + 'store' => 'CREATE TABLE `store` ( + `store_owner` varchar(255) DEFAULT NULL COMMENT \'Store Owner Name\' +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci' + ] +]; diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/table_removal.mariadb10427.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/table_removal.mariadb10427.php new file mode 100644 index 0000000000000..bc469f23f6e2b --- /dev/null +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/table_removal.mariadb10427.php @@ -0,0 +1,14 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +return [ + 'auto_increment_test' => 'CREATE TABLE `auto_increment_test` ( + `int_auto_increment_with_nullable` int(10) unsigned NOT NULL AUTO_INCREMENT, + `int_disabled_auto_increment` smallint(5) unsigned DEFAULT 0, + UNIQUE KEY `AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE` (`int_auto_increment_with_nullable`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci' +]; diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/table_removal.mariadb10611.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/table_removal.mariadb10611.php new file mode 100644 index 0000000000000..403957ca0921d --- /dev/null +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/table_removal.mariadb10611.php @@ -0,0 +1,14 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +return [ + 'auto_increment_test' => 'CREATE TABLE `auto_increment_test` ( + `int_auto_increment_with_nullable` int(10) unsigned NOT NULL AUTO_INCREMENT, + `int_disabled_auto_increment` smallint(5) unsigned DEFAULT 0, + UNIQUE KEY `AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE` (`int_auto_increment_with_nullable`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci' +]; diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/table_rename.mariadb10427.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/table_rename.mariadb10427.php new file mode 100644 index 0000000000000..3c62923cf256f --- /dev/null +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/table_rename.mariadb10427.php @@ -0,0 +1,15 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +return [ + 'before' => 'CREATE TABLE `some_table` ( + `some_column` varchar(255) DEFAULT NULL COMMENT \'Some Column Name\' +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci', + 'after' => 'CREATE TABLE `some_table_renamed` ( + `some_column` varchar(255) DEFAULT NULL COMMENT \'Some Column Name\' +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci', +]; diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/table_rename.mariadb10611.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/table_rename.mariadb10611.php new file mode 100644 index 0000000000000..6568a59de2a33 --- /dev/null +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/declarative_installer/table_rename.mariadb10611.php @@ -0,0 +1,15 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +return [ + 'before' => 'CREATE TABLE `some_table` ( + `some_column` varchar(255) DEFAULT NULL COMMENT \'Some Column Name\' +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci', + 'after' => 'CREATE TABLE `some_table_renamed` ( + `some_column` varchar(255) DEFAULT NULL COMMENT \'Some Column Name\' +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci', +]; diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/dry_run_log.mariadb10611.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/dry_run_log.mariadb10611.php new file mode 100644 index 0000000000000..4d49221074315 --- /dev/null +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule1/fixture/dry_run_log.mariadb10611.php @@ -0,0 +1,58 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +// @codingStandardsIgnoreFile +return ['CREATE TABLE `reference_table` ( +`tinyint_ref` tinyint NOT NULL AUTO_INCREMENT , +`tinyint_without_padding` tinyint NOT NULL DEFAULT 0 , +`bigint_without_padding` bigint NOT NULL DEFAULT 0 , +`smallint_without_padding` smallint NOT NULL DEFAULT 0 , +`integer_without_padding` int NOT NULL DEFAULT 0 , +`smallint_with_big_padding` smallint NOT NULL DEFAULT 0 , +`smallint_without_default` smallint NULL , +`int_without_unsigned` int NULL , +`int_unsigned` int UNSIGNED NULL , +`bigint_default_nullable` bigint UNSIGNED NULL DEFAULT 1 , +`bigint_not_default_not_nullable` bigint UNSIGNED NOT NULL , +CONSTRAINT PRIMARY KEY (`tinyint_ref`) +) ENGINE=innodb DEFAULT CHARSET=utf8mb3 DEFAULT COLLATE=utf8mb3_general_ci + +CREATE TABLE `auto_increment_test` ( +`int_auto_increment_with_nullable` int UNSIGNED NOT NULL AUTO_INCREMENT , +`int_disabled_auto_increment` smallint UNSIGNED NULL DEFAULT 0 , +CONSTRAINT `AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE` UNIQUE KEY (`int_auto_increment_with_nullable`) +) ENGINE=innodb DEFAULT CHARSET=utf8mb3 DEFAULT COLLATE=utf8mb3_general_ci + +CREATE TABLE `test_table` ( +`smallint` smallint NOT NULL AUTO_INCREMENT , +`tinyint` tinyint NULL , +`bigint` bigint NULL DEFAULT 0 , +`float` float(12, 4) NULL DEFAULT 0 , +`double` decimal(14, 6) NULL DEFAULT 11111111.111111 , +`decimal` decimal(15, 4) NULL DEFAULT 0 , +`date` date NULL , +`timestamp` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP , +`datetime` datetime NULL DEFAULT 0 , +`longtext` longtext NULL , +`mediumtext` mediumtext NULL , +`varchar` varchar(254) NULL , +`char` char(255) NULL , +`mediumblob` mediumblob NULL , +`blob` blob NULL , +`boolean` BOOLEAN NULL , +CONSTRAINT `TEST_TABLE_SMALLINT_BIGINT` UNIQUE KEY (`smallint`,`bigint`), +CONSTRAINT `TEST_TABLE_TINYINT_REFERENCE_TABLE_TINYINT_REF` FOREIGN KEY (`tinyint`) REFERENCES `reference_table` (`tinyint_ref`) ON DELETE NO ACTION, +INDEX `TEST_TABLE_TINYINT_BIGINT` (`tinyint`,`bigint`) +) ENGINE=innodb DEFAULT CHARSET=utf8mb3 DEFAULT COLLATE=utf8mb3_general_ci + +CREATE TABLE `patch_list` ( +`patch_id` int NOT NULL AUTO_INCREMENT COMMENT "Patch Auto Increment", +`patch_name` varchar(1024) NOT NULL COMMENT "Patch Class Name", +CONSTRAINT PRIMARY KEY (`patch_id`) +) ENGINE=innodb DEFAULT CHARSET=utf8mb3 DEFAULT COLLATE=utf8mb3_general_ci COMMENT="List of data/schema patches" + +']; diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule2/fixture/shards.mariadb10427.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule2/fixture/shards.mariadb10427.php new file mode 100644 index 0000000000000..2ec165aedf085 --- /dev/null +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule2/fixture/shards.mariadb10427.php @@ -0,0 +1,38 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +return [ + 'test_table_one' => 'CREATE TABLE `test_table_one` ( + `smallint` smallint(6) NOT NULL AUTO_INCREMENT, + `varchar` varchar(254) DEFAULT NULL, + PRIMARY KEY (`smallint`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci', + 'test_table_two' => 'CREATE TABLE `test_table_two` ( + `smallint` smallint(6) NOT NULL AUTO_INCREMENT, + `varchar` varchar(254) DEFAULT NULL, + PRIMARY KEY (`smallint`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci', + 'reference_table' => 'CREATE TABLE `reference_table` ( + `tinyint_ref` tinyint(4) NOT NULL AUTO_INCREMENT, + `tinyint_without_padding` tinyint(4) NOT NULL DEFAULT 0, + `bigint_without_padding` bigint(20) NOT NULL DEFAULT 0, + `smallint_without_padding` smallint(6) NOT NULL DEFAULT 0, + `integer_without_padding` int(11) NOT NULL DEFAULT 0, + `smallint_with_big_padding` smallint(6) NOT NULL DEFAULT 0, + `smallint_without_default` smallint(6) DEFAULT NULL, + `int_without_unsigned` int(11) DEFAULT NULL, + `int_unsigned` int(10) unsigned DEFAULT NULL, + `bigint_default_nullable` bigint(20) unsigned DEFAULT 1, + `bigint_not_default_not_nullable` bigint(20) unsigned NOT NULL, + PRIMARY KEY (`tinyint_ref`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci', + 'auto_increment_test' => 'CREATE TABLE `auto_increment_test` ( + `int_auto_increment_with_nullable` int(10) unsigned NOT NULL AUTO_INCREMENT, + `int_disabled_auto_increment` smallint(5) unsigned DEFAULT 0, + UNIQUE KEY `AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE` (`int_auto_increment_with_nullable`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci' +]; diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule2/fixture/shards.mariadb10611.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule2/fixture/shards.mariadb10611.php new file mode 100644 index 0000000000000..1a1b02dce67cd --- /dev/null +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule2/fixture/shards.mariadb10611.php @@ -0,0 +1,38 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +return [ + 'test_table_one' => 'CREATE TABLE `test_table_one` ( + `smallint` smallint(6) NOT NULL AUTO_INCREMENT, + `varchar` varchar(254) DEFAULT NULL, + PRIMARY KEY (`smallint`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci', + 'test_table_two' => 'CREATE TABLE `test_table_two` ( + `smallint` smallint(6) NOT NULL AUTO_INCREMENT, + `varchar` varchar(254) DEFAULT NULL, + PRIMARY KEY (`smallint`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci', + 'reference_table' => 'CREATE TABLE `reference_table` ( + `tinyint_ref` tinyint(4) NOT NULL AUTO_INCREMENT, + `tinyint_without_padding` tinyint(4) NOT NULL DEFAULT 0, + `bigint_without_padding` bigint(20) NOT NULL DEFAULT 0, + `smallint_without_padding` smallint(6) NOT NULL DEFAULT 0, + `integer_without_padding` int(11) NOT NULL DEFAULT 0, + `smallint_with_big_padding` smallint(6) NOT NULL DEFAULT 0, + `smallint_without_default` smallint(6) DEFAULT NULL, + `int_without_unsigned` int(11) DEFAULT NULL, + `int_unsigned` int(10) unsigned DEFAULT NULL, + `bigint_default_nullable` bigint(20) unsigned DEFAULT 1, + `bigint_not_default_not_nullable` bigint(20) unsigned NOT NULL, + PRIMARY KEY (`tinyint_ref`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci', + 'auto_increment_test' => 'CREATE TABLE `auto_increment_test` ( + `int_auto_increment_with_nullable` int(10) unsigned NOT NULL AUTO_INCREMENT, + `int_disabled_auto_increment` smallint(5) unsigned DEFAULT 0, + UNIQUE KEY `AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE` (`int_auto_increment_with_nullable`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci' +]; diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule9/fixture/declarative_installer/disabling_tables.mariadb10427.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule9/fixture/declarative_installer/disabling_tables.mariadb10427.php new file mode 100644 index 0000000000000..bc469f23f6e2b --- /dev/null +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule9/fixture/declarative_installer/disabling_tables.mariadb10427.php @@ -0,0 +1,14 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +return [ + 'auto_increment_test' => 'CREATE TABLE `auto_increment_test` ( + `int_auto_increment_with_nullable` int(10) unsigned NOT NULL AUTO_INCREMENT, + `int_disabled_auto_increment` smallint(5) unsigned DEFAULT 0, + UNIQUE KEY `AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE` (`int_auto_increment_with_nullable`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci' +]; diff --git a/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule9/fixture/declarative_installer/disabling_tables.mariadb10611.php b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule9/fixture/declarative_installer/disabling_tables.mariadb10611.php new file mode 100644 index 0000000000000..403957ca0921d --- /dev/null +++ b/dev/tests/setup-integration/_files/Magento/TestSetupDeclarationModule9/fixture/declarative_installer/disabling_tables.mariadb10611.php @@ -0,0 +1,14 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +return [ + 'auto_increment_test' => 'CREATE TABLE `auto_increment_test` ( + `int_auto_increment_with_nullable` int(10) unsigned NOT NULL AUTO_INCREMENT, + `int_disabled_auto_increment` smallint(5) unsigned DEFAULT 0, + UNIQUE KEY `AUTO_INCREMENT_TEST_INT_AUTO_INCREMENT_WITH_NULLABLE` (`int_auto_increment_with_nullable`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci' +]; diff --git a/dev/tests/setup-integration/framework/Magento/TestFramework/Annotation/DataProviderFromFile.php b/dev/tests/setup-integration/framework/Magento/TestFramework/Annotation/DataProviderFromFile.php index b6e1a877b00cd..ce4ac8b360514 100644 --- a/dev/tests/setup-integration/framework/Magento/TestFramework/Annotation/DataProviderFromFile.php +++ b/dev/tests/setup-integration/framework/Magento/TestFramework/Annotation/DataProviderFromFile.php @@ -29,7 +29,9 @@ class DataProviderFromFile SqlVersionProvider::MYSQL_8_0_VERSION => 'mysql8', SqlVersionProvider::MARIA_DB_10_4_VERSION => 'mariadb10', SqlVersionProvider::MARIA_DB_10_6_VERSION => 'mariadb106', - SqlVersionProvider::MYSQL_8_0_29_VERSION => 'mysql829' + SqlVersionProvider::MYSQL_8_0_29_VERSION => 'mysql829', + SqlVersionProvider::MARIA_DB_10_4_27_VERSION => 'mariadb10427', + SqlVersionProvider::MARIA_DB_10_6_11_VERSION => 'mariadb10611' ]; /** diff --git a/dev/tests/setup-integration/framework/Magento/TestFramework/TestCase/SetupTestCase.php b/dev/tests/setup-integration/framework/Magento/TestFramework/TestCase/SetupTestCase.php index e69d109be0719..d58f1c06a8a05 100644 --- a/dev/tests/setup-integration/framework/Magento/TestFramework/TestCase/SetupTestCase.php +++ b/dev/tests/setup-integration/framework/Magento/TestFramework/TestCase/SetupTestCase.php @@ -110,6 +110,12 @@ private function getDbKey(): string if ($this->sqlVersionProvider->isMysqlGte8029()) { $this->dbKey = DataProviderFromFile::POSSIBLE_SUFFIXES[SqlVersionProvider::MYSQL_8_0_29_VERSION]; break; + } elseif ($this->sqlVersionProvider->isMariaDBGte10427()) { + $this->dbKey = DataProviderFromFile::POSSIBLE_SUFFIXES[SqlVersionProvider::MARIA_DB_10_4_27_VERSION]; + break; + } elseif ($this->sqlVersionProvider->isMariaDBGte10611()) { + $this->dbKey = DataProviderFromFile::POSSIBLE_SUFFIXES[SqlVersionProvider::MARIA_DB_10_6_11_VERSION]; + break; } elseif (strpos($this->getDatabaseVersion(), (string)$possibleVersion) !== false) { $this->dbKey = $suffix; break; diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/_files/extension_dependencies_test/allowed_dependencies/ce.php b/dev/tests/static/testsuite/Magento/Test/Integrity/_files/extension_dependencies_test/allowed_dependencies/ce.php index b4506499d0044..278bff7f0abf3 100644 --- a/dev/tests/static/testsuite/Magento/Test/Integrity/_files/extension_dependencies_test/allowed_dependencies/ce.php +++ b/dev/tests/static/testsuite/Magento/Test/Integrity/_files/extension_dependencies_test/allowed_dependencies/ce.php @@ -8,6 +8,7 @@ return [ 'Magento\Elasticsearch' => [ 'Magento\Elasticsearch7', + 'Magento\Elasticsearch8', 'Magento\OpenSearch' ] ]; diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/Magento/Framework/App/Action/AbstractActionTest.php b/dev/tests/static/testsuite/Magento/Test/Legacy/Magento/Framework/App/Action/AbstractActionTest.php index 69050c3c51895..e89dc78cc1efc 100644 --- a/dev/tests/static/testsuite/Magento/Test/Legacy/Magento/Framework/App/Action/AbstractActionTest.php +++ b/dev/tests/static/testsuite/Magento/Test/Legacy/Magento/Framework/App/Action/AbstractActionTest.php @@ -66,6 +66,7 @@ public function testNewControllersDoNotExtendAbstractAction(): void private function getTestFiles(): array { $phpFiles = AddedFiles::getAddedFilesList($this->getChangedFilesBaseDir()); + $phpFiles = array_diff($phpFiles, $this->getIgnoredFiles()); $phpFiles = Files::composeDataSets($phpFiles); $fileTypes = Files::INCLUDE_APP_CODE | Files::INCLUDE_LIBS | Files::AS_DATA_SET; @@ -82,4 +83,23 @@ private function getChangedFilesBaseDir(): string return BP . DIRECTORY_SEPARATOR . 'dev' . DIRECTORY_SEPARATOR . 'tests' . DIRECTORY_SEPARATOR . 'static' . DIRECTORY_SEPARATOR . 'testsuite' . DIRECTORY_SEPARATOR . 'Magento' . DIRECTORY_SEPARATOR . 'Test'; } + + /** + * Reads list of controller files to ignore + * These are false positive cases so the static tests will ignore these controllers + * + * @return array + */ + private function getIgnoredFiles(): array + { + // phpcs:disable Magento2.Files.LineLength.MaxExceeded + $list = include __DIR__ . '/../../../../_files/blacklist/controller/controllers_extending_abstract_action.php'; + $ignored = []; + $appPath = BP; + foreach ($list as $file) { + // phpcs:ignore + $ignored = array_merge($ignored, glob($appPath . DIRECTORY_SEPARATOR . $file, GLOB_NOSORT)); + } + return $ignored; + } } diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/blacklist/controller/controllers_extending_abstract_action.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/blacklist/controller/controllers_extending_abstract_action.php new file mode 100644 index 0000000000000..c4489cb73350d --- /dev/null +++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/blacklist/controller/controllers_extending_abstract_action.php @@ -0,0 +1,10 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); +return [ + //this is to skip a false positive case as this new Controller extends an existing controller to add a 404 + 'app/code/Magento/HipaaImportExport/Controller/Adminhtml/Export/File/Delete.php' +]; diff --git a/lib/internal/Magento/Framework/Amqp/composer.json b/lib/internal/Magento/Framework/Amqp/composer.json index d6f7337988934..c57e65f34e2ea 100644 --- a/lib/internal/Magento/Framework/Amqp/composer.json +++ b/lib/internal/Magento/Framework/Amqp/composer.json @@ -1,25 +1,27 @@ { "name": "magento/framework-amqp", "description": "N/A", - "config": { - "sort-packages": true - }, "type": "magento2-library", "license": [ "OSL-3.0", "AFL-3.0" ], + "config": { + "sort-packages": true + }, + "version": "100.4.4", "require": { - "magento/framework": "*", + "magento/framework": "103.0.*", "php": "~8.1.0||~8.2.0", "php-amqplib/php-amqplib": "~3.2.0" }, "autoload": { - "psr-4": { - "Magento\\Framework\\Amqp\\": "" - }, "files": [ "registration.php" - ] + ], + "psr-4": { + "Magento\\Framework\\Amqp\\": "" + } } } + diff --git a/lib/internal/Magento/Framework/App/DeploymentConfig.php b/lib/internal/Magento/Framework/App/DeploymentConfig.php index 6713baa3a1d54..9045c3539e336 100644 --- a/lib/internal/Magento/Framework/App/DeploymentConfig.php +++ b/lib/internal/Magento/Framework/App/DeploymentConfig.php @@ -51,6 +51,21 @@ class DeploymentConfig */ private $overrideData; + /** + * @var array + */ + private $envOverrides = []; + + /** + * @var array + */ + private $readerLoad = []; + + /** + * @var array + */ + private $noConfigData = []; + /** * Constructor * @@ -84,7 +99,17 @@ public function get($key = null, $defaultValue = null) } $result = $this->getByKey($key); if ($result === null) { - $this->reloadData(); + if (empty($this->flatData) + || !isset($this->flatData[$key]) && !isset($this->noConfigData[$key]) + || count($this->getAllEnvOverrides()) + ) { + $this->resetData(); + $this->reloadData(); + } + + if (!isset($this->flatData[$key])) { + $this->noConfigData[$key] = $key; + } $result = $this->getByKey($key); } return $result ?? $defaultValue; @@ -114,13 +139,13 @@ public function getConfigData($key = null) { if ($key === null) { if (empty($this->data)) { - $this->reloadData(); + $this->reloadInitialData(); } return $this->data; } $result = $this->getConfigDataByKey($key); if ($result === null) { - $this->reloadData(); + $this->reloadInitialData(); $result = $this->getConfigDataByKey($key); } return $result; @@ -170,28 +195,55 @@ private function getEnvOverride() : array * @throws FileSystemException * @throws RuntimeException */ - private function reloadData(): void + private function reloadInitialData(): void { + if (empty($this->readerLoad) || empty($this->data) || empty($this->flatData)) { + $this->readerLoad = $this->reader->load(); + } $this->data = array_replace( - $this->reader->load(), + $this->readerLoad, $this->overrideData ?? [], $this->getEnvOverride() ); + } + + /** + * Loads the configuration data + * + * @return void + * @throws FileSystemException + * @throws RuntimeException + */ + private function reloadData(): void + { + $this->reloadInitialData(); // flatten data for config retrieval using get() $this->flatData = $this->flattenParams($this->data); + $this->flatData = $this->getAllEnvOverrides() + $this->flatData; + } - // allow reading values from env variables by convention - // MAGENTO_DC_{path}, like db/connection/default/host => - // can be overwritten by MAGENTO_DC_DB__CONNECTION__DEFAULT__HOST - foreach (getenv() as $key => $value) { - if (false !== \strpos($key, self::MAGENTO_ENV_PREFIX) - && $key !== self::OVERRIDE_KEY - ) { - // convert MAGENTO_DC_DB__CONNECTION__DEFAULT__HOST into db/connection/default/host - $flatKey = strtolower(str_replace([self::MAGENTO_ENV_PREFIX, '__'], ['', '/'], $key)); - $this->flatData[$flatKey] = $value; + /** + * Load all getenv() configs once + * + * @return array + */ + private function getAllEnvOverrides(): array + { + if (empty($this->envOverrides)) { + // allow reading values from env variables by convention + // MAGENTO_DC_{path}, like db/connection/default/host => + // can be overwritten by MAGENTO_DC_DB__CONNECTION__DEFAULT__HOST + foreach (getenv() as $key => $value) { + if (false !== \strpos($key, self::MAGENTO_ENV_PREFIX) + && $key !== self::OVERRIDE_KEY + ) { + // convert MAGENTO_DC_DB__CONNECTION__DEFAULT__HOST into db/connection/default/host + $flatKey = strtolower(str_replace([self::MAGENTO_ENV_PREFIX, '__'], ['', '/'], $key)); + $this->envOverrides[$flatKey] = $value; + } } } + return $this->envOverrides; } /** diff --git a/lib/internal/Magento/Framework/App/Http/Context.php b/lib/internal/Magento/Framework/App/Http/Context.php index b3fa5a5cca67b..92c4b282784d0 100644 --- a/lib/internal/Magento/Framework/App/Http/Context.php +++ b/lib/internal/Magento/Framework/App/Http/Context.php @@ -7,7 +7,9 @@ namespace Magento\Framework\App\Http; +use Magento\Framework\App\DeploymentConfig; use Magento\Framework\App\ObjectManager; +use Magento\Framework\Config\ConfigOptionsListConstants; use Magento\Framework\Serialize\Serializer\Json; /** @@ -20,7 +22,7 @@ class Context /** * Currency cache context */ - const CONTEXT_CURRENCY = 'current_currency'; + public const CONTEXT_CURRENCY = 'current_currency'; /** * Data storage @@ -39,6 +41,11 @@ class Context */ private $serializer; + /** + * @var DeploymentConfig|null + */ + private ?DeploymentConfig $deploymentConfig = null; + /** * @param array $data * @param array $default @@ -116,8 +123,11 @@ public function getVaryString() { $data = $this->getData(); if (!empty($data)) { + $salt = (string)$this->getDeploymentConfig()->get( + ConfigOptionsListConstants::CONFIG_PATH_CRYPT_KEY + ); ksort($data); - return sha1($this->serializer->serialize($data)); + return hash('sha256', $this->serializer->serialize($data) . '|' . $salt); } return null; } @@ -134,4 +144,18 @@ public function toArray() 'default' => $this->default ]; } + + /** + * Get DeploymentConfig + * + * @return DeploymentConfig + */ + private function getDeploymentConfig() : DeploymentConfig + { + if ($this->deploymentConfig === null) { + $this->deploymentConfig = ObjectManager::getInstance() + ->get(DeploymentConfig::class); + } + return $this->deploymentConfig; + } } diff --git a/lib/internal/Magento/Framework/App/Test/Unit/DeploymentConfigTest.php b/lib/internal/Magento/Framework/App/Test/Unit/DeploymentConfigTest.php index 42b4d7866c23b..5d586fc6686ee 100644 --- a/lib/internal/Magento/Framework/App/Test/Unit/DeploymentConfigTest.php +++ b/lib/internal/Magento/Framework/App/Test/Unit/DeploymentConfigTest.php @@ -50,6 +50,14 @@ class DeploymentConfigTest extends TestCase 'test_override' => 'overridden', ]; + /** + * @var array + */ + private static $flattenedFixtureSecond + = [ + 'test_override' => 'overridden2' + ]; + /** * @var array */ @@ -112,6 +120,25 @@ public function testGetters(): void $this->assertSame('overridden', $this->deploymentConfig->get('test_override')); } + /** + * @return void + * @throws FileSystemException + * @throws RuntimeException + */ + public function testGettersReloadConfig(): void + { + $this->readerMock->expects($this->any())->method('load')->willReturn(self::$flattenedFixtureSecond); + $this->deploymentConfig = new DeploymentConfig( + $this->readerMock, + ['test_override' => 'overridden2'] + ); + $this->assertNull($this->deploymentConfig->get('invalid_key')); + $this->assertNull($this->deploymentConfig->getConfigData('invalid_key')); + putenv('MAGENTO_DC_A=abc'); + $this->assertSame('abc', $this->deploymentConfig->get('a')); + $this->assertSame('overridden2', $this->deploymentConfig->get('test_override')); + } + /** * @return void * @throws FileSystemException @@ -149,7 +176,7 @@ public function testNotAvailable(): void */ public function testNotAvailableThenAvailable(): void { - $this->readerMock->expects($this->exactly(2))->method('load')->willReturn(['Test']); + $this->readerMock->expects($this->exactly(1))->method('load')->willReturn(['Test']); $object = new DeploymentConfig($this->readerMock); $this->assertFalse($object->isAvailable()); $this->assertFalse($object->isAvailable()); @@ -273,4 +300,34 @@ public function testEnvVariablesSubstitution(): void $this->assertSame('D', $this->deploymentConfig->get('b'), 'return value from env'); $this->assertSame('e$%^&', $this->deploymentConfig->get('c'), 'return default value'); } + + /** + * @return void + * @throws FileSystemException + * @throws RuntimeException + */ + public function testReloadDataOnMissingConfig(): void + { + $this->readerMock->expects($this->exactly(2)) + ->method('load') + ->willReturnOnConsecutiveCalls( + ['db' => ['connection' => ['default' => ['host' => 'localhost']]]], + [], + [] + ); + $connectionConfig1 = $this->deploymentConfig->get( + ConfigOptionsListConstants::CONFIG_PATH_DB_CONNECTIONS . '/' . 'default' + ); + $this->assertArrayHasKey('host', $connectionConfig1); + $connectionConfig2 = $this->deploymentConfig->get( + ConfigOptionsListConstants::CONFIG_PATH_DB_CONNECTIONS . '/' . 'default' + ); + $this->assertArrayHasKey('host', $connectionConfig2); + $result1 = $this->deploymentConfig->get('missing/key'); + $this->assertNull($result1); + $result2 = $this->deploymentConfig->get('missing/key'); + $this->assertNull($result2); + $result3 = $this->deploymentConfig->get('missing/key'); + $this->assertNull($result3); + } } diff --git a/lib/internal/Magento/Framework/App/Test/Unit/Http/ContextTest.php b/lib/internal/Magento/Framework/App/Test/Unit/Http/ContextTest.php index a1ab0f3d3f5f7..17aeb74988323 100644 --- a/lib/internal/Magento/Framework/App/Test/Unit/Http/ContextTest.php +++ b/lib/internal/Magento/Framework/App/Test/Unit/Http/ContextTest.php @@ -7,7 +7,10 @@ namespace Magento\Framework\App\Test\Unit\Http; +use Magento\Framework\App\DeploymentConfig; use Magento\Framework\App\Http\Context; +use Magento\Framework\Config\ConfigOptionsListConstants; +use Magento\Framework\ObjectManagerInterface; use Magento\Framework\Serialize\Serializer\Json; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use PHPUnit\Framework\MockObject\MockObject; @@ -25,6 +28,16 @@ class ContextTest extends TestCase */ protected $object; + /** + * @var DeploymentConfig|MockObject + */ + private $deploymentConfig; + + /** + * @var ObjectManagerInterface|MockObject + */ + private $objectManagerMock; + /** * @var Json|MockObject */ @@ -32,6 +45,12 @@ class ContextTest extends TestCase protected function setUp(): void { + $this->objectManagerMock = $this->getMockBuilder(ObjectManagerInterface::class) + ->disableOriginalConstructor() + ->onlyMethods(['create']) + ->getMockForAbstractClass(); + \Magento\Framework\App\ObjectManager::setInstance($this->objectManagerMock); + $this->objectManager = new ObjectManager($this); $this->serializerMock = $this->getMockBuilder(Json::class) ->setMethods(['serialize']) @@ -50,6 +69,10 @@ function ($value) { 'serializer' => $this->serializerMock ] ); + $this->deploymentConfig = $this->createPartialMock( + DeploymentConfig::class, + ['get'] + ); } public function testGetValue() @@ -81,6 +104,16 @@ public function testGetData() public function testGetVaryString() { + $this->objectManagerMock->expects($this->any()) + ->method('get') + ->with(DeploymentConfig::class) + ->willReturn($this->deploymentConfig); + + $this->deploymentConfig->expects($this->any()) + ->method('get') + ->with(ConfigOptionsListConstants::CONFIG_PATH_CRYPT_KEY) + ->willReturn('448198e08af35844a42d3c93c1ef4e03'); + $this->object->setValue('key2', 'value2', 'default2'); $this->object->setValue('key1', 'value1', 'default1'); $data = [ @@ -88,7 +121,11 @@ public function testGetVaryString() 'key1' => 'value1' ]; ksort($data); - $this->assertEquals(sha1(json_encode($data)), $this->object->getVaryString()); + + $salt = $this->deploymentConfig->get(ConfigOptionsListConstants::CONFIG_PATH_CRYPT_KEY); + $cacheKey = hash('sha256', $this->serializerMock->serialize($data) . '|' . $salt); + + $this->assertEquals($cacheKey, $this->object->getVaryString()); } public function testToArray() diff --git a/lib/internal/Magento/Framework/Bulk/composer.json b/lib/internal/Magento/Framework/Bulk/composer.json index 7beccb44975b3..9cc399090ec91 100644 --- a/lib/internal/Magento/Framework/Bulk/composer.json +++ b/lib/internal/Magento/Framework/Bulk/composer.json @@ -1,24 +1,26 @@ { "name": "magento/framework-bulk", "description": "N/A", - "config": { - "sort-packages": true - }, "type": "magento2-library", "license": [ "OSL-3.0", "AFL-3.0" ], + "config": { + "sort-packages": true + }, + "version": "101.0.2", "require": { - "magento/framework": "*", + "magento/framework": "103.0.*", "php": "~8.1.0||~8.2.0" }, "autoload": { - "psr-4": { - "Magento\\Framework\\Bulk\\": "" - }, "files": [ "registration.php" - ] + ], + "psr-4": { + "Magento\\Framework\\Bulk\\": "" + } } } + diff --git a/lib/internal/Magento/Framework/DB/Adapter/SqlVersionProvider.php b/lib/internal/Magento/Framework/DB/Adapter/SqlVersionProvider.php index 2fd4883af5eb5..46025f400b1d2 100644 --- a/lib/internal/Magento/Framework/DB/Adapter/SqlVersionProvider.php +++ b/lib/internal/Magento/Framework/DB/Adapter/SqlVersionProvider.php @@ -31,6 +31,10 @@ class SqlVersionProvider public const MYSQL_8_0_29_VERSION = '8.0.29'; + public const MARIA_DB_10_6_11_VERSION = '10.6.11'; + + public const MARIA_DB_10_4_27_VERSION = '10.4.27'; + /**#@-*/ /** @@ -139,4 +143,38 @@ public function isMysqlGte8029(): bool } return false; } + + /** + * Check if MariaDB version is greater than equal to 10.6.11 + * + * @return bool + * @throws ConnectionException + */ + public function isMariaDBGte10611(): bool + { + $sqlVersion = $this->getSqlVersion(); + $isMariaDB106 = str_contains($sqlVersion, SqlVersionProvider::MARIA_DB_10_6_VERSION); + $sqlExactVersion = $this->fetchSqlVersion(ResourceConnection::DEFAULT_CONNECTION); + if ($isMariaDB106 && version_compare($sqlExactVersion, '10.6.11', '>=')) { + return true; + } + return false; + } + + /** + * Check if MariaDB version is greater than equal to 10.4.27 + * + * @return bool + * @throws ConnectionException + */ + public function isMariaDBGte10427(): bool + { + $sqlVersion = $this->getSqlVersion(); + $isMariaDB104 = str_contains($sqlVersion, SqlVersionProvider::MARIA_DB_10_4_VERSION); + $sqlExactVersion = $this->fetchSqlVersion(ResourceConnection::DEFAULT_CONNECTION); + if ($isMariaDB104 && version_compare($sqlExactVersion, '10.4.27', '>=')) { + return true; + } + return false; + } } diff --git a/lib/internal/Magento/Framework/MessageQueue/composer.json b/lib/internal/Magento/Framework/MessageQueue/composer.json index 07cce7c905463..8588e4ed2ec04 100644 --- a/lib/internal/Magento/Framework/MessageQueue/composer.json +++ b/lib/internal/Magento/Framework/MessageQueue/composer.json @@ -1,24 +1,26 @@ { "name": "magento/framework-message-queue", "description": "N/A", - "config": { - "sort-packages": true - }, "type": "magento2-library", "license": [ "OSL-3.0", "AFL-3.0" ], + "config": { + "sort-packages": true + }, + "version": "100.4.6", "require": { - "magento/framework": "*", + "magento/framework": "103.0.*", "php": "~8.1.0||~8.2.0" }, "autoload": { - "psr-4": { - "Magento\\Framework\\MessageQueue\\": "" - }, "files": [ "registration.php" - ] + ], + "psr-4": { + "Magento\\Framework\\MessageQueue\\": "" + } } } + diff --git a/lib/internal/Magento/Framework/Module/ModuleList.php b/lib/internal/Magento/Framework/Module/ModuleList.php index b3cf433bbaf45..32e2d2b1550e1 100644 --- a/lib/internal/Magento/Framework/Module/ModuleList.php +++ b/lib/internal/Magento/Framework/Module/ModuleList.php @@ -140,8 +140,11 @@ public function isModuleInfoAvailable() */ private function loadConfigData() { - if (null === $this->configData && null !== $this->config->get(ConfigOptionsListConstants::KEY_MODULES)) { - $this->configData = $this->config->get(ConfigOptionsListConstants::KEY_MODULES); + if (null === $this->configData) { + $config = $this->config->get(ConfigOptionsListConstants::KEY_MODULES); + if (null !== $config) { + $this->configData = $config; + } } } } diff --git a/lib/internal/Magento/Framework/Module/Test/Unit/ModuleListTest.php b/lib/internal/Magento/Framework/Module/Test/Unit/ModuleListTest.php index 07d35c77026eb..c532af8580ca6 100644 --- a/lib/internal/Magento/Framework/Module/Test/Unit/ModuleListTest.php +++ b/lib/internal/Magento/Framework/Module/Test/Unit/ModuleListTest.php @@ -129,7 +129,7 @@ public function testIsModuleInfoAvailableNoConfig(): void { $this->config ->method('get') - ->willReturnOnConsecutiveCalls(['modules' => 'testModule'], null); + ->willReturnOnConsecutiveCalls(null); $this->assertFalse($this->model->isModuleInfoAvailable()); } @@ -144,7 +144,7 @@ public function testIsModuleInfoAvailableNoConfig(): void private function setLoadConfigExpectation($isExpected = true): void { if ($isExpected) { - $this->config->expects($this->exactly(2))->method('get')->willReturn(self::$enabledFixture); + $this->config->expects($this->once())->method('get')->willReturn(self::$enabledFixture); } else { $this->config->expects($this->never())->method('get'); } diff --git a/lib/internal/Magento/Framework/RegexValidator.php b/lib/internal/Magento/Framework/RegexValidator.php new file mode 100644 index 0000000000000..77274f0f52247 --- /dev/null +++ b/lib/internal/Magento/Framework/RegexValidator.php @@ -0,0 +1,53 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Framework; + +use Magento\Framework\App\ObjectManager; +use Magento\Framework\Validator\RegexFactory; + +class RegexValidator extends RegexFactory +{ + + /** + * @var RegexFactory + */ + private RegexFactory $regexValidatorFactory; + + /** + * Validation pattern for handles array + */ + private const VALIDATION_RULE_PATTERN = '/^[a-z0-9,.]+[a-z0-9_,.]*$/i'; + + /** + * @param RegexFactory|null $regexValidatorFactory + */ + public function __construct( + ?RegexFactory $regexValidatorFactory = null + ) { + $this->regexValidatorFactory = $regexValidatorFactory + ?: ObjectManager::getInstance()->get(RegexFactory::class); + } + + /** + * Validates parameter regex + * + * @param string $params + * @param string $pattern + * @return bool + */ + public function validateParamRegex(string $params, string $pattern = self::VALIDATION_RULE_PATTERN): bool + { + $validator = $this->regexValidatorFactory->create(['pattern' => $pattern]); + + if ($params && !$validator->isValid($params)) { + return false; + } + + return true; + } +} diff --git a/lib/internal/Magento/Framework/Url/Test/Unit/ValidatorTest.php b/lib/internal/Magento/Framework/Url/Test/Unit/ValidatorTest.php index 32c90cb1b8030..5cd86de6911f3 100644 --- a/lib/internal/Magento/Framework/Url/Test/Unit/ValidatorTest.php +++ b/lib/internal/Magento/Framework/Url/Test/Unit/ValidatorTest.php @@ -23,6 +23,9 @@ class ValidatorTest extends TestCase /** @var string[] */ protected $expectedValidationMessages = [Uri::INVALID => "Invalid URL '%value%'."]; + /** @var string[] */ + protected $invalidURL = [Uri::INVALID => "Invalid URL 'php://filter'."]; + protected function setUp(): void { $objectManager = new ObjectManager($this); @@ -59,4 +62,13 @@ public function testIsValidWhenInvalid() $this->assertFalse($this->object->isValid('%value%')); $this->assertEquals($this->expectedValidationMessages, $this->object->getMessages()); } + + public function testIsValidWhenInvalidURL() + { + $this->laminasValidator + ->method('isValid') + ->with('php://filter'); + $this->assertFalse($this->object->isValid('php://filter')); + $this->assertEquals($this->invalidURL, $this->object->getMessages()); + } } diff --git a/lib/internal/Magento/Framework/Url/Validator.php b/lib/internal/Magento/Framework/Url/Validator.php index 44fcf028d98c0..f2d3158029c8f 100644 --- a/lib/internal/Magento/Framework/Url/Validator.php +++ b/lib/internal/Magento/Framework/Url/Validator.php @@ -55,11 +55,14 @@ public function isValid($value) $this->setValue($value); $valid = $this->validator->isValid($value); - - if (!$valid) { - $this->error(Uri::INVALID); + // phpcs:ignore Magento2.Functions.DiscouragedFunction + $protocol = parse_url($value ? $value : '', PHP_URL_SCHEME); + if ($valid && ($protocol === 'https' || $protocol === 'http')) { + return true; } - return $valid; + $this->error(Uri::INVALID); + + return false; } } diff --git a/lib/internal/Magento/Framework/View/Element/AbstractBlock.php b/lib/internal/Magento/Framework/View/Element/AbstractBlock.php index a9b61d376c011..a1543b16e5a01 100644 --- a/lib/internal/Magento/Framework/View/Element/AbstractBlock.php +++ b/lib/internal/Magento/Framework/View/Element/AbstractBlock.php @@ -7,7 +7,10 @@ namespace Magento\Framework\View\Element; +use Magento\Framework\App\DeploymentConfig; +use Magento\Framework\App\ObjectManager; use Magento\Framework\Cache\LockGuardedCacheLoader; +use Magento\Framework\Config\ConfigOptionsListConstants; use Magento\Framework\DataObject\IdentityInterface; /** @@ -51,6 +54,7 @@ abstract class AbstractBlock extends \Magento\Framework\DataObject implements Bl /** * @var \Magento\Framework\Session\SidResolverInterface * @deprecated 102.0.5 Not used anymore. + * @see Session Id's In URL */ protected $_sidResolver; @@ -166,6 +170,11 @@ abstract class AbstractBlock extends \Magento\Framework\DataObject implements Bl */ protected $_cache; + /** + * @var DeploymentConfig + */ + private $deploymentConfig; + /** * @var LockGuardedCacheLoader */ @@ -199,6 +208,7 @@ public function __construct( $this->_localeDate = $context->getLocaleDate(); $this->inlineTranslation = $context->getInlineTranslation(); $this->lockQuery = $context->getLockGuardedCacheLoader(); + if (isset($data['jsLayout'])) { $this->jsLayout = $data['jsLayout']; unset($data['jsLayout']); @@ -880,6 +890,7 @@ public static function extractModuleName($className) * @param array|null $allowedTags * @return string * @deprecated 103.0.0 Use $escaper directly in templates and in blocks. + * @see Escaper Usage */ public function escapeHtml($data, $allowedTags = null) { @@ -893,6 +904,7 @@ public function escapeHtml($data, $allowedTags = null) * @return string * @since 101.0.0 * @deprecated 103.0.0 Use $escaper directly in templates and in blocks. + * @see Escaper Usage */ public function escapeJs($string) { @@ -907,6 +919,7 @@ public function escapeJs($string) * @return string * @since 101.0.0 * @deprecated 103.0.0 Use $escaper directly in templates and in blocks. + * @see Escaper Usage */ public function escapeHtmlAttr($string, $escapeSingleQuote = true) { @@ -920,6 +933,7 @@ public function escapeHtmlAttr($string, $escapeSingleQuote = true) * @return string * @since 101.0.0 * @deprecated 103.0.0 Use $escaper directly in templates and in blocks. + * @see Escaper Usage */ public function escapeCss($string) { @@ -947,6 +961,7 @@ public function stripTags($data, $allowableTags = null, $allowHtmlEntities = fal * @param string $string * @return string * @deprecated 103.0.0 Use $escaper directly in templates and in blocks. + * @see Escaper Usage */ public function escapeUrl($string) { @@ -959,6 +974,7 @@ public function escapeUrl($string) * @param string $data * @return string * @deprecated 101.0.0 + * @see Escaper Usage */ public function escapeXssInUrl($data) { @@ -974,6 +990,7 @@ public function escapeXssInUrl($data) * @param bool $addSlashes * @return string * @deprecated 101.0.0 + * @see Escaper Usage */ public function escapeQuote($data, $addSlashes = false) { @@ -988,6 +1005,7 @@ public function escapeQuote($data, $addSlashes = false) * * @return string|array * @deprecated 101.0.0 + * @see Escaper Usage */ public function escapeJsQuote($data, $quote = '\'') { @@ -1035,8 +1053,12 @@ public function getCacheKey() $key = array_values($key); // ignore array keys + $key[] = (string)$this->getDeploymentConfig()->get( + ConfigOptionsListConstants::CONFIG_PATH_CRYPT_KEY + ); + $key = implode('|', $key); - $key = sha1($key); // use hashing to hide potentially private data + $key = hash('sha256', $key); // use hashing to hide potentially private data return static::CACHE_KEY_PREFIX . $key; } @@ -1175,10 +1197,25 @@ public function getVar($name, $module = null) * * @return bool * @deprecated + * @see https://developer.adobe.com/commerce/php/development/cache/page/private-content * @since 103.0.1 */ public function isScopePrivate() { return $this->_isScopePrivate; } + + /** + * Get DeploymentConfig + * + * @return DeploymentConfig + */ + private function getDeploymentConfig() : DeploymentConfig + { + if ($this->deploymentConfig === null) { + $this->deploymentConfig = ObjectManager::getInstance() + ->get(DeploymentConfig::class); + } + return $this->deploymentConfig; + } } diff --git a/lib/internal/Magento/Framework/View/Test/Unit/Element/AbstractBlockTest.php b/lib/internal/Magento/Framework/View/Test/Unit/Element/AbstractBlockTest.php index fa425b413560b..55c84f9b5ca3a 100644 --- a/lib/internal/Magento/Framework/View/Test/Unit/Element/AbstractBlockTest.php +++ b/lib/internal/Magento/Framework/View/Test/Unit/Element/AbstractBlockTest.php @@ -9,10 +9,13 @@ use Magento\Framework\App\Cache\StateInterface as CacheStateInterface; use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\App\DeploymentConfig; use Magento\Framework\Cache\LockGuardedCacheLoader; +use Magento\Framework\Config\ConfigOptionsListConstants; use Magento\Framework\Config\View; use Magento\Framework\Escaper; use Magento\Framework\Event\ManagerInterface as EventManagerInterface; +use Magento\Framework\ObjectManagerInterface; use Magento\Framework\Session\SessionManagerInterface; use Magento\Framework\Session\SidResolverInterface; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; @@ -69,11 +72,26 @@ class AbstractBlockTest extends TestCase */ private $lockQuery; + /** + * @var DeploymentConfig|MockObject + */ + private $deploymentConfig; + + /** + * @var ObjectManagerInterface|MockObject + */ + private $objectManagerMock; + /** * @return void */ protected function setUp(): void { + $this->objectManagerMock = $this->getMockBuilder(ObjectManagerInterface::class) + ->disableOriginalConstructor() + ->onlyMethods(['create']) + ->getMockForAbstractClass(); + \Magento\Framework\App\ObjectManager::setInstance($this->objectManagerMock); $this->eventManagerMock = $this->getMockForAbstractClass(EventManagerInterface::class); $this->scopeConfigMock = $this->getMockForAbstractClass(ScopeConfigInterface::class); $this->cacheStateMock = $this->getMockForAbstractClass(CacheStateInterface::class); @@ -108,13 +126,18 @@ protected function setUp(): void $contextMock->expects($this->once()) ->method('getLockGuardedCacheLoader') ->willReturn($this->lockQuery); + $this->block = $this->getMockForAbstractClass( AbstractBlock::class, [ 'context' => $contextMock, - 'data' => [], + 'data' => [] ] ); + $this->deploymentConfig = $this->createPartialMock( + DeploymentConfig::class, + ['get'] + ); } /** @@ -224,9 +247,20 @@ public function testGetCacheKey() */ public function testGetCacheKeyByName() { + $this->objectManagerMock->expects($this->any()) + ->method('get') + ->with(DeploymentConfig::class) + ->willReturn($this->deploymentConfig); + + $this->deploymentConfig->expects($this->any()) + ->method('get') + ->with(ConfigOptionsListConstants::CONFIG_PATH_CRYPT_KEY) + ->willReturn('448198e08af35844a42d3c93c1ef4e03'); + $nameInLayout = 'testBlock'; $this->block->setNameInLayout($nameInLayout); - $cacheKey = sha1($nameInLayout); + $encryptionKey = $this->deploymentConfig->get(ConfigOptionsListConstants::CONFIG_PATH_CRYPT_KEY); + $cacheKey = hash('sha256', $nameInLayout . '|' . $encryptionKey); $this->assertEquals(AbstractBlock::CACHE_KEY_PREFIX . $cacheKey, $this->block->getCacheKey()); } diff --git a/lib/internal/Magento/Framework/composer.json b/lib/internal/Magento/Framework/composer.json index 488f553682957..145f03d8c55cd 100644 --- a/lib/internal/Magento/Framework/composer.json +++ b/lib/internal/Magento/Framework/composer.json @@ -9,6 +9,7 @@ "config": { "sort-packages": true }, + "version": "103.0.6-p3", "require": { "php": "~8.1.0||~8.2.0", "ext-bcmath": "*", @@ -64,11 +65,12 @@ "ext-imagick": "Use Image Magick >=3.0.0 as an optional alternative image processing library" }, "autoload": { - "psr-4": { - "Magento\\Framework\\": "" - }, "files": [ "registration.php" - ] + ], + "psr-4": { + "Magento\\Framework\\": "" + } } } + diff --git a/lib/web/jquery/fileUploader/vendor/jquery.ui.widget.js b/lib/web/jquery/fileUploader/vendor/jquery.ui.widget.js index 78e6255728ec3..0cdc176806389 100644 --- a/lib/web/jquery/fileUploader/vendor/jquery.ui.widget.js +++ b/lib/web/jquery/fileUploader/vendor/jquery.ui.widget.js @@ -1,4 +1,4 @@ -/*! jQuery UI - v1.12.1+0b7246b6eeadfa9e2696e22f3230f6452f8129dc - 2020-02-20 +/*! jQuery UI - v1.13.2 * http://jqueryui.com * Includes: widget.js * Copyright jQuery Foundation and other contributors; Licensed MIT */ @@ -7,799 +7,826 @@ /* eslint-disable no-param-reassign, new-cap, jsdoc/require-jsdoc */ (function (factory) { - 'use strict'; - if (typeof define === 'function' && define.amd) { - // AMD. Register as an anonymous module. - define(['jquery'], factory); - } else if (typeof exports === 'object') { - // Node/CommonJS - factory(require('jquery')); - } else { - // Browser globals - factory(window.jQuery); - } + 'use strict'; + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(['jquery'], factory); + } else if (typeof exports === 'object') { + // Node/CommonJS + factory(require('jquery')); + } else { + // Browser globals + factory(window.jQuery); + } })(function ($) { - ('use strict'); - - $.ui = $.ui || {}; - - $.ui.version = '1.12.1'; - - /*! - * jQuery UI Widget 1.12.1 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ - - //>>label: Widget - //>>group: Core - //>>description: Provides a factory for creating stateful widgets with a common API. - //>>docs: http://api.jqueryui.com/jQuery.widget/ - //>>demos: http://jqueryui.com/widget/ - - // Support: jQuery 1.9.x or older - // $.expr[ ":" ] is deprecated. - if (!$.expr.pseudos) { - $.expr.pseudos = $.expr[':']; - } - - // Support: jQuery 1.11.x or older - // $.unique has been renamed to $.uniqueSort - if (!$.uniqueSort) { - $.uniqueSort = $.unique; - } - - var widgetUuid = 0; - var widgetHasOwnProperty = Array.prototype.hasOwnProperty; - var widgetSlice = Array.prototype.slice; - - $.cleanData = (function (orig) { - return function (elems) { - var events, elem, i; - // eslint-disable-next-line eqeqeq - for (i = 0; (elem = elems[i]) != null; i++) { - // Only trigger remove when necessary to save time - events = $._data(elem, 'events'); - if (events && events.remove) { - $(elem).triggerHandler('remove'); + ('use strict'); + + $.ui = $.ui || {}; + + $.ui.version = '1.13.2'; + + /*! + * jQuery UI Widget 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + + //>>label: Widget + //>>group: Core + //>>description: Provides a factory for creating stateful widgets with a common API. + //>>docs: http://api.jqueryui.com/jQuery.widget/ + //>>demos: http://jqueryui.com/widget/ + + // Support: jQuery 1.9.x or older + // $.expr[ ":" ] is deprecated. + if (!$.expr.pseudos) { + $.expr.pseudos = $.expr[':']; + } + + // Support: jQuery 1.11.x or older + // $.unique has been renamed to $.uniqueSort + if (!$.uniqueSort) { + $.uniqueSort = $.unique; + } + var widgetUuid = 0; + var widgetHasOwnProperty = Array.prototype.hasOwnProperty; + var widgetSlice = Array.prototype.slice; + + $.cleanData = (function (orig) { + return function (elems) { + var events, elem, i; + for (i = 0; (elem = elems[i]) != null; i++) { + // Only trigger remove when necessary to save time + events = $._data(elem, 'events'); + if (events && events.remove) { + $(elem).triggerHandler('remove'); + } + } + orig(elems); + }; + })($.cleanData); + + $.widget = function (name, base, prototype) { + var existingConstructor, constructor, basePrototype; + + // ProxiedPrototype allows the provided prototype to remain unmodified + // so that it can be used as a mixin for multiple widgets (#8876) + var proxiedPrototype = {}; + + var namespace = name.split('.')[0]; + // eslint-disable-next-line no-param-reassign + name = name.split('.')[1]; + var fullName = namespace + '-' + name; + + if (!prototype) { + prototype = base; + base = $.Widget; } - } - orig(elems); - }; - })($.cleanData); - $.widget = function (name, base, prototype) { - var existingConstructor, constructor, basePrototype; + if (Array.isArray(prototype)) { + prototype = $.extend.apply(null, [{}].concat(prototype)); + } - // ProxiedPrototype allows the provided prototype to remain unmodified - // so that it can be used as a mixin for multiple widgets (#8876) - var proxiedPrototype = {}; + // Create selector for plugin + $.expr.pseudos[fullName.toLowerCase()] = function (elem) { + return !!$.data(elem, fullName); + }; - var namespace = name.split('.')[0]; - name = name.split('.')[1]; - var fullName = namespace + '-' + name; + $[namespace] = $[namespace] || {}; + existingConstructor = $[namespace][name]; + constructor = $[namespace][name] = function (options, element) { + // Allow instantiation without "new" keyword + if (!this || !this._createWidget) { + return new constructor(options, element); + } - if (!prototype) { - prototype = base; - base = $.Widget; - } + // Allow instantiation without initializing for simple inheritance + // must use "new" keyword (the code above always passes args) + if (arguments.length) { + this._createWidget(options, element); + } + }; - if ($.isArray(prototype)) { - prototype = $.extend.apply(null, [{}].concat(prototype)); - } + // Extend with the existing constructor to carry over any static properties + $.extend(constructor, existingConstructor, { + version: prototype.version, - // Create selector for plugin - $.expr.pseudos[fullName.toLowerCase()] = function (elem) { - return !!$.data(elem, fullName); - }; + // Copy the object used to create the prototype in case we need to + // redefine the widget later + _proto: $.extend({}, prototype), - $[namespace] = $[namespace] || {}; - existingConstructor = $[namespace][name]; - constructor = $[namespace][name] = function (options, element) { - // Allow instantiation without "new" keyword - if (!this._createWidget) { - return new constructor(options, element); - } - - // Allow instantiation without initializing for simple inheritance - // must use "new" keyword (the code above always passes args) - if (arguments.length) { - this._createWidget(options, element); - } - }; + // Track widgets that inherit from this widget in case this widget is + // redefined after a widget inherits from it + _childConstructors: [] + }); - // Extend with the existing constructor to carry over any static properties - $.extend(constructor, existingConstructor, { - version: prototype.version, + basePrototype = new base(); - // Copy the object used to create the prototype in case we need to - // redefine the widget later - _proto: $.extend({}, prototype), + // We need to make the options hash a property directly on the new instance + // otherwise we'll modify the options hash on the prototype that we're + // inheriting from + basePrototype.options = $.widget.extend({}, basePrototype.options); + $.each(prototype, function (prop, value) { + if (typeof value !== 'function') { + proxiedPrototype[prop] = value; + return; + } + proxiedPrototype[prop] = (function () { + /** + * + */ + function _super() { + return base.prototype[prop].apply(this, arguments); + } + + /** + * @param args + */ + function _superApply(args) { + return base.prototype[prop].apply(this, args); + } + + return function () { + var __super = this._super; + var __superApply = this._superApply; + var returnValue; + + this._super = _super; + this._superApply = _superApply; + + returnValue = value.apply(this, arguments); + + this._super = __super; + this._superApply = __superApply; + + return returnValue; + }; + })(); + }); + constructor.prototype = $.widget.extend( + basePrototype, + { + // TODO: remove support for widgetEventPrefix + // always use the name + a colon as the prefix, e.g., draggable:start + // don't prefix for widgets that aren't DOM-based + widgetEventPrefix: existingConstructor + ? basePrototype.widgetEventPrefix || name + : name + }, + proxiedPrototype, + { + constructor: constructor, + namespace: namespace, + widgetName: name, + widgetFullName: fullName + } + ); - // Track widgets that inherit from this widget in case this widget is - // redefined after a widget inherits from it - _childConstructors: [] - }); + // If this widget is being redefined then we need to find all widgets that + // are inheriting from it and redefine all of them so that they inherit from + // the new version of this widget. We're essentially trying to replace one + // level in the prototype chain. + if (existingConstructor) { + $.each(existingConstructor._childConstructors, function (i, child) { + var childPrototype = child.prototype; + + // Redefine the child widget using the same prototype that was + // originally used, but inherit from the new version of the base + $.widget( + childPrototype.namespace + '.' + childPrototype.widgetName, + constructor, + child._proto + ); + }); - basePrototype = new base(); - - // We need to make the options hash a property directly on the new instance - // otherwise we'll modify the options hash on the prototype that we're - // inheriting from - basePrototype.options = $.widget.extend({}, basePrototype.options); - $.each(prototype, function (prop, value) { - if (!$.isFunction(value)) { - proxiedPrototype[prop] = value; - return; - } - proxiedPrototype[prop] = (function () { - function _super() { - return base.prototype[prop].apply(this, arguments); + // Remove the list of existing child constructors from the old constructor + // so the old child constructors can be garbage collected + delete existingConstructor._childConstructors; + } else { + base._childConstructors.push(constructor); } - function _superApply(args) { - return base.prototype[prop].apply(this, args); + $.widget.bridge(name, constructor); + + return constructor; + }; + + $.widget.extend = function (target) { + var input = widgetSlice.call(arguments, 1); + var inputIndex = 0; + var inputLength = input.length; + var key; + var value; + + for (; inputIndex < inputLength; inputIndex++) { + for (key in input[inputIndex]) { + value = input[inputIndex][key]; + if ( + widgetHasOwnProperty.call(input[inputIndex], key) && + value !== undefined + ) { + // Clone objects + if ($.isPlainObject(value)) { + target[key] = $.isPlainObject(target[key]) + ? $.widget.extend({}, target[key], value) + : // Don't extend strings, arrays, etc. with objects + $.widget.extend({}, value); + + // Copy everything else by reference + } else { + target[key] = value; + } + } + } } + return target; + }; - return function () { - var __super = this._super; - var __superApply = this._superApply; - var returnValue; + $.widget.bridge = function (name, object) { + var fullName = object.prototype.widgetFullName || name; + $.fn[name] = function (options) { + var isMethodCall = typeof options === 'string'; + var args = widgetSlice.call(arguments, 1); + var returnValue = this; + + if (isMethodCall) { + // If this is an empty collection, we need to have the instance method + // return undefined instead of the jQuery instance + if (!this.length && options === 'instance') { + returnValue = undefined; + } else { + this.each(function () { + var methodValue; + var instance = $.data(this, fullName); + + if (options === 'instance') { + returnValue = instance; + return false; + } + + if (!instance) { + return $.error( + 'cannot call methods on ' + + name + + ' prior to initialization; ' + + "attempted to call method '" + + options + + "'" + ); + } + + if ( + typeof instance[options] !== 'function' || + options.charAt(0) === '_' + ) { + return $.error( + "no such method '" + + options + + "' for " + + name + + ' widget instance' + ); + } + + methodValue = instance[options].apply(instance, args); + + if (methodValue !== instance && methodValue !== undefined) { + returnValue = + methodValue && methodValue.jquery + ? returnValue.pushStack(methodValue.get()) + : methodValue; + return false; + } + }); + } + } else { + // Allow multiple hashes to be passed on init + if (args.length) { + options = $.widget.extend.apply(null, [options].concat(args)); + } + + this.each(function () { + var instance = $.data(this, fullName); + if (instance) { + instance.option(options || {}); + if (instance._init) { + instance._init(); + } + } else { + $.data(this, fullName, new object(options, this)); + } + }); + } - this._super = _super; - this._superApply = _superApply; + return returnValue; + }; + }; - returnValue = value.apply(this, arguments); + $.Widget = function (/* options, element */) {}; + $.Widget._childConstructors = []; - this._super = __super; - this._superApply = __superApply; + $.Widget.prototype = { + widgetName: 'widget', + widgetEventPrefix: '', + defaultElement: '<div>', - return returnValue; - }; - })(); - }); - constructor.prototype = $.widget.extend( - basePrototype, - { - // TODO: remove support for widgetEventPrefix - // always use the name + a colon as the prefix, e.g., draggable:start - // don't prefix for widgets that aren't DOM-based - widgetEventPrefix: existingConstructor - ? basePrototype.widgetEventPrefix || name - : name - }, - proxiedPrototype, - { - constructor: constructor, - namespace: namespace, - widgetName: name, - widgetFullName: fullName - } - ); - - // If this widget is being redefined then we need to find all widgets that - // are inheriting from it and redefine all of them so that they inherit from - // the new version of this widget. We're essentially trying to replace one - // level in the prototype chain. - if (existingConstructor) { - $.each(existingConstructor._childConstructors, function (i, child) { - var childPrototype = child.prototype; - - // Redefine the child widget using the same prototype that was - // originally used, but inherit from the new version of the base - $.widget( - childPrototype.namespace + '.' + childPrototype.widgetName, - constructor, - child._proto - ); - }); + options: { + classes: {}, + disabled: false, - // Remove the list of existing child constructors from the old constructor - // so the old child constructors can be garbage collected - delete existingConstructor._childConstructors; - } else { - base._childConstructors.push(constructor); - } + // Callbacks + create: null + }, - $.widget.bridge(name, constructor); - - return constructor; - }; - - $.widget.extend = function (target) { - var input = widgetSlice.call(arguments, 1); - var inputIndex = 0; - var inputLength = input.length; - var key; - var value; - - for (; inputIndex < inputLength; inputIndex++) { - for (key in input[inputIndex]) { - value = input[inputIndex][key]; - if ( - widgetHasOwnProperty.call(input[inputIndex], key) && - value !== undefined - ) { - // Clone objects - if ($.isPlainObject(value)) { - target[key] = $.isPlainObject(target[key]) - ? $.widget.extend({}, target[key], value) - : // Don't extend strings, arrays, etc. with objects - $.widget.extend({}, value); - - // Copy everything else by reference - } else { - target[key] = value; - } - } - } - } - return target; - }; - - $.widget.bridge = function (name, object) { - var fullName = object.prototype.widgetFullName || name; - $.fn[name] = function (options) { - var isMethodCall = typeof options === 'string'; - var args = widgetSlice.call(arguments, 1); - var returnValue = this; - - if (isMethodCall) { - // If this is an empty collection, we need to have the instance method - // return undefined instead of the jQuery instance - if (!this.length && options === 'instance') { - returnValue = undefined; - } else { - this.each(function () { - var methodValue; - var instance = $.data(this, fullName); + _createWidget: function (options, element) { + element = $(element || this.defaultElement || this)[0]; + this.element = $(element); + this.uuid = widgetUuid++; + this.eventNamespace = '.' + this.widgetName + this.uuid; + + this.bindings = $(); + this.hoverable = $(); + this.focusable = $(); + this.classesElementLookup = {}; + + if (element !== this) { + $.data(element, this.widgetFullName, this); + this._on(true, this.element, { + remove: function (event) { + if (event.target === element) { + this.destroy(); + } + } + }); + this.document = $( + element.style + ? // Element within the document + element.ownerDocument + : // Element is window or document + element.document || element + ); + this.window = $( + this.document[0].defaultView || this.document[0].parentWindow + ); + } - if (options === 'instance') { - returnValue = instance; - return false; + this.options = $.widget.extend( + {}, + this.options, + this._getCreateOptions(), + options + ); + + this._create(); + + if (this.options.disabled) { + this._setOptionDisabled(this.options.disabled); } - if (!instance) { - return $.error( - 'cannot call methods on ' + - name + - ' prior to initialization; ' + - "attempted to call method '" + - options + - "'" - ); + this._trigger('create', null, this._getCreateEventData()); + this._init(); + }, + + _getCreateOptions: function () { + return {}; + }, + + _getCreateEventData: $.noop, + + _create: $.noop, + + _init: $.noop, + + destroy: function () { + var that = this; + + this._destroy(); + $.each(this.classesElementLookup, function (key, value) { + that._removeClass(value, key); + }); + + // We can probably remove the unbind calls in 2.0 + // all event bindings should go through this._on() + this.element.off(this.eventNamespace).removeData(this.widgetFullName); + this.widget().off(this.eventNamespace).removeAttr('aria-disabled'); + + // Clean up events and states + this.bindings.off(this.eventNamespace); + }, + + _destroy: $.noop, + + widget: function () { + return this.element; + }, + + option: function (key, value) { + var options = key; + var parts; + var curOption; + var i; + + if (arguments.length === 0) { + // Don't return a reference to the internal hash + return $.widget.extend({}, this.options); } - if (!$.isFunction(instance[options]) || options.charAt(0) === '_') { - return $.error( - "no such method '" + - options + - "' for " + - name + - ' widget instance' - ); + if (typeof key === 'string') { + // Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } + options = {}; + parts = key.split('.'); + key = parts.shift(); + if (parts.length) { + curOption = options[key] = $.widget.extend({}, this.options[key]); + for (i = 0; i < parts.length - 1; i++) { + curOption[parts[i]] = curOption[parts[i]] || {}; + curOption = curOption[parts[i]]; + } + key = parts.pop(); + if (arguments.length === 1) { + return curOption[key] === undefined ? null : curOption[key]; + } + curOption[key] = value; + } else { + if (arguments.length === 1) { + return this.options[key] === undefined ? null : this.options[key]; + } + options[key] = value; + } } - methodValue = instance[options].apply(instance, args); + this._setOptions(options); + + return this; + }, - if (methodValue !== instance && methodValue !== undefined) { - returnValue = - methodValue && methodValue.jquery - ? returnValue.pushStack(methodValue.get()) - : methodValue; - return false; + _setOptions: function (options) { + var key; + + for (key in options) { + this._setOption(key, options[key]); } - }); - } - } else { - // Allow multiple hashes to be passed on init - if (args.length) { - options = $.widget.extend.apply(null, [options].concat(args)); - } - this.each(function () { - var instance = $.data(this, fullName); - if (instance) { - instance.option(options || {}); - if (instance._init) { - instance._init(); + return this; + }, + + _setOption: function (key, value) { + if (key === 'classes') { + this._setOptionClasses(value); } - } else { - $.data(this, fullName, new object(options, this)); - } - }); - } - return returnValue; - }; - }; - - $.Widget = function (/* options, element */) {}; - $.Widget._childConstructors = []; - - $.Widget.prototype = { - widgetName: 'widget', - widgetEventPrefix: '', - defaultElement: '<div>', - - options: { - classes: {}, - disabled: false, - - // Callbacks - create: null - }, - - _createWidget: function (options, element) { - element = $(element || this.defaultElement || this)[0]; - this.element = $(element); - this.uuid = widgetUuid++; - this.eventNamespace = '.' + this.widgetName + this.uuid; - - this.bindings = $(); - this.hoverable = $(); - this.focusable = $(); - this.classesElementLookup = {}; - - if (element !== this) { - $.data(element, this.widgetFullName, this); - this._on(true, this.element, { - remove: function (event) { - if (event.target === element) { - this.destroy(); + this.options[key] = value; + + if (key === 'disabled') { + this._setOptionDisabled(value); } - } - }); - this.document = $( - element.style - ? // Element within the document - element.ownerDocument - : // Element is window or document - element.document || element - ); - this.window = $( - this.document[0].defaultView || this.document[0].parentWindow - ); - } - - this.options = $.widget.extend( - {}, - this.options, - this._getCreateOptions(), - options - ); - - this._create(); - - if (this.options.disabled) { - this._setOptionDisabled(this.options.disabled); - } - - this._trigger('create', null, this._getCreateEventData()); - this._init(); - }, - - _getCreateOptions: function () { - return {}; - }, - - _getCreateEventData: $.noop, - - _create: $.noop, - - _init: $.noop, - - destroy: function () { - var that = this; - - this._destroy(); - $.each(this.classesElementLookup, function (key, value) { - that._removeClass(value, key); - }); - - // We can probably remove the unbind calls in 2.0 - // all event bindings should go through this._on() - this.element.off(this.eventNamespace).removeData(this.widgetFullName); - this.widget().off(this.eventNamespace).removeAttr('aria-disabled'); - - // Clean up events and states - this.bindings.off(this.eventNamespace); - }, - - _destroy: $.noop, - - widget: function () { - return this.element; - }, - - option: function (key, value) { - var options = key; - var parts; - var curOption; - var i; - - if (arguments.length === 0) { - // Don't return a reference to the internal hash - return $.widget.extend({}, this.options); - } - - if (typeof key === 'string') { - // Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } - options = {}; - parts = key.split('.'); - key = parts.shift(); - if (parts.length) { - curOption = options[key] = $.widget.extend({}, this.options[key]); - for (i = 0; i < parts.length - 1; i++) { - curOption[parts[i]] = curOption[parts[i]] || {}; - curOption = curOption[parts[i]]; - } - key = parts.pop(); - if (arguments.length === 1) { - return curOption[key] === undefined ? null : curOption[key]; - } - curOption[key] = value; - } else { - if (arguments.length === 1) { - return this.options[key] === undefined ? null : this.options[key]; - } - options[key] = value; - } - } - this._setOptions(options); + return this; + }, - return this; - }, + _setOptionClasses: function (value) { + var classKey, elements, currentElements; + + for (classKey in value) { + currentElements = this.classesElementLookup[classKey]; + if ( + value[classKey] === this.options.classes[classKey] || + !currentElements || + !currentElements.length + ) { + continue; + } + + // We are doing this to create a new jQuery object because the _removeClass() call + // on the next line is going to destroy the reference to the current elements being + // tracked. We need to save a copy of this collection so that we can add the new classes + // below. + elements = $(currentElements.get()); + this._removeClass(currentElements, classKey); + + // We don't use _addClass() here, because that uses this.options.classes + // for generating the string of classes. We want to use the value passed in from + // _setOption(), this is the new value of the classes option which was passed to + // _setOption(). We pass this value directly to _classes(). + elements.addClass( + this._classes({ + element: elements, + keys: classKey, + classes: value, + add: true + }) + ); + } + }, - _setOptions: function (options) { - var key; + _setOptionDisabled: function (value) { + this._toggleClass( + this.widget(), + this.widgetFullName + '-disabled', + null, + !!value + ); - for (key in options) { - this._setOption(key, options[key]); - } + // If the widget is becoming disabled, then nothing is interactive + if (value) { + this._removeClass(this.hoverable, null, 'ui-state-hover'); + this._removeClass(this.focusable, null, 'ui-state-focus'); + } + }, - return this; - }, + enable: function () { + return this._setOptions({ disabled: false }); + }, - _setOption: function (key, value) { - if (key === 'classes') { - this._setOptionClasses(value); - } + disable: function () { + return this._setOptions({ disabled: true }); + }, - this.options[key] = value; + _classes: function (options) { + var full = []; + var that = this; - if (key === 'disabled') { - this._setOptionDisabled(value); - } + options = $.extend( + { + element: this.element, + classes: this.options.classes || {} + }, + options + ); - return this; - }, + /** + * + */ + function bindRemoveEvent() { + var nodesToBind = []; + + options.element.each(function (_, element) { + var isTracked = $.map(that.classesElementLookup, function (elements) { + return elements; + }).some(function (elements) { + return elements.is(element); + }); + + if (!isTracked) { + nodesToBind.push(element); + } + }); + + that._on($(nodesToBind), { + remove: '_untrackClassesElement' + }); + } - _setOptionClasses: function (value) { - var classKey, elements, currentElements; + /** + * @param classes + * @param checkOption + */ + function processClassString(classes, checkOption) { + var current, i; + for (i = 0; i < classes.length; i++) { + current = that.classesElementLookup[classes[i]] || $(); + if (options.add) { + bindRemoveEvent(); + current = $( + $.uniqueSort(current.get().concat(options.element.get())) + ); + } else { + current = $(current.not(options.element).get()); + } + that.classesElementLookup[classes[i]] = current; + full.push(classes[i]); + if (checkOption && options.classes[classes[i]]) { + full.push(options.classes[classes[i]]); + } + } + } - for (classKey in value) { - currentElements = this.classesElementLookup[classKey]; - if ( - value[classKey] === this.options.classes[classKey] || - !currentElements || - !currentElements.length - ) { - continue; - } + if (options.keys) { + processClassString(options.keys.match(/\S+/g) || [], true); + } + if (options.extra) { + processClassString(options.extra.match(/\S+/g) || []); + } - // We are doing this to create a new jQuery object because the _removeClass() call - // on the next line is going to destroy the reference to the current elements being - // tracked. We need to save a copy of this collection so that we can add the new classes - // below. - elements = $(currentElements.get()); - this._removeClass(currentElements, classKey); - - // We don't use _addClass() here, because that uses this.options.classes - // for generating the string of classes. We want to use the value passed in from - // _setOption(), this is the new value of the classes option which was passed to - // _setOption(). We pass this value directly to _classes(). - elements.addClass( - this._classes({ - element: elements, - keys: classKey, - classes: value, - add: true - }) - ); - } - }, - - _setOptionDisabled: function (value) { - this._toggleClass( - this.widget(), - this.widgetFullName + '-disabled', - null, - !!value - ); - - // If the widget is becoming disabled, then nothing is interactive - if (value) { - this._removeClass(this.hoverable, null, 'ui-state-hover'); - this._removeClass(this.focusable, null, 'ui-state-focus'); - } - }, - - enable: function () { - return this._setOptions({ disabled: false }); - }, - - disable: function () { - return this._setOptions({ disabled: true }); - }, - - _classes: function (options) { - var full = []; - var that = this; - - options = $.extend( - { - element: this.element, - classes: this.options.classes || {} + return full.join(' '); }, - options - ); - - function bindRemoveEvent() { - options.element.each(function (_, element) { - var isTracked = $.map(that.classesElementLookup, function (elements) { - return elements; - }).some(function (elements) { - return elements.is(element); - }); - - if (!isTracked) { - that._on($(element), { - remove: '_untrackClassesElement' + + _untrackClassesElement: function (event) { + var that = this; + $.each(that.classesElementLookup, function (key, value) { + if ($.inArray(event.target, value) !== -1) { + that.classesElementLookup[key] = $(value.not(event.target).get()); + } }); - } - }); - } - - function processClassString(classes, checkOption) { - var current, i; - for (i = 0; i < classes.length; i++) { - current = that.classesElementLookup[classes[i]] || $(); - if (options.add) { - bindRemoveEvent(); - current = $( - $.uniqueSort(current.get().concat(options.element.get())) - ); - } else { - current = $(current.not(options.element).get()); - } - that.classesElementLookup[classes[i]] = current; - full.push(classes[i]); - if (checkOption && options.classes[classes[i]]) { - full.push(options.classes[classes[i]]); - } - } - } - - if (options.keys) { - processClassString(options.keys.match(/\S+/g) || [], true); - } - if (options.extra) { - processClassString(options.extra.match(/\S+/g) || []); - } - - return full.join(' '); - }, - - _untrackClassesElement: function (event) { - var that = this; - $.each(that.classesElementLookup, function (key, value) { - if ($.inArray(event.target, value) !== -1) { - that.classesElementLookup[key] = $(value.not(event.target).get()); - } - }); - - this._off($(event.target)); - }, - - _removeClass: function (element, keys, extra) { - return this._toggleClass(element, keys, extra, false); - }, - - _addClass: function (element, keys, extra) { - return this._toggleClass(element, keys, extra, true); - }, - - _toggleClass: function (element, keys, extra, add) { - add = typeof add === 'boolean' ? add : extra; - var shift = typeof element === 'string' || element === null, - options = { - extra: shift ? keys : extra, - keys: shift ? element : keys, - element: shift ? this.element : element, - add: add - }; - options.element.toggleClass(this._classes(options), add); - return this; - }, - - _on: function (suppressDisabledCheck, element, handlers) { - var delegateElement; - var instance = this; - - // No suppressDisabledCheck flag, shuffle arguments - if (typeof suppressDisabledCheck !== 'boolean') { - handlers = element; - element = suppressDisabledCheck; - suppressDisabledCheck = false; - } - - // No element argument, shuffle and use this.element - if (!handlers) { - handlers = element; - element = this.element; - delegateElement = this.widget(); - } else { - element = delegateElement = $(element); - this.bindings = this.bindings.add(element); - } - - $.each(handlers, function (event, handler) { - function handlerProxy() { - // Allow widgets to customize the disabled handling - // - disabled as an array instead of boolean - // - disabled class as method for disabling individual parts - if ( - !suppressDisabledCheck && - (instance.options.disabled === true || - $(this).hasClass('ui-state-disabled')) - ) { - return; - } - return ( - typeof handler === 'string' ? instance[handler] : handler - ).apply(instance, arguments); - } - // Copy the guid so direct unbinding works - if (typeof handler !== 'string') { - handlerProxy.guid = handler.guid = - handler.guid || handlerProxy.guid || $.guid++; - } + this._off($(event.target)); + }, - var match = event.match(/^([\w:-]*)\s*(.*)$/); - var eventName = match[1] + instance.eventNamespace; - var selector = match[2]; + _removeClass: function (element, keys, extra) { + return this._toggleClass(element, keys, extra, false); + }, - if (selector) { - delegateElement.on(eventName, selector, handlerProxy); - } else { - element.on(eventName, handlerProxy); - } - }); - }, - - _off: function (element, eventName) { - eventName = - (eventName || '').split(' ').join(this.eventNamespace + ' ') + - this.eventNamespace; - element.off(eventName); - - // Clear the stack to avoid memory leaks (#10056) - this.bindings = $(this.bindings.not(element).get()); - this.focusable = $(this.focusable.not(element).get()); - this.hoverable = $(this.hoverable.not(element).get()); - }, - - _delay: function (handler, delay) { - var instance = this; - function handlerProxy() { - return ( - typeof handler === 'string' ? instance[handler] : handler - ).apply(instance, arguments); - } - return setTimeout(handlerProxy, delay || 0); - }, - - _hoverable: function (element) { - this.hoverable = this.hoverable.add(element); - this._on(element, { - mouseenter: function (event) { - this._addClass($(event.currentTarget), null, 'ui-state-hover'); + _addClass: function (element, keys, extra) { + return this._toggleClass(element, keys, extra, true); }, - mouseleave: function (event) { - this._removeClass($(event.currentTarget), null, 'ui-state-hover'); - } - }); - }, - - _focusable: function (element) { - this.focusable = this.focusable.add(element); - this._on(element, { - focusin: function (event) { - this._addClass($(event.currentTarget), null, 'ui-state-focus'); + + _toggleClass: function (element, keys, extra, add) { + add = typeof add === 'boolean' ? add : extra; + var shift = typeof element === 'string' || element === null, + options = { + extra: shift ? keys : extra, + keys: shift ? element : keys, + element: shift ? this.element : element, + add: add + }; + options.element.toggleClass(this._classes(options), add); + return this; }, - focusout: function (event) { - this._removeClass($(event.currentTarget), null, 'ui-state-focus'); - } - }); - }, - - _trigger: function (type, event, data) { - var prop, orig; - var callback = this.options[type]; - - data = data || {}; - event = $.Event(event); - event.type = ( - type === this.widgetEventPrefix ? type : this.widgetEventPrefix + type - ).toLowerCase(); - - // The original event may come from any element - // so we need to reset the target on the new event - event.target = this.element[0]; - - // Copy original event properties over to the new event - orig = event.originalEvent; - if (orig) { - for (prop in orig) { - if (!(prop in event)) { - event[prop] = orig[prop]; - } + + _on: function (suppressDisabledCheck, element, handlers) { + var delegateElement; + var instance = this; + + // No suppressDisabledCheck flag, shuffle arguments + if (typeof suppressDisabledCheck !== 'boolean') { + handlers = element; + element = suppressDisabledCheck; + suppressDisabledCheck = false; + } + + // No element argument, shuffle and use this.element + if (!handlers) { + handlers = element; + element = this.element; + delegateElement = this.widget(); + } else { + element = delegateElement = $(element); + this.bindings = this.bindings.add(element); + } + + $.each(handlers, function (event, handler) { + /** + * + */ + function handlerProxy() { + // Allow widgets to customize the disabled handling + // - disabled as an array instead of boolean + // - disabled class as method for disabling individual parts + if ( + !suppressDisabledCheck && + (instance.options.disabled === true || + $(this).hasClass('ui-state-disabled')) + ) { + return; + } + return ( + typeof handler === 'string' ? instance[handler] : handler + ).apply(instance, arguments); + } + + // Copy the guid so direct unbinding works + if (typeof handler !== 'string') { + handlerProxy.guid = handler.guid = + handler.guid || handlerProxy.guid || $.guid++; + } + + var match = event.match(/^([\w:-]*)\s*(.*)$/); + var eventName = match[1] + instance.eventNamespace; + var selector = match[2]; + + if (selector) { + delegateElement.on(eventName, selector, handlerProxy); + } else { + element.on(eventName, handlerProxy); + } + }); + }, + + _off: function (element, eventName) { + eventName = + (eventName || '').split(' ').join(this.eventNamespace + ' ') + + this.eventNamespace; + element.off(eventName); + + // Clear the stack to avoid memory leaks (#10056) + this.bindings = $(this.bindings.not(element).get()); + this.focusable = $(this.focusable.not(element).get()); + this.hoverable = $(this.hoverable.not(element).get()); + }, + + _delay: function (handler, delay) { + /** + * + */ + function handlerProxy() { + return ( + typeof handler === 'string' ? instance[handler] : handler + ).apply(instance, arguments); + } + var instance = this; + return setTimeout(handlerProxy, delay || 0); + }, + + _hoverable: function (element) { + this.hoverable = this.hoverable.add(element); + this._on(element, { + mouseenter: function (event) { + this._addClass($(event.currentTarget), null, 'ui-state-hover'); + }, + mouseleave: function (event) { + this._removeClass($(event.currentTarget), null, 'ui-state-hover'); + } + }); + }, + + _focusable: function (element) { + this.focusable = this.focusable.add(element); + this._on(element, { + focusin: function (event) { + this._addClass($(event.currentTarget), null, 'ui-state-focus'); + }, + focusout: function (event) { + this._removeClass($(event.currentTarget), null, 'ui-state-focus'); + } + }); + }, + + _trigger: function (type, event, data) { + var prop, orig; + var callback = this.options[type]; + + data = data || {}; + event = $.Event(event); + event.type = ( + type === this.widgetEventPrefix ? type : this.widgetEventPrefix + type + ).toLowerCase(); + + // The original event may come from any element + // so we need to reset the target on the new event + event.target = this.element[0]; + + // Copy original event properties over to the new event + orig = event.originalEvent; + if (orig) { + for (prop in orig) { + if (!(prop in event)) { + event[prop] = orig[prop]; + } + } + } + + this.element.trigger(event, data); + return !( + (typeof callback === 'function' && + callback.apply(this.element[0], [event].concat(data)) === false) || + event.isDefaultPrevented() + ); } - } - - this.element.trigger(event, data); - return !( - ($.isFunction(callback) && - callback.apply(this.element[0], [event].concat(data)) === false) || - event.isDefaultPrevented() - ); - } - }; - - $.each({ show: 'fadeIn', hide: 'fadeOut' }, function (method, defaultEffect) { - $.Widget.prototype['_' + method] = function (element, options, callback) { - if (typeof options === 'string') { - options = { effect: options }; - } - - var hasOptions; - var effectName = !options - ? method - : options === true || typeof options === 'number' - ? defaultEffect - : options.effect || defaultEffect; - - options = options || {}; - if (typeof options === 'number') { - options = { duration: options }; - } - - hasOptions = !$.isEmptyObject(options); - options.complete = callback; - - if (options.delay) { - element.delay(options.delay); - } - - if (hasOptions && $.effects && $.effects.effect[effectName]) { - element[method](options); - } else if (effectName !== method && element[effectName]) { - element[effectName](options.duration, options.easing, callback); - } else { - element.queue(function (next) { - $(this)[method](); - if (callback) { - callback.call(element[0]); - } - next(); - }); - } }; - }); + + $.each({ show: 'fadeIn', hide: 'fadeOut' }, function (method, defaultEffect) { + $.Widget.prototype['_' + method] = function (element, options, callback) { + if (typeof options === 'string') { + options = { effect: options }; + } + + var hasOptions; + var effectName = !options + ? method + : options === true || typeof options === 'number' + ? defaultEffect + : options.effect || defaultEffect; + + options = options || {}; + if (typeof options === 'number') { + options = { duration: options }; + } else if (options === true) { + options = {}; + } + + hasOptions = !$.isEmptyObject(options); + options.complete = callback; + + if (options.delay) { + element.delay(options.delay); + } + + if (hasOptions && $.effects && $.effects.effect[effectName]) { + element[method](options); + } else if (effectName !== method && element[effectName]) { + element[effectName](options.duration, options.easing, callback); + } else { + element.queue(function (next) { + $(this)[method](); + if (callback) { + callback.call(element[0]); + } + next(); + }); + } + }; + }); }); diff --git a/lib/web/jquery/jquery-ui.js b/lib/web/jquery/jquery-ui.js index 4eb1385ca1ec8..1a613bf2f94b3 100644 --- a/lib/web/jquery/jquery-ui.js +++ b/lib/web/jquery/jquery-ui.js @@ -1,6 +1,6 @@ -/*! jQuery UI - v1.13.1 - 2022-02-22 +/*! jQuery UI - v1.13.2 - 2022-07-14 * http://jqueryui.com -* Includes: widget.js, position.js, data.js, disable-selection.js, focusable.js, form-reset-mixin.js, jquery-patch.js, keycode.js, labels.js, scroll-parent.js, tabbable.js, unique-id.js, widgets/draggable.js, widgets/droppable.js, widgets/resizable.js, widgets/selectable.js, widgets/sortable.js, widgets/accordion.js, widgets/autocomplete.js, widgets/button.js, widgets/checkboxradio.js, widgets/controlgroup.js, widgets/datepicker.js, widgets/dialog.js, widgets/menu.js, widgets/mouse.js, widgets/progressbar.js, widgets/selectmenu.js, widgets/slider.js, widgets/spinner.js, widgets/tabs.js, widgets/tooltip.js, effect.js, effects/effect-blind.js, effects/effect-bounce.js, effects/effect-clip.js, effects/effect-drop.js, effects/effect-explode.js, effects/effect-fade.js, effects/effect-fold.js, effects/effect-highlight.js, effects/effect-puff.js, effects/effect-pulsate.js, effects/effect-scale.js, effects/effect-shake.js, effects/effect-size.js, effects/effect-slide.js, effects/effect-transfer.js +* Includes: widget.js, position.js, data.js, disable-selection.js, effect.js, effects/effect-blind.js, effects/effect-bounce.js, effects/effect-clip.js, effects/effect-drop.js, effects/effect-explode.js, effects/effect-fade.js, effects/effect-fold.js, effects/effect-highlight.js, effects/effect-puff.js, effects/effect-pulsate.js, effects/effect-scale.js, effects/effect-shake.js, effects/effect-size.js, effects/effect-slide.js, effects/effect-transfer.js, focusable.js, form-reset-mixin.js, jquery-patch.js, keycode.js, labels.js, scroll-parent.js, tabbable.js, unique-id.js, widgets/accordion.js, widgets/autocomplete.js, widgets/button.js, widgets/checkboxradio.js, widgets/controlgroup.js, widgets/datepicker.js, widgets/dialog.js, widgets/draggable.js, widgets/droppable.js, widgets/menu.js, widgets/mouse.js, widgets/progressbar.js, widgets/resizable.js, widgets/selectable.js, widgets/selectmenu.js, widgets/slider.js, widgets/sortable.js, widgets/spinner.js, widgets/tabs.js, widgets/tooltip.js * Copyright jQuery Foundation and other contributors; Licensed MIT */ ( function( factory ) { @@ -20,11 +20,11 @@ $.ui = $.ui || {}; -var version = $.ui.version = "1.13.1"; +var version = $.ui.version = "1.13.2"; /*! - * jQuery UI Widget 1.13.1 + * jQuery UI Widget 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -766,7 +766,7 @@ var widget = $.widget; /*! - * jQuery UI Position 1.13.1 + * jQuery UI Position 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -1263,7 +1263,7 @@ var position = $.ui.position; /*! - * jQuery UI :data 1.13.1 + * jQuery UI :data 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -1292,7 +1292,7 @@ var data = $.extend( $.expr.pseudos, { } ); /*! - * jQuery UI Disable Selection 1.13.1 + * jQuery UI Disable Selection 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -1326,709 +1326,728 @@ var disableSelection = $.fn.extend( { } ); + +// Create a local jQuery because jQuery Color relies on it and the +// global may not exist with AMD and a custom build (#10199). +// This module is a noop if used as a regular AMD module. +// eslint-disable-next-line no-unused-vars +var jQuery = $; + + /*! - * jQuery UI Focusable 1.13.1 - * http://jqueryui.com + * jQuery Color Animations v2.2.0 + * https://github.com/jquery/jquery-color * - * Copyright jQuery Foundation and other contributors + * Copyright OpenJS Foundation and other contributors * Released under the MIT license. * http://jquery.org/license + * + * Date: Sun May 10 09:02:36 2020 +0200 */ -//>>label: :focusable Selector -//>>group: Core -//>>description: Selects elements which can be focused. -//>>docs: http://api.jqueryui.com/focusable-selector/ -// Selectors -$.ui.focusable = function( element, hasTabindex ) { - var map, mapName, img, focusableIfVisible, fieldset, - nodeName = element.nodeName.toLowerCase(); + var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor " + + "borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor", - if ( "area" === nodeName ) { - map = element.parentNode; - mapName = map.name; - if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { - return false; - } - img = $( "img[usemap='#" + mapName + "']" ); - return img.length > 0 && img.is( ":visible" ); - } + class2type = {}, + toString = class2type.toString, - if ( /^(input|select|textarea|button|object)$/.test( nodeName ) ) { - focusableIfVisible = !element.disabled; + // plusequals test for += 100 -= 100 + rplusequals = /^([\-+])=\s*(\d+\.?\d*)/, - if ( focusableIfVisible ) { + // a set of RE's that can match strings and generate color tuples. + stringParsers = [ { + re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, + parse: function( execResult ) { + return [ + execResult[ 1 ], + execResult[ 2 ], + execResult[ 3 ], + execResult[ 4 ] + ]; + } + }, { + re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, + parse: function( execResult ) { + return [ + execResult[ 1 ] * 2.55, + execResult[ 2 ] * 2.55, + execResult[ 3 ] * 2.55, + execResult[ 4 ] + ]; + } + }, { - // Form controls within a disabled fieldset are disabled. - // However, controls within the fieldset's legend do not get disabled. - // Since controls generally aren't placed inside legends, we skip - // this portion of the check. - fieldset = $( element ).closest( "fieldset" )[ 0 ]; - if ( fieldset ) { - focusableIfVisible = !fieldset.disabled; + // this regex ignores A-F because it's compared against an already lowercased string + re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})?/, + parse: function( execResult ) { + return [ + parseInt( execResult[ 1 ], 16 ), + parseInt( execResult[ 2 ], 16 ), + parseInt( execResult[ 3 ], 16 ), + execResult[ 4 ] ? + ( parseInt( execResult[ 4 ], 16 ) / 255 ).toFixed( 2 ) : + 1 + ]; } - } - } else if ( "a" === nodeName ) { - focusableIfVisible = element.href || hasTabindex; - } else { - focusableIfVisible = hasTabindex; - } + }, { - return focusableIfVisible && $( element ).is( ":visible" ) && visible( $( element ) ); -}; + // this regex ignores A-F because it's compared against an already lowercased string + re: /#([a-f0-9])([a-f0-9])([a-f0-9])([a-f0-9])?/, + parse: function( execResult ) { + return [ + parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ), + parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ), + parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ), + execResult[ 4 ] ? + ( parseInt( execResult[ 4 ] + execResult[ 4 ], 16 ) / 255 ) + .toFixed( 2 ) : + 1 + ]; + } + }, { + re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, + space: "hsla", + parse: function( execResult ) { + return [ + execResult[ 1 ], + execResult[ 2 ] / 100, + execResult[ 3 ] / 100, + execResult[ 4 ] + ]; + } + } ], -// Support: IE 8 only -// IE 8 doesn't resolve inherit to visible/hidden for computed values -function visible( element ) { - var visibility = element.css( "visibility" ); - while ( visibility === "inherit" ) { - element = element.parent(); - visibility = element.css( "visibility" ); - } - return visibility === "visible"; -} + // jQuery.Color( ) + color = jQuery.Color = function( color, green, blue, alpha ) { + return new jQuery.Color.fn.parse( color, green, blue, alpha ); + }, + spaces = { + rgba: { + props: { + red: { + idx: 0, + type: "byte" + }, + green: { + idx: 1, + type: "byte" + }, + blue: { + idx: 2, + type: "byte" + } + } + }, -$.extend( $.expr.pseudos, { - focusable: function( element ) { - return $.ui.focusable( element, $.attr( element, "tabindex" ) != null ); - } -} ); + hsla: { + props: { + hue: { + idx: 0, + type: "degrees" + }, + saturation: { + idx: 1, + type: "percent" + }, + lightness: { + idx: 2, + type: "percent" + } + } + } + }, + propTypes = { + "byte": { + floor: true, + max: 255 + }, + "percent": { + max: 1 + }, + "degrees": { + mod: 360, + floor: true + } + }, + support = color.support = {}, -var focusable = $.ui.focusable; + // element for support tests + supportElem = jQuery( "<p>" )[ 0 ], + // colors = jQuery.Color.names + colors, + // local aliases of functions called often + each = jQuery.each; -// Support: IE8 Only -// IE8 does not support the form attribute and when it is supplied. It overwrites the form prop -// with a string, so we need to find the proper form. -var form = $.fn._form = function() { - return typeof this[ 0 ].form === "string" ? this.closest( "form" ) : $( this[ 0 ].form ); -}; +// determine rgba support immediately +supportElem.style.cssText = "background-color:rgba(1,1,1,.5)"; +support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1; +// define cache name and alpha properties +// for rgba and hsla spaces +each( spaces, function( spaceName, space ) { + space.cache = "_" + spaceName; + space.props.alpha = { + idx: 3, + type: "percent", + def: 1 + }; +} ); -/*! - * jQuery UI Form Reset Mixin 1.13.1 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ +// Populate the class2type map +jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), + function( _i, name ) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); + } ); -//>>label: Form Reset Mixin -//>>group: Core -//>>description: Refresh input widgets when their form is reset -//>>docs: http://api.jqueryui.com/form-reset-mixin/ +function getType( obj ) { + if ( obj == null ) { + return obj + ""; + } + return typeof obj === "object" ? + class2type[ toString.call( obj ) ] || "object" : + typeof obj; +} -var formResetMixin = $.ui.formResetMixin = { - _formResetHandler: function() { - var form = $( this ); +function clamp( value, prop, allowEmpty ) { + var type = propTypes[ prop.type ] || {}; - // Wait for the form reset to actually happen before refreshing - setTimeout( function() { - var instances = form.data( "ui-form-reset-instances" ); - $.each( instances, function() { - this.refresh(); - } ); - } ); - }, + if ( value == null ) { + return ( allowEmpty || !prop.def ) ? null : prop.def; + } - _bindFormResetHandler: function() { - this.form = this.element._form(); - if ( !this.form.length ) { - return; - } + // ~~ is an short way of doing floor for positive numbers + value = type.floor ? ~~value : parseFloat( value ); - var instances = this.form.data( "ui-form-reset-instances" ) || []; - if ( !instances.length ) { - - // We don't use _on() here because we use a single event handler per form - this.form.on( "reset.ui-form-reset", this._formResetHandler ); - } - instances.push( this ); - this.form.data( "ui-form-reset-instances", instances ); - }, - - _unbindFormResetHandler: function() { - if ( !this.form.length ) { - return; - } - - var instances = this.form.data( "ui-form-reset-instances" ); - instances.splice( $.inArray( this, instances ), 1 ); - if ( instances.length ) { - this.form.data( "ui-form-reset-instances", instances ); - } else { - this.form - .removeData( "ui-form-reset-instances" ) - .off( "reset.ui-form-reset" ); - } + // IE will pass in empty strings as value for alpha, + // which will hit this case + if ( isNaN( value ) ) { + return prop.def; } -}; - - -/*! - * jQuery UI Support for jQuery core 1.8.x and newer 1.13.1 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - */ -//>>label: jQuery 1.8+ Support -//>>group: Core -//>>description: Support version 1.8.x and newer of jQuery core + if ( type.mod ) { + // we add mod before modding to make sure that negatives values + // get converted properly: -10 -> 350 + return ( value + type.mod ) % type.mod; + } -// Support: jQuery 1.9.x or older -// $.expr[ ":" ] is deprecated. -if ( !$.expr.pseudos ) { - $.expr.pseudos = $.expr[ ":" ]; + // for now all property types without mod have min and max + return Math.min( type.max, Math.max( 0, value ) ); } -// Support: jQuery 1.11.x or older -// $.unique has been renamed to $.uniqueSort -if ( !$.uniqueSort ) { - $.uniqueSort = $.unique; -} +function stringParse( string ) { + var inst = color(), + rgba = inst._rgba = []; -// Support: jQuery 2.2.x or older. -// This method has been defined in jQuery 3.0.0. -// Code from https://github.com/jquery/jquery/blob/e539bac79e666bba95bba86d690b4e609dca2286/src/selector/escapeSelector.js -if ( !$.escapeSelector ) { + string = string.toLowerCase(); - // CSS string/identifier serialization - // https://drafts.csswg.org/cssom/#common-serializing-idioms - var rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g; + each( stringParsers, function( _i, parser ) { + var parsed, + match = parser.re.exec( string ), + values = match && parser.parse( match ), + spaceName = parser.space || "rgba"; - var fcssescape = function( ch, asCodePoint ) { - if ( asCodePoint ) { + if ( values ) { + parsed = inst[ spaceName ]( values ); - // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER - if ( ch === "\0" ) { - return "\uFFFD"; - } + // if this was an rgba parse the assignment might happen twice + // oh well.... + inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ]; + rgba = inst._rgba = parsed._rgba; - // Control characters and (dependent upon position) numbers get escaped as code points - return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; + // exit each( stringParsers ) here because we matched + return false; } + } ); - // Other potentially-special ASCII characters get backslash-escaped - return "\\" + ch; - }; - - $.escapeSelector = function( sel ) { - return ( sel + "" ).replace( rcssescape, fcssescape ); - }; -} + // Found a stringParser that handled it + if ( rgba.length ) { -// Support: jQuery 3.4.x or older -// These methods have been defined in jQuery 3.5.0. -if ( !$.fn.even || !$.fn.odd ) { - $.fn.extend( { - even: function() { - return this.filter( function( i ) { - return i % 2 === 0; - } ); - }, - odd: function() { - return this.filter( function( i ) { - return i % 2 === 1; - } ); + // if this came from a parsed string, force "transparent" when alpha is 0 + // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0) + if ( rgba.join() === "0,0,0,0" ) { + jQuery.extend( rgba, colors.transparent ); } - } ); -} - -; -/*! - * jQuery UI Keycode 1.13.1 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ + return inst; + } -//>>label: Keycode -//>>group: Core -//>>description: Provide keycodes as keynames -//>>docs: http://api.jqueryui.com/jQuery.ui.keyCode/ + // named colors + return colors[ string ]; +} +color.fn = jQuery.extend( color.prototype, { + parse: function( red, green, blue, alpha ) { + if ( red === undefined ) { + this._rgba = [ null, null, null, null ]; + return this; + } + if ( red.jquery || red.nodeType ) { + red = jQuery( red ).css( green ); + green = undefined; + } -var keycode = $.ui.keyCode = { - BACKSPACE: 8, - COMMA: 188, - DELETE: 46, - DOWN: 40, - END: 35, - ENTER: 13, - ESCAPE: 27, - HOME: 36, - LEFT: 37, - PAGE_DOWN: 34, - PAGE_UP: 33, - PERIOD: 190, - RIGHT: 39, - SPACE: 32, - TAB: 9, - UP: 38 -}; + var inst = this, + type = getType( red ), + rgba = this._rgba = []; + // more than 1 argument specified - assume ( red, green, blue, alpha ) + if ( green !== undefined ) { + red = [ red, green, blue, alpha ]; + type = "array"; + } -/*! - * jQuery UI Labels 1.13.1 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ + if ( type === "string" ) { + return this.parse( stringParse( red ) || colors._default ); + } -//>>label: labels -//>>group: Core -//>>description: Find all the labels associated with a given input -//>>docs: http://api.jqueryui.com/labels/ + if ( type === "array" ) { + each( spaces.rgba.props, function( _key, prop ) { + rgba[ prop.idx ] = clamp( red[ prop.idx ], prop ); + } ); + return this; + } + if ( type === "object" ) { + if ( red instanceof color ) { + each( spaces, function( _spaceName, space ) { + if ( red[ space.cache ] ) { + inst[ space.cache ] = red[ space.cache ].slice(); + } + } ); + } else { + each( spaces, function( _spaceName, space ) { + var cache = space.cache; + each( space.props, function( key, prop ) { -var labels = $.fn.labels = function() { - var ancestor, selector, id, labels, ancestors; + // if the cache doesn't exist, and we know how to convert + if ( !inst[ cache ] && space.to ) { - if ( !this.length ) { - return this.pushStack( [] ); - } + // if the value was null, we don't need to copy it + // if the key was alpha, we don't need to copy it either + if ( key === "alpha" || red[ key ] == null ) { + return; + } + inst[ cache ] = space.to( inst._rgba ); + } - // Check control.labels first - if ( this[ 0 ].labels && this[ 0 ].labels.length ) { - return this.pushStack( this[ 0 ].labels ); - } + // this is the only case where we allow nulls for ALL properties. + // call clamp with alwaysAllowEmpty + inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true ); + } ); - // Support: IE <= 11, FF <= 37, Android <= 2.3 only - // Above browsers do not support control.labels. Everything below is to support them - // as well as document fragments. control.labels does not work on document fragments - labels = this.eq( 0 ).parents( "label" ); + // everything defined but alpha? + if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) { - // Look for the label based on the id - id = this.attr( "id" ); - if ( id ) { + // use the default of 1 + if ( inst[ cache ][ 3 ] == null ) { + inst[ cache ][ 3 ] = 1; + } - // We don't search against the document in case the element - // is disconnected from the DOM - ancestor = this.eq( 0 ).parents().last(); + if ( space.from ) { + inst._rgba = space.from( inst[ cache ] ); + } + } + } ); + } + return this; + } + }, + is: function( compare ) { + var is = color( compare ), + same = true, + inst = this; - // Get a full set of top level ancestors - ancestors = ancestor.add( ancestor.length ? ancestor.siblings() : this.siblings() ); - - // Create a selector for the label based on the id - selector = "label[for='" + $.escapeSelector( id ) + "']"; - - labels = labels.add( ancestors.find( selector ).addBack( selector ) ); - - } - - // Return whatever we have found for labels - return this.pushStack( labels ); -}; - - -/*! - * jQuery UI Scroll Parent 1.13.1 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ - -//>>label: scrollParent -//>>group: Core -//>>description: Get the closest ancestor element that is scrollable. -//>>docs: http://api.jqueryui.com/scrollParent/ - - -var scrollParent = $.fn.scrollParent = function( includeHidden ) { - var position = this.css( "position" ), - excludeStaticParent = position === "absolute", - overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/, - scrollParent = this.parents().filter( function() { - var parent = $( this ); - if ( excludeStaticParent && parent.css( "position" ) === "static" ) { - return false; + each( spaces, function( _, space ) { + var localCache, + isCache = is[ space.cache ]; + if ( isCache ) { + localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || []; + each( space.props, function( _, prop ) { + if ( isCache[ prop.idx ] != null ) { + same = ( isCache[ prop.idx ] === localCache[ prop.idx ] ); + return same; + } + } ); } - return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + - parent.css( "overflow-x" ) ); - } ).eq( 0 ); - - return position === "fixed" || !scrollParent.length ? - $( this[ 0 ].ownerDocument || document ) : - scrollParent; -}; - - -/*! - * jQuery UI Tabbable 1.13.1 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ - -//>>label: :tabbable Selector -//>>group: Core -//>>description: Selects elements which can be tabbed to. -//>>docs: http://api.jqueryui.com/tabbable-selector/ - - -var tabbable = $.extend( $.expr.pseudos, { - tabbable: function( element ) { - var tabIndex = $.attr( element, "tabindex" ), - hasTabindex = tabIndex != null; - return ( !hasTabindex || tabIndex >= 0 ) && $.ui.focusable( element, hasTabindex ); - } -} ); - - -/*! - * jQuery UI Unique ID 1.13.1 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ - -//>>label: uniqueId -//>>group: Core -//>>description: Functions to generate and remove uniqueId's -//>>docs: http://api.jqueryui.com/uniqueId/ + return same; + } ); + return same; + }, + _space: function() { + var used = [], + inst = this; + each( spaces, function( spaceName, space ) { + if ( inst[ space.cache ] ) { + used.push( spaceName ); + } + } ); + return used.pop(); + }, + transition: function( other, distance ) { + var end = color( other ), + spaceName = end._space(), + space = spaces[ spaceName ], + startColor = this.alpha() === 0 ? color( "transparent" ) : this, + start = startColor[ space.cache ] || space.to( startColor._rgba ), + result = start.slice(); + end = end[ space.cache ]; + each( space.props, function( _key, prop ) { + var index = prop.idx, + startValue = start[ index ], + endValue = end[ index ], + type = propTypes[ prop.type ] || {}; -var uniqueId = $.fn.extend( { - uniqueId: ( function() { - var uuid = 0; + // if null, don't override start value + if ( endValue === null ) { + return; + } - return function() { - return this.each( function() { - if ( !this.id ) { - this.id = "ui-id-" + ( ++uuid ); + // if null - use end + if ( startValue === null ) { + result[ index ] = endValue; + } else { + if ( type.mod ) { + if ( endValue - startValue > type.mod / 2 ) { + startValue += type.mod; + } else if ( startValue - endValue > type.mod / 2 ) { + startValue -= type.mod; + } } - } ); - }; - } )(), - - removeUniqueId: function() { - return this.each( function() { - if ( /^ui-id-\d+$/.test( this.id ) ) { - $( this ).removeAttr( "id" ); + result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop ); } } ); - } -} ); - - - -// This file is deprecated -var ie = $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() ); + return this[ spaceName ]( result ); + }, + blend: function( opaque ) { -/*! - * jQuery UI Mouse 1.13.1 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ + // if we are already opaque - return ourself + if ( this._rgba[ 3 ] === 1 ) { + return this; + } -//>>label: Mouse -//>>group: Widgets -//>>description: Abstracts mouse-based interactions to assist in creating certain widgets. -//>>docs: http://api.jqueryui.com/mouse/ + var rgb = this._rgba.slice(), + a = rgb.pop(), + blend = color( opaque )._rgba; + return color( jQuery.map( rgb, function( v, i ) { + return ( 1 - a ) * blend[ i ] + a * v; + } ) ); + }, + toRgbaString: function() { + var prefix = "rgba(", + rgba = jQuery.map( this._rgba, function( v, i ) { + if ( v != null ) { + return v; + } + return i > 2 ? 1 : 0; + } ); -var mouseHandled = false; -$( document ).on( "mouseup", function() { - mouseHandled = false; -} ); + if ( rgba[ 3 ] === 1 ) { + rgba.pop(); + prefix = "rgb("; + } -var widgetsMouse = $.widget( "ui.mouse", { - version: "1.13.1", - options: { - cancel: "input, textarea, button, select, option", - distance: 1, - delay: 0 + return prefix + rgba.join() + ")"; }, - _mouseInit: function() { - var that = this; + toHslaString: function() { + var prefix = "hsla(", + hsla = jQuery.map( this.hsla(), function( v, i ) { + if ( v == null ) { + v = i > 2 ? 1 : 0; + } - this.element - .on( "mousedown." + this.widgetName, function( event ) { - return that._mouseDown( event ); - } ) - .on( "click." + this.widgetName, function( event ) { - if ( true === $.data( event.target, that.widgetName + ".preventClickEvent" ) ) { - $.removeData( event.target, that.widgetName + ".preventClickEvent" ); - event.stopImmediatePropagation(); - return false; + // catch 1 and 2 + if ( i && i < 3 ) { + v = Math.round( v * 100 ) + "%"; } + return v; } ); - this.started = false; - }, - - // TODO: make sure destroying one instance of mouse doesn't mess with - // other instances of mouse - _mouseDestroy: function() { - this.element.off( "." + this.widgetName ); - if ( this._mouseMoveDelegate ) { - this.document - .off( "mousemove." + this.widgetName, this._mouseMoveDelegate ) - .off( "mouseup." + this.widgetName, this._mouseUpDelegate ); + if ( hsla[ 3 ] === 1 ) { + hsla.pop(); + prefix = "hsl("; } + return prefix + hsla.join() + ")"; }, + toHexString: function( includeAlpha ) { + var rgba = this._rgba.slice(), + alpha = rgba.pop(); - _mouseDown: function( event ) { - - // don't let more than one widget handle mouseStart - if ( mouseHandled ) { - return; + if ( includeAlpha ) { + rgba.push( ~~( alpha * 255 ) ); } - this._mouseMoved = false; - - // We may have missed mouseup (out of window) - if ( this._mouseStarted ) { - this._mouseUp( event ); - } + return "#" + jQuery.map( rgba, function( v ) { - this._mouseDownEvent = event; - - var that = this, - btnIsLeft = ( event.which === 1 ), + // default to 0 when nulls exist + v = ( v || 0 ).toString( 16 ); + return v.length === 1 ? "0" + v : v; + } ).join( "" ); + }, + toString: function() { + return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString(); + } +} ); +color.fn.parse.prototype = color.fn; - // event.target.nodeName works around a bug in IE 8 with - // disabled inputs (#7620) - elIsCancel = ( typeof this.options.cancel === "string" && event.target.nodeName ? - $( event.target ).closest( this.options.cancel ).length : false ); - if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) { - return true; - } +// hsla conversions adapted from: +// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021 - this.mouseDelayMet = !this.options.delay; - if ( !this.mouseDelayMet ) { - this._mouseDelayTimer = setTimeout( function() { - that.mouseDelayMet = true; - }, this.options.delay ); - } +function hue2rgb( p, q, h ) { + h = ( h + 1 ) % 1; + if ( h * 6 < 1 ) { + return p + ( q - p ) * h * 6; + } + if ( h * 2 < 1 ) { + return q; + } + if ( h * 3 < 2 ) { + return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6; + } + return p; +} - if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) { - this._mouseStarted = ( this._mouseStart( event ) !== false ); - if ( !this._mouseStarted ) { - event.preventDefault(); - return true; - } - } +spaces.hsla.to = function( rgba ) { + if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) { + return [ null, null, null, rgba[ 3 ] ]; + } + var r = rgba[ 0 ] / 255, + g = rgba[ 1 ] / 255, + b = rgba[ 2 ] / 255, + a = rgba[ 3 ], + max = Math.max( r, g, b ), + min = Math.min( r, g, b ), + diff = max - min, + add = max + min, + l = add * 0.5, + h, s; - // Click event may never have fired (Gecko & Opera) - if ( true === $.data( event.target, this.widgetName + ".preventClickEvent" ) ) { - $.removeData( event.target, this.widgetName + ".preventClickEvent" ); - } + if ( min === max ) { + h = 0; + } else if ( r === max ) { + h = ( 60 * ( g - b ) / diff ) + 360; + } else if ( g === max ) { + h = ( 60 * ( b - r ) / diff ) + 120; + } else { + h = ( 60 * ( r - g ) / diff ) + 240; + } - // These delegates are required to keep context - this._mouseMoveDelegate = function( event ) { - return that._mouseMove( event ); - }; - this._mouseUpDelegate = function( event ) { - return that._mouseUp( event ); - }; + // chroma (diff) == 0 means greyscale which, by definition, saturation = 0% + // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add) + if ( diff === 0 ) { + s = 0; + } else if ( l <= 0.5 ) { + s = diff / add; + } else { + s = diff / ( 2 - add ); + } + return [ Math.round( h ) % 360, s, l, a == null ? 1 : a ]; +}; - this.document - .on( "mousemove." + this.widgetName, this._mouseMoveDelegate ) - .on( "mouseup." + this.widgetName, this._mouseUpDelegate ); +spaces.hsla.from = function( hsla ) { + if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) { + return [ null, null, null, hsla[ 3 ] ]; + } + var h = hsla[ 0 ] / 360, + s = hsla[ 1 ], + l = hsla[ 2 ], + a = hsla[ 3 ], + q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s, + p = 2 * l - q; - event.preventDefault(); + return [ + Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ), + Math.round( hue2rgb( p, q, h ) * 255 ), + Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ), + a + ]; +}; - mouseHandled = true; - return true; - }, - _mouseMove: function( event ) { +each( spaces, function( spaceName, space ) { + var props = space.props, + cache = space.cache, + to = space.to, + from = space.from; - // Only check for mouseups outside the document if you've moved inside the document - // at least once. This prevents the firing of mouseup in the case of IE<9, which will - // fire a mousemove event if content is placed under the cursor. See #7778 - // Support: IE <9 - if ( this._mouseMoved ) { + // makes rgba() and hsla() + color.fn[ spaceName ] = function( value ) { - // IE mouseup check - mouseup happened when mouse was out of window - if ( $.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && - !event.button ) { - return this._mouseUp( event ); + // generate a cache for this space if it doesn't exist + if ( to && !this[ cache ] ) { + this[ cache ] = to( this._rgba ); + } + if ( value === undefined ) { + return this[ cache ].slice(); + } - // Iframe mouseup check - mouseup occurred in another document - } else if ( !event.which ) { + var ret, + type = getType( value ), + arr = ( type === "array" || type === "object" ) ? value : arguments, + local = this[ cache ].slice(); - // Support: Safari <=8 - 9 - // Safari sets which to 0 if you press any of the following keys - // during a drag (#14461) - if ( event.originalEvent.altKey || event.originalEvent.ctrlKey || - event.originalEvent.metaKey || event.originalEvent.shiftKey ) { - this.ignoreMissingWhich = true; - } else if ( !this.ignoreMissingWhich ) { - return this._mouseUp( event ); - } + each( props, function( key, prop ) { + var val = arr[ type === "object" ? key : prop.idx ]; + if ( val == null ) { + val = local[ prop.idx ]; } - } + local[ prop.idx ] = clamp( val, prop ); + } ); - if ( event.which || event.button ) { - this._mouseMoved = true; + if ( from ) { + ret = color( from( local ) ); + ret[ cache ] = local; + return ret; + } else { + return color( local ); } + }; - if ( this._mouseStarted ) { - this._mouseDrag( event ); - return event.preventDefault(); + // makes red() green() blue() alpha() hue() saturation() lightness() + each( props, function( key, prop ) { + + // alpha is included in more than one space + if ( color.fn[ key ] ) { + return; } + color.fn[ key ] = function( value ) { + var local, cur, match, fn, + vtype = getType( value ); - if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) { - this._mouseStarted = - ( this._mouseStart( this._mouseDownEvent, event ) !== false ); - if ( this._mouseStarted ) { - this._mouseDrag( event ); + if ( key === "alpha" ) { + fn = this._hsla ? "hsla" : "rgba"; } else { - this._mouseUp( event ); + fn = spaceName; } - } - - return !this._mouseStarted; - }, - - _mouseUp: function( event ) { - this.document - .off( "mousemove." + this.widgetName, this._mouseMoveDelegate ) - .off( "mouseup." + this.widgetName, this._mouseUpDelegate ); - - if ( this._mouseStarted ) { - this._mouseStarted = false; + local = this[ fn ](); + cur = local[ prop.idx ]; - if ( event.target === this._mouseDownEvent.target ) { - $.data( event.target, this.widgetName + ".preventClickEvent", true ); + if ( vtype === "undefined" ) { + return cur; } - this._mouseStop( event ); - } - - if ( this._mouseDelayTimer ) { - clearTimeout( this._mouseDelayTimer ); - delete this._mouseDelayTimer; - } + if ( vtype === "function" ) { + value = value.call( this, cur ); + vtype = getType( value ); + } + if ( value == null && prop.empty ) { + return this; + } + if ( vtype === "string" ) { + match = rplusequals.exec( value ); + if ( match ) { + value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 ); + } + } + local[ prop.idx ] = value; + return this[ fn ]( local ); + }; + } ); +} ); - this.ignoreMissingWhich = false; - mouseHandled = false; - event.preventDefault(); - }, +// add cssHook and .fx.step function for each named hook. +// accept a space separated string of properties +color.hook = function( hook ) { + var hooks = hook.split( " " ); + each( hooks, function( _i, hook ) { + jQuery.cssHooks[ hook ] = { + set: function( elem, value ) { + var parsed, curElem, + backgroundColor = ""; - _mouseDistanceMet: function( event ) { - return ( Math.max( - Math.abs( this._mouseDownEvent.pageX - event.pageX ), - Math.abs( this._mouseDownEvent.pageY - event.pageY ) - ) >= this.options.distance - ); - }, - - _mouseDelayMet: function( /* event */ ) { - return this.mouseDelayMet; - }, - - // These are placeholder methods, to be overriden by extending plugin - _mouseStart: function( /* event */ ) {}, - _mouseDrag: function( /* event */ ) {}, - _mouseStop: function( /* event */ ) {}, - _mouseCapture: function( /* event */ ) { - return true; - } -} ); - - - -// $.ui.plugin is deprecated. Use $.widget() extensions instead. -var plugin = $.ui.plugin = { - add: function( module, option, set ) { - var i, - proto = $.ui[ module ].prototype; - for ( i in set ) { - proto.plugins[ i ] = proto.plugins[ i ] || []; - proto.plugins[ i ].push( [ option, set[ i ] ] ); - } - }, - call: function( instance, name, args, allowDisconnected ) { - var i, - set = instance.plugins[ name ]; + if ( value !== "transparent" && ( getType( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) { + value = color( parsed || value ); + if ( !support.rgba && value._rgba[ 3 ] !== 1 ) { + curElem = hook === "backgroundColor" ? elem.parentNode : elem; + while ( + ( backgroundColor === "" || backgroundColor === "transparent" ) && + curElem && curElem.style + ) { + try { + backgroundColor = jQuery.css( curElem, "backgroundColor" ); + curElem = curElem.parentNode; + } catch ( e ) { + } + } - if ( !set ) { - return; - } + value = value.blend( backgroundColor && backgroundColor !== "transparent" ? + backgroundColor : + "_default" ); + } - if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode || - instance.element[ 0 ].parentNode.nodeType === 11 ) ) { - return; - } + value = value.toRgbaString(); + } + try { + elem.style[ hook ] = value; + } catch ( e ) { - for ( i = 0; i < set.length; i++ ) { - if ( instance.options[ set[ i ][ 0 ] ] ) { - set[ i ][ 1 ].apply( instance.element, args ); + // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit' + } } - } - } -}; - - + }; + jQuery.fx.step[ hook ] = function( fx ) { + if ( !fx.colorInit ) { + fx.start = color( fx.elem, hook ); + fx.end = color( fx.end ); + fx.colorInit = true; + } + jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) ); + }; + } ); -var safeActiveElement = $.ui.safeActiveElement = function( document ) { - var activeElement; +}; - // Support: IE 9 only - // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe> - try { - activeElement = document.activeElement; - } catch ( error ) { - activeElement = document.body; - } +color.hook( stepHooks ); - // Support: IE 9 - 11 only - // IE may return null instead of an element - // Interestingly, this only seems to occur when NOT in an iframe - if ( !activeElement ) { - activeElement = document.body; - } +jQuery.cssHooks.borderColor = { + expand: function( value ) { + var expanded = {}; - // Support: IE 11 only - // IE11 returns a seemingly empty object in some cases when accessing - // document.activeElement from an <iframe> - if ( !activeElement.nodeName ) { - activeElement = document.body; + each( [ "Top", "Right", "Bottom", "Left" ], function( _i, part ) { + expanded[ "border" + part + "Color" ] = value; + } ); + return expanded; } - - return activeElement; }; +// Basic color names only. +// Usage of any of the other color names requires adding yourself or including +// jquery.color.svg-names.js. +colors = jQuery.Color.names = { + // 4.1. Basic color keywords + aqua: "#00ffff", + black: "#000000", + blue: "#0000ff", + fuchsia: "#ff00ff", + gray: "#808080", + green: "#008000", + lime: "#00ff00", + maroon: "#800000", + navy: "#000080", + olive: "#808000", + purple: "#800080", + red: "#ff0000", + silver: "#c0c0c0", + teal: "#008080", + white: "#ffffff", + yellow: "#ffff00", -var safeBlur = $.ui.safeBlur = function( element ) { + // 4.2.3. "transparent" color keyword + transparent: [ null, null, null, 0 ], - // Support: IE9 - 10 only - // If the <body> is blurred, IE will switch windows, see #9420 - if ( element && element.nodeName.toLowerCase() !== "body" ) { - $( element ).trigger( "blur" ); - } + _default: "#ffffff" }; /*! - * jQuery UI Draggable 1.13.1 + * jQuery UI Effects 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -2036,1234 +2055,1333 @@ var safeBlur = $.ui.safeBlur = function( element ) { * http://jquery.org/license */ -//>>label: Draggable -//>>group: Interactions -//>>description: Enables dragging functionality for any element. -//>>docs: http://api.jqueryui.com/draggable/ -//>>demos: http://jqueryui.com/draggable/ -//>>css.structure: ../../themes/base/draggable.css - +//>>label: Effects Core +//>>group: Effects +/* eslint-disable max-len */ +//>>description: Extends the internal jQuery effects. Includes morphing and easing. Required by all other effects. +/* eslint-enable max-len */ +//>>docs: http://api.jqueryui.com/category/effects-core/ +//>>demos: http://jqueryui.com/effect/ -$.widget( "ui.draggable", $.ui.mouse, { - version: "1.13.1", - widgetEventPrefix: "drag", - options: { - addClasses: true, - appendTo: "parent", - axis: false, - connectToSortable: false, - containment: false, - cursor: "auto", - cursorAt: false, - grid: false, - handle: false, - helper: "original", - iframeFix: false, - opacity: false, - refreshPositions: false, - revert: false, - revertDuration: 500, - scope: "default", - scroll: true, - scrollSensitivity: 20, - scrollSpeed: 20, - snap: false, - snapMode: "both", - snapTolerance: 20, - stack: false, - zIndex: false, - // Callbacks - drag: null, - start: null, - stop: null - }, - _create: function() { +var dataSpace = "ui-effects-", + dataSpaceStyle = "ui-effects-style", + dataSpaceAnimated = "ui-effects-animated"; - if ( this.options.helper === "original" ) { - this._setPositionRelative(); - } - if ( this.options.addClasses ) { - this._addClass( "ui-draggable" ); - } - this._setHandleClassName(); +$.effects = { + effect: {} +}; - this._mouseInit(); - }, +/******************************************************************************/ +/****************************** CLASS ANIMATIONS ******************************/ +/******************************************************************************/ +( function() { - _setOption: function( key, value ) { - this._super( key, value ); - if ( key === "handle" ) { - this._removeHandleClassName(); - this._setHandleClassName(); - } - }, +var classAnimationActions = [ "add", "remove", "toggle" ], + shorthandStyles = { + border: 1, + borderBottom: 1, + borderColor: 1, + borderLeft: 1, + borderRight: 1, + borderTop: 1, + borderWidth: 1, + margin: 1, + padding: 1 + }; - _destroy: function() { - if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) { - this.destroyOnClear = true; - return; - } - this._removeHandleClassName(); - this._mouseDestroy(); - }, +$.each( + [ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], + function( _, prop ) { + $.fx.step[ prop ] = function( fx ) { + if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) { + jQuery.style( fx.elem, prop, fx.end ); + fx.setAttr = true; + } + }; + } +); - _mouseCapture: function( event ) { - var o = this.options; +function camelCase( string ) { + return string.replace( /-([\da-z])/gi, function( all, letter ) { + return letter.toUpperCase(); + } ); +} - // Among others, prevent a drag on a resizable-handle - if ( this.helper || o.disabled || - $( event.target ).closest( ".ui-resizable-handle" ).length > 0 ) { - return false; +function getElementStyles( elem ) { + var key, len, + style = elem.ownerDocument.defaultView ? + elem.ownerDocument.defaultView.getComputedStyle( elem, null ) : + elem.currentStyle, + styles = {}; + + if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) { + len = style.length; + while ( len-- ) { + key = style[ len ]; + if ( typeof style[ key ] === "string" ) { + styles[ camelCase( key ) ] = style[ key ]; + } } - //Quit if we're not on a valid handle - this.handle = this._getHandle( event ); - if ( !this.handle ) { - return false; + // Support: Opera, IE <9 + } else { + for ( key in style ) { + if ( typeof style[ key ] === "string" ) { + styles[ key ] = style[ key ]; + } } + } - this._blurActiveElement( event ); + return styles; +} - this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix ); +function styleDifference( oldStyle, newStyle ) { + var diff = {}, + name, value; - return true; + for ( name in newStyle ) { + value = newStyle[ name ]; + if ( oldStyle[ name ] !== value ) { + if ( !shorthandStyles[ name ] ) { + if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) { + diff[ name ] = value; + } + } + } + } - }, + return diff; +} - _blockFrames: function( selector ) { - this.iframeBlocks = this.document.find( selector ).map( function() { - var iframe = $( this ); +// Support: jQuery <1.8 +if ( !$.fn.addBack ) { + $.fn.addBack = function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter( selector ) + ); + }; +} - return $( "<div>" ) - .css( "position", "absolute" ) - .appendTo( iframe.parent() ) - .outerWidth( iframe.outerWidth() ) - .outerHeight( iframe.outerHeight() ) - .offset( iframe.offset() )[ 0 ]; - } ); - }, +$.effects.animateClass = function( value, duration, easing, callback ) { + var o = $.speed( duration, easing, callback ); - _unblockFrames: function() { - if ( this.iframeBlocks ) { - this.iframeBlocks.remove(); - delete this.iframeBlocks; - } - }, + return this.queue( function() { + var animated = $( this ), + baseClass = animated.attr( "class" ) || "", + applyClassChange, + allAnimations = o.children ? animated.find( "*" ).addBack() : animated; - _blurActiveElement: function( event ) { - var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ), - target = $( event.target ); + // Map the animated objects to store the original styles. + allAnimations = allAnimations.map( function() { + var el = $( this ); + return { + el: el, + start: getElementStyles( this ) + }; + } ); - // Don't blur if the event occurred on an element that is within - // the currently focused element - // See #10527, #12472 - if ( target.closest( activeElement ).length ) { - return; - } + // Apply class change + applyClassChange = function() { + $.each( classAnimationActions, function( i, action ) { + if ( value[ action ] ) { + animated[ action + "Class" ]( value[ action ] ); + } + } ); + }; + applyClassChange(); - // Blur any element that currently has focus, see #4261 - $.ui.safeBlur( activeElement ); - }, + // Map all animated objects again - calculate new styles and diff + allAnimations = allAnimations.map( function() { + this.end = getElementStyles( this.el[ 0 ] ); + this.diff = styleDifference( this.start, this.end ); + return this; + } ); - _mouseStart: function( event ) { + // Apply original class + animated.attr( "class", baseClass ); - var o = this.options; + // Map all animated objects again - this time collecting a promise + allAnimations = allAnimations.map( function() { + var styleInfo = this, + dfd = $.Deferred(), + opts = $.extend( {}, o, { + queue: false, + complete: function() { + dfd.resolve( styleInfo ); + } + } ); - //Create and append the visible helper - this.helper = this._createHelper( event ); + this.el.animate( this.diff, opts ); + return dfd.promise(); + } ); - this._addClass( this.helper, "ui-draggable-dragging" ); + // Once all animations have completed: + $.when.apply( $, allAnimations.get() ).done( function() { - //Cache the helper size - this._cacheHelperProportions(); + // Set the final class + applyClassChange(); - //If ddmanager is used for droppables, set the global draggable - if ( $.ui.ddmanager ) { - $.ui.ddmanager.current = this; - } + // For each animated element, + // clear all css properties that were animated + $.each( arguments, function() { + var el = this.el; + $.each( this.diff, function( key ) { + el.css( key, "" ); + } ); + } ); - /* - * - Position generation - - * This block generates everything position related - it's the core of draggables. - */ + // This is guarnteed to be there if you use jQuery.speed() + // it also handles dequeuing the next anim... + o.complete.call( animated[ 0 ] ); + } ); + } ); +}; - //Cache the margins of the original element - this._cacheMargins(); +$.fn.extend( { + addClass: ( function( orig ) { + return function( classNames, speed, easing, callback ) { + return speed ? + $.effects.animateClass.call( this, + { add: classNames }, speed, easing, callback ) : + orig.apply( this, arguments ); + }; + } )( $.fn.addClass ), - //Store the helper's css position - this.cssPosition = this.helper.css( "position" ); - this.scrollParent = this.helper.scrollParent( true ); - this.offsetParent = this.helper.offsetParent(); - this.hasFixedAncestor = this.helper.parents().filter( function() { - return $( this ).css( "position" ) === "fixed"; - } ).length > 0; + removeClass: ( function( orig ) { + return function( classNames, speed, easing, callback ) { + return arguments.length > 1 ? + $.effects.animateClass.call( this, + { remove: classNames }, speed, easing, callback ) : + orig.apply( this, arguments ); + }; + } )( $.fn.removeClass ), - //The element's absolute position on the page minus margins - this.positionAbs = this.element.offset(); - this._refreshOffsets( event ); + toggleClass: ( function( orig ) { + return function( classNames, force, speed, easing, callback ) { + if ( typeof force === "boolean" || force === undefined ) { + if ( !speed ) { - //Generate the original position - this.originalPosition = this.position = this._generatePosition( event, false ); - this.originalPageX = event.pageX; - this.originalPageY = event.pageY; + // Without speed parameter + return orig.apply( this, arguments ); + } else { + return $.effects.animateClass.call( this, + ( force ? { add: classNames } : { remove: classNames } ), + speed, easing, callback ); + } + } else { - //Adjust the mouse offset relative to the helper if "cursorAt" is supplied - if ( o.cursorAt ) { - this._adjustOffsetFromHelper( o.cursorAt ); - } + // Without force parameter + return $.effects.animateClass.call( this, + { toggle: classNames }, force, speed, easing ); + } + }; + } )( $.fn.toggleClass ), - //Set a containment if given in the options - this._setContainment(); + switchClass: function( remove, add, speed, easing, callback ) { + return $.effects.animateClass.call( this, { + add: add, + remove: remove + }, speed, easing, callback ); + } +} ); - //Trigger event + callbacks - if ( this._trigger( "start", event ) === false ) { - this._clear(); - return false; - } +} )(); - //Recache the helper size - this._cacheHelperProportions(); +/******************************************************************************/ +/*********************************** EFFECTS **********************************/ +/******************************************************************************/ - //Prepare the droppable offsets - if ( $.ui.ddmanager && !o.dropBehaviour ) { - $.ui.ddmanager.prepareOffsets( this, event ); - } +( function() { - // Execute the drag once - this causes the helper not to be visible before getting its - // correct position - this._mouseDrag( event, true ); +if ( $.expr && $.expr.pseudos && $.expr.pseudos.animated ) { + $.expr.pseudos.animated = ( function( orig ) { + return function( elem ) { + return !!$( elem ).data( dataSpaceAnimated ) || orig( elem ); + }; + } )( $.expr.pseudos.animated ); +} - // If the ddmanager is used for droppables, inform the manager that dragging has started - // (see #5003) - if ( $.ui.ddmanager ) { - $.ui.ddmanager.dragStart( this, event ); - } - - return true; - }, - - _refreshOffsets: function( event ) { - this.offset = { - top: this.positionAbs.top - this.margins.top, - left: this.positionAbs.left - this.margins.left, - scroll: false, - parent: this._getParentOffset(), - relative: this._getRelativeOffset() - }; +if ( $.uiBackCompat !== false ) { + $.extend( $.effects, { - this.offset.click = { - left: event.pageX - this.offset.left, - top: event.pageY - this.offset.top - }; - }, + // Saves a set of properties in a data storage + save: function( element, set ) { + var i = 0, length = set.length; + for ( ; i < length; i++ ) { + if ( set[ i ] !== null ) { + element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); + } + } + }, - _mouseDrag: function( event, noPropagation ) { + // Restores a set of previously saved properties from a data storage + restore: function( element, set ) { + var val, i = 0, length = set.length; + for ( ; i < length; i++ ) { + if ( set[ i ] !== null ) { + val = element.data( dataSpace + set[ i ] ); + element.css( set[ i ], val ); + } + } + }, - // reset any necessary cached properties (see #5009) - if ( this.hasFixedAncestor ) { - this.offset.parent = this._getParentOffset(); - } + setMode: function( el, mode ) { + if ( mode === "toggle" ) { + mode = el.is( ":hidden" ) ? "show" : "hide"; + } + return mode; + }, - //Compute the helpers position - this.position = this._generatePosition( event, true ); - this.positionAbs = this._convertPositionTo( "absolute" ); + // Wraps the element around a wrapper that copies position properties + createWrapper: function( element ) { - //Call plugins and callbacks and use the resulting position if something is returned - if ( !noPropagation ) { - var ui = this._uiHash(); - if ( this._trigger( "drag", event, ui ) === false ) { - this._mouseUp( new $.Event( "mouseup", event ) ); - return false; + // If the element is already wrapped, return it + if ( element.parent().is( ".ui-effects-wrapper" ) ) { + return element.parent(); } - this.position = ui.position; - } - this.helper[ 0 ].style.left = this.position.left + "px"; - this.helper[ 0 ].style.top = this.position.top + "px"; + // Wrap the element + var props = { + width: element.outerWidth( true ), + height: element.outerHeight( true ), + "float": element.css( "float" ) + }, + wrapper = $( "<div></div>" ) + .addClass( "ui-effects-wrapper" ) + .css( { + fontSize: "100%", + background: "transparent", + border: "none", + margin: 0, + padding: 0 + } ), - if ( $.ui.ddmanager ) { - $.ui.ddmanager.drag( this, event ); - } + // Store the size in case width/height are defined in % - Fixes #5245 + size = { + width: element.width(), + height: element.height() + }, + active = document.activeElement; - return false; - }, + // Support: Firefox + // Firefox incorrectly exposes anonymous content + // https://bugzilla.mozilla.org/show_bug.cgi?id=561664 + try { + // eslint-disable-next-line no-unused-expressions + active.id; + } catch ( e ) { + active = document.body; + } - _mouseStop: function( event ) { + element.wrap( wrapper ); - //If we are using droppables, inform the manager about the drop - var that = this, - dropped = false; - if ( $.ui.ddmanager && !this.options.dropBehaviour ) { - dropped = $.ui.ddmanager.drop( this, event ); - } + // Fixes #7595 - Elements lose focus when wrapped. + if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { + $( active ).trigger( "focus" ); + } - //if a drop comes from outside (a sortable) - if ( this.dropped ) { - dropped = this.dropped; - this.dropped = false; - } + // Hotfix for jQuery 1.4 since some change in wrap() seems to actually + // lose the reference to the wrapped element + wrapper = element.parent(); - if ( ( this.options.revert === "invalid" && !dropped ) || - ( this.options.revert === "valid" && dropped ) || - this.options.revert === true || ( typeof this.options.revert === "function" && - this.options.revert.call( this.element, dropped ) ) - ) { - $( this.helper ).animate( - this.originalPosition, - parseInt( this.options.revertDuration, 10 ), - function() { - if ( that._trigger( "stop", event ) !== false ) { - that._clear(); + // Transfer positioning properties to the wrapper + if ( element.css( "position" ) === "static" ) { + wrapper.css( { position: "relative" } ); + element.css( { position: "relative" } ); + } else { + $.extend( props, { + position: element.css( "position" ), + zIndex: element.css( "z-index" ) + } ); + $.each( [ "top", "left", "bottom", "right" ], function( i, pos ) { + props[ pos ] = element.css( pos ); + if ( isNaN( parseInt( props[ pos ], 10 ) ) ) { + props[ pos ] = "auto"; } - } - ); - } else { - if ( this._trigger( "stop", event ) !== false ) { - this._clear(); + } ); + element.css( { + position: "relative", + top: 0, + left: 0, + right: "auto", + bottom: "auto" + } ); } - } + element.css( size ); - return false; - }, + return wrapper.css( props ).show(); + }, - _mouseUp: function( event ) { - this._unblockFrames(); + removeWrapper: function( element ) { + var active = document.activeElement; - // If the ddmanager is used for droppables, inform the manager that dragging has stopped - // (see #5003) - if ( $.ui.ddmanager ) { - $.ui.ddmanager.dragStop( this, event ); + if ( element.parent().is( ".ui-effects-wrapper" ) ) { + element.parent().replaceWith( element ); + + // Fixes #7595 - Elements lose focus when wrapped. + if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { + $( active ).trigger( "focus" ); + } + } + + return element; } + } ); +} - // Only need to focus if the event occurred on the draggable itself, see #10527 - if ( this.handleElement.is( event.target ) ) { +$.extend( $.effects, { + version: "1.13.2", - // The interaction is over; whether or not the click resulted in a drag, - // focus the element - this.element.trigger( "focus" ); + define: function( name, mode, effect ) { + if ( !effect ) { + effect = mode; + mode = "effect"; } - return $.ui.mouse.prototype._mouseUp.call( this, event ); - }, + $.effects.effect[ name ] = effect; + $.effects.effect[ name ].mode = mode; - cancel: function() { + return effect; + }, - if ( this.helper.is( ".ui-draggable-dragging" ) ) { - this._mouseUp( new $.Event( "mouseup", { target: this.element[ 0 ] } ) ); - } else { - this._clear(); + scaledDimensions: function( element, percent, direction ) { + if ( percent === 0 ) { + return { + height: 0, + width: 0, + outerHeight: 0, + outerWidth: 0 + }; } - return this; + var x = direction !== "horizontal" ? ( ( percent || 100 ) / 100 ) : 1, + y = direction !== "vertical" ? ( ( percent || 100 ) / 100 ) : 1; - }, + return { + height: element.height() * y, + width: element.width() * x, + outerHeight: element.outerHeight() * y, + outerWidth: element.outerWidth() * x + }; - _getHandle: function( event ) { - return this.options.handle ? - !!$( event.target ).closest( this.element.find( this.options.handle ) ).length : - true; }, - _setHandleClassName: function() { - this.handleElement = this.options.handle ? - this.element.find( this.options.handle ) : this.element; - this._addClass( this.handleElement, "ui-draggable-handle" ); + clipToBox: function( animation ) { + return { + width: animation.clip.right - animation.clip.left, + height: animation.clip.bottom - animation.clip.top, + left: animation.clip.left, + top: animation.clip.top + }; }, - _removeHandleClassName: function() { - this._removeClass( this.handleElement, "ui-draggable-handle" ); + // Injects recently queued functions to be first in line (after "inprogress") + unshift: function( element, queueLength, count ) { + var queue = element.queue(); + + if ( queueLength > 1 ) { + queue.splice.apply( queue, + [ 1, 0 ].concat( queue.splice( queueLength, count ) ) ); + } + element.dequeue(); }, - _createHelper: function( event ) { + saveStyle: function( element ) { + element.data( dataSpaceStyle, element[ 0 ].style.cssText ); + }, - var o = this.options, - helperIsFunction = typeof o.helper === "function", - helper = helperIsFunction ? - $( o.helper.apply( this.element[ 0 ], [ event ] ) ) : - ( o.helper === "clone" ? - this.element.clone().removeAttr( "id" ) : - this.element ); + restoreStyle: function( element ) { + element[ 0 ].style.cssText = element.data( dataSpaceStyle ) || ""; + element.removeData( dataSpaceStyle ); + }, - if ( !helper.parents( "body" ).length ) { - helper.appendTo( ( o.appendTo === "parent" ? - this.element[ 0 ].parentNode : - o.appendTo ) ); - } + mode: function( element, mode ) { + var hidden = element.is( ":hidden" ); - // Http://bugs.jqueryui.com/ticket/9446 - // a helper function can return the original element - // which wouldn't have been set to relative in _create - if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) { - this._setPositionRelative(); + if ( mode === "toggle" ) { + mode = hidden ? "show" : "hide"; } - - if ( helper[ 0 ] !== this.element[ 0 ] && - !( /(fixed|absolute)/ ).test( helper.css( "position" ) ) ) { - helper.css( "position", "absolute" ); + if ( hidden ? mode === "hide" : mode === "show" ) { + mode = "none"; } - - return helper; - + return mode; }, - _setPositionRelative: function() { - if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) { - this.element[ 0 ].style.position = "relative"; - } - }, + // Translates a [top,left] array into a baseline value + getBaseline: function( origin, original ) { + var y, x; - _adjustOffsetFromHelper: function( obj ) { - if ( typeof obj === "string" ) { - obj = obj.split( " " ); - } - if ( Array.isArray( obj ) ) { - obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 }; - } - if ( "left" in obj ) { - this.offset.click.left = obj.left + this.margins.left; - } - if ( "right" in obj ) { - this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; - } - if ( "top" in obj ) { - this.offset.click.top = obj.top + this.margins.top; + switch ( origin[ 0 ] ) { + case "top": + y = 0; + break; + case "middle": + y = 0.5; + break; + case "bottom": + y = 1; + break; + default: + y = origin[ 0 ] / original.height; } - if ( "bottom" in obj ) { - this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; + + switch ( origin[ 1 ] ) { + case "left": + x = 0; + break; + case "center": + x = 0.5; + break; + case "right": + x = 1; + break; + default: + x = origin[ 1 ] / original.width; } - }, - _isRootNode: function( element ) { - return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ]; + return { + x: x, + y: y + }; }, - _getParentOffset: function() { + // Creates a placeholder element so that the original element can be made absolute + createPlaceholder: function( element ) { + var placeholder, + cssPosition = element.css( "position" ), + position = element.position(); - //Get the offsetParent and cache its position - var po = this.offsetParent.offset(), - document = this.document[ 0 ]; + // Lock in margins first to account for form elements, which + // will change margin if you explicitly set height + // see: http://jsfiddle.net/JZSMt/3/ https://bugs.webkit.org/show_bug.cgi?id=107380 + // Support: Safari + element.css( { + marginTop: element.css( "marginTop" ), + marginBottom: element.css( "marginBottom" ), + marginLeft: element.css( "marginLeft" ), + marginRight: element.css( "marginRight" ) + } ) + .outerWidth( element.outerWidth() ) + .outerHeight( element.outerHeight() ); - // This is a special case where we need to modify a offset calculated on start, since the - // following happened: - // 1. The position of the helper is absolute, so it's position is calculated based on the - // next positioned parent - // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't - // the document, which means that the scroll is included in the initial calculation of the - // offset of the parent, and never recalculated upon drag - if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== document && - $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) { - po.left += this.scrollParent.scrollLeft(); - po.top += this.scrollParent.scrollTop(); - } + if ( /^(static|relative)/.test( cssPosition ) ) { + cssPosition = "absolute"; - if ( this._isRootNode( this.offsetParent[ 0 ] ) ) { - po = { top: 0, left: 0 }; - } + placeholder = $( "<" + element[ 0 ].nodeName + ">" ).insertAfter( element ).css( { - return { - top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ), - left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 ) - }; + // Convert inline to inline block to account for inline elements + // that turn to inline block based on content (like img) + display: /^(inline|ruby)/.test( element.css( "display" ) ) ? + "inline-block" : + "block", + visibility: "hidden", - }, + // Margins need to be set to account for margin collapse + marginTop: element.css( "marginTop" ), + marginBottom: element.css( "marginBottom" ), + marginLeft: element.css( "marginLeft" ), + marginRight: element.css( "marginRight" ), + "float": element.css( "float" ) + } ) + .outerWidth( element.outerWidth() ) + .outerHeight( element.outerHeight() ) + .addClass( "ui-effects-placeholder" ); - _getRelativeOffset: function() { - if ( this.cssPosition !== "relative" ) { - return { top: 0, left: 0 }; + element.data( dataSpace + "placeholder", placeholder ); } - var p = this.element.position(), - scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ); - - return { - top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) + - ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ), - left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) + - ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 ) - }; + element.css( { + position: cssPosition, + left: position.left, + top: position.top + } ); + return placeholder; }, - _cacheMargins: function() { - this.margins = { - left: ( parseInt( this.element.css( "marginLeft" ), 10 ) || 0 ), - top: ( parseInt( this.element.css( "marginTop" ), 10 ) || 0 ), - right: ( parseInt( this.element.css( "marginRight" ), 10 ) || 0 ), - bottom: ( parseInt( this.element.css( "marginBottom" ), 10 ) || 0 ) - }; + removePlaceholder: function( element ) { + var dataKey = dataSpace + "placeholder", + placeholder = element.data( dataKey ); + + if ( placeholder ) { + placeholder.remove(); + element.removeData( dataKey ); + } }, - _cacheHelperProportions: function() { - this.helperProportions = { - width: this.helper.outerWidth(), - height: this.helper.outerHeight() - }; + // Removes a placeholder if it exists and restores + // properties that were modified during placeholder creation + cleanUp: function( element ) { + $.effects.restoreStyle( element ); + $.effects.removePlaceholder( element ); }, - _setContainment: function() { + setTransition: function( element, list, factor, value ) { + value = value || {}; + $.each( list, function( i, x ) { + var unit = element.cssUnit( x ); + if ( unit[ 0 ] > 0 ) { + value[ x ] = unit[ 0 ] * factor + unit[ 1 ]; + } + } ); + return value; + } +} ); - var isUserScrollable, c, ce, - o = this.options, - document = this.document[ 0 ]; +// Return an effect options object for the given parameters: +function _normalizeArguments( effect, options, speed, callback ) { - this.relativeContainer = null; + // Allow passing all options as the first parameter + if ( $.isPlainObject( effect ) ) { + options = effect; + effect = effect.effect; + } - if ( !o.containment ) { - this.containment = null; - return; - } + // Convert to an object + effect = { effect: effect }; - if ( o.containment === "window" ) { - this.containment = [ - $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left, - $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top, - $( window ).scrollLeft() + $( window ).width() - - this.helperProportions.width - this.margins.left, - $( window ).scrollTop() + - ( $( window ).height() || document.body.parentNode.scrollHeight ) - - this.helperProportions.height - this.margins.top - ]; - return; - } + // Catch (effect, null, ...) + if ( options == null ) { + options = {}; + } - if ( o.containment === "document" ) { - this.containment = [ - 0, - 0, - $( document ).width() - this.helperProportions.width - this.margins.left, - ( $( document ).height() || document.body.parentNode.scrollHeight ) - - this.helperProportions.height - this.margins.top - ]; - return; - } + // Catch (effect, callback) + if ( typeof options === "function" ) { + callback = options; + speed = null; + options = {}; + } - if ( o.containment.constructor === Array ) { - this.containment = o.containment; - return; - } + // Catch (effect, speed, ?) + if ( typeof options === "number" || $.fx.speeds[ options ] ) { + callback = speed; + speed = options; + options = {}; + } - if ( o.containment === "parent" ) { - o.containment = this.helper[ 0 ].parentNode; - } + // Catch (effect, options, callback) + if ( typeof speed === "function" ) { + callback = speed; + speed = null; + } - c = $( o.containment ); - ce = c[ 0 ]; + // Add options to effect + if ( options ) { + $.extend( effect, options ); + } - if ( !ce ) { - return; - } + speed = speed || options.duration; + effect.duration = $.fx.off ? 0 : + typeof speed === "number" ? speed : + speed in $.fx.speeds ? $.fx.speeds[ speed ] : + $.fx.speeds._default; - isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) ); + effect.complete = callback || options.complete; - this.containment = [ - ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + - ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ), - ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + - ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ), - ( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - - ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) - - ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) - - this.helperProportions.width - - this.margins.left - - this.margins.right, - ( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - - ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) - - ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) - - this.helperProportions.height - - this.margins.top - - this.margins.bottom - ]; - this.relativeContainer = c; - }, + return effect; +} - _convertPositionTo: function( d, pos ) { +function standardAnimationOption( option ) { - if ( !pos ) { - pos = this.position; - } + // Valid standard speeds (nothing, number, named speed) + if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) { + return true; + } - var mod = d === "absolute" ? 1 : -1, - scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ); + // Invalid strings - treat as "normal" speed + if ( typeof option === "string" && !$.effects.effect[ option ] ) { + return true; + } - return { - top: ( + // Complete callback + if ( typeof option === "function" ) { + return true; + } - // The absolute mouse position - pos.top + + // Options hash (but not naming an effect) + if ( typeof option === "object" && !option.effect ) { + return true; + } - // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.relative.top * mod + + // Didn't match any standard API + return false; +} - // The offsetParent's offset without borders (offset + border) - this.offset.parent.top * mod - - ( ( this.cssPosition === "fixed" ? - -this.offset.scroll.top : - ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod ) - ), - left: ( +$.fn.extend( { + effect: function( /* effect, options, speed, callback */ ) { + var args = _normalizeArguments.apply( this, arguments ), + effectMethod = $.effects.effect[ args.effect ], + defaultMode = effectMethod.mode, + queue = args.queue, + queueName = queue || "fx", + complete = args.complete, + mode = args.mode, + modes = [], + prefilter = function( next ) { + var el = $( this ), + normalizedMode = $.effects.mode( el, mode ) || defaultMode; - // The absolute mouse position - pos.left + + // Sentinel for duck-punching the :animated pseudo-selector + el.data( dataSpaceAnimated, true ); - // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.relative.left * mod + + // Save effect mode for later use, + // we can't just call $.effects.mode again later, + // as the .show() below destroys the initial state + modes.push( normalizedMode ); - // The offsetParent's offset without borders (offset + border) - this.offset.parent.left * mod - - ( ( this.cssPosition === "fixed" ? - -this.offset.scroll.left : - ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod ) - ) - }; + // See $.uiBackCompat inside of run() for removal of defaultMode in 1.14 + if ( defaultMode && ( normalizedMode === "show" || + ( normalizedMode === defaultMode && normalizedMode === "hide" ) ) ) { + el.show(); + } - }, + if ( !defaultMode || normalizedMode !== "none" ) { + $.effects.saveStyle( el ); + } - _generatePosition: function( event, constrainPosition ) { + if ( typeof next === "function" ) { + next(); + } + }; - var containment, co, top, left, - o = this.options, - scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ), - pageX = event.pageX, - pageY = event.pageY; + if ( $.fx.off || !effectMethod ) { - // Cache the scroll - if ( !scrollIsRootNode || !this.offset.scroll ) { - this.offset.scroll = { - top: this.scrollParent.scrollTop(), - left: this.scrollParent.scrollLeft() - }; + // Delegate to the original method (e.g., .show()) if possible + if ( mode ) { + return this[ mode ]( args.duration, complete ); + } else { + return this.each( function() { + if ( complete ) { + complete.call( this ); + } + } ); + } } - /* - * - Position constraining - - * Constrain the position to a mix of grid, containment. - */ + function run( next ) { + var elem = $( this ); - // If we are not dragging yet, we won't check for options - if ( constrainPosition ) { - if ( this.containment ) { - if ( this.relativeContainer ) { - co = this.relativeContainer.offset(); - containment = [ - this.containment[ 0 ] + co.left, - this.containment[ 1 ] + co.top, - this.containment[ 2 ] + co.left, - this.containment[ 3 ] + co.top - ]; - } else { - containment = this.containment; - } + function cleanup() { + elem.removeData( dataSpaceAnimated ); - if ( event.pageX - this.offset.click.left < containment[ 0 ] ) { - pageX = containment[ 0 ] + this.offset.click.left; - } - if ( event.pageY - this.offset.click.top < containment[ 1 ] ) { - pageY = containment[ 1 ] + this.offset.click.top; + $.effects.cleanUp( elem ); + + if ( args.mode === "hide" ) { + elem.hide(); } - if ( event.pageX - this.offset.click.left > containment[ 2 ] ) { - pageX = containment[ 2 ] + this.offset.click.left; + + done(); + } + + function done() { + if ( typeof complete === "function" ) { + complete.call( elem[ 0 ] ); } - if ( event.pageY - this.offset.click.top > containment[ 3 ] ) { - pageY = containment[ 3 ] + this.offset.click.top; + + if ( typeof next === "function" ) { + next(); } } - if ( o.grid ) { - - //Check for grid elements set to 0 to prevent divide by 0 error causing invalid - // argument errors in IE (see ticket #6950) - top = o.grid[ 1 ] ? this.originalPageY + Math.round( ( pageY - - this.originalPageY ) / o.grid[ 1 ] ) * o.grid[ 1 ] : this.originalPageY; - pageY = containment ? ( ( top - this.offset.click.top >= containment[ 1 ] || - top - this.offset.click.top > containment[ 3 ] ) ? - top : - ( ( top - this.offset.click.top >= containment[ 1 ] ) ? - top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : top; + // Override mode option on a per element basis, + // as toggle can be either show or hide depending on element state + args.mode = modes.shift(); - left = o.grid[ 0 ] ? this.originalPageX + - Math.round( ( pageX - this.originalPageX ) / o.grid[ 0 ] ) * o.grid[ 0 ] : - this.originalPageX; - pageX = containment ? ( ( left - this.offset.click.left >= containment[ 0 ] || - left - this.offset.click.left > containment[ 2 ] ) ? - left : - ( ( left - this.offset.click.left >= containment[ 0 ] ) ? - left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : left; - } + if ( $.uiBackCompat !== false && !defaultMode ) { + if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { - if ( o.axis === "y" ) { - pageX = this.originalPageX; - } + // Call the core method to track "olddisplay" properly + elem[ mode ](); + done(); + } else { + effectMethod.call( elem[ 0 ], args, done ); + } + } else { + if ( args.mode === "none" ) { - if ( o.axis === "x" ) { - pageY = this.originalPageY; + // Call the core method to track "olddisplay" properly + elem[ mode ](); + done(); + } else { + effectMethod.call( elem[ 0 ], args, cleanup ); + } } } - return { - top: ( - - // The absolute mouse position - pageY - - - // Click offset (relative to the element) - this.offset.click.top - - - // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.relative.top - - - // The offsetParent's offset without borders (offset + border) - this.offset.parent.top + - ( this.cssPosition === "fixed" ? - -this.offset.scroll.top : - ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) - ), - left: ( - - // The absolute mouse position - pageX - + // Run prefilter on all elements first to ensure that + // any showing or hiding happens before placeholder creation, + // which ensures that any layout changes are correctly captured. + return queue === false ? + this.each( prefilter ).each( run ) : + this.queue( queueName, prefilter ).queue( queueName, run ); + }, - // Click offset (relative to the element) - this.offset.click.left - + show: ( function( orig ) { + return function( option ) { + if ( standardAnimationOption( option ) ) { + return orig.apply( this, arguments ); + } else { + var args = _normalizeArguments.apply( this, arguments ); + args.mode = "show"; + return this.effect.call( this, args ); + } + }; + } )( $.fn.show ), - // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.relative.left - + hide: ( function( orig ) { + return function( option ) { + if ( standardAnimationOption( option ) ) { + return orig.apply( this, arguments ); + } else { + var args = _normalizeArguments.apply( this, arguments ); + args.mode = "hide"; + return this.effect.call( this, args ); + } + }; + } )( $.fn.hide ), - // The offsetParent's offset without borders (offset + border) - this.offset.parent.left + - ( this.cssPosition === "fixed" ? - -this.offset.scroll.left : - ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) - ) + toggle: ( function( orig ) { + return function( option ) { + if ( standardAnimationOption( option ) || typeof option === "boolean" ) { + return orig.apply( this, arguments ); + } else { + var args = _normalizeArguments.apply( this, arguments ); + args.mode = "toggle"; + return this.effect.call( this, args ); + } }; + } )( $.fn.toggle ), + cssUnit: function( key ) { + var style = this.css( key ), + val = []; + + $.each( [ "em", "px", "%", "pt" ], function( i, unit ) { + if ( style.indexOf( unit ) > 0 ) { + val = [ parseFloat( style ), unit ]; + } + } ); + return val; }, - _clear: function() { - this._removeClass( this.helper, "ui-draggable-dragging" ); - if ( this.helper[ 0 ] !== this.element[ 0 ] && !this.cancelHelperRemoval ) { - this.helper.remove(); - } - this.helper = null; - this.cancelHelperRemoval = false; - if ( this.destroyOnClear ) { - this.destroy(); + cssClip: function( clipObj ) { + if ( clipObj ) { + return this.css( "clip", "rect(" + clipObj.top + "px " + clipObj.right + "px " + + clipObj.bottom + "px " + clipObj.left + "px)" ); } + return parseClip( this.css( "clip" ), this ); }, - // From now on bulk stuff - mainly helpers - - _trigger: function( type, event, ui ) { - ui = ui || this._uiHash(); - $.ui.plugin.call( this, type, [ event, ui, this ], true ); + transfer: function( options, done ) { + var element = $( this ), + target = $( options.to ), + targetFixed = target.css( "position" ) === "fixed", + body = $( "body" ), + fixTop = targetFixed ? body.scrollTop() : 0, + fixLeft = targetFixed ? body.scrollLeft() : 0, + endPosition = target.offset(), + animation = { + top: endPosition.top - fixTop, + left: endPosition.left - fixLeft, + height: target.innerHeight(), + width: target.innerWidth() + }, + startPosition = element.offset(), + transfer = $( "<div class='ui-effects-transfer'></div>" ); - // Absolute position and offset (see #6884 ) have to be recalculated after plugins - if ( /^(drag|start|stop)/.test( type ) ) { - this.positionAbs = this._convertPositionTo( "absolute" ); - ui.offset = this.positionAbs; - } - return $.Widget.prototype._trigger.call( this, type, event, ui ); - }, + transfer + .appendTo( "body" ) + .addClass( options.className ) + .css( { + top: startPosition.top - fixTop, + left: startPosition.left - fixLeft, + height: element.innerHeight(), + width: element.innerWidth(), + position: targetFixed ? "fixed" : "absolute" + } ) + .animate( animation, options.duration, options.easing, function() { + transfer.remove(); + if ( typeof done === "function" ) { + done(); + } + } ); + } +} ); - plugins: {}, +function parseClip( str, element ) { + var outerWidth = element.outerWidth(), + outerHeight = element.outerHeight(), + clipRegex = /^rect\((-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto)\)$/, + values = clipRegex.exec( str ) || [ "", 0, outerWidth, outerHeight, 0 ]; - _uiHash: function() { return { - helper: this.helper, - position: this.position, - originalPosition: this.originalPosition, - offset: this.positionAbs + top: parseFloat( values[ 1 ] ) || 0, + right: values[ 2 ] === "auto" ? outerWidth : parseFloat( values[ 2 ] ), + bottom: values[ 3 ] === "auto" ? outerHeight : parseFloat( values[ 3 ] ), + left: parseFloat( values[ 4 ] ) || 0 }; +} + +$.fx.step.clip = function( fx ) { + if ( !fx.clipInit ) { + fx.start = $( fx.elem ).cssClip(); + if ( typeof fx.end === "string" ) { + fx.end = parseClip( fx.end, fx.elem ); + } + fx.clipInit = true; } -} ); + $( fx.elem ).cssClip( { + top: fx.pos * ( fx.end.top - fx.start.top ) + fx.start.top, + right: fx.pos * ( fx.end.right - fx.start.right ) + fx.start.right, + bottom: fx.pos * ( fx.end.bottom - fx.start.bottom ) + fx.start.bottom, + left: fx.pos * ( fx.end.left - fx.start.left ) + fx.start.left + } ); +}; -$.ui.plugin.add( "draggable", "connectToSortable", { - start: function( event, ui, draggable ) { - var uiSortable = $.extend( {}, ui, { - item: draggable.element - } ); +} )(); - draggable.sortables = []; - $( draggable.options.connectToSortable ).each( function() { - var sortable = $( this ).sortable( "instance" ); +/******************************************************************************/ +/*********************************** EASING ***********************************/ +/******************************************************************************/ - if ( sortable && !sortable.options.disabled ) { - draggable.sortables.push( sortable ); +( function() { - // RefreshPositions is called at drag start to refresh the containerCache - // which is used in drag. This ensures it's initialized and synchronized - // with any changes that might have happened on the page since initialization. - sortable.refreshPositions(); - sortable._trigger( "activate", event, uiSortable ); - } - } ); - }, - stop: function( event, ui, draggable ) { - var uiSortable = $.extend( {}, ui, { - item: draggable.element - } ); +// Based on easing equations from Robert Penner (http://www.robertpenner.com/easing) - draggable.cancelHelperRemoval = false; +var baseEasings = {}; - $.each( draggable.sortables, function() { - var sortable = this; +$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) { + baseEasings[ name ] = function( p ) { + return Math.pow( p, i + 2 ); + }; +} ); - if ( sortable.isOver ) { - sortable.isOver = 0; +$.extend( baseEasings, { + Sine: function( p ) { + return 1 - Math.cos( p * Math.PI / 2 ); + }, + Circ: function( p ) { + return 1 - Math.sqrt( 1 - p * p ); + }, + Elastic: function( p ) { + return p === 0 || p === 1 ? p : + -Math.pow( 2, 8 * ( p - 1 ) ) * Math.sin( ( ( p - 1 ) * 80 - 7.5 ) * Math.PI / 15 ); + }, + Back: function( p ) { + return p * p * ( 3 * p - 2 ); + }, + Bounce: function( p ) { + var pow2, + bounce = 4; - // Allow this sortable to handle removing the helper - draggable.cancelHelperRemoval = true; - sortable.cancelHelperRemoval = false; + while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {} + return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 ); + } +} ); - // Use _storedCSS To restore properties in the sortable, - // as this also handles revert (#9675) since the draggable - // may have modified them in unexpected ways (#8809) - sortable._storedCSS = { - position: sortable.placeholder.css( "position" ), - top: sortable.placeholder.css( "top" ), - left: sortable.placeholder.css( "left" ) - }; +$.each( baseEasings, function( name, easeIn ) { + $.easing[ "easeIn" + name ] = easeIn; + $.easing[ "easeOut" + name ] = function( p ) { + return 1 - easeIn( 1 - p ); + }; + $.easing[ "easeInOut" + name ] = function( p ) { + return p < 0.5 ? + easeIn( p * 2 ) / 2 : + 1 - easeIn( p * -2 + 2 ) / 2; + }; +} ); - sortable._mouseStop( event ); +} )(); - // Once drag has ended, the sortable should return to using - // its original helper, not the shared helper from draggable - sortable.options.helper = sortable.options._helper; - } else { +var effect = $.effects; - // Prevent this Sortable from removing the helper. - // However, don't set the draggable to remove the helper - // either as another connected Sortable may yet handle the removal. - sortable.cancelHelperRemoval = true; - - sortable._trigger( "deactivate", event, uiSortable ); - } - } ); - }, - drag: function( event, ui, draggable ) { - $.each( draggable.sortables, function() { - var innermostIntersecting = false, - sortable = this; - // Copy over variables that sortable's _intersectsWith uses - sortable.positionAbs = draggable.positionAbs; - sortable.helperProportions = draggable.helperProportions; - sortable.offset.click = draggable.offset.click; +/*! + * jQuery UI Effects Blind 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ - if ( sortable._intersectsWith( sortable.containerCache ) ) { - innermostIntersecting = true; +//>>label: Blind Effect +//>>group: Effects +//>>description: Blinds the element. +//>>docs: http://api.jqueryui.com/blind-effect/ +//>>demos: http://jqueryui.com/effect/ - $.each( draggable.sortables, function() { - // Copy over variables that sortable's _intersectsWith uses - this.positionAbs = draggable.positionAbs; - this.helperProportions = draggable.helperProportions; - this.offset.click = draggable.offset.click; +var effectsEffectBlind = $.effects.define( "blind", "hide", function( options, done ) { + var map = { + up: [ "bottom", "top" ], + vertical: [ "bottom", "top" ], + down: [ "top", "bottom" ], + left: [ "right", "left" ], + horizontal: [ "right", "left" ], + right: [ "left", "right" ] + }, + element = $( this ), + direction = options.direction || "up", + start = element.cssClip(), + animate = { clip: $.extend( {}, start ) }, + placeholder = $.effects.createPlaceholder( element ); - if ( this !== sortable && - this._intersectsWith( this.containerCache ) && - $.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) { - innermostIntersecting = false; - } + animate.clip[ map[ direction ][ 0 ] ] = animate.clip[ map[ direction ][ 1 ] ]; - return innermostIntersecting; - } ); - } + if ( options.mode === "show" ) { + element.cssClip( animate.clip ); + if ( placeholder ) { + placeholder.css( $.effects.clipToBox( animate ) ); + } - if ( innermostIntersecting ) { + animate.clip = start; + } - // If it intersects, we use a little isOver variable and set it once, - // so that the move-in stuff gets fired only once. - if ( !sortable.isOver ) { - sortable.isOver = 1; + if ( placeholder ) { + placeholder.animate( $.effects.clipToBox( animate ), options.duration, options.easing ); + } - // Store draggable's parent in case we need to reappend to it later. - draggable._parent = ui.helper.parent(); + element.animate( animate, { + queue: false, + duration: options.duration, + easing: options.easing, + complete: done + } ); +} ); - sortable.currentItem = ui.helper - .appendTo( sortable.element ) - .data( "ui-sortable-item", true ); - // Store helper option to later restore it - sortable.options._helper = sortable.options.helper; +/*! + * jQuery UI Effects Bounce 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ - sortable.options.helper = function() { - return ui.helper[ 0 ]; - }; +//>>label: Bounce Effect +//>>group: Effects +//>>description: Bounces an element horizontally or vertically n times. +//>>docs: http://api.jqueryui.com/bounce-effect/ +//>>demos: http://jqueryui.com/effect/ - // Fire the start events of the sortable with our passed browser event, - // and our own helper (so it doesn't create a new one) - event.target = sortable.currentItem[ 0 ]; - sortable._mouseCapture( event, true ); - sortable._mouseStart( event, true, true ); - // Because the browser event is way off the new appended portlet, - // modify necessary variables to reflect the changes - sortable.offset.click.top = draggable.offset.click.top; - sortable.offset.click.left = draggable.offset.click.left; - sortable.offset.parent.left -= draggable.offset.parent.left - - sortable.offset.parent.left; - sortable.offset.parent.top -= draggable.offset.parent.top - - sortable.offset.parent.top; +var effectsEffectBounce = $.effects.define( "bounce", function( options, done ) { + var upAnim, downAnim, refValue, + element = $( this ), - draggable._trigger( "toSortable", event ); + // Defaults: + mode = options.mode, + hide = mode === "hide", + show = mode === "show", + direction = options.direction || "up", + distance = options.distance, + times = options.times || 5, - // Inform draggable that the helper is in a valid drop zone, - // used solely in the revert option to handle "valid/invalid". - draggable.dropped = sortable.element; + // Number of internal animations + anims = times * 2 + ( show || hide ? 1 : 0 ), + speed = options.duration / anims, + easing = options.easing, - // Need to refreshPositions of all sortables in the case that - // adding to one sortable changes the location of the other sortables (#9675) - $.each( draggable.sortables, function() { - this.refreshPositions(); - } ); + // Utility: + ref = ( direction === "up" || direction === "down" ) ? "top" : "left", + motion = ( direction === "up" || direction === "left" ), + i = 0, - // Hack so receive/update callbacks work (mostly) - draggable.currentItem = draggable.element; - sortable.fromOutside = draggable; - } + queuelen = element.queue().length; - if ( sortable.currentItem ) { - sortable._mouseDrag( event ); + $.effects.createPlaceholder( element ); - // Copy the sortable's position because the draggable's can potentially reflect - // a relative position, while sortable is always absolute, which the dragged - // element has now become. (#8809) - ui.position = sortable.position; - } - } else { + refValue = element.css( ref ); - // If it doesn't intersect with the sortable, and it intersected before, - // we fake the drag stop of the sortable, but make sure it doesn't remove - // the helper by using cancelHelperRemoval. - if ( sortable.isOver ) { + // Default distance for the BIGGEST bounce is the outer Distance / 3 + if ( !distance ) { + distance = element[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3; + } - sortable.isOver = 0; - sortable.cancelHelperRemoval = true; + if ( show ) { + downAnim = { opacity: 1 }; + downAnim[ ref ] = refValue; - // Calling sortable's mouseStop would trigger a revert, - // so revert must be temporarily false until after mouseStop is called. - sortable.options._revert = sortable.options.revert; - sortable.options.revert = false; + // If we are showing, force opacity 0 and set the initial position + // then do the "first" animation + element + .css( "opacity", 0 ) + .css( ref, motion ? -distance * 2 : distance * 2 ) + .animate( downAnim, speed, easing ); + } - sortable._trigger( "out", event, sortable._uiHash( sortable ) ); - sortable._mouseStop( event, true ); + // Start at the smallest distance if we are hiding + if ( hide ) { + distance = distance / Math.pow( 2, times - 1 ); + } - // Restore sortable behaviors that were modfied - // when the draggable entered the sortable area (#9481) - sortable.options.revert = sortable.options._revert; - sortable.options.helper = sortable.options._helper; + downAnim = {}; + downAnim[ ref ] = refValue; - if ( sortable.placeholder ) { - sortable.placeholder.remove(); - } + // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here + for ( ; i < times; i++ ) { + upAnim = {}; + upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; - // Restore and recalculate the draggable's offset considering the sortable - // may have modified them in unexpected ways. (#8809, #10669) - ui.helper.appendTo( draggable._parent ); - draggable._refreshOffsets( event ); - ui.position = draggable._generatePosition( event, true ); + element + .animate( upAnim, speed, easing ) + .animate( downAnim, speed, easing ); - draggable._trigger( "fromSortable", event ); + distance = hide ? distance * 2 : distance / 2; + } - // Inform draggable that the helper is no longer in a valid drop zone - draggable.dropped = false; + // Last Bounce when Hiding + if ( hide ) { + upAnim = { opacity: 0 }; + upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; - // Need to refreshPositions of all sortables just in case removing - // from one sortable changes the location of other sortables (#9675) - $.each( draggable.sortables, function() { - this.refreshPositions(); - } ); - } - } - } ); + element.animate( upAnim, speed, easing ); } -} ); -$.ui.plugin.add( "draggable", "cursor", { - start: function( event, ui, instance ) { - var t = $( "body" ), - o = instance.options; + element.queue( done ); - if ( t.css( "cursor" ) ) { - o._cursor = t.css( "cursor" ); - } - t.css( "cursor", o.cursor ); - }, - stop: function( event, ui, instance ) { - var o = instance.options; - if ( o._cursor ) { - $( "body" ).css( "cursor", o._cursor ); - } - } + $.effects.unshift( element, queuelen, anims + 1 ); } ); -$.ui.plugin.add( "draggable", "opacity", { - start: function( event, ui, instance ) { - var t = $( ui.helper ), - o = instance.options; - if ( t.css( "opacity" ) ) { - o._opacity = t.css( "opacity" ); - } - t.css( "opacity", o.opacity ); - }, - stop: function( event, ui, instance ) { - var o = instance.options; - if ( o._opacity ) { - $( ui.helper ).css( "opacity", o._opacity ); - } + +/*! + * jQuery UI Effects Clip 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: Clip Effect +//>>group: Effects +//>>description: Clips the element on and off like an old TV. +//>>docs: http://api.jqueryui.com/clip-effect/ +//>>demos: http://jqueryui.com/effect/ + + +var effectsEffectClip = $.effects.define( "clip", "hide", function( options, done ) { + var start, + animate = {}, + element = $( this ), + direction = options.direction || "vertical", + both = direction === "both", + horizontal = both || direction === "horizontal", + vertical = both || direction === "vertical"; + + start = element.cssClip(); + animate.clip = { + top: vertical ? ( start.bottom - start.top ) / 2 : start.top, + right: horizontal ? ( start.right - start.left ) / 2 : start.right, + bottom: vertical ? ( start.bottom - start.top ) / 2 : start.bottom, + left: horizontal ? ( start.right - start.left ) / 2 : start.left + }; + + $.effects.createPlaceholder( element ); + + if ( options.mode === "show" ) { + element.cssClip( animate.clip ); + animate.clip = start; } + + element.animate( animate, { + queue: false, + duration: options.duration, + easing: options.easing, + complete: done + } ); + } ); -$.ui.plugin.add( "draggable", "scroll", { - start: function( event, ui, i ) { - if ( !i.scrollParentNotHidden ) { - i.scrollParentNotHidden = i.helper.scrollParent( false ); - } - if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && - i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) { - i.overflowOffset = i.scrollParentNotHidden.offset(); - } - }, - drag: function( event, ui, i ) { +/*! + * jQuery UI Effects Drop 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ - var o = i.options, - scrolled = false, - scrollParent = i.scrollParentNotHidden[ 0 ], - document = i.document[ 0 ]; +//>>label: Drop Effect +//>>group: Effects +//>>description: Moves an element in one direction and hides it at the same time. +//>>docs: http://api.jqueryui.com/drop-effect/ +//>>demos: http://jqueryui.com/effect/ - if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) { - if ( !o.axis || o.axis !== "x" ) { - if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < - o.scrollSensitivity ) { - scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed; - } else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) { - scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed; - } - } - if ( !o.axis || o.axis !== "y" ) { - if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < - o.scrollSensitivity ) { - scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed; - } else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) { - scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed; - } - } +var effectsEffectDrop = $.effects.define( "drop", "hide", function( options, done ) { - } else { + var distance, + element = $( this ), + mode = options.mode, + show = mode === "show", + direction = options.direction || "left", + ref = ( direction === "up" || direction === "down" ) ? "top" : "left", + motion = ( direction === "up" || direction === "left" ) ? "-=" : "+=", + oppositeMotion = ( motion === "+=" ) ? "-=" : "+=", + animation = { + opacity: 0 + }; - if ( !o.axis || o.axis !== "x" ) { - if ( event.pageY - $( document ).scrollTop() < o.scrollSensitivity ) { - scrolled = $( document ).scrollTop( $( document ).scrollTop() - o.scrollSpeed ); - } else if ( $( window ).height() - ( event.pageY - $( document ).scrollTop() ) < - o.scrollSensitivity ) { - scrolled = $( document ).scrollTop( $( document ).scrollTop() + o.scrollSpeed ); - } - } + $.effects.createPlaceholder( element ); - if ( !o.axis || o.axis !== "y" ) { - if ( event.pageX - $( document ).scrollLeft() < o.scrollSensitivity ) { - scrolled = $( document ).scrollLeft( - $( document ).scrollLeft() - o.scrollSpeed - ); - } else if ( $( window ).width() - ( event.pageX - $( document ).scrollLeft() ) < - o.scrollSensitivity ) { - scrolled = $( document ).scrollLeft( - $( document ).scrollLeft() + o.scrollSpeed - ); - } - } + distance = options.distance || + element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2; - } + animation[ ref ] = motion + distance; - if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) { - $.ui.ddmanager.prepareOffsets( i, event ); - } + if ( show ) { + element.css( animation ); + animation[ ref ] = oppositeMotion + distance; + animation.opacity = 1; } + + // Animate + element.animate( animation, { + queue: false, + duration: options.duration, + easing: options.easing, + complete: done + } ); } ); -$.ui.plugin.add( "draggable", "snap", { - start: function( event, ui, i ) { - var o = i.options; +/*! + * jQuery UI Effects Explode 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ - i.snapElements = []; +//>>label: Explode Effect +//>>group: Effects +/* eslint-disable max-len */ +//>>description: Explodes an element in all directions into n pieces. Implodes an element to its original wholeness. +/* eslint-enable max-len */ +//>>docs: http://api.jqueryui.com/explode-effect/ +//>>demos: http://jqueryui.com/effect/ - $( o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap ) - .each( function() { - var $t = $( this ), - $o = $t.offset(); - if ( this !== i.element[ 0 ] ) { - i.snapElements.push( { - item: this, - width: $t.outerWidth(), height: $t.outerHeight(), - top: $o.top, left: $o.left - } ); - } - } ); - }, - drag: function( event, ui, inst ) { +var effectsEffectExplode = $.effects.define( "explode", "hide", function( options, done ) { - var ts, bs, ls, rs, l, r, t, b, i, first, - o = inst.options, - d = o.snapTolerance, - x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width, - y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height; + var i, j, left, top, mx, my, + rows = options.pieces ? Math.round( Math.sqrt( options.pieces ) ) : 3, + cells = rows, + element = $( this ), + mode = options.mode, + show = mode === "show", - for ( i = inst.snapElements.length - 1; i >= 0; i-- ) { + // Show and then visibility:hidden the element before calculating offset + offset = element.show().css( "visibility", "hidden" ).offset(), - l = inst.snapElements[ i ].left - inst.margins.left; - r = l + inst.snapElements[ i ].width; - t = inst.snapElements[ i ].top - inst.margins.top; - b = t + inst.snapElements[ i ].height; + // Width and height of a piece + width = Math.ceil( element.outerWidth() / cells ), + height = Math.ceil( element.outerHeight() / rows ), + pieces = []; - if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || - !$.contains( inst.snapElements[ i ].item.ownerDocument, - inst.snapElements[ i ].item ) ) { - if ( inst.snapElements[ i ].snapping ) { - if ( inst.options.snap.release ) { - inst.options.snap.release.call( - inst.element, - event, - $.extend( inst._uiHash(), { snapItem: inst.snapElements[ i ].item } ) - ); - } - } - inst.snapElements[ i ].snapping = false; - continue; - } + // Children animate complete: + function childComplete() { + pieces.push( this ); + if ( pieces.length === rows * cells ) { + animComplete(); + } + } - if ( o.snapMode !== "inner" ) { - ts = Math.abs( t - y2 ) <= d; - bs = Math.abs( b - y1 ) <= d; - ls = Math.abs( l - x2 ) <= d; - rs = Math.abs( r - x1 ) <= d; - if ( ts ) { - ui.position.top = inst._convertPositionTo( "relative", { - top: t - inst.helperProportions.height, - left: 0 - } ).top; - } - if ( bs ) { - ui.position.top = inst._convertPositionTo( "relative", { - top: b, - left: 0 - } ).top; - } - if ( ls ) { - ui.position.left = inst._convertPositionTo( "relative", { - top: 0, - left: l - inst.helperProportions.width - } ).left; - } - if ( rs ) { - ui.position.left = inst._convertPositionTo( "relative", { - top: 0, - left: r - } ).left; - } - } + // Clone the element for each row and cell. + for ( i = 0; i < rows; i++ ) { // ===> + top = offset.top + i * height; + my = i - ( rows - 1 ) / 2; - first = ( ts || bs || ls || rs ); - - if ( o.snapMode !== "outer" ) { - ts = Math.abs( t - y1 ) <= d; - bs = Math.abs( b - y2 ) <= d; - ls = Math.abs( l - x1 ) <= d; - rs = Math.abs( r - x2 ) <= d; - if ( ts ) { - ui.position.top = inst._convertPositionTo( "relative", { - top: t, - left: 0 - } ).top; - } - if ( bs ) { - ui.position.top = inst._convertPositionTo( "relative", { - top: b - inst.helperProportions.height, - left: 0 - } ).top; - } - if ( ls ) { - ui.position.left = inst._convertPositionTo( "relative", { - top: 0, - left: l - } ).left; - } - if ( rs ) { - ui.position.left = inst._convertPositionTo( "relative", { - top: 0, - left: r - inst.helperProportions.width - } ).left; - } - } + for ( j = 0; j < cells; j++ ) { // ||| + left = offset.left + j * width; + mx = j - ( cells - 1 ) / 2; - if ( !inst.snapElements[ i ].snapping && ( ts || bs || ls || rs || first ) ) { - if ( inst.options.snap.snap ) { - inst.options.snap.snap.call( - inst.element, - event, - $.extend( inst._uiHash(), { - snapItem: inst.snapElements[ i ].item - } ) ); - } - } - inst.snapElements[ i ].snapping = ( ts || bs || ls || rs || first ); + // Create a clone of the now hidden main element that will be absolute positioned + // within a wrapper div off the -left and -top equal to size of our pieces + element + .clone() + .appendTo( "body" ) + .wrap( "<div></div>" ) + .css( { + position: "absolute", + visibility: "visible", + left: -j * width, + top: -i * height + } ) + // Select the wrapper - make it overflow: hidden and absolute positioned based on + // where the original was located +left and +top equal to the size of pieces + .parent() + .addClass( "ui-effects-explode" ) + .css( { + position: "absolute", + overflow: "hidden", + width: width, + height: height, + left: left + ( show ? mx * width : 0 ), + top: top + ( show ? my * height : 0 ), + opacity: show ? 0 : 1 + } ) + .animate( { + left: left + ( show ? 0 : mx * width ), + top: top + ( show ? 0 : my * height ), + opacity: show ? 1 : 0 + }, options.duration || 500, options.easing, childComplete ); } + } + function animComplete() { + element.css( { + visibility: "visible" + } ); + $( pieces ).remove(); + done(); } } ); -$.ui.plugin.add( "draggable", "stack", { - start: function( event, ui, instance ) { - var min, - o = instance.options, - group = $.makeArray( $( o.stack ) ).sort( function( a, b ) { - return ( parseInt( $( a ).css( "zIndex" ), 10 ) || 0 ) - - ( parseInt( $( b ).css( "zIndex" ), 10 ) || 0 ); - } ); - if ( !group.length ) { - return; - } +/*! + * jQuery UI Effects Fade 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ - min = parseInt( $( group[ 0 ] ).css( "zIndex" ), 10 ) || 0; - $( group ).each( function( i ) { - $( this ).css( "zIndex", min + i ); - } ); - this.css( "zIndex", ( min + group.length ) ); - } -} ); +//>>label: Fade Effect +//>>group: Effects +//>>description: Fades the element. +//>>docs: http://api.jqueryui.com/fade-effect/ +//>>demos: http://jqueryui.com/effect/ -$.ui.plugin.add( "draggable", "zIndex", { - start: function( event, ui, instance ) { - var t = $( ui.helper ), - o = instance.options; - if ( t.css( "zIndex" ) ) { - o._zIndex = t.css( "zIndex" ); - } - t.css( "zIndex", o.zIndex ); - }, - stop: function( event, ui, instance ) { - var o = instance.options; +var effectsEffectFade = $.effects.define( "fade", "toggle", function( options, done ) { + var show = options.mode === "show"; - if ( o._zIndex ) { - $( ui.helper ).css( "zIndex", o._zIndex ); - } - } + $( this ) + .css( "opacity", show ? 0 : 1 ) + .animate( { + opacity: show ? 1 : 0 + }, { + queue: false, + duration: options.duration, + easing: options.easing, + complete: done + } ); } ); -var widgetsDraggable = $.ui.draggable; - /*! - * jQuery UI Droppable 1.13.1 + * jQuery UI Effects Fold 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -3271,482 +3389,408 @@ var widgetsDraggable = $.ui.draggable; * http://jquery.org/license */ -//>>label: Droppable -//>>group: Interactions -//>>description: Enables drop targets for draggable elements. -//>>docs: http://api.jqueryui.com/droppable/ -//>>demos: http://jqueryui.com/droppable/ - - -$.widget( "ui.droppable", { - version: "1.13.1", - widgetEventPrefix: "drop", - options: { - accept: "*", - addClasses: true, - greedy: false, - scope: "default", - tolerance: "intersect", +//>>label: Fold Effect +//>>group: Effects +//>>description: Folds an element first horizontally and then vertically. +//>>docs: http://api.jqueryui.com/fold-effect/ +//>>demos: http://jqueryui.com/effect/ - // Callbacks - activate: null, - deactivate: null, - drop: null, - out: null, - over: null - }, - _create: function() { - var proportions, - o = this.options, - accept = o.accept; +var effectsEffectFold = $.effects.define( "fold", "hide", function( options, done ) { - this.isover = false; - this.isout = true; + // Create element + var element = $( this ), + mode = options.mode, + show = mode === "show", + hide = mode === "hide", + size = options.size || 15, + percent = /([0-9]+)%/.exec( size ), + horizFirst = !!options.horizFirst, + ref = horizFirst ? [ "right", "bottom" ] : [ "bottom", "right" ], + duration = options.duration / 2, - this.accept = typeof accept === "function" ? accept : function( d ) { - return d.is( accept ); - }; + placeholder = $.effects.createPlaceholder( element ), - this.proportions = function( /* valueToWrite */ ) { - if ( arguments.length ) { + start = element.cssClip(), + animation1 = { clip: $.extend( {}, start ) }, + animation2 = { clip: $.extend( {}, start ) }, - // Store the droppable's proportions - proportions = arguments[ 0 ]; - } else { + distance = [ start[ ref[ 0 ] ], start[ ref[ 1 ] ] ], - // Retrieve or derive the droppable's proportions - return proportions ? - proportions : - proportions = { - width: this.element[ 0 ].offsetWidth, - height: this.element[ 0 ].offsetHeight - }; - } - }; + queuelen = element.queue().length; - this._addToManager( o.scope ); + if ( percent ) { + size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ]; + } + animation1.clip[ ref[ 0 ] ] = size; + animation2.clip[ ref[ 0 ] ] = size; + animation2.clip[ ref[ 1 ] ] = 0; - if ( o.addClasses ) { - this._addClass( "ui-droppable" ); + if ( show ) { + element.cssClip( animation2.clip ); + if ( placeholder ) { + placeholder.css( $.effects.clipToBox( animation2 ) ); } - }, + animation2.clip = start; + } - _addToManager: function( scope ) { + // Animate + element + .queue( function( next ) { + if ( placeholder ) { + placeholder + .animate( $.effects.clipToBox( animation1 ), duration, options.easing ) + .animate( $.effects.clipToBox( animation2 ), duration, options.easing ); + } - // Add the reference and positions to the manager - $.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || []; - $.ui.ddmanager.droppables[ scope ].push( this ); - }, + next(); + } ) + .animate( animation1, duration, options.easing ) + .animate( animation2, duration, options.easing ) + .queue( done ); - _splice: function( drop ) { - var i = 0; - for ( ; i < drop.length; i++ ) { - if ( drop[ i ] === this ) { - drop.splice( i, 1 ); - } - } - }, + $.effects.unshift( element, queuelen, 4 ); +} ); - _destroy: function() { - var drop = $.ui.ddmanager.droppables[ this.options.scope ]; - this._splice( drop ); - }, +/*! + * jQuery UI Effects Highlight 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ - _setOption: function( key, value ) { +//>>label: Highlight Effect +//>>group: Effects +//>>description: Highlights the background of an element in a defined color for a custom duration. +//>>docs: http://api.jqueryui.com/highlight-effect/ +//>>demos: http://jqueryui.com/effect/ - if ( key === "accept" ) { - this.accept = typeof value === "function" ? value : function( d ) { - return d.is( value ); - }; - } else if ( key === "scope" ) { - var drop = $.ui.ddmanager.droppables[ this.options.scope ]; - this._splice( drop ); - this._addToManager( value ); - } +var effectsEffectHighlight = $.effects.define( "highlight", "show", function( options, done ) { + var element = $( this ), + animation = { + backgroundColor: element.css( "backgroundColor" ) + }; - this._super( key, value ); - }, + if ( options.mode === "hide" ) { + animation.opacity = 0; + } - _activate: function( event ) { - var draggable = $.ui.ddmanager.current; + $.effects.saveStyle( element ); - this._addActiveClass(); - if ( draggable ) { - this._trigger( "activate", event, this.ui( draggable ) ); - } - }, + element + .css( { + backgroundImage: "none", + backgroundColor: options.color || "#ffff99" + } ) + .animate( animation, { + queue: false, + duration: options.duration, + easing: options.easing, + complete: done + } ); +} ); - _deactivate: function( event ) { - var draggable = $.ui.ddmanager.current; - this._removeActiveClass(); - if ( draggable ) { - this._trigger( "deactivate", event, this.ui( draggable ) ); - } - }, +/*! + * jQuery UI Effects Size 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ - _over: function( event ) { +//>>label: Size Effect +//>>group: Effects +//>>description: Resize an element to a specified width and height. +//>>docs: http://api.jqueryui.com/size-effect/ +//>>demos: http://jqueryui.com/effect/ - var draggable = $.ui.ddmanager.current; - // Bail if draggable and droppable are same element - if ( !draggable || ( draggable.currentItem || - draggable.element )[ 0 ] === this.element[ 0 ] ) { - return; - } +var effectsEffectSize = $.effects.define( "size", function( options, done ) { - if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || - draggable.element ) ) ) { - this._addHoverClass(); - this._trigger( "over", event, this.ui( draggable ) ); - } + // Create element + var baseline, factor, temp, + element = $( this ), - }, + // Copy for children + cProps = [ "fontSize" ], + vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ], + hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ], - _out: function( event ) { + // Set options + mode = options.mode, + restore = mode !== "effect", + scale = options.scale || "both", + origin = options.origin || [ "middle", "center" ], + position = element.css( "position" ), + pos = element.position(), + original = $.effects.scaledDimensions( element ), + from = options.from || original, + to = options.to || $.effects.scaledDimensions( element, 0 ); - var draggable = $.ui.ddmanager.current; + $.effects.createPlaceholder( element ); - // Bail if draggable and droppable are same element - if ( !draggable || ( draggable.currentItem || - draggable.element )[ 0 ] === this.element[ 0 ] ) { - return; - } + if ( mode === "show" ) { + temp = from; + from = to; + to = temp; + } - if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || - draggable.element ) ) ) { - this._removeHoverClass(); - this._trigger( "out", event, this.ui( draggable ) ); + // Set scaling factor + factor = { + from: { + y: from.height / original.height, + x: from.width / original.width + }, + to: { + y: to.height / original.height, + x: to.width / original.width } + }; - }, - - _drop: function( event, custom ) { - - var draggable = custom || $.ui.ddmanager.current, - childrenIntersection = false; + // Scale the css box + if ( scale === "box" || scale === "both" ) { - // Bail if draggable and droppable are same element - if ( !draggable || ( draggable.currentItem || - draggable.element )[ 0 ] === this.element[ 0 ] ) { - return false; + // Vertical props scaling + if ( factor.from.y !== factor.to.y ) { + from = $.effects.setTransition( element, vProps, factor.from.y, from ); + to = $.effects.setTransition( element, vProps, factor.to.y, to ); } - this.element - .find( ":data(ui-droppable)" ) - .not( ".ui-draggable-dragging" ) - .each( function() { - var inst = $( this ).droppable( "instance" ); - if ( - inst.options.greedy && - !inst.options.disabled && - inst.options.scope === draggable.options.scope && - inst.accept.call( - inst.element[ 0 ], ( draggable.currentItem || draggable.element ) - ) && - $.ui.intersect( - draggable, - $.extend( inst, { offset: inst.element.offset() } ), - inst.options.tolerance, event - ) - ) { - childrenIntersection = true; - return false; - } - } ); - if ( childrenIntersection ) { - return false; + // Horizontal props scaling + if ( factor.from.x !== factor.to.x ) { + from = $.effects.setTransition( element, hProps, factor.from.x, from ); + to = $.effects.setTransition( element, hProps, factor.to.x, to ); } + } - if ( this.accept.call( this.element[ 0 ], - ( draggable.currentItem || draggable.element ) ) ) { - this._removeActiveClass(); - this._removeHoverClass(); + // Scale the content + if ( scale === "content" || scale === "both" ) { - this._trigger( "drop", event, this.ui( draggable ) ); - return this.element; + // Vertical props scaling + if ( factor.from.y !== factor.to.y ) { + from = $.effects.setTransition( element, cProps, factor.from.y, from ); + to = $.effects.setTransition( element, cProps, factor.to.y, to ); } + } - return false; - - }, + // Adjust the position properties based on the provided origin points + if ( origin ) { + baseline = $.effects.getBaseline( origin, original ); + from.top = ( original.outerHeight - from.outerHeight ) * baseline.y + pos.top; + from.left = ( original.outerWidth - from.outerWidth ) * baseline.x + pos.left; + to.top = ( original.outerHeight - to.outerHeight ) * baseline.y + pos.top; + to.left = ( original.outerWidth - to.outerWidth ) * baseline.x + pos.left; + } + delete from.outerHeight; + delete from.outerWidth; + element.css( from ); - ui: function( c ) { - return { - draggable: ( c.currentItem || c.element ), - helper: c.helper, - position: c.position, - offset: c.positionAbs - }; - }, + // Animate the children if desired + if ( scale === "content" || scale === "both" ) { - // Extension points just to make backcompat sane and avoid duplicating logic - // TODO: Remove in 1.14 along with call to it below - _addHoverClass: function() { - this._addClass( "ui-droppable-hover" ); - }, + vProps = vProps.concat( [ "marginTop", "marginBottom" ] ).concat( cProps ); + hProps = hProps.concat( [ "marginLeft", "marginRight" ] ); - _removeHoverClass: function() { - this._removeClass( "ui-droppable-hover" ); - }, + // Only animate children with width attributes specified + // TODO: is this right? should we include anything with css width specified as well + element.find( "*[width]" ).each( function() { + var child = $( this ), + childOriginal = $.effects.scaledDimensions( child ), + childFrom = { + height: childOriginal.height * factor.from.y, + width: childOriginal.width * factor.from.x, + outerHeight: childOriginal.outerHeight * factor.from.y, + outerWidth: childOriginal.outerWidth * factor.from.x + }, + childTo = { + height: childOriginal.height * factor.to.y, + width: childOriginal.width * factor.to.x, + outerHeight: childOriginal.height * factor.to.y, + outerWidth: childOriginal.width * factor.to.x + }; - _addActiveClass: function() { - this._addClass( "ui-droppable-active" ); - }, + // Vertical props scaling + if ( factor.from.y !== factor.to.y ) { + childFrom = $.effects.setTransition( child, vProps, factor.from.y, childFrom ); + childTo = $.effects.setTransition( child, vProps, factor.to.y, childTo ); + } - _removeActiveClass: function() { - this._removeClass( "ui-droppable-active" ); - } -} ); + // Horizontal props scaling + if ( factor.from.x !== factor.to.x ) { + childFrom = $.effects.setTransition( child, hProps, factor.from.x, childFrom ); + childTo = $.effects.setTransition( child, hProps, factor.to.x, childTo ); + } -$.ui.intersect = ( function() { - function isOverAxis( x, reference, size ) { - return ( x >= reference ) && ( x < ( reference + size ) ); - } - - return function( draggable, droppable, toleranceMode, event ) { - - if ( !droppable.offset ) { - return false; - } - - var x1 = ( draggable.positionAbs || - draggable.position.absolute ).left + draggable.margins.left, - y1 = ( draggable.positionAbs || - draggable.position.absolute ).top + draggable.margins.top, - x2 = x1 + draggable.helperProportions.width, - y2 = y1 + draggable.helperProportions.height, - l = droppable.offset.left, - t = droppable.offset.top, - r = l + droppable.proportions().width, - b = t + droppable.proportions().height; - - switch ( toleranceMode ) { - case "fit": - return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b ); - case "intersect": - return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half - x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half - t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half - y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half - case "pointer": - return isOverAxis( event.pageY, t, droppable.proportions().height ) && - isOverAxis( event.pageX, l, droppable.proportions().width ); - case "touch": - return ( - ( y1 >= t && y1 <= b ) || // Top edge touching - ( y2 >= t && y2 <= b ) || // Bottom edge touching - ( y1 < t && y2 > b ) // Surrounded vertically - ) && ( - ( x1 >= l && x1 <= r ) || // Left edge touching - ( x2 >= l && x2 <= r ) || // Right edge touching - ( x1 < l && x2 > r ) // Surrounded horizontally - ); - default: - return false; - } - }; -} )(); + if ( restore ) { + $.effects.saveStyle( child ); + } -/* - This manager tracks offsets of draggables and droppables -*/ -$.ui.ddmanager = { - current: null, - droppables: { "default": [] }, - prepareOffsets: function( t, event ) { + // Animate children + child.css( childFrom ); + child.animate( childTo, options.duration, options.easing, function() { - var i, j, - m = $.ui.ddmanager.droppables[ t.options.scope ] || [], - type = event ? event.type : null, // workaround for #2317 - list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack(); + // Restore children + if ( restore ) { + $.effects.restoreStyle( child ); + } + } ); + } ); + } - droppablesLoop: for ( i = 0; i < m.length; i++ ) { + // Animate + element.animate( to, { + queue: false, + duration: options.duration, + easing: options.easing, + complete: function() { - // No disabled and non-accepted - if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ], - ( t.currentItem || t.element ) ) ) ) { - continue; - } + var offset = element.offset(); - // Filter out elements in the current dragged item - for ( j = 0; j < list.length; j++ ) { - if ( list[ j ] === m[ i ].element[ 0 ] ) { - m[ i ].proportions().height = 0; - continue droppablesLoop; - } + if ( to.opacity === 0 ) { + element.css( "opacity", from.opacity ); } - m[ i ].visible = m[ i ].element.css( "display" ) !== "none"; - if ( !m[ i ].visible ) { - continue; - } + if ( !restore ) { + element + .css( "position", position === "static" ? "relative" : position ) + .offset( offset ); - // Activate the droppable if used directly from draggables - if ( type === "mousedown" ) { - m[ i ]._activate.call( m[ i ], event ); + // Need to save style here so that automatic style restoration + // doesn't restore to the original styles from before the animation. + $.effects.saveStyle( element ); } - m[ i ].offset = m[ i ].element.offset(); - m[ i ].proportions( { - width: m[ i ].element[ 0 ].offsetWidth, - height: m[ i ].element[ 0 ].offsetHeight - } ); - + done(); } + } ); - }, - drop: function( draggable, event ) { +} ); - var dropped = false; - // Create a copy of the droppables in case the list changes during the drop (#9116) - $.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() { +/*! + * jQuery UI Effects Scale 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ - if ( !this.options ) { - return; - } - if ( !this.options.disabled && this.visible && - $.ui.intersect( draggable, this, this.options.tolerance, event ) ) { - dropped = this._drop.call( this, event ) || dropped; - } +//>>label: Scale Effect +//>>group: Effects +//>>description: Grows or shrinks an element and its content. +//>>docs: http://api.jqueryui.com/scale-effect/ +//>>demos: http://jqueryui.com/effect/ - if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ], - ( draggable.currentItem || draggable.element ) ) ) { - this.isout = true; - this.isover = false; - this._deactivate.call( this, event ); - } - } ); - return dropped; +var effectsEffectScale = $.effects.define( "scale", function( options, done ) { - }, - dragStart: function( draggable, event ) { + // Create element + var el = $( this ), + mode = options.mode, + percent = parseInt( options.percent, 10 ) || + ( parseInt( options.percent, 10 ) === 0 ? 0 : ( mode !== "effect" ? 0 : 100 ) ), - // Listen for scrolling so that if the dragging causes scrolling the position of the - // droppables can be recalculated (see #5003) - draggable.element.parentsUntil( "body" ).on( "scroll.droppable", function() { - if ( !draggable.options.refreshPositions ) { - $.ui.ddmanager.prepareOffsets( draggable, event ); - } - } ); - }, - drag: function( draggable, event ) { + newOptions = $.extend( true, { + from: $.effects.scaledDimensions( el ), + to: $.effects.scaledDimensions( el, percent, options.direction || "both" ), + origin: options.origin || [ "middle", "center" ] + }, options ); - // If you have a highly dynamic page, you might try this option. It renders positions - // every time you move the mouse. - if ( draggable.options.refreshPositions ) { - $.ui.ddmanager.prepareOffsets( draggable, event ); - } + // Fade option to support puff + if ( options.fade ) { + newOptions.from.opacity = 1; + newOptions.to.opacity = 0; + } - // Run through all droppables and check their positions based on specific tolerance options - $.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() { + $.effects.effect.size.call( this, newOptions, done ); +} ); - if ( this.options.disabled || this.greedyChild || !this.visible ) { - return; - } - var parentInstance, scope, parent, - intersects = $.ui.intersect( draggable, this, this.options.tolerance, event ), - c = !intersects && this.isover ? - "isout" : - ( intersects && !this.isover ? "isover" : null ); - if ( !c ) { - return; - } +/*! + * jQuery UI Effects Puff 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ - if ( this.options.greedy ) { +//>>label: Puff Effect +//>>group: Effects +//>>description: Creates a puff effect by scaling the element up and hiding it at the same time. +//>>docs: http://api.jqueryui.com/puff-effect/ +//>>demos: http://jqueryui.com/effect/ - // find droppable parents with same scope - scope = this.options.scope; - parent = this.element.parents( ":data(ui-droppable)" ).filter( function() { - return $( this ).droppable( "instance" ).options.scope === scope; - } ); - if ( parent.length ) { - parentInstance = $( parent[ 0 ] ).droppable( "instance" ); - parentInstance.greedyChild = ( c === "isover" ); - } - } +var effectsEffectPuff = $.effects.define( "puff", "hide", function( options, done ) { + var newOptions = $.extend( true, {}, options, { + fade: true, + percent: parseInt( options.percent, 10 ) || 150 + } ); - // We just moved into a greedy child - if ( parentInstance && c === "isover" ) { - parentInstance.isover = false; - parentInstance.isout = true; - parentInstance._out.call( parentInstance, event ); - } + $.effects.effect.scale.call( this, newOptions, done ); +} ); - this[ c ] = true; - this[ c === "isout" ? "isover" : "isout" ] = false; - this[ c === "isover" ? "_over" : "_out" ].call( this, event ); - // We just moved out of a greedy child - if ( parentInstance && c === "isout" ) { - parentInstance.isout = false; - parentInstance.isover = true; - parentInstance._over.call( parentInstance, event ); - } - } ); +/*! + * jQuery UI Effects Pulsate 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ - }, - dragStop: function( draggable, event ) { - draggable.element.parentsUntil( "body" ).off( "scroll.droppable" ); +//>>label: Pulsate Effect +//>>group: Effects +//>>description: Pulsates an element n times by changing the opacity to zero and back. +//>>docs: http://api.jqueryui.com/pulsate-effect/ +//>>demos: http://jqueryui.com/effect/ - // Call prepareOffsets one final time since IE does not fire return scroll events when - // overflow was caused by drag (see #5003) - if ( !draggable.options.refreshPositions ) { - $.ui.ddmanager.prepareOffsets( draggable, event ); - } + +var effectsEffectPulsate = $.effects.define( "pulsate", "show", function( options, done ) { + var element = $( this ), + mode = options.mode, + show = mode === "show", + hide = mode === "hide", + showhide = show || hide, + + // Showing or hiding leaves off the "last" animation + anims = ( ( options.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ), + duration = options.duration / anims, + animateTo = 0, + i = 1, + queuelen = element.queue().length; + + if ( show || !element.is( ":visible" ) ) { + element.css( "opacity", 0 ).show(); + animateTo = 1; } -}; -// DEPRECATED -// TODO: switch return back to widget declaration at top of file when this is removed -if ( $.uiBackCompat !== false ) { + // Anims - 1 opacity "toggles" + for ( ; i < anims; i++ ) { + element.animate( { opacity: animateTo }, duration, options.easing ); + animateTo = 1 - animateTo; + } - // Backcompat for activeClass and hoverClass options - $.widget( "ui.droppable", $.ui.droppable, { - options: { - hoverClass: false, - activeClass: false - }, - _addActiveClass: function() { - this._super(); - if ( this.options.activeClass ) { - this.element.addClass( this.options.activeClass ); - } - }, - _removeActiveClass: function() { - this._super(); - if ( this.options.activeClass ) { - this.element.removeClass( this.options.activeClass ); - } - }, - _addHoverClass: function() { - this._super(); - if ( this.options.hoverClass ) { - this.element.addClass( this.options.hoverClass ); - } - }, - _removeHoverClass: function() { - this._super(); - if ( this.options.hoverClass ) { - this.element.removeClass( this.options.hoverClass ); - } - } - } ); -} + element.animate( { opacity: animateTo }, duration, options.easing ); -var widgetsDroppable = $.ui.droppable; + element.queue( done ); + + $.effects.unshift( element, queuelen, anims + 1 ); +} ); /*! - * jQuery UI Resizable 1.13.1 + * jQuery UI Effects Shake 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -3754,1197 +3798,1181 @@ var widgetsDroppable = $.ui.droppable; * http://jquery.org/license */ -//>>label: Resizable -//>>group: Interactions -//>>description: Enables resize functionality for any element. -//>>docs: http://api.jqueryui.com/resizable/ -//>>demos: http://jqueryui.com/resizable/ -//>>css.structure: ../../themes/base/core.css -//>>css.structure: ../../themes/base/resizable.css -//>>css.theme: ../../themes/base/theme.css +//>>label: Shake Effect +//>>group: Effects +//>>description: Shakes an element horizontally or vertically n times. +//>>docs: http://api.jqueryui.com/shake-effect/ +//>>demos: http://jqueryui.com/effect/ -$.widget( "ui.resizable", $.ui.mouse, { - version: "1.13.1", - widgetEventPrefix: "resize", - options: { - alsoResize: false, - animate: false, - animateDuration: "slow", - animateEasing: "swing", - aspectRatio: false, - autoHide: false, - classes: { - "ui-resizable-se": "ui-icon ui-icon-gripsmall-diagonal-se" - }, - containment: false, - ghost: false, - grid: false, - handles: "e,s,se", - helper: false, - maxHeight: null, - maxWidth: null, - minHeight: 10, - minWidth: 10, +var effectsEffectShake = $.effects.define( "shake", function( options, done ) { - // See #7960 - zIndex: 90, + var i = 1, + element = $( this ), + direction = options.direction || "left", + distance = options.distance || 20, + times = options.times || 3, + anims = times * 2 + 1, + speed = Math.round( options.duration / anims ), + ref = ( direction === "up" || direction === "down" ) ? "top" : "left", + positiveMotion = ( direction === "up" || direction === "left" ), + animation = {}, + animation1 = {}, + animation2 = {}, - // Callbacks - resize: null, - start: null, - stop: null - }, + queuelen = element.queue().length; - _num: function( value ) { - return parseFloat( value ) || 0; - }, + $.effects.createPlaceholder( element ); - _isNumber: function( value ) { - return !isNaN( parseFloat( value ) ); - }, + // Animation + animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance; + animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2; + animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2; - _hasScroll: function( el, a ) { + // Animate + element.animate( animation, speed, options.easing ); - if ( $( el ).css( "overflow" ) === "hidden" ) { - return false; - } + // Shakes + for ( ; i < times; i++ ) { + element + .animate( animation1, speed, options.easing ) + .animate( animation2, speed, options.easing ); + } - var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop", - has = false; + element + .animate( animation1, speed, options.easing ) + .animate( animation, speed / 2, options.easing ) + .queue( done ); - if ( el[ scroll ] > 0 ) { - return true; - } + $.effects.unshift( element, queuelen, anims + 1 ); +} ); - // TODO: determine which cases actually cause this to happen - // if the element doesn't have the scroll set, see if it's possible to - // set the scroll - try { - el[ scroll ] = 1; - has = ( el[ scroll ] > 0 ); - el[ scroll ] = 0; - } catch ( e ) { - // `el` might be a string, then setting `scroll` will throw - // an error in strict mode; ignore it. - } - return has; - }, +/*! + * jQuery UI Effects Slide 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ - _create: function() { +//>>label: Slide Effect +//>>group: Effects +//>>description: Slides an element in and out of the viewport. +//>>docs: http://api.jqueryui.com/slide-effect/ +//>>demos: http://jqueryui.com/effect/ - var margins, - o = this.options, - that = this; - this._addClass( "ui-resizable" ); - $.extend( this, { - _aspectRatio: !!( o.aspectRatio ), - aspectRatio: o.aspectRatio, - originalElement: this.element, - _proportionallyResizeElements: [], - _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null - } ); +var effectsEffectSlide = $.effects.define( "slide", "show", function( options, done ) { + var startClip, startRef, + element = $( this ), + map = { + up: [ "bottom", "top" ], + down: [ "top", "bottom" ], + left: [ "right", "left" ], + right: [ "left", "right" ] + }, + mode = options.mode, + direction = options.direction || "left", + ref = ( direction === "up" || direction === "down" ) ? "top" : "left", + positiveMotion = ( direction === "up" || direction === "left" ), + distance = options.distance || + element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ), + animation = {}; - // Wrap the element if it cannot hold child nodes - if ( this.element[ 0 ].nodeName.match( /^(canvas|textarea|input|select|button|img)$/i ) ) { + $.effects.createPlaceholder( element ); - this.element.wrap( - $( "<div class='ui-wrapper'></div>" ).css( { - overflow: "hidden", - position: this.element.css( "position" ), - width: this.element.outerWidth(), - height: this.element.outerHeight(), - top: this.element.css( "top" ), - left: this.element.css( "left" ) - } ) - ); + startClip = element.cssClip(); + startRef = element.position()[ ref ]; - this.element = this.element.parent().data( - "ui-resizable", this.element.resizable( "instance" ) - ); + // Define hide animation + animation[ ref ] = ( positiveMotion ? -1 : 1 ) * distance + startRef; + animation.clip = element.cssClip(); + animation.clip[ map[ direction ][ 1 ] ] = animation.clip[ map[ direction ][ 0 ] ]; - this.elementIsWrapper = true; + // Reverse the animation if we're showing + if ( mode === "show" ) { + element.cssClip( animation.clip ); + element.css( ref, animation[ ref ] ); + animation.clip = startClip; + animation[ ref ] = startRef; + } - margins = { - marginTop: this.originalElement.css( "marginTop" ), - marginRight: this.originalElement.css( "marginRight" ), - marginBottom: this.originalElement.css( "marginBottom" ), - marginLeft: this.originalElement.css( "marginLeft" ) - }; + // Actually animate + element.animate( animation, { + queue: false, + duration: options.duration, + easing: options.easing, + complete: done + } ); +} ); - this.element.css( margins ); - this.originalElement.css( "margin", 0 ); - - // support: Safari - // Prevent Safari textarea resize - this.originalResizeStyle = this.originalElement.css( "resize" ); - this.originalElement.css( "resize", "none" ); - this._proportionallyResizeElements.push( this.originalElement.css( { - position: "static", - zoom: 1, - display: "block" - } ) ); +/*! + * jQuery UI Effects Transfer 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ - // Support: IE9 - // avoid IE jump (hard set the margin) - this.originalElement.css( margins ); +//>>label: Transfer Effect +//>>group: Effects +//>>description: Displays a transfer effect from one element to another. +//>>docs: http://api.jqueryui.com/transfer-effect/ +//>>demos: http://jqueryui.com/effect/ - this._proportionallyResize(); - } - this._setupHandles(); +var effect; +if ( $.uiBackCompat !== false ) { + effect = $.effects.define( "transfer", function( options, done ) { + $( this ).transfer( options, done ); + } ); +} +var effectsEffectTransfer = effect; - if ( o.autoHide ) { - $( this.element ) - .on( "mouseenter", function() { - if ( o.disabled ) { - return; - } - that._removeClass( "ui-resizable-autohide" ); - that._handles.show(); - } ) - .on( "mouseleave", function() { - if ( o.disabled ) { - return; - } - if ( !that.resizing ) { - that._addClass( "ui-resizable-autohide" ); - that._handles.hide(); - } - } ); - } - this._mouseInit(); - }, +/*! + * jQuery UI Focusable 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ - _destroy: function() { +//>>label: :focusable Selector +//>>group: Core +//>>description: Selects elements which can be focused. +//>>docs: http://api.jqueryui.com/focusable-selector/ - this._mouseDestroy(); - this._addedHandles.remove(); - var wrapper, - _destroy = function( exp ) { - $( exp ) - .removeData( "resizable" ) - .removeData( "ui-resizable" ) - .off( ".resizable" ); - }; +// Selectors +$.ui.focusable = function( element, hasTabindex ) { + var map, mapName, img, focusableIfVisible, fieldset, + nodeName = element.nodeName.toLowerCase(); - // TODO: Unwrap at same DOM position - if ( this.elementIsWrapper ) { - _destroy( this.element ); - wrapper = this.element; - this.originalElement.css( { - position: wrapper.css( "position" ), - width: wrapper.outerWidth(), - height: wrapper.outerHeight(), - top: wrapper.css( "top" ), - left: wrapper.css( "left" ) - } ).insertAfter( wrapper ); - wrapper.remove(); + if ( "area" === nodeName ) { + map = element.parentNode; + mapName = map.name; + if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { + return false; } + img = $( "img[usemap='#" + mapName + "']" ); + return img.length > 0 && img.is( ":visible" ); + } - this.originalElement.css( "resize", this.originalResizeStyle ); - _destroy( this.originalElement ); - - return this; - }, + if ( /^(input|select|textarea|button|object)$/.test( nodeName ) ) { + focusableIfVisible = !element.disabled; - _setOption: function( key, value ) { - this._super( key, value ); + if ( focusableIfVisible ) { - switch ( key ) { - case "handles": - this._removeHandles(); - this._setupHandles(); - break; - case "aspectRatio": - this._aspectRatio = !!value; - break; - default: - break; + // Form controls within a disabled fieldset are disabled. + // However, controls within the fieldset's legend do not get disabled. + // Since controls generally aren't placed inside legends, we skip + // this portion of the check. + fieldset = $( element ).closest( "fieldset" )[ 0 ]; + if ( fieldset ) { + focusableIfVisible = !fieldset.disabled; + } } - }, - - _setupHandles: function() { - var o = this.options, handle, i, n, hname, axis, that = this; - this.handles = o.handles || - ( !$( ".ui-resizable-handle", this.element ).length ? - "e,s,se" : { - n: ".ui-resizable-n", - e: ".ui-resizable-e", - s: ".ui-resizable-s", - w: ".ui-resizable-w", - se: ".ui-resizable-se", - sw: ".ui-resizable-sw", - ne: ".ui-resizable-ne", - nw: ".ui-resizable-nw" - } ); - - this._handles = $(); - this._addedHandles = $(); - if ( this.handles.constructor === String ) { + } else if ( "a" === nodeName ) { + focusableIfVisible = element.href || hasTabindex; + } else { + focusableIfVisible = hasTabindex; + } - if ( this.handles === "all" ) { - this.handles = "n,e,s,w,se,sw,ne,nw"; - } + return focusableIfVisible && $( element ).is( ":visible" ) && visible( $( element ) ); +}; - n = this.handles.split( "," ); - this.handles = {}; +// Support: IE 8 only +// IE 8 doesn't resolve inherit to visible/hidden for computed values +function visible( element ) { + var visibility = element.css( "visibility" ); + while ( visibility === "inherit" ) { + element = element.parent(); + visibility = element.css( "visibility" ); + } + return visibility === "visible"; +} - for ( i = 0; i < n.length; i++ ) { +$.extend( $.expr.pseudos, { + focusable: function( element ) { + return $.ui.focusable( element, $.attr( element, "tabindex" ) != null ); + } +} ); - handle = String.prototype.trim.call( n[ i ] ); - hname = "ui-resizable-" + handle; - axis = $( "<div>" ); - this._addClass( axis, "ui-resizable-handle " + hname ); +var focusable = $.ui.focusable; - axis.css( { zIndex: o.zIndex } ); - this.handles[ handle ] = ".ui-resizable-" + handle; - if ( !this.element.children( this.handles[ handle ] ).length ) { - this.element.append( axis ); - this._addedHandles = this._addedHandles.add( axis ); - } - } - } +// Support: IE8 Only +// IE8 does not support the form attribute and when it is supplied. It overwrites the form prop +// with a string, so we need to find the proper form. +var form = $.fn._form = function() { + return typeof this[ 0 ].form === "string" ? this.closest( "form" ) : $( this[ 0 ].form ); +}; - this._renderAxis = function( target ) { - var i, axis, padPos, padWrapper; +/*! + * jQuery UI Form Reset Mixin 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ - target = target || this.element; +//>>label: Form Reset Mixin +//>>group: Core +//>>description: Refresh input widgets when their form is reset +//>>docs: http://api.jqueryui.com/form-reset-mixin/ - for ( i in this.handles ) { - if ( this.handles[ i ].constructor === String ) { - this.handles[ i ] = this.element.children( this.handles[ i ] ).first().show(); - } else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) { - this.handles[ i ] = $( this.handles[ i ] ); - this._on( this.handles[ i ], { "mousedown": that._mouseDown } ); - } +var formResetMixin = $.ui.formResetMixin = { + _formResetHandler: function() { + var form = $( this ); - if ( this.elementIsWrapper && - this.originalElement[ 0 ] - .nodeName - .match( /^(textarea|input|select|button)$/i ) ) { - axis = $( this.handles[ i ], this.element ); + // Wait for the form reset to actually happen before refreshing + setTimeout( function() { + var instances = form.data( "ui-form-reset-instances" ); + $.each( instances, function() { + this.refresh(); + } ); + } ); + }, - padWrapper = /sw|ne|nw|se|n|s/.test( i ) ? - axis.outerHeight() : - axis.outerWidth(); + _bindFormResetHandler: function() { + this.form = this.element._form(); + if ( !this.form.length ) { + return; + } - padPos = [ "padding", - /ne|nw|n/.test( i ) ? "Top" : - /se|sw|s/.test( i ) ? "Bottom" : - /^e$/.test( i ) ? "Right" : "Left" ].join( "" ); + var instances = this.form.data( "ui-form-reset-instances" ) || []; + if ( !instances.length ) { - target.css( padPos, padWrapper ); + // We don't use _on() here because we use a single event handler per form + this.form.on( "reset.ui-form-reset", this._formResetHandler ); + } + instances.push( this ); + this.form.data( "ui-form-reset-instances", instances ); + }, - this._proportionallyResize(); - } + _unbindFormResetHandler: function() { + if ( !this.form.length ) { + return; + } - this._handles = this._handles.add( this.handles[ i ] ); - } - }; + var instances = this.form.data( "ui-form-reset-instances" ); + instances.splice( $.inArray( this, instances ), 1 ); + if ( instances.length ) { + this.form.data( "ui-form-reset-instances", instances ); + } else { + this.form + .removeData( "ui-form-reset-instances" ) + .off( "reset.ui-form-reset" ); + } + } +}; - // TODO: make renderAxis a prototype function - this._renderAxis( this.element ); - this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) ); - this._handles.disableSelection(); +/*! + * jQuery UI Support for jQuery core 1.8.x and newer 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + */ - this._handles.on( "mouseover", function() { - if ( !that.resizing ) { - if ( this.className ) { - axis = this.className.match( /ui-resizable-(se|sw|ne|nw|n|e|s|w)/i ); - } - that.axis = axis && axis[ 1 ] ? axis[ 1 ] : "se"; - } - } ); +//>>label: jQuery 1.8+ Support +//>>group: Core +//>>description: Support version 1.8.x and newer of jQuery core - if ( o.autoHide ) { - this._handles.hide(); - this._addClass( "ui-resizable-autohide" ); - } - }, - _removeHandles: function() { - this._addedHandles.remove(); - }, +// Support: jQuery 1.9.x or older +// $.expr[ ":" ] is deprecated. +if ( !$.expr.pseudos ) { + $.expr.pseudos = $.expr[ ":" ]; +} - _mouseCapture: function( event ) { - var i, handle, - capture = false; +// Support: jQuery 1.11.x or older +// $.unique has been renamed to $.uniqueSort +if ( !$.uniqueSort ) { + $.uniqueSort = $.unique; +} - for ( i in this.handles ) { - handle = $( this.handles[ i ] )[ 0 ]; - if ( handle === event.target || $.contains( handle, event.target ) ) { - capture = true; - } - } +// Support: jQuery 2.2.x or older. +// This method has been defined in jQuery 3.0.0. +// Code from https://github.com/jquery/jquery/blob/e539bac79e666bba95bba86d690b4e609dca2286/src/selector/escapeSelector.js +if ( !$.escapeSelector ) { - return !this.options.disabled && capture; - }, + // CSS string/identifier serialization + // https://drafts.csswg.org/cssom/#common-serializing-idioms + var rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g; - _mouseStart: function( event ) { + var fcssescape = function( ch, asCodePoint ) { + if ( asCodePoint ) { - var curleft, curtop, cursor, - o = this.options, - el = this.element; + // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER + if ( ch === "\0" ) { + return "\uFFFD"; + } - this.resizing = true; + // Control characters and (dependent upon position) numbers get escaped as code points + return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; + } - this._renderProxy(); + // Other potentially-special ASCII characters get backslash-escaped + return "\\" + ch; + }; - curleft = this._num( this.helper.css( "left" ) ); - curtop = this._num( this.helper.css( "top" ) ); + $.escapeSelector = function( sel ) { + return ( sel + "" ).replace( rcssescape, fcssescape ); + }; +} - if ( o.containment ) { - curleft += $( o.containment ).scrollLeft() || 0; - curtop += $( o.containment ).scrollTop() || 0; +// Support: jQuery 3.4.x or older +// These methods have been defined in jQuery 3.5.0. +if ( !$.fn.even || !$.fn.odd ) { + $.fn.extend( { + even: function() { + return this.filter( function( i ) { + return i % 2 === 0; + } ); + }, + odd: function() { + return this.filter( function( i ) { + return i % 2 === 1; + } ); } + } ); +} - this.offset = this.helper.offset(); - this.position = { left: curleft, top: curtop }; - - this.size = this._helper ? { - width: this.helper.width(), - height: this.helper.height() - } : { - width: el.width(), - height: el.height() - }; - - this.originalSize = this._helper ? { - width: el.outerWidth(), - height: el.outerHeight() - } : { - width: el.width(), - height: el.height() - }; +; +/*! + * jQuery UI Keycode 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ - this.sizeDiff = { - width: el.outerWidth() - el.width(), - height: el.outerHeight() - el.height() - }; +//>>label: Keycode +//>>group: Core +//>>description: Provide keycodes as keynames +//>>docs: http://api.jqueryui.com/jQuery.ui.keyCode/ - this.originalPosition = { left: curleft, top: curtop }; - this.originalMousePosition = { left: event.pageX, top: event.pageY }; - this.aspectRatio = ( typeof o.aspectRatio === "number" ) ? - o.aspectRatio : - ( ( this.originalSize.width / this.originalSize.height ) || 1 ); +var keycode = $.ui.keyCode = { + BACKSPACE: 8, + COMMA: 188, + DELETE: 46, + DOWN: 40, + END: 35, + ENTER: 13, + ESCAPE: 27, + HOME: 36, + LEFT: 37, + PAGE_DOWN: 34, + PAGE_UP: 33, + PERIOD: 190, + RIGHT: 39, + SPACE: 32, + TAB: 9, + UP: 38 +}; - cursor = $( ".ui-resizable-" + this.axis ).css( "cursor" ); - $( "body" ).css( "cursor", cursor === "auto" ? this.axis + "-resize" : cursor ); - this._addClass( "ui-resizable-resizing" ); - this._propagate( "start", event ); - return true; - }, +/*! + * jQuery UI Labels 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ - _mouseDrag: function( event ) { +//>>label: labels +//>>group: Core +//>>description: Find all the labels associated with a given input +//>>docs: http://api.jqueryui.com/labels/ - var data, props, - smp = this.originalMousePosition, - a = this.axis, - dx = ( event.pageX - smp.left ) || 0, - dy = ( event.pageY - smp.top ) || 0, - trigger = this._change[ a ]; - this._updatePrevProperties(); +var labels = $.fn.labels = function() { + var ancestor, selector, id, labels, ancestors; - if ( !trigger ) { - return false; - } + if ( !this.length ) { + return this.pushStack( [] ); + } - data = trigger.apply( this, [ event, dx, dy ] ); + // Check control.labels first + if ( this[ 0 ].labels && this[ 0 ].labels.length ) { + return this.pushStack( this[ 0 ].labels ); + } - this._updateVirtualBoundaries( event.shiftKey ); - if ( this._aspectRatio || event.shiftKey ) { - data = this._updateRatio( data, event ); - } + // Support: IE <= 11, FF <= 37, Android <= 2.3 only + // Above browsers do not support control.labels. Everything below is to support them + // as well as document fragments. control.labels does not work on document fragments + labels = this.eq( 0 ).parents( "label" ); - data = this._respectSize( data, event ); + // Look for the label based on the id + id = this.attr( "id" ); + if ( id ) { - this._updateCache( data ); + // We don't search against the document in case the element + // is disconnected from the DOM + ancestor = this.eq( 0 ).parents().last(); - this._propagate( "resize", event ); + // Get a full set of top level ancestors + ancestors = ancestor.add( ancestor.length ? ancestor.siblings() : this.siblings() ); - props = this._applyChanges(); + // Create a selector for the label based on the id + selector = "label[for='" + $.escapeSelector( id ) + "']"; - if ( !this._helper && this._proportionallyResizeElements.length ) { - this._proportionallyResize(); - } + labels = labels.add( ancestors.find( selector ).addBack( selector ) ); - if ( !$.isEmptyObject( props ) ) { - this._updatePrevProperties(); - this._trigger( "resize", event, this.ui() ); - this._applyChanges(); - } + } - return false; - }, + // Return whatever we have found for labels + return this.pushStack( labels ); +}; - _mouseStop: function( event ) { - this.resizing = false; - var pr, ista, soffseth, soffsetw, s, left, top, - o = this.options, that = this; - - if ( this._helper ) { +/*! + * jQuery UI Scroll Parent 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ - pr = this._proportionallyResizeElements; - ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ); - soffseth = ista && this._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height; - soffsetw = ista ? 0 : that.sizeDiff.width; +//>>label: scrollParent +//>>group: Core +//>>description: Get the closest ancestor element that is scrollable. +//>>docs: http://api.jqueryui.com/scrollParent/ - s = { - width: ( that.helper.width() - soffsetw ), - height: ( that.helper.height() - soffseth ) - }; - left = ( parseFloat( that.element.css( "left" ) ) + - ( that.position.left - that.originalPosition.left ) ) || null; - top = ( parseFloat( that.element.css( "top" ) ) + - ( that.position.top - that.originalPosition.top ) ) || null; - if ( !o.animate ) { - this.element.css( $.extend( s, { top: top, left: left } ) ); +var scrollParent = $.fn.scrollParent = function( includeHidden ) { + var position = this.css( "position" ), + excludeStaticParent = position === "absolute", + overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/, + scrollParent = this.parents().filter( function() { + var parent = $( this ); + if ( excludeStaticParent && parent.css( "position" ) === "static" ) { + return false; } + return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + + parent.css( "overflow-x" ) ); + } ).eq( 0 ); - that.helper.height( that.size.height ); - that.helper.width( that.size.width ); + return position === "fixed" || !scrollParent.length ? + $( this[ 0 ].ownerDocument || document ) : + scrollParent; +}; - if ( this._helper && !o.animate ) { - this._proportionallyResize(); - } - } - $( "body" ).css( "cursor", "auto" ); +/*! + * jQuery UI Tabbable 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ - this._removeClass( "ui-resizable-resizing" ); +//>>label: :tabbable Selector +//>>group: Core +//>>description: Selects elements which can be tabbed to. +//>>docs: http://api.jqueryui.com/tabbable-selector/ - this._propagate( "stop", event ); - if ( this._helper ) { - this.helper.remove(); - } +var tabbable = $.extend( $.expr.pseudos, { + tabbable: function( element ) { + var tabIndex = $.attr( element, "tabindex" ), + hasTabindex = tabIndex != null; + return ( !hasTabindex || tabIndex >= 0 ) && $.ui.focusable( element, hasTabindex ); + } +} ); - return false; - }, +/*! + * jQuery UI Unique ID 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ - _updatePrevProperties: function() { - this.prevPosition = { - top: this.position.top, - left: this.position.left - }; - this.prevSize = { - width: this.size.width, - height: this.size.height - }; - }, +//>>label: uniqueId +//>>group: Core +//>>description: Functions to generate and remove uniqueId's +//>>docs: http://api.jqueryui.com/uniqueId/ - _applyChanges: function() { - var props = {}; - if ( this.position.top !== this.prevPosition.top ) { - props.top = this.position.top + "px"; - } - if ( this.position.left !== this.prevPosition.left ) { - props.left = this.position.left + "px"; - } - if ( this.size.width !== this.prevSize.width ) { - props.width = this.size.width + "px"; - } - if ( this.size.height !== this.prevSize.height ) { - props.height = this.size.height + "px"; - } +var uniqueId = $.fn.extend( { + uniqueId: ( function() { + var uuid = 0; - this.helper.css( props ); + return function() { + return this.each( function() { + if ( !this.id ) { + this.id = "ui-id-" + ( ++uuid ); + } + } ); + }; + } )(), - return props; - }, + removeUniqueId: function() { + return this.each( function() { + if ( /^ui-id-\d+$/.test( this.id ) ) { + $( this ).removeAttr( "id" ); + } + } ); + } +} ); - _updateVirtualBoundaries: function( forceAspectRatio ) { - var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b, - o = this.options; - b = { - minWidth: this._isNumber( o.minWidth ) ? o.minWidth : 0, - maxWidth: this._isNumber( o.maxWidth ) ? o.maxWidth : Infinity, - minHeight: this._isNumber( o.minHeight ) ? o.minHeight : 0, - maxHeight: this._isNumber( o.maxHeight ) ? o.maxHeight : Infinity - }; +/*! + * jQuery UI Accordion 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ - if ( this._aspectRatio || forceAspectRatio ) { - pMinWidth = b.minHeight * this.aspectRatio; - pMinHeight = b.minWidth / this.aspectRatio; - pMaxWidth = b.maxHeight * this.aspectRatio; - pMaxHeight = b.maxWidth / this.aspectRatio; +//>>label: Accordion +//>>group: Widgets +/* eslint-disable max-len */ +//>>description: Displays collapsible content panels for presenting information in a limited amount of space. +/* eslint-enable max-len */ +//>>docs: http://api.jqueryui.com/accordion/ +//>>demos: http://jqueryui.com/accordion/ +//>>css.structure: ../../themes/base/core.css +//>>css.structure: ../../themes/base/accordion.css +//>>css.theme: ../../themes/base/theme.css - if ( pMinWidth > b.minWidth ) { - b.minWidth = pMinWidth; - } - if ( pMinHeight > b.minHeight ) { - b.minHeight = pMinHeight; - } - if ( pMaxWidth < b.maxWidth ) { - b.maxWidth = pMaxWidth; - } - if ( pMaxHeight < b.maxHeight ) { - b.maxHeight = pMaxHeight; - } - } - this._vBoundaries = b; + +var widgetsAccordion = $.widget( "ui.accordion", { + version: "1.13.2", + options: { + active: 0, + animate: {}, + classes: { + "ui-accordion-header": "ui-corner-top", + "ui-accordion-header-collapsed": "ui-corner-all", + "ui-accordion-content": "ui-corner-bottom" + }, + collapsible: false, + event: "click", + header: function( elem ) { + return elem.find( "> li > :first-child" ).add( elem.find( "> :not(li)" ).even() ); + }, + heightStyle: "auto", + icons: { + activeHeader: "ui-icon-triangle-1-s", + header: "ui-icon-triangle-1-e" + }, + + // Callbacks + activate: null, + beforeActivate: null }, - _updateCache: function( data ) { - this.offset = this.helper.offset(); - if ( this._isNumber( data.left ) ) { - this.position.left = data.left; - } - if ( this._isNumber( data.top ) ) { - this.position.top = data.top; - } - if ( this._isNumber( data.height ) ) { - this.size.height = data.height; - } - if ( this._isNumber( data.width ) ) { - this.size.width = data.width; - } + hideProps: { + borderTopWidth: "hide", + borderBottomWidth: "hide", + paddingTop: "hide", + paddingBottom: "hide", + height: "hide" }, - _updateRatio: function( data ) { + showProps: { + borderTopWidth: "show", + borderBottomWidth: "show", + paddingTop: "show", + paddingBottom: "show", + height: "show" + }, - var cpos = this.position, - csize = this.size, - a = this.axis; + _create: function() { + var options = this.options; - if ( this._isNumber( data.height ) ) { - data.width = ( data.height * this.aspectRatio ); - } else if ( this._isNumber( data.width ) ) { - data.height = ( data.width / this.aspectRatio ); - } + this.prevShow = this.prevHide = $(); + this._addClass( "ui-accordion", "ui-widget ui-helper-reset" ); + this.element.attr( "role", "tablist" ); - if ( a === "sw" ) { - data.left = cpos.left + ( csize.width - data.width ); - data.top = null; - } - if ( a === "nw" ) { - data.top = cpos.top + ( csize.height - data.height ); - data.left = cpos.left + ( csize.width - data.width ); + // Don't allow collapsible: false and active: false / null + if ( !options.collapsible && ( options.active === false || options.active == null ) ) { + options.active = 0; } - return data; - }, + this._processPanels(); - _respectSize: function( data ) { - - var o = this._vBoundaries, - a = this.axis, - ismaxw = this._isNumber( data.width ) && o.maxWidth && ( o.maxWidth < data.width ), - ismaxh = this._isNumber( data.height ) && o.maxHeight && ( o.maxHeight < data.height ), - isminw = this._isNumber( data.width ) && o.minWidth && ( o.minWidth > data.width ), - isminh = this._isNumber( data.height ) && o.minHeight && ( o.minHeight > data.height ), - dw = this.originalPosition.left + this.originalSize.width, - dh = this.originalPosition.top + this.originalSize.height, - cw = /sw|nw|w/.test( a ), ch = /nw|ne|n/.test( a ); - if ( isminw ) { - data.width = o.minWidth; - } - if ( isminh ) { - data.height = o.minHeight; - } - if ( ismaxw ) { - data.width = o.maxWidth; - } - if ( ismaxh ) { - data.height = o.maxHeight; + // handle negative values + if ( options.active < 0 ) { + options.active += this.headers.length; } + this._refresh(); + }, - if ( isminw && cw ) { - data.left = dw - o.minWidth; - } - if ( ismaxw && cw ) { - data.left = dw - o.maxWidth; - } - if ( isminh && ch ) { - data.top = dh - o.minHeight; - } - if ( ismaxh && ch ) { - data.top = dh - o.maxHeight; - } + _getCreateEventData: function() { + return { + header: this.active, + panel: !this.active.length ? $() : this.active.next() + }; + }, - // Fixing jump error on top/left - bug #2330 - if ( !data.width && !data.height && !data.left && data.top ) { - data.top = null; - } else if ( !data.width && !data.height && !data.top && data.left ) { - data.left = null; + _createIcons: function() { + var icon, children, + icons = this.options.icons; + + if ( icons ) { + icon = $( "<span>" ); + this._addClass( icon, "ui-accordion-header-icon", "ui-icon " + icons.header ); + icon.prependTo( this.headers ); + children = this.active.children( ".ui-accordion-header-icon" ); + this._removeClass( children, icons.header ) + ._addClass( children, null, icons.activeHeader ) + ._addClass( this.headers, "ui-accordion-icons" ); } + }, - return data; + _destroyIcons: function() { + this._removeClass( this.headers, "ui-accordion-icons" ); + this.headers.children( ".ui-accordion-header-icon" ).remove(); }, - _getPaddingPlusBorderDimensions: function( element ) { - var i = 0, - widths = [], - borders = [ - element.css( "borderTopWidth" ), - element.css( "borderRightWidth" ), - element.css( "borderBottomWidth" ), - element.css( "borderLeftWidth" ) - ], - paddings = [ - element.css( "paddingTop" ), - element.css( "paddingRight" ), - element.css( "paddingBottom" ), - element.css( "paddingLeft" ) - ]; + _destroy: function() { + var contents; - for ( ; i < 4; i++ ) { - widths[ i ] = ( parseFloat( borders[ i ] ) || 0 ); - widths[ i ] += ( parseFloat( paddings[ i ] ) || 0 ); - } + // Clean up main element + this.element.removeAttr( "role" ); - return { - height: widths[ 0 ] + widths[ 2 ], - width: widths[ 1 ] + widths[ 3 ] - }; - }, + // Clean up headers + this.headers + .removeAttr( "role aria-expanded aria-selected aria-controls tabIndex" ) + .removeUniqueId(); - _proportionallyResize: function() { + this._destroyIcons(); - if ( !this._proportionallyResizeElements.length ) { - return; - } + // Clean up content panels + contents = this.headers.next() + .css( "display", "" ) + .removeAttr( "role aria-hidden aria-labelledby" ) + .removeUniqueId(); - var prel, - i = 0, - element = this.helper || this.element; + if ( this.options.heightStyle !== "content" ) { + contents.css( "height", "" ); + } + }, - for ( ; i < this._proportionallyResizeElements.length; i++ ) { + _setOption: function( key, value ) { + if ( key === "active" ) { - prel = this._proportionallyResizeElements[ i ]; + // _activate() will handle invalid values and update this.options + this._activate( value ); + return; + } - // TODO: Seems like a bug to cache this.outerDimensions - // considering that we are in a loop. - if ( !this.outerDimensions ) { - this.outerDimensions = this._getPaddingPlusBorderDimensions( prel ); + if ( key === "event" ) { + if ( this.options.event ) { + this._off( this.headers, this.options.event ); } + this._setupEvents( value ); + } - prel.css( { - height: ( element.height() - this.outerDimensions.height ) || 0, - width: ( element.width() - this.outerDimensions.width ) || 0 - } ); + this._super( key, value ); + // Setting collapsible: false while collapsed; open first panel + if ( key === "collapsible" && !value && this.options.active === false ) { + this._activate( 0 ); } + if ( key === "icons" ) { + this._destroyIcons(); + if ( value ) { + this._createIcons(); + } + } }, - _renderProxy: function() { - - var el = this.element, o = this.options; - this.elementOffset = el.offset(); + _setOptionDisabled: function( value ) { + this._super( value ); - if ( this._helper ) { + this.element.attr( "aria-disabled", value ); - this.helper = this.helper || $( "<div></div>" ).css( { overflow: "hidden" } ); + // Support: IE8 Only + // #5332 / #6059 - opacity doesn't cascade to positioned elements in IE + // so we need to add the disabled class to the headers and panels + this._toggleClass( null, "ui-state-disabled", !!value ); + this._toggleClass( this.headers.add( this.headers.next() ), null, "ui-state-disabled", + !!value ); + }, - this._addClass( this.helper, this._helper ); - this.helper.css( { - width: this.element.outerWidth(), - height: this.element.outerHeight(), - position: "absolute", - left: this.elementOffset.left + "px", - top: this.elementOffset.top + "px", - zIndex: ++o.zIndex //TODO: Don't modify option - } ); + _keydown: function( event ) { + if ( event.altKey || event.ctrlKey ) { + return; + } - this.helper - .appendTo( "body" ) - .disableSelection(); + var keyCode = $.ui.keyCode, + length = this.headers.length, + currentIndex = this.headers.index( event.target ), + toFocus = false; - } else { - this.helper = this.element; + switch ( event.keyCode ) { + case keyCode.RIGHT: + case keyCode.DOWN: + toFocus = this.headers[ ( currentIndex + 1 ) % length ]; + break; + case keyCode.LEFT: + case keyCode.UP: + toFocus = this.headers[ ( currentIndex - 1 + length ) % length ]; + break; + case keyCode.SPACE: + case keyCode.ENTER: + this._eventHandler( event ); + break; + case keyCode.HOME: + toFocus = this.headers[ 0 ]; + break; + case keyCode.END: + toFocus = this.headers[ length - 1 ]; + break; } - }, - - _change: { - e: function( event, dx ) { - return { width: this.originalSize.width + dx }; - }, - w: function( event, dx ) { - var cs = this.originalSize, sp = this.originalPosition; - return { left: sp.left + dx, width: cs.width - dx }; - }, - n: function( event, dx, dy ) { - var cs = this.originalSize, sp = this.originalPosition; - return { top: sp.top + dy, height: cs.height - dy }; - }, - s: function( event, dx, dy ) { - return { height: this.originalSize.height + dy }; - }, - se: function( event, dx, dy ) { - return $.extend( this._change.s.apply( this, arguments ), - this._change.e.apply( this, [ event, dx, dy ] ) ); - }, - sw: function( event, dx, dy ) { - return $.extend( this._change.s.apply( this, arguments ), - this._change.w.apply( this, [ event, dx, dy ] ) ); - }, - ne: function( event, dx, dy ) { - return $.extend( this._change.n.apply( this, arguments ), - this._change.e.apply( this, [ event, dx, dy ] ) ); - }, - nw: function( event, dx, dy ) { - return $.extend( this._change.n.apply( this, arguments ), - this._change.w.apply( this, [ event, dx, dy ] ) ); + if ( toFocus ) { + $( event.target ).attr( "tabIndex", -1 ); + $( toFocus ).attr( "tabIndex", 0 ); + $( toFocus ).trigger( "focus" ); + event.preventDefault(); } }, - _propagate: function( n, event ) { - $.ui.plugin.call( this, n, [ event, this.ui() ] ); - if ( n !== "resize" ) { - this._trigger( n, event, this.ui() ); + _panelKeyDown: function( event ) { + if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) { + $( event.currentTarget ).prev().trigger( "focus" ); } }, - plugins: {}, + refresh: function() { + var options = this.options; + this._processPanels(); - ui: function() { - return { - originalElement: this.originalElement, - element: this.element, - helper: this.helper, - position: this.position, - size: this.size, - originalSize: this.originalSize, - originalPosition: this.originalPosition - }; - } - -} ); - -/* - * Resizable Extensions - */ - -$.ui.plugin.add( "resizable", "animate", { - - stop: function( event ) { - var that = $( this ).resizable( "instance" ), - o = that.options, - pr = that._proportionallyResizeElements, - ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ), - soffseth = ista && that._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height, - soffsetw = ista ? 0 : that.sizeDiff.width, - style = { - width: ( that.size.width - soffsetw ), - height: ( that.size.height - soffseth ) - }, - left = ( parseFloat( that.element.css( "left" ) ) + - ( that.position.left - that.originalPosition.left ) ) || null, - top = ( parseFloat( that.element.css( "top" ) ) + - ( that.position.top - that.originalPosition.top ) ) || null; - - that.element.animate( - $.extend( style, top && left ? { top: top, left: left } : {} ), { - duration: o.animateDuration, - easing: o.animateEasing, - step: function() { + // Was collapsed or no panel + if ( ( options.active === false && options.collapsible === true ) || + !this.headers.length ) { + options.active = false; + this.active = $(); - var data = { - width: parseFloat( that.element.css( "width" ) ), - height: parseFloat( that.element.css( "height" ) ), - top: parseFloat( that.element.css( "top" ) ), - left: parseFloat( that.element.css( "left" ) ) - }; + // active false only when collapsible is true + } else if ( options.active === false ) { + this._activate( 0 ); - if ( pr && pr.length ) { - $( pr[ 0 ] ).css( { width: data.width, height: data.height } ); - } + // was active, but active panel is gone + } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { - // Propagating resize, and updating values for each animation step - that._updateCache( data ); - that._propagate( "resize", event ); + // all remaining panel are disabled + if ( this.headers.length === this.headers.find( ".ui-state-disabled" ).length ) { + options.active = false; + this.active = $(); - } + // activate previous panel + } else { + this._activate( Math.max( 0, options.active - 1 ) ); } - ); - } - -} ); - -$.ui.plugin.add( "resizable", "containment", { - - start: function() { - var element, p, co, ch, cw, width, height, - that = $( this ).resizable( "instance" ), - o = that.options, - el = that.element, - oc = o.containment, - ce = ( oc instanceof $ ) ? - oc.get( 0 ) : - ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc; - - if ( !ce ) { - return; - } - - that.containerElement = $( ce ); - - if ( /document/.test( oc ) || oc === document ) { - that.containerOffset = { - left: 0, - top: 0 - }; - that.containerPosition = { - left: 0, - top: 0 - }; - that.parentData = { - element: $( document ), - left: 0, - top: 0, - width: $( document ).width(), - height: $( document ).height() || document.body.parentNode.scrollHeight - }; + // was active, active panel still exists } else { - element = $( ce ); - p = []; - $( [ "Top", "Right", "Left", "Bottom" ] ).each( function( i, name ) { - p[ i ] = that._num( element.css( "padding" + name ) ); - } ); - that.containerOffset = element.offset(); - that.containerPosition = element.position(); - that.containerSize = { - height: ( element.innerHeight() - p[ 3 ] ), - width: ( element.innerWidth() - p[ 1 ] ) - }; + // make sure active index is correct + options.active = this.headers.index( this.active ); + } - co = that.containerOffset; - ch = that.containerSize.height; - cw = that.containerSize.width; - width = ( that._hasScroll( ce, "left" ) ? ce.scrollWidth : cw ); - height = ( that._hasScroll( ce ) ? ce.scrollHeight : ch ); + this._destroyIcons(); - that.parentData = { - element: ce, - left: co.left, - top: co.top, - width: width, - height: height - }; - } + this._refresh(); }, - resize: function( event ) { - var woset, hoset, isParent, isOffsetRelative, - that = $( this ).resizable( "instance" ), - o = that.options, - co = that.containerOffset, - cp = that.position, - pRatio = that._aspectRatio || event.shiftKey, - cop = { - top: 0, - left: 0 - }, - ce = that.containerElement, - continueResize = true; + _processPanels: function() { + var prevHeaders = this.headers, + prevPanels = this.panels; - if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) { - cop = co; + if ( typeof this.options.header === "function" ) { + this.headers = this.options.header( this.element ); + } else { + this.headers = this.element.find( this.options.header ); } + this._addClass( this.headers, "ui-accordion-header ui-accordion-header-collapsed", + "ui-state-default" ); - if ( cp.left < ( that._helper ? co.left : 0 ) ) { - that.size.width = that.size.width + - ( that._helper ? - ( that.position.left - co.left ) : - ( that.position.left - cop.left ) ); + this.panels = this.headers.next().filter( ":not(.ui-accordion-content-active)" ).hide(); + this._addClass( this.panels, "ui-accordion-content", "ui-helper-reset ui-widget-content" ); - if ( pRatio ) { - that.size.height = that.size.width / that.aspectRatio; - continueResize = false; - } - that.position.left = o.helper ? co.left : 0; + // Avoid memory leaks (#10056) + if ( prevPanels ) { + this._off( prevHeaders.not( this.headers ) ); + this._off( prevPanels.not( this.panels ) ); } + }, - if ( cp.top < ( that._helper ? co.top : 0 ) ) { - that.size.height = that.size.height + - ( that._helper ? - ( that.position.top - co.top ) : - that.position.top ); + _refresh: function() { + var maxHeight, + options = this.options, + heightStyle = options.heightStyle, + parent = this.element.parent(); - if ( pRatio ) { - that.size.width = that.size.height * that.aspectRatio; - continueResize = false; - } - that.position.top = that._helper ? co.top : 0; - } + this.active = this._findActive( options.active ); + this._addClass( this.active, "ui-accordion-header-active", "ui-state-active" ) + ._removeClass( this.active, "ui-accordion-header-collapsed" ); + this._addClass( this.active.next(), "ui-accordion-content-active" ); + this.active.next().show(); - isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 ); - isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) ); + this.headers + .attr( "role", "tab" ) + .each( function() { + var header = $( this ), + headerId = header.uniqueId().attr( "id" ), + panel = header.next(), + panelId = panel.uniqueId().attr( "id" ); + header.attr( "aria-controls", panelId ); + panel.attr( "aria-labelledby", headerId ); + } ) + .next() + .attr( "role", "tabpanel" ); - if ( isParent && isOffsetRelative ) { - that.offset.left = that.parentData.left + that.position.left; - that.offset.top = that.parentData.top + that.position.top; + this.headers + .not( this.active ) + .attr( { + "aria-selected": "false", + "aria-expanded": "false", + tabIndex: -1 + } ) + .next() + .attr( { + "aria-hidden": "true" + } ) + .hide(); + + // Make sure at least one header is in the tab order + if ( !this.active.length ) { + this.headers.eq( 0 ).attr( "tabIndex", 0 ); } else { - that.offset.left = that.element.offset().left; - that.offset.top = that.element.offset().top; + this.active.attr( { + "aria-selected": "true", + "aria-expanded": "true", + tabIndex: 0 + } ) + .next() + .attr( { + "aria-hidden": "false" + } ); } - woset = Math.abs( that.sizeDiff.width + - ( that._helper ? - that.offset.left - cop.left : - ( that.offset.left - co.left ) ) ); + this._createIcons(); - hoset = Math.abs( that.sizeDiff.height + - ( that._helper ? - that.offset.top - cop.top : - ( that.offset.top - co.top ) ) ); + this._setupEvents( options.event ); - if ( woset + that.size.width >= that.parentData.width ) { - that.size.width = that.parentData.width - woset; - if ( pRatio ) { - that.size.height = that.size.width / that.aspectRatio; - continueResize = false; - } - } + if ( heightStyle === "fill" ) { + maxHeight = parent.height(); + this.element.siblings( ":visible" ).each( function() { + var elem = $( this ), + position = elem.css( "position" ); - if ( hoset + that.size.height >= that.parentData.height ) { - that.size.height = that.parentData.height - hoset; - if ( pRatio ) { - that.size.width = that.size.height * that.aspectRatio; - continueResize = false; - } - } + if ( position === "absolute" || position === "fixed" ) { + return; + } + maxHeight -= elem.outerHeight( true ); + } ); - if ( !continueResize ) { - that.position.left = that.prevPosition.left; - that.position.top = that.prevPosition.top; - that.size.width = that.prevSize.width; - that.size.height = that.prevSize.height; + this.headers.each( function() { + maxHeight -= $( this ).outerHeight( true ); + } ); + + this.headers.next() + .each( function() { + $( this ).height( Math.max( 0, maxHeight - + $( this ).innerHeight() + $( this ).height() ) ); + } ) + .css( "overflow", "auto" ); + } else if ( heightStyle === "auto" ) { + maxHeight = 0; + this.headers.next() + .each( function() { + var isVisible = $( this ).is( ":visible" ); + if ( !isVisible ) { + $( this ).show(); + } + maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() ); + if ( !isVisible ) { + $( this ).hide(); + } + } ) + .height( maxHeight ); } }, - stop: function() { - var that = $( this ).resizable( "instance" ), - o = that.options, - co = that.containerOffset, - cop = that.containerPosition, - ce = that.containerElement, - helper = $( that.helper ), - ho = helper.offset(), - w = helper.outerWidth() - that.sizeDiff.width, - h = helper.outerHeight() - that.sizeDiff.height; - - if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) { - $( this ).css( { - left: ho.left - cop.left - co.left, - width: w, - height: h - } ); - } + _activate: function( index ) { + var active = this._findActive( index )[ 0 ]; - if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) { - $( this ).css( { - left: ho.left - cop.left - co.left, - width: w, - height: h - } ); + // Trying to activate the already active panel + if ( active === this.active[ 0 ] ) { + return; } - } -} ); - -$.ui.plugin.add( "resizable", "alsoResize", { - start: function() { - var that = $( this ).resizable( "instance" ), - o = that.options; + // Trying to collapse, simulate a click on the currently active header + active = active || this.active[ 0 ]; - $( o.alsoResize ).each( function() { - var el = $( this ); - el.data( "ui-resizable-alsoresize", { - width: parseFloat( el.width() ), height: parseFloat( el.height() ), - left: parseFloat( el.css( "left" ) ), top: parseFloat( el.css( "top" ) ) - } ); + this._eventHandler( { + target: active, + currentTarget: active, + preventDefault: $.noop } ); }, - resize: function( event, ui ) { - var that = $( this ).resizable( "instance" ), - o = that.options, - os = that.originalSize, - op = that.originalPosition, - delta = { - height: ( that.size.height - os.height ) || 0, - width: ( that.size.width - os.width ) || 0, - top: ( that.position.top - op.top ) || 0, - left: ( that.position.left - op.left ) || 0 - }; - - $( o.alsoResize ).each( function() { - var el = $( this ), start = $( this ).data( "ui-resizable-alsoresize" ), style = {}, - css = el.parents( ui.originalElement[ 0 ] ).length ? - [ "width", "height" ] : - [ "width", "height", "top", "left" ]; - - $.each( css, function( i, prop ) { - var sum = ( start[ prop ] || 0 ) + ( delta[ prop ] || 0 ); - if ( sum && sum >= 0 ) { - style[ prop ] = sum || null; - } - } ); + _findActive: function( selector ) { + return typeof selector === "number" ? this.headers.eq( selector ) : $(); + }, - el.css( style ); + _setupEvents: function( event ) { + var events = { + keydown: "_keydown" + }; + if ( event ) { + $.each( event.split( " " ), function( index, eventName ) { + events[ eventName ] = "_eventHandler"; } ); + } + + this._off( this.headers.add( this.headers.next() ) ); + this._on( this.headers, events ); + this._on( this.headers.next(), { keydown: "_panelKeyDown" } ); + this._hoverable( this.headers ); + this._focusable( this.headers ); }, - stop: function() { - $( this ).removeData( "ui-resizable-alsoresize" ); - } -} ); + _eventHandler: function( event ) { + var activeChildren, clickedChildren, + options = this.options, + active = this.active, + clicked = $( event.currentTarget ), + clickedIsActive = clicked[ 0 ] === active[ 0 ], + collapsing = clickedIsActive && options.collapsible, + toShow = collapsing ? $() : clicked.next(), + toHide = active.next(), + eventData = { + oldHeader: active, + oldPanel: toHide, + newHeader: collapsing ? $() : clicked, + newPanel: toShow + }; -$.ui.plugin.add( "resizable", "ghost", { + event.preventDefault(); - start: function() { + if ( - var that = $( this ).resizable( "instance" ), cs = that.size; + // click on active header, but not collapsible + ( clickedIsActive && !options.collapsible ) || - that.ghost = that.originalElement.clone(); - that.ghost.css( { - opacity: 0.25, - display: "block", - position: "relative", - height: cs.height, - width: cs.width, - margin: 0, - left: 0, - top: 0 - } ); + // allow canceling activation + ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { + return; + } - that._addClass( that.ghost, "ui-resizable-ghost" ); + options.active = collapsing ? false : this.headers.index( clicked ); - // DEPRECATED - // TODO: remove after 1.12 - if ( $.uiBackCompat !== false && typeof that.options.ghost === "string" ) { + // When the call to ._toggle() comes after the class changes + // it causes a very odd bug in IE 8 (see #6720) + this.active = clickedIsActive ? $() : clicked; + this._toggle( eventData ); - // Ghost option - that.ghost.addClass( this.options.ghost ); + // Switch classes + // corner classes on the previously active header stay after the animation + this._removeClass( active, "ui-accordion-header-active", "ui-state-active" ); + if ( options.icons ) { + activeChildren = active.children( ".ui-accordion-header-icon" ); + this._removeClass( activeChildren, null, options.icons.activeHeader ) + ._addClass( activeChildren, null, options.icons.header ); } - that.ghost.appendTo( that.helper ); - - }, + if ( !clickedIsActive ) { + this._removeClass( clicked, "ui-accordion-header-collapsed" ) + ._addClass( clicked, "ui-accordion-header-active", "ui-state-active" ); + if ( options.icons ) { + clickedChildren = clicked.children( ".ui-accordion-header-icon" ); + this._removeClass( clickedChildren, null, options.icons.header ) + ._addClass( clickedChildren, null, options.icons.activeHeader ); + } - resize: function() { - var that = $( this ).resizable( "instance" ); - if ( that.ghost ) { - that.ghost.css( { - position: "relative", - height: that.size.height, - width: that.size.width - } ); + this._addClass( clicked.next(), "ui-accordion-content-active" ); } }, - stop: function() { - var that = $( this ).resizable( "instance" ); - if ( that.ghost && that.helper ) { - that.helper.get( 0 ).removeChild( that.ghost.get( 0 ) ); - } - } + _toggle: function( data ) { + var toShow = data.newPanel, + toHide = this.prevShow.length ? this.prevShow : data.oldPanel; -} ); + // Handle activating a panel during the animation for another activation + this.prevShow.add( this.prevHide ).stop( true, true ); + this.prevShow = toShow; + this.prevHide = toHide; -$.ui.plugin.add( "resizable", "grid", { + if ( this.options.animate ) { + this._animate( toShow, toHide, data ); + } else { + toHide.hide(); + toShow.show(); + this._toggleComplete( data ); + } - resize: function() { - var outerDimensions, - that = $( this ).resizable( "instance" ), - o = that.options, - cs = that.size, - os = that.originalSize, - op = that.originalPosition, - a = that.axis, - grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid, - gridX = ( grid[ 0 ] || 1 ), - gridY = ( grid[ 1 ] || 1 ), - ox = Math.round( ( cs.width - os.width ) / gridX ) * gridX, - oy = Math.round( ( cs.height - os.height ) / gridY ) * gridY, - newWidth = os.width + ox, - newHeight = os.height + oy, - isMaxWidth = o.maxWidth && ( o.maxWidth < newWidth ), - isMaxHeight = o.maxHeight && ( o.maxHeight < newHeight ), - isMinWidth = o.minWidth && ( o.minWidth > newWidth ), - isMinHeight = o.minHeight && ( o.minHeight > newHeight ); + toHide.attr( { + "aria-hidden": "true" + } ); + toHide.prev().attr( { + "aria-selected": "false", + "aria-expanded": "false" + } ); - o.grid = grid; + // if we're switching panels, remove the old header from the tab order + // if we're opening from collapsed state, remove the previous header from the tab order + // if we're collapsing, then keep the collapsing header in the tab order + if ( toShow.length && toHide.length ) { + toHide.prev().attr( { + "tabIndex": -1, + "aria-expanded": "false" + } ); + } else if ( toShow.length ) { + this.headers.filter( function() { + return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0; + } ) + .attr( "tabIndex", -1 ); + } - if ( isMinWidth ) { - newWidth += gridX; + toShow + .attr( "aria-hidden", "false" ) + .prev() + .attr( { + "aria-selected": "true", + "aria-expanded": "true", + tabIndex: 0 + } ); + }, + + _animate: function( toShow, toHide, data ) { + var total, easing, duration, + that = this, + adjust = 0, + boxSizing = toShow.css( "box-sizing" ), + down = toShow.length && + ( !toHide.length || ( toShow.index() < toHide.index() ) ), + animate = this.options.animate || {}, + options = down && animate.down || animate, + complete = function() { + that._toggleComplete( data ); + }; + + if ( typeof options === "number" ) { + duration = options; } - if ( isMinHeight ) { - newHeight += gridY; + if ( typeof options === "string" ) { + easing = options; } - if ( isMaxWidth ) { - newWidth -= gridX; + + // fall back from options to animation in case of partial down settings + easing = easing || options.easing || animate.easing; + duration = duration || options.duration || animate.duration; + + if ( !toHide.length ) { + return toShow.animate( this.showProps, duration, easing, complete ); } - if ( isMaxHeight ) { - newHeight -= gridY; + if ( !toShow.length ) { + return toHide.animate( this.hideProps, duration, easing, complete ); } - if ( /^(se|s|e)$/.test( a ) ) { - that.size.width = newWidth; - that.size.height = newHeight; - } else if ( /^(ne)$/.test( a ) ) { - that.size.width = newWidth; - that.size.height = newHeight; - that.position.top = op.top - oy; - } else if ( /^(sw)$/.test( a ) ) { - that.size.width = newWidth; - that.size.height = newHeight; - that.position.left = op.left - ox; - } else { - if ( newHeight - gridY <= 0 || newWidth - gridX <= 0 ) { - outerDimensions = that._getPaddingPlusBorderDimensions( this ); + total = toShow.show().outerHeight(); + toHide.animate( this.hideProps, { + duration: duration, + easing: easing, + step: function( now, fx ) { + fx.now = Math.round( now ); } + } ); + toShow + .hide() + .animate( this.showProps, { + duration: duration, + easing: easing, + complete: complete, + step: function( now, fx ) { + fx.now = Math.round( now ); + if ( fx.prop !== "height" ) { + if ( boxSizing === "content-box" ) { + adjust += fx.now; + } + } else if ( that.options.heightStyle !== "content" ) { + fx.now = Math.round( total - toHide.outerHeight() - adjust ); + adjust = 0; + } + } + } ); + }, - if ( newHeight - gridY > 0 ) { - that.size.height = newHeight; - that.position.top = op.top - oy; - } else { - newHeight = gridY - outerDimensions.height; - that.size.height = newHeight; - that.position.top = op.top + os.height - newHeight; - } - if ( newWidth - gridX > 0 ) { - that.size.width = newWidth; - that.position.left = op.left - ox; - } else { - newWidth = gridX - outerDimensions.width; - that.size.width = newWidth; - that.position.left = op.left + os.width - newWidth; - } + _toggleComplete: function( data ) { + var toHide = data.oldPanel, + prev = toHide.prev(); + + this._removeClass( toHide, "ui-accordion-content-active" ); + this._removeClass( prev, "ui-accordion-header-active" ) + ._addClass( prev, "ui-accordion-header-collapsed" ); + + // Work around for rendering bug in IE (#5421) + if ( toHide.length ) { + toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className; } + this._trigger( "activate", null, data ); } - } ); -var widgetsResizable = $.ui.resizable; + + +var safeActiveElement = $.ui.safeActiveElement = function( document ) { + var activeElement; + + // Support: IE 9 only + // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe> + try { + activeElement = document.activeElement; + } catch ( error ) { + activeElement = document.body; + } + + // Support: IE 9 - 11 only + // IE may return null instead of an element + // Interestingly, this only seems to occur when NOT in an iframe + if ( !activeElement ) { + activeElement = document.body; + } + + // Support: IE 11 only + // IE11 returns a seemingly empty object in some cases when accessing + // document.activeElement from an <iframe> + if ( !activeElement.nodeName ) { + activeElement = document.body; + } + + return activeElement; +}; /*! - * jQuery UI Selectable 1.13.1 + * jQuery UI Menu 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -4952,1890 +4980,1902 @@ var widgetsResizable = $.ui.resizable; * http://jquery.org/license */ -//>>label: Selectable -//>>group: Interactions -//>>description: Allows groups of elements to be selected with the mouse. -//>>docs: http://api.jqueryui.com/selectable/ -//>>demos: http://jqueryui.com/selectable/ -//>>css.structure: ../../themes/base/selectable.css +//>>label: Menu +//>>group: Widgets +//>>description: Creates nestable menus. +//>>docs: http://api.jqueryui.com/menu/ +//>>demos: http://jqueryui.com/menu/ +//>>css.structure: ../../themes/base/core.css +//>>css.structure: ../../themes/base/menu.css +//>>css.theme: ../../themes/base/theme.css -var widgetsSelectable = $.widget( "ui.selectable", $.ui.mouse, { - version: "1.13.1", +var widgetsMenu = $.widget( "ui.menu", { + version: "1.13.2", + defaultElement: "<ul>", + delay: 300, options: { - appendTo: "body", - autoRefresh: true, - distance: 0, - filter: "*", - tolerance: "touch", + icons: { + submenu: "ui-icon-caret-1-e" + }, + items: "> *", + menus: "ul", + position: { + my: "left top", + at: "right top" + }, + role: "menu", // Callbacks - selected: null, - selecting: null, - start: null, - stop: null, - unselected: null, - unselecting: null + blur: null, + focus: null, + select: null }, - _create: function() { - var that = this; - - this._addClass( "ui-selectable" ); - this.dragged = false; + _create: function() { + this.activeMenu = this.element; - // Cache selectee children based on filter - this.refresh = function() { - that.elementPos = $( that.element[ 0 ] ).offset(); - that.selectees = $( that.options.filter, that.element[ 0 ] ); - that._addClass( that.selectees, "ui-selectee" ); - that.selectees.each( function() { - var $this = $( this ), - selecteeOffset = $this.offset(), - pos = { - left: selecteeOffset.left - that.elementPos.left, - top: selecteeOffset.top - that.elementPos.top - }; - $.data( this, "selectable-item", { - element: this, - $element: $this, - left: pos.left, - top: pos.top, - right: pos.left + $this.outerWidth(), - bottom: pos.top + $this.outerHeight(), - startselected: false, - selected: $this.hasClass( "ui-selected" ), - selecting: $this.hasClass( "ui-selecting" ), - unselecting: $this.hasClass( "ui-unselecting" ) - } ); + // Flag used to prevent firing of the click handler + // as the event bubbles up through nested menus + this.mouseHandled = false; + this.lastMousePosition = { x: null, y: null }; + this.element + .uniqueId() + .attr( { + role: this.options.role, + tabIndex: 0 } ); - }; - this.refresh(); - this._mouseInit(); + this._addClass( "ui-menu", "ui-widget ui-widget-content" ); + this._on( { - this.helper = $( "<div>" ); - this._addClass( this.helper, "ui-selectable-helper" ); - }, - - _destroy: function() { - this.selectees.removeData( "selectable-item" ); - this._mouseDestroy(); - }, - - _mouseStart: function( event ) { - var that = this, - options = this.options; - - this.opos = [ event.pageX, event.pageY ]; - this.elementPos = $( this.element[ 0 ] ).offset(); - - if ( this.options.disabled ) { - return; - } + // Prevent focus from sticking to links inside menu after clicking + // them (focus should always stay on UL during navigation). + "mousedown .ui-menu-item": function( event ) { + event.preventDefault(); - this.selectees = $( options.filter, this.element[ 0 ] ); + this._activateItem( event ); + }, + "click .ui-menu-item": function( event ) { + var target = $( event.target ); + var active = $( $.ui.safeActiveElement( this.document[ 0 ] ) ); + if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) { + this.select( event ); - this._trigger( "start", event ); + // Only set the mouseHandled flag if the event will bubble, see #9469. + if ( !event.isPropagationStopped() ) { + this.mouseHandled = true; + } - $( options.appendTo ).append( this.helper ); + // Open submenu on click + if ( target.has( ".ui-menu" ).length ) { + this.expand( event ); + } else if ( !this.element.is( ":focus" ) && + active.closest( ".ui-menu" ).length ) { - // position helper (lasso) - this.helper.css( { - "left": event.pageX, - "top": event.pageY, - "width": 0, - "height": 0 - } ); + // Redirect focus to the menu + this.element.trigger( "focus", [ true ] ); - if ( options.autoRefresh ) { - this.refresh(); - } + // If the active item is on the top level, let it stay active. + // Otherwise, blur the active item since it is no longer visible. + if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) { + clearTimeout( this.timer ); + } + } + } + }, + "mouseenter .ui-menu-item": "_activateItem", + "mousemove .ui-menu-item": "_activateItem", + mouseleave: "collapseAll", + "mouseleave .ui-menu": "collapseAll", + focus: function( event, keepActiveItem ) { - this.selectees.filter( ".ui-selected" ).each( function() { - var selectee = $.data( this, "selectable-item" ); - selectee.startselected = true; - if ( !event.metaKey && !event.ctrlKey ) { - that._removeClass( selectee.$element, "ui-selected" ); - selectee.selected = false; - that._addClass( selectee.$element, "ui-unselecting" ); - selectee.unselecting = true; + // If there's already an active item, keep it active + // If not, activate the first item + var item = this.active || this._menuItems().first(); - // selectable UNSELECTING callback - that._trigger( "unselecting", event, { - unselecting: selectee.element + if ( !keepActiveItem ) { + this.focus( event, item ); + } + }, + blur: function( event ) { + this._delay( function() { + var notContained = !$.contains( + this.element[ 0 ], + $.ui.safeActiveElement( this.document[ 0 ] ) + ); + if ( notContained ) { + this.collapseAll( event ); + } } ); - } + }, + keydown: "_keydown" } ); - $( event.target ).parents().addBack().each( function() { - var doSelect, - selectee = $.data( this, "selectable-item" ); - if ( selectee ) { - doSelect = ( !event.metaKey && !event.ctrlKey ) || - !selectee.$element.hasClass( "ui-selected" ); - that._removeClass( selectee.$element, doSelect ? "ui-unselecting" : "ui-selected" ) - ._addClass( selectee.$element, doSelect ? "ui-selecting" : "ui-unselecting" ); - selectee.unselecting = !doSelect; - selectee.selecting = doSelect; - selectee.selected = doSelect; + this.refresh(); - // selectable (UN)SELECTING callback - if ( doSelect ) { - that._trigger( "selecting", event, { - selecting: selectee.element - } ); - } else { - that._trigger( "unselecting", event, { - unselecting: selectee.element - } ); + // Clicks outside of a menu collapse any open menus + this._on( this.document, { + click: function( event ) { + if ( this._closeOnDocumentClick( event ) ) { + this.collapseAll( event, true ); } - return false; + + // Reset the mouseHandled flag + this.mouseHandled = false; } } ); - }, - _mouseDrag: function( event ) { + _activateItem: function( event ) { - this.dragged = true; + // Ignore mouse events while typeahead is active, see #10458. + // Prevents focusing the wrong item when typeahead causes a scroll while the mouse + // is over an item in the menu + if ( this.previousFilter ) { + return; + } - if ( this.options.disabled ) { + // If the mouse didn't actually move, but the page was scrolled, ignore the event (#9356) + if ( event.clientX === this.lastMousePosition.x && + event.clientY === this.lastMousePosition.y ) { return; } - var tmp, - that = this, - options = this.options, - x1 = this.opos[ 0 ], - y1 = this.opos[ 1 ], - x2 = event.pageX, - y2 = event.pageY; + this.lastMousePosition = { + x: event.clientX, + y: event.clientY + }; - if ( x1 > x2 ) { - tmp = x2; x2 = x1; x1 = tmp; + var actualTarget = $( event.target ).closest( ".ui-menu-item" ), + target = $( event.currentTarget ); + + // Ignore bubbled events on parent items, see #11641 + if ( actualTarget[ 0 ] !== target[ 0 ] ) { + return; } - if ( y1 > y2 ) { - tmp = y2; y2 = y1; y1 = tmp; + + // If the item is already active, there's nothing to do + if ( target.is( ".ui-state-active" ) ) { + return; } - this.helper.css( { left: x1, top: y1, width: x2 - x1, height: y2 - y1 } ); - this.selectees.each( function() { - var selectee = $.data( this, "selectable-item" ), - hit = false, - offset = {}; + // Remove ui-state-active class from siblings of the newly focused menu item + // to avoid a jump caused by adjacent elements both having a class with a border + this._removeClass( target.siblings().children( ".ui-state-active" ), + null, "ui-state-active" ); + this.focus( event, target ); + }, - //prevent helper from being selected if appendTo: selectable - if ( !selectee || selectee.element === that.element[ 0 ] ) { - return; + _destroy: function() { + var items = this.element.find( ".ui-menu-item" ) + .removeAttr( "role aria-disabled" ), + submenus = items.children( ".ui-menu-item-wrapper" ) + .removeUniqueId() + .removeAttr( "tabIndex role aria-haspopup" ); + + // Destroy (sub)menus + this.element + .removeAttr( "aria-activedescendant" ) + .find( ".ui-menu" ).addBack() + .removeAttr( "role aria-labelledby aria-expanded aria-hidden aria-disabled " + + "tabIndex" ) + .removeUniqueId() + .show(); + + submenus.children().each( function() { + var elem = $( this ); + if ( elem.data( "ui-menu-submenu-caret" ) ) { + elem.remove(); } + } ); + }, - offset.left = selectee.left + that.elementPos.left; - offset.right = selectee.right + that.elementPos.left; - offset.top = selectee.top + that.elementPos.top; - offset.bottom = selectee.bottom + that.elementPos.top; + _keydown: function( event ) { + var match, prev, character, skip, + preventDefault = true; - if ( options.tolerance === "touch" ) { - hit = ( !( offset.left > x2 || offset.right < x1 || offset.top > y2 || - offset.bottom < y1 ) ); - } else if ( options.tolerance === "fit" ) { - hit = ( offset.left > x1 && offset.right < x2 && offset.top > y1 && - offset.bottom < y2 ); + switch ( event.keyCode ) { + case $.ui.keyCode.PAGE_UP: + this.previousPage( event ); + break; + case $.ui.keyCode.PAGE_DOWN: + this.nextPage( event ); + break; + case $.ui.keyCode.HOME: + this._move( "first", "first", event ); + break; + case $.ui.keyCode.END: + this._move( "last", "last", event ); + break; + case $.ui.keyCode.UP: + this.previous( event ); + break; + case $.ui.keyCode.DOWN: + this.next( event ); + break; + case $.ui.keyCode.LEFT: + this.collapse( event ); + break; + case $.ui.keyCode.RIGHT: + if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { + this.expand( event ); } + break; + case $.ui.keyCode.ENTER: + case $.ui.keyCode.SPACE: + this._activate( event ); + break; + case $.ui.keyCode.ESCAPE: + this.collapse( event ); + break; + default: + preventDefault = false; + prev = this.previousFilter || ""; + skip = false; - if ( hit ) { + // Support number pad values + character = event.keyCode >= 96 && event.keyCode <= 105 ? + ( event.keyCode - 96 ).toString() : String.fromCharCode( event.keyCode ); - // SELECT - if ( selectee.selected ) { - that._removeClass( selectee.$element, "ui-selected" ); - selectee.selected = false; - } - if ( selectee.unselecting ) { - that._removeClass( selectee.$element, "ui-unselecting" ); - selectee.unselecting = false; - } - if ( !selectee.selecting ) { - that._addClass( selectee.$element, "ui-selecting" ); - selectee.selecting = true; + clearTimeout( this.filterTimer ); - // selectable SELECTING callback - that._trigger( "selecting", event, { - selecting: selectee.element - } ); - } + if ( character === prev ) { + skip = true; } else { + character = prev + character; + } - // UNSELECT - if ( selectee.selecting ) { - if ( ( event.metaKey || event.ctrlKey ) && selectee.startselected ) { - that._removeClass( selectee.$element, "ui-selecting" ); - selectee.selecting = false; - that._addClass( selectee.$element, "ui-selected" ); - selectee.selected = true; - } else { - that._removeClass( selectee.$element, "ui-selecting" ); - selectee.selecting = false; - if ( selectee.startselected ) { - that._addClass( selectee.$element, "ui-unselecting" ); - selectee.unselecting = true; - } - - // selectable UNSELECTING callback - that._trigger( "unselecting", event, { - unselecting: selectee.element - } ); - } - } - if ( selectee.selected ) { - if ( !event.metaKey && !event.ctrlKey && !selectee.startselected ) { - that._removeClass( selectee.$element, "ui-selected" ); - selectee.selected = false; + match = this._filterMenuItems( character ); + match = skip && match.index( this.active.next() ) !== -1 ? + this.active.nextAll( ".ui-menu-item" ) : + match; - that._addClass( selectee.$element, "ui-unselecting" ); - selectee.unselecting = true; + // If no matches on the current filter, reset to the last character pressed + // to move down the menu to the first item that starts with that character + if ( !match.length ) { + character = String.fromCharCode( event.keyCode ); + match = this._filterMenuItems( character ); + } - // selectable UNSELECTING callback - that._trigger( "unselecting", event, { - unselecting: selectee.element - } ); - } - } + if ( match.length ) { + this.focus( event, match ); + this.previousFilter = character; + this.filterTimer = this._delay( function() { + delete this.previousFilter; + }, 1000 ); + } else { + delete this.previousFilter; } - } ); + } - return false; + if ( preventDefault ) { + event.preventDefault(); + } }, - _mouseStop: function( event ) { - var that = this; - - this.dragged = false; + _activate: function( event ) { + if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { + if ( this.active.children( "[aria-haspopup='true']" ).length ) { + this.expand( event ); + } else { + this.select( event ); + } + } + }, - $( ".ui-unselecting", this.element[ 0 ] ).each( function() { - var selectee = $.data( this, "selectable-item" ); - that._removeClass( selectee.$element, "ui-unselecting" ); - selectee.unselecting = false; - selectee.startselected = false; - that._trigger( "unselected", event, { - unselected: selectee.element - } ); - } ); - $( ".ui-selecting", this.element[ 0 ] ).each( function() { - var selectee = $.data( this, "selectable-item" ); - that._removeClass( selectee.$element, "ui-selecting" ) - ._addClass( selectee.$element, "ui-selected" ); - selectee.selecting = false; - selectee.selected = true; - selectee.startselected = true; - that._trigger( "selected", event, { - selected: selectee.element - } ); - } ); - this._trigger( "stop", event ); + refresh: function() { + var menus, items, newSubmenus, newItems, newWrappers, + that = this, + icon = this.options.icons.submenu, + submenus = this.element.find( this.options.menus ); - this.helper.remove(); + this._toggleClass( "ui-menu-icons", null, !!this.element.find( ".ui-icon" ).length ); - return false; - } + // Initialize nested menus + newSubmenus = submenus.filter( ":not(.ui-menu)" ) + .hide() + .attr( { + role: this.options.role, + "aria-hidden": "true", + "aria-expanded": "false" + } ) + .each( function() { + var menu = $( this ), + item = menu.prev(), + submenuCaret = $( "<span>" ).data( "ui-menu-submenu-caret", true ); -} ); + that._addClass( submenuCaret, "ui-menu-icon", "ui-icon " + icon ); + item + .attr( "aria-haspopup", "true" ) + .prepend( submenuCaret ); + menu.attr( "aria-labelledby", item.attr( "id" ) ); + } ); + this._addClass( newSubmenus, "ui-menu", "ui-widget ui-widget-content ui-front" ); -/*! - * jQuery UI Sortable 1.13.1 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ + menus = submenus.add( this.element ); + items = menus.find( this.options.items ); -//>>label: Sortable -//>>group: Interactions -//>>description: Enables items in a list to be sorted using the mouse. -//>>docs: http://api.jqueryui.com/sortable/ -//>>demos: http://jqueryui.com/sortable/ -//>>css.structure: ../../themes/base/sortable.css + // Initialize menu-items containing spaces and/or dashes only as dividers + items.not( ".ui-menu-item" ).each( function() { + var item = $( this ); + if ( that._isDivider( item ) ) { + that._addClass( item, "ui-menu-divider", "ui-widget-content" ); + } + } ); + // Don't refresh list items that are already adapted + newItems = items.not( ".ui-menu-item, .ui-menu-divider" ); + newWrappers = newItems.children() + .not( ".ui-menu" ) + .uniqueId() + .attr( { + tabIndex: -1, + role: this._itemRole() + } ); + this._addClass( newItems, "ui-menu-item" ) + ._addClass( newWrappers, "ui-menu-item-wrapper" ); -var widgetsSortable = $.widget( "ui.sortable", $.ui.mouse, { - version: "1.13.1", - widgetEventPrefix: "sort", - ready: false, - options: { - appendTo: "parent", - axis: false, - connectWith: false, - containment: false, - cursor: "auto", - cursorAt: false, - dropOnEmpty: true, - forcePlaceholderSize: false, - forceHelperSize: false, - grid: false, - handle: false, - helper: "original", - items: "> *", - opacity: false, - placeholder: false, - revert: false, - scroll: true, - scrollSensitivity: 20, - scrollSpeed: 20, - scope: "default", - tolerance: "intersect", - zIndex: 1000, + // Add aria-disabled attribute to any disabled menu item + items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" ); - // Callbacks - activate: null, - beforeStop: null, - change: null, - deactivate: null, - out: null, - over: null, - receive: null, - remove: null, - sort: null, - start: null, - stop: null, - update: null + // If the active item has been removed, blur the menu + if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { + this.blur(); + } }, - _isOverAxis: function( x, reference, size ) { - return ( x >= reference ) && ( x < ( reference + size ) ); + _itemRole: function() { + return { + menu: "menuitem", + listbox: "option" + }[ this.options.role ]; }, - _isFloating: function( item ) { - return ( /left|right/ ).test( item.css( "float" ) ) || - ( /inline|table-cell/ ).test( item.css( "display" ) ); + _setOption: function( key, value ) { + if ( key === "icons" ) { + var icons = this.element.find( ".ui-menu-icon" ); + this._removeClass( icons, null, this.options.icons.submenu ) + ._addClass( icons, null, value.submenu ); + } + this._super( key, value ); }, - _create: function() { - this.containerCache = {}; - this._addClass( "ui-sortable" ); + _setOptionDisabled: function( value ) { + this._super( value ); - //Get the items - this.refresh(); + this.element.attr( "aria-disabled", String( value ) ); + this._toggleClass( null, "ui-state-disabled", !!value ); + }, - //Let's determine the parent's offset - this.offset = this.element.offset(); + focus: function( event, item ) { + var nested, focused, activeParent; + this.blur( event, event && event.type === "focus" ); - //Initialize mouse events for interaction - this._mouseInit(); + this._scrollIntoView( item ); - this._setHandleClassName(); + this.active = item.first(); - //We're ready to go - this.ready = true; - - }, - - _setOption: function( key, value ) { - this._super( key, value ); + focused = this.active.children( ".ui-menu-item-wrapper" ); + this._addClass( focused, null, "ui-state-active" ); - if ( key === "handle" ) { - this._setHandleClassName(); + // Only update aria-activedescendant if there's a role + // otherwise we assume focus is managed elsewhere + if ( this.options.role ) { + this.element.attr( "aria-activedescendant", focused.attr( "id" ) ); } - }, - - _setHandleClassName: function() { - var that = this; - this._removeClass( this.element.find( ".ui-sortable-handle" ), "ui-sortable-handle" ); - $.each( this.items, function() { - that._addClass( - this.instance.options.handle ? - this.item.find( this.instance.options.handle ) : - this.item, - "ui-sortable-handle" - ); - } ); - }, - _destroy: function() { - this._mouseDestroy(); + // Highlight active parent menu item, if any + activeParent = this.active + .parent() + .closest( ".ui-menu-item" ) + .children( ".ui-menu-item-wrapper" ); + this._addClass( activeParent, null, "ui-state-active" ); - for ( var i = this.items.length - 1; i >= 0; i-- ) { - this.items[ i ].item.removeData( this.widgetName + "-item" ); + if ( event && event.type === "keydown" ) { + this._close(); + } else { + this.timer = this._delay( function() { + this._close(); + }, this.delay ); } - return this; - }, - - _mouseCapture: function( event, overrideHandle ) { - var currentItem = null, - validHandle = false, - that = this; - - if ( this.reverting ) { - return false; + nested = item.children( ".ui-menu" ); + if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) { + this._startOpening( nested ); } + this.activeMenu = item.parent(); - if ( this.options.disabled || this.options.type === "static" ) { - return false; - } + this._trigger( "focus", event, { item: item } ); + }, - //We have to refresh the items data once first - this._refreshItems( event ); + _scrollIntoView: function( item ) { + var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight; + if ( this._hasScroll() ) { + borderTop = parseFloat( $.css( this.activeMenu[ 0 ], "borderTopWidth" ) ) || 0; + paddingTop = parseFloat( $.css( this.activeMenu[ 0 ], "paddingTop" ) ) || 0; + offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop; + scroll = this.activeMenu.scrollTop(); + elementHeight = this.activeMenu.height(); + itemHeight = item.outerHeight(); - //Find out if the clicked node (or one of its parents) is a actual item in this.items - $( event.target ).parents().each( function() { - if ( $.data( this, that.widgetName + "-item" ) === that ) { - currentItem = $( this ); - return false; + if ( offset < 0 ) { + this.activeMenu.scrollTop( scroll + offset ); + } else if ( offset + itemHeight > elementHeight ) { + this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight ); } - } ); - if ( $.data( event.target, that.widgetName + "-item" ) === that ) { - currentItem = $( event.target ); } + }, - if ( !currentItem ) { - return false; + blur: function( event, fromFocus ) { + if ( !fromFocus ) { + clearTimeout( this.timer ); } - if ( this.options.handle && !overrideHandle ) { - $( this.options.handle, currentItem ).find( "*" ).addBack().each( function() { - if ( this === event.target ) { - validHandle = true; - } - } ); - if ( !validHandle ) { - return false; - } + + if ( !this.active ) { + return; } - this.currentItem = currentItem; - this._removeCurrentsFromItems(); - return true; + this._removeClass( this.active.children( ".ui-menu-item-wrapper" ), + null, "ui-state-active" ); + this._trigger( "blur", event, { item: this.active } ); + this.active = null; }, - _mouseStart: function( event, overrideHandle, noActivation ) { + _startOpening: function( submenu ) { + clearTimeout( this.timer ); - var i, body, - o = this.options; + // Don't open if already open fixes a Firefox bug that caused a .5 pixel + // shift in the submenu position when mousing over the caret icon + if ( submenu.attr( "aria-hidden" ) !== "true" ) { + return; + } - this.currentContainer = this; + this.timer = this._delay( function() { + this._close(); + this._open( submenu ); + }, this.delay ); + }, - //We only need to call refreshPositions, because the refreshItems call has been moved to - // mouseCapture - this.refreshPositions(); + _open: function( submenu ) { + var position = $.extend( { + of: this.active + }, this.options.position ); - //Prepare the dragged items parent - this.appendTo = $( o.appendTo !== "parent" ? - o.appendTo : - this.currentItem.parent() ); + clearTimeout( this.timer ); + this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) ) + .hide() + .attr( "aria-hidden", "true" ); - //Create and append the visible helper - this.helper = this._createHelper( event ); + submenu + .show() + .removeAttr( "aria-hidden" ) + .attr( "aria-expanded", "true" ) + .position( position ); + }, - //Cache the helper size - this._cacheHelperProportions(); + collapseAll: function( event, all ) { + clearTimeout( this.timer ); + this.timer = this._delay( function() { - /* - * - Position generation - - * This block generates everything position related - it's the core of draggables. - */ + // If we were passed an event, look for the submenu that contains the event + var currentMenu = all ? this.element : + $( event && event.target ).closest( this.element.find( ".ui-menu" ) ); - //Cache the margins of the original element - this._cacheMargins(); + // If we found no valid submenu ancestor, use the main menu to close all + // sub menus anyway + if ( !currentMenu.length ) { + currentMenu = this.element; + } - //The element's absolute position on the page minus margins - this.offset = this.currentItem.offset(); - this.offset = { - top: this.offset.top - this.margins.top, - left: this.offset.left - this.margins.left - }; + this._close( currentMenu ); - $.extend( this.offset, { - click: { //Where the click happened, relative to the element - left: event.pageX - this.offset.left, - top: event.pageY - this.offset.top - }, + this.blur( event ); - // This is a relative to absolute position minus the actual position calculation - - // only used for relative positioned helper - relative: this._getRelativeOffset() - } ); + // Work around active item staying active after menu is blurred + this._removeClass( currentMenu.find( ".ui-state-active" ), null, "ui-state-active" ); - // After we get the helper offset, but before we get the parent offset we can - // change the helper's position to absolute - // TODO: Still need to figure out a way to make relative sorting possible - this.helper.css( "position", "absolute" ); - this.cssPosition = this.helper.css( "position" ); + this.activeMenu = currentMenu; + }, all ? 0 : this.delay ); + }, - //Adjust the mouse offset relative to the helper if "cursorAt" is supplied - if ( o.cursorAt ) { - this._adjustOffsetFromHelper( o.cursorAt ); + // With no arguments, closes the currently active menu - if nothing is active + // it closes all menus. If passed an argument, it will search for menus BELOW + _close: function( startMenu ) { + if ( !startMenu ) { + startMenu = this.active ? this.active.parent() : this.element; } - //Cache the former DOM position - this.domPosition = { - prev: this.currentItem.prev()[ 0 ], - parent: this.currentItem.parent()[ 0 ] - }; - - // If the helper is not the original, hide the original so it's not playing any role during - // the drag, won't cause anything bad this way - if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) { - this.currentItem.hide(); - } + startMenu.find( ".ui-menu" ) + .hide() + .attr( "aria-hidden", "true" ) + .attr( "aria-expanded", "false" ); + }, - //Create the placeholder - this._createPlaceholder(); + _closeOnDocumentClick: function( event ) { + return !$( event.target ).closest( ".ui-menu" ).length; + }, - //Get the next scrolling parent - this.scrollParent = this.placeholder.scrollParent(); + _isDivider: function( item ) { - $.extend( this.offset, { - parent: this._getParentOffset() - } ); + // Match hyphen, em dash, en dash + return !/[^\-\u2014\u2013\s]/.test( item.text() ); + }, - //Set a containment if given in the options - if ( o.containment ) { - this._setContainment(); + collapse: function( event ) { + var newItem = this.active && + this.active.parent().closest( ".ui-menu-item", this.element ); + if ( newItem && newItem.length ) { + this._close(); + this.focus( event, newItem ); } + }, - if ( o.cursor && o.cursor !== "auto" ) { // cursor option - body = this.document.find( "body" ); + expand: function( event ) { + var newItem = this.active && this._menuItems( this.active.children( ".ui-menu" ) ).first(); - // Support: IE - this.storedCursor = body.css( "cursor" ); - body.css( "cursor", o.cursor ); + if ( newItem && newItem.length ) { + this._open( newItem.parent() ); - this.storedStylesheet = - $( "<style>*{ cursor: " + o.cursor + " !important; }</style>" ).appendTo( body ); - } - - // We need to make sure to grab the zIndex before setting the - // opacity, because setting the opacity to anything lower than 1 - // causes the zIndex to change from "auto" to 0. - if ( o.zIndex ) { // zIndex option - if ( this.helper.css( "zIndex" ) ) { - this._storedZIndex = this.helper.css( "zIndex" ); - } - this.helper.css( "zIndex", o.zIndex ); + // Delay so Firefox will not hide activedescendant change in expanding submenu from AT + this._delay( function() { + this.focus( event, newItem ); + } ); } + }, - if ( o.opacity ) { // opacity option - if ( this.helper.css( "opacity" ) ) { - this._storedOpacity = this.helper.css( "opacity" ); - } - this.helper.css( "opacity", o.opacity ); - } + next: function( event ) { + this._move( "next", "first", event ); + }, - //Prepare scrolling - if ( this.scrollParent[ 0 ] !== this.document[ 0 ] && - this.scrollParent[ 0 ].tagName !== "HTML" ) { - this.overflowOffset = this.scrollParent.offset(); - } + previous: function( event ) { + this._move( "prev", "last", event ); + }, - //Call callbacks - this._trigger( "start", event, this._uiHash() ); + isFirstItem: function() { + return this.active && !this.active.prevAll( ".ui-menu-item" ).length; + }, - //Recache the helper size - if ( !this._preserveHelperProportions ) { - this._cacheHelperProportions(); - } + isLastItem: function() { + return this.active && !this.active.nextAll( ".ui-menu-item" ).length; + }, - //Post "activate" events to possible containers - if ( !noActivation ) { - for ( i = this.containers.length - 1; i >= 0; i-- ) { - this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) ); - } - } + _menuItems: function( menu ) { + return ( menu || this.element ) + .find( this.options.items ) + .filter( ".ui-menu-item" ); + }, - //Prepare possible droppables - if ( $.ui.ddmanager ) { - $.ui.ddmanager.current = this; + _move: function( direction, filter, event ) { + var next; + if ( this.active ) { + if ( direction === "first" || direction === "last" ) { + next = this.active + [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" ) + .last(); + } else { + next = this.active + [ direction + "All" ]( ".ui-menu-item" ) + .first(); + } } - - if ( $.ui.ddmanager && !o.dropBehaviour ) { - $.ui.ddmanager.prepareOffsets( this, event ); + if ( !next || !next.length || !this.active ) { + next = this._menuItems( this.activeMenu )[ filter ](); } - this.dragging = true; - - this._addClass( this.helper, "ui-sortable-helper" ); + this.focus( event, next ); + }, - //Move the helper, if needed - if ( !this.helper.parent().is( this.appendTo ) ) { - this.helper.detach().appendTo( this.appendTo ); + nextPage: function( event ) { + var item, base, height; - //Update position - this.offset.parent = this._getParentOffset(); + if ( !this.active ) { + this.next( event ); + return; } + if ( this.isLastItem() ) { + return; + } + if ( this._hasScroll() ) { + base = this.active.offset().top; + height = this.element.innerHeight(); - //Generate the original position - this.position = this.originalPosition = this._generatePosition( event ); - this.originalPageX = event.pageX; - this.originalPageY = event.pageY; - this.lastPositionAbs = this.positionAbs = this._convertPositionTo( "absolute" ); - - this._mouseDrag( event ); + // jQuery 3.2 doesn't include scrollbars in innerHeight, add it back. + if ( $.fn.jquery.indexOf( "3.2." ) === 0 ) { + height += this.element[ 0 ].offsetHeight - this.element.outerHeight(); + } - return true; + this.active.nextAll( ".ui-menu-item" ).each( function() { + item = $( this ); + return item.offset().top - base - height < 0; + } ); + this.focus( event, item ); + } else { + this.focus( event, this._menuItems( this.activeMenu ) + [ !this.active ? "first" : "last" ]() ); + } }, - _scroll: function( event ) { - var o = this.options, - scrolled = false; - - if ( this.scrollParent[ 0 ] !== this.document[ 0 ] && - this.scrollParent[ 0 ].tagName !== "HTML" ) { + previousPage: function( event ) { + var item, base, height; + if ( !this.active ) { + this.next( event ); + return; + } + if ( this.isFirstItem() ) { + return; + } + if ( this._hasScroll() ) { + base = this.active.offset().top; + height = this.element.innerHeight(); - if ( ( this.overflowOffset.top + this.scrollParent[ 0 ].offsetHeight ) - - event.pageY < o.scrollSensitivity ) { - this.scrollParent[ 0 ].scrollTop = - scrolled = this.scrollParent[ 0 ].scrollTop + o.scrollSpeed; - } else if ( event.pageY - this.overflowOffset.top < o.scrollSensitivity ) { - this.scrollParent[ 0 ].scrollTop = - scrolled = this.scrollParent[ 0 ].scrollTop - o.scrollSpeed; + // jQuery 3.2 doesn't include scrollbars in innerHeight, add it back. + if ( $.fn.jquery.indexOf( "3.2." ) === 0 ) { + height += this.element[ 0 ].offsetHeight - this.element.outerHeight(); } - if ( ( this.overflowOffset.left + this.scrollParent[ 0 ].offsetWidth ) - - event.pageX < o.scrollSensitivity ) { - this.scrollParent[ 0 ].scrollLeft = scrolled = - this.scrollParent[ 0 ].scrollLeft + o.scrollSpeed; - } else if ( event.pageX - this.overflowOffset.left < o.scrollSensitivity ) { - this.scrollParent[ 0 ].scrollLeft = scrolled = - this.scrollParent[ 0 ].scrollLeft - o.scrollSpeed; - } + this.active.prevAll( ".ui-menu-item" ).each( function() { + item = $( this ); + return item.offset().top - base + height > 0; + } ); + this.focus( event, item ); } else { - - if ( event.pageY - this.document.scrollTop() < o.scrollSensitivity ) { - scrolled = this.document.scrollTop( this.document.scrollTop() - o.scrollSpeed ); - } else if ( this.window.height() - ( event.pageY - this.document.scrollTop() ) < - o.scrollSensitivity ) { - scrolled = this.document.scrollTop( this.document.scrollTop() + o.scrollSpeed ); - } - - if ( event.pageX - this.document.scrollLeft() < o.scrollSensitivity ) { - scrolled = this.document.scrollLeft( - this.document.scrollLeft() - o.scrollSpeed - ); - } else if ( this.window.width() - ( event.pageX - this.document.scrollLeft() ) < - o.scrollSensitivity ) { - scrolled = this.document.scrollLeft( - this.document.scrollLeft() + o.scrollSpeed - ); - } - + this.focus( event, this._menuItems( this.activeMenu ).first() ); } - - return scrolled; }, - _mouseDrag: function( event ) { - var i, item, itemElement, intersection, - o = this.options; + _hasScroll: function() { + return this.element.outerHeight() < this.element.prop( "scrollHeight" ); + }, - //Compute the helpers position - this.position = this._generatePosition( event ); - this.positionAbs = this._convertPositionTo( "absolute" ); + select: function( event ) { - //Set the helper position - if ( !this.options.axis || this.options.axis !== "y" ) { - this.helper[ 0 ].style.left = this.position.left + "px"; - } - if ( !this.options.axis || this.options.axis !== "x" ) { - this.helper[ 0 ].style.top = this.position.top + "px"; + // TODO: It should never be possible to not have an active item at this + // point, but the tests don't trigger mouseenter before click. + this.active = this.active || $( event.target ).closest( ".ui-menu-item" ); + var ui = { item: this.active }; + if ( !this.active.has( ".ui-menu" ).length ) { + this.collapseAll( event, true ); } + this._trigger( "select", event, ui ); + }, - //Do scrolling - if ( o.scroll ) { - if ( this._scroll( event ) !== false ) { + _filterMenuItems: function( character ) { + var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ), + regex = new RegExp( "^" + escapedCharacter, "i" ); - //Update item positions used in position checks - this._refreshItemPositions( true ); + return this.activeMenu + .find( this.options.items ) - if ( $.ui.ddmanager && !o.dropBehaviour ) { - $.ui.ddmanager.prepareOffsets( this, event ); - } - } - } + // Only match on items, not dividers or other content (#10571) + .filter( ".ui-menu-item" ) + .filter( function() { + return regex.test( + String.prototype.trim.call( + $( this ).children( ".ui-menu-item-wrapper" ).text() ) ); + } ); + } +} ); - this.dragDirection = { - vertical: this._getDragVerticalDirection(), - horizontal: this._getDragHorizontalDirection() - }; - //Rearrange - for ( i = this.items.length - 1; i >= 0; i-- ) { +/*! + * jQuery UI Autocomplete 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ - //Cache variables and intersection, continue if no intersection - item = this.items[ i ]; - itemElement = item.item[ 0 ]; - intersection = this._intersectsWithPointer( item ); - if ( !intersection ) { - continue; - } +//>>label: Autocomplete +//>>group: Widgets +//>>description: Lists suggested words as the user is typing. +//>>docs: http://api.jqueryui.com/autocomplete/ +//>>demos: http://jqueryui.com/autocomplete/ +//>>css.structure: ../../themes/base/core.css +//>>css.structure: ../../themes/base/autocomplete.css +//>>css.theme: ../../themes/base/theme.css - // Only put the placeholder inside the current Container, skip all - // items from other containers. This works because when moving - // an item from one container to another the - // currentContainer is switched before the placeholder is moved. - // - // Without this, moving items in "sub-sortables" can cause - // the placeholder to jitter between the outer and inner container. - if ( item.instance !== this.currentContainer ) { - continue; - } - // Cannot intersect with itself - // no useless actions that have been done before - // no action if the item moved is the parent of the item checked - if ( itemElement !== this.currentItem[ 0 ] && - this.placeholder[ intersection === 1 ? - "next" : "prev" ]()[ 0 ] !== itemElement && - !$.contains( this.placeholder[ 0 ], itemElement ) && - ( this.options.type === "semi-dynamic" ? - !$.contains( this.element[ 0 ], itemElement ) : - true - ) - ) { +$.widget( "ui.autocomplete", { + version: "1.13.2", + defaultElement: "<input>", + options: { + appendTo: null, + autoFocus: false, + delay: 300, + minLength: 1, + position: { + my: "left top", + at: "left bottom", + collision: "none" + }, + source: null, - this.direction = intersection === 1 ? "down" : "up"; + // Callbacks + change: null, + close: null, + focus: null, + open: null, + response: null, + search: null, + select: null + }, - if ( this.options.tolerance === "pointer" || - this._intersectsWithSides( item ) ) { - this._rearrange( event, item ); - } else { - break; - } + requestIndex: 0, + pending: 0, + liveRegionTimer: null, - this._trigger( "change", event, this._uiHash() ); - break; - } - } + _create: function() { - //Post events to containers - this._contactContainers( event ); + // Some browsers only repeat keydown events, not keypress events, + // so we use the suppressKeyPress flag to determine if we've already + // handled the keydown event. #7269 + // Unfortunately the code for & in keypress is the same as the up arrow, + // so we use the suppressKeyPressRepeat flag to avoid handling keypress + // events when we know the keydown event was used to modify the + // search term. #7799 + var suppressKeyPress, suppressKeyPressRepeat, suppressInput, + nodeName = this.element[ 0 ].nodeName.toLowerCase(), + isTextarea = nodeName === "textarea", + isInput = nodeName === "input"; - //Interconnect with droppables - if ( $.ui.ddmanager ) { - $.ui.ddmanager.drag( this, event ); - } + // Textareas are always multi-line + // Inputs are always single-line, even if inside a contentEditable element + // IE also treats inputs as contentEditable + // All other element types are determined by whether or not they're contentEditable + this.isMultiLine = isTextarea || !isInput && this._isContentEditable( this.element ); - //Call callbacks - this._trigger( "sort", event, this._uiHash() ); + this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ]; + this.isNewMenu = true; - this.lastPositionAbs = this.positionAbs; - return false; + this._addClass( "ui-autocomplete-input" ); + this.element.attr( "autocomplete", "off" ); - }, + this._on( this.element, { + keydown: function( event ) { + if ( this.element.prop( "readOnly" ) ) { + suppressKeyPress = true; + suppressInput = true; + suppressKeyPressRepeat = true; + return; + } - _mouseStop: function( event, noPropagation ) { + suppressKeyPress = false; + suppressInput = false; + suppressKeyPressRepeat = false; + var keyCode = $.ui.keyCode; + switch ( event.keyCode ) { + case keyCode.PAGE_UP: + suppressKeyPress = true; + this._move( "previousPage", event ); + break; + case keyCode.PAGE_DOWN: + suppressKeyPress = true; + this._move( "nextPage", event ); + break; + case keyCode.UP: + suppressKeyPress = true; + this._keyEvent( "previous", event ); + break; + case keyCode.DOWN: + suppressKeyPress = true; + this._keyEvent( "next", event ); + break; + case keyCode.ENTER: - if ( !event ) { - return; - } + // when menu is open and has focus + if ( this.menu.active ) { - //If we are using droppables, inform the manager about the drop - if ( $.ui.ddmanager && !this.options.dropBehaviour ) { - $.ui.ddmanager.drop( this, event ); - } + // #6055 - Opera still allows the keypress to occur + // which causes forms to submit + suppressKeyPress = true; + event.preventDefault(); + this.menu.select( event ); + } + break; + case keyCode.TAB: + if ( this.menu.active ) { + this.menu.select( event ); + } + break; + case keyCode.ESCAPE: + if ( this.menu.element.is( ":visible" ) ) { + if ( !this.isMultiLine ) { + this._value( this.term ); + } + this.close( event ); - if ( this.options.revert ) { - var that = this, - cur = this.placeholder.offset(), - axis = this.options.axis, - animation = {}; + // Different browsers have different default behavior for escape + // Single press can mean undo or clear + // Double press in IE means clear the whole form + event.preventDefault(); + } + break; + default: + suppressKeyPressRepeat = true; - if ( !axis || axis === "x" ) { - animation.left = cur.left - this.offset.parent.left - this.margins.left + - ( this.offsetParent[ 0 ] === this.document[ 0 ].body ? - 0 : - this.offsetParent[ 0 ].scrollLeft - ); - } - if ( !axis || axis === "y" ) { - animation.top = cur.top - this.offset.parent.top - this.margins.top + - ( this.offsetParent[ 0 ] === this.document[ 0 ].body ? - 0 : - this.offsetParent[ 0 ].scrollTop - ); - } - this.reverting = true; - $( this.helper ).animate( - animation, - parseInt( this.options.revert, 10 ) || 500, - function() { - that._clear( event ); + // search timeout should be triggered before the input value is changed + this._searchTimeout( event ); + break; + } + }, + keypress: function( event ) { + if ( suppressKeyPress ) { + suppressKeyPress = false; + if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { + event.preventDefault(); + } + return; + } + if ( suppressKeyPressRepeat ) { + return; } - ); - } else { - this._clear( event, noPropagation ); - } - return false; + // Replicate some key handlers to allow them to repeat in Firefox and Opera + var keyCode = $.ui.keyCode; + switch ( event.keyCode ) { + case keyCode.PAGE_UP: + this._move( "previousPage", event ); + break; + case keyCode.PAGE_DOWN: + this._move( "nextPage", event ); + break; + case keyCode.UP: + this._keyEvent( "previous", event ); + break; + case keyCode.DOWN: + this._keyEvent( "next", event ); + break; + } + }, + input: function( event ) { + if ( suppressInput ) { + suppressInput = false; + event.preventDefault(); + return; + } + this._searchTimeout( event ); + }, + focus: function() { + this.selectedItem = null; + this.previous = this._value(); + }, + blur: function( event ) { + clearTimeout( this.searching ); + this.close( event ); + this._change( event ); + } + } ); - }, + this._initSource(); + this.menu = $( "<ul>" ) + .appendTo( this._appendTo() ) + .menu( { - cancel: function() { + // disable ARIA support, the live region takes care of that + role: null + } ) + .hide() - if ( this.dragging ) { + // Support: IE 11 only, Edge <= 14 + // For other browsers, we preventDefault() on the mousedown event + // to keep the dropdown from taking focus from the input. This doesn't + // work for IE/Edge, causing problems with selection and scrolling (#9638) + // Happily, IE and Edge support an "unselectable" attribute that + // prevents an element from receiving focus, exactly what we want here. + .attr( { + "unselectable": "on" + } ) + .menu( "instance" ); - this._mouseUp( new $.Event( "mouseup", { target: null } ) ); + this._addClass( this.menu.element, "ui-autocomplete", "ui-front" ); + this._on( this.menu.element, { + mousedown: function( event ) { - if ( this.options.helper === "original" ) { - this.currentItem.css( this._storedCSS ); - this._removeClass( this.currentItem, "ui-sortable-helper" ); - } else { - this.currentItem.show(); - } + // Prevent moving focus out of the text field + event.preventDefault(); + }, + menufocus: function( event, ui ) { + var label, item; - //Post deactivating events to containers - for ( var i = this.containers.length - 1; i >= 0; i-- ) { - this.containers[ i ]._trigger( "deactivate", null, this._uiHash( this ) ); - if ( this.containers[ i ].containerCache.over ) { - this.containers[ i ]._trigger( "out", null, this._uiHash( this ) ); - this.containers[ i ].containerCache.over = 0; - } - } + // support: Firefox + // Prevent accidental activation of menu items in Firefox (#7024 #9118) + if ( this.isNewMenu ) { + this.isNewMenu = false; + if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) { + this.menu.blur(); - } + this.document.one( "mousemove", function() { + $( event.target ).trigger( event.originalEvent ); + } ); - if ( this.placeholder ) { + return; + } + } - //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, - // it unbinds ALL events from the original node! - if ( this.placeholder[ 0 ].parentNode ) { - this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] ); - } - if ( this.options.helper !== "original" && this.helper && - this.helper[ 0 ].parentNode ) { - this.helper.remove(); - } + item = ui.item.data( "ui-autocomplete-item" ); + if ( false !== this._trigger( "focus", event, { item: item } ) ) { - $.extend( this, { - helper: null, - dragging: false, - reverting: false, - _noFinalSort: null - } ); + // use value to match what will end up in the input, if it was a key event + if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) { + this._value( item.value ); + } + } - if ( this.domPosition.prev ) { - $( this.domPosition.prev ).after( this.currentItem ); - } else { - $( this.domPosition.parent ).prepend( this.currentItem ); - } - } + // Announce the value in the liveRegion + label = ui.item.attr( "aria-label" ) || item.value; + if ( label && String.prototype.trim.call( label ).length ) { + clearTimeout( this.liveRegionTimer ); + this.liveRegionTimer = this._delay( function() { + this.liveRegion.html( $( "<div>" ).text( label ) ); + }, 100 ); + } + }, + menuselect: function( event, ui ) { + var item = ui.item.data( "ui-autocomplete-item" ), + previous = this.previous; - return this; + // Only trigger when focus was lost (click on menu) + if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) { + this.element.trigger( "focus" ); + this.previous = previous; - }, + // #6109 - IE triggers two focus events and the second + // is asynchronous, so we need to reset the previous + // term synchronously and asynchronously :-( + this._delay( function() { + this.previous = previous; + this.selectedItem = item; + } ); + } - serialize: function( o ) { + if ( false !== this._trigger( "select", event, { item: item } ) ) { + this._value( item.value ); + } - var items = this._getItemsAsjQuery( o && o.connected ), - str = []; - o = o || {}; + // reset the term after the select event + // this allows custom select handling to work properly + this.term = this._value(); - $( items ).each( function() { - var res = ( $( o.item || this ).attr( o.attribute || "id" ) || "" ) - .match( o.expression || ( /(.+)[\-=_](.+)/ ) ); - if ( res ) { - str.push( - ( o.key || res[ 1 ] + "[]" ) + - "=" + ( o.key && o.expression ? res[ 1 ] : res[ 2 ] ) ); + this.close( event ); + this.selectedItem = item; } } ); - if ( !str.length && o.key ) { - str.push( o.key + "=" ); - } - - return str.join( "&" ); - - }, - - toArray: function( o ) { - - var items = this._getItemsAsjQuery( o && o.connected ), - ret = []; + this.liveRegion = $( "<div>", { + role: "status", + "aria-live": "assertive", + "aria-relevant": "additions" + } ) + .appendTo( this.document[ 0 ].body ); - o = o || {}; + this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" ); - items.each( function() { - ret.push( $( o.item || this ).attr( o.attribute || "id" ) || "" ); + // Turning off autocomplete prevents the browser from remembering the + // value when navigating through history, so we re-enable autocomplete + // if the page is unloaded before the widget is destroyed. #7790 + this._on( this.window, { + beforeunload: function() { + this.element.removeAttr( "autocomplete" ); + } } ); - return ret; - }, - /* Be careful with the following core functions */ - _intersectsWith: function( item ) { - - var x1 = this.positionAbs.left, - x2 = x1 + this.helperProportions.width, - y1 = this.positionAbs.top, - y2 = y1 + this.helperProportions.height, - l = item.left, - r = l + item.width, - t = item.top, - b = t + item.height, - dyClick = this.offset.click.top, - dxClick = this.offset.click.left, - isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && - ( y1 + dyClick ) < b ), - isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && - ( x1 + dxClick ) < r ), - isOverElement = isOverElementHeight && isOverElementWidth; - - if ( this.options.tolerance === "pointer" || - this.options.forcePointerForContainers || - ( this.options.tolerance !== "pointer" && - this.helperProportions[ this.floating ? "width" : "height" ] > - item[ this.floating ? "width" : "height" ] ) - ) { - return isOverElement; - } else { - - return ( l < x1 + ( this.helperProportions.width / 2 ) && // Right Half - x2 - ( this.helperProportions.width / 2 ) < r && // Left Half - t < y1 + ( this.helperProportions.height / 2 ) && // Bottom Half - y2 - ( this.helperProportions.height / 2 ) < b ); // Top Half - - } + _destroy: function() { + clearTimeout( this.searching ); + this.element.removeAttr( "autocomplete" ); + this.menu.element.remove(); + this.liveRegion.remove(); }, - _intersectsWithPointer: function( item ) { - var verticalDirection, horizontalDirection, - isOverElementHeight = ( this.options.axis === "x" ) || - this._isOverAxis( - this.positionAbs.top + this.offset.click.top, item.top, item.height ), - isOverElementWidth = ( this.options.axis === "y" ) || - this._isOverAxis( - this.positionAbs.left + this.offset.click.left, item.left, item.width ), - isOverElement = isOverElementHeight && isOverElementWidth; - - if ( !isOverElement ) { - return false; + _setOption: function( key, value ) { + this._super( key, value ); + if ( key === "source" ) { + this._initSource(); } + if ( key === "appendTo" ) { + this.menu.element.appendTo( this._appendTo() ); + } + if ( key === "disabled" && value && this.xhr ) { + this.xhr.abort(); + } + }, - verticalDirection = this.dragDirection.vertical; - horizontalDirection = this.dragDirection.horizontal; - - return this.floating ? - ( ( horizontalDirection === "right" || verticalDirection === "down" ) ? 2 : 1 ) : - ( verticalDirection && ( verticalDirection === "down" ? 2 : 1 ) ); + _isEventTargetInWidget: function( event ) { + var menuElement = this.menu.element[ 0 ]; + return event.target === this.element[ 0 ] || + event.target === menuElement || + $.contains( menuElement, event.target ); }, - _intersectsWithSides: function( item ) { + _closeOnClickOutside: function( event ) { + if ( !this._isEventTargetInWidget( event ) ) { + this.close(); + } + }, - var isOverBottomHalf = this._isOverAxis( this.positionAbs.top + - this.offset.click.top, item.top + ( item.height / 2 ), item.height ), - isOverRightHalf = this._isOverAxis( this.positionAbs.left + - this.offset.click.left, item.left + ( item.width / 2 ), item.width ), - verticalDirection = this.dragDirection.vertical, - horizontalDirection = this.dragDirection.horizontal; + _appendTo: function() { + var element = this.options.appendTo; - if ( this.floating && horizontalDirection ) { - return ( ( horizontalDirection === "right" && isOverRightHalf ) || - ( horizontalDirection === "left" && !isOverRightHalf ) ); - } else { - return verticalDirection && ( ( verticalDirection === "down" && isOverBottomHalf ) || - ( verticalDirection === "up" && !isOverBottomHalf ) ); + if ( element ) { + element = element.jquery || element.nodeType ? + $( element ) : + this.document.find( element ).eq( 0 ); } - }, + if ( !element || !element[ 0 ] ) { + element = this.element.closest( ".ui-front, dialog" ); + } - _getDragVerticalDirection: function() { - var delta = this.positionAbs.top - this.lastPositionAbs.top; - return delta !== 0 && ( delta > 0 ? "down" : "up" ); - }, + if ( !element.length ) { + element = this.document[ 0 ].body; + } - _getDragHorizontalDirection: function() { - var delta = this.positionAbs.left - this.lastPositionAbs.left; - return delta !== 0 && ( delta > 0 ? "right" : "left" ); + return element; }, - refresh: function( event ) { - this._refreshItems( event ); - this._setHandleClassName(); - this.refreshPositions(); - return this; - }, - - _connectWith: function() { - var options = this.options; - return options.connectWith.constructor === String ? - [ options.connectWith ] : - options.connectWith; + _initSource: function() { + var array, url, + that = this; + if ( Array.isArray( this.options.source ) ) { + array = this.options.source; + this.source = function( request, response ) { + response( $.ui.autocomplete.filter( array, request.term ) ); + }; + } else if ( typeof this.options.source === "string" ) { + url = this.options.source; + this.source = function( request, response ) { + if ( that.xhr ) { + that.xhr.abort(); + } + that.xhr = $.ajax( { + url: url, + data: request, + dataType: "json", + success: function( data ) { + response( data ); + }, + error: function() { + response( [] ); + } + } ); + }; + } else { + this.source = this.options.source; + } }, - _getItemsAsjQuery: function( connected ) { + _searchTimeout: function( event ) { + clearTimeout( this.searching ); + this.searching = this._delay( function() { - var i, j, cur, inst, - items = [], - queries = [], - connectWith = this._connectWith(); + // Search if the value has changed, or if the user retypes the same value (see #7434) + var equalValues = this.term === this._value(), + menuVisible = this.menu.element.is( ":visible" ), + modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey; - if ( connectWith && connected ) { - for ( i = connectWith.length - 1; i >= 0; i-- ) { - cur = $( connectWith[ i ], this.document[ 0 ] ); - for ( j = cur.length - 1; j >= 0; j-- ) { - inst = $.data( cur[ j ], this.widgetFullName ); - if ( inst && inst !== this && !inst.options.disabled ) { - queries.push( [ typeof inst.options.items === "function" ? - inst.options.items.call( inst.element ) : - $( inst.options.items, inst.element ) - .not( ".ui-sortable-helper" ) - .not( ".ui-sortable-placeholder" ), inst ] ); - } - } + if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) { + this.selectedItem = null; + this.search( null, event ); } - } + }, this.options.delay ); + }, - queries.push( [ typeof this.options.items === "function" ? - this.options.items - .call( this.element, null, { options: this.options, item: this.currentItem } ) : - $( this.options.items, this.element ) - .not( ".ui-sortable-helper" ) - .not( ".ui-sortable-placeholder" ), this ] ); + search: function( value, event ) { + value = value != null ? value : this._value(); - function addItems() { - items.push( this ); - } - for ( i = queries.length - 1; i >= 0; i-- ) { - queries[ i ][ 0 ].each( addItems ); + // Always save the actual value, not the one passed as an argument + this.term = this._value(); + + if ( value.length < this.options.minLength ) { + return this.close( event ); } - return $( items ); + if ( this._trigger( "search", event ) === false ) { + return; + } + return this._search( value ); }, - _removeCurrentsFromItems: function() { + _search: function( value ) { + this.pending++; + this._addClass( "ui-autocomplete-loading" ); + this.cancelSearch = false; - var list = this.currentItem.find( ":data(" + this.widgetName + "-item)" ); + this.source( { term: value }, this._response() ); + }, - this.items = $.grep( this.items, function( item ) { - for ( var j = 0; j < list.length; j++ ) { - if ( list[ j ] === item.item[ 0 ] ) { - return false; - } + _response: function() { + var index = ++this.requestIndex; + + return function( content ) { + if ( index === this.requestIndex ) { + this.__response( content ); } - return true; - } ); + this.pending--; + if ( !this.pending ) { + this._removeClass( "ui-autocomplete-loading" ); + } + }.bind( this ); }, - _refreshItems: function( event ) { - - this.items = []; - this.containers = [ this ]; - - var i, j, cur, inst, targetData, _queries, item, queriesLength, - items = this.items, - queries = [ [ typeof this.options.items === "function" ? - this.options.items.call( this.element[ 0 ], event, { item: this.currentItem } ) : - $( this.options.items, this.element ), this ] ], - connectWith = this._connectWith(); + __response: function( content ) { + if ( content ) { + content = this._normalize( content ); + } + this._trigger( "response", null, { content: content } ); + if ( !this.options.disabled && content && content.length && !this.cancelSearch ) { + this._suggest( content ); + this._trigger( "open" ); + } else { - //Shouldn't be run the first time through due to massive slow-down - if ( connectWith && this.ready ) { - for ( i = connectWith.length - 1; i >= 0; i-- ) { - cur = $( connectWith[ i ], this.document[ 0 ] ); - for ( j = cur.length - 1; j >= 0; j-- ) { - inst = $.data( cur[ j ], this.widgetFullName ); - if ( inst && inst !== this && !inst.options.disabled ) { - queries.push( [ typeof inst.options.items === "function" ? - inst.options.items - .call( inst.element[ 0 ], event, { item: this.currentItem } ) : - $( inst.options.items, inst.element ), inst ] ); - this.containers.push( inst ); - } - } - } + // use ._close() instead of .close() so we don't cancel future searches + this._close(); } + }, - for ( i = queries.length - 1; i >= 0; i-- ) { - targetData = queries[ i ][ 1 ]; - _queries = queries[ i ][ 0 ]; + close: function( event ) { + this.cancelSearch = true; + this._close( event ); + }, - for ( j = 0, queriesLength = _queries.length; j < queriesLength; j++ ) { - item = $( _queries[ j ] ); + _close: function( event ) { - // Data for target checking (mouse manager) - item.data( this.widgetName + "-item", targetData ); + // Remove the handler that closes the menu on outside clicks + this._off( this.document, "mousedown" ); - items.push( { - item: item, - instance: targetData, - width: 0, height: 0, - left: 0, top: 0 - } ); - } + if ( this.menu.element.is( ":visible" ) ) { + this.menu.element.hide(); + this.menu.blur(); + this.isNewMenu = true; + this._trigger( "close", event ); } - }, - _refreshItemPositions: function( fast ) { - var i, item, t, p; + _change: function( event ) { + if ( this.previous !== this._value() ) { + this._trigger( "change", event, { item: this.selectedItem } ); + } + }, - for ( i = this.items.length - 1; i >= 0; i-- ) { - item = this.items[ i ]; + _normalize: function( items ) { - //We ignore calculating positions of all connected containers when we're not over them - if ( this.currentContainer && item.instance !== this.currentContainer && - item.item[ 0 ] !== this.currentItem[ 0 ] ) { - continue; + // assume all items have the right format when the first item is complete + if ( items.length && items[ 0 ].label && items[ 0 ].value ) { + return items; + } + return $.map( items, function( item ) { + if ( typeof item === "string" ) { + return { + label: item, + value: item + }; } + return $.extend( {}, item, { + label: item.label || item.value, + value: item.value || item.label + } ); + } ); + }, - t = this.options.toleranceElement ? - $( this.options.toleranceElement, item.item ) : - item.item; + _suggest: function( items ) { + var ul = this.menu.element.empty(); + this._renderMenu( ul, items ); + this.isNewMenu = true; + this.menu.refresh(); - if ( !fast ) { - item.width = t.outerWidth(); - item.height = t.outerHeight(); - } + // Size and position menu + ul.show(); + this._resizeMenu(); + ul.position( $.extend( { + of: this.element + }, this.options.position ) ); - p = t.offset(); - item.left = p.left; - item.top = p.top; + if ( this.options.autoFocus ) { + this.menu.next(); } + + // Listen for interactions outside of the widget (#6642) + this._on( this.document, { + mousedown: "_closeOnClickOutside" + } ); }, - refreshPositions: function( fast ) { + _resizeMenu: function() { + var ul = this.menu.element; + ul.outerWidth( Math.max( - // Determine whether items are being displayed horizontally - this.floating = this.items.length ? - this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) : - false; + // Firefox wraps long text (possibly a rounding bug) + // so we add 1px to avoid the wrapping (#7513) + ul.width( "" ).outerWidth() + 1, + this.element.outerWidth() + ) ); + }, - // This has to be redone because due to the item being moved out/into the offsetParent, - // the offsetParent's position will change - if ( this.offsetParent && this.helper ) { - this.offset.parent = this._getParentOffset(); - } - - this._refreshItemPositions( fast ); - - var i, p; - - if ( this.options.custom && this.options.custom.refreshContainers ) { - this.options.custom.refreshContainers.call( this ); - } else { - for ( i = this.containers.length - 1; i >= 0; i-- ) { - p = this.containers[ i ].element.offset(); - this.containers[ i ].containerCache.left = p.left; - this.containers[ i ].containerCache.top = p.top; - this.containers[ i ].containerCache.width = - this.containers[ i ].element.outerWidth(); - this.containers[ i ].containerCache.height = - this.containers[ i ].element.outerHeight(); - } - } + _renderMenu: function( ul, items ) { + var that = this; + $.each( items, function( index, item ) { + that._renderItemData( ul, item ); + } ); + }, - return this; + _renderItemData: function( ul, item ) { + return this._renderItem( ul, item ).data( "ui-autocomplete-item", item ); }, - _createPlaceholder: function( that ) { - that = that || this; - var className, nodeName, - o = that.options; + _renderItem: function( ul, item ) { + return $( "<li>" ) + .append( $( "<div>" ).text( item.label ) ) + .appendTo( ul ); + }, - if ( !o.placeholder || o.placeholder.constructor === String ) { - className = o.placeholder; - nodeName = that.currentItem[ 0 ].nodeName.toLowerCase(); - o.placeholder = { - element: function() { + _move: function( direction, event ) { + if ( !this.menu.element.is( ":visible" ) ) { + this.search( null, event ); + return; + } + if ( this.menu.isFirstItem() && /^previous/.test( direction ) || + this.menu.isLastItem() && /^next/.test( direction ) ) { - var element = $( "<" + nodeName + ">", that.document[ 0 ] ); + if ( !this.isMultiLine ) { + this._value( this.term ); + } - that._addClass( element, "ui-sortable-placeholder", - className || that.currentItem[ 0 ].className ) - ._removeClass( element, "ui-sortable-helper" ); + this.menu.blur(); + return; + } + this.menu[ direction ]( event ); + }, - if ( nodeName === "tbody" ) { - that._createTrPlaceholder( - that.currentItem.find( "tr" ).eq( 0 ), - $( "<tr>", that.document[ 0 ] ).appendTo( element ) - ); - } else if ( nodeName === "tr" ) { - that._createTrPlaceholder( that.currentItem, element ); - } else if ( nodeName === "img" ) { - element.attr( "src", that.currentItem.attr( "src" ) ); - } + widget: function() { + return this.menu.element; + }, - if ( !className ) { - element.css( "visibility", "hidden" ); - } + _value: function() { + return this.valueMethod.apply( this.element, arguments ); + }, - return element; - }, - update: function( container, p ) { + _keyEvent: function( keyEvent, event ) { + if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { + this._move( keyEvent, event ); - // 1. If a className is set as 'placeholder option, we don't force sizes - - // the class is responsible for that - // 2. The option 'forcePlaceholderSize can be enabled to force it even if a - // class name is specified - if ( className && !o.forcePlaceholderSize ) { - return; - } + // Prevents moving cursor to beginning/end of the text field in some browsers + event.preventDefault(); + } + }, - // If the element doesn't have a actual height or width by itself (without - // styles coming from a stylesheet), it receives the inline height and width - // from the dragged item. Or, if it's a tbody or tr, it's going to have a height - // anyway since we're populating them with <td>s above, but they're unlikely to - // be the correct height on their own if the row heights are dynamic, so we'll - // always assign the height of the dragged item given forcePlaceholderSize - // is true. - if ( !p.height() || ( o.forcePlaceholderSize && - ( nodeName === "tbody" || nodeName === "tr" ) ) ) { - p.height( - that.currentItem.innerHeight() - - parseInt( that.currentItem.css( "paddingTop" ) || 0, 10 ) - - parseInt( that.currentItem.css( "paddingBottom" ) || 0, 10 ) ); - } - if ( !p.width() ) { - p.width( - that.currentItem.innerWidth() - - parseInt( that.currentItem.css( "paddingLeft" ) || 0, 10 ) - - parseInt( that.currentItem.css( "paddingRight" ) || 0, 10 ) ); - } - } - }; + // Support: Chrome <=50 + // We should be able to just use this.element.prop( "isContentEditable" ) + // but hidden elements always report false in Chrome. + // https://code.google.com/p/chromium/issues/detail?id=313082 + _isContentEditable: function( element ) { + if ( !element.length ) { + return false; } - //Create the placeholder - that.placeholder = $( o.placeholder.element.call( that.element, that.currentItem ) ); + var editable = element.prop( "contentEditable" ); - //Append it after the actual current item - that.currentItem.after( that.placeholder ); + if ( editable === "inherit" ) { + return this._isContentEditable( element.parent() ); + } - //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) - o.placeholder.update( that, that.placeholder ); + return editable === "true"; + } +} ); +$.extend( $.ui.autocomplete, { + escapeRegex: function( value ) { + return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ); }, - - _createTrPlaceholder: function( sourceTr, targetTr ) { - var that = this; - - sourceTr.children().each( function() { - $( "<td> </td>", that.document[ 0 ] ) - .attr( "colspan", $( this ).attr( "colspan" ) || 1 ) - .appendTo( targetTr ); + filter: function( array, term ) { + var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" ); + return $.grep( array, function( value ) { + return matcher.test( value.label || value.value || value ); } ); - }, + } +} ); - _contactContainers: function( event ) { - var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom, - floating, axis, - innermostContainer = null, - innermostIndex = null; +// Live region extension, adding a `messages` option +// NOTE: This is an experimental API. We are still investigating +// a full solution for string manipulation and internationalization. +$.widget( "ui.autocomplete", $.ui.autocomplete, { + options: { + messages: { + noResults: "No search results.", + results: function( amount ) { + return amount + ( amount > 1 ? " results are" : " result is" ) + + " available, use up and down arrow keys to navigate."; + } + } + }, - // Get innermost container that intersects with item - for ( i = this.containers.length - 1; i >= 0; i-- ) { + __response: function( content ) { + var message; + this._superApply( arguments ); + if ( this.options.disabled || this.cancelSearch ) { + return; + } + if ( content && content.length ) { + message = this.options.messages.results( content.length ); + } else { + message = this.options.messages.noResults; + } + clearTimeout( this.liveRegionTimer ); + this.liveRegionTimer = this._delay( function() { + this.liveRegion.html( $( "<div>" ).text( message ) ); + }, 100 ); + } +} ); - // Never consider a container that's located within the item itself - if ( $.contains( this.currentItem[ 0 ], this.containers[ i ].element[ 0 ] ) ) { - continue; - } +var widgetsAutocomplete = $.ui.autocomplete; - if ( this._intersectsWith( this.containers[ i ].containerCache ) ) { - // If we've already found a container and it's more "inner" than this, then continue - if ( innermostContainer && - $.contains( - this.containers[ i ].element[ 0 ], - innermostContainer.element[ 0 ] ) ) { - continue; - } +/*! + * jQuery UI Controlgroup 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ - innermostContainer = this.containers[ i ]; - innermostIndex = i; +//>>label: Controlgroup +//>>group: Widgets +//>>description: Visually groups form control widgets +//>>docs: http://api.jqueryui.com/controlgroup/ +//>>demos: http://jqueryui.com/controlgroup/ +//>>css.structure: ../../themes/base/core.css +//>>css.structure: ../../themes/base/controlgroup.css +//>>css.theme: ../../themes/base/theme.css - } else { - // container doesn't intersect. trigger "out" event if necessary - if ( this.containers[ i ].containerCache.over ) { - this.containers[ i ]._trigger( "out", event, this._uiHash( this ) ); - this.containers[ i ].containerCache.over = 0; - } - } +var controlgroupCornerRegex = /ui-corner-([a-z]){2,6}/g; +var widgetsControlgroup = $.widget( "ui.controlgroup", { + version: "1.13.2", + defaultElement: "<div>", + options: { + direction: "horizontal", + disabled: null, + onlyVisible: true, + items: { + "button": "input[type=button], input[type=submit], input[type=reset], button, a", + "controlgroupLabel": ".ui-controlgroup-label", + "checkboxradio": "input[type='checkbox'], input[type='radio']", + "selectmenu": "select", + "spinner": ".ui-spinner-input" } + }, - // If no intersecting containers found, return - if ( !innermostContainer ) { - return; - } + _create: function() { + this._enhance(); + }, - // Move the item into the container if it's not there already - if ( this.containers.length === 1 ) { - if ( !this.containers[ innermostIndex ].containerCache.over ) { - this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) ); - this.containers[ innermostIndex ].containerCache.over = 1; - } - } else { + // To support the enhanced option in jQuery Mobile, we isolate DOM manipulation + _enhance: function() { + this.element.attr( "role", "toolbar" ); + this.refresh(); + }, - // When entering a new container, we will find the item with the least distance and - // append our item near it - dist = 10000; - itemWithLeastDistance = null; - floating = innermostContainer.floating || this._isFloating( this.currentItem ); - posProperty = floating ? "left" : "top"; - sizeProperty = floating ? "width" : "height"; - axis = floating ? "pageX" : "pageY"; + _destroy: function() { + this._callChildMethod( "destroy" ); + this.childWidgets.removeData( "ui-controlgroup-data" ); + this.element.removeAttr( "role" ); + if ( this.options.items.controlgroupLabel ) { + this.element + .find( this.options.items.controlgroupLabel ) + .find( ".ui-controlgroup-label-contents" ) + .contents().unwrap(); + } + }, - for ( j = this.items.length - 1; j >= 0; j-- ) { - if ( !$.contains( - this.containers[ innermostIndex ].element[ 0 ], this.items[ j ].item[ 0 ] ) - ) { - continue; - } - if ( this.items[ j ].item[ 0 ] === this.currentItem[ 0 ] ) { - continue; - } + _initWidgets: function() { + var that = this, + childWidgets = []; - cur = this.items[ j ].item.offset()[ posProperty ]; - nearBottom = false; - if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) { - nearBottom = true; - } + // First we iterate over each of the items options + $.each( this.options.items, function( widget, selector ) { + var labels; + var options = {}; - if ( Math.abs( event[ axis ] - cur ) < dist ) { - dist = Math.abs( event[ axis ] - cur ); - itemWithLeastDistance = this.items[ j ]; - this.direction = nearBottom ? "up" : "down"; - } + // Make sure the widget has a selector set + if ( !selector ) { + return; } - //Check if dropOnEmpty is enabled - if ( !itemWithLeastDistance && !this.options.dropOnEmpty ) { + if ( widget === "controlgroupLabel" ) { + labels = that.element.find( selector ); + labels.each( function() { + var element = $( this ); + + if ( element.children( ".ui-controlgroup-label-contents" ).length ) { + return; + } + element.contents() + .wrapAll( "<span class='ui-controlgroup-label-contents'></span>" ); + } ); + that._addClass( labels, null, "ui-widget ui-widget-content ui-state-default" ); + childWidgets = childWidgets.concat( labels.get() ); return; } - if ( this.currentContainer === this.containers[ innermostIndex ] ) { - if ( !this.currentContainer.containerCache.over ) { - this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() ); - this.currentContainer.containerCache.over = 1; - } + // Make sure the widget actually exists + if ( !$.fn[ widget ] ) { return; } - if ( itemWithLeastDistance ) { - this._rearrange( event, itemWithLeastDistance, null, true ); + // We assume everything is in the middle to start because we can't determine + // first / last elements until all enhancments are done. + if ( that[ "_" + widget + "Options" ] ) { + options = that[ "_" + widget + "Options" ]( "middle" ); } else { - this._rearrange( event, null, this.containers[ innermostIndex ].element, true ); - } - this._trigger( "change", event, this._uiHash() ); - this.containers[ innermostIndex ]._trigger( "change", event, this._uiHash( this ) ); - this.currentContainer = this.containers[ innermostIndex ]; - - //Update the placeholder - this.options.placeholder.update( this.currentContainer, this.placeholder ); - - //Update scrollParent - this.scrollParent = this.placeholder.scrollParent(); - - //Update overflowOffset - if ( this.scrollParent[ 0 ] !== this.document[ 0 ] && - this.scrollParent[ 0 ].tagName !== "HTML" ) { - this.overflowOffset = this.scrollParent.offset(); + options = { classes: {} }; } - this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) ); - this.containers[ innermostIndex ].containerCache.over = 1; - } - - }, + // Find instances of this widget inside controlgroup and init them + that.element + .find( selector ) + .each( function() { + var element = $( this ); + var instance = element[ widget ]( "instance" ); - _createHelper: function( event ) { + // We need to clone the default options for this type of widget to avoid + // polluting the variable options which has a wider scope than a single widget. + var instanceOptions = $.widget.extend( {}, options ); - var o = this.options, - helper = typeof o.helper === "function" ? - $( o.helper.apply( this.element[ 0 ], [ event, this.currentItem ] ) ) : - ( o.helper === "clone" ? this.currentItem.clone() : this.currentItem ); + // If the button is the child of a spinner ignore it + // TODO: Find a more generic solution + if ( widget === "button" && element.parent( ".ui-spinner" ).length ) { + return; + } - //Add the helper to the DOM if that didn't happen already - if ( !helper.parents( "body" ).length ) { - this.appendTo[ 0 ].appendChild( helper[ 0 ] ); - } + // Create the widget if it doesn't exist + if ( !instance ) { + instance = element[ widget ]()[ widget ]( "instance" ); + } + if ( instance ) { + instanceOptions.classes = + that._resolveClassesValues( instanceOptions.classes, instance ); + } + element[ widget ]( instanceOptions ); - if ( helper[ 0 ] === this.currentItem[ 0 ] ) { - this._storedCSS = { - width: this.currentItem[ 0 ].style.width, - height: this.currentItem[ 0 ].style.height, - position: this.currentItem.css( "position" ), - top: this.currentItem.css( "top" ), - left: this.currentItem.css( "left" ) - }; - } + // Store an instance of the controlgroup to be able to reference + // from the outermost element for changing options and refresh + var widgetElement = element[ widget ]( "widget" ); + $.data( widgetElement[ 0 ], "ui-controlgroup-data", + instance ? instance : element[ widget ]( "instance" ) ); - if ( !helper[ 0 ].style.width || o.forceHelperSize ) { - helper.width( this.currentItem.width() ); - } - if ( !helper[ 0 ].style.height || o.forceHelperSize ) { - helper.height( this.currentItem.height() ); - } + childWidgets.push( widgetElement[ 0 ] ); + } ); + } ); - return helper; + this.childWidgets = $( $.uniqueSort( childWidgets ) ); + this._addClass( this.childWidgets, "ui-controlgroup-item" ); + }, + _callChildMethod: function( method ) { + this.childWidgets.each( function() { + var element = $( this ), + data = element.data( "ui-controlgroup-data" ); + if ( data && data[ method ] ) { + data[ method ](); + } + } ); }, - _adjustOffsetFromHelper: function( obj ) { - if ( typeof obj === "string" ) { - obj = obj.split( " " ); - } - if ( Array.isArray( obj ) ) { - obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 }; - } - if ( "left" in obj ) { - this.offset.click.left = obj.left + this.margins.left; - } - if ( "right" in obj ) { - this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; - } - if ( "top" in obj ) { - this.offset.click.top = obj.top + this.margins.top; - } - if ( "bottom" in obj ) { - this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; - } + _updateCornerClass: function( element, position ) { + var remove = "ui-corner-top ui-corner-bottom ui-corner-left ui-corner-right ui-corner-all"; + var add = this._buildSimpleOptions( position, "label" ).classes.label; + + this._removeClass( element, null, remove ); + this._addClass( element, null, add ); }, - _getParentOffset: function() { + _buildSimpleOptions: function( position, key ) { + var direction = this.options.direction === "vertical"; + var result = { + classes: {} + }; + result.classes[ key ] = { + "middle": "", + "first": "ui-corner-" + ( direction ? "top" : "left" ), + "last": "ui-corner-" + ( direction ? "bottom" : "right" ), + "only": "ui-corner-all" + }[ position ]; - //Get the offsetParent and cache its position - this.offsetParent = this.helper.offsetParent(); - var po = this.offsetParent.offset(); + return result; + }, - // This is a special case where we need to modify a offset calculated on start, since the - // following happened: - // 1. The position of the helper is absolute, so it's position is calculated based on the - // next positioned parent - // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't - // the document, which means that the scroll is included in the initial calculation of the - // offset of the parent, and never recalculated upon drag - if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== this.document[ 0 ] && - $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) { - po.left += this.scrollParent.scrollLeft(); - po.top += this.scrollParent.scrollTop(); - } + _spinnerOptions: function( position ) { + var options = this._buildSimpleOptions( position, "ui-spinner" ); - // This needs to be actually done for all browsers, since pageX/pageY includes this - // information with an ugly IE fix - if ( this.offsetParent[ 0 ] === this.document[ 0 ].body || - ( this.offsetParent[ 0 ].tagName && - this.offsetParent[ 0 ].tagName.toLowerCase() === "html" && $.ui.ie ) ) { - po = { top: 0, left: 0 }; - } + options.classes[ "ui-spinner-up" ] = ""; + options.classes[ "ui-spinner-down" ] = ""; - return { - top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ), - left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 ) - }; + return options; + }, + _buttonOptions: function( position ) { + return this._buildSimpleOptions( position, "ui-button" ); }, - _getRelativeOffset: function() { + _checkboxradioOptions: function( position ) { + return this._buildSimpleOptions( position, "ui-checkboxradio-label" ); + }, - if ( this.cssPosition === "relative" ) { - var p = this.currentItem.position(); - return { - top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) + - this.scrollParent.scrollTop(), - left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) + - this.scrollParent.scrollLeft() - }; - } else { - return { top: 0, left: 0 }; - } + _selectmenuOptions: function( position ) { + var direction = this.options.direction === "vertical"; + return { + width: direction ? "auto" : false, + classes: { + middle: { + "ui-selectmenu-button-open": "", + "ui-selectmenu-button-closed": "" + }, + first: { + "ui-selectmenu-button-open": "ui-corner-" + ( direction ? "top" : "tl" ), + "ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "top" : "left" ) + }, + last: { + "ui-selectmenu-button-open": direction ? "" : "ui-corner-tr", + "ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "bottom" : "right" ) + }, + only: { + "ui-selectmenu-button-open": "ui-corner-top", + "ui-selectmenu-button-closed": "ui-corner-all" + } + }[ position ] + }; }, - _cacheMargins: function() { - this.margins = { - left: ( parseInt( this.currentItem.css( "marginLeft" ), 10 ) || 0 ), - top: ( parseInt( this.currentItem.css( "marginTop" ), 10 ) || 0 ) - }; + _resolveClassesValues: function( classes, instance ) { + var result = {}; + $.each( classes, function( key ) { + var current = instance.options.classes[ key ] || ""; + current = String.prototype.trim.call( current.replace( controlgroupCornerRegex, "" ) ); + result[ key ] = ( current + " " + classes[ key ] ).replace( /\s+/g, " " ); + } ); + return result; }, - _cacheHelperProportions: function() { - this.helperProportions = { - width: this.helper.outerWidth(), - height: this.helper.outerHeight() - }; + _setOption: function( key, value ) { + if ( key === "direction" ) { + this._removeClass( "ui-controlgroup-" + this.options.direction ); + } + + this._super( key, value ); + if ( key === "disabled" ) { + this._callChildMethod( value ? "disable" : "enable" ); + return; + } + + this.refresh(); }, - _setContainment: function() { + refresh: function() { + var children, + that = this; - var ce, co, over, - o = this.options; - if ( o.containment === "parent" ) { - o.containment = this.helper[ 0 ].parentNode; + this._addClass( "ui-controlgroup ui-controlgroup-" + this.options.direction ); + + if ( this.options.direction === "horizontal" ) { + this._addClass( null, "ui-helper-clearfix" ); } - if ( o.containment === "document" || o.containment === "window" ) { - this.containment = [ - 0 - this.offset.relative.left - this.offset.parent.left, - 0 - this.offset.relative.top - this.offset.parent.top, - o.containment === "document" ? - this.document.width() : - this.window.width() - this.helperProportions.width - this.margins.left, - ( o.containment === "document" ? - ( this.document.height() || document.body.parentNode.scrollHeight ) : - this.window.height() || this.document[ 0 ].body.parentNode.scrollHeight - ) - this.helperProportions.height - this.margins.top - ]; + this._initWidgets(); + + children = this.childWidgets; + + // We filter here because we need to track all childWidgets not just the visible ones + if ( this.options.onlyVisible ) { + children = children.filter( ":visible" ); } - if ( !( /^(document|window|parent)$/ ).test( o.containment ) ) { - ce = $( o.containment )[ 0 ]; - co = $( o.containment ).offset(); - over = ( $( ce ).css( "overflow" ) !== "hidden" ); + if ( children.length ) { - this.containment = [ - co.left + ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) + - ( parseInt( $( ce ).css( "paddingLeft" ), 10 ) || 0 ) - this.margins.left, - co.top + ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) + - ( parseInt( $( ce ).css( "paddingTop" ), 10 ) || 0 ) - this.margins.top, - co.left + ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - - ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) - - ( parseInt( $( ce ).css( "paddingRight" ), 10 ) || 0 ) - - this.helperProportions.width - this.margins.left, - co.top + ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - - ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) - - ( parseInt( $( ce ).css( "paddingBottom" ), 10 ) || 0 ) - - this.helperProportions.height - this.margins.top - ]; + // We do this last because we need to make sure all enhancment is done + // before determining first and last + $.each( [ "first", "last" ], function( index, value ) { + var instance = children[ value ]().data( "ui-controlgroup-data" ); + + if ( instance && that[ "_" + instance.widgetName + "Options" ] ) { + var options = that[ "_" + instance.widgetName + "Options" ]( + children.length === 1 ? "only" : value + ); + options.classes = that._resolveClassesValues( options.classes, instance ); + instance.element[ instance.widgetName ]( options ); + } else { + that._updateCornerClass( children[ value ](), value ); + } + } ); + + // Finally call the refresh method on each of the child widgets. + this._callChildMethod( "refresh" ); } + } +} ); - }, +/*! + * jQuery UI Checkboxradio 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ - _convertPositionTo: function( d, pos ) { +//>>label: Checkboxradio +//>>group: Widgets +//>>description: Enhances a form with multiple themeable checkboxes or radio buttons. +//>>docs: http://api.jqueryui.com/checkboxradio/ +//>>demos: http://jqueryui.com/checkboxradio/ +//>>css.structure: ../../themes/base/core.css +//>>css.structure: ../../themes/base/button.css +//>>css.structure: ../../themes/base/checkboxradio.css +//>>css.theme: ../../themes/base/theme.css - if ( !pos ) { - pos = this.position; + +$.widget( "ui.checkboxradio", [ $.ui.formResetMixin, { + version: "1.13.2", + options: { + disabled: null, + label: null, + icon: true, + classes: { + "ui-checkboxradio-label": "ui-corner-all", + "ui-checkboxradio-icon": "ui-corner-all" } - var mod = d === "absolute" ? 1 : -1, - scroll = this.cssPosition === "absolute" && - !( this.scrollParent[ 0 ] !== this.document[ 0 ] && - $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? - this.offsetParent : - this.scrollParent, - scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName ); + }, - return { - top: ( + _getCreateOptions: function() { + var disabled, labels, labelContents; + var options = this._super() || {}; - // The absolute mouse position - pos.top + + // We read the type here, because it makes more sense to throw a element type error first, + // rather then the error for lack of a label. Often if its the wrong type, it + // won't have a label (e.g. calling on a div, btn, etc) + this._readType(); - // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.relative.top * mod + + labels = this.element.labels(); - // The offsetParent's offset without borders (offset + border) - this.offset.parent.top * mod - - ( ( this.cssPosition === "fixed" ? - -this.scrollParent.scrollTop() : - ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod ) - ), - left: ( + // If there are multiple labels, use the last one + this.label = $( labels[ labels.length - 1 ] ); + if ( !this.label.length ) { + $.error( "No label found for checkboxradio widget" ); + } - // The absolute mouse position - pos.left + + this.originalLabel = ""; - // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.relative.left * mod + + // We need to get the label text but this may also need to make sure it does not contain the + // input itself. + // The label contents could be text, html, or a mix. We wrap all elements + // and read the wrapper's `innerHTML` to get a string representation of + // the label, without the input as part of it. + labelContents = this.label.contents().not( this.element[ 0 ] ); - // The offsetParent's offset without borders (offset + border) - this.offset.parent.left * mod - - ( ( this.cssPosition === "fixed" ? - -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : - scroll.scrollLeft() ) * mod ) - ) - }; + if ( labelContents.length ) { + this.originalLabel += labelContents + .clone() + .wrapAll( "<div></div>" ) + .parent() + .html(); + } + + // Set the label option if we found label text + if ( this.originalLabel ) { + options.label = this.originalLabel; + } + disabled = this.element[ 0 ].disabled; + if ( disabled != null ) { + options.disabled = disabled; + } + return options; }, - _generatePosition: function( event ) { + _create: function() { + var checked = this.element[ 0 ].checked; - var top, left, - o = this.options, - pageX = event.pageX, - pageY = event.pageY, - scroll = this.cssPosition === "absolute" && - !( this.scrollParent[ 0 ] !== this.document[ 0 ] && - $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? - this.offsetParent : - this.scrollParent, - scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName ); + this._bindFormResetHandler(); - // This is another very weird special case that only happens for relative elements: - // 1. If the css position is relative - // 2. and the scroll parent is the document or similar to the offset parent - // we have to refresh the relative offset during the scroll so there are no jumps - if ( this.cssPosition === "relative" && !( this.scrollParent[ 0 ] !== this.document[ 0 ] && - this.scrollParent[ 0 ] !== this.offsetParent[ 0 ] ) ) { - this.offset.relative = this._getRelativeOffset(); + if ( this.options.disabled == null ) { + this.options.disabled = this.element[ 0 ].disabled; } - /* - * - Position constraining - - * Constrain the position to a mix of grid, containment. - */ + this._setOption( "disabled", this.options.disabled ); + this._addClass( "ui-checkboxradio", "ui-helper-hidden-accessible" ); + this._addClass( this.label, "ui-checkboxradio-label", "ui-button ui-widget" ); - if ( this.originalPosition ) { //If we are not dragging yet, we won't check for options + if ( this.type === "radio" ) { + this._addClass( this.label, "ui-checkboxradio-radio-label" ); + } - if ( this.containment ) { - if ( event.pageX - this.offset.click.left < this.containment[ 0 ] ) { - pageX = this.containment[ 0 ] + this.offset.click.left; - } - if ( event.pageY - this.offset.click.top < this.containment[ 1 ] ) { - pageY = this.containment[ 1 ] + this.offset.click.top; - } - if ( event.pageX - this.offset.click.left > this.containment[ 2 ] ) { - pageX = this.containment[ 2 ] + this.offset.click.left; - } - if ( event.pageY - this.offset.click.top > this.containment[ 3 ] ) { - pageY = this.containment[ 3 ] + this.offset.click.top; - } - } - - if ( o.grid ) { - top = this.originalPageY + Math.round( ( pageY - this.originalPageY ) / - o.grid[ 1 ] ) * o.grid[ 1 ]; - pageY = this.containment ? - ( ( top - this.offset.click.top >= this.containment[ 1 ] && - top - this.offset.click.top <= this.containment[ 3 ] ) ? - top : - ( ( top - this.offset.click.top >= this.containment[ 1 ] ) ? - top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : - top; + if ( this.options.label && this.options.label !== this.originalLabel ) { + this._updateLabel(); + } else if ( this.originalLabel ) { + this.options.label = this.originalLabel; + } - left = this.originalPageX + Math.round( ( pageX - this.originalPageX ) / - o.grid[ 0 ] ) * o.grid[ 0 ]; - pageX = this.containment ? - ( ( left - this.offset.click.left >= this.containment[ 0 ] && - left - this.offset.click.left <= this.containment[ 2 ] ) ? - left : - ( ( left - this.offset.click.left >= this.containment[ 0 ] ) ? - left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : - left; - } + this._enhance(); + if ( checked ) { + this._addClass( this.label, "ui-checkboxradio-checked", "ui-state-active" ); } - return { - top: ( - - // The absolute mouse position - pageY - + this._on( { + change: "_toggleClasses", + focus: function() { + this._addClass( this.label, null, "ui-state-focus ui-visual-focus" ); + }, + blur: function() { + this._removeClass( this.label, null, "ui-state-focus ui-visual-focus" ); + } + } ); + }, - // Click offset (relative to the element) - this.offset.click.top - + _readType: function() { + var nodeName = this.element[ 0 ].nodeName.toLowerCase(); + this.type = this.element[ 0 ].type; + if ( nodeName !== "input" || !/radio|checkbox/.test( this.type ) ) { + $.error( "Can't create checkboxradio on element.nodeName=" + nodeName + + " and element.type=" + this.type ); + } + }, - // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.relative.top - + // Support jQuery Mobile enhanced option + _enhance: function() { + this._updateIcon( this.element[ 0 ].checked ); + }, - // The offsetParent's offset without borders (offset + border) - this.offset.parent.top + - ( ( this.cssPosition === "fixed" ? - -this.scrollParent.scrollTop() : - ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) ) - ), - left: ( + widget: function() { + return this.label; + }, - // The absolute mouse position - pageX - + _getRadioGroup: function() { + var group; + var name = this.element[ 0 ].name; + var nameSelector = "input[name='" + $.escapeSelector( name ) + "']"; - // Click offset (relative to the element) - this.offset.click.left - + if ( !name ) { + return $( [] ); + } - // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.relative.left - + if ( this.form.length ) { + group = $( this.form[ 0 ].elements ).filter( nameSelector ); + } else { - // The offsetParent's offset without borders (offset + border) - this.offset.parent.left + - ( ( this.cssPosition === "fixed" ? - -this.scrollParent.scrollLeft() : - scrollIsRootNode ? 0 : scroll.scrollLeft() ) ) - ) - }; + // Not inside a form, check all inputs that also are not inside a form + group = $( nameSelector ).filter( function() { + return $( this )._form().length === 0; + } ); + } + return group.not( this.element ); }, - _rearrange: function( event, i, a, hardRefresh ) { + _toggleClasses: function() { + var checked = this.element[ 0 ].checked; + this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked ); - if ( a ) { - a[ 0 ].appendChild( this.placeholder[ 0 ] ); - } else { - i.item[ 0 ].parentNode.insertBefore( this.placeholder[ 0 ], - ( this.direction === "down" ? i.item[ 0 ] : i.item[ 0 ].nextSibling ) ); + if ( this.options.icon && this.type === "checkbox" ) { + this._toggleClass( this.icon, null, "ui-icon-check ui-state-checked", checked ) + ._toggleClass( this.icon, null, "ui-icon-blank", !checked ); } - //Various things done here to improve the performance: - // 1. we create a setTimeout, that calls refreshPositions - // 2. on the instance, we have a counter variable, that get's higher after every append - // 3. on the local scope, we copy the counter variable, and check in the timeout, - // if it's still the same - // 4. this lets only the last addition to the timeout stack through - this.counter = this.counter ? ++this.counter : 1; - var counter = this.counter; - - this._delay( function() { - if ( counter === this.counter ) { - - //Precompute after each DOM insertion, NOT on mousemove - this.refreshPositions( !hardRefresh ); - } - } ); + if ( this.type === "radio" ) { + this._getRadioGroup() + .each( function() { + var instance = $( this ).checkboxradio( "instance" ); + if ( instance ) { + instance._removeClass( instance.label, + "ui-checkboxradio-checked", "ui-state-active" ); + } + } ); + } }, - _clear: function( event, noPropagation ) { + _destroy: function() { + this._unbindFormResetHandler(); - this.reverting = false; + if ( this.icon ) { + this.icon.remove(); + this.iconSpace.remove(); + } + }, - // We delay all events that have to be triggered to after the point where the placeholder - // has been removed and everything else normalized again - var i, - delayedTriggers = []; + _setOption: function( key, value ) { - // We first have to update the dom position of the actual currentItem - // Note: don't do it if the current item is already removed (by a user), or it gets - // reappended (see #4088) - if ( !this._noFinalSort && this.currentItem.parent().length ) { - this.placeholder.before( this.currentItem ); + // We don't allow the value to be set to nothing + if ( key === "label" && !value ) { + return; } - this._noFinalSort = null; - if ( this.helper[ 0 ] === this.currentItem[ 0 ] ) { - for ( i in this._storedCSS ) { - if ( this._storedCSS[ i ] === "auto" || this._storedCSS[ i ] === "static" ) { - this._storedCSS[ i ] = ""; - } - } - this.currentItem.css( this._storedCSS ); - this._removeClass( this.currentItem, "ui-sortable-helper" ); - } else { - this.currentItem.show(); - } + this._super( key, value ); - if ( this.fromOutside && !noPropagation ) { - delayedTriggers.push( function( event ) { - this._trigger( "receive", event, this._uiHash( this.fromOutside ) ); - } ); - } - if ( ( this.fromOutside || - this.domPosition.prev !== - this.currentItem.prev().not( ".ui-sortable-helper" )[ 0 ] || - this.domPosition.parent !== this.currentItem.parent()[ 0 ] ) && !noPropagation ) { + if ( key === "disabled" ) { + this._toggleClass( this.label, null, "ui-state-disabled", value ); + this.element[ 0 ].disabled = value; - // Trigger update callback if the DOM position has changed - delayedTriggers.push( function( event ) { - this._trigger( "update", event, this._uiHash() ); - } ); + // Don't refresh when setting disabled + return; } + this.refresh(); + }, - // Check if the items Container has Changed and trigger appropriate - // events. - if ( this !== this.currentContainer ) { - if ( !noPropagation ) { - delayedTriggers.push( function( event ) { - this._trigger( "remove", event, this._uiHash() ); - } ); - delayedTriggers.push( ( function( c ) { - return function( event ) { - c._trigger( "receive", event, this._uiHash( this ) ); - }; - } ).call( this, this.currentContainer ) ); - delayedTriggers.push( ( function( c ) { - return function( event ) { - c._trigger( "update", event, this._uiHash( this ) ); - }; - } ).call( this, this.currentContainer ) ); + _updateIcon: function( checked ) { + var toAdd = "ui-icon ui-icon-background "; + + if ( this.options.icon ) { + if ( !this.icon ) { + this.icon = $( "<span>" ); + this.iconSpace = $( "<span> </span>" ); + this._addClass( this.iconSpace, "ui-checkboxradio-icon-space" ); } - } - //Post events to containers - function delayEvent( type, instance, container ) { - return function( event ) { - container._trigger( type, event, instance._uiHash( instance ) ); - }; - } - for ( i = this.containers.length - 1; i >= 0; i-- ) { - if ( !noPropagation ) { - delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) ); + if ( this.type === "checkbox" ) { + toAdd += checked ? "ui-icon-check ui-state-checked" : "ui-icon-blank"; + this._removeClass( this.icon, null, checked ? "ui-icon-blank" : "ui-icon-check" ); + } else { + toAdd += "ui-icon-blank"; } - if ( this.containers[ i ].containerCache.over ) { - delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) ); - this.containers[ i ].containerCache.over = 0; + this._addClass( this.icon, "ui-checkboxradio-icon", toAdd ); + if ( !checked ) { + this._removeClass( this.icon, null, "ui-icon-check ui-state-checked" ); } + this.icon.prependTo( this.label ).after( this.iconSpace ); + } else if ( this.icon !== undefined ) { + this.icon.remove(); + this.iconSpace.remove(); + delete this.icon; } + }, - //Do what was originally in plugins - if ( this.storedCursor ) { - this.document.find( "body" ).css( "cursor", this.storedCursor ); - this.storedStylesheet.remove(); - } - if ( this._storedOpacity ) { - this.helper.css( "opacity", this._storedOpacity ); - } - if ( this._storedZIndex ) { - this.helper.css( "zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex ); - } - - this.dragging = false; - - if ( !noPropagation ) { - this._trigger( "beforeStop", event, this._uiHash() ); - } - - //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, - // it unbinds ALL events from the original node! - this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] ); + _updateLabel: function() { - if ( !this.cancelHelperRemoval ) { - if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) { - this.helper.remove(); - } - this.helper = null; + // Remove the contents of the label ( minus the icon, icon space, and input ) + var contents = this.label.contents().not( this.element[ 0 ] ); + if ( this.icon ) { + contents = contents.not( this.icon[ 0 ] ); } - - if ( !noPropagation ) { - for ( i = 0; i < delayedTriggers.length; i++ ) { - - // Trigger all delayed events - delayedTriggers[ i ].call( this, event ); - } - this._trigger( "stop", event, this._uiHash() ); + if ( this.iconSpace ) { + contents = contents.not( this.iconSpace[ 0 ] ); } + contents.remove(); - this.fromOutside = false; - return !this.cancelHelperRemoval; - + this.label.append( this.options.label ); }, - _trigger: function() { - if ( $.Widget.prototype._trigger.apply( this, arguments ) === false ) { - this.cancel(); + refresh: function() { + var checked = this.element[ 0 ].checked, + isDisabled = this.element[ 0 ].disabled; + + this._updateIcon( checked ); + this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked ); + if ( this.options.label !== null ) { + this._updateLabel(); } - }, - _uiHash: function( _inst ) { - var inst = _inst || this; - return { - helper: inst.helper, - placeholder: inst.placeholder || $( [] ), - position: inst.position, - originalPosition: inst.originalPosition, - offset: inst.positionAbs, - item: inst.currentItem, - sender: _inst ? _inst.element : null - }; + if ( isDisabled !== this.options.disabled ) { + this._setOptions( { "disabled": isDisabled } ); + } } -} ); +} ] ); + +var widgetsCheckboxradio = $.ui.checkboxradio; /*! - * jQuery UI Accordion 1.13.1 + * jQuery UI Button 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -6843,7638 +6883,7214 @@ var widgetsSortable = $.widget( "ui.sortable", $.ui.mouse, { * http://jquery.org/license */ -//>>label: Accordion +//>>label: Button //>>group: Widgets -/* eslint-disable max-len */ -//>>description: Displays collapsible content panels for presenting information in a limited amount of space. -/* eslint-enable max-len */ -//>>docs: http://api.jqueryui.com/accordion/ -//>>demos: http://jqueryui.com/accordion/ +//>>description: Enhances a form with themeable buttons. +//>>docs: http://api.jqueryui.com/button/ +//>>demos: http://jqueryui.com/button/ //>>css.structure: ../../themes/base/core.css -//>>css.structure: ../../themes/base/accordion.css +//>>css.structure: ../../themes/base/button.css //>>css.theme: ../../themes/base/theme.css -var widgetsAccordion = $.widget( "ui.accordion", { - version: "1.13.1", +$.widget( "ui.button", { + version: "1.13.2", + defaultElement: "<button>", options: { - active: 0, - animate: {}, classes: { - "ui-accordion-header": "ui-corner-top", - "ui-accordion-header-collapsed": "ui-corner-all", - "ui-accordion-content": "ui-corner-bottom" - }, - collapsible: false, - event: "click", - header: function( elem ) { - return elem.find( "> li > :first-child" ).add( elem.find( "> :not(li)" ).even() ); - }, - heightStyle: "auto", - icons: { - activeHeader: "ui-icon-triangle-1-s", - header: "ui-icon-triangle-1-e" + "ui-button": "ui-corner-all" }, - - // Callbacks - activate: null, - beforeActivate: null - }, - - hideProps: { - borderTopWidth: "hide", - borderBottomWidth: "hide", - paddingTop: "hide", - paddingBottom: "hide", - height: "hide" + disabled: null, + icon: null, + iconPosition: "beginning", + label: null, + showLabel: true }, - showProps: { - borderTopWidth: "show", - borderBottomWidth: "show", - paddingTop: "show", - paddingBottom: "show", - height: "show" - }, + _getCreateOptions: function() { + var disabled, - _create: function() { - var options = this.options; + // This is to support cases like in jQuery Mobile where the base widget does have + // an implementation of _getCreateOptions + options = this._super() || {}; - this.prevShow = this.prevHide = $(); - this._addClass( "ui-accordion", "ui-widget ui-helper-reset" ); - this.element.attr( "role", "tablist" ); + this.isInput = this.element.is( "input" ); - // Don't allow collapsible: false and active: false / null - if ( !options.collapsible && ( options.active === false || options.active == null ) ) { - options.active = 0; + disabled = this.element[ 0 ].disabled; + if ( disabled != null ) { + options.disabled = disabled; } - this._processPanels(); - - // handle negative values - if ( options.active < 0 ) { - options.active += this.headers.length; + this.originalLabel = this.isInput ? this.element.val() : this.element.html(); + if ( this.originalLabel ) { + options.label = this.originalLabel; } - this._refresh(); - }, - _getCreateEventData: function() { - return { - header: this.active, - panel: !this.active.length ? $() : this.active.next() - }; + return options; }, - _createIcons: function() { - var icon, children, - icons = this.options.icons; - - if ( icons ) { - icon = $( "<span>" ); - this._addClass( icon, "ui-accordion-header-icon", "ui-icon " + icons.header ); - icon.prependTo( this.headers ); - children = this.active.children( ".ui-accordion-header-icon" ); - this._removeClass( children, icons.header ) - ._addClass( children, null, icons.activeHeader ) - ._addClass( this.headers, "ui-accordion-icons" ); + _create: function() { + if ( !this.option.showLabel & !this.options.icon ) { + this.options.showLabel = true; } - }, - _destroyIcons: function() { - this._removeClass( this.headers, "ui-accordion-icons" ); - this.headers.children( ".ui-accordion-header-icon" ).remove(); - }, + // We have to check the option again here even though we did in _getCreateOptions, + // because null may have been passed on init which would override what was set in + // _getCreateOptions + if ( this.options.disabled == null ) { + this.options.disabled = this.element[ 0 ].disabled || false; + } - _destroy: function() { - var contents; + this.hasTitle = !!this.element.attr( "title" ); - // Clean up main element - this.element.removeAttr( "role" ); + // Check to see if the label needs to be set or if its already correct + if ( this.options.label && this.options.label !== this.originalLabel ) { + if ( this.isInput ) { + this.element.val( this.options.label ); + } else { + this.element.html( this.options.label ); + } + } + this._addClass( "ui-button", "ui-widget" ); + this._setOption( "disabled", this.options.disabled ); + this._enhance(); - // Clean up headers - this.headers - .removeAttr( "role aria-expanded aria-selected aria-controls tabIndex" ) - .removeUniqueId(); + if ( this.element.is( "a" ) ) { + this._on( { + "keyup": function( event ) { + if ( event.keyCode === $.ui.keyCode.SPACE ) { + event.preventDefault(); - this._destroyIcons(); + // Support: PhantomJS <= 1.9, IE 8 Only + // If a native click is available use it so we actually cause navigation + // otherwise just trigger a click event + if ( this.element[ 0 ].click ) { + this.element[ 0 ].click(); + } else { + this.element.trigger( "click" ); + } + } + } + } ); + } + }, - // Clean up content panels - contents = this.headers.next() - .css( "display", "" ) - .removeAttr( "role aria-hidden aria-labelledby" ) - .removeUniqueId(); + _enhance: function() { + if ( !this.element.is( "button" ) ) { + this.element.attr( "role", "button" ); + } - if ( this.options.heightStyle !== "content" ) { - contents.css( "height", "" ); + if ( this.options.icon ) { + this._updateIcon( "icon", this.options.icon ); + this._updateTooltip(); } }, - _setOption: function( key, value ) { - if ( key === "active" ) { + _updateTooltip: function() { + this.title = this.element.attr( "title" ); - // _activate() will handle invalid values and update this.options - this._activate( value ); - return; + if ( !this.options.showLabel && !this.title ) { + this.element.attr( "title", this.options.label ); } + }, - if ( key === "event" ) { - if ( this.options.event ) { - this._off( this.headers, this.options.event ); - } - this._setupEvents( value ); - } + _updateIcon: function( option, value ) { + var icon = option !== "iconPosition", + position = icon ? this.options.iconPosition : value, + displayBlock = position === "top" || position === "bottom"; - this._super( key, value ); + // Create icon + if ( !this.icon ) { + this.icon = $( "<span>" ); - // Setting collapsible: false while collapsed; open first panel - if ( key === "collapsible" && !value && this.options.active === false ) { - this._activate( 0 ); - } + this._addClass( this.icon, "ui-button-icon", "ui-icon" ); - if ( key === "icons" ) { - this._destroyIcons(); - if ( value ) { - this._createIcons(); + if ( !this.options.showLabel ) { + this._addClass( "ui-button-icon-only" ); } + } else if ( icon ) { + + // If we are updating the icon remove the old icon class + this._removeClass( this.icon, null, this.options.icon ); } - }, - _setOptionDisabled: function( value ) { - this._super( value ); + // If we are updating the icon add the new icon class + if ( icon ) { + this._addClass( this.icon, null, value ); + } - this.element.attr( "aria-disabled", value ); + this._attachIcon( position ); - // Support: IE8 Only - // #5332 / #6059 - opacity doesn't cascade to positioned elements in IE - // so we need to add the disabled class to the headers and panels - this._toggleClass( null, "ui-state-disabled", !!value ); - this._toggleClass( this.headers.add( this.headers.next() ), null, "ui-state-disabled", - !!value ); - }, + // If the icon is on top or bottom we need to add the ui-widget-icon-block class and remove + // the iconSpace if there is one. + if ( displayBlock ) { + this._addClass( this.icon, null, "ui-widget-icon-block" ); + if ( this.iconSpace ) { + this.iconSpace.remove(); + } + } else { - _keydown: function( event ) { - if ( event.altKey || event.ctrlKey ) { - return; + // Position is beginning or end so remove the ui-widget-icon-block class and add the + // space if it does not exist + if ( !this.iconSpace ) { + this.iconSpace = $( "<span> </span>" ); + this._addClass( this.iconSpace, "ui-button-icon-space" ); + } + this._removeClass( this.icon, null, "ui-wiget-icon-block" ); + this._attachIconSpace( position ); } + }, - var keyCode = $.ui.keyCode, - length = this.headers.length, - currentIndex = this.headers.index( event.target ), - toFocus = false; + _destroy: function() { + this.element.removeAttr( "role" ); - switch ( event.keyCode ) { - case keyCode.RIGHT: - case keyCode.DOWN: - toFocus = this.headers[ ( currentIndex + 1 ) % length ]; - break; - case keyCode.LEFT: - case keyCode.UP: - toFocus = this.headers[ ( currentIndex - 1 + length ) % length ]; - break; - case keyCode.SPACE: - case keyCode.ENTER: - this._eventHandler( event ); - break; - case keyCode.HOME: - toFocus = this.headers[ 0 ]; - break; - case keyCode.END: - toFocus = this.headers[ length - 1 ]; - break; + if ( this.icon ) { + this.icon.remove(); } - - if ( toFocus ) { - $( event.target ).attr( "tabIndex", -1 ); - $( toFocus ).attr( "tabIndex", 0 ); - $( toFocus ).trigger( "focus" ); - event.preventDefault(); + if ( this.iconSpace ) { + this.iconSpace.remove(); } - }, - - _panelKeyDown: function( event ) { - if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) { - $( event.currentTarget ).prev().trigger( "focus" ); + if ( !this.hasTitle ) { + this.element.removeAttr( "title" ); } }, - refresh: function() { - var options = this.options; - this._processPanels(); - - // Was collapsed or no panel - if ( ( options.active === false && options.collapsible === true ) || - !this.headers.length ) { - options.active = false; - this.active = $(); + _attachIconSpace: function( iconPosition ) { + this.icon[ /^(?:end|bottom)/.test( iconPosition ) ? "before" : "after" ]( this.iconSpace ); + }, - // active false only when collapsible is true - } else if ( options.active === false ) { - this._activate( 0 ); + _attachIcon: function( iconPosition ) { + this.element[ /^(?:end|bottom)/.test( iconPosition ) ? "append" : "prepend" ]( this.icon ); + }, - // was active, but active panel is gone - } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { + _setOptions: function( options ) { + var newShowLabel = options.showLabel === undefined ? + this.options.showLabel : + options.showLabel, + newIcon = options.icon === undefined ? this.options.icon : options.icon; - // all remaining panel are disabled - if ( this.headers.length === this.headers.find( ".ui-state-disabled" ).length ) { - options.active = false; - this.active = $(); + if ( !newShowLabel && !newIcon ) { + options.showLabel = true; + } + this._super( options ); + }, - // activate previous panel - } else { - this._activate( Math.max( 0, options.active - 1 ) ); + _setOption: function( key, value ) { + if ( key === "icon" ) { + if ( value ) { + this._updateIcon( key, value ); + } else if ( this.icon ) { + this.icon.remove(); + if ( this.iconSpace ) { + this.iconSpace.remove(); + } } - - // was active, active panel still exists - } else { - - // make sure active index is correct - options.active = this.headers.index( this.active ); } - this._destroyIcons(); + if ( key === "iconPosition" ) { + this._updateIcon( key, value ); + } - this._refresh(); - }, + // Make sure we can't end up with a button that has neither text nor icon + if ( key === "showLabel" ) { + this._toggleClass( "ui-button-icon-only", null, !value ); + this._updateTooltip(); + } - _processPanels: function() { - var prevHeaders = this.headers, - prevPanels = this.panels; + if ( key === "label" ) { + if ( this.isInput ) { + this.element.val( value ); + } else { - if ( typeof this.options.header === "function" ) { - this.headers = this.options.header( this.element ); - } else { - this.headers = this.element.find( this.options.header ); + // If there is an icon, append it, else nothing then append the value + // this avoids removal of the icon when setting label text + this.element.html( value ); + if ( this.icon ) { + this._attachIcon( this.options.iconPosition ); + this._attachIconSpace( this.options.iconPosition ); + } + } } - this._addClass( this.headers, "ui-accordion-header ui-accordion-header-collapsed", - "ui-state-default" ); - this.panels = this.headers.next().filter( ":not(.ui-accordion-content-active)" ).hide(); - this._addClass( this.panels, "ui-accordion-content", "ui-helper-reset ui-widget-content" ); + this._super( key, value ); - // Avoid memory leaks (#10056) - if ( prevPanels ) { - this._off( prevHeaders.not( this.headers ) ); - this._off( prevPanels.not( this.panels ) ); + if ( key === "disabled" ) { + this._toggleClass( null, "ui-state-disabled", value ); + this.element[ 0 ].disabled = value; + if ( value ) { + this.element.trigger( "blur" ); + } } }, - _refresh: function() { - var maxHeight, - options = this.options, - heightStyle = options.heightStyle, - parent = this.element.parent(); + refresh: function() { - this.active = this._findActive( options.active ); - this._addClass( this.active, "ui-accordion-header-active", "ui-state-active" ) - ._removeClass( this.active, "ui-accordion-header-collapsed" ); - this._addClass( this.active.next(), "ui-accordion-content-active" ); - this.active.next().show(); + // Make sure to only check disabled if its an element that supports this otherwise + // check for the disabled class to determine state + var isDisabled = this.element.is( "input, button" ) ? + this.element[ 0 ].disabled : this.element.hasClass( "ui-button-disabled" ); - this.headers - .attr( "role", "tab" ) - .each( function() { - var header = $( this ), - headerId = header.uniqueId().attr( "id" ), - panel = header.next(), - panelId = panel.uniqueId().attr( "id" ); - header.attr( "aria-controls", panelId ); - panel.attr( "aria-labelledby", headerId ); - } ) - .next() - .attr( "role", "tabpanel" ); + if ( isDisabled !== this.options.disabled ) { + this._setOptions( { disabled: isDisabled } ); + } - this.headers - .not( this.active ) - .attr( { - "aria-selected": "false", - "aria-expanded": "false", - tabIndex: -1 - } ) - .next() - .attr( { - "aria-hidden": "true" - } ) - .hide(); + this._updateTooltip(); + } +} ); - // Make sure at least one header is in the tab order - if ( !this.active.length ) { - this.headers.eq( 0 ).attr( "tabIndex", 0 ); - } else { - this.active.attr( { - "aria-selected": "true", - "aria-expanded": "true", - tabIndex: 0 - } ) - .next() - .attr( { - "aria-hidden": "false" - } ); - } - - this._createIcons(); +// DEPRECATED +if ( $.uiBackCompat !== false ) { - this._setupEvents( options.event ); + // Text and Icons options + $.widget( "ui.button", $.ui.button, { + options: { + text: true, + icons: { + primary: null, + secondary: null + } + }, - if ( heightStyle === "fill" ) { - maxHeight = parent.height(); - this.element.siblings( ":visible" ).each( function() { - var elem = $( this ), - position = elem.css( "position" ); + _create: function() { + if ( this.options.showLabel && !this.options.text ) { + this.options.showLabel = this.options.text; + } + if ( !this.options.showLabel && this.options.text ) { + this.options.text = this.options.showLabel; + } + if ( !this.options.icon && ( this.options.icons.primary || + this.options.icons.secondary ) ) { + if ( this.options.icons.primary ) { + this.options.icon = this.options.icons.primary; + } else { + this.options.icon = this.options.icons.secondary; + this.options.iconPosition = "end"; + } + } else if ( this.options.icon ) { + this.options.icons.primary = this.options.icon; + } + this._super(); + }, - if ( position === "absolute" || position === "fixed" ) { - return; + _setOption: function( key, value ) { + if ( key === "text" ) { + this._super( "showLabel", value ); + return; + } + if ( key === "showLabel" ) { + this.options.text = value; + } + if ( key === "icon" ) { + this.options.icons.primary = value; + } + if ( key === "icons" ) { + if ( value.primary ) { + this._super( "icon", value.primary ); + this._super( "iconPosition", "beginning" ); + } else if ( value.secondary ) { + this._super( "icon", value.secondary ); + this._super( "iconPosition", "end" ); } - maxHeight -= elem.outerHeight( true ); - } ); + } + this._superApply( arguments ); + } + } ); - this.headers.each( function() { - maxHeight -= $( this ).outerHeight( true ); - } ); + $.fn.button = ( function( orig ) { + return function( options ) { + var isMethodCall = typeof options === "string"; + var args = Array.prototype.slice.call( arguments, 1 ); + var returnValue = this; - this.headers.next() - .each( function() { - $( this ).height( Math.max( 0, maxHeight - - $( this ).innerHeight() + $( this ).height() ) ); - } ) - .css( "overflow", "auto" ); - } else if ( heightStyle === "auto" ) { - maxHeight = 0; - this.headers.next() - .each( function() { - var isVisible = $( this ).is( ":visible" ); - if ( !isVisible ) { - $( this ).show(); - } - maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() ); - if ( !isVisible ) { - $( this ).hide(); - } - } ) - .height( maxHeight ); - } - }, + if ( isMethodCall ) { - _activate: function( index ) { - var active = this._findActive( index )[ 0 ]; + // If this is an empty collection, we need to have the instance method + // return undefined instead of the jQuery instance + if ( !this.length && options === "instance" ) { + returnValue = undefined; + } else { + this.each( function() { + var methodValue; + var type = $( this ).attr( "type" ); + var name = type !== "checkbox" && type !== "radio" ? + "button" : + "checkboxradio"; + var instance = $.data( this, "ui-" + name ); - // Trying to activate the already active panel - if ( active === this.active[ 0 ] ) { - return; - } + if ( options === "instance" ) { + returnValue = instance; + return false; + } - // Trying to collapse, simulate a click on the currently active header - active = active || this.active[ 0 ]; + if ( !instance ) { + return $.error( "cannot call methods on button" + + " prior to initialization; " + + "attempted to call method '" + options + "'" ); + } - this._eventHandler( { - target: active, - currentTarget: active, - preventDefault: $.noop - } ); - }, + if ( typeof instance[ options ] !== "function" || + options.charAt( 0 ) === "_" ) { + return $.error( "no such method '" + options + "' for button" + + " widget instance" ); + } - _findActive: function( selector ) { - return typeof selector === "number" ? this.headers.eq( selector ) : $(); - }, + methodValue = instance[ options ].apply( instance, args ); - _setupEvents: function( event ) { - var events = { - keydown: "_keydown" - }; - if ( event ) { - $.each( event.split( " " ), function( index, eventName ) { - events[ eventName ] = "_eventHandler"; - } ); - } + if ( methodValue !== instance && methodValue !== undefined ) { + returnValue = methodValue && methodValue.jquery ? + returnValue.pushStack( methodValue.get() ) : + methodValue; + return false; + } + } ); + } + } else { - this._off( this.headers.add( this.headers.next() ) ); - this._on( this.headers, events ); - this._on( this.headers.next(), { keydown: "_panelKeyDown" } ); - this._hoverable( this.headers ); - this._focusable( this.headers ); - }, + // Allow multiple hashes to be passed on init + if ( args.length ) { + options = $.widget.extend.apply( null, [ options ].concat( args ) ); + } - _eventHandler: function( event ) { - var activeChildren, clickedChildren, - options = this.options, - active = this.active, - clicked = $( event.currentTarget ), - clickedIsActive = clicked[ 0 ] === active[ 0 ], - collapsing = clickedIsActive && options.collapsible, - toShow = collapsing ? $() : clicked.next(), - toHide = active.next(), - eventData = { - oldHeader: active, - oldPanel: toHide, - newHeader: collapsing ? $() : clicked, - newPanel: toShow - }; + this.each( function() { + var type = $( this ).attr( "type" ); + var name = type !== "checkbox" && type !== "radio" ? "button" : "checkboxradio"; + var instance = $.data( this, "ui-" + name ); - event.preventDefault(); + if ( instance ) { + instance.option( options || {} ); + if ( instance._init ) { + instance._init(); + } + } else { + if ( name === "button" ) { + orig.call( $( this ), options ); + return; + } - if ( + $( this ).checkboxradio( $.extend( { icon: false }, options ) ); + } + } ); + } - // click on active header, but not collapsible - ( clickedIsActive && !options.collapsible ) || + return returnValue; + }; + } )( $.fn.button ); - // allow canceling activation - ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { - return; + $.fn.buttonset = function() { + if ( !$.ui.controlgroup ) { + $.error( "Controlgroup widget missing" ); + } + if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" && arguments[ 2 ] ) { + return this.controlgroup.apply( this, + [ arguments[ 0 ], "items.button", arguments[ 2 ] ] ); + } + if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" ) { + return this.controlgroup.apply( this, [ arguments[ 0 ], "items.button" ] ); + } + if ( typeof arguments[ 0 ] === "object" && arguments[ 0 ].items ) { + arguments[ 0 ].items = { + button: arguments[ 0 ].items + }; } + return this.controlgroup.apply( this, arguments ); + }; +} - options.active = collapsing ? false : this.headers.index( clicked ); +var widgetsButton = $.ui.button; - // When the call to ._toggle() comes after the class changes - // it causes a very odd bug in IE 8 (see #6720) - this.active = clickedIsActive ? $() : clicked; - this._toggle( eventData ); - // Switch classes - // corner classes on the previously active header stay after the animation - this._removeClass( active, "ui-accordion-header-active", "ui-state-active" ); - if ( options.icons ) { - activeChildren = active.children( ".ui-accordion-header-icon" ); - this._removeClass( activeChildren, null, options.icons.activeHeader ) - ._addClass( activeChildren, null, options.icons.header ); - } +/* eslint-disable max-len, camelcase */ +/*! + * jQuery UI Datepicker 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ - if ( !clickedIsActive ) { - this._removeClass( clicked, "ui-accordion-header-collapsed" ) - ._addClass( clicked, "ui-accordion-header-active", "ui-state-active" ); - if ( options.icons ) { - clickedChildren = clicked.children( ".ui-accordion-header-icon" ); - this._removeClass( clickedChildren, null, options.icons.header ) - ._addClass( clickedChildren, null, options.icons.activeHeader ); - } +//>>label: Datepicker +//>>group: Widgets +//>>description: Displays a calendar from an input or inline for selecting dates. +//>>docs: http://api.jqueryui.com/datepicker/ +//>>demos: http://jqueryui.com/datepicker/ +//>>css.structure: ../../themes/base/core.css +//>>css.structure: ../../themes/base/datepicker.css +//>>css.theme: ../../themes/base/theme.css - this._addClass( clicked.next(), "ui-accordion-content-active" ); - } - }, - _toggle: function( data ) { - var toShow = data.newPanel, - toHide = this.prevShow.length ? this.prevShow : data.oldPanel; +$.extend( $.ui, { datepicker: { version: "1.13.2" } } ); - // Handle activating a panel during the animation for another activation - this.prevShow.add( this.prevHide ).stop( true, true ); - this.prevShow = toShow; - this.prevHide = toHide; +var datepicker_instActive; - if ( this.options.animate ) { - this._animate( toShow, toHide, data ); - } else { - toHide.hide(); - toShow.show(); - this._toggleComplete( data ); - } +function datepicker_getZindex( elem ) { + var position, value; + while ( elem.length && elem[ 0 ] !== document ) { - toHide.attr( { - "aria-hidden": "true" - } ); - toHide.prev().attr( { - "aria-selected": "false", - "aria-expanded": "false" - } ); + // Ignore z-index if position is set to a value where z-index is ignored by the browser + // This makes behavior of this function consistent across browsers + // WebKit always returns auto if the element is positioned + position = elem.css( "position" ); + if ( position === "absolute" || position === "relative" || position === "fixed" ) { - // if we're switching panels, remove the old header from the tab order - // if we're opening from collapsed state, remove the previous header from the tab order - // if we're collapsing, then keep the collapsing header in the tab order - if ( toShow.length && toHide.length ) { - toHide.prev().attr( { - "tabIndex": -1, - "aria-expanded": "false" - } ); - } else if ( toShow.length ) { - this.headers.filter( function() { - return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0; - } ) - .attr( "tabIndex", -1 ); + // IE returns 0 when zIndex is not specified + // other browsers return a string + // we ignore the case of nested elements with an explicit value of 0 + // <div style="z-index: -10;"><div style="z-index: 0;"></div></div> + value = parseInt( elem.css( "zIndex" ), 10 ); + if ( !isNaN( value ) && value !== 0 ) { + return value; + } } + elem = elem.parent(); + } - toShow - .attr( "aria-hidden", "false" ) - .prev() - .attr( { - "aria-selected": "true", - "aria-expanded": "true", - tabIndex: 0 - } ); - }, + return 0; +} - _animate: function( toShow, toHide, data ) { - var total, easing, duration, - that = this, - adjust = 0, - boxSizing = toShow.css( "box-sizing" ), - down = toShow.length && - ( !toHide.length || ( toShow.index() < toHide.index() ) ), - animate = this.options.animate || {}, - options = down && animate.down || animate, - complete = function() { - that._toggleComplete( data ); - }; +/* Date picker manager. + Use the singleton instance of this class, $.datepicker, to interact with the date picker. + Settings for (groups of) date pickers are maintained in an instance object, + allowing multiple different settings on the same page. */ - if ( typeof options === "number" ) { - duration = options; - } - if ( typeof options === "string" ) { - easing = options; - } +function Datepicker() { + this._curInst = null; // The current instance in use + this._keyEvent = false; // If the last event was a key event + this._disabledInputs = []; // List of date picker inputs that have been disabled + this._datepickerShowing = false; // True if the popup picker is showing , false if not + this._inDialog = false; // True if showing within a "dialog", false if not + this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division + this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class + this._appendClass = "ui-datepicker-append"; // The name of the append marker class + this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class + this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class + this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class + this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class + this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class + this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class + this.regional = []; // Available regional settings, indexed by language code + this.regional[ "" ] = { // Default regional settings + closeText: "Done", // Display text for close link + prevText: "Prev", // Display text for previous month link + nextText: "Next", // Display text for next month link + currentText: "Today", // Display text for current month link + monthNames: [ "January", "February", "March", "April", "May", "June", + "July", "August", "September", "October", "November", "December" ], // Names of months for drop-down and formatting + monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ], // For formatting + dayNames: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], // For formatting + dayNamesShort: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], // For formatting + dayNamesMin: [ "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" ], // Column headings for days starting at Sunday + weekHeader: "Wk", // Column header for week of the year + dateFormat: "mm/dd/yy", // See format options on parseDate + firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... + isRTL: false, // True if right-to-left language, false if left-to-right + showMonthAfterYear: false, // True if the year select precedes month, false for month then year + yearSuffix: "", // Additional text to append to the year in the month headers, + selectMonthLabel: "Select month", // Invisible label for month selector + selectYearLabel: "Select year" // Invisible label for year selector + }; + this._defaults = { // Global defaults for all the date picker instances + showOn: "focus", // "focus" for popup on focus, + // "button" for trigger button, or "both" for either + showAnim: "fadeIn", // Name of jQuery animation for popup + showOptions: {}, // Options for enhanced animations + defaultDate: null, // Used when field is blank: actual date, + // +/-number for offset from today, null for today + appendText: "", // Display text following the input box, e.g. showing the format + buttonText: "...", // Text for trigger button + buttonImage: "", // URL for trigger button image + buttonImageOnly: false, // True if the image appears alone, false if it appears on a button + hideIfNoPrevNext: false, // True to hide next/previous month links + // if not applicable, false to just disable them + navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links + gotoCurrent: false, // True if today link goes back to current selection instead + changeMonth: false, // True if month can be selected directly, false if only prev/next + changeYear: false, // True if year can be selected directly, false if only prev/next + yearRange: "c-10:c+10", // Range of years to display in drop-down, + // either relative to today's year (-nn:+nn), relative to currently displayed year + // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n) + showOtherMonths: false, // True to show dates in other months, false to leave blank + selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable + showWeek: false, // True to show week of the year, false to not show it + calculateWeek: this.iso8601Week, // How to calculate the week of the year, + // takes a Date and returns the number of the week for it + shortYearCutoff: "+10", // Short year values < this are in the current century, + // > this are in the previous century, + // string value starting with "+" for current year + value + minDate: null, // The earliest selectable date, or null for no limit + maxDate: null, // The latest selectable date, or null for no limit + duration: "fast", // Duration of display/closure + beforeShowDay: null, // Function that takes a date and returns an array with + // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "", + // [2] = cell title (optional), e.g. $.datepicker.noWeekends + beforeShow: null, // Function that takes an input field and + // returns a set of custom settings for the date picker + onSelect: null, // Define a callback function when a date is selected + onChangeMonthYear: null, // Define a callback function when the month or year is changed + onClose: null, // Define a callback function when the datepicker is closed + onUpdateDatepicker: null, // Define a callback function when the datepicker is updated + numberOfMonths: 1, // Number of months to show at a time + showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0) + stepMonths: 1, // Number of months to step back/forward + stepBigMonths: 12, // Number of months to step back/forward for the big links + altField: "", // Selector for an alternate field to store selected dates into + altFormat: "", // The date format to use for the alternate field + constrainInput: true, // The input is constrained by the current date format + showButtonPanel: false, // True to show button panel, false to not show it + autoSize: false, // True to size the input for the date format, false to leave as is + disabled: false // The initial disabled state + }; + $.extend( this._defaults, this.regional[ "" ] ); + this.regional.en = $.extend( true, {}, this.regional[ "" ] ); + this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en ); + this.dpDiv = datepicker_bindHover( $( "<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ); +} - // fall back from options to animation in case of partial down settings - easing = easing || options.easing || animate.easing; - duration = duration || options.duration || animate.duration; +$.extend( Datepicker.prototype, { - if ( !toHide.length ) { - return toShow.animate( this.showProps, duration, easing, complete ); - } - if ( !toShow.length ) { - return toHide.animate( this.hideProps, duration, easing, complete ); - } + /* Class name added to elements to indicate already configured with a date picker. */ + markerClassName: "hasDatepicker", - total = toShow.show().outerHeight(); - toHide.animate( this.hideProps, { - duration: duration, - easing: easing, - step: function( now, fx ) { - fx.now = Math.round( now ); - } - } ); - toShow - .hide() - .animate( this.showProps, { - duration: duration, - easing: easing, - complete: complete, - step: function( now, fx ) { - fx.now = Math.round( now ); - if ( fx.prop !== "height" ) { - if ( boxSizing === "content-box" ) { - adjust += fx.now; - } - } else if ( that.options.heightStyle !== "content" ) { - fx.now = Math.round( total - toHide.outerHeight() - adjust ); - adjust = 0; - } - } - } ); - }, + //Keep track of the maximum number of rows displayed (see #7043) + maxRows: 4, - _toggleComplete: function( data ) { - var toHide = data.oldPanel, - prev = toHide.prev(); + // TODO rename to "widget" when switching to widget factory + _widgetDatepicker: function() { + return this.dpDiv; + }, - this._removeClass( toHide, "ui-accordion-content-active" ); - this._removeClass( prev, "ui-accordion-header-active" ) - ._addClass( prev, "ui-accordion-header-collapsed" ); + /* Override the default settings for all instances of the date picker. + * @param settings object - the new settings to use as defaults (anonymous object) + * @return the manager object + */ + setDefaults: function( settings ) { + datepicker_extendRemove( this._defaults, settings || {} ); + return this; + }, - // Work around for rendering bug in IE (#5421) - if ( toHide.length ) { - toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className; + /* Attach the date picker to a jQuery selection. + * @param target element - the target input field or division or span + * @param settings object - the new settings to use for this date picker instance (anonymous) + */ + _attachDatepicker: function( target, settings ) { + var nodeName, inline, inst; + nodeName = target.nodeName.toLowerCase(); + inline = ( nodeName === "div" || nodeName === "span" ); + if ( !target.id ) { + this.uuid += 1; + target.id = "dp" + this.uuid; + } + inst = this._newInst( $( target ), inline ); + inst.settings = $.extend( {}, settings || {} ); + if ( nodeName === "input" ) { + this._connectDatepicker( target, inst ); + } else if ( inline ) { + this._inlineDatepicker( target, inst ); } - this._trigger( "activate", null, data ); - } -} ); - - -/*! - * jQuery UI Menu 1.13.1 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ - -//>>label: Menu -//>>group: Widgets -//>>description: Creates nestable menus. -//>>docs: http://api.jqueryui.com/menu/ -//>>demos: http://jqueryui.com/menu/ -//>>css.structure: ../../themes/base/core.css -//>>css.structure: ../../themes/base/menu.css -//>>css.theme: ../../themes/base/theme.css - - -var widgetsMenu = $.widget( "ui.menu", { - version: "1.13.1", - defaultElement: "<ul>", - delay: 300, - options: { - icons: { - submenu: "ui-icon-caret-1-e" - }, - items: "> *", - menus: "ul", - position: { - my: "left top", - at: "right top" - }, - role: "menu", - - // Callbacks - blur: null, - focus: null, - select: null }, - _create: function() { - this.activeMenu = this.element; + /* Create a new instance object. */ + _newInst: function( target, inline ) { + var id = target[ 0 ].id.replace( /([^A-Za-z0-9_\-])/g, "\\\\$1" ); // escape jQuery meta chars + return { id: id, input: target, // associated target + selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection + drawMonth: 0, drawYear: 0, // month being drawn + inline: inline, // is datepicker inline or not + dpDiv: ( !inline ? this.dpDiv : // presentation div + datepicker_bindHover( $( "<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ) ) }; + }, - // Flag used to prevent firing of the click handler - // as the event bubbles up through nested menus - this.mouseHandled = false; - this.lastMousePosition = { x: null, y: null }; - this.element - .uniqueId() - .attr( { - role: this.options.role, - tabIndex: 0 - } ); + /* Attach the date picker to an input field. */ + _connectDatepicker: function( target, inst ) { + var input = $( target ); + inst.append = $( [] ); + inst.trigger = $( [] ); + if ( input.hasClass( this.markerClassName ) ) { + return; + } + this._attachments( input, inst ); + input.addClass( this.markerClassName ).on( "keydown", this._doKeyDown ). + on( "keypress", this._doKeyPress ).on( "keyup", this._doKeyUp ); + this._autoSize( inst ); + $.data( target, "datepicker", inst ); - this._addClass( "ui-menu", "ui-widget ui-widget-content" ); - this._on( { + //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665) + if ( inst.settings.disabled ) { + this._disableDatepicker( target ); + } + }, - // Prevent focus from sticking to links inside menu after clicking - // them (focus should always stay on UL during navigation). - "mousedown .ui-menu-item": function( event ) { - event.preventDefault(); + /* Make attachments based on settings. */ + _attachments: function( input, inst ) { + var showOn, buttonText, buttonImage, + appendText = this._get( inst, "appendText" ), + isRTL = this._get( inst, "isRTL" ); - this._activateItem( event ); - }, - "click .ui-menu-item": function( event ) { - var target = $( event.target ); - var active = $( $.ui.safeActiveElement( this.document[ 0 ] ) ); - if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) { - this.select( event ); + if ( inst.append ) { + inst.append.remove(); + } + if ( appendText ) { + inst.append = $( "<span>" ) + .addClass( this._appendClass ) + .text( appendText ); + input[ isRTL ? "before" : "after" ]( inst.append ); + } - // Only set the mouseHandled flag if the event will bubble, see #9469. - if ( !event.isPropagationStopped() ) { - this.mouseHandled = true; - } + input.off( "focus", this._showDatepicker ); - // Open submenu on click - if ( target.has( ".ui-menu" ).length ) { - this.expand( event ); - } else if ( !this.element.is( ":focus" ) && - active.closest( ".ui-menu" ).length ) { + if ( inst.trigger ) { + inst.trigger.remove(); + } - // Redirect focus to the menu - this.element.trigger( "focus", [ true ] ); + showOn = this._get( inst, "showOn" ); + if ( showOn === "focus" || showOn === "both" ) { // pop-up date picker when in the marked field + input.on( "focus", this._showDatepicker ); + } + if ( showOn === "button" || showOn === "both" ) { // pop-up date picker when button clicked + buttonText = this._get( inst, "buttonText" ); + buttonImage = this._get( inst, "buttonImage" ); - // If the active item is on the top level, let it stay active. - // Otherwise, blur the active item since it is no longer visible. - if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) { - clearTimeout( this.timer ); - } - } + if ( this._get( inst, "buttonImageOnly" ) ) { + inst.trigger = $( "<img>" ) + .addClass( this._triggerClass ) + .attr( { + src: buttonImage, + alt: buttonText, + title: buttonText + } ); + } else { + inst.trigger = $( "<button type='button'>" ) + .addClass( this._triggerClass ); + if ( buttonImage ) { + inst.trigger.html( + $( "<img>" ) + .attr( { + src: buttonImage, + alt: buttonText, + title: buttonText + } ) + ); + } else { + inst.trigger.text( buttonText ); } - }, - "mouseenter .ui-menu-item": "_activateItem", - "mousemove .ui-menu-item": "_activateItem", - mouseleave: "collapseAll", - "mouseleave .ui-menu": "collapseAll", - focus: function( event, keepActiveItem ) { - - // If there's already an active item, keep it active - // If not, activate the first item - var item = this.active || this._menuItems().first(); + } - if ( !keepActiveItem ) { - this.focus( event, item ); + input[ isRTL ? "before" : "after" ]( inst.trigger ); + inst.trigger.on( "click", function() { + if ( $.datepicker._datepickerShowing && $.datepicker._lastInput === input[ 0 ] ) { + $.datepicker._hideDatepicker(); + } else if ( $.datepicker._datepickerShowing && $.datepicker._lastInput !== input[ 0 ] ) { + $.datepicker._hideDatepicker(); + $.datepicker._showDatepicker( input[ 0 ] ); + } else { + $.datepicker._showDatepicker( input[ 0 ] ); } - }, - blur: function( event ) { - this._delay( function() { - var notContained = !$.contains( - this.element[ 0 ], - $.ui.safeActiveElement( this.document[ 0 ] ) - ); - if ( notContained ) { - this.collapseAll( event ); - } - } ); - }, - keydown: "_keydown" - } ); - - this.refresh(); + return false; + } ); + } + }, - // Clicks outside of a menu collapse any open menus - this._on( this.document, { - click: function( event ) { - if ( this._closeOnDocumentClick( event ) ) { - this.collapseAll( event, true ); - } + /* Apply the maximum length for the date format. */ + _autoSize: function( inst ) { + if ( this._get( inst, "autoSize" ) && !inst.inline ) { + var findMax, max, maxI, i, + date = new Date( 2009, 12 - 1, 20 ), // Ensure double digits + dateFormat = this._get( inst, "dateFormat" ); - // Reset the mouseHandled flag - this.mouseHandled = false; + if ( dateFormat.match( /[DM]/ ) ) { + findMax = function( names ) { + max = 0; + maxI = 0; + for ( i = 0; i < names.length; i++ ) { + if ( names[ i ].length > max ) { + max = names[ i ].length; + maxI = i; + } + } + return maxI; + }; + date.setMonth( findMax( this._get( inst, ( dateFormat.match( /MM/ ) ? + "monthNames" : "monthNamesShort" ) ) ) ); + date.setDate( findMax( this._get( inst, ( dateFormat.match( /DD/ ) ? + "dayNames" : "dayNamesShort" ) ) ) + 20 - date.getDay() ); } - } ); + inst.input.attr( "size", this._formatDate( inst, date ).length ); + } }, - _activateItem: function( event ) { - - // Ignore mouse events while typeahead is active, see #10458. - // Prevents focusing the wrong item when typeahead causes a scroll while the mouse - // is over an item in the menu - if ( this.previousFilter ) { + /* Attach an inline date picker to a div. */ + _inlineDatepicker: function( target, inst ) { + var divSpan = $( target ); + if ( divSpan.hasClass( this.markerClassName ) ) { return; } + divSpan.addClass( this.markerClassName ).append( inst.dpDiv ); + $.data( target, "datepicker", inst ); + this._setDate( inst, this._getDefaultDate( inst ), true ); + this._updateDatepicker( inst ); + this._updateAlternate( inst ); - // If the mouse didn't actually move, but the page was scrolled, ignore the event (#9356) - if ( event.clientX === this.lastMousePosition.x && - event.clientY === this.lastMousePosition.y ) { - return; + //If disabled option is true, disable the datepicker before showing it (see ticket #5665) + if ( inst.settings.disabled ) { + this._disableDatepicker( target ); } - this.lastMousePosition = { - x: event.clientX, - y: event.clientY - }; + // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements + // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height + inst.dpDiv.css( "display", "block" ); + }, - var actualTarget = $( event.target ).closest( ".ui-menu-item" ), - target = $( event.currentTarget ); + /* Pop-up the date picker in a "dialog" box. + * @param input element - ignored + * @param date string or Date - the initial date to display + * @param onSelect function - the function to call when a date is selected + * @param settings object - update the dialog date picker instance's settings (anonymous object) + * @param pos int[2] - coordinates for the dialog's position within the screen or + * event - with x/y coordinates or + * leave empty for default (screen centre) + * @return the manager object + */ + _dialogDatepicker: function( input, date, onSelect, settings, pos ) { + var id, browserWidth, browserHeight, scrollX, scrollY, + inst = this._dialogInst; // internal instance - // Ignore bubbled events on parent items, see #11641 - if ( actualTarget[ 0 ] !== target[ 0 ] ) { - return; + if ( !inst ) { + this.uuid += 1; + id = "dp" + this.uuid; + this._dialogInput = $( "<input type='text' id='" + id + + "' style='position: absolute; top: -100px; width: 0px;'/>" ); + this._dialogInput.on( "keydown", this._doKeyDown ); + $( "body" ).append( this._dialogInput ); + inst = this._dialogInst = this._newInst( this._dialogInput, false ); + inst.settings = {}; + $.data( this._dialogInput[ 0 ], "datepicker", inst ); } + datepicker_extendRemove( inst.settings, settings || {} ); + date = ( date && date.constructor === Date ? this._formatDate( inst, date ) : date ); + this._dialogInput.val( date ); - // If the item is already active, there's nothing to do - if ( target.is( ".ui-state-active" ) ) { - return; + this._pos = ( pos ? ( pos.length ? pos : [ pos.pageX, pos.pageY ] ) : null ); + if ( !this._pos ) { + browserWidth = document.documentElement.clientWidth; + browserHeight = document.documentElement.clientHeight; + scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; + scrollY = document.documentElement.scrollTop || document.body.scrollTop; + this._pos = // should use actual width/height below + [ ( browserWidth / 2 ) - 100 + scrollX, ( browserHeight / 2 ) - 150 + scrollY ]; } - // Remove ui-state-active class from siblings of the newly focused menu item - // to avoid a jump caused by adjacent elements both having a class with a border - this._removeClass( target.siblings().children( ".ui-state-active" ), - null, "ui-state-active" ); - this.focus( event, target ); - }, - - _destroy: function() { - var items = this.element.find( ".ui-menu-item" ) - .removeAttr( "role aria-disabled" ), - submenus = items.children( ".ui-menu-item-wrapper" ) - .removeUniqueId() - .removeAttr( "tabIndex role aria-haspopup" ); - - // Destroy (sub)menus - this.element - .removeAttr( "aria-activedescendant" ) - .find( ".ui-menu" ).addBack() - .removeAttr( "role aria-labelledby aria-expanded aria-hidden aria-disabled " + - "tabIndex" ) - .removeUniqueId() - .show(); - - submenus.children().each( function() { - var elem = $( this ); - if ( elem.data( "ui-menu-submenu-caret" ) ) { - elem.remove(); - } - } ); + // Move input on screen for focus, but hidden behind dialog + this._dialogInput.css( "left", ( this._pos[ 0 ] + 20 ) + "px" ).css( "top", this._pos[ 1 ] + "px" ); + inst.settings.onSelect = onSelect; + this._inDialog = true; + this.dpDiv.addClass( this._dialogClass ); + this._showDatepicker( this._dialogInput[ 0 ] ); + if ( $.blockUI ) { + $.blockUI( this.dpDiv ); + } + $.data( this._dialogInput[ 0 ], "datepicker", inst ); + return this; }, - _keydown: function( event ) { - var match, prev, character, skip, - preventDefault = true; - - switch ( event.keyCode ) { - case $.ui.keyCode.PAGE_UP: - this.previousPage( event ); - break; - case $.ui.keyCode.PAGE_DOWN: - this.nextPage( event ); - break; - case $.ui.keyCode.HOME: - this._move( "first", "first", event ); - break; - case $.ui.keyCode.END: - this._move( "last", "last", event ); - break; - case $.ui.keyCode.UP: - this.previous( event ); - break; - case $.ui.keyCode.DOWN: - this.next( event ); - break; - case $.ui.keyCode.LEFT: - this.collapse( event ); - break; - case $.ui.keyCode.RIGHT: - if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { - this.expand( event ); - } - break; - case $.ui.keyCode.ENTER: - case $.ui.keyCode.SPACE: - this._activate( event ); - break; - case $.ui.keyCode.ESCAPE: - this.collapse( event ); - break; - default: - preventDefault = false; - prev = this.previousFilter || ""; - skip = false; - - // Support number pad values - character = event.keyCode >= 96 && event.keyCode <= 105 ? - ( event.keyCode - 96 ).toString() : String.fromCharCode( event.keyCode ); - - clearTimeout( this.filterTimer ); - - if ( character === prev ) { - skip = true; - } else { - character = prev + character; - } - - match = this._filterMenuItems( character ); - match = skip && match.index( this.active.next() ) !== -1 ? - this.active.nextAll( ".ui-menu-item" ) : - match; + /* Detach a datepicker from its control. + * @param target element - the target input field or division or span + */ + _destroyDatepicker: function( target ) { + var nodeName, + $target = $( target ), + inst = $.data( target, "datepicker" ); - // If no matches on the current filter, reset to the last character pressed - // to move down the menu to the first item that starts with that character - if ( !match.length ) { - character = String.fromCharCode( event.keyCode ); - match = this._filterMenuItems( character ); - } + if ( !$target.hasClass( this.markerClassName ) ) { + return; + } - if ( match.length ) { - this.focus( event, match ); - this.previousFilter = character; - this.filterTimer = this._delay( function() { - delete this.previousFilter; - }, 1000 ); - } else { - delete this.previousFilter; - } + nodeName = target.nodeName.toLowerCase(); + $.removeData( target, "datepicker" ); + if ( nodeName === "input" ) { + inst.append.remove(); + inst.trigger.remove(); + $target.removeClass( this.markerClassName ). + off( "focus", this._showDatepicker ). + off( "keydown", this._doKeyDown ). + off( "keypress", this._doKeyPress ). + off( "keyup", this._doKeyUp ); + } else if ( nodeName === "div" || nodeName === "span" ) { + $target.removeClass( this.markerClassName ).empty(); } - if ( preventDefault ) { - event.preventDefault(); + if ( datepicker_instActive === inst ) { + datepicker_instActive = null; + this._curInst = null; } }, - _activate: function( event ) { - if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { - if ( this.active.children( "[aria-haspopup='true']" ).length ) { - this.expand( event ); - } else { - this.select( event ); - } + /* Enable the date picker to a jQuery selection. + * @param target element - the target input field or division or span + */ + _enableDatepicker: function( target ) { + var nodeName, inline, + $target = $( target ), + inst = $.data( target, "datepicker" ); + + if ( !$target.hasClass( this.markerClassName ) ) { + return; } - }, - refresh: function() { - var menus, items, newSubmenus, newItems, newWrappers, - that = this, - icon = this.options.icons.submenu, - submenus = this.element.find( this.options.menus ); + nodeName = target.nodeName.toLowerCase(); + if ( nodeName === "input" ) { + target.disabled = false; + inst.trigger.filter( "button" ). + each( function() { + this.disabled = false; + } ).end(). + filter( "img" ).css( { opacity: "1.0", cursor: "" } ); + } else if ( nodeName === "div" || nodeName === "span" ) { + inline = $target.children( "." + this._inlineClass ); + inline.children().removeClass( "ui-state-disabled" ); + inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ). + prop( "disabled", false ); + } + this._disabledInputs = $.map( this._disabledInputs, - this._toggleClass( "ui-menu-icons", null, !!this.element.find( ".ui-icon" ).length ); + // Delete entry + function( value ) { + return ( value === target ? null : value ); + } ); + }, - // Initialize nested menus - newSubmenus = submenus.filter( ":not(.ui-menu)" ) - .hide() - .attr( { - role: this.options.role, - "aria-hidden": "true", - "aria-expanded": "false" - } ) - .each( function() { - var menu = $( this ), - item = menu.prev(), - submenuCaret = $( "<span>" ).data( "ui-menu-submenu-caret", true ); - - that._addClass( submenuCaret, "ui-menu-icon", "ui-icon " + icon ); - item - .attr( "aria-haspopup", "true" ) - .prepend( submenuCaret ); - menu.attr( "aria-labelledby", item.attr( "id" ) ); - } ); - - this._addClass( newSubmenus, "ui-menu", "ui-widget ui-widget-content ui-front" ); - - menus = submenus.add( this.element ); - items = menus.find( this.options.items ); - - // Initialize menu-items containing spaces and/or dashes only as dividers - items.not( ".ui-menu-item" ).each( function() { - var item = $( this ); - if ( that._isDivider( item ) ) { - that._addClass( item, "ui-menu-divider", "ui-widget-content" ); - } - } ); - - // Don't refresh list items that are already adapted - newItems = items.not( ".ui-menu-item, .ui-menu-divider" ); - newWrappers = newItems.children() - .not( ".ui-menu" ) - .uniqueId() - .attr( { - tabIndex: -1, - role: this._itemRole() - } ); - this._addClass( newItems, "ui-menu-item" ) - ._addClass( newWrappers, "ui-menu-item-wrapper" ); + /* Disable the date picker to a jQuery selection. + * @param target element - the target input field or division or span + */ + _disableDatepicker: function( target ) { + var nodeName, inline, + $target = $( target ), + inst = $.data( target, "datepicker" ); - // Add aria-disabled attribute to any disabled menu item - items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" ); + if ( !$target.hasClass( this.markerClassName ) ) { + return; + } - // If the active item has been removed, blur the menu - if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { - this.blur(); + nodeName = target.nodeName.toLowerCase(); + if ( nodeName === "input" ) { + target.disabled = true; + inst.trigger.filter( "button" ). + each( function() { + this.disabled = true; + } ).end(). + filter( "img" ).css( { opacity: "0.5", cursor: "default" } ); + } else if ( nodeName === "div" || nodeName === "span" ) { + inline = $target.children( "." + this._inlineClass ); + inline.children().addClass( "ui-state-disabled" ); + inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ). + prop( "disabled", true ); } - }, + this._disabledInputs = $.map( this._disabledInputs, - _itemRole: function() { - return { - menu: "menuitem", - listbox: "option" - }[ this.options.role ]; + // Delete entry + function( value ) { + return ( value === target ? null : value ); + } ); + this._disabledInputs[ this._disabledInputs.length ] = target; }, - _setOption: function( key, value ) { - if ( key === "icons" ) { - var icons = this.element.find( ".ui-menu-icon" ); - this._removeClass( icons, null, this.options.icons.submenu ) - ._addClass( icons, null, value.submenu ); + /* Is the first field in a jQuery collection disabled as a datepicker? + * @param target element - the target input field or division or span + * @return boolean - true if disabled, false if enabled + */ + _isDisabledDatepicker: function( target ) { + if ( !target ) { + return false; } - this._super( key, value ); + for ( var i = 0; i < this._disabledInputs.length; i++ ) { + if ( this._disabledInputs[ i ] === target ) { + return true; + } + } + return false; }, - _setOptionDisabled: function( value ) { - this._super( value ); - - this.element.attr( "aria-disabled", String( value ) ); - this._toggleClass( null, "ui-state-disabled", !!value ); + /* Retrieve the instance data for the target control. + * @param target element - the target input field or division or span + * @return object - the associated instance data + * @throws error if a jQuery problem getting data + */ + _getInst: function( target ) { + try { + return $.data( target, "datepicker" ); + } catch ( err ) { + throw "Missing instance data for this datepicker"; + } }, - focus: function( event, item ) { - var nested, focused, activeParent; - this.blur( event, event && event.type === "focus" ); - - this._scrollIntoView( item ); - - this.active = item.first(); + /* Update or retrieve the settings for a date picker attached to an input field or division. + * @param target element - the target input field or division or span + * @param name object - the new settings to update or + * string - the name of the setting to change or retrieve, + * when retrieving also "all" for all instance settings or + * "defaults" for all global defaults + * @param value any - the new value for the setting + * (omit if above is an object or to retrieve a value) + */ + _optionDatepicker: function( target, name, value ) { + var settings, date, minDate, maxDate, + inst = this._getInst( target ); - focused = this.active.children( ".ui-menu-item-wrapper" ); - this._addClass( focused, null, "ui-state-active" ); + if ( arguments.length === 2 && typeof name === "string" ) { + return ( name === "defaults" ? $.extend( {}, $.datepicker._defaults ) : + ( inst ? ( name === "all" ? $.extend( {}, inst.settings ) : + this._get( inst, name ) ) : null ) ); + } - // Only update aria-activedescendant if there's a role - // otherwise we assume focus is managed elsewhere - if ( this.options.role ) { - this.element.attr( "aria-activedescendant", focused.attr( "id" ) ); + settings = name || {}; + if ( typeof name === "string" ) { + settings = {}; + settings[ name ] = value; } - // Highlight active parent menu item, if any - activeParent = this.active - .parent() - .closest( ".ui-menu-item" ) - .children( ".ui-menu-item-wrapper" ); - this._addClass( activeParent, null, "ui-state-active" ); + if ( inst ) { + if ( this._curInst === inst ) { + this._hideDatepicker(); + } - if ( event && event.type === "keydown" ) { - this._close(); - } else { - this.timer = this._delay( function() { - this._close(); - }, this.delay ); - } + date = this._getDateDatepicker( target, true ); + minDate = this._getMinMaxDate( inst, "min" ); + maxDate = this._getMinMaxDate( inst, "max" ); + datepicker_extendRemove( inst.settings, settings ); - nested = item.children( ".ui-menu" ); - if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) { - this._startOpening( nested ); + // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided + if ( minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined ) { + inst.settings.minDate = this._formatDate( inst, minDate ); + } + if ( maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined ) { + inst.settings.maxDate = this._formatDate( inst, maxDate ); + } + if ( "disabled" in settings ) { + if ( settings.disabled ) { + this._disableDatepicker( target ); + } else { + this._enableDatepicker( target ); + } + } + this._attachments( $( target ), inst ); + this._autoSize( inst ); + this._setDate( inst, date ); + this._updateAlternate( inst ); + this._updateDatepicker( inst ); } - this.activeMenu = item.parent(); - - this._trigger( "focus", event, { item: item } ); }, - _scrollIntoView: function( item ) { - var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight; - if ( this._hasScroll() ) { - borderTop = parseFloat( $.css( this.activeMenu[ 0 ], "borderTopWidth" ) ) || 0; - paddingTop = parseFloat( $.css( this.activeMenu[ 0 ], "paddingTop" ) ) || 0; - offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop; - scroll = this.activeMenu.scrollTop(); - elementHeight = this.activeMenu.height(); - itemHeight = item.outerHeight(); + // Change method deprecated + _changeDatepicker: function( target, name, value ) { + this._optionDatepicker( target, name, value ); + }, - if ( offset < 0 ) { - this.activeMenu.scrollTop( scroll + offset ); - } else if ( offset + itemHeight > elementHeight ) { - this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight ); - } + /* Redraw the date picker attached to an input field or division. + * @param target element - the target input field or division or span + */ + _refreshDatepicker: function( target ) { + var inst = this._getInst( target ); + if ( inst ) { + this._updateDatepicker( inst ); } }, - blur: function( event, fromFocus ) { - if ( !fromFocus ) { - clearTimeout( this.timer ); + /* Set the dates for a jQuery selection. + * @param target element - the target input field or division or span + * @param date Date - the new date + */ + _setDateDatepicker: function( target, date ) { + var inst = this._getInst( target ); + if ( inst ) { + this._setDate( inst, date ); + this._updateDatepicker( inst ); + this._updateAlternate( inst ); } + }, - if ( !this.active ) { - return; + /* Get the date(s) for the first entry in a jQuery selection. + * @param target element - the target input field or division or span + * @param noDefault boolean - true if no default date is to be used + * @return Date - the current date + */ + _getDateDatepicker: function( target, noDefault ) { + var inst = this._getInst( target ); + if ( inst && !inst.inline ) { + this._setDateFromField( inst, noDefault ); } - - this._removeClass( this.active.children( ".ui-menu-item-wrapper" ), - null, "ui-state-active" ); - - this._trigger( "blur", event, { item: this.active } ); - this.active = null; + return ( inst ? this._getDate( inst ) : null ); }, - _startOpening: function( submenu ) { - clearTimeout( this.timer ); + /* Handle keystrokes. */ + _doKeyDown: function( event ) { + var onSelect, dateStr, sel, + inst = $.datepicker._getInst( event.target ), + handled = true, + isRTL = inst.dpDiv.is( ".ui-datepicker-rtl" ); - // Don't open if already open fixes a Firefox bug that caused a .5 pixel - // shift in the submenu position when mousing over the caret icon - if ( submenu.attr( "aria-hidden" ) !== "true" ) { - return; - } + inst._keyEvent = true; + if ( $.datepicker._datepickerShowing ) { + switch ( event.keyCode ) { + case 9: $.datepicker._hideDatepicker(); + handled = false; + break; // hide on tab out + case 13: sel = $( "td." + $.datepicker._dayOverClass + ":not(." + + $.datepicker._currentClass + ")", inst.dpDiv ); + if ( sel[ 0 ] ) { + $.datepicker._selectDay( event.target, inst.selectedMonth, inst.selectedYear, sel[ 0 ] ); + } - this.timer = this._delay( function() { - this._close(); - this._open( submenu ); - }, this.delay ); - }, + onSelect = $.datepicker._get( inst, "onSelect" ); + if ( onSelect ) { + dateStr = $.datepicker._formatDate( inst ); - _open: function( submenu ) { - var position = $.extend( { - of: this.active - }, this.options.position ); + // Trigger custom callback + onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] ); + } else { + $.datepicker._hideDatepicker(); + } - clearTimeout( this.timer ); - this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) ) - .hide() - .attr( "aria-hidden", "true" ); + return false; // don't submit the form + case 27: $.datepicker._hideDatepicker(); + break; // hide on escape + case 33: $.datepicker._adjustDate( event.target, ( event.ctrlKey ? + -$.datepicker._get( inst, "stepBigMonths" ) : + -$.datepicker._get( inst, "stepMonths" ) ), "M" ); + break; // previous month/year on page up/+ ctrl + case 34: $.datepicker._adjustDate( event.target, ( event.ctrlKey ? + +$.datepicker._get( inst, "stepBigMonths" ) : + +$.datepicker._get( inst, "stepMonths" ) ), "M" ); + break; // next month/year on page down/+ ctrl + case 35: if ( event.ctrlKey || event.metaKey ) { + $.datepicker._clearDate( event.target ); + } + handled = event.ctrlKey || event.metaKey; + break; // clear on ctrl or command +end + case 36: if ( event.ctrlKey || event.metaKey ) { + $.datepicker._gotoToday( event.target ); + } + handled = event.ctrlKey || event.metaKey; + break; // current on ctrl or command +home + case 37: if ( event.ctrlKey || event.metaKey ) { + $.datepicker._adjustDate( event.target, ( isRTL ? +1 : -1 ), "D" ); + } + handled = event.ctrlKey || event.metaKey; - submenu - .show() - .removeAttr( "aria-hidden" ) - .attr( "aria-expanded", "true" ) - .position( position ); - }, + // -1 day on ctrl or command +left + if ( event.originalEvent.altKey ) { + $.datepicker._adjustDate( event.target, ( event.ctrlKey ? + -$.datepicker._get( inst, "stepBigMonths" ) : + -$.datepicker._get( inst, "stepMonths" ) ), "M" ); + } - collapseAll: function( event, all ) { - clearTimeout( this.timer ); - this.timer = this._delay( function() { + // next month/year on alt +left on Mac + break; + case 38: if ( event.ctrlKey || event.metaKey ) { + $.datepicker._adjustDate( event.target, -7, "D" ); + } + handled = event.ctrlKey || event.metaKey; + break; // -1 week on ctrl or command +up + case 39: if ( event.ctrlKey || event.metaKey ) { + $.datepicker._adjustDate( event.target, ( isRTL ? -1 : +1 ), "D" ); + } + handled = event.ctrlKey || event.metaKey; - // If we were passed an event, look for the submenu that contains the event - var currentMenu = all ? this.element : - $( event && event.target ).closest( this.element.find( ".ui-menu" ) ); + // +1 day on ctrl or command +right + if ( event.originalEvent.altKey ) { + $.datepicker._adjustDate( event.target, ( event.ctrlKey ? + +$.datepicker._get( inst, "stepBigMonths" ) : + +$.datepicker._get( inst, "stepMonths" ) ), "M" ); + } - // If we found no valid submenu ancestor, use the main menu to close all - // sub menus anyway - if ( !currentMenu.length ) { - currentMenu = this.element; + // next month/year on alt +right + break; + case 40: if ( event.ctrlKey || event.metaKey ) { + $.datepicker._adjustDate( event.target, +7, "D" ); + } + handled = event.ctrlKey || event.metaKey; + break; // +1 week on ctrl or command +down + default: handled = false; } - - this._close( currentMenu ); - - this.blur( event ); - - // Work around active item staying active after menu is blurred - this._removeClass( currentMenu.find( ".ui-state-active" ), null, "ui-state-active" ); - - this.activeMenu = currentMenu; - }, all ? 0 : this.delay ); - }, - - // With no arguments, closes the currently active menu - if nothing is active - // it closes all menus. If passed an argument, it will search for menus BELOW - _close: function( startMenu ) { - if ( !startMenu ) { - startMenu = this.active ? this.active.parent() : this.element; + } else if ( event.keyCode === 36 && event.ctrlKey ) { // display the date picker on ctrl+home + $.datepicker._showDatepicker( this ); + } else { + handled = false; } - startMenu.find( ".ui-menu" ) - .hide() - .attr( "aria-hidden", "true" ) - .attr( "aria-expanded", "false" ); - }, - - _closeOnDocumentClick: function( event ) { - return !$( event.target ).closest( ".ui-menu" ).length; + if ( handled ) { + event.preventDefault(); + event.stopPropagation(); + } }, - _isDivider: function( item ) { - - // Match hyphen, em dash, en dash - return !/[^\-\u2014\u2013\s]/.test( item.text() ); - }, + /* Filter entered characters - based on date format. */ + _doKeyPress: function( event ) { + var chars, chr, + inst = $.datepicker._getInst( event.target ); - collapse: function( event ) { - var newItem = this.active && - this.active.parent().closest( ".ui-menu-item", this.element ); - if ( newItem && newItem.length ) { - this._close(); - this.focus( event, newItem ); + if ( $.datepicker._get( inst, "constrainInput" ) ) { + chars = $.datepicker._possibleChars( $.datepicker._get( inst, "dateFormat" ) ); + chr = String.fromCharCode( event.charCode == null ? event.keyCode : event.charCode ); + return event.ctrlKey || event.metaKey || ( chr < " " || !chars || chars.indexOf( chr ) > -1 ); } }, - expand: function( event ) { - var newItem = this.active && this._menuItems( this.active.children( ".ui-menu" ) ).first(); + /* Synchronise manual entry and field/alternate field. */ + _doKeyUp: function( event ) { + var date, + inst = $.datepicker._getInst( event.target ); - if ( newItem && newItem.length ) { - this._open( newItem.parent() ); + if ( inst.input.val() !== inst.lastVal ) { + try { + date = $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ), + ( inst.input ? inst.input.val() : null ), + $.datepicker._getFormatConfig( inst ) ); - // Delay so Firefox will not hide activedescendant change in expanding submenu from AT - this._delay( function() { - this.focus( event, newItem ); - } ); + if ( date ) { // only if valid + $.datepicker._setDateFromField( inst ); + $.datepicker._updateAlternate( inst ); + $.datepicker._updateDatepicker( inst ); + } + } catch ( err ) { + } } + return true; }, - next: function( event ) { - this._move( "next", "first", event ); - }, - - previous: function( event ) { - this._move( "prev", "last", event ); - }, - - isFirstItem: function() { - return this.active && !this.active.prevAll( ".ui-menu-item" ).length; - }, + /* Pop-up the date picker for a given input field. + * If false returned from beforeShow event handler do not show. + * @param input element - the input field attached to the date picker or + * event - if triggered by focus + */ + _showDatepicker: function( input ) { + input = input.target || input; + if ( input.nodeName.toLowerCase() !== "input" ) { // find from button/image trigger + input = $( "input", input.parentNode )[ 0 ]; + } - isLastItem: function() { - return this.active && !this.active.nextAll( ".ui-menu-item" ).length; - }, + if ( $.datepicker._isDisabledDatepicker( input ) || $.datepicker._lastInput === input ) { // already here + return; + } - _menuItems: function( menu ) { - return ( menu || this.element ) - .find( this.options.items ) - .filter( ".ui-menu-item" ); - }, + var inst, beforeShow, beforeShowSettings, isFixed, + offset, showAnim, duration; - _move: function( direction, filter, event ) { - var next; - if ( this.active ) { - if ( direction === "first" || direction === "last" ) { - next = this.active - [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" ) - .last(); - } else { - next = this.active - [ direction + "All" ]( ".ui-menu-item" ) - .first(); + inst = $.datepicker._getInst( input ); + if ( $.datepicker._curInst && $.datepicker._curInst !== inst ) { + $.datepicker._curInst.dpDiv.stop( true, true ); + if ( inst && $.datepicker._datepickerShowing ) { + $.datepicker._hideDatepicker( $.datepicker._curInst.input[ 0 ] ); } } - if ( !next || !next.length || !this.active ) { - next = this._menuItems( this.activeMenu )[ filter ](); + + beforeShow = $.datepicker._get( inst, "beforeShow" ); + beforeShowSettings = beforeShow ? beforeShow.apply( input, [ input, inst ] ) : {}; + if ( beforeShowSettings === false ) { + return; } + datepicker_extendRemove( inst.settings, beforeShowSettings ); - this.focus( event, next ); - }, + inst.lastVal = null; + $.datepicker._lastInput = input; + $.datepicker._setDateFromField( inst ); - nextPage: function( event ) { - var item, base, height; - - if ( !this.active ) { - this.next( event ); - return; + if ( $.datepicker._inDialog ) { // hide cursor + input.value = ""; } - if ( this.isLastItem() ) { - return; + if ( !$.datepicker._pos ) { // position below input + $.datepicker._pos = $.datepicker._findPos( input ); + $.datepicker._pos[ 1 ] += input.offsetHeight; // add the height } - if ( this._hasScroll() ) { - base = this.active.offset().top; - height = this.element.innerHeight(); - // jQuery 3.2 doesn't include scrollbars in innerHeight, add it back. - if ( $.fn.jquery.indexOf( "3.2." ) === 0 ) { - height += this.element[ 0 ].offsetHeight - this.element.outerHeight(); - } + isFixed = false; + $( input ).parents().each( function() { + isFixed |= $( this ).css( "position" ) === "fixed"; + return !isFixed; + } ); - this.active.nextAll( ".ui-menu-item" ).each( function() { - item = $( this ); - return item.offset().top - base - height < 0; - } ); + offset = { left: $.datepicker._pos[ 0 ], top: $.datepicker._pos[ 1 ] }; + $.datepicker._pos = null; - this.focus( event, item ); - } else { - this.focus( event, this._menuItems( this.activeMenu ) - [ !this.active ? "first" : "last" ]() ); - } - }, + //to avoid flashes on Firefox + inst.dpDiv.empty(); - previousPage: function( event ) { - var item, base, height; - if ( !this.active ) { - this.next( event ); - return; - } - if ( this.isFirstItem() ) { - return; - } - if ( this._hasScroll() ) { - base = this.active.offset().top; - height = this.element.innerHeight(); + // determine sizing offscreen + inst.dpDiv.css( { position: "absolute", display: "block", top: "-1000px" } ); + $.datepicker._updateDatepicker( inst ); - // jQuery 3.2 doesn't include scrollbars in innerHeight, add it back. - if ( $.fn.jquery.indexOf( "3.2." ) === 0 ) { - height += this.element[ 0 ].offsetHeight - this.element.outerHeight(); + // fix width for dynamic number of date pickers + // and adjust position before showing + offset = $.datepicker._checkOffset( inst, offset, isFixed ); + inst.dpDiv.css( { position: ( $.datepicker._inDialog && $.blockUI ? + "static" : ( isFixed ? "fixed" : "absolute" ) ), display: "none", + left: offset.left + "px", top: offset.top + "px" } ); + + if ( !inst.inline ) { + showAnim = $.datepicker._get( inst, "showAnim" ); + duration = $.datepicker._get( inst, "duration" ); + inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 ); + $.datepicker._datepickerShowing = true; + + if ( $.effects && $.effects.effect[ showAnim ] ) { + inst.dpDiv.show( showAnim, $.datepicker._get( inst, "showOptions" ), duration ); + } else { + inst.dpDiv[ showAnim || "show" ]( showAnim ? duration : null ); } - this.active.prevAll( ".ui-menu-item" ).each( function() { - item = $( this ); - return item.offset().top - base + height > 0; - } ); + if ( $.datepicker._shouldFocusInput( inst ) ) { + inst.input.trigger( "focus" ); + } - this.focus( event, item ); - } else { - this.focus( event, this._menuItems( this.activeMenu ).first() ); + $.datepicker._curInst = inst; } }, - _hasScroll: function() { - return this.element.outerHeight() < this.element.prop( "scrollHeight" ); - }, + /* Generate the date picker content. */ + _updateDatepicker: function( inst ) { + this.maxRows = 4; //Reset the max number of rows being displayed (see #7043) + datepicker_instActive = inst; // for delegate hover events + inst.dpDiv.empty().append( this._generateHTML( inst ) ); + this._attachHandlers( inst ); - select: function( event ) { + var origyearshtml, + numMonths = this._getNumberOfMonths( inst ), + cols = numMonths[ 1 ], + width = 17, + activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" ), + onUpdateDatepicker = $.datepicker._get( inst, "onUpdateDatepicker" ); - // TODO: It should never be possible to not have an active item at this - // point, but the tests don't trigger mouseenter before click. - this.active = this.active || $( event.target ).closest( ".ui-menu-item" ); - var ui = { item: this.active }; - if ( !this.active.has( ".ui-menu" ).length ) { - this.collapseAll( event, true ); + if ( activeCell.length > 0 ) { + datepicker_handleMouseover.apply( activeCell.get( 0 ) ); } - this._trigger( "select", event, ui ); - }, - _filterMenuItems: function( character ) { - var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ), - regex = new RegExp( "^" + escapedCharacter, "i" ); + inst.dpDiv.removeClass( "ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4" ).width( "" ); + if ( cols > 1 ) { + inst.dpDiv.addClass( "ui-datepicker-multi-" + cols ).css( "width", ( width * cols ) + "em" ); + } + inst.dpDiv[ ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ? "add" : "remove" ) + + "Class" ]( "ui-datepicker-multi" ); + inst.dpDiv[ ( this._get( inst, "isRTL" ) ? "add" : "remove" ) + + "Class" ]( "ui-datepicker-rtl" ); - return this.activeMenu - .find( this.options.items ) + if ( inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) { + inst.input.trigger( "focus" ); + } - // Only match on items, not dividers or other content (#10571) - .filter( ".ui-menu-item" ) - .filter( function() { - return regex.test( - String.prototype.trim.call( - $( this ).children( ".ui-menu-item-wrapper" ).text() ) ); - } ); - } -} ); + // Deffered render of the years select (to avoid flashes on Firefox) + if ( inst.yearshtml ) { + origyearshtml = inst.yearshtml; + setTimeout( function() { + //assure that inst.yearshtml didn't change. + if ( origyearshtml === inst.yearshtml && inst.yearshtml ) { + inst.dpDiv.find( "select.ui-datepicker-year" ).first().replaceWith( inst.yearshtml ); + } + origyearshtml = inst.yearshtml = null; + }, 0 ); + } -/*! - * jQuery UI Autocomplete 1.13.1 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ + if ( onUpdateDatepicker ) { + onUpdateDatepicker.apply( ( inst.input ? inst.input[ 0 ] : null ), [ inst ] ); + } + }, -//>>label: Autocomplete -//>>group: Widgets -//>>description: Lists suggested words as the user is typing. -//>>docs: http://api.jqueryui.com/autocomplete/ -//>>demos: http://jqueryui.com/autocomplete/ -//>>css.structure: ../../themes/base/core.css -//>>css.structure: ../../themes/base/autocomplete.css -//>>css.theme: ../../themes/base/theme.css + // #6694 - don't focus the input if it's already focused + // this breaks the change event in IE + // Support: IE and jQuery <1.9 + _shouldFocusInput: function( inst ) { + return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" ); + }, + /* Check positioning to remain on screen. */ + _checkOffset: function( inst, offset, isFixed ) { + var dpWidth = inst.dpDiv.outerWidth(), + dpHeight = inst.dpDiv.outerHeight(), + inputWidth = inst.input ? inst.input.outerWidth() : 0, + inputHeight = inst.input ? inst.input.outerHeight() : 0, + viewWidth = document.documentElement.clientWidth + ( isFixed ? 0 : $( document ).scrollLeft() ), + viewHeight = document.documentElement.clientHeight + ( isFixed ? 0 : $( document ).scrollTop() ); -$.widget( "ui.autocomplete", { - version: "1.13.1", - defaultElement: "<input>", - options: { - appendTo: null, - autoFocus: false, - delay: 300, - minLength: 1, - position: { - my: "left top", - at: "left bottom", - collision: "none" - }, - source: null, + offset.left -= ( this._get( inst, "isRTL" ) ? ( dpWidth - inputWidth ) : 0 ); + offset.left -= ( isFixed && offset.left === inst.input.offset().left ) ? $( document ).scrollLeft() : 0; + offset.top -= ( isFixed && offset.top === ( inst.input.offset().top + inputHeight ) ) ? $( document ).scrollTop() : 0; - // Callbacks - change: null, - close: null, - focus: null, - open: null, - response: null, - search: null, - select: null - }, + // Now check if datepicker is showing outside window viewport - move to a better place if so. + offset.left -= Math.min( offset.left, ( offset.left + dpWidth > viewWidth && viewWidth > dpWidth ) ? + Math.abs( offset.left + dpWidth - viewWidth ) : 0 ); + offset.top -= Math.min( offset.top, ( offset.top + dpHeight > viewHeight && viewHeight > dpHeight ) ? + Math.abs( dpHeight + inputHeight ) : 0 ); - requestIndex: 0, - pending: 0, - liveRegionTimer: null, + return offset; + }, - _create: function() { + /* Find an object's position on the screen. */ + _findPos: function( obj ) { + var position, + inst = this._getInst( obj ), + isRTL = this._get( inst, "isRTL" ); - // Some browsers only repeat keydown events, not keypress events, - // so we use the suppressKeyPress flag to determine if we've already - // handled the keydown event. #7269 - // Unfortunately the code for & in keypress is the same as the up arrow, - // so we use the suppressKeyPressRepeat flag to avoid handling keypress - // events when we know the keydown event was used to modify the - // search term. #7799 - var suppressKeyPress, suppressKeyPressRepeat, suppressInput, - nodeName = this.element[ 0 ].nodeName.toLowerCase(), - isTextarea = nodeName === "textarea", - isInput = nodeName === "input"; + while ( obj && ( obj.type === "hidden" || obj.nodeType !== 1 || $.expr.pseudos.hidden( obj ) ) ) { + obj = obj[ isRTL ? "previousSibling" : "nextSibling" ]; + } - // Textareas are always multi-line - // Inputs are always single-line, even if inside a contentEditable element - // IE also treats inputs as contentEditable - // All other element types are determined by whether or not they're contentEditable - this.isMultiLine = isTextarea || !isInput && this._isContentEditable( this.element ); + position = $( obj ).offset(); + return [ position.left, position.top ]; + }, - this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ]; - this.isNewMenu = true; + /* Hide the date picker from view. + * @param input element - the input field attached to the date picker + */ + _hideDatepicker: function( input ) { + var showAnim, duration, postProcess, onClose, + inst = this._curInst; - this._addClass( "ui-autocomplete-input" ); - this.element.attr( "autocomplete", "off" ); + if ( !inst || ( input && inst !== $.data( input, "datepicker" ) ) ) { + return; + } - this._on( this.element, { - keydown: function( event ) { - if ( this.element.prop( "readOnly" ) ) { - suppressKeyPress = true; - suppressInput = true; - suppressKeyPressRepeat = true; - return; - } - - suppressKeyPress = false; - suppressInput = false; - suppressKeyPressRepeat = false; - var keyCode = $.ui.keyCode; - switch ( event.keyCode ) { - case keyCode.PAGE_UP: - suppressKeyPress = true; - this._move( "previousPage", event ); - break; - case keyCode.PAGE_DOWN: - suppressKeyPress = true; - this._move( "nextPage", event ); - break; - case keyCode.UP: - suppressKeyPress = true; - this._keyEvent( "previous", event ); - break; - case keyCode.DOWN: - suppressKeyPress = true; - this._keyEvent( "next", event ); - break; - case keyCode.ENTER: - - // when menu is open and has focus - if ( this.menu.active ) { + if ( this._datepickerShowing ) { + showAnim = this._get( inst, "showAnim" ); + duration = this._get( inst, "duration" ); + postProcess = function() { + $.datepicker._tidyDialog( inst ); + }; - // #6055 - Opera still allows the keypress to occur - // which causes forms to submit - suppressKeyPress = true; - event.preventDefault(); - this.menu.select( event ); - } - break; - case keyCode.TAB: - if ( this.menu.active ) { - this.menu.select( event ); - } - break; - case keyCode.ESCAPE: - if ( this.menu.element.is( ":visible" ) ) { - if ( !this.isMultiLine ) { - this._value( this.term ); - } - this.close( event ); + // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed + if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) { + inst.dpDiv.hide( showAnim, $.datepicker._get( inst, "showOptions" ), duration, postProcess ); + } else { + inst.dpDiv[ ( showAnim === "slideDown" ? "slideUp" : + ( showAnim === "fadeIn" ? "fadeOut" : "hide" ) ) ]( ( showAnim ? duration : null ), postProcess ); + } - // Different browsers have different default behavior for escape - // Single press can mean undo or clear - // Double press in IE means clear the whole form - event.preventDefault(); - } - break; - default: - suppressKeyPressRepeat = true; + if ( !showAnim ) { + postProcess(); + } + this._datepickerShowing = false; - // search timeout should be triggered before the input value is changed - this._searchTimeout( event ); - break; - } - }, - keypress: function( event ) { - if ( suppressKeyPress ) { - suppressKeyPress = false; - if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { - event.preventDefault(); - } - return; - } - if ( suppressKeyPressRepeat ) { - return; - } + onClose = this._get( inst, "onClose" ); + if ( onClose ) { + onClose.apply( ( inst.input ? inst.input[ 0 ] : null ), [ ( inst.input ? inst.input.val() : "" ), inst ] ); + } - // Replicate some key handlers to allow them to repeat in Firefox and Opera - var keyCode = $.ui.keyCode; - switch ( event.keyCode ) { - case keyCode.PAGE_UP: - this._move( "previousPage", event ); - break; - case keyCode.PAGE_DOWN: - this._move( "nextPage", event ); - break; - case keyCode.UP: - this._keyEvent( "previous", event ); - break; - case keyCode.DOWN: - this._keyEvent( "next", event ); - break; - } - }, - input: function( event ) { - if ( suppressInput ) { - suppressInput = false; - event.preventDefault(); - return; + this._lastInput = null; + if ( this._inDialog ) { + this._dialogInput.css( { position: "absolute", left: "0", top: "-100px" } ); + if ( $.blockUI ) { + $.unblockUI(); + $( "body" ).append( this.dpDiv ); } - this._searchTimeout( event ); - }, - focus: function() { - this.selectedItem = null; - this.previous = this._value(); - }, - blur: function( event ) { - clearTimeout( this.searching ); - this.close( event ); - this._change( event ); } - } ); + this._inDialog = false; + } + }, - this._initSource(); - this.menu = $( "<ul>" ) - .appendTo( this._appendTo() ) - .menu( { + /* Tidy up after a dialog display. */ + _tidyDialog: function( inst ) { + inst.dpDiv.removeClass( this._dialogClass ).off( ".ui-datepicker-calendar" ); + }, - // disable ARIA support, the live region takes care of that - role: null - } ) - .hide() + /* Close date picker if clicked elsewhere. */ + _checkExternalClick: function( event ) { + if ( !$.datepicker._curInst ) { + return; + } - // Support: IE 11 only, Edge <= 14 - // For other browsers, we preventDefault() on the mousedown event - // to keep the dropdown from taking focus from the input. This doesn't - // work for IE/Edge, causing problems with selection and scrolling (#9638) - // Happily, IE and Edge support an "unselectable" attribute that - // prevents an element from receiving focus, exactly what we want here. - .attr( { - "unselectable": "on" - } ) - .menu( "instance" ); + var $target = $( event.target ), + inst = $.datepicker._getInst( $target[ 0 ] ); - this._addClass( this.menu.element, "ui-autocomplete", "ui-front" ); - this._on( this.menu.element, { - mousedown: function( event ) { + if ( ( ( $target[ 0 ].id !== $.datepicker._mainDivId && + $target.parents( "#" + $.datepicker._mainDivId ).length === 0 && + !$target.hasClass( $.datepicker.markerClassName ) && + !$target.closest( "." + $.datepicker._triggerClass ).length && + $.datepicker._datepickerShowing && !( $.datepicker._inDialog && $.blockUI ) ) ) || + ( $target.hasClass( $.datepicker.markerClassName ) && $.datepicker._curInst !== inst ) ) { + $.datepicker._hideDatepicker(); + } + }, - // Prevent moving focus out of the text field - event.preventDefault(); - }, - menufocus: function( event, ui ) { - var label, item; + /* Adjust one of the date sub-fields. */ + _adjustDate: function( id, offset, period ) { + var target = $( id ), + inst = this._getInst( target[ 0 ] ); - // support: Firefox - // Prevent accidental activation of menu items in Firefox (#7024 #9118) - if ( this.isNewMenu ) { - this.isNewMenu = false; - if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) { - this.menu.blur(); + if ( this._isDisabledDatepicker( target[ 0 ] ) ) { + return; + } + this._adjustInstDate( inst, offset, period ); + this._updateDatepicker( inst ); + }, - this.document.one( "mousemove", function() { - $( event.target ).trigger( event.originalEvent ); - } ); + /* Action for current link. */ + _gotoToday: function( id ) { + var date, + target = $( id ), + inst = this._getInst( target[ 0 ] ); - return; - } - } + if ( this._get( inst, "gotoCurrent" ) && inst.currentDay ) { + inst.selectedDay = inst.currentDay; + inst.drawMonth = inst.selectedMonth = inst.currentMonth; + inst.drawYear = inst.selectedYear = inst.currentYear; + } else { + date = new Date(); + inst.selectedDay = date.getDate(); + inst.drawMonth = inst.selectedMonth = date.getMonth(); + inst.drawYear = inst.selectedYear = date.getFullYear(); + } + this._notifyChange( inst ); + this._adjustDate( target ); + }, - item = ui.item.data( "ui-autocomplete-item" ); - if ( false !== this._trigger( "focus", event, { item: item } ) ) { + /* Action for selecting a new month/year. */ + _selectMonthYear: function( id, select, period ) { + var target = $( id ), + inst = this._getInst( target[ 0 ] ); - // use value to match what will end up in the input, if it was a key event - if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) { - this._value( item.value ); - } - } + inst[ "selected" + ( period === "M" ? "Month" : "Year" ) ] = + inst[ "draw" + ( period === "M" ? "Month" : "Year" ) ] = + parseInt( select.options[ select.selectedIndex ].value, 10 ); - // Announce the value in the liveRegion - label = ui.item.attr( "aria-label" ) || item.value; - if ( label && String.prototype.trim.call( label ).length ) { - clearTimeout( this.liveRegionTimer ); - this.liveRegionTimer = this._delay( function() { - this.liveRegion.html( $( "<div>" ).text( label ) ); - }, 100 ); - } - }, - menuselect: function( event, ui ) { - var item = ui.item.data( "ui-autocomplete-item" ), - previous = this.previous; + this._notifyChange( inst ); + this._adjustDate( target ); + }, - // Only trigger when focus was lost (click on menu) - if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) { - this.element.trigger( "focus" ); - this.previous = previous; - - // #6109 - IE triggers two focus events and the second - // is asynchronous, so we need to reset the previous - // term synchronously and asynchronously :-( - this._delay( function() { - this.previous = previous; - this.selectedItem = item; - } ); - } - - if ( false !== this._trigger( "select", event, { item: item } ) ) { - this._value( item.value ); - } - - // reset the term after the select event - // this allows custom select handling to work properly - this.term = this._value(); - - this.close( event ); - this.selectedItem = item; - } - } ); - - this.liveRegion = $( "<div>", { - role: "status", - "aria-live": "assertive", - "aria-relevant": "additions" - } ) - .appendTo( this.document[ 0 ].body ); - - this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" ); - - // Turning off autocomplete prevents the browser from remembering the - // value when navigating through history, so we re-enable autocomplete - // if the page is unloaded before the widget is destroyed. #7790 - this._on( this.window, { - beforeunload: function() { - this.element.removeAttr( "autocomplete" ); - } - } ); - }, - - _destroy: function() { - clearTimeout( this.searching ); - this.element.removeAttr( "autocomplete" ); - this.menu.element.remove(); - this.liveRegion.remove(); - }, + /* Action for selecting a day. */ + _selectDay: function( id, month, year, td ) { + var inst, + target = $( id ); - _setOption: function( key, value ) { - this._super( key, value ); - if ( key === "source" ) { - this._initSource(); - } - if ( key === "appendTo" ) { - this.menu.element.appendTo( this._appendTo() ); - } - if ( key === "disabled" && value && this.xhr ) { - this.xhr.abort(); + if ( $( td ).hasClass( this._unselectableClass ) || this._isDisabledDatepicker( target[ 0 ] ) ) { + return; } - }, - - _isEventTargetInWidget: function( event ) { - var menuElement = this.menu.element[ 0 ]; - return event.target === this.element[ 0 ] || - event.target === menuElement || - $.contains( menuElement, event.target ); + inst = this._getInst( target[ 0 ] ); + inst.selectedDay = inst.currentDay = parseInt( $( "a", td ).attr( "data-date" ) ); + inst.selectedMonth = inst.currentMonth = month; + inst.selectedYear = inst.currentYear = year; + this._selectDate( id, this._formatDate( inst, + inst.currentDay, inst.currentMonth, inst.currentYear ) ); }, - _closeOnClickOutside: function( event ) { - if ( !this._isEventTargetInWidget( event ) ) { - this.close(); - } + /* Erase the input field and hide the date picker. */ + _clearDate: function( id ) { + var target = $( id ); + this._selectDate( target, "" ); }, - _appendTo: function() { - var element = this.options.appendTo; - - if ( element ) { - element = element.jquery || element.nodeType ? - $( element ) : - this.document.find( element ).eq( 0 ); - } + /* Update the input field with the selected date. */ + _selectDate: function( id, dateStr ) { + var onSelect, + target = $( id ), + inst = this._getInst( target[ 0 ] ); - if ( !element || !element[ 0 ] ) { - element = this.element.closest( ".ui-front, dialog" ); + dateStr = ( dateStr != null ? dateStr : this._formatDate( inst ) ); + if ( inst.input ) { + inst.input.val( dateStr ); } + this._updateAlternate( inst ); - if ( !element.length ) { - element = this.document[ 0 ].body; + onSelect = this._get( inst, "onSelect" ); + if ( onSelect ) { + onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] ); // trigger custom callback + } else if ( inst.input ) { + inst.input.trigger( "change" ); // fire the change event } - return element; - }, - - _initSource: function() { - var array, url, - that = this; - if ( Array.isArray( this.options.source ) ) { - array = this.options.source; - this.source = function( request, response ) { - response( $.ui.autocomplete.filter( array, request.term ) ); - }; - } else if ( typeof this.options.source === "string" ) { - url = this.options.source; - this.source = function( request, response ) { - if ( that.xhr ) { - that.xhr.abort(); - } - that.xhr = $.ajax( { - url: url, - data: request, - dataType: "json", - success: function( data ) { - response( data ); - }, - error: function() { - response( [] ); - } - } ); - }; + if ( inst.inline ) { + this._updateDatepicker( inst ); } else { - this.source = this.options.source; - } - }, - - _searchTimeout: function( event ) { - clearTimeout( this.searching ); - this.searching = this._delay( function() { - - // Search if the value has changed, or if the user retypes the same value (see #7434) - var equalValues = this.term === this._value(), - menuVisible = this.menu.element.is( ":visible" ), - modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey; - - if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) { - this.selectedItem = null; - this.search( null, event ); + this._hideDatepicker(); + this._lastInput = inst.input[ 0 ]; + if ( typeof( inst.input[ 0 ] ) !== "object" ) { + inst.input.trigger( "focus" ); // restore focus } - }, this.options.delay ); + this._lastInput = null; + } }, - search: function( value, event ) { - value = value != null ? value : this._value(); - - // Always save the actual value, not the one passed as an argument - this.term = this._value(); - - if ( value.length < this.options.minLength ) { - return this.close( event ); - } + /* Update any alternate field to synchronise with the main field. */ + _updateAlternate: function( inst ) { + var altFormat, date, dateStr, + altField = this._get( inst, "altField" ); - if ( this._trigger( "search", event ) === false ) { - return; + if ( altField ) { // update alternate field too + altFormat = this._get( inst, "altFormat" ) || this._get( inst, "dateFormat" ); + date = this._getDate( inst ); + dateStr = this.formatDate( altFormat, date, this._getFormatConfig( inst ) ); + $( document ).find( altField ).val( dateStr ); } - - return this._search( value ); }, - _search: function( value ) { - this.pending++; - this._addClass( "ui-autocomplete-loading" ); - this.cancelSearch = false; - - this.source( { term: value }, this._response() ); + /* Set as beforeShowDay function to prevent selection of weekends. + * @param date Date - the date to customise + * @return [boolean, string] - is this date selectable?, what is its CSS class? + */ + noWeekends: function( date ) { + var day = date.getDay(); + return [ ( day > 0 && day < 6 ), "" ]; }, - _response: function() { - var index = ++this.requestIndex; + /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. + * @param date Date - the date to get the week for + * @return number - the number of the week within the year that contains this date + */ + iso8601Week: function( date ) { + var time, + checkDate = new Date( date.getTime() ); - return function( content ) { - if ( index === this.requestIndex ) { - this.__response( content ); - } + // Find Thursday of this week starting on Monday + checkDate.setDate( checkDate.getDate() + 4 - ( checkDate.getDay() || 7 ) ); - this.pending--; - if ( !this.pending ) { - this._removeClass( "ui-autocomplete-loading" ); - } - }.bind( this ); + time = checkDate.getTime(); + checkDate.setMonth( 0 ); // Compare with Jan 1 + checkDate.setDate( 1 ); + return Math.floor( Math.round( ( time - checkDate ) / 86400000 ) / 7 ) + 1; }, - __response: function( content ) { - if ( content ) { - content = this._normalize( content ); + /* Parse a string value into a date object. + * See formatDate below for the possible formats. + * + * @param format string - the expected format of the date + * @param value string - the date in the above format + * @param settings Object - attributes include: + * shortYearCutoff number - the cutoff year for determining the century (optional) + * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) + * dayNames string[7] - names of the days from Sunday (optional) + * monthNamesShort string[12] - abbreviated names of the months (optional) + * monthNames string[12] - names of the months (optional) + * @return Date - the extracted date value or null if value is blank + */ + parseDate: function( format, value, settings ) { + if ( format == null || value == null ) { + throw "Invalid arguments"; } - this._trigger( "response", null, { content: content } ); - if ( !this.options.disabled && content && content.length && !this.cancelSearch ) { - this._suggest( content ); - this._trigger( "open" ); - } else { - // use ._close() instead of .close() so we don't cancel future searches - this._close(); + value = ( typeof value === "object" ? value.toString() : value + "" ); + if ( value === "" ) { + return null; } - }, - close: function( event ) { - this.cancelSearch = true; - this._close( event ); - }, + var iFormat, dim, extra, + iValue = 0, + shortYearCutoffTemp = ( settings ? settings.shortYearCutoff : null ) || this._defaults.shortYearCutoff, + shortYearCutoff = ( typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp : + new Date().getFullYear() % 100 + parseInt( shortYearCutoffTemp, 10 ) ), + dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort, + dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames, + monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort, + monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames, + year = -1, + month = -1, + day = -1, + doy = -1, + literal = false, + date, - _close: function( event ) { + // Check whether a format character is doubled + lookAhead = function( match ) { + var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match ); + if ( matches ) { + iFormat++; + } + return matches; + }, - // Remove the handler that closes the menu on outside clicks - this._off( this.document, "mousedown" ); + // Extract a number from the string value + getNumber = function( match ) { + var isDoubled = lookAhead( match ), + size = ( match === "@" ? 14 : ( match === "!" ? 20 : + ( match === "y" && isDoubled ? 4 : ( match === "o" ? 3 : 2 ) ) ) ), + minSize = ( match === "y" ? size : 1 ), + digits = new RegExp( "^\\d{" + minSize + "," + size + "}" ), + num = value.substring( iValue ).match( digits ); + if ( !num ) { + throw "Missing number at position " + iValue; + } + iValue += num[ 0 ].length; + return parseInt( num[ 0 ], 10 ); + }, - if ( this.menu.element.is( ":visible" ) ) { - this.menu.element.hide(); - this.menu.blur(); - this.isNewMenu = true; - this._trigger( "close", event ); - } - }, + // Extract a name from the string value and convert to an index + getName = function( match, shortNames, longNames ) { + var index = -1, + names = $.map( lookAhead( match ) ? longNames : shortNames, function( v, k ) { + return [ [ k, v ] ]; + } ).sort( function( a, b ) { + return -( a[ 1 ].length - b[ 1 ].length ); + } ); - _change: function( event ) { - if ( this.previous !== this._value() ) { - this._trigger( "change", event, { item: this.selectedItem } ); - } - }, + $.each( names, function( i, pair ) { + var name = pair[ 1 ]; + if ( value.substr( iValue, name.length ).toLowerCase() === name.toLowerCase() ) { + index = pair[ 0 ]; + iValue += name.length; + return false; + } + } ); + if ( index !== -1 ) { + return index + 1; + } else { + throw "Unknown name at position " + iValue; + } + }, - _normalize: function( items ) { + // Confirm that a literal character matches the string value + checkLiteral = function() { + if ( value.charAt( iValue ) !== format.charAt( iFormat ) ) { + throw "Unexpected literal at position " + iValue; + } + iValue++; + }; - // assume all items have the right format when the first item is complete - if ( items.length && items[ 0 ].label && items[ 0 ].value ) { - return items; - } - return $.map( items, function( item ) { - if ( typeof item === "string" ) { - return { - label: item, - value: item - }; + for ( iFormat = 0; iFormat < format.length; iFormat++ ) { + if ( literal ) { + if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) { + literal = false; + } else { + checkLiteral(); + } + } else { + switch ( format.charAt( iFormat ) ) { + case "d": + day = getNumber( "d" ); + break; + case "D": + getName( "D", dayNamesShort, dayNames ); + break; + case "o": + doy = getNumber( "o" ); + break; + case "m": + month = getNumber( "m" ); + break; + case "M": + month = getName( "M", monthNamesShort, monthNames ); + break; + case "y": + year = getNumber( "y" ); + break; + case "@": + date = new Date( getNumber( "@" ) ); + year = date.getFullYear(); + month = date.getMonth() + 1; + day = date.getDate(); + break; + case "!": + date = new Date( ( getNumber( "!" ) - this._ticksTo1970 ) / 10000 ); + year = date.getFullYear(); + month = date.getMonth() + 1; + day = date.getDate(); + break; + case "'": + if ( lookAhead( "'" ) ) { + checkLiteral(); + } else { + literal = true; + } + break; + default: + checkLiteral(); + } } - return $.extend( {}, item, { - label: item.label || item.value, - value: item.value || item.label - } ); - } ); - }, - - _suggest: function( items ) { - var ul = this.menu.element.empty(); - this._renderMenu( ul, items ); - this.isNewMenu = true; - this.menu.refresh(); - - // Size and position menu - ul.show(); - this._resizeMenu(); - ul.position( $.extend( { - of: this.element - }, this.options.position ) ); - - if ( this.options.autoFocus ) { - this.menu.next(); - } - - // Listen for interactions outside of the widget (#6642) - this._on( this.document, { - mousedown: "_closeOnClickOutside" - } ); - }, - - _resizeMenu: function() { - var ul = this.menu.element; - ul.outerWidth( Math.max( - - // Firefox wraps long text (possibly a rounding bug) - // so we add 1px to avoid the wrapping (#7513) - ul.width( "" ).outerWidth() + 1, - this.element.outerWidth() - ) ); - }, - - _renderMenu: function( ul, items ) { - var that = this; - $.each( items, function( index, item ) { - that._renderItemData( ul, item ); - } ); - }, - - _renderItemData: function( ul, item ) { - return this._renderItem( ul, item ).data( "ui-autocomplete-item", item ); - }, - - _renderItem: function( ul, item ) { - return $( "<li>" ) - .append( $( "<div>" ).text( item.label ) ) - .appendTo( ul ); - }, - - _move: function( direction, event ) { - if ( !this.menu.element.is( ":visible" ) ) { - this.search( null, event ); - return; } - if ( this.menu.isFirstItem() && /^previous/.test( direction ) || - this.menu.isLastItem() && /^next/.test( direction ) ) { - if ( !this.isMultiLine ) { - this._value( this.term ); + if ( iValue < value.length ) { + extra = value.substr( iValue ); + if ( !/^\s+/.test( extra ) ) { + throw "Extra/unparsed characters found in date: " + extra; } - - this.menu.blur(); - return; } - this.menu[ direction ]( event ); - }, - - widget: function() { - return this.menu.element; - }, - _value: function() { - return this.valueMethod.apply( this.element, arguments ); - }, + if ( year === -1 ) { + year = new Date().getFullYear(); + } else if ( year < 100 ) { + year += new Date().getFullYear() - new Date().getFullYear() % 100 + + ( year <= shortYearCutoff ? 0 : -100 ); + } - _keyEvent: function( keyEvent, event ) { - if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { - this._move( keyEvent, event ); + if ( doy > -1 ) { + month = 1; + day = doy; + do { + dim = this._getDaysInMonth( year, month - 1 ); + if ( day <= dim ) { + break; + } + month++; + day -= dim; + } while ( true ); + } - // Prevents moving cursor to beginning/end of the text field in some browsers - event.preventDefault(); + date = this._daylightSavingAdjust( new Date( year, month - 1, day ) ); + if ( date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day ) { + throw "Invalid date"; // E.g. 31/02/00 } + return date; }, - // Support: Chrome <=50 - // We should be able to just use this.element.prop( "isContentEditable" ) - // but hidden elements always report false in Chrome. - // https://code.google.com/p/chromium/issues/detail?id=313082 - _isContentEditable: function( element ) { - if ( !element.length ) { - return false; - } + /* Standard date formats. */ + ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601) + COOKIE: "D, dd M yy", + ISO_8601: "yy-mm-dd", + RFC_822: "D, d M y", + RFC_850: "DD, dd-M-y", + RFC_1036: "D, d M y", + RFC_1123: "D, d M yy", + RFC_2822: "D, d M yy", + RSS: "D, d M y", // RFC 822 + TICKS: "!", + TIMESTAMP: "@", + W3C: "yy-mm-dd", // ISO 8601 - var editable = element.prop( "contentEditable" ); + _ticksTo1970: ( ( ( 1970 - 1 ) * 365 + Math.floor( 1970 / 4 ) - Math.floor( 1970 / 100 ) + + Math.floor( 1970 / 400 ) ) * 24 * 60 * 60 * 10000000 ), - if ( editable === "inherit" ) { - return this._isContentEditable( element.parent() ); + /* Format a date object into a string value. + * The format can be combinations of the following: + * d - day of month (no leading zero) + * dd - day of month (two digit) + * o - day of year (no leading zeros) + * oo - day of year (three digit) + * D - day name short + * DD - day name long + * m - month of year (no leading zero) + * mm - month of year (two digit) + * M - month name short + * MM - month name long + * y - year (two digit) + * yy - year (four digit) + * @ - Unix timestamp (ms since 01/01/1970) + * ! - Windows ticks (100ns since 01/01/0001) + * "..." - literal text + * '' - single quote + * + * @param format string - the desired format of the date + * @param date Date - the date value to format + * @param settings Object - attributes include: + * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) + * dayNames string[7] - names of the days from Sunday (optional) + * monthNamesShort string[12] - abbreviated names of the months (optional) + * monthNames string[12] - names of the months (optional) + * @return string - the date in the above format + */ + formatDate: function( format, date, settings ) { + if ( !date ) { + return ""; } - return editable === "true"; - } -} ); + var iFormat, + dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort, + dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames, + monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort, + monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames, -$.extend( $.ui.autocomplete, { - escapeRegex: function( value ) { - return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ); - }, - filter: function( array, term ) { - var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" ); - return $.grep( array, function( value ) { - return matcher.test( value.label || value.value || value ); - } ); - } -} ); + // Check whether a format character is doubled + lookAhead = function( match ) { + var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match ); + if ( matches ) { + iFormat++; + } + return matches; + }, -// Live region extension, adding a `messages` option -// NOTE: This is an experimental API. We are still investigating -// a full solution for string manipulation and internationalization. -$.widget( "ui.autocomplete", $.ui.autocomplete, { - options: { - messages: { - noResults: "No search results.", - results: function( amount ) { - return amount + ( amount > 1 ? " results are" : " result is" ) + - " available, use up and down arrow keys to navigate."; + // Format a number, with leading zero if necessary + formatNumber = function( match, value, len ) { + var num = "" + value; + if ( lookAhead( match ) ) { + while ( num.length < len ) { + num = "0" + num; + } + } + return num; + }, + + // Format a name, short or long as requested + formatName = function( match, value, shortNames, longNames ) { + return ( lookAhead( match ) ? longNames[ value ] : shortNames[ value ] ); + }, + output = "", + literal = false; + + if ( date ) { + for ( iFormat = 0; iFormat < format.length; iFormat++ ) { + if ( literal ) { + if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) { + literal = false; + } else { + output += format.charAt( iFormat ); + } + } else { + switch ( format.charAt( iFormat ) ) { + case "d": + output += formatNumber( "d", date.getDate(), 2 ); + break; + case "D": + output += formatName( "D", date.getDay(), dayNamesShort, dayNames ); + break; + case "o": + output += formatNumber( "o", + Math.round( ( new Date( date.getFullYear(), date.getMonth(), date.getDate() ).getTime() - new Date( date.getFullYear(), 0, 0 ).getTime() ) / 86400000 ), 3 ); + break; + case "m": + output += formatNumber( "m", date.getMonth() + 1, 2 ); + break; + case "M": + output += formatName( "M", date.getMonth(), monthNamesShort, monthNames ); + break; + case "y": + output += ( lookAhead( "y" ) ? date.getFullYear() : + ( date.getFullYear() % 100 < 10 ? "0" : "" ) + date.getFullYear() % 100 ); + break; + case "@": + output += date.getTime(); + break; + case "!": + output += date.getTime() * 10000 + this._ticksTo1970; + break; + case "'": + if ( lookAhead( "'" ) ) { + output += "'"; + } else { + literal = true; + } + break; + default: + output += format.charAt( iFormat ); + } + } } } + return output; }, - __response: function( content ) { - var message; - this._superApply( arguments ); - if ( this.options.disabled || this.cancelSearch ) { - return; - } - if ( content && content.length ) { - message = this.options.messages.results( content.length ); - } else { - message = this.options.messages.noResults; - } - clearTimeout( this.liveRegionTimer ); - this.liveRegionTimer = this._delay( function() { - this.liveRegion.html( $( "<div>" ).text( message ) ); - }, 100 ); - } -} ); - -var widgetsAutocomplete = $.ui.autocomplete; - - -/*! - * jQuery UI Controlgroup 1.13.1 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ - -//>>label: Controlgroup -//>>group: Widgets -//>>description: Visually groups form control widgets -//>>docs: http://api.jqueryui.com/controlgroup/ -//>>demos: http://jqueryui.com/controlgroup/ -//>>css.structure: ../../themes/base/core.css -//>>css.structure: ../../themes/base/controlgroup.css -//>>css.theme: ../../themes/base/theme.css - + /* Extract all possible characters from the date format. */ + _possibleChars: function( format ) { + var iFormat, + chars = "", + literal = false, -var controlgroupCornerRegex = /ui-corner-([a-z]){2,6}/g; + // Check whether a format character is doubled + lookAhead = function( match ) { + var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match ); + if ( matches ) { + iFormat++; + } + return matches; + }; -var widgetsControlgroup = $.widget( "ui.controlgroup", { - version: "1.13.1", - defaultElement: "<div>", - options: { - direction: "horizontal", - disabled: null, - onlyVisible: true, - items: { - "button": "input[type=button], input[type=submit], input[type=reset], button, a", - "controlgroupLabel": ".ui-controlgroup-label", - "checkboxradio": "input[type='checkbox'], input[type='radio']", - "selectmenu": "select", - "spinner": ".ui-spinner-input" + for ( iFormat = 0; iFormat < format.length; iFormat++ ) { + if ( literal ) { + if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) { + literal = false; + } else { + chars += format.charAt( iFormat ); + } + } else { + switch ( format.charAt( iFormat ) ) { + case "d": case "m": case "y": case "@": + chars += "0123456789"; + break; + case "D": case "M": + return null; // Accept anything + case "'": + if ( lookAhead( "'" ) ) { + chars += "'"; + } else { + literal = true; + } + break; + default: + chars += format.charAt( iFormat ); + } + } } + return chars; }, - _create: function() { - this._enhance(); + /* Get a setting value, defaulting if necessary. */ + _get: function( inst, name ) { + return inst.settings[ name ] !== undefined ? + inst.settings[ name ] : this._defaults[ name ]; }, - // To support the enhanced option in jQuery Mobile, we isolate DOM manipulation - _enhance: function() { - this.element.attr( "role", "toolbar" ); - this.refresh(); - }, - - _destroy: function() { - this._callChildMethod( "destroy" ); - this.childWidgets.removeData( "ui-controlgroup-data" ); - this.element.removeAttr( "role" ); - if ( this.options.items.controlgroupLabel ) { - this.element - .find( this.options.items.controlgroupLabel ) - .find( ".ui-controlgroup-label-contents" ) - .contents().unwrap(); + /* Parse existing date and initialise date picker. */ + _setDateFromField: function( inst, noDefault ) { + if ( inst.input.val() === inst.lastVal ) { + return; } - }, - - _initWidgets: function() { - var that = this, - childWidgets = []; - - // First we iterate over each of the items options - $.each( this.options.items, function( widget, selector ) { - var labels; - var options = {}; - - // Make sure the widget has a selector set - if ( !selector ) { - return; - } - if ( widget === "controlgroupLabel" ) { - labels = that.element.find( selector ); - labels.each( function() { - var element = $( this ); - - if ( element.children( ".ui-controlgroup-label-contents" ).length ) { - return; - } - element.contents() - .wrapAll( "<span class='ui-controlgroup-label-contents'></span>" ); - } ); - that._addClass( labels, null, "ui-widget ui-widget-content ui-state-default" ); - childWidgets = childWidgets.concat( labels.get() ); - return; - } + var dateFormat = this._get( inst, "dateFormat" ), + dates = inst.lastVal = inst.input ? inst.input.val() : null, + defaultDate = this._getDefaultDate( inst ), + date = defaultDate, + settings = this._getFormatConfig( inst ); - // Make sure the widget actually exists - if ( !$.fn[ widget ] ) { - return; - } + try { + date = this.parseDate( dateFormat, dates, settings ) || defaultDate; + } catch ( event ) { + dates = ( noDefault ? "" : dates ); + } + inst.selectedDay = date.getDate(); + inst.drawMonth = inst.selectedMonth = date.getMonth(); + inst.drawYear = inst.selectedYear = date.getFullYear(); + inst.currentDay = ( dates ? date.getDate() : 0 ); + inst.currentMonth = ( dates ? date.getMonth() : 0 ); + inst.currentYear = ( dates ? date.getFullYear() : 0 ); + this._adjustInstDate( inst ); + }, - // We assume everything is in the middle to start because we can't determine - // first / last elements until all enhancments are done. - if ( that[ "_" + widget + "Options" ] ) { - options = that[ "_" + widget + "Options" ]( "middle" ); - } else { - options = { classes: {} }; - } + /* Retrieve the default date shown on opening. */ + _getDefaultDate: function( inst ) { + return this._restrictMinMax( inst, + this._determineDate( inst, this._get( inst, "defaultDate" ), new Date() ) ); + }, - // Find instances of this widget inside controlgroup and init them - that.element - .find( selector ) - .each( function() { - var element = $( this ); - var instance = element[ widget ]( "instance" ); + /* A date may be specified as an exact value or a relative one. */ + _determineDate: function( inst, date, defaultDate ) { + var offsetNumeric = function( offset ) { + var date = new Date(); + date.setDate( date.getDate() + offset ); + return date; + }, + offsetString = function( offset ) { + try { + return $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ), + offset, $.datepicker._getFormatConfig( inst ) ); + } catch ( e ) { - // We need to clone the default options for this type of widget to avoid - // polluting the variable options which has a wider scope than a single widget. - var instanceOptions = $.widget.extend( {}, options ); + // Ignore + } - // If the button is the child of a spinner ignore it - // TODO: Find a more generic solution - if ( widget === "button" && element.parent( ".ui-spinner" ).length ) { - return; - } + var date = ( offset.toLowerCase().match( /^c/ ) ? + $.datepicker._getDate( inst ) : null ) || new Date(), + year = date.getFullYear(), + month = date.getMonth(), + day = date.getDate(), + pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g, + matches = pattern.exec( offset ); - // Create the widget if it doesn't exist - if ( !instance ) { - instance = element[ widget ]()[ widget ]( "instance" ); - } - if ( instance ) { - instanceOptions.classes = - that._resolveClassesValues( instanceOptions.classes, instance ); + while ( matches ) { + switch ( matches[ 2 ] || "d" ) { + case "d" : case "D" : + day += parseInt( matches[ 1 ], 10 ); break; + case "w" : case "W" : + day += parseInt( matches[ 1 ], 10 ) * 7; break; + case "m" : case "M" : + month += parseInt( matches[ 1 ], 10 ); + day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) ); + break; + case "y": case "Y" : + year += parseInt( matches[ 1 ], 10 ); + day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) ); + break; } - element[ widget ]( instanceOptions ); - - // Store an instance of the controlgroup to be able to reference - // from the outermost element for changing options and refresh - var widgetElement = element[ widget ]( "widget" ); - $.data( widgetElement[ 0 ], "ui-controlgroup-data", - instance ? instance : element[ widget ]( "instance" ) ); - - childWidgets.push( widgetElement[ 0 ] ); - } ); - } ); - - this.childWidgets = $( $.uniqueSort( childWidgets ) ); - this._addClass( this.childWidgets, "ui-controlgroup-item" ); - }, - - _callChildMethod: function( method ) { - this.childWidgets.each( function() { - var element = $( this ), - data = element.data( "ui-controlgroup-data" ); - if ( data && data[ method ] ) { - data[ method ](); - } - } ); - }, - - _updateCornerClass: function( element, position ) { - var remove = "ui-corner-top ui-corner-bottom ui-corner-left ui-corner-right ui-corner-all"; - var add = this._buildSimpleOptions( position, "label" ).classes.label; + matches = pattern.exec( offset ); + } + return new Date( year, month, day ); + }, + newDate = ( date == null || date === "" ? defaultDate : ( typeof date === "string" ? offsetString( date ) : + ( typeof date === "number" ? ( isNaN( date ) ? defaultDate : offsetNumeric( date ) ) : new Date( date.getTime() ) ) ) ); - this._removeClass( element, null, remove ); - this._addClass( element, null, add ); + newDate = ( newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate ); + if ( newDate ) { + newDate.setHours( 0 ); + newDate.setMinutes( 0 ); + newDate.setSeconds( 0 ); + newDate.setMilliseconds( 0 ); + } + return this._daylightSavingAdjust( newDate ); }, - _buildSimpleOptions: function( position, key ) { - var direction = this.options.direction === "vertical"; - var result = { - classes: {} - }; - result.classes[ key ] = { - "middle": "", - "first": "ui-corner-" + ( direction ? "top" : "left" ), - "last": "ui-corner-" + ( direction ? "bottom" : "right" ), - "only": "ui-corner-all" - }[ position ]; - - return result; + /* Handle switch to/from daylight saving. + * Hours may be non-zero on daylight saving cut-over: + * > 12 when midnight changeover, but then cannot generate + * midnight datetime, so jump to 1AM, otherwise reset. + * @param date (Date) the date to check + * @return (Date) the corrected date + */ + _daylightSavingAdjust: function( date ) { + if ( !date ) { + return null; + } + date.setHours( date.getHours() > 12 ? date.getHours() + 2 : 0 ); + return date; }, - _spinnerOptions: function( position ) { - var options = this._buildSimpleOptions( position, "ui-spinner" ); - - options.classes[ "ui-spinner-up" ] = ""; - options.classes[ "ui-spinner-down" ] = ""; - - return options; - }, + /* Set the date(s) directly. */ + _setDate: function( inst, date, noChange ) { + var clear = !date, + origMonth = inst.selectedMonth, + origYear = inst.selectedYear, + newDate = this._restrictMinMax( inst, this._determineDate( inst, date, new Date() ) ); - _buttonOptions: function( position ) { - return this._buildSimpleOptions( position, "ui-button" ); + inst.selectedDay = inst.currentDay = newDate.getDate(); + inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth(); + inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear(); + if ( ( origMonth !== inst.selectedMonth || origYear !== inst.selectedYear ) && !noChange ) { + this._notifyChange( inst ); + } + this._adjustInstDate( inst ); + if ( inst.input ) { + inst.input.val( clear ? "" : this._formatDate( inst ) ); + } }, - _checkboxradioOptions: function( position ) { - return this._buildSimpleOptions( position, "ui-checkboxradio-label" ); + /* Retrieve the date(s) directly. */ + _getDate: function( inst ) { + var startDate = ( !inst.currentYear || ( inst.input && inst.input.val() === "" ) ? null : + this._daylightSavingAdjust( new Date( + inst.currentYear, inst.currentMonth, inst.currentDay ) ) ); + return startDate; }, - _selectmenuOptions: function( position ) { - var direction = this.options.direction === "vertical"; - return { - width: direction ? "auto" : false, - classes: { - middle: { - "ui-selectmenu-button-open": "", - "ui-selectmenu-button-closed": "" - }, - first: { - "ui-selectmenu-button-open": "ui-corner-" + ( direction ? "top" : "tl" ), - "ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "top" : "left" ) - }, - last: { - "ui-selectmenu-button-open": direction ? "" : "ui-corner-tr", - "ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "bottom" : "right" ) + /* Attach the onxxx handlers. These are declared statically so + * they work with static code transformers like Caja. + */ + _attachHandlers: function( inst ) { + var stepMonths = this._get( inst, "stepMonths" ), + id = "#" + inst.id.replace( /\\\\/g, "\\" ); + inst.dpDiv.find( "[data-handler]" ).map( function() { + var handler = { + prev: function() { + $.datepicker._adjustDate( id, -stepMonths, "M" ); }, - only: { - "ui-selectmenu-button-open": "ui-corner-top", - "ui-selectmenu-button-closed": "ui-corner-all" + next: function() { + $.datepicker._adjustDate( id, +stepMonths, "M" ); + }, + hide: function() { + $.datepicker._hideDatepicker(); + }, + today: function() { + $.datepicker._gotoToday( id ); + }, + selectDay: function() { + $.datepicker._selectDay( id, +this.getAttribute( "data-month" ), +this.getAttribute( "data-year" ), this ); + return false; + }, + selectMonth: function() { + $.datepicker._selectMonthYear( id, this, "M" ); + return false; + }, + selectYear: function() { + $.datepicker._selectMonthYear( id, this, "Y" ); + return false; } - - }[ position ] - }; - }, - - _resolveClassesValues: function( classes, instance ) { - var result = {}; - $.each( classes, function( key ) { - var current = instance.options.classes[ key ] || ""; - current = String.prototype.trim.call( current.replace( controlgroupCornerRegex, "" ) ); - result[ key ] = ( current + " " + classes[ key ] ).replace( /\s+/g, " " ); + }; + $( this ).on( this.getAttribute( "data-event" ), handler[ this.getAttribute( "data-handler" ) ] ); } ); - return result; }, - _setOption: function( key, value ) { - if ( key === "direction" ) { - this._removeClass( "ui-controlgroup-" + this.options.direction ); - } + /* Generate the HTML for the current state of the date picker. */ + _generateHTML: function( inst ) { + var maxDraw, prevText, prev, nextText, next, currentText, gotoDate, + controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin, + monthNames, monthNamesShort, beforeShowDay, showOtherMonths, + selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate, + cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows, + printDate, dRow, tbody, daySettings, otherMonth, unselectable, + tempDate = new Date(), + today = this._daylightSavingAdjust( + new Date( tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate() ) ), // clear time + isRTL = this._get( inst, "isRTL" ), + showButtonPanel = this._get( inst, "showButtonPanel" ), + hideIfNoPrevNext = this._get( inst, "hideIfNoPrevNext" ), + navigationAsDateFormat = this._get( inst, "navigationAsDateFormat" ), + numMonths = this._getNumberOfMonths( inst ), + showCurrentAtPos = this._get( inst, "showCurrentAtPos" ), + stepMonths = this._get( inst, "stepMonths" ), + isMultiMonth = ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ), + currentDate = this._daylightSavingAdjust( ( !inst.currentDay ? new Date( 9999, 9, 9 ) : + new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ), + minDate = this._getMinMaxDate( inst, "min" ), + maxDate = this._getMinMaxDate( inst, "max" ), + drawMonth = inst.drawMonth - showCurrentAtPos, + drawYear = inst.drawYear; - this._super( key, value ); - if ( key === "disabled" ) { - this._callChildMethod( value ? "disable" : "enable" ); - return; + if ( drawMonth < 0 ) { + drawMonth += 12; + drawYear--; } + if ( maxDate ) { + maxDraw = this._daylightSavingAdjust( new Date( maxDate.getFullYear(), + maxDate.getMonth() - ( numMonths[ 0 ] * numMonths[ 1 ] ) + 1, maxDate.getDate() ) ); + maxDraw = ( minDate && maxDraw < minDate ? minDate : maxDraw ); + while ( this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 ) ) > maxDraw ) { + drawMonth--; + if ( drawMonth < 0 ) { + drawMonth = 11; + drawYear--; + } + } + } + inst.drawMonth = drawMonth; + inst.drawYear = drawYear; - this.refresh(); - }, - - refresh: function() { - var children, - that = this; - - this._addClass( "ui-controlgroup ui-controlgroup-" + this.options.direction ); + prevText = this._get( inst, "prevText" ); + prevText = ( !navigationAsDateFormat ? prevText : this.formatDate( prevText, + this._daylightSavingAdjust( new Date( drawYear, drawMonth - stepMonths, 1 ) ), + this._getFormatConfig( inst ) ) ); - if ( this.options.direction === "horizontal" ) { - this._addClass( null, "ui-helper-clearfix" ); + if ( this._canAdjustMonth( inst, -1, drawYear, drawMonth ) ) { + prev = $( "<a>" ) + .attr( { + "class": "ui-datepicker-prev ui-corner-all", + "data-handler": "prev", + "data-event": "click", + title: prevText + } ) + .append( + $( "<span>" ) + .addClass( "ui-icon ui-icon-circle-triangle-" + + ( isRTL ? "e" : "w" ) ) + .text( prevText ) + )[ 0 ].outerHTML; + } else if ( hideIfNoPrevNext ) { + prev = ""; + } else { + prev = $( "<a>" ) + .attr( { + "class": "ui-datepicker-prev ui-corner-all ui-state-disabled", + title: prevText + } ) + .append( + $( "<span>" ) + .addClass( "ui-icon ui-icon-circle-triangle-" + + ( isRTL ? "e" : "w" ) ) + .text( prevText ) + )[ 0 ].outerHTML; } - this._initWidgets(); - children = this.childWidgets; + nextText = this._get( inst, "nextText" ); + nextText = ( !navigationAsDateFormat ? nextText : this.formatDate( nextText, + this._daylightSavingAdjust( new Date( drawYear, drawMonth + stepMonths, 1 ) ), + this._getFormatConfig( inst ) ) ); - // We filter here because we need to track all childWidgets not just the visible ones - if ( this.options.onlyVisible ) { - children = children.filter( ":visible" ); + if ( this._canAdjustMonth( inst, +1, drawYear, drawMonth ) ) { + next = $( "<a>" ) + .attr( { + "class": "ui-datepicker-next ui-corner-all", + "data-handler": "next", + "data-event": "click", + title: nextText + } ) + .append( + $( "<span>" ) + .addClass( "ui-icon ui-icon-circle-triangle-" + + ( isRTL ? "w" : "e" ) ) + .text( nextText ) + )[ 0 ].outerHTML; + } else if ( hideIfNoPrevNext ) { + next = ""; + } else { + next = $( "<a>" ) + .attr( { + "class": "ui-datepicker-next ui-corner-all ui-state-disabled", + title: nextText + } ) + .append( + $( "<span>" ) + .attr( "class", "ui-icon ui-icon-circle-triangle-" + + ( isRTL ? "w" : "e" ) ) + .text( nextText ) + )[ 0 ].outerHTML; } - if ( children.length ) { - - // We do this last because we need to make sure all enhancment is done - // before determining first and last - $.each( [ "first", "last" ], function( index, value ) { - var instance = children[ value ]().data( "ui-controlgroup-data" ); + currentText = this._get( inst, "currentText" ); + gotoDate = ( this._get( inst, "gotoCurrent" ) && inst.currentDay ? currentDate : today ); + currentText = ( !navigationAsDateFormat ? currentText : + this.formatDate( currentText, gotoDate, this._getFormatConfig( inst ) ) ); - if ( instance && that[ "_" + instance.widgetName + "Options" ] ) { - var options = that[ "_" + instance.widgetName + "Options" ]( - children.length === 1 ? "only" : value - ); - options.classes = that._resolveClassesValues( options.classes, instance ); - instance.element[ instance.widgetName ]( options ); - } else { - that._updateCornerClass( children[ value ](), value ); - } - } ); + controls = ""; + if ( !inst.inline ) { + controls = $( "<button>" ) + .attr( { + type: "button", + "class": "ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all", + "data-handler": "hide", + "data-event": "click" + } ) + .text( this._get( inst, "closeText" ) )[ 0 ].outerHTML; + } - // Finally call the refresh method on each of the child widgets. - this._callChildMethod( "refresh" ); + buttonPanel = ""; + if ( showButtonPanel ) { + buttonPanel = $( "<div class='ui-datepicker-buttonpane ui-widget-content'>" ) + .append( isRTL ? controls : "" ) + .append( this._isInRange( inst, gotoDate ) ? + $( "<button>" ) + .attr( { + type: "button", + "class": "ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all", + "data-handler": "today", + "data-event": "click" + } ) + .text( currentText ) : + "" ) + .append( isRTL ? "" : controls )[ 0 ].outerHTML; } - } -} ); -/*! - * jQuery UI Checkboxradio 1.13.1 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ + firstDay = parseInt( this._get( inst, "firstDay" ), 10 ); + firstDay = ( isNaN( firstDay ) ? 0 : firstDay ); -//>>label: Checkboxradio -//>>group: Widgets -//>>description: Enhances a form with multiple themeable checkboxes or radio buttons. -//>>docs: http://api.jqueryui.com/checkboxradio/ -//>>demos: http://jqueryui.com/checkboxradio/ -//>>css.structure: ../../themes/base/core.css -//>>css.structure: ../../themes/base/button.css -//>>css.structure: ../../themes/base/checkboxradio.css -//>>css.theme: ../../themes/base/theme.css + showWeek = this._get( inst, "showWeek" ); + dayNames = this._get( inst, "dayNames" ); + dayNamesMin = this._get( inst, "dayNamesMin" ); + monthNames = this._get( inst, "monthNames" ); + monthNamesShort = this._get( inst, "monthNamesShort" ); + beforeShowDay = this._get( inst, "beforeShowDay" ); + showOtherMonths = this._get( inst, "showOtherMonths" ); + selectOtherMonths = this._get( inst, "selectOtherMonths" ); + defaultDate = this._getDefaultDate( inst ); + html = ""; + for ( row = 0; row < numMonths[ 0 ]; row++ ) { + group = ""; + this.maxRows = 4; + for ( col = 0; col < numMonths[ 1 ]; col++ ) { + selectedDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, inst.selectedDay ) ); + cornerClass = " ui-corner-all"; + calender = ""; + if ( isMultiMonth ) { + calender += "<div class='ui-datepicker-group"; + if ( numMonths[ 1 ] > 1 ) { + switch ( col ) { + case 0: calender += " ui-datepicker-group-first"; + cornerClass = " ui-corner-" + ( isRTL ? "right" : "left" ); break; + case numMonths[ 1 ] - 1: calender += " ui-datepicker-group-last"; + cornerClass = " ui-corner-" + ( isRTL ? "left" : "right" ); break; + default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break; + } + } + calender += "'>"; + } + calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" + + ( /all|left/.test( cornerClass ) && row === 0 ? ( isRTL ? next : prev ) : "" ) + + ( /all|right/.test( cornerClass ) && row === 0 ? ( isRTL ? prev : next ) : "" ) + + this._generateMonthYearHeader( inst, drawMonth, drawYear, minDate, maxDate, + row > 0 || col > 0, monthNames, monthNamesShort ) + // draw month headers + "</div><table class='ui-datepicker-calendar'><thead>" + + "<tr>"; + thead = ( showWeek ? "<th class='ui-datepicker-week-col'>" + this._get( inst, "weekHeader" ) + "</th>" : "" ); + for ( dow = 0; dow < 7; dow++ ) { // days of the week + day = ( dow + firstDay ) % 7; + thead += "<th scope='col'" + ( ( dow + firstDay + 6 ) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "" ) + ">" + + "<span title='" + dayNames[ day ] + "'>" + dayNamesMin[ day ] + "</span></th>"; + } + calender += thead + "</tr></thead><tbody>"; + daysInMonth = this._getDaysInMonth( drawYear, drawMonth ); + if ( drawYear === inst.selectedYear && drawMonth === inst.selectedMonth ) { + inst.selectedDay = Math.min( inst.selectedDay, daysInMonth ); + } + leadDays = ( this._getFirstDayOfMonth( drawYear, drawMonth ) - firstDay + 7 ) % 7; + curRows = Math.ceil( ( leadDays + daysInMonth ) / 7 ); // calculate the number of rows to generate + numRows = ( isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows ); //If multiple months, use the higher number of rows (see #7043) + this.maxRows = numRows; + printDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 - leadDays ) ); + for ( dRow = 0; dRow < numRows; dRow++ ) { // create date picker rows + calender += "<tr>"; + tbody = ( !showWeek ? "" : "<td class='ui-datepicker-week-col'>" + + this._get( inst, "calculateWeek" )( printDate ) + "</td>" ); + for ( dow = 0; dow < 7; dow++ ) { // create date picker days + daySettings = ( beforeShowDay ? + beforeShowDay.apply( ( inst.input ? inst.input[ 0 ] : null ), [ printDate ] ) : [ true, "" ] ); + otherMonth = ( printDate.getMonth() !== drawMonth ); + unselectable = ( otherMonth && !selectOtherMonths ) || !daySettings[ 0 ] || + ( minDate && printDate < minDate ) || ( maxDate && printDate > maxDate ); + tbody += "<td class='" + + ( ( dow + firstDay + 6 ) % 7 >= 5 ? " ui-datepicker-week-end" : "" ) + // highlight weekends + ( otherMonth ? " ui-datepicker-other-month" : "" ) + // highlight days from other months + ( ( printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent ) || // user pressed key + ( defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime() ) ? -$.widget( "ui.checkboxradio", [ $.ui.formResetMixin, { - version: "1.13.1", - options: { - disabled: null, - label: null, - icon: true, - classes: { - "ui-checkboxradio-label": "ui-corner-all", - "ui-checkboxradio-icon": "ui-corner-all" + // or defaultDate is current printedDate and defaultDate is selectedDate + " " + this._dayOverClass : "" ) + // highlight selected day + ( unselectable ? " " + this._unselectableClass + " ui-state-disabled" : "" ) + // highlight unselectable days + ( otherMonth && !showOtherMonths ? "" : " " + daySettings[ 1 ] + // highlight custom dates + ( printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "" ) + // highlight selected day + ( printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "" ) ) + "'" + // highlight today (if different) + ( ( !otherMonth || showOtherMonths ) && daySettings[ 2 ] ? " title='" + daySettings[ 2 ].replace( /'/g, "'" ) + "'" : "" ) + // cell title + ( unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'" ) + ">" + // actions + ( otherMonth && !showOtherMonths ? " " : // display for other months + ( unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" + + ( printDate.getTime() === today.getTime() ? " ui-state-highlight" : "" ) + + ( printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "" ) + // highlight selected day + ( otherMonth ? " ui-priority-secondary" : "" ) + // distinguish dates from other months + "' href='#' aria-current='" + ( printDate.getTime() === currentDate.getTime() ? "true" : "false" ) + // mark date as selected for screen reader + "' data-date='" + printDate.getDate() + // store date as data + "'>" + printDate.getDate() + "</a>" ) ) + "</td>"; // display selectable date + printDate.setDate( printDate.getDate() + 1 ); + printDate = this._daylightSavingAdjust( printDate ); + } + calender += tbody + "</tr>"; + } + drawMonth++; + if ( drawMonth > 11 ) { + drawMonth = 0; + drawYear++; + } + calender += "</tbody></table>" + ( isMultiMonth ? "</div>" + + ( ( numMonths[ 0 ] > 0 && col === numMonths[ 1 ] - 1 ) ? "<div class='ui-datepicker-row-break'></div>" : "" ) : "" ); + group += calender; + } + html += group; } + html += buttonPanel; + inst._keyEvent = false; + return html; }, - _getCreateOptions: function() { - var disabled, labels; - var that = this; - var options = this._super() || {}; - - // We read the type here, because it makes more sense to throw a element type error first, - // rather then the error for lack of a label. Often if its the wrong type, it - // won't have a label (e.g. calling on a div, btn, etc) - this._readType(); + /* Generate the month and year header. */ + _generateMonthYearHeader: function( inst, drawMonth, drawYear, minDate, maxDate, + secondary, monthNames, monthNamesShort ) { - labels = this.element.labels(); + var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear, + changeMonth = this._get( inst, "changeMonth" ), + changeYear = this._get( inst, "changeYear" ), + showMonthAfterYear = this._get( inst, "showMonthAfterYear" ), + selectMonthLabel = this._get( inst, "selectMonthLabel" ), + selectYearLabel = this._get( inst, "selectYearLabel" ), + html = "<div class='ui-datepicker-title'>", + monthHtml = ""; - // If there are multiple labels, use the last one - this.label = $( labels[ labels.length - 1 ] ); - if ( !this.label.length ) { - $.error( "No label found for checkboxradio widget" ); + // Month selection + if ( secondary || !changeMonth ) { + monthHtml += "<span class='ui-datepicker-month'>" + monthNames[ drawMonth ] + "</span>"; + } else { + inMinYear = ( minDate && minDate.getFullYear() === drawYear ); + inMaxYear = ( maxDate && maxDate.getFullYear() === drawYear ); + monthHtml += "<select class='ui-datepicker-month' aria-label='" + selectMonthLabel + "' data-handler='selectMonth' data-event='change'>"; + for ( month = 0; month < 12; month++ ) { + if ( ( !inMinYear || month >= minDate.getMonth() ) && ( !inMaxYear || month <= maxDate.getMonth() ) ) { + monthHtml += "<option value='" + month + "'" + + ( month === drawMonth ? " selected='selected'" : "" ) + + ">" + monthNamesShort[ month ] + "</option>"; + } + } + monthHtml += "</select>"; } - this.originalLabel = ""; + if ( !showMonthAfterYear ) { + html += monthHtml + ( secondary || !( changeMonth && changeYear ) ? " " : "" ); + } - // We need to get the label text but this may also need to make sure it does not contain the - // input itself. - this.label.contents().not( this.element[ 0 ] ).each( function() { + // Year selection + if ( !inst.yearshtml ) { + inst.yearshtml = ""; + if ( secondary || !changeYear ) { + html += "<span class='ui-datepicker-year'>" + drawYear + "</span>"; + } else { - // The label contents could be text, html, or a mix. We concat each element to get a - // string representation of the label, without the input as part of it. - that.originalLabel += this.nodeType === 3 ? $( this ).text() : this.outerHTML; - } ); + // determine range of years to display + years = this._get( inst, "yearRange" ).split( ":" ); + thisYear = new Date().getFullYear(); + determineYear = function( value ) { + var year = ( value.match( /c[+\-].*/ ) ? drawYear + parseInt( value.substring( 1 ), 10 ) : + ( value.match( /[+\-].*/ ) ? thisYear + parseInt( value, 10 ) : + parseInt( value, 10 ) ) ); + return ( isNaN( year ) ? thisYear : year ); + }; + year = determineYear( years[ 0 ] ); + endYear = Math.max( year, determineYear( years[ 1 ] || "" ) ); + year = ( minDate ? Math.max( year, minDate.getFullYear() ) : year ); + endYear = ( maxDate ? Math.min( endYear, maxDate.getFullYear() ) : endYear ); + inst.yearshtml += "<select class='ui-datepicker-year' aria-label='" + selectYearLabel + "' data-handler='selectYear' data-event='change'>"; + for ( ; year <= endYear; year++ ) { + inst.yearshtml += "<option value='" + year + "'" + + ( year === drawYear ? " selected='selected'" : "" ) + + ">" + year + "</option>"; + } + inst.yearshtml += "</select>"; - // Set the label option if we found label text - if ( this.originalLabel ) { - options.label = this.originalLabel; + html += inst.yearshtml; + inst.yearshtml = null; + } } - disabled = this.element[ 0 ].disabled; - if ( disabled != null ) { - options.disabled = disabled; + html += this._get( inst, "yearSuffix" ); + if ( showMonthAfterYear ) { + html += ( secondary || !( changeMonth && changeYear ) ? " " : "" ) + monthHtml; } - return options; + html += "</div>"; // Close datepicker_header + return html; }, - _create: function() { - var checked = this.element[ 0 ].checked; - - this._bindFormResetHandler(); + /* Adjust one of the date sub-fields. */ + _adjustInstDate: function( inst, offset, period ) { + var year = inst.selectedYear + ( period === "Y" ? offset : 0 ), + month = inst.selectedMonth + ( period === "M" ? offset : 0 ), + day = Math.min( inst.selectedDay, this._getDaysInMonth( year, month ) ) + ( period === "D" ? offset : 0 ), + date = this._restrictMinMax( inst, this._daylightSavingAdjust( new Date( year, month, day ) ) ); - if ( this.options.disabled == null ) { - this.options.disabled = this.element[ 0 ].disabled; + inst.selectedDay = date.getDate(); + inst.drawMonth = inst.selectedMonth = date.getMonth(); + inst.drawYear = inst.selectedYear = date.getFullYear(); + if ( period === "M" || period === "Y" ) { + this._notifyChange( inst ); } + }, - this._setOption( "disabled", this.options.disabled ); - this._addClass( "ui-checkboxradio", "ui-helper-hidden-accessible" ); - this._addClass( this.label, "ui-checkboxradio-label", "ui-button ui-widget" ); - - if ( this.type === "radio" ) { - this._addClass( this.label, "ui-checkboxradio-radio-label" ); - } + /* Ensure a date is within any min/max bounds. */ + _restrictMinMax: function( inst, date ) { + var minDate = this._getMinMaxDate( inst, "min" ), + maxDate = this._getMinMaxDate( inst, "max" ), + newDate = ( minDate && date < minDate ? minDate : date ); + return ( maxDate && newDate > maxDate ? maxDate : newDate ); + }, - if ( this.options.label && this.options.label !== this.originalLabel ) { - this._updateLabel(); - } else if ( this.originalLabel ) { - this.options.label = this.originalLabel; + /* Notify change of month/year. */ + _notifyChange: function( inst ) { + var onChange = this._get( inst, "onChangeMonthYear" ); + if ( onChange ) { + onChange.apply( ( inst.input ? inst.input[ 0 ] : null ), + [ inst.selectedYear, inst.selectedMonth + 1, inst ] ); } + }, - this._enhance(); + /* Determine the number of months to show. */ + _getNumberOfMonths: function( inst ) { + var numMonths = this._get( inst, "numberOfMonths" ); + return ( numMonths == null ? [ 1, 1 ] : ( typeof numMonths === "number" ? [ 1, numMonths ] : numMonths ) ); + }, - if ( checked ) { - this._addClass( this.label, "ui-checkboxradio-checked", "ui-state-active" ); - } + /* Determine the current maximum date - ensure no time components are set. */ + _getMinMaxDate: function( inst, minMax ) { + return this._determineDate( inst, this._get( inst, minMax + "Date" ), null ); + }, - this._on( { - change: "_toggleClasses", - focus: function() { - this._addClass( this.label, null, "ui-state-focus ui-visual-focus" ); - }, - blur: function() { - this._removeClass( this.label, null, "ui-state-focus ui-visual-focus" ); - } - } ); + /* Find the number of days in a given month. */ + _getDaysInMonth: function( year, month ) { + return 32 - this._daylightSavingAdjust( new Date( year, month, 32 ) ).getDate(); }, - _readType: function() { - var nodeName = this.element[ 0 ].nodeName.toLowerCase(); - this.type = this.element[ 0 ].type; - if ( nodeName !== "input" || !/radio|checkbox/.test( this.type ) ) { - $.error( "Can't create checkboxradio on element.nodeName=" + nodeName + - " and element.type=" + this.type ); - } - }, - - // Support jQuery Mobile enhanced option - _enhance: function() { - this._updateIcon( this.element[ 0 ].checked ); - }, - - widget: function() { - return this.label; + /* Find the day of the week of the first of a month. */ + _getFirstDayOfMonth: function( year, month ) { + return new Date( year, month, 1 ).getDay(); }, - _getRadioGroup: function() { - var group; - var name = this.element[ 0 ].name; - var nameSelector = "input[name='" + $.escapeSelector( name ) + "']"; + /* Determines if we should allow a "next/prev" month display change. */ + _canAdjustMonth: function( inst, offset, curYear, curMonth ) { + var numMonths = this._getNumberOfMonths( inst ), + date = this._daylightSavingAdjust( new Date( curYear, + curMonth + ( offset < 0 ? offset : numMonths[ 0 ] * numMonths[ 1 ] ), 1 ) ); - if ( !name ) { - return $( [] ); + if ( offset < 0 ) { + date.setDate( this._getDaysInMonth( date.getFullYear(), date.getMonth() ) ); } + return this._isInRange( inst, date ); + }, - if ( this.form.length ) { - group = $( this.form[ 0 ].elements ).filter( nameSelector ); - } else { - - // Not inside a form, check all inputs that also are not inside a form - group = $( nameSelector ).filter( function() { - return $( this )._form().length === 0; - } ); - } + /* Is the given date in the accepted range? */ + _isInRange: function( inst, date ) { + var yearSplit, currentYear, + minDate = this._getMinMaxDate( inst, "min" ), + maxDate = this._getMinMaxDate( inst, "max" ), + minYear = null, + maxYear = null, + years = this._get( inst, "yearRange" ); + if ( years ) { + yearSplit = years.split( ":" ); + currentYear = new Date().getFullYear(); + minYear = parseInt( yearSplit[ 0 ], 10 ); + maxYear = parseInt( yearSplit[ 1 ], 10 ); + if ( yearSplit[ 0 ].match( /[+\-].*/ ) ) { + minYear += currentYear; + } + if ( yearSplit[ 1 ].match( /[+\-].*/ ) ) { + maxYear += currentYear; + } + } - return group.not( this.element ); + return ( ( !minDate || date.getTime() >= minDate.getTime() ) && + ( !maxDate || date.getTime() <= maxDate.getTime() ) && + ( !minYear || date.getFullYear() >= minYear ) && + ( !maxYear || date.getFullYear() <= maxYear ) ); }, - _toggleClasses: function() { - var checked = this.element[ 0 ].checked; - this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked ); + /* Provide the configuration settings for formatting/parsing. */ + _getFormatConfig: function( inst ) { + var shortYearCutoff = this._get( inst, "shortYearCutoff" ); + shortYearCutoff = ( typeof shortYearCutoff !== "string" ? shortYearCutoff : + new Date().getFullYear() % 100 + parseInt( shortYearCutoff, 10 ) ); + return { shortYearCutoff: shortYearCutoff, + dayNamesShort: this._get( inst, "dayNamesShort" ), dayNames: this._get( inst, "dayNames" ), + monthNamesShort: this._get( inst, "monthNamesShort" ), monthNames: this._get( inst, "monthNames" ) }; + }, - if ( this.options.icon && this.type === "checkbox" ) { - this._toggleClass( this.icon, null, "ui-icon-check ui-state-checked", checked ) - ._toggleClass( this.icon, null, "ui-icon-blank", !checked ); + /* Format the given date for display. */ + _formatDate: function( inst, day, month, year ) { + if ( !day ) { + inst.currentDay = inst.selectedDay; + inst.currentMonth = inst.selectedMonth; + inst.currentYear = inst.selectedYear; } + var date = ( day ? ( typeof day === "object" ? day : + this._daylightSavingAdjust( new Date( year, month, day ) ) ) : + this._daylightSavingAdjust( new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ); + return this.formatDate( this._get( inst, "dateFormat" ), date, this._getFormatConfig( inst ) ); + } +} ); - if ( this.type === "radio" ) { - this._getRadioGroup() - .each( function() { - var instance = $( this ).checkboxradio( "instance" ); +/* + * Bind hover events for datepicker elements. + * Done via delegate so the binding only occurs once in the lifetime of the parent div. + * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. + */ +function datepicker_bindHover( dpDiv ) { + var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a"; + return dpDiv.on( "mouseout", selector, function() { + $( this ).removeClass( "ui-state-hover" ); + if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) { + $( this ).removeClass( "ui-datepicker-prev-hover" ); + } + if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) { + $( this ).removeClass( "ui-datepicker-next-hover" ); + } + } ) + .on( "mouseover", selector, datepicker_handleMouseover ); +} - if ( instance ) { - instance._removeClass( instance.label, - "ui-checkboxradio-checked", "ui-state-active" ); - } - } ); +function datepicker_handleMouseover() { + if ( !$.datepicker._isDisabledDatepicker( datepicker_instActive.inline ? datepicker_instActive.dpDiv.parent()[ 0 ] : datepicker_instActive.input[ 0 ] ) ) { + $( this ).parents( ".ui-datepicker-calendar" ).find( "a" ).removeClass( "ui-state-hover" ); + $( this ).addClass( "ui-state-hover" ); + if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) { + $( this ).addClass( "ui-datepicker-prev-hover" ); } - }, - - _destroy: function() { - this._unbindFormResetHandler(); + if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) { + $( this ).addClass( "ui-datepicker-next-hover" ); + } + } +} - if ( this.icon ) { - this.icon.remove(); - this.iconSpace.remove(); +/* jQuery extend now ignores nulls! */ +function datepicker_extendRemove( target, props ) { + $.extend( target, props ); + for ( var name in props ) { + if ( props[ name ] == null ) { + target[ name ] = props[ name ]; } - }, + } + return target; +} - _setOption: function( key, value ) { +/* Invoke the datepicker functionality. + @param options string - a command, optionally followed by additional parameters or + Object - settings for attaching new datepicker functionality + @return jQuery object */ +$.fn.datepicker = function( options ) { - // We don't allow the value to be set to nothing - if ( key === "label" && !value ) { - return; - } + /* Verify an empty collection wasn't passed - Fixes #6976 */ + if ( !this.length ) { + return this; + } - this._super( key, value ); + /* Initialise the date picker. */ + if ( !$.datepicker.initialized ) { + $( document ).on( "mousedown", $.datepicker._checkExternalClick ); + $.datepicker.initialized = true; + } - if ( key === "disabled" ) { - this._toggleClass( this.label, null, "ui-state-disabled", value ); - this.element[ 0 ].disabled = value; + /* Append datepicker main container to body if not exist. */ + if ( $( "#" + $.datepicker._mainDivId ).length === 0 ) { + $( "body" ).append( $.datepicker.dpDiv ); + } - // Don't refresh when setting disabled - return; + var otherArgs = Array.prototype.slice.call( arguments, 1 ); + if ( typeof options === "string" && ( options === "isDisabled" || options === "getDate" || options === "widget" ) ) { + return $.datepicker[ "_" + options + "Datepicker" ]. + apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) ); + } + if ( options === "option" && arguments.length === 2 && typeof arguments[ 1 ] === "string" ) { + return $.datepicker[ "_" + options + "Datepicker" ]. + apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) ); + } + return this.each( function() { + if ( typeof options === "string" ) { + $.datepicker[ "_" + options + "Datepicker" ] + .apply( $.datepicker, [ this ].concat( otherArgs ) ); + } else { + $.datepicker._attachDatepicker( this, options ); } - this.refresh(); - }, + } ); +}; - _updateIcon: function( checked ) { - var toAdd = "ui-icon ui-icon-background "; +$.datepicker = new Datepicker(); // singleton instance +$.datepicker.initialized = false; +$.datepicker.uuid = new Date().getTime(); +$.datepicker.version = "1.13.2"; - if ( this.options.icon ) { - if ( !this.icon ) { - this.icon = $( "<span>" ); - this.iconSpace = $( "<span> </span>" ); - this._addClass( this.iconSpace, "ui-checkboxradio-icon-space" ); - } +var widgetsDatepicker = $.datepicker; - if ( this.type === "checkbox" ) { - toAdd += checked ? "ui-icon-check ui-state-checked" : "ui-icon-blank"; - this._removeClass( this.icon, null, checked ? "ui-icon-blank" : "ui-icon-check" ); - } else { - toAdd += "ui-icon-blank"; - } - this._addClass( this.icon, "ui-checkboxradio-icon", toAdd ); - if ( !checked ) { - this._removeClass( this.icon, null, "ui-icon-check ui-state-checked" ); - } - this.icon.prependTo( this.label ).after( this.iconSpace ); - } else if ( this.icon !== undefined ) { - this.icon.remove(); - this.iconSpace.remove(); - delete this.icon; - } - }, - _updateLabel: function() { - // Remove the contents of the label ( minus the icon, icon space, and input ) - var contents = this.label.contents().not( this.element[ 0 ] ); - if ( this.icon ) { - contents = contents.not( this.icon[ 0 ] ); - } - if ( this.iconSpace ) { - contents = contents.not( this.iconSpace[ 0 ] ); - } - contents.remove(); +// This file is deprecated +var ie = $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() ); - this.label.append( this.options.label ); - }, +/*! + * jQuery UI Mouse 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ - refresh: function() { - var checked = this.element[ 0 ].checked, - isDisabled = this.element[ 0 ].disabled; +//>>label: Mouse +//>>group: Widgets +//>>description: Abstracts mouse-based interactions to assist in creating certain widgets. +//>>docs: http://api.jqueryui.com/mouse/ - this._updateIcon( checked ); - this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked ); - if ( this.options.label !== null ) { - this._updateLabel(); - } - if ( isDisabled !== this.options.disabled ) { - this._setOptions( { "disabled": isDisabled } ); - } - } +var mouseHandled = false; +$( document ).on( "mouseup", function() { + mouseHandled = false; +} ); -} ] ); +var widgetsMouse = $.widget( "ui.mouse", { + version: "1.13.2", + options: { + cancel: "input, textarea, button, select, option", + distance: 1, + delay: 0 + }, + _mouseInit: function() { + var that = this; -var widgetsCheckboxradio = $.ui.checkboxradio; + this.element + .on( "mousedown." + this.widgetName, function( event ) { + return that._mouseDown( event ); + } ) + .on( "click." + this.widgetName, function( event ) { + if ( true === $.data( event.target, that.widgetName + ".preventClickEvent" ) ) { + $.removeData( event.target, that.widgetName + ".preventClickEvent" ); + event.stopImmediatePropagation(); + return false; + } + } ); + this.started = false; + }, -/*! - * jQuery UI Button 1.13.1 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ + // TODO: make sure destroying one instance of mouse doesn't mess with + // other instances of mouse + _mouseDestroy: function() { + this.element.off( "." + this.widgetName ); + if ( this._mouseMoveDelegate ) { + this.document + .off( "mousemove." + this.widgetName, this._mouseMoveDelegate ) + .off( "mouseup." + this.widgetName, this._mouseUpDelegate ); + } + }, -//>>label: Button -//>>group: Widgets -//>>description: Enhances a form with themeable buttons. -//>>docs: http://api.jqueryui.com/button/ -//>>demos: http://jqueryui.com/button/ -//>>css.structure: ../../themes/base/core.css -//>>css.structure: ../../themes/base/button.css -//>>css.theme: ../../themes/base/theme.css + _mouseDown: function( event ) { + // don't let more than one widget handle mouseStart + if ( mouseHandled ) { + return; + } -$.widget( "ui.button", { - version: "1.13.1", - defaultElement: "<button>", - options: { - classes: { - "ui-button": "ui-corner-all" - }, - disabled: null, - icon: null, - iconPosition: "beginning", - label: null, - showLabel: true - }, + this._mouseMoved = false; - _getCreateOptions: function() { - var disabled, + // We may have missed mouseup (out of window) + if ( this._mouseStarted ) { + this._mouseUp( event ); + } - // This is to support cases like in jQuery Mobile where the base widget does have - // an implementation of _getCreateOptions - options = this._super() || {}; + this._mouseDownEvent = event; - this.isInput = this.element.is( "input" ); + var that = this, + btnIsLeft = ( event.which === 1 ), - disabled = this.element[ 0 ].disabled; - if ( disabled != null ) { - options.disabled = disabled; + // event.target.nodeName works around a bug in IE 8 with + // disabled inputs (#7620) + elIsCancel = ( typeof this.options.cancel === "string" && event.target.nodeName ? + $( event.target ).closest( this.options.cancel ).length : false ); + if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) { + return true; } - this.originalLabel = this.isInput ? this.element.val() : this.element.html(); - if ( this.originalLabel ) { - options.label = this.originalLabel; + this.mouseDelayMet = !this.options.delay; + if ( !this.mouseDelayMet ) { + this._mouseDelayTimer = setTimeout( function() { + that.mouseDelayMet = true; + }, this.options.delay ); } - return options; - }, - - _create: function() { - if ( !this.option.showLabel & !this.options.icon ) { - this.options.showLabel = true; + if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) { + this._mouseStarted = ( this._mouseStart( event ) !== false ); + if ( !this._mouseStarted ) { + event.preventDefault(); + return true; + } } - // We have to check the option again here even though we did in _getCreateOptions, - // because null may have been passed on init which would override what was set in - // _getCreateOptions - if ( this.options.disabled == null ) { - this.options.disabled = this.element[ 0 ].disabled || false; + // Click event may never have fired (Gecko & Opera) + if ( true === $.data( event.target, this.widgetName + ".preventClickEvent" ) ) { + $.removeData( event.target, this.widgetName + ".preventClickEvent" ); } - this.hasTitle = !!this.element.attr( "title" ); + // These delegates are required to keep context + this._mouseMoveDelegate = function( event ) { + return that._mouseMove( event ); + }; + this._mouseUpDelegate = function( event ) { + return that._mouseUp( event ); + }; - // Check to see if the label needs to be set or if its already correct - if ( this.options.label && this.options.label !== this.originalLabel ) { - if ( this.isInput ) { - this.element.val( this.options.label ); - } else { - this.element.html( this.options.label ); - } - } - this._addClass( "ui-button", "ui-widget" ); - this._setOption( "disabled", this.options.disabled ); - this._enhance(); + this.document + .on( "mousemove." + this.widgetName, this._mouseMoveDelegate ) + .on( "mouseup." + this.widgetName, this._mouseUpDelegate ); - if ( this.element.is( "a" ) ) { - this._on( { - "keyup": function( event ) { - if ( event.keyCode === $.ui.keyCode.SPACE ) { - event.preventDefault(); + event.preventDefault(); - // Support: PhantomJS <= 1.9, IE 8 Only - // If a native click is available use it so we actually cause navigation - // otherwise just trigger a click event - if ( this.element[ 0 ].click ) { - this.element[ 0 ].click(); - } else { - this.element.trigger( "click" ); - } - } - } - } ); - } + mouseHandled = true; + return true; }, - _enhance: function() { - if ( !this.element.is( "button" ) ) { - this.element.attr( "role", "button" ); + _mouseMove: function( event ) { + + // Only check for mouseups outside the document if you've moved inside the document + // at least once. This prevents the firing of mouseup in the case of IE<9, which will + // fire a mousemove event if content is placed under the cursor. See #7778 + // Support: IE <9 + if ( this._mouseMoved ) { + + // IE mouseup check - mouseup happened when mouse was out of window + if ( $.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && + !event.button ) { + return this._mouseUp( event ); + + // Iframe mouseup check - mouseup occurred in another document + } else if ( !event.which ) { + + // Support: Safari <=8 - 9 + // Safari sets which to 0 if you press any of the following keys + // during a drag (#14461) + if ( event.originalEvent.altKey || event.originalEvent.ctrlKey || + event.originalEvent.metaKey || event.originalEvent.shiftKey ) { + this.ignoreMissingWhich = true; + } else if ( !this.ignoreMissingWhich ) { + return this._mouseUp( event ); + } + } } - if ( this.options.icon ) { - this._updateIcon( "icon", this.options.icon ); - this._updateTooltip(); + if ( event.which || event.button ) { + this._mouseMoved = true; } - }, - _updateTooltip: function() { - this.title = this.element.attr( "title" ); + if ( this._mouseStarted ) { + this._mouseDrag( event ); + return event.preventDefault(); + } - if ( !this.options.showLabel && !this.title ) { - this.element.attr( "title", this.options.label ); + if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) { + this._mouseStarted = + ( this._mouseStart( this._mouseDownEvent, event ) !== false ); + if ( this._mouseStarted ) { + this._mouseDrag( event ); + } else { + this._mouseUp( event ); + } } - }, - _updateIcon: function( option, value ) { - var icon = option !== "iconPosition", - position = icon ? this.options.iconPosition : value, - displayBlock = position === "top" || position === "bottom"; + return !this._mouseStarted; + }, - // Create icon - if ( !this.icon ) { - this.icon = $( "<span>" ); + _mouseUp: function( event ) { + this.document + .off( "mousemove." + this.widgetName, this._mouseMoveDelegate ) + .off( "mouseup." + this.widgetName, this._mouseUpDelegate ); - this._addClass( this.icon, "ui-button-icon", "ui-icon" ); + if ( this._mouseStarted ) { + this._mouseStarted = false; - if ( !this.options.showLabel ) { - this._addClass( "ui-button-icon-only" ); + if ( event.target === this._mouseDownEvent.target ) { + $.data( event.target, this.widgetName + ".preventClickEvent", true ); } - } else if ( icon ) { - // If we are updating the icon remove the old icon class - this._removeClass( this.icon, null, this.options.icon ); + this._mouseStop( event ); } - // If we are updating the icon add the new icon class - if ( icon ) { - this._addClass( this.icon, null, value ); + if ( this._mouseDelayTimer ) { + clearTimeout( this._mouseDelayTimer ); + delete this._mouseDelayTimer; } - this._attachIcon( position ); + this.ignoreMissingWhich = false; + mouseHandled = false; + event.preventDefault(); + }, - // If the icon is on top or bottom we need to add the ui-widget-icon-block class and remove - // the iconSpace if there is one. - if ( displayBlock ) { - this._addClass( this.icon, null, "ui-widget-icon-block" ); - if ( this.iconSpace ) { - this.iconSpace.remove(); - } - } else { - - // Position is beginning or end so remove the ui-widget-icon-block class and add the - // space if it does not exist - if ( !this.iconSpace ) { - this.iconSpace = $( "<span> </span>" ); - this._addClass( this.iconSpace, "ui-button-icon-space" ); - } - this._removeClass( this.icon, null, "ui-wiget-icon-block" ); - this._attachIconSpace( position ); - } + _mouseDistanceMet: function( event ) { + return ( Math.max( + Math.abs( this._mouseDownEvent.pageX - event.pageX ), + Math.abs( this._mouseDownEvent.pageY - event.pageY ) + ) >= this.options.distance + ); }, - _destroy: function() { - this.element.removeAttr( "role" ); - - if ( this.icon ) { - this.icon.remove(); - } - if ( this.iconSpace ) { - this.iconSpace.remove(); - } - if ( !this.hasTitle ) { - this.element.removeAttr( "title" ); - } + _mouseDelayMet: function( /* event */ ) { + return this.mouseDelayMet; }, - _attachIconSpace: function( iconPosition ) { - this.icon[ /^(?:end|bottom)/.test( iconPosition ) ? "before" : "after" ]( this.iconSpace ); - }, + // These are placeholder methods, to be overriden by extending plugin + _mouseStart: function( /* event */ ) {}, + _mouseDrag: function( /* event */ ) {}, + _mouseStop: function( /* event */ ) {}, + _mouseCapture: function( /* event */ ) { + return true; + } +} ); - _attachIcon: function( iconPosition ) { - this.element[ /^(?:end|bottom)/.test( iconPosition ) ? "append" : "prepend" ]( this.icon ); - }, - _setOptions: function( options ) { - var newShowLabel = options.showLabel === undefined ? - this.options.showLabel : - options.showLabel, - newIcon = options.icon === undefined ? this.options.icon : options.icon; - if ( !newShowLabel && !newIcon ) { - options.showLabel = true; +// $.ui.plugin is deprecated. Use $.widget() extensions instead. +var plugin = $.ui.plugin = { + add: function( module, option, set ) { + var i, + proto = $.ui[ module ].prototype; + for ( i in set ) { + proto.plugins[ i ] = proto.plugins[ i ] || []; + proto.plugins[ i ].push( [ option, set[ i ] ] ); } - this._super( options ); }, + call: function( instance, name, args, allowDisconnected ) { + var i, + set = instance.plugins[ name ]; - _setOption: function( key, value ) { - if ( key === "icon" ) { - if ( value ) { - this._updateIcon( key, value ); - } else if ( this.icon ) { - this.icon.remove(); - if ( this.iconSpace ) { - this.iconSpace.remove(); - } - } + if ( !set ) { + return; } - if ( key === "iconPosition" ) { - this._updateIcon( key, value ); + if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode || + instance.element[ 0 ].parentNode.nodeType === 11 ) ) { + return; } - // Make sure we can't end up with a button that has neither text nor icon - if ( key === "showLabel" ) { - this._toggleClass( "ui-button-icon-only", null, !value ); - this._updateTooltip(); + for ( i = 0; i < set.length; i++ ) { + if ( instance.options[ set[ i ][ 0 ] ] ) { + set[ i ][ 1 ].apply( instance.element, args ); + } } + } +}; - if ( key === "label" ) { - if ( this.isInput ) { - this.element.val( value ); - } else { - // If there is an icon, append it, else nothing then append the value - // this avoids removal of the icon when setting label text - this.element.html( value ); - if ( this.icon ) { - this._attachIcon( this.options.iconPosition ); - this._attachIconSpace( this.options.iconPosition ); - } - } + +var safeBlur = $.ui.safeBlur = function( element ) { + + // Support: IE9 - 10 only + // If the <body> is blurred, IE will switch windows, see #9420 + if ( element && element.nodeName.toLowerCase() !== "body" ) { + $( element ).trigger( "blur" ); + } +}; + + +/*! + * jQuery UI Draggable 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: Draggable +//>>group: Interactions +//>>description: Enables dragging functionality for any element. +//>>docs: http://api.jqueryui.com/draggable/ +//>>demos: http://jqueryui.com/draggable/ +//>>css.structure: ../../themes/base/draggable.css + + +$.widget( "ui.draggable", $.ui.mouse, { + version: "1.13.2", + widgetEventPrefix: "drag", + options: { + addClasses: true, + appendTo: "parent", + axis: false, + connectToSortable: false, + containment: false, + cursor: "auto", + cursorAt: false, + grid: false, + handle: false, + helper: "original", + iframeFix: false, + opacity: false, + refreshPositions: false, + revert: false, + revertDuration: 500, + scope: "default", + scroll: true, + scrollSensitivity: 20, + scrollSpeed: 20, + snap: false, + snapMode: "both", + snapTolerance: 20, + stack: false, + zIndex: false, + + // Callbacks + drag: null, + start: null, + stop: null + }, + _create: function() { + + if ( this.options.helper === "original" ) { + this._setPositionRelative(); + } + if ( this.options.addClasses ) { + this._addClass( "ui-draggable" ); } + this._setHandleClassName(); + + this._mouseInit(); + }, + _setOption: function( key, value ) { this._super( key, value ); + if ( key === "handle" ) { + this._removeHandleClassName(); + this._setHandleClassName(); + } + }, - if ( key === "disabled" ) { - this._toggleClass( null, "ui-state-disabled", value ); - this.element[ 0 ].disabled = value; - if ( value ) { - this.element.trigger( "blur" ); - } + _destroy: function() { + if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) { + this.destroyOnClear = true; + return; } + this._removeHandleClassName(); + this._mouseDestroy(); }, - refresh: function() { + _mouseCapture: function( event ) { + var o = this.options; - // Make sure to only check disabled if its an element that supports this otherwise - // check for the disabled class to determine state - var isDisabled = this.element.is( "input, button" ) ? - this.element[ 0 ].disabled : this.element.hasClass( "ui-button-disabled" ); + // Among others, prevent a drag on a resizable-handle + if ( this.helper || o.disabled || + $( event.target ).closest( ".ui-resizable-handle" ).length > 0 ) { + return false; + } - if ( isDisabled !== this.options.disabled ) { - this._setOptions( { disabled: isDisabled } ); + //Quit if we're not on a valid handle + this.handle = this._getHandle( event ); + if ( !this.handle ) { + return false; } - this._updateTooltip(); - } -} ); + this._blurActiveElement( event ); -// DEPRECATED -if ( $.uiBackCompat !== false ) { + this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix ); - // Text and Icons options - $.widget( "ui.button", $.ui.button, { - options: { - text: true, - icons: { - primary: null, - secondary: null - } - }, + return true; - _create: function() { - if ( this.options.showLabel && !this.options.text ) { - this.options.showLabel = this.options.text; - } - if ( !this.options.showLabel && this.options.text ) { - this.options.text = this.options.showLabel; - } - if ( !this.options.icon && ( this.options.icons.primary || - this.options.icons.secondary ) ) { - if ( this.options.icons.primary ) { - this.options.icon = this.options.icons.primary; - } else { - this.options.icon = this.options.icons.secondary; - this.options.iconPosition = "end"; - } - } else if ( this.options.icon ) { - this.options.icons.primary = this.options.icon; - } - this._super(); - }, + }, - _setOption: function( key, value ) { - if ( key === "text" ) { - this._super( "showLabel", value ); - return; - } - if ( key === "showLabel" ) { - this.options.text = value; - } - if ( key === "icon" ) { - this.options.icons.primary = value; - } - if ( key === "icons" ) { - if ( value.primary ) { - this._super( "icon", value.primary ); - this._super( "iconPosition", "beginning" ); - } else if ( value.secondary ) { - this._super( "icon", value.secondary ); - this._super( "iconPosition", "end" ); - } - } - this._superApply( arguments ); + _blockFrames: function( selector ) { + this.iframeBlocks = this.document.find( selector ).map( function() { + var iframe = $( this ); + + return $( "<div>" ) + .css( "position", "absolute" ) + .appendTo( iframe.parent() ) + .outerWidth( iframe.outerWidth() ) + .outerHeight( iframe.outerHeight() ) + .offset( iframe.offset() )[ 0 ]; + } ); + }, + + _unblockFrames: function() { + if ( this.iframeBlocks ) { + this.iframeBlocks.remove(); + delete this.iframeBlocks; } - } ); + }, - $.fn.button = ( function( orig ) { - return function( options ) { - var isMethodCall = typeof options === "string"; - var args = Array.prototype.slice.call( arguments, 1 ); - var returnValue = this; + _blurActiveElement: function( event ) { + var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ), + target = $( event.target ); - if ( isMethodCall ) { + // Don't blur if the event occurred on an element that is within + // the currently focused element + // See #10527, #12472 + if ( target.closest( activeElement ).length ) { + return; + } - // If this is an empty collection, we need to have the instance method - // return undefined instead of the jQuery instance - if ( !this.length && options === "instance" ) { - returnValue = undefined; - } else { - this.each( function() { - var methodValue; - var type = $( this ).attr( "type" ); - var name = type !== "checkbox" && type !== "radio" ? - "button" : - "checkboxradio"; - var instance = $.data( this, "ui-" + name ); + // Blur any element that currently has focus, see #4261 + $.ui.safeBlur( activeElement ); + }, - if ( options === "instance" ) { - returnValue = instance; - return false; - } + _mouseStart: function( event ) { - if ( !instance ) { - return $.error( "cannot call methods on button" + - " prior to initialization; " + - "attempted to call method '" + options + "'" ); - } + var o = this.options; - if ( typeof instance[ options ] !== "function" || - options.charAt( 0 ) === "_" ) { - return $.error( "no such method '" + options + "' for button" + - " widget instance" ); - } + //Create and append the visible helper + this.helper = this._createHelper( event ); - methodValue = instance[ options ].apply( instance, args ); + this._addClass( this.helper, "ui-draggable-dragging" ); - if ( methodValue !== instance && methodValue !== undefined ) { - returnValue = methodValue && methodValue.jquery ? - returnValue.pushStack( methodValue.get() ) : - methodValue; - return false; - } - } ); - } - } else { + //Cache the helper size + this._cacheHelperProportions(); - // Allow multiple hashes to be passed on init - if ( args.length ) { - options = $.widget.extend.apply( null, [ options ].concat( args ) ); - } + //If ddmanager is used for droppables, set the global draggable + if ( $.ui.ddmanager ) { + $.ui.ddmanager.current = this; + } - this.each( function() { - var type = $( this ).attr( "type" ); - var name = type !== "checkbox" && type !== "radio" ? "button" : "checkboxradio"; - var instance = $.data( this, "ui-" + name ); + /* + * - Position generation - + * This block generates everything position related - it's the core of draggables. + */ - if ( instance ) { - instance.option( options || {} ); - if ( instance._init ) { - instance._init(); - } - } else { - if ( name === "button" ) { - orig.call( $( this ), options ); - return; - } + //Cache the margins of the original element + this._cacheMargins(); - $( this ).checkboxradio( $.extend( { icon: false }, options ) ); - } - } ); - } + //Store the helper's css position + this.cssPosition = this.helper.css( "position" ); + this.scrollParent = this.helper.scrollParent( true ); + this.offsetParent = this.helper.offsetParent(); + this.hasFixedAncestor = this.helper.parents().filter( function() { + return $( this ).css( "position" ) === "fixed"; + } ).length > 0; - return returnValue; - }; - } )( $.fn.button ); + //The element's absolute position on the page minus margins + this.positionAbs = this.element.offset(); + this._refreshOffsets( event ); - $.fn.buttonset = function() { - if ( !$.ui.controlgroup ) { - $.error( "Controlgroup widget missing" ); - } - if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" && arguments[ 2 ] ) { - return this.controlgroup.apply( this, - [ arguments[ 0 ], "items.button", arguments[ 2 ] ] ); - } - if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" ) { - return this.controlgroup.apply( this, [ arguments[ 0 ], "items.button" ] ); - } - if ( typeof arguments[ 0 ] === "object" && arguments[ 0 ].items ) { - arguments[ 0 ].items = { - button: arguments[ 0 ].items - }; + //Generate the original position + this.originalPosition = this.position = this._generatePosition( event, false ); + this.originalPageX = event.pageX; + this.originalPageY = event.pageY; + + //Adjust the mouse offset relative to the helper if "cursorAt" is supplied + if ( o.cursorAt ) { + this._adjustOffsetFromHelper( o.cursorAt ); } - return this.controlgroup.apply( this, arguments ); - }; -} -var widgetsButton = $.ui.button; + //Set a containment if given in the options + this._setContainment(); + //Trigger event + callbacks + if ( this._trigger( "start", event ) === false ) { + this._clear(); + return false; + } -/* eslint-disable max-len, camelcase */ -/*! - * jQuery UI Datepicker 1.13.1 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ + //Recache the helper size + this._cacheHelperProportions(); -//>>label: Datepicker -//>>group: Widgets -//>>description: Displays a calendar from an input or inline for selecting dates. -//>>docs: http://api.jqueryui.com/datepicker/ -//>>demos: http://jqueryui.com/datepicker/ -//>>css.structure: ../../themes/base/core.css -//>>css.structure: ../../themes/base/datepicker.css -//>>css.theme: ../../themes/base/theme.css + //Prepare the droppable offsets + if ( $.ui.ddmanager && !o.dropBehaviour ) { + $.ui.ddmanager.prepareOffsets( this, event ); + } + // Execute the drag once - this causes the helper not to be visible before getting its + // correct position + this._mouseDrag( event, true ); -$.extend( $.ui, { datepicker: { version: "1.13.1" } } ); + // If the ddmanager is used for droppables, inform the manager that dragging has started + // (see #5003) + if ( $.ui.ddmanager ) { + $.ui.ddmanager.dragStart( this, event ); + } -var datepicker_instActive; + return true; + }, -function datepicker_getZindex( elem ) { - var position, value; - while ( elem.length && elem[ 0 ] !== document ) { + _refreshOffsets: function( event ) { + this.offset = { + top: this.positionAbs.top - this.margins.top, + left: this.positionAbs.left - this.margins.left, + scroll: false, + parent: this._getParentOffset(), + relative: this._getRelativeOffset() + }; - // Ignore z-index if position is set to a value where z-index is ignored by the browser - // This makes behavior of this function consistent across browsers - // WebKit always returns auto if the element is positioned - position = elem.css( "position" ); - if ( position === "absolute" || position === "relative" || position === "fixed" ) { + this.offset.click = { + left: event.pageX - this.offset.left, + top: event.pageY - this.offset.top + }; + }, - // IE returns 0 when zIndex is not specified - // other browsers return a string - // we ignore the case of nested elements with an explicit value of 0 - // <div style="z-index: -10;"><div style="z-index: 0;"></div></div> - value = parseInt( elem.css( "zIndex" ), 10 ); - if ( !isNaN( value ) && value !== 0 ) { - return value; - } + _mouseDrag: function( event, noPropagation ) { + + // reset any necessary cached properties (see #5009) + if ( this.hasFixedAncestor ) { + this.offset.parent = this._getParentOffset(); } - elem = elem.parent(); - } - return 0; -} + //Compute the helpers position + this.position = this._generatePosition( event, true ); + this.positionAbs = this._convertPositionTo( "absolute" ); -/* Date picker manager. - Use the singleton instance of this class, $.datepicker, to interact with the date picker. - Settings for (groups of) date pickers are maintained in an instance object, - allowing multiple different settings on the same page. */ - -function Datepicker() { - this._curInst = null; // The current instance in use - this._keyEvent = false; // If the last event was a key event - this._disabledInputs = []; // List of date picker inputs that have been disabled - this._datepickerShowing = false; // True if the popup picker is showing , false if not - this._inDialog = false; // True if showing within a "dialog", false if not - this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division - this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class - this._appendClass = "ui-datepicker-append"; // The name of the append marker class - this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class - this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class - this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class - this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class - this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class - this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class - this.regional = []; // Available regional settings, indexed by language code - this.regional[ "" ] = { // Default regional settings - closeText: "Done", // Display text for close link - prevText: "Prev", // Display text for previous month link - nextText: "Next", // Display text for next month link - currentText: "Today", // Display text for current month link - monthNames: [ "January", "February", "March", "April", "May", "June", - "July", "August", "September", "October", "November", "December" ], // Names of months for drop-down and formatting - monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ], // For formatting - dayNames: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], // For formatting - dayNamesShort: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], // For formatting - dayNamesMin: [ "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" ], // Column headings for days starting at Sunday - weekHeader: "Wk", // Column header for week of the year - dateFormat: "mm/dd/yy", // See format options on parseDate - firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... - isRTL: false, // True if right-to-left language, false if left-to-right - showMonthAfterYear: false, // True if the year select precedes month, false for month then year - yearSuffix: "", // Additional text to append to the year in the month headers, - selectMonthLabel: "Select month", // Invisible label for month selector - selectYearLabel: "Select year" // Invisible label for year selector - }; - this._defaults = { // Global defaults for all the date picker instances - showOn: "focus", // "focus" for popup on focus, - // "button" for trigger button, or "both" for either - showAnim: "fadeIn", // Name of jQuery animation for popup - showOptions: {}, // Options for enhanced animations - defaultDate: null, // Used when field is blank: actual date, - // +/-number for offset from today, null for today - appendText: "", // Display text following the input box, e.g. showing the format - buttonText: "...", // Text for trigger button - buttonImage: "", // URL for trigger button image - buttonImageOnly: false, // True if the image appears alone, false if it appears on a button - hideIfNoPrevNext: false, // True to hide next/previous month links - // if not applicable, false to just disable them - navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links - gotoCurrent: false, // True if today link goes back to current selection instead - changeMonth: false, // True if month can be selected directly, false if only prev/next - changeYear: false, // True if year can be selected directly, false if only prev/next - yearRange: "c-10:c+10", // Range of years to display in drop-down, - // either relative to today's year (-nn:+nn), relative to currently displayed year - // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n) - showOtherMonths: false, // True to show dates in other months, false to leave blank - selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable - showWeek: false, // True to show week of the year, false to not show it - calculateWeek: this.iso8601Week, // How to calculate the week of the year, - // takes a Date and returns the number of the week for it - shortYearCutoff: "+10", // Short year values < this are in the current century, - // > this are in the previous century, - // string value starting with "+" for current year + value - minDate: null, // The earliest selectable date, or null for no limit - maxDate: null, // The latest selectable date, or null for no limit - duration: "fast", // Duration of display/closure - beforeShowDay: null, // Function that takes a date and returns an array with - // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "", - // [2] = cell title (optional), e.g. $.datepicker.noWeekends - beforeShow: null, // Function that takes an input field and - // returns a set of custom settings for the date picker - onSelect: null, // Define a callback function when a date is selected - onChangeMonthYear: null, // Define a callback function when the month or year is changed - onClose: null, // Define a callback function when the datepicker is closed - onUpdateDatepicker: null, // Define a callback function when the datepicker is updated - numberOfMonths: 1, // Number of months to show at a time - showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0) - stepMonths: 1, // Number of months to step back/forward - stepBigMonths: 12, // Number of months to step back/forward for the big links - altField: "", // Selector for an alternate field to store selected dates into - altFormat: "", // The date format to use for the alternate field - constrainInput: true, // The input is constrained by the current date format - showButtonPanel: false, // True to show button panel, false to not show it - autoSize: false, // True to size the input for the date format, false to leave as is - disabled: false // The initial disabled state - }; - $.extend( this._defaults, this.regional[ "" ] ); - this.regional.en = $.extend( true, {}, this.regional[ "" ] ); - this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en ); - this.dpDiv = datepicker_bindHover( $( "<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ); -} - -$.extend( Datepicker.prototype, { + //Call plugins and callbacks and use the resulting position if something is returned + if ( !noPropagation ) { + var ui = this._uiHash(); + if ( this._trigger( "drag", event, ui ) === false ) { + this._mouseUp( new $.Event( "mouseup", event ) ); + return false; + } + this.position = ui.position; + } - /* Class name added to elements to indicate already configured with a date picker. */ - markerClassName: "hasDatepicker", + this.helper[ 0 ].style.left = this.position.left + "px"; + this.helper[ 0 ].style.top = this.position.top + "px"; - //Keep track of the maximum number of rows displayed (see #7043) - maxRows: 4, + if ( $.ui.ddmanager ) { + $.ui.ddmanager.drag( this, event ); + } - // TODO rename to "widget" when switching to widget factory - _widgetDatepicker: function() { - return this.dpDiv; + return false; }, - /* Override the default settings for all instances of the date picker. - * @param settings object - the new settings to use as defaults (anonymous object) - * @return the manager object - */ - setDefaults: function( settings ) { - datepicker_extendRemove( this._defaults, settings || {} ); - return this; - }, + _mouseStop: function( event ) { - /* Attach the date picker to a jQuery selection. - * @param target element - the target input field or division or span - * @param settings object - the new settings to use for this date picker instance (anonymous) - */ - _attachDatepicker: function( target, settings ) { - var nodeName, inline, inst; - nodeName = target.nodeName.toLowerCase(); - inline = ( nodeName === "div" || nodeName === "span" ); - if ( !target.id ) { - this.uuid += 1; - target.id = "dp" + this.uuid; + //If we are using droppables, inform the manager about the drop + var that = this, + dropped = false; + if ( $.ui.ddmanager && !this.options.dropBehaviour ) { + dropped = $.ui.ddmanager.drop( this, event ); } - inst = this._newInst( $( target ), inline ); - inst.settings = $.extend( {}, settings || {} ); - if ( nodeName === "input" ) { - this._connectDatepicker( target, inst ); - } else if ( inline ) { - this._inlineDatepicker( target, inst ); + + //if a drop comes from outside (a sortable) + if ( this.dropped ) { + dropped = this.dropped; + this.dropped = false; } - }, - /* Create a new instance object. */ - _newInst: function( target, inline ) { - var id = target[ 0 ].id.replace( /([^A-Za-z0-9_\-])/g, "\\\\$1" ); // escape jQuery meta chars - return { id: id, input: target, // associated target - selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection - drawMonth: 0, drawYear: 0, // month being drawn - inline: inline, // is datepicker inline or not - dpDiv: ( !inline ? this.dpDiv : // presentation div - datepicker_bindHover( $( "<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ) ) }; + if ( ( this.options.revert === "invalid" && !dropped ) || + ( this.options.revert === "valid" && dropped ) || + this.options.revert === true || ( typeof this.options.revert === "function" && + this.options.revert.call( this.element, dropped ) ) + ) { + $( this.helper ).animate( + this.originalPosition, + parseInt( this.options.revertDuration, 10 ), + function() { + if ( that._trigger( "stop", event ) !== false ) { + that._clear(); + } + } + ); + } else { + if ( this._trigger( "stop", event ) !== false ) { + this._clear(); + } + } + + return false; }, - /* Attach the date picker to an input field. */ - _connectDatepicker: function( target, inst ) { - var input = $( target ); - inst.append = $( [] ); - inst.trigger = $( [] ); - if ( input.hasClass( this.markerClassName ) ) { - return; + _mouseUp: function( event ) { + this._unblockFrames(); + + // If the ddmanager is used for droppables, inform the manager that dragging has stopped + // (see #5003) + if ( $.ui.ddmanager ) { + $.ui.ddmanager.dragStop( this, event ); } - this._attachments( input, inst ); - input.addClass( this.markerClassName ).on( "keydown", this._doKeyDown ). - on( "keypress", this._doKeyPress ).on( "keyup", this._doKeyUp ); - this._autoSize( inst ); - $.data( target, "datepicker", inst ); - //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665) - if ( inst.settings.disabled ) { - this._disableDatepicker( target ); + // Only need to focus if the event occurred on the draggable itself, see #10527 + if ( this.handleElement.is( event.target ) ) { + + // The interaction is over; whether or not the click resulted in a drag, + // focus the element + this.element.trigger( "focus" ); } + + return $.ui.mouse.prototype._mouseUp.call( this, event ); }, - /* Make attachments based on settings. */ - _attachments: function( input, inst ) { - var showOn, buttonText, buttonImage, - appendText = this._get( inst, "appendText" ), - isRTL = this._get( inst, "isRTL" ); + cancel: function() { - if ( inst.append ) { - inst.append.remove(); - } - if ( appendText ) { - inst.append = $( "<span>" ) - .addClass( this._appendClass ) - .text( appendText ); - input[ isRTL ? "before" : "after" ]( inst.append ); + if ( this.helper.is( ".ui-draggable-dragging" ) ) { + this._mouseUp( new $.Event( "mouseup", { target: this.element[ 0 ] } ) ); + } else { + this._clear(); } - input.off( "focus", this._showDatepicker ); + return this; - if ( inst.trigger ) { - inst.trigger.remove(); - } + }, - showOn = this._get( inst, "showOn" ); - if ( showOn === "focus" || showOn === "both" ) { // pop-up date picker when in the marked field - input.on( "focus", this._showDatepicker ); - } - if ( showOn === "button" || showOn === "both" ) { // pop-up date picker when button clicked - buttonText = this._get( inst, "buttonText" ); - buttonImage = this._get( inst, "buttonImage" ); + _getHandle: function( event ) { + return this.options.handle ? + !!$( event.target ).closest( this.element.find( this.options.handle ) ).length : + true; + }, - if ( this._get( inst, "buttonImageOnly" ) ) { - inst.trigger = $( "<img>" ) - .addClass( this._triggerClass ) - .attr( { - src: buttonImage, - alt: buttonText, - title: buttonText - } ); - } else { - inst.trigger = $( "<button type='button'>" ) - .addClass( this._triggerClass ); - if ( buttonImage ) { - inst.trigger.html( - $( "<img>" ) - .attr( { - src: buttonImage, - alt: buttonText, - title: buttonText - } ) - ); - } else { - inst.trigger.text( buttonText ); - } - } + _setHandleClassName: function() { + this.handleElement = this.options.handle ? + this.element.find( this.options.handle ) : this.element; + this._addClass( this.handleElement, "ui-draggable-handle" ); + }, - input[ isRTL ? "before" : "after" ]( inst.trigger ); - inst.trigger.on( "click", function() { - if ( $.datepicker._datepickerShowing && $.datepicker._lastInput === input[ 0 ] ) { - $.datepicker._hideDatepicker(); - } else if ( $.datepicker._datepickerShowing && $.datepicker._lastInput !== input[ 0 ] ) { - $.datepicker._hideDatepicker(); - $.datepicker._showDatepicker( input[ 0 ] ); - } else { - $.datepicker._showDatepicker( input[ 0 ] ); - } - return false; - } ); - } + _removeHandleClassName: function() { + this._removeClass( this.handleElement, "ui-draggable-handle" ); }, - /* Apply the maximum length for the date format. */ - _autoSize: function( inst ) { - if ( this._get( inst, "autoSize" ) && !inst.inline ) { - var findMax, max, maxI, i, - date = new Date( 2009, 12 - 1, 20 ), // Ensure double digits - dateFormat = this._get( inst, "dateFormat" ); + _createHelper: function( event ) { - if ( dateFormat.match( /[DM]/ ) ) { - findMax = function( names ) { - max = 0; - maxI = 0; - for ( i = 0; i < names.length; i++ ) { - if ( names[ i ].length > max ) { - max = names[ i ].length; - maxI = i; - } - } - return maxI; - }; - date.setMonth( findMax( this._get( inst, ( dateFormat.match( /MM/ ) ? - "monthNames" : "monthNamesShort" ) ) ) ); - date.setDate( findMax( this._get( inst, ( dateFormat.match( /DD/ ) ? - "dayNames" : "dayNamesShort" ) ) ) + 20 - date.getDay() ); - } - inst.input.attr( "size", this._formatDate( inst, date ).length ); + var o = this.options, + helperIsFunction = typeof o.helper === "function", + helper = helperIsFunction ? + $( o.helper.apply( this.element[ 0 ], [ event ] ) ) : + ( o.helper === "clone" ? + this.element.clone().removeAttr( "id" ) : + this.element ); + + if ( !helper.parents( "body" ).length ) { + helper.appendTo( ( o.appendTo === "parent" ? + this.element[ 0 ].parentNode : + o.appendTo ) ); } - }, - /* Attach an inline date picker to a div. */ - _inlineDatepicker: function( target, inst ) { - var divSpan = $( target ); - if ( divSpan.hasClass( this.markerClassName ) ) { - return; + // Http://bugs.jqueryui.com/ticket/9446 + // a helper function can return the original element + // which wouldn't have been set to relative in _create + if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) { + this._setPositionRelative(); } - divSpan.addClass( this.markerClassName ).append( inst.dpDiv ); - $.data( target, "datepicker", inst ); - this._setDate( inst, this._getDefaultDate( inst ), true ); - this._updateDatepicker( inst ); - this._updateAlternate( inst ); - //If disabled option is true, disable the datepicker before showing it (see ticket #5665) - if ( inst.settings.disabled ) { - this._disableDatepicker( target ); + if ( helper[ 0 ] !== this.element[ 0 ] && + !( /(fixed|absolute)/ ).test( helper.css( "position" ) ) ) { + helper.css( "position", "absolute" ); } - // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements - // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height - inst.dpDiv.css( "display", "block" ); - }, + return helper; - /* Pop-up the date picker in a "dialog" box. - * @param input element - ignored - * @param date string or Date - the initial date to display - * @param onSelect function - the function to call when a date is selected - * @param settings object - update the dialog date picker instance's settings (anonymous object) - * @param pos int[2] - coordinates for the dialog's position within the screen or - * event - with x/y coordinates or - * leave empty for default (screen centre) - * @return the manager object - */ - _dialogDatepicker: function( input, date, onSelect, settings, pos ) { - var id, browserWidth, browserHeight, scrollX, scrollY, - inst = this._dialogInst; // internal instance + }, - if ( !inst ) { - this.uuid += 1; - id = "dp" + this.uuid; - this._dialogInput = $( "<input type='text' id='" + id + - "' style='position: absolute; top: -100px; width: 0px;'/>" ); - this._dialogInput.on( "keydown", this._doKeyDown ); - $( "body" ).append( this._dialogInput ); - inst = this._dialogInst = this._newInst( this._dialogInput, false ); - inst.settings = {}; - $.data( this._dialogInput[ 0 ], "datepicker", inst ); + _setPositionRelative: function() { + if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) { + this.element[ 0 ].style.position = "relative"; } - datepicker_extendRemove( inst.settings, settings || {} ); - date = ( date && date.constructor === Date ? this._formatDate( inst, date ) : date ); - this._dialogInput.val( date ); + }, - this._pos = ( pos ? ( pos.length ? pos : [ pos.pageX, pos.pageY ] ) : null ); - if ( !this._pos ) { - browserWidth = document.documentElement.clientWidth; - browserHeight = document.documentElement.clientHeight; - scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; - scrollY = document.documentElement.scrollTop || document.body.scrollTop; - this._pos = // should use actual width/height below - [ ( browserWidth / 2 ) - 100 + scrollX, ( browserHeight / 2 ) - 150 + scrollY ]; + _adjustOffsetFromHelper: function( obj ) { + if ( typeof obj === "string" ) { + obj = obj.split( " " ); } - - // Move input on screen for focus, but hidden behind dialog - this._dialogInput.css( "left", ( this._pos[ 0 ] + 20 ) + "px" ).css( "top", this._pos[ 1 ] + "px" ); - inst.settings.onSelect = onSelect; - this._inDialog = true; - this.dpDiv.addClass( this._dialogClass ); - this._showDatepicker( this._dialogInput[ 0 ] ); - if ( $.blockUI ) { - $.blockUI( this.dpDiv ); + if ( Array.isArray( obj ) ) { + obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 }; + } + if ( "left" in obj ) { + this.offset.click.left = obj.left + this.margins.left; + } + if ( "right" in obj ) { + this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; + } + if ( "top" in obj ) { + this.offset.click.top = obj.top + this.margins.top; + } + if ( "bottom" in obj ) { + this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; } - $.data( this._dialogInput[ 0 ], "datepicker", inst ); - return this; }, - /* Detach a datepicker from its control. - * @param target element - the target input field or division or span - */ - _destroyDatepicker: function( target ) { - var nodeName, - $target = $( target ), - inst = $.data( target, "datepicker" ); + _isRootNode: function( element ) { + return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ]; + }, - if ( !$target.hasClass( this.markerClassName ) ) { - return; - } + _getParentOffset: function() { - nodeName = target.nodeName.toLowerCase(); - $.removeData( target, "datepicker" ); - if ( nodeName === "input" ) { - inst.append.remove(); - inst.trigger.remove(); - $target.removeClass( this.markerClassName ). - off( "focus", this._showDatepicker ). - off( "keydown", this._doKeyDown ). - off( "keypress", this._doKeyPress ). - off( "keyup", this._doKeyUp ); - } else if ( nodeName === "div" || nodeName === "span" ) { - $target.removeClass( this.markerClassName ).empty(); + //Get the offsetParent and cache its position + var po = this.offsetParent.offset(), + document = this.document[ 0 ]; + + // This is a special case where we need to modify a offset calculated on start, since the + // following happened: + // 1. The position of the helper is absolute, so it's position is calculated based on the + // next positioned parent + // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't + // the document, which means that the scroll is included in the initial calculation of the + // offset of the parent, and never recalculated upon drag + if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== document && + $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) { + po.left += this.scrollParent.scrollLeft(); + po.top += this.scrollParent.scrollTop(); } - if ( datepicker_instActive === inst ) { - datepicker_instActive = null; - this._curInst = null; + if ( this._isRootNode( this.offsetParent[ 0 ] ) ) { + po = { top: 0, left: 0 }; } - }, - /* Enable the date picker to a jQuery selection. - * @param target element - the target input field or division or span - */ - _enableDatepicker: function( target ) { - var nodeName, inline, - $target = $( target ), - inst = $.data( target, "datepicker" ); + return { + top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ), + left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 ) + }; - if ( !$target.hasClass( this.markerClassName ) ) { - return; - } + }, - nodeName = target.nodeName.toLowerCase(); - if ( nodeName === "input" ) { - target.disabled = false; - inst.trigger.filter( "button" ). - each( function() { - this.disabled = false; - } ).end(). - filter( "img" ).css( { opacity: "1.0", cursor: "" } ); - } else if ( nodeName === "div" || nodeName === "span" ) { - inline = $target.children( "." + this._inlineClass ); - inline.children().removeClass( "ui-state-disabled" ); - inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ). - prop( "disabled", false ); + _getRelativeOffset: function() { + if ( this.cssPosition !== "relative" ) { + return { top: 0, left: 0 }; } - this._disabledInputs = $.map( this._disabledInputs, - // Delete entry - function( value ) { - return ( value === target ? null : value ); - } ); - }, + var p = this.element.position(), + scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ); - /* Disable the date picker to a jQuery selection. - * @param target element - the target input field or division or span - */ - _disableDatepicker: function( target ) { - var nodeName, inline, - $target = $( target ), - inst = $.data( target, "datepicker" ); - - if ( !$target.hasClass( this.markerClassName ) ) { - return; - } - - nodeName = target.nodeName.toLowerCase(); - if ( nodeName === "input" ) { - target.disabled = true; - inst.trigger.filter( "button" ). - each( function() { - this.disabled = true; - } ).end(). - filter( "img" ).css( { opacity: "0.5", cursor: "default" } ); - } else if ( nodeName === "div" || nodeName === "span" ) { - inline = $target.children( "." + this._inlineClass ); - inline.children().addClass( "ui-state-disabled" ); - inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ). - prop( "disabled", true ); - } - this._disabledInputs = $.map( this._disabledInputs, + return { + top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) + + ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ), + left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) + + ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 ) + }; - // Delete entry - function( value ) { - return ( value === target ? null : value ); - } ); - this._disabledInputs[ this._disabledInputs.length ] = target; }, - /* Is the first field in a jQuery collection disabled as a datepicker? - * @param target element - the target input field or division or span - * @return boolean - true if disabled, false if enabled - */ - _isDisabledDatepicker: function( target ) { - if ( !target ) { - return false; - } - for ( var i = 0; i < this._disabledInputs.length; i++ ) { - if ( this._disabledInputs[ i ] === target ) { - return true; - } - } - return false; + _cacheMargins: function() { + this.margins = { + left: ( parseInt( this.element.css( "marginLeft" ), 10 ) || 0 ), + top: ( parseInt( this.element.css( "marginTop" ), 10 ) || 0 ), + right: ( parseInt( this.element.css( "marginRight" ), 10 ) || 0 ), + bottom: ( parseInt( this.element.css( "marginBottom" ), 10 ) || 0 ) + }; }, - /* Retrieve the instance data for the target control. - * @param target element - the target input field or division or span - * @return object - the associated instance data - * @throws error if a jQuery problem getting data - */ - _getInst: function( target ) { - try { - return $.data( target, "datepicker" ); - } catch ( err ) { - throw "Missing instance data for this datepicker"; - } + _cacheHelperProportions: function() { + this.helperProportions = { + width: this.helper.outerWidth(), + height: this.helper.outerHeight() + }; }, - /* Update or retrieve the settings for a date picker attached to an input field or division. - * @param target element - the target input field or division or span - * @param name object - the new settings to update or - * string - the name of the setting to change or retrieve, - * when retrieving also "all" for all instance settings or - * "defaults" for all global defaults - * @param value any - the new value for the setting - * (omit if above is an object or to retrieve a value) - */ - _optionDatepicker: function( target, name, value ) { - var settings, date, minDate, maxDate, - inst = this._getInst( target ); + _setContainment: function() { - if ( arguments.length === 2 && typeof name === "string" ) { - return ( name === "defaults" ? $.extend( {}, $.datepicker._defaults ) : - ( inst ? ( name === "all" ? $.extend( {}, inst.settings ) : - this._get( inst, name ) ) : null ) ); + var isUserScrollable, c, ce, + o = this.options, + document = this.document[ 0 ]; + + this.relativeContainer = null; + + if ( !o.containment ) { + this.containment = null; + return; } - settings = name || {}; - if ( typeof name === "string" ) { - settings = {}; - settings[ name ] = value; + if ( o.containment === "window" ) { + this.containment = [ + $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left, + $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top, + $( window ).scrollLeft() + $( window ).width() - + this.helperProportions.width - this.margins.left, + $( window ).scrollTop() + + ( $( window ).height() || document.body.parentNode.scrollHeight ) - + this.helperProportions.height - this.margins.top + ]; + return; } - if ( inst ) { - if ( this._curInst === inst ) { - this._hideDatepicker(); - } + if ( o.containment === "document" ) { + this.containment = [ + 0, + 0, + $( document ).width() - this.helperProportions.width - this.margins.left, + ( $( document ).height() || document.body.parentNode.scrollHeight ) - + this.helperProportions.height - this.margins.top + ]; + return; + } - date = this._getDateDatepicker( target, true ); - minDate = this._getMinMaxDate( inst, "min" ); - maxDate = this._getMinMaxDate( inst, "max" ); - datepicker_extendRemove( inst.settings, settings ); + if ( o.containment.constructor === Array ) { + this.containment = o.containment; + return; + } - // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided - if ( minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined ) { - inst.settings.minDate = this._formatDate( inst, minDate ); - } - if ( maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined ) { - inst.settings.maxDate = this._formatDate( inst, maxDate ); - } - if ( "disabled" in settings ) { - if ( settings.disabled ) { - this._disableDatepicker( target ); - } else { - this._enableDatepicker( target ); - } - } - this._attachments( $( target ), inst ); - this._autoSize( inst ); - this._setDate( inst, date ); - this._updateAlternate( inst ); - this._updateDatepicker( inst ); + if ( o.containment === "parent" ) { + o.containment = this.helper[ 0 ].parentNode; } - }, - // Change method deprecated - _changeDatepicker: function( target, name, value ) { - this._optionDatepicker( target, name, value ); - }, + c = $( o.containment ); + ce = c[ 0 ]; - /* Redraw the date picker attached to an input field or division. - * @param target element - the target input field or division or span - */ - _refreshDatepicker: function( target ) { - var inst = this._getInst( target ); - if ( inst ) { - this._updateDatepicker( inst ); + if ( !ce ) { + return; } - }, - /* Set the dates for a jQuery selection. - * @param target element - the target input field or division or span - * @param date Date - the new date - */ - _setDateDatepicker: function( target, date ) { - var inst = this._getInst( target ); - if ( inst ) { - this._setDate( inst, date ); - this._updateDatepicker( inst ); - this._updateAlternate( inst ); - } + isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) ); + + this.containment = [ + ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ), + ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ), + ( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - + ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) - + ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) - + this.helperProportions.width - + this.margins.left - + this.margins.right, + ( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - + ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) - + ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) - + this.helperProportions.height - + this.margins.top - + this.margins.bottom + ]; + this.relativeContainer = c; }, - /* Get the date(s) for the first entry in a jQuery selection. - * @param target element - the target input field or division or span - * @param noDefault boolean - true if no default date is to be used - * @return Date - the current date - */ - _getDateDatepicker: function( target, noDefault ) { - var inst = this._getInst( target ); - if ( inst && !inst.inline ) { - this._setDateFromField( inst, noDefault ); + _convertPositionTo: function( d, pos ) { + + if ( !pos ) { + pos = this.position; } - return ( inst ? this._getDate( inst ) : null ); - }, - /* Handle keystrokes. */ - _doKeyDown: function( event ) { - var onSelect, dateStr, sel, - inst = $.datepicker._getInst( event.target ), - handled = true, - isRTL = inst.dpDiv.is( ".ui-datepicker-rtl" ); + var mod = d === "absolute" ? 1 : -1, + scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ); - inst._keyEvent = true; - if ( $.datepicker._datepickerShowing ) { - switch ( event.keyCode ) { - case 9: $.datepicker._hideDatepicker(); - handled = false; - break; // hide on tab out - case 13: sel = $( "td." + $.datepicker._dayOverClass + ":not(." + - $.datepicker._currentClass + ")", inst.dpDiv ); - if ( sel[ 0 ] ) { - $.datepicker._selectDay( event.target, inst.selectedMonth, inst.selectedYear, sel[ 0 ] ); - } + return { + top: ( - onSelect = $.datepicker._get( inst, "onSelect" ); - if ( onSelect ) { - dateStr = $.datepicker._formatDate( inst ); + // The absolute mouse position + pos.top + - // Trigger custom callback - onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] ); - } else { - $.datepicker._hideDatepicker(); - } + // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.relative.top * mod + - return false; // don't submit the form - case 27: $.datepicker._hideDatepicker(); - break; // hide on escape - case 33: $.datepicker._adjustDate( event.target, ( event.ctrlKey ? - -$.datepicker._get( inst, "stepBigMonths" ) : - -$.datepicker._get( inst, "stepMonths" ) ), "M" ); - break; // previous month/year on page up/+ ctrl - case 34: $.datepicker._adjustDate( event.target, ( event.ctrlKey ? - +$.datepicker._get( inst, "stepBigMonths" ) : - +$.datepicker._get( inst, "stepMonths" ) ), "M" ); - break; // next month/year on page down/+ ctrl - case 35: if ( event.ctrlKey || event.metaKey ) { - $.datepicker._clearDate( event.target ); - } - handled = event.ctrlKey || event.metaKey; - break; // clear on ctrl or command +end - case 36: if ( event.ctrlKey || event.metaKey ) { - $.datepicker._gotoToday( event.target ); - } - handled = event.ctrlKey || event.metaKey; - break; // current on ctrl or command +home - case 37: if ( event.ctrlKey || event.metaKey ) { - $.datepicker._adjustDate( event.target, ( isRTL ? +1 : -1 ), "D" ); - } - handled = event.ctrlKey || event.metaKey; - - // -1 day on ctrl or command +left - if ( event.originalEvent.altKey ) { - $.datepicker._adjustDate( event.target, ( event.ctrlKey ? - -$.datepicker._get( inst, "stepBigMonths" ) : - -$.datepicker._get( inst, "stepMonths" ) ), "M" ); - } + // The offsetParent's offset without borders (offset + border) + this.offset.parent.top * mod - + ( ( this.cssPosition === "fixed" ? + -this.offset.scroll.top : + ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod ) + ), + left: ( - // next month/year on alt +left on Mac - break; - case 38: if ( event.ctrlKey || event.metaKey ) { - $.datepicker._adjustDate( event.target, -7, "D" ); - } - handled = event.ctrlKey || event.metaKey; - break; // -1 week on ctrl or command +up - case 39: if ( event.ctrlKey || event.metaKey ) { - $.datepicker._adjustDate( event.target, ( isRTL ? -1 : +1 ), "D" ); - } - handled = event.ctrlKey || event.metaKey; + // The absolute mouse position + pos.left + - // +1 day on ctrl or command +right - if ( event.originalEvent.altKey ) { - $.datepicker._adjustDate( event.target, ( event.ctrlKey ? - +$.datepicker._get( inst, "stepBigMonths" ) : - +$.datepicker._get( inst, "stepMonths" ) ), "M" ); - } + // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.relative.left * mod + - // next month/year on alt +right - break; - case 40: if ( event.ctrlKey || event.metaKey ) { - $.datepicker._adjustDate( event.target, +7, "D" ); - } - handled = event.ctrlKey || event.metaKey; - break; // +1 week on ctrl or command +down - default: handled = false; - } - } else if ( event.keyCode === 36 && event.ctrlKey ) { // display the date picker on ctrl+home - $.datepicker._showDatepicker( this ); - } else { - handled = false; - } + // The offsetParent's offset without borders (offset + border) + this.offset.parent.left * mod - + ( ( this.cssPosition === "fixed" ? + -this.offset.scroll.left : + ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod ) + ) + }; - if ( handled ) { - event.preventDefault(); - event.stopPropagation(); - } }, - /* Filter entered characters - based on date format. */ - _doKeyPress: function( event ) { - var chars, chr, - inst = $.datepicker._getInst( event.target ); + _generatePosition: function( event, constrainPosition ) { - if ( $.datepicker._get( inst, "constrainInput" ) ) { - chars = $.datepicker._possibleChars( $.datepicker._get( inst, "dateFormat" ) ); - chr = String.fromCharCode( event.charCode == null ? event.keyCode : event.charCode ); - return event.ctrlKey || event.metaKey || ( chr < " " || !chars || chars.indexOf( chr ) > -1 ); + var containment, co, top, left, + o = this.options, + scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ), + pageX = event.pageX, + pageY = event.pageY; + + // Cache the scroll + if ( !scrollIsRootNode || !this.offset.scroll ) { + this.offset.scroll = { + top: this.scrollParent.scrollTop(), + left: this.scrollParent.scrollLeft() + }; } - }, - /* Synchronise manual entry and field/alternate field. */ - _doKeyUp: function( event ) { - var date, - inst = $.datepicker._getInst( event.target ); + /* + * - Position constraining - + * Constrain the position to a mix of grid, containment. + */ - if ( inst.input.val() !== inst.lastVal ) { - try { - date = $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ), - ( inst.input ? inst.input.val() : null ), - $.datepicker._getFormatConfig( inst ) ); + // If we are not dragging yet, we won't check for options + if ( constrainPosition ) { + if ( this.containment ) { + if ( this.relativeContainer ) { + co = this.relativeContainer.offset(); + containment = [ + this.containment[ 0 ] + co.left, + this.containment[ 1 ] + co.top, + this.containment[ 2 ] + co.left, + this.containment[ 3 ] + co.top + ]; + } else { + containment = this.containment; + } - if ( date ) { // only if valid - $.datepicker._setDateFromField( inst ); - $.datepicker._updateAlternate( inst ); - $.datepicker._updateDatepicker( inst ); + if ( event.pageX - this.offset.click.left < containment[ 0 ] ) { + pageX = containment[ 0 ] + this.offset.click.left; + } + if ( event.pageY - this.offset.click.top < containment[ 1 ] ) { + pageY = containment[ 1 ] + this.offset.click.top; + } + if ( event.pageX - this.offset.click.left > containment[ 2 ] ) { + pageX = containment[ 2 ] + this.offset.click.left; + } + if ( event.pageY - this.offset.click.top > containment[ 3 ] ) { + pageY = containment[ 3 ] + this.offset.click.top; } - } catch ( err ) { } - } - return true; - }, - /* Pop-up the date picker for a given input field. - * If false returned from beforeShow event handler do not show. - * @param input element - the input field attached to the date picker or - * event - if triggered by focus - */ - _showDatepicker: function( input ) { - input = input.target || input; - if ( input.nodeName.toLowerCase() !== "input" ) { // find from button/image trigger - input = $( "input", input.parentNode )[ 0 ]; - } + if ( o.grid ) { - if ( $.datepicker._isDisabledDatepicker( input ) || $.datepicker._lastInput === input ) { // already here - return; - } + //Check for grid elements set to 0 to prevent divide by 0 error causing invalid + // argument errors in IE (see ticket #6950) + top = o.grid[ 1 ] ? this.originalPageY + Math.round( ( pageY - + this.originalPageY ) / o.grid[ 1 ] ) * o.grid[ 1 ] : this.originalPageY; + pageY = containment ? ( ( top - this.offset.click.top >= containment[ 1 ] || + top - this.offset.click.top > containment[ 3 ] ) ? + top : + ( ( top - this.offset.click.top >= containment[ 1 ] ) ? + top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : top; - var inst, beforeShow, beforeShowSettings, isFixed, - offset, showAnim, duration; + left = o.grid[ 0 ] ? this.originalPageX + + Math.round( ( pageX - this.originalPageX ) / o.grid[ 0 ] ) * o.grid[ 0 ] : + this.originalPageX; + pageX = containment ? ( ( left - this.offset.click.left >= containment[ 0 ] || + left - this.offset.click.left > containment[ 2 ] ) ? + left : + ( ( left - this.offset.click.left >= containment[ 0 ] ) ? + left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : left; + } - inst = $.datepicker._getInst( input ); - if ( $.datepicker._curInst && $.datepicker._curInst !== inst ) { - $.datepicker._curInst.dpDiv.stop( true, true ); - if ( inst && $.datepicker._datepickerShowing ) { - $.datepicker._hideDatepicker( $.datepicker._curInst.input[ 0 ] ); + if ( o.axis === "y" ) { + pageX = this.originalPageX; } - } - beforeShow = $.datepicker._get( inst, "beforeShow" ); - beforeShowSettings = beforeShow ? beforeShow.apply( input, [ input, inst ] ) : {}; - if ( beforeShowSettings === false ) { - return; + if ( o.axis === "x" ) { + pageY = this.originalPageY; + } } - datepicker_extendRemove( inst.settings, beforeShowSettings ); - - inst.lastVal = null; - $.datepicker._lastInput = input; - $.datepicker._setDateFromField( inst ); - if ( $.datepicker._inDialog ) { // hide cursor - input.value = ""; - } - if ( !$.datepicker._pos ) { // position below input - $.datepicker._pos = $.datepicker._findPos( input ); - $.datepicker._pos[ 1 ] += input.offsetHeight; // add the height - } + return { + top: ( - isFixed = false; - $( input ).parents().each( function() { - isFixed |= $( this ).css( "position" ) === "fixed"; - return !isFixed; - } ); + // The absolute mouse position + pageY - - offset = { left: $.datepicker._pos[ 0 ], top: $.datepicker._pos[ 1 ] }; - $.datepicker._pos = null; + // Click offset (relative to the element) + this.offset.click.top - - //to avoid flashes on Firefox - inst.dpDiv.empty(); + // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.relative.top - - // determine sizing offscreen - inst.dpDiv.css( { position: "absolute", display: "block", top: "-1000px" } ); - $.datepicker._updateDatepicker( inst ); + // The offsetParent's offset without borders (offset + border) + this.offset.parent.top + + ( this.cssPosition === "fixed" ? + -this.offset.scroll.top : + ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) + ), + left: ( - // fix width for dynamic number of date pickers - // and adjust position before showing - offset = $.datepicker._checkOffset( inst, offset, isFixed ); - inst.dpDiv.css( { position: ( $.datepicker._inDialog && $.blockUI ? - "static" : ( isFixed ? "fixed" : "absolute" ) ), display: "none", - left: offset.left + "px", top: offset.top + "px" } ); + // The absolute mouse position + pageX - - if ( !inst.inline ) { - showAnim = $.datepicker._get( inst, "showAnim" ); - duration = $.datepicker._get( inst, "duration" ); - inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 ); - $.datepicker._datepickerShowing = true; + // Click offset (relative to the element) + this.offset.click.left - - if ( $.effects && $.effects.effect[ showAnim ] ) { - inst.dpDiv.show( showAnim, $.datepicker._get( inst, "showOptions" ), duration ); - } else { - inst.dpDiv[ showAnim || "show" ]( showAnim ? duration : null ); - } + // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.relative.left - - if ( $.datepicker._shouldFocusInput( inst ) ) { - inst.input.trigger( "focus" ); - } + // The offsetParent's offset without borders (offset + border) + this.offset.parent.left + + ( this.cssPosition === "fixed" ? + -this.offset.scroll.left : + ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) + ) + }; - $.datepicker._curInst = inst; - } }, - /* Generate the date picker content. */ - _updateDatepicker: function( inst ) { - this.maxRows = 4; //Reset the max number of rows being displayed (see #7043) - datepicker_instActive = inst; // for delegate hover events - inst.dpDiv.empty().append( this._generateHTML( inst ) ); - this._attachHandlers( inst ); - - var origyearshtml, - numMonths = this._getNumberOfMonths( inst ), - cols = numMonths[ 1 ], - width = 17, - activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" ), - onUpdateDatepicker = $.datepicker._get( inst, "onUpdateDatepicker" ); - - if ( activeCell.length > 0 ) { - datepicker_handleMouseover.apply( activeCell.get( 0 ) ); - } - - inst.dpDiv.removeClass( "ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4" ).width( "" ); - if ( cols > 1 ) { - inst.dpDiv.addClass( "ui-datepicker-multi-" + cols ).css( "width", ( width * cols ) + "em" ); + _clear: function() { + this._removeClass( this.helper, "ui-draggable-dragging" ); + if ( this.helper[ 0 ] !== this.element[ 0 ] && !this.cancelHelperRemoval ) { + this.helper.remove(); } - inst.dpDiv[ ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ? "add" : "remove" ) + - "Class" ]( "ui-datepicker-multi" ); - inst.dpDiv[ ( this._get( inst, "isRTL" ) ? "add" : "remove" ) + - "Class" ]( "ui-datepicker-rtl" ); - - if ( inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) { - inst.input.trigger( "focus" ); + this.helper = null; + this.cancelHelperRemoval = false; + if ( this.destroyOnClear ) { + this.destroy(); } + }, - // Deffered render of the years select (to avoid flashes on Firefox) - if ( inst.yearshtml ) { - origyearshtml = inst.yearshtml; - setTimeout( function() { + // From now on bulk stuff - mainly helpers - //assure that inst.yearshtml didn't change. - if ( origyearshtml === inst.yearshtml && inst.yearshtml ) { - inst.dpDiv.find( "select.ui-datepicker-year" ).first().replaceWith( inst.yearshtml ); - } - origyearshtml = inst.yearshtml = null; - }, 0 ); - } + _trigger: function( type, event, ui ) { + ui = ui || this._uiHash(); + $.ui.plugin.call( this, type, [ event, ui, this ], true ); - if ( onUpdateDatepicker ) { - onUpdateDatepicker.apply( ( inst.input ? inst.input[ 0 ] : null ), [ inst ] ); + // Absolute position and offset (see #6884 ) have to be recalculated after plugins + if ( /^(drag|start|stop)/.test( type ) ) { + this.positionAbs = this._convertPositionTo( "absolute" ); + ui.offset = this.positionAbs; } + return $.Widget.prototype._trigger.call( this, type, event, ui ); }, - // #6694 - don't focus the input if it's already focused - // this breaks the change event in IE - // Support: IE and jQuery <1.9 - _shouldFocusInput: function( inst ) { - return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" ); - }, + plugins: {}, - /* Check positioning to remain on screen. */ - _checkOffset: function( inst, offset, isFixed ) { - var dpWidth = inst.dpDiv.outerWidth(), - dpHeight = inst.dpDiv.outerHeight(), - inputWidth = inst.input ? inst.input.outerWidth() : 0, - inputHeight = inst.input ? inst.input.outerHeight() : 0, - viewWidth = document.documentElement.clientWidth + ( isFixed ? 0 : $( document ).scrollLeft() ), - viewHeight = document.documentElement.clientHeight + ( isFixed ? 0 : $( document ).scrollTop() ); + _uiHash: function() { + return { + helper: this.helper, + position: this.position, + originalPosition: this.originalPosition, + offset: this.positionAbs + }; + } - offset.left -= ( this._get( inst, "isRTL" ) ? ( dpWidth - inputWidth ) : 0 ); - offset.left -= ( isFixed && offset.left === inst.input.offset().left ) ? $( document ).scrollLeft() : 0; - offset.top -= ( isFixed && offset.top === ( inst.input.offset().top + inputHeight ) ) ? $( document ).scrollTop() : 0; +} ); - // Now check if datepicker is showing outside window viewport - move to a better place if so. - offset.left -= Math.min( offset.left, ( offset.left + dpWidth > viewWidth && viewWidth > dpWidth ) ? - Math.abs( offset.left + dpWidth - viewWidth ) : 0 ); - offset.top -= Math.min( offset.top, ( offset.top + dpHeight > viewHeight && viewHeight > dpHeight ) ? - Math.abs( dpHeight + inputHeight ) : 0 ); +$.ui.plugin.add( "draggable", "connectToSortable", { + start: function( event, ui, draggable ) { + var uiSortable = $.extend( {}, ui, { + item: draggable.element + } ); - return offset; + draggable.sortables = []; + $( draggable.options.connectToSortable ).each( function() { + var sortable = $( this ).sortable( "instance" ); + + if ( sortable && !sortable.options.disabled ) { + draggable.sortables.push( sortable ); + + // RefreshPositions is called at drag start to refresh the containerCache + // which is used in drag. This ensures it's initialized and synchronized + // with any changes that might have happened on the page since initialization. + sortable.refreshPositions(); + sortable._trigger( "activate", event, uiSortable ); + } + } ); }, + stop: function( event, ui, draggable ) { + var uiSortable = $.extend( {}, ui, { + item: draggable.element + } ); - /* Find an object's position on the screen. */ - _findPos: function( obj ) { - var position, - inst = this._getInst( obj ), - isRTL = this._get( inst, "isRTL" ); + draggable.cancelHelperRemoval = false; - while ( obj && ( obj.type === "hidden" || obj.nodeType !== 1 || $.expr.pseudos.hidden( obj ) ) ) { - obj = obj[ isRTL ? "previousSibling" : "nextSibling" ]; - } + $.each( draggable.sortables, function() { + var sortable = this; - position = $( obj ).offset(); - return [ position.left, position.top ]; - }, + if ( sortable.isOver ) { + sortable.isOver = 0; - /* Hide the date picker from view. - * @param input element - the input field attached to the date picker - */ - _hideDatepicker: function( input ) { - var showAnim, duration, postProcess, onClose, - inst = this._curInst; + // Allow this sortable to handle removing the helper + draggable.cancelHelperRemoval = true; + sortable.cancelHelperRemoval = false; - if ( !inst || ( input && inst !== $.data( input, "datepicker" ) ) ) { - return; - } + // Use _storedCSS To restore properties in the sortable, + // as this also handles revert (#9675) since the draggable + // may have modified them in unexpected ways (#8809) + sortable._storedCSS = { + position: sortable.placeholder.css( "position" ), + top: sortable.placeholder.css( "top" ), + left: sortable.placeholder.css( "left" ) + }; - if ( this._datepickerShowing ) { - showAnim = this._get( inst, "showAnim" ); - duration = this._get( inst, "duration" ); - postProcess = function() { - $.datepicker._tidyDialog( inst ); - }; + sortable._mouseStop( event ); - // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed - if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) { - inst.dpDiv.hide( showAnim, $.datepicker._get( inst, "showOptions" ), duration, postProcess ); + // Once drag has ended, the sortable should return to using + // its original helper, not the shared helper from draggable + sortable.options.helper = sortable.options._helper; } else { - inst.dpDiv[ ( showAnim === "slideDown" ? "slideUp" : - ( showAnim === "fadeIn" ? "fadeOut" : "hide" ) ) ]( ( showAnim ? duration : null ), postProcess ); - } - - if ( !showAnim ) { - postProcess(); - } - this._datepickerShowing = false; - onClose = this._get( inst, "onClose" ); - if ( onClose ) { - onClose.apply( ( inst.input ? inst.input[ 0 ] : null ), [ ( inst.input ? inst.input.val() : "" ), inst ] ); - } + // Prevent this Sortable from removing the helper. + // However, don't set the draggable to remove the helper + // either as another connected Sortable may yet handle the removal. + sortable.cancelHelperRemoval = true; - this._lastInput = null; - if ( this._inDialog ) { - this._dialogInput.css( { position: "absolute", left: "0", top: "-100px" } ); - if ( $.blockUI ) { - $.unblockUI(); - $( "body" ).append( this.dpDiv ); - } + sortable._trigger( "deactivate", event, uiSortable ); } - this._inDialog = false; - } + } ); }, + drag: function( event, ui, draggable ) { + $.each( draggable.sortables, function() { + var innermostIntersecting = false, + sortable = this; - /* Tidy up after a dialog display. */ - _tidyDialog: function( inst ) { - inst.dpDiv.removeClass( this._dialogClass ).off( ".ui-datepicker-calendar" ); - }, + // Copy over variables that sortable's _intersectsWith uses + sortable.positionAbs = draggable.positionAbs; + sortable.helperProportions = draggable.helperProportions; + sortable.offset.click = draggable.offset.click; - /* Close date picker if clicked elsewhere. */ - _checkExternalClick: function( event ) { - if ( !$.datepicker._curInst ) { - return; - } + if ( sortable._intersectsWith( sortable.containerCache ) ) { + innermostIntersecting = true; - var $target = $( event.target ), - inst = $.datepicker._getInst( $target[ 0 ] ); + $.each( draggable.sortables, function() { - if ( ( ( $target[ 0 ].id !== $.datepicker._mainDivId && - $target.parents( "#" + $.datepicker._mainDivId ).length === 0 && - !$target.hasClass( $.datepicker.markerClassName ) && - !$target.closest( "." + $.datepicker._triggerClass ).length && - $.datepicker._datepickerShowing && !( $.datepicker._inDialog && $.blockUI ) ) ) || - ( $target.hasClass( $.datepicker.markerClassName ) && $.datepicker._curInst !== inst ) ) { - $.datepicker._hideDatepicker(); - } - }, + // Copy over variables that sortable's _intersectsWith uses + this.positionAbs = draggable.positionAbs; + this.helperProportions = draggable.helperProportions; + this.offset.click = draggable.offset.click; - /* Adjust one of the date sub-fields. */ - _adjustDate: function( id, offset, period ) { - var target = $( id ), - inst = this._getInst( target[ 0 ] ); + if ( this !== sortable && + this._intersectsWith( this.containerCache ) && + $.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) { + innermostIntersecting = false; + } - if ( this._isDisabledDatepicker( target[ 0 ] ) ) { - return; - } - this._adjustInstDate( inst, offset, period ); - this._updateDatepicker( inst ); - }, + return innermostIntersecting; + } ); + } - /* Action for current link. */ - _gotoToday: function( id ) { - var date, - target = $( id ), - inst = this._getInst( target[ 0 ] ); + if ( innermostIntersecting ) { - if ( this._get( inst, "gotoCurrent" ) && inst.currentDay ) { - inst.selectedDay = inst.currentDay; - inst.drawMonth = inst.selectedMonth = inst.currentMonth; - inst.drawYear = inst.selectedYear = inst.currentYear; - } else { - date = new Date(); - inst.selectedDay = date.getDate(); - inst.drawMonth = inst.selectedMonth = date.getMonth(); - inst.drawYear = inst.selectedYear = date.getFullYear(); - } - this._notifyChange( inst ); - this._adjustDate( target ); - }, + // If it intersects, we use a little isOver variable and set it once, + // so that the move-in stuff gets fired only once. + if ( !sortable.isOver ) { + sortable.isOver = 1; - /* Action for selecting a new month/year. */ - _selectMonthYear: function( id, select, period ) { - var target = $( id ), - inst = this._getInst( target[ 0 ] ); + // Store draggable's parent in case we need to reappend to it later. + draggable._parent = ui.helper.parent(); - inst[ "selected" + ( period === "M" ? "Month" : "Year" ) ] = - inst[ "draw" + ( period === "M" ? "Month" : "Year" ) ] = - parseInt( select.options[ select.selectedIndex ].value, 10 ); + sortable.currentItem = ui.helper + .appendTo( sortable.element ) + .data( "ui-sortable-item", true ); - this._notifyChange( inst ); - this._adjustDate( target ); - }, + // Store helper option to later restore it + sortable.options._helper = sortable.options.helper; - /* Action for selecting a day. */ - _selectDay: function( id, month, year, td ) { - var inst, - target = $( id ); + sortable.options.helper = function() { + return ui.helper[ 0 ]; + }; - if ( $( td ).hasClass( this._unselectableClass ) || this._isDisabledDatepicker( target[ 0 ] ) ) { - return; - } + // Fire the start events of the sortable with our passed browser event, + // and our own helper (so it doesn't create a new one) + event.target = sortable.currentItem[ 0 ]; + sortable._mouseCapture( event, true ); + sortable._mouseStart( event, true, true ); - inst = this._getInst( target[ 0 ] ); - inst.selectedDay = inst.currentDay = parseInt( $( "a", td ).attr( "data-date" ) ); - inst.selectedMonth = inst.currentMonth = month; - inst.selectedYear = inst.currentYear = year; - this._selectDate( id, this._formatDate( inst, - inst.currentDay, inst.currentMonth, inst.currentYear ) ); - }, + // Because the browser event is way off the new appended portlet, + // modify necessary variables to reflect the changes + sortable.offset.click.top = draggable.offset.click.top; + sortable.offset.click.left = draggable.offset.click.left; + sortable.offset.parent.left -= draggable.offset.parent.left - + sortable.offset.parent.left; + sortable.offset.parent.top -= draggable.offset.parent.top - + sortable.offset.parent.top; - /* Erase the input field and hide the date picker. */ - _clearDate: function( id ) { - var target = $( id ); - this._selectDate( target, "" ); - }, + draggable._trigger( "toSortable", event ); - /* Update the input field with the selected date. */ - _selectDate: function( id, dateStr ) { - var onSelect, - target = $( id ), - inst = this._getInst( target[ 0 ] ); + // Inform draggable that the helper is in a valid drop zone, + // used solely in the revert option to handle "valid/invalid". + draggable.dropped = sortable.element; - dateStr = ( dateStr != null ? dateStr : this._formatDate( inst ) ); - if ( inst.input ) { - inst.input.val( dateStr ); - } - this._updateAlternate( inst ); + // Need to refreshPositions of all sortables in the case that + // adding to one sortable changes the location of the other sortables (#9675) + $.each( draggable.sortables, function() { + this.refreshPositions(); + } ); - onSelect = this._get( inst, "onSelect" ); - if ( onSelect ) { - onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] ); // trigger custom callback - } else if ( inst.input ) { - inst.input.trigger( "change" ); // fire the change event - } + // Hack so receive/update callbacks work (mostly) + draggable.currentItem = draggable.element; + sortable.fromOutside = draggable; + } - if ( inst.inline ) { - this._updateDatepicker( inst ); - } else { - this._hideDatepicker(); - this._lastInput = inst.input[ 0 ]; - if ( typeof( inst.input[ 0 ] ) !== "object" ) { - inst.input.trigger( "focus" ); // restore focus - } - this._lastInput = null; - } - }, + if ( sortable.currentItem ) { + sortable._mouseDrag( event ); - /* Update any alternate field to synchronise with the main field. */ - _updateAlternate: function( inst ) { - var altFormat, date, dateStr, - altField = this._get( inst, "altField" ); + // Copy the sortable's position because the draggable's can potentially reflect + // a relative position, while sortable is always absolute, which the dragged + // element has now become. (#8809) + ui.position = sortable.position; + } + } else { - if ( altField ) { // update alternate field too - altFormat = this._get( inst, "altFormat" ) || this._get( inst, "dateFormat" ); - date = this._getDate( inst ); - dateStr = this.formatDate( altFormat, date, this._getFormatConfig( inst ) ); - $( document ).find( altField ).val( dateStr ); - } - }, + // If it doesn't intersect with the sortable, and it intersected before, + // we fake the drag stop of the sortable, but make sure it doesn't remove + // the helper by using cancelHelperRemoval. + if ( sortable.isOver ) { - /* Set as beforeShowDay function to prevent selection of weekends. - * @param date Date - the date to customise - * @return [boolean, string] - is this date selectable?, what is its CSS class? - */ - noWeekends: function( date ) { - var day = date.getDay(); - return [ ( day > 0 && day < 6 ), "" ]; - }, + sortable.isOver = 0; + sortable.cancelHelperRemoval = true; - /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. - * @param date Date - the date to get the week for - * @return number - the number of the week within the year that contains this date - */ - iso8601Week: function( date ) { - var time, - checkDate = new Date( date.getTime() ); + // Calling sortable's mouseStop would trigger a revert, + // so revert must be temporarily false until after mouseStop is called. + sortable.options._revert = sortable.options.revert; + sortable.options.revert = false; - // Find Thursday of this week starting on Monday - checkDate.setDate( checkDate.getDate() + 4 - ( checkDate.getDay() || 7 ) ); + sortable._trigger( "out", event, sortable._uiHash( sortable ) ); + sortable._mouseStop( event, true ); - time = checkDate.getTime(); - checkDate.setMonth( 0 ); // Compare with Jan 1 - checkDate.setDate( 1 ); - return Math.floor( Math.round( ( time - checkDate ) / 86400000 ) / 7 ) + 1; - }, + // Restore sortable behaviors that were modfied + // when the draggable entered the sortable area (#9481) + sortable.options.revert = sortable.options._revert; + sortable.options.helper = sortable.options._helper; - /* Parse a string value into a date object. - * See formatDate below for the possible formats. - * - * @param format string - the expected format of the date - * @param value string - the date in the above format - * @param settings Object - attributes include: - * shortYearCutoff number - the cutoff year for determining the century (optional) - * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) - * dayNames string[7] - names of the days from Sunday (optional) - * monthNamesShort string[12] - abbreviated names of the months (optional) - * monthNames string[12] - names of the months (optional) - * @return Date - the extracted date value or null if value is blank - */ - parseDate: function( format, value, settings ) { - if ( format == null || value == null ) { - throw "Invalid arguments"; - } + if ( sortable.placeholder ) { + sortable.placeholder.remove(); + } - value = ( typeof value === "object" ? value.toString() : value + "" ); - if ( value === "" ) { - return null; - } + // Restore and recalculate the draggable's offset considering the sortable + // may have modified them in unexpected ways. (#8809, #10669) + ui.helper.appendTo( draggable._parent ); + draggable._refreshOffsets( event ); + ui.position = draggable._generatePosition( event, true ); - var iFormat, dim, extra, - iValue = 0, - shortYearCutoffTemp = ( settings ? settings.shortYearCutoff : null ) || this._defaults.shortYearCutoff, - shortYearCutoff = ( typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp : - new Date().getFullYear() % 100 + parseInt( shortYearCutoffTemp, 10 ) ), - dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort, - dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames, - monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort, - monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames, - year = -1, - month = -1, - day = -1, - doy = -1, - literal = false, - date, + draggable._trigger( "fromSortable", event ); - // Check whether a format character is doubled - lookAhead = function( match ) { - var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match ); - if ( matches ) { - iFormat++; - } - return matches; - }, + // Inform draggable that the helper is no longer in a valid drop zone + draggable.dropped = false; - // Extract a number from the string value - getNumber = function( match ) { - var isDoubled = lookAhead( match ), - size = ( match === "@" ? 14 : ( match === "!" ? 20 : - ( match === "y" && isDoubled ? 4 : ( match === "o" ? 3 : 2 ) ) ) ), - minSize = ( match === "y" ? size : 1 ), - digits = new RegExp( "^\\d{" + minSize + "," + size + "}" ), - num = value.substring( iValue ).match( digits ); - if ( !num ) { - throw "Missing number at position " + iValue; + // Need to refreshPositions of all sortables just in case removing + // from one sortable changes the location of other sortables (#9675) + $.each( draggable.sortables, function() { + this.refreshPositions(); + } ); } - iValue += num[ 0 ].length; - return parseInt( num[ 0 ], 10 ); - }, + } + } ); + } +} ); - // Extract a name from the string value and convert to an index - getName = function( match, shortNames, longNames ) { - var index = -1, - names = $.map( lookAhead( match ) ? longNames : shortNames, function( v, k ) { - return [ [ k, v ] ]; - } ).sort( function( a, b ) { - return -( a[ 1 ].length - b[ 1 ].length ); - } ); - - $.each( names, function( i, pair ) { - var name = pair[ 1 ]; - if ( value.substr( iValue, name.length ).toLowerCase() === name.toLowerCase() ) { - index = pair[ 0 ]; - iValue += name.length; - return false; - } - } ); - if ( index !== -1 ) { - return index + 1; - } else { - throw "Unknown name at position " + iValue; - } - }, - - // Confirm that a literal character matches the string value - checkLiteral = function() { - if ( value.charAt( iValue ) !== format.charAt( iFormat ) ) { - throw "Unexpected literal at position " + iValue; - } - iValue++; - }; +$.ui.plugin.add( "draggable", "cursor", { + start: function( event, ui, instance ) { + var t = $( "body" ), + o = instance.options; - for ( iFormat = 0; iFormat < format.length; iFormat++ ) { - if ( literal ) { - if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) { - literal = false; - } else { - checkLiteral(); - } - } else { - switch ( format.charAt( iFormat ) ) { - case "d": - day = getNumber( "d" ); - break; - case "D": - getName( "D", dayNamesShort, dayNames ); - break; - case "o": - doy = getNumber( "o" ); - break; - case "m": - month = getNumber( "m" ); - break; - case "M": - month = getName( "M", monthNamesShort, monthNames ); - break; - case "y": - year = getNumber( "y" ); - break; - case "@": - date = new Date( getNumber( "@" ) ); - year = date.getFullYear(); - month = date.getMonth() + 1; - day = date.getDate(); - break; - case "!": - date = new Date( ( getNumber( "!" ) - this._ticksTo1970 ) / 10000 ); - year = date.getFullYear(); - month = date.getMonth() + 1; - day = date.getDate(); - break; - case "'": - if ( lookAhead( "'" ) ) { - checkLiteral(); - } else { - literal = true; - } - break; - default: - checkLiteral(); - } - } + if ( t.css( "cursor" ) ) { + o._cursor = t.css( "cursor" ); } - - if ( iValue < value.length ) { - extra = value.substr( iValue ); - if ( !/^\s+/.test( extra ) ) { - throw "Extra/unparsed characters found in date: " + extra; - } + t.css( "cursor", o.cursor ); + }, + stop: function( event, ui, instance ) { + var o = instance.options; + if ( o._cursor ) { + $( "body" ).css( "cursor", o._cursor ); } + } +} ); - if ( year === -1 ) { - year = new Date().getFullYear(); - } else if ( year < 100 ) { - year += new Date().getFullYear() - new Date().getFullYear() % 100 + - ( year <= shortYearCutoff ? 0 : -100 ); +$.ui.plugin.add( "draggable", "opacity", { + start: function( event, ui, instance ) { + var t = $( ui.helper ), + o = instance.options; + if ( t.css( "opacity" ) ) { + o._opacity = t.css( "opacity" ); } + t.css( "opacity", o.opacity ); + }, + stop: function( event, ui, instance ) { + var o = instance.options; + if ( o._opacity ) { + $( ui.helper ).css( "opacity", o._opacity ); + } + } +} ); - if ( doy > -1 ) { - month = 1; - day = doy; - do { - dim = this._getDaysInMonth( year, month - 1 ); - if ( day <= dim ) { - break; - } - month++; - day -= dim; - } while ( true ); +$.ui.plugin.add( "draggable", "scroll", { + start: function( event, ui, i ) { + if ( !i.scrollParentNotHidden ) { + i.scrollParentNotHidden = i.helper.scrollParent( false ); } - date = this._daylightSavingAdjust( new Date( year, month - 1, day ) ); - if ( date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day ) { - throw "Invalid date"; // E.g. 31/02/00 + if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && + i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) { + i.overflowOffset = i.scrollParentNotHidden.offset(); } - return date; }, + drag: function( event, ui, i ) { - /* Standard date formats. */ - ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601) - COOKIE: "D, dd M yy", - ISO_8601: "yy-mm-dd", - RFC_822: "D, d M y", - RFC_850: "DD, dd-M-y", - RFC_1036: "D, d M y", - RFC_1123: "D, d M yy", - RFC_2822: "D, d M yy", - RSS: "D, d M y", // RFC 822 - TICKS: "!", - TIMESTAMP: "@", - W3C: "yy-mm-dd", // ISO 8601 + var o = i.options, + scrolled = false, + scrollParent = i.scrollParentNotHidden[ 0 ], + document = i.document[ 0 ]; - _ticksTo1970: ( ( ( 1970 - 1 ) * 365 + Math.floor( 1970 / 4 ) - Math.floor( 1970 / 100 ) + - Math.floor( 1970 / 400 ) ) * 24 * 60 * 60 * 10000000 ), + if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) { + if ( !o.axis || o.axis !== "x" ) { + if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < + o.scrollSensitivity ) { + scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed; + } else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) { + scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed; + } + } - /* Format a date object into a string value. - * The format can be combinations of the following: - * d - day of month (no leading zero) - * dd - day of month (two digit) - * o - day of year (no leading zeros) - * oo - day of year (three digit) - * D - day name short - * DD - day name long - * m - month of year (no leading zero) - * mm - month of year (two digit) - * M - month name short - * MM - month name long - * y - year (two digit) - * yy - year (four digit) - * @ - Unix timestamp (ms since 01/01/1970) - * ! - Windows ticks (100ns since 01/01/0001) - * "..." - literal text - * '' - single quote - * - * @param format string - the desired format of the date - * @param date Date - the date value to format - * @param settings Object - attributes include: - * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) - * dayNames string[7] - names of the days from Sunday (optional) - * monthNamesShort string[12] - abbreviated names of the months (optional) - * monthNames string[12] - names of the months (optional) - * @return string - the date in the above format - */ - formatDate: function( format, date, settings ) { - if ( !date ) { - return ""; - } + if ( !o.axis || o.axis !== "y" ) { + if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < + o.scrollSensitivity ) { + scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed; + } else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) { + scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed; + } + } - var iFormat, - dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort, - dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames, - monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort, - monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames, + } else { - // Check whether a format character is doubled - lookAhead = function( match ) { - var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match ); - if ( matches ) { - iFormat++; + if ( !o.axis || o.axis !== "x" ) { + if ( event.pageY - $( document ).scrollTop() < o.scrollSensitivity ) { + scrolled = $( document ).scrollTop( $( document ).scrollTop() - o.scrollSpeed ); + } else if ( $( window ).height() - ( event.pageY - $( document ).scrollTop() ) < + o.scrollSensitivity ) { + scrolled = $( document ).scrollTop( $( document ).scrollTop() + o.scrollSpeed ); } - return matches; - }, + } - // Format a number, with leading zero if necessary - formatNumber = function( match, value, len ) { - var num = "" + value; - if ( lookAhead( match ) ) { - while ( num.length < len ) { - num = "0" + num; - } + if ( !o.axis || o.axis !== "y" ) { + if ( event.pageX - $( document ).scrollLeft() < o.scrollSensitivity ) { + scrolled = $( document ).scrollLeft( + $( document ).scrollLeft() - o.scrollSpeed + ); + } else if ( $( window ).width() - ( event.pageX - $( document ).scrollLeft() ) < + o.scrollSensitivity ) { + scrolled = $( document ).scrollLeft( + $( document ).scrollLeft() + o.scrollSpeed + ); } - return num; - }, + } - // Format a name, short or long as requested - formatName = function( match, value, shortNames, longNames ) { - return ( lookAhead( match ) ? longNames[ value ] : shortNames[ value ] ); - }, - output = "", - literal = false; - - if ( date ) { - for ( iFormat = 0; iFormat < format.length; iFormat++ ) { - if ( literal ) { - if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) { - literal = false; - } else { - output += format.charAt( iFormat ); - } - } else { - switch ( format.charAt( iFormat ) ) { - case "d": - output += formatNumber( "d", date.getDate(), 2 ); - break; - case "D": - output += formatName( "D", date.getDay(), dayNamesShort, dayNames ); - break; - case "o": - output += formatNumber( "o", - Math.round( ( new Date( date.getFullYear(), date.getMonth(), date.getDate() ).getTime() - new Date( date.getFullYear(), 0, 0 ).getTime() ) / 86400000 ), 3 ); - break; - case "m": - output += formatNumber( "m", date.getMonth() + 1, 2 ); - break; - case "M": - output += formatName( "M", date.getMonth(), monthNamesShort, monthNames ); - break; - case "y": - output += ( lookAhead( "y" ) ? date.getFullYear() : - ( date.getFullYear() % 100 < 10 ? "0" : "" ) + date.getFullYear() % 100 ); - break; - case "@": - output += date.getTime(); - break; - case "!": - output += date.getTime() * 10000 + this._ticksTo1970; - break; - case "'": - if ( lookAhead( "'" ) ) { - output += "'"; - } else { - literal = true; - } - break; - default: - output += format.charAt( iFormat ); - } - } - } } - return output; - }, - - /* Extract all possible characters from the date format. */ - _possibleChars: function( format ) { - var iFormat, - chars = "", - literal = false, - - // Check whether a format character is doubled - lookAhead = function( match ) { - var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match ); - if ( matches ) { - iFormat++; - } - return matches; - }; - for ( iFormat = 0; iFormat < format.length; iFormat++ ) { - if ( literal ) { - if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) { - literal = false; - } else { - chars += format.charAt( iFormat ); - } - } else { - switch ( format.charAt( iFormat ) ) { - case "d": case "m": case "y": case "@": - chars += "0123456789"; - break; - case "D": case "M": - return null; // Accept anything - case "'": - if ( lookAhead( "'" ) ) { - chars += "'"; - } else { - literal = true; - } - break; - default: - chars += format.charAt( iFormat ); - } - } + if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) { + $.ui.ddmanager.prepareOffsets( i, event ); } - return chars; - }, - /* Get a setting value, defaulting if necessary. */ - _get: function( inst, name ) { - return inst.settings[ name ] !== undefined ? - inst.settings[ name ] : this._defaults[ name ]; - }, + } +} ); - /* Parse existing date and initialise date picker. */ - _setDateFromField: function( inst, noDefault ) { - if ( inst.input.val() === inst.lastVal ) { - return; - } +$.ui.plugin.add( "draggable", "snap", { + start: function( event, ui, i ) { - var dateFormat = this._get( inst, "dateFormat" ), - dates = inst.lastVal = inst.input ? inst.input.val() : null, - defaultDate = this._getDefaultDate( inst ), - date = defaultDate, - settings = this._getFormatConfig( inst ); + var o = i.options; - try { - date = this.parseDate( dateFormat, dates, settings ) || defaultDate; - } catch ( event ) { - dates = ( noDefault ? "" : dates ); - } - inst.selectedDay = date.getDate(); - inst.drawMonth = inst.selectedMonth = date.getMonth(); - inst.drawYear = inst.selectedYear = date.getFullYear(); - inst.currentDay = ( dates ? date.getDate() : 0 ); - inst.currentMonth = ( dates ? date.getMonth() : 0 ); - inst.currentYear = ( dates ? date.getFullYear() : 0 ); - this._adjustInstDate( inst ); - }, + i.snapElements = []; + + $( o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap ) + .each( function() { + var $t = $( this ), + $o = $t.offset(); + if ( this !== i.element[ 0 ] ) { + i.snapElements.push( { + item: this, + width: $t.outerWidth(), height: $t.outerHeight(), + top: $o.top, left: $o.left + } ); + } + } ); - /* Retrieve the default date shown on opening. */ - _getDefaultDate: function( inst ) { - return this._restrictMinMax( inst, - this._determineDate( inst, this._get( inst, "defaultDate" ), new Date() ) ); }, + drag: function( event, ui, inst ) { - /* A date may be specified as an exact value or a relative one. */ - _determineDate: function( inst, date, defaultDate ) { - var offsetNumeric = function( offset ) { - var date = new Date(); - date.setDate( date.getDate() + offset ); - return date; - }, - offsetString = function( offset ) { - try { - return $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ), - offset, $.datepicker._getFormatConfig( inst ) ); - } catch ( e ) { + var ts, bs, ls, rs, l, r, t, b, i, first, + o = inst.options, + d = o.snapTolerance, + x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width, + y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height; - // Ignore - } + for ( i = inst.snapElements.length - 1; i >= 0; i-- ) { - var date = ( offset.toLowerCase().match( /^c/ ) ? - $.datepicker._getDate( inst ) : null ) || new Date(), - year = date.getFullYear(), - month = date.getMonth(), - day = date.getDate(), - pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g, - matches = pattern.exec( offset ); + l = inst.snapElements[ i ].left - inst.margins.left; + r = l + inst.snapElements[ i ].width; + t = inst.snapElements[ i ].top - inst.margins.top; + b = t + inst.snapElements[ i ].height; - while ( matches ) { - switch ( matches[ 2 ] || "d" ) { - case "d" : case "D" : - day += parseInt( matches[ 1 ], 10 ); break; - case "w" : case "W" : - day += parseInt( matches[ 1 ], 10 ) * 7; break; - case "m" : case "M" : - month += parseInt( matches[ 1 ], 10 ); - day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) ); - break; - case "y": case "Y" : - year += parseInt( matches[ 1 ], 10 ); - day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) ); - break; + if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || + !$.contains( inst.snapElements[ i ].item.ownerDocument, + inst.snapElements[ i ].item ) ) { + if ( inst.snapElements[ i ].snapping ) { + if ( inst.options.snap.release ) { + inst.options.snap.release.call( + inst.element, + event, + $.extend( inst._uiHash(), { snapItem: inst.snapElements[ i ].item } ) + ); } - matches = pattern.exec( offset ); } - return new Date( year, month, day ); - }, - newDate = ( date == null || date === "" ? defaultDate : ( typeof date === "string" ? offsetString( date ) : - ( typeof date === "number" ? ( isNaN( date ) ? defaultDate : offsetNumeric( date ) ) : new Date( date.getTime() ) ) ) ); + inst.snapElements[ i ].snapping = false; + continue; + } - newDate = ( newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate ); - if ( newDate ) { - newDate.setHours( 0 ); - newDate.setMinutes( 0 ); - newDate.setSeconds( 0 ); - newDate.setMilliseconds( 0 ); - } - return this._daylightSavingAdjust( newDate ); - }, + if ( o.snapMode !== "inner" ) { + ts = Math.abs( t - y2 ) <= d; + bs = Math.abs( b - y1 ) <= d; + ls = Math.abs( l - x2 ) <= d; + rs = Math.abs( r - x1 ) <= d; + if ( ts ) { + ui.position.top = inst._convertPositionTo( "relative", { + top: t - inst.helperProportions.height, + left: 0 + } ).top; + } + if ( bs ) { + ui.position.top = inst._convertPositionTo( "relative", { + top: b, + left: 0 + } ).top; + } + if ( ls ) { + ui.position.left = inst._convertPositionTo( "relative", { + top: 0, + left: l - inst.helperProportions.width + } ).left; + } + if ( rs ) { + ui.position.left = inst._convertPositionTo( "relative", { + top: 0, + left: r + } ).left; + } + } + + first = ( ts || bs || ls || rs ); + + if ( o.snapMode !== "outer" ) { + ts = Math.abs( t - y1 ) <= d; + bs = Math.abs( b - y2 ) <= d; + ls = Math.abs( l - x1 ) <= d; + rs = Math.abs( r - x2 ) <= d; + if ( ts ) { + ui.position.top = inst._convertPositionTo( "relative", { + top: t, + left: 0 + } ).top; + } + if ( bs ) { + ui.position.top = inst._convertPositionTo( "relative", { + top: b - inst.helperProportions.height, + left: 0 + } ).top; + } + if ( ls ) { + ui.position.left = inst._convertPositionTo( "relative", { + top: 0, + left: l + } ).left; + } + if ( rs ) { + ui.position.left = inst._convertPositionTo( "relative", { + top: 0, + left: r - inst.helperProportions.width + } ).left; + } + } + + if ( !inst.snapElements[ i ].snapping && ( ts || bs || ls || rs || first ) ) { + if ( inst.options.snap.snap ) { + inst.options.snap.snap.call( + inst.element, + event, + $.extend( inst._uiHash(), { + snapItem: inst.snapElements[ i ].item + } ) ); + } + } + inst.snapElements[ i ].snapping = ( ts || bs || ls || rs || first ); - /* Handle switch to/from daylight saving. - * Hours may be non-zero on daylight saving cut-over: - * > 12 when midnight changeover, but then cannot generate - * midnight datetime, so jump to 1AM, otherwise reset. - * @param date (Date) the date to check - * @return (Date) the corrected date - */ - _daylightSavingAdjust: function( date ) { - if ( !date ) { - return null; } - date.setHours( date.getHours() > 12 ? date.getHours() + 2 : 0 ); - return date; - }, - /* Set the date(s) directly. */ - _setDate: function( inst, date, noChange ) { - var clear = !date, - origMonth = inst.selectedMonth, - origYear = inst.selectedYear, - newDate = this._restrictMinMax( inst, this._determineDate( inst, date, new Date() ) ); + } +} ); - inst.selectedDay = inst.currentDay = newDate.getDate(); - inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth(); - inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear(); - if ( ( origMonth !== inst.selectedMonth || origYear !== inst.selectedYear ) && !noChange ) { - this._notifyChange( inst ); +$.ui.plugin.add( "draggable", "stack", { + start: function( event, ui, instance ) { + var min, + o = instance.options, + group = $.makeArray( $( o.stack ) ).sort( function( a, b ) { + return ( parseInt( $( a ).css( "zIndex" ), 10 ) || 0 ) - + ( parseInt( $( b ).css( "zIndex" ), 10 ) || 0 ); + } ); + + if ( !group.length ) { + return; } - this._adjustInstDate( inst ); - if ( inst.input ) { - inst.input.val( clear ? "" : this._formatDate( inst ) ); + + min = parseInt( $( group[ 0 ] ).css( "zIndex" ), 10 ) || 0; + $( group ).each( function( i ) { + $( this ).css( "zIndex", min + i ); + } ); + this.css( "zIndex", ( min + group.length ) ); + } +} ); + +$.ui.plugin.add( "draggable", "zIndex", { + start: function( event, ui, instance ) { + var t = $( ui.helper ), + o = instance.options; + + if ( t.css( "zIndex" ) ) { + o._zIndex = t.css( "zIndex" ); } + t.css( "zIndex", o.zIndex ); }, + stop: function( event, ui, instance ) { + var o = instance.options; - /* Retrieve the date(s) directly. */ - _getDate: function( inst ) { - var startDate = ( !inst.currentYear || ( inst.input && inst.input.val() === "" ) ? null : - this._daylightSavingAdjust( new Date( - inst.currentYear, inst.currentMonth, inst.currentDay ) ) ); - return startDate; + if ( o._zIndex ) { + $( ui.helper ).css( "zIndex", o._zIndex ); + } + } +} ); + +var widgetsDraggable = $.ui.draggable; + + +/*! + * jQuery UI Resizable 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: Resizable +//>>group: Interactions +//>>description: Enables resize functionality for any element. +//>>docs: http://api.jqueryui.com/resizable/ +//>>demos: http://jqueryui.com/resizable/ +//>>css.structure: ../../themes/base/core.css +//>>css.structure: ../../themes/base/resizable.css +//>>css.theme: ../../themes/base/theme.css + + +$.widget( "ui.resizable", $.ui.mouse, { + version: "1.13.2", + widgetEventPrefix: "resize", + options: { + alsoResize: false, + animate: false, + animateDuration: "slow", + animateEasing: "swing", + aspectRatio: false, + autoHide: false, + classes: { + "ui-resizable-se": "ui-icon ui-icon-gripsmall-diagonal-se" + }, + containment: false, + ghost: false, + grid: false, + handles: "e,s,se", + helper: false, + maxHeight: null, + maxWidth: null, + minHeight: 10, + minWidth: 10, + + // See #7960 + zIndex: 90, + + // Callbacks + resize: null, + start: null, + stop: null }, - /* Attach the onxxx handlers. These are declared statically so - * they work with static code transformers like Caja. - */ - _attachHandlers: function( inst ) { - var stepMonths = this._get( inst, "stepMonths" ), - id = "#" + inst.id.replace( /\\\\/g, "\\" ); - inst.dpDiv.find( "[data-handler]" ).map( function() { - var handler = { - prev: function() { - $.datepicker._adjustDate( id, -stepMonths, "M" ); - }, - next: function() { - $.datepicker._adjustDate( id, +stepMonths, "M" ); - }, - hide: function() { - $.datepicker._hideDatepicker(); - }, - today: function() { - $.datepicker._gotoToday( id ); - }, - selectDay: function() { - $.datepicker._selectDay( id, +this.getAttribute( "data-month" ), +this.getAttribute( "data-year" ), this ); - return false; - }, - selectMonth: function() { - $.datepicker._selectMonthYear( id, this, "M" ); - return false; - }, - selectYear: function() { - $.datepicker._selectMonthYear( id, this, "Y" ); - return false; - } - }; - $( this ).on( this.getAttribute( "data-event" ), handler[ this.getAttribute( "data-handler" ) ] ); - } ); + _num: function( value ) { + return parseFloat( value ) || 0; }, - /* Generate the HTML for the current state of the date picker. */ - _generateHTML: function( inst ) { - var maxDraw, prevText, prev, nextText, next, currentText, gotoDate, - controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin, - monthNames, monthNamesShort, beforeShowDay, showOtherMonths, - selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate, - cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows, - printDate, dRow, tbody, daySettings, otherMonth, unselectable, - tempDate = new Date(), - today = this._daylightSavingAdjust( - new Date( tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate() ) ), // clear time - isRTL = this._get( inst, "isRTL" ), - showButtonPanel = this._get( inst, "showButtonPanel" ), - hideIfNoPrevNext = this._get( inst, "hideIfNoPrevNext" ), - navigationAsDateFormat = this._get( inst, "navigationAsDateFormat" ), - numMonths = this._getNumberOfMonths( inst ), - showCurrentAtPos = this._get( inst, "showCurrentAtPos" ), - stepMonths = this._get( inst, "stepMonths" ), - isMultiMonth = ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ), - currentDate = this._daylightSavingAdjust( ( !inst.currentDay ? new Date( 9999, 9, 9 ) : - new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ), - minDate = this._getMinMaxDate( inst, "min" ), - maxDate = this._getMinMaxDate( inst, "max" ), - drawMonth = inst.drawMonth - showCurrentAtPos, - drawYear = inst.drawYear; + _isNumber: function( value ) { + return !isNaN( parseFloat( value ) ); + }, - if ( drawMonth < 0 ) { - drawMonth += 12; - drawYear--; - } - if ( maxDate ) { - maxDraw = this._daylightSavingAdjust( new Date( maxDate.getFullYear(), - maxDate.getMonth() - ( numMonths[ 0 ] * numMonths[ 1 ] ) + 1, maxDate.getDate() ) ); - maxDraw = ( minDate && maxDraw < minDate ? minDate : maxDraw ); - while ( this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 ) ) > maxDraw ) { - drawMonth--; - if ( drawMonth < 0 ) { - drawMonth = 11; - drawYear--; - } - } + _hasScroll: function( el, a ) { + + if ( $( el ).css( "overflow" ) === "hidden" ) { + return false; } - inst.drawMonth = drawMonth; - inst.drawYear = drawYear; - prevText = this._get( inst, "prevText" ); - prevText = ( !navigationAsDateFormat ? prevText : this.formatDate( prevText, - this._daylightSavingAdjust( new Date( drawYear, drawMonth - stepMonths, 1 ) ), - this._getFormatConfig( inst ) ) ); + var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop", + has = false; - if ( this._canAdjustMonth( inst, -1, drawYear, drawMonth ) ) { - prev = $( "<a>" ) - .attr( { - "class": "ui-datepicker-prev ui-corner-all", - "data-handler": "prev", - "data-event": "click", - title: prevText - } ) - .append( - $( "<span>" ) - .addClass( "ui-icon ui-icon-circle-triangle-" + - ( isRTL ? "e" : "w" ) ) - .text( prevText ) - )[ 0 ].outerHTML; - } else if ( hideIfNoPrevNext ) { - prev = ""; - } else { - prev = $( "<a>" ) - .attr( { - "class": "ui-datepicker-prev ui-corner-all ui-state-disabled", - title: prevText - } ) - .append( - $( "<span>" ) - .addClass( "ui-icon ui-icon-circle-triangle-" + - ( isRTL ? "e" : "w" ) ) - .text( prevText ) - )[ 0 ].outerHTML; + if ( el[ scroll ] > 0 ) { + return true; } - nextText = this._get( inst, "nextText" ); - nextText = ( !navigationAsDateFormat ? nextText : this.formatDate( nextText, - this._daylightSavingAdjust( new Date( drawYear, drawMonth + stepMonths, 1 ) ), - this._getFormatConfig( inst ) ) ); + // TODO: determine which cases actually cause this to happen + // if the element doesn't have the scroll set, see if it's possible to + // set the scroll + try { + el[ scroll ] = 1; + has = ( el[ scroll ] > 0 ); + el[ scroll ] = 0; + } catch ( e ) { - if ( this._canAdjustMonth( inst, +1, drawYear, drawMonth ) ) { - next = $( "<a>" ) - .attr( { - "class": "ui-datepicker-next ui-corner-all", - "data-handler": "next", - "data-event": "click", - title: nextText - } ) - .append( - $( "<span>" ) - .addClass( "ui-icon ui-icon-circle-triangle-" + - ( isRTL ? "w" : "e" ) ) - .text( nextText ) - )[ 0 ].outerHTML; - } else if ( hideIfNoPrevNext ) { - next = ""; - } else { - next = $( "<a>" ) - .attr( { - "class": "ui-datepicker-next ui-corner-all ui-state-disabled", - title: nextText + // `el` might be a string, then setting `scroll` will throw + // an error in strict mode; ignore it. + } + return has; + }, + + _create: function() { + + var margins, + o = this.options, + that = this; + this._addClass( "ui-resizable" ); + + $.extend( this, { + _aspectRatio: !!( o.aspectRatio ), + aspectRatio: o.aspectRatio, + originalElement: this.element, + _proportionallyResizeElements: [], + _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null + } ); + + // Wrap the element if it cannot hold child nodes + if ( this.element[ 0 ].nodeName.match( /^(canvas|textarea|input|select|button|img)$/i ) ) { + + this.element.wrap( + $( "<div class='ui-wrapper'></div>" ).css( { + overflow: "hidden", + position: this.element.css( "position" ), + width: this.element.outerWidth(), + height: this.element.outerHeight(), + top: this.element.css( "top" ), + left: this.element.css( "left" ) } ) - .append( - $( "<span>" ) - .attr( "class", "ui-icon ui-icon-circle-triangle-" + - ( isRTL ? "w" : "e" ) ) - .text( nextText ) - )[ 0 ].outerHTML; + ); + + this.element = this.element.parent().data( + "ui-resizable", this.element.resizable( "instance" ) + ); + + this.elementIsWrapper = true; + + margins = { + marginTop: this.originalElement.css( "marginTop" ), + marginRight: this.originalElement.css( "marginRight" ), + marginBottom: this.originalElement.css( "marginBottom" ), + marginLeft: this.originalElement.css( "marginLeft" ) + }; + + this.element.css( margins ); + this.originalElement.css( "margin", 0 ); + + // support: Safari + // Prevent Safari textarea resize + this.originalResizeStyle = this.originalElement.css( "resize" ); + this.originalElement.css( "resize", "none" ); + + this._proportionallyResizeElements.push( this.originalElement.css( { + position: "static", + zoom: 1, + display: "block" + } ) ); + + // Support: IE9 + // avoid IE jump (hard set the margin) + this.originalElement.css( margins ); + + this._proportionallyResize(); } - currentText = this._get( inst, "currentText" ); - gotoDate = ( this._get( inst, "gotoCurrent" ) && inst.currentDay ? currentDate : today ); - currentText = ( !navigationAsDateFormat ? currentText : - this.formatDate( currentText, gotoDate, this._getFormatConfig( inst ) ) ); + this._setupHandles(); - controls = ""; - if ( !inst.inline ) { - controls = $( "<button>" ) - .attr( { - type: "button", - "class": "ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all", - "data-handler": "hide", - "data-event": "click" + if ( o.autoHide ) { + $( this.element ) + .on( "mouseenter", function() { + if ( o.disabled ) { + return; + } + that._removeClass( "ui-resizable-autohide" ); + that._handles.show(); } ) - .text( this._get( inst, "closeText" ) )[ 0 ].outerHTML; + .on( "mouseleave", function() { + if ( o.disabled ) { + return; + } + if ( !that.resizing ) { + that._addClass( "ui-resizable-autohide" ); + that._handles.hide(); + } + } ); } - buttonPanel = ""; - if ( showButtonPanel ) { - buttonPanel = $( "<div class='ui-datepicker-buttonpane ui-widget-content'>" ) - .append( isRTL ? controls : "" ) - .append( this._isInRange( inst, gotoDate ) ? - $( "<button>" ) - .attr( { - type: "button", - "class": "ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all", - "data-handler": "today", - "data-event": "click" - } ) - .text( currentText ) : - "" ) - .append( isRTL ? "" : controls )[ 0 ].outerHTML; + this._mouseInit(); + }, + + _destroy: function() { + + this._mouseDestroy(); + this._addedHandles.remove(); + + var wrapper, + _destroy = function( exp ) { + $( exp ) + .removeData( "resizable" ) + .removeData( "ui-resizable" ) + .off( ".resizable" ); + }; + + // TODO: Unwrap at same DOM position + if ( this.elementIsWrapper ) { + _destroy( this.element ); + wrapper = this.element; + this.originalElement.css( { + position: wrapper.css( "position" ), + width: wrapper.outerWidth(), + height: wrapper.outerHeight(), + top: wrapper.css( "top" ), + left: wrapper.css( "left" ) + } ).insertAfter( wrapper ); + wrapper.remove(); } - firstDay = parseInt( this._get( inst, "firstDay" ), 10 ); - firstDay = ( isNaN( firstDay ) ? 0 : firstDay ); + this.originalElement.css( "resize", this.originalResizeStyle ); + _destroy( this.originalElement ); - showWeek = this._get( inst, "showWeek" ); - dayNames = this._get( inst, "dayNames" ); - dayNamesMin = this._get( inst, "dayNamesMin" ); - monthNames = this._get( inst, "monthNames" ); - monthNamesShort = this._get( inst, "monthNamesShort" ); - beforeShowDay = this._get( inst, "beforeShowDay" ); - showOtherMonths = this._get( inst, "showOtherMonths" ); - selectOtherMonths = this._get( inst, "selectOtherMonths" ); - defaultDate = this._getDefaultDate( inst ); - html = ""; + return this; + }, - for ( row = 0; row < numMonths[ 0 ]; row++ ) { - group = ""; - this.maxRows = 4; - for ( col = 0; col < numMonths[ 1 ]; col++ ) { - selectedDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, inst.selectedDay ) ); - cornerClass = " ui-corner-all"; - calender = ""; - if ( isMultiMonth ) { - calender += "<div class='ui-datepicker-group"; - if ( numMonths[ 1 ] > 1 ) { - switch ( col ) { - case 0: calender += " ui-datepicker-group-first"; - cornerClass = " ui-corner-" + ( isRTL ? "right" : "left" ); break; - case numMonths[ 1 ] - 1: calender += " ui-datepicker-group-last"; - cornerClass = " ui-corner-" + ( isRTL ? "left" : "right" ); break; - default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break; - } - } - calender += "'>"; - } - calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" + - ( /all|left/.test( cornerClass ) && row === 0 ? ( isRTL ? next : prev ) : "" ) + - ( /all|right/.test( cornerClass ) && row === 0 ? ( isRTL ? prev : next ) : "" ) + - this._generateMonthYearHeader( inst, drawMonth, drawYear, minDate, maxDate, - row > 0 || col > 0, monthNames, monthNamesShort ) + // draw month headers - "</div><table class='ui-datepicker-calendar'><thead>" + - "<tr>"; - thead = ( showWeek ? "<th class='ui-datepicker-week-col'>" + this._get( inst, "weekHeader" ) + "</th>" : "" ); - for ( dow = 0; dow < 7; dow++ ) { // days of the week - day = ( dow + firstDay ) % 7; - thead += "<th scope='col'" + ( ( dow + firstDay + 6 ) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "" ) + ">" + - "<span title='" + dayNames[ day ] + "'>" + dayNamesMin[ day ] + "</span></th>"; - } - calender += thead + "</tr></thead><tbody>"; - daysInMonth = this._getDaysInMonth( drawYear, drawMonth ); - if ( drawYear === inst.selectedYear && drawMonth === inst.selectedMonth ) { - inst.selectedDay = Math.min( inst.selectedDay, daysInMonth ); - } - leadDays = ( this._getFirstDayOfMonth( drawYear, drawMonth ) - firstDay + 7 ) % 7; - curRows = Math.ceil( ( leadDays + daysInMonth ) / 7 ); // calculate the number of rows to generate - numRows = ( isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows ); //If multiple months, use the higher number of rows (see #7043) - this.maxRows = numRows; - printDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 - leadDays ) ); - for ( dRow = 0; dRow < numRows; dRow++ ) { // create date picker rows - calender += "<tr>"; - tbody = ( !showWeek ? "" : "<td class='ui-datepicker-week-col'>" + - this._get( inst, "calculateWeek" )( printDate ) + "</td>" ); - for ( dow = 0; dow < 7; dow++ ) { // create date picker days - daySettings = ( beforeShowDay ? - beforeShowDay.apply( ( inst.input ? inst.input[ 0 ] : null ), [ printDate ] ) : [ true, "" ] ); - otherMonth = ( printDate.getMonth() !== drawMonth ); - unselectable = ( otherMonth && !selectOtherMonths ) || !daySettings[ 0 ] || - ( minDate && printDate < minDate ) || ( maxDate && printDate > maxDate ); - tbody += "<td class='" + - ( ( dow + firstDay + 6 ) % 7 >= 5 ? " ui-datepicker-week-end" : "" ) + // highlight weekends - ( otherMonth ? " ui-datepicker-other-month" : "" ) + // highlight days from other months - ( ( printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent ) || // user pressed key - ( defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime() ) ? + _setOption: function( key, value ) { + this._super( key, value ); - // or defaultDate is current printedDate and defaultDate is selectedDate - " " + this._dayOverClass : "" ) + // highlight selected day - ( unselectable ? " " + this._unselectableClass + " ui-state-disabled" : "" ) + // highlight unselectable days - ( otherMonth && !showOtherMonths ? "" : " " + daySettings[ 1 ] + // highlight custom dates - ( printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "" ) + // highlight selected day - ( printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "" ) ) + "'" + // highlight today (if different) - ( ( !otherMonth || showOtherMonths ) && daySettings[ 2 ] ? " title='" + daySettings[ 2 ].replace( /'/g, "'" ) + "'" : "" ) + // cell title - ( unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'" ) + ">" + // actions - ( otherMonth && !showOtherMonths ? " " : // display for other months - ( unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" + - ( printDate.getTime() === today.getTime() ? " ui-state-highlight" : "" ) + - ( printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "" ) + // highlight selected day - ( otherMonth ? " ui-priority-secondary" : "" ) + // distinguish dates from other months - "' href='#' aria-current='" + ( printDate.getTime() === currentDate.getTime() ? "true" : "false" ) + // mark date as selected for screen reader - "' data-date='" + printDate.getDate() + // store date as data - "'>" + printDate.getDate() + "</a>" ) ) + "</td>"; // display selectable date - printDate.setDate( printDate.getDate() + 1 ); - printDate = this._daylightSavingAdjust( printDate ); - } - calender += tbody + "</tr>"; - } - drawMonth++; - if ( drawMonth > 11 ) { - drawMonth = 0; - drawYear++; - } - calender += "</tbody></table>" + ( isMultiMonth ? "</div>" + - ( ( numMonths[ 0 ] > 0 && col === numMonths[ 1 ] - 1 ) ? "<div class='ui-datepicker-row-break'></div>" : "" ) : "" ); - group += calender; + switch ( key ) { + case "handles": + this._removeHandles(); + this._setupHandles(); + break; + case "aspectRatio": + this._aspectRatio = !!value; + break; + default: + break; + } + }, + + _setupHandles: function() { + var o = this.options, handle, i, n, hname, axis, that = this; + this.handles = o.handles || + ( !$( ".ui-resizable-handle", this.element ).length ? + "e,s,se" : { + n: ".ui-resizable-n", + e: ".ui-resizable-e", + s: ".ui-resizable-s", + w: ".ui-resizable-w", + se: ".ui-resizable-se", + sw: ".ui-resizable-sw", + ne: ".ui-resizable-ne", + nw: ".ui-resizable-nw" + } ); + + this._handles = $(); + this._addedHandles = $(); + if ( this.handles.constructor === String ) { + + if ( this.handles === "all" ) { + this.handles = "n,e,s,w,se,sw,ne,nw"; } - html += group; - } - html += buttonPanel; - inst._keyEvent = false; - return html; - }, - /* Generate the month and year header. */ - _generateMonthYearHeader: function( inst, drawMonth, drawYear, minDate, maxDate, - secondary, monthNames, monthNamesShort ) { + n = this.handles.split( "," ); + this.handles = {}; - var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear, - changeMonth = this._get( inst, "changeMonth" ), - changeYear = this._get( inst, "changeYear" ), - showMonthAfterYear = this._get( inst, "showMonthAfterYear" ), - selectMonthLabel = this._get( inst, "selectMonthLabel" ), - selectYearLabel = this._get( inst, "selectYearLabel" ), - html = "<div class='ui-datepicker-title'>", - monthHtml = ""; + for ( i = 0; i < n.length; i++ ) { - // Month selection - if ( secondary || !changeMonth ) { - monthHtml += "<span class='ui-datepicker-month'>" + monthNames[ drawMonth ] + "</span>"; - } else { - inMinYear = ( minDate && minDate.getFullYear() === drawYear ); - inMaxYear = ( maxDate && maxDate.getFullYear() === drawYear ); - monthHtml += "<select class='ui-datepicker-month' aria-label='" + selectMonthLabel + "' data-handler='selectMonth' data-event='change'>"; - for ( month = 0; month < 12; month++ ) { - if ( ( !inMinYear || month >= minDate.getMonth() ) && ( !inMaxYear || month <= maxDate.getMonth() ) ) { - monthHtml += "<option value='" + month + "'" + - ( month === drawMonth ? " selected='selected'" : "" ) + - ">" + monthNamesShort[ month ] + "</option>"; + handle = String.prototype.trim.call( n[ i ] ); + hname = "ui-resizable-" + handle; + axis = $( "<div>" ); + this._addClass( axis, "ui-resizable-handle " + hname ); + + axis.css( { zIndex: o.zIndex } ); + + this.handles[ handle ] = ".ui-resizable-" + handle; + if ( !this.element.children( this.handles[ handle ] ).length ) { + this.element.append( axis ); + this._addedHandles = this._addedHandles.add( axis ); } } - monthHtml += "</select>"; - } - if ( !showMonthAfterYear ) { - html += monthHtml + ( secondary || !( changeMonth && changeYear ) ? " " : "" ); } - // Year selection - if ( !inst.yearshtml ) { - inst.yearshtml = ""; - if ( secondary || !changeYear ) { - html += "<span class='ui-datepicker-year'>" + drawYear + "</span>"; - } else { + this._renderAxis = function( target ) { - // determine range of years to display - years = this._get( inst, "yearRange" ).split( ":" ); - thisYear = new Date().getFullYear(); - determineYear = function( value ) { - var year = ( value.match( /c[+\-].*/ ) ? drawYear + parseInt( value.substring( 1 ), 10 ) : - ( value.match( /[+\-].*/ ) ? thisYear + parseInt( value, 10 ) : - parseInt( value, 10 ) ) ); - return ( isNaN( year ) ? thisYear : year ); - }; - year = determineYear( years[ 0 ] ); - endYear = Math.max( year, determineYear( years[ 1 ] || "" ) ); - year = ( minDate ? Math.max( year, minDate.getFullYear() ) : year ); - endYear = ( maxDate ? Math.min( endYear, maxDate.getFullYear() ) : endYear ); - inst.yearshtml += "<select class='ui-datepicker-year' aria-label='" + selectYearLabel + "' data-handler='selectYear' data-event='change'>"; - for ( ; year <= endYear; year++ ) { - inst.yearshtml += "<option value='" + year + "'" + - ( year === drawYear ? " selected='selected'" : "" ) + - ">" + year + "</option>"; + var i, axis, padPos, padWrapper; + + target = target || this.element; + + for ( i in this.handles ) { + + if ( this.handles[ i ].constructor === String ) { + this.handles[ i ] = this.element.children( this.handles[ i ] ).first().show(); + } else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) { + this.handles[ i ] = $( this.handles[ i ] ); + this._on( this.handles[ i ], { "mousedown": that._mouseDown } ); } - inst.yearshtml += "</select>"; - html += inst.yearshtml; - inst.yearshtml = null; + if ( this.elementIsWrapper && + this.originalElement[ 0 ] + .nodeName + .match( /^(textarea|input|select|button)$/i ) ) { + axis = $( this.handles[ i ], this.element ); + + padWrapper = /sw|ne|nw|se|n|s/.test( i ) ? + axis.outerHeight() : + axis.outerWidth(); + + padPos = [ "padding", + /ne|nw|n/.test( i ) ? "Top" : + /se|sw|s/.test( i ) ? "Bottom" : + /^e$/.test( i ) ? "Right" : "Left" ].join( "" ); + + target.css( padPos, padWrapper ); + + this._proportionallyResize(); + } + + this._handles = this._handles.add( this.handles[ i ] ); } - } + }; - html += this._get( inst, "yearSuffix" ); - if ( showMonthAfterYear ) { - html += ( secondary || !( changeMonth && changeYear ) ? " " : "" ) + monthHtml; - } - html += "</div>"; // Close datepicker_header - return html; - }, + // TODO: make renderAxis a prototype function + this._renderAxis( this.element ); - /* Adjust one of the date sub-fields. */ - _adjustInstDate: function( inst, offset, period ) { - var year = inst.selectedYear + ( period === "Y" ? offset : 0 ), - month = inst.selectedMonth + ( period === "M" ? offset : 0 ), - day = Math.min( inst.selectedDay, this._getDaysInMonth( year, month ) ) + ( period === "D" ? offset : 0 ), - date = this._restrictMinMax( inst, this._daylightSavingAdjust( new Date( year, month, day ) ) ); + this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) ); + this._handles.disableSelection(); - inst.selectedDay = date.getDate(); - inst.drawMonth = inst.selectedMonth = date.getMonth(); - inst.drawYear = inst.selectedYear = date.getFullYear(); - if ( period === "M" || period === "Y" ) { - this._notifyChange( inst ); + this._handles.on( "mouseover", function() { + if ( !that.resizing ) { + if ( this.className ) { + axis = this.className.match( /ui-resizable-(se|sw|ne|nw|n|e|s|w)/i ); + } + that.axis = axis && axis[ 1 ] ? axis[ 1 ] : "se"; + } + } ); + + if ( o.autoHide ) { + this._handles.hide(); + this._addClass( "ui-resizable-autohide" ); } }, - /* Ensure a date is within any min/max bounds. */ - _restrictMinMax: function( inst, date ) { - var minDate = this._getMinMaxDate( inst, "min" ), - maxDate = this._getMinMaxDate( inst, "max" ), - newDate = ( minDate && date < minDate ? minDate : date ); - return ( maxDate && newDate > maxDate ? maxDate : newDate ); + _removeHandles: function() { + this._addedHandles.remove(); }, - /* Notify change of month/year. */ - _notifyChange: function( inst ) { - var onChange = this._get( inst, "onChangeMonthYear" ); - if ( onChange ) { - onChange.apply( ( inst.input ? inst.input[ 0 ] : null ), - [ inst.selectedYear, inst.selectedMonth + 1, inst ] ); + _mouseCapture: function( event ) { + var i, handle, + capture = false; + + for ( i in this.handles ) { + handle = $( this.handles[ i ] )[ 0 ]; + if ( handle === event.target || $.contains( handle, event.target ) ) { + capture = true; + } } - }, - /* Determine the number of months to show. */ - _getNumberOfMonths: function( inst ) { - var numMonths = this._get( inst, "numberOfMonths" ); - return ( numMonths == null ? [ 1, 1 ] : ( typeof numMonths === "number" ? [ 1, numMonths ] : numMonths ) ); + return !this.options.disabled && capture; }, - /* Determine the current maximum date - ensure no time components are set. */ - _getMinMaxDate: function( inst, minMax ) { - return this._determineDate( inst, this._get( inst, minMax + "Date" ), null ); - }, + _mouseStart: function( event ) { - /* Find the number of days in a given month. */ - _getDaysInMonth: function( year, month ) { - return 32 - this._daylightSavingAdjust( new Date( year, month, 32 ) ).getDate(); - }, + var curleft, curtop, cursor, + o = this.options, + el = this.element; - /* Find the day of the week of the first of a month. */ - _getFirstDayOfMonth: function( year, month ) { - return new Date( year, month, 1 ).getDay(); - }, + this.resizing = true; - /* Determines if we should allow a "next/prev" month display change. */ - _canAdjustMonth: function( inst, offset, curYear, curMonth ) { - var numMonths = this._getNumberOfMonths( inst ), - date = this._daylightSavingAdjust( new Date( curYear, - curMonth + ( offset < 0 ? offset : numMonths[ 0 ] * numMonths[ 1 ] ), 1 ) ); + this._renderProxy(); - if ( offset < 0 ) { - date.setDate( this._getDaysInMonth( date.getFullYear(), date.getMonth() ) ); + curleft = this._num( this.helper.css( "left" ) ); + curtop = this._num( this.helper.css( "top" ) ); + + if ( o.containment ) { + curleft += $( o.containment ).scrollLeft() || 0; + curtop += $( o.containment ).scrollTop() || 0; } - return this._isInRange( inst, date ); - }, - /* Is the given date in the accepted range? */ - _isInRange: function( inst, date ) { - var yearSplit, currentYear, - minDate = this._getMinMaxDate( inst, "min" ), - maxDate = this._getMinMaxDate( inst, "max" ), - minYear = null, - maxYear = null, - years = this._get( inst, "yearRange" ); - if ( years ) { - yearSplit = years.split( ":" ); - currentYear = new Date().getFullYear(); - minYear = parseInt( yearSplit[ 0 ], 10 ); - maxYear = parseInt( yearSplit[ 1 ], 10 ); - if ( yearSplit[ 0 ].match( /[+\-].*/ ) ) { - minYear += currentYear; - } - if ( yearSplit[ 1 ].match( /[+\-].*/ ) ) { - maxYear += currentYear; - } - } + this.offset = this.helper.offset(); + this.position = { left: curleft, top: curtop }; + + this.size = this._helper ? { + width: this.helper.width(), + height: this.helper.height() + } : { + width: el.width(), + height: el.height() + }; + + this.originalSize = this._helper ? { + width: el.outerWidth(), + height: el.outerHeight() + } : { + width: el.width(), + height: el.height() + }; + + this.sizeDiff = { + width: el.outerWidth() - el.width(), + height: el.outerHeight() - el.height() + }; + + this.originalPosition = { left: curleft, top: curtop }; + this.originalMousePosition = { left: event.pageX, top: event.pageY }; + + this.aspectRatio = ( typeof o.aspectRatio === "number" ) ? + o.aspectRatio : + ( ( this.originalSize.width / this.originalSize.height ) || 1 ); - return ( ( !minDate || date.getTime() >= minDate.getTime() ) && - ( !maxDate || date.getTime() <= maxDate.getTime() ) && - ( !minYear || date.getFullYear() >= minYear ) && - ( !maxYear || date.getFullYear() <= maxYear ) ); - }, + cursor = $( ".ui-resizable-" + this.axis ).css( "cursor" ); + $( "body" ).css( "cursor", cursor === "auto" ? this.axis + "-resize" : cursor ); - /* Provide the configuration settings for formatting/parsing. */ - _getFormatConfig: function( inst ) { - var shortYearCutoff = this._get( inst, "shortYearCutoff" ); - shortYearCutoff = ( typeof shortYearCutoff !== "string" ? shortYearCutoff : - new Date().getFullYear() % 100 + parseInt( shortYearCutoff, 10 ) ); - return { shortYearCutoff: shortYearCutoff, - dayNamesShort: this._get( inst, "dayNamesShort" ), dayNames: this._get( inst, "dayNames" ), - monthNamesShort: this._get( inst, "monthNamesShort" ), monthNames: this._get( inst, "monthNames" ) }; + this._addClass( "ui-resizable-resizing" ); + this._propagate( "start", event ); + return true; }, - /* Format the given date for display. */ - _formatDate: function( inst, day, month, year ) { - if ( !day ) { - inst.currentDay = inst.selectedDay; - inst.currentMonth = inst.selectedMonth; - inst.currentYear = inst.selectedYear; - } - var date = ( day ? ( typeof day === "object" ? day : - this._daylightSavingAdjust( new Date( year, month, day ) ) ) : - this._daylightSavingAdjust( new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ); - return this.formatDate( this._get( inst, "dateFormat" ), date, this._getFormatConfig( inst ) ); - } -} ); + _mouseDrag: function( event ) { -/* - * Bind hover events for datepicker elements. - * Done via delegate so the binding only occurs once in the lifetime of the parent div. - * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. - */ -function datepicker_bindHover( dpDiv ) { - var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a"; - return dpDiv.on( "mouseout", selector, function() { - $( this ).removeClass( "ui-state-hover" ); - if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) { - $( this ).removeClass( "ui-datepicker-prev-hover" ); - } - if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) { - $( this ).removeClass( "ui-datepicker-next-hover" ); - } - } ) - .on( "mouseover", selector, datepicker_handleMouseover ); -} + var data, props, + smp = this.originalMousePosition, + a = this.axis, + dx = ( event.pageX - smp.left ) || 0, + dy = ( event.pageY - smp.top ) || 0, + trigger = this._change[ a ]; -function datepicker_handleMouseover() { - if ( !$.datepicker._isDisabledDatepicker( datepicker_instActive.inline ? datepicker_instActive.dpDiv.parent()[ 0 ] : datepicker_instActive.input[ 0 ] ) ) { - $( this ).parents( ".ui-datepicker-calendar" ).find( "a" ).removeClass( "ui-state-hover" ); - $( this ).addClass( "ui-state-hover" ); - if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) { - $( this ).addClass( "ui-datepicker-prev-hover" ); - } - if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) { - $( this ).addClass( "ui-datepicker-next-hover" ); + this._updatePrevProperties(); + + if ( !trigger ) { + return false; } - } -} -/* jQuery extend now ignores nulls! */ -function datepicker_extendRemove( target, props ) { - $.extend( target, props ); - for ( var name in props ) { - if ( props[ name ] == null ) { - target[ name ] = props[ name ]; + data = trigger.apply( this, [ event, dx, dy ] ); + + this._updateVirtualBoundaries( event.shiftKey ); + if ( this._aspectRatio || event.shiftKey ) { + data = this._updateRatio( data, event ); } - } - return target; -} -/* Invoke the datepicker functionality. - @param options string - a command, optionally followed by additional parameters or - Object - settings for attaching new datepicker functionality - @return jQuery object */ -$.fn.datepicker = function( options ) { + data = this._respectSize( data, event ); - /* Verify an empty collection wasn't passed - Fixes #6976 */ - if ( !this.length ) { - return this; - } + this._updateCache( data ); - /* Initialise the date picker. */ - if ( !$.datepicker.initialized ) { - $( document ).on( "mousedown", $.datepicker._checkExternalClick ); - $.datepicker.initialized = true; - } + this._propagate( "resize", event ); - /* Append datepicker main container to body if not exist. */ - if ( $( "#" + $.datepicker._mainDivId ).length === 0 ) { - $( "body" ).append( $.datepicker.dpDiv ); - } + props = this._applyChanges(); - var otherArgs = Array.prototype.slice.call( arguments, 1 ); - if ( typeof options === "string" && ( options === "isDisabled" || options === "getDate" || options === "widget" ) ) { - return $.datepicker[ "_" + options + "Datepicker" ]. - apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) ); - } - if ( options === "option" && arguments.length === 2 && typeof arguments[ 1 ] === "string" ) { - return $.datepicker[ "_" + options + "Datepicker" ]. - apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) ); - } - return this.each( function() { - if ( typeof options === "string" ) { - $.datepicker[ "_" + options + "Datepicker" ] - .apply( $.datepicker, [ this ].concat( otherArgs ) ); - } else { - $.datepicker._attachDatepicker( this, options ); + if ( !this._helper && this._proportionallyResizeElements.length ) { + this._proportionallyResize(); } - } ); -}; -$.datepicker = new Datepicker(); // singleton instance -$.datepicker.initialized = false; -$.datepicker.uuid = new Date().getTime(); -$.datepicker.version = "1.13.1"; + if ( !$.isEmptyObject( props ) ) { + this._updatePrevProperties(); + this._trigger( "resize", event, this.ui() ); + this._applyChanges(); + } -var widgetsDatepicker = $.datepicker; + return false; + }, + _mouseStop: function( event ) { -/*! - * jQuery UI Dialog 1.13.1 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ + this.resizing = false; + var pr, ista, soffseth, soffsetw, s, left, top, + o = this.options, that = this; -//>>label: Dialog -//>>group: Widgets -//>>description: Displays customizable dialog windows. -//>>docs: http://api.jqueryui.com/dialog/ -//>>demos: http://jqueryui.com/dialog/ -//>>css.structure: ../../themes/base/core.css -//>>css.structure: ../../themes/base/dialog.css -//>>css.theme: ../../themes/base/theme.css + if ( this._helper ) { + pr = this._proportionallyResizeElements; + ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ); + soffseth = ista && this._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height; + soffsetw = ista ? 0 : that.sizeDiff.width; -$.widget( "ui.dialog", { - version: "1.13.1", - options: { - appendTo: "body", - autoOpen: true, - buttons: [], - classes: { - "ui-dialog": "ui-corner-all", - "ui-dialog-titlebar": "ui-corner-all" - }, - closeOnEscape: true, - closeText: "Close", - draggable: true, - hide: null, - height: "auto", - maxHeight: null, - maxWidth: null, - minHeight: 150, - minWidth: 150, - modal: false, - position: { - my: "center", - at: "center", - of: window, - collision: "fit", + s = { + width: ( that.helper.width() - soffsetw ), + height: ( that.helper.height() - soffseth ) + }; + left = ( parseFloat( that.element.css( "left" ) ) + + ( that.position.left - that.originalPosition.left ) ) || null; + top = ( parseFloat( that.element.css( "top" ) ) + + ( that.position.top - that.originalPosition.top ) ) || null; - // Ensure the titlebar is always visible - using: function( pos ) { - var topOffset = $( this ).css( pos ).offset().top; - if ( topOffset < 0 ) { - $( this ).css( "top", pos.top - topOffset ); - } + if ( !o.animate ) { + this.element.css( $.extend( s, { top: top, left: left } ) ); } - }, - resizable: true, - show: null, - title: null, - width: 300, - - // Callbacks - beforeClose: null, - close: null, - drag: null, - dragStart: null, - dragStop: null, - focus: null, - open: null, - resize: null, - resizeStart: null, - resizeStop: null - }, - - sizeRelatedOptions: { - buttons: true, - height: true, - maxHeight: true, - maxWidth: true, - minHeight: true, - minWidth: true, - width: true - }, - resizableRelatedOptions: { - maxHeight: true, - maxWidth: true, - minHeight: true, - minWidth: true - }, + that.helper.height( that.size.height ); + that.helper.width( that.size.width ); - _create: function() { - this.originalCss = { - display: this.element[ 0 ].style.display, - width: this.element[ 0 ].style.width, - minHeight: this.element[ 0 ].style.minHeight, - maxHeight: this.element[ 0 ].style.maxHeight, - height: this.element[ 0 ].style.height - }; - this.originalPosition = { - parent: this.element.parent(), - index: this.element.parent().children().index( this.element ) - }; - this.originalTitle = this.element.attr( "title" ); - if ( this.options.title == null && this.originalTitle != null ) { - this.options.title = this.originalTitle; + if ( this._helper && !o.animate ) { + this._proportionallyResize(); + } } - // Dialogs can't be disabled - if ( this.options.disabled ) { - this.options.disabled = false; + $( "body" ).css( "cursor", "auto" ); + + this._removeClass( "ui-resizable-resizing" ); + + this._propagate( "stop", event ); + + if ( this._helper ) { + this.helper.remove(); } - this._createWrapper(); + return false; - this.element - .show() - .removeAttr( "title" ) - .appendTo( this.uiDialog ); + }, - this._addClass( "ui-dialog-content", "ui-widget-content" ); + _updatePrevProperties: function() { + this.prevPosition = { + top: this.position.top, + left: this.position.left + }; + this.prevSize = { + width: this.size.width, + height: this.size.height + }; + }, - this._createTitlebar(); - this._createButtonPane(); + _applyChanges: function() { + var props = {}; - if ( this.options.draggable && $.fn.draggable ) { - this._makeDraggable(); + if ( this.position.top !== this.prevPosition.top ) { + props.top = this.position.top + "px"; } - if ( this.options.resizable && $.fn.resizable ) { - this._makeResizable(); + if ( this.position.left !== this.prevPosition.left ) { + props.left = this.position.left + "px"; + } + if ( this.size.width !== this.prevSize.width ) { + props.width = this.size.width + "px"; + } + if ( this.size.height !== this.prevSize.height ) { + props.height = this.size.height + "px"; } - this._isOpen = false; + this.helper.css( props ); - this._trackFocus(); + return props; }, - _init: function() { - if ( this.options.autoOpen ) { - this.open(); + _updateVirtualBoundaries: function( forceAspectRatio ) { + var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b, + o = this.options; + + b = { + minWidth: this._isNumber( o.minWidth ) ? o.minWidth : 0, + maxWidth: this._isNumber( o.maxWidth ) ? o.maxWidth : Infinity, + minHeight: this._isNumber( o.minHeight ) ? o.minHeight : 0, + maxHeight: this._isNumber( o.maxHeight ) ? o.maxHeight : Infinity + }; + + if ( this._aspectRatio || forceAspectRatio ) { + pMinWidth = b.minHeight * this.aspectRatio; + pMinHeight = b.minWidth / this.aspectRatio; + pMaxWidth = b.maxHeight * this.aspectRatio; + pMaxHeight = b.maxWidth / this.aspectRatio; + + if ( pMinWidth > b.minWidth ) { + b.minWidth = pMinWidth; + } + if ( pMinHeight > b.minHeight ) { + b.minHeight = pMinHeight; + } + if ( pMaxWidth < b.maxWidth ) { + b.maxWidth = pMaxWidth; + } + if ( pMaxHeight < b.maxHeight ) { + b.maxHeight = pMaxHeight; + } } + this._vBoundaries = b; }, - _appendTo: function() { - var element = this.options.appendTo; - if ( element && ( element.jquery || element.nodeType ) ) { - return $( element ); + _updateCache: function( data ) { + this.offset = this.helper.offset(); + if ( this._isNumber( data.left ) ) { + this.position.left = data.left; + } + if ( this._isNumber( data.top ) ) { + this.position.top = data.top; + } + if ( this._isNumber( data.height ) ) { + this.size.height = data.height; + } + if ( this._isNumber( data.width ) ) { + this.size.width = data.width; } - return this.document.find( element || "body" ).eq( 0 ); }, - _destroy: function() { - var next, - originalPosition = this.originalPosition; + _updateRatio: function( data ) { - this._untrackInstance(); - this._destroyOverlay(); + var cpos = this.position, + csize = this.size, + a = this.axis; - this.element - .removeUniqueId() - .css( this.originalCss ) + if ( this._isNumber( data.height ) ) { + data.width = ( data.height * this.aspectRatio ); + } else if ( this._isNumber( data.width ) ) { + data.height = ( data.width / this.aspectRatio ); + } - // Without detaching first, the following becomes really slow - .detach(); + if ( a === "sw" ) { + data.left = cpos.left + ( csize.width - data.width ); + data.top = null; + } + if ( a === "nw" ) { + data.top = cpos.top + ( csize.height - data.height ); + data.left = cpos.left + ( csize.width - data.width ); + } - this.uiDialog.remove(); + return data; + }, - if ( this.originalTitle ) { - this.element.attr( "title", this.originalTitle ); + _respectSize: function( data ) { + + var o = this._vBoundaries, + a = this.axis, + ismaxw = this._isNumber( data.width ) && o.maxWidth && ( o.maxWidth < data.width ), + ismaxh = this._isNumber( data.height ) && o.maxHeight && ( o.maxHeight < data.height ), + isminw = this._isNumber( data.width ) && o.minWidth && ( o.minWidth > data.width ), + isminh = this._isNumber( data.height ) && o.minHeight && ( o.minHeight > data.height ), + dw = this.originalPosition.left + this.originalSize.width, + dh = this.originalPosition.top + this.originalSize.height, + cw = /sw|nw|w/.test( a ), ch = /nw|ne|n/.test( a ); + if ( isminw ) { + data.width = o.minWidth; + } + if ( isminh ) { + data.height = o.minHeight; + } + if ( ismaxw ) { + data.width = o.maxWidth; + } + if ( ismaxh ) { + data.height = o.maxHeight; } - next = originalPosition.parent.children().eq( originalPosition.index ); + if ( isminw && cw ) { + data.left = dw - o.minWidth; + } + if ( ismaxw && cw ) { + data.left = dw - o.maxWidth; + } + if ( isminh && ch ) { + data.top = dh - o.minHeight; + } + if ( ismaxh && ch ) { + data.top = dh - o.maxHeight; + } - // Don't try to place the dialog next to itself (#8613) - if ( next.length && next[ 0 ] !== this.element[ 0 ] ) { - next.before( this.element ); - } else { - originalPosition.parent.append( this.element ); + // Fixing jump error on top/left - bug #2330 + if ( !data.width && !data.height && !data.left && data.top ) { + data.top = null; + } else if ( !data.width && !data.height && !data.top && data.left ) { + data.left = null; } - }, - widget: function() { - return this.uiDialog; + return data; }, - disable: $.noop, - enable: $.noop, - - close: function( event ) { - var that = this; + _getPaddingPlusBorderDimensions: function( element ) { + var i = 0, + widths = [], + borders = [ + element.css( "borderTopWidth" ), + element.css( "borderRightWidth" ), + element.css( "borderBottomWidth" ), + element.css( "borderLeftWidth" ) + ], + paddings = [ + element.css( "paddingTop" ), + element.css( "paddingRight" ), + element.css( "paddingBottom" ), + element.css( "paddingLeft" ) + ]; - if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) { - return; + for ( ; i < 4; i++ ) { + widths[ i ] = ( parseFloat( borders[ i ] ) || 0 ); + widths[ i ] += ( parseFloat( paddings[ i ] ) || 0 ); } - this._isOpen = false; - this._focusedElement = null; - this._destroyOverlay(); - this._untrackInstance(); + return { + height: widths[ 0 ] + widths[ 2 ], + width: widths[ 1 ] + widths[ 3 ] + }; + }, - if ( !this.opener.filter( ":focusable" ).trigger( "focus" ).length ) { + _proportionallyResize: function() { - // Hiding a focused element doesn't trigger blur in WebKit - // so in case we have nothing to focus on, explicitly blur the active element - // https://bugs.webkit.org/show_bug.cgi?id=47182 - $.ui.safeBlur( $.ui.safeActiveElement( this.document[ 0 ] ) ); + if ( !this._proportionallyResizeElements.length ) { + return; } - this._hide( this.uiDialog, this.options.hide, function() { - that._trigger( "close", event ); - } ); - }, + var prel, + i = 0, + element = this.helper || this.element; - isOpen: function() { - return this._isOpen; - }, + for ( ; i < this._proportionallyResizeElements.length; i++ ) { - moveToTop: function() { - this._moveToTop(); - }, + prel = this._proportionallyResizeElements[ i ]; - _moveToTop: function( event, silent ) { - var moved = false, - zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map( function() { - return +$( this ).css( "z-index" ); - } ).get(), - zIndexMax = Math.max.apply( null, zIndices ); + // TODO: Seems like a bug to cache this.outerDimensions + // considering that we are in a loop. + if ( !this.outerDimensions ) { + this.outerDimensions = this._getPaddingPlusBorderDimensions( prel ); + } + + prel.css( { + height: ( element.height() - this.outerDimensions.height ) || 0, + width: ( element.width() - this.outerDimensions.width ) || 0 + } ); - if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) { - this.uiDialog.css( "z-index", zIndexMax + 1 ); - moved = true; } - if ( moved && !silent ) { - this._trigger( "focus", event ); - } - return moved; }, - open: function() { - var that = this; - if ( this._isOpen ) { - if ( this._moveToTop() ) { - this._focusTabbable(); - } - return; - } + _renderProxy: function() { - this._isOpen = true; - this.opener = $( $.ui.safeActiveElement( this.document[ 0 ] ) ); + var el = this.element, o = this.options; + this.elementOffset = el.offset(); - this._size(); - this._position(); - this._createOverlay(); - this._moveToTop( null, true ); + if ( this._helper ) { - // Ensure the overlay is moved to the top with the dialog, but only when - // opening. The overlay shouldn't move after the dialog is open so that - // modeless dialogs opened after the modal dialog stack properly. - if ( this.overlay ) { - this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 ); - } + this.helper = this.helper || $( "<div></div>" ).css( { overflow: "hidden" } ); - this._show( this.uiDialog, this.options.show, function() { - that._focusTabbable(); - that._trigger( "focus" ); - } ); + this._addClass( this.helper, this._helper ); + this.helper.css( { + width: this.element.outerWidth(), + height: this.element.outerHeight(), + position: "absolute", + left: this.elementOffset.left + "px", + top: this.elementOffset.top + "px", + zIndex: ++o.zIndex //TODO: Don't modify option + } ); - // Track the dialog immediately upon opening in case a focus event - // somehow occurs outside of the dialog before an element inside the - // dialog is focused (#10152) - this._makeFocusTarget(); + this.helper + .appendTo( "body" ) + .disableSelection(); - this._trigger( "open" ); - }, + } else { + this.helper = this.element; + } - _focusTabbable: function() { + }, - // Set focus to the first match: - // 1. An element that was focused previously - // 2. First element inside the dialog matching [autofocus] - // 3. Tabbable element inside the content element - // 4. Tabbable element inside the buttonpane - // 5. The close button - // 6. The dialog itself - var hasFocus = this._focusedElement; - if ( !hasFocus ) { - hasFocus = this.element.find( "[autofocus]" ); - } - if ( !hasFocus.length ) { - hasFocus = this.element.find( ":tabbable" ); - } - if ( !hasFocus.length ) { - hasFocus = this.uiDialogButtonPane.find( ":tabbable" ); - } - if ( !hasFocus.length ) { - hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" ); - } - if ( !hasFocus.length ) { - hasFocus = this.uiDialog; + _change: { + e: function( event, dx ) { + return { width: this.originalSize.width + dx }; + }, + w: function( event, dx ) { + var cs = this.originalSize, sp = this.originalPosition; + return { left: sp.left + dx, width: cs.width - dx }; + }, + n: function( event, dx, dy ) { + var cs = this.originalSize, sp = this.originalPosition; + return { top: sp.top + dy, height: cs.height - dy }; + }, + s: function( event, dx, dy ) { + return { height: this.originalSize.height + dy }; + }, + se: function( event, dx, dy ) { + return $.extend( this._change.s.apply( this, arguments ), + this._change.e.apply( this, [ event, dx, dy ] ) ); + }, + sw: function( event, dx, dy ) { + return $.extend( this._change.s.apply( this, arguments ), + this._change.w.apply( this, [ event, dx, dy ] ) ); + }, + ne: function( event, dx, dy ) { + return $.extend( this._change.n.apply( this, arguments ), + this._change.e.apply( this, [ event, dx, dy ] ) ); + }, + nw: function( event, dx, dy ) { + return $.extend( this._change.n.apply( this, arguments ), + this._change.w.apply( this, [ event, dx, dy ] ) ); } - hasFocus.eq( 0 ).trigger( "focus" ); }, - _restoreTabbableFocus: function() { - var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ), - isActive = this.uiDialog[ 0 ] === activeElement || - $.contains( this.uiDialog[ 0 ], activeElement ); - if ( !isActive ) { - this._focusTabbable(); + _propagate: function( n, event ) { + $.ui.plugin.call( this, n, [ event, this.ui() ] ); + if ( n !== "resize" ) { + this._trigger( n, event, this.ui() ); } }, - _keepFocus: function( event ) { - event.preventDefault(); - this._restoreTabbableFocus(); - - // support: IE - // IE <= 8 doesn't prevent moving focus even with event.preventDefault() - // so we check again later - this._delay( this._restoreTabbableFocus ); - }, + plugins: {}, - _createWrapper: function() { - this.uiDialog = $( "<div>" ) - .hide() - .attr( { + ui: function() { + return { + originalElement: this.originalElement, + element: this.element, + helper: this.helper, + position: this.position, + size: this.size, + originalSize: this.originalSize, + originalPosition: this.originalPosition + }; + } - // Setting tabIndex makes the div focusable - tabIndex: -1, - role: "dialog" - } ) - .appendTo( this._appendTo() ); +} ); - this._addClass( this.uiDialog, "ui-dialog", "ui-widget ui-widget-content ui-front" ); - this._on( this.uiDialog, { - keydown: function( event ) { - if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && - event.keyCode === $.ui.keyCode.ESCAPE ) { - event.preventDefault(); - this.close( event ); - return; - } +/* + * Resizable Extensions + */ - // Prevent tabbing out of dialogs - if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) { - return; - } - var tabbables = this.uiDialog.find( ":tabbable" ), - first = tabbables.first(), - last = tabbables.last(); +$.ui.plugin.add( "resizable", "animate", { - if ( ( event.target === last[ 0 ] || event.target === this.uiDialog[ 0 ] ) && - !event.shiftKey ) { - this._delay( function() { - first.trigger( "focus" ); - } ); - event.preventDefault(); - } else if ( ( event.target === first[ 0 ] || - event.target === this.uiDialog[ 0 ] ) && event.shiftKey ) { - this._delay( function() { - last.trigger( "focus" ); - } ); - event.preventDefault(); - } + stop: function( event ) { + var that = $( this ).resizable( "instance" ), + o = that.options, + pr = that._proportionallyResizeElements, + ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ), + soffseth = ista && that._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height, + soffsetw = ista ? 0 : that.sizeDiff.width, + style = { + width: ( that.size.width - soffsetw ), + height: ( that.size.height - soffseth ) }, - mousedown: function( event ) { - if ( this._moveToTop( event ) ) { - this._focusTabbable(); + left = ( parseFloat( that.element.css( "left" ) ) + + ( that.position.left - that.originalPosition.left ) ) || null, + top = ( parseFloat( that.element.css( "top" ) ) + + ( that.position.top - that.originalPosition.top ) ) || null; + + that.element.animate( + $.extend( style, top && left ? { top: top, left: left } : {} ), { + duration: o.animateDuration, + easing: o.animateEasing, + step: function() { + + var data = { + width: parseFloat( that.element.css( "width" ) ), + height: parseFloat( that.element.css( "height" ) ), + top: parseFloat( that.element.css( "top" ) ), + left: parseFloat( that.element.css( "left" ) ) + }; + + if ( pr && pr.length ) { + $( pr[ 0 ] ).css( { width: data.width, height: data.height } ); + } + + // Propagating resize, and updating values for each animation step + that._updateCache( data ); + that._propagate( "resize", event ); + } } - } ); + ); + } + +} ); + +$.ui.plugin.add( "resizable", "containment", { + + start: function() { + var element, p, co, ch, cw, width, height, + that = $( this ).resizable( "instance" ), + o = that.options, + el = that.element, + oc = o.containment, + ce = ( oc instanceof $ ) ? + oc.get( 0 ) : + ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc; + + if ( !ce ) { + return; + } + + that.containerElement = $( ce ); + + if ( /document/.test( oc ) || oc === document ) { + that.containerOffset = { + left: 0, + top: 0 + }; + that.containerPosition = { + left: 0, + top: 0 + }; - // We assume that any existing aria-describedby attribute means - // that the dialog content is marked up properly - // otherwise we brute force the content as the description - if ( !this.element.find( "[aria-describedby]" ).length ) { - this.uiDialog.attr( { - "aria-describedby": this.element.uniqueId().attr( "id" ) + that.parentData = { + element: $( document ), + left: 0, + top: 0, + width: $( document ).width(), + height: $( document ).height() || document.body.parentNode.scrollHeight + }; + } else { + element = $( ce ); + p = []; + $( [ "Top", "Right", "Left", "Bottom" ] ).each( function( i, name ) { + p[ i ] = that._num( element.css( "padding" + name ) ); } ); + + that.containerOffset = element.offset(); + that.containerPosition = element.position(); + that.containerSize = { + height: ( element.innerHeight() - p[ 3 ] ), + width: ( element.innerWidth() - p[ 1 ] ) + }; + + co = that.containerOffset; + ch = that.containerSize.height; + cw = that.containerSize.width; + width = ( that._hasScroll( ce, "left" ) ? ce.scrollWidth : cw ); + height = ( that._hasScroll( ce ) ? ce.scrollHeight : ch ); + + that.parentData = { + element: ce, + left: co.left, + top: co.top, + width: width, + height: height + }; } }, - _createTitlebar: function() { - var uiDialogTitle; + resize: function( event ) { + var woset, hoset, isParent, isOffsetRelative, + that = $( this ).resizable( "instance" ), + o = that.options, + co = that.containerOffset, + cp = that.position, + pRatio = that._aspectRatio || event.shiftKey, + cop = { + top: 0, + left: 0 + }, + ce = that.containerElement, + continueResize = true; - this.uiDialogTitlebar = $( "<div>" ); - this._addClass( this.uiDialogTitlebar, - "ui-dialog-titlebar", "ui-widget-header ui-helper-clearfix" ); - this._on( this.uiDialogTitlebar, { - mousedown: function( event ) { + if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) { + cop = co; + } - // Don't prevent click on close button (#8838) - // Focusing a dialog that is partially scrolled out of view - // causes the browser to scroll it into view, preventing the click event - if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) { + if ( cp.left < ( that._helper ? co.left : 0 ) ) { + that.size.width = that.size.width + + ( that._helper ? + ( that.position.left - co.left ) : + ( that.position.left - cop.left ) ); - // Dialog isn't getting focus when dragging (#8063) - this.uiDialog.trigger( "focus" ); - } + if ( pRatio ) { + that.size.height = that.size.width / that.aspectRatio; + continueResize = false; } - } ); + that.position.left = o.helper ? co.left : 0; + } - // Support: IE - // Use type="button" to prevent enter keypresses in textboxes from closing the - // dialog in IE (#9312) - this.uiDialogTitlebarClose = $( "<button type='button'></button>" ) - .button( { - label: $( "<a>" ).text( this.options.closeText ).html(), - icon: "ui-icon-closethick", - showLabel: false - } ) - .appendTo( this.uiDialogTitlebar ); + if ( cp.top < ( that._helper ? co.top : 0 ) ) { + that.size.height = that.size.height + + ( that._helper ? + ( that.position.top - co.top ) : + that.position.top ); - this._addClass( this.uiDialogTitlebarClose, "ui-dialog-titlebar-close" ); - this._on( this.uiDialogTitlebarClose, { - click: function( event ) { - event.preventDefault(); - this.close( event ); + if ( pRatio ) { + that.size.width = that.size.height * that.aspectRatio; + continueResize = false; } - } ); - - uiDialogTitle = $( "<span>" ).uniqueId().prependTo( this.uiDialogTitlebar ); - this._addClass( uiDialogTitle, "ui-dialog-title" ); - this._title( uiDialogTitle ); - - this.uiDialogTitlebar.prependTo( this.uiDialog ); + that.position.top = that._helper ? co.top : 0; + } - this.uiDialog.attr( { - "aria-labelledby": uiDialogTitle.attr( "id" ) - } ); - }, + isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 ); + isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) ); - _title: function( title ) { - if ( this.options.title ) { - title.text( this.options.title ); + if ( isParent && isOffsetRelative ) { + that.offset.left = that.parentData.left + that.position.left; + that.offset.top = that.parentData.top + that.position.top; } else { - title.html( " " ); + that.offset.left = that.element.offset().left; + that.offset.top = that.element.offset().top; } - }, - _createButtonPane: function() { - this.uiDialogButtonPane = $( "<div>" ); - this._addClass( this.uiDialogButtonPane, "ui-dialog-buttonpane", - "ui-widget-content ui-helper-clearfix" ); + woset = Math.abs( that.sizeDiff.width + + ( that._helper ? + that.offset.left - cop.left : + ( that.offset.left - co.left ) ) ); - this.uiButtonSet = $( "<div>" ) - .appendTo( this.uiDialogButtonPane ); - this._addClass( this.uiButtonSet, "ui-dialog-buttonset" ); + hoset = Math.abs( that.sizeDiff.height + + ( that._helper ? + that.offset.top - cop.top : + ( that.offset.top - co.top ) ) ); - this._createButtons(); + if ( woset + that.size.width >= that.parentData.width ) { + that.size.width = that.parentData.width - woset; + if ( pRatio ) { + that.size.height = that.size.width / that.aspectRatio; + continueResize = false; + } + } + + if ( hoset + that.size.height >= that.parentData.height ) { + that.size.height = that.parentData.height - hoset; + if ( pRatio ) { + that.size.width = that.size.height * that.aspectRatio; + continueResize = false; + } + } + + if ( !continueResize ) { + that.position.left = that.prevPosition.left; + that.position.top = that.prevPosition.top; + that.size.width = that.prevSize.width; + that.size.height = that.prevSize.height; + } }, - _createButtons: function() { - var that = this, - buttons = this.options.buttons; + stop: function() { + var that = $( this ).resizable( "instance" ), + o = that.options, + co = that.containerOffset, + cop = that.containerPosition, + ce = that.containerElement, + helper = $( that.helper ), + ho = helper.offset(), + w = helper.outerWidth() - that.sizeDiff.width, + h = helper.outerHeight() - that.sizeDiff.height; - // If we already have a button pane, remove it - this.uiDialogButtonPane.remove(); - this.uiButtonSet.empty(); + if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) { + $( this ).css( { + left: ho.left - cop.left - co.left, + width: w, + height: h + } ); + } - if ( $.isEmptyObject( buttons ) || ( Array.isArray( buttons ) && !buttons.length ) ) { - this._removeClass( this.uiDialog, "ui-dialog-buttons" ); - return; + if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) { + $( this ).css( { + left: ho.left - cop.left - co.left, + width: w, + height: h + } ); } + } +} ); - $.each( buttons, function( name, props ) { - var click, buttonOptions; - props = typeof props === "function" ? - { click: props, text: name } : - props; +$.ui.plugin.add( "resizable", "alsoResize", { - // Default to a non-submitting button - props = $.extend( { type: "button" }, props ); + start: function() { + var that = $( this ).resizable( "instance" ), + o = that.options; - // Change the context for the click callback to be the main element - click = props.click; - buttonOptions = { - icon: props.icon, - iconPosition: props.iconPosition, - showLabel: props.showLabel, + $( o.alsoResize ).each( function() { + var el = $( this ); + el.data( "ui-resizable-alsoresize", { + width: parseFloat( el.width() ), height: parseFloat( el.height() ), + left: parseFloat( el.css( "left" ) ), top: parseFloat( el.css( "top" ) ) + } ); + } ); + }, - // Deprecated options - icons: props.icons, - text: props.text + resize: function( event, ui ) { + var that = $( this ).resizable( "instance" ), + o = that.options, + os = that.originalSize, + op = that.originalPosition, + delta = { + height: ( that.size.height - os.height ) || 0, + width: ( that.size.width - os.width ) || 0, + top: ( that.position.top - op.top ) || 0, + left: ( that.position.left - op.left ) || 0 }; - delete props.click; - delete props.icon; - delete props.iconPosition; - delete props.showLabel; - - // Deprecated options - delete props.icons; - if ( typeof props.text === "boolean" ) { - delete props.text; - } + $( o.alsoResize ).each( function() { + var el = $( this ), start = $( this ).data( "ui-resizable-alsoresize" ), style = {}, + css = el.parents( ui.originalElement[ 0 ] ).length ? + [ "width", "height" ] : + [ "width", "height", "top", "left" ]; - $( "<button></button>", props ) - .button( buttonOptions ) - .appendTo( that.uiButtonSet ) - .on( "click", function() { - click.apply( that.element[ 0 ], arguments ); + $.each( css, function( i, prop ) { + var sum = ( start[ prop ] || 0 ) + ( delta[ prop ] || 0 ); + if ( sum && sum >= 0 ) { + style[ prop ] = sum || null; + } } ); - } ); - this._addClass( this.uiDialog, "ui-dialog-buttons" ); - this.uiDialogButtonPane.appendTo( this.uiDialog ); + + el.css( style ); + } ); }, - _makeDraggable: function() { - var that = this, - options = this.options; + stop: function() { + $( this ).removeData( "ui-resizable-alsoresize" ); + } +} ); - function filteredUi( ui ) { - return { - position: ui.position, - offset: ui.offset - }; - } +$.ui.plugin.add( "resizable", "ghost", { - this.uiDialog.draggable( { - cancel: ".ui-dialog-content, .ui-dialog-titlebar-close", - handle: ".ui-dialog-titlebar", - containment: "document", - start: function( event, ui ) { - that._addClass( $( this ), "ui-dialog-dragging" ); - that._blockFrames(); - that._trigger( "dragStart", event, filteredUi( ui ) ); - }, - drag: function( event, ui ) { - that._trigger( "drag", event, filteredUi( ui ) ); - }, - stop: function( event, ui ) { - var left = ui.offset.left - that.document.scrollLeft(), - top = ui.offset.top - that.document.scrollTop(); + start: function() { - options.position = { - my: "left top", - at: "left" + ( left >= 0 ? "+" : "" ) + left + " " + - "top" + ( top >= 0 ? "+" : "" ) + top, - of: that.window - }; - that._removeClass( $( this ), "ui-dialog-dragging" ); - that._unblockFrames(); - that._trigger( "dragStop", event, filteredUi( ui ) ); - } + var that = $( this ).resizable( "instance" ), cs = that.size; + + that.ghost = that.originalElement.clone(); + that.ghost.css( { + opacity: 0.25, + display: "block", + position: "relative", + height: cs.height, + width: cs.width, + margin: 0, + left: 0, + top: 0 } ); - }, - _makeResizable: function() { - var that = this, - options = this.options, - handles = options.resizable, + that._addClass( that.ghost, "ui-resizable-ghost" ); - // .ui-resizable has position: relative defined in the stylesheet - // but dialogs have to use absolute or fixed positioning - position = this.uiDialog.css( "position" ), - resizeHandles = typeof handles === "string" ? - handles : - "n,e,s,w,se,sw,ne,nw"; + // DEPRECATED + // TODO: remove after 1.12 + if ( $.uiBackCompat !== false && typeof that.options.ghost === "string" ) { - function filteredUi( ui ) { - return { - originalPosition: ui.originalPosition, - originalSize: ui.originalSize, - position: ui.position, - size: ui.size - }; + // Ghost option + that.ghost.addClass( this.options.ghost ); } - this.uiDialog.resizable( { - cancel: ".ui-dialog-content", - containment: "document", - alsoResize: this.element, - maxWidth: options.maxWidth, - maxHeight: options.maxHeight, - minWidth: options.minWidth, - minHeight: this._minHeight(), - handles: resizeHandles, - start: function( event, ui ) { - that._addClass( $( this ), "ui-dialog-resizing" ); - that._blockFrames(); - that._trigger( "resizeStart", event, filteredUi( ui ) ); - }, - resize: function( event, ui ) { - that._trigger( "resize", event, filteredUi( ui ) ); - }, - stop: function( event, ui ) { - var offset = that.uiDialog.offset(), - left = offset.left - that.document.scrollLeft(), - top = offset.top - that.document.scrollTop(); - - options.height = that.uiDialog.height(); - options.width = that.uiDialog.width(); - options.position = { - my: "left top", - at: "left" + ( left >= 0 ? "+" : "" ) + left + " " + - "top" + ( top >= 0 ? "+" : "" ) + top, - of: that.window - }; - that._removeClass( $( this ), "ui-dialog-resizing" ); - that._unblockFrames(); - that._trigger( "resizeStop", event, filteredUi( ui ) ); - } - } ) - .css( "position", position ); - }, - - _trackFocus: function() { - this._on( this.widget(), { - focusin: function( event ) { - this._makeFocusTarget(); - this._focusedElement = $( event.target ); - } - } ); - }, + that.ghost.appendTo( that.helper ); - _makeFocusTarget: function() { - this._untrackInstance(); - this._trackingInstances().unshift( this ); }, - _untrackInstance: function() { - var instances = this._trackingInstances(), - exists = $.inArray( this, instances ); - if ( exists !== -1 ) { - instances.splice( exists, 1 ); + resize: function() { + var that = $( this ).resizable( "instance" ); + if ( that.ghost ) { + that.ghost.css( { + position: "relative", + height: that.size.height, + width: that.size.width + } ); } }, - _trackingInstances: function() { - var instances = this.document.data( "ui-dialog-instances" ); - if ( !instances ) { - instances = []; - this.document.data( "ui-dialog-instances", instances ); + stop: function() { + var that = $( this ).resizable( "instance" ); + if ( that.ghost && that.helper ) { + that.helper.get( 0 ).removeChild( that.ghost.get( 0 ) ); } - return instances; - }, + } - _minHeight: function() { - var options = this.options; +} ); - return options.height === "auto" ? - options.minHeight : - Math.min( options.minHeight, options.height ); - }, +$.ui.plugin.add( "resizable", "grid", { - _position: function() { + resize: function() { + var outerDimensions, + that = $( this ).resizable( "instance" ), + o = that.options, + cs = that.size, + os = that.originalSize, + op = that.originalPosition, + a = that.axis, + grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid, + gridX = ( grid[ 0 ] || 1 ), + gridY = ( grid[ 1 ] || 1 ), + ox = Math.round( ( cs.width - os.width ) / gridX ) * gridX, + oy = Math.round( ( cs.height - os.height ) / gridY ) * gridY, + newWidth = os.width + ox, + newHeight = os.height + oy, + isMaxWidth = o.maxWidth && ( o.maxWidth < newWidth ), + isMaxHeight = o.maxHeight && ( o.maxHeight < newHeight ), + isMinWidth = o.minWidth && ( o.minWidth > newWidth ), + isMinHeight = o.minHeight && ( o.minHeight > newHeight ); - // Need to show the dialog to get the actual offset in the position plugin - var isVisible = this.uiDialog.is( ":visible" ); - if ( !isVisible ) { - this.uiDialog.show(); + o.grid = grid; + + if ( isMinWidth ) { + newWidth += gridX; } - this.uiDialog.position( this.options.position ); - if ( !isVisible ) { - this.uiDialog.hide(); + if ( isMinHeight ) { + newHeight += gridY; + } + if ( isMaxWidth ) { + newWidth -= gridX; + } + if ( isMaxHeight ) { + newHeight -= gridY; } - }, - - _setOptions: function( options ) { - var that = this, - resize = false, - resizableOptions = {}; - $.each( options, function( key, value ) { - that._setOption( key, value ); + if ( /^(se|s|e)$/.test( a ) ) { + that.size.width = newWidth; + that.size.height = newHeight; + } else if ( /^(ne)$/.test( a ) ) { + that.size.width = newWidth; + that.size.height = newHeight; + that.position.top = op.top - oy; + } else if ( /^(sw)$/.test( a ) ) { + that.size.width = newWidth; + that.size.height = newHeight; + that.position.left = op.left - ox; + } else { + if ( newHeight - gridY <= 0 || newWidth - gridX <= 0 ) { + outerDimensions = that._getPaddingPlusBorderDimensions( this ); + } - if ( key in that.sizeRelatedOptions ) { - resize = true; + if ( newHeight - gridY > 0 ) { + that.size.height = newHeight; + that.position.top = op.top - oy; + } else { + newHeight = gridY - outerDimensions.height; + that.size.height = newHeight; + that.position.top = op.top + os.height - newHeight; } - if ( key in that.resizableRelatedOptions ) { - resizableOptions[ key ] = value; + if ( newWidth - gridX > 0 ) { + that.size.width = newWidth; + that.position.left = op.left - ox; + } else { + newWidth = gridX - outerDimensions.width; + that.size.width = newWidth; + that.position.left = op.left + os.width - newWidth; } - } ); - - if ( resize ) { - this._size(); - this._position(); - } - if ( this.uiDialog.is( ":data(ui-resizable)" ) ) { - this.uiDialog.resizable( "option", resizableOptions ); } - }, - - _setOption: function( key, value ) { - var isDraggable, isResizable, - uiDialog = this.uiDialog; + } - if ( key === "disabled" ) { - return; - } +} ); - this._super( key, value ); +var widgetsResizable = $.ui.resizable; - if ( key === "appendTo" ) { - this.uiDialog.appendTo( this._appendTo() ); - } - if ( key === "buttons" ) { - this._createButtons(); - } +/*! + * jQuery UI Dialog 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ - if ( key === "closeText" ) { - this.uiDialogTitlebarClose.button( { +//>>label: Dialog +//>>group: Widgets +//>>description: Displays customizable dialog windows. +//>>docs: http://api.jqueryui.com/dialog/ +//>>demos: http://jqueryui.com/dialog/ +//>>css.structure: ../../themes/base/core.css +//>>css.structure: ../../themes/base/dialog.css +//>>css.theme: ../../themes/base/theme.css - // Ensure that we always pass a string - label: $( "<a>" ).text( "" + this.options.closeText ).html() - } ); - } - if ( key === "draggable" ) { - isDraggable = uiDialog.is( ":data(ui-draggable)" ); - if ( isDraggable && !value ) { - uiDialog.draggable( "destroy" ); - } +$.widget( "ui.dialog", { + version: "1.13.2", + options: { + appendTo: "body", + autoOpen: true, + buttons: [], + classes: { + "ui-dialog": "ui-corner-all", + "ui-dialog-titlebar": "ui-corner-all" + }, + closeOnEscape: true, + closeText: "Close", + draggable: true, + hide: null, + height: "auto", + maxHeight: null, + maxWidth: null, + minHeight: 150, + minWidth: 150, + modal: false, + position: { + my: "center", + at: "center", + of: window, + collision: "fit", - if ( !isDraggable && value ) { - this._makeDraggable(); + // Ensure the titlebar is always visible + using: function( pos ) { + var topOffset = $( this ).css( pos ).offset().top; + if ( topOffset < 0 ) { + $( this ).css( "top", pos.top - topOffset ); + } } - } - - if ( key === "position" ) { - this._position(); - } + }, + resizable: true, + show: null, + title: null, + width: 300, - if ( key === "resizable" ) { + // Callbacks + beforeClose: null, + close: null, + drag: null, + dragStart: null, + dragStop: null, + focus: null, + open: null, + resize: null, + resizeStart: null, + resizeStop: null + }, - // currently resizable, becoming non-resizable - isResizable = uiDialog.is( ":data(ui-resizable)" ); - if ( isResizable && !value ) { - uiDialog.resizable( "destroy" ); - } + sizeRelatedOptions: { + buttons: true, + height: true, + maxHeight: true, + maxWidth: true, + minHeight: true, + minWidth: true, + width: true + }, - // Currently resizable, changing handles - if ( isResizable && typeof value === "string" ) { - uiDialog.resizable( "option", "handles", value ); - } + resizableRelatedOptions: { + maxHeight: true, + maxWidth: true, + minHeight: true, + minWidth: true + }, - // Currently non-resizable, becoming resizable - if ( !isResizable && value !== false ) { - this._makeResizable(); - } + _create: function() { + this.originalCss = { + display: this.element[ 0 ].style.display, + width: this.element[ 0 ].style.width, + minHeight: this.element[ 0 ].style.minHeight, + maxHeight: this.element[ 0 ].style.maxHeight, + height: this.element[ 0 ].style.height + }; + this.originalPosition = { + parent: this.element.parent(), + index: this.element.parent().children().index( this.element ) + }; + this.originalTitle = this.element.attr( "title" ); + if ( this.options.title == null && this.originalTitle != null ) { + this.options.title = this.originalTitle; } - if ( key === "title" ) { - this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) ); + // Dialogs can't be disabled + if ( this.options.disabled ) { + this.options.disabled = false; } - }, - _size: function() { - - // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content - // divs will both have width and height set, so we need to reset them - var nonContentHeight, minContentHeight, maxContentHeight, - options = this.options; + this._createWrapper(); - // Reset content sizing - this.element.show().css( { - width: "auto", - minHeight: 0, - maxHeight: "none", - height: 0 - } ); + this.element + .show() + .removeAttr( "title" ) + .appendTo( this.uiDialog ); - if ( options.minWidth > options.width ) { - options.width = options.minWidth; - } + this._addClass( "ui-dialog-content", "ui-widget-content" ); - // Reset wrapper sizing - // determine the height of all the non-content elements - nonContentHeight = this.uiDialog.css( { - height: "auto", - width: options.width - } ) - .outerHeight(); - minContentHeight = Math.max( 0, options.minHeight - nonContentHeight ); - maxContentHeight = typeof options.maxHeight === "number" ? - Math.max( 0, options.maxHeight - nonContentHeight ) : - "none"; + this._createTitlebar(); + this._createButtonPane(); - if ( options.height === "auto" ) { - this.element.css( { - minHeight: minContentHeight, - maxHeight: maxContentHeight, - height: "auto" - } ); - } else { - this.element.height( Math.max( 0, options.height - nonContentHeight ) ); + if ( this.options.draggable && $.fn.draggable ) { + this._makeDraggable(); } - - if ( this.uiDialog.is( ":data(ui-resizable)" ) ) { - this.uiDialog.resizable( "option", "minHeight", this._minHeight() ); + if ( this.options.resizable && $.fn.resizable ) { + this._makeResizable(); } - }, - _blockFrames: function() { - this.iframeBlocks = this.document.find( "iframe" ).map( function() { - var iframe = $( this ); + this._isOpen = false; - return $( "<div>" ) - .css( { - position: "absolute", - width: iframe.outerWidth(), - height: iframe.outerHeight() - } ) - .appendTo( iframe.parent() ) - .offset( iframe.offset() )[ 0 ]; - } ); + this._trackFocus(); }, - _unblockFrames: function() { - if ( this.iframeBlocks ) { - this.iframeBlocks.remove(); - delete this.iframeBlocks; + _init: function() { + if ( this.options.autoOpen ) { + this.open(); } }, - _allowInteraction: function( event ) { - if ( $( event.target ).closest( ".ui-dialog" ).length ) { - return true; + _appendTo: function() { + var element = this.options.appendTo; + if ( element && ( element.jquery || element.nodeType ) ) { + return $( element ); } - - // TODO: Remove hack when datepicker implements - // the .ui-front logic (#8989) - return !!$( event.target ).closest( ".ui-datepicker" ).length; + return this.document.find( element || "body" ).eq( 0 ); }, - _createOverlay: function() { - if ( !this.options.modal ) { - return; - } - - var jqMinor = $.fn.jquery.substring( 0, 4 ); - - // We use a delay in case the overlay is created from an - // event that we're going to be cancelling (#2804) - var isOpening = true; - this._delay( function() { - isOpening = false; - } ); + _destroy: function() { + var next, + originalPosition = this.originalPosition; - if ( !this.document.data( "ui-dialog-overlays" ) ) { + this._untrackInstance(); + this._destroyOverlay(); - // Prevent use of anchors and inputs - // This doesn't use `_on()` because it is a shared event handler - // across all open modal dialogs. - this.document.on( "focusin.ui-dialog", function( event ) { - if ( isOpening ) { - return; - } + this.element + .removeUniqueId() + .css( this.originalCss ) - var instance = this._trackingInstances()[ 0 ]; - if ( !instance._allowInteraction( event ) ) { - event.preventDefault(); - instance._focusTabbable(); + // Without detaching first, the following becomes really slow + .detach(); - // Support: jQuery >=3.4 <3.6 only - // Focus re-triggering in jQuery 3.4/3.5 makes the original element - // have its focus event propagated last, breaking the re-targeting. - // Trigger focus in a delay in addition if needed to avoid the issue - // See https://github.com/jquery/jquery/issues/4382 - if ( jqMinor === "3.4." || jqMinor === "3.5." ) { - instance._delay( instance._restoreTabbableFocus ); - } - } - }.bind( this ) ); + this.uiDialog.remove(); + + if ( this.originalTitle ) { + this.element.attr( "title", this.originalTitle ); } - this.overlay = $( "<div>" ) - .appendTo( this._appendTo() ); + next = originalPosition.parent.children().eq( originalPosition.index ); - this._addClass( this.overlay, null, "ui-widget-overlay ui-front" ); - this._on( this.overlay, { - mousedown: "_keepFocus" - } ); - this.document.data( "ui-dialog-overlays", - ( this.document.data( "ui-dialog-overlays" ) || 0 ) + 1 ); + // Don't try to place the dialog next to itself (#8613) + if ( next.length && next[ 0 ] !== this.element[ 0 ] ) { + next.before( this.element ); + } else { + originalPosition.parent.append( this.element ); + } }, - _destroyOverlay: function() { - if ( !this.options.modal ) { - return; - } + widget: function() { + return this.uiDialog; + }, - if ( this.overlay ) { - var overlays = this.document.data( "ui-dialog-overlays" ) - 1; + disable: $.noop, + enable: $.noop, - if ( !overlays ) { - this.document.off( "focusin.ui-dialog" ); - this.document.removeData( "ui-dialog-overlays" ); - } else { - this.document.data( "ui-dialog-overlays", overlays ); - } + close: function( event ) { + var that = this; - this.overlay.remove(); - this.overlay = null; + if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) { + return; } - } -} ); -// DEPRECATED -// TODO: switch return back to widget declaration at top of file when this is removed -if ( $.uiBackCompat !== false ) { + this._isOpen = false; + this._focusedElement = null; + this._destroyOverlay(); + this._untrackInstance(); - // Backcompat for dialogClass option - $.widget( "ui.dialog", $.ui.dialog, { - options: { - dialogClass: "" - }, - _createWrapper: function() { - this._super(); - this.uiDialog.addClass( this.options.dialogClass ); - }, - _setOption: function( key, value ) { - if ( key === "dialogClass" ) { - this.uiDialog - .removeClass( this.options.dialogClass ) - .addClass( value ); - } - this._superApply( arguments ); - } - } ); -} + if ( !this.opener.filter( ":focusable" ).trigger( "focus" ).length ) { -var widgetsDialog = $.ui.dialog; + // Hiding a focused element doesn't trigger blur in WebKit + // so in case we have nothing to focus on, explicitly blur the active element + // https://bugs.webkit.org/show_bug.cgi?id=47182 + $.ui.safeBlur( $.ui.safeActiveElement( this.document[ 0 ] ) ); + } + this._hide( this.uiDialog, this.options.hide, function() { + that._trigger( "close", event ); + } ); + }, -/*! - * jQuery UI Progressbar 1.13.1 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ + isOpen: function() { + return this._isOpen; + }, -//>>label: Progressbar -//>>group: Widgets -/* eslint-disable max-len */ -//>>description: Displays a status indicator for loading state, standard percentage, and other progress indicators. -/* eslint-enable max-len */ -//>>docs: http://api.jqueryui.com/progressbar/ -//>>demos: http://jqueryui.com/progressbar/ -//>>css.structure: ../../themes/base/core.css -//>>css.structure: ../../themes/base/progressbar.css -//>>css.theme: ../../themes/base/theme.css + moveToTop: function() { + this._moveToTop(); + }, + _moveToTop: function( event, silent ) { + var moved = false, + zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map( function() { + return +$( this ).css( "z-index" ); + } ).get(), + zIndexMax = Math.max.apply( null, zIndices ); -var widgetsProgressbar = $.widget( "ui.progressbar", { - version: "1.13.1", - options: { - classes: { - "ui-progressbar": "ui-corner-all", - "ui-progressbar-value": "ui-corner-left", - "ui-progressbar-complete": "ui-corner-right" - }, - max: 100, - value: 0, + if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) { + this.uiDialog.css( "z-index", zIndexMax + 1 ); + moved = true; + } - change: null, - complete: null + if ( moved && !silent ) { + this._trigger( "focus", event ); + } + return moved; }, - min: 0, + open: function() { + var that = this; + if ( this._isOpen ) { + if ( this._moveToTop() ) { + this._focusTabbable(); + } + return; + } - _create: function() { + this._isOpen = true; + this.opener = $( $.ui.safeActiveElement( this.document[ 0 ] ) ); - // Constrain initial value - this.oldValue = this.options.value = this._constrainedValue(); + this._size(); + this._position(); + this._createOverlay(); + this._moveToTop( null, true ); - this.element.attr( { + // Ensure the overlay is moved to the top with the dialog, but only when + // opening. The overlay shouldn't move after the dialog is open so that + // modeless dialogs opened after the modal dialog stack properly. + if ( this.overlay ) { + this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 ); + } - // Only set static values; aria-valuenow and aria-valuemax are - // set inside _refreshValue() - role: "progressbar", - "aria-valuemin": this.min + this._show( this.uiDialog, this.options.show, function() { + that._focusTabbable(); + that._trigger( "focus" ); } ); - this._addClass( "ui-progressbar", "ui-widget ui-widget-content" ); - - this.valueDiv = $( "<div>" ).appendTo( this.element ); - this._addClass( this.valueDiv, "ui-progressbar-value", "ui-widget-header" ); - this._refreshValue(); - }, - _destroy: function() { - this.element.removeAttr( "role aria-valuemin aria-valuemax aria-valuenow" ); + // Track the dialog immediately upon opening in case a focus event + // somehow occurs outside of the dialog before an element inside the + // dialog is focused (#10152) + this._makeFocusTarget(); - this.valueDiv.remove(); + this._trigger( "open" ); }, - value: function( newValue ) { - if ( newValue === undefined ) { - return this.options.value; - } + _focusTabbable: function() { - this.options.value = this._constrainedValue( newValue ); - this._refreshValue(); + // Set focus to the first match: + // 1. An element that was focused previously + // 2. First element inside the dialog matching [autofocus] + // 3. Tabbable element inside the content element + // 4. Tabbable element inside the buttonpane + // 5. The close button + // 6. The dialog itself + var hasFocus = this._focusedElement; + if ( !hasFocus ) { + hasFocus = this.element.find( "[autofocus]" ); + } + if ( !hasFocus.length ) { + hasFocus = this.element.find( ":tabbable" ); + } + if ( !hasFocus.length ) { + hasFocus = this.uiDialogButtonPane.find( ":tabbable" ); + } + if ( !hasFocus.length ) { + hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" ); + } + if ( !hasFocus.length ) { + hasFocus = this.uiDialog; + } + hasFocus.eq( 0 ).trigger( "focus" ); }, - _constrainedValue: function( newValue ) { - if ( newValue === undefined ) { - newValue = this.options.value; + _restoreTabbableFocus: function() { + var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ), + isActive = this.uiDialog[ 0 ] === activeElement || + $.contains( this.uiDialog[ 0 ], activeElement ); + if ( !isActive ) { + this._focusTabbable(); } + }, - this.indeterminate = newValue === false; - - // Sanitize value - if ( typeof newValue !== "number" ) { - newValue = 0; - } + _keepFocus: function( event ) { + event.preventDefault(); + this._restoreTabbableFocus(); - return this.indeterminate ? false : - Math.min( this.options.max, Math.max( this.min, newValue ) ); + // support: IE + // IE <= 8 doesn't prevent moving focus even with event.preventDefault() + // so we check again later + this._delay( this._restoreTabbableFocus ); }, - _setOptions: function( options ) { + _createWrapper: function() { + this.uiDialog = $( "<div>" ) + .hide() + .attr( { - // Ensure "value" option is set after other values (like max) - var value = options.value; - delete options.value; + // Setting tabIndex makes the div focusable + tabIndex: -1, + role: "dialog" + } ) + .appendTo( this._appendTo() ); - this._super( options ); + this._addClass( this.uiDialog, "ui-dialog", "ui-widget ui-widget-content ui-front" ); + this._on( this.uiDialog, { + keydown: function( event ) { + if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && + event.keyCode === $.ui.keyCode.ESCAPE ) { + event.preventDefault(); + this.close( event ); + return; + } - this.options.value = this._constrainedValue( value ); - this._refreshValue(); - }, + // Prevent tabbing out of dialogs + if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) { + return; + } + var tabbables = this.uiDialog.find( ":tabbable" ), + first = tabbables.first(), + last = tabbables.last(); - _setOption: function( key, value ) { - if ( key === "max" ) { + if ( ( event.target === last[ 0 ] || event.target === this.uiDialog[ 0 ] ) && + !event.shiftKey ) { + this._delay( function() { + first.trigger( "focus" ); + } ); + event.preventDefault(); + } else if ( ( event.target === first[ 0 ] || + event.target === this.uiDialog[ 0 ] ) && event.shiftKey ) { + this._delay( function() { + last.trigger( "focus" ); + } ); + event.preventDefault(); + } + }, + mousedown: function( event ) { + if ( this._moveToTop( event ) ) { + this._focusTabbable(); + } + } + } ); - // Don't allow a max less than min - value = Math.max( this.min, value ); + // We assume that any existing aria-describedby attribute means + // that the dialog content is marked up properly + // otherwise we brute force the content as the description + if ( !this.element.find( "[aria-describedby]" ).length ) { + this.uiDialog.attr( { + "aria-describedby": this.element.uniqueId().attr( "id" ) + } ); } - this._super( key, value ); }, - _setOptionDisabled: function( value ) { - this._super( value ); - - this.element.attr( "aria-disabled", value ); - this._toggleClass( null, "ui-state-disabled", !!value ); - }, + _createTitlebar: function() { + var uiDialogTitle; - _percentage: function() { - return this.indeterminate ? - 100 : - 100 * ( this.options.value - this.min ) / ( this.options.max - this.min ); - }, + this.uiDialogTitlebar = $( "<div>" ); + this._addClass( this.uiDialogTitlebar, + "ui-dialog-titlebar", "ui-widget-header ui-helper-clearfix" ); + this._on( this.uiDialogTitlebar, { + mousedown: function( event ) { - _refreshValue: function() { - var value = this.options.value, - percentage = this._percentage(); + // Don't prevent click on close button (#8838) + // Focusing a dialog that is partially scrolled out of view + // causes the browser to scroll it into view, preventing the click event + if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) { - this.valueDiv - .toggle( this.indeterminate || value > this.min ) - .width( percentage.toFixed( 0 ) + "%" ); + // Dialog isn't getting focus when dragging (#8063) + this.uiDialog.trigger( "focus" ); + } + } + } ); - this - ._toggleClass( this.valueDiv, "ui-progressbar-complete", null, - value === this.options.max ) - ._toggleClass( "ui-progressbar-indeterminate", null, this.indeterminate ); + // Support: IE + // Use type="button" to prevent enter keypresses in textboxes from closing the + // dialog in IE (#9312) + this.uiDialogTitlebarClose = $( "<button type='button'></button>" ) + .button( { + label: $( "<a>" ).text( this.options.closeText ).html(), + icon: "ui-icon-closethick", + showLabel: false + } ) + .appendTo( this.uiDialogTitlebar ); - if ( this.indeterminate ) { - this.element.removeAttr( "aria-valuenow" ); - if ( !this.overlayDiv ) { - this.overlayDiv = $( "<div>" ).appendTo( this.valueDiv ); - this._addClass( this.overlayDiv, "ui-progressbar-overlay" ); - } - } else { - this.element.attr( { - "aria-valuemax": this.options.max, - "aria-valuenow": value - } ); - if ( this.overlayDiv ) { - this.overlayDiv.remove(); - this.overlayDiv = null; + this._addClass( this.uiDialogTitlebarClose, "ui-dialog-titlebar-close" ); + this._on( this.uiDialogTitlebarClose, { + click: function( event ) { + event.preventDefault(); + this.close( event ); } - } + } ); - if ( this.oldValue !== value ) { - this.oldValue = value; - this._trigger( "change" ); - } - if ( value === this.options.max ) { - this._trigger( "complete" ); - } - } -} ); + uiDialogTitle = $( "<span>" ).uniqueId().prependTo( this.uiDialogTitlebar ); + this._addClass( uiDialogTitle, "ui-dialog-title" ); + this._title( uiDialogTitle ); + this.uiDialogTitlebar.prependTo( this.uiDialog ); -/*! - * jQuery UI Selectmenu 1.13.1 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ + this.uiDialog.attr( { + "aria-labelledby": uiDialogTitle.attr( "id" ) + } ); + }, -//>>label: Selectmenu -//>>group: Widgets -/* eslint-disable max-len */ -//>>description: Duplicates and extends the functionality of a native HTML select element, allowing it to be customizable in behavior and appearance far beyond the limitations of a native select. -/* eslint-enable max-len */ -//>>docs: http://api.jqueryui.com/selectmenu/ -//>>demos: http://jqueryui.com/selectmenu/ -//>>css.structure: ../../themes/base/core.css -//>>css.structure: ../../themes/base/selectmenu.css, ../../themes/base/button.css -//>>css.theme: ../../themes/base/theme.css + _title: function( title ) { + if ( this.options.title ) { + title.text( this.options.title ); + } else { + title.html( " " ); + } + }, + _createButtonPane: function() { + this.uiDialogButtonPane = $( "<div>" ); + this._addClass( this.uiDialogButtonPane, "ui-dialog-buttonpane", + "ui-widget-content ui-helper-clearfix" ); -var widgetsSelectmenu = $.widget( "ui.selectmenu", [ $.ui.formResetMixin, { - version: "1.13.1", - defaultElement: "<select>", - options: { - appendTo: null, - classes: { - "ui-selectmenu-button-open": "ui-corner-top", - "ui-selectmenu-button-closed": "ui-corner-all" - }, - disabled: null, - icons: { - button: "ui-icon-triangle-1-s" - }, - position: { - my: "left top", - at: "left bottom", - collision: "none" - }, - width: false, + this.uiButtonSet = $( "<div>" ) + .appendTo( this.uiDialogButtonPane ); + this._addClass( this.uiButtonSet, "ui-dialog-buttonset" ); - // Callbacks - change: null, - close: null, - focus: null, - open: null, - select: null + this._createButtons(); }, - _create: function() { - var selectmenuId = this.element.uniqueId().attr( "id" ); - this.ids = { - element: selectmenuId, - button: selectmenuId + "-button", - menu: selectmenuId + "-menu" - }; + _createButtons: function() { + var that = this, + buttons = this.options.buttons; - this._drawButton(); - this._drawMenu(); - this._bindFormResetHandler(); + // If we already have a button pane, remove it + this.uiDialogButtonPane.remove(); + this.uiButtonSet.empty(); - this._rendered = false; - this.menuItems = $(); - }, + if ( $.isEmptyObject( buttons ) || ( Array.isArray( buttons ) && !buttons.length ) ) { + this._removeClass( this.uiDialog, "ui-dialog-buttons" ); + return; + } - _drawButton: function() { - var icon, - that = this, - item = this._parseOption( - this.element.find( "option:selected" ), - this.element[ 0 ].selectedIndex - ); + $.each( buttons, function( name, props ) { + var click, buttonOptions; + props = typeof props === "function" ? + { click: props, text: name } : + props; - // Associate existing label with the new button - this.labels = this.element.labels().attr( "for", this.ids.button ); - this._on( this.labels, { - click: function( event ) { - this.button.trigger( "focus" ); - event.preventDefault(); - } - } ); + // Default to a non-submitting button + props = $.extend( { type: "button" }, props ); + + // Change the context for the click callback to be the main element + click = props.click; + buttonOptions = { + icon: props.icon, + iconPosition: props.iconPosition, + showLabel: props.showLabel, - // Hide original select element - this.element.hide(); + // Deprecated options + icons: props.icons, + text: props.text + }; - // Create button - this.button = $( "<span>", { - tabindex: this.options.disabled ? -1 : 0, - id: this.ids.button, - role: "combobox", - "aria-expanded": "false", - "aria-autocomplete": "list", - "aria-owns": this.ids.menu, - "aria-haspopup": "true", - title: this.element.attr( "title" ) - } ) - .insertAfter( this.element ); + delete props.click; + delete props.icon; + delete props.iconPosition; + delete props.showLabel; - this._addClass( this.button, "ui-selectmenu-button ui-selectmenu-button-closed", - "ui-button ui-widget" ); + // Deprecated options + delete props.icons; + if ( typeof props.text === "boolean" ) { + delete props.text; + } - icon = $( "<span>" ).appendTo( this.button ); - this._addClass( icon, "ui-selectmenu-icon", "ui-icon " + this.options.icons.button ); - this.buttonItem = this._renderButtonItem( item ) - .appendTo( this.button ); + $( "<button></button>", props ) + .button( buttonOptions ) + .appendTo( that.uiButtonSet ) + .on( "click", function() { + click.apply( that.element[ 0 ], arguments ); + } ); + } ); + this._addClass( this.uiDialog, "ui-dialog-buttons" ); + this.uiDialogButtonPane.appendTo( this.uiDialog ); + }, - if ( this.options.width !== false ) { - this._resizeButton(); + _makeDraggable: function() { + var that = this, + options = this.options; + + function filteredUi( ui ) { + return { + position: ui.position, + offset: ui.offset + }; } - this._on( this.button, this._buttonEvents ); - this.button.one( "focusin", function() { + this.uiDialog.draggable( { + cancel: ".ui-dialog-content, .ui-dialog-titlebar-close", + handle: ".ui-dialog-titlebar", + containment: "document", + start: function( event, ui ) { + that._addClass( $( this ), "ui-dialog-dragging" ); + that._blockFrames(); + that._trigger( "dragStart", event, filteredUi( ui ) ); + }, + drag: function( event, ui ) { + that._trigger( "drag", event, filteredUi( ui ) ); + }, + stop: function( event, ui ) { + var left = ui.offset.left - that.document.scrollLeft(), + top = ui.offset.top - that.document.scrollTop(); - // Delay rendering the menu items until the button receives focus. - // The menu may have already been rendered via a programmatic open. - if ( !that._rendered ) { - that._refreshMenu(); + options.position = { + my: "left top", + at: "left" + ( left >= 0 ? "+" : "" ) + left + " " + + "top" + ( top >= 0 ? "+" : "" ) + top, + of: that.window + }; + that._removeClass( $( this ), "ui-dialog-dragging" ); + that._unblockFrames(); + that._trigger( "dragStop", event, filteredUi( ui ) ); } } ); }, - _drawMenu: function() { - var that = this; + _makeResizable: function() { + var that = this, + options = this.options, + handles = options.resizable, - // Create menu - this.menu = $( "<ul>", { - "aria-hidden": "true", - "aria-labelledby": this.ids.button, - id: this.ids.menu - } ); + // .ui-resizable has position: relative defined in the stylesheet + // but dialogs have to use absolute or fixed positioning + position = this.uiDialog.css( "position" ), + resizeHandles = typeof handles === "string" ? + handles : + "n,e,s,w,se,sw,ne,nw"; - // Wrap menu - this.menuWrap = $( "<div>" ).append( this.menu ); - this._addClass( this.menuWrap, "ui-selectmenu-menu", "ui-front" ); - this.menuWrap.appendTo( this._appendTo() ); + function filteredUi( ui ) { + return { + originalPosition: ui.originalPosition, + originalSize: ui.originalSize, + position: ui.position, + size: ui.size + }; + } - // Initialize menu widget - this.menuInstance = this.menu - .menu( { - classes: { - "ui-menu": "ui-corner-bottom" - }, - role: "listbox", - select: function( event, ui ) { - event.preventDefault(); + this.uiDialog.resizable( { + cancel: ".ui-dialog-content", + containment: "document", + alsoResize: this.element, + maxWidth: options.maxWidth, + maxHeight: options.maxHeight, + minWidth: options.minWidth, + minHeight: this._minHeight(), + handles: resizeHandles, + start: function( event, ui ) { + that._addClass( $( this ), "ui-dialog-resizing" ); + that._blockFrames(); + that._trigger( "resizeStart", event, filteredUi( ui ) ); + }, + resize: function( event, ui ) { + that._trigger( "resize", event, filteredUi( ui ) ); + }, + stop: function( event, ui ) { + var offset = that.uiDialog.offset(), + left = offset.left - that.document.scrollLeft(), + top = offset.top - that.document.scrollTop(); - // Support: IE8 - // If the item was selected via a click, the text selection - // will be destroyed in IE - that._setSelection(); + options.height = that.uiDialog.height(); + options.width = that.uiDialog.width(); + options.position = { + my: "left top", + at: "left" + ( left >= 0 ? "+" : "" ) + left + " " + + "top" + ( top >= 0 ? "+" : "" ) + top, + of: that.window + }; + that._removeClass( $( this ), "ui-dialog-resizing" ); + that._unblockFrames(); + that._trigger( "resizeStop", event, filteredUi( ui ) ); + } + } ) + .css( "position", position ); + }, - that._select( ui.item.data( "ui-selectmenu-item" ), event ); - }, - focus: function( event, ui ) { - var item = ui.item.data( "ui-selectmenu-item" ); + _trackFocus: function() { + this._on( this.widget(), { + focusin: function( event ) { + this._makeFocusTarget(); + this._focusedElement = $( event.target ); + } + } ); + }, - // Prevent inital focus from firing and check if its a newly focused item - if ( that.focusIndex != null && item.index !== that.focusIndex ) { - that._trigger( "focus", event, { item: item } ); - if ( !that.isOpen ) { - that._select( item, event ); - } - } - that.focusIndex = item.index; + _makeFocusTarget: function() { + this._untrackInstance(); + this._trackingInstances().unshift( this ); + }, - that.button.attr( "aria-activedescendant", - that.menuItems.eq( item.index ).attr( "id" ) ); - } - } ) - .menu( "instance" ); + _untrackInstance: function() { + var instances = this._trackingInstances(), + exists = $.inArray( this, instances ); + if ( exists !== -1 ) { + instances.splice( exists, 1 ); + } + }, - // Don't close the menu on mouseleave - this.menuInstance._off( this.menu, "mouseleave" ); + _trackingInstances: function() { + var instances = this.document.data( "ui-dialog-instances" ); + if ( !instances ) { + instances = []; + this.document.data( "ui-dialog-instances", instances ); + } + return instances; + }, - // Cancel the menu's collapseAll on document click - this.menuInstance._closeOnDocumentClick = function() { - return false; - }; + _minHeight: function() { + var options = this.options; - // Selects often contain empty items, but never contain dividers - this.menuInstance._isDivider = function() { - return false; - }; + return options.height === "auto" ? + options.minHeight : + Math.min( options.minHeight, options.height ); }, - refresh: function() { - this._refreshMenu(); - this.buttonItem.replaceWith( - this.buttonItem = this._renderButtonItem( + _position: function() { - // Fall back to an empty object in case there are no options - this._getSelectedItem().data( "ui-selectmenu-item" ) || {} - ) - ); - if ( this.options.width === null ) { - this._resizeButton(); + // Need to show the dialog to get the actual offset in the position plugin + var isVisible = this.uiDialog.is( ":visible" ); + if ( !isVisible ) { + this.uiDialog.show(); + } + this.uiDialog.position( this.options.position ); + if ( !isVisible ) { + this.uiDialog.hide(); } }, - _refreshMenu: function() { - var item, - options = this.element.find( "option" ); + _setOptions: function( options ) { + var that = this, + resize = false, + resizableOptions = {}; - this.menu.empty(); + $.each( options, function( key, value ) { + that._setOption( key, value ); - this._parseOptions( options ); - this._renderMenu( this.menu, this.items ); + if ( key in that.sizeRelatedOptions ) { + resize = true; + } + if ( key in that.resizableRelatedOptions ) { + resizableOptions[ key ] = value; + } + } ); - this.menuInstance.refresh(); - this.menuItems = this.menu.find( "li" ) - .not( ".ui-selectmenu-optgroup" ) - .find( ".ui-menu-item-wrapper" ); + if ( resize ) { + this._size(); + this._position(); + } + if ( this.uiDialog.is( ":data(ui-resizable)" ) ) { + this.uiDialog.resizable( "option", resizableOptions ); + } + }, - this._rendered = true; + _setOption: function( key, value ) { + var isDraggable, isResizable, + uiDialog = this.uiDialog; - if ( !options.length ) { + if ( key === "disabled" ) { return; } - item = this._getSelectedItem(); + this._super( key, value ); - // Update the menu to have the correct item focused - this.menuInstance.focus( null, item ); - this._setAria( item.data( "ui-selectmenu-item" ) ); + if ( key === "appendTo" ) { + this.uiDialog.appendTo( this._appendTo() ); + } - // Set disabled state - this._setOption( "disabled", this.element.prop( "disabled" ) ); - }, + if ( key === "buttons" ) { + this._createButtons(); + } - open: function( event ) { - if ( this.options.disabled ) { - return; + if ( key === "closeText" ) { + this.uiDialogTitlebarClose.button( { + + // Ensure that we always pass a string + label: $( "<a>" ).text( "" + this.options.closeText ).html() + } ); } - // If this is the first time the menu is being opened, render the items - if ( !this._rendered ) { - this._refreshMenu(); - } else { + if ( key === "draggable" ) { + isDraggable = uiDialog.is( ":data(ui-draggable)" ); + if ( isDraggable && !value ) { + uiDialog.draggable( "destroy" ); + } - // Menu clears focus on close, reset focus to selected item - this._removeClass( this.menu.find( ".ui-state-active" ), null, "ui-state-active" ); - this.menuInstance.focus( null, this._getSelectedItem() ); + if ( !isDraggable && value ) { + this._makeDraggable(); + } } - // If there are no options, don't open the menu - if ( !this.menuItems.length ) { - return; + if ( key === "position" ) { + this._position(); } - this.isOpen = true; - this._toggleAttr(); - this._resizeMenu(); - this._position(); + if ( key === "resizable" ) { - this._on( this.document, this._documentClick ); + // currently resizable, becoming non-resizable + isResizable = uiDialog.is( ":data(ui-resizable)" ); + if ( isResizable && !value ) { + uiDialog.resizable( "destroy" ); + } - this._trigger( "open", event ); - }, + // Currently resizable, changing handles + if ( isResizable && typeof value === "string" ) { + uiDialog.resizable( "option", "handles", value ); + } - _position: function() { - this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) ); - }, + // Currently non-resizable, becoming resizable + if ( !isResizable && value !== false ) { + this._makeResizable(); + } + } - close: function( event ) { - if ( !this.isOpen ) { - return; + if ( key === "title" ) { + this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) ); } + }, - this.isOpen = false; - this._toggleAttr(); + _size: function() { - this.range = null; - this._off( this.document ); + // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content + // divs will both have width and height set, so we need to reset them + var nonContentHeight, minContentHeight, maxContentHeight, + options = this.options; - this._trigger( "close", event ); - }, + // Reset content sizing + this.element.show().css( { + width: "auto", + minHeight: 0, + maxHeight: "none", + height: 0 + } ); - widget: function() { - return this.button; - }, + if ( options.minWidth > options.width ) { + options.width = options.minWidth; + } - menuWidget: function() { - return this.menu; - }, + // Reset wrapper sizing + // determine the height of all the non-content elements + nonContentHeight = this.uiDialog.css( { + height: "auto", + width: options.width + } ) + .outerHeight(); + minContentHeight = Math.max( 0, options.minHeight - nonContentHeight ); + maxContentHeight = typeof options.maxHeight === "number" ? + Math.max( 0, options.maxHeight - nonContentHeight ) : + "none"; - _renderButtonItem: function( item ) { - var buttonItem = $( "<span>" ); + if ( options.height === "auto" ) { + this.element.css( { + minHeight: minContentHeight, + maxHeight: maxContentHeight, + height: "auto" + } ); + } else { + this.element.height( Math.max( 0, options.height - nonContentHeight ) ); + } - this._setText( buttonItem, item.label ); - this._addClass( buttonItem, "ui-selectmenu-text" ); + if ( this.uiDialog.is( ":data(ui-resizable)" ) ) { + this.uiDialog.resizable( "option", "minHeight", this._minHeight() ); + } + }, - return buttonItem; + _blockFrames: function() { + this.iframeBlocks = this.document.find( "iframe" ).map( function() { + var iframe = $( this ); + + return $( "<div>" ) + .css( { + position: "absolute", + width: iframe.outerWidth(), + height: iframe.outerHeight() + } ) + .appendTo( iframe.parent() ) + .offset( iframe.offset() )[ 0 ]; + } ); }, - _renderMenu: function( ul, items ) { - var that = this, - currentOptgroup = ""; + _unblockFrames: function() { + if ( this.iframeBlocks ) { + this.iframeBlocks.remove(); + delete this.iframeBlocks; + } + }, - $.each( items, function( index, item ) { - var li; + _allowInteraction: function( event ) { + if ( $( event.target ).closest( ".ui-dialog" ).length ) { + return true; + } - if ( item.optgroup !== currentOptgroup ) { - li = $( "<li>", { - text: item.optgroup - } ); - that._addClass( li, "ui-selectmenu-optgroup", "ui-menu-divider" + - ( item.element.parent( "optgroup" ).prop( "disabled" ) ? - " ui-state-disabled" : - "" ) ); + // TODO: Remove hack when datepicker implements + // the .ui-front logic (#8989) + return !!$( event.target ).closest( ".ui-datepicker" ).length; + }, - li.appendTo( ul ); + _createOverlay: function() { + if ( !this.options.modal ) { + return; + } - currentOptgroup = item.optgroup; - } + var jqMinor = $.fn.jquery.substring( 0, 4 ); - that._renderItemData( ul, item ); + // We use a delay in case the overlay is created from an + // event that we're going to be cancelling (#2804) + var isOpening = true; + this._delay( function() { + isOpening = false; } ); - }, - _renderItemData: function( ul, item ) { - return this._renderItem( ul, item ).data( "ui-selectmenu-item", item ); - }, + if ( !this.document.data( "ui-dialog-overlays" ) ) { - _renderItem: function( ul, item ) { - var li = $( "<li>" ), - wrapper = $( "<div>", { - title: item.element.attr( "title" ) - } ); + // Prevent use of anchors and inputs + // This doesn't use `_on()` because it is a shared event handler + // across all open modal dialogs. + this.document.on( "focusin.ui-dialog", function( event ) { + if ( isOpening ) { + return; + } - if ( item.disabled ) { - this._addClass( li, null, "ui-state-disabled" ); + var instance = this._trackingInstances()[ 0 ]; + if ( !instance._allowInteraction( event ) ) { + event.preventDefault(); + instance._focusTabbable(); + + // Support: jQuery >=3.4 <3.6 only + // Focus re-triggering in jQuery 3.4/3.5 makes the original element + // have its focus event propagated last, breaking the re-targeting. + // Trigger focus in a delay in addition if needed to avoid the issue + // See https://github.com/jquery/jquery/issues/4382 + if ( jqMinor === "3.4." || jqMinor === "3.5." ) { + instance._delay( instance._restoreTabbableFocus ); + } + } + }.bind( this ) ); } - this._setText( wrapper, item.label ); - return li.append( wrapper ).appendTo( ul ); + this.overlay = $( "<div>" ) + .appendTo( this._appendTo() ); + + this._addClass( this.overlay, null, "ui-widget-overlay ui-front" ); + this._on( this.overlay, { + mousedown: "_keepFocus" + } ); + this.document.data( "ui-dialog-overlays", + ( this.document.data( "ui-dialog-overlays" ) || 0 ) + 1 ); }, - _setText: function( element, value ) { - if ( value ) { - element.text( value ); - } else { - element.html( " " ); + _destroyOverlay: function() { + if ( !this.options.modal ) { + return; } - }, - _move: function( direction, event ) { - var item, next, - filter = ".ui-menu-item"; + if ( this.overlay ) { + var overlays = this.document.data( "ui-dialog-overlays" ) - 1; - if ( this.isOpen ) { - item = this.menuItems.eq( this.focusIndex ).parent( "li" ); - } else { - item = this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" ); - filter += ":not(.ui-state-disabled)"; - } + if ( !overlays ) { + this.document.off( "focusin.ui-dialog" ); + this.document.removeData( "ui-dialog-overlays" ); + } else { + this.document.data( "ui-dialog-overlays", overlays ); + } - if ( direction === "first" || direction === "last" ) { - next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 ); - } else { - next = item[ direction + "All" ]( filter ).eq( 0 ); + this.overlay.remove(); + this.overlay = null; } + } +} ); - if ( next.length ) { - this.menuInstance.focus( event, next ); +// DEPRECATED +// TODO: switch return back to widget declaration at top of file when this is removed +if ( $.uiBackCompat !== false ) { + + // Backcompat for dialogClass option + $.widget( "ui.dialog", $.ui.dialog, { + options: { + dialogClass: "" + }, + _createWrapper: function() { + this._super(); + this.uiDialog.addClass( this.options.dialogClass ); + }, + _setOption: function( key, value ) { + if ( key === "dialogClass" ) { + this.uiDialog + .removeClass( this.options.dialogClass ) + .addClass( value ); + } + this._superApply( arguments ); } - }, + } ); +} - _getSelectedItem: function() { - return this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" ); - }, +var widgetsDialog = $.ui.dialog; - _toggle: function( event ) { - this[ this.isOpen ? "close" : "open" ]( event ); - }, - _setSelection: function() { - var selection; +/*! + * jQuery UI Droppable 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ - if ( !this.range ) { - return; - } +//>>label: Droppable +//>>group: Interactions +//>>description: Enables drop targets for draggable elements. +//>>docs: http://api.jqueryui.com/droppable/ +//>>demos: http://jqueryui.com/droppable/ - if ( window.getSelection ) { - selection = window.getSelection(); - selection.removeAllRanges(); - selection.addRange( this.range ); - // Support: IE8 - } else { - this.range.select(); - } +$.widget( "ui.droppable", { + version: "1.13.2", + widgetEventPrefix: "drop", + options: { + accept: "*", + addClasses: true, + greedy: false, + scope: "default", + tolerance: "intersect", - // Support: IE - // Setting the text selection kills the button focus in IE, but - // restoring the focus doesn't kill the selection. - this.button.focus(); + // Callbacks + activate: null, + deactivate: null, + drop: null, + out: null, + over: null }, + _create: function() { - _documentClick: { - mousedown: function( event ) { - if ( !this.isOpen ) { - return; - } - - if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" + - $.escapeSelector( this.ids.button ) ).length ) { - this.close( event ); - } - } - }, + var proportions, + o = this.options, + accept = o.accept; - _buttonEvents: { + this.isover = false; + this.isout = true; - // Prevent text selection from being reset when interacting with the selectmenu (#10144) - mousedown: function() { - var selection; + this.accept = typeof accept === "function" ? accept : function( d ) { + return d.is( accept ); + }; - if ( window.getSelection ) { - selection = window.getSelection(); - if ( selection.rangeCount ) { - this.range = selection.getRangeAt( 0 ); - } + this.proportions = function( /* valueToWrite */ ) { + if ( arguments.length ) { - // Support: IE8 + // Store the droppable's proportions + proportions = arguments[ 0 ]; } else { - this.range = document.selection.createRange(); - } - }, - - click: function( event ) { - this._setSelection(); - this._toggle( event ); - }, - keydown: function( event ) { - var preventDefault = true; - switch ( event.keyCode ) { - case $.ui.keyCode.TAB: - case $.ui.keyCode.ESCAPE: - this.close( event ); - preventDefault = false; - break; - case $.ui.keyCode.ENTER: - if ( this.isOpen ) { - this._selectFocusedItem( event ); - } - break; - case $.ui.keyCode.UP: - if ( event.altKey ) { - this._toggle( event ); - } else { - this._move( "prev", event ); - } - break; - case $.ui.keyCode.DOWN: - if ( event.altKey ) { - this._toggle( event ); - } else { - this._move( "next", event ); - } - break; - case $.ui.keyCode.SPACE: - if ( this.isOpen ) { - this._selectFocusedItem( event ); - } else { - this._toggle( event ); - } - break; - case $.ui.keyCode.LEFT: - this._move( "prev", event ); - break; - case $.ui.keyCode.RIGHT: - this._move( "next", event ); - break; - case $.ui.keyCode.HOME: - case $.ui.keyCode.PAGE_UP: - this._move( "first", event ); - break; - case $.ui.keyCode.END: - case $.ui.keyCode.PAGE_DOWN: - this._move( "last", event ); - break; - default: - this.menu.trigger( event ); - preventDefault = false; + // Retrieve or derive the droppable's proportions + return proportions ? + proportions : + proportions = { + width: this.element[ 0 ].offsetWidth, + height: this.element[ 0 ].offsetHeight + }; } + }; - if ( preventDefault ) { - event.preventDefault(); - } - } - }, + this._addToManager( o.scope ); - _selectFocusedItem: function( event ) { - var item = this.menuItems.eq( this.focusIndex ).parent( "li" ); - if ( !item.hasClass( "ui-state-disabled" ) ) { - this._select( item.data( "ui-selectmenu-item" ), event ); + if ( o.addClasses ) { + this._addClass( "ui-droppable" ); } + }, - _select: function( item, event ) { - var oldIndex = this.element[ 0 ].selectedIndex; + _addToManager: function( scope ) { - // Change native select element - this.element[ 0 ].selectedIndex = item.index; - this.buttonItem.replaceWith( this.buttonItem = this._renderButtonItem( item ) ); - this._setAria( item ); - this._trigger( "select", event, { item: item } ); + // Add the reference and positions to the manager + $.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || []; + $.ui.ddmanager.droppables[ scope ].push( this ); + }, - if ( item.index !== oldIndex ) { - this._trigger( "change", event, { item: item } ); + _splice: function( drop ) { + var i = 0; + for ( ; i < drop.length; i++ ) { + if ( drop[ i ] === this ) { + drop.splice( i, 1 ); + } } - - this.close( event ); }, - _setAria: function( item ) { - var id = this.menuItems.eq( item.index ).attr( "id" ); + _destroy: function() { + var drop = $.ui.ddmanager.droppables[ this.options.scope ]; - this.button.attr( { - "aria-labelledby": id, - "aria-activedescendant": id - } ); - this.menu.attr( "aria-activedescendant", id ); + this._splice( drop ); }, _setOption: function( key, value ) { - if ( key === "icons" ) { - var icon = this.button.find( "span.ui-icon" ); - this._removeClass( icon, null, this.options.icons.button ) - ._addClass( icon, null, value.button ); + + if ( key === "accept" ) { + this.accept = typeof value === "function" ? value : function( d ) { + return d.is( value ); + }; + } else if ( key === "scope" ) { + var drop = $.ui.ddmanager.droppables[ this.options.scope ]; + + this._splice( drop ); + this._addToManager( value ); } this._super( key, value ); + }, - if ( key === "appendTo" ) { - this.menuWrap.appendTo( this._appendTo() ); - } + _activate: function( event ) { + var draggable = $.ui.ddmanager.current; - if ( key === "width" ) { - this._resizeButton(); + this._addActiveClass(); + if ( draggable ) { + this._trigger( "activate", event, this.ui( draggable ) ); } }, - _setOptionDisabled: function( value ) { - this._super( value ); - - this.menuInstance.option( "disabled", value ); - this.button.attr( "aria-disabled", value ); - this._toggleClass( this.button, null, "ui-state-disabled", value ); + _deactivate: function( event ) { + var draggable = $.ui.ddmanager.current; - this.element.prop( "disabled", value ); - if ( value ) { - this.button.attr( "tabindex", -1 ); - this.close(); - } else { - this.button.attr( "tabindex", 0 ); + this._removeActiveClass(); + if ( draggable ) { + this._trigger( "deactivate", event, this.ui( draggable ) ); } }, - _appendTo: function() { - var element = this.options.appendTo; + _over: function( event ) { - if ( element ) { - element = element.jquery || element.nodeType ? - $( element ) : - this.document.find( element ).eq( 0 ); - } + var draggable = $.ui.ddmanager.current; - if ( !element || !element[ 0 ] ) { - element = this.element.closest( ".ui-front, dialog" ); + // Bail if draggable and droppable are same element + if ( !draggable || ( draggable.currentItem || + draggable.element )[ 0 ] === this.element[ 0 ] ) { + return; } - if ( !element.length ) { - element = this.document[ 0 ].body; + if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || + draggable.element ) ) ) { + this._addHoverClass(); + this._trigger( "over", event, this.ui( draggable ) ); } - return element; }, - _toggleAttr: function() { - this.button.attr( "aria-expanded", this.isOpen ); - - // We can't use two _toggleClass() calls here, because we need to make sure - // we always remove classes first and add them second, otherwise if both classes have the - // same theme class, it will be removed after we add it. - this._removeClass( this.button, "ui-selectmenu-button-" + - ( this.isOpen ? "closed" : "open" ) ) - ._addClass( this.button, "ui-selectmenu-button-" + - ( this.isOpen ? "open" : "closed" ) ) - ._toggleClass( this.menuWrap, "ui-selectmenu-open", null, this.isOpen ); - - this.menu.attr( "aria-hidden", !this.isOpen ); - }, + _out: function( event ) { - _resizeButton: function() { - var width = this.options.width; + var draggable = $.ui.ddmanager.current; - // For `width: false`, just remove inline style and stop - if ( width === false ) { - this.button.css( "width", "" ); + // Bail if draggable and droppable are same element + if ( !draggable || ( draggable.currentItem || + draggable.element )[ 0 ] === this.element[ 0 ] ) { return; } - // For `width: null`, match the width of the original element - if ( width === null ) { - width = this.element.show().outerWidth(); - this.element.hide(); + if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || + draggable.element ) ) ) { + this._removeHoverClass(); + this._trigger( "out", event, this.ui( draggable ) ); } - this.button.outerWidth( width ); }, - _resizeMenu: function() { - this.menu.outerWidth( Math.max( - this.button.outerWidth(), + _drop: function( event, custom ) { - // Support: IE10 - // IE10 wraps long text (possibly a rounding bug) - // so we add 1px to avoid the wrapping - this.menu.width( "" ).outerWidth() + 1 - ) ); - }, + var draggable = custom || $.ui.ddmanager.current, + childrenIntersection = false; - _getCreateOptions: function() { - var options = this._super(); + // Bail if draggable and droppable are same element + if ( !draggable || ( draggable.currentItem || + draggable.element )[ 0 ] === this.element[ 0 ] ) { + return false; + } - options.disabled = this.element.prop( "disabled" ); + this.element + .find( ":data(ui-droppable)" ) + .not( ".ui-draggable-dragging" ) + .each( function() { + var inst = $( this ).droppable( "instance" ); + if ( + inst.options.greedy && + !inst.options.disabled && + inst.options.scope === draggable.options.scope && + inst.accept.call( + inst.element[ 0 ], ( draggable.currentItem || draggable.element ) + ) && + $.ui.intersect( + draggable, + $.extend( inst, { offset: inst.element.offset() } ), + inst.options.tolerance, event + ) + ) { + childrenIntersection = true; + return false; + } + } ); + if ( childrenIntersection ) { + return false; + } - return options; - }, + if ( this.accept.call( this.element[ 0 ], + ( draggable.currentItem || draggable.element ) ) ) { + this._removeActiveClass(); + this._removeHoverClass(); - _parseOptions: function( options ) { - var that = this, - data = []; - options.each( function( index, item ) { - if ( item.hidden ) { - return; - } + this._trigger( "drop", event, this.ui( draggable ) ); + return this.element; + } - data.push( that._parseOption( $( item ), index ) ); - } ); - this.items = data; - }, + return false; - _parseOption: function( option, index ) { - var optgroup = option.parent( "optgroup" ); + }, + ui: function( c ) { return { - element: option, - index: index, - value: option.val(), - label: option.text(), - optgroup: optgroup.attr( "label" ) || "", - disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" ) + draggable: ( c.currentItem || c.element ), + helper: c.helper, + position: c.position, + offset: c.positionAbs }; }, - _destroy: function() { - this._unbindFormResetHandler(); - this.menuWrap.remove(); - this.button.remove(); - this.element.show(); - this.element.removeUniqueId(); - this.labels.attr( "for", this.ids.element ); - } -} ] ); - - -/*! - * jQuery UI Slider 1.13.1 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ - -//>>label: Slider -//>>group: Widgets -//>>description: Displays a flexible slider with ranges and accessibility via keyboard. -//>>docs: http://api.jqueryui.com/slider/ -//>>demos: http://jqueryui.com/slider/ -//>>css.structure: ../../themes/base/core.css -//>>css.structure: ../../themes/base/slider.css -//>>css.theme: ../../themes/base/theme.css - - -var widgetsSlider = $.widget( "ui.slider", $.ui.mouse, { - version: "1.13.1", - widgetEventPrefix: "slide", - - options: { - animate: false, - classes: { - "ui-slider": "ui-corner-all", - "ui-slider-handle": "ui-corner-all", - - // Note: ui-widget-header isn't the most fittingly semantic framework class for this - // element, but worked best visually with a variety of themes - "ui-slider-range": "ui-corner-all ui-widget-header" - }, - distance: 0, - max: 100, - min: 0, - orientation: "horizontal", - range: false, - step: 1, - value: 0, - values: null, - - // Callbacks - change: null, - slide: null, - start: null, - stop: null + // Extension points just to make backcompat sane and avoid duplicating logic + // TODO: Remove in 1.14 along with call to it below + _addHoverClass: function() { + this._addClass( "ui-droppable-hover" ); }, - // Number of pages in a slider - // (how many times can you page up/down to go through the whole range) - numPages: 5, - - _create: function() { - this._keySliding = false; - this._mouseSliding = false; - this._animateOff = true; - this._handleIndex = null; - this._detectOrientation(); - this._mouseInit(); - this._calculateNewMax(); - - this._addClass( "ui-slider ui-slider-" + this.orientation, - "ui-widget ui-widget-content" ); - - this._refresh(); - - this._animateOff = false; + _removeHoverClass: function() { + this._removeClass( "ui-droppable-hover" ); }, - _refresh: function() { - this._createRange(); - this._createHandles(); - this._setupEvents(); - this._refreshValue(); + _addActiveClass: function() { + this._addClass( "ui-droppable-active" ); }, - _createHandles: function() { - var i, handleCount, - options = this.options, - existingHandles = this.element.find( ".ui-slider-handle" ), - handle = "<span tabindex='0'></span>", - handles = []; + _removeActiveClass: function() { + this._removeClass( "ui-droppable-active" ); + } +} ); - handleCount = ( options.values && options.values.length ) || 1; +$.ui.intersect = ( function() { + function isOverAxis( x, reference, size ) { + return ( x >= reference ) && ( x < ( reference + size ) ); + } - if ( existingHandles.length > handleCount ) { - existingHandles.slice( handleCount ).remove(); - existingHandles = existingHandles.slice( 0, handleCount ); - } + return function( draggable, droppable, toleranceMode, event ) { - for ( i = existingHandles.length; i < handleCount; i++ ) { - handles.push( handle ); + if ( !droppable.offset ) { + return false; } - this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) ); + var x1 = ( draggable.positionAbs || + draggable.position.absolute ).left + draggable.margins.left, + y1 = ( draggable.positionAbs || + draggable.position.absolute ).top + draggable.margins.top, + x2 = x1 + draggable.helperProportions.width, + y2 = y1 + draggable.helperProportions.height, + l = droppable.offset.left, + t = droppable.offset.top, + r = l + droppable.proportions().width, + b = t + droppable.proportions().height; - this._addClass( this.handles, "ui-slider-handle", "ui-state-default" ); + switch ( toleranceMode ) { + case "fit": + return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b ); + case "intersect": + return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half + x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half + t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half + y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half + case "pointer": + return isOverAxis( event.pageY, t, droppable.proportions().height ) && + isOverAxis( event.pageX, l, droppable.proportions().width ); + case "touch": + return ( + ( y1 >= t && y1 <= b ) || // Top edge touching + ( y2 >= t && y2 <= b ) || // Bottom edge touching + ( y1 < t && y2 > b ) // Surrounded vertically + ) && ( + ( x1 >= l && x1 <= r ) || // Left edge touching + ( x2 >= l && x2 <= r ) || // Right edge touching + ( x1 < l && x2 > r ) // Surrounded horizontally + ); + default: + return false; + } + }; +} )(); - this.handle = this.handles.eq( 0 ); +/* + This manager tracks offsets of draggables and droppables +*/ +$.ui.ddmanager = { + current: null, + droppables: { "default": [] }, + prepareOffsets: function( t, event ) { - this.handles.each( function( i ) { - $( this ) - .data( "ui-slider-handle-index", i ) - .attr( "tabIndex", 0 ); - } ); - }, + var i, j, + m = $.ui.ddmanager.droppables[ t.options.scope ] || [], + type = event ? event.type : null, // workaround for #2317 + list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack(); - _createRange: function() { - var options = this.options; + droppablesLoop: for ( i = 0; i < m.length; i++ ) { - if ( options.range ) { - if ( options.range === true ) { - if ( !options.values ) { - options.values = [ this._valueMin(), this._valueMin() ]; - } else if ( options.values.length && options.values.length !== 2 ) { - options.values = [ options.values[ 0 ], options.values[ 0 ] ]; - } else if ( Array.isArray( options.values ) ) { - options.values = options.values.slice( 0 ); - } + // No disabled and non-accepted + if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ], + ( t.currentItem || t.element ) ) ) ) { + continue; } - if ( !this.range || !this.range.length ) { - this.range = $( "<div>" ) - .appendTo( this.element ); - - this._addClass( this.range, "ui-slider-range" ); - } else { - this._removeClass( this.range, "ui-slider-range-min ui-slider-range-max" ); - - // Handle range switching from true to min/max - this.range.css( { - "left": "", - "bottom": "" - } ); + // Filter out elements in the current dragged item + for ( j = 0; j < list.length; j++ ) { + if ( list[ j ] === m[ i ].element[ 0 ] ) { + m[ i ].proportions().height = 0; + continue droppablesLoop; + } } - if ( options.range === "min" || options.range === "max" ) { - this._addClass( this.range, "ui-slider-range-" + options.range ); + + m[ i ].visible = m[ i ].element.css( "display" ) !== "none"; + if ( !m[ i ].visible ) { + continue; } - } else { - if ( this.range ) { - this.range.remove(); + + // Activate the droppable if used directly from draggables + if ( type === "mousedown" ) { + m[ i ]._activate.call( m[ i ], event ); } - this.range = null; - } - }, - _setupEvents: function() { - this._off( this.handles ); - this._on( this.handles, this._handleEvents ); - this._hoverable( this.handles ); - this._focusable( this.handles ); - }, + m[ i ].offset = m[ i ].element.offset(); + m[ i ].proportions( { + width: m[ i ].element[ 0 ].offsetWidth, + height: m[ i ].element[ 0 ].offsetHeight + } ); - _destroy: function() { - this.handles.remove(); - if ( this.range ) { - this.range.remove(); } - this._mouseDestroy(); }, + drop: function( draggable, event ) { - _mouseCapture: function( event ) { - var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle, - that = this, - o = this.options; - - if ( o.disabled ) { - return false; - } + var dropped = false; - this.elementSize = { - width: this.element.outerWidth(), - height: this.element.outerHeight() - }; - this.elementOffset = this.element.offset(); + // Create a copy of the droppables in case the list changes during the drop (#9116) + $.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() { - position = { x: event.pageX, y: event.pageY }; - normValue = this._normValueFromMouse( position ); - distance = this._valueMax() - this._valueMin() + 1; - this.handles.each( function( i ) { - var thisDistance = Math.abs( normValue - that.values( i ) ); - if ( ( distance > thisDistance ) || - ( distance === thisDistance && - ( i === that._lastChangedValue || that.values( i ) === o.min ) ) ) { - distance = thisDistance; - closestHandle = $( this ); - index = i; + if ( !this.options ) { + return; + } + if ( !this.options.disabled && this.visible && + $.ui.intersect( draggable, this, this.options.tolerance, event ) ) { + dropped = this._drop.call( this, event ) || dropped; } - } ); - allowed = this._start( event, index ); - if ( allowed === false ) { - return false; - } - this._mouseSliding = true; + if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ], + ( draggable.currentItem || draggable.element ) ) ) { + this.isout = true; + this.isover = false; + this._deactivate.call( this, event ); + } - this._handleIndex = index; + } ); + return dropped; - this._addClass( closestHandle, null, "ui-state-active" ); - closestHandle.trigger( "focus" ); + }, + dragStart: function( draggable, event ) { - offset = closestHandle.offset(); - mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" ); - this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : { - left: event.pageX - offset.left - ( closestHandle.width() / 2 ), - top: event.pageY - offset.top - - ( closestHandle.height() / 2 ) - - ( parseInt( closestHandle.css( "borderTopWidth" ), 10 ) || 0 ) - - ( parseInt( closestHandle.css( "borderBottomWidth" ), 10 ) || 0 ) + - ( parseInt( closestHandle.css( "marginTop" ), 10 ) || 0 ) - }; + // Listen for scrolling so that if the dragging causes scrolling the position of the + // droppables can be recalculated (see #5003) + draggable.element.parentsUntil( "body" ).on( "scroll.droppable", function() { + if ( !draggable.options.refreshPositions ) { + $.ui.ddmanager.prepareOffsets( draggable, event ); + } + } ); + }, + drag: function( draggable, event ) { - if ( !this.handles.hasClass( "ui-state-hover" ) ) { - this._slide( event, index, normValue ); + // If you have a highly dynamic page, you might try this option. It renders positions + // every time you move the mouse. + if ( draggable.options.refreshPositions ) { + $.ui.ddmanager.prepareOffsets( draggable, event ); } - this._animateOff = true; - return true; - }, - _mouseStart: function() { - return true; - }, + // Run through all droppables and check their positions based on specific tolerance options + $.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() { - _mouseDrag: function( event ) { - var position = { x: event.pageX, y: event.pageY }, - normValue = this._normValueFromMouse( position ); + if ( this.options.disabled || this.greedyChild || !this.visible ) { + return; + } + + var parentInstance, scope, parent, + intersects = $.ui.intersect( draggable, this, this.options.tolerance, event ), + c = !intersects && this.isover ? + "isout" : + ( intersects && !this.isover ? "isover" : null ); + if ( !c ) { + return; + } - this._slide( event, this._handleIndex, normValue ); + if ( this.options.greedy ) { - return false; - }, + // find droppable parents with same scope + scope = this.options.scope; + parent = this.element.parents( ":data(ui-droppable)" ).filter( function() { + return $( this ).droppable( "instance" ).options.scope === scope; + } ); - _mouseStop: function( event ) { - this._removeClass( this.handles, null, "ui-state-active" ); - this._mouseSliding = false; + if ( parent.length ) { + parentInstance = $( parent[ 0 ] ).droppable( "instance" ); + parentInstance.greedyChild = ( c === "isover" ); + } + } - this._stop( event, this._handleIndex ); - this._change( event, this._handleIndex ); + // We just moved into a greedy child + if ( parentInstance && c === "isover" ) { + parentInstance.isover = false; + parentInstance.isout = true; + parentInstance._out.call( parentInstance, event ); + } - this._handleIndex = null; - this._clickOffset = null; - this._animateOff = false; + this[ c ] = true; + this[ c === "isout" ? "isover" : "isout" ] = false; + this[ c === "isover" ? "_over" : "_out" ].call( this, event ); - return false; - }, + // We just moved out of a greedy child + if ( parentInstance && c === "isout" ) { + parentInstance.isout = false; + parentInstance.isover = true; + parentInstance._over.call( parentInstance, event ); + } + } ); - _detectOrientation: function() { - this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal"; }, + dragStop: function( draggable, event ) { + draggable.element.parentsUntil( "body" ).off( "scroll.droppable" ); - _normValueFromMouse: function( position ) { - var pixelTotal, - pixelMouse, - percentMouse, - valueTotal, - valueMouse; - - if ( this.orientation === "horizontal" ) { - pixelTotal = this.elementSize.width; - pixelMouse = position.x - this.elementOffset.left - - ( this._clickOffset ? this._clickOffset.left : 0 ); - } else { - pixelTotal = this.elementSize.height; - pixelMouse = position.y - this.elementOffset.top - - ( this._clickOffset ? this._clickOffset.top : 0 ); + // Call prepareOffsets one final time since IE does not fire return scroll events when + // overflow was caused by drag (see #5003) + if ( !draggable.options.refreshPositions ) { + $.ui.ddmanager.prepareOffsets( draggable, event ); } + } +}; - percentMouse = ( pixelMouse / pixelTotal ); - if ( percentMouse > 1 ) { - percentMouse = 1; - } - if ( percentMouse < 0 ) { - percentMouse = 0; - } - if ( this.orientation === "vertical" ) { - percentMouse = 1 - percentMouse; +// DEPRECATED +// TODO: switch return back to widget declaration at top of file when this is removed +if ( $.uiBackCompat !== false ) { + + // Backcompat for activeClass and hoverClass options + $.widget( "ui.droppable", $.ui.droppable, { + options: { + hoverClass: false, + activeClass: false + }, + _addActiveClass: function() { + this._super(); + if ( this.options.activeClass ) { + this.element.addClass( this.options.activeClass ); + } + }, + _removeActiveClass: function() { + this._super(); + if ( this.options.activeClass ) { + this.element.removeClass( this.options.activeClass ); + } + }, + _addHoverClass: function() { + this._super(); + if ( this.options.hoverClass ) { + this.element.addClass( this.options.hoverClass ); + } + }, + _removeHoverClass: function() { + this._super(); + if ( this.options.hoverClass ) { + this.element.removeClass( this.options.hoverClass ); + } } + } ); +} - valueTotal = this._valueMax() - this._valueMin(); - valueMouse = this._valueMin() + percentMouse * valueTotal; +var widgetsDroppable = $.ui.droppable; - return this._trimAlignValue( valueMouse ); - }, - _uiHash: function( index, value, values ) { - var uiHash = { - handle: this.handles[ index ], - handleIndex: index, - value: value !== undefined ? value : this.value() - }; +/*! + * jQuery UI Progressbar 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ - if ( this._hasMultipleValues() ) { - uiHash.value = value !== undefined ? value : this.values( index ); - uiHash.values = values || this.values(); - } +//>>label: Progressbar +//>>group: Widgets +/* eslint-disable max-len */ +//>>description: Displays a status indicator for loading state, standard percentage, and other progress indicators. +/* eslint-enable max-len */ +//>>docs: http://api.jqueryui.com/progressbar/ +//>>demos: http://jqueryui.com/progressbar/ +//>>css.structure: ../../themes/base/core.css +//>>css.structure: ../../themes/base/progressbar.css +//>>css.theme: ../../themes/base/theme.css - return uiHash; - }, - _hasMultipleValues: function() { - return this.options.values && this.options.values.length; - }, +var widgetsProgressbar = $.widget( "ui.progressbar", { + version: "1.13.2", + options: { + classes: { + "ui-progressbar": "ui-corner-all", + "ui-progressbar-value": "ui-corner-left", + "ui-progressbar-complete": "ui-corner-right" + }, + max: 100, + value: 0, - _start: function( event, index ) { - return this._trigger( "start", event, this._uiHash( index ) ); + change: null, + complete: null }, - _slide: function( event, index, newVal ) { - var allowed, otherVal, - currentValue = this.value(), - newValues = this.values(); - - if ( this._hasMultipleValues() ) { - otherVal = this.values( index ? 0 : 1 ); - currentValue = this.values( index ); - - if ( this.options.values.length === 2 && this.options.range === true ) { - newVal = index === 0 ? Math.min( otherVal, newVal ) : Math.max( otherVal, newVal ); - } - - newValues[ index ] = newVal; - } + min: 0, - if ( newVal === currentValue ) { - return; - } + _create: function() { - allowed = this._trigger( "slide", event, this._uiHash( index, newVal, newValues ) ); + // Constrain initial value + this.oldValue = this.options.value = this._constrainedValue(); - // A slide can be canceled by returning false from the slide callback - if ( allowed === false ) { - return; - } + this.element.attr( { - if ( this._hasMultipleValues() ) { - this.values( index, newVal ); - } else { - this.value( newVal ); - } - }, + // Only set static values; aria-valuenow and aria-valuemax are + // set inside _refreshValue() + role: "progressbar", + "aria-valuemin": this.min + } ); + this._addClass( "ui-progressbar", "ui-widget ui-widget-content" ); - _stop: function( event, index ) { - this._trigger( "stop", event, this._uiHash( index ) ); + this.valueDiv = $( "<div>" ).appendTo( this.element ); + this._addClass( this.valueDiv, "ui-progressbar-value", "ui-widget-header" ); + this._refreshValue(); }, - _change: function( event, index ) { - if ( !this._keySliding && !this._mouseSliding ) { + _destroy: function() { + this.element.removeAttr( "role aria-valuemin aria-valuemax aria-valuenow" ); - //store the last changed value index for reference when handles overlap - this._lastChangedValue = index; - this._trigger( "change", event, this._uiHash( index ) ); - } + this.valueDiv.remove(); }, value: function( newValue ) { - if ( arguments.length ) { - this.options.value = this._trimAlignValue( newValue ); - this._refreshValue(); - this._change( null, 0 ); - return; - } - - return this._value(); - }, - - values: function( index, newValue ) { - var vals, - newValues, - i; - - if ( arguments.length > 1 ) { - this.options.values[ index ] = this._trimAlignValue( newValue ); - this._refreshValue(); - this._change( null, index ); - return; + if ( newValue === undefined ) { + return this.options.value; } - if ( arguments.length ) { - if ( Array.isArray( arguments[ 0 ] ) ) { - vals = this.options.values; - newValues = arguments[ 0 ]; - for ( i = 0; i < vals.length; i += 1 ) { - vals[ i ] = this._trimAlignValue( newValues[ i ] ); - this._change( null, i ); - } - this._refreshValue(); - } else { - if ( this._hasMultipleValues() ) { - return this._values( index ); - } else { - return this.value(); - } - } - } else { - return this._values(); - } + this.options.value = this._constrainedValue( newValue ); + this._refreshValue(); }, - _setOption: function( key, value ) { - var i, - valsLength = 0; - - if ( key === "range" && this.options.range === true ) { - if ( value === "min" ) { - this.options.value = this._values( 0 ); - this.options.values = null; - } else if ( value === "max" ) { - this.options.value = this._values( this.options.values.length - 1 ); - this.options.values = null; - } + _constrainedValue: function( newValue ) { + if ( newValue === undefined ) { + newValue = this.options.value; } - if ( Array.isArray( this.options.values ) ) { - valsLength = this.options.values.length; + this.indeterminate = newValue === false; + + // Sanitize value + if ( typeof newValue !== "number" ) { + newValue = 0; } - this._super( key, value ); + return this.indeterminate ? false : + Math.min( this.options.max, Math.max( this.min, newValue ) ); + }, - switch ( key ) { - case "orientation": - this._detectOrientation(); - this._removeClass( "ui-slider-horizontal ui-slider-vertical" ) - ._addClass( "ui-slider-" + this.orientation ); - this._refreshValue(); - if ( this.options.range ) { - this._refreshRange( value ); - } + _setOptions: function( options ) { - // Reset positioning from previous orientation - this.handles.css( value === "horizontal" ? "bottom" : "left", "" ); - break; - case "value": - this._animateOff = true; - this._refreshValue(); - this._change( null, 0 ); - this._animateOff = false; - break; - case "values": - this._animateOff = true; - this._refreshValue(); + // Ensure "value" option is set after other values (like max) + var value = options.value; + delete options.value; - // Start from the last handle to prevent unreachable handles (#9046) - for ( i = valsLength - 1; i >= 0; i-- ) { - this._change( null, i ); - } - this._animateOff = false; - break; - case "step": - case "min": - case "max": - this._animateOff = true; - this._calculateNewMax(); - this._refreshValue(); - this._animateOff = false; - break; - case "range": - this._animateOff = true; - this._refresh(); - this._animateOff = false; - break; + this._super( options ); + + this.options.value = this._constrainedValue( value ); + this._refreshValue(); + }, + + _setOption: function( key, value ) { + if ( key === "max" ) { + + // Don't allow a max less than min + value = Math.max( this.min, value ); } + this._super( key, value ); }, _setOptionDisabled: function( value ) { this._super( value ); + this.element.attr( "aria-disabled", value ); this._toggleClass( null, "ui-state-disabled", !!value ); }, - //internal value getter - // _value() returns value trimmed by min and max, aligned by step - _value: function() { - var val = this.options.value; - val = this._trimAlignValue( val ); - - return val; + _percentage: function() { + return this.indeterminate ? + 100 : + 100 * ( this.options.value - this.min ) / ( this.options.max - this.min ); }, - //internal values getter - // _values() returns array of values trimmed by min and max, aligned by step - // _values( index ) returns single value trimmed by min and max, aligned by step - _values: function( index ) { - var val, - vals, - i; + _refreshValue: function() { + var value = this.options.value, + percentage = this._percentage(); - if ( arguments.length ) { - val = this.options.values[ index ]; - val = this._trimAlignValue( val ); + this.valueDiv + .toggle( this.indeterminate || value > this.min ) + .width( percentage.toFixed( 0 ) + "%" ); - return val; - } else if ( this._hasMultipleValues() ) { + this + ._toggleClass( this.valueDiv, "ui-progressbar-complete", null, + value === this.options.max ) + ._toggleClass( "ui-progressbar-indeterminate", null, this.indeterminate ); - // .slice() creates a copy of the array - // this copy gets trimmed by min and max and then returned - vals = this.options.values.slice(); - for ( i = 0; i < vals.length; i += 1 ) { - vals[ i ] = this._trimAlignValue( vals[ i ] ); + if ( this.indeterminate ) { + this.element.removeAttr( "aria-valuenow" ); + if ( !this.overlayDiv ) { + this.overlayDiv = $( "<div>" ).appendTo( this.valueDiv ); + this._addClass( this.overlayDiv, "ui-progressbar-overlay" ); } - - return vals; } else { - return []; + this.element.attr( { + "aria-valuemax": this.options.max, + "aria-valuenow": value + } ); + if ( this.overlayDiv ) { + this.overlayDiv.remove(); + this.overlayDiv = null; + } } - }, - // Returns the step-aligned value that val is closest to, between (inclusive) min and max - _trimAlignValue: function( val ) { - if ( val <= this._valueMin() ) { - return this._valueMin(); + if ( this.oldValue !== value ) { + this.oldValue = value; + this._trigger( "change" ); } - if ( val >= this._valueMax() ) { - return this._valueMax(); + if ( value === this.options.max ) { + this._trigger( "complete" ); } - var step = ( this.options.step > 0 ) ? this.options.step : 1, - valModStep = ( val - this._valueMin() ) % step, - alignValue = val - valModStep; + } +} ); + + +/*! + * jQuery UI Selectable 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: Selectable +//>>group: Interactions +//>>description: Allows groups of elements to be selected with the mouse. +//>>docs: http://api.jqueryui.com/selectable/ +//>>demos: http://jqueryui.com/selectable/ +//>>css.structure: ../../themes/base/selectable.css + + +var widgetsSelectable = $.widget( "ui.selectable", $.ui.mouse, { + version: "1.13.2", + options: { + appendTo: "body", + autoRefresh: true, + distance: 0, + filter: "*", + tolerance: "touch", + + // Callbacks + selected: null, + selecting: null, + start: null, + stop: null, + unselected: null, + unselecting: null + }, + _create: function() { + var that = this; + + this._addClass( "ui-selectable" ); + + this.dragged = false; + + // Cache selectee children based on filter + this.refresh = function() { + that.elementPos = $( that.element[ 0 ] ).offset(); + that.selectees = $( that.options.filter, that.element[ 0 ] ); + that._addClass( that.selectees, "ui-selectee" ); + that.selectees.each( function() { + var $this = $( this ), + selecteeOffset = $this.offset(), + pos = { + left: selecteeOffset.left - that.elementPos.left, + top: selecteeOffset.top - that.elementPos.top + }; + $.data( this, "selectable-item", { + element: this, + $element: $this, + left: pos.left, + top: pos.top, + right: pos.left + $this.outerWidth(), + bottom: pos.top + $this.outerHeight(), + startselected: false, + selected: $this.hasClass( "ui-selected" ), + selecting: $this.hasClass( "ui-selecting" ), + unselecting: $this.hasClass( "ui-unselecting" ) + } ); + } ); + }; + this.refresh(); + + this._mouseInit(); + + this.helper = $( "<div>" ); + this._addClass( this.helper, "ui-selectable-helper" ); + }, + + _destroy: function() { + this.selectees.removeData( "selectable-item" ); + this._mouseDestroy(); + }, + + _mouseStart: function( event ) { + var that = this, + options = this.options; + + this.opos = [ event.pageX, event.pageY ]; + this.elementPos = $( this.element[ 0 ] ).offset(); + + if ( this.options.disabled ) { + return; + } + + this.selectees = $( options.filter, this.element[ 0 ] ); + + this._trigger( "start", event ); + + $( options.appendTo ).append( this.helper ); + + // position helper (lasso) + this.helper.css( { + "left": event.pageX, + "top": event.pageY, + "width": 0, + "height": 0 + } ); - if ( Math.abs( valModStep ) * 2 >= step ) { - alignValue += ( valModStep > 0 ) ? step : ( -step ); + if ( options.autoRefresh ) { + this.refresh(); } - // Since JavaScript has problems with large floats, round - // the final value to 5 digits after the decimal point (see #4124) - return parseFloat( alignValue.toFixed( 5 ) ); - }, + this.selectees.filter( ".ui-selected" ).each( function() { + var selectee = $.data( this, "selectable-item" ); + selectee.startselected = true; + if ( !event.metaKey && !event.ctrlKey ) { + that._removeClass( selectee.$element, "ui-selected" ); + selectee.selected = false; + that._addClass( selectee.$element, "ui-unselecting" ); + selectee.unselecting = true; - _calculateNewMax: function() { - var max = this.options.max, - min = this._valueMin(), - step = this.options.step, - aboveMin = Math.round( ( max - min ) / step ) * step; - max = aboveMin + min; - if ( max > this.options.max ) { + // selectable UNSELECTING callback + that._trigger( "unselecting", event, { + unselecting: selectee.element + } ); + } + } ); - //If max is not divisible by step, rounding off may increase its value - max -= step; - } - this.max = parseFloat( max.toFixed( this._precision() ) ); - }, + $( event.target ).parents().addBack().each( function() { + var doSelect, + selectee = $.data( this, "selectable-item" ); + if ( selectee ) { + doSelect = ( !event.metaKey && !event.ctrlKey ) || + !selectee.$element.hasClass( "ui-selected" ); + that._removeClass( selectee.$element, doSelect ? "ui-unselecting" : "ui-selected" ) + ._addClass( selectee.$element, doSelect ? "ui-selecting" : "ui-unselecting" ); + selectee.unselecting = !doSelect; + selectee.selecting = doSelect; + selectee.selected = doSelect; - _precision: function() { - var precision = this._precisionOf( this.options.step ); - if ( this.options.min !== null ) { - precision = Math.max( precision, this._precisionOf( this.options.min ) ); - } - return precision; - }, + // selectable (UN)SELECTING callback + if ( doSelect ) { + that._trigger( "selecting", event, { + selecting: selectee.element + } ); + } else { + that._trigger( "unselecting", event, { + unselecting: selectee.element + } ); + } + return false; + } + } ); - _precisionOf: function( num ) { - var str = num.toString(), - decimal = str.indexOf( "." ); - return decimal === -1 ? 0 : str.length - decimal - 1; }, - _valueMin: function() { - return this.options.min; - }, + _mouseDrag: function( event ) { - _valueMax: function() { - return this.max; - }, + this.dragged = true; - _refreshRange: function( orientation ) { - if ( orientation === "vertical" ) { - this.range.css( { "width": "", "left": "" } ); - } - if ( orientation === "horizontal" ) { - this.range.css( { "height": "", "bottom": "" } ); + if ( this.options.disabled ) { + return; } - }, - _refreshValue: function() { - var lastValPercent, valPercent, value, valueMin, valueMax, - oRange = this.options.range, - o = this.options, + var tmp, that = this, - animate = ( !this._animateOff ) ? o.animate : false, - _set = {}; + options = this.options, + x1 = this.opos[ 0 ], + y1 = this.opos[ 1 ], + x2 = event.pageX, + y2 = event.pageY; - if ( this._hasMultipleValues() ) { - this.handles.each( function( i ) { - valPercent = ( that.values( i ) - that._valueMin() ) / ( that._valueMax() - - that._valueMin() ) * 100; - _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; - $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); - if ( that.options.range === true ) { - if ( that.orientation === "horizontal" ) { - if ( i === 0 ) { - that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { - left: valPercent + "%" - }, o.animate ); - } - if ( i === 1 ) { - that.range[ animate ? "animate" : "css" ]( { - width: ( valPercent - lastValPercent ) + "%" - }, { - queue: false, - duration: o.animate - } ); - } - } else { - if ( i === 0 ) { - that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { - bottom: ( valPercent ) + "%" - }, o.animate ); - } - if ( i === 1 ) { - that.range[ animate ? "animate" : "css" ]( { - height: ( valPercent - lastValPercent ) + "%" - }, { - queue: false, - duration: o.animate - } ); - } - } - } - lastValPercent = valPercent; - } ); - } else { - value = this.value(); - valueMin = this._valueMin(); - valueMax = this._valueMax(); - valPercent = ( valueMax !== valueMin ) ? - ( value - valueMin ) / ( valueMax - valueMin ) * 100 : - 0; - _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; - this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); + if ( x1 > x2 ) { + tmp = x2; x2 = x1; x1 = tmp; + } + if ( y1 > y2 ) { + tmp = y2; y2 = y1; y1 = tmp; + } + this.helper.css( { left: x1, top: y1, width: x2 - x1, height: y2 - y1 } ); - if ( oRange === "min" && this.orientation === "horizontal" ) { - this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { - width: valPercent + "%" - }, o.animate ); - } - if ( oRange === "max" && this.orientation === "horizontal" ) { - this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { - width: ( 100 - valPercent ) + "%" - }, o.animate ); - } - if ( oRange === "min" && this.orientation === "vertical" ) { - this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { - height: valPercent + "%" - }, o.animate ); - } - if ( oRange === "max" && this.orientation === "vertical" ) { - this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { - height: ( 100 - valPercent ) + "%" - }, o.animate ); + this.selectees.each( function() { + var selectee = $.data( this, "selectable-item" ), + hit = false, + offset = {}; + + //prevent helper from being selected if appendTo: selectable + if ( !selectee || selectee.element === that.element[ 0 ] ) { + return; } - } - }, - _handleEvents: { - keydown: function( event ) { - var allowed, curVal, newVal, step, - index = $( event.target ).data( "ui-slider-handle-index" ); + offset.left = selectee.left + that.elementPos.left; + offset.right = selectee.right + that.elementPos.left; + offset.top = selectee.top + that.elementPos.top; + offset.bottom = selectee.bottom + that.elementPos.top; - switch ( event.keyCode ) { - case $.ui.keyCode.HOME: - case $.ui.keyCode.END: - case $.ui.keyCode.PAGE_UP: - case $.ui.keyCode.PAGE_DOWN: - case $.ui.keyCode.UP: - case $.ui.keyCode.RIGHT: - case $.ui.keyCode.DOWN: - case $.ui.keyCode.LEFT: - event.preventDefault(); - if ( !this._keySliding ) { - this._keySliding = true; - this._addClass( $( event.target ), null, "ui-state-active" ); - allowed = this._start( event, index ); - if ( allowed === false ) { - return; - } - } - break; + if ( options.tolerance === "touch" ) { + hit = ( !( offset.left > x2 || offset.right < x1 || offset.top > y2 || + offset.bottom < y1 ) ); + } else if ( options.tolerance === "fit" ) { + hit = ( offset.left > x1 && offset.right < x2 && offset.top > y1 && + offset.bottom < y2 ); } - step = this.options.step; - if ( this._hasMultipleValues() ) { - curVal = newVal = this.values( index ); + if ( hit ) { + + // SELECT + if ( selectee.selected ) { + that._removeClass( selectee.$element, "ui-selected" ); + selectee.selected = false; + } + if ( selectee.unselecting ) { + that._removeClass( selectee.$element, "ui-unselecting" ); + selectee.unselecting = false; + } + if ( !selectee.selecting ) { + that._addClass( selectee.$element, "ui-selecting" ); + selectee.selecting = true; + + // selectable SELECTING callback + that._trigger( "selecting", event, { + selecting: selectee.element + } ); + } } else { - curVal = newVal = this.value(); - } - switch ( event.keyCode ) { - case $.ui.keyCode.HOME: - newVal = this._valueMin(); - break; - case $.ui.keyCode.END: - newVal = this._valueMax(); - break; - case $.ui.keyCode.PAGE_UP: - newVal = this._trimAlignValue( - curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages ) - ); - break; - case $.ui.keyCode.PAGE_DOWN: - newVal = this._trimAlignValue( - curVal - ( ( this._valueMax() - this._valueMin() ) / this.numPages ) ); - break; - case $.ui.keyCode.UP: - case $.ui.keyCode.RIGHT: - if ( curVal === this._valueMax() ) { - return; + // UNSELECT + if ( selectee.selecting ) { + if ( ( event.metaKey || event.ctrlKey ) && selectee.startselected ) { + that._removeClass( selectee.$element, "ui-selecting" ); + selectee.selecting = false; + that._addClass( selectee.$element, "ui-selected" ); + selectee.selected = true; + } else { + that._removeClass( selectee.$element, "ui-selecting" ); + selectee.selecting = false; + if ( selectee.startselected ) { + that._addClass( selectee.$element, "ui-unselecting" ); + selectee.unselecting = true; + } + + // selectable UNSELECTING callback + that._trigger( "unselecting", event, { + unselecting: selectee.element + } ); } - newVal = this._trimAlignValue( curVal + step ); - break; - case $.ui.keyCode.DOWN: - case $.ui.keyCode.LEFT: - if ( curVal === this._valueMin() ) { - return; + } + if ( selectee.selected ) { + if ( !event.metaKey && !event.ctrlKey && !selectee.startselected ) { + that._removeClass( selectee.$element, "ui-selected" ); + selectee.selected = false; + + that._addClass( selectee.$element, "ui-unselecting" ); + selectee.unselecting = true; + + // selectable UNSELECTING callback + that._trigger( "unselecting", event, { + unselecting: selectee.element + } ); } - newVal = this._trimAlignValue( curVal - step ); - break; + } } + } ); - this._slide( event, index, newVal ); - }, - keyup: function( event ) { - var index = $( event.target ).data( "ui-slider-handle-index" ); + return false; + }, - if ( this._keySliding ) { - this._keySliding = false; - this._stop( event, index ); - this._change( event, index ); - this._removeClass( $( event.target ), null, "ui-state-active" ); - } - } + _mouseStop: function( event ) { + var that = this; + + this.dragged = false; + + $( ".ui-unselecting", this.element[ 0 ] ).each( function() { + var selectee = $.data( this, "selectable-item" ); + that._removeClass( selectee.$element, "ui-unselecting" ); + selectee.unselecting = false; + selectee.startselected = false; + that._trigger( "unselected", event, { + unselected: selectee.element + } ); + } ); + $( ".ui-selecting", this.element[ 0 ] ).each( function() { + var selectee = $.data( this, "selectable-item" ); + that._removeClass( selectee.$element, "ui-selecting" ) + ._addClass( selectee.$element, "ui-selected" ); + selectee.selecting = false; + selectee.selected = true; + selectee.startselected = true; + that._trigger( "selected", event, { + selected: selectee.element + } ); + } ); + this._trigger( "stop", event ); + + this.helper.remove(); + + return false; } + } ); /*! - * jQuery UI Spinner 1.13.1 + * jQuery UI Selectmenu 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -14482,560 +14098,668 @@ var widgetsSlider = $.widget( "ui.slider", $.ui.mouse, { * http://jquery.org/license */ -//>>label: Spinner +//>>label: Selectmenu //>>group: Widgets -//>>description: Displays buttons to easily input numbers via the keyboard or mouse. -//>>docs: http://api.jqueryui.com/spinner/ -//>>demos: http://jqueryui.com/spinner/ +/* eslint-disable max-len */ +//>>description: Duplicates and extends the functionality of a native HTML select element, allowing it to be customizable in behavior and appearance far beyond the limitations of a native select. +/* eslint-enable max-len */ +//>>docs: http://api.jqueryui.com/selectmenu/ +//>>demos: http://jqueryui.com/selectmenu/ //>>css.structure: ../../themes/base/core.css -//>>css.structure: ../../themes/base/spinner.css +//>>css.structure: ../../themes/base/selectmenu.css, ../../themes/base/button.css //>>css.theme: ../../themes/base/theme.css -function spinnerModifier( fn ) { - return function() { - var previous = this.element.val(); - fn.apply( this, arguments ); - this._refresh(); - if ( previous !== this.element.val() ) { - this._trigger( "change" ); - } - }; -} +var widgetsSelectmenu = $.widget( "ui.selectmenu", [ $.ui.formResetMixin, { + version: "1.13.2", + defaultElement: "<select>", + options: { + appendTo: null, + classes: { + "ui-selectmenu-button-open": "ui-corner-top", + "ui-selectmenu-button-closed": "ui-corner-all" + }, + disabled: null, + icons: { + button: "ui-icon-triangle-1-s" + }, + position: { + my: "left top", + at: "left bottom", + collision: "none" + }, + width: false, + + // Callbacks + change: null, + close: null, + focus: null, + open: null, + select: null + }, + + _create: function() { + var selectmenuId = this.element.uniqueId().attr( "id" ); + this.ids = { + element: selectmenuId, + button: selectmenuId + "-button", + menu: selectmenuId + "-menu" + }; + + this._drawButton(); + this._drawMenu(); + this._bindFormResetHandler(); + + this._rendered = false; + this.menuItems = $(); + }, + + _drawButton: function() { + var icon, + that = this, + item = this._parseOption( + this.element.find( "option:selected" ), + this.element[ 0 ].selectedIndex + ); + + // Associate existing label with the new button + this.labels = this.element.labels().attr( "for", this.ids.button ); + this._on( this.labels, { + click: function( event ) { + this.button.trigger( "focus" ); + event.preventDefault(); + } + } ); + + // Hide original select element + this.element.hide(); + + // Create button + this.button = $( "<span>", { + tabindex: this.options.disabled ? -1 : 0, + id: this.ids.button, + role: "combobox", + "aria-expanded": "false", + "aria-autocomplete": "list", + "aria-owns": this.ids.menu, + "aria-haspopup": "true", + title: this.element.attr( "title" ) + } ) + .insertAfter( this.element ); + + this._addClass( this.button, "ui-selectmenu-button ui-selectmenu-button-closed", + "ui-button ui-widget" ); + + icon = $( "<span>" ).appendTo( this.button ); + this._addClass( icon, "ui-selectmenu-icon", "ui-icon " + this.options.icons.button ); + this.buttonItem = this._renderButtonItem( item ) + .appendTo( this.button ); + + if ( this.options.width !== false ) { + this._resizeButton(); + } + + this._on( this.button, this._buttonEvents ); + this.button.one( "focusin", function() { + + // Delay rendering the menu items until the button receives focus. + // The menu may have already been rendered via a programmatic open. + if ( !that._rendered ) { + that._refreshMenu(); + } + } ); + }, + + _drawMenu: function() { + var that = this; + + // Create menu + this.menu = $( "<ul>", { + "aria-hidden": "true", + "aria-labelledby": this.ids.button, + id: this.ids.menu + } ); + + // Wrap menu + this.menuWrap = $( "<div>" ).append( this.menu ); + this._addClass( this.menuWrap, "ui-selectmenu-menu", "ui-front" ); + this.menuWrap.appendTo( this._appendTo() ); + + // Initialize menu widget + this.menuInstance = this.menu + .menu( { + classes: { + "ui-menu": "ui-corner-bottom" + }, + role: "listbox", + select: function( event, ui ) { + event.preventDefault(); + + // Support: IE8 + // If the item was selected via a click, the text selection + // will be destroyed in IE + that._setSelection(); + + that._select( ui.item.data( "ui-selectmenu-item" ), event ); + }, + focus: function( event, ui ) { + var item = ui.item.data( "ui-selectmenu-item" ); + + // Prevent inital focus from firing and check if its a newly focused item + if ( that.focusIndex != null && item.index !== that.focusIndex ) { + that._trigger( "focus", event, { item: item } ); + if ( !that.isOpen ) { + that._select( item, event ); + } + } + that.focusIndex = item.index; + + that.button.attr( "aria-activedescendant", + that.menuItems.eq( item.index ).attr( "id" ) ); + } + } ) + .menu( "instance" ); + + // Don't close the menu on mouseleave + this.menuInstance._off( this.menu, "mouseleave" ); + + // Cancel the menu's collapseAll on document click + this.menuInstance._closeOnDocumentClick = function() { + return false; + }; + + // Selects often contain empty items, but never contain dividers + this.menuInstance._isDivider = function() { + return false; + }; + }, -$.widget( "ui.spinner", { - version: "1.13.1", - defaultElement: "<input>", - widgetEventPrefix: "spin", - options: { - classes: { - "ui-spinner": "ui-corner-all", - "ui-spinner-down": "ui-corner-br", - "ui-spinner-up": "ui-corner-tr" - }, - culture: null, - icons: { - down: "ui-icon-triangle-1-s", - up: "ui-icon-triangle-1-n" - }, - incremental: true, - max: null, - min: null, - numberFormat: null, - page: 10, - step: 1, + refresh: function() { + this._refreshMenu(); + this.buttonItem.replaceWith( + this.buttonItem = this._renderButtonItem( - change: null, - spin: null, - start: null, - stop: null + // Fall back to an empty object in case there are no options + this._getSelectedItem().data( "ui-selectmenu-item" ) || {} + ) + ); + if ( this.options.width === null ) { + this._resizeButton(); + } }, - _create: function() { + _refreshMenu: function() { + var item, + options = this.element.find( "option" ); - // handle string values that need to be parsed - this._setOption( "max", this.options.max ); - this._setOption( "min", this.options.min ); - this._setOption( "step", this.options.step ); + this.menu.empty(); - // Only format if there is a value, prevents the field from being marked - // as invalid in Firefox, see #9573. - if ( this.value() !== "" ) { + this._parseOptions( options ); + this._renderMenu( this.menu, this.items ); - // Format the value, but don't constrain. - this._value( this.element.val(), true ); - } + this.menuInstance.refresh(); + this.menuItems = this.menu.find( "li" ) + .not( ".ui-selectmenu-optgroup" ) + .find( ".ui-menu-item-wrapper" ); - this._draw(); - this._on( this._events ); - this._refresh(); + this._rendered = true; - // Turning off autocomplete prevents the browser from remembering the - // value when navigating through history, so we re-enable autocomplete - // if the page is unloaded before the widget is destroyed. #7790 - this._on( this.window, { - beforeunload: function() { - this.element.removeAttr( "autocomplete" ); - } - } ); - }, + if ( !options.length ) { + return; + } - _getCreateOptions: function() { - var options = this._super(); - var element = this.element; + item = this._getSelectedItem(); - $.each( [ "min", "max", "step" ], function( i, option ) { - var value = element.attr( option ); - if ( value != null && value.length ) { - options[ option ] = value; - } - } ); + // Update the menu to have the correct item focused + this.menuInstance.focus( null, item ); + this._setAria( item.data( "ui-selectmenu-item" ) ); - return options; + // Set disabled state + this._setOption( "disabled", this.element.prop( "disabled" ) ); }, - _events: { - keydown: function( event ) { - if ( this._start( event ) && this._keydown( event ) ) { - event.preventDefault(); - } - }, - keyup: "_stop", - focus: function() { - this.previous = this.element.val(); - }, - blur: function( event ) { - if ( this.cancelBlur ) { - delete this.cancelBlur; - return; - } + open: function( event ) { + if ( this.options.disabled ) { + return; + } - this._stop(); - this._refresh(); - if ( this.previous !== this.element.val() ) { - this._trigger( "change", event ); - } - }, - mousewheel: function( event, delta ) { - var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ); - var isActive = this.element[ 0 ] === activeElement; + // If this is the first time the menu is being opened, render the items + if ( !this._rendered ) { + this._refreshMenu(); + } else { - if ( !isActive || !delta ) { - return; - } + // Menu clears focus on close, reset focus to selected item + this._removeClass( this.menu.find( ".ui-state-active" ), null, "ui-state-active" ); + this.menuInstance.focus( null, this._getSelectedItem() ); + } - if ( !this.spinning && !this._start( event ) ) { - return false; - } + // If there are no options, don't open the menu + if ( !this.menuItems.length ) { + return; + } - this._spin( ( delta > 0 ? 1 : -1 ) * this.options.step, event ); - clearTimeout( this.mousewheelTimer ); - this.mousewheelTimer = this._delay( function() { - if ( this.spinning ) { - this._stop( event ); - } - }, 100 ); - event.preventDefault(); - }, - "mousedown .ui-spinner-button": function( event ) { - var previous; + this.isOpen = true; + this._toggleAttr(); + this._resizeMenu(); + this._position(); - // We never want the buttons to have focus; whenever the user is - // interacting with the spinner, the focus should be on the input. - // If the input is focused then this.previous is properly set from - // when the input first received focus. If the input is not focused - // then we need to set this.previous based on the value before spinning. - previous = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] ) ? - this.previous : this.element.val(); - function checkFocus() { - var isActive = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] ); - if ( !isActive ) { - this.element.trigger( "focus" ); - this.previous = previous; + this._on( this.document, this._documentClick ); - // support: IE - // IE sets focus asynchronously, so we need to check if focus - // moved off of the input because the user clicked on the button. - this._delay( function() { - this.previous = previous; - } ); - } - } + this._trigger( "open", event ); + }, - // Ensure focus is on (or stays on) the text field - event.preventDefault(); - checkFocus.call( this ); + _position: function() { + this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) ); + }, - // Support: IE - // IE doesn't prevent moving focus even with event.preventDefault() - // so we set a flag to know when we should ignore the blur event - // and check (again) if focus moved off of the input. - this.cancelBlur = true; - this._delay( function() { - delete this.cancelBlur; - checkFocus.call( this ); - } ); + close: function( event ) { + if ( !this.isOpen ) { + return; + } - if ( this._start( event ) === false ) { - return; - } + this.isOpen = false; + this._toggleAttr(); - this._repeat( null, $( event.currentTarget ) - .hasClass( "ui-spinner-up" ) ? 1 : -1, event ); - }, - "mouseup .ui-spinner-button": "_stop", - "mouseenter .ui-spinner-button": function( event ) { + this.range = null; + this._off( this.document ); - // button will add ui-state-active if mouse was down while mouseleave and kept down - if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) { - return; - } + this._trigger( "close", event ); + }, - if ( this._start( event ) === false ) { - return false; - } - this._repeat( null, $( event.currentTarget ) - .hasClass( "ui-spinner-up" ) ? 1 : -1, event ); - }, + widget: function() { + return this.button; + }, - // TODO: do we really want to consider this a stop? - // shouldn't we just stop the repeater and wait until mouseup before - // we trigger the stop event? - "mouseleave .ui-spinner-button": "_stop" + menuWidget: function() { + return this.menu; }, - // Support mobile enhanced option and make backcompat more sane - _enhance: function() { - this.uiSpinner = this.element - .attr( "autocomplete", "off" ) - .wrap( "<span>" ) - .parent() + _renderButtonItem: function( item ) { + var buttonItem = $( "<span>" ); + + this._setText( buttonItem, item.label ); + this._addClass( buttonItem, "ui-selectmenu-text" ); - // Add buttons - .append( - "<a></a><a></a>" - ); + return buttonItem; }, - _draw: function() { - this._enhance(); + _renderMenu: function( ul, items ) { + var that = this, + currentOptgroup = ""; - this._addClass( this.uiSpinner, "ui-spinner", "ui-widget ui-widget-content" ); - this._addClass( "ui-spinner-input" ); + $.each( items, function( index, item ) { + var li; - this.element.attr( "role", "spinbutton" ); + if ( item.optgroup !== currentOptgroup ) { + li = $( "<li>", { + text: item.optgroup + } ); + that._addClass( li, "ui-selectmenu-optgroup", "ui-menu-divider" + + ( item.element.parent( "optgroup" ).prop( "disabled" ) ? + " ui-state-disabled" : + "" ) ); - // Button bindings - this.buttons = this.uiSpinner.children( "a" ) - .attr( "tabIndex", -1 ) - .attr( "aria-hidden", true ) - .button( { - classes: { - "ui-button": "" - } - } ); + li.appendTo( ul ); - // TODO: Right now button does not support classes this is already updated in button PR - this._removeClass( this.buttons, "ui-corner-all" ); + currentOptgroup = item.optgroup; + } - this._addClass( this.buttons.first(), "ui-spinner-button ui-spinner-up" ); - this._addClass( this.buttons.last(), "ui-spinner-button ui-spinner-down" ); - this.buttons.first().button( { - "icon": this.options.icons.up, - "showLabel": false - } ); - this.buttons.last().button( { - "icon": this.options.icons.down, - "showLabel": false + that._renderItemData( ul, item ); } ); + }, - // IE 6 doesn't understand height: 50% for the buttons - // unless the wrapper has an explicit height - if ( this.buttons.height() > Math.ceil( this.uiSpinner.height() * 0.5 ) && - this.uiSpinner.height() > 0 ) { - this.uiSpinner.height( this.uiSpinner.height() ); - } + _renderItemData: function( ul, item ) { + return this._renderItem( ul, item ).data( "ui-selectmenu-item", item ); }, - _keydown: function( event ) { - var options = this.options, - keyCode = $.ui.keyCode; + _renderItem: function( ul, item ) { + var li = $( "<li>" ), + wrapper = $( "<div>", { + title: item.element.attr( "title" ) + } ); - switch ( event.keyCode ) { - case keyCode.UP: - this._repeat( null, 1, event ); - return true; - case keyCode.DOWN: - this._repeat( null, -1, event ); - return true; - case keyCode.PAGE_UP: - this._repeat( null, options.page, event ); - return true; - case keyCode.PAGE_DOWN: - this._repeat( null, -options.page, event ); - return true; + if ( item.disabled ) { + this._addClass( li, null, "ui-state-disabled" ); } + this._setText( wrapper, item.label ); - return false; + return li.append( wrapper ).appendTo( ul ); }, - _start: function( event ) { - if ( !this.spinning && this._trigger( "start", event ) === false ) { - return false; - } - - if ( !this.counter ) { - this.counter = 1; + _setText: function( element, value ) { + if ( value ) { + element.text( value ); + } else { + element.html( " " ); } - this.spinning = true; - return true; }, - _repeat: function( i, steps, event ) { - i = i || 500; + _move: function( direction, event ) { + var item, next, + filter = ".ui-menu-item"; - clearTimeout( this.timer ); - this.timer = this._delay( function() { - this._repeat( 40, steps, event ); - }, i ); + if ( this.isOpen ) { + item = this.menuItems.eq( this.focusIndex ).parent( "li" ); + } else { + item = this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" ); + filter += ":not(.ui-state-disabled)"; + } - this._spin( steps * this.options.step, event ); + if ( direction === "first" || direction === "last" ) { + next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 ); + } else { + next = item[ direction + "All" ]( filter ).eq( 0 ); + } + + if ( next.length ) { + this.menuInstance.focus( event, next ); + } }, - _spin: function( step, event ) { - var value = this.value() || 0; + _getSelectedItem: function() { + return this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" ); + }, - if ( !this.counter ) { - this.counter = 1; - } + _toggle: function( event ) { + this[ this.isOpen ? "close" : "open" ]( event ); + }, - value = this._adjustValue( value + step * this._increment( this.counter ) ); + _setSelection: function() { + var selection; - if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false ) { - this._value( value ); - this.counter++; + if ( !this.range ) { + return; } - }, - _increment: function( i ) { - var incremental = this.options.incremental; + if ( window.getSelection ) { + selection = window.getSelection(); + selection.removeAllRanges(); + selection.addRange( this.range ); - if ( incremental ) { - return typeof incremental === "function" ? - incremental( i ) : - Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 ); + // Support: IE8 + } else { + this.range.select(); } - return 1; + // Support: IE + // Setting the text selection kills the button focus in IE, but + // restoring the focus doesn't kill the selection. + this.button.trigger( "focus" ); }, - _precision: function() { - var precision = this._precisionOf( this.options.step ); - if ( this.options.min !== null ) { - precision = Math.max( precision, this._precisionOf( this.options.min ) ); + _documentClick: { + mousedown: function( event ) { + if ( !this.isOpen ) { + return; + } + + if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" + + $.escapeSelector( this.ids.button ) ).length ) { + this.close( event ); + } } - return precision; }, - _precisionOf: function( num ) { - var str = num.toString(), - decimal = str.indexOf( "." ); - return decimal === -1 ? 0 : str.length - decimal - 1; - }, + _buttonEvents: { - _adjustValue: function( value ) { - var base, aboveMin, - options = this.options; + // Prevent text selection from being reset when interacting with the selectmenu (#10144) + mousedown: function() { + var selection; - // Make sure we're at a valid step - // - find out where we are relative to the base (min or 0) - base = options.min !== null ? options.min : 0; - aboveMin = value - base; + if ( window.getSelection ) { + selection = window.getSelection(); + if ( selection.rangeCount ) { + this.range = selection.getRangeAt( 0 ); + } + + // Support: IE8 + } else { + this.range = document.selection.createRange(); + } + }, + + click: function( event ) { + this._setSelection(); + this._toggle( event ); + }, + + keydown: function( event ) { + var preventDefault = true; + switch ( event.keyCode ) { + case $.ui.keyCode.TAB: + case $.ui.keyCode.ESCAPE: + this.close( event ); + preventDefault = false; + break; + case $.ui.keyCode.ENTER: + if ( this.isOpen ) { + this._selectFocusedItem( event ); + } + break; + case $.ui.keyCode.UP: + if ( event.altKey ) { + this._toggle( event ); + } else { + this._move( "prev", event ); + } + break; + case $.ui.keyCode.DOWN: + if ( event.altKey ) { + this._toggle( event ); + } else { + this._move( "next", event ); + } + break; + case $.ui.keyCode.SPACE: + if ( this.isOpen ) { + this._selectFocusedItem( event ); + } else { + this._toggle( event ); + } + break; + case $.ui.keyCode.LEFT: + this._move( "prev", event ); + break; + case $.ui.keyCode.RIGHT: + this._move( "next", event ); + break; + case $.ui.keyCode.HOME: + case $.ui.keyCode.PAGE_UP: + this._move( "first", event ); + break; + case $.ui.keyCode.END: + case $.ui.keyCode.PAGE_DOWN: + this._move( "last", event ); + break; + default: + this.menu.trigger( event ); + preventDefault = false; + } - // - round to the nearest step - aboveMin = Math.round( aboveMin / options.step ) * options.step; + if ( preventDefault ) { + event.preventDefault(); + } + } + }, - // - rounding is based on 0, so adjust back to our base - value = base + aboveMin; + _selectFocusedItem: function( event ) { + var item = this.menuItems.eq( this.focusIndex ).parent( "li" ); + if ( !item.hasClass( "ui-state-disabled" ) ) { + this._select( item.data( "ui-selectmenu-item" ), event ); + } + }, - // Fix precision from bad JS floating point math - value = parseFloat( value.toFixed( this._precision() ) ); + _select: function( item, event ) { + var oldIndex = this.element[ 0 ].selectedIndex; - // Clamp the value - if ( options.max !== null && value > options.max ) { - return options.max; - } - if ( options.min !== null && value < options.min ) { - return options.min; + // Change native select element + this.element[ 0 ].selectedIndex = item.index; + this.buttonItem.replaceWith( this.buttonItem = this._renderButtonItem( item ) ); + this._setAria( item ); + this._trigger( "select", event, { item: item } ); + + if ( item.index !== oldIndex ) { + this._trigger( "change", event, { item: item } ); } - return value; + this.close( event ); }, - _stop: function( event ) { - if ( !this.spinning ) { - return; - } + _setAria: function( item ) { + var id = this.menuItems.eq( item.index ).attr( "id" ); - clearTimeout( this.timer ); - clearTimeout( this.mousewheelTimer ); - this.counter = 0; - this.spinning = false; - this._trigger( "stop", event ); + this.button.attr( { + "aria-labelledby": id, + "aria-activedescendant": id + } ); + this.menu.attr( "aria-activedescendant", id ); }, _setOption: function( key, value ) { - var prevValue, first, last; - - if ( key === "culture" || key === "numberFormat" ) { - prevValue = this._parse( this.element.val() ); - this.options[ key ] = value; - this.element.val( this._format( prevValue ) ); - return; - } - - if ( key === "max" || key === "min" || key === "step" ) { - if ( typeof value === "string" ) { - value = this._parse( value ); - } - } if ( key === "icons" ) { - first = this.buttons.first().find( ".ui-icon" ); - this._removeClass( first, null, this.options.icons.up ); - this._addClass( first, null, value.up ); - last = this.buttons.last().find( ".ui-icon" ); - this._removeClass( last, null, this.options.icons.down ); - this._addClass( last, null, value.down ); + var icon = this.button.find( "span.ui-icon" ); + this._removeClass( icon, null, this.options.icons.button ) + ._addClass( icon, null, value.button ); } this._super( key, value ); + + if ( key === "appendTo" ) { + this.menuWrap.appendTo( this._appendTo() ); + } + + if ( key === "width" ) { + this._resizeButton(); + } }, _setOptionDisabled: function( value ) { this._super( value ); - this._toggleClass( this.uiSpinner, null, "ui-state-disabled", !!value ); - this.element.prop( "disabled", !!value ); - this.buttons.button( value ? "disable" : "enable" ); + this.menuInstance.option( "disabled", value ); + this.button.attr( "aria-disabled", value ); + this._toggleClass( this.button, null, "ui-state-disabled", value ); + + this.element.prop( "disabled", value ); + if ( value ) { + this.button.attr( "tabindex", -1 ); + this.close(); + } else { + this.button.attr( "tabindex", 0 ); + } }, - _setOptions: spinnerModifier( function( options ) { - this._super( options ); - } ), + _appendTo: function() { + var element = this.options.appendTo; - _parse: function( val ) { - if ( typeof val === "string" && val !== "" ) { - val = window.Globalize && this.options.numberFormat ? - Globalize.parseFloat( val, 10, this.options.culture ) : +val; + if ( element ) { + element = element.jquery || element.nodeType ? + $( element ) : + this.document.find( element ).eq( 0 ); } - return val === "" || isNaN( val ) ? null : val; - }, - _format: function( value ) { - if ( value === "" ) { - return ""; + if ( !element || !element[ 0 ] ) { + element = this.element.closest( ".ui-front, dialog" ); } - return window.Globalize && this.options.numberFormat ? - Globalize.format( value, this.options.numberFormat, this.options.culture ) : - value; - }, - _refresh: function() { - this.element.attr( { - "aria-valuemin": this.options.min, - "aria-valuemax": this.options.max, + if ( !element.length ) { + element = this.document[ 0 ].body; + } - // TODO: what should we do with values that can't be parsed? - "aria-valuenow": this._parse( this.element.val() ) - } ); + return element; }, - isValid: function() { - var value = this.value(); + _toggleAttr: function() { + this.button.attr( "aria-expanded", this.isOpen ); - // Null is invalid - if ( value === null ) { - return false; - } + // We can't use two _toggleClass() calls here, because we need to make sure + // we always remove classes first and add them second, otherwise if both classes have the + // same theme class, it will be removed after we add it. + this._removeClass( this.button, "ui-selectmenu-button-" + + ( this.isOpen ? "closed" : "open" ) ) + ._addClass( this.button, "ui-selectmenu-button-" + + ( this.isOpen ? "open" : "closed" ) ) + ._toggleClass( this.menuWrap, "ui-selectmenu-open", null, this.isOpen ); - // If value gets adjusted, it's invalid - return value === this._adjustValue( value ); + this.menu.attr( "aria-hidden", !this.isOpen ); }, - // Update the value without triggering change - _value: function( value, allowAny ) { - var parsed; - if ( value !== "" ) { - parsed = this._parse( value ); - if ( parsed !== null ) { - if ( !allowAny ) { - parsed = this._adjustValue( parsed ); - } - value = this._format( parsed ); - } + _resizeButton: function() { + var width = this.options.width; + + // For `width: false`, just remove inline style and stop + if ( width === false ) { + this.button.css( "width", "" ); + return; } - this.element.val( value ); - this._refresh(); - }, - _destroy: function() { - this.element - .prop( "disabled", false ) - .removeAttr( "autocomplete role aria-valuemin aria-valuemax aria-valuenow" ); + // For `width: null`, match the width of the original element + if ( width === null ) { + width = this.element.show().outerWidth(); + this.element.hide(); + } - this.uiSpinner.replaceWith( this.element ); + this.button.outerWidth( width ); }, - stepUp: spinnerModifier( function( steps ) { - this._stepUp( steps ); - } ), - _stepUp: function( steps ) { - if ( this._start() ) { - this._spin( ( steps || 1 ) * this.options.step ); - this._stop(); - } - }, + _resizeMenu: function() { + this.menu.outerWidth( Math.max( + this.button.outerWidth(), - stepDown: spinnerModifier( function( steps ) { - this._stepDown( steps ); - } ), - _stepDown: function( steps ) { - if ( this._start() ) { - this._spin( ( steps || 1 ) * -this.options.step ); - this._stop(); - } + // Support: IE10 + // IE10 wraps long text (possibly a rounding bug) + // so we add 1px to avoid the wrapping + this.menu.width( "" ).outerWidth() + 1 + ) ); }, - pageUp: spinnerModifier( function( pages ) { - this._stepUp( ( pages || 1 ) * this.options.page ); - } ), + _getCreateOptions: function() { + var options = this._super(); - pageDown: spinnerModifier( function( pages ) { - this._stepDown( ( pages || 1 ) * this.options.page ); - } ), + options.disabled = this.element.prop( "disabled" ); - value: function( newVal ) { - if ( !arguments.length ) { - return this._parse( this.element.val() ); - } - spinnerModifier( this._value ).call( this, newVal ); + return options; }, - widget: function() { - return this.uiSpinner; - } -} ); - -// DEPRECATED -// TODO: switch return back to widget declaration at top of file when this is removed -if ( $.uiBackCompat !== false ) { - - // Backcompat for spinner html extension points - $.widget( "ui.spinner", $.ui.spinner, { - _enhance: function() { - this.uiSpinner = this.element - .attr( "autocomplete", "off" ) - .wrap( this._uiSpinnerHtml() ) - .parent() + _parseOptions: function( options ) { + var that = this, + data = []; + options.each( function( index, item ) { + if ( item.hidden ) { + return; + } - // Add buttons - .append( this._buttonHtml() ); - }, - _uiSpinnerHtml: function() { - return "<span>"; - }, + data.push( that._parseOption( $( item ), index ) ); + } ); + this.items = data; + }, - _buttonHtml: function() { - return "<a></a><a></a>"; - } - } ); -} + _parseOption: function( option, index ) { + var optgroup = option.parent( "optgroup" ); -var widgetsSpinner = $.ui.spinner; + return { + element: option, + index: index, + value: option.val(), + label: option.text(), + optgroup: optgroup.attr( "label" ) || "", + disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" ) + }; + }, + + _destroy: function() { + this._unbindFormResetHandler(); + this.menuWrap.remove(); + this.button.remove(); + this.element.show(); + this.element.removeUniqueId(); + this.labels.attr( "for", this.ids.element ); + } +} ] ); /*! - * jQuery UI Tabs 1.13.1 + * jQuery UI Slider 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -15043,3579 +14767,3792 @@ var widgetsSpinner = $.ui.spinner; * http://jquery.org/license */ -//>>label: Tabs +//>>label: Slider //>>group: Widgets -//>>description: Transforms a set of container elements into a tab structure. -//>>docs: http://api.jqueryui.com/tabs/ -//>>demos: http://jqueryui.com/tabs/ +//>>description: Displays a flexible slider with ranges and accessibility via keyboard. +//>>docs: http://api.jqueryui.com/slider/ +//>>demos: http://jqueryui.com/slider/ //>>css.structure: ../../themes/base/core.css -//>>css.structure: ../../themes/base/tabs.css +//>>css.structure: ../../themes/base/slider.css //>>css.theme: ../../themes/base/theme.css -$.widget( "ui.tabs", { - version: "1.13.1", - delay: 300, +var widgetsSlider = $.widget( "ui.slider", $.ui.mouse, { + version: "1.13.2", + widgetEventPrefix: "slide", + options: { - active: null, + animate: false, classes: { - "ui-tabs": "ui-corner-all", - "ui-tabs-nav": "ui-corner-all", - "ui-tabs-panel": "ui-corner-bottom", - "ui-tabs-tab": "ui-corner-top" + "ui-slider": "ui-corner-all", + "ui-slider-handle": "ui-corner-all", + + // Note: ui-widget-header isn't the most fittingly semantic framework class for this + // element, but worked best visually with a variety of themes + "ui-slider-range": "ui-corner-all ui-widget-header" }, - collapsible: false, - event: "click", - heightStyle: "content", - hide: null, - show: null, + distance: 0, + max: 100, + min: 0, + orientation: "horizontal", + range: false, + step: 1, + value: 0, + values: null, // Callbacks - activate: null, - beforeActivate: null, - beforeLoad: null, - load: null + change: null, + slide: null, + start: null, + stop: null }, - _isLocal: ( function() { - var rhash = /#.*$/; - - return function( anchor ) { - var anchorUrl, locationUrl; + // Number of pages in a slider + // (how many times can you page up/down to go through the whole range) + numPages: 5, - anchorUrl = anchor.href.replace( rhash, "" ); - locationUrl = location.href.replace( rhash, "" ); + _create: function() { + this._keySliding = false; + this._mouseSliding = false; + this._animateOff = true; + this._handleIndex = null; + this._detectOrientation(); + this._mouseInit(); + this._calculateNewMax(); - // Decoding may throw an error if the URL isn't UTF-8 (#9518) - try { - anchorUrl = decodeURIComponent( anchorUrl ); - } catch ( error ) {} - try { - locationUrl = decodeURIComponent( locationUrl ); - } catch ( error ) {} + this._addClass( "ui-slider ui-slider-" + this.orientation, + "ui-widget ui-widget-content" ); - return anchor.hash.length > 1 && anchorUrl === locationUrl; - }; - } )(), + this._refresh(); - _create: function() { - var that = this, - options = this.options; + this._animateOff = false; + }, - this.running = false; + _refresh: function() { + this._createRange(); + this._createHandles(); + this._setupEvents(); + this._refreshValue(); + }, - this._addClass( "ui-tabs", "ui-widget ui-widget-content" ); - this._toggleClass( "ui-tabs-collapsible", null, options.collapsible ); + _createHandles: function() { + var i, handleCount, + options = this.options, + existingHandles = this.element.find( ".ui-slider-handle" ), + handle = "<span tabindex='0'></span>", + handles = []; - this._processTabs(); - options.active = this._initialActive(); + handleCount = ( options.values && options.values.length ) || 1; - // Take disabling tabs via class attribute from HTML - // into account and update option properly. - if ( Array.isArray( options.disabled ) ) { - options.disabled = $.uniqueSort( options.disabled.concat( - $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) { - return that.tabs.index( li ); - } ) - ) ).sort(); + if ( existingHandles.length > handleCount ) { + existingHandles.slice( handleCount ).remove(); + existingHandles = existingHandles.slice( 0, handleCount ); } - // Check for length avoids error when initializing empty list - if ( this.options.active !== false && this.anchors.length ) { - this.active = this._findActive( options.active ); - } else { - this.active = $(); + for ( i = existingHandles.length; i < handleCount; i++ ) { + handles.push( handle ); } - this._refresh(); + this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) ); - if ( this.active.length ) { - this.load( options.active ); - } + this._addClass( this.handles, "ui-slider-handle", "ui-state-default" ); + + this.handle = this.handles.eq( 0 ); + + this.handles.each( function( i ) { + $( this ) + .data( "ui-slider-handle-index", i ) + .attr( "tabIndex", 0 ); + } ); }, - _initialActive: function() { - var active = this.options.active, - collapsible = this.options.collapsible, - locationHash = location.hash.substring( 1 ); + _createRange: function() { + var options = this.options; - if ( active === null ) { + if ( options.range ) { + if ( options.range === true ) { + if ( !options.values ) { + options.values = [ this._valueMin(), this._valueMin() ]; + } else if ( options.values.length && options.values.length !== 2 ) { + options.values = [ options.values[ 0 ], options.values[ 0 ] ]; + } else if ( Array.isArray( options.values ) ) { + options.values = options.values.slice( 0 ); + } + } - // check the fragment identifier in the URL - if ( locationHash ) { - this.tabs.each( function( i, tab ) { - if ( $( tab ).attr( "aria-controls" ) === locationHash ) { - active = i; - return false; - } + if ( !this.range || !this.range.length ) { + this.range = $( "<div>" ) + .appendTo( this.element ); + + this._addClass( this.range, "ui-slider-range" ); + } else { + this._removeClass( this.range, "ui-slider-range-min ui-slider-range-max" ); + + // Handle range switching from true to min/max + this.range.css( { + "left": "", + "bottom": "" } ); } - - // Check for a tab marked active via a class - if ( active === null ) { - active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) ); + if ( options.range === "min" || options.range === "max" ) { + this._addClass( this.range, "ui-slider-range-" + options.range ); + } + } else { + if ( this.range ) { + this.range.remove(); } + this.range = null; + } + }, - // No active tab, set to false - if ( active === null || active === -1 ) { - active = this.tabs.length ? 0 : false; + _setupEvents: function() { + this._off( this.handles ); + this._on( this.handles, this._handleEvents ); + this._hoverable( this.handles ); + this._focusable( this.handles ); + }, + + _destroy: function() { + this.handles.remove(); + if ( this.range ) { + this.range.remove(); + } + + this._mouseDestroy(); + }, + + _mouseCapture: function( event ) { + var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle, + that = this, + o = this.options; + + if ( o.disabled ) { + return false; + } + + this.elementSize = { + width: this.element.outerWidth(), + height: this.element.outerHeight() + }; + this.elementOffset = this.element.offset(); + + position = { x: event.pageX, y: event.pageY }; + normValue = this._normValueFromMouse( position ); + distance = this._valueMax() - this._valueMin() + 1; + this.handles.each( function( i ) { + var thisDistance = Math.abs( normValue - that.values( i ) ); + if ( ( distance > thisDistance ) || + ( distance === thisDistance && + ( i === that._lastChangedValue || that.values( i ) === o.min ) ) ) { + distance = thisDistance; + closestHandle = $( this ); + index = i; } - } + } ); - // Handle numbers: negative, out of range - if ( active !== false ) { - active = this.tabs.index( this.tabs.eq( active ) ); - if ( active === -1 ) { - active = collapsible ? false : 0; - } + allowed = this._start( event, index ); + if ( allowed === false ) { + return false; } + this._mouseSliding = true; - // Don't allow collapsible: false and active: false - if ( !collapsible && active === false && this.anchors.length ) { - active = 0; - } + this._handleIndex = index; - return active; - }, + this._addClass( closestHandle, null, "ui-state-active" ); + closestHandle.trigger( "focus" ); - _getCreateEventData: function() { - return { - tab: this.active, - panel: !this.active.length ? $() : this._getPanelForTab( this.active ) + offset = closestHandle.offset(); + mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" ); + this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : { + left: event.pageX - offset.left - ( closestHandle.width() / 2 ), + top: event.pageY - offset.top - + ( closestHandle.height() / 2 ) - + ( parseInt( closestHandle.css( "borderTopWidth" ), 10 ) || 0 ) - + ( parseInt( closestHandle.css( "borderBottomWidth" ), 10 ) || 0 ) + + ( parseInt( closestHandle.css( "marginTop" ), 10 ) || 0 ) }; - }, - - _tabKeydown: function( event ) { - var focusedTab = $( $.ui.safeActiveElement( this.document[ 0 ] ) ).closest( "li" ), - selectedIndex = this.tabs.index( focusedTab ), - goingForward = true; - if ( this._handlePageNav( event ) ) { - return; + if ( !this.handles.hasClass( "ui-state-hover" ) ) { + this._slide( event, index, normValue ); } + this._animateOff = true; + return true; + }, - switch ( event.keyCode ) { - case $.ui.keyCode.RIGHT: - case $.ui.keyCode.DOWN: - selectedIndex++; - break; - case $.ui.keyCode.UP: - case $.ui.keyCode.LEFT: - goingForward = false; - selectedIndex--; - break; - case $.ui.keyCode.END: - selectedIndex = this.anchors.length - 1; - break; - case $.ui.keyCode.HOME: - selectedIndex = 0; - break; - case $.ui.keyCode.SPACE: + _mouseStart: function() { + return true; + }, - // Activate only, no collapsing - event.preventDefault(); - clearTimeout( this.activating ); - this._activate( selectedIndex ); - return; - case $.ui.keyCode.ENTER: + _mouseDrag: function( event ) { + var position = { x: event.pageX, y: event.pageY }, + normValue = this._normValueFromMouse( position ); - // Toggle (cancel delayed activation, allow collapsing) - event.preventDefault(); - clearTimeout( this.activating ); + this._slide( event, this._handleIndex, normValue ); - // Determine if we should collapse or activate - this._activate( selectedIndex === this.options.active ? false : selectedIndex ); - return; - default: - return; - } + return false; + }, - // Focus the appropriate tab, based on which key was pressed - event.preventDefault(); - clearTimeout( this.activating ); - selectedIndex = this._focusNextTab( selectedIndex, goingForward ); + _mouseStop: function( event ) { + this._removeClass( this.handles, null, "ui-state-active" ); + this._mouseSliding = false; - // Navigating with control/command key will prevent automatic activation - if ( !event.ctrlKey && !event.metaKey ) { + this._stop( event, this._handleIndex ); + this._change( event, this._handleIndex ); - // Update aria-selected immediately so that AT think the tab is already selected. - // Otherwise AT may confuse the user by stating that they need to activate the tab, - // but the tab will already be activated by the time the announcement finishes. - focusedTab.attr( "aria-selected", "false" ); - this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" ); + this._handleIndex = null; + this._clickOffset = null; + this._animateOff = false; - this.activating = this._delay( function() { - this.option( "active", selectedIndex ); - }, this.delay ); - } + return false; }, - _panelKeydown: function( event ) { - if ( this._handlePageNav( event ) ) { - return; - } + _detectOrientation: function() { + this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal"; + }, - // Ctrl+up moves focus to the current tab - if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) { - event.preventDefault(); - this.active.trigger( "focus" ); + _normValueFromMouse: function( position ) { + var pixelTotal, + pixelMouse, + percentMouse, + valueTotal, + valueMouse; + + if ( this.orientation === "horizontal" ) { + pixelTotal = this.elementSize.width; + pixelMouse = position.x - this.elementOffset.left - + ( this._clickOffset ? this._clickOffset.left : 0 ); + } else { + pixelTotal = this.elementSize.height; + pixelMouse = position.y - this.elementOffset.top - + ( this._clickOffset ? this._clickOffset.top : 0 ); } - }, - // Alt+page up/down moves focus to the previous/next tab (and activates) - _handlePageNav: function( event ) { - if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) { - this._activate( this._focusNextTab( this.options.active - 1, false ) ); - return true; + percentMouse = ( pixelMouse / pixelTotal ); + if ( percentMouse > 1 ) { + percentMouse = 1; } - if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) { - this._activate( this._focusNextTab( this.options.active + 1, true ) ); - return true; + if ( percentMouse < 0 ) { + percentMouse = 0; + } + if ( this.orientation === "vertical" ) { + percentMouse = 1 - percentMouse; } - }, - _findNextTab: function( index, goingForward ) { - var lastTabIndex = this.tabs.length - 1; + valueTotal = this._valueMax() - this._valueMin(); + valueMouse = this._valueMin() + percentMouse * valueTotal; - function constrain() { - if ( index > lastTabIndex ) { - index = 0; - } - if ( index < 0 ) { - index = lastTabIndex; - } - return index; - } + return this._trimAlignValue( valueMouse ); + }, - while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) { - index = goingForward ? index + 1 : index - 1; + _uiHash: function( index, value, values ) { + var uiHash = { + handle: this.handles[ index ], + handleIndex: index, + value: value !== undefined ? value : this.value() + }; + + if ( this._hasMultipleValues() ) { + uiHash.value = value !== undefined ? value : this.values( index ); + uiHash.values = values || this.values(); } - return index; + return uiHash; }, - _focusNextTab: function( index, goingForward ) { - index = this._findNextTab( index, goingForward ); - this.tabs.eq( index ).trigger( "focus" ); - return index; + _hasMultipleValues: function() { + return this.options.values && this.options.values.length; }, - _setOption: function( key, value ) { - if ( key === "active" ) { - - // _activate() will handle invalid values and update this.options - this._activate( value ); - return; - } + _start: function( event, index ) { + return this._trigger( "start", event, this._uiHash( index ) ); + }, - this._super( key, value ); + _slide: function( event, index, newVal ) { + var allowed, otherVal, + currentValue = this.value(), + newValues = this.values(); - if ( key === "collapsible" ) { - this._toggleClass( "ui-tabs-collapsible", null, value ); + if ( this._hasMultipleValues() ) { + otherVal = this.values( index ? 0 : 1 ); + currentValue = this.values( index ); - // Setting collapsible: false while collapsed; open first panel - if ( !value && this.options.active === false ) { - this._activate( 0 ); + if ( this.options.values.length === 2 && this.options.range === true ) { + newVal = index === 0 ? Math.min( otherVal, newVal ) : Math.max( otherVal, newVal ); } - } - if ( key === "event" ) { - this._setupEvents( value ); + newValues[ index ] = newVal; } - if ( key === "heightStyle" ) { - this._setupHeightStyle( value ); + if ( newVal === currentValue ) { + return; } - }, - - _sanitizeSelector: function( hash ) { - return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : ""; - }, - - refresh: function() { - var options = this.options, - lis = this.tablist.children( ":has(a[href])" ); - - // Get disabled tabs from class attribute from HTML - // this will get converted to a boolean if needed in _refresh() - options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) { - return lis.index( tab ); - } ); - this._processTabs(); + allowed = this._trigger( "slide", event, this._uiHash( index, newVal, newValues ) ); - // Was collapsed or no tabs - if ( options.active === false || !this.anchors.length ) { - options.active = false; - this.active = $(); + // A slide can be canceled by returning false from the slide callback + if ( allowed === false ) { + return; + } - // was active, but active tab is gone - } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) { + if ( this._hasMultipleValues() ) { + this.values( index, newVal ); + } else { + this.value( newVal ); + } + }, - // all remaining tabs are disabled - if ( this.tabs.length === options.disabled.length ) { - options.active = false; - this.active = $(); + _stop: function( event, index ) { + this._trigger( "stop", event, this._uiHash( index ) ); + }, - // activate previous tab - } else { - this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) ); - } + _change: function( event, index ) { + if ( !this._keySliding && !this._mouseSliding ) { - // was active, active tab still exists - } else { + //store the last changed value index for reference when handles overlap + this._lastChangedValue = index; + this._trigger( "change", event, this._uiHash( index ) ); + } + }, - // make sure active index is correct - options.active = this.tabs.index( this.active ); + value: function( newValue ) { + if ( arguments.length ) { + this.options.value = this._trimAlignValue( newValue ); + this._refreshValue(); + this._change( null, 0 ); + return; } - this._refresh(); + return this._value(); }, - _refresh: function() { - this._setOptionDisabled( this.options.disabled ); - this._setupEvents( this.options.event ); - this._setupHeightStyle( this.options.heightStyle ); + values: function( index, newValue ) { + var vals, + newValues, + i; - this.tabs.not( this.active ).attr( { - "aria-selected": "false", - "aria-expanded": "false", - tabIndex: -1 - } ); - this.panels.not( this._getPanelForTab( this.active ) ) - .hide() - .attr( { - "aria-hidden": "true" - } ); + if ( arguments.length > 1 ) { + this.options.values[ index ] = this._trimAlignValue( newValue ); + this._refreshValue(); + this._change( null, index ); + return; + } - // Make sure one tab is in the tab order - if ( !this.active.length ) { - this.tabs.eq( 0 ).attr( "tabIndex", 0 ); + if ( arguments.length ) { + if ( Array.isArray( arguments[ 0 ] ) ) { + vals = this.options.values; + newValues = arguments[ 0 ]; + for ( i = 0; i < vals.length; i += 1 ) { + vals[ i ] = this._trimAlignValue( newValues[ i ] ); + this._change( null, i ); + } + this._refreshValue(); + } else { + if ( this._hasMultipleValues() ) { + return this._values( index ); + } else { + return this.value(); + } + } } else { - this.active - .attr( { - "aria-selected": "true", - "aria-expanded": "true", - tabIndex: 0 - } ); - this._addClass( this.active, "ui-tabs-active", "ui-state-active" ); - this._getPanelForTab( this.active ) - .show() - .attr( { - "aria-hidden": "false" - } ); + return this._values(); } }, - _processTabs: function() { - var that = this, - prevTabs = this.tabs, - prevAnchors = this.anchors, - prevPanels = this.panels; + _setOption: function( key, value ) { + var i, + valsLength = 0; - this.tablist = this._getList().attr( "role", "tablist" ); - this._addClass( this.tablist, "ui-tabs-nav", - "ui-helper-reset ui-helper-clearfix ui-widget-header" ); + if ( key === "range" && this.options.range === true ) { + if ( value === "min" ) { + this.options.value = this._values( 0 ); + this.options.values = null; + } else if ( value === "max" ) { + this.options.value = this._values( this.options.values.length - 1 ); + this.options.values = null; + } + } - // Prevent users from focusing disabled tabs via click - this.tablist - .on( "mousedown" + this.eventNamespace, "> li", function( event ) { - if ( $( this ).is( ".ui-state-disabled" ) ) { - event.preventDefault(); + if ( Array.isArray( this.options.values ) ) { + valsLength = this.options.values.length; + } + + this._super( key, value ); + + switch ( key ) { + case "orientation": + this._detectOrientation(); + this._removeClass( "ui-slider-horizontal ui-slider-vertical" ) + ._addClass( "ui-slider-" + this.orientation ); + this._refreshValue(); + if ( this.options.range ) { + this._refreshRange( value ); } - } ) - // Support: IE <9 - // Preventing the default action in mousedown doesn't prevent IE - // from focusing the element, so if the anchor gets focused, blur. - // We don't have to worry about focusing the previously focused - // element since clicking on a non-focusable element should focus - // the body anyway. - .on( "focus" + this.eventNamespace, ".ui-tabs-anchor", function() { - if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) { - this.blur(); + // Reset positioning from previous orientation + this.handles.css( value === "horizontal" ? "bottom" : "left", "" ); + break; + case "value": + this._animateOff = true; + this._refreshValue(); + this._change( null, 0 ); + this._animateOff = false; + break; + case "values": + this._animateOff = true; + this._refreshValue(); + + // Start from the last handle to prevent unreachable handles (#9046) + for ( i = valsLength - 1; i >= 0; i-- ) { + this._change( null, i ); } - } ); + this._animateOff = false; + break; + case "step": + case "min": + case "max": + this._animateOff = true; + this._calculateNewMax(); + this._refreshValue(); + this._animateOff = false; + break; + case "range": + this._animateOff = true; + this._refresh(); + this._animateOff = false; + break; + } + }, - this.tabs = this.tablist.find( "> li:has(a[href])" ) - .attr( { - role: "tab", - tabIndex: -1 - } ); - this._addClass( this.tabs, "ui-tabs-tab", "ui-state-default" ); + _setOptionDisabled: function( value ) { + this._super( value ); - this.anchors = this.tabs.map( function() { - return $( "a", this )[ 0 ]; - } ) - .attr( { - tabIndex: -1 - } ); - this._addClass( this.anchors, "ui-tabs-anchor" ); + this._toggleClass( null, "ui-state-disabled", !!value ); + }, - this.panels = $(); + //internal value getter + // _value() returns value trimmed by min and max, aligned by step + _value: function() { + var val = this.options.value; + val = this._trimAlignValue( val ); - this.anchors.each( function( i, anchor ) { - var selector, panel, panelId, - anchorId = $( anchor ).uniqueId().attr( "id" ), - tab = $( anchor ).closest( "li" ), - originalAriaControls = tab.attr( "aria-controls" ); + return val; + }, - // Inline tab - if ( that._isLocal( anchor ) ) { - selector = anchor.hash; - panelId = selector.substring( 1 ); - panel = that.element.find( that._sanitizeSelector( selector ) ); + //internal values getter + // _values() returns array of values trimmed by min and max, aligned by step + // _values( index ) returns single value trimmed by min and max, aligned by step + _values: function( index ) { + var val, + vals, + i; - // remote tab - } else { + if ( arguments.length ) { + val = this.options.values[ index ]; + val = this._trimAlignValue( val ); - // If the tab doesn't already have aria-controls, - // generate an id by using a throw-away element - panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id; - selector = "#" + panelId; - panel = that.element.find( selector ); - if ( !panel.length ) { - panel = that._createPanel( panelId ); - panel.insertAfter( that.panels[ i - 1 ] || that.tablist ); - } - panel.attr( "aria-live", "polite" ); - } + return val; + } else if ( this._hasMultipleValues() ) { - if ( panel.length ) { - that.panels = that.panels.add( panel ); - } - if ( originalAriaControls ) { - tab.data( "ui-tabs-aria-controls", originalAriaControls ); + // .slice() creates a copy of the array + // this copy gets trimmed by min and max and then returned + vals = this.options.values.slice(); + for ( i = 0; i < vals.length; i += 1 ) { + vals[ i ] = this._trimAlignValue( vals[ i ] ); } - tab.attr( { - "aria-controls": panelId, - "aria-labelledby": anchorId - } ); - panel.attr( "aria-labelledby", anchorId ); - } ); - - this.panels.attr( "role", "tabpanel" ); - this._addClass( this.panels, "ui-tabs-panel", "ui-widget-content" ); - // Avoid memory leaks (#10056) - if ( prevTabs ) { - this._off( prevTabs.not( this.tabs ) ); - this._off( prevAnchors.not( this.anchors ) ); - this._off( prevPanels.not( this.panels ) ); + return vals; + } else { + return []; } }, - // Allow overriding how to find the list for rare usage scenarios (#7715) - _getList: function() { - return this.tablist || this.element.find( "ol, ul" ).eq( 0 ); - }, + // Returns the step-aligned value that val is closest to, between (inclusive) min and max + _trimAlignValue: function( val ) { + if ( val <= this._valueMin() ) { + return this._valueMin(); + } + if ( val >= this._valueMax() ) { + return this._valueMax(); + } + var step = ( this.options.step > 0 ) ? this.options.step : 1, + valModStep = ( val - this._valueMin() ) % step, + alignValue = val - valModStep; - _createPanel: function( id ) { - return $( "<div>" ) - .attr( "id", id ) - .data( "ui-tabs-destroy", true ); + if ( Math.abs( valModStep ) * 2 >= step ) { + alignValue += ( valModStep > 0 ) ? step : ( -step ); + } + + // Since JavaScript has problems with large floats, round + // the final value to 5 digits after the decimal point (see #4124) + return parseFloat( alignValue.toFixed( 5 ) ); }, - _setOptionDisabled: function( disabled ) { - var currentItem, li, i; + _calculateNewMax: function() { + var max = this.options.max, + min = this._valueMin(), + step = this.options.step, + aboveMin = Math.round( ( max - min ) / step ) * step; + max = aboveMin + min; + if ( max > this.options.max ) { - if ( Array.isArray( disabled ) ) { - if ( !disabled.length ) { - disabled = false; - } else if ( disabled.length === this.anchors.length ) { - disabled = true; - } + //If max is not divisible by step, rounding off may increase its value + max -= step; } + this.max = parseFloat( max.toFixed( this._precision() ) ); + }, - // Disable tabs - for ( i = 0; ( li = this.tabs[ i ] ); i++ ) { - currentItem = $( li ); - if ( disabled === true || $.inArray( i, disabled ) !== -1 ) { - currentItem.attr( "aria-disabled", "true" ); - this._addClass( currentItem, null, "ui-state-disabled" ); - } else { - currentItem.removeAttr( "aria-disabled" ); - this._removeClass( currentItem, null, "ui-state-disabled" ); - } + _precision: function() { + var precision = this._precisionOf( this.options.step ); + if ( this.options.min !== null ) { + precision = Math.max( precision, this._precisionOf( this.options.min ) ); } + return precision; + }, - this.options.disabled = disabled; + _precisionOf: function( num ) { + var str = num.toString(), + decimal = str.indexOf( "." ); + return decimal === -1 ? 0 : str.length - decimal - 1; + }, - this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, - disabled === true ); + _valueMin: function() { + return this.options.min; }, - _setupEvents: function( event ) { - var events = {}; - if ( event ) { - $.each( event.split( " " ), function( index, eventName ) { - events[ eventName ] = "_eventHandler"; - } ); + _valueMax: function() { + return this.max; + }, + + _refreshRange: function( orientation ) { + if ( orientation === "vertical" ) { + this.range.css( { "width": "", "left": "" } ); + } + if ( orientation === "horizontal" ) { + this.range.css( { "height": "", "bottom": "" } ); } + }, - this._off( this.anchors.add( this.tabs ).add( this.panels ) ); + _refreshValue: function() { + var lastValPercent, valPercent, value, valueMin, valueMax, + oRange = this.options.range, + o = this.options, + that = this, + animate = ( !this._animateOff ) ? o.animate : false, + _set = {}; - // Always prevent the default action, even when disabled - this._on( true, this.anchors, { - click: function( event ) { - event.preventDefault(); - } - } ); - this._on( this.anchors, events ); - this._on( this.tabs, { keydown: "_tabKeydown" } ); - this._on( this.panels, { keydown: "_panelKeydown" } ); + if ( this._hasMultipleValues() ) { + this.handles.each( function( i ) { + valPercent = ( that.values( i ) - that._valueMin() ) / ( that._valueMax() - + that._valueMin() ) * 100; + _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; + $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); + if ( that.options.range === true ) { + if ( that.orientation === "horizontal" ) { + if ( i === 0 ) { + that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { + left: valPercent + "%" + }, o.animate ); + } + if ( i === 1 ) { + that.range[ animate ? "animate" : "css" ]( { + width: ( valPercent - lastValPercent ) + "%" + }, { + queue: false, + duration: o.animate + } ); + } + } else { + if ( i === 0 ) { + that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { + bottom: ( valPercent ) + "%" + }, o.animate ); + } + if ( i === 1 ) { + that.range[ animate ? "animate" : "css" ]( { + height: ( valPercent - lastValPercent ) + "%" + }, { + queue: false, + duration: o.animate + } ); + } + } + } + lastValPercent = valPercent; + } ); + } else { + value = this.value(); + valueMin = this._valueMin(); + valueMax = this._valueMax(); + valPercent = ( valueMax !== valueMin ) ? + ( value - valueMin ) / ( valueMax - valueMin ) * 100 : + 0; + _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; + this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); - this._focusable( this.tabs ); - this._hoverable( this.tabs ); + if ( oRange === "min" && this.orientation === "horizontal" ) { + this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { + width: valPercent + "%" + }, o.animate ); + } + if ( oRange === "max" && this.orientation === "horizontal" ) { + this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { + width: ( 100 - valPercent ) + "%" + }, o.animate ); + } + if ( oRange === "min" && this.orientation === "vertical" ) { + this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { + height: valPercent + "%" + }, o.animate ); + } + if ( oRange === "max" && this.orientation === "vertical" ) { + this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { + height: ( 100 - valPercent ) + "%" + }, o.animate ); + } + } }, - _setupHeightStyle: function( heightStyle ) { - var maxHeight, - parent = this.element.parent(); + _handleEvents: { + keydown: function( event ) { + var allowed, curVal, newVal, step, + index = $( event.target ).data( "ui-slider-handle-index" ); - if ( heightStyle === "fill" ) { - maxHeight = parent.height(); - maxHeight -= this.element.outerHeight() - this.element.height(); + switch ( event.keyCode ) { + case $.ui.keyCode.HOME: + case $.ui.keyCode.END: + case $.ui.keyCode.PAGE_UP: + case $.ui.keyCode.PAGE_DOWN: + case $.ui.keyCode.UP: + case $.ui.keyCode.RIGHT: + case $.ui.keyCode.DOWN: + case $.ui.keyCode.LEFT: + event.preventDefault(); + if ( !this._keySliding ) { + this._keySliding = true; + this._addClass( $( event.target ), null, "ui-state-active" ); + allowed = this._start( event, index ); + if ( allowed === false ) { + return; + } + } + break; + } - this.element.siblings( ":visible" ).each( function() { - var elem = $( this ), - position = elem.css( "position" ); + step = this.options.step; + if ( this._hasMultipleValues() ) { + curVal = newVal = this.values( index ); + } else { + curVal = newVal = this.value(); + } - if ( position === "absolute" || position === "fixed" ) { - return; - } - maxHeight -= elem.outerHeight( true ); - } ); + switch ( event.keyCode ) { + case $.ui.keyCode.HOME: + newVal = this._valueMin(); + break; + case $.ui.keyCode.END: + newVal = this._valueMax(); + break; + case $.ui.keyCode.PAGE_UP: + newVal = this._trimAlignValue( + curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages ) + ); + break; + case $.ui.keyCode.PAGE_DOWN: + newVal = this._trimAlignValue( + curVal - ( ( this._valueMax() - this._valueMin() ) / this.numPages ) ); + break; + case $.ui.keyCode.UP: + case $.ui.keyCode.RIGHT: + if ( curVal === this._valueMax() ) { + return; + } + newVal = this._trimAlignValue( curVal + step ); + break; + case $.ui.keyCode.DOWN: + case $.ui.keyCode.LEFT: + if ( curVal === this._valueMin() ) { + return; + } + newVal = this._trimAlignValue( curVal - step ); + break; + } - this.element.children().not( this.panels ).each( function() { - maxHeight -= $( this ).outerHeight( true ); - } ); + this._slide( event, index, newVal ); + }, + keyup: function( event ) { + var index = $( event.target ).data( "ui-slider-handle-index" ); - this.panels.each( function() { - $( this ).height( Math.max( 0, maxHeight - - $( this ).innerHeight() + $( this ).height() ) ); - } ) - .css( "overflow", "auto" ); - } else if ( heightStyle === "auto" ) { - maxHeight = 0; - this.panels.each( function() { - maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); - } ).height( maxHeight ); + if ( this._keySliding ) { + this._keySliding = false; + this._stop( event, index ); + this._change( event, index ); + this._removeClass( $( event.target ), null, "ui-state-active" ); + } } - }, + } +} ); - _eventHandler: function( event ) { - var options = this.options, - active = this.active, - anchor = $( event.currentTarget ), - tab = anchor.closest( "li" ), - clickedIsActive = tab[ 0 ] === active[ 0 ], - collapsing = clickedIsActive && options.collapsible, - toShow = collapsing ? $() : this._getPanelForTab( tab ), - toHide = !active.length ? $() : this._getPanelForTab( active ), - eventData = { - oldTab: active, - oldPanel: toHide, - newTab: collapsing ? $() : tab, - newPanel: toShow - }; - event.preventDefault(); +/*! + * jQuery UI Sortable 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ - if ( tab.hasClass( "ui-state-disabled" ) || +//>>label: Sortable +//>>group: Interactions +//>>description: Enables items in a list to be sorted using the mouse. +//>>docs: http://api.jqueryui.com/sortable/ +//>>demos: http://jqueryui.com/sortable/ +//>>css.structure: ../../themes/base/sortable.css - // tab is already loading - tab.hasClass( "ui-tabs-loading" ) || - // can't switch durning an animation - this.running || +var widgetsSortable = $.widget( "ui.sortable", $.ui.mouse, { + version: "1.13.2", + widgetEventPrefix: "sort", + ready: false, + options: { + appendTo: "parent", + axis: false, + connectWith: false, + containment: false, + cursor: "auto", + cursorAt: false, + dropOnEmpty: true, + forcePlaceholderSize: false, + forceHelperSize: false, + grid: false, + handle: false, + helper: "original", + items: "> *", + opacity: false, + placeholder: false, + revert: false, + scroll: true, + scrollSensitivity: 20, + scrollSpeed: 20, + scope: "default", + tolerance: "intersect", + zIndex: 1000, - // click on active header, but not collapsible - ( clickedIsActive && !options.collapsible ) || + // Callbacks + activate: null, + beforeStop: null, + change: null, + deactivate: null, + out: null, + over: null, + receive: null, + remove: null, + sort: null, + start: null, + stop: null, + update: null + }, - // allow canceling activation - ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { - return; - } + _isOverAxis: function( x, reference, size ) { + return ( x >= reference ) && ( x < ( reference + size ) ); + }, - options.active = collapsing ? false : this.tabs.index( tab ); + _isFloating: function( item ) { + return ( /left|right/ ).test( item.css( "float" ) ) || + ( /inline|table-cell/ ).test( item.css( "display" ) ); + }, - this.active = clickedIsActive ? $() : tab; - if ( this.xhr ) { - this.xhr.abort(); - } + _create: function() { + this.containerCache = {}; + this._addClass( "ui-sortable" ); - if ( !toHide.length && !toShow.length ) { - $.error( "jQuery UI Tabs: Mismatching fragment identifier." ); - } + //Get the items + this.refresh(); - if ( toShow.length ) { - this.load( this.tabs.index( tab ), event ); - } - this._toggle( event, eventData ); - }, + //Let's determine the parent's offset + this.offset = this.element.offset(); - // Handles show/hide for selecting tabs - _toggle: function( event, eventData ) { - var that = this, - toShow = eventData.newPanel, - toHide = eventData.oldPanel; + //Initialize mouse events for interaction + this._mouseInit(); - this.running = true; + this._setHandleClassName(); - function complete() { - that.running = false; - that._trigger( "activate", event, eventData ); - } + //We're ready to go + this.ready = true; - function show() { - that._addClass( eventData.newTab.closest( "li" ), "ui-tabs-active", "ui-state-active" ); + }, - if ( toShow.length && that.options.show ) { - that._show( toShow, that.options.show, complete ); - } else { - toShow.show(); - complete(); - } - } + _setOption: function( key, value ) { + this._super( key, value ); - // Start out by hiding, then showing, then completing - if ( toHide.length && this.options.hide ) { - this._hide( toHide, this.options.hide, function() { - that._removeClass( eventData.oldTab.closest( "li" ), - "ui-tabs-active", "ui-state-active" ); - show(); - } ); - } else { - this._removeClass( eventData.oldTab.closest( "li" ), - "ui-tabs-active", "ui-state-active" ); - toHide.hide(); - show(); + if ( key === "handle" ) { + this._setHandleClassName(); } + }, - toHide.attr( "aria-hidden", "true" ); - eventData.oldTab.attr( { - "aria-selected": "false", - "aria-expanded": "false" + _setHandleClassName: function() { + var that = this; + this._removeClass( this.element.find( ".ui-sortable-handle" ), "ui-sortable-handle" ); + $.each( this.items, function() { + that._addClass( + this.instance.options.handle ? + this.item.find( this.instance.options.handle ) : + this.item, + "ui-sortable-handle" + ); } ); + }, - // If we're switching tabs, remove the old tab from the tab order. - // If we're opening from collapsed state, remove the previous tab from the tab order. - // If we're collapsing, then keep the collapsing tab in the tab order. - if ( toShow.length && toHide.length ) { - eventData.oldTab.attr( "tabIndex", -1 ); - } else if ( toShow.length ) { - this.tabs.filter( function() { - return $( this ).attr( "tabIndex" ) === 0; - } ) - .attr( "tabIndex", -1 ); + _destroy: function() { + this._mouseDestroy(); + + for ( var i = this.items.length - 1; i >= 0; i-- ) { + this.items[ i ].item.removeData( this.widgetName + "-item" ); } - toShow.attr( "aria-hidden", "false" ); - eventData.newTab.attr( { - "aria-selected": "true", - "aria-expanded": "true", - tabIndex: 0 - } ); + return this; }, - _activate: function( index ) { - var anchor, - active = this._findActive( index ); + _mouseCapture: function( event, overrideHandle ) { + var currentItem = null, + validHandle = false, + that = this; - // Trying to activate the already active panel - if ( active[ 0 ] === this.active[ 0 ] ) { - return; + if ( this.reverting ) { + return false; } - // Trying to collapse, simulate a click on the current active header - if ( !active.length ) { - active = this.active; + if ( this.options.disabled || this.options.type === "static" ) { + return false; } - anchor = active.find( ".ui-tabs-anchor" )[ 0 ]; - this._eventHandler( { - target: anchor, - currentTarget: anchor, - preventDefault: $.noop + //We have to refresh the items data once first + this._refreshItems( event ); + + //Find out if the clicked node (or one of its parents) is a actual item in this.items + $( event.target ).parents().each( function() { + if ( $.data( this, that.widgetName + "-item" ) === that ) { + currentItem = $( this ); + return false; + } } ); - }, + if ( $.data( event.target, that.widgetName + "-item" ) === that ) { + currentItem = $( event.target ); + } + + if ( !currentItem ) { + return false; + } + if ( this.options.handle && !overrideHandle ) { + $( this.options.handle, currentItem ).find( "*" ).addBack().each( function() { + if ( this === event.target ) { + validHandle = true; + } + } ); + if ( !validHandle ) { + return false; + } + } + + this.currentItem = currentItem; + this._removeCurrentsFromItems(); + return true; - _findActive: function( index ) { - return index === false ? $() : this.tabs.eq( index ); }, - _getIndex: function( index ) { + _mouseStart: function( event, overrideHandle, noActivation ) { - // meta-function to give users option to provide a href string instead of a numerical index. - if ( typeof index === "string" ) { - index = this.anchors.index( this.anchors.filter( "[href$='" + - $.escapeSelector( index ) + "']" ) ); - } + var i, body, + o = this.options; - return index; - }, + this.currentContainer = this; - _destroy: function() { - if ( this.xhr ) { - this.xhr.abort(); - } + //We only need to call refreshPositions, because the refreshItems call has been moved to + // mouseCapture + this.refreshPositions(); - this.tablist - .removeAttr( "role" ) - .off( this.eventNamespace ); + //Prepare the dragged items parent + this.appendTo = $( o.appendTo !== "parent" ? + o.appendTo : + this.currentItem.parent() ); - this.anchors - .removeAttr( "role tabIndex" ) - .removeUniqueId(); + //Create and append the visible helper + this.helper = this._createHelper( event ); - this.tabs.add( this.panels ).each( function() { - if ( $.data( this, "ui-tabs-destroy" ) ) { - $( this ).remove(); - } else { - $( this ).removeAttr( "role tabIndex " + - "aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded" ); - } - } ); + //Cache the helper size + this._cacheHelperProportions(); - this.tabs.each( function() { - var li = $( this ), - prev = li.data( "ui-tabs-aria-controls" ); - if ( prev ) { - li - .attr( "aria-controls", prev ) - .removeData( "ui-tabs-aria-controls" ); - } else { - li.removeAttr( "aria-controls" ); - } - } ); + /* + * - Position generation - + * This block generates everything position related - it's the core of draggables. + */ - this.panels.show(); + //Cache the margins of the original element + this._cacheMargins(); - if ( this.options.heightStyle !== "content" ) { - this.panels.css( "height", "" ); - } - }, + //The element's absolute position on the page minus margins + this.offset = this.currentItem.offset(); + this.offset = { + top: this.offset.top - this.margins.top, + left: this.offset.left - this.margins.left + }; - enable: function( index ) { - var disabled = this.options.disabled; - if ( disabled === false ) { - return; - } + $.extend( this.offset, { + click: { //Where the click happened, relative to the element + left: event.pageX - this.offset.left, + top: event.pageY - this.offset.top + }, - if ( index === undefined ) { - disabled = false; - } else { - index = this._getIndex( index ); - if ( Array.isArray( disabled ) ) { - disabled = $.map( disabled, function( num ) { - return num !== index ? num : null; - } ); - } else { - disabled = $.map( this.tabs, function( li, num ) { - return num !== index ? num : null; - } ); - } - } - this._setOptionDisabled( disabled ); - }, + // This is a relative to absolute position minus the actual position calculation - + // only used for relative positioned helper + relative: this._getRelativeOffset() + } ); - disable: function( index ) { - var disabled = this.options.disabled; - if ( disabled === true ) { - return; + // After we get the helper offset, but before we get the parent offset we can + // change the helper's position to absolute + // TODO: Still need to figure out a way to make relative sorting possible + this.helper.css( "position", "absolute" ); + this.cssPosition = this.helper.css( "position" ); + + //Adjust the mouse offset relative to the helper if "cursorAt" is supplied + if ( o.cursorAt ) { + this._adjustOffsetFromHelper( o.cursorAt ); } - if ( index === undefined ) { - disabled = true; - } else { - index = this._getIndex( index ); - if ( $.inArray( index, disabled ) !== -1 ) { - return; - } - if ( Array.isArray( disabled ) ) { - disabled = $.merge( [ index ], disabled ).sort(); - } else { - disabled = [ index ]; - } + //Cache the former DOM position + this.domPosition = { + prev: this.currentItem.prev()[ 0 ], + parent: this.currentItem.parent()[ 0 ] + }; + + // If the helper is not the original, hide the original so it's not playing any role during + // the drag, won't cause anything bad this way + if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) { + this.currentItem.hide(); } - this._setOptionDisabled( disabled ); - }, - load: function( index, event ) { - index = this._getIndex( index ); - var that = this, - tab = this.tabs.eq( index ), - anchor = tab.find( ".ui-tabs-anchor" ), - panel = this._getPanelForTab( tab ), - eventData = { - tab: tab, - panel: panel - }, - complete = function( jqXHR, status ) { - if ( status === "abort" ) { - that.panels.stop( false, true ); - } + //Create the placeholder + this._createPlaceholder(); - that._removeClass( tab, "ui-tabs-loading" ); - panel.removeAttr( "aria-busy" ); + //Get the next scrolling parent + this.scrollParent = this.placeholder.scrollParent(); - if ( jqXHR === that.xhr ) { - delete that.xhr; - } - }; + $.extend( this.offset, { + parent: this._getParentOffset() + } ); - // Not remote - if ( this._isLocal( anchor[ 0 ] ) ) { - return; + //Set a containment if given in the options + if ( o.containment ) { + this._setContainment(); } - this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) ); - - // Support: jQuery <1.8 - // jQuery <1.8 returns false if the request is canceled in beforeSend, - // but as of 1.8, $.ajax() always returns a jqXHR object. - if ( this.xhr && this.xhr.statusText !== "canceled" ) { - this._addClass( tab, "ui-tabs-loading" ); - panel.attr( "aria-busy", "true" ); + if ( o.cursor && o.cursor !== "auto" ) { // cursor option + body = this.document.find( "body" ); - this.xhr - .done( function( response, status, jqXHR ) { + // Support: IE + this.storedCursor = body.css( "cursor" ); + body.css( "cursor", o.cursor ); - // support: jQuery <1.8 - // http://bugs.jquery.com/ticket/11778 - setTimeout( function() { - panel.html( response ); - that._trigger( "load", event, eventData ); + this.storedStylesheet = + $( "<style>*{ cursor: " + o.cursor + " !important; }</style>" ).appendTo( body ); + } - complete( jqXHR, status ); - }, 1 ); - } ) - .fail( function( jqXHR, status ) { + // We need to make sure to grab the zIndex before setting the + // opacity, because setting the opacity to anything lower than 1 + // causes the zIndex to change from "auto" to 0. + if ( o.zIndex ) { // zIndex option + if ( this.helper.css( "zIndex" ) ) { + this._storedZIndex = this.helper.css( "zIndex" ); + } + this.helper.css( "zIndex", o.zIndex ); + } - // support: jQuery <1.8 - // http://bugs.jquery.com/ticket/11778 - setTimeout( function() { - complete( jqXHR, status ); - }, 1 ); - } ); + if ( o.opacity ) { // opacity option + if ( this.helper.css( "opacity" ) ) { + this._storedOpacity = this.helper.css( "opacity" ); + } + this.helper.css( "opacity", o.opacity ); } - }, - _ajaxSettings: function( anchor, event, eventData ) { - var that = this; - return { + //Prepare scrolling + if ( this.scrollParent[ 0 ] !== this.document[ 0 ] && + this.scrollParent[ 0 ].tagName !== "HTML" ) { + this.overflowOffset = this.scrollParent.offset(); + } - // Support: IE <11 only - // Strip any hash that exists to prevent errors with the Ajax request - url: anchor.attr( "href" ).replace( /#.*$/, "" ), - beforeSend: function( jqXHR, settings ) { - return that._trigger( "beforeLoad", event, - $.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) ); - } - }; - }, + //Call callbacks + this._trigger( "start", event, this._uiHash() ); - _getPanelForTab: function( tab ) { - var id = $( tab ).attr( "aria-controls" ); - return this.element.find( this._sanitizeSelector( "#" + id ) ); - } -} ); + //Recache the helper size + if ( !this._preserveHelperProportions ) { + this._cacheHelperProportions(); + } -// DEPRECATED -// TODO: Switch return back to widget declaration at top of file when this is removed -if ( $.uiBackCompat !== false ) { + //Post "activate" events to possible containers + if ( !noActivation ) { + for ( i = this.containers.length - 1; i >= 0; i-- ) { + this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) ); + } + } - // Backcompat for ui-tab class (now ui-tabs-tab) - $.widget( "ui.tabs", $.ui.tabs, { - _processTabs: function() { - this._superApply( arguments ); - this._addClass( this.tabs, "ui-tab" ); + //Prepare possible droppables + if ( $.ui.ddmanager ) { + $.ui.ddmanager.current = this; } - } ); -} -var widgetsTabs = $.ui.tabs; + if ( $.ui.ddmanager && !o.dropBehaviour ) { + $.ui.ddmanager.prepareOffsets( this, event ); + } + this.dragging = true; -/*! - * jQuery UI Tooltip 1.13.1 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ + this._addClass( this.helper, "ui-sortable-helper" ); -//>>label: Tooltip -//>>group: Widgets -//>>description: Shows additional information for any element on hover or focus. -//>>docs: http://api.jqueryui.com/tooltip/ -//>>demos: http://jqueryui.com/tooltip/ -//>>css.structure: ../../themes/base/core.css -//>>css.structure: ../../themes/base/tooltip.css -//>>css.theme: ../../themes/base/theme.css + //Move the helper, if needed + if ( !this.helper.parent().is( this.appendTo ) ) { + this.helper.detach().appendTo( this.appendTo ); + //Update position + this.offset.parent = this._getParentOffset(); + } -$.widget( "ui.tooltip", { - version: "1.13.1", - options: { - classes: { - "ui-tooltip": "ui-corner-all ui-widget-shadow" - }, - content: function() { - var title = $( this ).attr( "title" ); + //Generate the original position + this.position = this.originalPosition = this._generatePosition( event ); + this.originalPageX = event.pageX; + this.originalPageY = event.pageY; + this.lastPositionAbs = this.positionAbs = this._convertPositionTo( "absolute" ); - // Escape title, since we're going from an attribute to raw HTML - return $( "<a>" ).text( title ).html(); - }, - hide: true, + this._mouseDrag( event ); - // Disabled elements have inconsistent behavior across browsers (#8661) - items: "[title]:not([disabled])", - position: { - my: "left top+15", - at: "left bottom", - collision: "flipfit flip" - }, - show: true, - track: false, + return true; - // Callbacks - close: null, - open: null }, - _addDescribedBy: function( elem, id ) { - var describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ); - describedby.push( id ); - elem - .data( "ui-tooltip-id", id ) - .attr( "aria-describedby", String.prototype.trim.call( describedby.join( " " ) ) ); - }, + _scroll: function( event ) { + var o = this.options, + scrolled = false; - _removeDescribedBy: function( elem ) { - var id = elem.data( "ui-tooltip-id" ), - describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ), - index = $.inArray( id, describedby ); + if ( this.scrollParent[ 0 ] !== this.document[ 0 ] && + this.scrollParent[ 0 ].tagName !== "HTML" ) { - if ( index !== -1 ) { - describedby.splice( index, 1 ); - } + if ( ( this.overflowOffset.top + this.scrollParent[ 0 ].offsetHeight ) - + event.pageY < o.scrollSensitivity ) { + this.scrollParent[ 0 ].scrollTop = + scrolled = this.scrollParent[ 0 ].scrollTop + o.scrollSpeed; + } else if ( event.pageY - this.overflowOffset.top < o.scrollSensitivity ) { + this.scrollParent[ 0 ].scrollTop = + scrolled = this.scrollParent[ 0 ].scrollTop - o.scrollSpeed; + } - elem.removeData( "ui-tooltip-id" ); - describedby = String.prototype.trim.call( describedby.join( " " ) ); - if ( describedby ) { - elem.attr( "aria-describedby", describedby ); - } else { - elem.removeAttr( "aria-describedby" ); - } - }, + if ( ( this.overflowOffset.left + this.scrollParent[ 0 ].offsetWidth ) - + event.pageX < o.scrollSensitivity ) { + this.scrollParent[ 0 ].scrollLeft = scrolled = + this.scrollParent[ 0 ].scrollLeft + o.scrollSpeed; + } else if ( event.pageX - this.overflowOffset.left < o.scrollSensitivity ) { + this.scrollParent[ 0 ].scrollLeft = scrolled = + this.scrollParent[ 0 ].scrollLeft - o.scrollSpeed; + } - _create: function() { - this._on( { - mouseover: "open", - focusin: "open" - } ); + } else { - // IDs of generated tooltips, needed for destroy - this.tooltips = {}; + if ( event.pageY - this.document.scrollTop() < o.scrollSensitivity ) { + scrolled = this.document.scrollTop( this.document.scrollTop() - o.scrollSpeed ); + } else if ( this.window.height() - ( event.pageY - this.document.scrollTop() ) < + o.scrollSensitivity ) { + scrolled = this.document.scrollTop( this.document.scrollTop() + o.scrollSpeed ); + } - // IDs of parent tooltips where we removed the title attribute - this.parents = {}; + if ( event.pageX - this.document.scrollLeft() < o.scrollSensitivity ) { + scrolled = this.document.scrollLeft( + this.document.scrollLeft() - o.scrollSpeed + ); + } else if ( this.window.width() - ( event.pageX - this.document.scrollLeft() ) < + o.scrollSensitivity ) { + scrolled = this.document.scrollLeft( + this.document.scrollLeft() + o.scrollSpeed + ); + } - // Append the aria-live region so tooltips announce correctly - this.liveRegion = $( "<div>" ) - .attr( { - role: "log", - "aria-live": "assertive", - "aria-relevant": "additions" - } ) - .appendTo( this.document[ 0 ].body ); - this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" ); + } - this.disabledTitles = $( [] ); + return scrolled; }, - _setOption: function( key, value ) { - var that = this; + _mouseDrag: function( event ) { + var i, item, itemElement, intersection, + o = this.options; - this._super( key, value ); + //Compute the helpers position + this.position = this._generatePosition( event ); + this.positionAbs = this._convertPositionTo( "absolute" ); - if ( key === "content" ) { - $.each( this.tooltips, function( id, tooltipData ) { - that._updateContent( tooltipData.element ); - } ); + //Set the helper position + if ( !this.options.axis || this.options.axis !== "y" ) { + this.helper[ 0 ].style.left = this.position.left + "px"; + } + if ( !this.options.axis || this.options.axis !== "x" ) { + this.helper[ 0 ].style.top = this.position.top + "px"; } - }, - _setOptionDisabled: function( value ) { - this[ value ? "_disable" : "_enable" ](); - }, + //Do scrolling + if ( o.scroll ) { + if ( this._scroll( event ) !== false ) { - _disable: function() { - var that = this; + //Update item positions used in position checks + this._refreshItemPositions( true ); - // Close open tooltips - $.each( this.tooltips, function( id, tooltipData ) { - var event = $.Event( "blur" ); - event.target = event.currentTarget = tooltipData.element[ 0 ]; - that.close( event, true ); - } ); + if ( $.ui.ddmanager && !o.dropBehaviour ) { + $.ui.ddmanager.prepareOffsets( this, event ); + } + } + } - // Remove title attributes to prevent native tooltips - this.disabledTitles = this.disabledTitles.add( - this.element.find( this.options.items ).addBack() - .filter( function() { - var element = $( this ); - if ( element.is( "[title]" ) ) { - return element - .data( "ui-tooltip-title", element.attr( "title" ) ) - .removeAttr( "title" ); - } - } ) - ); - }, + this.dragDirection = { + vertical: this._getDragVerticalDirection(), + horizontal: this._getDragHorizontalDirection() + }; - _enable: function() { + //Rearrange + for ( i = this.items.length - 1; i >= 0; i-- ) { - // restore title attributes - this.disabledTitles.each( function() { - var element = $( this ); - if ( element.data( "ui-tooltip-title" ) ) { - element.attr( "title", element.data( "ui-tooltip-title" ) ); + //Cache variables and intersection, continue if no intersection + item = this.items[ i ]; + itemElement = item.item[ 0 ]; + intersection = this._intersectsWithPointer( item ); + if ( !intersection ) { + continue; } - } ); - this.disabledTitles = $( [] ); - }, - open: function( event ) { - var that = this, - target = $( event ? event.target : this.element ) + // Only put the placeholder inside the current Container, skip all + // items from other containers. This works because when moving + // an item from one container to another the + // currentContainer is switched before the placeholder is moved. + // + // Without this, moving items in "sub-sortables" can cause + // the placeholder to jitter between the outer and inner container. + if ( item.instance !== this.currentContainer ) { + continue; + } + + // Cannot intersect with itself + // no useless actions that have been done before + // no action if the item moved is the parent of the item checked + if ( itemElement !== this.currentItem[ 0 ] && + this.placeholder[ intersection === 1 ? + "next" : "prev" ]()[ 0 ] !== itemElement && + !$.contains( this.placeholder[ 0 ], itemElement ) && + ( this.options.type === "semi-dynamic" ? + !$.contains( this.element[ 0 ], itemElement ) : + true + ) + ) { + + this.direction = intersection === 1 ? "down" : "up"; - // we need closest here due to mouseover bubbling, - // but always pointing at the same event target - .closest( this.options.items ); + if ( this.options.tolerance === "pointer" || + this._intersectsWithSides( item ) ) { + this._rearrange( event, item ); + } else { + break; + } - // No element to show a tooltip for or the tooltip is already open - if ( !target.length || target.data( "ui-tooltip-id" ) ) { - return; + this._trigger( "change", event, this._uiHash() ); + break; + } } - if ( target.attr( "title" ) ) { - target.data( "ui-tooltip-title", target.attr( "title" ) ); + //Post events to containers + this._contactContainers( event ); + + //Interconnect with droppables + if ( $.ui.ddmanager ) { + $.ui.ddmanager.drag( this, event ); } - target.data( "ui-tooltip-open", true ); + //Call callbacks + this._trigger( "sort", event, this._uiHash() ); - // Kill parent tooltips, custom or native, for hover - if ( event && event.type === "mouseover" ) { - target.parents().each( function() { - var parent = $( this ), - blurEvent; - if ( parent.data( "ui-tooltip-open" ) ) { - blurEvent = $.Event( "blur" ); - blurEvent.target = blurEvent.currentTarget = this; - that.close( blurEvent, true ); - } - if ( parent.attr( "title" ) ) { - parent.uniqueId(); - that.parents[ this.id ] = { - element: this, - title: parent.attr( "title" ) - }; - parent.attr( "title", "" ); - } - } ); - } + this.lastPositionAbs = this.positionAbs; + return false; - this._registerCloseHandlers( event, target ); - this._updateContent( target, event ); }, - _updateContent: function( target, event ) { - var content, - contentOption = this.options.content, - that = this, - eventType = event ? event.type : null; + _mouseStop: function( event, noPropagation ) { - if ( typeof contentOption === "string" || contentOption.nodeType || - contentOption.jquery ) { - return this._open( event, target, contentOption ); + if ( !event ) { + return; } - content = contentOption.call( target[ 0 ], function( response ) { - - // IE may instantly serve a cached response for ajax requests - // delay this call to _open so the other call to _open runs first - that._delay( function() { + //If we are using droppables, inform the manager about the drop + if ( $.ui.ddmanager && !this.options.dropBehaviour ) { + $.ui.ddmanager.drop( this, event ); + } - // Ignore async response if tooltip was closed already - if ( !target.data( "ui-tooltip-open" ) ) { - return; - } + if ( this.options.revert ) { + var that = this, + cur = this.placeholder.offset(), + axis = this.options.axis, + animation = {}; - // JQuery creates a special event for focusin when it doesn't - // exist natively. To improve performance, the native event - // object is reused and the type is changed. Therefore, we can't - // rely on the type being correct after the event finished - // bubbling, so we set it back to the previous value. (#8740) - if ( event ) { - event.type = eventType; + if ( !axis || axis === "x" ) { + animation.left = cur.left - this.offset.parent.left - this.margins.left + + ( this.offsetParent[ 0 ] === this.document[ 0 ].body ? + 0 : + this.offsetParent[ 0 ].scrollLeft + ); + } + if ( !axis || axis === "y" ) { + animation.top = cur.top - this.offset.parent.top - this.margins.top + + ( this.offsetParent[ 0 ] === this.document[ 0 ].body ? + 0 : + this.offsetParent[ 0 ].scrollTop + ); + } + this.reverting = true; + $( this.helper ).animate( + animation, + parseInt( this.options.revert, 10 ) || 500, + function() { + that._clear( event ); } - this._open( event, target, response ); - } ); - } ); - if ( content ) { - this._open( event, target, content ); + ); + } else { + this._clear( event, noPropagation ); } + + return false; + }, - _open: function( event, target, content ) { - var tooltipData, tooltip, delayedShow, a11yContent, - positionOption = $.extend( {}, this.options.position ); + cancel: function() { - if ( !content ) { - return; - } + if ( this.dragging ) { - // Content can be updated multiple times. If the tooltip already - // exists, then just update the content and bail. - tooltipData = this._find( target ); - if ( tooltipData ) { - tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content ); - return; - } + this._mouseUp( new $.Event( "mouseup", { target: null } ) ); - // If we have a title, clear it to prevent the native tooltip - // we have to check first to avoid defining a title if none exists - // (we don't want to cause an element to start matching [title]) - // - // We use removeAttr only for key events, to allow IE to export the correct - // accessible attributes. For mouse events, set to empty string to avoid - // native tooltip showing up (happens only when removing inside mouseover). - if ( target.is( "[title]" ) ) { - if ( event && event.type === "mouseover" ) { - target.attr( "title", "" ); + if ( this.options.helper === "original" ) { + this.currentItem.css( this._storedCSS ); + this._removeClass( this.currentItem, "ui-sortable-helper" ); } else { - target.removeAttr( "title" ); + this.currentItem.show(); } - } - tooltipData = this._tooltip( target ); - tooltip = tooltipData.tooltip; - this._addDescribedBy( target, tooltip.attr( "id" ) ); - tooltip.find( ".ui-tooltip-content" ).html( content ); + //Post deactivating events to containers + for ( var i = this.containers.length - 1; i >= 0; i-- ) { + this.containers[ i ]._trigger( "deactivate", null, this._uiHash( this ) ); + if ( this.containers[ i ].containerCache.over ) { + this.containers[ i ]._trigger( "out", null, this._uiHash( this ) ); + this.containers[ i ].containerCache.over = 0; + } + } - // Support: Voiceover on OS X, JAWS on IE <= 9 - // JAWS announces deletions even when aria-relevant="additions" - // Voiceover will sometimes re-read the entire log region's contents from the beginning - this.liveRegion.children().hide(); - a11yContent = $( "<div>" ).html( tooltip.find( ".ui-tooltip-content" ).html() ); - a11yContent.removeAttr( "name" ).find( "[name]" ).removeAttr( "name" ); - a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" ); - a11yContent.appendTo( this.liveRegion ); + } - function position( event ) { - positionOption.of = event; - if ( tooltip.is( ":hidden" ) ) { - return; + if ( this.placeholder ) { + + //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, + // it unbinds ALL events from the original node! + if ( this.placeholder[ 0 ].parentNode ) { + this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] ); } - tooltip.position( positionOption ); - } - if ( this.options.track && event && /^mouse/.test( event.type ) ) { - this._on( this.document, { - mousemove: position + if ( this.options.helper !== "original" && this.helper && + this.helper[ 0 ].parentNode ) { + this.helper.remove(); + } + + $.extend( this, { + helper: null, + dragging: false, + reverting: false, + _noFinalSort: null } ); - // trigger once to override element-relative positioning - position( event ); - } else { - tooltip.position( $.extend( { - of: target - }, this.options.position ) ); + if ( this.domPosition.prev ) { + $( this.domPosition.prev ).after( this.currentItem ); + } else { + $( this.domPosition.parent ).prepend( this.currentItem ); + } } - tooltip.hide(); + return this; - this._show( tooltip, this.options.show ); + }, - // Handle tracking tooltips that are shown with a delay (#8644). As soon - // as the tooltip is visible, position the tooltip using the most recent - // event. - // Adds the check to add the timers only when both delay and track options are set (#14682) - if ( this.options.track && this.options.show && this.options.show.delay ) { - delayedShow = this.delayedShow = setInterval( function() { - if ( tooltip.is( ":visible" ) ) { - position( positionOption.of ); - clearInterval( delayedShow ); - } - }, 13 ); - } + serialize: function( o ) { - this._trigger( "open", event, { tooltip: tooltip } ); - }, + var items = this._getItemsAsjQuery( o && o.connected ), + str = []; + o = o || {}; - _registerCloseHandlers: function( event, target ) { - var events = { - keyup: function( event ) { - if ( event.keyCode === $.ui.keyCode.ESCAPE ) { - var fakeEvent = $.Event( event ); - fakeEvent.currentTarget = target[ 0 ]; - this.close( fakeEvent, true ); - } + $( items ).each( function() { + var res = ( $( o.item || this ).attr( o.attribute || "id" ) || "" ) + .match( o.expression || ( /(.+)[\-=_](.+)/ ) ); + if ( res ) { + str.push( + ( o.key || res[ 1 ] + "[]" ) + + "=" + ( o.key && o.expression ? res[ 1 ] : res[ 2 ] ) ); } - }; + } ); - // Only bind remove handler for delegated targets. Non-delegated - // tooltips will handle this in destroy. - if ( target[ 0 ] !== this.element[ 0 ] ) { - events.remove = function() { - var targetElement = this._find( target ); - if ( targetElement ) { - this._removeTooltip( targetElement.tooltip ); - } - }; + if ( !str.length && o.key ) { + str.push( o.key + "=" ); } - if ( !event || event.type === "mouseover" ) { - events.mouseleave = "close"; - } - if ( !event || event.type === "focusin" ) { - events.focusout = "close"; - } - this._on( true, target, events ); - }, + return str.join( "&" ); - close: function( event ) { - var tooltip, - that = this, - target = $( event ? event.currentTarget : this.element ), - tooltipData = this._find( target ); + }, - // The tooltip may already be closed - if ( !tooltipData ) { + toArray: function( o ) { - // We set ui-tooltip-open immediately upon open (in open()), but only set the - // additional data once there's actually content to show (in _open()). So even if the - // tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in - // the period between open() and _open(). - target.removeData( "ui-tooltip-open" ); - return; - } + var items = this._getItemsAsjQuery( o && o.connected ), + ret = []; - tooltip = tooltipData.tooltip; + o = o || {}; - // Disabling closes the tooltip, so we need to track when we're closing - // to avoid an infinite loop in case the tooltip becomes disabled on close - if ( tooltipData.closing ) { - return; - } + items.each( function() { + ret.push( $( o.item || this ).attr( o.attribute || "id" ) || "" ); + } ); + return ret; - // Clear the interval for delayed tracking tooltips - clearInterval( this.delayedShow ); + }, - // Only set title if we had one before (see comment in _open()) - // If the title attribute has changed since open(), don't restore - if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) { - target.attr( "title", target.data( "ui-tooltip-title" ) ); - } + /* Be careful with the following core functions */ + _intersectsWith: function( item ) { - this._removeDescribedBy( target ); + var x1 = this.positionAbs.left, + x2 = x1 + this.helperProportions.width, + y1 = this.positionAbs.top, + y2 = y1 + this.helperProportions.height, + l = item.left, + r = l + item.width, + t = item.top, + b = t + item.height, + dyClick = this.offset.click.top, + dxClick = this.offset.click.left, + isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && + ( y1 + dyClick ) < b ), + isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && + ( x1 + dxClick ) < r ), + isOverElement = isOverElementHeight && isOverElementWidth; - tooltipData.hiding = true; - tooltip.stop( true ); - this._hide( tooltip, this.options.hide, function() { - that._removeTooltip( $( this ) ); - } ); + if ( this.options.tolerance === "pointer" || + this.options.forcePointerForContainers || + ( this.options.tolerance !== "pointer" && + this.helperProportions[ this.floating ? "width" : "height" ] > + item[ this.floating ? "width" : "height" ] ) + ) { + return isOverElement; + } else { - target.removeData( "ui-tooltip-open" ); - this._off( target, "mouseleave focusout keyup" ); + return ( l < x1 + ( this.helperProportions.width / 2 ) && // Right Half + x2 - ( this.helperProportions.width / 2 ) < r && // Left Half + t < y1 + ( this.helperProportions.height / 2 ) && // Bottom Half + y2 - ( this.helperProportions.height / 2 ) < b ); // Top Half - // Remove 'remove' binding only on delegated targets - if ( target[ 0 ] !== this.element[ 0 ] ) { - this._off( target, "remove" ); } - this._off( this.document, "mousemove" ); + }, - if ( event && event.type === "mouseleave" ) { - $.each( this.parents, function( id, parent ) { - $( parent.element ).attr( "title", parent.title ); - delete that.parents[ id ]; - } ); - } + _intersectsWithPointer: function( item ) { + var verticalDirection, horizontalDirection, + isOverElementHeight = ( this.options.axis === "x" ) || + this._isOverAxis( + this.positionAbs.top + this.offset.click.top, item.top, item.height ), + isOverElementWidth = ( this.options.axis === "y" ) || + this._isOverAxis( + this.positionAbs.left + this.offset.click.left, item.left, item.width ), + isOverElement = isOverElementHeight && isOverElementWidth; - tooltipData.closing = true; - this._trigger( "close", event, { tooltip: tooltip } ); - if ( !tooltipData.hiding ) { - tooltipData.closing = false; + if ( !isOverElement ) { + return false; } + + verticalDirection = this.dragDirection.vertical; + horizontalDirection = this.dragDirection.horizontal; + + return this.floating ? + ( ( horizontalDirection === "right" || verticalDirection === "down" ) ? 2 : 1 ) : + ( verticalDirection && ( verticalDirection === "down" ? 2 : 1 ) ); + }, - _tooltip: function( element ) { - var tooltip = $( "<div>" ).attr( "role", "tooltip" ), - content = $( "<div>" ).appendTo( tooltip ), - id = tooltip.uniqueId().attr( "id" ); + _intersectsWithSides: function( item ) { - this._addClass( content, "ui-tooltip-content" ); - this._addClass( tooltip, "ui-tooltip", "ui-widget ui-widget-content" ); + var isOverBottomHalf = this._isOverAxis( this.positionAbs.top + + this.offset.click.top, item.top + ( item.height / 2 ), item.height ), + isOverRightHalf = this._isOverAxis( this.positionAbs.left + + this.offset.click.left, item.left + ( item.width / 2 ), item.width ), + verticalDirection = this.dragDirection.vertical, + horizontalDirection = this.dragDirection.horizontal; - tooltip.appendTo( this._appendTo( element ) ); + if ( this.floating && horizontalDirection ) { + return ( ( horizontalDirection === "right" && isOverRightHalf ) || + ( horizontalDirection === "left" && !isOverRightHalf ) ); + } else { + return verticalDirection && ( ( verticalDirection === "down" && isOverBottomHalf ) || + ( verticalDirection === "up" && !isOverBottomHalf ) ); + } - return this.tooltips[ id ] = { - element: element, - tooltip: tooltip - }; }, - _find: function( target ) { - var id = target.data( "ui-tooltip-id" ); - return id ? this.tooltips[ id ] : null; + _getDragVerticalDirection: function() { + var delta = this.positionAbs.top - this.lastPositionAbs.top; + return delta !== 0 && ( delta > 0 ? "down" : "up" ); }, - _removeTooltip: function( tooltip ) { + _getDragHorizontalDirection: function() { + var delta = this.positionAbs.left - this.lastPositionAbs.left; + return delta !== 0 && ( delta > 0 ? "right" : "left" ); + }, - // Clear the interval for delayed tracking tooltips - clearInterval( this.delayedShow ); + refresh: function( event ) { + this._refreshItems( event ); + this._setHandleClassName(); + this.refreshPositions(); + return this; + }, - tooltip.remove(); - delete this.tooltips[ tooltip.attr( "id" ) ]; + _connectWith: function() { + var options = this.options; + return options.connectWith.constructor === String ? + [ options.connectWith ] : + options.connectWith; }, - _appendTo: function( target ) { - var element = target.closest( ".ui-front, dialog" ); + _getItemsAsjQuery: function( connected ) { - if ( !element.length ) { - element = this.document[ 0 ].body; + var i, j, cur, inst, + items = [], + queries = [], + connectWith = this._connectWith(); + + if ( connectWith && connected ) { + for ( i = connectWith.length - 1; i >= 0; i-- ) { + cur = $( connectWith[ i ], this.document[ 0 ] ); + for ( j = cur.length - 1; j >= 0; j-- ) { + inst = $.data( cur[ j ], this.widgetFullName ); + if ( inst && inst !== this && !inst.options.disabled ) { + queries.push( [ typeof inst.options.items === "function" ? + inst.options.items.call( inst.element ) : + $( inst.options.items, inst.element ) + .not( ".ui-sortable-helper" ) + .not( ".ui-sortable-placeholder" ), inst ] ); + } + } + } } - return element; - }, + queries.push( [ typeof this.options.items === "function" ? + this.options.items + .call( this.element, null, { options: this.options, item: this.currentItem } ) : + $( this.options.items, this.element ) + .not( ".ui-sortable-helper" ) + .not( ".ui-sortable-placeholder" ), this ] ); - _destroy: function() { - var that = this; + function addItems() { + items.push( this ); + } + for ( i = queries.length - 1; i >= 0; i-- ) { + queries[ i ][ 0 ].each( addItems ); + } - // Close open tooltips - $.each( this.tooltips, function( id, tooltipData ) { + return $( items ); - // Delegate to close method to handle common cleanup - var event = $.Event( "blur" ), - element = tooltipData.element; - event.target = event.currentTarget = element[ 0 ]; - that.close( event, true ); + }, - // Remove immediately; destroying an open tooltip doesn't use the - // hide animation - $( "#" + id ).remove(); + _removeCurrentsFromItems: function() { - // Restore the title - if ( element.data( "ui-tooltip-title" ) ) { + var list = this.currentItem.find( ":data(" + this.widgetName + "-item)" ); - // If the title attribute has changed since open(), don't restore - if ( !element.attr( "title" ) ) { - element.attr( "title", element.data( "ui-tooltip-title" ) ); + this.items = $.grep( this.items, function( item ) { + for ( var j = 0; j < list.length; j++ ) { + if ( list[ j ] === item.item[ 0 ] ) { + return false; } - element.removeData( "ui-tooltip-title" ); - } - } ); - this.liveRegion.remove(); - } -} ); - -// DEPRECATED -// TODO: Switch return back to widget declaration at top of file when this is removed -if ( $.uiBackCompat !== false ) { - - // Backcompat for tooltipClass option - $.widget( "ui.tooltip", $.ui.tooltip, { - options: { - tooltipClass: null - }, - _tooltip: function() { - var tooltipData = this._superApply( arguments ); - if ( this.options.tooltipClass ) { - tooltipData.tooltip.addClass( this.options.tooltipClass ); } - return tooltipData; - } - } ); -} + return true; + } ); -var widgetsTooltip = $.ui.tooltip; + }, + _refreshItems: function( event ) { + this.items = []; + this.containers = [ this ]; -// Create a local jQuery because jQuery Color relies on it and the -// global may not exist with AMD and a custom build (#10199). -// This module is a noop if used as a regular AMD module. -// eslint-disable-next-line no-unused-vars -var jQuery = $; + var i, j, cur, inst, targetData, _queries, item, queriesLength, + items = this.items, + queries = [ [ typeof this.options.items === "function" ? + this.options.items.call( this.element[ 0 ], event, { item: this.currentItem } ) : + $( this.options.items, this.element ), this ] ], + connectWith = this._connectWith(); + //Shouldn't be run the first time through due to massive slow-down + if ( connectWith && this.ready ) { + for ( i = connectWith.length - 1; i >= 0; i-- ) { + cur = $( connectWith[ i ], this.document[ 0 ] ); + for ( j = cur.length - 1; j >= 0; j-- ) { + inst = $.data( cur[ j ], this.widgetFullName ); + if ( inst && inst !== this && !inst.options.disabled ) { + queries.push( [ typeof inst.options.items === "function" ? + inst.options.items + .call( inst.element[ 0 ], event, { item: this.currentItem } ) : + $( inst.options.items, inst.element ), inst ] ); + this.containers.push( inst ); + } + } + } + } -/*! - * jQuery Color Animations v2.2.0 - * https://github.com/jquery/jquery-color - * - * Copyright OpenJS Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * Date: Sun May 10 09:02:36 2020 +0200 - */ + for ( i = queries.length - 1; i >= 0; i-- ) { + targetData = queries[ i ][ 1 ]; + _queries = queries[ i ][ 0 ]; + for ( j = 0, queriesLength = _queries.length; j < queriesLength; j++ ) { + item = $( _queries[ j ] ); + // Data for target checking (mouse manager) + item.data( this.widgetName + "-item", targetData ); - var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor " + - "borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor", + items.push( { + item: item, + instance: targetData, + width: 0, height: 0, + left: 0, top: 0 + } ); + } + } - class2type = {}, - toString = class2type.toString, + }, - // plusequals test for += 100 -= 100 - rplusequals = /^([\-+])=\s*(\d+\.?\d*)/, + _refreshItemPositions: function( fast ) { + var i, item, t, p; - // a set of RE's that can match strings and generate color tuples. - stringParsers = [ { - re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, - parse: function( execResult ) { - return [ - execResult[ 1 ], - execResult[ 2 ], - execResult[ 3 ], - execResult[ 4 ] - ]; - } - }, { - re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, - parse: function( execResult ) { - return [ - execResult[ 1 ] * 2.55, - execResult[ 2 ] * 2.55, - execResult[ 3 ] * 2.55, - execResult[ 4 ] - ]; - } - }, { + for ( i = this.items.length - 1; i >= 0; i-- ) { + item = this.items[ i ]; - // this regex ignores A-F because it's compared against an already lowercased string - re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})?/, - parse: function( execResult ) { - return [ - parseInt( execResult[ 1 ], 16 ), - parseInt( execResult[ 2 ], 16 ), - parseInt( execResult[ 3 ], 16 ), - execResult[ 4 ] ? - ( parseInt( execResult[ 4 ], 16 ) / 255 ).toFixed( 2 ) : - 1 - ]; + //We ignore calculating positions of all connected containers when we're not over them + if ( this.currentContainer && item.instance !== this.currentContainer && + item.item[ 0 ] !== this.currentItem[ 0 ] ) { + continue; } - }, { - // this regex ignores A-F because it's compared against an already lowercased string - re: /#([a-f0-9])([a-f0-9])([a-f0-9])([a-f0-9])?/, - parse: function( execResult ) { - return [ - parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ), - parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ), - parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ), - execResult[ 4 ] ? - ( parseInt( execResult[ 4 ] + execResult[ 4 ], 16 ) / 255 ) - .toFixed( 2 ) : - 1 - ]; - } - }, { - re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, - space: "hsla", - parse: function( execResult ) { - return [ - execResult[ 1 ], - execResult[ 2 ] / 100, - execResult[ 3 ] / 100, - execResult[ 4 ] - ]; - } - } ], + t = this.options.toleranceElement ? + $( this.options.toleranceElement, item.item ) : + item.item; - // jQuery.Color( ) - color = jQuery.Color = function( color, green, blue, alpha ) { - return new jQuery.Color.fn.parse( color, green, blue, alpha ); - }, - spaces = { - rgba: { - props: { - red: { - idx: 0, - type: "byte" - }, - green: { - idx: 1, - type: "byte" - }, - blue: { - idx: 2, - type: "byte" - } + if ( !fast ) { + item.width = t.outerWidth(); + item.height = t.outerHeight(); } - }, - hsla: { - props: { - hue: { - idx: 0, - type: "degrees" - }, - saturation: { - idx: 1, - type: "percent" - }, - lightness: { - idx: 2, - type: "percent" - } - } + p = t.offset(); + item.left = p.left; + item.top = p.top; } }, - propTypes = { - "byte": { - floor: true, - max: 255 - }, - "percent": { - max: 1 - }, - "degrees": { - mod: 360, - floor: true + + refreshPositions: function( fast ) { + + // Determine whether items are being displayed horizontally + this.floating = this.items.length ? + this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) : + false; + + // This has to be redone because due to the item being moved out/into the offsetParent, + // the offsetParent's position will change + if ( this.offsetParent && this.helper ) { + this.offset.parent = this._getParentOffset(); } - }, - support = color.support = {}, - // element for support tests - supportElem = jQuery( "<p>" )[ 0 ], + this._refreshItemPositions( fast ); - // colors = jQuery.Color.names - colors, + var i, p; - // local aliases of functions called often - each = jQuery.each; + if ( this.options.custom && this.options.custom.refreshContainers ) { + this.options.custom.refreshContainers.call( this ); + } else { + for ( i = this.containers.length - 1; i >= 0; i-- ) { + p = this.containers[ i ].element.offset(); + this.containers[ i ].containerCache.left = p.left; + this.containers[ i ].containerCache.top = p.top; + this.containers[ i ].containerCache.width = + this.containers[ i ].element.outerWidth(); + this.containers[ i ].containerCache.height = + this.containers[ i ].element.outerHeight(); + } + } -// determine rgba support immediately -supportElem.style.cssText = "background-color:rgba(1,1,1,.5)"; -support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1; + return this; + }, -// define cache name and alpha properties -// for rgba and hsla spaces -each( spaces, function( spaceName, space ) { - space.cache = "_" + spaceName; - space.props.alpha = { - idx: 3, - type: "percent", - def: 1 - }; -} ); + _createPlaceholder: function( that ) { + that = that || this; + var className, nodeName, + o = that.options; -// Populate the class2type map -jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), - function( _i, name ) { - class2type[ "[object " + name + "]" ] = name.toLowerCase(); - } ); + if ( !o.placeholder || o.placeholder.constructor === String ) { + className = o.placeholder; + nodeName = that.currentItem[ 0 ].nodeName.toLowerCase(); + o.placeholder = { + element: function() { + + var element = $( "<" + nodeName + ">", that.document[ 0 ] ); + + that._addClass( element, "ui-sortable-placeholder", + className || that.currentItem[ 0 ].className ) + ._removeClass( element, "ui-sortable-helper" ); -function getType( obj ) { - if ( obj == null ) { - return obj + ""; - } + if ( nodeName === "tbody" ) { + that._createTrPlaceholder( + that.currentItem.find( "tr" ).eq( 0 ), + $( "<tr>", that.document[ 0 ] ).appendTo( element ) + ); + } else if ( nodeName === "tr" ) { + that._createTrPlaceholder( that.currentItem, element ); + } else if ( nodeName === "img" ) { + element.attr( "src", that.currentItem.attr( "src" ) ); + } - return typeof obj === "object" ? - class2type[ toString.call( obj ) ] || "object" : - typeof obj; -} + if ( !className ) { + element.css( "visibility", "hidden" ); + } -function clamp( value, prop, allowEmpty ) { - var type = propTypes[ prop.type ] || {}; + return element; + }, + update: function( container, p ) { - if ( value == null ) { - return ( allowEmpty || !prop.def ) ? null : prop.def; - } + // 1. If a className is set as 'placeholder option, we don't force sizes - + // the class is responsible for that + // 2. The option 'forcePlaceholderSize can be enabled to force it even if a + // class name is specified + if ( className && !o.forcePlaceholderSize ) { + return; + } - // ~~ is an short way of doing floor for positive numbers - value = type.floor ? ~~value : parseFloat( value ); + // If the element doesn't have a actual height or width by itself (without + // styles coming from a stylesheet), it receives the inline height and width + // from the dragged item. Or, if it's a tbody or tr, it's going to have a height + // anyway since we're populating them with <td>s above, but they're unlikely to + // be the correct height on their own if the row heights are dynamic, so we'll + // always assign the height of the dragged item given forcePlaceholderSize + // is true. + if ( !p.height() || ( o.forcePlaceholderSize && + ( nodeName === "tbody" || nodeName === "tr" ) ) ) { + p.height( + that.currentItem.innerHeight() - + parseInt( that.currentItem.css( "paddingTop" ) || 0, 10 ) - + parseInt( that.currentItem.css( "paddingBottom" ) || 0, 10 ) ); + } + if ( !p.width() ) { + p.width( + that.currentItem.innerWidth() - + parseInt( that.currentItem.css( "paddingLeft" ) || 0, 10 ) - + parseInt( that.currentItem.css( "paddingRight" ) || 0, 10 ) ); + } + } + }; + } - // IE will pass in empty strings as value for alpha, - // which will hit this case - if ( isNaN( value ) ) { - return prop.def; - } + //Create the placeholder + that.placeholder = $( o.placeholder.element.call( that.element, that.currentItem ) ); - if ( type.mod ) { + //Append it after the actual current item + that.currentItem.after( that.placeholder ); - // we add mod before modding to make sure that negatives values - // get converted properly: -10 -> 350 - return ( value + type.mod ) % type.mod; - } + //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) + o.placeholder.update( that, that.placeholder ); - // for now all property types without mod have min and max - return Math.min( type.max, Math.max( 0, value ) ); -} + }, -function stringParse( string ) { - var inst = color(), - rgba = inst._rgba = []; + _createTrPlaceholder: function( sourceTr, targetTr ) { + var that = this; - string = string.toLowerCase(); + sourceTr.children().each( function() { + $( "<td> </td>", that.document[ 0 ] ) + .attr( "colspan", $( this ).attr( "colspan" ) || 1 ) + .appendTo( targetTr ); + } ); + }, - each( stringParsers, function( _i, parser ) { - var parsed, - match = parser.re.exec( string ), - values = match && parser.parse( match ), - spaceName = parser.space || "rgba"; + _contactContainers: function( event ) { + var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom, + floating, axis, + innermostContainer = null, + innermostIndex = null; - if ( values ) { - parsed = inst[ spaceName ]( values ); + // Get innermost container that intersects with item + for ( i = this.containers.length - 1; i >= 0; i-- ) { - // if this was an rgba parse the assignment might happen twice - // oh well.... - inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ]; - rgba = inst._rgba = parsed._rgba; + // Never consider a container that's located within the item itself + if ( $.contains( this.currentItem[ 0 ], this.containers[ i ].element[ 0 ] ) ) { + continue; + } - // exit each( stringParsers ) here because we matched - return false; - } - } ); + if ( this._intersectsWith( this.containers[ i ].containerCache ) ) { - // Found a stringParser that handled it - if ( rgba.length ) { + // If we've already found a container and it's more "inner" than this, then continue + if ( innermostContainer && + $.contains( + this.containers[ i ].element[ 0 ], + innermostContainer.element[ 0 ] ) ) { + continue; + } - // if this came from a parsed string, force "transparent" when alpha is 0 - // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0) - if ( rgba.join() === "0,0,0,0" ) { - jQuery.extend( rgba, colors.transparent ); - } - return inst; - } + innermostContainer = this.containers[ i ]; + innermostIndex = i; - // named colors - return colors[ string ]; -} + } else { + + // container doesn't intersect. trigger "out" event if necessary + if ( this.containers[ i ].containerCache.over ) { + this.containers[ i ]._trigger( "out", event, this._uiHash( this ) ); + this.containers[ i ].containerCache.over = 0; + } + } -color.fn = jQuery.extend( color.prototype, { - parse: function( red, green, blue, alpha ) { - if ( red === undefined ) { - this._rgba = [ null, null, null, null ]; - return this; } - if ( red.jquery || red.nodeType ) { - red = jQuery( red ).css( green ); - green = undefined; + + // If no intersecting containers found, return + if ( !innermostContainer ) { + return; } - var inst = this, - type = getType( red ), - rgba = this._rgba = []; + // Move the item into the container if it's not there already + if ( this.containers.length === 1 ) { + if ( !this.containers[ innermostIndex ].containerCache.over ) { + this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) ); + this.containers[ innermostIndex ].containerCache.over = 1; + } + } else { - // more than 1 argument specified - assume ( red, green, blue, alpha ) - if ( green !== undefined ) { - red = [ red, green, blue, alpha ]; - type = "array"; - } + // When entering a new container, we will find the item with the least distance and + // append our item near it + dist = 10000; + itemWithLeastDistance = null; + floating = innermostContainer.floating || this._isFloating( this.currentItem ); + posProperty = floating ? "left" : "top"; + sizeProperty = floating ? "width" : "height"; + axis = floating ? "pageX" : "pageY"; - if ( type === "string" ) { - return this.parse( stringParse( red ) || colors._default ); - } + for ( j = this.items.length - 1; j >= 0; j-- ) { + if ( !$.contains( + this.containers[ innermostIndex ].element[ 0 ], this.items[ j ].item[ 0 ] ) + ) { + continue; + } + if ( this.items[ j ].item[ 0 ] === this.currentItem[ 0 ] ) { + continue; + } - if ( type === "array" ) { - each( spaces.rgba.props, function( _key, prop ) { - rgba[ prop.idx ] = clamp( red[ prop.idx ], prop ); - } ); - return this; - } + cur = this.items[ j ].item.offset()[ posProperty ]; + nearBottom = false; + if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) { + nearBottom = true; + } - if ( type === "object" ) { - if ( red instanceof color ) { - each( spaces, function( _spaceName, space ) { - if ( red[ space.cache ] ) { - inst[ space.cache ] = red[ space.cache ].slice(); - } - } ); - } else { - each( spaces, function( _spaceName, space ) { - var cache = space.cache; - each( space.props, function( key, prop ) { + if ( Math.abs( event[ axis ] - cur ) < dist ) { + dist = Math.abs( event[ axis ] - cur ); + itemWithLeastDistance = this.items[ j ]; + this.direction = nearBottom ? "up" : "down"; + } + } - // if the cache doesn't exist, and we know how to convert - if ( !inst[ cache ] && space.to ) { + //Check if dropOnEmpty is enabled + if ( !itemWithLeastDistance && !this.options.dropOnEmpty ) { + return; + } - // if the value was null, we don't need to copy it - // if the key was alpha, we don't need to copy it either - if ( key === "alpha" || red[ key ] == null ) { - return; - } - inst[ cache ] = space.to( inst._rgba ); - } + if ( this.currentContainer === this.containers[ innermostIndex ] ) { + if ( !this.currentContainer.containerCache.over ) { + this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() ); + this.currentContainer.containerCache.over = 1; + } + return; + } - // this is the only case where we allow nulls for ALL properties. - // call clamp with alwaysAllowEmpty - inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true ); - } ); + if ( itemWithLeastDistance ) { + this._rearrange( event, itemWithLeastDistance, null, true ); + } else { + this._rearrange( event, null, this.containers[ innermostIndex ].element, true ); + } + this._trigger( "change", event, this._uiHash() ); + this.containers[ innermostIndex ]._trigger( "change", event, this._uiHash( this ) ); + this.currentContainer = this.containers[ innermostIndex ]; - // everything defined but alpha? - if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) { + //Update the placeholder + this.options.placeholder.update( this.currentContainer, this.placeholder ); - // use the default of 1 - if ( inst[ cache ][ 3 ] == null ) { - inst[ cache ][ 3 ] = 1; - } + //Update scrollParent + this.scrollParent = this.placeholder.scrollParent(); - if ( space.from ) { - inst._rgba = space.from( inst[ cache ] ); - } - } - } ); + //Update overflowOffset + if ( this.scrollParent[ 0 ] !== this.document[ 0 ] && + this.scrollParent[ 0 ].tagName !== "HTML" ) { + this.overflowOffset = this.scrollParent.offset(); } - return this; + + this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) ); + this.containers[ innermostIndex ].containerCache.over = 1; } - }, - is: function( compare ) { - var is = color( compare ), - same = true, - inst = this; - each( spaces, function( _, space ) { - var localCache, - isCache = is[ space.cache ]; - if ( isCache ) { - localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || []; - each( space.props, function( _, prop ) { - if ( isCache[ prop.idx ] != null ) { - same = ( isCache[ prop.idx ] === localCache[ prop.idx ] ); - return same; - } - } ); - } - return same; - } ); - return same; - }, - _space: function() { - var used = [], - inst = this; - each( spaces, function( spaceName, space ) { - if ( inst[ space.cache ] ) { - used.push( spaceName ); - } - } ); - return used.pop(); }, - transition: function( other, distance ) { - var end = color( other ), - spaceName = end._space(), - space = spaces[ spaceName ], - startColor = this.alpha() === 0 ? color( "transparent" ) : this, - start = startColor[ space.cache ] || space.to( startColor._rgba ), - result = start.slice(); - end = end[ space.cache ]; - each( space.props, function( _key, prop ) { - var index = prop.idx, - startValue = start[ index ], - endValue = end[ index ], - type = propTypes[ prop.type ] || {}; + _createHelper: function( event ) { - // if null, don't override start value - if ( endValue === null ) { - return; - } + var o = this.options, + helper = typeof o.helper === "function" ? + $( o.helper.apply( this.element[ 0 ], [ event, this.currentItem ] ) ) : + ( o.helper === "clone" ? this.currentItem.clone() : this.currentItem ); - // if null - use end - if ( startValue === null ) { - result[ index ] = endValue; - } else { - if ( type.mod ) { - if ( endValue - startValue > type.mod / 2 ) { - startValue += type.mod; - } else if ( startValue - endValue > type.mod / 2 ) { - startValue -= type.mod; - } - } - result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop ); - } - } ); - return this[ spaceName ]( result ); - }, - blend: function( opaque ) { + //Add the helper to the DOM if that didn't happen already + if ( !helper.parents( "body" ).length ) { + this.appendTo[ 0 ].appendChild( helper[ 0 ] ); + } - // if we are already opaque - return ourself - if ( this._rgba[ 3 ] === 1 ) { - return this; + if ( helper[ 0 ] === this.currentItem[ 0 ] ) { + this._storedCSS = { + width: this.currentItem[ 0 ].style.width, + height: this.currentItem[ 0 ].style.height, + position: this.currentItem.css( "position" ), + top: this.currentItem.css( "top" ), + left: this.currentItem.css( "left" ) + }; } - var rgb = this._rgba.slice(), - a = rgb.pop(), - blend = color( opaque )._rgba; + if ( !helper[ 0 ].style.width || o.forceHelperSize ) { + helper.width( this.currentItem.width() ); + } + if ( !helper[ 0 ].style.height || o.forceHelperSize ) { + helper.height( this.currentItem.height() ); + } + + return helper; - return color( jQuery.map( rgb, function( v, i ) { - return ( 1 - a ) * blend[ i ] + a * v; - } ) ); }, - toRgbaString: function() { - var prefix = "rgba(", - rgba = jQuery.map( this._rgba, function( v, i ) { - if ( v != null ) { - return v; - } - return i > 2 ? 1 : 0; - } ); - if ( rgba[ 3 ] === 1 ) { - rgba.pop(); - prefix = "rgb("; + _adjustOffsetFromHelper: function( obj ) { + if ( typeof obj === "string" ) { + obj = obj.split( " " ); + } + if ( Array.isArray( obj ) ) { + obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 }; + } + if ( "left" in obj ) { + this.offset.click.left = obj.left + this.margins.left; + } + if ( "right" in obj ) { + this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; + } + if ( "top" in obj ) { + this.offset.click.top = obj.top + this.margins.top; + } + if ( "bottom" in obj ) { + this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; } - - return prefix + rgba.join() + ")"; }, - toHslaString: function() { - var prefix = "hsla(", - hsla = jQuery.map( this.hsla(), function( v, i ) { - if ( v == null ) { - v = i > 2 ? 1 : 0; - } - // catch 1 and 2 - if ( i && i < 3 ) { - v = Math.round( v * 100 ) + "%"; - } - return v; - } ); + _getParentOffset: function() { - if ( hsla[ 3 ] === 1 ) { - hsla.pop(); - prefix = "hsl("; + //Get the offsetParent and cache its position + this.offsetParent = this.helper.offsetParent(); + var po = this.offsetParent.offset(); + + // This is a special case where we need to modify a offset calculated on start, since the + // following happened: + // 1. The position of the helper is absolute, so it's position is calculated based on the + // next positioned parent + // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't + // the document, which means that the scroll is included in the initial calculation of the + // offset of the parent, and never recalculated upon drag + if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== this.document[ 0 ] && + $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) { + po.left += this.scrollParent.scrollLeft(); + po.top += this.scrollParent.scrollTop(); } - return prefix + hsla.join() + ")"; + + // This needs to be actually done for all browsers, since pageX/pageY includes this + // information with an ugly IE fix + if ( this.offsetParent[ 0 ] === this.document[ 0 ].body || + ( this.offsetParent[ 0 ].tagName && + this.offsetParent[ 0 ].tagName.toLowerCase() === "html" && $.ui.ie ) ) { + po = { top: 0, left: 0 }; + } + + return { + top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ), + left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 ) + }; + }, - toHexString: function( includeAlpha ) { - var rgba = this._rgba.slice(), - alpha = rgba.pop(); - if ( includeAlpha ) { - rgba.push( ~~( alpha * 255 ) ); + _getRelativeOffset: function() { + + if ( this.cssPosition === "relative" ) { + var p = this.currentItem.position(); + return { + top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) + + this.scrollParent.scrollTop(), + left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) + + this.scrollParent.scrollLeft() + }; + } else { + return { top: 0, left: 0 }; } - return "#" + jQuery.map( rgba, function( v ) { + }, - // default to 0 when nulls exist - v = ( v || 0 ).toString( 16 ); - return v.length === 1 ? "0" + v : v; - } ).join( "" ); + _cacheMargins: function() { + this.margins = { + left: ( parseInt( this.currentItem.css( "marginLeft" ), 10 ) || 0 ), + top: ( parseInt( this.currentItem.css( "marginTop" ), 10 ) || 0 ) + }; }, - toString: function() { - return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString(); - } -} ); -color.fn.parse.prototype = color.fn; -// hsla conversions adapted from: -// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021 + _cacheHelperProportions: function() { + this.helperProportions = { + width: this.helper.outerWidth(), + height: this.helper.outerHeight() + }; + }, + + _setContainment: function() { + + var ce, co, over, + o = this.options; + if ( o.containment === "parent" ) { + o.containment = this.helper[ 0 ].parentNode; + } + if ( o.containment === "document" || o.containment === "window" ) { + this.containment = [ + 0 - this.offset.relative.left - this.offset.parent.left, + 0 - this.offset.relative.top - this.offset.parent.top, + o.containment === "document" ? + this.document.width() : + this.window.width() - this.helperProportions.width - this.margins.left, + ( o.containment === "document" ? + ( this.document.height() || document.body.parentNode.scrollHeight ) : + this.window.height() || this.document[ 0 ].body.parentNode.scrollHeight + ) - this.helperProportions.height - this.margins.top + ]; + } + + if ( !( /^(document|window|parent)$/ ).test( o.containment ) ) { + ce = $( o.containment )[ 0 ]; + co = $( o.containment ).offset(); + over = ( $( ce ).css( "overflow" ) !== "hidden" ); -function hue2rgb( p, q, h ) { - h = ( h + 1 ) % 1; - if ( h * 6 < 1 ) { - return p + ( q - p ) * h * 6; - } - if ( h * 2 < 1 ) { - return q; - } - if ( h * 3 < 2 ) { - return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6; - } - return p; -} + this.containment = [ + co.left + ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) + + ( parseInt( $( ce ).css( "paddingLeft" ), 10 ) || 0 ) - this.margins.left, + co.top + ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) + + ( parseInt( $( ce ).css( "paddingTop" ), 10 ) || 0 ) - this.margins.top, + co.left + ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - + ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) - + ( parseInt( $( ce ).css( "paddingRight" ), 10 ) || 0 ) - + this.helperProportions.width - this.margins.left, + co.top + ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - + ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) - + ( parseInt( $( ce ).css( "paddingBottom" ), 10 ) || 0 ) - + this.helperProportions.height - this.margins.top + ]; + } -spaces.hsla.to = function( rgba ) { - if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) { - return [ null, null, null, rgba[ 3 ] ]; - } - var r = rgba[ 0 ] / 255, - g = rgba[ 1 ] / 255, - b = rgba[ 2 ] / 255, - a = rgba[ 3 ], - max = Math.max( r, g, b ), - min = Math.min( r, g, b ), - diff = max - min, - add = max + min, - l = add * 0.5, - h, s; + }, - if ( min === max ) { - h = 0; - } else if ( r === max ) { - h = ( 60 * ( g - b ) / diff ) + 360; - } else if ( g === max ) { - h = ( 60 * ( b - r ) / diff ) + 120; - } else { - h = ( 60 * ( r - g ) / diff ) + 240; - } + _convertPositionTo: function( d, pos ) { - // chroma (diff) == 0 means greyscale which, by definition, saturation = 0% - // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add) - if ( diff === 0 ) { - s = 0; - } else if ( l <= 0.5 ) { - s = diff / add; - } else { - s = diff / ( 2 - add ); - } - return [ Math.round( h ) % 360, s, l, a == null ? 1 : a ]; -}; + if ( !pos ) { + pos = this.position; + } + var mod = d === "absolute" ? 1 : -1, + scroll = this.cssPosition === "absolute" && + !( this.scrollParent[ 0 ] !== this.document[ 0 ] && + $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? + this.offsetParent : + this.scrollParent, + scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName ); -spaces.hsla.from = function( hsla ) { - if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) { - return [ null, null, null, hsla[ 3 ] ]; - } - var h = hsla[ 0 ] / 360, - s = hsla[ 1 ], - l = hsla[ 2 ], - a = hsla[ 3 ], - q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s, - p = 2 * l - q; + return { + top: ( - return [ - Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ), - Math.round( hue2rgb( p, q, h ) * 255 ), - Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ), - a - ]; -}; + // The absolute mouse position + pos.top + + // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.relative.top * mod + -each( spaces, function( spaceName, space ) { - var props = space.props, - cache = space.cache, - to = space.to, - from = space.from; + // The offsetParent's offset without borders (offset + border) + this.offset.parent.top * mod - + ( ( this.cssPosition === "fixed" ? + -this.scrollParent.scrollTop() : + ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod ) + ), + left: ( - // makes rgba() and hsla() - color.fn[ spaceName ] = function( value ) { + // The absolute mouse position + pos.left + - // generate a cache for this space if it doesn't exist - if ( to && !this[ cache ] ) { - this[ cache ] = to( this._rgba ); - } - if ( value === undefined ) { - return this[ cache ].slice(); - } + // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.relative.left * mod + - var ret, - type = getType( value ), - arr = ( type === "array" || type === "object" ) ? value : arguments, - local = this[ cache ].slice(); + // The offsetParent's offset without borders (offset + border) + this.offset.parent.left * mod - + ( ( this.cssPosition === "fixed" ? + -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : + scroll.scrollLeft() ) * mod ) + ) + }; - each( props, function( key, prop ) { - var val = arr[ type === "object" ? key : prop.idx ]; - if ( val == null ) { - val = local[ prop.idx ]; - } - local[ prop.idx ] = clamp( val, prop ); - } ); + }, - if ( from ) { - ret = color( from( local ) ); - ret[ cache ] = local; - return ret; - } else { - return color( local ); - } - }; + _generatePosition: function( event ) { - // makes red() green() blue() alpha() hue() saturation() lightness() - each( props, function( key, prop ) { + var top, left, + o = this.options, + pageX = event.pageX, + pageY = event.pageY, + scroll = this.cssPosition === "absolute" && + !( this.scrollParent[ 0 ] !== this.document[ 0 ] && + $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? + this.offsetParent : + this.scrollParent, + scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName ); - // alpha is included in more than one space - if ( color.fn[ key ] ) { - return; + // This is another very weird special case that only happens for relative elements: + // 1. If the css position is relative + // 2. and the scroll parent is the document or similar to the offset parent + // we have to refresh the relative offset during the scroll so there are no jumps + if ( this.cssPosition === "relative" && !( this.scrollParent[ 0 ] !== this.document[ 0 ] && + this.scrollParent[ 0 ] !== this.offsetParent[ 0 ] ) ) { + this.offset.relative = this._getRelativeOffset(); } - color.fn[ key ] = function( value ) { - var local, cur, match, fn, - vtype = getType( value ); - if ( key === "alpha" ) { - fn = this._hsla ? "hsla" : "rgba"; - } else { - fn = spaceName; - } - local = this[ fn ](); - cur = local[ prop.idx ]; + /* + * - Position constraining - + * Constrain the position to a mix of grid, containment. + */ - if ( vtype === "undefined" ) { - return cur; - } + if ( this.originalPosition ) { //If we are not dragging yet, we won't check for options - if ( vtype === "function" ) { - value = value.call( this, cur ); - vtype = getType( value ); - } - if ( value == null && prop.empty ) { - return this; - } - if ( vtype === "string" ) { - match = rplusequals.exec( value ); - if ( match ) { - value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 ); + if ( this.containment ) { + if ( event.pageX - this.offset.click.left < this.containment[ 0 ] ) { + pageX = this.containment[ 0 ] + this.offset.click.left; + } + if ( event.pageY - this.offset.click.top < this.containment[ 1 ] ) { + pageY = this.containment[ 1 ] + this.offset.click.top; + } + if ( event.pageX - this.offset.click.left > this.containment[ 2 ] ) { + pageX = this.containment[ 2 ] + this.offset.click.left; + } + if ( event.pageY - this.offset.click.top > this.containment[ 3 ] ) { + pageY = this.containment[ 3 ] + this.offset.click.top; } } - local[ prop.idx ] = value; - return this[ fn ]( local ); - }; - } ); -} ); -// add cssHook and .fx.step function for each named hook. -// accept a space separated string of properties -color.hook = function( hook ) { - var hooks = hook.split( " " ); - each( hooks, function( _i, hook ) { - jQuery.cssHooks[ hook ] = { - set: function( elem, value ) { - var parsed, curElem, - backgroundColor = ""; + if ( o.grid ) { + top = this.originalPageY + Math.round( ( pageY - this.originalPageY ) / + o.grid[ 1 ] ) * o.grid[ 1 ]; + pageY = this.containment ? + ( ( top - this.offset.click.top >= this.containment[ 1 ] && + top - this.offset.click.top <= this.containment[ 3 ] ) ? + top : + ( ( top - this.offset.click.top >= this.containment[ 1 ] ) ? + top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : + top; + + left = this.originalPageX + Math.round( ( pageX - this.originalPageX ) / + o.grid[ 0 ] ) * o.grid[ 0 ]; + pageX = this.containment ? + ( ( left - this.offset.click.left >= this.containment[ 0 ] && + left - this.offset.click.left <= this.containment[ 2 ] ) ? + left : + ( ( left - this.offset.click.left >= this.containment[ 0 ] ) ? + left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : + left; + } - if ( value !== "transparent" && ( getType( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) { - value = color( parsed || value ); - if ( !support.rgba && value._rgba[ 3 ] !== 1 ) { - curElem = hook === "backgroundColor" ? elem.parentNode : elem; - while ( - ( backgroundColor === "" || backgroundColor === "transparent" ) && - curElem && curElem.style - ) { - try { - backgroundColor = jQuery.css( curElem, "backgroundColor" ); - curElem = curElem.parentNode; - } catch ( e ) { - } - } + } - value = value.blend( backgroundColor && backgroundColor !== "transparent" ? - backgroundColor : - "_default" ); - } + return { + top: ( - value = value.toRgbaString(); - } - try { - elem.style[ hook ] = value; - } catch ( e ) { + // The absolute mouse position + pageY - - // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit' - } - } - }; - jQuery.fx.step[ hook ] = function( fx ) { - if ( !fx.colorInit ) { - fx.start = color( fx.elem, hook ); - fx.end = color( fx.end ); - fx.colorInit = true; - } - jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) ); - }; - } ); + // Click offset (relative to the element) + this.offset.click.top - -}; + // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.relative.top - -color.hook( stepHooks ); + // The offsetParent's offset without borders (offset + border) + this.offset.parent.top + + ( ( this.cssPosition === "fixed" ? + -this.scrollParent.scrollTop() : + ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) ) + ), + left: ( -jQuery.cssHooks.borderColor = { - expand: function( value ) { - var expanded = {}; + // The absolute mouse position + pageX - - each( [ "Top", "Right", "Bottom", "Left" ], function( _i, part ) { - expanded[ "border" + part + "Color" ] = value; - } ); - return expanded; - } -}; + // Click offset (relative to the element) + this.offset.click.left - -// Basic color names only. -// Usage of any of the other color names requires adding yourself or including -// jquery.color.svg-names.js. -colors = jQuery.Color.names = { + // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.relative.left - - // 4.1. Basic color keywords - aqua: "#00ffff", - black: "#000000", - blue: "#0000ff", - fuchsia: "#ff00ff", - gray: "#808080", - green: "#008000", - lime: "#00ff00", - maroon: "#800000", - navy: "#000080", - olive: "#808000", - purple: "#800080", - red: "#ff0000", - silver: "#c0c0c0", - teal: "#008080", - white: "#ffffff", - yellow: "#ffff00", + // The offsetParent's offset without borders (offset + border) + this.offset.parent.left + + ( ( this.cssPosition === "fixed" ? + -this.scrollParent.scrollLeft() : + scrollIsRootNode ? 0 : scroll.scrollLeft() ) ) + ) + }; - // 4.2.3. "transparent" color keyword - transparent: [ null, null, null, 0 ], + }, - _default: "#ffffff" -}; + _rearrange: function( event, i, a, hardRefresh ) { + if ( a ) { + a[ 0 ].appendChild( this.placeholder[ 0 ] ); + } else { + i.item[ 0 ].parentNode.insertBefore( this.placeholder[ 0 ], + ( this.direction === "down" ? i.item[ 0 ] : i.item[ 0 ].nextSibling ) ); + } -/*! - * jQuery UI Effects 1.13.1 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ + //Various things done here to improve the performance: + // 1. we create a setTimeout, that calls refreshPositions + // 2. on the instance, we have a counter variable, that get's higher after every append + // 3. on the local scope, we copy the counter variable, and check in the timeout, + // if it's still the same + // 4. this lets only the last addition to the timeout stack through + this.counter = this.counter ? ++this.counter : 1; + var counter = this.counter; -//>>label: Effects Core -//>>group: Effects -/* eslint-disable max-len */ -//>>description: Extends the internal jQuery effects. Includes morphing and easing. Required by all other effects. -/* eslint-enable max-len */ -//>>docs: http://api.jqueryui.com/category/effects-core/ -//>>demos: http://jqueryui.com/effect/ + this._delay( function() { + if ( counter === this.counter ) { + //Precompute after each DOM insertion, NOT on mousemove + this.refreshPositions( !hardRefresh ); + } + } ); -var dataSpace = "ui-effects-", - dataSpaceStyle = "ui-effects-style", - dataSpaceAnimated = "ui-effects-animated"; + }, -$.effects = { - effect: {} -}; + _clear: function( event, noPropagation ) { -/******************************************************************************/ -/****************************** CLASS ANIMATIONS ******************************/ -/******************************************************************************/ -( function() { + this.reverting = false; -var classAnimationActions = [ "add", "remove", "toggle" ], - shorthandStyles = { - border: 1, - borderBottom: 1, - borderColor: 1, - borderLeft: 1, - borderRight: 1, - borderTop: 1, - borderWidth: 1, - margin: 1, - padding: 1 - }; + // We delay all events that have to be triggered to after the point where the placeholder + // has been removed and everything else normalized again + var i, + delayedTriggers = []; -$.each( - [ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], - function( _, prop ) { - $.fx.step[ prop ] = function( fx ) { - if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) { - jQuery.style( fx.elem, prop, fx.end ); - fx.setAttr = true; + // We first have to update the dom position of the actual currentItem + // Note: don't do it if the current item is already removed (by a user), or it gets + // reappended (see #4088) + if ( !this._noFinalSort && this.currentItem.parent().length ) { + this.placeholder.before( this.currentItem ); + } + this._noFinalSort = null; + + if ( this.helper[ 0 ] === this.currentItem[ 0 ] ) { + for ( i in this._storedCSS ) { + if ( this._storedCSS[ i ] === "auto" || this._storedCSS[ i ] === "static" ) { + this._storedCSS[ i ] = ""; + } } - }; - } -); + this.currentItem.css( this._storedCSS ); + this._removeClass( this.currentItem, "ui-sortable-helper" ); + } else { + this.currentItem.show(); + } -function camelCase( string ) { - return string.replace( /-([\da-z])/gi, function( all, letter ) { - return letter.toUpperCase(); - } ); -} + if ( this.fromOutside && !noPropagation ) { + delayedTriggers.push( function( event ) { + this._trigger( "receive", event, this._uiHash( this.fromOutside ) ); + } ); + } + if ( ( this.fromOutside || + this.domPosition.prev !== + this.currentItem.prev().not( ".ui-sortable-helper" )[ 0 ] || + this.domPosition.parent !== this.currentItem.parent()[ 0 ] ) && !noPropagation ) { -function getElementStyles( elem ) { - var key, len, - style = elem.ownerDocument.defaultView ? - elem.ownerDocument.defaultView.getComputedStyle( elem, null ) : - elem.currentStyle, - styles = {}; + // Trigger update callback if the DOM position has changed + delayedTriggers.push( function( event ) { + this._trigger( "update", event, this._uiHash() ); + } ); + } - if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) { - len = style.length; - while ( len-- ) { - key = style[ len ]; - if ( typeof style[ key ] === "string" ) { - styles[ camelCase( key ) ] = style[ key ]; + // Check if the items Container has Changed and trigger appropriate + // events. + if ( this !== this.currentContainer ) { + if ( !noPropagation ) { + delayedTriggers.push( function( event ) { + this._trigger( "remove", event, this._uiHash() ); + } ); + delayedTriggers.push( ( function( c ) { + return function( event ) { + c._trigger( "receive", event, this._uiHash( this ) ); + }; + } ).call( this, this.currentContainer ) ); + delayedTriggers.push( ( function( c ) { + return function( event ) { + c._trigger( "update", event, this._uiHash( this ) ); + }; + } ).call( this, this.currentContainer ) ); + } + } + + //Post events to containers + function delayEvent( type, instance, container ) { + return function( event ) { + container._trigger( type, event, instance._uiHash( instance ) ); + }; + } + for ( i = this.containers.length - 1; i >= 0; i-- ) { + if ( !noPropagation ) { + delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) ); + } + if ( this.containers[ i ].containerCache.over ) { + delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) ); + this.containers[ i ].containerCache.over = 0; } } - // Support: Opera, IE <9 - } else { - for ( key in style ) { - if ( typeof style[ key ] === "string" ) { - styles[ key ] = style[ key ]; - } + //Do what was originally in plugins + if ( this.storedCursor ) { + this.document.find( "body" ).css( "cursor", this.storedCursor ); + this.storedStylesheet.remove(); + } + if ( this._storedOpacity ) { + this.helper.css( "opacity", this._storedOpacity ); + } + if ( this._storedZIndex ) { + this.helper.css( "zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex ); } - } - return styles; -} + this.dragging = false; -function styleDifference( oldStyle, newStyle ) { - var diff = {}, - name, value; + if ( !noPropagation ) { + this._trigger( "beforeStop", event, this._uiHash() ); + } - for ( name in newStyle ) { - value = newStyle[ name ]; - if ( oldStyle[ name ] !== value ) { - if ( !shorthandStyles[ name ] ) { - if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) { - diff[ name ] = value; - } + //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, + // it unbinds ALL events from the original node! + this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] ); + + if ( !this.cancelHelperRemoval ) { + if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) { + this.helper.remove(); } + this.helper = null; } - } - return diff; -} + if ( !noPropagation ) { + for ( i = 0; i < delayedTriggers.length; i++ ) { -// Support: jQuery <1.8 -if ( !$.fn.addBack ) { - $.fn.addBack = function( selector ) { - return this.add( selector == null ? - this.prevObject : this.prevObject.filter( selector ) - ); - }; -} + // Trigger all delayed events + delayedTriggers[ i ].call( this, event ); + } + this._trigger( "stop", event, this._uiHash() ); + } -$.effects.animateClass = function( value, duration, easing, callback ) { - var o = $.speed( duration, easing, callback ); + this.fromOutside = false; + return !this.cancelHelperRemoval; - return this.queue( function() { - var animated = $( this ), - baseClass = animated.attr( "class" ) || "", - applyClassChange, - allAnimations = o.children ? animated.find( "*" ).addBack() : animated; + }, - // Map the animated objects to store the original styles. - allAnimations = allAnimations.map( function() { - var el = $( this ); - return { - el: el, - start: getElementStyles( this ) - }; - } ); + _trigger: function() { + if ( $.Widget.prototype._trigger.apply( this, arguments ) === false ) { + this.cancel(); + } + }, - // Apply class change - applyClassChange = function() { - $.each( classAnimationActions, function( i, action ) { - if ( value[ action ] ) { - animated[ action + "Class" ]( value[ action ] ); - } - } ); + _uiHash: function( _inst ) { + var inst = _inst || this; + return { + helper: inst.helper, + placeholder: inst.placeholder || $( [] ), + position: inst.position, + originalPosition: inst.originalPosition, + offset: inst.positionAbs, + item: inst.currentItem, + sender: _inst ? _inst.element : null }; - applyClassChange(); - - // Map all animated objects again - calculate new styles and diff - allAnimations = allAnimations.map( function() { - this.end = getElementStyles( this.el[ 0 ] ); - this.diff = styleDifference( this.start, this.end ); - return this; - } ); - - // Apply original class - animated.attr( "class", baseClass ); - - // Map all animated objects again - this time collecting a promise - allAnimations = allAnimations.map( function() { - var styleInfo = this, - dfd = $.Deferred(), - opts = $.extend( {}, o, { - queue: false, - complete: function() { - dfd.resolve( styleInfo ); - } - } ); - - this.el.animate( this.diff, opts ); - return dfd.promise(); - } ); + } - // Once all animations have completed: - $.when.apply( $, allAnimations.get() ).done( function() { +} ); - // Set the final class - applyClassChange(); - // For each animated element, - // clear all css properties that were animated - $.each( arguments, function() { - var el = this.el; - $.each( this.diff, function( key ) { - el.css( key, "" ); - } ); - } ); +/*! + * jQuery UI Spinner 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ - // This is guarnteed to be there if you use jQuery.speed() - // it also handles dequeuing the next anim... - o.complete.call( animated[ 0 ] ); - } ); - } ); -}; +//>>label: Spinner +//>>group: Widgets +//>>description: Displays buttons to easily input numbers via the keyboard or mouse. +//>>docs: http://api.jqueryui.com/spinner/ +//>>demos: http://jqueryui.com/spinner/ +//>>css.structure: ../../themes/base/core.css +//>>css.structure: ../../themes/base/spinner.css +//>>css.theme: ../../themes/base/theme.css -$.fn.extend( { - addClass: ( function( orig ) { - return function( classNames, speed, easing, callback ) { - return speed ? - $.effects.animateClass.call( this, - { add: classNames }, speed, easing, callback ) : - orig.apply( this, arguments ); - }; - } )( $.fn.addClass ), - removeClass: ( function( orig ) { - return function( classNames, speed, easing, callback ) { - return arguments.length > 1 ? - $.effects.animateClass.call( this, - { remove: classNames }, speed, easing, callback ) : - orig.apply( this, arguments ); - }; - } )( $.fn.removeClass ), +function spinnerModifier( fn ) { + return function() { + var previous = this.element.val(); + fn.apply( this, arguments ); + this._refresh(); + if ( previous !== this.element.val() ) { + this._trigger( "change" ); + } + }; +} - toggleClass: ( function( orig ) { - return function( classNames, force, speed, easing, callback ) { - if ( typeof force === "boolean" || force === undefined ) { - if ( !speed ) { +$.widget( "ui.spinner", { + version: "1.13.2", + defaultElement: "<input>", + widgetEventPrefix: "spin", + options: { + classes: { + "ui-spinner": "ui-corner-all", + "ui-spinner-down": "ui-corner-br", + "ui-spinner-up": "ui-corner-tr" + }, + culture: null, + icons: { + down: "ui-icon-triangle-1-s", + up: "ui-icon-triangle-1-n" + }, + incremental: true, + max: null, + min: null, + numberFormat: null, + page: 10, + step: 1, - // Without speed parameter - return orig.apply( this, arguments ); - } else { - return $.effects.animateClass.call( this, - ( force ? { add: classNames } : { remove: classNames } ), - speed, easing, callback ); - } - } else { + change: null, + spin: null, + start: null, + stop: null + }, - // Without force parameter - return $.effects.animateClass.call( this, - { toggle: classNames }, force, speed, easing ); - } - }; - } )( $.fn.toggleClass ), + _create: function() { - switchClass: function( remove, add, speed, easing, callback ) { - return $.effects.animateClass.call( this, { - add: add, - remove: remove - }, speed, easing, callback ); - } -} ); + // handle string values that need to be parsed + this._setOption( "max", this.options.max ); + this._setOption( "min", this.options.min ); + this._setOption( "step", this.options.step ); -} )(); + // Only format if there is a value, prevents the field from being marked + // as invalid in Firefox, see #9573. + if ( this.value() !== "" ) { -/******************************************************************************/ -/*********************************** EFFECTS **********************************/ -/******************************************************************************/ + // Format the value, but don't constrain. + this._value( this.element.val(), true ); + } -( function() { + this._draw(); + this._on( this._events ); + this._refresh(); -if ( $.expr && $.expr.pseudos && $.expr.pseudos.animated ) { - $.expr.pseudos.animated = ( function( orig ) { - return function( elem ) { - return !!$( elem ).data( dataSpaceAnimated ) || orig( elem ); - }; - } )( $.expr.pseudos.animated ); -} + // Turning off autocomplete prevents the browser from remembering the + // value when navigating through history, so we re-enable autocomplete + // if the page is unloaded before the widget is destroyed. #7790 + this._on( this.window, { + beforeunload: function() { + this.element.removeAttr( "autocomplete" ); + } + } ); + }, -if ( $.uiBackCompat !== false ) { - $.extend( $.effects, { + _getCreateOptions: function() { + var options = this._super(); + var element = this.element; - // Saves a set of properties in a data storage - save: function( element, set ) { - var i = 0, length = set.length; - for ( ; i < length; i++ ) { - if ( set[ i ] !== null ) { - element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); - } + $.each( [ "min", "max", "step" ], function( i, option ) { + var value = element.attr( option ); + if ( value != null && value.length ) { + options[ option ] = value; } - }, + } ); - // Restores a set of previously saved properties from a data storage - restore: function( element, set ) { - var val, i = 0, length = set.length; - for ( ; i < length; i++ ) { - if ( set[ i ] !== null ) { - val = element.data( dataSpace + set[ i ] ); - element.css( set[ i ], val ); - } + return options; + }, + + _events: { + keydown: function( event ) { + if ( this._start( event ) && this._keydown( event ) ) { + event.preventDefault(); } }, + keyup: "_stop", + focus: function() { + this.previous = this.element.val(); + }, + blur: function( event ) { + if ( this.cancelBlur ) { + delete this.cancelBlur; + return; + } - setMode: function( el, mode ) { - if ( mode === "toggle" ) { - mode = el.is( ":hidden" ) ? "show" : "hide"; + this._stop(); + this._refresh(); + if ( this.previous !== this.element.val() ) { + this._trigger( "change", event ); } - return mode; }, + mousewheel: function( event, delta ) { + var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ); + var isActive = this.element[ 0 ] === activeElement; - // Wraps the element around a wrapper that copies position properties - createWrapper: function( element ) { + if ( !isActive || !delta ) { + return; + } - // If the element is already wrapped, return it - if ( element.parent().is( ".ui-effects-wrapper" ) ) { - return element.parent(); + if ( !this.spinning && !this._start( event ) ) { + return false; } - // Wrap the element - var props = { - width: element.outerWidth( true ), - height: element.outerHeight( true ), - "float": element.css( "float" ) - }, - wrapper = $( "<div></div>" ) - .addClass( "ui-effects-wrapper" ) - .css( { - fontSize: "100%", - background: "transparent", - border: "none", - margin: 0, - padding: 0 - } ), + this._spin( ( delta > 0 ? 1 : -1 ) * this.options.step, event ); + clearTimeout( this.mousewheelTimer ); + this.mousewheelTimer = this._delay( function() { + if ( this.spinning ) { + this._stop( event ); + } + }, 100 ); + event.preventDefault(); + }, + "mousedown .ui-spinner-button": function( event ) { + var previous; - // Store the size in case width/height are defined in % - Fixes #5245 - size = { - width: element.width(), - height: element.height() - }, - active = document.activeElement; + // We never want the buttons to have focus; whenever the user is + // interacting with the spinner, the focus should be on the input. + // If the input is focused then this.previous is properly set from + // when the input first received focus. If the input is not focused + // then we need to set this.previous based on the value before spinning. + previous = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] ) ? + this.previous : this.element.val(); + function checkFocus() { + var isActive = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] ); + if ( !isActive ) { + this.element.trigger( "focus" ); + this.previous = previous; - // Support: Firefox - // Firefox incorrectly exposes anonymous content - // https://bugzilla.mozilla.org/show_bug.cgi?id=561664 - try { - // eslint-disable-next-line no-unused-expressions - active.id; - } catch ( e ) { - active = document.body; + // support: IE + // IE sets focus asynchronously, so we need to check if focus + // moved off of the input because the user clicked on the button. + this._delay( function() { + this.previous = previous; + } ); + } } - element.wrap( wrapper ); + // Ensure focus is on (or stays on) the text field + event.preventDefault(); + checkFocus.call( this ); - // Fixes #7595 - Elements lose focus when wrapped. - if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { - $( active ).trigger( "focus" ); + // Support: IE + // IE doesn't prevent moving focus even with event.preventDefault() + // so we set a flag to know when we should ignore the blur event + // and check (again) if focus moved off of the input. + this.cancelBlur = true; + this._delay( function() { + delete this.cancelBlur; + checkFocus.call( this ); + } ); + + if ( this._start( event ) === false ) { + return; } - // Hotfix for jQuery 1.4 since some change in wrap() seems to actually - // lose the reference to the wrapped element - wrapper = element.parent(); + this._repeat( null, $( event.currentTarget ) + .hasClass( "ui-spinner-up" ) ? 1 : -1, event ); + }, + "mouseup .ui-spinner-button": "_stop", + "mouseenter .ui-spinner-button": function( event ) { - // Transfer positioning properties to the wrapper - if ( element.css( "position" ) === "static" ) { - wrapper.css( { position: "relative" } ); - element.css( { position: "relative" } ); - } else { - $.extend( props, { - position: element.css( "position" ), - zIndex: element.css( "z-index" ) - } ); - $.each( [ "top", "left", "bottom", "right" ], function( i, pos ) { - props[ pos ] = element.css( pos ); - if ( isNaN( parseInt( props[ pos ], 10 ) ) ) { - props[ pos ] = "auto"; - } - } ); - element.css( { - position: "relative", - top: 0, - left: 0, - right: "auto", - bottom: "auto" - } ); + // button will add ui-state-active if mouse was down while mouseleave and kept down + if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) { + return; } - element.css( size ); - return wrapper.css( props ).show(); + if ( this._start( event ) === false ) { + return false; + } + this._repeat( null, $( event.currentTarget ) + .hasClass( "ui-spinner-up" ) ? 1 : -1, event ); }, - removeWrapper: function( element ) { - var active = document.activeElement; + // TODO: do we really want to consider this a stop? + // shouldn't we just stop the repeater and wait until mouseup before + // we trigger the stop event? + "mouseleave .ui-spinner-button": "_stop" + }, - if ( element.parent().is( ".ui-effects-wrapper" ) ) { - element.parent().replaceWith( element ); + // Support mobile enhanced option and make backcompat more sane + _enhance: function() { + this.uiSpinner = this.element + .attr( "autocomplete", "off" ) + .wrap( "<span>" ) + .parent() - // Fixes #7595 - Elements lose focus when wrapped. - if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { - $( active ).trigger( "focus" ); + // Add buttons + .append( + "<a></a><a></a>" + ); + }, + + _draw: function() { + this._enhance(); + + this._addClass( this.uiSpinner, "ui-spinner", "ui-widget ui-widget-content" ); + this._addClass( "ui-spinner-input" ); + + this.element.attr( "role", "spinbutton" ); + + // Button bindings + this.buttons = this.uiSpinner.children( "a" ) + .attr( "tabIndex", -1 ) + .attr( "aria-hidden", true ) + .button( { + classes: { + "ui-button": "" } - } + } ); + + // TODO: Right now button does not support classes this is already updated in button PR + this._removeClass( this.buttons, "ui-corner-all" ); + + this._addClass( this.buttons.first(), "ui-spinner-button ui-spinner-up" ); + this._addClass( this.buttons.last(), "ui-spinner-button ui-spinner-down" ); + this.buttons.first().button( { + "icon": this.options.icons.up, + "showLabel": false + } ); + this.buttons.last().button( { + "icon": this.options.icons.down, + "showLabel": false + } ); - return element; + // IE 6 doesn't understand height: 50% for the buttons + // unless the wrapper has an explicit height + if ( this.buttons.height() > Math.ceil( this.uiSpinner.height() * 0.5 ) && + this.uiSpinner.height() > 0 ) { + this.uiSpinner.height( this.uiSpinner.height() ); } - } ); -} + }, -$.extend( $.effects, { - version: "1.13.1", + _keydown: function( event ) { + var options = this.options, + keyCode = $.ui.keyCode; - define: function( name, mode, effect ) { - if ( !effect ) { - effect = mode; - mode = "effect"; + switch ( event.keyCode ) { + case keyCode.UP: + this._repeat( null, 1, event ); + return true; + case keyCode.DOWN: + this._repeat( null, -1, event ); + return true; + case keyCode.PAGE_UP: + this._repeat( null, options.page, event ); + return true; + case keyCode.PAGE_DOWN: + this._repeat( null, -options.page, event ); + return true; } - $.effects.effect[ name ] = effect; - $.effects.effect[ name ].mode = mode; - - return effect; + return false; }, - scaledDimensions: function( element, percent, direction ) { - if ( percent === 0 ) { - return { - height: 0, - width: 0, - outerHeight: 0, - outerWidth: 0 - }; + _start: function( event ) { + if ( !this.spinning && this._trigger( "start", event ) === false ) { + return false; } - var x = direction !== "horizontal" ? ( ( percent || 100 ) / 100 ) : 1, - y = direction !== "vertical" ? ( ( percent || 100 ) / 100 ) : 1; + if ( !this.counter ) { + this.counter = 1; + } + this.spinning = true; + return true; + }, - return { - height: element.height() * y, - width: element.width() * x, - outerHeight: element.outerHeight() * y, - outerWidth: element.outerWidth() * x - }; + _repeat: function( i, steps, event ) { + i = i || 500; - }, + clearTimeout( this.timer ); + this.timer = this._delay( function() { + this._repeat( 40, steps, event ); + }, i ); - clipToBox: function( animation ) { - return { - width: animation.clip.right - animation.clip.left, - height: animation.clip.bottom - animation.clip.top, - left: animation.clip.left, - top: animation.clip.top - }; + this._spin( steps * this.options.step, event ); }, - // Injects recently queued functions to be first in line (after "inprogress") - unshift: function( element, queueLength, count ) { - var queue = element.queue(); + _spin: function( step, event ) { + var value = this.value() || 0; - if ( queueLength > 1 ) { - queue.splice.apply( queue, - [ 1, 0 ].concat( queue.splice( queueLength, count ) ) ); + if ( !this.counter ) { + this.counter = 1; } - element.dequeue(); - }, - saveStyle: function( element ) { - element.data( dataSpaceStyle, element[ 0 ].style.cssText ); - }, + value = this._adjustValue( value + step * this._increment( this.counter ) ); - restoreStyle: function( element ) { - element[ 0 ].style.cssText = element.data( dataSpaceStyle ) || ""; - element.removeData( dataSpaceStyle ); + if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false ) { + this._value( value ); + this.counter++; + } }, - mode: function( element, mode ) { - var hidden = element.is( ":hidden" ); + _increment: function( i ) { + var incremental = this.options.incremental; - if ( mode === "toggle" ) { - mode = hidden ? "show" : "hide"; + if ( incremental ) { + return typeof incremental === "function" ? + incremental( i ) : + Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 ); } - if ( hidden ? mode === "hide" : mode === "show" ) { - mode = "none"; + + return 1; + }, + + _precision: function() { + var precision = this._precisionOf( this.options.step ); + if ( this.options.min !== null ) { + precision = Math.max( precision, this._precisionOf( this.options.min ) ); } - return mode; + return precision; }, - // Translates a [top,left] array into a baseline value - getBaseline: function( origin, original ) { - var y, x; + _precisionOf: function( num ) { + var str = num.toString(), + decimal = str.indexOf( "." ); + return decimal === -1 ? 0 : str.length - decimal - 1; + }, - switch ( origin[ 0 ] ) { - case "top": - y = 0; - break; - case "middle": - y = 0.5; - break; - case "bottom": - y = 1; - break; - default: - y = origin[ 0 ] / original.height; - } + _adjustValue: function( value ) { + var base, aboveMin, + options = this.options; - switch ( origin[ 1 ] ) { - case "left": - x = 0; - break; - case "center": - x = 0.5; - break; - case "right": - x = 1; - break; - default: - x = origin[ 1 ] / original.width; - } + // Make sure we're at a valid step + // - find out where we are relative to the base (min or 0) + base = options.min !== null ? options.min : 0; + aboveMin = value - base; - return { - x: x, - y: y - }; - }, + // - round to the nearest step + aboveMin = Math.round( aboveMin / options.step ) * options.step; - // Creates a placeholder element so that the original element can be made absolute - createPlaceholder: function( element ) { - var placeholder, - cssPosition = element.css( "position" ), - position = element.position(); + // - rounding is based on 0, so adjust back to our base + value = base + aboveMin; - // Lock in margins first to account for form elements, which - // will change margin if you explicitly set height - // see: http://jsfiddle.net/JZSMt/3/ https://bugs.webkit.org/show_bug.cgi?id=107380 - // Support: Safari - element.css( { - marginTop: element.css( "marginTop" ), - marginBottom: element.css( "marginBottom" ), - marginLeft: element.css( "marginLeft" ), - marginRight: element.css( "marginRight" ) - } ) - .outerWidth( element.outerWidth() ) - .outerHeight( element.outerHeight() ); + // Fix precision from bad JS floating point math + value = parseFloat( value.toFixed( this._precision() ) ); - if ( /^(static|relative)/.test( cssPosition ) ) { - cssPosition = "absolute"; + // Clamp the value + if ( options.max !== null && value > options.max ) { + return options.max; + } + if ( options.min !== null && value < options.min ) { + return options.min; + } - placeholder = $( "<" + element[ 0 ].nodeName + ">" ).insertAfter( element ).css( { + return value; + }, - // Convert inline to inline block to account for inline elements - // that turn to inline block based on content (like img) - display: /^(inline|ruby)/.test( element.css( "display" ) ) ? - "inline-block" : - "block", - visibility: "hidden", + _stop: function( event ) { + if ( !this.spinning ) { + return; + } - // Margins need to be set to account for margin collapse - marginTop: element.css( "marginTop" ), - marginBottom: element.css( "marginBottom" ), - marginLeft: element.css( "marginLeft" ), - marginRight: element.css( "marginRight" ), - "float": element.css( "float" ) - } ) - .outerWidth( element.outerWidth() ) - .outerHeight( element.outerHeight() ) - .addClass( "ui-effects-placeholder" ); + clearTimeout( this.timer ); + clearTimeout( this.mousewheelTimer ); + this.counter = 0; + this.spinning = false; + this._trigger( "stop", event ); + }, - element.data( dataSpace + "placeholder", placeholder ); + _setOption: function( key, value ) { + var prevValue, first, last; + + if ( key === "culture" || key === "numberFormat" ) { + prevValue = this._parse( this.element.val() ); + this.options[ key ] = value; + this.element.val( this._format( prevValue ) ); + return; } - element.css( { - position: cssPosition, - left: position.left, - top: position.top - } ); + if ( key === "max" || key === "min" || key === "step" ) { + if ( typeof value === "string" ) { + value = this._parse( value ); + } + } + if ( key === "icons" ) { + first = this.buttons.first().find( ".ui-icon" ); + this._removeClass( first, null, this.options.icons.up ); + this._addClass( first, null, value.up ); + last = this.buttons.last().find( ".ui-icon" ); + this._removeClass( last, null, this.options.icons.down ); + this._addClass( last, null, value.down ); + } + + this._super( key, value ); + }, - return placeholder; + _setOptionDisabled: function( value ) { + this._super( value ); + + this._toggleClass( this.uiSpinner, null, "ui-state-disabled", !!value ); + this.element.prop( "disabled", !!value ); + this.buttons.button( value ? "disable" : "enable" ); }, - removePlaceholder: function( element ) { - var dataKey = dataSpace + "placeholder", - placeholder = element.data( dataKey ); + _setOptions: spinnerModifier( function( options ) { + this._super( options ); + } ), - if ( placeholder ) { - placeholder.remove(); - element.removeData( dataKey ); + _parse: function( val ) { + if ( typeof val === "string" && val !== "" ) { + val = window.Globalize && this.options.numberFormat ? + Globalize.parseFloat( val, 10, this.options.culture ) : +val; } + return val === "" || isNaN( val ) ? null : val; }, - // Removes a placeholder if it exists and restores - // properties that were modified during placeholder creation - cleanUp: function( element ) { - $.effects.restoreStyle( element ); - $.effects.removePlaceholder( element ); + _format: function( value ) { + if ( value === "" ) { + return ""; + } + return window.Globalize && this.options.numberFormat ? + Globalize.format( value, this.options.numberFormat, this.options.culture ) : + value; }, - setTransition: function( element, list, factor, value ) { - value = value || {}; - $.each( list, function( i, x ) { - var unit = element.cssUnit( x ); - if ( unit[ 0 ] > 0 ) { - value[ x ] = unit[ 0 ] * factor + unit[ 1 ]; - } - } ); - return value; - } -} ); + _refresh: function() { + this.element.attr( { + "aria-valuemin": this.options.min, + "aria-valuemax": this.options.max, -// Return an effect options object for the given parameters: -function _normalizeArguments( effect, options, speed, callback ) { + // TODO: what should we do with values that can't be parsed? + "aria-valuenow": this._parse( this.element.val() ) + } ); + }, - // Allow passing all options as the first parameter - if ( $.isPlainObject( effect ) ) { - options = effect; - effect = effect.effect; - } + isValid: function() { + var value = this.value(); - // Convert to an object - effect = { effect: effect }; + // Null is invalid + if ( value === null ) { + return false; + } - // Catch (effect, null, ...) - if ( options == null ) { - options = {}; - } + // If value gets adjusted, it's invalid + return value === this._adjustValue( value ); + }, - // Catch (effect, callback) - if ( typeof options === "function" ) { - callback = options; - speed = null; - options = {}; - } + // Update the value without triggering change + _value: function( value, allowAny ) { + var parsed; + if ( value !== "" ) { + parsed = this._parse( value ); + if ( parsed !== null ) { + if ( !allowAny ) { + parsed = this._adjustValue( parsed ); + } + value = this._format( parsed ); + } + } + this.element.val( value ); + this._refresh(); + }, - // Catch (effect, speed, ?) - if ( typeof options === "number" || $.fx.speeds[ options ] ) { - callback = speed; - speed = options; - options = {}; - } + _destroy: function() { + this.element + .prop( "disabled", false ) + .removeAttr( "autocomplete role aria-valuemin aria-valuemax aria-valuenow" ); - // Catch (effect, options, callback) - if ( typeof speed === "function" ) { - callback = speed; - speed = null; - } + this.uiSpinner.replaceWith( this.element ); + }, - // Add options to effect - if ( options ) { - $.extend( effect, options ); - } + stepUp: spinnerModifier( function( steps ) { + this._stepUp( steps ); + } ), + _stepUp: function( steps ) { + if ( this._start() ) { + this._spin( ( steps || 1 ) * this.options.step ); + this._stop(); + } + }, - speed = speed || options.duration; - effect.duration = $.fx.off ? 0 : - typeof speed === "number" ? speed : - speed in $.fx.speeds ? $.fx.speeds[ speed ] : - $.fx.speeds._default; + stepDown: spinnerModifier( function( steps ) { + this._stepDown( steps ); + } ), + _stepDown: function( steps ) { + if ( this._start() ) { + this._spin( ( steps || 1 ) * -this.options.step ); + this._stop(); + } + }, - effect.complete = callback || options.complete; + pageUp: spinnerModifier( function( pages ) { + this._stepUp( ( pages || 1 ) * this.options.page ); + } ), - return effect; -} + pageDown: spinnerModifier( function( pages ) { + this._stepDown( ( pages || 1 ) * this.options.page ); + } ), -function standardAnimationOption( option ) { + value: function( newVal ) { + if ( !arguments.length ) { + return this._parse( this.element.val() ); + } + spinnerModifier( this._value ).call( this, newVal ); + }, - // Valid standard speeds (nothing, number, named speed) - if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) { - return true; + widget: function() { + return this.uiSpinner; } +} ); - // Invalid strings - treat as "normal" speed - if ( typeof option === "string" && !$.effects.effect[ option ] ) { - return true; - } +// DEPRECATED +// TODO: switch return back to widget declaration at top of file when this is removed +if ( $.uiBackCompat !== false ) { - // Complete callback - if ( typeof option === "function" ) { - return true; - } + // Backcompat for spinner html extension points + $.widget( "ui.spinner", $.ui.spinner, { + _enhance: function() { + this.uiSpinner = this.element + .attr( "autocomplete", "off" ) + .wrap( this._uiSpinnerHtml() ) + .parent() - // Options hash (but not naming an effect) - if ( typeof option === "object" && !option.effect ) { - return true; - } + // Add buttons + .append( this._buttonHtml() ); + }, + _uiSpinnerHtml: function() { + return "<span>"; + }, - // Didn't match any standard API - return false; + _buttonHtml: function() { + return "<a></a><a></a>"; + } + } ); } -$.fn.extend( { - effect: function( /* effect, options, speed, callback */ ) { - var args = _normalizeArguments.apply( this, arguments ), - effectMethod = $.effects.effect[ args.effect ], - defaultMode = effectMethod.mode, - queue = args.queue, - queueName = queue || "fx", - complete = args.complete, - mode = args.mode, - modes = [], - prefilter = function( next ) { - var el = $( this ), - normalizedMode = $.effects.mode( el, mode ) || defaultMode; - - // Sentinel for duck-punching the :animated pseudo-selector - el.data( dataSpaceAnimated, true ); +var widgetsSpinner = $.ui.spinner; - // Save effect mode for later use, - // we can't just call $.effects.mode again later, - // as the .show() below destroys the initial state - modes.push( normalizedMode ); - // See $.uiBackCompat inside of run() for removal of defaultMode in 1.14 - if ( defaultMode && ( normalizedMode === "show" || - ( normalizedMode === defaultMode && normalizedMode === "hide" ) ) ) { - el.show(); - } +/*! + * jQuery UI Tabs 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ - if ( !defaultMode || normalizedMode !== "none" ) { - $.effects.saveStyle( el ); - } +//>>label: Tabs +//>>group: Widgets +//>>description: Transforms a set of container elements into a tab structure. +//>>docs: http://api.jqueryui.com/tabs/ +//>>demos: http://jqueryui.com/tabs/ +//>>css.structure: ../../themes/base/core.css +//>>css.structure: ../../themes/base/tabs.css +//>>css.theme: ../../themes/base/theme.css - if ( typeof next === "function" ) { - next(); - } - }; - if ( $.fx.off || !effectMethod ) { +$.widget( "ui.tabs", { + version: "1.13.2", + delay: 300, + options: { + active: null, + classes: { + "ui-tabs": "ui-corner-all", + "ui-tabs-nav": "ui-corner-all", + "ui-tabs-panel": "ui-corner-bottom", + "ui-tabs-tab": "ui-corner-top" + }, + collapsible: false, + event: "click", + heightStyle: "content", + hide: null, + show: null, - // Delegate to the original method (e.g., .show()) if possible - if ( mode ) { - return this[ mode ]( args.duration, complete ); - } else { - return this.each( function() { - if ( complete ) { - complete.call( this ); - } - } ); - } - } + // Callbacks + activate: null, + beforeActivate: null, + beforeLoad: null, + load: null + }, - function run( next ) { - var elem = $( this ); + _isLocal: ( function() { + var rhash = /#.*$/; - function cleanup() { - elem.removeData( dataSpaceAnimated ); + return function( anchor ) { + var anchorUrl, locationUrl; - $.effects.cleanUp( elem ); + anchorUrl = anchor.href.replace( rhash, "" ); + locationUrl = location.href.replace( rhash, "" ); - if ( args.mode === "hide" ) { - elem.hide(); - } + // Decoding may throw an error if the URL isn't UTF-8 (#9518) + try { + anchorUrl = decodeURIComponent( anchorUrl ); + } catch ( error ) {} + try { + locationUrl = decodeURIComponent( locationUrl ); + } catch ( error ) {} - done(); - } + return anchor.hash.length > 1 && anchorUrl === locationUrl; + }; + } )(), - function done() { - if ( typeof complete === "function" ) { - complete.call( elem[ 0 ] ); - } + _create: function() { + var that = this, + options = this.options; - if ( typeof next === "function" ) { - next(); - } - } + this.running = false; - // Override mode option on a per element basis, - // as toggle can be either show or hide depending on element state - args.mode = modes.shift(); + this._addClass( "ui-tabs", "ui-widget ui-widget-content" ); + this._toggleClass( "ui-tabs-collapsible", null, options.collapsible ); - if ( $.uiBackCompat !== false && !defaultMode ) { - if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { + this._processTabs(); + options.active = this._initialActive(); - // Call the core method to track "olddisplay" properly - elem[ mode ](); - done(); - } else { - effectMethod.call( elem[ 0 ], args, done ); - } - } else { - if ( args.mode === "none" ) { + // Take disabling tabs via class attribute from HTML + // into account and update option properly. + if ( Array.isArray( options.disabled ) ) { + options.disabled = $.uniqueSort( options.disabled.concat( + $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) { + return that.tabs.index( li ); + } ) + ) ).sort(); + } - // Call the core method to track "olddisplay" properly - elem[ mode ](); - done(); - } else { - effectMethod.call( elem[ 0 ], args, cleanup ); - } - } + // Check for length avoids error when initializing empty list + if ( this.options.active !== false && this.anchors.length ) { + this.active = this._findActive( options.active ); + } else { + this.active = $(); } - // Run prefilter on all elements first to ensure that - // any showing or hiding happens before placeholder creation, - // which ensures that any layout changes are correctly captured. - return queue === false ? - this.each( prefilter ).each( run ) : - this.queue( queueName, prefilter ).queue( queueName, run ); + this._refresh(); + + if ( this.active.length ) { + this.load( options.active ); + } }, - show: ( function( orig ) { - return function( option ) { - if ( standardAnimationOption( option ) ) { - return orig.apply( this, arguments ); - } else { - var args = _normalizeArguments.apply( this, arguments ); - args.mode = "show"; - return this.effect.call( this, args ); - } - }; - } )( $.fn.show ), + _initialActive: function() { + var active = this.options.active, + collapsible = this.options.collapsible, + locationHash = location.hash.substring( 1 ); - hide: ( function( orig ) { - return function( option ) { - if ( standardAnimationOption( option ) ) { - return orig.apply( this, arguments ); - } else { - var args = _normalizeArguments.apply( this, arguments ); - args.mode = "hide"; - return this.effect.call( this, args ); + if ( active === null ) { + + // check the fragment identifier in the URL + if ( locationHash ) { + this.tabs.each( function( i, tab ) { + if ( $( tab ).attr( "aria-controls" ) === locationHash ) { + active = i; + return false; + } + } ); } - }; - } )( $.fn.hide ), - toggle: ( function( orig ) { - return function( option ) { - if ( standardAnimationOption( option ) || typeof option === "boolean" ) { - return orig.apply( this, arguments ); - } else { - var args = _normalizeArguments.apply( this, arguments ); - args.mode = "toggle"; - return this.effect.call( this, args ); + // Check for a tab marked active via a class + if ( active === null ) { + active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) ); } - }; - } )( $.fn.toggle ), - cssUnit: function( key ) { - var style = this.css( key ), - val = []; + // No active tab, set to false + if ( active === null || active === -1 ) { + active = this.tabs.length ? 0 : false; + } + } - $.each( [ "em", "px", "%", "pt" ], function( i, unit ) { - if ( style.indexOf( unit ) > 0 ) { - val = [ parseFloat( style ), unit ]; + // Handle numbers: negative, out of range + if ( active !== false ) { + active = this.tabs.index( this.tabs.eq( active ) ); + if ( active === -1 ) { + active = collapsible ? false : 0; } - } ); - return val; - }, + } - cssClip: function( clipObj ) { - if ( clipObj ) { - return this.css( "clip", "rect(" + clipObj.top + "px " + clipObj.right + "px " + - clipObj.bottom + "px " + clipObj.left + "px)" ); + // Don't allow collapsible: false and active: false + if ( !collapsible && active === false && this.anchors.length ) { + active = 0; } - return parseClip( this.css( "clip" ), this ); + + return active; }, - transfer: function( options, done ) { - var element = $( this ), - target = $( options.to ), - targetFixed = target.css( "position" ) === "fixed", - body = $( "body" ), - fixTop = targetFixed ? body.scrollTop() : 0, - fixLeft = targetFixed ? body.scrollLeft() : 0, - endPosition = target.offset(), - animation = { - top: endPosition.top - fixTop, - left: endPosition.left - fixLeft, - height: target.innerHeight(), - width: target.innerWidth() - }, - startPosition = element.offset(), - transfer = $( "<div class='ui-effects-transfer'></div>" ); + _getCreateEventData: function() { + return { + tab: this.active, + panel: !this.active.length ? $() : this._getPanelForTab( this.active ) + }; + }, - transfer - .appendTo( "body" ) - .addClass( options.className ) - .css( { - top: startPosition.top - fixTop, - left: startPosition.left - fixLeft, - height: element.innerHeight(), - width: element.innerWidth(), - position: targetFixed ? "fixed" : "absolute" - } ) - .animate( animation, options.duration, options.easing, function() { - transfer.remove(); - if ( typeof done === "function" ) { - done(); - } - } ); - } -} ); + _tabKeydown: function( event ) { + var focusedTab = $( $.ui.safeActiveElement( this.document[ 0 ] ) ).closest( "li" ), + selectedIndex = this.tabs.index( focusedTab ), + goingForward = true; -function parseClip( str, element ) { - var outerWidth = element.outerWidth(), - outerHeight = element.outerHeight(), - clipRegex = /^rect\((-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto)\)$/, - values = clipRegex.exec( str ) || [ "", 0, outerWidth, outerHeight, 0 ]; + if ( this._handlePageNav( event ) ) { + return; + } - return { - top: parseFloat( values[ 1 ] ) || 0, - right: values[ 2 ] === "auto" ? outerWidth : parseFloat( values[ 2 ] ), - bottom: values[ 3 ] === "auto" ? outerHeight : parseFloat( values[ 3 ] ), - left: parseFloat( values[ 4 ] ) || 0 - }; -} + switch ( event.keyCode ) { + case $.ui.keyCode.RIGHT: + case $.ui.keyCode.DOWN: + selectedIndex++; + break; + case $.ui.keyCode.UP: + case $.ui.keyCode.LEFT: + goingForward = false; + selectedIndex--; + break; + case $.ui.keyCode.END: + selectedIndex = this.anchors.length - 1; + break; + case $.ui.keyCode.HOME: + selectedIndex = 0; + break; + case $.ui.keyCode.SPACE: -$.fx.step.clip = function( fx ) { - if ( !fx.clipInit ) { - fx.start = $( fx.elem ).cssClip(); - if ( typeof fx.end === "string" ) { - fx.end = parseClip( fx.end, fx.elem ); - } - fx.clipInit = true; - } + // Activate only, no collapsing + event.preventDefault(); + clearTimeout( this.activating ); + this._activate( selectedIndex ); + return; + case $.ui.keyCode.ENTER: - $( fx.elem ).cssClip( { - top: fx.pos * ( fx.end.top - fx.start.top ) + fx.start.top, - right: fx.pos * ( fx.end.right - fx.start.right ) + fx.start.right, - bottom: fx.pos * ( fx.end.bottom - fx.start.bottom ) + fx.start.bottom, - left: fx.pos * ( fx.end.left - fx.start.left ) + fx.start.left - } ); -}; + // Toggle (cancel delayed activation, allow collapsing) + event.preventDefault(); + clearTimeout( this.activating ); -} )(); + // Determine if we should collapse or activate + this._activate( selectedIndex === this.options.active ? false : selectedIndex ); + return; + default: + return; + } -/******************************************************************************/ -/*********************************** EASING ***********************************/ -/******************************************************************************/ + // Focus the appropriate tab, based on which key was pressed + event.preventDefault(); + clearTimeout( this.activating ); + selectedIndex = this._focusNextTab( selectedIndex, goingForward ); -( function() { + // Navigating with control/command key will prevent automatic activation + if ( !event.ctrlKey && !event.metaKey ) { -// Based on easing equations from Robert Penner (http://www.robertpenner.com/easing) + // Update aria-selected immediately so that AT think the tab is already selected. + // Otherwise AT may confuse the user by stating that they need to activate the tab, + // but the tab will already be activated by the time the announcement finishes. + focusedTab.attr( "aria-selected", "false" ); + this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" ); -var baseEasings = {}; + this.activating = this._delay( function() { + this.option( "active", selectedIndex ); + }, this.delay ); + } + }, -$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) { - baseEasings[ name ] = function( p ) { - return Math.pow( p, i + 2 ); - }; -} ); + _panelKeydown: function( event ) { + if ( this._handlePageNav( event ) ) { + return; + } -$.extend( baseEasings, { - Sine: function( p ) { - return 1 - Math.cos( p * Math.PI / 2 ); + // Ctrl+up moves focus to the current tab + if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) { + event.preventDefault(); + this.active.trigger( "focus" ); + } }, - Circ: function( p ) { - return 1 - Math.sqrt( 1 - p * p ); + + // Alt+page up/down moves focus to the previous/next tab (and activates) + _handlePageNav: function( event ) { + if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) { + this._activate( this._focusNextTab( this.options.active - 1, false ) ); + return true; + } + if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) { + this._activate( this._focusNextTab( this.options.active + 1, true ) ); + return true; + } }, - Elastic: function( p ) { - return p === 0 || p === 1 ? p : - -Math.pow( 2, 8 * ( p - 1 ) ) * Math.sin( ( ( p - 1 ) * 80 - 7.5 ) * Math.PI / 15 ); + + _findNextTab: function( index, goingForward ) { + var lastTabIndex = this.tabs.length - 1; + + function constrain() { + if ( index > lastTabIndex ) { + index = 0; + } + if ( index < 0 ) { + index = lastTabIndex; + } + return index; + } + + while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) { + index = goingForward ? index + 1 : index - 1; + } + + return index; }, - Back: function( p ) { - return p * p * ( 3 * p - 2 ); + + _focusNextTab: function( index, goingForward ) { + index = this._findNextTab( index, goingForward ); + this.tabs.eq( index ).trigger( "focus" ); + return index; }, - Bounce: function( p ) { - var pow2, - bounce = 4; - while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {} - return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 ); - } -} ); + _setOption: function( key, value ) { + if ( key === "active" ) { -$.each( baseEasings, function( name, easeIn ) { - $.easing[ "easeIn" + name ] = easeIn; - $.easing[ "easeOut" + name ] = function( p ) { - return 1 - easeIn( 1 - p ); - }; - $.easing[ "easeInOut" + name ] = function( p ) { - return p < 0.5 ? - easeIn( p * 2 ) / 2 : - 1 - easeIn( p * -2 + 2 ) / 2; - }; -} ); + // _activate() will handle invalid values and update this.options + this._activate( value ); + return; + } -} )(); + this._super( key, value ); -var effect = $.effects; + if ( key === "collapsible" ) { + this._toggleClass( "ui-tabs-collapsible", null, value ); + // Setting collapsible: false while collapsed; open first panel + if ( !value && this.options.active === false ) { + this._activate( 0 ); + } + } -/*! - * jQuery UI Effects Blind 1.13.1 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ + if ( key === "event" ) { + this._setupEvents( value ); + } -//>>label: Blind Effect -//>>group: Effects -//>>description: Blinds the element. -//>>docs: http://api.jqueryui.com/blind-effect/ -//>>demos: http://jqueryui.com/effect/ + if ( key === "heightStyle" ) { + this._setupHeightStyle( value ); + } + }, + _sanitizeSelector: function( hash ) { + return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : ""; + }, -var effectsEffectBlind = $.effects.define( "blind", "hide", function( options, done ) { - var map = { - up: [ "bottom", "top" ], - vertical: [ "bottom", "top" ], - down: [ "top", "bottom" ], - left: [ "right", "left" ], - horizontal: [ "right", "left" ], - right: [ "left", "right" ] - }, - element = $( this ), - direction = options.direction || "up", - start = element.cssClip(), - animate = { clip: $.extend( {}, start ) }, - placeholder = $.effects.createPlaceholder( element ); + refresh: function() { + var options = this.options, + lis = this.tablist.children( ":has(a[href])" ); - animate.clip[ map[ direction ][ 0 ] ] = animate.clip[ map[ direction ][ 1 ] ]; + // Get disabled tabs from class attribute from HTML + // this will get converted to a boolean if needed in _refresh() + options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) { + return lis.index( tab ); + } ); - if ( options.mode === "show" ) { - element.cssClip( animate.clip ); - if ( placeholder ) { - placeholder.css( $.effects.clipToBox( animate ) ); - } + this._processTabs(); - animate.clip = start; - } + // Was collapsed or no tabs + if ( options.active === false || !this.anchors.length ) { + options.active = false; + this.active = $(); - if ( placeholder ) { - placeholder.animate( $.effects.clipToBox( animate ), options.duration, options.easing ); - } + // was active, but active tab is gone + } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) { - element.animate( animate, { - queue: false, - duration: options.duration, - easing: options.easing, - complete: done - } ); -} ); + // all remaining tabs are disabled + if ( this.tabs.length === options.disabled.length ) { + options.active = false; + this.active = $(); + // activate previous tab + } else { + this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) ); + } -/*! - * jQuery UI Effects Bounce 1.13.1 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ + // was active, active tab still exists + } else { -//>>label: Bounce Effect -//>>group: Effects -//>>description: Bounces an element horizontally or vertically n times. -//>>docs: http://api.jqueryui.com/bounce-effect/ -//>>demos: http://jqueryui.com/effect/ + // make sure active index is correct + options.active = this.tabs.index( this.active ); + } + + this._refresh(); + }, + + _refresh: function() { + this._setOptionDisabled( this.options.disabled ); + this._setupEvents( this.options.event ); + this._setupHeightStyle( this.options.heightStyle ); + this.tabs.not( this.active ).attr( { + "aria-selected": "false", + "aria-expanded": "false", + tabIndex: -1 + } ); + this.panels.not( this._getPanelForTab( this.active ) ) + .hide() + .attr( { + "aria-hidden": "true" + } ); -var effectsEffectBounce = $.effects.define( "bounce", function( options, done ) { - var upAnim, downAnim, refValue, - element = $( this ), + // Make sure one tab is in the tab order + if ( !this.active.length ) { + this.tabs.eq( 0 ).attr( "tabIndex", 0 ); + } else { + this.active + .attr( { + "aria-selected": "true", + "aria-expanded": "true", + tabIndex: 0 + } ); + this._addClass( this.active, "ui-tabs-active", "ui-state-active" ); + this._getPanelForTab( this.active ) + .show() + .attr( { + "aria-hidden": "false" + } ); + } + }, - // Defaults: - mode = options.mode, - hide = mode === "hide", - show = mode === "show", - direction = options.direction || "up", - distance = options.distance, - times = options.times || 5, + _processTabs: function() { + var that = this, + prevTabs = this.tabs, + prevAnchors = this.anchors, + prevPanels = this.panels; - // Number of internal animations - anims = times * 2 + ( show || hide ? 1 : 0 ), - speed = options.duration / anims, - easing = options.easing, + this.tablist = this._getList().attr( "role", "tablist" ); + this._addClass( this.tablist, "ui-tabs-nav", + "ui-helper-reset ui-helper-clearfix ui-widget-header" ); - // Utility: - ref = ( direction === "up" || direction === "down" ) ? "top" : "left", - motion = ( direction === "up" || direction === "left" ), - i = 0, + // Prevent users from focusing disabled tabs via click + this.tablist + .on( "mousedown" + this.eventNamespace, "> li", function( event ) { + if ( $( this ).is( ".ui-state-disabled" ) ) { + event.preventDefault(); + } + } ) - queuelen = element.queue().length; + // Support: IE <9 + // Preventing the default action in mousedown doesn't prevent IE + // from focusing the element, so if the anchor gets focused, blur. + // We don't have to worry about focusing the previously focused + // element since clicking on a non-focusable element should focus + // the body anyway. + .on( "focus" + this.eventNamespace, ".ui-tabs-anchor", function() { + if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) { + this.blur(); + } + } ); - $.effects.createPlaceholder( element ); + this.tabs = this.tablist.find( "> li:has(a[href])" ) + .attr( { + role: "tab", + tabIndex: -1 + } ); + this._addClass( this.tabs, "ui-tabs-tab", "ui-state-default" ); - refValue = element.css( ref ); + this.anchors = this.tabs.map( function() { + return $( "a", this )[ 0 ]; + } ) + .attr( { + tabIndex: -1 + } ); + this._addClass( this.anchors, "ui-tabs-anchor" ); - // Default distance for the BIGGEST bounce is the outer Distance / 3 - if ( !distance ) { - distance = element[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3; - } + this.panels = $(); - if ( show ) { - downAnim = { opacity: 1 }; - downAnim[ ref ] = refValue; + this.anchors.each( function( i, anchor ) { + var selector, panel, panelId, + anchorId = $( anchor ).uniqueId().attr( "id" ), + tab = $( anchor ).closest( "li" ), + originalAriaControls = tab.attr( "aria-controls" ); - // If we are showing, force opacity 0 and set the initial position - // then do the "first" animation - element - .css( "opacity", 0 ) - .css( ref, motion ? -distance * 2 : distance * 2 ) - .animate( downAnim, speed, easing ); - } + // Inline tab + if ( that._isLocal( anchor ) ) { + selector = anchor.hash; + panelId = selector.substring( 1 ); + panel = that.element.find( that._sanitizeSelector( selector ) ); - // Start at the smallest distance if we are hiding - if ( hide ) { - distance = distance / Math.pow( 2, times - 1 ); - } + // remote tab + } else { - downAnim = {}; - downAnim[ ref ] = refValue; + // If the tab doesn't already have aria-controls, + // generate an id by using a throw-away element + panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id; + selector = "#" + panelId; + panel = that.element.find( selector ); + if ( !panel.length ) { + panel = that._createPanel( panelId ); + panel.insertAfter( that.panels[ i - 1 ] || that.tablist ); + } + panel.attr( "aria-live", "polite" ); + } - // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here - for ( ; i < times; i++ ) { - upAnim = {}; - upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; + if ( panel.length ) { + that.panels = that.panels.add( panel ); + } + if ( originalAriaControls ) { + tab.data( "ui-tabs-aria-controls", originalAriaControls ); + } + tab.attr( { + "aria-controls": panelId, + "aria-labelledby": anchorId + } ); + panel.attr( "aria-labelledby", anchorId ); + } ); - element - .animate( upAnim, speed, easing ) - .animate( downAnim, speed, easing ); + this.panels.attr( "role", "tabpanel" ); + this._addClass( this.panels, "ui-tabs-panel", "ui-widget-content" ); - distance = hide ? distance * 2 : distance / 2; - } + // Avoid memory leaks (#10056) + if ( prevTabs ) { + this._off( prevTabs.not( this.tabs ) ); + this._off( prevAnchors.not( this.anchors ) ); + this._off( prevPanels.not( this.panels ) ); + } + }, - // Last Bounce when Hiding - if ( hide ) { - upAnim = { opacity: 0 }; - upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; + // Allow overriding how to find the list for rare usage scenarios (#7715) + _getList: function() { + return this.tablist || this.element.find( "ol, ul" ).eq( 0 ); + }, - element.animate( upAnim, speed, easing ); - } + _createPanel: function( id ) { + return $( "<div>" ) + .attr( "id", id ) + .data( "ui-tabs-destroy", true ); + }, - element.queue( done ); + _setOptionDisabled: function( disabled ) { + var currentItem, li, i; - $.effects.unshift( element, queuelen, anims + 1 ); -} ); + if ( Array.isArray( disabled ) ) { + if ( !disabled.length ) { + disabled = false; + } else if ( disabled.length === this.anchors.length ) { + disabled = true; + } + } + // Disable tabs + for ( i = 0; ( li = this.tabs[ i ] ); i++ ) { + currentItem = $( li ); + if ( disabled === true || $.inArray( i, disabled ) !== -1 ) { + currentItem.attr( "aria-disabled", "true" ); + this._addClass( currentItem, null, "ui-state-disabled" ); + } else { + currentItem.removeAttr( "aria-disabled" ); + this._removeClass( currentItem, null, "ui-state-disabled" ); + } + } -/*! - * jQuery UI Effects Clip 1.13.1 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ + this.options.disabled = disabled; -//>>label: Clip Effect -//>>group: Effects -//>>description: Clips the element on and off like an old TV. -//>>docs: http://api.jqueryui.com/clip-effect/ -//>>demos: http://jqueryui.com/effect/ + this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, + disabled === true ); + }, + _setupEvents: function( event ) { + var events = {}; + if ( event ) { + $.each( event.split( " " ), function( index, eventName ) { + events[ eventName ] = "_eventHandler"; + } ); + } -var effectsEffectClip = $.effects.define( "clip", "hide", function( options, done ) { - var start, - animate = {}, - element = $( this ), - direction = options.direction || "vertical", - both = direction === "both", - horizontal = both || direction === "horizontal", - vertical = both || direction === "vertical"; + this._off( this.anchors.add( this.tabs ).add( this.panels ) ); - start = element.cssClip(); - animate.clip = { - top: vertical ? ( start.bottom - start.top ) / 2 : start.top, - right: horizontal ? ( start.right - start.left ) / 2 : start.right, - bottom: vertical ? ( start.bottom - start.top ) / 2 : start.bottom, - left: horizontal ? ( start.right - start.left ) / 2 : start.left - }; + // Always prevent the default action, even when disabled + this._on( true, this.anchors, { + click: function( event ) { + event.preventDefault(); + } + } ); + this._on( this.anchors, events ); + this._on( this.tabs, { keydown: "_tabKeydown" } ); + this._on( this.panels, { keydown: "_panelKeydown" } ); - $.effects.createPlaceholder( element ); + this._focusable( this.tabs ); + this._hoverable( this.tabs ); + }, - if ( options.mode === "show" ) { - element.cssClip( animate.clip ); - animate.clip = start; - } + _setupHeightStyle: function( heightStyle ) { + var maxHeight, + parent = this.element.parent(); - element.animate( animate, { - queue: false, - duration: options.duration, - easing: options.easing, - complete: done - } ); + if ( heightStyle === "fill" ) { + maxHeight = parent.height(); + maxHeight -= this.element.outerHeight() - this.element.height(); -} ); + this.element.siblings( ":visible" ).each( function() { + var elem = $( this ), + position = elem.css( "position" ); + if ( position === "absolute" || position === "fixed" ) { + return; + } + maxHeight -= elem.outerHeight( true ); + } ); -/*! - * jQuery UI Effects Drop 1.13.1 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ + this.element.children().not( this.panels ).each( function() { + maxHeight -= $( this ).outerHeight( true ); + } ); -//>>label: Drop Effect -//>>group: Effects -//>>description: Moves an element in one direction and hides it at the same time. -//>>docs: http://api.jqueryui.com/drop-effect/ -//>>demos: http://jqueryui.com/effect/ + this.panels.each( function() { + $( this ).height( Math.max( 0, maxHeight - + $( this ).innerHeight() + $( this ).height() ) ); + } ) + .css( "overflow", "auto" ); + } else if ( heightStyle === "auto" ) { + maxHeight = 0; + this.panels.each( function() { + maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); + } ).height( maxHeight ); + } + }, + _eventHandler: function( event ) { + var options = this.options, + active = this.active, + anchor = $( event.currentTarget ), + tab = anchor.closest( "li" ), + clickedIsActive = tab[ 0 ] === active[ 0 ], + collapsing = clickedIsActive && options.collapsible, + toShow = collapsing ? $() : this._getPanelForTab( tab ), + toHide = !active.length ? $() : this._getPanelForTab( active ), + eventData = { + oldTab: active, + oldPanel: toHide, + newTab: collapsing ? $() : tab, + newPanel: toShow + }; -var effectsEffectDrop = $.effects.define( "drop", "hide", function( options, done ) { + event.preventDefault(); - var distance, - element = $( this ), - mode = options.mode, - show = mode === "show", - direction = options.direction || "left", - ref = ( direction === "up" || direction === "down" ) ? "top" : "left", - motion = ( direction === "up" || direction === "left" ) ? "-=" : "+=", - oppositeMotion = ( motion === "+=" ) ? "-=" : "+=", - animation = { - opacity: 0 - }; + if ( tab.hasClass( "ui-state-disabled" ) || - $.effects.createPlaceholder( element ); + // tab is already loading + tab.hasClass( "ui-tabs-loading" ) || - distance = options.distance || - element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2; + // can't switch durning an animation + this.running || - animation[ ref ] = motion + distance; + // click on active header, but not collapsible + ( clickedIsActive && !options.collapsible ) || - if ( show ) { - element.css( animation ); + // allow canceling activation + ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { + return; + } - animation[ ref ] = oppositeMotion + distance; - animation.opacity = 1; - } + options.active = collapsing ? false : this.tabs.index( tab ); - // Animate - element.animate( animation, { - queue: false, - duration: options.duration, - easing: options.easing, - complete: done - } ); -} ); + this.active = clickedIsActive ? $() : tab; + if ( this.xhr ) { + this.xhr.abort(); + } + if ( !toHide.length && !toShow.length ) { + $.error( "jQuery UI Tabs: Mismatching fragment identifier." ); + } -/*! - * jQuery UI Effects Explode 1.13.1 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ + if ( toShow.length ) { + this.load( this.tabs.index( tab ), event ); + } + this._toggle( event, eventData ); + }, -//>>label: Explode Effect -//>>group: Effects -/* eslint-disable max-len */ -//>>description: Explodes an element in all directions into n pieces. Implodes an element to its original wholeness. -/* eslint-enable max-len */ -//>>docs: http://api.jqueryui.com/explode-effect/ -//>>demos: http://jqueryui.com/effect/ + // Handles show/hide for selecting tabs + _toggle: function( event, eventData ) { + var that = this, + toShow = eventData.newPanel, + toHide = eventData.oldPanel; + this.running = true; -var effectsEffectExplode = $.effects.define( "explode", "hide", function( options, done ) { + function complete() { + that.running = false; + that._trigger( "activate", event, eventData ); + } - var i, j, left, top, mx, my, - rows = options.pieces ? Math.round( Math.sqrt( options.pieces ) ) : 3, - cells = rows, - element = $( this ), - mode = options.mode, - show = mode === "show", + function show() { + that._addClass( eventData.newTab.closest( "li" ), "ui-tabs-active", "ui-state-active" ); - // Show and then visibility:hidden the element before calculating offset - offset = element.show().css( "visibility", "hidden" ).offset(), + if ( toShow.length && that.options.show ) { + that._show( toShow, that.options.show, complete ); + } else { + toShow.show(); + complete(); + } + } - // Width and height of a piece - width = Math.ceil( element.outerWidth() / cells ), - height = Math.ceil( element.outerHeight() / rows ), - pieces = []; + // Start out by hiding, then showing, then completing + if ( toHide.length && this.options.hide ) { + this._hide( toHide, this.options.hide, function() { + that._removeClass( eventData.oldTab.closest( "li" ), + "ui-tabs-active", "ui-state-active" ); + show(); + } ); + } else { + this._removeClass( eventData.oldTab.closest( "li" ), + "ui-tabs-active", "ui-state-active" ); + toHide.hide(); + show(); + } - // Children animate complete: - function childComplete() { - pieces.push( this ); - if ( pieces.length === rows * cells ) { - animComplete(); + toHide.attr( "aria-hidden", "true" ); + eventData.oldTab.attr( { + "aria-selected": "false", + "aria-expanded": "false" + } ); + + // If we're switching tabs, remove the old tab from the tab order. + // If we're opening from collapsed state, remove the previous tab from the tab order. + // If we're collapsing, then keep the collapsing tab in the tab order. + if ( toShow.length && toHide.length ) { + eventData.oldTab.attr( "tabIndex", -1 ); + } else if ( toShow.length ) { + this.tabs.filter( function() { + return $( this ).attr( "tabIndex" ) === 0; + } ) + .attr( "tabIndex", -1 ); } - } - // Clone the element for each row and cell. - for ( i = 0; i < rows; i++ ) { // ===> - top = offset.top + i * height; - my = i - ( rows - 1 ) / 2; + toShow.attr( "aria-hidden", "false" ); + eventData.newTab.attr( { + "aria-selected": "true", + "aria-expanded": "true", + tabIndex: 0 + } ); + }, - for ( j = 0; j < cells; j++ ) { // ||| - left = offset.left + j * width; - mx = j - ( cells - 1 ) / 2; + _activate: function( index ) { + var anchor, + active = this._findActive( index ); - // Create a clone of the now hidden main element that will be absolute positioned - // within a wrapper div off the -left and -top equal to size of our pieces - element - .clone() - .appendTo( "body" ) - .wrap( "<div></div>" ) - .css( { - position: "absolute", - visibility: "visible", - left: -j * width, - top: -i * height - } ) + // Trying to activate the already active panel + if ( active[ 0 ] === this.active[ 0 ] ) { + return; + } - // Select the wrapper - make it overflow: hidden and absolute positioned based on - // where the original was located +left and +top equal to the size of pieces - .parent() - .addClass( "ui-effects-explode" ) - .css( { - position: "absolute", - overflow: "hidden", - width: width, - height: height, - left: left + ( show ? mx * width : 0 ), - top: top + ( show ? my * height : 0 ), - opacity: show ? 0 : 1 - } ) - .animate( { - left: left + ( show ? 0 : mx * width ), - top: top + ( show ? 0 : my * height ), - opacity: show ? 1 : 0 - }, options.duration || 500, options.easing, childComplete ); + // Trying to collapse, simulate a click on the current active header + if ( !active.length ) { + active = this.active; } - } - function animComplete() { - element.css( { - visibility: "visible" + anchor = active.find( ".ui-tabs-anchor" )[ 0 ]; + this._eventHandler( { + target: anchor, + currentTarget: anchor, + preventDefault: $.noop } ); - $( pieces ).remove(); - done(); - } -} ); + }, + _findActive: function( index ) { + return index === false ? $() : this.tabs.eq( index ); + }, -/*! - * jQuery UI Effects Fade 1.13.1 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ + _getIndex: function( index ) { -//>>label: Fade Effect -//>>group: Effects -//>>description: Fades the element. -//>>docs: http://api.jqueryui.com/fade-effect/ -//>>demos: http://jqueryui.com/effect/ + // meta-function to give users option to provide a href string instead of a numerical index. + if ( typeof index === "string" ) { + index = this.anchors.index( this.anchors.filter( "[href$='" + + $.escapeSelector( index ) + "']" ) ); + } + return index; + }, -var effectsEffectFade = $.effects.define( "fade", "toggle", function( options, done ) { - var show = options.mode === "show"; + _destroy: function() { + if ( this.xhr ) { + this.xhr.abort(); + } - $( this ) - .css( "opacity", show ? 0 : 1 ) - .animate( { - opacity: show ? 1 : 0 - }, { - queue: false, - duration: options.duration, - easing: options.easing, - complete: done - } ); -} ); + this.tablist + .removeAttr( "role" ) + .off( this.eventNamespace ); + this.anchors + .removeAttr( "role tabIndex" ) + .removeUniqueId(); -/*! - * jQuery UI Effects Fold 1.13.1 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ + this.tabs.add( this.panels ).each( function() { + if ( $.data( this, "ui-tabs-destroy" ) ) { + $( this ).remove(); + } else { + $( this ).removeAttr( "role tabIndex " + + "aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded" ); + } + } ); -//>>label: Fold Effect -//>>group: Effects -//>>description: Folds an element first horizontally and then vertically. -//>>docs: http://api.jqueryui.com/fold-effect/ -//>>demos: http://jqueryui.com/effect/ + this.tabs.each( function() { + var li = $( this ), + prev = li.data( "ui-tabs-aria-controls" ); + if ( prev ) { + li + .attr( "aria-controls", prev ) + .removeData( "ui-tabs-aria-controls" ); + } else { + li.removeAttr( "aria-controls" ); + } + } ); + this.panels.show(); -var effectsEffectFold = $.effects.define( "fold", "hide", function( options, done ) { + if ( this.options.heightStyle !== "content" ) { + this.panels.css( "height", "" ); + } + }, - // Create element - var element = $( this ), - mode = options.mode, - show = mode === "show", - hide = mode === "hide", - size = options.size || 15, - percent = /([0-9]+)%/.exec( size ), - horizFirst = !!options.horizFirst, - ref = horizFirst ? [ "right", "bottom" ] : [ "bottom", "right" ], - duration = options.duration / 2, + enable: function( index ) { + var disabled = this.options.disabled; + if ( disabled === false ) { + return; + } - placeholder = $.effects.createPlaceholder( element ), + if ( index === undefined ) { + disabled = false; + } else { + index = this._getIndex( index ); + if ( Array.isArray( disabled ) ) { + disabled = $.map( disabled, function( num ) { + return num !== index ? num : null; + } ); + } else { + disabled = $.map( this.tabs, function( li, num ) { + return num !== index ? num : null; + } ); + } + } + this._setOptionDisabled( disabled ); + }, - start = element.cssClip(), - animation1 = { clip: $.extend( {}, start ) }, - animation2 = { clip: $.extend( {}, start ) }, + disable: function( index ) { + var disabled = this.options.disabled; + if ( disabled === true ) { + return; + } - distance = [ start[ ref[ 0 ] ], start[ ref[ 1 ] ] ], + if ( index === undefined ) { + disabled = true; + } else { + index = this._getIndex( index ); + if ( $.inArray( index, disabled ) !== -1 ) { + return; + } + if ( Array.isArray( disabled ) ) { + disabled = $.merge( [ index ], disabled ).sort(); + } else { + disabled = [ index ]; + } + } + this._setOptionDisabled( disabled ); + }, - queuelen = element.queue().length; + load: function( index, event ) { + index = this._getIndex( index ); + var that = this, + tab = this.tabs.eq( index ), + anchor = tab.find( ".ui-tabs-anchor" ), + panel = this._getPanelForTab( tab ), + eventData = { + tab: tab, + panel: panel + }, + complete = function( jqXHR, status ) { + if ( status === "abort" ) { + that.panels.stop( false, true ); + } - if ( percent ) { - size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ]; - } - animation1.clip[ ref[ 0 ] ] = size; - animation2.clip[ ref[ 0 ] ] = size; - animation2.clip[ ref[ 1 ] ] = 0; + that._removeClass( tab, "ui-tabs-loading" ); + panel.removeAttr( "aria-busy" ); - if ( show ) { - element.cssClip( animation2.clip ); - if ( placeholder ) { - placeholder.css( $.effects.clipToBox( animation2 ) ); - } + if ( jqXHR === that.xhr ) { + delete that.xhr; + } + }; - animation2.clip = start; - } + // Not remote + if ( this._isLocal( anchor[ 0 ] ) ) { + return; + } - // Animate - element - .queue( function( next ) { - if ( placeholder ) { - placeholder - .animate( $.effects.clipToBox( animation1 ), duration, options.easing ) - .animate( $.effects.clipToBox( animation2 ), duration, options.easing ); - } + this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) ); - next(); - } ) - .animate( animation1, duration, options.easing ) - .animate( animation2, duration, options.easing ) - .queue( done ); + // Support: jQuery <1.8 + // jQuery <1.8 returns false if the request is canceled in beforeSend, + // but as of 1.8, $.ajax() always returns a jqXHR object. + if ( this.xhr && this.xhr.statusText !== "canceled" ) { + this._addClass( tab, "ui-tabs-loading" ); + panel.attr( "aria-busy", "true" ); - $.effects.unshift( element, queuelen, 4 ); -} ); + this.xhr + .done( function( response, status, jqXHR ) { + // support: jQuery <1.8 + // http://bugs.jquery.com/ticket/11778 + setTimeout( function() { + panel.html( response ); + that._trigger( "load", event, eventData ); -/*! - * jQuery UI Effects Highlight 1.13.1 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ + complete( jqXHR, status ); + }, 1 ); + } ) + .fail( function( jqXHR, status ) { -//>>label: Highlight Effect -//>>group: Effects -//>>description: Highlights the background of an element in a defined color for a custom duration. -//>>docs: http://api.jqueryui.com/highlight-effect/ -//>>demos: http://jqueryui.com/effect/ + // support: jQuery <1.8 + // http://bugs.jquery.com/ticket/11778 + setTimeout( function() { + complete( jqXHR, status ); + }, 1 ); + } ); + } + }, + _ajaxSettings: function( anchor, event, eventData ) { + var that = this; + return { -var effectsEffectHighlight = $.effects.define( "highlight", "show", function( options, done ) { - var element = $( this ), - animation = { - backgroundColor: element.css( "backgroundColor" ) + // Support: IE <11 only + // Strip any hash that exists to prevent errors with the Ajax request + url: anchor.attr( "href" ).replace( /#.*$/, "" ), + beforeSend: function( jqXHR, settings ) { + return that._trigger( "beforeLoad", event, + $.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) ); + } }; - - if ( options.mode === "hide" ) { - animation.opacity = 0; + }, + + _getPanelForTab: function( tab ) { + var id = $( tab ).attr( "aria-controls" ); + return this.element.find( this._sanitizeSelector( "#" + id ) ); } +} ); - $.effects.saveStyle( element ); +// DEPRECATED +// TODO: Switch return back to widget declaration at top of file when this is removed +if ( $.uiBackCompat !== false ) { - element - .css( { - backgroundImage: "none", - backgroundColor: options.color || "#ffff99" - } ) - .animate( animation, { - queue: false, - duration: options.duration, - easing: options.easing, - complete: done - } ); -} ); + // Backcompat for ui-tab class (now ui-tabs-tab) + $.widget( "ui.tabs", $.ui.tabs, { + _processTabs: function() { + this._superApply( arguments ); + this._addClass( this.tabs, "ui-tab" ); + } + } ); +} + +var widgetsTabs = $.ui.tabs; /*! - * jQuery UI Effects Size 1.13.1 + * jQuery UI Tooltip 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -18623,433 +18560,501 @@ var effectsEffectHighlight = $.effects.define( "highlight", "show", function( op * http://jquery.org/license */ -//>>label: Size Effect -//>>group: Effects -//>>description: Resize an element to a specified width and height. -//>>docs: http://api.jqueryui.com/size-effect/ -//>>demos: http://jqueryui.com/effect/ - - -var effectsEffectSize = $.effects.define( "size", function( options, done ) { +//>>label: Tooltip +//>>group: Widgets +//>>description: Shows additional information for any element on hover or focus. +//>>docs: http://api.jqueryui.com/tooltip/ +//>>demos: http://jqueryui.com/tooltip/ +//>>css.structure: ../../themes/base/core.css +//>>css.structure: ../../themes/base/tooltip.css +//>>css.theme: ../../themes/base/theme.css - // Create element - var baseline, factor, temp, - element = $( this ), - // Copy for children - cProps = [ "fontSize" ], - vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ], - hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ], +$.widget( "ui.tooltip", { + version: "1.13.2", + options: { + classes: { + "ui-tooltip": "ui-corner-all ui-widget-shadow" + }, + content: function() { + var title = $( this ).attr( "title" ); - // Set options - mode = options.mode, - restore = mode !== "effect", - scale = options.scale || "both", - origin = options.origin || [ "middle", "center" ], - position = element.css( "position" ), - pos = element.position(), - original = $.effects.scaledDimensions( element ), - from = options.from || original, - to = options.to || $.effects.scaledDimensions( element, 0 ); + // Escape title, since we're going from an attribute to raw HTML + return $( "<a>" ).text( title ).html(); + }, + hide: true, - $.effects.createPlaceholder( element ); + // Disabled elements have inconsistent behavior across browsers (#8661) + items: "[title]:not([disabled])", + position: { + my: "left top+15", + at: "left bottom", + collision: "flipfit flip" + }, + show: true, + track: false, - if ( mode === "show" ) { - temp = from; - from = to; - to = temp; - } + // Callbacks + close: null, + open: null + }, - // Set scaling factor - factor = { - from: { - y: from.height / original.height, - x: from.width / original.width - }, - to: { - y: to.height / original.height, - x: to.width / original.width - } - }; + _addDescribedBy: function( elem, id ) { + var describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ); + describedby.push( id ); + elem + .data( "ui-tooltip-id", id ) + .attr( "aria-describedby", String.prototype.trim.call( describedby.join( " " ) ) ); + }, - // Scale the css box - if ( scale === "box" || scale === "both" ) { + _removeDescribedBy: function( elem ) { + var id = elem.data( "ui-tooltip-id" ), + describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ), + index = $.inArray( id, describedby ); - // Vertical props scaling - if ( factor.from.y !== factor.to.y ) { - from = $.effects.setTransition( element, vProps, factor.from.y, from ); - to = $.effects.setTransition( element, vProps, factor.to.y, to ); + if ( index !== -1 ) { + describedby.splice( index, 1 ); } - // Horizontal props scaling - if ( factor.from.x !== factor.to.x ) { - from = $.effects.setTransition( element, hProps, factor.from.x, from ); - to = $.effects.setTransition( element, hProps, factor.to.x, to ); + elem.removeData( "ui-tooltip-id" ); + describedby = String.prototype.trim.call( describedby.join( " " ) ); + if ( describedby ) { + elem.attr( "aria-describedby", describedby ); + } else { + elem.removeAttr( "aria-describedby" ); } - } + }, - // Scale the content - if ( scale === "content" || scale === "both" ) { + _create: function() { + this._on( { + mouseover: "open", + focusin: "open" + } ); - // Vertical props scaling - if ( factor.from.y !== factor.to.y ) { - from = $.effects.setTransition( element, cProps, factor.from.y, from ); - to = $.effects.setTransition( element, cProps, factor.to.y, to ); - } - } + // IDs of generated tooltips, needed for destroy + this.tooltips = {}; - // Adjust the position properties based on the provided origin points - if ( origin ) { - baseline = $.effects.getBaseline( origin, original ); - from.top = ( original.outerHeight - from.outerHeight ) * baseline.y + pos.top; - from.left = ( original.outerWidth - from.outerWidth ) * baseline.x + pos.left; - to.top = ( original.outerHeight - to.outerHeight ) * baseline.y + pos.top; - to.left = ( original.outerWidth - to.outerWidth ) * baseline.x + pos.left; - } - delete from.outerHeight; - delete from.outerWidth; - element.css( from ); + // IDs of parent tooltips where we removed the title attribute + this.parents = {}; - // Animate the children if desired - if ( scale === "content" || scale === "both" ) { + // Append the aria-live region so tooltips announce correctly + this.liveRegion = $( "<div>" ) + .attr( { + role: "log", + "aria-live": "assertive", + "aria-relevant": "additions" + } ) + .appendTo( this.document[ 0 ].body ); + this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" ); - vProps = vProps.concat( [ "marginTop", "marginBottom" ] ).concat( cProps ); - hProps = hProps.concat( [ "marginLeft", "marginRight" ] ); + this.disabledTitles = $( [] ); + }, - // Only animate children with width attributes specified - // TODO: is this right? should we include anything with css width specified as well - element.find( "*[width]" ).each( function() { - var child = $( this ), - childOriginal = $.effects.scaledDimensions( child ), - childFrom = { - height: childOriginal.height * factor.from.y, - width: childOriginal.width * factor.from.x, - outerHeight: childOriginal.outerHeight * factor.from.y, - outerWidth: childOriginal.outerWidth * factor.from.x - }, - childTo = { - height: childOriginal.height * factor.to.y, - width: childOriginal.width * factor.to.x, - outerHeight: childOriginal.height * factor.to.y, - outerWidth: childOriginal.width * factor.to.x - }; + _setOption: function( key, value ) { + var that = this; - // Vertical props scaling - if ( factor.from.y !== factor.to.y ) { - childFrom = $.effects.setTransition( child, vProps, factor.from.y, childFrom ); - childTo = $.effects.setTransition( child, vProps, factor.to.y, childTo ); - } + this._super( key, value ); - // Horizontal props scaling - if ( factor.from.x !== factor.to.x ) { - childFrom = $.effects.setTransition( child, hProps, factor.from.x, childFrom ); - childTo = $.effects.setTransition( child, hProps, factor.to.x, childTo ); - } + if ( key === "content" ) { + $.each( this.tooltips, function( id, tooltipData ) { + that._updateContent( tooltipData.element ); + } ); + } + }, - if ( restore ) { - $.effects.saveStyle( child ); - } + _setOptionDisabled: function( value ) { + this[ value ? "_disable" : "_enable" ](); + }, - // Animate children - child.css( childFrom ); - child.animate( childTo, options.duration, options.easing, function() { + _disable: function() { + var that = this; - // Restore children - if ( restore ) { - $.effects.restoreStyle( child ); - } - } ); + // Close open tooltips + $.each( this.tooltips, function( id, tooltipData ) { + var event = $.Event( "blur" ); + event.target = event.currentTarget = tooltipData.element[ 0 ]; + that.close( event, true ); } ); - } - // Animate - element.animate( to, { - queue: false, - duration: options.duration, - easing: options.easing, - complete: function() { + // Remove title attributes to prevent native tooltips + this.disabledTitles = this.disabledTitles.add( + this.element.find( this.options.items ).addBack() + .filter( function() { + var element = $( this ); + if ( element.is( "[title]" ) ) { + return element + .data( "ui-tooltip-title", element.attr( "title" ) ) + .removeAttr( "title" ); + } + } ) + ); + }, - var offset = element.offset(); + _enable: function() { - if ( to.opacity === 0 ) { - element.css( "opacity", from.opacity ); + // restore title attributes + this.disabledTitles.each( function() { + var element = $( this ); + if ( element.data( "ui-tooltip-title" ) ) { + element.attr( "title", element.data( "ui-tooltip-title" ) ); } + } ); + this.disabledTitles = $( [] ); + }, - if ( !restore ) { - element - .css( "position", position === "static" ? "relative" : position ) - .offset( offset ); + open: function( event ) { + var that = this, + target = $( event ? event.target : this.element ) - // Need to save style here so that automatic style restoration - // doesn't restore to the original styles from before the animation. - $.effects.saveStyle( element ); - } + // we need closest here due to mouseover bubbling, + // but always pointing at the same event target + .closest( this.options.items ); - done(); + // No element to show a tooltip for or the tooltip is already open + if ( !target.length || target.data( "ui-tooltip-id" ) ) { + return; } - } ); -} ); + if ( target.attr( "title" ) ) { + target.data( "ui-tooltip-title", target.attr( "title" ) ); + } + target.data( "ui-tooltip-open", true ); -/*! - * jQuery UI Effects Scale 1.13.1 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ + // Kill parent tooltips, custom or native, for hover + if ( event && event.type === "mouseover" ) { + target.parents().each( function() { + var parent = $( this ), + blurEvent; + if ( parent.data( "ui-tooltip-open" ) ) { + blurEvent = $.Event( "blur" ); + blurEvent.target = blurEvent.currentTarget = this; + that.close( blurEvent, true ); + } + if ( parent.attr( "title" ) ) { + parent.uniqueId(); + that.parents[ this.id ] = { + element: this, + title: parent.attr( "title" ) + }; + parent.attr( "title", "" ); + } + } ); + } -//>>label: Scale Effect -//>>group: Effects -//>>description: Grows or shrinks an element and its content. -//>>docs: http://api.jqueryui.com/scale-effect/ -//>>demos: http://jqueryui.com/effect/ + this._registerCloseHandlers( event, target ); + this._updateContent( target, event ); + }, + _updateContent: function( target, event ) { + var content, + contentOption = this.options.content, + that = this, + eventType = event ? event.type : null; -var effectsEffectScale = $.effects.define( "scale", function( options, done ) { + if ( typeof contentOption === "string" || contentOption.nodeType || + contentOption.jquery ) { + return this._open( event, target, contentOption ); + } - // Create element - var el = $( this ), - mode = options.mode, - percent = parseInt( options.percent, 10 ) || - ( parseInt( options.percent, 10 ) === 0 ? 0 : ( mode !== "effect" ? 0 : 100 ) ), + content = contentOption.call( target[ 0 ], function( response ) { - newOptions = $.extend( true, { - from: $.effects.scaledDimensions( el ), - to: $.effects.scaledDimensions( el, percent, options.direction || "both" ), - origin: options.origin || [ "middle", "center" ] - }, options ); + // IE may instantly serve a cached response for ajax requests + // delay this call to _open so the other call to _open runs first + that._delay( function() { - // Fade option to support puff - if ( options.fade ) { - newOptions.from.opacity = 1; - newOptions.to.opacity = 0; - } + // Ignore async response if tooltip was closed already + if ( !target.data( "ui-tooltip-open" ) ) { + return; + } - $.effects.effect.size.call( this, newOptions, done ); -} ); + // JQuery creates a special event for focusin when it doesn't + // exist natively. To improve performance, the native event + // object is reused and the type is changed. Therefore, we can't + // rely on the type being correct after the event finished + // bubbling, so we set it back to the previous value. (#8740) + if ( event ) { + event.type = eventType; + } + this._open( event, target, response ); + } ); + } ); + if ( content ) { + this._open( event, target, content ); + } + }, + _open: function( event, target, content ) { + var tooltipData, tooltip, delayedShow, a11yContent, + positionOption = $.extend( {}, this.options.position ); -/*! - * jQuery UI Effects Puff 1.13.1 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ + if ( !content ) { + return; + } -//>>label: Puff Effect -//>>group: Effects -//>>description: Creates a puff effect by scaling the element up and hiding it at the same time. -//>>docs: http://api.jqueryui.com/puff-effect/ -//>>demos: http://jqueryui.com/effect/ + // Content can be updated multiple times. If the tooltip already + // exists, then just update the content and bail. + tooltipData = this._find( target ); + if ( tooltipData ) { + tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content ); + return; + } + // If we have a title, clear it to prevent the native tooltip + // we have to check first to avoid defining a title if none exists + // (we don't want to cause an element to start matching [title]) + // + // We use removeAttr only for key events, to allow IE to export the correct + // accessible attributes. For mouse events, set to empty string to avoid + // native tooltip showing up (happens only when removing inside mouseover). + if ( target.is( "[title]" ) ) { + if ( event && event.type === "mouseover" ) { + target.attr( "title", "" ); + } else { + target.removeAttr( "title" ); + } + } -var effectsEffectPuff = $.effects.define( "puff", "hide", function( options, done ) { - var newOptions = $.extend( true, {}, options, { - fade: true, - percent: parseInt( options.percent, 10 ) || 150 - } ); + tooltipData = this._tooltip( target ); + tooltip = tooltipData.tooltip; + this._addDescribedBy( target, tooltip.attr( "id" ) ); + tooltip.find( ".ui-tooltip-content" ).html( content ); - $.effects.effect.scale.call( this, newOptions, done ); -} ); + // Support: Voiceover on OS X, JAWS on IE <= 9 + // JAWS announces deletions even when aria-relevant="additions" + // Voiceover will sometimes re-read the entire log region's contents from the beginning + this.liveRegion.children().hide(); + a11yContent = $( "<div>" ).html( tooltip.find( ".ui-tooltip-content" ).html() ); + a11yContent.removeAttr( "name" ).find( "[name]" ).removeAttr( "name" ); + a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" ); + a11yContent.appendTo( this.liveRegion ); + function position( event ) { + positionOption.of = event; + if ( tooltip.is( ":hidden" ) ) { + return; + } + tooltip.position( positionOption ); + } + if ( this.options.track && event && /^mouse/.test( event.type ) ) { + this._on( this.document, { + mousemove: position + } ); -/*! - * jQuery UI Effects Pulsate 1.13.1 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ + // trigger once to override element-relative positioning + position( event ); + } else { + tooltip.position( $.extend( { + of: target + }, this.options.position ) ); + } -//>>label: Pulsate Effect -//>>group: Effects -//>>description: Pulsates an element n times by changing the opacity to zero and back. -//>>docs: http://api.jqueryui.com/pulsate-effect/ -//>>demos: http://jqueryui.com/effect/ + tooltip.hide(); + this._show( tooltip, this.options.show ); -var effectsEffectPulsate = $.effects.define( "pulsate", "show", function( options, done ) { - var element = $( this ), - mode = options.mode, - show = mode === "show", - hide = mode === "hide", - showhide = show || hide, + // Handle tracking tooltips that are shown with a delay (#8644). As soon + // as the tooltip is visible, position the tooltip using the most recent + // event. + // Adds the check to add the timers only when both delay and track options are set (#14682) + if ( this.options.track && this.options.show && this.options.show.delay ) { + delayedShow = this.delayedShow = setInterval( function() { + if ( tooltip.is( ":visible" ) ) { + position( positionOption.of ); + clearInterval( delayedShow ); + } + }, 13 ); + } - // Showing or hiding leaves off the "last" animation - anims = ( ( options.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ), - duration = options.duration / anims, - animateTo = 0, - i = 1, - queuelen = element.queue().length; + this._trigger( "open", event, { tooltip: tooltip } ); + }, - if ( show || !element.is( ":visible" ) ) { - element.css( "opacity", 0 ).show(); - animateTo = 1; - } + _registerCloseHandlers: function( event, target ) { + var events = { + keyup: function( event ) { + if ( event.keyCode === $.ui.keyCode.ESCAPE ) { + var fakeEvent = $.Event( event ); + fakeEvent.currentTarget = target[ 0 ]; + this.close( fakeEvent, true ); + } + } + }; + + // Only bind remove handler for delegated targets. Non-delegated + // tooltips will handle this in destroy. + if ( target[ 0 ] !== this.element[ 0 ] ) { + events.remove = function() { + var targetElement = this._find( target ); + if ( targetElement ) { + this._removeTooltip( targetElement.tooltip ); + } + }; + } - // Anims - 1 opacity "toggles" - for ( ; i < anims; i++ ) { - element.animate( { opacity: animateTo }, duration, options.easing ); - animateTo = 1 - animateTo; - } + if ( !event || event.type === "mouseover" ) { + events.mouseleave = "close"; + } + if ( !event || event.type === "focusin" ) { + events.focusout = "close"; + } + this._on( true, target, events ); + }, - element.animate( { opacity: animateTo }, duration, options.easing ); + close: function( event ) { + var tooltip, + that = this, + target = $( event ? event.currentTarget : this.element ), + tooltipData = this._find( target ); - element.queue( done ); + // The tooltip may already be closed + if ( !tooltipData ) { - $.effects.unshift( element, queuelen, anims + 1 ); -} ); + // We set ui-tooltip-open immediately upon open (in open()), but only set the + // additional data once there's actually content to show (in _open()). So even if the + // tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in + // the period between open() and _open(). + target.removeData( "ui-tooltip-open" ); + return; + } + tooltip = tooltipData.tooltip; -/*! - * jQuery UI Effects Shake 1.13.1 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ + // Disabling closes the tooltip, so we need to track when we're closing + // to avoid an infinite loop in case the tooltip becomes disabled on close + if ( tooltipData.closing ) { + return; + } -//>>label: Shake Effect -//>>group: Effects -//>>description: Shakes an element horizontally or vertically n times. -//>>docs: http://api.jqueryui.com/shake-effect/ -//>>demos: http://jqueryui.com/effect/ + // Clear the interval for delayed tracking tooltips + clearInterval( this.delayedShow ); + // Only set title if we had one before (see comment in _open()) + // If the title attribute has changed since open(), don't restore + if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) { + target.attr( "title", target.data( "ui-tooltip-title" ) ); + } -var effectsEffectShake = $.effects.define( "shake", function( options, done ) { + this._removeDescribedBy( target ); - var i = 1, - element = $( this ), - direction = options.direction || "left", - distance = options.distance || 20, - times = options.times || 3, - anims = times * 2 + 1, - speed = Math.round( options.duration / anims ), - ref = ( direction === "up" || direction === "down" ) ? "top" : "left", - positiveMotion = ( direction === "up" || direction === "left" ), - animation = {}, - animation1 = {}, - animation2 = {}, + tooltipData.hiding = true; + tooltip.stop( true ); + this._hide( tooltip, this.options.hide, function() { + that._removeTooltip( $( this ) ); + } ); - queuelen = element.queue().length; + target.removeData( "ui-tooltip-open" ); + this._off( target, "mouseleave focusout keyup" ); - $.effects.createPlaceholder( element ); + // Remove 'remove' binding only on delegated targets + if ( target[ 0 ] !== this.element[ 0 ] ) { + this._off( target, "remove" ); + } + this._off( this.document, "mousemove" ); - // Animation - animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance; - animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2; - animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2; + if ( event && event.type === "mouseleave" ) { + $.each( this.parents, function( id, parent ) { + $( parent.element ).attr( "title", parent.title ); + delete that.parents[ id ]; + } ); + } - // Animate - element.animate( animation, speed, options.easing ); + tooltipData.closing = true; + this._trigger( "close", event, { tooltip: tooltip } ); + if ( !tooltipData.hiding ) { + tooltipData.closing = false; + } + }, - // Shakes - for ( ; i < times; i++ ) { - element - .animate( animation1, speed, options.easing ) - .animate( animation2, speed, options.easing ); - } + _tooltip: function( element ) { + var tooltip = $( "<div>" ).attr( "role", "tooltip" ), + content = $( "<div>" ).appendTo( tooltip ), + id = tooltip.uniqueId().attr( "id" ); - element - .animate( animation1, speed, options.easing ) - .animate( animation, speed / 2, options.easing ) - .queue( done ); + this._addClass( content, "ui-tooltip-content" ); + this._addClass( tooltip, "ui-tooltip", "ui-widget ui-widget-content" ); - $.effects.unshift( element, queuelen, anims + 1 ); -} ); + tooltip.appendTo( this._appendTo( element ) ); + return this.tooltips[ id ] = { + element: element, + tooltip: tooltip + }; + }, -/*! - * jQuery UI Effects Slide 1.13.1 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ + _find: function( target ) { + var id = target.data( "ui-tooltip-id" ); + return id ? this.tooltips[ id ] : null; + }, -//>>label: Slide Effect -//>>group: Effects -//>>description: Slides an element in and out of the viewport. -//>>docs: http://api.jqueryui.com/slide-effect/ -//>>demos: http://jqueryui.com/effect/ + _removeTooltip: function( tooltip ) { + // Clear the interval for delayed tracking tooltips + clearInterval( this.delayedShow ); -var effectsEffectSlide = $.effects.define( "slide", "show", function( options, done ) { - var startClip, startRef, - element = $( this ), - map = { - up: [ "bottom", "top" ], - down: [ "top", "bottom" ], - left: [ "right", "left" ], - right: [ "left", "right" ] - }, - mode = options.mode, - direction = options.direction || "left", - ref = ( direction === "up" || direction === "down" ) ? "top" : "left", - positiveMotion = ( direction === "up" || direction === "left" ), - distance = options.distance || - element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ), - animation = {}; + tooltip.remove(); + delete this.tooltips[ tooltip.attr( "id" ) ]; + }, - $.effects.createPlaceholder( element ); + _appendTo: function( target ) { + var element = target.closest( ".ui-front, dialog" ); - startClip = element.cssClip(); - startRef = element.position()[ ref ]; + if ( !element.length ) { + element = this.document[ 0 ].body; + } - // Define hide animation - animation[ ref ] = ( positiveMotion ? -1 : 1 ) * distance + startRef; - animation.clip = element.cssClip(); - animation.clip[ map[ direction ][ 1 ] ] = animation.clip[ map[ direction ][ 0 ] ]; + return element; + }, - // Reverse the animation if we're showing - if ( mode === "show" ) { - element.cssClip( animation.clip ); - element.css( ref, animation[ ref ] ); - animation.clip = startClip; - animation[ ref ] = startRef; - } + _destroy: function() { + var that = this; - // Actually animate - element.animate( animation, { - queue: false, - duration: options.duration, - easing: options.easing, - complete: done - } ); -} ); + // Close open tooltips + $.each( this.tooltips, function( id, tooltipData ) { + // Delegate to close method to handle common cleanup + var event = $.Event( "blur" ), + element = tooltipData.element; + event.target = event.currentTarget = element[ 0 ]; + that.close( event, true ); -/*! - * jQuery UI Effects Transfer 1.13.1 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - */ + // Remove immediately; destroying an open tooltip doesn't use the + // hide animation + $( "#" + id ).remove(); -//>>label: Transfer Effect -//>>group: Effects -//>>description: Displays a transfer effect from one element to another. -//>>docs: http://api.jqueryui.com/transfer-effect/ -//>>demos: http://jqueryui.com/effect/ + // Restore the title + if ( element.data( "ui-tooltip-title" ) ) { + // If the title attribute has changed since open(), don't restore + if ( !element.attr( "title" ) ) { + element.attr( "title", element.data( "ui-tooltip-title" ) ); + } + element.removeData( "ui-tooltip-title" ); + } + } ); + this.liveRegion.remove(); + } +} ); -var effect; +// DEPRECATED +// TODO: Switch return back to widget declaration at top of file when this is removed if ( $.uiBackCompat !== false ) { - effect = $.effects.define( "transfer", function( options, done ) { - $( this ).transfer( options, done ); + + // Backcompat for tooltipClass option + $.widget( "ui.tooltip", $.ui.tooltip, { + options: { + tooltipClass: null + }, + _tooltip: function() { + var tooltipData = this._superApply( arguments ); + if ( this.options.tooltipClass ) { + tooltipData.tooltip.addClass( this.options.tooltipClass ); + } + return tooltipData; + } } ); } -var effectsEffectTransfer = effect; + +var widgetsTooltip = $.ui.tooltip; diff --git a/lib/web/jquery/jquery.validate.js b/lib/web/jquery/jquery.validate.js index b9bc14f55e393..c2ba9084d91a8 100644 --- a/lib/web/jquery/jquery.validate.js +++ b/lib/web/jquery/jquery.validate.js @@ -1,9 +1,9 @@ /*! - * jQuery Validation Plugin v1.19.3 + * jQuery Validation Plugin v1.19.5 * * https://jqueryvalidation.org/ * - * Copyright (c) 2021 Jörn Zaefferer + * Copyright (c) 2022 Jörn Zaefferer * Released under the MIT license */ (function( factory ) { @@ -378,7 +378,6 @@ dateISO: "Please enter a valid date (ISO).", number: "Please enter a valid number.", digits: "Please enter only digits.", - creditcard: "Please enter a valid credit card number.", equalTo: "Please enter the same value again.", maxlength: $.validator.format( "Please enter no more than {0} characters." ), minlength: $.validator.format( "Please enter at least {0} characters." ), @@ -784,7 +783,7 @@ normalizer = this.settings.normalizer; } - // If normalizer is defined, then call it to retrieve the changed value instead + // If normalizer is defined, then call it to the changed value instead // of using the real one. // Note that `this` in the normalizer is `element`. if ( normalizer ) { @@ -875,13 +874,13 @@ } var message = this.findDefined( - this.customMessage( element.name, rule.method ), - this.customDataMessage( element, rule.method ), + this.customMessage( element.name, rule.method ), + this.customDataMessage( element, rule.method ), - // 'title' is never undefined, so handle empty string as undefined - !this.settings.ignoreTitle && element.title || undefined, - $.validator.messages[ rule.method ], - "<strong>Warning: No message defined for " + element.name + "</strong>" + // 'title' is never undefined, so handle empty string as undefined + !this.settings.ignoreTitle && element.title || undefined, + $.validator.messages[ rule.method ], + "<strong>Warning: No message defined for " + element.name + "</strong>" ), theregex = /\$?\{(\d+)\}/g; if ( typeof message === "function" ) { @@ -982,7 +981,7 @@ if ( this.labelContainer.length ) { this.labelContainer.append( place ); } else if ( this.settings.errorPlacement ) { - this.settings.errorPlacement( place, $( element ) ); + this.settings.errorPlacement.call( this, place, $( element ) ); } else { place.insertAfter( element ); } @@ -1052,7 +1051,11 @@ // meta-characters that should be escaped in order to be used with JQuery // as a literal part of a name/id or any selector. escapeCssMeta: function( string ) { - return (string || '').replace( /([\\!"#$%&'()*+,./:;<=>?@\[\]^`{|}~])/g, "\\$1" ); + if ( string === undefined ) { + return ""; + } + + return string.replace( /([\\!"#$%&'()*+,./:;<=>?@\[\]^`{|}~])/g, "\\$1" ); }, idOrName: function( element ) { @@ -1128,8 +1131,8 @@ } delete this.pending[ element.name ]; $( element ).removeClass( this.settings.pendingClass ); - if ( valid && this.pendingRequest === 0 && this.formSubmitted && this.form() ) { - $( this.currentForm ).submit(); + if ( valid && this.pendingRequest === 0 && this.formSubmitted && this.form() && this.pendingRequest === 0 ) { + $( this.currentForm ).trigger( "submit" ); // Remove the hidden input that was used as a replacement for the // missing submit button. The hidden input is added by `handle()` @@ -1234,7 +1237,7 @@ // Exception: the jquery validate 'range' method // does not test for the html5 'range' type - rules[ method ] = true; + rules[ type === "date" ? "dateISO" : method ] = true; } }, @@ -1443,7 +1446,7 @@ // https://gist.github.com/dperini/729294 // see also https://mathiasbynens.be/demo/url-regex // modified to allow protocol-relative URLs - return this.optional( element ) || /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z0-9\u00a1-\uffff][a-z0-9\u00a1-\uffff_-]{0,62})?[a-z0-9\u00a1-\uffff]\.)+(?:[a-z\u00a1-\uffff]{2,}\.?))(?::\d{2,5})?(?:[/?#]\S*)?$/i.test( value ); + return this.optional( element ) || /^(?:(?:(?:https?|ftp):)?\/\/)(?:(?:[^\]\[?\/<~#`!@$^&*()+=}|:";',>{ ]|%[0-9A-Fa-f]{2})+(?::(?:[^\]\[?\/<~#`!@$^&*()+=}|:";',>{ ]|%[0-9A-Fa-f]{2})*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z0-9\u00a1-\uffff][a-z0-9\u00a1-\uffff_-]{0,62})?[a-z0-9\u00a1-\uffff]\.)+(?:[a-z\u00a1-\uffff]{2,}\.?))(?::\d{2,5})?(?:[/?#]\S*)?$/i.test( value ); }, // https://jqueryvalidation.org/date-method/ diff --git a/lib/web/jquery/ui-modules/data.js b/lib/web/jquery/ui-modules/data.js index c0fcedc7d5d13..f3a4bc4adc9d1 100644 --- a/lib/web/jquery/ui-modules/data.js +++ b/lib/web/jquery/ui-modules/data.js @@ -1,5 +1,5 @@ /*! - * jQuery UI :data 1.13.1 + * jQuery UI :data 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -13,31 +13,31 @@ //>>docs: http://api.jqueryui.com/data-selector/ ( function( factory ) { - "use strict"; + "use strict"; - if ( typeof define === "function" && define.amd ) { + if ( typeof define === "function" && define.amd ) { - // AMD. Register as an anonymous module. - define( [ "jquery", "./version" ], factory ); - } else { + // AMD. Register as an anonymous module. + define( [ "jquery", "./version" ], factory ); + } else { - // Browser globals - factory( jQuery ); - } + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; + "use strict"; -return $.extend( $.expr.pseudos, { - data: $.expr.createPseudo ? - $.expr.createPseudo( function( dataName ) { - return function( elem ) { - return !!$.data( elem, dataName ); - }; - } ) : + return $.extend( $.expr.pseudos, { + data: $.expr.createPseudo ? + $.expr.createPseudo( function( dataName ) { + return function( elem ) { + return !!$.data( elem, dataName ); + }; + } ) : - // Support: jQuery <1.8 - function( elem, i, match ) { - return !!$.data( elem, match[ 3 ] ); - } -} ); + // Support: jQuery <1.8 + function( elem, i, match ) { + return !!$.data( elem, match[ 3 ] ); + } + } ); } ); diff --git a/lib/web/jquery/ui-modules/disable-selection.js b/lib/web/jquery/ui-modules/disable-selection.js index 9f6bf815c9f03..40169ddbdaa8a 100644 --- a/lib/web/jquery/ui-modules/disable-selection.js +++ b/lib/web/jquery/ui-modules/disable-selection.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Disable Selection 1.13.1 + * jQuery UI Disable Selection 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -14,36 +14,36 @@ // This file is deprecated ( function( factory ) { - "use strict"; + "use strict"; - if ( typeof define === "function" && define.amd ) { + if ( typeof define === "function" && define.amd ) { - // AMD. Register as an anonymous module. - define( [ "jquery", "./version" ], factory ); - } else { + // AMD. Register as an anonymous module. + define( [ "jquery", "./version" ], factory ); + } else { - // Browser globals - factory( jQuery ); - } + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; - -return $.fn.extend( { - disableSelection: ( function() { - var eventType = "onselectstart" in document.createElement( "div" ) ? - "selectstart" : - "mousedown"; - - return function() { - return this.on( eventType + ".ui-disableSelection", function( event ) { - event.preventDefault(); - } ); - }; - } )(), - - enableSelection: function() { - return this.off( ".ui-disableSelection" ); - } -} ); + "use strict"; + + return $.fn.extend( { + disableSelection: ( function() { + var eventType = "onselectstart" in document.createElement( "div" ) ? + "selectstart" : + "mousedown"; + + return function() { + return this.on( eventType + ".ui-disableSelection", function( event ) { + event.preventDefault(); + } ); + }; + } )(), + + enableSelection: function() { + return this.off( ".ui-disableSelection" ); + } + } ); } ); diff --git a/lib/web/jquery/ui-modules/effect.js b/lib/web/jquery/ui-modules/effect.js index f8acb728a9252..bac518feb15da 100644 --- a/lib/web/jquery/ui-modules/effect.js +++ b/lib/web/jquery/ui-modules/effect.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Effects 1.13.1 + * jQuery UI Effects 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -16,956 +16,956 @@ //>>demos: http://jqueryui.com/effect/ ( function( factory ) { - "use strict"; - - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define( [ - "jquery", - "./jquery-var-for-color", - "./vendor/jquery-color/jquery.color", - "./version" - ], factory ); - } else { - - // Browser globals - factory( jQuery ); - } + "use strict"; + + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ + "jquery", + "./jquery-var-for-color", + "./vendor/jquery-color/jquery.color", + "./version" + ], factory ); + } else { + + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; - -var dataSpace = "ui-effects-", - dataSpaceStyle = "ui-effects-style", - dataSpaceAnimated = "ui-effects-animated"; - -$.effects = { - effect: {} -}; - -/******************************************************************************/ -/****************************** CLASS ANIMATIONS ******************************/ -/******************************************************************************/ -( function() { - -var classAnimationActions = [ "add", "remove", "toggle" ], - shorthandStyles = { - border: 1, - borderBottom: 1, - borderColor: 1, - borderLeft: 1, - borderRight: 1, - borderTop: 1, - borderWidth: 1, - margin: 1, - padding: 1 - }; - -$.each( - [ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], - function( _, prop ) { - $.fx.step[ prop ] = function( fx ) { - if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) { - jQuery.style( fx.elem, prop, fx.end ); - fx.setAttr = true; - } - }; - } -); - -function camelCase( string ) { - return string.replace( /-([\da-z])/gi, function( all, letter ) { - return letter.toUpperCase(); - } ); -} - -function getElementStyles( elem ) { - var key, len, - style = elem.ownerDocument.defaultView ? - elem.ownerDocument.defaultView.getComputedStyle( elem, null ) : - elem.currentStyle, - styles = {}; - - if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) { - len = style.length; - while ( len-- ) { - key = style[ len ]; - if ( typeof style[ key ] === "string" ) { - styles[ camelCase( key ) ] = style[ key ]; - } - } - - // Support: Opera, IE <9 - } else { - for ( key in style ) { - if ( typeof style[ key ] === "string" ) { - styles[ key ] = style[ key ]; - } - } - } - - return styles; -} - -function styleDifference( oldStyle, newStyle ) { - var diff = {}, - name, value; - - for ( name in newStyle ) { - value = newStyle[ name ]; - if ( oldStyle[ name ] !== value ) { - if ( !shorthandStyles[ name ] ) { - if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) { - diff[ name ] = value; - } - } - } - } - - return diff; -} + "use strict"; + + var dataSpace = "ui-effects-", + dataSpaceStyle = "ui-effects-style", + dataSpaceAnimated = "ui-effects-animated"; + + $.effects = { + effect: {} + }; + + /******************************************************************************/ + /****************************** CLASS ANIMATIONS ******************************/ + /******************************************************************************/ + ( function() { + + var classAnimationActions = [ "add", "remove", "toggle" ], + shorthandStyles = { + border: 1, + borderBottom: 1, + borderColor: 1, + borderLeft: 1, + borderRight: 1, + borderTop: 1, + borderWidth: 1, + margin: 1, + padding: 1 + }; + + $.each( + [ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], + function( _, prop ) { + $.fx.step[ prop ] = function( fx ) { + if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) { + jQuery.style( fx.elem, prop, fx.end ); + fx.setAttr = true; + } + }; + } + ); + + function camelCase( string ) { + return string.replace( /-([\da-z])/gi, function( all, letter ) { + return letter.toUpperCase(); + } ); + } + + function getElementStyles( elem ) { + var key, len, + style = elem.ownerDocument.defaultView ? + elem.ownerDocument.defaultView.getComputedStyle( elem, null ) : + elem.currentStyle, + styles = {}; + + if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) { + len = style.length; + while ( len-- ) { + key = style[ len ]; + if ( typeof style[ key ] === "string" ) { + styles[ camelCase( key ) ] = style[ key ]; + } + } + + // Support: Opera, IE <9 + } else { + for ( key in style ) { + if ( typeof style[ key ] === "string" ) { + styles[ key ] = style[ key ]; + } + } + } + + return styles; + } + + function styleDifference( oldStyle, newStyle ) { + var diff = {}, + name, value; + + for ( name in newStyle ) { + value = newStyle[ name ]; + if ( oldStyle[ name ] !== value ) { + if ( !shorthandStyles[ name ] ) { + if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) { + diff[ name ] = value; + } + } + } + } + + return diff; + } // Support: jQuery <1.8 -if ( !$.fn.addBack ) { - $.fn.addBack = function( selector ) { - return this.add( selector == null ? - this.prevObject : this.prevObject.filter( selector ) - ); - }; -} - -$.effects.animateClass = function( value, duration, easing, callback ) { - var o = $.speed( duration, easing, callback ); - - return this.queue( function() { - var animated = $( this ), - baseClass = animated.attr( "class" ) || "", - applyClassChange, - allAnimations = o.children ? animated.find( "*" ).addBack() : animated; - - // Map the animated objects to store the original styles. - allAnimations = allAnimations.map( function() { - var el = $( this ); - return { - el: el, - start: getElementStyles( this ) - }; - } ); - - // Apply class change - applyClassChange = function() { - $.each( classAnimationActions, function( i, action ) { - if ( value[ action ] ) { - animated[ action + "Class" ]( value[ action ] ); - } - } ); - }; - applyClassChange(); - - // Map all animated objects again - calculate new styles and diff - allAnimations = allAnimations.map( function() { - this.end = getElementStyles( this.el[ 0 ] ); - this.diff = styleDifference( this.start, this.end ); - return this; - } ); - - // Apply original class - animated.attr( "class", baseClass ); - - // Map all animated objects again - this time collecting a promise - allAnimations = allAnimations.map( function() { - var styleInfo = this, - dfd = $.Deferred(), - opts = $.extend( {}, o, { - queue: false, - complete: function() { - dfd.resolve( styleInfo ); - } - } ); - - this.el.animate( this.diff, opts ); - return dfd.promise(); - } ); - - // Once all animations have completed: - $.when.apply( $, allAnimations.get() ).done( function() { - - // Set the final class - applyClassChange(); - - // For each animated element, - // clear all css properties that were animated - $.each( arguments, function() { - var el = this.el; - $.each( this.diff, function( key ) { - el.css( key, "" ); - } ); - } ); - - // This is guarnteed to be there if you use jQuery.speed() - // it also handles dequeuing the next anim... - o.complete.call( animated[ 0 ] ); - } ); - } ); -}; - -$.fn.extend( { - addClass: ( function( orig ) { - return function( classNames, speed, easing, callback ) { - return speed ? - $.effects.animateClass.call( this, - { add: classNames }, speed, easing, callback ) : - orig.apply( this, arguments ); - }; - } )( $.fn.addClass ), - - removeClass: ( function( orig ) { - return function( classNames, speed, easing, callback ) { - return arguments.length > 1 ? - $.effects.animateClass.call( this, - { remove: classNames }, speed, easing, callback ) : - orig.apply( this, arguments ); - }; - } )( $.fn.removeClass ), - - toggleClass: ( function( orig ) { - return function( classNames, force, speed, easing, callback ) { - if ( typeof force === "boolean" || force === undefined ) { - if ( !speed ) { - - // Without speed parameter - return orig.apply( this, arguments ); - } else { - return $.effects.animateClass.call( this, - ( force ? { add: classNames } : { remove: classNames } ), - speed, easing, callback ); - } - } else { - - // Without force parameter - return $.effects.animateClass.call( this, - { toggle: classNames }, force, speed, easing ); - } - }; - } )( $.fn.toggleClass ), - - switchClass: function( remove, add, speed, easing, callback ) { - return $.effects.animateClass.call( this, { - add: add, - remove: remove - }, speed, easing, callback ); - } -} ); - -} )(); - -/******************************************************************************/ -/*********************************** EFFECTS **********************************/ -/******************************************************************************/ - -( function() { - -if ( $.expr && $.expr.pseudos && $.expr.pseudos.animated ) { - $.expr.pseudos.animated = ( function( orig ) { - return function( elem ) { - return !!$( elem ).data( dataSpaceAnimated ) || orig( elem ); - }; - } )( $.expr.pseudos.animated ); -} - -if ( $.uiBackCompat !== false ) { - $.extend( $.effects, { - - // Saves a set of properties in a data storage - save: function( element, set ) { - var i = 0, length = set.length; - for ( ; i < length; i++ ) { - if ( set[ i ] !== null ) { - element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); - } - } - }, - - // Restores a set of previously saved properties from a data storage - restore: function( element, set ) { - var val, i = 0, length = set.length; - for ( ; i < length; i++ ) { - if ( set[ i ] !== null ) { - val = element.data( dataSpace + set[ i ] ); - element.css( set[ i ], val ); - } - } - }, - - setMode: function( el, mode ) { - if ( mode === "toggle" ) { - mode = el.is( ":hidden" ) ? "show" : "hide"; - } - return mode; - }, - - // Wraps the element around a wrapper that copies position properties - createWrapper: function( element ) { - - // If the element is already wrapped, return it - if ( element.parent().is( ".ui-effects-wrapper" ) ) { - return element.parent(); - } - - // Wrap the element - var props = { - width: element.outerWidth( true ), - height: element.outerHeight( true ), - "float": element.css( "float" ) - }, - wrapper = $( "<div></div>" ) - .addClass( "ui-effects-wrapper" ) - .css( { - fontSize: "100%", - background: "transparent", - border: "none", - margin: 0, - padding: 0 - } ), - - // Store the size in case width/height are defined in % - Fixes #5245 - size = { - width: element.width(), - height: element.height() - }, - active = document.activeElement; - - // Support: Firefox - // Firefox incorrectly exposes anonymous content - // https://bugzilla.mozilla.org/show_bug.cgi?id=561664 - try { - // eslint-disable-next-line no-unused-expressions - active.id; - } catch ( e ) { - active = document.body; - } - - element.wrap( wrapper ); - - // Fixes #7595 - Elements lose focus when wrapped. - if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { - $( active ).trigger( "focus" ); - } - - // Hotfix for jQuery 1.4 since some change in wrap() seems to actually - // lose the reference to the wrapped element - wrapper = element.parent(); - - // Transfer positioning properties to the wrapper - if ( element.css( "position" ) === "static" ) { - wrapper.css( { position: "relative" } ); - element.css( { position: "relative" } ); - } else { - $.extend( props, { - position: element.css( "position" ), - zIndex: element.css( "z-index" ) - } ); - $.each( [ "top", "left", "bottom", "right" ], function( i, pos ) { - props[ pos ] = element.css( pos ); - if ( isNaN( parseInt( props[ pos ], 10 ) ) ) { - props[ pos ] = "auto"; - } - } ); - element.css( { - position: "relative", - top: 0, - left: 0, - right: "auto", - bottom: "auto" - } ); - } - element.css( size ); - - return wrapper.css( props ).show(); - }, - - removeWrapper: function( element ) { - var active = document.activeElement; - - if ( element.parent().is( ".ui-effects-wrapper" ) ) { - element.parent().replaceWith( element ); - - // Fixes #7595 - Elements lose focus when wrapped. - if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { - $( active ).trigger( "focus" ); - } - } - - return element; - } - } ); -} - -$.extend( $.effects, { - version: "1.13.1", - - define: function( name, mode, effect ) { - if ( !effect ) { - effect = mode; - mode = "effect"; - } - - $.effects.effect[ name ] = effect; - $.effects.effect[ name ].mode = mode; - - return effect; - }, - - scaledDimensions: function( element, percent, direction ) { - if ( percent === 0 ) { - return { - height: 0, - width: 0, - outerHeight: 0, - outerWidth: 0 - }; - } - - var x = direction !== "horizontal" ? ( ( percent || 100 ) / 100 ) : 1, - y = direction !== "vertical" ? ( ( percent || 100 ) / 100 ) : 1; - - return { - height: element.height() * y, - width: element.width() * x, - outerHeight: element.outerHeight() * y, - outerWidth: element.outerWidth() * x - }; - - }, - - clipToBox: function( animation ) { - return { - width: animation.clip.right - animation.clip.left, - height: animation.clip.bottom - animation.clip.top, - left: animation.clip.left, - top: animation.clip.top - }; - }, - - // Injects recently queued functions to be first in line (after "inprogress") - unshift: function( element, queueLength, count ) { - var queue = element.queue(); - - if ( queueLength > 1 ) { - queue.splice.apply( queue, - [ 1, 0 ].concat( queue.splice( queueLength, count ) ) ); - } - element.dequeue(); - }, - - saveStyle: function( element ) { - element.data( dataSpaceStyle, element[ 0 ].style.cssText ); - }, - - restoreStyle: function( element ) { - element[ 0 ].style.cssText = element.data( dataSpaceStyle ) || ""; - element.removeData( dataSpaceStyle ); - }, - - mode: function( element, mode ) { - var hidden = element.is( ":hidden" ); - - if ( mode === "toggle" ) { - mode = hidden ? "show" : "hide"; - } - if ( hidden ? mode === "hide" : mode === "show" ) { - mode = "none"; - } - return mode; - }, - - // Translates a [top,left] array into a baseline value - getBaseline: function( origin, original ) { - var y, x; - - switch ( origin[ 0 ] ) { - case "top": - y = 0; - break; - case "middle": - y = 0.5; - break; - case "bottom": - y = 1; - break; - default: - y = origin[ 0 ] / original.height; - } - - switch ( origin[ 1 ] ) { - case "left": - x = 0; - break; - case "center": - x = 0.5; - break; - case "right": - x = 1; - break; - default: - x = origin[ 1 ] / original.width; - } - - return { - x: x, - y: y - }; - }, - - // Creates a placeholder element so that the original element can be made absolute - createPlaceholder: function( element ) { - var placeholder, - cssPosition = element.css( "position" ), - position = element.position(); - - // Lock in margins first to account for form elements, which - // will change margin if you explicitly set height - // see: http://jsfiddle.net/JZSMt/3/ https://bugs.webkit.org/show_bug.cgi?id=107380 - // Support: Safari - element.css( { - marginTop: element.css( "marginTop" ), - marginBottom: element.css( "marginBottom" ), - marginLeft: element.css( "marginLeft" ), - marginRight: element.css( "marginRight" ) - } ) - .outerWidth( element.outerWidth() ) - .outerHeight( element.outerHeight() ); - - if ( /^(static|relative)/.test( cssPosition ) ) { - cssPosition = "absolute"; - - placeholder = $( "<" + element[ 0 ].nodeName + ">" ).insertAfter( element ).css( { - - // Convert inline to inline block to account for inline elements - // that turn to inline block based on content (like img) - display: /^(inline|ruby)/.test( element.css( "display" ) ) ? - "inline-block" : - "block", - visibility: "hidden", - - // Margins need to be set to account for margin collapse - marginTop: element.css( "marginTop" ), - marginBottom: element.css( "marginBottom" ), - marginLeft: element.css( "marginLeft" ), - marginRight: element.css( "marginRight" ), - "float": element.css( "float" ) - } ) - .outerWidth( element.outerWidth() ) - .outerHeight( element.outerHeight() ) - .addClass( "ui-effects-placeholder" ); - - element.data( dataSpace + "placeholder", placeholder ); - } - - element.css( { - position: cssPosition, - left: position.left, - top: position.top - } ); - - return placeholder; - }, - - removePlaceholder: function( element ) { - var dataKey = dataSpace + "placeholder", - placeholder = element.data( dataKey ); - - if ( placeholder ) { - placeholder.remove(); - element.removeData( dataKey ); - } - }, - - // Removes a placeholder if it exists and restores - // properties that were modified during placeholder creation - cleanUp: function( element ) { - $.effects.restoreStyle( element ); - $.effects.removePlaceholder( element ); - }, - - setTransition: function( element, list, factor, value ) { - value = value || {}; - $.each( list, function( i, x ) { - var unit = element.cssUnit( x ); - if ( unit[ 0 ] > 0 ) { - value[ x ] = unit[ 0 ] * factor + unit[ 1 ]; - } - } ); - return value; - } -} ); + if ( !$.fn.addBack ) { + $.fn.addBack = function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter( selector ) + ); + }; + } + + $.effects.animateClass = function( value, duration, easing, callback ) { + var o = $.speed( duration, easing, callback ); + + return this.queue( function() { + var animated = $( this ), + baseClass = animated.attr( "class" ) || "", + applyClassChange, + allAnimations = o.children ? animated.find( "*" ).addBack() : animated; + + // Map the animated objects to store the original styles. + allAnimations = allAnimations.map( function() { + var el = $( this ); + return { + el: el, + start: getElementStyles( this ) + }; + } ); + + // Apply class change + applyClassChange = function() { + $.each( classAnimationActions, function( i, action ) { + if ( value[ action ] ) { + animated[ action + "Class" ]( value[ action ] ); + } + } ); + }; + applyClassChange(); + + // Map all animated objects again - calculate new styles and diff + allAnimations = allAnimations.map( function() { + this.end = getElementStyles( this.el[ 0 ] ); + this.diff = styleDifference( this.start, this.end ); + return this; + } ); + + // Apply original class + animated.attr( "class", baseClass ); + + // Map all animated objects again - this time collecting a promise + allAnimations = allAnimations.map( function() { + var styleInfo = this, + dfd = $.Deferred(), + opts = $.extend( {}, o, { + queue: false, + complete: function() { + dfd.resolve( styleInfo ); + } + } ); + + this.el.animate( this.diff, opts ); + return dfd.promise(); + } ); + + // Once all animations have completed: + $.when.apply( $, allAnimations.get() ).done( function() { + + // Set the final class + applyClassChange(); + + // For each animated element, + // clear all css properties that were animated + $.each( arguments, function() { + var el = this.el; + $.each( this.diff, function( key ) { + el.css( key, "" ); + } ); + } ); + + // This is guarnteed to be there if you use jQuery.speed() + // it also handles dequeuing the next anim... + o.complete.call( animated[ 0 ] ); + } ); + } ); + }; + + $.fn.extend( { + addClass: ( function( orig ) { + return function( classNames, speed, easing, callback ) { + return speed ? + $.effects.animateClass.call( this, + { add: classNames }, speed, easing, callback ) : + orig.apply( this, arguments ); + }; + } )( $.fn.addClass ), + + removeClass: ( function( orig ) { + return function( classNames, speed, easing, callback ) { + return arguments.length > 1 ? + $.effects.animateClass.call( this, + { remove: classNames }, speed, easing, callback ) : + orig.apply( this, arguments ); + }; + } )( $.fn.removeClass ), + + toggleClass: ( function( orig ) { + return function( classNames, force, speed, easing, callback ) { + if ( typeof force === "boolean" || force === undefined ) { + if ( !speed ) { + + // Without speed parameter + return orig.apply( this, arguments ); + } else { + return $.effects.animateClass.call( this, + ( force ? { add: classNames } : { remove: classNames } ), + speed, easing, callback ); + } + } else { + + // Without force parameter + return $.effects.animateClass.call( this, + { toggle: classNames }, force, speed, easing ); + } + }; + } )( $.fn.toggleClass ), + + switchClass: function( remove, add, speed, easing, callback ) { + return $.effects.animateClass.call( this, { + add: add, + remove: remove + }, speed, easing, callback ); + } + } ); + + } )(); + + /******************************************************************************/ + /*********************************** EFFECTS **********************************/ + /******************************************************************************/ + + ( function() { + + if ( $.expr && $.expr.pseudos && $.expr.pseudos.animated ) { + $.expr.pseudos.animated = ( function( orig ) { + return function( elem ) { + return !!$( elem ).data( dataSpaceAnimated ) || orig( elem ); + }; + } )( $.expr.pseudos.animated ); + } + + if ( $.uiBackCompat !== false ) { + $.extend( $.effects, { + + // Saves a set of properties in a data storage + save: function( element, set ) { + var i = 0, length = set.length; + for ( ; i < length; i++ ) { + if ( set[ i ] !== null ) { + element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); + } + } + }, + + // Restores a set of previously saved properties from a data storage + restore: function( element, set ) { + var val, i = 0, length = set.length; + for ( ; i < length; i++ ) { + if ( set[ i ] !== null ) { + val = element.data( dataSpace + set[ i ] ); + element.css( set[ i ], val ); + } + } + }, + + setMode: function( el, mode ) { + if ( mode === "toggle" ) { + mode = el.is( ":hidden" ) ? "show" : "hide"; + } + return mode; + }, + + // Wraps the element around a wrapper that copies position properties + createWrapper: function( element ) { + + // If the element is already wrapped, return it + if ( element.parent().is( ".ui-effects-wrapper" ) ) { + return element.parent(); + } + + // Wrap the element + var props = { + width: element.outerWidth( true ), + height: element.outerHeight( true ), + "float": element.css( "float" ) + }, + wrapper = $( "<div></div>" ) + .addClass( "ui-effects-wrapper" ) + .css( { + fontSize: "100%", + background: "transparent", + border: "none", + margin: 0, + padding: 0 + } ), + + // Store the size in case width/height are defined in % - Fixes #5245 + size = { + width: element.width(), + height: element.height() + }, + active = document.activeElement; + + // Support: Firefox + // Firefox incorrectly exposes anonymous content + // https://bugzilla.mozilla.org/show_bug.cgi?id=561664 + try { + // eslint-disable-next-line no-unused-expressions + active.id; + } catch ( e ) { + active = document.body; + } + + element.wrap( wrapper ); + + // Fixes #7595 - Elements lose focus when wrapped. + if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { + $( active ).trigger( "focus" ); + } + + // Hotfix for jQuery 1.4 since some change in wrap() seems to actually + // lose the reference to the wrapped element + wrapper = element.parent(); + + // Transfer positioning properties to the wrapper + if ( element.css( "position" ) === "static" ) { + wrapper.css( { position: "relative" } ); + element.css( { position: "relative" } ); + } else { + $.extend( props, { + position: element.css( "position" ), + zIndex: element.css( "z-index" ) + } ); + $.each( [ "top", "left", "bottom", "right" ], function( i, pos ) { + props[ pos ] = element.css( pos ); + if ( isNaN( parseInt( props[ pos ], 10 ) ) ) { + props[ pos ] = "auto"; + } + } ); + element.css( { + position: "relative", + top: 0, + left: 0, + right: "auto", + bottom: "auto" + } ); + } + element.css( size ); + + return wrapper.css( props ).show(); + }, + + removeWrapper: function( element ) { + var active = document.activeElement; + + if ( element.parent().is( ".ui-effects-wrapper" ) ) { + element.parent().replaceWith( element ); + + // Fixes #7595 - Elements lose focus when wrapped. + if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { + $( active ).trigger( "focus" ); + } + } + + return element; + } + } ); + } + + $.extend( $.effects, { + version: "1.13.2", + + define: function( name, mode, effect ) { + if ( !effect ) { + effect = mode; + mode = "effect"; + } + + $.effects.effect[ name ] = effect; + $.effects.effect[ name ].mode = mode; + + return effect; + }, + + scaledDimensions: function( element, percent, direction ) { + if ( percent === 0 ) { + return { + height: 0, + width: 0, + outerHeight: 0, + outerWidth: 0 + }; + } + + var x = direction !== "horizontal" ? ( ( percent || 100 ) / 100 ) : 1, + y = direction !== "vertical" ? ( ( percent || 100 ) / 100 ) : 1; + + return { + height: element.height() * y, + width: element.width() * x, + outerHeight: element.outerHeight() * y, + outerWidth: element.outerWidth() * x + }; + + }, + + clipToBox: function( animation ) { + return { + width: animation.clip.right - animation.clip.left, + height: animation.clip.bottom - animation.clip.top, + left: animation.clip.left, + top: animation.clip.top + }; + }, + + // Injects recently queued functions to be first in line (after "inprogress") + unshift: function( element, queueLength, count ) { + var queue = element.queue(); + + if ( queueLength > 1 ) { + queue.splice.apply( queue, + [ 1, 0 ].concat( queue.splice( queueLength, count ) ) ); + } + element.dequeue(); + }, + + saveStyle: function( element ) { + element.data( dataSpaceStyle, element[ 0 ].style.cssText ); + }, + + restoreStyle: function( element ) { + element[ 0 ].style.cssText = element.data( dataSpaceStyle ) || ""; + element.removeData( dataSpaceStyle ); + }, + + mode: function( element, mode ) { + var hidden = element.is( ":hidden" ); + + if ( mode === "toggle" ) { + mode = hidden ? "show" : "hide"; + } + if ( hidden ? mode === "hide" : mode === "show" ) { + mode = "none"; + } + return mode; + }, + + // Translates a [top,left] array into a baseline value + getBaseline: function( origin, original ) { + var y, x; + + switch ( origin[ 0 ] ) { + case "top": + y = 0; + break; + case "middle": + y = 0.5; + break; + case "bottom": + y = 1; + break; + default: + y = origin[ 0 ] / original.height; + } + + switch ( origin[ 1 ] ) { + case "left": + x = 0; + break; + case "center": + x = 0.5; + break; + case "right": + x = 1; + break; + default: + x = origin[ 1 ] / original.width; + } + + return { + x: x, + y: y + }; + }, + + // Creates a placeholder element so that the original element can be made absolute + createPlaceholder: function( element ) { + var placeholder, + cssPosition = element.css( "position" ), + position = element.position(); + + // Lock in margins first to account for form elements, which + // will change margin if you explicitly set height + // see: http://jsfiddle.net/JZSMt/3/ https://bugs.webkit.org/show_bug.cgi?id=107380 + // Support: Safari + element.css( { + marginTop: element.css( "marginTop" ), + marginBottom: element.css( "marginBottom" ), + marginLeft: element.css( "marginLeft" ), + marginRight: element.css( "marginRight" ) + } ) + .outerWidth( element.outerWidth() ) + .outerHeight( element.outerHeight() ); + + if ( /^(static|relative)/.test( cssPosition ) ) { + cssPosition = "absolute"; + + placeholder = $( "<" + element[ 0 ].nodeName + ">" ).insertAfter( element ).css( { + + // Convert inline to inline block to account for inline elements + // that turn to inline block based on content (like img) + display: /^(inline|ruby)/.test( element.css( "display" ) ) ? + "inline-block" : + "block", + visibility: "hidden", + + // Margins need to be set to account for margin collapse + marginTop: element.css( "marginTop" ), + marginBottom: element.css( "marginBottom" ), + marginLeft: element.css( "marginLeft" ), + marginRight: element.css( "marginRight" ), + "float": element.css( "float" ) + } ) + .outerWidth( element.outerWidth() ) + .outerHeight( element.outerHeight() ) + .addClass( "ui-effects-placeholder" ); + + element.data( dataSpace + "placeholder", placeholder ); + } + + element.css( { + position: cssPosition, + left: position.left, + top: position.top + } ); + + return placeholder; + }, + + removePlaceholder: function( element ) { + var dataKey = dataSpace + "placeholder", + placeholder = element.data( dataKey ); + + if ( placeholder ) { + placeholder.remove(); + element.removeData( dataKey ); + } + }, + + // Removes a placeholder if it exists and restores + // properties that were modified during placeholder creation + cleanUp: function( element ) { + $.effects.restoreStyle( element ); + $.effects.removePlaceholder( element ); + }, + + setTransition: function( element, list, factor, value ) { + value = value || {}; + $.each( list, function( i, x ) { + var unit = element.cssUnit( x ); + if ( unit[ 0 ] > 0 ) { + value[ x ] = unit[ 0 ] * factor + unit[ 1 ]; + } + } ); + return value; + } + } ); // Return an effect options object for the given parameters: -function _normalizeArguments( effect, options, speed, callback ) { - - // Allow passing all options as the first parameter - if ( $.isPlainObject( effect ) ) { - options = effect; - effect = effect.effect; - } - - // Convert to an object - effect = { effect: effect }; - - // Catch (effect, null, ...) - if ( options == null ) { - options = {}; - } - - // Catch (effect, callback) - if ( typeof options === "function" ) { - callback = options; - speed = null; - options = {}; - } - - // Catch (effect, speed, ?) - if ( typeof options === "number" || $.fx.speeds[ options ] ) { - callback = speed; - speed = options; - options = {}; - } - - // Catch (effect, options, callback) - if ( typeof speed === "function" ) { - callback = speed; - speed = null; - } - - // Add options to effect - if ( options ) { - $.extend( effect, options ); - } - - speed = speed || options.duration; - effect.duration = $.fx.off ? 0 : - typeof speed === "number" ? speed : - speed in $.fx.speeds ? $.fx.speeds[ speed ] : - $.fx.speeds._default; - - effect.complete = callback || options.complete; - - return effect; -} - -function standardAnimationOption( option ) { - - // Valid standard speeds (nothing, number, named speed) - if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) { - return true; - } - - // Invalid strings - treat as "normal" speed - if ( typeof option === "string" && !$.effects.effect[ option ] ) { - return true; - } - - // Complete callback - if ( typeof option === "function" ) { - return true; - } - - // Options hash (but not naming an effect) - if ( typeof option === "object" && !option.effect ) { - return true; - } - - // Didn't match any standard API - return false; -} - -$.fn.extend( { - effect: function( /* effect, options, speed, callback */ ) { - var args = _normalizeArguments.apply( this, arguments ), - effectMethod = $.effects.effect[ args.effect ], - defaultMode = effectMethod.mode, - queue = args.queue, - queueName = queue || "fx", - complete = args.complete, - mode = args.mode, - modes = [], - prefilter = function( next ) { - var el = $( this ), - normalizedMode = $.effects.mode( el, mode ) || defaultMode; - - // Sentinel for duck-punching the :animated pseudo-selector - el.data( dataSpaceAnimated, true ); - - // Save effect mode for later use, - // we can't just call $.effects.mode again later, - // as the .show() below destroys the initial state - modes.push( normalizedMode ); - - // See $.uiBackCompat inside of run() for removal of defaultMode in 1.14 - if ( defaultMode && ( normalizedMode === "show" || - ( normalizedMode === defaultMode && normalizedMode === "hide" ) ) ) { - el.show(); - } - - if ( !defaultMode || normalizedMode !== "none" ) { - $.effects.saveStyle( el ); - } - - if ( typeof next === "function" ) { - next(); - } - }; - - if ( $.fx.off || !effectMethod ) { - - // Delegate to the original method (e.g., .show()) if possible - if ( mode ) { - return this[ mode ]( args.duration, complete ); - } else { - return this.each( function() { - if ( complete ) { - complete.call( this ); - } - } ); - } - } - - function run( next ) { - var elem = $( this ); - - function cleanup() { - elem.removeData( dataSpaceAnimated ); - - $.effects.cleanUp( elem ); - - if ( args.mode === "hide" ) { - elem.hide(); - } - - done(); - } - - function done() { - if ( typeof complete === "function" ) { - complete.call( elem[ 0 ] ); - } - - if ( typeof next === "function" ) { - next(); - } - } - - // Override mode option on a per element basis, - // as toggle can be either show or hide depending on element state - args.mode = modes.shift(); - - if ( $.uiBackCompat !== false && !defaultMode ) { - if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { - - // Call the core method to track "olddisplay" properly - elem[ mode ](); - done(); - } else { - effectMethod.call( elem[ 0 ], args, done ); - } - } else { - if ( args.mode === "none" ) { - - // Call the core method to track "olddisplay" properly - elem[ mode ](); - done(); - } else { - effectMethod.call( elem[ 0 ], args, cleanup ); - } - } - } - - // Run prefilter on all elements first to ensure that - // any showing or hiding happens before placeholder creation, - // which ensures that any layout changes are correctly captured. - return queue === false ? - this.each( prefilter ).each( run ) : - this.queue( queueName, prefilter ).queue( queueName, run ); - }, - - show: ( function( orig ) { - return function( option ) { - if ( standardAnimationOption( option ) ) { - return orig.apply( this, arguments ); - } else { - var args = _normalizeArguments.apply( this, arguments ); - args.mode = "show"; - return this.effect.call( this, args ); - } - }; - } )( $.fn.show ), - - hide: ( function( orig ) { - return function( option ) { - if ( standardAnimationOption( option ) ) { - return orig.apply( this, arguments ); - } else { - var args = _normalizeArguments.apply( this, arguments ); - args.mode = "hide"; - return this.effect.call( this, args ); - } - }; - } )( $.fn.hide ), - - toggle: ( function( orig ) { - return function( option ) { - if ( standardAnimationOption( option ) || typeof option === "boolean" ) { - return orig.apply( this, arguments ); - } else { - var args = _normalizeArguments.apply( this, arguments ); - args.mode = "toggle"; - return this.effect.call( this, args ); - } - }; - } )( $.fn.toggle ), - - cssUnit: function( key ) { - var style = this.css( key ), - val = []; - - $.each( [ "em", "px", "%", "pt" ], function( i, unit ) { - if ( style.indexOf( unit ) > 0 ) { - val = [ parseFloat( style ), unit ]; - } - } ); - return val; - }, - - cssClip: function( clipObj ) { - if ( clipObj ) { - return this.css( "clip", "rect(" + clipObj.top + "px " + clipObj.right + "px " + - clipObj.bottom + "px " + clipObj.left + "px)" ); - } - return parseClip( this.css( "clip" ), this ); - }, - - transfer: function( options, done ) { - var element = $( this ), - target = $( options.to ), - targetFixed = target.css( "position" ) === "fixed", - body = $( "body" ), - fixTop = targetFixed ? body.scrollTop() : 0, - fixLeft = targetFixed ? body.scrollLeft() : 0, - endPosition = target.offset(), - animation = { - top: endPosition.top - fixTop, - left: endPosition.left - fixLeft, - height: target.innerHeight(), - width: target.innerWidth() - }, - startPosition = element.offset(), - transfer = $( "<div class='ui-effects-transfer'></div>" ); - - transfer - .appendTo( "body" ) - .addClass( options.className ) - .css( { - top: startPosition.top - fixTop, - left: startPosition.left - fixLeft, - height: element.innerHeight(), - width: element.innerWidth(), - position: targetFixed ? "fixed" : "absolute" - } ) - .animate( animation, options.duration, options.easing, function() { - transfer.remove(); - if ( typeof done === "function" ) { - done(); - } - } ); - } -} ); - -function parseClip( str, element ) { - var outerWidth = element.outerWidth(), - outerHeight = element.outerHeight(), - clipRegex = /^rect\((-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto)\)$/, - values = clipRegex.exec( str ) || [ "", 0, outerWidth, outerHeight, 0 ]; - - return { - top: parseFloat( values[ 1 ] ) || 0, - right: values[ 2 ] === "auto" ? outerWidth : parseFloat( values[ 2 ] ), - bottom: values[ 3 ] === "auto" ? outerHeight : parseFloat( values[ 3 ] ), - left: parseFloat( values[ 4 ] ) || 0 - }; -} - -$.fx.step.clip = function( fx ) { - if ( !fx.clipInit ) { - fx.start = $( fx.elem ).cssClip(); - if ( typeof fx.end === "string" ) { - fx.end = parseClip( fx.end, fx.elem ); - } - fx.clipInit = true; - } - - $( fx.elem ).cssClip( { - top: fx.pos * ( fx.end.top - fx.start.top ) + fx.start.top, - right: fx.pos * ( fx.end.right - fx.start.right ) + fx.start.right, - bottom: fx.pos * ( fx.end.bottom - fx.start.bottom ) + fx.start.bottom, - left: fx.pos * ( fx.end.left - fx.start.left ) + fx.start.left - } ); -}; - -} )(); - -/******************************************************************************/ -/*********************************** EASING ***********************************/ -/******************************************************************************/ - -( function() { + function _normalizeArguments( effect, options, speed, callback ) { + + // Allow passing all options as the first parameter + if ( $.isPlainObject( effect ) ) { + options = effect; + effect = effect.effect; + } + + // Convert to an object + effect = { effect: effect }; + + // Catch (effect, null, ...) + if ( options == null ) { + options = {}; + } + + // Catch (effect, callback) + if ( typeof options === "function" ) { + callback = options; + speed = null; + options = {}; + } + + // Catch (effect, speed, ?) + if ( typeof options === "number" || $.fx.speeds[ options ] ) { + callback = speed; + speed = options; + options = {}; + } + + // Catch (effect, options, callback) + if ( typeof speed === "function" ) { + callback = speed; + speed = null; + } + + // Add options to effect + if ( options ) { + $.extend( effect, options ); + } + + speed = speed || options.duration; + effect.duration = $.fx.off ? 0 : + typeof speed === "number" ? speed : + speed in $.fx.speeds ? $.fx.speeds[ speed ] : + $.fx.speeds._default; + + effect.complete = callback || options.complete; + + return effect; + } + + function standardAnimationOption( option ) { + + // Valid standard speeds (nothing, number, named speed) + if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) { + return true; + } + + // Invalid strings - treat as "normal" speed + if ( typeof option === "string" && !$.effects.effect[ option ] ) { + return true; + } + + // Complete callback + if ( typeof option === "function" ) { + return true; + } + + // Options hash (but not naming an effect) + if ( typeof option === "object" && !option.effect ) { + return true; + } + + // Didn't match any standard API + return false; + } + + $.fn.extend( { + effect: function( /* effect, options, speed, callback */ ) { + var args = _normalizeArguments.apply( this, arguments ), + effectMethod = $.effects.effect[ args.effect ], + defaultMode = effectMethod.mode, + queue = args.queue, + queueName = queue || "fx", + complete = args.complete, + mode = args.mode, + modes = [], + prefilter = function( next ) { + var el = $( this ), + normalizedMode = $.effects.mode( el, mode ) || defaultMode; + + // Sentinel for duck-punching the :animated pseudo-selector + el.data( dataSpaceAnimated, true ); + + // Save effect mode for later use, + // we can't just call $.effects.mode again later, + // as the .show() below destroys the initial state + modes.push( normalizedMode ); + + // See $.uiBackCompat inside of run() for removal of defaultMode in 1.14 + if ( defaultMode && ( normalizedMode === "show" || + ( normalizedMode === defaultMode && normalizedMode === "hide" ) ) ) { + el.show(); + } + + if ( !defaultMode || normalizedMode !== "none" ) { + $.effects.saveStyle( el ); + } + + if ( typeof next === "function" ) { + next(); + } + }; + + if ( $.fx.off || !effectMethod ) { + + // Delegate to the original method (e.g., .show()) if possible + if ( mode ) { + return this[ mode ]( args.duration, complete ); + } else { + return this.each( function() { + if ( complete ) { + complete.call( this ); + } + } ); + } + } + + function run( next ) { + var elem = $( this ); + + function cleanup() { + elem.removeData( dataSpaceAnimated ); + + $.effects.cleanUp( elem ); + + if ( args.mode === "hide" ) { + elem.hide(); + } + + done(); + } + + function done() { + if ( typeof complete === "function" ) { + complete.call( elem[ 0 ] ); + } + + if ( typeof next === "function" ) { + next(); + } + } + + // Override mode option on a per element basis, + // as toggle can be either show or hide depending on element state + args.mode = modes.shift(); + + if ( $.uiBackCompat !== false && !defaultMode ) { + if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { + + // Call the core method to track "olddisplay" properly + elem[ mode ](); + done(); + } else { + effectMethod.call( elem[ 0 ], args, done ); + } + } else { + if ( args.mode === "none" ) { + + // Call the core method to track "olddisplay" properly + elem[ mode ](); + done(); + } else { + effectMethod.call( elem[ 0 ], args, cleanup ); + } + } + } + + // Run prefilter on all elements first to ensure that + // any showing or hiding happens before placeholder creation, + // which ensures that any layout changes are correctly captured. + return queue === false ? + this.each( prefilter ).each( run ) : + this.queue( queueName, prefilter ).queue( queueName, run ); + }, + + show: ( function( orig ) { + return function( option ) { + if ( standardAnimationOption( option ) ) { + return orig.apply( this, arguments ); + } else { + var args = _normalizeArguments.apply( this, arguments ); + args.mode = "show"; + return this.effect.call( this, args ); + } + }; + } )( $.fn.show ), + + hide: ( function( orig ) { + return function( option ) { + if ( standardAnimationOption( option ) ) { + return orig.apply( this, arguments ); + } else { + var args = _normalizeArguments.apply( this, arguments ); + args.mode = "hide"; + return this.effect.call( this, args ); + } + }; + } )( $.fn.hide ), + + toggle: ( function( orig ) { + return function( option ) { + if ( standardAnimationOption( option ) || typeof option === "boolean" ) { + return orig.apply( this, arguments ); + } else { + var args = _normalizeArguments.apply( this, arguments ); + args.mode = "toggle"; + return this.effect.call( this, args ); + } + }; + } )( $.fn.toggle ), + + cssUnit: function( key ) { + var style = this.css( key ), + val = []; + + $.each( [ "em", "px", "%", "pt" ], function( i, unit ) { + if ( style.indexOf( unit ) > 0 ) { + val = [ parseFloat( style ), unit ]; + } + } ); + return val; + }, + + cssClip: function( clipObj ) { + if ( clipObj ) { + return this.css( "clip", "rect(" + clipObj.top + "px " + clipObj.right + "px " + + clipObj.bottom + "px " + clipObj.left + "px)" ); + } + return parseClip( this.css( "clip" ), this ); + }, + + transfer: function( options, done ) { + var element = $( this ), + target = $( options.to ), + targetFixed = target.css( "position" ) === "fixed", + body = $( "body" ), + fixTop = targetFixed ? body.scrollTop() : 0, + fixLeft = targetFixed ? body.scrollLeft() : 0, + endPosition = target.offset(), + animation = { + top: endPosition.top - fixTop, + left: endPosition.left - fixLeft, + height: target.innerHeight(), + width: target.innerWidth() + }, + startPosition = element.offset(), + transfer = $( "<div class='ui-effects-transfer'></div>" ); + + transfer + .appendTo( "body" ) + .addClass( options.className ) + .css( { + top: startPosition.top - fixTop, + left: startPosition.left - fixLeft, + height: element.innerHeight(), + width: element.innerWidth(), + position: targetFixed ? "fixed" : "absolute" + } ) + .animate( animation, options.duration, options.easing, function() { + transfer.remove(); + if ( typeof done === "function" ) { + done(); + } + } ); + } + } ); + + function parseClip( str, element ) { + var outerWidth = element.outerWidth(), + outerHeight = element.outerHeight(), + clipRegex = /^rect\((-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto)\)$/, + values = clipRegex.exec( str ) || [ "", 0, outerWidth, outerHeight, 0 ]; + + return { + top: parseFloat( values[ 1 ] ) || 0, + right: values[ 2 ] === "auto" ? outerWidth : parseFloat( values[ 2 ] ), + bottom: values[ 3 ] === "auto" ? outerHeight : parseFloat( values[ 3 ] ), + left: parseFloat( values[ 4 ] ) || 0 + }; + } + + $.fx.step.clip = function( fx ) { + if ( !fx.clipInit ) { + fx.start = $( fx.elem ).cssClip(); + if ( typeof fx.end === "string" ) { + fx.end = parseClip( fx.end, fx.elem ); + } + fx.clipInit = true; + } + + $( fx.elem ).cssClip( { + top: fx.pos * ( fx.end.top - fx.start.top ) + fx.start.top, + right: fx.pos * ( fx.end.right - fx.start.right ) + fx.start.right, + bottom: fx.pos * ( fx.end.bottom - fx.start.bottom ) + fx.start.bottom, + left: fx.pos * ( fx.end.left - fx.start.left ) + fx.start.left + } ); + }; + + } )(); + + /******************************************************************************/ + /*********************************** EASING ***********************************/ + /******************************************************************************/ + + ( function() { // Based on easing equations from Robert Penner (http://www.robertpenner.com/easing) -var baseEasings = {}; - -$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) { - baseEasings[ name ] = function( p ) { - return Math.pow( p, i + 2 ); - }; -} ); - -$.extend( baseEasings, { - Sine: function( p ) { - return 1 - Math.cos( p * Math.PI / 2 ); - }, - Circ: function( p ) { - return 1 - Math.sqrt( 1 - p * p ); - }, - Elastic: function( p ) { - return p === 0 || p === 1 ? p : - -Math.pow( 2, 8 * ( p - 1 ) ) * Math.sin( ( ( p - 1 ) * 80 - 7.5 ) * Math.PI / 15 ); - }, - Back: function( p ) { - return p * p * ( 3 * p - 2 ); - }, - Bounce: function( p ) { - var pow2, - bounce = 4; - - while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {} - return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 ); - } -} ); - -$.each( baseEasings, function( name, easeIn ) { - $.easing[ "easeIn" + name ] = easeIn; - $.easing[ "easeOut" + name ] = function( p ) { - return 1 - easeIn( 1 - p ); - }; - $.easing[ "easeInOut" + name ] = function( p ) { - return p < 0.5 ? - easeIn( p * 2 ) / 2 : - 1 - easeIn( p * -2 + 2 ) / 2; - }; -} ); - -} )(); - -return $.effects; + var baseEasings = {}; + + $.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) { + baseEasings[ name ] = function( p ) { + return Math.pow( p, i + 2 ); + }; + } ); + + $.extend( baseEasings, { + Sine: function( p ) { + return 1 - Math.cos( p * Math.PI / 2 ); + }, + Circ: function( p ) { + return 1 - Math.sqrt( 1 - p * p ); + }, + Elastic: function( p ) { + return p === 0 || p === 1 ? p : + -Math.pow( 2, 8 * ( p - 1 ) ) * Math.sin( ( ( p - 1 ) * 80 - 7.5 ) * Math.PI / 15 ); + }, + Back: function( p ) { + return p * p * ( 3 * p - 2 ); + }, + Bounce: function( p ) { + var pow2, + bounce = 4; + + while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {} + return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 ); + } + } ); + + $.each( baseEasings, function( name, easeIn ) { + $.easing[ "easeIn" + name ] = easeIn; + $.easing[ "easeOut" + name ] = function( p ) { + return 1 - easeIn( 1 - p ); + }; + $.easing[ "easeInOut" + name ] = function( p ) { + return p < 0.5 ? + easeIn( p * 2 ) / 2 : + 1 - easeIn( p * -2 + 2 ) / 2; + }; + } ); + + } )(); + + return $.effects; } ); diff --git a/lib/web/jquery/ui-modules/effects/effect-blind.js b/lib/web/jquery/ui-modules/effects/effect-blind.js index fb682963cf21e..95c1874c574fd 100644 --- a/lib/web/jquery/ui-modules/effects/effect-blind.js +++ b/lib/web/jquery/ui-modules/effects/effect-blind.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Effects Blind 1.13.1 + * jQuery UI Effects Blind 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -14,60 +14,60 @@ //>>demos: http://jqueryui.com/effect/ ( function( factory ) { - "use strict"; + "use strict"; - if ( typeof define === "function" && define.amd ) { + if ( typeof define === "function" && define.amd ) { - // AMD. Register as an anonymous module. - define( [ - "jquery", - "../version", - "../effect" - ], factory ); - } else { + // AMD. Register as an anonymous module. + define( [ + "jquery", + "../version", + "../effect" + ], factory ); + } else { - // Browser globals - factory( jQuery ); - } + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; + "use strict"; -return $.effects.define( "blind", "hide", function( options, done ) { - var map = { - up: [ "bottom", "top" ], - vertical: [ "bottom", "top" ], - down: [ "top", "bottom" ], - left: [ "right", "left" ], - horizontal: [ "right", "left" ], - right: [ "left", "right" ] - }, - element = $( this ), - direction = options.direction || "up", - start = element.cssClip(), - animate = { clip: $.extend( {}, start ) }, - placeholder = $.effects.createPlaceholder( element ); + return $.effects.define( "blind", "hide", function( options, done ) { + var map = { + up: [ "bottom", "top" ], + vertical: [ "bottom", "top" ], + down: [ "top", "bottom" ], + left: [ "right", "left" ], + horizontal: [ "right", "left" ], + right: [ "left", "right" ] + }, + element = $( this ), + direction = options.direction || "up", + start = element.cssClip(), + animate = { clip: $.extend( {}, start ) }, + placeholder = $.effects.createPlaceholder( element ); - animate.clip[ map[ direction ][ 0 ] ] = animate.clip[ map[ direction ][ 1 ] ]; + animate.clip[ map[ direction ][ 0 ] ] = animate.clip[ map[ direction ][ 1 ] ]; - if ( options.mode === "show" ) { - element.cssClip( animate.clip ); - if ( placeholder ) { - placeholder.css( $.effects.clipToBox( animate ) ); - } + if ( options.mode === "show" ) { + element.cssClip( animate.clip ); + if ( placeholder ) { + placeholder.css( $.effects.clipToBox( animate ) ); + } - animate.clip = start; - } + animate.clip = start; + } - if ( placeholder ) { - placeholder.animate( $.effects.clipToBox( animate ), options.duration, options.easing ); - } + if ( placeholder ) { + placeholder.animate( $.effects.clipToBox( animate ), options.duration, options.easing ); + } - element.animate( animate, { - queue: false, - duration: options.duration, - easing: options.easing, - complete: done - } ); -} ); + element.animate( animate, { + queue: false, + duration: options.duration, + easing: options.easing, + complete: done + } ); + } ); } ); diff --git a/lib/web/jquery/ui-modules/effects/effect-bounce.js b/lib/web/jquery/ui-modules/effects/effect-bounce.js index 0ac0e839acf12..af627f1f206f4 100644 --- a/lib/web/jquery/ui-modules/effects/effect-bounce.js +++ b/lib/web/jquery/ui-modules/effects/effect-bounce.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Effects Bounce 1.13.1 + * jQuery UI Effects Bounce 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -14,100 +14,100 @@ //>>demos: http://jqueryui.com/effect/ ( function( factory ) { - "use strict"; + "use strict"; - if ( typeof define === "function" && define.amd ) { + if ( typeof define === "function" && define.amd ) { - // AMD. Register as an anonymous module. - define( [ - "jquery", - "../version", - "../effect" - ], factory ); - } else { + // AMD. Register as an anonymous module. + define( [ + "jquery", + "../version", + "../effect" + ], factory ); + } else { - // Browser globals - factory( jQuery ); - } + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; + "use strict"; -return $.effects.define( "bounce", function( options, done ) { - var upAnim, downAnim, refValue, - element = $( this ), + return $.effects.define( "bounce", function( options, done ) { + var upAnim, downAnim, refValue, + element = $( this ), - // Defaults: - mode = options.mode, - hide = mode === "hide", - show = mode === "show", - direction = options.direction || "up", - distance = options.distance, - times = options.times || 5, + // Defaults: + mode = options.mode, + hide = mode === "hide", + show = mode === "show", + direction = options.direction || "up", + distance = options.distance, + times = options.times || 5, - // Number of internal animations - anims = times * 2 + ( show || hide ? 1 : 0 ), - speed = options.duration / anims, - easing = options.easing, + // Number of internal animations + anims = times * 2 + ( show || hide ? 1 : 0 ), + speed = options.duration / anims, + easing = options.easing, - // Utility: - ref = ( direction === "up" || direction === "down" ) ? "top" : "left", - motion = ( direction === "up" || direction === "left" ), - i = 0, + // Utility: + ref = ( direction === "up" || direction === "down" ) ? "top" : "left", + motion = ( direction === "up" || direction === "left" ), + i = 0, - queuelen = element.queue().length; + queuelen = element.queue().length; - $.effects.createPlaceholder( element ); + $.effects.createPlaceholder( element ); - refValue = element.css( ref ); + refValue = element.css( ref ); - // Default distance for the BIGGEST bounce is the outer Distance / 3 - if ( !distance ) { - distance = element[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3; - } + // Default distance for the BIGGEST bounce is the outer Distance / 3 + if ( !distance ) { + distance = element[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3; + } - if ( show ) { - downAnim = { opacity: 1 }; - downAnim[ ref ] = refValue; + if ( show ) { + downAnim = { opacity: 1 }; + downAnim[ ref ] = refValue; - // If we are showing, force opacity 0 and set the initial position - // then do the "first" animation - element - .css( "opacity", 0 ) - .css( ref, motion ? -distance * 2 : distance * 2 ) - .animate( downAnim, speed, easing ); - } + // If we are showing, force opacity 0 and set the initial position + // then do the "first" animation + element + .css( "opacity", 0 ) + .css( ref, motion ? -distance * 2 : distance * 2 ) + .animate( downAnim, speed, easing ); + } - // Start at the smallest distance if we are hiding - if ( hide ) { - distance = distance / Math.pow( 2, times - 1 ); - } + // Start at the smallest distance if we are hiding + if ( hide ) { + distance = distance / Math.pow( 2, times - 1 ); + } - downAnim = {}; - downAnim[ ref ] = refValue; + downAnim = {}; + downAnim[ ref ] = refValue; - // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here - for ( ; i < times; i++ ) { - upAnim = {}; - upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; + // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here + for ( ; i < times; i++ ) { + upAnim = {}; + upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; - element - .animate( upAnim, speed, easing ) - .animate( downAnim, speed, easing ); + element + .animate( upAnim, speed, easing ) + .animate( downAnim, speed, easing ); - distance = hide ? distance * 2 : distance / 2; - } + distance = hide ? distance * 2 : distance / 2; + } - // Last Bounce when Hiding - if ( hide ) { - upAnim = { opacity: 0 }; - upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; + // Last Bounce when Hiding + if ( hide ) { + upAnim = { opacity: 0 }; + upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; - element.animate( upAnim, speed, easing ); - } + element.animate( upAnim, speed, easing ); + } - element.queue( done ); + element.queue( done ); - $.effects.unshift( element, queuelen, anims + 1 ); -} ); + $.effects.unshift( element, queuelen, anims + 1 ); + } ); } ); diff --git a/lib/web/jquery/ui-modules/effects/effect-clip.js b/lib/web/jquery/ui-modules/effects/effect-clip.js index c8ace468ce0dd..f34f45c4e1e90 100644 --- a/lib/web/jquery/ui-modules/effects/effect-clip.js +++ b/lib/web/jquery/ui-modules/effects/effect-clip.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Effects Clip 1.13.1 + * jQuery UI Effects Clip 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -14,55 +14,55 @@ //>>demos: http://jqueryui.com/effect/ ( function( factory ) { - "use strict"; + "use strict"; - if ( typeof define === "function" && define.amd ) { + if ( typeof define === "function" && define.amd ) { - // AMD. Register as an anonymous module. - define( [ - "jquery", - "../version", - "../effect" - ], factory ); - } else { + // AMD. Register as an anonymous module. + define( [ + "jquery", + "../version", + "../effect" + ], factory ); + } else { - // Browser globals - factory( jQuery ); - } + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; + "use strict"; -return $.effects.define( "clip", "hide", function( options, done ) { - var start, - animate = {}, - element = $( this ), - direction = options.direction || "vertical", - both = direction === "both", - horizontal = both || direction === "horizontal", - vertical = both || direction === "vertical"; + return $.effects.define( "clip", "hide", function( options, done ) { + var start, + animate = {}, + element = $( this ), + direction = options.direction || "vertical", + both = direction === "both", + horizontal = both || direction === "horizontal", + vertical = both || direction === "vertical"; - start = element.cssClip(); - animate.clip = { - top: vertical ? ( start.bottom - start.top ) / 2 : start.top, - right: horizontal ? ( start.right - start.left ) / 2 : start.right, - bottom: vertical ? ( start.bottom - start.top ) / 2 : start.bottom, - left: horizontal ? ( start.right - start.left ) / 2 : start.left - }; + start = element.cssClip(); + animate.clip = { + top: vertical ? ( start.bottom - start.top ) / 2 : start.top, + right: horizontal ? ( start.right - start.left ) / 2 : start.right, + bottom: vertical ? ( start.bottom - start.top ) / 2 : start.bottom, + left: horizontal ? ( start.right - start.left ) / 2 : start.left + }; - $.effects.createPlaceholder( element ); + $.effects.createPlaceholder( element ); - if ( options.mode === "show" ) { - element.cssClip( animate.clip ); - animate.clip = start; - } + if ( options.mode === "show" ) { + element.cssClip( animate.clip ); + animate.clip = start; + } - element.animate( animate, { - queue: false, - duration: options.duration, - easing: options.easing, - complete: done - } ); + element.animate( animate, { + queue: false, + duration: options.duration, + easing: options.easing, + complete: done + } ); -} ); + } ); } ); diff --git a/lib/web/jquery/ui-modules/effects/effect-drop.js b/lib/web/jquery/ui-modules/effects/effect-drop.js index fa891f3f21a3b..f34f45c4e1e90 100644 --- a/lib/web/jquery/ui-modules/effects/effect-drop.js +++ b/lib/web/jquery/ui-modules/effects/effect-drop.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Effects Drop 1.13.1 + * jQuery UI Effects Clip 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -7,66 +7,62 @@ * http://jquery.org/license */ -//>>label: Drop Effect +//>>label: Clip Effect //>>group: Effects -//>>description: Moves an element in one direction and hides it at the same time. -//>>docs: http://api.jqueryui.com/drop-effect/ +//>>description: Clips the element on and off like an old TV. +//>>docs: http://api.jqueryui.com/clip-effect/ //>>demos: http://jqueryui.com/effect/ ( function( factory ) { - "use strict"; + "use strict"; - if ( typeof define === "function" && define.amd ) { + if ( typeof define === "function" && define.amd ) { - // AMD. Register as an anonymous module. - define( [ - "jquery", - "../version", - "../effect" - ], factory ); - } else { + // AMD. Register as an anonymous module. + define( [ + "jquery", + "../version", + "../effect" + ], factory ); + } else { - // Browser globals - factory( jQuery ); - } + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; + "use strict"; -return $.effects.define( "drop", "hide", function( options, done ) { + return $.effects.define( "clip", "hide", function( options, done ) { + var start, + animate = {}, + element = $( this ), + direction = options.direction || "vertical", + both = direction === "both", + horizontal = both || direction === "horizontal", + vertical = both || direction === "vertical"; - var distance, - element = $( this ), - mode = options.mode, - show = mode === "show", - direction = options.direction || "left", - ref = ( direction === "up" || direction === "down" ) ? "top" : "left", - motion = ( direction === "up" || direction === "left" ) ? "-=" : "+=", - oppositeMotion = ( motion === "+=" ) ? "-=" : "+=", - animation = { - opacity: 0 - }; + start = element.cssClip(); + animate.clip = { + top: vertical ? ( start.bottom - start.top ) / 2 : start.top, + right: horizontal ? ( start.right - start.left ) / 2 : start.right, + bottom: vertical ? ( start.bottom - start.top ) / 2 : start.bottom, + left: horizontal ? ( start.right - start.left ) / 2 : start.left + }; - $.effects.createPlaceholder( element ); + $.effects.createPlaceholder( element ); - distance = options.distance || - element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2; + if ( options.mode === "show" ) { + element.cssClip( animate.clip ); + animate.clip = start; + } - animation[ ref ] = motion + distance; + element.animate( animate, { + queue: false, + duration: options.duration, + easing: options.easing, + complete: done + } ); - if ( show ) { - element.css( animation ); - - animation[ ref ] = oppositeMotion + distance; - animation.opacity = 1; - } - - // Animate - element.animate( animation, { - queue: false, - duration: options.duration, - easing: options.easing, - complete: done - } ); -} ); + } ); } ); diff --git a/lib/web/jquery/ui-modules/effects/effect-explode.js b/lib/web/jquery/ui-modules/effects/effect-explode.js index e92a2fe3b47ba..4ce3cd162034b 100644 --- a/lib/web/jquery/ui-modules/effects/effect-explode.js +++ b/lib/web/jquery/ui-modules/effects/effect-explode.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Effects Explode 1.13.1 + * jQuery UI Effects Explode 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -16,99 +16,99 @@ //>>demos: http://jqueryui.com/effect/ ( function( factory ) { - "use strict"; + "use strict"; - if ( typeof define === "function" && define.amd ) { + if ( typeof define === "function" && define.amd ) { - // AMD. Register as an anonymous module. - define( [ - "jquery", - "../version", - "../effect" - ], factory ); - } else { + // AMD. Register as an anonymous module. + define( [ + "jquery", + "../version", + "../effect" + ], factory ); + } else { - // Browser globals - factory( jQuery ); - } + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; - -return $.effects.define( "explode", "hide", function( options, done ) { - - var i, j, left, top, mx, my, - rows = options.pieces ? Math.round( Math.sqrt( options.pieces ) ) : 3, - cells = rows, - element = $( this ), - mode = options.mode, - show = mode === "show", - - // Show and then visibility:hidden the element before calculating offset - offset = element.show().css( "visibility", "hidden" ).offset(), - - // Width and height of a piece - width = Math.ceil( element.outerWidth() / cells ), - height = Math.ceil( element.outerHeight() / rows ), - pieces = []; - - // Children animate complete: - function childComplete() { - pieces.push( this ); - if ( pieces.length === rows * cells ) { - animComplete(); - } - } - - // Clone the element for each row and cell. - for ( i = 0; i < rows; i++ ) { // ===> - top = offset.top + i * height; - my = i - ( rows - 1 ) / 2; - - for ( j = 0; j < cells; j++ ) { // ||| - left = offset.left + j * width; - mx = j - ( cells - 1 ) / 2; - - // Create a clone of the now hidden main element that will be absolute positioned - // within a wrapper div off the -left and -top equal to size of our pieces - element - .clone() - .appendTo( "body" ) - .wrap( "<div></div>" ) - .css( { - position: "absolute", - visibility: "visible", - left: -j * width, - top: -i * height - } ) - - // Select the wrapper - make it overflow: hidden and absolute positioned based on - // where the original was located +left and +top equal to the size of pieces - .parent() - .addClass( "ui-effects-explode" ) - .css( { - position: "absolute", - overflow: "hidden", - width: width, - height: height, - left: left + ( show ? mx * width : 0 ), - top: top + ( show ? my * height : 0 ), - opacity: show ? 0 : 1 - } ) - .animate( { - left: left + ( show ? 0 : mx * width ), - top: top + ( show ? 0 : my * height ), - opacity: show ? 1 : 0 - }, options.duration || 500, options.easing, childComplete ); - } - } - - function animComplete() { - element.css( { - visibility: "visible" - } ); - $( pieces ).remove(); - done(); - } -} ); + "use strict"; + + return $.effects.define( "explode", "hide", function( options, done ) { + + var i, j, left, top, mx, my, + rows = options.pieces ? Math.round( Math.sqrt( options.pieces ) ) : 3, + cells = rows, + element = $( this ), + mode = options.mode, + show = mode === "show", + + // Show and then visibility:hidden the element before calculating offset + offset = element.show().css( "visibility", "hidden" ).offset(), + + // Width and height of a piece + width = Math.ceil( element.outerWidth() / cells ), + height = Math.ceil( element.outerHeight() / rows ), + pieces = []; + + // Children animate complete: + function childComplete() { + pieces.push( this ); + if ( pieces.length === rows * cells ) { + animComplete(); + } + } + + // Clone the element for each row and cell. + for ( i = 0; i < rows; i++ ) { // ===> + top = offset.top + i * height; + my = i - ( rows - 1 ) / 2; + + for ( j = 0; j < cells; j++ ) { // ||| + left = offset.left + j * width; + mx = j - ( cells - 1 ) / 2; + + // Create a clone of the now hidden main element that will be absolute positioned + // within a wrapper div off the -left and -top equal to size of our pieces + element + .clone() + .appendTo( "body" ) + .wrap( "<div></div>" ) + .css( { + position: "absolute", + visibility: "visible", + left: -j * width, + top: -i * height + } ) + + // Select the wrapper - make it overflow: hidden and absolute positioned based on + // where the original was located +left and +top equal to the size of pieces + .parent() + .addClass( "ui-effects-explode" ) + .css( { + position: "absolute", + overflow: "hidden", + width: width, + height: height, + left: left + ( show ? mx * width : 0 ), + top: top + ( show ? my * height : 0 ), + opacity: show ? 0 : 1 + } ) + .animate( { + left: left + ( show ? 0 : mx * width ), + top: top + ( show ? 0 : my * height ), + opacity: show ? 1 : 0 + }, options.duration || 500, options.easing, childComplete ); + } + } + + function animComplete() { + element.css( { + visibility: "visible" + } ); + $( pieces ).remove(); + done(); + } + } ); } ); diff --git a/lib/web/jquery/ui-modules/effects/effect-fade.js b/lib/web/jquery/ui-modules/effects/effect-fade.js index 58ebf88df9913..798baa9d4d9e9 100644 --- a/lib/web/jquery/ui-modules/effects/effect-fade.js +++ b/lib/web/jquery/ui-modules/effects/effect-fade.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Effects Fade 1.13.1 + * jQuery UI Effects Fade 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -14,37 +14,37 @@ //>>demos: http://jqueryui.com/effect/ ( function( factory ) { - "use strict"; + "use strict"; - if ( typeof define === "function" && define.amd ) { + if ( typeof define === "function" && define.amd ) { - // AMD. Register as an anonymous module. - define( [ - "jquery", - "../version", - "../effect" - ], factory ); - } else { + // AMD. Register as an anonymous module. + define( [ + "jquery", + "../version", + "../effect" + ], factory ); + } else { - // Browser globals - factory( jQuery ); - } + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; - -return $.effects.define( "fade", "toggle", function( options, done ) { - var show = options.mode === "show"; - - $( this ) - .css( "opacity", show ? 0 : 1 ) - .animate( { - opacity: show ? 1 : 0 - }, { - queue: false, - duration: options.duration, - easing: options.easing, - complete: done - } ); -} ); + "use strict"; + + return $.effects.define( "fade", "toggle", function( options, done ) { + var show = options.mode === "show"; + + $( this ) + .css( "opacity", show ? 0 : 1 ) + .animate( { + opacity: show ? 1 : 0 + }, { + queue: false, + duration: options.duration, + easing: options.easing, + complete: done + } ); + } ); } ); diff --git a/lib/web/jquery/ui-modules/effects/effect-fold.js b/lib/web/jquery/ui-modules/effects/effect-fold.js index b3243dbeb6855..77a872a7e849d 100644 --- a/lib/web/jquery/ui-modules/effects/effect-fold.js +++ b/lib/web/jquery/ui-modules/effects/effect-fold.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Effects Fold 1.13.1 + * jQuery UI Effects Fold 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -14,79 +14,79 @@ //>>demos: http://jqueryui.com/effect/ ( function( factory ) { - "use strict"; + "use strict"; - if ( typeof define === "function" && define.amd ) { + if ( typeof define === "function" && define.amd ) { - // AMD. Register as an anonymous module. - define( [ - "jquery", - "../version", - "../effect" - ], factory ); - } else { + // AMD. Register as an anonymous module. + define( [ + "jquery", + "../version", + "../effect" + ], factory ); + } else { - // Browser globals - factory( jQuery ); - } + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; - -return $.effects.define( "fold", "hide", function( options, done ) { - - // Create element - var element = $( this ), - mode = options.mode, - show = mode === "show", - hide = mode === "hide", - size = options.size || 15, - percent = /([0-9]+)%/.exec( size ), - horizFirst = !!options.horizFirst, - ref = horizFirst ? [ "right", "bottom" ] : [ "bottom", "right" ], - duration = options.duration / 2, - - placeholder = $.effects.createPlaceholder( element ), - - start = element.cssClip(), - animation1 = { clip: $.extend( {}, start ) }, - animation2 = { clip: $.extend( {}, start ) }, - - distance = [ start[ ref[ 0 ] ], start[ ref[ 1 ] ] ], - - queuelen = element.queue().length; - - if ( percent ) { - size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ]; - } - animation1.clip[ ref[ 0 ] ] = size; - animation2.clip[ ref[ 0 ] ] = size; - animation2.clip[ ref[ 1 ] ] = 0; - - if ( show ) { - element.cssClip( animation2.clip ); - if ( placeholder ) { - placeholder.css( $.effects.clipToBox( animation2 ) ); - } - - animation2.clip = start; - } - - // Animate - element - .queue( function( next ) { - if ( placeholder ) { - placeholder - .animate( $.effects.clipToBox( animation1 ), duration, options.easing ) - .animate( $.effects.clipToBox( animation2 ), duration, options.easing ); - } - - next(); - } ) - .animate( animation1, duration, options.easing ) - .animate( animation2, duration, options.easing ) - .queue( done ); - - $.effects.unshift( element, queuelen, 4 ); -} ); + "use strict"; + + return $.effects.define( "fold", "hide", function( options, done ) { + + // Create element + var element = $( this ), + mode = options.mode, + show = mode === "show", + hide = mode === "hide", + size = options.size || 15, + percent = /([0-9]+)%/.exec( size ), + horizFirst = !!options.horizFirst, + ref = horizFirst ? [ "right", "bottom" ] : [ "bottom", "right" ], + duration = options.duration / 2, + + placeholder = $.effects.createPlaceholder( element ), + + start = element.cssClip(), + animation1 = { clip: $.extend( {}, start ) }, + animation2 = { clip: $.extend( {}, start ) }, + + distance = [ start[ ref[ 0 ] ], start[ ref[ 1 ] ] ], + + queuelen = element.queue().length; + + if ( percent ) { + size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ]; + } + animation1.clip[ ref[ 0 ] ] = size; + animation2.clip[ ref[ 0 ] ] = size; + animation2.clip[ ref[ 1 ] ] = 0; + + if ( show ) { + element.cssClip( animation2.clip ); + if ( placeholder ) { + placeholder.css( $.effects.clipToBox( animation2 ) ); + } + + animation2.clip = start; + } + + // Animate + element + .queue( function( next ) { + if ( placeholder ) { + placeholder + .animate( $.effects.clipToBox( animation1 ), duration, options.easing ) + .animate( $.effects.clipToBox( animation2 ), duration, options.easing ); + } + + next(); + } ) + .animate( animation1, duration, options.easing ) + .animate( animation2, duration, options.easing ) + .queue( done ); + + $.effects.unshift( element, queuelen, 4 ); + } ); } ); diff --git a/lib/web/jquery/ui-modules/effects/effect-highlight.js b/lib/web/jquery/ui-modules/effects/effect-highlight.js index 50a1afa72d585..34838a6b9b715 100644 --- a/lib/web/jquery/ui-modules/effects/effect-highlight.js +++ b/lib/web/jquery/ui-modules/effects/effect-highlight.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Effects Highlight 1.13.1 + * jQuery UI Effects Highlight 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -14,47 +14,47 @@ //>>demos: http://jqueryui.com/effect/ ( function( factory ) { - "use strict"; + "use strict"; - if ( typeof define === "function" && define.amd ) { + if ( typeof define === "function" && define.amd ) { - // AMD. Register as an anonymous module. - define( [ - "jquery", - "../version", - "../effect" - ], factory ); - } else { + // AMD. Register as an anonymous module. + define( [ + "jquery", + "../version", + "../effect" + ], factory ); + } else { - // Browser globals - factory( jQuery ); - } + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; - -return $.effects.define( "highlight", "show", function( options, done ) { - var element = $( this ), - animation = { - backgroundColor: element.css( "backgroundColor" ) - }; - - if ( options.mode === "hide" ) { - animation.opacity = 0; - } - - $.effects.saveStyle( element ); - - element - .css( { - backgroundImage: "none", - backgroundColor: options.color || "#ffff99" - } ) - .animate( animation, { - queue: false, - duration: options.duration, - easing: options.easing, - complete: done - } ); -} ); + "use strict"; + + return $.effects.define( "highlight", "show", function( options, done ) { + var element = $( this ), + animation = { + backgroundColor: element.css( "backgroundColor" ) + }; + + if ( options.mode === "hide" ) { + animation.opacity = 0; + } + + $.effects.saveStyle( element ); + + element + .css( { + backgroundImage: "none", + backgroundColor: options.color || "#ffff99" + } ) + .animate( animation, { + queue: false, + duration: options.duration, + easing: options.easing, + complete: done + } ); + } ); } ); diff --git a/lib/web/jquery/ui-modules/effects/effect-puff.js b/lib/web/jquery/ui-modules/effects/effect-puff.js index d1b9dd9d3da40..ec52765cfc461 100644 --- a/lib/web/jquery/ui-modules/effects/effect-puff.js +++ b/lib/web/jquery/ui-modules/effects/effect-puff.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Effects Puff 1.13.1 + * jQuery UI Effects Puff 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -14,32 +14,32 @@ //>>demos: http://jqueryui.com/effect/ ( function( factory ) { - "use strict"; - - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define( [ - "jquery", - "../version", - "../effect", - "./effect-scale" - ], factory ); - } else { - - // Browser globals - factory( jQuery ); - } + "use strict"; + + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ + "jquery", + "../version", + "../effect", + "./effect-scale" + ], factory ); + } else { + + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; + "use strict"; -return $.effects.define( "puff", "hide", function( options, done ) { - var newOptions = $.extend( true, {}, options, { - fade: true, - percent: parseInt( options.percent, 10 ) || 150 - } ); + return $.effects.define( "puff", "hide", function( options, done ) { + var newOptions = $.extend( true, {}, options, { + fade: true, + percent: parseInt( options.percent, 10 ) || 150 + } ); - $.effects.effect.scale.call( this, newOptions, done ); -} ); + $.effects.effect.scale.call( this, newOptions, done ); + } ); } ); diff --git a/lib/web/jquery/ui-modules/effects/effect-pulsate.js b/lib/web/jquery/ui-modules/effects/effect-pulsate.js index 0b40f1a07b56b..47638e50f3784 100644 --- a/lib/web/jquery/ui-modules/effects/effect-pulsate.js +++ b/lib/web/jquery/ui-modules/effects/effect-pulsate.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Effects Pulsate 1.13.1 + * jQuery UI Effects Pulsate 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -14,54 +14,54 @@ //>>demos: http://jqueryui.com/effect/ ( function( factory ) { - "use strict"; + "use strict"; - if ( typeof define === "function" && define.amd ) { + if ( typeof define === "function" && define.amd ) { - // AMD. Register as an anonymous module. - define( [ - "jquery", - "../version", - "../effect" - ], factory ); - } else { + // AMD. Register as an anonymous module. + define( [ + "jquery", + "../version", + "../effect" + ], factory ); + } else { - // Browser globals - factory( jQuery ); - } + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; + "use strict"; -return $.effects.define( "pulsate", "show", function( options, done ) { - var element = $( this ), - mode = options.mode, - show = mode === "show", - hide = mode === "hide", - showhide = show || hide, + return $.effects.define( "pulsate", "show", function( options, done ) { + var element = $( this ), + mode = options.mode, + show = mode === "show", + hide = mode === "hide", + showhide = show || hide, - // Showing or hiding leaves off the "last" animation - anims = ( ( options.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ), - duration = options.duration / anims, - animateTo = 0, - i = 1, - queuelen = element.queue().length; + // Showing or hiding leaves off the "last" animation + anims = ( ( options.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ), + duration = options.duration / anims, + animateTo = 0, + i = 1, + queuelen = element.queue().length; - if ( show || !element.is( ":visible" ) ) { - element.css( "opacity", 0 ).show(); - animateTo = 1; - } + if ( show || !element.is( ":visible" ) ) { + element.css( "opacity", 0 ).show(); + animateTo = 1; + } - // Anims - 1 opacity "toggles" - for ( ; i < anims; i++ ) { - element.animate( { opacity: animateTo }, duration, options.easing ); - animateTo = 1 - animateTo; - } + // Anims - 1 opacity "toggles" + for ( ; i < anims; i++ ) { + element.animate( { opacity: animateTo }, duration, options.easing ); + animateTo = 1 - animateTo; + } - element.animate( { opacity: animateTo }, duration, options.easing ); + element.animate( { opacity: animateTo }, duration, options.easing ); - element.queue( done ); + element.queue( done ); - $.effects.unshift( element, queuelen, anims + 1 ); -} ); + $.effects.unshift( element, queuelen, anims + 1 ); + } ); } ); diff --git a/lib/web/jquery/ui-modules/effects/effect-scale.js b/lib/web/jquery/ui-modules/effects/effect-scale.js index 1da6358b6ee69..e62f5cf74cece 100644 --- a/lib/web/jquery/ui-modules/effects/effect-scale.js +++ b/lib/web/jquery/ui-modules/effects/effect-scale.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Effects Scale 1.13.1 + * jQuery UI Effects Scale 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -14,46 +14,46 @@ //>>demos: http://jqueryui.com/effect/ ( function( factory ) { - "use strict"; - - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define( [ - "jquery", - "../version", - "../effect", - "./effect-size" - ], factory ); - } else { - - // Browser globals - factory( jQuery ); - } + "use strict"; + + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ + "jquery", + "../version", + "../effect", + "./effect-size" + ], factory ); + } else { + + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; - -return $.effects.define( "scale", function( options, done ) { - - // Create element - var el = $( this ), - mode = options.mode, - percent = parseInt( options.percent, 10 ) || - ( parseInt( options.percent, 10 ) === 0 ? 0 : ( mode !== "effect" ? 0 : 100 ) ), - - newOptions = $.extend( true, { - from: $.effects.scaledDimensions( el ), - to: $.effects.scaledDimensions( el, percent, options.direction || "both" ), - origin: options.origin || [ "middle", "center" ] - }, options ); - - // Fade option to support puff - if ( options.fade ) { - newOptions.from.opacity = 1; - newOptions.to.opacity = 0; - } - - $.effects.effect.size.call( this, newOptions, done ); -} ); + "use strict"; + + return $.effects.define( "scale", function( options, done ) { + + // Create element + var el = $( this ), + mode = options.mode, + percent = parseInt( options.percent, 10 ) || + ( parseInt( options.percent, 10 ) === 0 ? 0 : ( mode !== "effect" ? 0 : 100 ) ), + + newOptions = $.extend( true, { + from: $.effects.scaledDimensions( el ), + to: $.effects.scaledDimensions( el, percent, options.direction || "both" ), + origin: options.origin || [ "middle", "center" ] + }, options ); + + // Fade option to support puff + if ( options.fade ) { + newOptions.from.opacity = 1; + newOptions.to.opacity = 0; + } + + $.effects.effect.size.call( this, newOptions, done ); + } ); } ); diff --git a/lib/web/jquery/ui-modules/effects/effect-shake.js b/lib/web/jquery/ui-modules/effects/effect-shake.js index b37d52c3fc5fa..660ac1e24ef30 100644 --- a/lib/web/jquery/ui-modules/effects/effect-shake.js +++ b/lib/web/jquery/ui-modules/effects/effect-shake.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Effects Shake 1.13.1 + * jQuery UI Effects Shake 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -14,64 +14,64 @@ //>>demos: http://jqueryui.com/effect/ ( function( factory ) { - "use strict"; + "use strict"; - if ( typeof define === "function" && define.amd ) { + if ( typeof define === "function" && define.amd ) { - // AMD. Register as an anonymous module. - define( [ - "jquery", - "../version", - "../effect" - ], factory ); - } else { + // AMD. Register as an anonymous module. + define( [ + "jquery", + "../version", + "../effect" + ], factory ); + } else { - // Browser globals - factory( jQuery ); - } + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; + "use strict"; -return $.effects.define( "shake", function( options, done ) { + return $.effects.define( "shake", function( options, done ) { - var i = 1, - element = $( this ), - direction = options.direction || "left", - distance = options.distance || 20, - times = options.times || 3, - anims = times * 2 + 1, - speed = Math.round( options.duration / anims ), - ref = ( direction === "up" || direction === "down" ) ? "top" : "left", - positiveMotion = ( direction === "up" || direction === "left" ), - animation = {}, - animation1 = {}, - animation2 = {}, + var i = 1, + element = $( this ), + direction = options.direction || "left", + distance = options.distance || 20, + times = options.times || 3, + anims = times * 2 + 1, + speed = Math.round( options.duration / anims ), + ref = ( direction === "up" || direction === "down" ) ? "top" : "left", + positiveMotion = ( direction === "up" || direction === "left" ), + animation = {}, + animation1 = {}, + animation2 = {}, - queuelen = element.queue().length; + queuelen = element.queue().length; - $.effects.createPlaceholder( element ); + $.effects.createPlaceholder( element ); - // Animation - animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance; - animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2; - animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2; + // Animation + animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance; + animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2; + animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2; - // Animate - element.animate( animation, speed, options.easing ); + // Animate + element.animate( animation, speed, options.easing ); - // Shakes - for ( ; i < times; i++ ) { - element - .animate( animation1, speed, options.easing ) - .animate( animation2, speed, options.easing ); - } + // Shakes + for ( ; i < times; i++ ) { + element + .animate( animation1, speed, options.easing ) + .animate( animation2, speed, options.easing ); + } - element - .animate( animation1, speed, options.easing ) - .animate( animation, speed / 2, options.easing ) - .queue( done ); + element + .animate( animation1, speed, options.easing ) + .animate( animation, speed / 2, options.easing ) + .queue( done ); - $.effects.unshift( element, queuelen, anims + 1 ); -} ); + $.effects.unshift( element, queuelen, anims + 1 ); + } ); } ); diff --git a/lib/web/jquery/ui-modules/effects/effect-size.js b/lib/web/jquery/ui-modules/effects/effect-size.js index df6da07d10452..a531c8401120d 100644 --- a/lib/web/jquery/ui-modules/effects/effect-size.js +++ b/lib/web/jquery/ui-modules/effects/effect-size.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Effects Size 1.13.1 + * jQuery UI Effects Size 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -14,183 +14,183 @@ //>>demos: http://jqueryui.com/effect/ ( function( factory ) { - "use strict"; + "use strict"; - if ( typeof define === "function" && define.amd ) { + if ( typeof define === "function" && define.amd ) { - // AMD. Register as an anonymous module. - define( [ - "jquery", - "../version", - "../effect" - ], factory ); - } else { + // AMD. Register as an anonymous module. + define( [ + "jquery", + "../version", + "../effect" + ], factory ); + } else { - // Browser globals - factory( jQuery ); - } + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; - -return $.effects.define( "size", function( options, done ) { - - // Create element - var baseline, factor, temp, - element = $( this ), - - // Copy for children - cProps = [ "fontSize" ], - vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ], - hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ], - - // Set options - mode = options.mode, - restore = mode !== "effect", - scale = options.scale || "both", - origin = options.origin || [ "middle", "center" ], - position = element.css( "position" ), - pos = element.position(), - original = $.effects.scaledDimensions( element ), - from = options.from || original, - to = options.to || $.effects.scaledDimensions( element, 0 ); - - $.effects.createPlaceholder( element ); - - if ( mode === "show" ) { - temp = from; - from = to; - to = temp; - } - - // Set scaling factor - factor = { - from: { - y: from.height / original.height, - x: from.width / original.width - }, - to: { - y: to.height / original.height, - x: to.width / original.width - } - }; - - // Scale the css box - if ( scale === "box" || scale === "both" ) { - - // Vertical props scaling - if ( factor.from.y !== factor.to.y ) { - from = $.effects.setTransition( element, vProps, factor.from.y, from ); - to = $.effects.setTransition( element, vProps, factor.to.y, to ); - } - - // Horizontal props scaling - if ( factor.from.x !== factor.to.x ) { - from = $.effects.setTransition( element, hProps, factor.from.x, from ); - to = $.effects.setTransition( element, hProps, factor.to.x, to ); - } - } - - // Scale the content - if ( scale === "content" || scale === "both" ) { - - // Vertical props scaling - if ( factor.from.y !== factor.to.y ) { - from = $.effects.setTransition( element, cProps, factor.from.y, from ); - to = $.effects.setTransition( element, cProps, factor.to.y, to ); - } - } - - // Adjust the position properties based on the provided origin points - if ( origin ) { - baseline = $.effects.getBaseline( origin, original ); - from.top = ( original.outerHeight - from.outerHeight ) * baseline.y + pos.top; - from.left = ( original.outerWidth - from.outerWidth ) * baseline.x + pos.left; - to.top = ( original.outerHeight - to.outerHeight ) * baseline.y + pos.top; - to.left = ( original.outerWidth - to.outerWidth ) * baseline.x + pos.left; - } - delete from.outerHeight; - delete from.outerWidth; - element.css( from ); - - // Animate the children if desired - if ( scale === "content" || scale === "both" ) { - - vProps = vProps.concat( [ "marginTop", "marginBottom" ] ).concat( cProps ); - hProps = hProps.concat( [ "marginLeft", "marginRight" ] ); - - // Only animate children with width attributes specified - // TODO: is this right? should we include anything with css width specified as well - element.find( "*[width]" ).each( function() { - var child = $( this ), - childOriginal = $.effects.scaledDimensions( child ), - childFrom = { - height: childOriginal.height * factor.from.y, - width: childOriginal.width * factor.from.x, - outerHeight: childOriginal.outerHeight * factor.from.y, - outerWidth: childOriginal.outerWidth * factor.from.x - }, - childTo = { - height: childOriginal.height * factor.to.y, - width: childOriginal.width * factor.to.x, - outerHeight: childOriginal.height * factor.to.y, - outerWidth: childOriginal.width * factor.to.x - }; - - // Vertical props scaling - if ( factor.from.y !== factor.to.y ) { - childFrom = $.effects.setTransition( child, vProps, factor.from.y, childFrom ); - childTo = $.effects.setTransition( child, vProps, factor.to.y, childTo ); - } - - // Horizontal props scaling - if ( factor.from.x !== factor.to.x ) { - childFrom = $.effects.setTransition( child, hProps, factor.from.x, childFrom ); - childTo = $.effects.setTransition( child, hProps, factor.to.x, childTo ); - } - - if ( restore ) { - $.effects.saveStyle( child ); - } - - // Animate children - child.css( childFrom ); - child.animate( childTo, options.duration, options.easing, function() { - - // Restore children - if ( restore ) { - $.effects.restoreStyle( child ); - } - } ); - } ); - } - - // Animate - element.animate( to, { - queue: false, - duration: options.duration, - easing: options.easing, - complete: function() { - - var offset = element.offset(); - - if ( to.opacity === 0 ) { - element.css( "opacity", from.opacity ); - } - - if ( !restore ) { - element - .css( "position", position === "static" ? "relative" : position ) - .offset( offset ); - - // Need to save style here so that automatic style restoration - // doesn't restore to the original styles from before the animation. - $.effects.saveStyle( element ); - } - - done(); - } - } ); - -} ); + "use strict"; + + return $.effects.define( "size", function( options, done ) { + + // Create element + var baseline, factor, temp, + element = $( this ), + + // Copy for children + cProps = [ "fontSize" ], + vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ], + hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ], + + // Set options + mode = options.mode, + restore = mode !== "effect", + scale = options.scale || "both", + origin = options.origin || [ "middle", "center" ], + position = element.css( "position" ), + pos = element.position(), + original = $.effects.scaledDimensions( element ), + from = options.from || original, + to = options.to || $.effects.scaledDimensions( element, 0 ); + + $.effects.createPlaceholder( element ); + + if ( mode === "show" ) { + temp = from; + from = to; + to = temp; + } + + // Set scaling factor + factor = { + from: { + y: from.height / original.height, + x: from.width / original.width + }, + to: { + y: to.height / original.height, + x: to.width / original.width + } + }; + + // Scale the css box + if ( scale === "box" || scale === "both" ) { + + // Vertical props scaling + if ( factor.from.y !== factor.to.y ) { + from = $.effects.setTransition( element, vProps, factor.from.y, from ); + to = $.effects.setTransition( element, vProps, factor.to.y, to ); + } + + // Horizontal props scaling + if ( factor.from.x !== factor.to.x ) { + from = $.effects.setTransition( element, hProps, factor.from.x, from ); + to = $.effects.setTransition( element, hProps, factor.to.x, to ); + } + } + + // Scale the content + if ( scale === "content" || scale === "both" ) { + + // Vertical props scaling + if ( factor.from.y !== factor.to.y ) { + from = $.effects.setTransition( element, cProps, factor.from.y, from ); + to = $.effects.setTransition( element, cProps, factor.to.y, to ); + } + } + + // Adjust the position properties based on the provided origin points + if ( origin ) { + baseline = $.effects.getBaseline( origin, original ); + from.top = ( original.outerHeight - from.outerHeight ) * baseline.y + pos.top; + from.left = ( original.outerWidth - from.outerWidth ) * baseline.x + pos.left; + to.top = ( original.outerHeight - to.outerHeight ) * baseline.y + pos.top; + to.left = ( original.outerWidth - to.outerWidth ) * baseline.x + pos.left; + } + delete from.outerHeight; + delete from.outerWidth; + element.css( from ); + + // Animate the children if desired + if ( scale === "content" || scale === "both" ) { + + vProps = vProps.concat( [ "marginTop", "marginBottom" ] ).concat( cProps ); + hProps = hProps.concat( [ "marginLeft", "marginRight" ] ); + + // Only animate children with width attributes specified + // TODO: is this right? should we include anything with css width specified as well + element.find( "*[width]" ).each( function() { + var child = $( this ), + childOriginal = $.effects.scaledDimensions( child ), + childFrom = { + height: childOriginal.height * factor.from.y, + width: childOriginal.width * factor.from.x, + outerHeight: childOriginal.outerHeight * factor.from.y, + outerWidth: childOriginal.outerWidth * factor.from.x + }, + childTo = { + height: childOriginal.height * factor.to.y, + width: childOriginal.width * factor.to.x, + outerHeight: childOriginal.height * factor.to.y, + outerWidth: childOriginal.width * factor.to.x + }; + + // Vertical props scaling + if ( factor.from.y !== factor.to.y ) { + childFrom = $.effects.setTransition( child, vProps, factor.from.y, childFrom ); + childTo = $.effects.setTransition( child, vProps, factor.to.y, childTo ); + } + + // Horizontal props scaling + if ( factor.from.x !== factor.to.x ) { + childFrom = $.effects.setTransition( child, hProps, factor.from.x, childFrom ); + childTo = $.effects.setTransition( child, hProps, factor.to.x, childTo ); + } + + if ( restore ) { + $.effects.saveStyle( child ); + } + + // Animate children + child.css( childFrom ); + child.animate( childTo, options.duration, options.easing, function() { + + // Restore children + if ( restore ) { + $.effects.restoreStyle( child ); + } + } ); + } ); + } + + // Animate + element.animate( to, { + queue: false, + duration: options.duration, + easing: options.easing, + complete: function() { + + var offset = element.offset(); + + if ( to.opacity === 0 ) { + element.css( "opacity", from.opacity ); + } + + if ( !restore ) { + element + .css( "position", position === "static" ? "relative" : position ) + .offset( offset ); + + // Need to save style here so that automatic style restoration + // doesn't restore to the original styles from before the animation. + $.effects.saveStyle( element ); + } + + done(); + } + } ); + + } ); } ); diff --git a/lib/web/jquery/ui-modules/effects/effect-slide.js b/lib/web/jquery/ui-modules/effects/effect-slide.js index 7d93ac31c2d93..78b7f59b803bb 100644 --- a/lib/web/jquery/ui-modules/effects/effect-slide.js +++ b/lib/web/jquery/ui-modules/effects/effect-slide.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Effects Slide 1.13.1 + * jQuery UI Effects Slide 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -14,66 +14,66 @@ //>>demos: http://jqueryui.com/effect/ ( function( factory ) { - "use strict"; + "use strict"; - if ( typeof define === "function" && define.amd ) { + if ( typeof define === "function" && define.amd ) { - // AMD. Register as an anonymous module. - define( [ - "jquery", - "../version", - "../effect" - ], factory ); - } else { + // AMD. Register as an anonymous module. + define( [ + "jquery", + "../version", + "../effect" + ], factory ); + } else { - // Browser globals - factory( jQuery ); - } + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; + "use strict"; -return $.effects.define( "slide", "show", function( options, done ) { - var startClip, startRef, - element = $( this ), - map = { - up: [ "bottom", "top" ], - down: [ "top", "bottom" ], - left: [ "right", "left" ], - right: [ "left", "right" ] - }, - mode = options.mode, - direction = options.direction || "left", - ref = ( direction === "up" || direction === "down" ) ? "top" : "left", - positiveMotion = ( direction === "up" || direction === "left" ), - distance = options.distance || - element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ), - animation = {}; + return $.effects.define( "slide", "show", function( options, done ) { + var startClip, startRef, + element = $( this ), + map = { + up: [ "bottom", "top" ], + down: [ "top", "bottom" ], + left: [ "right", "left" ], + right: [ "left", "right" ] + }, + mode = options.mode, + direction = options.direction || "left", + ref = ( direction === "up" || direction === "down" ) ? "top" : "left", + positiveMotion = ( direction === "up" || direction === "left" ), + distance = options.distance || + element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ), + animation = {}; - $.effects.createPlaceholder( element ); + $.effects.createPlaceholder( element ); - startClip = element.cssClip(); - startRef = element.position()[ ref ]; + startClip = element.cssClip(); + startRef = element.position()[ ref ]; - // Define hide animation - animation[ ref ] = ( positiveMotion ? -1 : 1 ) * distance + startRef; - animation.clip = element.cssClip(); - animation.clip[ map[ direction ][ 1 ] ] = animation.clip[ map[ direction ][ 0 ] ]; + // Define hide animation + animation[ ref ] = ( positiveMotion ? -1 : 1 ) * distance + startRef; + animation.clip = element.cssClip(); + animation.clip[ map[ direction ][ 1 ] ] = animation.clip[ map[ direction ][ 0 ] ]; - // Reverse the animation if we're showing - if ( mode === "show" ) { - element.cssClip( animation.clip ); - element.css( ref, animation[ ref ] ); - animation.clip = startClip; - animation[ ref ] = startRef; - } + // Reverse the animation if we're showing + if ( mode === "show" ) { + element.cssClip( animation.clip ); + element.css( ref, animation[ ref ] ); + animation.clip = startClip; + animation[ ref ] = startRef; + } - // Actually animate - element.animate( animation, { - queue: false, - duration: options.duration, - easing: options.easing, - complete: done - } ); -} ); + // Actually animate + element.animate( animation, { + queue: false, + duration: options.duration, + easing: options.easing, + complete: done + } ); + } ); } ); diff --git a/lib/web/jquery/ui-modules/effects/effect-transfer.js b/lib/web/jquery/ui-modules/effects/effect-transfer.js index 160848adaa57c..23c95996f325d 100644 --- a/lib/web/jquery/ui-modules/effects/effect-transfer.js +++ b/lib/web/jquery/ui-modules/effects/effect-transfer.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Effects Transfer 1.13.1 + * jQuery UI Effects Transfer 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -14,30 +14,30 @@ //>>demos: http://jqueryui.com/effect/ ( function( factory ) { - "use strict"; + "use strict"; - if ( typeof define === "function" && define.amd ) { + if ( typeof define === "function" && define.amd ) { - // AMD. Register as an anonymous module. - define( [ - "jquery", - "../version", - "../effect" - ], factory ); - } else { + // AMD. Register as an anonymous module. + define( [ + "jquery", + "../version", + "../effect" + ], factory ); + } else { - // Browser globals - factory( jQuery ); - } + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; + "use strict"; -var effect; -if ( $.uiBackCompat !== false ) { - effect = $.effects.define( "transfer", function( options, done ) { - $( this ).transfer( options, done ); - } ); -} -return effect; + var effect; + if ( $.uiBackCompat !== false ) { + effect = $.effects.define( "transfer", function( options, done ) { + $( this ).transfer( options, done ); + } ); + } + return effect; } ); diff --git a/lib/web/jquery/ui-modules/focusable.js b/lib/web/jquery/ui-modules/focusable.js index 9ed3f85c98a5c..528929318f28a 100644 --- a/lib/web/jquery/ui-modules/focusable.js +++ b/lib/web/jquery/ui-modules/focusable.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Focusable 1.13.1 + * jQuery UI Focusable 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -13,75 +13,75 @@ //>>docs: http://api.jqueryui.com/focusable-selector/ ( function( factory ) { - "use strict"; + "use strict"; - if ( typeof define === "function" && define.amd ) { + if ( typeof define === "function" && define.amd ) { - // AMD. Register as an anonymous module. - define( [ "jquery", "./version" ], factory ); - } else { + // AMD. Register as an anonymous module. + define( [ "jquery", "./version" ], factory ); + } else { - // Browser globals - factory( jQuery ); - } + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; + "use strict"; // Selectors -$.ui.focusable = function( element, hasTabindex ) { - var map, mapName, img, focusableIfVisible, fieldset, - nodeName = element.nodeName.toLowerCase(); + $.ui.focusable = function( element, hasTabindex ) { + var map, mapName, img, focusableIfVisible, fieldset, + nodeName = element.nodeName.toLowerCase(); - if ( "area" === nodeName ) { - map = element.parentNode; - mapName = map.name; - if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { - return false; - } - img = $( "img[usemap='#" + mapName + "']" ); - return img.length > 0 && img.is( ":visible" ); - } + if ( "area" === nodeName ) { + map = element.parentNode; + mapName = map.name; + if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { + return false; + } + img = $( "img[usemap='#" + mapName + "']" ); + return img.length > 0 && img.is( ":visible" ); + } - if ( /^(input|select|textarea|button|object)$/.test( nodeName ) ) { - focusableIfVisible = !element.disabled; + if ( /^(input|select|textarea|button|object)$/.test( nodeName ) ) { + focusableIfVisible = !element.disabled; - if ( focusableIfVisible ) { + if ( focusableIfVisible ) { - // Form controls within a disabled fieldset are disabled. - // However, controls within the fieldset's legend do not get disabled. - // Since controls generally aren't placed inside legends, we skip - // this portion of the check. - fieldset = $( element ).closest( "fieldset" )[ 0 ]; - if ( fieldset ) { - focusableIfVisible = !fieldset.disabled; - } - } - } else if ( "a" === nodeName ) { - focusableIfVisible = element.href || hasTabindex; - } else { - focusableIfVisible = hasTabindex; - } + // Form controls within a disabled fieldset are disabled. + // However, controls within the fieldset's legend do not get disabled. + // Since controls generally aren't placed inside legends, we skip + // this portion of the check. + fieldset = $( element ).closest( "fieldset" )[ 0 ]; + if ( fieldset ) { + focusableIfVisible = !fieldset.disabled; + } + } + } else if ( "a" === nodeName ) { + focusableIfVisible = element.href || hasTabindex; + } else { + focusableIfVisible = hasTabindex; + } - return focusableIfVisible && $( element ).is( ":visible" ) && visible( $( element ) ); -}; + return focusableIfVisible && $( element ).is( ":visible" ) && visible( $( element ) ); + }; // Support: IE 8 only // IE 8 doesn't resolve inherit to visible/hidden for computed values -function visible( element ) { - var visibility = element.css( "visibility" ); - while ( visibility === "inherit" ) { - element = element.parent(); - visibility = element.css( "visibility" ); - } - return visibility === "visible"; -} + function visible( element ) { + var visibility = element.css( "visibility" ); + while ( visibility === "inherit" ) { + element = element.parent(); + visibility = element.css( "visibility" ); + } + return visibility === "visible"; + } -$.extend( $.expr.pseudos, { - focusable: function( element ) { - return $.ui.focusable( element, $.attr( element, "tabindex" ) != null ); - } -} ); + $.extend( $.expr.pseudos, { + focusable: function( element ) { + return $.ui.focusable( element, $.attr( element, "tabindex" ) != null ); + } + } ); -return $.ui.focusable; + return $.ui.focusable; } ); diff --git a/lib/web/jquery/ui-modules/form-reset-mixin.js b/lib/web/jquery/ui-modules/form-reset-mixin.js index 590a6c5ee697b..23a35ccbddcf9 100644 --- a/lib/web/jquery/ui-modules/form-reset-mixin.js +++ b/lib/web/jquery/ui-modules/form-reset-mixin.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Form Reset Mixin 1.13.1 + * jQuery UI Form Reset Mixin 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -13,68 +13,68 @@ //>>docs: http://api.jqueryui.com/form-reset-mixin/ ( function( factory ) { - "use strict"; + "use strict"; - if ( typeof define === "function" && define.amd ) { + if ( typeof define === "function" && define.amd ) { - // AMD. Register as an anonymous module. - define( [ - "jquery", - "./form", - "./version" - ], factory ); - } else { + // AMD. Register as an anonymous module. + define( [ + "jquery", + "./form", + "./version" + ], factory ); + } else { - // Browser globals - factory( jQuery ); - } + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; + "use strict"; -return $.ui.formResetMixin = { - _formResetHandler: function() { - var form = $( this ); + return $.ui.formResetMixin = { + _formResetHandler: function() { + var form = $( this ); - // Wait for the form reset to actually happen before refreshing - setTimeout( function() { - var instances = form.data( "ui-form-reset-instances" ); - $.each( instances, function() { - this.refresh(); - } ); - } ); - }, + // Wait for the form reset to actually happen before refreshing + setTimeout( function() { + var instances = form.data( "ui-form-reset-instances" ); + $.each( instances, function() { + this.refresh(); + } ); + } ); + }, - _bindFormResetHandler: function() { - this.form = this.element._form(); - if ( !this.form.length ) { - return; - } + _bindFormResetHandler: function() { + this.form = this.element._form(); + if ( !this.form.length ) { + return; + } - var instances = this.form.data( "ui-form-reset-instances" ) || []; - if ( !instances.length ) { + var instances = this.form.data( "ui-form-reset-instances" ) || []; + if ( !instances.length ) { - // We don't use _on() here because we use a single event handler per form - this.form.on( "reset.ui-form-reset", this._formResetHandler ); - } - instances.push( this ); - this.form.data( "ui-form-reset-instances", instances ); - }, + // We don't use _on() here because we use a single event handler per form + this.form.on( "reset.ui-form-reset", this._formResetHandler ); + } + instances.push( this ); + this.form.data( "ui-form-reset-instances", instances ); + }, - _unbindFormResetHandler: function() { - if ( !this.form.length ) { - return; - } + _unbindFormResetHandler: function() { + if ( !this.form.length ) { + return; + } - var instances = this.form.data( "ui-form-reset-instances" ); - instances.splice( $.inArray( this, instances ), 1 ); - if ( instances.length ) { - this.form.data( "ui-form-reset-instances", instances ); - } else { - this.form - .removeData( "ui-form-reset-instances" ) - .off( "reset.ui-form-reset" ); - } - } -}; + var instances = this.form.data( "ui-form-reset-instances" ); + instances.splice( $.inArray( this, instances ), 1 ); + if ( instances.length ) { + this.form.data( "ui-form-reset-instances", instances ); + } else { + this.form + .removeData( "ui-form-reset-instances" ) + .off( "reset.ui-form-reset" ); + } + } + }; } ); diff --git a/lib/web/jquery/ui-modules/jquery-patch.js b/lib/web/jquery/ui-modules/jquery-patch.js index 8362c3bdb36b4..dca38cd29e5c4 100644 --- a/lib/web/jquery/ui-modules/jquery-patch.js +++ b/lib/web/jquery/ui-modules/jquery-patch.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Support for jQuery core 1.8.x and newer 1.13.1 + * jQuery UI Support for jQuery core 1.8.x and newer 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -13,77 +13,77 @@ //>>description: Support version 1.8.x and newer of jQuery core ( function( factory ) { -"use strict"; + "use strict"; - if ( typeof define === "function" && define.amd ) { + if ( typeof define === "function" && define.amd ) { - // AMD. Register as an anonymous module. - define( [ "jquery", "./version" ], factory ); - } else { + // AMD. Register as an anonymous module. + define( [ "jquery", "./version" ], factory ); + } else { - // Browser globals - factory( jQuery ); - } + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; + "use strict"; // Support: jQuery 1.9.x or older // $.expr[ ":" ] is deprecated. -if ( !$.expr.pseudos ) { - $.expr.pseudos = $.expr[ ":" ]; -} + if ( !$.expr.pseudos ) { + $.expr.pseudos = $.expr[ ":" ]; + } // Support: jQuery 1.11.x or older // $.unique has been renamed to $.uniqueSort -if ( !$.uniqueSort ) { - $.uniqueSort = $.unique; -} + if ( !$.uniqueSort ) { + $.uniqueSort = $.unique; + } // Support: jQuery 2.2.x or older. // This method has been defined in jQuery 3.0.0. // Code from https://github.com/jquery/jquery/blob/e539bac79e666bba95bba86d690b4e609dca2286/src/selector/escapeSelector.js -if ( !$.escapeSelector ) { + if ( !$.escapeSelector ) { - // CSS string/identifier serialization - // https://drafts.csswg.org/cssom/#common-serializing-idioms - var rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g; + // CSS string/identifier serialization + // https://drafts.csswg.org/cssom/#common-serializing-idioms + var rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g; - var fcssescape = function( ch, asCodePoint ) { - if ( asCodePoint ) { + var fcssescape = function( ch, asCodePoint ) { + if ( asCodePoint ) { - // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER - if ( ch === "\0" ) { - return "\uFFFD"; - } + // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER + if ( ch === "\0" ) { + return "\uFFFD"; + } - // Control characters and (dependent upon position) numbers get escaped as code points - return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; - } + // Control characters and (dependent upon position) numbers get escaped as code points + return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; + } - // Other potentially-special ASCII characters get backslash-escaped - return "\\" + ch; - }; + // Other potentially-special ASCII characters get backslash-escaped + return "\\" + ch; + }; - $.escapeSelector = function( sel ) { - return ( sel + "" ).replace( rcssescape, fcssescape ); - }; -} + $.escapeSelector = function( sel ) { + return ( sel + "" ).replace( rcssescape, fcssescape ); + }; + } // Support: jQuery 3.4.x or older // These methods have been defined in jQuery 3.5.0. -if ( !$.fn.even || !$.fn.odd ) { - $.fn.extend( { - even: function() { - return this.filter( function( i ) { - return i % 2 === 0; - } ); - }, - odd: function() { - return this.filter( function( i ) { - return i % 2 === 1; - } ); - } - } ); -} + if ( !$.fn.even || !$.fn.odd ) { + $.fn.extend( { + even: function() { + return this.filter( function( i ) { + return i % 2 === 0; + } ); + }, + odd: function() { + return this.filter( function( i ) { + return i % 2 === 1; + } ); + } + } ); + } } ); diff --git a/lib/web/jquery/ui-modules/keycode.js b/lib/web/jquery/ui-modules/keycode.js index 989563f3394d9..53ae009bb06b8 100644 --- a/lib/web/jquery/ui-modules/keycode.js +++ b/lib/web/jquery/ui-modules/keycode.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Keycode 1.13.1 + * jQuery UI Keycode 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -13,37 +13,37 @@ //>>docs: http://api.jqueryui.com/jQuery.ui.keyCode/ ( function( factory ) { - "use strict"; + "use strict"; - if ( typeof define === "function" && define.amd ) { + if ( typeof define === "function" && define.amd ) { - // AMD. Register as an anonymous module. - define( [ "jquery", "./version" ], factory ); - } else { + // AMD. Register as an anonymous module. + define( [ "jquery", "./version" ], factory ); + } else { - // Browser globals - factory( jQuery ); - } + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; + "use strict"; -return $.ui.keyCode = { - BACKSPACE: 8, - COMMA: 188, - DELETE: 46, - DOWN: 40, - END: 35, - ENTER: 13, - ESCAPE: 27, - HOME: 36, - LEFT: 37, - PAGE_DOWN: 34, - PAGE_UP: 33, - PERIOD: 190, - RIGHT: 39, - SPACE: 32, - TAB: 9, - UP: 38 -}; + return $.ui.keyCode = { + BACKSPACE: 8, + COMMA: 188, + DELETE: 46, + DOWN: 40, + END: 35, + ENTER: 13, + ESCAPE: 27, + HOME: 36, + LEFT: 37, + PAGE_DOWN: 34, + PAGE_UP: 33, + PERIOD: 190, + RIGHT: 39, + SPACE: 32, + TAB: 9, + UP: 38 + }; } ); diff --git a/lib/web/jquery/ui-modules/labels.js b/lib/web/jquery/ui-modules/labels.js index b2cc01543de06..b45e273a8b8fe 100644 --- a/lib/web/jquery/ui-modules/labels.js +++ b/lib/web/jquery/ui-modules/labels.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Labels 1.13.1 + * jQuery UI Labels 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -13,57 +13,57 @@ //>>docs: http://api.jqueryui.com/labels/ ( function( factory ) { - "use strict"; + "use strict"; - if ( typeof define === "function" && define.amd ) { + if ( typeof define === "function" && define.amd ) { - // AMD. Register as an anonymous module. - define( [ "jquery", "./version" ], factory ); - } else { + // AMD. Register as an anonymous module. + define( [ "jquery", "./version" ], factory ); + } else { - // Browser globals - factory( jQuery ); - } + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; + "use strict"; -return $.fn.labels = function() { - var ancestor, selector, id, labels, ancestors; + return $.fn.labels = function() { + var ancestor, selector, id, labels, ancestors; - if ( !this.length ) { - return this.pushStack( [] ); - } + if ( !this.length ) { + return this.pushStack( [] ); + } - // Check control.labels first - if ( this[ 0 ].labels && this[ 0 ].labels.length ) { - return this.pushStack( this[ 0 ].labels ); - } + // Check control.labels first + if ( this[ 0 ].labels && this[ 0 ].labels.length ) { + return this.pushStack( this[ 0 ].labels ); + } - // Support: IE <= 11, FF <= 37, Android <= 2.3 only - // Above browsers do not support control.labels. Everything below is to support them - // as well as document fragments. control.labels does not work on document fragments - labels = this.eq( 0 ).parents( "label" ); + // Support: IE <= 11, FF <= 37, Android <= 2.3 only + // Above browsers do not support control.labels. Everything below is to support them + // as well as document fragments. control.labels does not work on document fragments + labels = this.eq( 0 ).parents( "label" ); - // Look for the label based on the id - id = this.attr( "id" ); - if ( id ) { + // Look for the label based on the id + id = this.attr( "id" ); + if ( id ) { - // We don't search against the document in case the element - // is disconnected from the DOM - ancestor = this.eq( 0 ).parents().last(); + // We don't search against the document in case the element + // is disconnected from the DOM + ancestor = this.eq( 0 ).parents().last(); - // Get a full set of top level ancestors - ancestors = ancestor.add( ancestor.length ? ancestor.siblings() : this.siblings() ); + // Get a full set of top level ancestors + ancestors = ancestor.add( ancestor.length ? ancestor.siblings() : this.siblings() ); - // Create a selector for the label based on the id - selector = "label[for='" + $.escapeSelector( id ) + "']"; + // Create a selector for the label based on the id + selector = "label[for='" + $.escapeSelector( id ) + "']"; - labels = labels.add( ancestors.find( selector ).addBack( selector ) ); + labels = labels.add( ancestors.find( selector ).addBack( selector ) ); - } + } - // Return whatever we have found for labels - return this.pushStack( labels ); -}; + // Return whatever we have found for labels + return this.pushStack( labels ); + }; } ); diff --git a/lib/web/jquery/ui-modules/position.js b/lib/web/jquery/ui-modules/position.js index 2f5da8742ddc4..3315a27b7005d 100644 --- a/lib/web/jquery/ui-modules/position.js +++ b/lib/web/jquery/ui-modules/position.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Position 1.13.1 + * jQuery UI Position 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -16,496 +16,496 @@ //>>demos: http://jqueryui.com/position/ ( function( factory ) { - "use strict"; + "use strict"; - if ( typeof define === "function" && define.amd ) { + if ( typeof define === "function" && define.amd ) { - // AMD. Register as an anonymous module. - define( [ "jquery", "./version" ], factory ); - } else { + // AMD. Register as an anonymous module. + define( [ "jquery", "./version" ], factory ); + } else { - // Browser globals - factory( jQuery ); - } + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; - -( function() { -var cachedScrollbarWidth, - max = Math.max, - abs = Math.abs, - rhorizontal = /left|center|right/, - rvertical = /top|center|bottom/, - roffset = /[\+\-]\d+(\.[\d]+)?%?/, - rposition = /^\w+/, - rpercent = /%$/, - _position = $.fn.position; - -function getOffsets( offsets, width, height ) { - return [ - parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), - parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) - ]; -} - -function parseCss( element, property ) { - return parseInt( $.css( element, property ), 10 ) || 0; -} - -function isWindow( obj ) { - return obj != null && obj === obj.window; -} - -function getDimensions( elem ) { - var raw = elem[ 0 ]; - if ( raw.nodeType === 9 ) { - return { - width: elem.width(), - height: elem.height(), - offset: { top: 0, left: 0 } - }; - } - if ( isWindow( raw ) ) { - return { - width: elem.width(), - height: elem.height(), - offset: { top: elem.scrollTop(), left: elem.scrollLeft() } - }; - } - if ( raw.preventDefault ) { - return { - width: 0, - height: 0, - offset: { top: raw.pageY, left: raw.pageX } - }; - } - return { - width: elem.outerWidth(), - height: elem.outerHeight(), - offset: elem.offset() - }; -} - -$.position = { - scrollbarWidth: function() { - if ( cachedScrollbarWidth !== undefined ) { - return cachedScrollbarWidth; - } - var w1, w2, - div = $( "<div style=" + - "'display:block;position:absolute;width:200px;height:200px;overflow:hidden;'>" + - "<div style='height:300px;width:auto;'></div></div>" ), - innerDiv = div.children()[ 0 ]; - - $( "body" ).append( div ); - w1 = innerDiv.offsetWidth; - div.css( "overflow", "scroll" ); - - w2 = innerDiv.offsetWidth; - - if ( w1 === w2 ) { - w2 = div[ 0 ].clientWidth; - } - - div.remove(); - - return ( cachedScrollbarWidth = w1 - w2 ); - }, - getScrollInfo: function( within ) { - var overflowX = within.isWindow || within.isDocument ? "" : - within.element.css( "overflow-x" ), - overflowY = within.isWindow || within.isDocument ? "" : - within.element.css( "overflow-y" ), - hasOverflowX = overflowX === "scroll" || - ( overflowX === "auto" && within.width < within.element[ 0 ].scrollWidth ), - hasOverflowY = overflowY === "scroll" || - ( overflowY === "auto" && within.height < within.element[ 0 ].scrollHeight ); - return { - width: hasOverflowY ? $.position.scrollbarWidth() : 0, - height: hasOverflowX ? $.position.scrollbarWidth() : 0 - }; - }, - getWithinInfo: function( element ) { - var withinElement = $( element || window ), - isElemWindow = isWindow( withinElement[ 0 ] ), - isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9, - hasOffset = !isElemWindow && !isDocument; - return { - element: withinElement, - isWindow: isElemWindow, - isDocument: isDocument, - offset: hasOffset ? $( element ).offset() : { left: 0, top: 0 }, - scrollLeft: withinElement.scrollLeft(), - scrollTop: withinElement.scrollTop(), - width: withinElement.outerWidth(), - height: withinElement.outerHeight() - }; - } -}; - -$.fn.position = function( options ) { - if ( !options || !options.of ) { - return _position.apply( this, arguments ); - } - - // Make a copy, we don't want to modify arguments - options = $.extend( {}, options ); - - var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, - - // Make sure string options are treated as CSS selectors - target = typeof options.of === "string" ? - $( document ).find( options.of ) : - $( options.of ), - - within = $.position.getWithinInfo( options.within ), - scrollInfo = $.position.getScrollInfo( within ), - collision = ( options.collision || "flip" ).split( " " ), - offsets = {}; - - dimensions = getDimensions( target ); - if ( target[ 0 ].preventDefault ) { - - // Force left top to allow flipping - options.at = "left top"; - } - targetWidth = dimensions.width; - targetHeight = dimensions.height; - targetOffset = dimensions.offset; - - // Clone to reuse original targetOffset later - basePosition = $.extend( {}, targetOffset ); - - // Force my and at to have valid horizontal and vertical positions - // if a value is missing or invalid, it will be converted to center - $.each( [ "my", "at" ], function() { - var pos = ( options[ this ] || "" ).split( " " ), - horizontalOffset, - verticalOffset; - - if ( pos.length === 1 ) { - pos = rhorizontal.test( pos[ 0 ] ) ? - pos.concat( [ "center" ] ) : - rvertical.test( pos[ 0 ] ) ? - [ "center" ].concat( pos ) : - [ "center", "center" ]; - } - pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; - pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; - - // Calculate offsets - horizontalOffset = roffset.exec( pos[ 0 ] ); - verticalOffset = roffset.exec( pos[ 1 ] ); - offsets[ this ] = [ - horizontalOffset ? horizontalOffset[ 0 ] : 0, - verticalOffset ? verticalOffset[ 0 ] : 0 - ]; - - // Reduce to just the positions without the offsets - options[ this ] = [ - rposition.exec( pos[ 0 ] )[ 0 ], - rposition.exec( pos[ 1 ] )[ 0 ] - ]; - } ); - - // Normalize collision option - if ( collision.length === 1 ) { - collision[ 1 ] = collision[ 0 ]; - } - - if ( options.at[ 0 ] === "right" ) { - basePosition.left += targetWidth; - } else if ( options.at[ 0 ] === "center" ) { - basePosition.left += targetWidth / 2; - } - - if ( options.at[ 1 ] === "bottom" ) { - basePosition.top += targetHeight; - } else if ( options.at[ 1 ] === "center" ) { - basePosition.top += targetHeight / 2; - } - - atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); - basePosition.left += atOffset[ 0 ]; - basePosition.top += atOffset[ 1 ]; - - return this.each( function() { - var collisionPosition, using, - elem = $( this ), - elemWidth = elem.outerWidth(), - elemHeight = elem.outerHeight(), - marginLeft = parseCss( this, "marginLeft" ), - marginTop = parseCss( this, "marginTop" ), - collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + - scrollInfo.width, - collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + - scrollInfo.height, - position = $.extend( {}, basePosition ), - myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); - - if ( options.my[ 0 ] === "right" ) { - position.left -= elemWidth; - } else if ( options.my[ 0 ] === "center" ) { - position.left -= elemWidth / 2; - } - - if ( options.my[ 1 ] === "bottom" ) { - position.top -= elemHeight; - } else if ( options.my[ 1 ] === "center" ) { - position.top -= elemHeight / 2; - } - - position.left += myOffset[ 0 ]; - position.top += myOffset[ 1 ]; - - collisionPosition = { - marginLeft: marginLeft, - marginTop: marginTop - }; - - $.each( [ "left", "top" ], function( i, dir ) { - if ( $.ui.position[ collision[ i ] ] ) { - $.ui.position[ collision[ i ] ][ dir ]( position, { - targetWidth: targetWidth, - targetHeight: targetHeight, - elemWidth: elemWidth, - elemHeight: elemHeight, - collisionPosition: collisionPosition, - collisionWidth: collisionWidth, - collisionHeight: collisionHeight, - offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], - my: options.my, - at: options.at, - within: within, - elem: elem - } ); - } - } ); - - if ( options.using ) { - - // Adds feedback as second argument to using callback, if present - using = function( props ) { - var left = targetOffset.left - position.left, - right = left + targetWidth - elemWidth, - top = targetOffset.top - position.top, - bottom = top + targetHeight - elemHeight, - feedback = { - target: { - element: target, - left: targetOffset.left, - top: targetOffset.top, - width: targetWidth, - height: targetHeight - }, - element: { - element: elem, - left: position.left, - top: position.top, - width: elemWidth, - height: elemHeight - }, - horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", - vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" - }; - if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { - feedback.horizontal = "center"; - } - if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { - feedback.vertical = "middle"; - } - if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { - feedback.important = "horizontal"; - } else { - feedback.important = "vertical"; - } - options.using.call( this, props, feedback ); - }; - } - - elem.offset( $.extend( position, { using: using } ) ); - } ); -}; - -$.ui.position = { - fit: { - left: function( position, data ) { - var within = data.within, - withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, - outerWidth = within.width, - collisionPosLeft = position.left - data.collisionPosition.marginLeft, - overLeft = withinOffset - collisionPosLeft, - overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, - newOverRight; - - // Element is wider than within - if ( data.collisionWidth > outerWidth ) { - - // Element is initially over the left side of within - if ( overLeft > 0 && overRight <= 0 ) { - newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - - withinOffset; - position.left += overLeft - newOverRight; - - // Element is initially over right side of within - } else if ( overRight > 0 && overLeft <= 0 ) { - position.left = withinOffset; - - // Element is initially over both left and right sides of within - } else { - if ( overLeft > overRight ) { - position.left = withinOffset + outerWidth - data.collisionWidth; - } else { - position.left = withinOffset; - } - } - - // Too far left -> align with left edge - } else if ( overLeft > 0 ) { - position.left += overLeft; - - // Too far right -> align with right edge - } else if ( overRight > 0 ) { - position.left -= overRight; - - // Adjust based on position and margin - } else { - position.left = max( position.left - collisionPosLeft, position.left ); - } - }, - top: function( position, data ) { - var within = data.within, - withinOffset = within.isWindow ? within.scrollTop : within.offset.top, - outerHeight = data.within.height, - collisionPosTop = position.top - data.collisionPosition.marginTop, - overTop = withinOffset - collisionPosTop, - overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, - newOverBottom; - - // Element is taller than within - if ( data.collisionHeight > outerHeight ) { - - // Element is initially over the top of within - if ( overTop > 0 && overBottom <= 0 ) { - newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - - withinOffset; - position.top += overTop - newOverBottom; - - // Element is initially over bottom of within - } else if ( overBottom > 0 && overTop <= 0 ) { - position.top = withinOffset; - - // Element is initially over both top and bottom of within - } else { - if ( overTop > overBottom ) { - position.top = withinOffset + outerHeight - data.collisionHeight; - } else { - position.top = withinOffset; - } - } - - // Too far up -> align with top - } else if ( overTop > 0 ) { - position.top += overTop; - - // Too far down -> align with bottom edge - } else if ( overBottom > 0 ) { - position.top -= overBottom; - - // Adjust based on position and margin - } else { - position.top = max( position.top - collisionPosTop, position.top ); - } - } - }, - flip: { - left: function( position, data ) { - var within = data.within, - withinOffset = within.offset.left + within.scrollLeft, - outerWidth = within.width, - offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, - collisionPosLeft = position.left - data.collisionPosition.marginLeft, - overLeft = collisionPosLeft - offsetLeft, - overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, - myOffset = data.my[ 0 ] === "left" ? - -data.elemWidth : - data.my[ 0 ] === "right" ? - data.elemWidth : - 0, - atOffset = data.at[ 0 ] === "left" ? - data.targetWidth : - data.at[ 0 ] === "right" ? - -data.targetWidth : - 0, - offset = -2 * data.offset[ 0 ], - newOverRight, - newOverLeft; - - if ( overLeft < 0 ) { - newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - - outerWidth - withinOffset; - if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { - position.left += myOffset + atOffset + offset; - } - } else if ( overRight > 0 ) { - newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + - atOffset + offset - offsetLeft; - if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { - position.left += myOffset + atOffset + offset; - } - } - }, - top: function( position, data ) { - var within = data.within, - withinOffset = within.offset.top + within.scrollTop, - outerHeight = within.height, - offsetTop = within.isWindow ? within.scrollTop : within.offset.top, - collisionPosTop = position.top - data.collisionPosition.marginTop, - overTop = collisionPosTop - offsetTop, - overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, - top = data.my[ 1 ] === "top", - myOffset = top ? - -data.elemHeight : - data.my[ 1 ] === "bottom" ? - data.elemHeight : - 0, - atOffset = data.at[ 1 ] === "top" ? - data.targetHeight : - data.at[ 1 ] === "bottom" ? - -data.targetHeight : - 0, - offset = -2 * data.offset[ 1 ], - newOverTop, - newOverBottom; - if ( overTop < 0 ) { - newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - - outerHeight - withinOffset; - if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) { - position.top += myOffset + atOffset + offset; - } - } else if ( overBottom > 0 ) { - newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + - offset - offsetTop; - if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) { - position.top += myOffset + atOffset + offset; - } - } - } - }, - flipfit: { - left: function() { - $.ui.position.flip.left.apply( this, arguments ); - $.ui.position.fit.left.apply( this, arguments ); - }, - top: function() { - $.ui.position.flip.top.apply( this, arguments ); - $.ui.position.fit.top.apply( this, arguments ); - } - } -}; - -} )(); - -return $.ui.position; + "use strict"; + + ( function() { + var cachedScrollbarWidth, + max = Math.max, + abs = Math.abs, + rhorizontal = /left|center|right/, + rvertical = /top|center|bottom/, + roffset = /[\+\-]\d+(\.[\d]+)?%?/, + rposition = /^\w+/, + rpercent = /%$/, + _position = $.fn.position; + + function getOffsets( offsets, width, height ) { + return [ + parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), + parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) + ]; + } + + function parseCss( element, property ) { + return parseInt( $.css( element, property ), 10 ) || 0; + } + + function isWindow( obj ) { + return obj != null && obj === obj.window; + } + + function getDimensions( elem ) { + var raw = elem[ 0 ]; + if ( raw.nodeType === 9 ) { + return { + width: elem.width(), + height: elem.height(), + offset: { top: 0, left: 0 } + }; + } + if ( isWindow( raw ) ) { + return { + width: elem.width(), + height: elem.height(), + offset: { top: elem.scrollTop(), left: elem.scrollLeft() } + }; + } + if ( raw.preventDefault ) { + return { + width: 0, + height: 0, + offset: { top: raw.pageY, left: raw.pageX } + }; + } + return { + width: elem.outerWidth(), + height: elem.outerHeight(), + offset: elem.offset() + }; + } + + $.position = { + scrollbarWidth: function() { + if ( cachedScrollbarWidth !== undefined ) { + return cachedScrollbarWidth; + } + var w1, w2, + div = $( "<div style=" + + "'display:block;position:absolute;width:200px;height:200px;overflow:hidden;'>" + + "<div style='height:300px;width:auto;'></div></div>" ), + innerDiv = div.children()[ 0 ]; + + $( "body" ).append( div ); + w1 = innerDiv.offsetWidth; + div.css( "overflow", "scroll" ); + + w2 = innerDiv.offsetWidth; + + if ( w1 === w2 ) { + w2 = div[ 0 ].clientWidth; + } + + div.remove(); + + return ( cachedScrollbarWidth = w1 - w2 ); + }, + getScrollInfo: function( within ) { + var overflowX = within.isWindow || within.isDocument ? "" : + within.element.css( "overflow-x" ), + overflowY = within.isWindow || within.isDocument ? "" : + within.element.css( "overflow-y" ), + hasOverflowX = overflowX === "scroll" || + ( overflowX === "auto" && within.width < within.element[ 0 ].scrollWidth ), + hasOverflowY = overflowY === "scroll" || + ( overflowY === "auto" && within.height < within.element[ 0 ].scrollHeight ); + return { + width: hasOverflowY ? $.position.scrollbarWidth() : 0, + height: hasOverflowX ? $.position.scrollbarWidth() : 0 + }; + }, + getWithinInfo: function( element ) { + var withinElement = $( element || window ), + isElemWindow = isWindow( withinElement[ 0 ] ), + isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9, + hasOffset = !isElemWindow && !isDocument; + return { + element: withinElement, + isWindow: isElemWindow, + isDocument: isDocument, + offset: hasOffset ? $( element ).offset() : { left: 0, top: 0 }, + scrollLeft: withinElement.scrollLeft(), + scrollTop: withinElement.scrollTop(), + width: withinElement.outerWidth(), + height: withinElement.outerHeight() + }; + } + }; + + $.fn.position = function( options ) { + if ( !options || !options.of ) { + return _position.apply( this, arguments ); + } + + // Make a copy, we don't want to modify arguments + options = $.extend( {}, options ); + + var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, + + // Make sure string options are treated as CSS selectors + target = typeof options.of === "string" ? + $( document ).find( options.of ) : + $( options.of ), + + within = $.position.getWithinInfo( options.within ), + scrollInfo = $.position.getScrollInfo( within ), + collision = ( options.collision || "flip" ).split( " " ), + offsets = {}; + + dimensions = getDimensions( target ); + if ( target[ 0 ].preventDefault ) { + + // Force left top to allow flipping + options.at = "left top"; + } + targetWidth = dimensions.width; + targetHeight = dimensions.height; + targetOffset = dimensions.offset; + + // Clone to reuse original targetOffset later + basePosition = $.extend( {}, targetOffset ); + + // Force my and at to have valid horizontal and vertical positions + // if a value is missing or invalid, it will be converted to center + $.each( [ "my", "at" ], function() { + var pos = ( options[ this ] || "" ).split( " " ), + horizontalOffset, + verticalOffset; + + if ( pos.length === 1 ) { + pos = rhorizontal.test( pos[ 0 ] ) ? + pos.concat( [ "center" ] ) : + rvertical.test( pos[ 0 ] ) ? + [ "center" ].concat( pos ) : + [ "center", "center" ]; + } + pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; + pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; + + // Calculate offsets + horizontalOffset = roffset.exec( pos[ 0 ] ); + verticalOffset = roffset.exec( pos[ 1 ] ); + offsets[ this ] = [ + horizontalOffset ? horizontalOffset[ 0 ] : 0, + verticalOffset ? verticalOffset[ 0 ] : 0 + ]; + + // Reduce to just the positions without the offsets + options[ this ] = [ + rposition.exec( pos[ 0 ] )[ 0 ], + rposition.exec( pos[ 1 ] )[ 0 ] + ]; + } ); + + // Normalize collision option + if ( collision.length === 1 ) { + collision[ 1 ] = collision[ 0 ]; + } + + if ( options.at[ 0 ] === "right" ) { + basePosition.left += targetWidth; + } else if ( options.at[ 0 ] === "center" ) { + basePosition.left += targetWidth / 2; + } + + if ( options.at[ 1 ] === "bottom" ) { + basePosition.top += targetHeight; + } else if ( options.at[ 1 ] === "center" ) { + basePosition.top += targetHeight / 2; + } + + atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); + basePosition.left += atOffset[ 0 ]; + basePosition.top += atOffset[ 1 ]; + + return this.each( function() { + var collisionPosition, using, + elem = $( this ), + elemWidth = elem.outerWidth(), + elemHeight = elem.outerHeight(), + marginLeft = parseCss( this, "marginLeft" ), + marginTop = parseCss( this, "marginTop" ), + collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + + scrollInfo.width, + collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + + scrollInfo.height, + position = $.extend( {}, basePosition ), + myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); + + if ( options.my[ 0 ] === "right" ) { + position.left -= elemWidth; + } else if ( options.my[ 0 ] === "center" ) { + position.left -= elemWidth / 2; + } + + if ( options.my[ 1 ] === "bottom" ) { + position.top -= elemHeight; + } else if ( options.my[ 1 ] === "center" ) { + position.top -= elemHeight / 2; + } + + position.left += myOffset[ 0 ]; + position.top += myOffset[ 1 ]; + + collisionPosition = { + marginLeft: marginLeft, + marginTop: marginTop + }; + + $.each( [ "left", "top" ], function( i, dir ) { + if ( $.ui.position[ collision[ i ] ] ) { + $.ui.position[ collision[ i ] ][ dir ]( position, { + targetWidth: targetWidth, + targetHeight: targetHeight, + elemWidth: elemWidth, + elemHeight: elemHeight, + collisionPosition: collisionPosition, + collisionWidth: collisionWidth, + collisionHeight: collisionHeight, + offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], + my: options.my, + at: options.at, + within: within, + elem: elem + } ); + } + } ); + + if ( options.using ) { + + // Adds feedback as second argument to using callback, if present + using = function( props ) { + var left = targetOffset.left - position.left, + right = left + targetWidth - elemWidth, + top = targetOffset.top - position.top, + bottom = top + targetHeight - elemHeight, + feedback = { + target: { + element: target, + left: targetOffset.left, + top: targetOffset.top, + width: targetWidth, + height: targetHeight + }, + element: { + element: elem, + left: position.left, + top: position.top, + width: elemWidth, + height: elemHeight + }, + horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", + vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" + }; + if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { + feedback.horizontal = "center"; + } + if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { + feedback.vertical = "middle"; + } + if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { + feedback.important = "horizontal"; + } else { + feedback.important = "vertical"; + } + options.using.call( this, props, feedback ); + }; + } + + elem.offset( $.extend( position, { using: using } ) ); + } ); + }; + + $.ui.position = { + fit: { + left: function( position, data ) { + var within = data.within, + withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, + outerWidth = within.width, + collisionPosLeft = position.left - data.collisionPosition.marginLeft, + overLeft = withinOffset - collisionPosLeft, + overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, + newOverRight; + + // Element is wider than within + if ( data.collisionWidth > outerWidth ) { + + // Element is initially over the left side of within + if ( overLeft > 0 && overRight <= 0 ) { + newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - + withinOffset; + position.left += overLeft - newOverRight; + + // Element is initially over right side of within + } else if ( overRight > 0 && overLeft <= 0 ) { + position.left = withinOffset; + + // Element is initially over both left and right sides of within + } else { + if ( overLeft > overRight ) { + position.left = withinOffset + outerWidth - data.collisionWidth; + } else { + position.left = withinOffset; + } + } + + // Too far left -> align with left edge + } else if ( overLeft > 0 ) { + position.left += overLeft; + + // Too far right -> align with right edge + } else if ( overRight > 0 ) { + position.left -= overRight; + + // Adjust based on position and margin + } else { + position.left = max( position.left - collisionPosLeft, position.left ); + } + }, + top: function( position, data ) { + var within = data.within, + withinOffset = within.isWindow ? within.scrollTop : within.offset.top, + outerHeight = data.within.height, + collisionPosTop = position.top - data.collisionPosition.marginTop, + overTop = withinOffset - collisionPosTop, + overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, + newOverBottom; + + // Element is taller than within + if ( data.collisionHeight > outerHeight ) { + + // Element is initially over the top of within + if ( overTop > 0 && overBottom <= 0 ) { + newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - + withinOffset; + position.top += overTop - newOverBottom; + + // Element is initially over bottom of within + } else if ( overBottom > 0 && overTop <= 0 ) { + position.top = withinOffset; + + // Element is initially over both top and bottom of within + } else { + if ( overTop > overBottom ) { + position.top = withinOffset + outerHeight - data.collisionHeight; + } else { + position.top = withinOffset; + } + } + + // Too far up -> align with top + } else if ( overTop > 0 ) { + position.top += overTop; + + // Too far down -> align with bottom edge + } else if ( overBottom > 0 ) { + position.top -= overBottom; + + // Adjust based on position and margin + } else { + position.top = max( position.top - collisionPosTop, position.top ); + } + } + }, + flip: { + left: function( position, data ) { + var within = data.within, + withinOffset = within.offset.left + within.scrollLeft, + outerWidth = within.width, + offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, + collisionPosLeft = position.left - data.collisionPosition.marginLeft, + overLeft = collisionPosLeft - offsetLeft, + overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, + myOffset = data.my[ 0 ] === "left" ? + -data.elemWidth : + data.my[ 0 ] === "right" ? + data.elemWidth : + 0, + atOffset = data.at[ 0 ] === "left" ? + data.targetWidth : + data.at[ 0 ] === "right" ? + -data.targetWidth : + 0, + offset = -2 * data.offset[ 0 ], + newOverRight, + newOverLeft; + + if ( overLeft < 0 ) { + newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - + outerWidth - withinOffset; + if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { + position.left += myOffset + atOffset + offset; + } + } else if ( overRight > 0 ) { + newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + + atOffset + offset - offsetLeft; + if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { + position.left += myOffset + atOffset + offset; + } + } + }, + top: function( position, data ) { + var within = data.within, + withinOffset = within.offset.top + within.scrollTop, + outerHeight = within.height, + offsetTop = within.isWindow ? within.scrollTop : within.offset.top, + collisionPosTop = position.top - data.collisionPosition.marginTop, + overTop = collisionPosTop - offsetTop, + overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, + top = data.my[ 1 ] === "top", + myOffset = top ? + -data.elemHeight : + data.my[ 1 ] === "bottom" ? + data.elemHeight : + 0, + atOffset = data.at[ 1 ] === "top" ? + data.targetHeight : + data.at[ 1 ] === "bottom" ? + -data.targetHeight : + 0, + offset = -2 * data.offset[ 1 ], + newOverTop, + newOverBottom; + if ( overTop < 0 ) { + newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - + outerHeight - withinOffset; + if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) { + position.top += myOffset + atOffset + offset; + } + } else if ( overBottom > 0 ) { + newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + + offset - offsetTop; + if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) { + position.top += myOffset + atOffset + offset; + } + } + } + }, + flipfit: { + left: function() { + $.ui.position.flip.left.apply( this, arguments ); + $.ui.position.fit.left.apply( this, arguments ); + }, + top: function() { + $.ui.position.flip.top.apply( this, arguments ); + $.ui.position.fit.top.apply( this, arguments ); + } + } + }; + + } )(); + + return $.ui.position; } ); diff --git a/lib/web/jquery/ui-modules/scroll-parent.js b/lib/web/jquery/ui-modules/scroll-parent.js index 242bbb82e7419..fec16a6682e0c 100644 --- a/lib/web/jquery/ui-modules/scroll-parent.js +++ b/lib/web/jquery/ui-modules/scroll-parent.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Scroll Parent 1.13.1 + * jQuery UI Scroll Parent 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -13,36 +13,36 @@ //>>docs: http://api.jqueryui.com/scrollParent/ ( function( factory ) { - "use strict"; + "use strict"; - if ( typeof define === "function" && define.amd ) { + if ( typeof define === "function" && define.amd ) { - // AMD. Register as an anonymous module. - define( [ "jquery", "./version" ], factory ); - } else { + // AMD. Register as an anonymous module. + define( [ "jquery", "./version" ], factory ); + } else { - // Browser globals - factory( jQuery ); - } + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; - -return $.fn.scrollParent = function( includeHidden ) { - var position = this.css( "position" ), - excludeStaticParent = position === "absolute", - overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/, - scrollParent = this.parents().filter( function() { - var parent = $( this ); - if ( excludeStaticParent && parent.css( "position" ) === "static" ) { - return false; - } - return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + - parent.css( "overflow-x" ) ); - } ).eq( 0 ); - - return position === "fixed" || !scrollParent.length ? - $( this[ 0 ].ownerDocument || document ) : - scrollParent; -}; + "use strict"; + + return $.fn.scrollParent = function( includeHidden ) { + var position = this.css( "position" ), + excludeStaticParent = position === "absolute", + overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/, + scrollParent = this.parents().filter( function() { + var parent = $( this ); + if ( excludeStaticParent && parent.css( "position" ) === "static" ) { + return false; + } + return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + + parent.css( "overflow-x" ) ); + } ).eq( 0 ); + + return position === "fixed" || !scrollParent.length ? + $( this[ 0 ].ownerDocument || document ) : + scrollParent; + }; } ); diff --git a/lib/web/jquery/ui-modules/tabbable.js b/lib/web/jquery/ui-modules/tabbable.js index e936f6c3eb1ef..71a5887f7a71b 100644 --- a/lib/web/jquery/ui-modules/tabbable.js +++ b/lib/web/jquery/ui-modules/tabbable.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Tabbable 1.13.1 + * jQuery UI Tabbable 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -13,26 +13,26 @@ //>>docs: http://api.jqueryui.com/tabbable-selector/ ( function( factory ) { - "use strict"; + "use strict"; - if ( typeof define === "function" && define.amd ) { + if ( typeof define === "function" && define.amd ) { - // AMD. Register as an anonymous module. - define( [ "jquery", "./version", "./focusable" ], factory ); - } else { + // AMD. Register as an anonymous module. + define( [ "jquery", "./version", "./focusable" ], factory ); + } else { - // Browser globals - factory( jQuery ); - } + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; + "use strict"; -return $.extend( $.expr.pseudos, { - tabbable: function( element ) { - var tabIndex = $.attr( element, "tabindex" ), - hasTabindex = tabIndex != null; - return ( !hasTabindex || tabIndex >= 0 ) && $.ui.focusable( element, hasTabindex ); - } -} ); + return $.extend( $.expr.pseudos, { + tabbable: function( element ) { + var tabIndex = $.attr( element, "tabindex" ), + hasTabindex = tabIndex != null; + return ( !hasTabindex || tabIndex >= 0 ) && $.ui.focusable( element, hasTabindex ); + } + } ); } ); diff --git a/lib/web/jquery/ui-modules/unique-id.js b/lib/web/jquery/ui-modules/unique-id.js index b3acdff70221b..5d7395a19eb0c 100644 --- a/lib/web/jquery/ui-modules/unique-id.js +++ b/lib/web/jquery/ui-modules/unique-id.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Unique ID 1.13.1 + * jQuery UI Unique ID 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -13,40 +13,40 @@ //>>docs: http://api.jqueryui.com/uniqueId/ ( function( factory ) { - "use strict"; + "use strict"; - if ( typeof define === "function" && define.amd ) { + if ( typeof define === "function" && define.amd ) { - // AMD. Register as an anonymous module. - define( [ "jquery", "./version" ], factory ); - } else { + // AMD. Register as an anonymous module. + define( [ "jquery", "./version" ], factory ); + } else { - // Browser globals - factory( jQuery ); - } + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; - -return $.fn.extend( { - uniqueId: ( function() { - var uuid = 0; - - return function() { - return this.each( function() { - if ( !this.id ) { - this.id = "ui-id-" + ( ++uuid ); - } - } ); - }; - } )(), - - removeUniqueId: function() { - return this.each( function() { - if ( /^ui-id-\d+$/.test( this.id ) ) { - $( this ).removeAttr( "id" ); - } - } ); - } -} ); + "use strict"; + + return $.fn.extend( { + uniqueId: ( function() { + var uuid = 0; + + return function() { + return this.each( function() { + if ( !this.id ) { + this.id = "ui-id-" + ( ++uuid ); + } + } ); + }; + } )(), + + removeUniqueId: function() { + return this.each( function() { + if ( /^ui-id-\d+$/.test( this.id ) ) { + $( this ).removeAttr( "id" ); + } + } ); + } + } ); } ); diff --git a/lib/web/jquery/ui-modules/version.js b/lib/web/jquery/ui-modules/version.js index fc3e1d035c2f7..1bc1044884d5e 100644 --- a/lib/web/jquery/ui-modules/version.js +++ b/lib/web/jquery/ui-modules/version.js @@ -1,20 +1,20 @@ ( function( factory ) { - "use strict"; + "use strict"; - if ( typeof define === "function" && define.amd ) { + if ( typeof define === "function" && define.amd ) { - // AMD. Register as an anonymous module. - define( [ "jquery" ], factory ); - } else { + // AMD. Register as an anonymous module. + define( [ "jquery" ], factory ); + } else { - // Browser globals - factory( jQuery ); - } + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; + "use strict"; -$.ui = $.ui || {}; + $.ui = $.ui || {}; -return $.ui.version = "1.13.1"; + return $.ui.version = "1.13.2"; } ); diff --git a/lib/web/jquery/ui-modules/widget.js b/lib/web/jquery/ui-modules/widget.js index 59cf7130e7d7e..ba52fba1d0170 100644 --- a/lib/web/jquery/ui-modules/widget.js +++ b/lib/web/jquery/ui-modules/widget.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Widget 1.13.1 + * jQuery UI Widget 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -14,743 +14,743 @@ //>>demos: http://jqueryui.com/widget/ ( function( factory ) { - "use strict"; + "use strict"; - if ( typeof define === "function" && define.amd ) { + if ( typeof define === "function" && define.amd ) { - // AMD. Register as an anonymous module. - define( [ "jquery", "./version" ], factory ); - } else { + // AMD. Register as an anonymous module. + define( [ "jquery", "./version" ], factory ); + } else { - // Browser globals - factory( jQuery ); - } + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; - -var widgetUuid = 0; -var widgetHasOwnProperty = Array.prototype.hasOwnProperty; -var widgetSlice = Array.prototype.slice; - -$.cleanData = ( function( orig ) { - return function( elems ) { - var events, elem, i; - for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) { - - // Only trigger remove when necessary to save time - events = $._data( elem, "events" ); - if ( events && events.remove ) { - $( elem ).triggerHandler( "remove" ); - } - } - orig( elems ); - }; -} )( $.cleanData ); - -$.widget = function( name, base, prototype ) { - var existingConstructor, constructor, basePrototype; - - // ProxiedPrototype allows the provided prototype to remain unmodified - // so that it can be used as a mixin for multiple widgets (#8876) - var proxiedPrototype = {}; - - var namespace = name.split( "." )[ 0 ]; - name = name.split( "." )[ 1 ]; - var fullName = namespace + "-" + name; - - if ( !prototype ) { - prototype = base; - base = $.Widget; - } - - if ( Array.isArray( prototype ) ) { - prototype = $.extend.apply( null, [ {} ].concat( prototype ) ); - } - - // Create selector for plugin - $.expr.pseudos[ fullName.toLowerCase() ] = function( elem ) { - return !!$.data( elem, fullName ); - }; - - $[ namespace ] = $[ namespace ] || {}; - existingConstructor = $[ namespace ][ name ]; - constructor = $[ namespace ][ name ] = function( options, element ) { - - // Allow instantiation without "new" keyword - if ( !this || !this._createWidget ) { - return new constructor( options, element ); - } - - // Allow instantiation without initializing for simple inheritance - // must use "new" keyword (the code above always passes args) - if ( arguments.length ) { - this._createWidget( options, element ); - } - }; - - // Extend with the existing constructor to carry over any static properties - $.extend( constructor, existingConstructor, { - version: prototype.version, - - // Copy the object used to create the prototype in case we need to - // redefine the widget later - _proto: $.extend( {}, prototype ), - - // Track widgets that inherit from this widget in case this widget is - // redefined after a widget inherits from it - _childConstructors: [] - } ); - - basePrototype = new base(); - - // We need to make the options hash a property directly on the new instance - // otherwise we'll modify the options hash on the prototype that we're - // inheriting from - basePrototype.options = $.widget.extend( {}, basePrototype.options ); - $.each( prototype, function( prop, value ) { - if ( typeof value !== "function" ) { - proxiedPrototype[ prop ] = value; - return; - } - proxiedPrototype[ prop ] = ( function() { - function _super() { - return base.prototype[ prop ].apply( this, arguments ); - } - - function _superApply( args ) { - return base.prototype[ prop ].apply( this, args ); - } - - return function() { - var __super = this._super; - var __superApply = this._superApply; - var returnValue; - - this._super = _super; - this._superApply = _superApply; - - returnValue = value.apply( this, arguments ); - - this._super = __super; - this._superApply = __superApply; - - return returnValue; - }; - } )(); - } ); - constructor.prototype = $.widget.extend( basePrototype, { - - // TODO: remove support for widgetEventPrefix - // always use the name + a colon as the prefix, e.g., draggable:start - // don't prefix for widgets that aren't DOM-based - widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name - }, proxiedPrototype, { - constructor: constructor, - namespace: namespace, - widgetName: name, - widgetFullName: fullName - } ); - - // If this widget is being redefined then we need to find all widgets that - // are inheriting from it and redefine all of them so that they inherit from - // the new version of this widget. We're essentially trying to replace one - // level in the prototype chain. - if ( existingConstructor ) { - $.each( existingConstructor._childConstructors, function( i, child ) { - var childPrototype = child.prototype; - - // Redefine the child widget using the same prototype that was - // originally used, but inherit from the new version of the base - $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, - child._proto ); - } ); - - // Remove the list of existing child constructors from the old constructor - // so the old child constructors can be garbage collected - delete existingConstructor._childConstructors; - } else { - base._childConstructors.push( constructor ); - } - - $.widget.bridge( name, constructor ); - - return constructor; -}; - -$.widget.extend = function( target ) { - var input = widgetSlice.call( arguments, 1 ); - var inputIndex = 0; - var inputLength = input.length; - var key; - var value; - - for ( ; inputIndex < inputLength; inputIndex++ ) { - for ( key in input[ inputIndex ] ) { - value = input[ inputIndex ][ key ]; - if ( widgetHasOwnProperty.call( input[ inputIndex ], key ) && value !== undefined ) { - - // Clone objects - if ( $.isPlainObject( value ) ) { - target[ key ] = $.isPlainObject( target[ key ] ) ? - $.widget.extend( {}, target[ key ], value ) : - - // Don't extend strings, arrays, etc. with objects - $.widget.extend( {}, value ); - - // Copy everything else by reference - } else { - target[ key ] = value; - } - } - } - } - return target; -}; - -$.widget.bridge = function( name, object ) { - var fullName = object.prototype.widgetFullName || name; - $.fn[ name ] = function( options ) { - var isMethodCall = typeof options === "string"; - var args = widgetSlice.call( arguments, 1 ); - var returnValue = this; - - if ( isMethodCall ) { - - // If this is an empty collection, we need to have the instance method - // return undefined instead of the jQuery instance - if ( !this.length && options === "instance" ) { - returnValue = undefined; - } else { - this.each( function() { - var methodValue; - var instance = $.data( this, fullName ); - - if ( options === "instance" ) { - returnValue = instance; - return false; - } - - if ( !instance ) { - return $.error( "cannot call methods on " + name + - " prior to initialization; " + - "attempted to call method '" + options + "'" ); - } - - if ( typeof instance[ options ] !== "function" || - options.charAt( 0 ) === "_" ) { - return $.error( "no such method '" + options + "' for " + name + - " widget instance" ); - } - - methodValue = instance[ options ].apply( instance, args ); - - if ( methodValue !== instance && methodValue !== undefined ) { - returnValue = methodValue && methodValue.jquery ? - returnValue.pushStack( methodValue.get() ) : - methodValue; - return false; - } - } ); - } - } else { - - // Allow multiple hashes to be passed on init - if ( args.length ) { - options = $.widget.extend.apply( null, [ options ].concat( args ) ); - } - - this.each( function() { - var instance = $.data( this, fullName ); - if ( instance ) { - instance.option( options || {} ); - if ( instance._init ) { - instance._init(); - } - } else { - $.data( this, fullName, new object( options, this ) ); - } - } ); - } - - return returnValue; - }; -}; - -$.Widget = function( /* options, element */ ) {}; -$.Widget._childConstructors = []; - -$.Widget.prototype = { - widgetName: "widget", - widgetEventPrefix: "", - defaultElement: "<div>", - - options: { - classes: {}, - disabled: false, - - // Callbacks - create: null - }, - - _createWidget: function( options, element ) { - element = $( element || this.defaultElement || this )[ 0 ]; - this.element = $( element ); - this.uuid = widgetUuid++; - this.eventNamespace = "." + this.widgetName + this.uuid; - - this.bindings = $(); - this.hoverable = $(); - this.focusable = $(); - this.classesElementLookup = {}; - - if ( element !== this ) { - $.data( element, this.widgetFullName, this ); - this._on( true, this.element, { - remove: function( event ) { - if ( event.target === element ) { - this.destroy(); - } - } - } ); - this.document = $( element.style ? - - // Element within the document - element.ownerDocument : - - // Element is window or document - element.document || element ); - this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow ); - } - - this.options = $.widget.extend( {}, - this.options, - this._getCreateOptions(), - options ); - - this._create(); - - if ( this.options.disabled ) { - this._setOptionDisabled( this.options.disabled ); - } - - this._trigger( "create", null, this._getCreateEventData() ); - this._init(); - }, - - _getCreateOptions: function() { - return {}; - }, - - _getCreateEventData: $.noop, - - _create: $.noop, - - _init: $.noop, - - destroy: function() { - var that = this; - - this._destroy(); - $.each( this.classesElementLookup, function( key, value ) { - that._removeClass( value, key ); - } ); - - // We can probably remove the unbind calls in 2.0 - // all event bindings should go through this._on() - this.element - .off( this.eventNamespace ) - .removeData( this.widgetFullName ); - this.widget() - .off( this.eventNamespace ) - .removeAttr( "aria-disabled" ); - - // Clean up events and states - this.bindings.off( this.eventNamespace ); - }, - - _destroy: $.noop, - - widget: function() { - return this.element; - }, - - option: function( key, value ) { - var options = key; - var parts; - var curOption; - var i; - - if ( arguments.length === 0 ) { - - // Don't return a reference to the internal hash - return $.widget.extend( {}, this.options ); - } - - if ( typeof key === "string" ) { - - // Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } - options = {}; - parts = key.split( "." ); - key = parts.shift(); - if ( parts.length ) { - curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); - for ( i = 0; i < parts.length - 1; i++ ) { - curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; - curOption = curOption[ parts[ i ] ]; - } - key = parts.pop(); - if ( arguments.length === 1 ) { - return curOption[ key ] === undefined ? null : curOption[ key ]; - } - curOption[ key ] = value; - } else { - if ( arguments.length === 1 ) { - return this.options[ key ] === undefined ? null : this.options[ key ]; - } - options[ key ] = value; - } - } - - this._setOptions( options ); - - return this; - }, - - _setOptions: function( options ) { - var key; - - for ( key in options ) { - this._setOption( key, options[ key ] ); - } - - return this; - }, - - _setOption: function( key, value ) { - if ( key === "classes" ) { - this._setOptionClasses( value ); - } - - this.options[ key ] = value; - - if ( key === "disabled" ) { - this._setOptionDisabled( value ); - } - - return this; - }, - - _setOptionClasses: function( value ) { - var classKey, elements, currentElements; - - for ( classKey in value ) { - currentElements = this.classesElementLookup[ classKey ]; - if ( value[ classKey ] === this.options.classes[ classKey ] || - !currentElements || - !currentElements.length ) { - continue; - } - - // We are doing this to create a new jQuery object because the _removeClass() call - // on the next line is going to destroy the reference to the current elements being - // tracked. We need to save a copy of this collection so that we can add the new classes - // below. - elements = $( currentElements.get() ); - this._removeClass( currentElements, classKey ); - - // We don't use _addClass() here, because that uses this.options.classes - // for generating the string of classes. We want to use the value passed in from - // _setOption(), this is the new value of the classes option which was passed to - // _setOption(). We pass this value directly to _classes(). - elements.addClass( this._classes( { - element: elements, - keys: classKey, - classes: value, - add: true - } ) ); - } - }, - - _setOptionDisabled: function( value ) { - this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value ); - - // If the widget is becoming disabled, then nothing is interactive - if ( value ) { - this._removeClass( this.hoverable, null, "ui-state-hover" ); - this._removeClass( this.focusable, null, "ui-state-focus" ); - } - }, - - enable: function() { - return this._setOptions( { disabled: false } ); - }, - - disable: function() { - return this._setOptions( { disabled: true } ); - }, - - _classes: function( options ) { - var full = []; - var that = this; - - options = $.extend( { - element: this.element, - classes: this.options.classes || {} - }, options ); - - function bindRemoveEvent() { - var nodesToBind = []; - - options.element.each( function( _, element ) { - var isTracked = $.map( that.classesElementLookup, function( elements ) { - return elements; - } ) - .some( function( elements ) { - return elements.is( element ); - } ); - - if ( !isTracked ) { - nodesToBind.push( element ); - } - } ); - - that._on( $( nodesToBind ), { - remove: "_untrackClassesElement" - } ); - } - - function processClassString( classes, checkOption ) { - var current, i; - for ( i = 0; i < classes.length; i++ ) { - current = that.classesElementLookup[ classes[ i ] ] || $(); - if ( options.add ) { - bindRemoveEvent(); - current = $( $.uniqueSort( current.get().concat( options.element.get() ) ) ); - } else { - current = $( current.not( options.element ).get() ); - } - that.classesElementLookup[ classes[ i ] ] = current; - full.push( classes[ i ] ); - if ( checkOption && options.classes[ classes[ i ] ] ) { - full.push( options.classes[ classes[ i ] ] ); - } - } - } - - if ( options.keys ) { - processClassString( options.keys.match( /\S+/g ) || [], true ); - } - if ( options.extra ) { - processClassString( options.extra.match( /\S+/g ) || [] ); - } - - return full.join( " " ); - }, - - _untrackClassesElement: function( event ) { - var that = this; - $.each( that.classesElementLookup, function( key, value ) { - if ( $.inArray( event.target, value ) !== -1 ) { - that.classesElementLookup[ key ] = $( value.not( event.target ).get() ); - } - } ); - - this._off( $( event.target ) ); - }, - - _removeClass: function( element, keys, extra ) { - return this._toggleClass( element, keys, extra, false ); - }, - - _addClass: function( element, keys, extra ) { - return this._toggleClass( element, keys, extra, true ); - }, - - _toggleClass: function( element, keys, extra, add ) { - add = ( typeof add === "boolean" ) ? add : extra; - var shift = ( typeof element === "string" || element === null ), - options = { - extra: shift ? keys : extra, - keys: shift ? element : keys, - element: shift ? this.element : element, - add: add - }; - options.element.toggleClass( this._classes( options ), add ); - return this; - }, - - _on: function( suppressDisabledCheck, element, handlers ) { - var delegateElement; - var instance = this; - - // No suppressDisabledCheck flag, shuffle arguments - if ( typeof suppressDisabledCheck !== "boolean" ) { - handlers = element; - element = suppressDisabledCheck; - suppressDisabledCheck = false; - } - - // No element argument, shuffle and use this.element - if ( !handlers ) { - handlers = element; - element = this.element; - delegateElement = this.widget(); - } else { - element = delegateElement = $( element ); - this.bindings = this.bindings.add( element ); - } - - $.each( handlers, function( event, handler ) { - function handlerProxy() { - - // Allow widgets to customize the disabled handling - // - disabled as an array instead of boolean - // - disabled class as method for disabling individual parts - if ( !suppressDisabledCheck && - ( instance.options.disabled === true || - $( this ).hasClass( "ui-state-disabled" ) ) ) { - return; - } - return ( typeof handler === "string" ? instance[ handler ] : handler ) - .apply( instance, arguments ); - } - - // Copy the guid so direct unbinding works - if ( typeof handler !== "string" ) { - handlerProxy.guid = handler.guid = - handler.guid || handlerProxy.guid || $.guid++; - } - - var match = event.match( /^([\w:-]*)\s*(.*)$/ ); - var eventName = match[ 1 ] + instance.eventNamespace; - var selector = match[ 2 ]; - - if ( selector ) { - delegateElement.on( eventName, selector, handlerProxy ); - } else { - element.on( eventName, handlerProxy ); - } - } ); - }, - - _off: function( element, eventName ) { - eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) + - this.eventNamespace; - element.off( eventName ); - - // Clear the stack to avoid memory leaks (#10056) - this.bindings = $( this.bindings.not( element ).get() ); - this.focusable = $( this.focusable.not( element ).get() ); - this.hoverable = $( this.hoverable.not( element ).get() ); - }, - - _delay: function( handler, delay ) { - function handlerProxy() { - return ( typeof handler === "string" ? instance[ handler ] : handler ) - .apply( instance, arguments ); - } - var instance = this; - return setTimeout( handlerProxy, delay || 0 ); - }, - - _hoverable: function( element ) { - this.hoverable = this.hoverable.add( element ); - this._on( element, { - mouseenter: function( event ) { - this._addClass( $( event.currentTarget ), null, "ui-state-hover" ); - }, - mouseleave: function( event ) { - this._removeClass( $( event.currentTarget ), null, "ui-state-hover" ); - } - } ); - }, - - _focusable: function( element ) { - this.focusable = this.focusable.add( element ); - this._on( element, { - focusin: function( event ) { - this._addClass( $( event.currentTarget ), null, "ui-state-focus" ); - }, - focusout: function( event ) { - this._removeClass( $( event.currentTarget ), null, "ui-state-focus" ); - } - } ); - }, - - _trigger: function( type, event, data ) { - var prop, orig; - var callback = this.options[ type ]; - - data = data || {}; - event = $.Event( event ); - event.type = ( type === this.widgetEventPrefix ? - type : - this.widgetEventPrefix + type ).toLowerCase(); - - // The original event may come from any element - // so we need to reset the target on the new event - event.target = this.element[ 0 ]; - - // Copy original event properties over to the new event - orig = event.originalEvent; - if ( orig ) { - for ( prop in orig ) { - if ( !( prop in event ) ) { - event[ prop ] = orig[ prop ]; - } - } - } - - this.element.trigger( event, data ); - return !( typeof callback === "function" && - callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false || - event.isDefaultPrevented() ); - } -}; - -$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { - $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { - if ( typeof options === "string" ) { - options = { effect: options }; - } - - var hasOptions; - var effectName = !options ? - method : - options === true || typeof options === "number" ? - defaultEffect : - options.effect || defaultEffect; - - options = options || {}; - if ( typeof options === "number" ) { - options = { duration: options }; - } else if ( options === true ) { - options = {}; - } - - hasOptions = !$.isEmptyObject( options ); - options.complete = callback; - - if ( options.delay ) { - element.delay( options.delay ); - } - - if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { - element[ method ]( options ); - } else if ( effectName !== method && element[ effectName ] ) { - element[ effectName ]( options.duration, options.easing, callback ); - } else { - element.queue( function( next ) { - $( this )[ method ](); - if ( callback ) { - callback.call( element[ 0 ] ); - } - next(); - } ); - } - }; -} ); - -return $.widget; + "use strict"; + + var widgetUuid = 0; + var widgetHasOwnProperty = Array.prototype.hasOwnProperty; + var widgetSlice = Array.prototype.slice; + + $.cleanData = ( function( orig ) { + return function( elems ) { + var events, elem, i; + for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) { + + // Only trigger remove when necessary to save time + events = $._data( elem, "events" ); + if ( events && events.remove ) { + $( elem ).triggerHandler( "remove" ); + } + } + orig( elems ); + }; + } )( $.cleanData ); + + $.widget = function( name, base, prototype ) { + var existingConstructor, constructor, basePrototype; + + // ProxiedPrototype allows the provided prototype to remain unmodified + // so that it can be used as a mixin for multiple widgets (#8876) + var proxiedPrototype = {}; + + var namespace = name.split( "." )[ 0 ]; + name = name.split( "." )[ 1 ]; + var fullName = namespace + "-" + name; + + if ( !prototype ) { + prototype = base; + base = $.Widget; + } + + if ( Array.isArray( prototype ) ) { + prototype = $.extend.apply( null, [ {} ].concat( prototype ) ); + } + + // Create selector for plugin + $.expr.pseudos[ fullName.toLowerCase() ] = function( elem ) { + return !!$.data( elem, fullName ); + }; + + $[ namespace ] = $[ namespace ] || {}; + existingConstructor = $[ namespace ][ name ]; + constructor = $[ namespace ][ name ] = function( options, element ) { + + // Allow instantiation without "new" keyword + if ( !this || !this._createWidget ) { + return new constructor( options, element ); + } + + // Allow instantiation without initializing for simple inheritance + // must use "new" keyword (the code above always passes args) + if ( arguments.length ) { + this._createWidget( options, element ); + } + }; + + // Extend with the existing constructor to carry over any static properties + $.extend( constructor, existingConstructor, { + version: prototype.version, + + // Copy the object used to create the prototype in case we need to + // redefine the widget later + _proto: $.extend( {}, prototype ), + + // Track widgets that inherit from this widget in case this widget is + // redefined after a widget inherits from it + _childConstructors: [] + } ); + + basePrototype = new base(); + + // We need to make the options hash a property directly on the new instance + // otherwise we'll modify the options hash on the prototype that we're + // inheriting from + basePrototype.options = $.widget.extend( {}, basePrototype.options ); + $.each( prototype, function( prop, value ) { + if ( typeof value !== "function" ) { + proxiedPrototype[ prop ] = value; + return; + } + proxiedPrototype[ prop ] = ( function() { + function _super() { + return base.prototype[ prop ].apply( this, arguments ); + } + + function _superApply( args ) { + return base.prototype[ prop ].apply( this, args ); + } + + return function() { + var __super = this._super; + var __superApply = this._superApply; + var returnValue; + + this._super = _super; + this._superApply = _superApply; + + returnValue = value.apply( this, arguments ); + + this._super = __super; + this._superApply = __superApply; + + return returnValue; + }; + } )(); + } ); + constructor.prototype = $.widget.extend( basePrototype, { + + // TODO: remove support for widgetEventPrefix + // always use the name + a colon as the prefix, e.g., draggable:start + // don't prefix for widgets that aren't DOM-based + widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name + }, proxiedPrototype, { + constructor: constructor, + namespace: namespace, + widgetName: name, + widgetFullName: fullName + } ); + + // If this widget is being redefined then we need to find all widgets that + // are inheriting from it and redefine all of them so that they inherit from + // the new version of this widget. We're essentially trying to replace one + // level in the prototype chain. + if ( existingConstructor ) { + $.each( existingConstructor._childConstructors, function( i, child ) { + var childPrototype = child.prototype; + + // Redefine the child widget using the same prototype that was + // originally used, but inherit from the new version of the base + $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, + child._proto ); + } ); + + // Remove the list of existing child constructors from the old constructor + // so the old child constructors can be garbage collected + delete existingConstructor._childConstructors; + } else { + base._childConstructors.push( constructor ); + } + + $.widget.bridge( name, constructor ); + + return constructor; + }; + + $.widget.extend = function( target ) { + var input = widgetSlice.call( arguments, 1 ); + var inputIndex = 0; + var inputLength = input.length; + var key; + var value; + + for ( ; inputIndex < inputLength; inputIndex++ ) { + for ( key in input[ inputIndex ] ) { + value = input[ inputIndex ][ key ]; + if ( widgetHasOwnProperty.call( input[ inputIndex ], key ) && value !== undefined ) { + + // Clone objects + if ( $.isPlainObject( value ) ) { + target[ key ] = $.isPlainObject( target[ key ] ) ? + $.widget.extend( {}, target[ key ], value ) : + + // Don't extend strings, arrays, etc. with objects + $.widget.extend( {}, value ); + + // Copy everything else by reference + } else { + target[ key ] = value; + } + } + } + } + return target; + }; + + $.widget.bridge = function( name, object ) { + var fullName = object.prototype.widgetFullName || name; + $.fn[ name ] = function( options ) { + var isMethodCall = typeof options === "string"; + var args = widgetSlice.call( arguments, 1 ); + var returnValue = this; + + if ( isMethodCall ) { + + // If this is an empty collection, we need to have the instance method + // return undefined instead of the jQuery instance + if ( !this.length && options === "instance" ) { + returnValue = undefined; + } else { + this.each( function() { + var methodValue; + var instance = $.data( this, fullName ); + + if ( options === "instance" ) { + returnValue = instance; + return false; + } + + if ( !instance ) { + return $.error( "cannot call methods on " + name + + " prior to initialization; " + + "attempted to call method '" + options + "'" ); + } + + if ( typeof instance[ options ] !== "function" || + options.charAt( 0 ) === "_" ) { + return $.error( "no such method '" + options + "' for " + name + + " widget instance" ); + } + + methodValue = instance[ options ].apply( instance, args ); + + if ( methodValue !== instance && methodValue !== undefined ) { + returnValue = methodValue && methodValue.jquery ? + returnValue.pushStack( methodValue.get() ) : + methodValue; + return false; + } + } ); + } + } else { + + // Allow multiple hashes to be passed on init + if ( args.length ) { + options = $.widget.extend.apply( null, [ options ].concat( args ) ); + } + + this.each( function() { + var instance = $.data( this, fullName ); + if ( instance ) { + instance.option( options || {} ); + if ( instance._init ) { + instance._init(); + } + } else { + $.data( this, fullName, new object( options, this ) ); + } + } ); + } + + return returnValue; + }; + }; + + $.Widget = function( /* options, element */ ) {}; + $.Widget._childConstructors = []; + + $.Widget.prototype = { + widgetName: "widget", + widgetEventPrefix: "", + defaultElement: "<div>", + + options: { + classes: {}, + disabled: false, + + // Callbacks + create: null + }, + + _createWidget: function( options, element ) { + element = $( element || this.defaultElement || this )[ 0 ]; + this.element = $( element ); + this.uuid = widgetUuid++; + this.eventNamespace = "." + this.widgetName + this.uuid; + + this.bindings = $(); + this.hoverable = $(); + this.focusable = $(); + this.classesElementLookup = {}; + + if ( element !== this ) { + $.data( element, this.widgetFullName, this ); + this._on( true, this.element, { + remove: function( event ) { + if ( event.target === element ) { + this.destroy(); + } + } + } ); + this.document = $( element.style ? + + // Element within the document + element.ownerDocument : + + // Element is window or document + element.document || element ); + this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow ); + } + + this.options = $.widget.extend( {}, + this.options, + this._getCreateOptions(), + options ); + + this._create(); + + if ( this.options.disabled ) { + this._setOptionDisabled( this.options.disabled ); + } + + this._trigger( "create", null, this._getCreateEventData() ); + this._init(); + }, + + _getCreateOptions: function() { + return {}; + }, + + _getCreateEventData: $.noop, + + _create: $.noop, + + _init: $.noop, + + destroy: function() { + var that = this; + + this._destroy(); + $.each( this.classesElementLookup, function( key, value ) { + that._removeClass( value, key ); + } ); + + // We can probably remove the unbind calls in 2.0 + // all event bindings should go through this._on() + this.element + .off( this.eventNamespace ) + .removeData( this.widgetFullName ); + this.widget() + .off( this.eventNamespace ) + .removeAttr( "aria-disabled" ); + + // Clean up events and states + this.bindings.off( this.eventNamespace ); + }, + + _destroy: $.noop, + + widget: function() { + return this.element; + }, + + option: function( key, value ) { + var options = key; + var parts; + var curOption; + var i; + + if ( arguments.length === 0 ) { + + // Don't return a reference to the internal hash + return $.widget.extend( {}, this.options ); + } + + if ( typeof key === "string" ) { + + // Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } + options = {}; + parts = key.split( "." ); + key = parts.shift(); + if ( parts.length ) { + curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); + for ( i = 0; i < parts.length - 1; i++ ) { + curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; + curOption = curOption[ parts[ i ] ]; + } + key = parts.pop(); + if ( arguments.length === 1 ) { + return curOption[ key ] === undefined ? null : curOption[ key ]; + } + curOption[ key ] = value; + } else { + if ( arguments.length === 1 ) { + return this.options[ key ] === undefined ? null : this.options[ key ]; + } + options[ key ] = value; + } + } + + this._setOptions( options ); + + return this; + }, + + _setOptions: function( options ) { + var key; + + for ( key in options ) { + this._setOption( key, options[ key ] ); + } + + return this; + }, + + _setOption: function( key, value ) { + if ( key === "classes" ) { + this._setOptionClasses( value ); + } + + this.options[ key ] = value; + + if ( key === "disabled" ) { + this._setOptionDisabled( value ); + } + + return this; + }, + + _setOptionClasses: function( value ) { + var classKey, elements, currentElements; + + for ( classKey in value ) { + currentElements = this.classesElementLookup[ classKey ]; + if ( value[ classKey ] === this.options.classes[ classKey ] || + !currentElements || + !currentElements.length ) { + continue; + } + + // We are doing this to create a new jQuery object because the _removeClass() call + // on the next line is going to destroy the reference to the current elements being + // tracked. We need to save a copy of this collection so that we can add the new classes + // below. + elements = $( currentElements.get() ); + this._removeClass( currentElements, classKey ); + + // We don't use _addClass() here, because that uses this.options.classes + // for generating the string of classes. We want to use the value passed in from + // _setOption(), this is the new value of the classes option which was passed to + // _setOption(). We pass this value directly to _classes(). + elements.addClass( this._classes( { + element: elements, + keys: classKey, + classes: value, + add: true + } ) ); + } + }, + + _setOptionDisabled: function( value ) { + this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value ); + + // If the widget is becoming disabled, then nothing is interactive + if ( value ) { + this._removeClass( this.hoverable, null, "ui-state-hover" ); + this._removeClass( this.focusable, null, "ui-state-focus" ); + } + }, + + enable: function() { + return this._setOptions( { disabled: false } ); + }, + + disable: function() { + return this._setOptions( { disabled: true } ); + }, + + _classes: function( options ) { + var full = []; + var that = this; + + options = $.extend( { + element: this.element, + classes: this.options.classes || {} + }, options ); + + function bindRemoveEvent() { + var nodesToBind = []; + + options.element.each( function( _, element ) { + var isTracked = $.map( that.classesElementLookup, function( elements ) { + return elements; + } ) + .some( function( elements ) { + return elements.is( element ); + } ); + + if ( !isTracked ) { + nodesToBind.push( element ); + } + } ); + + that._on( $( nodesToBind ), { + remove: "_untrackClassesElement" + } ); + } + + function processClassString( classes, checkOption ) { + var current, i; + for ( i = 0; i < classes.length; i++ ) { + current = that.classesElementLookup[ classes[ i ] ] || $(); + if ( options.add ) { + bindRemoveEvent(); + current = $( $.uniqueSort( current.get().concat( options.element.get() ) ) ); + } else { + current = $( current.not( options.element ).get() ); + } + that.classesElementLookup[ classes[ i ] ] = current; + full.push( classes[ i ] ); + if ( checkOption && options.classes[ classes[ i ] ] ) { + full.push( options.classes[ classes[ i ] ] ); + } + } + } + + if ( options.keys ) { + processClassString( options.keys.match( /\S+/g ) || [], true ); + } + if ( options.extra ) { + processClassString( options.extra.match( /\S+/g ) || [] ); + } + + return full.join( " " ); + }, + + _untrackClassesElement: function( event ) { + var that = this; + $.each( that.classesElementLookup, function( key, value ) { + if ( $.inArray( event.target, value ) !== -1 ) { + that.classesElementLookup[ key ] = $( value.not( event.target ).get() ); + } + } ); + + this._off( $( event.target ) ); + }, + + _removeClass: function( element, keys, extra ) { + return this._toggleClass( element, keys, extra, false ); + }, + + _addClass: function( element, keys, extra ) { + return this._toggleClass( element, keys, extra, true ); + }, + + _toggleClass: function( element, keys, extra, add ) { + add = ( typeof add === "boolean" ) ? add : extra; + var shift = ( typeof element === "string" || element === null ), + options = { + extra: shift ? keys : extra, + keys: shift ? element : keys, + element: shift ? this.element : element, + add: add + }; + options.element.toggleClass( this._classes( options ), add ); + return this; + }, + + _on: function( suppressDisabledCheck, element, handlers ) { + var delegateElement; + var instance = this; + + // No suppressDisabledCheck flag, shuffle arguments + if ( typeof suppressDisabledCheck !== "boolean" ) { + handlers = element; + element = suppressDisabledCheck; + suppressDisabledCheck = false; + } + + // No element argument, shuffle and use this.element + if ( !handlers ) { + handlers = element; + element = this.element; + delegateElement = this.widget(); + } else { + element = delegateElement = $( element ); + this.bindings = this.bindings.add( element ); + } + + $.each( handlers, function( event, handler ) { + function handlerProxy() { + + // Allow widgets to customize the disabled handling + // - disabled as an array instead of boolean + // - disabled class as method for disabling individual parts + if ( !suppressDisabledCheck && + ( instance.options.disabled === true || + $( this ).hasClass( "ui-state-disabled" ) ) ) { + return; + } + return ( typeof handler === "string" ? instance[ handler ] : handler ) + .apply( instance, arguments ); + } + + // Copy the guid so direct unbinding works + if ( typeof handler !== "string" ) { + handlerProxy.guid = handler.guid = + handler.guid || handlerProxy.guid || $.guid++; + } + + var match = event.match( /^([\w:-]*)\s*(.*)$/ ); + var eventName = match[ 1 ] + instance.eventNamespace; + var selector = match[ 2 ]; + + if ( selector ) { + delegateElement.on( eventName, selector, handlerProxy ); + } else { + element.on( eventName, handlerProxy ); + } + } ); + }, + + _off: function( element, eventName ) { + eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) + + this.eventNamespace; + element.off( eventName ); + + // Clear the stack to avoid memory leaks (#10056) + this.bindings = $( this.bindings.not( element ).get() ); + this.focusable = $( this.focusable.not( element ).get() ); + this.hoverable = $( this.hoverable.not( element ).get() ); + }, + + _delay: function( handler, delay ) { + function handlerProxy() { + return ( typeof handler === "string" ? instance[ handler ] : handler ) + .apply( instance, arguments ); + } + var instance = this; + return setTimeout( handlerProxy, delay || 0 ); + }, + + _hoverable: function( element ) { + this.hoverable = this.hoverable.add( element ); + this._on( element, { + mouseenter: function( event ) { + this._addClass( $( event.currentTarget ), null, "ui-state-hover" ); + }, + mouseleave: function( event ) { + this._removeClass( $( event.currentTarget ), null, "ui-state-hover" ); + } + } ); + }, + + _focusable: function( element ) { + this.focusable = this.focusable.add( element ); + this._on( element, { + focusin: function( event ) { + this._addClass( $( event.currentTarget ), null, "ui-state-focus" ); + }, + focusout: function( event ) { + this._removeClass( $( event.currentTarget ), null, "ui-state-focus" ); + } + } ); + }, + + _trigger: function( type, event, data ) { + var prop, orig; + var callback = this.options[ type ]; + + data = data || {}; + event = $.Event( event ); + event.type = ( type === this.widgetEventPrefix ? + type : + this.widgetEventPrefix + type ).toLowerCase(); + + // The original event may come from any element + // so we need to reset the target on the new event + event.target = this.element[ 0 ]; + + // Copy original event properties over to the new event + orig = event.originalEvent; + if ( orig ) { + for ( prop in orig ) { + if ( !( prop in event ) ) { + event[ prop ] = orig[ prop ]; + } + } + } + + this.element.trigger( event, data ); + return !( typeof callback === "function" && + callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false || + event.isDefaultPrevented() ); + } + }; + + $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { + $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { + if ( typeof options === "string" ) { + options = { effect: options }; + } + + var hasOptions; + var effectName = !options ? + method : + options === true || typeof options === "number" ? + defaultEffect : + options.effect || defaultEffect; + + options = options || {}; + if ( typeof options === "number" ) { + options = { duration: options }; + } else if ( options === true ) { + options = {}; + } + + hasOptions = !$.isEmptyObject( options ); + options.complete = callback; + + if ( options.delay ) { + element.delay( options.delay ); + } + + if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { + element[ method ]( options ); + } else if ( effectName !== method && element[ effectName ] ) { + element[ effectName ]( options.duration, options.easing, callback ); + } else { + element.queue( function( next ) { + $( this )[ method ](); + if ( callback ) { + callback.call( element[ 0 ] ); + } + next(); + } ); + } + }; + } ); + + return $.widget; } ); diff --git a/lib/web/jquery/ui-modules/widgets/accordion.js b/lib/web/jquery/ui-modules/widgets/accordion.js index b14bf2f7af746..f0d2a2448281d 100644 --- a/lib/web/jquery/ui-modules/widgets/accordion.js +++ b/lib/web/jquery/ui-modules/widgets/accordion.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Accordion 1.13.1 + * jQuery UI Accordion 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -19,604 +19,604 @@ //>>css.theme: ../../themes/base/theme.css ( function( factory ) { - "use strict"; - - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define( [ - "jquery", - "../version", - "../keycode", - "../unique-id", - "../widget" - ], factory ); - } else { - - // Browser globals - factory( jQuery ); - } + "use strict"; + + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ + "jquery", + "../version", + "../keycode", + "../unique-id", + "../widget" + ], factory ); + } else { + + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; - -return $.widget( "ui.accordion", { - version: "1.13.1", - options: { - active: 0, - animate: {}, - classes: { - "ui-accordion-header": "ui-corner-top", - "ui-accordion-header-collapsed": "ui-corner-all", - "ui-accordion-content": "ui-corner-bottom" - }, - collapsible: false, - event: "click", - header: function( elem ) { - return elem.find( "> li > :first-child" ).add( elem.find( "> :not(li)" ).even() ); - }, - heightStyle: "auto", - icons: { - activeHeader: "ui-icon-triangle-1-s", - header: "ui-icon-triangle-1-e" - }, - - // Callbacks - activate: null, - beforeActivate: null - }, - - hideProps: { - borderTopWidth: "hide", - borderBottomWidth: "hide", - paddingTop: "hide", - paddingBottom: "hide", - height: "hide" - }, - - showProps: { - borderTopWidth: "show", - borderBottomWidth: "show", - paddingTop: "show", - paddingBottom: "show", - height: "show" - }, - - _create: function() { - var options = this.options; - - this.prevShow = this.prevHide = $(); - this._addClass( "ui-accordion", "ui-widget ui-helper-reset" ); - this.element.attr( "role", "tablist" ); - - // Don't allow collapsible: false and active: false / null - if ( !options.collapsible && ( options.active === false || options.active == null ) ) { - options.active = 0; - } - - this._processPanels(); - - // handle negative values - if ( options.active < 0 ) { - options.active += this.headers.length; - } - this._refresh(); - }, - - _getCreateEventData: function() { - return { - header: this.active, - panel: !this.active.length ? $() : this.active.next() - }; - }, - - _createIcons: function() { - var icon, children, - icons = this.options.icons; - - if ( icons ) { - icon = $( "<span>" ); - this._addClass( icon, "ui-accordion-header-icon", "ui-icon " + icons.header ); - icon.prependTo( this.headers ); - children = this.active.children( ".ui-accordion-header-icon" ); - this._removeClass( children, icons.header ) - ._addClass( children, null, icons.activeHeader ) - ._addClass( this.headers, "ui-accordion-icons" ); - } - }, - - _destroyIcons: function() { - this._removeClass( this.headers, "ui-accordion-icons" ); - this.headers.children( ".ui-accordion-header-icon" ).remove(); - }, - - _destroy: function() { - var contents; - - // Clean up main element - this.element.removeAttr( "role" ); - - // Clean up headers - this.headers - .removeAttr( "role aria-expanded aria-selected aria-controls tabIndex" ) - .removeUniqueId(); - - this._destroyIcons(); - - // Clean up content panels - contents = this.headers.next() - .css( "display", "" ) - .removeAttr( "role aria-hidden aria-labelledby" ) - .removeUniqueId(); - - if ( this.options.heightStyle !== "content" ) { - contents.css( "height", "" ); - } - }, - - _setOption: function( key, value ) { - if ( key === "active" ) { - - // _activate() will handle invalid values and update this.options - this._activate( value ); - return; - } - - if ( key === "event" ) { - if ( this.options.event ) { - this._off( this.headers, this.options.event ); - } - this._setupEvents( value ); - } - - this._super( key, value ); - - // Setting collapsible: false while collapsed; open first panel - if ( key === "collapsible" && !value && this.options.active === false ) { - this._activate( 0 ); - } - - if ( key === "icons" ) { - this._destroyIcons(); - if ( value ) { - this._createIcons(); - } - } - }, - - _setOptionDisabled: function( value ) { - this._super( value ); - - this.element.attr( "aria-disabled", value ); - - // Support: IE8 Only - // #5332 / #6059 - opacity doesn't cascade to positioned elements in IE - // so we need to add the disabled class to the headers and panels - this._toggleClass( null, "ui-state-disabled", !!value ); - this._toggleClass( this.headers.add( this.headers.next() ), null, "ui-state-disabled", - !!value ); - }, - - _keydown: function( event ) { - if ( event.altKey || event.ctrlKey ) { - return; - } - - var keyCode = $.ui.keyCode, - length = this.headers.length, - currentIndex = this.headers.index( event.target ), - toFocus = false; - - switch ( event.keyCode ) { - case keyCode.RIGHT: - case keyCode.DOWN: - toFocus = this.headers[ ( currentIndex + 1 ) % length ]; - break; - case keyCode.LEFT: - case keyCode.UP: - toFocus = this.headers[ ( currentIndex - 1 + length ) % length ]; - break; - case keyCode.SPACE: - case keyCode.ENTER: - this._eventHandler( event ); - break; - case keyCode.HOME: - toFocus = this.headers[ 0 ]; - break; - case keyCode.END: - toFocus = this.headers[ length - 1 ]; - break; - } - - if ( toFocus ) { - $( event.target ).attr( "tabIndex", -1 ); - $( toFocus ).attr( "tabIndex", 0 ); - $( toFocus ).trigger( "focus" ); - event.preventDefault(); - } - }, - - _panelKeyDown: function( event ) { - if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) { - $( event.currentTarget ).prev().trigger( "focus" ); - } - }, - - refresh: function() { - var options = this.options; - this._processPanels(); - - // Was collapsed or no panel - if ( ( options.active === false && options.collapsible === true ) || - !this.headers.length ) { - options.active = false; - this.active = $(); - - // active false only when collapsible is true - } else if ( options.active === false ) { - this._activate( 0 ); - - // was active, but active panel is gone - } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { - - // all remaining panel are disabled - if ( this.headers.length === this.headers.find( ".ui-state-disabled" ).length ) { - options.active = false; - this.active = $(); - - // activate previous panel - } else { - this._activate( Math.max( 0, options.active - 1 ) ); - } - - // was active, active panel still exists - } else { - - // make sure active index is correct - options.active = this.headers.index( this.active ); - } - - this._destroyIcons(); - - this._refresh(); - }, - - _processPanels: function() { - var prevHeaders = this.headers, - prevPanels = this.panels; - - if ( typeof this.options.header === "function" ) { - this.headers = this.options.header( this.element ); - } else { - this.headers = this.element.find( this.options.header ); - } - this._addClass( this.headers, "ui-accordion-header ui-accordion-header-collapsed", - "ui-state-default" ); - - this.panels = this.headers.next().filter( ":not(.ui-accordion-content-active)" ).hide(); - this._addClass( this.panels, "ui-accordion-content", "ui-helper-reset ui-widget-content" ); - - // Avoid memory leaks (#10056) - if ( prevPanels ) { - this._off( prevHeaders.not( this.headers ) ); - this._off( prevPanels.not( this.panels ) ); - } - }, - - _refresh: function() { - var maxHeight, - options = this.options, - heightStyle = options.heightStyle, - parent = this.element.parent(); - - this.active = this._findActive( options.active ); - this._addClass( this.active, "ui-accordion-header-active", "ui-state-active" ) - ._removeClass( this.active, "ui-accordion-header-collapsed" ); - this._addClass( this.active.next(), "ui-accordion-content-active" ); - this.active.next().show(); - - this.headers - .attr( "role", "tab" ) - .each( function() { - var header = $( this ), - headerId = header.uniqueId().attr( "id" ), - panel = header.next(), - panelId = panel.uniqueId().attr( "id" ); - header.attr( "aria-controls", panelId ); - panel.attr( "aria-labelledby", headerId ); - } ) - .next() - .attr( "role", "tabpanel" ); - - this.headers - .not( this.active ) - .attr( { - "aria-selected": "false", - "aria-expanded": "false", - tabIndex: -1 - } ) - .next() - .attr( { - "aria-hidden": "true" - } ) - .hide(); - - // Make sure at least one header is in the tab order - if ( !this.active.length ) { - this.headers.eq( 0 ).attr( "tabIndex", 0 ); - } else { - this.active.attr( { - "aria-selected": "true", - "aria-expanded": "true", - tabIndex: 0 - } ) - .next() - .attr( { - "aria-hidden": "false" - } ); - } - - this._createIcons(); - - this._setupEvents( options.event ); - - if ( heightStyle === "fill" ) { - maxHeight = parent.height(); - this.element.siblings( ":visible" ).each( function() { - var elem = $( this ), - position = elem.css( "position" ); - - if ( position === "absolute" || position === "fixed" ) { - return; - } - maxHeight -= elem.outerHeight( true ); - } ); - - this.headers.each( function() { - maxHeight -= $( this ).outerHeight( true ); - } ); - - this.headers.next() - .each( function() { - $( this ).height( Math.max( 0, maxHeight - - $( this ).innerHeight() + $( this ).height() ) ); - } ) - .css( "overflow", "auto" ); - } else if ( heightStyle === "auto" ) { - maxHeight = 0; - this.headers.next() - .each( function() { - var isVisible = $( this ).is( ":visible" ); - if ( !isVisible ) { - $( this ).show(); - } - maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() ); - if ( !isVisible ) { - $( this ).hide(); - } - } ) - .height( maxHeight ); - } - }, - - _activate: function( index ) { - var active = this._findActive( index )[ 0 ]; - - // Trying to activate the already active panel - if ( active === this.active[ 0 ] ) { - return; - } - - // Trying to collapse, simulate a click on the currently active header - active = active || this.active[ 0 ]; - - this._eventHandler( { - target: active, - currentTarget: active, - preventDefault: $.noop - } ); - }, - - _findActive: function( selector ) { - return typeof selector === "number" ? this.headers.eq( selector ) : $(); - }, - - _setupEvents: function( event ) { - var events = { - keydown: "_keydown" - }; - if ( event ) { - $.each( event.split( " " ), function( index, eventName ) { - events[ eventName ] = "_eventHandler"; - } ); - } - - this._off( this.headers.add( this.headers.next() ) ); - this._on( this.headers, events ); - this._on( this.headers.next(), { keydown: "_panelKeyDown" } ); - this._hoverable( this.headers ); - this._focusable( this.headers ); - }, - - _eventHandler: function( event ) { - var activeChildren, clickedChildren, - options = this.options, - active = this.active, - clicked = $( event.currentTarget ), - clickedIsActive = clicked[ 0 ] === active[ 0 ], - collapsing = clickedIsActive && options.collapsible, - toShow = collapsing ? $() : clicked.next(), - toHide = active.next(), - eventData = { - oldHeader: active, - oldPanel: toHide, - newHeader: collapsing ? $() : clicked, - newPanel: toShow - }; - - event.preventDefault(); - - if ( - - // click on active header, but not collapsible - ( clickedIsActive && !options.collapsible ) || - - // allow canceling activation - ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { - return; - } - - options.active = collapsing ? false : this.headers.index( clicked ); - - // When the call to ._toggle() comes after the class changes - // it causes a very odd bug in IE 8 (see #6720) - this.active = clickedIsActive ? $() : clicked; - this._toggle( eventData ); - - // Switch classes - // corner classes on the previously active header stay after the animation - this._removeClass( active, "ui-accordion-header-active", "ui-state-active" ); - if ( options.icons ) { - activeChildren = active.children( ".ui-accordion-header-icon" ); - this._removeClass( activeChildren, null, options.icons.activeHeader ) - ._addClass( activeChildren, null, options.icons.header ); - } - - if ( !clickedIsActive ) { - this._removeClass( clicked, "ui-accordion-header-collapsed" ) - ._addClass( clicked, "ui-accordion-header-active", "ui-state-active" ); - if ( options.icons ) { - clickedChildren = clicked.children( ".ui-accordion-header-icon" ); - this._removeClass( clickedChildren, null, options.icons.header ) - ._addClass( clickedChildren, null, options.icons.activeHeader ); - } - - this._addClass( clicked.next(), "ui-accordion-content-active" ); - } - }, - - _toggle: function( data ) { - var toShow = data.newPanel, - toHide = this.prevShow.length ? this.prevShow : data.oldPanel; - - // Handle activating a panel during the animation for another activation - this.prevShow.add( this.prevHide ).stop( true, true ); - this.prevShow = toShow; - this.prevHide = toHide; - - if ( this.options.animate ) { - this._animate( toShow, toHide, data ); - } else { - toHide.hide(); - toShow.show(); - this._toggleComplete( data ); - } - - toHide.attr( { - "aria-hidden": "true" - } ); - toHide.prev().attr( { - "aria-selected": "false", - "aria-expanded": "false" - } ); - - // if we're switching panels, remove the old header from the tab order - // if we're opening from collapsed state, remove the previous header from the tab order - // if we're collapsing, then keep the collapsing header in the tab order - if ( toShow.length && toHide.length ) { - toHide.prev().attr( { - "tabIndex": -1, - "aria-expanded": "false" - } ); - } else if ( toShow.length ) { - this.headers.filter( function() { - return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0; - } ) - .attr( "tabIndex", -1 ); - } - - toShow - .attr( "aria-hidden", "false" ) - .prev() - .attr( { - "aria-selected": "true", - "aria-expanded": "true", - tabIndex: 0 - } ); - }, - - _animate: function( toShow, toHide, data ) { - var total, easing, duration, - that = this, - adjust = 0, - boxSizing = toShow.css( "box-sizing" ), - down = toShow.length && - ( !toHide.length || ( toShow.index() < toHide.index() ) ), - animate = this.options.animate || {}, - options = down && animate.down || animate, - complete = function() { - that._toggleComplete( data ); - }; - - if ( typeof options === "number" ) { - duration = options; - } - if ( typeof options === "string" ) { - easing = options; - } - - // fall back from options to animation in case of partial down settings - easing = easing || options.easing || animate.easing; - duration = duration || options.duration || animate.duration; - - if ( !toHide.length ) { - return toShow.animate( this.showProps, duration, easing, complete ); - } - if ( !toShow.length ) { - return toHide.animate( this.hideProps, duration, easing, complete ); - } - - total = toShow.show().outerHeight(); - toHide.animate( this.hideProps, { - duration: duration, - easing: easing, - step: function( now, fx ) { - fx.now = Math.round( now ); - } - } ); - toShow - .hide() - .animate( this.showProps, { - duration: duration, - easing: easing, - complete: complete, - step: function( now, fx ) { - fx.now = Math.round( now ); - if ( fx.prop !== "height" ) { - if ( boxSizing === "content-box" ) { - adjust += fx.now; - } - } else if ( that.options.heightStyle !== "content" ) { - fx.now = Math.round( total - toHide.outerHeight() - adjust ); - adjust = 0; - } - } - } ); - }, - - _toggleComplete: function( data ) { - var toHide = data.oldPanel, - prev = toHide.prev(); - - this._removeClass( toHide, "ui-accordion-content-active" ); - this._removeClass( prev, "ui-accordion-header-active" ) - ._addClass( prev, "ui-accordion-header-collapsed" ); - - // Work around for rendering bug in IE (#5421) - if ( toHide.length ) { - toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className; - } - this._trigger( "activate", null, data ); - } -} ); + "use strict"; + + return $.widget( "ui.accordion", { + version: "1.13.2", + options: { + active: 0, + animate: {}, + classes: { + "ui-accordion-header": "ui-corner-top", + "ui-accordion-header-collapsed": "ui-corner-all", + "ui-accordion-content": "ui-corner-bottom" + }, + collapsible: false, + event: "click", + header: function( elem ) { + return elem.find( "> li > :first-child" ).add( elem.find( "> :not(li)" ).even() ); + }, + heightStyle: "auto", + icons: { + activeHeader: "ui-icon-triangle-1-s", + header: "ui-icon-triangle-1-e" + }, + + // Callbacks + activate: null, + beforeActivate: null + }, + + hideProps: { + borderTopWidth: "hide", + borderBottomWidth: "hide", + paddingTop: "hide", + paddingBottom: "hide", + height: "hide" + }, + + showProps: { + borderTopWidth: "show", + borderBottomWidth: "show", + paddingTop: "show", + paddingBottom: "show", + height: "show" + }, + + _create: function() { + var options = this.options; + + this.prevShow = this.prevHide = $(); + this._addClass( "ui-accordion", "ui-widget ui-helper-reset" ); + this.element.attr( "role", "tablist" ); + + // Don't allow collapsible: false and active: false / null + if ( !options.collapsible && ( options.active === false || options.active == null ) ) { + options.active = 0; + } + + this._processPanels(); + + // handle negative values + if ( options.active < 0 ) { + options.active += this.headers.length; + } + this._refresh(); + }, + + _getCreateEventData: function() { + return { + header: this.active, + panel: !this.active.length ? $() : this.active.next() + }; + }, + + _createIcons: function() { + var icon, children, + icons = this.options.icons; + + if ( icons ) { + icon = $( "<span>" ); + this._addClass( icon, "ui-accordion-header-icon", "ui-icon " + icons.header ); + icon.prependTo( this.headers ); + children = this.active.children( ".ui-accordion-header-icon" ); + this._removeClass( children, icons.header ) + ._addClass( children, null, icons.activeHeader ) + ._addClass( this.headers, "ui-accordion-icons" ); + } + }, + + _destroyIcons: function() { + this._removeClass( this.headers, "ui-accordion-icons" ); + this.headers.children( ".ui-accordion-header-icon" ).remove(); + }, + + _destroy: function() { + var contents; + + // Clean up main element + this.element.removeAttr( "role" ); + + // Clean up headers + this.headers + .removeAttr( "role aria-expanded aria-selected aria-controls tabIndex" ) + .removeUniqueId(); + + this._destroyIcons(); + + // Clean up content panels + contents = this.headers.next() + .css( "display", "" ) + .removeAttr( "role aria-hidden aria-labelledby" ) + .removeUniqueId(); + + if ( this.options.heightStyle !== "content" ) { + contents.css( "height", "" ); + } + }, + + _setOption: function( key, value ) { + if ( key === "active" ) { + + // _activate() will handle invalid values and update this.options + this._activate( value ); + return; + } + + if ( key === "event" ) { + if ( this.options.event ) { + this._off( this.headers, this.options.event ); + } + this._setupEvents( value ); + } + + this._super( key, value ); + + // Setting collapsible: false while collapsed; open first panel + if ( key === "collapsible" && !value && this.options.active === false ) { + this._activate( 0 ); + } + + if ( key === "icons" ) { + this._destroyIcons(); + if ( value ) { + this._createIcons(); + } + } + }, + + _setOptionDisabled: function( value ) { + this._super( value ); + + this.element.attr( "aria-disabled", value ); + + // Support: IE8 Only + // #5332 / #6059 - opacity doesn't cascade to positioned elements in IE + // so we need to add the disabled class to the headers and panels + this._toggleClass( null, "ui-state-disabled", !!value ); + this._toggleClass( this.headers.add( this.headers.next() ), null, "ui-state-disabled", + !!value ); + }, + + _keydown: function( event ) { + if ( event.altKey || event.ctrlKey ) { + return; + } + + var keyCode = $.ui.keyCode, + length = this.headers.length, + currentIndex = this.headers.index( event.target ), + toFocus = false; + + switch ( event.keyCode ) { + case keyCode.RIGHT: + case keyCode.DOWN: + toFocus = this.headers[ ( currentIndex + 1 ) % length ]; + break; + case keyCode.LEFT: + case keyCode.UP: + toFocus = this.headers[ ( currentIndex - 1 + length ) % length ]; + break; + case keyCode.SPACE: + case keyCode.ENTER: + this._eventHandler( event ); + break; + case keyCode.HOME: + toFocus = this.headers[ 0 ]; + break; + case keyCode.END: + toFocus = this.headers[ length - 1 ]; + break; + } + + if ( toFocus ) { + $( event.target ).attr( "tabIndex", -1 ); + $( toFocus ).attr( "tabIndex", 0 ); + $( toFocus ).trigger( "focus" ); + event.preventDefault(); + } + }, + + _panelKeyDown: function( event ) { + if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) { + $( event.currentTarget ).prev().trigger( "focus" ); + } + }, + + refresh: function() { + var options = this.options; + this._processPanels(); + + // Was collapsed or no panel + if ( ( options.active === false && options.collapsible === true ) || + !this.headers.length ) { + options.active = false; + this.active = $(); + + // active false only when collapsible is true + } else if ( options.active === false ) { + this._activate( 0 ); + + // was active, but active panel is gone + } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { + + // all remaining panel are disabled + if ( this.headers.length === this.headers.find( ".ui-state-disabled" ).length ) { + options.active = false; + this.active = $(); + + // activate previous panel + } else { + this._activate( Math.max( 0, options.active - 1 ) ); + } + + // was active, active panel still exists + } else { + + // make sure active index is correct + options.active = this.headers.index( this.active ); + } + + this._destroyIcons(); + + this._refresh(); + }, + + _processPanels: function() { + var prevHeaders = this.headers, + prevPanels = this.panels; + + if ( typeof this.options.header === "function" ) { + this.headers = this.options.header( this.element ); + } else { + this.headers = this.element.find( this.options.header ); + } + this._addClass( this.headers, "ui-accordion-header ui-accordion-header-collapsed", + "ui-state-default" ); + + this.panels = this.headers.next().filter( ":not(.ui-accordion-content-active)" ).hide(); + this._addClass( this.panels, "ui-accordion-content", "ui-helper-reset ui-widget-content" ); + + // Avoid memory leaks (#10056) + if ( prevPanels ) { + this._off( prevHeaders.not( this.headers ) ); + this._off( prevPanels.not( this.panels ) ); + } + }, + + _refresh: function() { + var maxHeight, + options = this.options, + heightStyle = options.heightStyle, + parent = this.element.parent(); + + this.active = this._findActive( options.active ); + this._addClass( this.active, "ui-accordion-header-active", "ui-state-active" ) + ._removeClass( this.active, "ui-accordion-header-collapsed" ); + this._addClass( this.active.next(), "ui-accordion-content-active" ); + this.active.next().show(); + + this.headers + .attr( "role", "tab" ) + .each( function() { + var header = $( this ), + headerId = header.uniqueId().attr( "id" ), + panel = header.next(), + panelId = panel.uniqueId().attr( "id" ); + header.attr( "aria-controls", panelId ); + panel.attr( "aria-labelledby", headerId ); + } ) + .next() + .attr( "role", "tabpanel" ); + + this.headers + .not( this.active ) + .attr( { + "aria-selected": "false", + "aria-expanded": "false", + tabIndex: -1 + } ) + .next() + .attr( { + "aria-hidden": "true" + } ) + .hide(); + + // Make sure at least one header is in the tab order + if ( !this.active.length ) { + this.headers.eq( 0 ).attr( "tabIndex", 0 ); + } else { + this.active.attr( { + "aria-selected": "true", + "aria-expanded": "true", + tabIndex: 0 + } ) + .next() + .attr( { + "aria-hidden": "false" + } ); + } + + this._createIcons(); + + this._setupEvents( options.event ); + + if ( heightStyle === "fill" ) { + maxHeight = parent.height(); + this.element.siblings( ":visible" ).each( function() { + var elem = $( this ), + position = elem.css( "position" ); + + if ( position === "absolute" || position === "fixed" ) { + return; + } + maxHeight -= elem.outerHeight( true ); + } ); + + this.headers.each( function() { + maxHeight -= $( this ).outerHeight( true ); + } ); + + this.headers.next() + .each( function() { + $( this ).height( Math.max( 0, maxHeight - + $( this ).innerHeight() + $( this ).height() ) ); + } ) + .css( "overflow", "auto" ); + } else if ( heightStyle === "auto" ) { + maxHeight = 0; + this.headers.next() + .each( function() { + var isVisible = $( this ).is( ":visible" ); + if ( !isVisible ) { + $( this ).show(); + } + maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() ); + if ( !isVisible ) { + $( this ).hide(); + } + } ) + .height( maxHeight ); + } + }, + + _activate: function( index ) { + var active = this._findActive( index )[ 0 ]; + + // Trying to activate the already active panel + if ( active === this.active[ 0 ] ) { + return; + } + + // Trying to collapse, simulate a click on the currently active header + active = active || this.active[ 0 ]; + + this._eventHandler( { + target: active, + currentTarget: active, + preventDefault: $.noop + } ); + }, + + _findActive: function( selector ) { + return typeof selector === "number" ? this.headers.eq( selector ) : $(); + }, + + _setupEvents: function( event ) { + var events = { + keydown: "_keydown" + }; + if ( event ) { + $.each( event.split( " " ), function( index, eventName ) { + events[ eventName ] = "_eventHandler"; + } ); + } + + this._off( this.headers.add( this.headers.next() ) ); + this._on( this.headers, events ); + this._on( this.headers.next(), { keydown: "_panelKeyDown" } ); + this._hoverable( this.headers ); + this._focusable( this.headers ); + }, + + _eventHandler: function( event ) { + var activeChildren, clickedChildren, + options = this.options, + active = this.active, + clicked = $( event.currentTarget ), + clickedIsActive = clicked[ 0 ] === active[ 0 ], + collapsing = clickedIsActive && options.collapsible, + toShow = collapsing ? $() : clicked.next(), + toHide = active.next(), + eventData = { + oldHeader: active, + oldPanel: toHide, + newHeader: collapsing ? $() : clicked, + newPanel: toShow + }; + + event.preventDefault(); + + if ( + + // click on active header, but not collapsible + ( clickedIsActive && !options.collapsible ) || + + // allow canceling activation + ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { + return; + } + + options.active = collapsing ? false : this.headers.index( clicked ); + + // When the call to ._toggle() comes after the class changes + // it causes a very odd bug in IE 8 (see #6720) + this.active = clickedIsActive ? $() : clicked; + this._toggle( eventData ); + + // Switch classes + // corner classes on the previously active header stay after the animation + this._removeClass( active, "ui-accordion-header-active", "ui-state-active" ); + if ( options.icons ) { + activeChildren = active.children( ".ui-accordion-header-icon" ); + this._removeClass( activeChildren, null, options.icons.activeHeader ) + ._addClass( activeChildren, null, options.icons.header ); + } + + if ( !clickedIsActive ) { + this._removeClass( clicked, "ui-accordion-header-collapsed" ) + ._addClass( clicked, "ui-accordion-header-active", "ui-state-active" ); + if ( options.icons ) { + clickedChildren = clicked.children( ".ui-accordion-header-icon" ); + this._removeClass( clickedChildren, null, options.icons.header ) + ._addClass( clickedChildren, null, options.icons.activeHeader ); + } + + this._addClass( clicked.next(), "ui-accordion-content-active" ); + } + }, + + _toggle: function( data ) { + var toShow = data.newPanel, + toHide = this.prevShow.length ? this.prevShow : data.oldPanel; + + // Handle activating a panel during the animation for another activation + this.prevShow.add( this.prevHide ).stop( true, true ); + this.prevShow = toShow; + this.prevHide = toHide; + + if ( this.options.animate ) { + this._animate( toShow, toHide, data ); + } else { + toHide.hide(); + toShow.show(); + this._toggleComplete( data ); + } + + toHide.attr( { + "aria-hidden": "true" + } ); + toHide.prev().attr( { + "aria-selected": "false", + "aria-expanded": "false" + } ); + + // if we're switching panels, remove the old header from the tab order + // if we're opening from collapsed state, remove the previous header from the tab order + // if we're collapsing, then keep the collapsing header in the tab order + if ( toShow.length && toHide.length ) { + toHide.prev().attr( { + "tabIndex": -1, + "aria-expanded": "false" + } ); + } else if ( toShow.length ) { + this.headers.filter( function() { + return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0; + } ) + .attr( "tabIndex", -1 ); + } + + toShow + .attr( "aria-hidden", "false" ) + .prev() + .attr( { + "aria-selected": "true", + "aria-expanded": "true", + tabIndex: 0 + } ); + }, + + _animate: function( toShow, toHide, data ) { + var total, easing, duration, + that = this, + adjust = 0, + boxSizing = toShow.css( "box-sizing" ), + down = toShow.length && + ( !toHide.length || ( toShow.index() < toHide.index() ) ), + animate = this.options.animate || {}, + options = down && animate.down || animate, + complete = function() { + that._toggleComplete( data ); + }; + + if ( typeof options === "number" ) { + duration = options; + } + if ( typeof options === "string" ) { + easing = options; + } + + // fall back from options to animation in case of partial down settings + easing = easing || options.easing || animate.easing; + duration = duration || options.duration || animate.duration; + + if ( !toHide.length ) { + return toShow.animate( this.showProps, duration, easing, complete ); + } + if ( !toShow.length ) { + return toHide.animate( this.hideProps, duration, easing, complete ); + } + + total = toShow.show().outerHeight(); + toHide.animate( this.hideProps, { + duration: duration, + easing: easing, + step: function( now, fx ) { + fx.now = Math.round( now ); + } + } ); + toShow + .hide() + .animate( this.showProps, { + duration: duration, + easing: easing, + complete: complete, + step: function( now, fx ) { + fx.now = Math.round( now ); + if ( fx.prop !== "height" ) { + if ( boxSizing === "content-box" ) { + adjust += fx.now; + } + } else if ( that.options.heightStyle !== "content" ) { + fx.now = Math.round( total - toHide.outerHeight() - adjust ); + adjust = 0; + } + } + } ); + }, + + _toggleComplete: function( data ) { + var toHide = data.oldPanel, + prev = toHide.prev(); + + this._removeClass( toHide, "ui-accordion-content-active" ); + this._removeClass( prev, "ui-accordion-header-active" ) + ._addClass( prev, "ui-accordion-header-collapsed" ); + + // Work around for rendering bug in IE (#5421) + if ( toHide.length ) { + toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className; + } + this._trigger( "activate", null, data ); + } + } ); } ); diff --git a/lib/web/jquery/ui-modules/widgets/autocomplete.js b/lib/web/jquery/ui-modules/widgets/autocomplete.js index dcc2df3f2ac2c..7547350d95ab8 100644 --- a/lib/web/jquery/ui-modules/widgets/autocomplete.js +++ b/lib/web/jquery/ui-modules/widgets/autocomplete.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Autocomplete 1.13.1 + * jQuery UI Autocomplete 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -17,662 +17,662 @@ //>>css.theme: ../../themes/base/theme.css ( function( factory ) { - "use strict"; - - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define( [ - "jquery", - "./menu", - "../keycode", - "../position", - "../safe-active-element", - "../version", - "../widget" - ], factory ); - } else { - - // Browser globals - factory( jQuery ); - } + "use strict"; + + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ + "jquery", + "./menu", + "../keycode", + "../position", + "../safe-active-element", + "../version", + "../widget" + ], factory ); + } else { + + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; - -$.widget( "ui.autocomplete", { - version: "1.13.1", - defaultElement: "<input>", - options: { - appendTo: null, - autoFocus: false, - delay: 300, - minLength: 1, - position: { - my: "left top", - at: "left bottom", - collision: "none" - }, - source: null, - - // Callbacks - change: null, - close: null, - focus: null, - open: null, - response: null, - search: null, - select: null - }, - - requestIndex: 0, - pending: 0, - liveRegionTimer: null, - - _create: function() { - - // Some browsers only repeat keydown events, not keypress events, - // so we use the suppressKeyPress flag to determine if we've already - // handled the keydown event. #7269 - // Unfortunately the code for & in keypress is the same as the up arrow, - // so we use the suppressKeyPressRepeat flag to avoid handling keypress - // events when we know the keydown event was used to modify the - // search term. #7799 - var suppressKeyPress, suppressKeyPressRepeat, suppressInput, - nodeName = this.element[ 0 ].nodeName.toLowerCase(), - isTextarea = nodeName === "textarea", - isInput = nodeName === "input"; - - // Textareas are always multi-line - // Inputs are always single-line, even if inside a contentEditable element - // IE also treats inputs as contentEditable - // All other element types are determined by whether or not they're contentEditable - this.isMultiLine = isTextarea || !isInput && this._isContentEditable( this.element ); - - this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ]; - this.isNewMenu = true; - - this._addClass( "ui-autocomplete-input" ); - this.element.attr( "autocomplete", "off" ); - - this._on( this.element, { - keydown: function( event ) { - if ( this.element.prop( "readOnly" ) ) { - suppressKeyPress = true; - suppressInput = true; - suppressKeyPressRepeat = true; - return; - } - - suppressKeyPress = false; - suppressInput = false; - suppressKeyPressRepeat = false; - var keyCode = $.ui.keyCode; - switch ( event.keyCode ) { - case keyCode.PAGE_UP: - suppressKeyPress = true; - this._move( "previousPage", event ); - break; - case keyCode.PAGE_DOWN: - suppressKeyPress = true; - this._move( "nextPage", event ); - break; - case keyCode.UP: - suppressKeyPress = true; - this._keyEvent( "previous", event ); - break; - case keyCode.DOWN: - suppressKeyPress = true; - this._keyEvent( "next", event ); - break; - case keyCode.ENTER: - - // when menu is open and has focus - if ( this.menu.active ) { - - // #6055 - Opera still allows the keypress to occur - // which causes forms to submit - suppressKeyPress = true; - event.preventDefault(); - this.menu.select( event ); - } - break; - case keyCode.TAB: - if ( this.menu.active ) { - this.menu.select( event ); - } - break; - case keyCode.ESCAPE: - if ( this.menu.element.is( ":visible" ) ) { - if ( !this.isMultiLine ) { - this._value( this.term ); - } - this.close( event ); - - // Different browsers have different default behavior for escape - // Single press can mean undo or clear - // Double press in IE means clear the whole form - event.preventDefault(); - } - break; - default: - suppressKeyPressRepeat = true; - - // search timeout should be triggered before the input value is changed - this._searchTimeout( event ); - break; - } - }, - keypress: function( event ) { - if ( suppressKeyPress ) { - suppressKeyPress = false; - if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { - event.preventDefault(); - } - return; - } - if ( suppressKeyPressRepeat ) { - return; - } - - // Replicate some key handlers to allow them to repeat in Firefox and Opera - var keyCode = $.ui.keyCode; - switch ( event.keyCode ) { - case keyCode.PAGE_UP: - this._move( "previousPage", event ); - break; - case keyCode.PAGE_DOWN: - this._move( "nextPage", event ); - break; - case keyCode.UP: - this._keyEvent( "previous", event ); - break; - case keyCode.DOWN: - this._keyEvent( "next", event ); - break; - } - }, - input: function( event ) { - if ( suppressInput ) { - suppressInput = false; - event.preventDefault(); - return; - } - this._searchTimeout( event ); - }, - focus: function() { - this.selectedItem = null; - this.previous = this._value(); - }, - blur: function( event ) { - clearTimeout( this.searching ); - this.close( event ); - this._change( event ); - } - } ); - - this._initSource(); - this.menu = $( "<ul>" ) - .appendTo( this._appendTo() ) - .menu( { - - // disable ARIA support, the live region takes care of that - role: null - } ) - .hide() - - // Support: IE 11 only, Edge <= 14 - // For other browsers, we preventDefault() on the mousedown event - // to keep the dropdown from taking focus from the input. This doesn't - // work for IE/Edge, causing problems with selection and scrolling (#9638) - // Happily, IE and Edge support an "unselectable" attribute that - // prevents an element from receiving focus, exactly what we want here. - .attr( { - "unselectable": "on" - } ) - .menu( "instance" ); - - this._addClass( this.menu.element, "ui-autocomplete", "ui-front" ); - this._on( this.menu.element, { - mousedown: function( event ) { - - // Prevent moving focus out of the text field - event.preventDefault(); - }, - menufocus: function( event, ui ) { - var label, item; - - // support: Firefox - // Prevent accidental activation of menu items in Firefox (#7024 #9118) - if ( this.isNewMenu ) { - this.isNewMenu = false; - if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) { - this.menu.blur(); - - this.document.one( "mousemove", function() { - $( event.target ).trigger( event.originalEvent ); - } ); - - return; - } - } - - item = ui.item.data( "ui-autocomplete-item" ); - if ( false !== this._trigger( "focus", event, { item: item } ) ) { - - // use value to match what will end up in the input, if it was a key event - if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) { - this._value( item.value ); - } - } - - // Announce the value in the liveRegion - label = ui.item.attr( "aria-label" ) || item.value; - if ( label && String.prototype.trim.call( label ).length ) { - clearTimeout( this.liveRegionTimer ); - this.liveRegionTimer = this._delay( function() { - this.liveRegion.html( $( "<div>" ).text( label ) ); - }, 100 ); - } - }, - menuselect: function( event, ui ) { - var item = ui.item.data( "ui-autocomplete-item" ), - previous = this.previous; - - // Only trigger when focus was lost (click on menu) - if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) { - this.element.trigger( "focus" ); - this.previous = previous; - - // #6109 - IE triggers two focus events and the second - // is asynchronous, so we need to reset the previous - // term synchronously and asynchronously :-( - this._delay( function() { - this.previous = previous; - this.selectedItem = item; - } ); - } - - if ( false !== this._trigger( "select", event, { item: item } ) ) { - this._value( item.value ); - } - - // reset the term after the select event - // this allows custom select handling to work properly - this.term = this._value(); - - this.close( event ); - this.selectedItem = item; - } - } ); - - this.liveRegion = $( "<div>", { - role: "status", - "aria-live": "assertive", - "aria-relevant": "additions" - } ) - .appendTo( this.document[ 0 ].body ); - - this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" ); - - // Turning off autocomplete prevents the browser from remembering the - // value when navigating through history, so we re-enable autocomplete - // if the page is unloaded before the widget is destroyed. #7790 - this._on( this.window, { - beforeunload: function() { - this.element.removeAttr( "autocomplete" ); - } - } ); - }, - - _destroy: function() { - clearTimeout( this.searching ); - this.element.removeAttr( "autocomplete" ); - this.menu.element.remove(); - this.liveRegion.remove(); - }, - - _setOption: function( key, value ) { - this._super( key, value ); - if ( key === "source" ) { - this._initSource(); - } - if ( key === "appendTo" ) { - this.menu.element.appendTo( this._appendTo() ); - } - if ( key === "disabled" && value && this.xhr ) { - this.xhr.abort(); - } - }, - - _isEventTargetInWidget: function( event ) { - var menuElement = this.menu.element[ 0 ]; - - return event.target === this.element[ 0 ] || - event.target === menuElement || - $.contains( menuElement, event.target ); - }, - - _closeOnClickOutside: function( event ) { - if ( !this._isEventTargetInWidget( event ) ) { - this.close(); - } - }, - - _appendTo: function() { - var element = this.options.appendTo; - - if ( element ) { - element = element.jquery || element.nodeType ? - $( element ) : - this.document.find( element ).eq( 0 ); - } - - if ( !element || !element[ 0 ] ) { - element = this.element.closest( ".ui-front, dialog" ); - } - - if ( !element.length ) { - element = this.document[ 0 ].body; - } - - return element; - }, - - _initSource: function() { - var array, url, - that = this; - if ( Array.isArray( this.options.source ) ) { - array = this.options.source; - this.source = function( request, response ) { - response( $.ui.autocomplete.filter( array, request.term ) ); - }; - } else if ( typeof this.options.source === "string" ) { - url = this.options.source; - this.source = function( request, response ) { - if ( that.xhr ) { - that.xhr.abort(); - } - that.xhr = $.ajax( { - url: url, - data: request, - dataType: "json", - success: function( data ) { - response( data ); - }, - error: function() { - response( [] ); - } - } ); - }; - } else { - this.source = this.options.source; - } - }, - - _searchTimeout: function( event ) { - clearTimeout( this.searching ); - this.searching = this._delay( function() { - - // Search if the value has changed, or if the user retypes the same value (see #7434) - var equalValues = this.term === this._value(), - menuVisible = this.menu.element.is( ":visible" ), - modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey; - - if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) { - this.selectedItem = null; - this.search( null, event ); - } - }, this.options.delay ); - }, - - search: function( value, event ) { - value = value != null ? value : this._value(); - - // Always save the actual value, not the one passed as an argument - this.term = this._value(); - - if ( value.length < this.options.minLength ) { - return this.close( event ); - } - - if ( this._trigger( "search", event ) === false ) { - return; - } - - return this._search( value ); - }, - - _search: function( value ) { - this.pending++; - this._addClass( "ui-autocomplete-loading" ); - this.cancelSearch = false; - - this.source( { term: value }, this._response() ); - }, - - _response: function() { - var index = ++this.requestIndex; - - return function( content ) { - if ( index === this.requestIndex ) { - this.__response( content ); - } - - this.pending--; - if ( !this.pending ) { - this._removeClass( "ui-autocomplete-loading" ); - } - }.bind( this ); - }, - - __response: function( content ) { - if ( content ) { - content = this._normalize( content ); - } - this._trigger( "response", null, { content: content } ); - if ( !this.options.disabled && content && content.length && !this.cancelSearch ) { - this._suggest( content ); - this._trigger( "open" ); - } else { - - // use ._close() instead of .close() so we don't cancel future searches - this._close(); - } - }, - - close: function( event ) { - this.cancelSearch = true; - this._close( event ); - }, - - _close: function( event ) { - - // Remove the handler that closes the menu on outside clicks - this._off( this.document, "mousedown" ); - - if ( this.menu.element.is( ":visible" ) ) { - this.menu.element.hide(); - this.menu.blur(); - this.isNewMenu = true; - this._trigger( "close", event ); - } - }, - - _change: function( event ) { - if ( this.previous !== this._value() ) { - this._trigger( "change", event, { item: this.selectedItem } ); - } - }, - - _normalize: function( items ) { - - // assume all items have the right format when the first item is complete - if ( items.length && items[ 0 ].label && items[ 0 ].value ) { - return items; - } - return $.map( items, function( item ) { - if ( typeof item === "string" ) { - return { - label: item, - value: item - }; - } - return $.extend( {}, item, { - label: item.label || item.value, - value: item.value || item.label - } ); - } ); - }, - - _suggest: function( items ) { - var ul = this.menu.element.empty(); - this._renderMenu( ul, items ); - this.isNewMenu = true; - this.menu.refresh(); - - // Size and position menu - ul.show(); - this._resizeMenu(); - ul.position( $.extend( { - of: this.element - }, this.options.position ) ); - - if ( this.options.autoFocus ) { - this.menu.next(); - } - - // Listen for interactions outside of the widget (#6642) - this._on( this.document, { - mousedown: "_closeOnClickOutside" - } ); - }, - - _resizeMenu: function() { - var ul = this.menu.element; - ul.outerWidth( Math.max( - - // Firefox wraps long text (possibly a rounding bug) - // so we add 1px to avoid the wrapping (#7513) - ul.width( "" ).outerWidth() + 1, - this.element.outerWidth() - ) ); - }, - - _renderMenu: function( ul, items ) { - var that = this; - $.each( items, function( index, item ) { - that._renderItemData( ul, item ); - } ); - }, - - _renderItemData: function( ul, item ) { - return this._renderItem( ul, item ).data( "ui-autocomplete-item", item ); - }, - - _renderItem: function( ul, item ) { - return $( "<li>" ) - .append( $( "<div>" ).text( item.label ) ) - .appendTo( ul ); - }, - - _move: function( direction, event ) { - if ( !this.menu.element.is( ":visible" ) ) { - this.search( null, event ); - return; - } - if ( this.menu.isFirstItem() && /^previous/.test( direction ) || - this.menu.isLastItem() && /^next/.test( direction ) ) { - - if ( !this.isMultiLine ) { - this._value( this.term ); - } - - this.menu.blur(); - return; - } - this.menu[ direction ]( event ); - }, - - widget: function() { - return this.menu.element; - }, - - _value: function() { - return this.valueMethod.apply( this.element, arguments ); - }, - - _keyEvent: function( keyEvent, event ) { - if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { - this._move( keyEvent, event ); - - // Prevents moving cursor to beginning/end of the text field in some browsers - event.preventDefault(); - } - }, - - // Support: Chrome <=50 - // We should be able to just use this.element.prop( "isContentEditable" ) - // but hidden elements always report false in Chrome. - // https://code.google.com/p/chromium/issues/detail?id=313082 - _isContentEditable: function( element ) { - if ( !element.length ) { - return false; - } - - var editable = element.prop( "contentEditable" ); - - if ( editable === "inherit" ) { - return this._isContentEditable( element.parent() ); - } - - return editable === "true"; - } -} ); - -$.extend( $.ui.autocomplete, { - escapeRegex: function( value ) { - return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ); - }, - filter: function( array, term ) { - var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" ); - return $.grep( array, function( value ) { - return matcher.test( value.label || value.value || value ); - } ); - } -} ); + "use strict"; + + $.widget( "ui.autocomplete", { + version: "1.13.2", + defaultElement: "<input>", + options: { + appendTo: null, + autoFocus: false, + delay: 300, + minLength: 1, + position: { + my: "left top", + at: "left bottom", + collision: "none" + }, + source: null, + + // Callbacks + change: null, + close: null, + focus: null, + open: null, + response: null, + search: null, + select: null + }, + + requestIndex: 0, + pending: 0, + liveRegionTimer: null, + + _create: function() { + + // Some browsers only repeat keydown events, not keypress events, + // so we use the suppressKeyPress flag to determine if we've already + // handled the keydown event. #7269 + // Unfortunately the code for & in keypress is the same as the up arrow, + // so we use the suppressKeyPressRepeat flag to avoid handling keypress + // events when we know the keydown event was used to modify the + // search term. #7799 + var suppressKeyPress, suppressKeyPressRepeat, suppressInput, + nodeName = this.element[ 0 ].nodeName.toLowerCase(), + isTextarea = nodeName === "textarea", + isInput = nodeName === "input"; + + // Textareas are always multi-line + // Inputs are always single-line, even if inside a contentEditable element + // IE also treats inputs as contentEditable + // All other element types are determined by whether or not they're contentEditable + this.isMultiLine = isTextarea || !isInput && this._isContentEditable( this.element ); + + this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ]; + this.isNewMenu = true; + + this._addClass( "ui-autocomplete-input" ); + this.element.attr( "autocomplete", "off" ); + + this._on( this.element, { + keydown: function( event ) { + if ( this.element.prop( "readOnly" ) ) { + suppressKeyPress = true; + suppressInput = true; + suppressKeyPressRepeat = true; + return; + } + + suppressKeyPress = false; + suppressInput = false; + suppressKeyPressRepeat = false; + var keyCode = $.ui.keyCode; + switch ( event.keyCode ) { + case keyCode.PAGE_UP: + suppressKeyPress = true; + this._move( "previousPage", event ); + break; + case keyCode.PAGE_DOWN: + suppressKeyPress = true; + this._move( "nextPage", event ); + break; + case keyCode.UP: + suppressKeyPress = true; + this._keyEvent( "previous", event ); + break; + case keyCode.DOWN: + suppressKeyPress = true; + this._keyEvent( "next", event ); + break; + case keyCode.ENTER: + + // when menu is open and has focus + if ( this.menu.active ) { + + // #6055 - Opera still allows the keypress to occur + // which causes forms to submit + suppressKeyPress = true; + event.preventDefault(); + this.menu.select( event ); + } + break; + case keyCode.TAB: + if ( this.menu.active ) { + this.menu.select( event ); + } + break; + case keyCode.ESCAPE: + if ( this.menu.element.is( ":visible" ) ) { + if ( !this.isMultiLine ) { + this._value( this.term ); + } + this.close( event ); + + // Different browsers have different default behavior for escape + // Single press can mean undo or clear + // Double press in IE means clear the whole form + event.preventDefault(); + } + break; + default: + suppressKeyPressRepeat = true; + + // search timeout should be triggered before the input value is changed + this._searchTimeout( event ); + break; + } + }, + keypress: function( event ) { + if ( suppressKeyPress ) { + suppressKeyPress = false; + if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { + event.preventDefault(); + } + return; + } + if ( suppressKeyPressRepeat ) { + return; + } + + // Replicate some key handlers to allow them to repeat in Firefox and Opera + var keyCode = $.ui.keyCode; + switch ( event.keyCode ) { + case keyCode.PAGE_UP: + this._move( "previousPage", event ); + break; + case keyCode.PAGE_DOWN: + this._move( "nextPage", event ); + break; + case keyCode.UP: + this._keyEvent( "previous", event ); + break; + case keyCode.DOWN: + this._keyEvent( "next", event ); + break; + } + }, + input: function( event ) { + if ( suppressInput ) { + suppressInput = false; + event.preventDefault(); + return; + } + this._searchTimeout( event ); + }, + focus: function() { + this.selectedItem = null; + this.previous = this._value(); + }, + blur: function( event ) { + clearTimeout( this.searching ); + this.close( event ); + this._change( event ); + } + } ); + + this._initSource(); + this.menu = $( "<ul>" ) + .appendTo( this._appendTo() ) + .menu( { + + // disable ARIA support, the live region takes care of that + role: null + } ) + .hide() + + // Support: IE 11 only, Edge <= 14 + // For other browsers, we preventDefault() on the mousedown event + // to keep the dropdown from taking focus from the input. This doesn't + // work for IE/Edge, causing problems with selection and scrolling (#9638) + // Happily, IE and Edge support an "unselectable" attribute that + // prevents an element from receiving focus, exactly what we want here. + .attr( { + "unselectable": "on" + } ) + .menu( "instance" ); + + this._addClass( this.menu.element, "ui-autocomplete", "ui-front" ); + this._on( this.menu.element, { + mousedown: function( event ) { + + // Prevent moving focus out of the text field + event.preventDefault(); + }, + menufocus: function( event, ui ) { + var label, item; + + // support: Firefox + // Prevent accidental activation of menu items in Firefox (#7024 #9118) + if ( this.isNewMenu ) { + this.isNewMenu = false; + if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) { + this.menu.blur(); + + this.document.one( "mousemove", function() { + $( event.target ).trigger( event.originalEvent ); + } ); + + return; + } + } + + item = ui.item.data( "ui-autocomplete-item" ); + if ( false !== this._trigger( "focus", event, { item: item } ) ) { + + // use value to match what will end up in the input, if it was a key event + if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) { + this._value( item.value ); + } + } + + // Announce the value in the liveRegion + label = ui.item.attr( "aria-label" ) || item.value; + if ( label && String.prototype.trim.call( label ).length ) { + clearTimeout( this.liveRegionTimer ); + this.liveRegionTimer = this._delay( function() { + this.liveRegion.html( $( "<div>" ).text( label ) ); + }, 100 ); + } + }, + menuselect: function( event, ui ) { + var item = ui.item.data( "ui-autocomplete-item" ), + previous = this.previous; + + // Only trigger when focus was lost (click on menu) + if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) { + this.element.trigger( "focus" ); + this.previous = previous; + + // #6109 - IE triggers two focus events and the second + // is asynchronous, so we need to reset the previous + // term synchronously and asynchronously :-( + this._delay( function() { + this.previous = previous; + this.selectedItem = item; + } ); + } + + if ( false !== this._trigger( "select", event, { item: item } ) ) { + this._value( item.value ); + } + + // reset the term after the select event + // this allows custom select handling to work properly + this.term = this._value(); + + this.close( event ); + this.selectedItem = item; + } + } ); + + this.liveRegion = $( "<div>", { + role: "status", + "aria-live": "assertive", + "aria-relevant": "additions" + } ) + .appendTo( this.document[ 0 ].body ); + + this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" ); + + // Turning off autocomplete prevents the browser from remembering the + // value when navigating through history, so we re-enable autocomplete + // if the page is unloaded before the widget is destroyed. #7790 + this._on( this.window, { + beforeunload: function() { + this.element.removeAttr( "autocomplete" ); + } + } ); + }, + + _destroy: function() { + clearTimeout( this.searching ); + this.element.removeAttr( "autocomplete" ); + this.menu.element.remove(); + this.liveRegion.remove(); + }, + + _setOption: function( key, value ) { + this._super( key, value ); + if ( key === "source" ) { + this._initSource(); + } + if ( key === "appendTo" ) { + this.menu.element.appendTo( this._appendTo() ); + } + if ( key === "disabled" && value && this.xhr ) { + this.xhr.abort(); + } + }, + + _isEventTargetInWidget: function( event ) { + var menuElement = this.menu.element[ 0 ]; + + return event.target === this.element[ 0 ] || + event.target === menuElement || + $.contains( menuElement, event.target ); + }, + + _closeOnClickOutside: function( event ) { + if ( !this._isEventTargetInWidget( event ) ) { + this.close(); + } + }, + + _appendTo: function() { + var element = this.options.appendTo; + + if ( element ) { + element = element.jquery || element.nodeType ? + $( element ) : + this.document.find( element ).eq( 0 ); + } + + if ( !element || !element[ 0 ] ) { + element = this.element.closest( ".ui-front, dialog" ); + } + + if ( !element.length ) { + element = this.document[ 0 ].body; + } + + return element; + }, + + _initSource: function() { + var array, url, + that = this; + if ( Array.isArray( this.options.source ) ) { + array = this.options.source; + this.source = function( request, response ) { + response( $.ui.autocomplete.filter( array, request.term ) ); + }; + } else if ( typeof this.options.source === "string" ) { + url = this.options.source; + this.source = function( request, response ) { + if ( that.xhr ) { + that.xhr.abort(); + } + that.xhr = $.ajax( { + url: url, + data: request, + dataType: "json", + success: function( data ) { + response( data ); + }, + error: function() { + response( [] ); + } + } ); + }; + } else { + this.source = this.options.source; + } + }, + + _searchTimeout: function( event ) { + clearTimeout( this.searching ); + this.searching = this._delay( function() { + + // Search if the value has changed, or if the user retypes the same value (see #7434) + var equalValues = this.term === this._value(), + menuVisible = this.menu.element.is( ":visible" ), + modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey; + + if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) { + this.selectedItem = null; + this.search( null, event ); + } + }, this.options.delay ); + }, + + search: function( value, event ) { + value = value != null ? value : this._value(); + + // Always save the actual value, not the one passed as an argument + this.term = this._value(); + + if ( value.length < this.options.minLength ) { + return this.close( event ); + } + + if ( this._trigger( "search", event ) === false ) { + return; + } + + return this._search( value ); + }, + + _search: function( value ) { + this.pending++; + this._addClass( "ui-autocomplete-loading" ); + this.cancelSearch = false; + + this.source( { term: value }, this._response() ); + }, + + _response: function() { + var index = ++this.requestIndex; + + return function( content ) { + if ( index === this.requestIndex ) { + this.__response( content ); + } + + this.pending--; + if ( !this.pending ) { + this._removeClass( "ui-autocomplete-loading" ); + } + }.bind( this ); + }, + + __response: function( content ) { + if ( content ) { + content = this._normalize( content ); + } + this._trigger( "response", null, { content: content } ); + if ( !this.options.disabled && content && content.length && !this.cancelSearch ) { + this._suggest( content ); + this._trigger( "open" ); + } else { + + // use ._close() instead of .close() so we don't cancel future searches + this._close(); + } + }, + + close: function( event ) { + this.cancelSearch = true; + this._close( event ); + }, + + _close: function( event ) { + + // Remove the handler that closes the menu on outside clicks + this._off( this.document, "mousedown" ); + + if ( this.menu.element.is( ":visible" ) ) { + this.menu.element.hide(); + this.menu.blur(); + this.isNewMenu = true; + this._trigger( "close", event ); + } + }, + + _change: function( event ) { + if ( this.previous !== this._value() ) { + this._trigger( "change", event, { item: this.selectedItem } ); + } + }, + + _normalize: function( items ) { + + // assume all items have the right format when the first item is complete + if ( items.length && items[ 0 ].label && items[ 0 ].value ) { + return items; + } + return $.map( items, function( item ) { + if ( typeof item === "string" ) { + return { + label: item, + value: item + }; + } + return $.extend( {}, item, { + label: item.label || item.value, + value: item.value || item.label + } ); + } ); + }, + + _suggest: function( items ) { + var ul = this.menu.element.empty(); + this._renderMenu( ul, items ); + this.isNewMenu = true; + this.menu.refresh(); + + // Size and position menu + ul.show(); + this._resizeMenu(); + ul.position( $.extend( { + of: this.element + }, this.options.position ) ); + + if ( this.options.autoFocus ) { + this.menu.next(); + } + + // Listen for interactions outside of the widget (#6642) + this._on( this.document, { + mousedown: "_closeOnClickOutside" + } ); + }, + + _resizeMenu: function() { + var ul = this.menu.element; + ul.outerWidth( Math.max( + + // Firefox wraps long text (possibly a rounding bug) + // so we add 1px to avoid the wrapping (#7513) + ul.width( "" ).outerWidth() + 1, + this.element.outerWidth() + ) ); + }, + + _renderMenu: function( ul, items ) { + var that = this; + $.each( items, function( index, item ) { + that._renderItemData( ul, item ); + } ); + }, + + _renderItemData: function( ul, item ) { + return this._renderItem( ul, item ).data( "ui-autocomplete-item", item ); + }, + + _renderItem: function( ul, item ) { + return $( "<li>" ) + .append( $( "<div>" ).text( item.label ) ) + .appendTo( ul ); + }, + + _move: function( direction, event ) { + if ( !this.menu.element.is( ":visible" ) ) { + this.search( null, event ); + return; + } + if ( this.menu.isFirstItem() && /^previous/.test( direction ) || + this.menu.isLastItem() && /^next/.test( direction ) ) { + + if ( !this.isMultiLine ) { + this._value( this.term ); + } + + this.menu.blur(); + return; + } + this.menu[ direction ]( event ); + }, + + widget: function() { + return this.menu.element; + }, + + _value: function() { + return this.valueMethod.apply( this.element, arguments ); + }, + + _keyEvent: function( keyEvent, event ) { + if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { + this._move( keyEvent, event ); + + // Prevents moving cursor to beginning/end of the text field in some browsers + event.preventDefault(); + } + }, + + // Support: Chrome <=50 + // We should be able to just use this.element.prop( "isContentEditable" ) + // but hidden elements always report false in Chrome. + // https://code.google.com/p/chromium/issues/detail?id=313082 + _isContentEditable: function( element ) { + if ( !element.length ) { + return false; + } + + var editable = element.prop( "contentEditable" ); + + if ( editable === "inherit" ) { + return this._isContentEditable( element.parent() ); + } + + return editable === "true"; + } + } ); + + $.extend( $.ui.autocomplete, { + escapeRegex: function( value ) { + return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ); + }, + filter: function( array, term ) { + var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" ); + return $.grep( array, function( value ) { + return matcher.test( value.label || value.value || value ); + } ); + } + } ); // Live region extension, adding a `messages` option // NOTE: This is an experimental API. We are still investigating // a full solution for string manipulation and internationalization. -$.widget( "ui.autocomplete", $.ui.autocomplete, { - options: { - messages: { - noResults: "No search results.", - results: function( amount ) { - return amount + ( amount > 1 ? " results are" : " result is" ) + - " available, use up and down arrow keys to navigate."; - } - } - }, - - __response: function( content ) { - var message; - this._superApply( arguments ); - if ( this.options.disabled || this.cancelSearch ) { - return; - } - if ( content && content.length ) { - message = this.options.messages.results( content.length ); - } else { - message = this.options.messages.noResults; - } - clearTimeout( this.liveRegionTimer ); - this.liveRegionTimer = this._delay( function() { - this.liveRegion.html( $( "<div>" ).text( message ) ); - }, 100 ); - } -} ); - -return $.ui.autocomplete; + $.widget( "ui.autocomplete", $.ui.autocomplete, { + options: { + messages: { + noResults: "No search results.", + results: function( amount ) { + return amount + ( amount > 1 ? " results are" : " result is" ) + + " available, use up and down arrow keys to navigate."; + } + } + }, + + __response: function( content ) { + var message; + this._superApply( arguments ); + if ( this.options.disabled || this.cancelSearch ) { + return; + } + if ( content && content.length ) { + message = this.options.messages.results( content.length ); + } else { + message = this.options.messages.noResults; + } + clearTimeout( this.liveRegionTimer ); + this.liveRegionTimer = this._delay( function() { + this.liveRegion.html( $( "<div>" ).text( message ) ); + }, 100 ); + } + } ); + + return $.ui.autocomplete; } ); diff --git a/lib/web/jquery/ui-modules/widgets/button.js b/lib/web/jquery/ui-modules/widgets/button.js index 398c4ef55307b..f24e5b36ea2b6 100644 --- a/lib/web/jquery/ui-modules/widgets/button.js +++ b/lib/web/jquery/ui-modules/widgets/button.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Button 1.13.1 + * jQuery UI Button 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -17,433 +17,433 @@ //>>css.theme: ../../themes/base/theme.css ( function( factory ) { - "use strict"; + "use strict"; - if ( typeof define === "function" && define.amd ) { + if ( typeof define === "function" && define.amd ) { - // AMD. Register as an anonymous module. - define( [ - "jquery", + // AMD. Register as an anonymous module. + define( [ + "jquery", - // These are only for backcompat - // TODO: Remove after 1.12 - "./controlgroup", - "./checkboxradio", + // These are only for backcompat + // TODO: Remove after 1.12 + "./controlgroup", + "./checkboxradio", - "../keycode", - "../widget" - ], factory ); - } else { + "../keycode", + "../widget" + ], factory ); + } else { - // Browser globals - factory( jQuery ); - } + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; - -$.widget( "ui.button", { - version: "1.13.1", - defaultElement: "<button>", - options: { - classes: { - "ui-button": "ui-corner-all" - }, - disabled: null, - icon: null, - iconPosition: "beginning", - label: null, - showLabel: true - }, - - _getCreateOptions: function() { - var disabled, - - // This is to support cases like in jQuery Mobile where the base widget does have - // an implementation of _getCreateOptions - options = this._super() || {}; - - this.isInput = this.element.is( "input" ); - - disabled = this.element[ 0 ].disabled; - if ( disabled != null ) { - options.disabled = disabled; - } - - this.originalLabel = this.isInput ? this.element.val() : this.element.html(); - if ( this.originalLabel ) { - options.label = this.originalLabel; - } - - return options; - }, - - _create: function() { - if ( !this.option.showLabel & !this.options.icon ) { - this.options.showLabel = true; - } - - // We have to check the option again here even though we did in _getCreateOptions, - // because null may have been passed on init which would override what was set in - // _getCreateOptions - if ( this.options.disabled == null ) { - this.options.disabled = this.element[ 0 ].disabled || false; - } - - this.hasTitle = !!this.element.attr( "title" ); - - // Check to see if the label needs to be set or if its already correct - if ( this.options.label && this.options.label !== this.originalLabel ) { - if ( this.isInput ) { - this.element.val( this.options.label ); - } else { - this.element.html( this.options.label ); - } - } - this._addClass( "ui-button", "ui-widget" ); - this._setOption( "disabled", this.options.disabled ); - this._enhance(); - - if ( this.element.is( "a" ) ) { - this._on( { - "keyup": function( event ) { - if ( event.keyCode === $.ui.keyCode.SPACE ) { - event.preventDefault(); - - // Support: PhantomJS <= 1.9, IE 8 Only - // If a native click is available use it so we actually cause navigation - // otherwise just trigger a click event - if ( this.element[ 0 ].click ) { - this.element[ 0 ].click(); - } else { - this.element.trigger( "click" ); - } - } - } - } ); - } - }, - - _enhance: function() { - if ( !this.element.is( "button" ) ) { - this.element.attr( "role", "button" ); - } - - if ( this.options.icon ) { - this._updateIcon( "icon", this.options.icon ); - this._updateTooltip(); - } - }, - - _updateTooltip: function() { - this.title = this.element.attr( "title" ); - - if ( !this.options.showLabel && !this.title ) { - this.element.attr( "title", this.options.label ); - } - }, - - _updateIcon: function( option, value ) { - var icon = option !== "iconPosition", - position = icon ? this.options.iconPosition : value, - displayBlock = position === "top" || position === "bottom"; - - // Create icon - if ( !this.icon ) { - this.icon = $( "<span>" ); - - this._addClass( this.icon, "ui-button-icon", "ui-icon" ); - - if ( !this.options.showLabel ) { - this._addClass( "ui-button-icon-only" ); - } - } else if ( icon ) { - - // If we are updating the icon remove the old icon class - this._removeClass( this.icon, null, this.options.icon ); - } - - // If we are updating the icon add the new icon class - if ( icon ) { - this._addClass( this.icon, null, value ); - } - - this._attachIcon( position ); - - // If the icon is on top or bottom we need to add the ui-widget-icon-block class and remove - // the iconSpace if there is one. - if ( displayBlock ) { - this._addClass( this.icon, null, "ui-widget-icon-block" ); - if ( this.iconSpace ) { - this.iconSpace.remove(); - } - } else { - - // Position is beginning or end so remove the ui-widget-icon-block class and add the - // space if it does not exist - if ( !this.iconSpace ) { - this.iconSpace = $( "<span> </span>" ); - this._addClass( this.iconSpace, "ui-button-icon-space" ); - } - this._removeClass( this.icon, null, "ui-wiget-icon-block" ); - this._attachIconSpace( position ); - } - }, - - _destroy: function() { - this.element.removeAttr( "role" ); - - if ( this.icon ) { - this.icon.remove(); - } - if ( this.iconSpace ) { - this.iconSpace.remove(); - } - if ( !this.hasTitle ) { - this.element.removeAttr( "title" ); - } - }, - - _attachIconSpace: function( iconPosition ) { - this.icon[ /^(?:end|bottom)/.test( iconPosition ) ? "before" : "after" ]( this.iconSpace ); - }, - - _attachIcon: function( iconPosition ) { - this.element[ /^(?:end|bottom)/.test( iconPosition ) ? "append" : "prepend" ]( this.icon ); - }, - - _setOptions: function( options ) { - var newShowLabel = options.showLabel === undefined ? - this.options.showLabel : - options.showLabel, - newIcon = options.icon === undefined ? this.options.icon : options.icon; - - if ( !newShowLabel && !newIcon ) { - options.showLabel = true; - } - this._super( options ); - }, - - _setOption: function( key, value ) { - if ( key === "icon" ) { - if ( value ) { - this._updateIcon( key, value ); - } else if ( this.icon ) { - this.icon.remove(); - if ( this.iconSpace ) { - this.iconSpace.remove(); - } - } - } - - if ( key === "iconPosition" ) { - this._updateIcon( key, value ); - } - - // Make sure we can't end up with a button that has neither text nor icon - if ( key === "showLabel" ) { - this._toggleClass( "ui-button-icon-only", null, !value ); - this._updateTooltip(); - } - - if ( key === "label" ) { - if ( this.isInput ) { - this.element.val( value ); - } else { - - // If there is an icon, append it, else nothing then append the value - // this avoids removal of the icon when setting label text - this.element.html( value ); - if ( this.icon ) { - this._attachIcon( this.options.iconPosition ); - this._attachIconSpace( this.options.iconPosition ); - } - } - } - - this._super( key, value ); - - if ( key === "disabled" ) { - this._toggleClass( null, "ui-state-disabled", value ); - this.element[ 0 ].disabled = value; - if ( value ) { - this.element.trigger( "blur" ); - } - } - }, - - refresh: function() { - - // Make sure to only check disabled if its an element that supports this otherwise - // check for the disabled class to determine state - var isDisabled = this.element.is( "input, button" ) ? - this.element[ 0 ].disabled : this.element.hasClass( "ui-button-disabled" ); - - if ( isDisabled !== this.options.disabled ) { - this._setOptions( { disabled: isDisabled } ); - } - - this._updateTooltip(); - } -} ); + "use strict"; + + $.widget( "ui.button", { + version: "1.13.2", + defaultElement: "<button>", + options: { + classes: { + "ui-button": "ui-corner-all" + }, + disabled: null, + icon: null, + iconPosition: "beginning", + label: null, + showLabel: true + }, + + _getCreateOptions: function() { + var disabled, + + // This is to support cases like in jQuery Mobile where the base widget does have + // an implementation of _getCreateOptions + options = this._super() || {}; + + this.isInput = this.element.is( "input" ); + + disabled = this.element[ 0 ].disabled; + if ( disabled != null ) { + options.disabled = disabled; + } + + this.originalLabel = this.isInput ? this.element.val() : this.element.html(); + if ( this.originalLabel ) { + options.label = this.originalLabel; + } + + return options; + }, + + _create: function() { + if ( !this.option.showLabel & !this.options.icon ) { + this.options.showLabel = true; + } + + // We have to check the option again here even though we did in _getCreateOptions, + // because null may have been passed on init which would override what was set in + // _getCreateOptions + if ( this.options.disabled == null ) { + this.options.disabled = this.element[ 0 ].disabled || false; + } + + this.hasTitle = !!this.element.attr( "title" ); + + // Check to see if the label needs to be set or if its already correct + if ( this.options.label && this.options.label !== this.originalLabel ) { + if ( this.isInput ) { + this.element.val( this.options.label ); + } else { + this.element.html( this.options.label ); + } + } + this._addClass( "ui-button", "ui-widget" ); + this._setOption( "disabled", this.options.disabled ); + this._enhance(); + + if ( this.element.is( "a" ) ) { + this._on( { + "keyup": function( event ) { + if ( event.keyCode === $.ui.keyCode.SPACE ) { + event.preventDefault(); + + // Support: PhantomJS <= 1.9, IE 8 Only + // If a native click is available use it so we actually cause navigation + // otherwise just trigger a click event + if ( this.element[ 0 ].click ) { + this.element[ 0 ].click(); + } else { + this.element.trigger( "click" ); + } + } + } + } ); + } + }, + + _enhance: function() { + if ( !this.element.is( "button" ) ) { + this.element.attr( "role", "button" ); + } + + if ( this.options.icon ) { + this._updateIcon( "icon", this.options.icon ); + this._updateTooltip(); + } + }, + + _updateTooltip: function() { + this.title = this.element.attr( "title" ); + + if ( !this.options.showLabel && !this.title ) { + this.element.attr( "title", this.options.label ); + } + }, + + _updateIcon: function( option, value ) { + var icon = option !== "iconPosition", + position = icon ? this.options.iconPosition : value, + displayBlock = position === "top" || position === "bottom"; + + // Create icon + if ( !this.icon ) { + this.icon = $( "<span>" ); + + this._addClass( this.icon, "ui-button-icon", "ui-icon" ); + + if ( !this.options.showLabel ) { + this._addClass( "ui-button-icon-only" ); + } + } else if ( icon ) { + + // If we are updating the icon remove the old icon class + this._removeClass( this.icon, null, this.options.icon ); + } + + // If we are updating the icon add the new icon class + if ( icon ) { + this._addClass( this.icon, null, value ); + } + + this._attachIcon( position ); + + // If the icon is on top or bottom we need to add the ui-widget-icon-block class and remove + // the iconSpace if there is one. + if ( displayBlock ) { + this._addClass( this.icon, null, "ui-widget-icon-block" ); + if ( this.iconSpace ) { + this.iconSpace.remove(); + } + } else { + + // Position is beginning or end so remove the ui-widget-icon-block class and add the + // space if it does not exist + if ( !this.iconSpace ) { + this.iconSpace = $( "<span> </span>" ); + this._addClass( this.iconSpace, "ui-button-icon-space" ); + } + this._removeClass( this.icon, null, "ui-wiget-icon-block" ); + this._attachIconSpace( position ); + } + }, + + _destroy: function() { + this.element.removeAttr( "role" ); + + if ( this.icon ) { + this.icon.remove(); + } + if ( this.iconSpace ) { + this.iconSpace.remove(); + } + if ( !this.hasTitle ) { + this.element.removeAttr( "title" ); + } + }, + + _attachIconSpace: function( iconPosition ) { + this.icon[ /^(?:end|bottom)/.test( iconPosition ) ? "before" : "after" ]( this.iconSpace ); + }, + + _attachIcon: function( iconPosition ) { + this.element[ /^(?:end|bottom)/.test( iconPosition ) ? "append" : "prepend" ]( this.icon ); + }, + + _setOptions: function( options ) { + var newShowLabel = options.showLabel === undefined ? + this.options.showLabel : + options.showLabel, + newIcon = options.icon === undefined ? this.options.icon : options.icon; + + if ( !newShowLabel && !newIcon ) { + options.showLabel = true; + } + this._super( options ); + }, + + _setOption: function( key, value ) { + if ( key === "icon" ) { + if ( value ) { + this._updateIcon( key, value ); + } else if ( this.icon ) { + this.icon.remove(); + if ( this.iconSpace ) { + this.iconSpace.remove(); + } + } + } + + if ( key === "iconPosition" ) { + this._updateIcon( key, value ); + } + + // Make sure we can't end up with a button that has neither text nor icon + if ( key === "showLabel" ) { + this._toggleClass( "ui-button-icon-only", null, !value ); + this._updateTooltip(); + } + + if ( key === "label" ) { + if ( this.isInput ) { + this.element.val( value ); + } else { + + // If there is an icon, append it, else nothing then append the value + // this avoids removal of the icon when setting label text + this.element.html( value ); + if ( this.icon ) { + this._attachIcon( this.options.iconPosition ); + this._attachIconSpace( this.options.iconPosition ); + } + } + } + + this._super( key, value ); + + if ( key === "disabled" ) { + this._toggleClass( null, "ui-state-disabled", value ); + this.element[ 0 ].disabled = value; + if ( value ) { + this.element.trigger( "blur" ); + } + } + }, + + refresh: function() { + + // Make sure to only check disabled if its an element that supports this otherwise + // check for the disabled class to determine state + var isDisabled = this.element.is( "input, button" ) ? + this.element[ 0 ].disabled : this.element.hasClass( "ui-button-disabled" ); + + if ( isDisabled !== this.options.disabled ) { + this._setOptions( { disabled: isDisabled } ); + } + + this._updateTooltip(); + } + } ); // DEPRECATED -if ( $.uiBackCompat !== false ) { - - // Text and Icons options - $.widget( "ui.button", $.ui.button, { - options: { - text: true, - icons: { - primary: null, - secondary: null - } - }, - - _create: function() { - if ( this.options.showLabel && !this.options.text ) { - this.options.showLabel = this.options.text; - } - if ( !this.options.showLabel && this.options.text ) { - this.options.text = this.options.showLabel; - } - if ( !this.options.icon && ( this.options.icons.primary || - this.options.icons.secondary ) ) { - if ( this.options.icons.primary ) { - this.options.icon = this.options.icons.primary; - } else { - this.options.icon = this.options.icons.secondary; - this.options.iconPosition = "end"; - } - } else if ( this.options.icon ) { - this.options.icons.primary = this.options.icon; - } - this._super(); - }, - - _setOption: function( key, value ) { - if ( key === "text" ) { - this._super( "showLabel", value ); - return; - } - if ( key === "showLabel" ) { - this.options.text = value; - } - if ( key === "icon" ) { - this.options.icons.primary = value; - } - if ( key === "icons" ) { - if ( value.primary ) { - this._super( "icon", value.primary ); - this._super( "iconPosition", "beginning" ); - } else if ( value.secondary ) { - this._super( "icon", value.secondary ); - this._super( "iconPosition", "end" ); - } - } - this._superApply( arguments ); - } - } ); - - $.fn.button = ( function( orig ) { - return function( options ) { - var isMethodCall = typeof options === "string"; - var args = Array.prototype.slice.call( arguments, 1 ); - var returnValue = this; - - if ( isMethodCall ) { - - // If this is an empty collection, we need to have the instance method - // return undefined instead of the jQuery instance - if ( !this.length && options === "instance" ) { - returnValue = undefined; - } else { - this.each( function() { - var methodValue; - var type = $( this ).attr( "type" ); - var name = type !== "checkbox" && type !== "radio" ? - "button" : - "checkboxradio"; - var instance = $.data( this, "ui-" + name ); - - if ( options === "instance" ) { - returnValue = instance; - return false; - } - - if ( !instance ) { - return $.error( "cannot call methods on button" + - " prior to initialization; " + - "attempted to call method '" + options + "'" ); - } - - if ( typeof instance[ options ] !== "function" || - options.charAt( 0 ) === "_" ) { - return $.error( "no such method '" + options + "' for button" + - " widget instance" ); - } - - methodValue = instance[ options ].apply( instance, args ); - - if ( methodValue !== instance && methodValue !== undefined ) { - returnValue = methodValue && methodValue.jquery ? - returnValue.pushStack( methodValue.get() ) : - methodValue; - return false; - } - } ); - } - } else { - - // Allow multiple hashes to be passed on init - if ( args.length ) { - options = $.widget.extend.apply( null, [ options ].concat( args ) ); - } - - this.each( function() { - var type = $( this ).attr( "type" ); - var name = type !== "checkbox" && type !== "radio" ? "button" : "checkboxradio"; - var instance = $.data( this, "ui-" + name ); - - if ( instance ) { - instance.option( options || {} ); - if ( instance._init ) { - instance._init(); - } - } else { - if ( name === "button" ) { - orig.call( $( this ), options ); - return; - } - - $( this ).checkboxradio( $.extend( { icon: false }, options ) ); - } - } ); - } - - return returnValue; - }; - } )( $.fn.button ); - - $.fn.buttonset = function() { - if ( !$.ui.controlgroup ) { - $.error( "Controlgroup widget missing" ); - } - if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" && arguments[ 2 ] ) { - return this.controlgroup.apply( this, - [ arguments[ 0 ], "items.button", arguments[ 2 ] ] ); - } - if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" ) { - return this.controlgroup.apply( this, [ arguments[ 0 ], "items.button" ] ); - } - if ( typeof arguments[ 0 ] === "object" && arguments[ 0 ].items ) { - arguments[ 0 ].items = { - button: arguments[ 0 ].items - }; - } - return this.controlgroup.apply( this, arguments ); - }; -} - -return $.ui.button; + if ( $.uiBackCompat !== false ) { + + // Text and Icons options + $.widget( "ui.button", $.ui.button, { + options: { + text: true, + icons: { + primary: null, + secondary: null + } + }, + + _create: function() { + if ( this.options.showLabel && !this.options.text ) { + this.options.showLabel = this.options.text; + } + if ( !this.options.showLabel && this.options.text ) { + this.options.text = this.options.showLabel; + } + if ( !this.options.icon && ( this.options.icons.primary || + this.options.icons.secondary ) ) { + if ( this.options.icons.primary ) { + this.options.icon = this.options.icons.primary; + } else { + this.options.icon = this.options.icons.secondary; + this.options.iconPosition = "end"; + } + } else if ( this.options.icon ) { + this.options.icons.primary = this.options.icon; + } + this._super(); + }, + + _setOption: function( key, value ) { + if ( key === "text" ) { + this._super( "showLabel", value ); + return; + } + if ( key === "showLabel" ) { + this.options.text = value; + } + if ( key === "icon" ) { + this.options.icons.primary = value; + } + if ( key === "icons" ) { + if ( value.primary ) { + this._super( "icon", value.primary ); + this._super( "iconPosition", "beginning" ); + } else if ( value.secondary ) { + this._super( "icon", value.secondary ); + this._super( "iconPosition", "end" ); + } + } + this._superApply( arguments ); + } + } ); + + $.fn.button = ( function( orig ) { + return function( options ) { + var isMethodCall = typeof options === "string"; + var args = Array.prototype.slice.call( arguments, 1 ); + var returnValue = this; + + if ( isMethodCall ) { + + // If this is an empty collection, we need to have the instance method + // return undefined instead of the jQuery instance + if ( !this.length && options === "instance" ) { + returnValue = undefined; + } else { + this.each( function() { + var methodValue; + var type = $( this ).attr( "type" ); + var name = type !== "checkbox" && type !== "radio" ? + "button" : + "checkboxradio"; + var instance = $.data( this, "ui-" + name ); + + if ( options === "instance" ) { + returnValue = instance; + return false; + } + + if ( !instance ) { + return $.error( "cannot call methods on button" + + " prior to initialization; " + + "attempted to call method '" + options + "'" ); + } + + if ( typeof instance[ options ] !== "function" || + options.charAt( 0 ) === "_" ) { + return $.error( "no such method '" + options + "' for button" + + " widget instance" ); + } + + methodValue = instance[ options ].apply( instance, args ); + + if ( methodValue !== instance && methodValue !== undefined ) { + returnValue = methodValue && methodValue.jquery ? + returnValue.pushStack( methodValue.get() ) : + methodValue; + return false; + } + } ); + } + } else { + + // Allow multiple hashes to be passed on init + if ( args.length ) { + options = $.widget.extend.apply( null, [ options ].concat( args ) ); + } + + this.each( function() { + var type = $( this ).attr( "type" ); + var name = type !== "checkbox" && type !== "radio" ? "button" : "checkboxradio"; + var instance = $.data( this, "ui-" + name ); + + if ( instance ) { + instance.option( options || {} ); + if ( instance._init ) { + instance._init(); + } + } else { + if ( name === "button" ) { + orig.call( $( this ), options ); + return; + } + + $( this ).checkboxradio( $.extend( { icon: false }, options ) ); + } + } ); + } + + return returnValue; + }; + } )( $.fn.button ); + + $.fn.buttonset = function() { + if ( !$.ui.controlgroup ) { + $.error( "Controlgroup widget missing" ); + } + if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" && arguments[ 2 ] ) { + return this.controlgroup.apply( this, + [ arguments[ 0 ], "items.button", arguments[ 2 ] ] ); + } + if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" ) { + return this.controlgroup.apply( this, [ arguments[ 0 ], "items.button" ] ); + } + if ( typeof arguments[ 0 ] === "object" && arguments[ 0 ].items ) { + arguments[ 0 ].items = { + button: arguments[ 0 ].items + }; + } + return this.controlgroup.apply( this, arguments ); + }; + } + + return $.ui.button; } ); diff --git a/lib/web/jquery/ui-modules/widgets/checkboxradio.js b/lib/web/jquery/ui-modules/widgets/checkboxradio.js index 6ee7fe6cd201a..9d57eb56e4f63 100644 --- a/lib/web/jquery/ui-modules/widgets/checkboxradio.js +++ b/lib/web/jquery/ui-modules/widgets/checkboxradio.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Checkboxradio 1.13.1 + * jQuery UI Checkboxradio 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -18,268 +18,273 @@ //>>css.theme: ../../themes/base/theme.css ( function( factory ) { - "use strict"; - - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define( [ - "jquery", - "../form-reset-mixin", - "../labels", - "../widget" - ], factory ); - } else { - - // Browser globals - factory( jQuery ); - } + "use strict"; + + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ + "jquery", + "../form-reset-mixin", + "../labels", + "../widget" + ], factory ); + } else { + + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; - -$.widget( "ui.checkboxradio", [ $.ui.formResetMixin, { - version: "1.13.1", - options: { - disabled: null, - label: null, - icon: true, - classes: { - "ui-checkboxradio-label": "ui-corner-all", - "ui-checkboxradio-icon": "ui-corner-all" - } - }, - - _getCreateOptions: function() { - var disabled, labels; - var that = this; - var options = this._super() || {}; - - // We read the type here, because it makes more sense to throw a element type error first, - // rather then the error for lack of a label. Often if its the wrong type, it - // won't have a label (e.g. calling on a div, btn, etc) - this._readType(); - - labels = this.element.labels(); - - // If there are multiple labels, use the last one - this.label = $( labels[ labels.length - 1 ] ); - if ( !this.label.length ) { - $.error( "No label found for checkboxradio widget" ); - } - - this.originalLabel = ""; - - // We need to get the label text but this may also need to make sure it does not contain the - // input itself. - this.label.contents().not( this.element[ 0 ] ).each( function() { - - // The label contents could be text, html, or a mix. We concat each element to get a - // string representation of the label, without the input as part of it. - that.originalLabel += this.nodeType === 3 ? $( this ).text() : this.outerHTML; - } ); - - // Set the label option if we found label text - if ( this.originalLabel ) { - options.label = this.originalLabel; - } - - disabled = this.element[ 0 ].disabled; - if ( disabled != null ) { - options.disabled = disabled; - } - return options; - }, - - _create: function() { - var checked = this.element[ 0 ].checked; - - this._bindFormResetHandler(); - - if ( this.options.disabled == null ) { - this.options.disabled = this.element[ 0 ].disabled; - } - - this._setOption( "disabled", this.options.disabled ); - this._addClass( "ui-checkboxradio", "ui-helper-hidden-accessible" ); - this._addClass( this.label, "ui-checkboxradio-label", "ui-button ui-widget" ); - - if ( this.type === "radio" ) { - this._addClass( this.label, "ui-checkboxradio-radio-label" ); - } - - if ( this.options.label && this.options.label !== this.originalLabel ) { - this._updateLabel(); - } else if ( this.originalLabel ) { - this.options.label = this.originalLabel; - } - - this._enhance(); - - if ( checked ) { - this._addClass( this.label, "ui-checkboxradio-checked", "ui-state-active" ); - } - - this._on( { - change: "_toggleClasses", - focus: function() { - this._addClass( this.label, null, "ui-state-focus ui-visual-focus" ); - }, - blur: function() { - this._removeClass( this.label, null, "ui-state-focus ui-visual-focus" ); - } - } ); - }, - - _readType: function() { - var nodeName = this.element[ 0 ].nodeName.toLowerCase(); - this.type = this.element[ 0 ].type; - if ( nodeName !== "input" || !/radio|checkbox/.test( this.type ) ) { - $.error( "Can't create checkboxradio on element.nodeName=" + nodeName + - " and element.type=" + this.type ); - } - }, - - // Support jQuery Mobile enhanced option - _enhance: function() { - this._updateIcon( this.element[ 0 ].checked ); - }, - - widget: function() { - return this.label; - }, - - _getRadioGroup: function() { - var group; - var name = this.element[ 0 ].name; - var nameSelector = "input[name='" + $.escapeSelector( name ) + "']"; - - if ( !name ) { - return $( [] ); - } - - if ( this.form.length ) { - group = $( this.form[ 0 ].elements ).filter( nameSelector ); - } else { - - // Not inside a form, check all inputs that also are not inside a form - group = $( nameSelector ).filter( function() { - return $( this )._form().length === 0; - } ); - } - - return group.not( this.element ); - }, - - _toggleClasses: function() { - var checked = this.element[ 0 ].checked; - this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked ); - - if ( this.options.icon && this.type === "checkbox" ) { - this._toggleClass( this.icon, null, "ui-icon-check ui-state-checked", checked ) - ._toggleClass( this.icon, null, "ui-icon-blank", !checked ); - } - - if ( this.type === "radio" ) { - this._getRadioGroup() - .each( function() { - var instance = $( this ).checkboxradio( "instance" ); - - if ( instance ) { - instance._removeClass( instance.label, - "ui-checkboxradio-checked", "ui-state-active" ); - } - } ); - } - }, - - _destroy: function() { - this._unbindFormResetHandler(); - - if ( this.icon ) { - this.icon.remove(); - this.iconSpace.remove(); - } - }, - - _setOption: function( key, value ) { - - // We don't allow the value to be set to nothing - if ( key === "label" && !value ) { - return; - } - - this._super( key, value ); - - if ( key === "disabled" ) { - this._toggleClass( this.label, null, "ui-state-disabled", value ); - this.element[ 0 ].disabled = value; - - // Don't refresh when setting disabled - return; - } - this.refresh(); - }, - - _updateIcon: function( checked ) { - var toAdd = "ui-icon ui-icon-background "; - - if ( this.options.icon ) { - if ( !this.icon ) { - this.icon = $( "<span>" ); - this.iconSpace = $( "<span> </span>" ); - this._addClass( this.iconSpace, "ui-checkboxradio-icon-space" ); - } - - if ( this.type === "checkbox" ) { - toAdd += checked ? "ui-icon-check ui-state-checked" : "ui-icon-blank"; - this._removeClass( this.icon, null, checked ? "ui-icon-blank" : "ui-icon-check" ); - } else { - toAdd += "ui-icon-blank"; - } - this._addClass( this.icon, "ui-checkboxradio-icon", toAdd ); - if ( !checked ) { - this._removeClass( this.icon, null, "ui-icon-check ui-state-checked" ); - } - this.icon.prependTo( this.label ).after( this.iconSpace ); - } else if ( this.icon !== undefined ) { - this.icon.remove(); - this.iconSpace.remove(); - delete this.icon; - } - }, - - _updateLabel: function() { - - // Remove the contents of the label ( minus the icon, icon space, and input ) - var contents = this.label.contents().not( this.element[ 0 ] ); - if ( this.icon ) { - contents = contents.not( this.icon[ 0 ] ); - } - if ( this.iconSpace ) { - contents = contents.not( this.iconSpace[ 0 ] ); - } - contents.remove(); - - this.label.append( this.options.label ); - }, - - refresh: function() { - var checked = this.element[ 0 ].checked, - isDisabled = this.element[ 0 ].disabled; - - this._updateIcon( checked ); - this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked ); - if ( this.options.label !== null ) { - this._updateLabel(); - } - - if ( isDisabled !== this.options.disabled ) { - this._setOptions( { "disabled": isDisabled } ); - } - } - -} ] ); - -return $.ui.checkboxradio; + "use strict"; + + $.widget( "ui.checkboxradio", [ $.ui.formResetMixin, { + version: "1.13.2", + options: { + disabled: null, + label: null, + icon: true, + classes: { + "ui-checkboxradio-label": "ui-corner-all", + "ui-checkboxradio-icon": "ui-corner-all" + } + }, + + _getCreateOptions: function() { + var disabled, labels, labelContents; + var options = this._super() || {}; + + // We read the type here, because it makes more sense to throw a element type error first, + // rather then the error for lack of a label. Often if its the wrong type, it + // won't have a label (e.g. calling on a div, btn, etc) + this._readType(); + + labels = this.element.labels(); + + // If there are multiple labels, use the last one + this.label = $( labels[ labels.length - 1 ] ); + if ( !this.label.length ) { + $.error( "No label found for checkboxradio widget" ); + } + + this.originalLabel = ""; + + // We need to get the label text but this may also need to make sure it does not contain the + // input itself. + // The label contents could be text, html, or a mix. We wrap all elements + // and read the wrapper's `innerHTML` to get a string representation of + // the label, without the input as part of it. + labelContents = this.label.contents().not( this.element[ 0 ] ); + + if ( labelContents.length ) { + this.originalLabel += labelContents + .clone() + .wrapAll( "<div></div>" ) + .parent() + .html(); + } + + // Set the label option if we found label text + if ( this.originalLabel ) { + options.label = this.originalLabel; + } + + disabled = this.element[ 0 ].disabled; + if ( disabled != null ) { + options.disabled = disabled; + } + return options; + }, + + _create: function() { + var checked = this.element[ 0 ].checked; + + this._bindFormResetHandler(); + + if ( this.options.disabled == null ) { + this.options.disabled = this.element[ 0 ].disabled; + } + + this._setOption( "disabled", this.options.disabled ); + this._addClass( "ui-checkboxradio", "ui-helper-hidden-accessible" ); + this._addClass( this.label, "ui-checkboxradio-label", "ui-button ui-widget" ); + + if ( this.type === "radio" ) { + this._addClass( this.label, "ui-checkboxradio-radio-label" ); + } + + if ( this.options.label && this.options.label !== this.originalLabel ) { + this._updateLabel(); + } else if ( this.originalLabel ) { + this.options.label = this.originalLabel; + } + + this._enhance(); + + if ( checked ) { + this._addClass( this.label, "ui-checkboxradio-checked", "ui-state-active" ); + } + + this._on( { + change: "_toggleClasses", + focus: function() { + this._addClass( this.label, null, "ui-state-focus ui-visual-focus" ); + }, + blur: function() { + this._removeClass( this.label, null, "ui-state-focus ui-visual-focus" ); + } + } ); + }, + + _readType: function() { + var nodeName = this.element[ 0 ].nodeName.toLowerCase(); + this.type = this.element[ 0 ].type; + if ( nodeName !== "input" || !/radio|checkbox/.test( this.type ) ) { + $.error( "Can't create checkboxradio on element.nodeName=" + nodeName + + " and element.type=" + this.type ); + } + }, + + // Support jQuery Mobile enhanced option + _enhance: function() { + this._updateIcon( this.element[ 0 ].checked ); + }, + + widget: function() { + return this.label; + }, + + _getRadioGroup: function() { + var group; + var name = this.element[ 0 ].name; + var nameSelector = "input[name='" + $.escapeSelector( name ) + "']"; + + if ( !name ) { + return $( [] ); + } + + if ( this.form.length ) { + group = $( this.form[ 0 ].elements ).filter( nameSelector ); + } else { + + // Not inside a form, check all inputs that also are not inside a form + group = $( nameSelector ).filter( function() { + return $( this )._form().length === 0; + } ); + } + + return group.not( this.element ); + }, + + _toggleClasses: function() { + var checked = this.element[ 0 ].checked; + this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked ); + + if ( this.options.icon && this.type === "checkbox" ) { + this._toggleClass( this.icon, null, "ui-icon-check ui-state-checked", checked ) + ._toggleClass( this.icon, null, "ui-icon-blank", !checked ); + } + + if ( this.type === "radio" ) { + this._getRadioGroup() + .each( function() { + var instance = $( this ).checkboxradio( "instance" ); + + if ( instance ) { + instance._removeClass( instance.label, + "ui-checkboxradio-checked", "ui-state-active" ); + } + } ); + } + }, + + _destroy: function() { + this._unbindFormResetHandler(); + + if ( this.icon ) { + this.icon.remove(); + this.iconSpace.remove(); + } + }, + + _setOption: function( key, value ) { + + // We don't allow the value to be set to nothing + if ( key === "label" && !value ) { + return; + } + + this._super( key, value ); + + if ( key === "disabled" ) { + this._toggleClass( this.label, null, "ui-state-disabled", value ); + this.element[ 0 ].disabled = value; + + // Don't refresh when setting disabled + return; + } + this.refresh(); + }, + + _updateIcon: function( checked ) { + var toAdd = "ui-icon ui-icon-background "; + + if ( this.options.icon ) { + if ( !this.icon ) { + this.icon = $( "<span>" ); + this.iconSpace = $( "<span> </span>" ); + this._addClass( this.iconSpace, "ui-checkboxradio-icon-space" ); + } + + if ( this.type === "checkbox" ) { + toAdd += checked ? "ui-icon-check ui-state-checked" : "ui-icon-blank"; + this._removeClass( this.icon, null, checked ? "ui-icon-blank" : "ui-icon-check" ); + } else { + toAdd += "ui-icon-blank"; + } + this._addClass( this.icon, "ui-checkboxradio-icon", toAdd ); + if ( !checked ) { + this._removeClass( this.icon, null, "ui-icon-check ui-state-checked" ); + } + this.icon.prependTo( this.label ).after( this.iconSpace ); + } else if ( this.icon !== undefined ) { + this.icon.remove(); + this.iconSpace.remove(); + delete this.icon; + } + }, + + _updateLabel: function() { + + // Remove the contents of the label ( minus the icon, icon space, and input ) + var contents = this.label.contents().not( this.element[ 0 ] ); + if ( this.icon ) { + contents = contents.not( this.icon[ 0 ] ); + } + if ( this.iconSpace ) { + contents = contents.not( this.iconSpace[ 0 ] ); + } + contents.remove(); + + this.label.append( this.options.label ); + }, + + refresh: function() { + var checked = this.element[ 0 ].checked, + isDisabled = this.element[ 0 ].disabled; + + this._updateIcon( checked ); + this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked ); + if ( this.options.label !== null ) { + this._updateLabel(); + } + + if ( isDisabled !== this.options.disabled ) { + this._setOptions( { "disabled": isDisabled } ); + } + } + + } ] ); + + return $.ui.checkboxradio; } ); diff --git a/lib/web/jquery/ui-modules/widgets/controlgroup.js b/lib/web/jquery/ui-modules/widgets/controlgroup.js index f52f35af66173..71a63f0c17339 100644 --- a/lib/web/jquery/ui-modules/widgets/controlgroup.js +++ b/lib/web/jquery/ui-modules/widgets/controlgroup.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Controlgroup 1.13.1 + * jQuery UI Controlgroup 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -17,286 +17,286 @@ //>>css.theme: ../../themes/base/theme.css ( function( factory ) { - "use strict"; + "use strict"; - if ( typeof define === "function" && define.amd ) { + if ( typeof define === "function" && define.amd ) { - // AMD. Register as an anonymous module. - define( [ - "jquery", - "../widget" - ], factory ); - } else { + // AMD. Register as an anonymous module. + define( [ + "jquery", + "../widget" + ], factory ); + } else { - // Browser globals - factory( jQuery ); - } + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; - -var controlgroupCornerRegex = /ui-corner-([a-z]){2,6}/g; - -return $.widget( "ui.controlgroup", { - version: "1.13.1", - defaultElement: "<div>", - options: { - direction: "horizontal", - disabled: null, - onlyVisible: true, - items: { - "button": "input[type=button], input[type=submit], input[type=reset], button, a", - "controlgroupLabel": ".ui-controlgroup-label", - "checkboxradio": "input[type='checkbox'], input[type='radio']", - "selectmenu": "select", - "spinner": ".ui-spinner-input" - } - }, - - _create: function() { - this._enhance(); - }, - - // To support the enhanced option in jQuery Mobile, we isolate DOM manipulation - _enhance: function() { - this.element.attr( "role", "toolbar" ); - this.refresh(); - }, - - _destroy: function() { - this._callChildMethod( "destroy" ); - this.childWidgets.removeData( "ui-controlgroup-data" ); - this.element.removeAttr( "role" ); - if ( this.options.items.controlgroupLabel ) { - this.element - .find( this.options.items.controlgroupLabel ) - .find( ".ui-controlgroup-label-contents" ) - .contents().unwrap(); - } - }, - - _initWidgets: function() { - var that = this, - childWidgets = []; - - // First we iterate over each of the items options - $.each( this.options.items, function( widget, selector ) { - var labels; - var options = {}; - - // Make sure the widget has a selector set - if ( !selector ) { - return; - } - - if ( widget === "controlgroupLabel" ) { - labels = that.element.find( selector ); - labels.each( function() { - var element = $( this ); - - if ( element.children( ".ui-controlgroup-label-contents" ).length ) { - return; - } - element.contents() - .wrapAll( "<span class='ui-controlgroup-label-contents'></span>" ); - } ); - that._addClass( labels, null, "ui-widget ui-widget-content ui-state-default" ); - childWidgets = childWidgets.concat( labels.get() ); - return; - } - - // Make sure the widget actually exists - if ( !$.fn[ widget ] ) { - return; - } - - // We assume everything is in the middle to start because we can't determine - // first / last elements until all enhancments are done. - if ( that[ "_" + widget + "Options" ] ) { - options = that[ "_" + widget + "Options" ]( "middle" ); - } else { - options = { classes: {} }; - } - - // Find instances of this widget inside controlgroup and init them - that.element - .find( selector ) - .each( function() { - var element = $( this ); - var instance = element[ widget ]( "instance" ); - - // We need to clone the default options for this type of widget to avoid - // polluting the variable options which has a wider scope than a single widget. - var instanceOptions = $.widget.extend( {}, options ); - - // If the button is the child of a spinner ignore it - // TODO: Find a more generic solution - if ( widget === "button" && element.parent( ".ui-spinner" ).length ) { - return; - } - - // Create the widget if it doesn't exist - if ( !instance ) { - instance = element[ widget ]()[ widget ]( "instance" ); - } - if ( instance ) { - instanceOptions.classes = - that._resolveClassesValues( instanceOptions.classes, instance ); - } - element[ widget ]( instanceOptions ); - - // Store an instance of the controlgroup to be able to reference - // from the outermost element for changing options and refresh - var widgetElement = element[ widget ]( "widget" ); - $.data( widgetElement[ 0 ], "ui-controlgroup-data", - instance ? instance : element[ widget ]( "instance" ) ); - - childWidgets.push( widgetElement[ 0 ] ); - } ); - } ); - - this.childWidgets = $( $.uniqueSort( childWidgets ) ); - this._addClass( this.childWidgets, "ui-controlgroup-item" ); - }, - - _callChildMethod: function( method ) { - this.childWidgets.each( function() { - var element = $( this ), - data = element.data( "ui-controlgroup-data" ); - if ( data && data[ method ] ) { - data[ method ](); - } - } ); - }, - - _updateCornerClass: function( element, position ) { - var remove = "ui-corner-top ui-corner-bottom ui-corner-left ui-corner-right ui-corner-all"; - var add = this._buildSimpleOptions( position, "label" ).classes.label; - - this._removeClass( element, null, remove ); - this._addClass( element, null, add ); - }, - - _buildSimpleOptions: function( position, key ) { - var direction = this.options.direction === "vertical"; - var result = { - classes: {} - }; - result.classes[ key ] = { - "middle": "", - "first": "ui-corner-" + ( direction ? "top" : "left" ), - "last": "ui-corner-" + ( direction ? "bottom" : "right" ), - "only": "ui-corner-all" - }[ position ]; - - return result; - }, - - _spinnerOptions: function( position ) { - var options = this._buildSimpleOptions( position, "ui-spinner" ); - - options.classes[ "ui-spinner-up" ] = ""; - options.classes[ "ui-spinner-down" ] = ""; - - return options; - }, - - _buttonOptions: function( position ) { - return this._buildSimpleOptions( position, "ui-button" ); - }, - - _checkboxradioOptions: function( position ) { - return this._buildSimpleOptions( position, "ui-checkboxradio-label" ); - }, - - _selectmenuOptions: function( position ) { - var direction = this.options.direction === "vertical"; - return { - width: direction ? "auto" : false, - classes: { - middle: { - "ui-selectmenu-button-open": "", - "ui-selectmenu-button-closed": "" - }, - first: { - "ui-selectmenu-button-open": "ui-corner-" + ( direction ? "top" : "tl" ), - "ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "top" : "left" ) - }, - last: { - "ui-selectmenu-button-open": direction ? "" : "ui-corner-tr", - "ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "bottom" : "right" ) - }, - only: { - "ui-selectmenu-button-open": "ui-corner-top", - "ui-selectmenu-button-closed": "ui-corner-all" - } - - }[ position ] - }; - }, - - _resolveClassesValues: function( classes, instance ) { - var result = {}; - $.each( classes, function( key ) { - var current = instance.options.classes[ key ] || ""; - current = String.prototype.trim.call( current.replace( controlgroupCornerRegex, "" ) ); - result[ key ] = ( current + " " + classes[ key ] ).replace( /\s+/g, " " ); - } ); - return result; - }, - - _setOption: function( key, value ) { - if ( key === "direction" ) { - this._removeClass( "ui-controlgroup-" + this.options.direction ); - } - - this._super( key, value ); - if ( key === "disabled" ) { - this._callChildMethod( value ? "disable" : "enable" ); - return; - } - - this.refresh(); - }, - - refresh: function() { - var children, - that = this; - - this._addClass( "ui-controlgroup ui-controlgroup-" + this.options.direction ); - - if ( this.options.direction === "horizontal" ) { - this._addClass( null, "ui-helper-clearfix" ); - } - this._initWidgets(); - - children = this.childWidgets; - - // We filter here because we need to track all childWidgets not just the visible ones - if ( this.options.onlyVisible ) { - children = children.filter( ":visible" ); - } - - if ( children.length ) { - - // We do this last because we need to make sure all enhancment is done - // before determining first and last - $.each( [ "first", "last" ], function( index, value ) { - var instance = children[ value ]().data( "ui-controlgroup-data" ); - - if ( instance && that[ "_" + instance.widgetName + "Options" ] ) { - var options = that[ "_" + instance.widgetName + "Options" ]( - children.length === 1 ? "only" : value - ); - options.classes = that._resolveClassesValues( options.classes, instance ); - instance.element[ instance.widgetName ]( options ); - } else { - that._updateCornerClass( children[ value ](), value ); - } - } ); - - // Finally call the refresh method on each of the child widgets. - this._callChildMethod( "refresh" ); - } - } -} ); + "use strict"; + + var controlgroupCornerRegex = /ui-corner-([a-z]){2,6}/g; + + return $.widget( "ui.controlgroup", { + version: "1.13.2", + defaultElement: "<div>", + options: { + direction: "horizontal", + disabled: null, + onlyVisible: true, + items: { + "button": "input[type=button], input[type=submit], input[type=reset], button, a", + "controlgroupLabel": ".ui-controlgroup-label", + "checkboxradio": "input[type='checkbox'], input[type='radio']", + "selectmenu": "select", + "spinner": ".ui-spinner-input" + } + }, + + _create: function() { + this._enhance(); + }, + + // To support the enhanced option in jQuery Mobile, we isolate DOM manipulation + _enhance: function() { + this.element.attr( "role", "toolbar" ); + this.refresh(); + }, + + _destroy: function() { + this._callChildMethod( "destroy" ); + this.childWidgets.removeData( "ui-controlgroup-data" ); + this.element.removeAttr( "role" ); + if ( this.options.items.controlgroupLabel ) { + this.element + .find( this.options.items.controlgroupLabel ) + .find( ".ui-controlgroup-label-contents" ) + .contents().unwrap(); + } + }, + + _initWidgets: function() { + var that = this, + childWidgets = []; + + // First we iterate over each of the items options + $.each( this.options.items, function( widget, selector ) { + var labels; + var options = {}; + + // Make sure the widget has a selector set + if ( !selector ) { + return; + } + + if ( widget === "controlgroupLabel" ) { + labels = that.element.find( selector ); + labels.each( function() { + var element = $( this ); + + if ( element.children( ".ui-controlgroup-label-contents" ).length ) { + return; + } + element.contents() + .wrapAll( "<span class='ui-controlgroup-label-contents'></span>" ); + } ); + that._addClass( labels, null, "ui-widget ui-widget-content ui-state-default" ); + childWidgets = childWidgets.concat( labels.get() ); + return; + } + + // Make sure the widget actually exists + if ( !$.fn[ widget ] ) { + return; + } + + // We assume everything is in the middle to start because we can't determine + // first / last elements until all enhancments are done. + if ( that[ "_" + widget + "Options" ] ) { + options = that[ "_" + widget + "Options" ]( "middle" ); + } else { + options = { classes: {} }; + } + + // Find instances of this widget inside controlgroup and init them + that.element + .find( selector ) + .each( function() { + var element = $( this ); + var instance = element[ widget ]( "instance" ); + + // We need to clone the default options for this type of widget to avoid + // polluting the variable options which has a wider scope than a single widget. + var instanceOptions = $.widget.extend( {}, options ); + + // If the button is the child of a spinner ignore it + // TODO: Find a more generic solution + if ( widget === "button" && element.parent( ".ui-spinner" ).length ) { + return; + } + + // Create the widget if it doesn't exist + if ( !instance ) { + instance = element[ widget ]()[ widget ]( "instance" ); + } + if ( instance ) { + instanceOptions.classes = + that._resolveClassesValues( instanceOptions.classes, instance ); + } + element[ widget ]( instanceOptions ); + + // Store an instance of the controlgroup to be able to reference + // from the outermost element for changing options and refresh + var widgetElement = element[ widget ]( "widget" ); + $.data( widgetElement[ 0 ], "ui-controlgroup-data", + instance ? instance : element[ widget ]( "instance" ) ); + + childWidgets.push( widgetElement[ 0 ] ); + } ); + } ); + + this.childWidgets = $( $.uniqueSort( childWidgets ) ); + this._addClass( this.childWidgets, "ui-controlgroup-item" ); + }, + + _callChildMethod: function( method ) { + this.childWidgets.each( function() { + var element = $( this ), + data = element.data( "ui-controlgroup-data" ); + if ( data && data[ method ] ) { + data[ method ](); + } + } ); + }, + + _updateCornerClass: function( element, position ) { + var remove = "ui-corner-top ui-corner-bottom ui-corner-left ui-corner-right ui-corner-all"; + var add = this._buildSimpleOptions( position, "label" ).classes.label; + + this._removeClass( element, null, remove ); + this._addClass( element, null, add ); + }, + + _buildSimpleOptions: function( position, key ) { + var direction = this.options.direction === "vertical"; + var result = { + classes: {} + }; + result.classes[ key ] = { + "middle": "", + "first": "ui-corner-" + ( direction ? "top" : "left" ), + "last": "ui-corner-" + ( direction ? "bottom" : "right" ), + "only": "ui-corner-all" + }[ position ]; + + return result; + }, + + _spinnerOptions: function( position ) { + var options = this._buildSimpleOptions( position, "ui-spinner" ); + + options.classes[ "ui-spinner-up" ] = ""; + options.classes[ "ui-spinner-down" ] = ""; + + return options; + }, + + _buttonOptions: function( position ) { + return this._buildSimpleOptions( position, "ui-button" ); + }, + + _checkboxradioOptions: function( position ) { + return this._buildSimpleOptions( position, "ui-checkboxradio-label" ); + }, + + _selectmenuOptions: function( position ) { + var direction = this.options.direction === "vertical"; + return { + width: direction ? "auto" : false, + classes: { + middle: { + "ui-selectmenu-button-open": "", + "ui-selectmenu-button-closed": "" + }, + first: { + "ui-selectmenu-button-open": "ui-corner-" + ( direction ? "top" : "tl" ), + "ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "top" : "left" ) + }, + last: { + "ui-selectmenu-button-open": direction ? "" : "ui-corner-tr", + "ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "bottom" : "right" ) + }, + only: { + "ui-selectmenu-button-open": "ui-corner-top", + "ui-selectmenu-button-closed": "ui-corner-all" + } + + }[ position ] + }; + }, + + _resolveClassesValues: function( classes, instance ) { + var result = {}; + $.each( classes, function( key ) { + var current = instance.options.classes[ key ] || ""; + current = String.prototype.trim.call( current.replace( controlgroupCornerRegex, "" ) ); + result[ key ] = ( current + " " + classes[ key ] ).replace( /\s+/g, " " ); + } ); + return result; + }, + + _setOption: function( key, value ) { + if ( key === "direction" ) { + this._removeClass( "ui-controlgroup-" + this.options.direction ); + } + + this._super( key, value ); + if ( key === "disabled" ) { + this._callChildMethod( value ? "disable" : "enable" ); + return; + } + + this.refresh(); + }, + + refresh: function() { + var children, + that = this; + + this._addClass( "ui-controlgroup ui-controlgroup-" + this.options.direction ); + + if ( this.options.direction === "horizontal" ) { + this._addClass( null, "ui-helper-clearfix" ); + } + this._initWidgets(); + + children = this.childWidgets; + + // We filter here because we need to track all childWidgets not just the visible ones + if ( this.options.onlyVisible ) { + children = children.filter( ":visible" ); + } + + if ( children.length ) { + + // We do this last because we need to make sure all enhancment is done + // before determining first and last + $.each( [ "first", "last" ], function( index, value ) { + var instance = children[ value ]().data( "ui-controlgroup-data" ); + + if ( instance && that[ "_" + instance.widgetName + "Options" ] ) { + var options = that[ "_" + instance.widgetName + "Options" ]( + children.length === 1 ? "only" : value + ); + options.classes = that._resolveClassesValues( options.classes, instance ); + instance.element[ instance.widgetName ]( options ); + } else { + that._updateCornerClass( children[ value ](), value ); + } + } ); + + // Finally call the refresh method on each of the child widgets. + this._callChildMethod( "refresh" ); + } + } + } ); } ); diff --git a/lib/web/jquery/ui-modules/widgets/datepicker.js b/lib/web/jquery/ui-modules/widgets/datepicker.js index ea8d1447cf63e..55b122c18988f 100644 --- a/lib/web/jquery/ui-modules/widgets/datepicker.js +++ b/lib/web/jquery/ui-modules/widgets/datepicker.js @@ -1,6 +1,6 @@ /* eslint-disable max-len, camelcase */ /*! - * jQuery UI Datepicker 1.13.1 + * jQuery UI Datepicker 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -18,2223 +18,2223 @@ //>>css.theme: ../../themes/base/theme.css ( function( factory ) { - "use strict"; + "use strict"; - if ( typeof define === "function" && define.amd ) { + if ( typeof define === "function" && define.amd ) { - // AMD. Register as an anonymous module. - define( [ - "jquery", - "../version", - "../keycode" - ], factory ); - } else { + // AMD. Register as an anonymous module. + define( [ + "jquery", + "../version", + "../keycode" + ], factory ); + } else { - // Browser globals - factory( jQuery ); - } + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; - -$.extend( $.ui, { datepicker: { version: "1.13.1" } } ); - -var datepicker_instActive; - -function datepicker_getZindex( elem ) { - var position, value; - while ( elem.length && elem[ 0 ] !== document ) { - - // Ignore z-index if position is set to a value where z-index is ignored by the browser - // This makes behavior of this function consistent across browsers - // WebKit always returns auto if the element is positioned - position = elem.css( "position" ); - if ( position === "absolute" || position === "relative" || position === "fixed" ) { - - // IE returns 0 when zIndex is not specified - // other browsers return a string - // we ignore the case of nested elements with an explicit value of 0 - // <div style="z-index: -10;"><div style="z-index: 0;"></div></div> - value = parseInt( elem.css( "zIndex" ), 10 ); - if ( !isNaN( value ) && value !== 0 ) { - return value; - } - } - elem = elem.parent(); - } - - return 0; -} - -/* Date picker manager. - Use the singleton instance of this class, $.datepicker, to interact with the date picker. - Settings for (groups of) date pickers are maintained in an instance object, - allowing multiple different settings on the same page. */ - -function Datepicker() { - this._curInst = null; // The current instance in use - this._keyEvent = false; // If the last event was a key event - this._disabledInputs = []; // List of date picker inputs that have been disabled - this._datepickerShowing = false; // True if the popup picker is showing , false if not - this._inDialog = false; // True if showing within a "dialog", false if not - this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division - this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class - this._appendClass = "ui-datepicker-append"; // The name of the append marker class - this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class - this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class - this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class - this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class - this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class - this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class - this.regional = []; // Available regional settings, indexed by language code - this.regional[ "" ] = { // Default regional settings - closeText: "Done", // Display text for close link - prevText: "Prev", // Display text for previous month link - nextText: "Next", // Display text for next month link - currentText: "Today", // Display text for current month link - monthNames: [ "January", "February", "March", "April", "May", "June", - "July", "August", "September", "October", "November", "December" ], // Names of months for drop-down and formatting - monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ], // For formatting - dayNames: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], // For formatting - dayNamesShort: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], // For formatting - dayNamesMin: [ "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" ], // Column headings for days starting at Sunday - weekHeader: "Wk", // Column header for week of the year - dateFormat: "mm/dd/yy", // See format options on parseDate - firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... - isRTL: false, // True if right-to-left language, false if left-to-right - showMonthAfterYear: false, // True if the year select precedes month, false for month then year - yearSuffix: "", // Additional text to append to the year in the month headers, - selectMonthLabel: "Select month", // Invisible label for month selector - selectYearLabel: "Select year" // Invisible label for year selector - }; - this._defaults = { // Global defaults for all the date picker instances - showOn: "focus", // "focus" for popup on focus, - // "button" for trigger button, or "both" for either - showAnim: "fadeIn", // Name of jQuery animation for popup - showOptions: {}, // Options for enhanced animations - defaultDate: null, // Used when field is blank: actual date, - // +/-number for offset from today, null for today - appendText: "", // Display text following the input box, e.g. showing the format - buttonText: "...", // Text for trigger button - buttonImage: "", // URL for trigger button image - buttonImageOnly: false, // True if the image appears alone, false if it appears on a button - hideIfNoPrevNext: false, // True to hide next/previous month links - // if not applicable, false to just disable them - navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links - gotoCurrent: false, // True if today link goes back to current selection instead - changeMonth: false, // True if month can be selected directly, false if only prev/next - changeYear: false, // True if year can be selected directly, false if only prev/next - yearRange: "c-10:c+10", // Range of years to display in drop-down, - // either relative to today's year (-nn:+nn), relative to currently displayed year - // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n) - showOtherMonths: false, // True to show dates in other months, false to leave blank - selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable - showWeek: false, // True to show week of the year, false to not show it - calculateWeek: this.iso8601Week, // How to calculate the week of the year, - // takes a Date and returns the number of the week for it - shortYearCutoff: "+10", // Short year values < this are in the current century, - // > this are in the previous century, - // string value starting with "+" for current year + value - minDate: null, // The earliest selectable date, or null for no limit - maxDate: null, // The latest selectable date, or null for no limit - duration: "fast", // Duration of display/closure - beforeShowDay: null, // Function that takes a date and returns an array with - // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "", - // [2] = cell title (optional), e.g. $.datepicker.noWeekends - beforeShow: null, // Function that takes an input field and - // returns a set of custom settings for the date picker - onSelect: null, // Define a callback function when a date is selected - onChangeMonthYear: null, // Define a callback function when the month or year is changed - onClose: null, // Define a callback function when the datepicker is closed - onUpdateDatepicker: null, // Define a callback function when the datepicker is updated - numberOfMonths: 1, // Number of months to show at a time - showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0) - stepMonths: 1, // Number of months to step back/forward - stepBigMonths: 12, // Number of months to step back/forward for the big links - altField: "", // Selector for an alternate field to store selected dates into - altFormat: "", // The date format to use for the alternate field - constrainInput: true, // The input is constrained by the current date format - showButtonPanel: false, // True to show button panel, false to not show it - autoSize: false, // True to size the input for the date format, false to leave as is - disabled: false // The initial disabled state - }; - $.extend( this._defaults, this.regional[ "" ] ); - this.regional.en = $.extend( true, {}, this.regional[ "" ] ); - this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en ); - this.dpDiv = datepicker_bindHover( $( "<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ); -} - -$.extend( Datepicker.prototype, { - - /* Class name added to elements to indicate already configured with a date picker. */ - markerClassName: "hasDatepicker", - - //Keep track of the maximum number of rows displayed (see #7043) - maxRows: 4, - - // TODO rename to "widget" when switching to widget factory - _widgetDatepicker: function() { - return this.dpDiv; - }, - - /* Override the default settings for all instances of the date picker. - * @param settings object - the new settings to use as defaults (anonymous object) - * @return the manager object - */ - setDefaults: function( settings ) { - datepicker_extendRemove( this._defaults, settings || {} ); - return this; - }, - - /* Attach the date picker to a jQuery selection. - * @param target element - the target input field or division or span - * @param settings object - the new settings to use for this date picker instance (anonymous) - */ - _attachDatepicker: function( target, settings ) { - var nodeName, inline, inst; - nodeName = target.nodeName.toLowerCase(); - inline = ( nodeName === "div" || nodeName === "span" ); - if ( !target.id ) { - this.uuid += 1; - target.id = "dp" + this.uuid; - } - inst = this._newInst( $( target ), inline ); - inst.settings = $.extend( {}, settings || {} ); - if ( nodeName === "input" ) { - this._connectDatepicker( target, inst ); - } else if ( inline ) { - this._inlineDatepicker( target, inst ); - } - }, - - /* Create a new instance object. */ - _newInst: function( target, inline ) { - var id = target[ 0 ].id.replace( /([^A-Za-z0-9_\-])/g, "\\\\$1" ); // escape jQuery meta chars - return { id: id, input: target, // associated target - selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection - drawMonth: 0, drawYear: 0, // month being drawn - inline: inline, // is datepicker inline or not - dpDiv: ( !inline ? this.dpDiv : // presentation div - datepicker_bindHover( $( "<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ) ) }; - }, - - /* Attach the date picker to an input field. */ - _connectDatepicker: function( target, inst ) { - var input = $( target ); - inst.append = $( [] ); - inst.trigger = $( [] ); - if ( input.hasClass( this.markerClassName ) ) { - return; - } - this._attachments( input, inst ); - input.addClass( this.markerClassName ).on( "keydown", this._doKeyDown ). - on( "keypress", this._doKeyPress ).on( "keyup", this._doKeyUp ); - this._autoSize( inst ); - $.data( target, "datepicker", inst ); - - //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665) - if ( inst.settings.disabled ) { - this._disableDatepicker( target ); - } - }, - - /* Make attachments based on settings. */ - _attachments: function( input, inst ) { - var showOn, buttonText, buttonImage, - appendText = this._get( inst, "appendText" ), - isRTL = this._get( inst, "isRTL" ); - - if ( inst.append ) { - inst.append.remove(); - } - if ( appendText ) { - inst.append = $( "<span>" ) - .addClass( this._appendClass ) - .text( appendText ); - input[ isRTL ? "before" : "after" ]( inst.append ); - } - - input.off( "focus", this._showDatepicker ); - - if ( inst.trigger ) { - inst.trigger.remove(); - } - - showOn = this._get( inst, "showOn" ); - if ( showOn === "focus" || showOn === "both" ) { // pop-up date picker when in the marked field - input.on( "focus", this._showDatepicker ); - } - if ( showOn === "button" || showOn === "both" ) { // pop-up date picker when button clicked - buttonText = this._get( inst, "buttonText" ); - buttonImage = this._get( inst, "buttonImage" ); - - if ( this._get( inst, "buttonImageOnly" ) ) { - inst.trigger = $( "<img>" ) - .addClass( this._triggerClass ) - .attr( { - src: buttonImage, - alt: buttonText, - title: buttonText - } ); - } else { - inst.trigger = $( "<button type='button'>" ) - .addClass( this._triggerClass ); - if ( buttonImage ) { - inst.trigger.html( - $( "<img>" ) - .attr( { - src: buttonImage, - alt: buttonText, - title: buttonText - } ) - ); - } else { - inst.trigger.text( buttonText ); - } - } - - input[ isRTL ? "before" : "after" ]( inst.trigger ); - inst.trigger.on( "click", function() { - if ( $.datepicker._datepickerShowing && $.datepicker._lastInput === input[ 0 ] ) { - $.datepicker._hideDatepicker(); - } else if ( $.datepicker._datepickerShowing && $.datepicker._lastInput !== input[ 0 ] ) { - $.datepicker._hideDatepicker(); - $.datepicker._showDatepicker( input[ 0 ] ); - } else { - $.datepicker._showDatepicker( input[ 0 ] ); - } - return false; - } ); - } - }, - - /* Apply the maximum length for the date format. */ - _autoSize: function( inst ) { - if ( this._get( inst, "autoSize" ) && !inst.inline ) { - var findMax, max, maxI, i, - date = new Date( 2009, 12 - 1, 20 ), // Ensure double digits - dateFormat = this._get( inst, "dateFormat" ); - - if ( dateFormat.match( /[DM]/ ) ) { - findMax = function( names ) { - max = 0; - maxI = 0; - for ( i = 0; i < names.length; i++ ) { - if ( names[ i ].length > max ) { - max = names[ i ].length; - maxI = i; - } - } - return maxI; - }; - date.setMonth( findMax( this._get( inst, ( dateFormat.match( /MM/ ) ? - "monthNames" : "monthNamesShort" ) ) ) ); - date.setDate( findMax( this._get( inst, ( dateFormat.match( /DD/ ) ? - "dayNames" : "dayNamesShort" ) ) ) + 20 - date.getDay() ); - } - inst.input.attr( "size", this._formatDate( inst, date ).length ); - } - }, - - /* Attach an inline date picker to a div. */ - _inlineDatepicker: function( target, inst ) { - var divSpan = $( target ); - if ( divSpan.hasClass( this.markerClassName ) ) { - return; - } - divSpan.addClass( this.markerClassName ).append( inst.dpDiv ); - $.data( target, "datepicker", inst ); - this._setDate( inst, this._getDefaultDate( inst ), true ); - this._updateDatepicker( inst ); - this._updateAlternate( inst ); - - //If disabled option is true, disable the datepicker before showing it (see ticket #5665) - if ( inst.settings.disabled ) { - this._disableDatepicker( target ); - } - - // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements - // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height - inst.dpDiv.css( "display", "block" ); - }, - - /* Pop-up the date picker in a "dialog" box. - * @param input element - ignored - * @param date string or Date - the initial date to display - * @param onSelect function - the function to call when a date is selected - * @param settings object - update the dialog date picker instance's settings (anonymous object) - * @param pos int[2] - coordinates for the dialog's position within the screen or - * event - with x/y coordinates or - * leave empty for default (screen centre) - * @return the manager object - */ - _dialogDatepicker: function( input, date, onSelect, settings, pos ) { - var id, browserWidth, browserHeight, scrollX, scrollY, - inst = this._dialogInst; // internal instance - - if ( !inst ) { - this.uuid += 1; - id = "dp" + this.uuid; - this._dialogInput = $( "<input type='text' id='" + id + - "' style='position: absolute; top: -100px; width: 0px;'/>" ); - this._dialogInput.on( "keydown", this._doKeyDown ); - $( "body" ).append( this._dialogInput ); - inst = this._dialogInst = this._newInst( this._dialogInput, false ); - inst.settings = {}; - $.data( this._dialogInput[ 0 ], "datepicker", inst ); - } - datepicker_extendRemove( inst.settings, settings || {} ); - date = ( date && date.constructor === Date ? this._formatDate( inst, date ) : date ); - this._dialogInput.val( date ); - - this._pos = ( pos ? ( pos.length ? pos : [ pos.pageX, pos.pageY ] ) : null ); - if ( !this._pos ) { - browserWidth = document.documentElement.clientWidth; - browserHeight = document.documentElement.clientHeight; - scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; - scrollY = document.documentElement.scrollTop || document.body.scrollTop; - this._pos = // should use actual width/height below - [ ( browserWidth / 2 ) - 100 + scrollX, ( browserHeight / 2 ) - 150 + scrollY ]; - } - - // Move input on screen for focus, but hidden behind dialog - this._dialogInput.css( "left", ( this._pos[ 0 ] + 20 ) + "px" ).css( "top", this._pos[ 1 ] + "px" ); - inst.settings.onSelect = onSelect; - this._inDialog = true; - this.dpDiv.addClass( this._dialogClass ); - this._showDatepicker( this._dialogInput[ 0 ] ); - if ( $.blockUI ) { - $.blockUI( this.dpDiv ); - } - $.data( this._dialogInput[ 0 ], "datepicker", inst ); - return this; - }, - - /* Detach a datepicker from its control. - * @param target element - the target input field or division or span - */ - _destroyDatepicker: function( target ) { - var nodeName, - $target = $( target ), - inst = $.data( target, "datepicker" ); - - if ( !$target.hasClass( this.markerClassName ) ) { - return; - } - - nodeName = target.nodeName.toLowerCase(); - $.removeData( target, "datepicker" ); - if ( nodeName === "input" ) { - inst.append.remove(); - inst.trigger.remove(); - $target.removeClass( this.markerClassName ). - off( "focus", this._showDatepicker ). - off( "keydown", this._doKeyDown ). - off( "keypress", this._doKeyPress ). - off( "keyup", this._doKeyUp ); - } else if ( nodeName === "div" || nodeName === "span" ) { - $target.removeClass( this.markerClassName ).empty(); - } - - if ( datepicker_instActive === inst ) { - datepicker_instActive = null; - this._curInst = null; - } - }, - - /* Enable the date picker to a jQuery selection. - * @param target element - the target input field or division or span - */ - _enableDatepicker: function( target ) { - var nodeName, inline, - $target = $( target ), - inst = $.data( target, "datepicker" ); - - if ( !$target.hasClass( this.markerClassName ) ) { - return; - } - - nodeName = target.nodeName.toLowerCase(); - if ( nodeName === "input" ) { - target.disabled = false; - inst.trigger.filter( "button" ). - each( function() { - this.disabled = false; - } ).end(). - filter( "img" ).css( { opacity: "1.0", cursor: "" } ); - } else if ( nodeName === "div" || nodeName === "span" ) { - inline = $target.children( "." + this._inlineClass ); - inline.children().removeClass( "ui-state-disabled" ); - inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ). - prop( "disabled", false ); - } - this._disabledInputs = $.map( this._disabledInputs, - - // Delete entry - function( value ) { - return ( value === target ? null : value ); - } ); - }, - - /* Disable the date picker to a jQuery selection. - * @param target element - the target input field or division or span - */ - _disableDatepicker: function( target ) { - var nodeName, inline, - $target = $( target ), - inst = $.data( target, "datepicker" ); - - if ( !$target.hasClass( this.markerClassName ) ) { - return; - } - - nodeName = target.nodeName.toLowerCase(); - if ( nodeName === "input" ) { - target.disabled = true; - inst.trigger.filter( "button" ). - each( function() { - this.disabled = true; - } ).end(). - filter( "img" ).css( { opacity: "0.5", cursor: "default" } ); - } else if ( nodeName === "div" || nodeName === "span" ) { - inline = $target.children( "." + this._inlineClass ); - inline.children().addClass( "ui-state-disabled" ); - inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ). - prop( "disabled", true ); - } - this._disabledInputs = $.map( this._disabledInputs, - - // Delete entry - function( value ) { - return ( value === target ? null : value ); - } ); - this._disabledInputs[ this._disabledInputs.length ] = target; - }, - - /* Is the first field in a jQuery collection disabled as a datepicker? - * @param target element - the target input field or division or span - * @return boolean - true if disabled, false if enabled - */ - _isDisabledDatepicker: function( target ) { - if ( !target ) { - return false; - } - for ( var i = 0; i < this._disabledInputs.length; i++ ) { - if ( this._disabledInputs[ i ] === target ) { - return true; - } - } - return false; - }, - - /* Retrieve the instance data for the target control. - * @param target element - the target input field or division or span - * @return object - the associated instance data - * @throws error if a jQuery problem getting data - */ - _getInst: function( target ) { - try { - return $.data( target, "datepicker" ); - } catch ( err ) { - throw "Missing instance data for this datepicker"; - } - }, - - /* Update or retrieve the settings for a date picker attached to an input field or division. - * @param target element - the target input field or division or span - * @param name object - the new settings to update or - * string - the name of the setting to change or retrieve, - * when retrieving also "all" for all instance settings or - * "defaults" for all global defaults - * @param value any - the new value for the setting - * (omit if above is an object or to retrieve a value) - */ - _optionDatepicker: function( target, name, value ) { - var settings, date, minDate, maxDate, - inst = this._getInst( target ); - - if ( arguments.length === 2 && typeof name === "string" ) { - return ( name === "defaults" ? $.extend( {}, $.datepicker._defaults ) : - ( inst ? ( name === "all" ? $.extend( {}, inst.settings ) : - this._get( inst, name ) ) : null ) ); - } - - settings = name || {}; - if ( typeof name === "string" ) { - settings = {}; - settings[ name ] = value; - } - - if ( inst ) { - if ( this._curInst === inst ) { - this._hideDatepicker(); - } - - date = this._getDateDatepicker( target, true ); - minDate = this._getMinMaxDate( inst, "min" ); - maxDate = this._getMinMaxDate( inst, "max" ); - datepicker_extendRemove( inst.settings, settings ); - - // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided - if ( minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined ) { - inst.settings.minDate = this._formatDate( inst, minDate ); - } - if ( maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined ) { - inst.settings.maxDate = this._formatDate( inst, maxDate ); - } - if ( "disabled" in settings ) { - if ( settings.disabled ) { - this._disableDatepicker( target ); - } else { - this._enableDatepicker( target ); - } - } - this._attachments( $( target ), inst ); - this._autoSize( inst ); - this._setDate( inst, date ); - this._updateAlternate( inst ); - this._updateDatepicker( inst ); - } - }, - - // Change method deprecated - _changeDatepicker: function( target, name, value ) { - this._optionDatepicker( target, name, value ); - }, - - /* Redraw the date picker attached to an input field or division. - * @param target element - the target input field or division or span - */ - _refreshDatepicker: function( target ) { - var inst = this._getInst( target ); - if ( inst ) { - this._updateDatepicker( inst ); - } - }, - - /* Set the dates for a jQuery selection. - * @param target element - the target input field or division or span - * @param date Date - the new date - */ - _setDateDatepicker: function( target, date ) { - var inst = this._getInst( target ); - if ( inst ) { - this._setDate( inst, date ); - this._updateDatepicker( inst ); - this._updateAlternate( inst ); - } - }, - - /* Get the date(s) for the first entry in a jQuery selection. - * @param target element - the target input field or division or span - * @param noDefault boolean - true if no default date is to be used - * @return Date - the current date - */ - _getDateDatepicker: function( target, noDefault ) { - var inst = this._getInst( target ); - if ( inst && !inst.inline ) { - this._setDateFromField( inst, noDefault ); - } - return ( inst ? this._getDate( inst ) : null ); - }, - - /* Handle keystrokes. */ - _doKeyDown: function( event ) { - var onSelect, dateStr, sel, - inst = $.datepicker._getInst( event.target ), - handled = true, - isRTL = inst.dpDiv.is( ".ui-datepicker-rtl" ); - - inst._keyEvent = true; - if ( $.datepicker._datepickerShowing ) { - switch ( event.keyCode ) { - case 9: $.datepicker._hideDatepicker(); - handled = false; - break; // hide on tab out - case 13: sel = $( "td." + $.datepicker._dayOverClass + ":not(." + - $.datepicker._currentClass + ")", inst.dpDiv ); - if ( sel[ 0 ] ) { - $.datepicker._selectDay( event.target, inst.selectedMonth, inst.selectedYear, sel[ 0 ] ); - } - - onSelect = $.datepicker._get( inst, "onSelect" ); - if ( onSelect ) { - dateStr = $.datepicker._formatDate( inst ); - - // Trigger custom callback - onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] ); - } else { - $.datepicker._hideDatepicker(); - } - - return false; // don't submit the form - case 27: $.datepicker._hideDatepicker(); - break; // hide on escape - case 33: $.datepicker._adjustDate( event.target, ( event.ctrlKey ? - -$.datepicker._get( inst, "stepBigMonths" ) : - -$.datepicker._get( inst, "stepMonths" ) ), "M" ); - break; // previous month/year on page up/+ ctrl - case 34: $.datepicker._adjustDate( event.target, ( event.ctrlKey ? - +$.datepicker._get( inst, "stepBigMonths" ) : - +$.datepicker._get( inst, "stepMonths" ) ), "M" ); - break; // next month/year on page down/+ ctrl - case 35: if ( event.ctrlKey || event.metaKey ) { - $.datepicker._clearDate( event.target ); - } - handled = event.ctrlKey || event.metaKey; - break; // clear on ctrl or command +end - case 36: if ( event.ctrlKey || event.metaKey ) { - $.datepicker._gotoToday( event.target ); - } - handled = event.ctrlKey || event.metaKey; - break; // current on ctrl or command +home - case 37: if ( event.ctrlKey || event.metaKey ) { - $.datepicker._adjustDate( event.target, ( isRTL ? +1 : -1 ), "D" ); - } - handled = event.ctrlKey || event.metaKey; - - // -1 day on ctrl or command +left - if ( event.originalEvent.altKey ) { - $.datepicker._adjustDate( event.target, ( event.ctrlKey ? - -$.datepicker._get( inst, "stepBigMonths" ) : - -$.datepicker._get( inst, "stepMonths" ) ), "M" ); - } - - // next month/year on alt +left on Mac - break; - case 38: if ( event.ctrlKey || event.metaKey ) { - $.datepicker._adjustDate( event.target, -7, "D" ); - } - handled = event.ctrlKey || event.metaKey; - break; // -1 week on ctrl or command +up - case 39: if ( event.ctrlKey || event.metaKey ) { - $.datepicker._adjustDate( event.target, ( isRTL ? -1 : +1 ), "D" ); - } - handled = event.ctrlKey || event.metaKey; - - // +1 day on ctrl or command +right - if ( event.originalEvent.altKey ) { - $.datepicker._adjustDate( event.target, ( event.ctrlKey ? - +$.datepicker._get( inst, "stepBigMonths" ) : - +$.datepicker._get( inst, "stepMonths" ) ), "M" ); - } - - // next month/year on alt +right - break; - case 40: if ( event.ctrlKey || event.metaKey ) { - $.datepicker._adjustDate( event.target, +7, "D" ); - } - handled = event.ctrlKey || event.metaKey; - break; // +1 week on ctrl or command +down - default: handled = false; - } - } else if ( event.keyCode === 36 && event.ctrlKey ) { // display the date picker on ctrl+home - $.datepicker._showDatepicker( this ); - } else { - handled = false; - } - - if ( handled ) { - event.preventDefault(); - event.stopPropagation(); - } - }, - - /* Filter entered characters - based on date format. */ - _doKeyPress: function( event ) { - var chars, chr, - inst = $.datepicker._getInst( event.target ); - - if ( $.datepicker._get( inst, "constrainInput" ) ) { - chars = $.datepicker._possibleChars( $.datepicker._get( inst, "dateFormat" ) ); - chr = String.fromCharCode( event.charCode == null ? event.keyCode : event.charCode ); - return event.ctrlKey || event.metaKey || ( chr < " " || !chars || chars.indexOf( chr ) > -1 ); - } - }, - - /* Synchronise manual entry and field/alternate field. */ - _doKeyUp: function( event ) { - var date, - inst = $.datepicker._getInst( event.target ); - - if ( inst.input.val() !== inst.lastVal ) { - try { - date = $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ), - ( inst.input ? inst.input.val() : null ), - $.datepicker._getFormatConfig( inst ) ); - - if ( date ) { // only if valid - $.datepicker._setDateFromField( inst ); - $.datepicker._updateAlternate( inst ); - $.datepicker._updateDatepicker( inst ); - } - } catch ( err ) { - } - } - return true; - }, - - /* Pop-up the date picker for a given input field. - * If false returned from beforeShow event handler do not show. - * @param input element - the input field attached to the date picker or - * event - if triggered by focus - */ - _showDatepicker: function( input ) { - input = input.target || input; - if ( input.nodeName.toLowerCase() !== "input" ) { // find from button/image trigger - input = $( "input", input.parentNode )[ 0 ]; - } - - if ( $.datepicker._isDisabledDatepicker( input ) || $.datepicker._lastInput === input ) { // already here - return; - } - - var inst, beforeShow, beforeShowSettings, isFixed, - offset, showAnim, duration; - - inst = $.datepicker._getInst( input ); - if ( $.datepicker._curInst && $.datepicker._curInst !== inst ) { - $.datepicker._curInst.dpDiv.stop( true, true ); - if ( inst && $.datepicker._datepickerShowing ) { - $.datepicker._hideDatepicker( $.datepicker._curInst.input[ 0 ] ); - } - } - - beforeShow = $.datepicker._get( inst, "beforeShow" ); - beforeShowSettings = beforeShow ? beforeShow.apply( input, [ input, inst ] ) : {}; - if ( beforeShowSettings === false ) { - return; - } - datepicker_extendRemove( inst.settings, beforeShowSettings ); - - inst.lastVal = null; - $.datepicker._lastInput = input; - $.datepicker._setDateFromField( inst ); - - if ( $.datepicker._inDialog ) { // hide cursor - input.value = ""; - } - if ( !$.datepicker._pos ) { // position below input - $.datepicker._pos = $.datepicker._findPos( input ); - $.datepicker._pos[ 1 ] += input.offsetHeight; // add the height - } - - isFixed = false; - $( input ).parents().each( function() { - isFixed |= $( this ).css( "position" ) === "fixed"; - return !isFixed; - } ); - - offset = { left: $.datepicker._pos[ 0 ], top: $.datepicker._pos[ 1 ] }; - $.datepicker._pos = null; - - //to avoid flashes on Firefox - inst.dpDiv.empty(); - - // determine sizing offscreen - inst.dpDiv.css( { position: "absolute", display: "block", top: "-1000px" } ); - $.datepicker._updateDatepicker( inst ); - - // fix width for dynamic number of date pickers - // and adjust position before showing - offset = $.datepicker._checkOffset( inst, offset, isFixed ); - inst.dpDiv.css( { position: ( $.datepicker._inDialog && $.blockUI ? - "static" : ( isFixed ? "fixed" : "absolute" ) ), display: "none", - left: offset.left + "px", top: offset.top + "px" } ); - - if ( !inst.inline ) { - showAnim = $.datepicker._get( inst, "showAnim" ); - duration = $.datepicker._get( inst, "duration" ); - inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 ); - $.datepicker._datepickerShowing = true; - - if ( $.effects && $.effects.effect[ showAnim ] ) { - inst.dpDiv.show( showAnim, $.datepicker._get( inst, "showOptions" ), duration ); - } else { - inst.dpDiv[ showAnim || "show" ]( showAnim ? duration : null ); - } - - if ( $.datepicker._shouldFocusInput( inst ) ) { - inst.input.trigger( "focus" ); - } - - $.datepicker._curInst = inst; - } - }, - - /* Generate the date picker content. */ - _updateDatepicker: function( inst ) { - this.maxRows = 4; //Reset the max number of rows being displayed (see #7043) - datepicker_instActive = inst; // for delegate hover events - inst.dpDiv.empty().append( this._generateHTML( inst ) ); - this._attachHandlers( inst ); - - var origyearshtml, - numMonths = this._getNumberOfMonths( inst ), - cols = numMonths[ 1 ], - width = 17, - activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" ), - onUpdateDatepicker = $.datepicker._get( inst, "onUpdateDatepicker" ); - - if ( activeCell.length > 0 ) { - datepicker_handleMouseover.apply( activeCell.get( 0 ) ); - } - - inst.dpDiv.removeClass( "ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4" ).width( "" ); - if ( cols > 1 ) { - inst.dpDiv.addClass( "ui-datepicker-multi-" + cols ).css( "width", ( width * cols ) + "em" ); - } - inst.dpDiv[ ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ? "add" : "remove" ) + - "Class" ]( "ui-datepicker-multi" ); - inst.dpDiv[ ( this._get( inst, "isRTL" ) ? "add" : "remove" ) + - "Class" ]( "ui-datepicker-rtl" ); - - if ( inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) { - inst.input.trigger( "focus" ); - } - - // Deffered render of the years select (to avoid flashes on Firefox) - if ( inst.yearshtml ) { - origyearshtml = inst.yearshtml; - setTimeout( function() { - - //assure that inst.yearshtml didn't change. - if ( origyearshtml === inst.yearshtml && inst.yearshtml ) { - inst.dpDiv.find( "select.ui-datepicker-year" ).first().replaceWith( inst.yearshtml ); - } - origyearshtml = inst.yearshtml = null; - }, 0 ); - } - - if ( onUpdateDatepicker ) { - onUpdateDatepicker.apply( ( inst.input ? inst.input[ 0 ] : null ), [ inst ] ); - } - }, - - // #6694 - don't focus the input if it's already focused - // this breaks the change event in IE - // Support: IE and jQuery <1.9 - _shouldFocusInput: function( inst ) { - return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" ); - }, - - /* Check positioning to remain on screen. */ - _checkOffset: function( inst, offset, isFixed ) { - var dpWidth = inst.dpDiv.outerWidth(), - dpHeight = inst.dpDiv.outerHeight(), - inputWidth = inst.input ? inst.input.outerWidth() : 0, - inputHeight = inst.input ? inst.input.outerHeight() : 0, - viewWidth = document.documentElement.clientWidth + ( isFixed ? 0 : $( document ).scrollLeft() ), - viewHeight = document.documentElement.clientHeight + ( isFixed ? 0 : $( document ).scrollTop() ); - - offset.left -= ( this._get( inst, "isRTL" ) ? ( dpWidth - inputWidth ) : 0 ); - offset.left -= ( isFixed && offset.left === inst.input.offset().left ) ? $( document ).scrollLeft() : 0; - offset.top -= ( isFixed && offset.top === ( inst.input.offset().top + inputHeight ) ) ? $( document ).scrollTop() : 0; - - // Now check if datepicker is showing outside window viewport - move to a better place if so. - offset.left -= Math.min( offset.left, ( offset.left + dpWidth > viewWidth && viewWidth > dpWidth ) ? - Math.abs( offset.left + dpWidth - viewWidth ) : 0 ); - offset.top -= Math.min( offset.top, ( offset.top + dpHeight > viewHeight && viewHeight > dpHeight ) ? - Math.abs( dpHeight + inputHeight ) : 0 ); - - return offset; - }, - - /* Find an object's position on the screen. */ - _findPos: function( obj ) { - var position, - inst = this._getInst( obj ), - isRTL = this._get( inst, "isRTL" ); - - while ( obj && ( obj.type === "hidden" || obj.nodeType !== 1 || $.expr.pseudos.hidden( obj ) ) ) { - obj = obj[ isRTL ? "previousSibling" : "nextSibling" ]; - } - - position = $( obj ).offset(); - return [ position.left, position.top ]; - }, - - /* Hide the date picker from view. - * @param input element - the input field attached to the date picker - */ - _hideDatepicker: function( input ) { - var showAnim, duration, postProcess, onClose, - inst = this._curInst; - - if ( !inst || ( input && inst !== $.data( input, "datepicker" ) ) ) { - return; - } - - if ( this._datepickerShowing ) { - showAnim = this._get( inst, "showAnim" ); - duration = this._get( inst, "duration" ); - postProcess = function() { - $.datepicker._tidyDialog( inst ); - }; - - // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed - if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) { - inst.dpDiv.hide( showAnim, $.datepicker._get( inst, "showOptions" ), duration, postProcess ); - } else { - inst.dpDiv[ ( showAnim === "slideDown" ? "slideUp" : - ( showAnim === "fadeIn" ? "fadeOut" : "hide" ) ) ]( ( showAnim ? duration : null ), postProcess ); - } - - if ( !showAnim ) { - postProcess(); - } - this._datepickerShowing = false; - - onClose = this._get( inst, "onClose" ); - if ( onClose ) { - onClose.apply( ( inst.input ? inst.input[ 0 ] : null ), [ ( inst.input ? inst.input.val() : "" ), inst ] ); - } - - this._lastInput = null; - if ( this._inDialog ) { - this._dialogInput.css( { position: "absolute", left: "0", top: "-100px" } ); - if ( $.blockUI ) { - $.unblockUI(); - $( "body" ).append( this.dpDiv ); - } - } - this._inDialog = false; - } - }, - - /* Tidy up after a dialog display. */ - _tidyDialog: function( inst ) { - inst.dpDiv.removeClass( this._dialogClass ).off( ".ui-datepicker-calendar" ); - }, - - /* Close date picker if clicked elsewhere. */ - _checkExternalClick: function( event ) { - if ( !$.datepicker._curInst ) { - return; - } - - var $target = $( event.target ), - inst = $.datepicker._getInst( $target[ 0 ] ); - - if ( ( ( $target[ 0 ].id !== $.datepicker._mainDivId && - $target.parents( "#" + $.datepicker._mainDivId ).length === 0 && - !$target.hasClass( $.datepicker.markerClassName ) && - !$target.closest( "." + $.datepicker._triggerClass ).length && - $.datepicker._datepickerShowing && !( $.datepicker._inDialog && $.blockUI ) ) ) || - ( $target.hasClass( $.datepicker.markerClassName ) && $.datepicker._curInst !== inst ) ) { - $.datepicker._hideDatepicker(); - } - }, - - /* Adjust one of the date sub-fields. */ - _adjustDate: function( id, offset, period ) { - var target = $( id ), - inst = this._getInst( target[ 0 ] ); - - if ( this._isDisabledDatepicker( target[ 0 ] ) ) { - return; - } - this._adjustInstDate( inst, offset, period ); - this._updateDatepicker( inst ); - }, - - /* Action for current link. */ - _gotoToday: function( id ) { - var date, - target = $( id ), - inst = this._getInst( target[ 0 ] ); - - if ( this._get( inst, "gotoCurrent" ) && inst.currentDay ) { - inst.selectedDay = inst.currentDay; - inst.drawMonth = inst.selectedMonth = inst.currentMonth; - inst.drawYear = inst.selectedYear = inst.currentYear; - } else { - date = new Date(); - inst.selectedDay = date.getDate(); - inst.drawMonth = inst.selectedMonth = date.getMonth(); - inst.drawYear = inst.selectedYear = date.getFullYear(); - } - this._notifyChange( inst ); - this._adjustDate( target ); - }, - - /* Action for selecting a new month/year. */ - _selectMonthYear: function( id, select, period ) { - var target = $( id ), - inst = this._getInst( target[ 0 ] ); - - inst[ "selected" + ( period === "M" ? "Month" : "Year" ) ] = - inst[ "draw" + ( period === "M" ? "Month" : "Year" ) ] = - parseInt( select.options[ select.selectedIndex ].value, 10 ); - - this._notifyChange( inst ); - this._adjustDate( target ); - }, - - /* Action for selecting a day. */ - _selectDay: function( id, month, year, td ) { - var inst, - target = $( id ); - - if ( $( td ).hasClass( this._unselectableClass ) || this._isDisabledDatepicker( target[ 0 ] ) ) { - return; - } - - inst = this._getInst( target[ 0 ] ); - inst.selectedDay = inst.currentDay = parseInt( $( "a", td ).attr( "data-date" ) ); - inst.selectedMonth = inst.currentMonth = month; - inst.selectedYear = inst.currentYear = year; - this._selectDate( id, this._formatDate( inst, - inst.currentDay, inst.currentMonth, inst.currentYear ) ); - }, - - /* Erase the input field and hide the date picker. */ - _clearDate: function( id ) { - var target = $( id ); - this._selectDate( target, "" ); - }, - - /* Update the input field with the selected date. */ - _selectDate: function( id, dateStr ) { - var onSelect, - target = $( id ), - inst = this._getInst( target[ 0 ] ); - - dateStr = ( dateStr != null ? dateStr : this._formatDate( inst ) ); - if ( inst.input ) { - inst.input.val( dateStr ); - } - this._updateAlternate( inst ); - - onSelect = this._get( inst, "onSelect" ); - if ( onSelect ) { - onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] ); // trigger custom callback - } else if ( inst.input ) { - inst.input.trigger( "change" ); // fire the change event - } - - if ( inst.inline ) { - this._updateDatepicker( inst ); - } else { - this._hideDatepicker(); - this._lastInput = inst.input[ 0 ]; - if ( typeof( inst.input[ 0 ] ) !== "object" ) { - inst.input.trigger( "focus" ); // restore focus - } - this._lastInput = null; - } - }, - - /* Update any alternate field to synchronise with the main field. */ - _updateAlternate: function( inst ) { - var altFormat, date, dateStr, - altField = this._get( inst, "altField" ); - - if ( altField ) { // update alternate field too - altFormat = this._get( inst, "altFormat" ) || this._get( inst, "dateFormat" ); - date = this._getDate( inst ); - dateStr = this.formatDate( altFormat, date, this._getFormatConfig( inst ) ); - $( document ).find( altField ).val( dateStr ); - } - }, - - /* Set as beforeShowDay function to prevent selection of weekends. - * @param date Date - the date to customise - * @return [boolean, string] - is this date selectable?, what is its CSS class? - */ - noWeekends: function( date ) { - var day = date.getDay(); - return [ ( day > 0 && day < 6 ), "" ]; - }, - - /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. - * @param date Date - the date to get the week for - * @return number - the number of the week within the year that contains this date - */ - iso8601Week: function( date ) { - var time, - checkDate = new Date( date.getTime() ); - - // Find Thursday of this week starting on Monday - checkDate.setDate( checkDate.getDate() + 4 - ( checkDate.getDay() || 7 ) ); - - time = checkDate.getTime(); - checkDate.setMonth( 0 ); // Compare with Jan 1 - checkDate.setDate( 1 ); - return Math.floor( Math.round( ( time - checkDate ) / 86400000 ) / 7 ) + 1; - }, - - /* Parse a string value into a date object. - * See formatDate below for the possible formats. - * - * @param format string - the expected format of the date - * @param value string - the date in the above format - * @param settings Object - attributes include: - * shortYearCutoff number - the cutoff year for determining the century (optional) - * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) - * dayNames string[7] - names of the days from Sunday (optional) - * monthNamesShort string[12] - abbreviated names of the months (optional) - * monthNames string[12] - names of the months (optional) - * @return Date - the extracted date value or null if value is blank - */ - parseDate: function( format, value, settings ) { - if ( format == null || value == null ) { - throw "Invalid arguments"; - } - - value = ( typeof value === "object" ? value.toString() : value + "" ); - if ( value === "" ) { - return null; - } - - var iFormat, dim, extra, - iValue = 0, - shortYearCutoffTemp = ( settings ? settings.shortYearCutoff : null ) || this._defaults.shortYearCutoff, - shortYearCutoff = ( typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp : - new Date().getFullYear() % 100 + parseInt( shortYearCutoffTemp, 10 ) ), - dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort, - dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames, - monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort, - monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames, - year = -1, - month = -1, - day = -1, - doy = -1, - literal = false, - date, - - // Check whether a format character is doubled - lookAhead = function( match ) { - var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match ); - if ( matches ) { - iFormat++; - } - return matches; - }, - - // Extract a number from the string value - getNumber = function( match ) { - var isDoubled = lookAhead( match ), - size = ( match === "@" ? 14 : ( match === "!" ? 20 : - ( match === "y" && isDoubled ? 4 : ( match === "o" ? 3 : 2 ) ) ) ), - minSize = ( match === "y" ? size : 1 ), - digits = new RegExp( "^\\d{" + minSize + "," + size + "}" ), - num = value.substring( iValue ).match( digits ); - if ( !num ) { - throw "Missing number at position " + iValue; - } - iValue += num[ 0 ].length; - return parseInt( num[ 0 ], 10 ); - }, - - // Extract a name from the string value and convert to an index - getName = function( match, shortNames, longNames ) { - var index = -1, - names = $.map( lookAhead( match ) ? longNames : shortNames, function( v, k ) { - return [ [ k, v ] ]; - } ).sort( function( a, b ) { - return -( a[ 1 ].length - b[ 1 ].length ); - } ); - - $.each( names, function( i, pair ) { - var name = pair[ 1 ]; - if ( value.substr( iValue, name.length ).toLowerCase() === name.toLowerCase() ) { - index = pair[ 0 ]; - iValue += name.length; - return false; - } - } ); - if ( index !== -1 ) { - return index + 1; - } else { - throw "Unknown name at position " + iValue; - } - }, - - // Confirm that a literal character matches the string value - checkLiteral = function() { - if ( value.charAt( iValue ) !== format.charAt( iFormat ) ) { - throw "Unexpected literal at position " + iValue; - } - iValue++; - }; - - for ( iFormat = 0; iFormat < format.length; iFormat++ ) { - if ( literal ) { - if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) { - literal = false; - } else { - checkLiteral(); - } - } else { - switch ( format.charAt( iFormat ) ) { - case "d": - day = getNumber( "d" ); - break; - case "D": - getName( "D", dayNamesShort, dayNames ); - break; - case "o": - doy = getNumber( "o" ); - break; - case "m": - month = getNumber( "m" ); - break; - case "M": - month = getName( "M", monthNamesShort, monthNames ); - break; - case "y": - year = getNumber( "y" ); - break; - case "@": - date = new Date( getNumber( "@" ) ); - year = date.getFullYear(); - month = date.getMonth() + 1; - day = date.getDate(); - break; - case "!": - date = new Date( ( getNumber( "!" ) - this._ticksTo1970 ) / 10000 ); - year = date.getFullYear(); - month = date.getMonth() + 1; - day = date.getDate(); - break; - case "'": - if ( lookAhead( "'" ) ) { - checkLiteral(); - } else { - literal = true; - } - break; - default: - checkLiteral(); - } - } - } - - if ( iValue < value.length ) { - extra = value.substr( iValue ); - if ( !/^\s+/.test( extra ) ) { - throw "Extra/unparsed characters found in date: " + extra; - } - } - - if ( year === -1 ) { - year = new Date().getFullYear(); - } else if ( year < 100 ) { - year += new Date().getFullYear() - new Date().getFullYear() % 100 + - ( year <= shortYearCutoff ? 0 : -100 ); - } - - if ( doy > -1 ) { - month = 1; - day = doy; - do { - dim = this._getDaysInMonth( year, month - 1 ); - if ( day <= dim ) { - break; - } - month++; - day -= dim; - } while ( true ); - } - - date = this._daylightSavingAdjust( new Date( year, month - 1, day ) ); - if ( date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day ) { - throw "Invalid date"; // E.g. 31/02/00 - } - return date; - }, - - /* Standard date formats. */ - ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601) - COOKIE: "D, dd M yy", - ISO_8601: "yy-mm-dd", - RFC_822: "D, d M y", - RFC_850: "DD, dd-M-y", - RFC_1036: "D, d M y", - RFC_1123: "D, d M yy", - RFC_2822: "D, d M yy", - RSS: "D, d M y", // RFC 822 - TICKS: "!", - TIMESTAMP: "@", - W3C: "yy-mm-dd", // ISO 8601 - - _ticksTo1970: ( ( ( 1970 - 1 ) * 365 + Math.floor( 1970 / 4 ) - Math.floor( 1970 / 100 ) + - Math.floor( 1970 / 400 ) ) * 24 * 60 * 60 * 10000000 ), - - /* Format a date object into a string value. - * The format can be combinations of the following: - * d - day of month (no leading zero) - * dd - day of month (two digit) - * o - day of year (no leading zeros) - * oo - day of year (three digit) - * D - day name short - * DD - day name long - * m - month of year (no leading zero) - * mm - month of year (two digit) - * M - month name short - * MM - month name long - * y - year (two digit) - * yy - year (four digit) - * @ - Unix timestamp (ms since 01/01/1970) - * ! - Windows ticks (100ns since 01/01/0001) - * "..." - literal text - * '' - single quote - * - * @param format string - the desired format of the date - * @param date Date - the date value to format - * @param settings Object - attributes include: - * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) - * dayNames string[7] - names of the days from Sunday (optional) - * monthNamesShort string[12] - abbreviated names of the months (optional) - * monthNames string[12] - names of the months (optional) - * @return string - the date in the above format - */ - formatDate: function( format, date, settings ) { - if ( !date ) { - return ""; - } - - var iFormat, - dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort, - dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames, - monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort, - monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames, - - // Check whether a format character is doubled - lookAhead = function( match ) { - var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match ); - if ( matches ) { - iFormat++; - } - return matches; - }, - - // Format a number, with leading zero if necessary - formatNumber = function( match, value, len ) { - var num = "" + value; - if ( lookAhead( match ) ) { - while ( num.length < len ) { - num = "0" + num; - } - } - return num; - }, - - // Format a name, short or long as requested - formatName = function( match, value, shortNames, longNames ) { - return ( lookAhead( match ) ? longNames[ value ] : shortNames[ value ] ); - }, - output = "", - literal = false; - - if ( date ) { - for ( iFormat = 0; iFormat < format.length; iFormat++ ) { - if ( literal ) { - if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) { - literal = false; - } else { - output += format.charAt( iFormat ); - } - } else { - switch ( format.charAt( iFormat ) ) { - case "d": - output += formatNumber( "d", date.getDate(), 2 ); - break; - case "D": - output += formatName( "D", date.getDay(), dayNamesShort, dayNames ); - break; - case "o": - output += formatNumber( "o", - Math.round( ( new Date( date.getFullYear(), date.getMonth(), date.getDate() ).getTime() - new Date( date.getFullYear(), 0, 0 ).getTime() ) / 86400000 ), 3 ); - break; - case "m": - output += formatNumber( "m", date.getMonth() + 1, 2 ); - break; - case "M": - output += formatName( "M", date.getMonth(), monthNamesShort, monthNames ); - break; - case "y": - output += ( lookAhead( "y" ) ? date.getFullYear() : - ( date.getFullYear() % 100 < 10 ? "0" : "" ) + date.getFullYear() % 100 ); - break; - case "@": - output += date.getTime(); - break; - case "!": - output += date.getTime() * 10000 + this._ticksTo1970; - break; - case "'": - if ( lookAhead( "'" ) ) { - output += "'"; - } else { - literal = true; - } - break; - default: - output += format.charAt( iFormat ); - } - } - } - } - return output; - }, - - /* Extract all possible characters from the date format. */ - _possibleChars: function( format ) { - var iFormat, - chars = "", - literal = false, - - // Check whether a format character is doubled - lookAhead = function( match ) { - var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match ); - if ( matches ) { - iFormat++; - } - return matches; - }; - - for ( iFormat = 0; iFormat < format.length; iFormat++ ) { - if ( literal ) { - if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) { - literal = false; - } else { - chars += format.charAt( iFormat ); - } - } else { - switch ( format.charAt( iFormat ) ) { - case "d": case "m": case "y": case "@": - chars += "0123456789"; - break; - case "D": case "M": - return null; // Accept anything - case "'": - if ( lookAhead( "'" ) ) { - chars += "'"; - } else { - literal = true; - } - break; - default: - chars += format.charAt( iFormat ); - } - } - } - return chars; - }, - - /* Get a setting value, defaulting if necessary. */ - _get: function( inst, name ) { - return inst.settings[ name ] !== undefined ? - inst.settings[ name ] : this._defaults[ name ]; - }, - - /* Parse existing date and initialise date picker. */ - _setDateFromField: function( inst, noDefault ) { - if ( inst.input.val() === inst.lastVal ) { - return; - } - - var dateFormat = this._get( inst, "dateFormat" ), - dates = inst.lastVal = inst.input ? inst.input.val() : null, - defaultDate = this._getDefaultDate( inst ), - date = defaultDate, - settings = this._getFormatConfig( inst ); - - try { - date = this.parseDate( dateFormat, dates, settings ) || defaultDate; - } catch ( event ) { - dates = ( noDefault ? "" : dates ); - } - inst.selectedDay = date.getDate(); - inst.drawMonth = inst.selectedMonth = date.getMonth(); - inst.drawYear = inst.selectedYear = date.getFullYear(); - inst.currentDay = ( dates ? date.getDate() : 0 ); - inst.currentMonth = ( dates ? date.getMonth() : 0 ); - inst.currentYear = ( dates ? date.getFullYear() : 0 ); - this._adjustInstDate( inst ); - }, - - /* Retrieve the default date shown on opening. */ - _getDefaultDate: function( inst ) { - return this._restrictMinMax( inst, - this._determineDate( inst, this._get( inst, "defaultDate" ), new Date() ) ); - }, - - /* A date may be specified as an exact value or a relative one. */ - _determineDate: function( inst, date, defaultDate ) { - var offsetNumeric = function( offset ) { - var date = new Date(); - date.setDate( date.getDate() + offset ); - return date; - }, - offsetString = function( offset ) { - try { - return $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ), - offset, $.datepicker._getFormatConfig( inst ) ); - } catch ( e ) { - - // Ignore - } - - var date = ( offset.toLowerCase().match( /^c/ ) ? - $.datepicker._getDate( inst ) : null ) || new Date(), - year = date.getFullYear(), - month = date.getMonth(), - day = date.getDate(), - pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g, - matches = pattern.exec( offset ); - - while ( matches ) { - switch ( matches[ 2 ] || "d" ) { - case "d" : case "D" : - day += parseInt( matches[ 1 ], 10 ); break; - case "w" : case "W" : - day += parseInt( matches[ 1 ], 10 ) * 7; break; - case "m" : case "M" : - month += parseInt( matches[ 1 ], 10 ); - day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) ); - break; - case "y": case "Y" : - year += parseInt( matches[ 1 ], 10 ); - day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) ); - break; - } - matches = pattern.exec( offset ); - } - return new Date( year, month, day ); - }, - newDate = ( date == null || date === "" ? defaultDate : ( typeof date === "string" ? offsetString( date ) : - ( typeof date === "number" ? ( isNaN( date ) ? defaultDate : offsetNumeric( date ) ) : new Date( date.getTime() ) ) ) ); - - newDate = ( newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate ); - if ( newDate ) { - newDate.setHours( 0 ); - newDate.setMinutes( 0 ); - newDate.setSeconds( 0 ); - newDate.setMilliseconds( 0 ); - } - return this._daylightSavingAdjust( newDate ); - }, - - /* Handle switch to/from daylight saving. - * Hours may be non-zero on daylight saving cut-over: - * > 12 when midnight changeover, but then cannot generate - * midnight datetime, so jump to 1AM, otherwise reset. - * @param date (Date) the date to check - * @return (Date) the corrected date - */ - _daylightSavingAdjust: function( date ) { - if ( !date ) { - return null; - } - date.setHours( date.getHours() > 12 ? date.getHours() + 2 : 0 ); - return date; - }, - - /* Set the date(s) directly. */ - _setDate: function( inst, date, noChange ) { - var clear = !date, - origMonth = inst.selectedMonth, - origYear = inst.selectedYear, - newDate = this._restrictMinMax( inst, this._determineDate( inst, date, new Date() ) ); - - inst.selectedDay = inst.currentDay = newDate.getDate(); - inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth(); - inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear(); - if ( ( origMonth !== inst.selectedMonth || origYear !== inst.selectedYear ) && !noChange ) { - this._notifyChange( inst ); - } - this._adjustInstDate( inst ); - if ( inst.input ) { - inst.input.val( clear ? "" : this._formatDate( inst ) ); - } - }, - - /* Retrieve the date(s) directly. */ - _getDate: function( inst ) { - var startDate = ( !inst.currentYear || ( inst.input && inst.input.val() === "" ) ? null : - this._daylightSavingAdjust( new Date( - inst.currentYear, inst.currentMonth, inst.currentDay ) ) ); - return startDate; - }, - - /* Attach the onxxx handlers. These are declared statically so - * they work with static code transformers like Caja. - */ - _attachHandlers: function( inst ) { - var stepMonths = this._get( inst, "stepMonths" ), - id = "#" + inst.id.replace( /\\\\/g, "\\" ); - inst.dpDiv.find( "[data-handler]" ).map( function() { - var handler = { - prev: function() { - $.datepicker._adjustDate( id, -stepMonths, "M" ); - }, - next: function() { - $.datepicker._adjustDate( id, +stepMonths, "M" ); - }, - hide: function() { - $.datepicker._hideDatepicker(); - }, - today: function() { - $.datepicker._gotoToday( id ); - }, - selectDay: function() { - $.datepicker._selectDay( id, +this.getAttribute( "data-month" ), +this.getAttribute( "data-year" ), this ); - return false; - }, - selectMonth: function() { - $.datepicker._selectMonthYear( id, this, "M" ); - return false; - }, - selectYear: function() { - $.datepicker._selectMonthYear( id, this, "Y" ); - return false; - } - }; - $( this ).on( this.getAttribute( "data-event" ), handler[ this.getAttribute( "data-handler" ) ] ); - } ); - }, - - /* Generate the HTML for the current state of the date picker. */ - _generateHTML: function( inst ) { - var maxDraw, prevText, prev, nextText, next, currentText, gotoDate, - controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin, - monthNames, monthNamesShort, beforeShowDay, showOtherMonths, - selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate, - cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows, - printDate, dRow, tbody, daySettings, otherMonth, unselectable, - tempDate = new Date(), - today = this._daylightSavingAdjust( - new Date( tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate() ) ), // clear time - isRTL = this._get( inst, "isRTL" ), - showButtonPanel = this._get( inst, "showButtonPanel" ), - hideIfNoPrevNext = this._get( inst, "hideIfNoPrevNext" ), - navigationAsDateFormat = this._get( inst, "navigationAsDateFormat" ), - numMonths = this._getNumberOfMonths( inst ), - showCurrentAtPos = this._get( inst, "showCurrentAtPos" ), - stepMonths = this._get( inst, "stepMonths" ), - isMultiMonth = ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ), - currentDate = this._daylightSavingAdjust( ( !inst.currentDay ? new Date( 9999, 9, 9 ) : - new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ), - minDate = this._getMinMaxDate( inst, "min" ), - maxDate = this._getMinMaxDate( inst, "max" ), - drawMonth = inst.drawMonth - showCurrentAtPos, - drawYear = inst.drawYear; - - if ( drawMonth < 0 ) { - drawMonth += 12; - drawYear--; - } - if ( maxDate ) { - maxDraw = this._daylightSavingAdjust( new Date( maxDate.getFullYear(), - maxDate.getMonth() - ( numMonths[ 0 ] * numMonths[ 1 ] ) + 1, maxDate.getDate() ) ); - maxDraw = ( minDate && maxDraw < minDate ? minDate : maxDraw ); - while ( this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 ) ) > maxDraw ) { - drawMonth--; - if ( drawMonth < 0 ) { - drawMonth = 11; - drawYear--; - } - } - } - inst.drawMonth = drawMonth; - inst.drawYear = drawYear; - - prevText = this._get( inst, "prevText" ); - prevText = ( !navigationAsDateFormat ? prevText : this.formatDate( prevText, - this._daylightSavingAdjust( new Date( drawYear, drawMonth - stepMonths, 1 ) ), - this._getFormatConfig( inst ) ) ); - - if ( this._canAdjustMonth( inst, -1, drawYear, drawMonth ) ) { - prev = $( "<a>" ) - .attr( { - "class": "ui-datepicker-prev ui-corner-all", - "data-handler": "prev", - "data-event": "click", - title: prevText - } ) - .append( - $( "<span>" ) - .addClass( "ui-icon ui-icon-circle-triangle-" + - ( isRTL ? "e" : "w" ) ) - .text( prevText ) - )[ 0 ].outerHTML; - } else if ( hideIfNoPrevNext ) { - prev = ""; - } else { - prev = $( "<a>" ) - .attr( { - "class": "ui-datepicker-prev ui-corner-all ui-state-disabled", - title: prevText - } ) - .append( - $( "<span>" ) - .addClass( "ui-icon ui-icon-circle-triangle-" + - ( isRTL ? "e" : "w" ) ) - .text( prevText ) - )[ 0 ].outerHTML; - } - - nextText = this._get( inst, "nextText" ); - nextText = ( !navigationAsDateFormat ? nextText : this.formatDate( nextText, - this._daylightSavingAdjust( new Date( drawYear, drawMonth + stepMonths, 1 ) ), - this._getFormatConfig( inst ) ) ); - - if ( this._canAdjustMonth( inst, +1, drawYear, drawMonth ) ) { - next = $( "<a>" ) - .attr( { - "class": "ui-datepicker-next ui-corner-all", - "data-handler": "next", - "data-event": "click", - title: nextText - } ) - .append( - $( "<span>" ) - .addClass( "ui-icon ui-icon-circle-triangle-" + - ( isRTL ? "w" : "e" ) ) - .text( nextText ) - )[ 0 ].outerHTML; - } else if ( hideIfNoPrevNext ) { - next = ""; - } else { - next = $( "<a>" ) - .attr( { - "class": "ui-datepicker-next ui-corner-all ui-state-disabled", - title: nextText - } ) - .append( - $( "<span>" ) - .attr( "class", "ui-icon ui-icon-circle-triangle-" + - ( isRTL ? "w" : "e" ) ) - .text( nextText ) - )[ 0 ].outerHTML; - } - - currentText = this._get( inst, "currentText" ); - gotoDate = ( this._get( inst, "gotoCurrent" ) && inst.currentDay ? currentDate : today ); - currentText = ( !navigationAsDateFormat ? currentText : - this.formatDate( currentText, gotoDate, this._getFormatConfig( inst ) ) ); - - controls = ""; - if ( !inst.inline ) { - controls = $( "<button>" ) - .attr( { - type: "button", - "class": "ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all", - "data-handler": "hide", - "data-event": "click" - } ) - .text( this._get( inst, "closeText" ) )[ 0 ].outerHTML; - } - - buttonPanel = ""; - if ( showButtonPanel ) { - buttonPanel = $( "<div class='ui-datepicker-buttonpane ui-widget-content'>" ) - .append( isRTL ? controls : "" ) - .append( this._isInRange( inst, gotoDate ) ? - $( "<button>" ) - .attr( { - type: "button", - "class": "ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all", - "data-handler": "today", - "data-event": "click" - } ) - .text( currentText ) : - "" ) - .append( isRTL ? "" : controls )[ 0 ].outerHTML; - } - - firstDay = parseInt( this._get( inst, "firstDay" ), 10 ); - firstDay = ( isNaN( firstDay ) ? 0 : firstDay ); - - showWeek = this._get( inst, "showWeek" ); - dayNames = this._get( inst, "dayNames" ); - dayNamesMin = this._get( inst, "dayNamesMin" ); - monthNames = this._get( inst, "monthNames" ); - monthNamesShort = this._get( inst, "monthNamesShort" ); - beforeShowDay = this._get( inst, "beforeShowDay" ); - showOtherMonths = this._get( inst, "showOtherMonths" ); - selectOtherMonths = this._get( inst, "selectOtherMonths" ); - defaultDate = this._getDefaultDate( inst ); - html = ""; - - for ( row = 0; row < numMonths[ 0 ]; row++ ) { - group = ""; - this.maxRows = 4; - for ( col = 0; col < numMonths[ 1 ]; col++ ) { - selectedDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, inst.selectedDay ) ); - cornerClass = " ui-corner-all"; - calender = ""; - if ( isMultiMonth ) { - calender += "<div class='ui-datepicker-group"; - if ( numMonths[ 1 ] > 1 ) { - switch ( col ) { - case 0: calender += " ui-datepicker-group-first"; - cornerClass = " ui-corner-" + ( isRTL ? "right" : "left" ); break; - case numMonths[ 1 ] - 1: calender += " ui-datepicker-group-last"; - cornerClass = " ui-corner-" + ( isRTL ? "left" : "right" ); break; - default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break; - } - } - calender += "'>"; - } - calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" + - ( /all|left/.test( cornerClass ) && row === 0 ? ( isRTL ? next : prev ) : "" ) + - ( /all|right/.test( cornerClass ) && row === 0 ? ( isRTL ? prev : next ) : "" ) + - this._generateMonthYearHeader( inst, drawMonth, drawYear, minDate, maxDate, - row > 0 || col > 0, monthNames, monthNamesShort ) + // draw month headers - "</div><table class='ui-datepicker-calendar'><thead>" + - "<tr>"; - thead = ( showWeek ? "<th class='ui-datepicker-week-col'>" + this._get( inst, "weekHeader" ) + "</th>" : "" ); - for ( dow = 0; dow < 7; dow++ ) { // days of the week - day = ( dow + firstDay ) % 7; - thead += "<th scope='col'" + ( ( dow + firstDay + 6 ) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "" ) + ">" + - "<span title='" + dayNames[ day ] + "'>" + dayNamesMin[ day ] + "</span></th>"; - } - calender += thead + "</tr></thead><tbody>"; - daysInMonth = this._getDaysInMonth( drawYear, drawMonth ); - if ( drawYear === inst.selectedYear && drawMonth === inst.selectedMonth ) { - inst.selectedDay = Math.min( inst.selectedDay, daysInMonth ); - } - leadDays = ( this._getFirstDayOfMonth( drawYear, drawMonth ) - firstDay + 7 ) % 7; - curRows = Math.ceil( ( leadDays + daysInMonth ) / 7 ); // calculate the number of rows to generate - numRows = ( isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows ); //If multiple months, use the higher number of rows (see #7043) - this.maxRows = numRows; - printDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 - leadDays ) ); - for ( dRow = 0; dRow < numRows; dRow++ ) { // create date picker rows - calender += "<tr>"; - tbody = ( !showWeek ? "" : "<td class='ui-datepicker-week-col'>" + - this._get( inst, "calculateWeek" )( printDate ) + "</td>" ); - for ( dow = 0; dow < 7; dow++ ) { // create date picker days - daySettings = ( beforeShowDay ? - beforeShowDay.apply( ( inst.input ? inst.input[ 0 ] : null ), [ printDate ] ) : [ true, "" ] ); - otherMonth = ( printDate.getMonth() !== drawMonth ); - unselectable = ( otherMonth && !selectOtherMonths ) || !daySettings[ 0 ] || - ( minDate && printDate < minDate ) || ( maxDate && printDate > maxDate ); - tbody += "<td class='" + - ( ( dow + firstDay + 6 ) % 7 >= 5 ? " ui-datepicker-week-end" : "" ) + // highlight weekends - ( otherMonth ? " ui-datepicker-other-month" : "" ) + // highlight days from other months - ( ( printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent ) || // user pressed key - ( defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime() ) ? - - // or defaultDate is current printedDate and defaultDate is selectedDate - " " + this._dayOverClass : "" ) + // highlight selected day - ( unselectable ? " " + this._unselectableClass + " ui-state-disabled" : "" ) + // highlight unselectable days - ( otherMonth && !showOtherMonths ? "" : " " + daySettings[ 1 ] + // highlight custom dates - ( printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "" ) + // highlight selected day - ( printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "" ) ) + "'" + // highlight today (if different) - ( ( !otherMonth || showOtherMonths ) && daySettings[ 2 ] ? " title='" + daySettings[ 2 ].replace( /'/g, "'" ) + "'" : "" ) + // cell title - ( unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'" ) + ">" + // actions - ( otherMonth && !showOtherMonths ? " " : // display for other months - ( unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" + - ( printDate.getTime() === today.getTime() ? " ui-state-highlight" : "" ) + - ( printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "" ) + // highlight selected day - ( otherMonth ? " ui-priority-secondary" : "" ) + // distinguish dates from other months - "' href='#' aria-current='" + ( printDate.getTime() === currentDate.getTime() ? "true" : "false" ) + // mark date as selected for screen reader - "' data-date='" + printDate.getDate() + // store date as data - "'>" + printDate.getDate() + "</a>" ) ) + "</td>"; // display selectable date - printDate.setDate( printDate.getDate() + 1 ); - printDate = this._daylightSavingAdjust( printDate ); - } - calender += tbody + "</tr>"; - } - drawMonth++; - if ( drawMonth > 11 ) { - drawMonth = 0; - drawYear++; - } - calender += "</tbody></table>" + ( isMultiMonth ? "</div>" + - ( ( numMonths[ 0 ] > 0 && col === numMonths[ 1 ] - 1 ) ? "<div class='ui-datepicker-row-break'></div>" : "" ) : "" ); - group += calender; - } - html += group; - } - html += buttonPanel; - inst._keyEvent = false; - return html; - }, - - /* Generate the month and year header. */ - _generateMonthYearHeader: function( inst, drawMonth, drawYear, minDate, maxDate, - secondary, monthNames, monthNamesShort ) { - - var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear, - changeMonth = this._get( inst, "changeMonth" ), - changeYear = this._get( inst, "changeYear" ), - showMonthAfterYear = this._get( inst, "showMonthAfterYear" ), - selectMonthLabel = this._get( inst, "selectMonthLabel" ), - selectYearLabel = this._get( inst, "selectYearLabel" ), - html = "<div class='ui-datepicker-title'>", - monthHtml = ""; - - // Month selection - if ( secondary || !changeMonth ) { - monthHtml += "<span class='ui-datepicker-month'>" + monthNames[ drawMonth ] + "</span>"; - } else { - inMinYear = ( minDate && minDate.getFullYear() === drawYear ); - inMaxYear = ( maxDate && maxDate.getFullYear() === drawYear ); - monthHtml += "<select class='ui-datepicker-month' aria-label='" + selectMonthLabel + "' data-handler='selectMonth' data-event='change'>"; - for ( month = 0; month < 12; month++ ) { - if ( ( !inMinYear || month >= minDate.getMonth() ) && ( !inMaxYear || month <= maxDate.getMonth() ) ) { - monthHtml += "<option value='" + month + "'" + - ( month === drawMonth ? " selected='selected'" : "" ) + - ">" + monthNamesShort[ month ] + "</option>"; - } - } - monthHtml += "</select>"; - } - - if ( !showMonthAfterYear ) { - html += monthHtml + ( secondary || !( changeMonth && changeYear ) ? " " : "" ); - } - - // Year selection - if ( !inst.yearshtml ) { - inst.yearshtml = ""; - if ( secondary || !changeYear ) { - html += "<span class='ui-datepicker-year'>" + drawYear + "</span>"; - } else { - - // determine range of years to display - years = this._get( inst, "yearRange" ).split( ":" ); - thisYear = new Date().getFullYear(); - determineYear = function( value ) { - var year = ( value.match( /c[+\-].*/ ) ? drawYear + parseInt( value.substring( 1 ), 10 ) : - ( value.match( /[+\-].*/ ) ? thisYear + parseInt( value, 10 ) : - parseInt( value, 10 ) ) ); - return ( isNaN( year ) ? thisYear : year ); - }; - year = determineYear( years[ 0 ] ); - endYear = Math.max( year, determineYear( years[ 1 ] || "" ) ); - year = ( minDate ? Math.max( year, minDate.getFullYear() ) : year ); - endYear = ( maxDate ? Math.min( endYear, maxDate.getFullYear() ) : endYear ); - inst.yearshtml += "<select class='ui-datepicker-year' aria-label='" + selectYearLabel + "' data-handler='selectYear' data-event='change'>"; - for ( ; year <= endYear; year++ ) { - inst.yearshtml += "<option value='" + year + "'" + - ( year === drawYear ? " selected='selected'" : "" ) + - ">" + year + "</option>"; - } - inst.yearshtml += "</select>"; - - html += inst.yearshtml; - inst.yearshtml = null; - } - } - - html += this._get( inst, "yearSuffix" ); - if ( showMonthAfterYear ) { - html += ( secondary || !( changeMonth && changeYear ) ? " " : "" ) + monthHtml; - } - html += "</div>"; // Close datepicker_header - return html; - }, - - /* Adjust one of the date sub-fields. */ - _adjustInstDate: function( inst, offset, period ) { - var year = inst.selectedYear + ( period === "Y" ? offset : 0 ), - month = inst.selectedMonth + ( period === "M" ? offset : 0 ), - day = Math.min( inst.selectedDay, this._getDaysInMonth( year, month ) ) + ( period === "D" ? offset : 0 ), - date = this._restrictMinMax( inst, this._daylightSavingAdjust( new Date( year, month, day ) ) ); - - inst.selectedDay = date.getDate(); - inst.drawMonth = inst.selectedMonth = date.getMonth(); - inst.drawYear = inst.selectedYear = date.getFullYear(); - if ( period === "M" || period === "Y" ) { - this._notifyChange( inst ); - } - }, - - /* Ensure a date is within any min/max bounds. */ - _restrictMinMax: function( inst, date ) { - var minDate = this._getMinMaxDate( inst, "min" ), - maxDate = this._getMinMaxDate( inst, "max" ), - newDate = ( minDate && date < minDate ? minDate : date ); - return ( maxDate && newDate > maxDate ? maxDate : newDate ); - }, - - /* Notify change of month/year. */ - _notifyChange: function( inst ) { - var onChange = this._get( inst, "onChangeMonthYear" ); - if ( onChange ) { - onChange.apply( ( inst.input ? inst.input[ 0 ] : null ), - [ inst.selectedYear, inst.selectedMonth + 1, inst ] ); - } - }, - - /* Determine the number of months to show. */ - _getNumberOfMonths: function( inst ) { - var numMonths = this._get( inst, "numberOfMonths" ); - return ( numMonths == null ? [ 1, 1 ] : ( typeof numMonths === "number" ? [ 1, numMonths ] : numMonths ) ); - }, - - /* Determine the current maximum date - ensure no time components are set. */ - _getMinMaxDate: function( inst, minMax ) { - return this._determineDate( inst, this._get( inst, minMax + "Date" ), null ); - }, - - /* Find the number of days in a given month. */ - _getDaysInMonth: function( year, month ) { - return 32 - this._daylightSavingAdjust( new Date( year, month, 32 ) ).getDate(); - }, - - /* Find the day of the week of the first of a month. */ - _getFirstDayOfMonth: function( year, month ) { - return new Date( year, month, 1 ).getDay(); - }, - - /* Determines if we should allow a "next/prev" month display change. */ - _canAdjustMonth: function( inst, offset, curYear, curMonth ) { - var numMonths = this._getNumberOfMonths( inst ), - date = this._daylightSavingAdjust( new Date( curYear, - curMonth + ( offset < 0 ? offset : numMonths[ 0 ] * numMonths[ 1 ] ), 1 ) ); - - if ( offset < 0 ) { - date.setDate( this._getDaysInMonth( date.getFullYear(), date.getMonth() ) ); - } - return this._isInRange( inst, date ); - }, - - /* Is the given date in the accepted range? */ - _isInRange: function( inst, date ) { - var yearSplit, currentYear, - minDate = this._getMinMaxDate( inst, "min" ), - maxDate = this._getMinMaxDate( inst, "max" ), - minYear = null, - maxYear = null, - years = this._get( inst, "yearRange" ); - if ( years ) { - yearSplit = years.split( ":" ); - currentYear = new Date().getFullYear(); - minYear = parseInt( yearSplit[ 0 ], 10 ); - maxYear = parseInt( yearSplit[ 1 ], 10 ); - if ( yearSplit[ 0 ].match( /[+\-].*/ ) ) { - minYear += currentYear; - } - if ( yearSplit[ 1 ].match( /[+\-].*/ ) ) { - maxYear += currentYear; - } - } - - return ( ( !minDate || date.getTime() >= minDate.getTime() ) && - ( !maxDate || date.getTime() <= maxDate.getTime() ) && - ( !minYear || date.getFullYear() >= minYear ) && - ( !maxYear || date.getFullYear() <= maxYear ) ); - }, - - /* Provide the configuration settings for formatting/parsing. */ - _getFormatConfig: function( inst ) { - var shortYearCutoff = this._get( inst, "shortYearCutoff" ); - shortYearCutoff = ( typeof shortYearCutoff !== "string" ? shortYearCutoff : - new Date().getFullYear() % 100 + parseInt( shortYearCutoff, 10 ) ); - return { shortYearCutoff: shortYearCutoff, - dayNamesShort: this._get( inst, "dayNamesShort" ), dayNames: this._get( inst, "dayNames" ), - monthNamesShort: this._get( inst, "monthNamesShort" ), monthNames: this._get( inst, "monthNames" ) }; - }, - - /* Format the given date for display. */ - _formatDate: function( inst, day, month, year ) { - if ( !day ) { - inst.currentDay = inst.selectedDay; - inst.currentMonth = inst.selectedMonth; - inst.currentYear = inst.selectedYear; - } - var date = ( day ? ( typeof day === "object" ? day : - this._daylightSavingAdjust( new Date( year, month, day ) ) ) : - this._daylightSavingAdjust( new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ); - return this.formatDate( this._get( inst, "dateFormat" ), date, this._getFormatConfig( inst ) ); - } -} ); - -/* - * Bind hover events for datepicker elements. - * Done via delegate so the binding only occurs once in the lifetime of the parent div. - * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. - */ -function datepicker_bindHover( dpDiv ) { - var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a"; - return dpDiv.on( "mouseout", selector, function() { - $( this ).removeClass( "ui-state-hover" ); - if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) { - $( this ).removeClass( "ui-datepicker-prev-hover" ); - } - if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) { - $( this ).removeClass( "ui-datepicker-next-hover" ); - } - } ) - .on( "mouseover", selector, datepicker_handleMouseover ); -} - -function datepicker_handleMouseover() { - if ( !$.datepicker._isDisabledDatepicker( datepicker_instActive.inline ? datepicker_instActive.dpDiv.parent()[ 0 ] : datepicker_instActive.input[ 0 ] ) ) { - $( this ).parents( ".ui-datepicker-calendar" ).find( "a" ).removeClass( "ui-state-hover" ); - $( this ).addClass( "ui-state-hover" ); - if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) { - $( this ).addClass( "ui-datepicker-prev-hover" ); - } - if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) { - $( this ).addClass( "ui-datepicker-next-hover" ); - } - } -} - -/* jQuery extend now ignores nulls! */ -function datepicker_extendRemove( target, props ) { - $.extend( target, props ); - for ( var name in props ) { - if ( props[ name ] == null ) { - target[ name ] = props[ name ]; - } - } - return target; -} - -/* Invoke the datepicker functionality. - @param options string - a command, optionally followed by additional parameters or - Object - settings for attaching new datepicker functionality - @return jQuery object */ -$.fn.datepicker = function( options ) { - - /* Verify an empty collection wasn't passed - Fixes #6976 */ - if ( !this.length ) { - return this; - } - - /* Initialise the date picker. */ - if ( !$.datepicker.initialized ) { - $( document ).on( "mousedown", $.datepicker._checkExternalClick ); - $.datepicker.initialized = true; - } - - /* Append datepicker main container to body if not exist. */ - if ( $( "#" + $.datepicker._mainDivId ).length === 0 ) { - $( "body" ).append( $.datepicker.dpDiv ); - } - - var otherArgs = Array.prototype.slice.call( arguments, 1 ); - if ( typeof options === "string" && ( options === "isDisabled" || options === "getDate" || options === "widget" ) ) { - return $.datepicker[ "_" + options + "Datepicker" ]. - apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) ); - } - if ( options === "option" && arguments.length === 2 && typeof arguments[ 1 ] === "string" ) { - return $.datepicker[ "_" + options + "Datepicker" ]. - apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) ); - } - return this.each( function() { - if ( typeof options === "string" ) { - $.datepicker[ "_" + options + "Datepicker" ] - .apply( $.datepicker, [ this ].concat( otherArgs ) ); - } else { - $.datepicker._attachDatepicker( this, options ); - } - } ); -}; - -$.datepicker = new Datepicker(); // singleton instance -$.datepicker.initialized = false; -$.datepicker.uuid = new Date().getTime(); -$.datepicker.version = "1.13.1"; - -return $.datepicker; + "use strict"; + + $.extend( $.ui, { datepicker: { version: "1.13.2" } } ); + + var datepicker_instActive; + + function datepicker_getZindex( elem ) { + var position, value; + while ( elem.length && elem[ 0 ] !== document ) { + + // Ignore z-index if position is set to a value where z-index is ignored by the browser + // This makes behavior of this function consistent across browsers + // WebKit always returns auto if the element is positioned + position = elem.css( "position" ); + if ( position === "absolute" || position === "relative" || position === "fixed" ) { + + // IE returns 0 when zIndex is not specified + // other browsers return a string + // we ignore the case of nested elements with an explicit value of 0 + // <div style="z-index: -10;"><div style="z-index: 0;"></div></div> + value = parseInt( elem.css( "zIndex" ), 10 ); + if ( !isNaN( value ) && value !== 0 ) { + return value; + } + } + elem = elem.parent(); + } + + return 0; + } + + /* Date picker manager. + Use the singleton instance of this class, $.datepicker, to interact with the date picker. + Settings for (groups of) date pickers are maintained in an instance object, + allowing multiple different settings on the same page. */ + + function Datepicker() { + this._curInst = null; // The current instance in use + this._keyEvent = false; // If the last event was a key event + this._disabledInputs = []; // List of date picker inputs that have been disabled + this._datepickerShowing = false; // True if the popup picker is showing , false if not + this._inDialog = false; // True if showing within a "dialog", false if not + this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division + this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class + this._appendClass = "ui-datepicker-append"; // The name of the append marker class + this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class + this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class + this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class + this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class + this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class + this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class + this.regional = []; // Available regional settings, indexed by language code + this.regional[ "" ] = { // Default regional settings + closeText: "Done", // Display text for close link + prevText: "Prev", // Display text for previous month link + nextText: "Next", // Display text for next month link + currentText: "Today", // Display text for current month link + monthNames: [ "January", "February", "March", "April", "May", "June", + "July", "August", "September", "October", "November", "December" ], // Names of months for drop-down and formatting + monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ], // For formatting + dayNames: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], // For formatting + dayNamesShort: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], // For formatting + dayNamesMin: [ "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" ], // Column headings for days starting at Sunday + weekHeader: "Wk", // Column header for week of the year + dateFormat: "mm/dd/yy", // See format options on parseDate + firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... + isRTL: false, // True if right-to-left language, false if left-to-right + showMonthAfterYear: false, // True if the year select precedes month, false for month then year + yearSuffix: "", // Additional text to append to the year in the month headers, + selectMonthLabel: "Select month", // Invisible label for month selector + selectYearLabel: "Select year" // Invisible label for year selector + }; + this._defaults = { // Global defaults for all the date picker instances + showOn: "focus", // "focus" for popup on focus, + // "button" for trigger button, or "both" for either + showAnim: "fadeIn", // Name of jQuery animation for popup + showOptions: {}, // Options for enhanced animations + defaultDate: null, // Used when field is blank: actual date, + // +/-number for offset from today, null for today + appendText: "", // Display text following the input box, e.g. showing the format + buttonText: "...", // Text for trigger button + buttonImage: "", // URL for trigger button image + buttonImageOnly: false, // True if the image appears alone, false if it appears on a button + hideIfNoPrevNext: false, // True to hide next/previous month links + // if not applicable, false to just disable them + navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links + gotoCurrent: false, // True if today link goes back to current selection instead + changeMonth: false, // True if month can be selected directly, false if only prev/next + changeYear: false, // True if year can be selected directly, false if only prev/next + yearRange: "c-10:c+10", // Range of years to display in drop-down, + // either relative to today's year (-nn:+nn), relative to currently displayed year + // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n) + showOtherMonths: false, // True to show dates in other months, false to leave blank + selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable + showWeek: false, // True to show week of the year, false to not show it + calculateWeek: this.iso8601Week, // How to calculate the week of the year, + // takes a Date and returns the number of the week for it + shortYearCutoff: "+10", // Short year values < this are in the current century, + // > this are in the previous century, + // string value starting with "+" for current year + value + minDate: null, // The earliest selectable date, or null for no limit + maxDate: null, // The latest selectable date, or null for no limit + duration: "fast", // Duration of display/closure + beforeShowDay: null, // Function that takes a date and returns an array with + // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "", + // [2] = cell title (optional), e.g. $.datepicker.noWeekends + beforeShow: null, // Function that takes an input field and + // returns a set of custom settings for the date picker + onSelect: null, // Define a callback function when a date is selected + onChangeMonthYear: null, // Define a callback function when the month or year is changed + onClose: null, // Define a callback function when the datepicker is closed + onUpdateDatepicker: null, // Define a callback function when the datepicker is updated + numberOfMonths: 1, // Number of months to show at a time + showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0) + stepMonths: 1, // Number of months to step back/forward + stepBigMonths: 12, // Number of months to step back/forward for the big links + altField: "", // Selector for an alternate field to store selected dates into + altFormat: "", // The date format to use for the alternate field + constrainInput: true, // The input is constrained by the current date format + showButtonPanel: false, // True to show button panel, false to not show it + autoSize: false, // True to size the input for the date format, false to leave as is + disabled: false // The initial disabled state + }; + $.extend( this._defaults, this.regional[ "" ] ); + this.regional.en = $.extend( true, {}, this.regional[ "" ] ); + this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en ); + this.dpDiv = datepicker_bindHover( $( "<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ); + } + + $.extend( Datepicker.prototype, { + + /* Class name added to elements to indicate already configured with a date picker. */ + markerClassName: "hasDatepicker", + + //Keep track of the maximum number of rows displayed (see #7043) + maxRows: 4, + + // TODO rename to "widget" when switching to widget factory + _widgetDatepicker: function() { + return this.dpDiv; + }, + + /* Override the default settings for all instances of the date picker. + * @param settings object - the new settings to use as defaults (anonymous object) + * @return the manager object + */ + setDefaults: function( settings ) { + datepicker_extendRemove( this._defaults, settings || {} ); + return this; + }, + + /* Attach the date picker to a jQuery selection. + * @param target element - the target input field or division or span + * @param settings object - the new settings to use for this date picker instance (anonymous) + */ + _attachDatepicker: function( target, settings ) { + var nodeName, inline, inst; + nodeName = target.nodeName.toLowerCase(); + inline = ( nodeName === "div" || nodeName === "span" ); + if ( !target.id ) { + this.uuid += 1; + target.id = "dp" + this.uuid; + } + inst = this._newInst( $( target ), inline ); + inst.settings = $.extend( {}, settings || {} ); + if ( nodeName === "input" ) { + this._connectDatepicker( target, inst ); + } else if ( inline ) { + this._inlineDatepicker( target, inst ); + } + }, + + /* Create a new instance object. */ + _newInst: function( target, inline ) { + var id = target[ 0 ].id.replace( /([^A-Za-z0-9_\-])/g, "\\\\$1" ); // escape jQuery meta chars + return { id: id, input: target, // associated target + selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection + drawMonth: 0, drawYear: 0, // month being drawn + inline: inline, // is datepicker inline or not + dpDiv: ( !inline ? this.dpDiv : // presentation div + datepicker_bindHover( $( "<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ) ) }; + }, + + /* Attach the date picker to an input field. */ + _connectDatepicker: function( target, inst ) { + var input = $( target ); + inst.append = $( [] ); + inst.trigger = $( [] ); + if ( input.hasClass( this.markerClassName ) ) { + return; + } + this._attachments( input, inst ); + input.addClass( this.markerClassName ).on( "keydown", this._doKeyDown ). + on( "keypress", this._doKeyPress ).on( "keyup", this._doKeyUp ); + this._autoSize( inst ); + $.data( target, "datepicker", inst ); + + //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665) + if ( inst.settings.disabled ) { + this._disableDatepicker( target ); + } + }, + + /* Make attachments based on settings. */ + _attachments: function( input, inst ) { + var showOn, buttonText, buttonImage, + appendText = this._get( inst, "appendText" ), + isRTL = this._get( inst, "isRTL" ); + + if ( inst.append ) { + inst.append.remove(); + } + if ( appendText ) { + inst.append = $( "<span>" ) + .addClass( this._appendClass ) + .text( appendText ); + input[ isRTL ? "before" : "after" ]( inst.append ); + } + + input.off( "focus", this._showDatepicker ); + + if ( inst.trigger ) { + inst.trigger.remove(); + } + + showOn = this._get( inst, "showOn" ); + if ( showOn === "focus" || showOn === "both" ) { // pop-up date picker when in the marked field + input.on( "focus", this._showDatepicker ); + } + if ( showOn === "button" || showOn === "both" ) { // pop-up date picker when button clicked + buttonText = this._get( inst, "buttonText" ); + buttonImage = this._get( inst, "buttonImage" ); + + if ( this._get( inst, "buttonImageOnly" ) ) { + inst.trigger = $( "<img>" ) + .addClass( this._triggerClass ) + .attr( { + src: buttonImage, + alt: buttonText, + title: buttonText + } ); + } else { + inst.trigger = $( "<button type='button'>" ) + .addClass( this._triggerClass ); + if ( buttonImage ) { + inst.trigger.html( + $( "<img>" ) + .attr( { + src: buttonImage, + alt: buttonText, + title: buttonText + } ) + ); + } else { + inst.trigger.text( buttonText ); + } + } + + input[ isRTL ? "before" : "after" ]( inst.trigger ); + inst.trigger.on( "click", function() { + if ( $.datepicker._datepickerShowing && $.datepicker._lastInput === input[ 0 ] ) { + $.datepicker._hideDatepicker(); + } else if ( $.datepicker._datepickerShowing && $.datepicker._lastInput !== input[ 0 ] ) { + $.datepicker._hideDatepicker(); + $.datepicker._showDatepicker( input[ 0 ] ); + } else { + $.datepicker._showDatepicker( input[ 0 ] ); + } + return false; + } ); + } + }, + + /* Apply the maximum length for the date format. */ + _autoSize: function( inst ) { + if ( this._get( inst, "autoSize" ) && !inst.inline ) { + var findMax, max, maxI, i, + date = new Date( 2009, 12 - 1, 20 ), // Ensure double digits + dateFormat = this._get( inst, "dateFormat" ); + + if ( dateFormat.match( /[DM]/ ) ) { + findMax = function( names ) { + max = 0; + maxI = 0; + for ( i = 0; i < names.length; i++ ) { + if ( names[ i ].length > max ) { + max = names[ i ].length; + maxI = i; + } + } + return maxI; + }; + date.setMonth( findMax( this._get( inst, ( dateFormat.match( /MM/ ) ? + "monthNames" : "monthNamesShort" ) ) ) ); + date.setDate( findMax( this._get( inst, ( dateFormat.match( /DD/ ) ? + "dayNames" : "dayNamesShort" ) ) ) + 20 - date.getDay() ); + } + inst.input.attr( "size", this._formatDate( inst, date ).length ); + } + }, + + /* Attach an inline date picker to a div. */ + _inlineDatepicker: function( target, inst ) { + var divSpan = $( target ); + if ( divSpan.hasClass( this.markerClassName ) ) { + return; + } + divSpan.addClass( this.markerClassName ).append( inst.dpDiv ); + $.data( target, "datepicker", inst ); + this._setDate( inst, this._getDefaultDate( inst ), true ); + this._updateDatepicker( inst ); + this._updateAlternate( inst ); + + //If disabled option is true, disable the datepicker before showing it (see ticket #5665) + if ( inst.settings.disabled ) { + this._disableDatepicker( target ); + } + + // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements + // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height + inst.dpDiv.css( "display", "block" ); + }, + + /* Pop-up the date picker in a "dialog" box. + * @param input element - ignored + * @param date string or Date - the initial date to display + * @param onSelect function - the function to call when a date is selected + * @param settings object - update the dialog date picker instance's settings (anonymous object) + * @param pos int[2] - coordinates for the dialog's position within the screen or + * event - with x/y coordinates or + * leave empty for default (screen centre) + * @return the manager object + */ + _dialogDatepicker: function( input, date, onSelect, settings, pos ) { + var id, browserWidth, browserHeight, scrollX, scrollY, + inst = this._dialogInst; // internal instance + + if ( !inst ) { + this.uuid += 1; + id = "dp" + this.uuid; + this._dialogInput = $( "<input type='text' id='" + id + + "' style='position: absolute; top: -100px; width: 0px;'/>" ); + this._dialogInput.on( "keydown", this._doKeyDown ); + $( "body" ).append( this._dialogInput ); + inst = this._dialogInst = this._newInst( this._dialogInput, false ); + inst.settings = {}; + $.data( this._dialogInput[ 0 ], "datepicker", inst ); + } + datepicker_extendRemove( inst.settings, settings || {} ); + date = ( date && date.constructor === Date ? this._formatDate( inst, date ) : date ); + this._dialogInput.val( date ); + + this._pos = ( pos ? ( pos.length ? pos : [ pos.pageX, pos.pageY ] ) : null ); + if ( !this._pos ) { + browserWidth = document.documentElement.clientWidth; + browserHeight = document.documentElement.clientHeight; + scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; + scrollY = document.documentElement.scrollTop || document.body.scrollTop; + this._pos = // should use actual width/height below + [ ( browserWidth / 2 ) - 100 + scrollX, ( browserHeight / 2 ) - 150 + scrollY ]; + } + + // Move input on screen for focus, but hidden behind dialog + this._dialogInput.css( "left", ( this._pos[ 0 ] + 20 ) + "px" ).css( "top", this._pos[ 1 ] + "px" ); + inst.settings.onSelect = onSelect; + this._inDialog = true; + this.dpDiv.addClass( this._dialogClass ); + this._showDatepicker( this._dialogInput[ 0 ] ); + if ( $.blockUI ) { + $.blockUI( this.dpDiv ); + } + $.data( this._dialogInput[ 0 ], "datepicker", inst ); + return this; + }, + + /* Detach a datepicker from its control. + * @param target element - the target input field or division or span + */ + _destroyDatepicker: function( target ) { + var nodeName, + $target = $( target ), + inst = $.data( target, "datepicker" ); + + if ( !$target.hasClass( this.markerClassName ) ) { + return; + } + + nodeName = target.nodeName.toLowerCase(); + $.removeData( target, "datepicker" ); + if ( nodeName === "input" ) { + inst.append.remove(); + inst.trigger.remove(); + $target.removeClass( this.markerClassName ). + off( "focus", this._showDatepicker ). + off( "keydown", this._doKeyDown ). + off( "keypress", this._doKeyPress ). + off( "keyup", this._doKeyUp ); + } else if ( nodeName === "div" || nodeName === "span" ) { + $target.removeClass( this.markerClassName ).empty(); + } + + if ( datepicker_instActive === inst ) { + datepicker_instActive = null; + this._curInst = null; + } + }, + + /* Enable the date picker to a jQuery selection. + * @param target element - the target input field or division or span + */ + _enableDatepicker: function( target ) { + var nodeName, inline, + $target = $( target ), + inst = $.data( target, "datepicker" ); + + if ( !$target.hasClass( this.markerClassName ) ) { + return; + } + + nodeName = target.nodeName.toLowerCase(); + if ( nodeName === "input" ) { + target.disabled = false; + inst.trigger.filter( "button" ). + each( function() { + this.disabled = false; + } ).end(). + filter( "img" ).css( { opacity: "1.0", cursor: "" } ); + } else if ( nodeName === "div" || nodeName === "span" ) { + inline = $target.children( "." + this._inlineClass ); + inline.children().removeClass( "ui-state-disabled" ); + inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ). + prop( "disabled", false ); + } + this._disabledInputs = $.map( this._disabledInputs, + + // Delete entry + function( value ) { + return ( value === target ? null : value ); + } ); + }, + + /* Disable the date picker to a jQuery selection. + * @param target element - the target input field or division or span + */ + _disableDatepicker: function( target ) { + var nodeName, inline, + $target = $( target ), + inst = $.data( target, "datepicker" ); + + if ( !$target.hasClass( this.markerClassName ) ) { + return; + } + + nodeName = target.nodeName.toLowerCase(); + if ( nodeName === "input" ) { + target.disabled = true; + inst.trigger.filter( "button" ). + each( function() { + this.disabled = true; + } ).end(). + filter( "img" ).css( { opacity: "0.5", cursor: "default" } ); + } else if ( nodeName === "div" || nodeName === "span" ) { + inline = $target.children( "." + this._inlineClass ); + inline.children().addClass( "ui-state-disabled" ); + inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ). + prop( "disabled", true ); + } + this._disabledInputs = $.map( this._disabledInputs, + + // Delete entry + function( value ) { + return ( value === target ? null : value ); + } ); + this._disabledInputs[ this._disabledInputs.length ] = target; + }, + + /* Is the first field in a jQuery collection disabled as a datepicker? + * @param target element - the target input field or division or span + * @return boolean - true if disabled, false if enabled + */ + _isDisabledDatepicker: function( target ) { + if ( !target ) { + return false; + } + for ( var i = 0; i < this._disabledInputs.length; i++ ) { + if ( this._disabledInputs[ i ] === target ) { + return true; + } + } + return false; + }, + + /* Retrieve the instance data for the target control. + * @param target element - the target input field or division or span + * @return object - the associated instance data + * @throws error if a jQuery problem getting data + */ + _getInst: function( target ) { + try { + return $.data( target, "datepicker" ); + } catch ( err ) { + throw "Missing instance data for this datepicker"; + } + }, + + /* Update or retrieve the settings for a date picker attached to an input field or division. + * @param target element - the target input field or division or span + * @param name object - the new settings to update or + * string - the name of the setting to change or retrieve, + * when retrieving also "all" for all instance settings or + * "defaults" for all global defaults + * @param value any - the new value for the setting + * (omit if above is an object or to retrieve a value) + */ + _optionDatepicker: function( target, name, value ) { + var settings, date, minDate, maxDate, + inst = this._getInst( target ); + + if ( arguments.length === 2 && typeof name === "string" ) { + return ( name === "defaults" ? $.extend( {}, $.datepicker._defaults ) : + ( inst ? ( name === "all" ? $.extend( {}, inst.settings ) : + this._get( inst, name ) ) : null ) ); + } + + settings = name || {}; + if ( typeof name === "string" ) { + settings = {}; + settings[ name ] = value; + } + + if ( inst ) { + if ( this._curInst === inst ) { + this._hideDatepicker(); + } + + date = this._getDateDatepicker( target, true ); + minDate = this._getMinMaxDate( inst, "min" ); + maxDate = this._getMinMaxDate( inst, "max" ); + datepicker_extendRemove( inst.settings, settings ); + + // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided + if ( minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined ) { + inst.settings.minDate = this._formatDate( inst, minDate ); + } + if ( maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined ) { + inst.settings.maxDate = this._formatDate( inst, maxDate ); + } + if ( "disabled" in settings ) { + if ( settings.disabled ) { + this._disableDatepicker( target ); + } else { + this._enableDatepicker( target ); + } + } + this._attachments( $( target ), inst ); + this._autoSize( inst ); + this._setDate( inst, date ); + this._updateAlternate( inst ); + this._updateDatepicker( inst ); + } + }, + + // Change method deprecated + _changeDatepicker: function( target, name, value ) { + this._optionDatepicker( target, name, value ); + }, + + /* Redraw the date picker attached to an input field or division. + * @param target element - the target input field or division or span + */ + _refreshDatepicker: function( target ) { + var inst = this._getInst( target ); + if ( inst ) { + this._updateDatepicker( inst ); + } + }, + + /* Set the dates for a jQuery selection. + * @param target element - the target input field or division or span + * @param date Date - the new date + */ + _setDateDatepicker: function( target, date ) { + var inst = this._getInst( target ); + if ( inst ) { + this._setDate( inst, date ); + this._updateDatepicker( inst ); + this._updateAlternate( inst ); + } + }, + + /* Get the date(s) for the first entry in a jQuery selection. + * @param target element - the target input field or division or span + * @param noDefault boolean - true if no default date is to be used + * @return Date - the current date + */ + _getDateDatepicker: function( target, noDefault ) { + var inst = this._getInst( target ); + if ( inst && !inst.inline ) { + this._setDateFromField( inst, noDefault ); + } + return ( inst ? this._getDate( inst ) : null ); + }, + + /* Handle keystrokes. */ + _doKeyDown: function( event ) { + var onSelect, dateStr, sel, + inst = $.datepicker._getInst( event.target ), + handled = true, + isRTL = inst.dpDiv.is( ".ui-datepicker-rtl" ); + + inst._keyEvent = true; + if ( $.datepicker._datepickerShowing ) { + switch ( event.keyCode ) { + case 9: $.datepicker._hideDatepicker(); + handled = false; + break; // hide on tab out + case 13: sel = $( "td." + $.datepicker._dayOverClass + ":not(." + + $.datepicker._currentClass + ")", inst.dpDiv ); + if ( sel[ 0 ] ) { + $.datepicker._selectDay( event.target, inst.selectedMonth, inst.selectedYear, sel[ 0 ] ); + } + + onSelect = $.datepicker._get( inst, "onSelect" ); + if ( onSelect ) { + dateStr = $.datepicker._formatDate( inst ); + + // Trigger custom callback + onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] ); + } else { + $.datepicker._hideDatepicker(); + } + + return false; // don't submit the form + case 27: $.datepicker._hideDatepicker(); + break; // hide on escape + case 33: $.datepicker._adjustDate( event.target, ( event.ctrlKey ? + -$.datepicker._get( inst, "stepBigMonths" ) : + -$.datepicker._get( inst, "stepMonths" ) ), "M" ); + break; // previous month/year on page up/+ ctrl + case 34: $.datepicker._adjustDate( event.target, ( event.ctrlKey ? + +$.datepicker._get( inst, "stepBigMonths" ) : + +$.datepicker._get( inst, "stepMonths" ) ), "M" ); + break; // next month/year on page down/+ ctrl + case 35: if ( event.ctrlKey || event.metaKey ) { + $.datepicker._clearDate( event.target ); + } + handled = event.ctrlKey || event.metaKey; + break; // clear on ctrl or command +end + case 36: if ( event.ctrlKey || event.metaKey ) { + $.datepicker._gotoToday( event.target ); + } + handled = event.ctrlKey || event.metaKey; + break; // current on ctrl or command +home + case 37: if ( event.ctrlKey || event.metaKey ) { + $.datepicker._adjustDate( event.target, ( isRTL ? +1 : -1 ), "D" ); + } + handled = event.ctrlKey || event.metaKey; + + // -1 day on ctrl or command +left + if ( event.originalEvent.altKey ) { + $.datepicker._adjustDate( event.target, ( event.ctrlKey ? + -$.datepicker._get( inst, "stepBigMonths" ) : + -$.datepicker._get( inst, "stepMonths" ) ), "M" ); + } + + // next month/year on alt +left on Mac + break; + case 38: if ( event.ctrlKey || event.metaKey ) { + $.datepicker._adjustDate( event.target, -7, "D" ); + } + handled = event.ctrlKey || event.metaKey; + break; // -1 week on ctrl or command +up + case 39: if ( event.ctrlKey || event.metaKey ) { + $.datepicker._adjustDate( event.target, ( isRTL ? -1 : +1 ), "D" ); + } + handled = event.ctrlKey || event.metaKey; + + // +1 day on ctrl or command +right + if ( event.originalEvent.altKey ) { + $.datepicker._adjustDate( event.target, ( event.ctrlKey ? + +$.datepicker._get( inst, "stepBigMonths" ) : + +$.datepicker._get( inst, "stepMonths" ) ), "M" ); + } + + // next month/year on alt +right + break; + case 40: if ( event.ctrlKey || event.metaKey ) { + $.datepicker._adjustDate( event.target, +7, "D" ); + } + handled = event.ctrlKey || event.metaKey; + break; // +1 week on ctrl or command +down + default: handled = false; + } + } else if ( event.keyCode === 36 && event.ctrlKey ) { // display the date picker on ctrl+home + $.datepicker._showDatepicker( this ); + } else { + handled = false; + } + + if ( handled ) { + event.preventDefault(); + event.stopPropagation(); + } + }, + + /* Filter entered characters - based on date format. */ + _doKeyPress: function( event ) { + var chars, chr, + inst = $.datepicker._getInst( event.target ); + + if ( $.datepicker._get( inst, "constrainInput" ) ) { + chars = $.datepicker._possibleChars( $.datepicker._get( inst, "dateFormat" ) ); + chr = String.fromCharCode( event.charCode == null ? event.keyCode : event.charCode ); + return event.ctrlKey || event.metaKey || ( chr < " " || !chars || chars.indexOf( chr ) > -1 ); + } + }, + + /* Synchronise manual entry and field/alternate field. */ + _doKeyUp: function( event ) { + var date, + inst = $.datepicker._getInst( event.target ); + + if ( inst.input.val() !== inst.lastVal ) { + try { + date = $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ), + ( inst.input ? inst.input.val() : null ), + $.datepicker._getFormatConfig( inst ) ); + + if ( date ) { // only if valid + $.datepicker._setDateFromField( inst ); + $.datepicker._updateAlternate( inst ); + $.datepicker._updateDatepicker( inst ); + } + } catch ( err ) { + } + } + return true; + }, + + /* Pop-up the date picker for a given input field. + * If false returned from beforeShow event handler do not show. + * @param input element - the input field attached to the date picker or + * event - if triggered by focus + */ + _showDatepicker: function( input ) { + input = input.target || input; + if ( input.nodeName.toLowerCase() !== "input" ) { // find from button/image trigger + input = $( "input", input.parentNode )[ 0 ]; + } + + if ( $.datepicker._isDisabledDatepicker( input ) || $.datepicker._lastInput === input ) { // already here + return; + } + + var inst, beforeShow, beforeShowSettings, isFixed, + offset, showAnim, duration; + + inst = $.datepicker._getInst( input ); + if ( $.datepicker._curInst && $.datepicker._curInst !== inst ) { + $.datepicker._curInst.dpDiv.stop( true, true ); + if ( inst && $.datepicker._datepickerShowing ) { + $.datepicker._hideDatepicker( $.datepicker._curInst.input[ 0 ] ); + } + } + + beforeShow = $.datepicker._get( inst, "beforeShow" ); + beforeShowSettings = beforeShow ? beforeShow.apply( input, [ input, inst ] ) : {}; + if ( beforeShowSettings === false ) { + return; + } + datepicker_extendRemove( inst.settings, beforeShowSettings ); + + inst.lastVal = null; + $.datepicker._lastInput = input; + $.datepicker._setDateFromField( inst ); + + if ( $.datepicker._inDialog ) { // hide cursor + input.value = ""; + } + if ( !$.datepicker._pos ) { // position below input + $.datepicker._pos = $.datepicker._findPos( input ); + $.datepicker._pos[ 1 ] += input.offsetHeight; // add the height + } + + isFixed = false; + $( input ).parents().each( function() { + isFixed |= $( this ).css( "position" ) === "fixed"; + return !isFixed; + } ); + + offset = { left: $.datepicker._pos[ 0 ], top: $.datepicker._pos[ 1 ] }; + $.datepicker._pos = null; + + //to avoid flashes on Firefox + inst.dpDiv.empty(); + + // determine sizing offscreen + inst.dpDiv.css( { position: "absolute", display: "block", top: "-1000px" } ); + $.datepicker._updateDatepicker( inst ); + + // fix width for dynamic number of date pickers + // and adjust position before showing + offset = $.datepicker._checkOffset( inst, offset, isFixed ); + inst.dpDiv.css( { position: ( $.datepicker._inDialog && $.blockUI ? + "static" : ( isFixed ? "fixed" : "absolute" ) ), display: "none", + left: offset.left + "px", top: offset.top + "px" } ); + + if ( !inst.inline ) { + showAnim = $.datepicker._get( inst, "showAnim" ); + duration = $.datepicker._get( inst, "duration" ); + inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 ); + $.datepicker._datepickerShowing = true; + + if ( $.effects && $.effects.effect[ showAnim ] ) { + inst.dpDiv.show( showAnim, $.datepicker._get( inst, "showOptions" ), duration ); + } else { + inst.dpDiv[ showAnim || "show" ]( showAnim ? duration : null ); + } + + if ( $.datepicker._shouldFocusInput( inst ) ) { + inst.input.trigger( "focus" ); + } + + $.datepicker._curInst = inst; + } + }, + + /* Generate the date picker content. */ + _updateDatepicker: function( inst ) { + this.maxRows = 4; //Reset the max number of rows being displayed (see #7043) + datepicker_instActive = inst; // for delegate hover events + inst.dpDiv.empty().append( this._generateHTML( inst ) ); + this._attachHandlers( inst ); + + var origyearshtml, + numMonths = this._getNumberOfMonths( inst ), + cols = numMonths[ 1 ], + width = 17, + activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" ), + onUpdateDatepicker = $.datepicker._get( inst, "onUpdateDatepicker" ); + + if ( activeCell.length > 0 ) { + datepicker_handleMouseover.apply( activeCell.get( 0 ) ); + } + + inst.dpDiv.removeClass( "ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4" ).width( "" ); + if ( cols > 1 ) { + inst.dpDiv.addClass( "ui-datepicker-multi-" + cols ).css( "width", ( width * cols ) + "em" ); + } + inst.dpDiv[ ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ? "add" : "remove" ) + + "Class" ]( "ui-datepicker-multi" ); + inst.dpDiv[ ( this._get( inst, "isRTL" ) ? "add" : "remove" ) + + "Class" ]( "ui-datepicker-rtl" ); + + if ( inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) { + inst.input.trigger( "focus" ); + } + + // Deffered render of the years select (to avoid flashes on Firefox) + if ( inst.yearshtml ) { + origyearshtml = inst.yearshtml; + setTimeout( function() { + + //assure that inst.yearshtml didn't change. + if ( origyearshtml === inst.yearshtml && inst.yearshtml ) { + inst.dpDiv.find( "select.ui-datepicker-year" ).first().replaceWith( inst.yearshtml ); + } + origyearshtml = inst.yearshtml = null; + }, 0 ); + } + + if ( onUpdateDatepicker ) { + onUpdateDatepicker.apply( ( inst.input ? inst.input[ 0 ] : null ), [ inst ] ); + } + }, + + // #6694 - don't focus the input if it's already focused + // this breaks the change event in IE + // Support: IE and jQuery <1.9 + _shouldFocusInput: function( inst ) { + return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" ); + }, + + /* Check positioning to remain on screen. */ + _checkOffset: function( inst, offset, isFixed ) { + var dpWidth = inst.dpDiv.outerWidth(), + dpHeight = inst.dpDiv.outerHeight(), + inputWidth = inst.input ? inst.input.outerWidth() : 0, + inputHeight = inst.input ? inst.input.outerHeight() : 0, + viewWidth = document.documentElement.clientWidth + ( isFixed ? 0 : $( document ).scrollLeft() ), + viewHeight = document.documentElement.clientHeight + ( isFixed ? 0 : $( document ).scrollTop() ); + + offset.left -= ( this._get( inst, "isRTL" ) ? ( dpWidth - inputWidth ) : 0 ); + offset.left -= ( isFixed && offset.left === inst.input.offset().left ) ? $( document ).scrollLeft() : 0; + offset.top -= ( isFixed && offset.top === ( inst.input.offset().top + inputHeight ) ) ? $( document ).scrollTop() : 0; + + // Now check if datepicker is showing outside window viewport - move to a better place if so. + offset.left -= Math.min( offset.left, ( offset.left + dpWidth > viewWidth && viewWidth > dpWidth ) ? + Math.abs( offset.left + dpWidth - viewWidth ) : 0 ); + offset.top -= Math.min( offset.top, ( offset.top + dpHeight > viewHeight && viewHeight > dpHeight ) ? + Math.abs( dpHeight + inputHeight ) : 0 ); + + return offset; + }, + + /* Find an object's position on the screen. */ + _findPos: function( obj ) { + var position, + inst = this._getInst( obj ), + isRTL = this._get( inst, "isRTL" ); + + while ( obj && ( obj.type === "hidden" || obj.nodeType !== 1 || $.expr.pseudos.hidden( obj ) ) ) { + obj = obj[ isRTL ? "previousSibling" : "nextSibling" ]; + } + + position = $( obj ).offset(); + return [ position.left, position.top ]; + }, + + /* Hide the date picker from view. + * @param input element - the input field attached to the date picker + */ + _hideDatepicker: function( input ) { + var showAnim, duration, postProcess, onClose, + inst = this._curInst; + + if ( !inst || ( input && inst !== $.data( input, "datepicker" ) ) ) { + return; + } + + if ( this._datepickerShowing ) { + showAnim = this._get( inst, "showAnim" ); + duration = this._get( inst, "duration" ); + postProcess = function() { + $.datepicker._tidyDialog( inst ); + }; + + // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed + if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) { + inst.dpDiv.hide( showAnim, $.datepicker._get( inst, "showOptions" ), duration, postProcess ); + } else { + inst.dpDiv[ ( showAnim === "slideDown" ? "slideUp" : + ( showAnim === "fadeIn" ? "fadeOut" : "hide" ) ) ]( ( showAnim ? duration : null ), postProcess ); + } + + if ( !showAnim ) { + postProcess(); + } + this._datepickerShowing = false; + + onClose = this._get( inst, "onClose" ); + if ( onClose ) { + onClose.apply( ( inst.input ? inst.input[ 0 ] : null ), [ ( inst.input ? inst.input.val() : "" ), inst ] ); + } + + this._lastInput = null; + if ( this._inDialog ) { + this._dialogInput.css( { position: "absolute", left: "0", top: "-100px" } ); + if ( $.blockUI ) { + $.unblockUI(); + $( "body" ).append( this.dpDiv ); + } + } + this._inDialog = false; + } + }, + + /* Tidy up after a dialog display. */ + _tidyDialog: function( inst ) { + inst.dpDiv.removeClass( this._dialogClass ).off( ".ui-datepicker-calendar" ); + }, + + /* Close date picker if clicked elsewhere. */ + _checkExternalClick: function( event ) { + if ( !$.datepicker._curInst ) { + return; + } + + var $target = $( event.target ), + inst = $.datepicker._getInst( $target[ 0 ] ); + + if ( ( ( $target[ 0 ].id !== $.datepicker._mainDivId && + $target.parents( "#" + $.datepicker._mainDivId ).length === 0 && + !$target.hasClass( $.datepicker.markerClassName ) && + !$target.closest( "." + $.datepicker._triggerClass ).length && + $.datepicker._datepickerShowing && !( $.datepicker._inDialog && $.blockUI ) ) ) || + ( $target.hasClass( $.datepicker.markerClassName ) && $.datepicker._curInst !== inst ) ) { + $.datepicker._hideDatepicker(); + } + }, + + /* Adjust one of the date sub-fields. */ + _adjustDate: function( id, offset, period ) { + var target = $( id ), + inst = this._getInst( target[ 0 ] ); + + if ( this._isDisabledDatepicker( target[ 0 ] ) ) { + return; + } + this._adjustInstDate( inst, offset, period ); + this._updateDatepicker( inst ); + }, + + /* Action for current link. */ + _gotoToday: function( id ) { + var date, + target = $( id ), + inst = this._getInst( target[ 0 ] ); + + if ( this._get( inst, "gotoCurrent" ) && inst.currentDay ) { + inst.selectedDay = inst.currentDay; + inst.drawMonth = inst.selectedMonth = inst.currentMonth; + inst.drawYear = inst.selectedYear = inst.currentYear; + } else { + date = new Date(); + inst.selectedDay = date.getDate(); + inst.drawMonth = inst.selectedMonth = date.getMonth(); + inst.drawYear = inst.selectedYear = date.getFullYear(); + } + this._notifyChange( inst ); + this._adjustDate( target ); + }, + + /* Action for selecting a new month/year. */ + _selectMonthYear: function( id, select, period ) { + var target = $( id ), + inst = this._getInst( target[ 0 ] ); + + inst[ "selected" + ( period === "M" ? "Month" : "Year" ) ] = + inst[ "draw" + ( period === "M" ? "Month" : "Year" ) ] = + parseInt( select.options[ select.selectedIndex ].value, 10 ); + + this._notifyChange( inst ); + this._adjustDate( target ); + }, + + /* Action for selecting a day. */ + _selectDay: function( id, month, year, td ) { + var inst, + target = $( id ); + + if ( $( td ).hasClass( this._unselectableClass ) || this._isDisabledDatepicker( target[ 0 ] ) ) { + return; + } + + inst = this._getInst( target[ 0 ] ); + inst.selectedDay = inst.currentDay = parseInt( $( "a", td ).attr( "data-date" ) ); + inst.selectedMonth = inst.currentMonth = month; + inst.selectedYear = inst.currentYear = year; + this._selectDate( id, this._formatDate( inst, + inst.currentDay, inst.currentMonth, inst.currentYear ) ); + }, + + /* Erase the input field and hide the date picker. */ + _clearDate: function( id ) { + var target = $( id ); + this._selectDate( target, "" ); + }, + + /* Update the input field with the selected date. */ + _selectDate: function( id, dateStr ) { + var onSelect, + target = $( id ), + inst = this._getInst( target[ 0 ] ); + + dateStr = ( dateStr != null ? dateStr : this._formatDate( inst ) ); + if ( inst.input ) { + inst.input.val( dateStr ); + } + this._updateAlternate( inst ); + + onSelect = this._get( inst, "onSelect" ); + if ( onSelect ) { + onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] ); // trigger custom callback + } else if ( inst.input ) { + inst.input.trigger( "change" ); // fire the change event + } + + if ( inst.inline ) { + this._updateDatepicker( inst ); + } else { + this._hideDatepicker(); + this._lastInput = inst.input[ 0 ]; + if ( typeof( inst.input[ 0 ] ) !== "object" ) { + inst.input.trigger( "focus" ); // restore focus + } + this._lastInput = null; + } + }, + + /* Update any alternate field to synchronise with the main field. */ + _updateAlternate: function( inst ) { + var altFormat, date, dateStr, + altField = this._get( inst, "altField" ); + + if ( altField ) { // update alternate field too + altFormat = this._get( inst, "altFormat" ) || this._get( inst, "dateFormat" ); + date = this._getDate( inst ); + dateStr = this.formatDate( altFormat, date, this._getFormatConfig( inst ) ); + $( document ).find( altField ).val( dateStr ); + } + }, + + /* Set as beforeShowDay function to prevent selection of weekends. + * @param date Date - the date to customise + * @return [boolean, string] - is this date selectable?, what is its CSS class? + */ + noWeekends: function( date ) { + var day = date.getDay(); + return [ ( day > 0 && day < 6 ), "" ]; + }, + + /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. + * @param date Date - the date to get the week for + * @return number - the number of the week within the year that contains this date + */ + iso8601Week: function( date ) { + var time, + checkDate = new Date( date.getTime() ); + + // Find Thursday of this week starting on Monday + checkDate.setDate( checkDate.getDate() + 4 - ( checkDate.getDay() || 7 ) ); + + time = checkDate.getTime(); + checkDate.setMonth( 0 ); // Compare with Jan 1 + checkDate.setDate( 1 ); + return Math.floor( Math.round( ( time - checkDate ) / 86400000 ) / 7 ) + 1; + }, + + /* Parse a string value into a date object. + * See formatDate below for the possible formats. + * + * @param format string - the expected format of the date + * @param value string - the date in the above format + * @param settings Object - attributes include: + * shortYearCutoff number - the cutoff year for determining the century (optional) + * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) + * dayNames string[7] - names of the days from Sunday (optional) + * monthNamesShort string[12] - abbreviated names of the months (optional) + * monthNames string[12] - names of the months (optional) + * @return Date - the extracted date value or null if value is blank + */ + parseDate: function( format, value, settings ) { + if ( format == null || value == null ) { + throw "Invalid arguments"; + } + + value = ( typeof value === "object" ? value.toString() : value + "" ); + if ( value === "" ) { + return null; + } + + var iFormat, dim, extra, + iValue = 0, + shortYearCutoffTemp = ( settings ? settings.shortYearCutoff : null ) || this._defaults.shortYearCutoff, + shortYearCutoff = ( typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp : + new Date().getFullYear() % 100 + parseInt( shortYearCutoffTemp, 10 ) ), + dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort, + dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames, + monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort, + monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames, + year = -1, + month = -1, + day = -1, + doy = -1, + literal = false, + date, + + // Check whether a format character is doubled + lookAhead = function( match ) { + var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match ); + if ( matches ) { + iFormat++; + } + return matches; + }, + + // Extract a number from the string value + getNumber = function( match ) { + var isDoubled = lookAhead( match ), + size = ( match === "@" ? 14 : ( match === "!" ? 20 : + ( match === "y" && isDoubled ? 4 : ( match === "o" ? 3 : 2 ) ) ) ), + minSize = ( match === "y" ? size : 1 ), + digits = new RegExp( "^\\d{" + minSize + "," + size + "}" ), + num = value.substring( iValue ).match( digits ); + if ( !num ) { + throw "Missing number at position " + iValue; + } + iValue += num[ 0 ].length; + return parseInt( num[ 0 ], 10 ); + }, + + // Extract a name from the string value and convert to an index + getName = function( match, shortNames, longNames ) { + var index = -1, + names = $.map( lookAhead( match ) ? longNames : shortNames, function( v, k ) { + return [ [ k, v ] ]; + } ).sort( function( a, b ) { + return -( a[ 1 ].length - b[ 1 ].length ); + } ); + + $.each( names, function( i, pair ) { + var name = pair[ 1 ]; + if ( value.substr( iValue, name.length ).toLowerCase() === name.toLowerCase() ) { + index = pair[ 0 ]; + iValue += name.length; + return false; + } + } ); + if ( index !== -1 ) { + return index + 1; + } else { + throw "Unknown name at position " + iValue; + } + }, + + // Confirm that a literal character matches the string value + checkLiteral = function() { + if ( value.charAt( iValue ) !== format.charAt( iFormat ) ) { + throw "Unexpected literal at position " + iValue; + } + iValue++; + }; + + for ( iFormat = 0; iFormat < format.length; iFormat++ ) { + if ( literal ) { + if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) { + literal = false; + } else { + checkLiteral(); + } + } else { + switch ( format.charAt( iFormat ) ) { + case "d": + day = getNumber( "d" ); + break; + case "D": + getName( "D", dayNamesShort, dayNames ); + break; + case "o": + doy = getNumber( "o" ); + break; + case "m": + month = getNumber( "m" ); + break; + case "M": + month = getName( "M", monthNamesShort, monthNames ); + break; + case "y": + year = getNumber( "y" ); + break; + case "@": + date = new Date( getNumber( "@" ) ); + year = date.getFullYear(); + month = date.getMonth() + 1; + day = date.getDate(); + break; + case "!": + date = new Date( ( getNumber( "!" ) - this._ticksTo1970 ) / 10000 ); + year = date.getFullYear(); + month = date.getMonth() + 1; + day = date.getDate(); + break; + case "'": + if ( lookAhead( "'" ) ) { + checkLiteral(); + } else { + literal = true; + } + break; + default: + checkLiteral(); + } + } + } + + if ( iValue < value.length ) { + extra = value.substr( iValue ); + if ( !/^\s+/.test( extra ) ) { + throw "Extra/unparsed characters found in date: " + extra; + } + } + + if ( year === -1 ) { + year = new Date().getFullYear(); + } else if ( year < 100 ) { + year += new Date().getFullYear() - new Date().getFullYear() % 100 + + ( year <= shortYearCutoff ? 0 : -100 ); + } + + if ( doy > -1 ) { + month = 1; + day = doy; + do { + dim = this._getDaysInMonth( year, month - 1 ); + if ( day <= dim ) { + break; + } + month++; + day -= dim; + } while ( true ); + } + + date = this._daylightSavingAdjust( new Date( year, month - 1, day ) ); + if ( date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day ) { + throw "Invalid date"; // E.g. 31/02/00 + } + return date; + }, + + /* Standard date formats. */ + ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601) + COOKIE: "D, dd M yy", + ISO_8601: "yy-mm-dd", + RFC_822: "D, d M y", + RFC_850: "DD, dd-M-y", + RFC_1036: "D, d M y", + RFC_1123: "D, d M yy", + RFC_2822: "D, d M yy", + RSS: "D, d M y", // RFC 822 + TICKS: "!", + TIMESTAMP: "@", + W3C: "yy-mm-dd", // ISO 8601 + + _ticksTo1970: ( ( ( 1970 - 1 ) * 365 + Math.floor( 1970 / 4 ) - Math.floor( 1970 / 100 ) + + Math.floor( 1970 / 400 ) ) * 24 * 60 * 60 * 10000000 ), + + /* Format a date object into a string value. + * The format can be combinations of the following: + * d - day of month (no leading zero) + * dd - day of month (two digit) + * o - day of year (no leading zeros) + * oo - day of year (three digit) + * D - day name short + * DD - day name long + * m - month of year (no leading zero) + * mm - month of year (two digit) + * M - month name short + * MM - month name long + * y - year (two digit) + * yy - year (four digit) + * @ - Unix timestamp (ms since 01/01/1970) + * ! - Windows ticks (100ns since 01/01/0001) + * "..." - literal text + * '' - single quote + * + * @param format string - the desired format of the date + * @param date Date - the date value to format + * @param settings Object - attributes include: + * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) + * dayNames string[7] - names of the days from Sunday (optional) + * monthNamesShort string[12] - abbreviated names of the months (optional) + * monthNames string[12] - names of the months (optional) + * @return string - the date in the above format + */ + formatDate: function( format, date, settings ) { + if ( !date ) { + return ""; + } + + var iFormat, + dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort, + dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames, + monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort, + monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames, + + // Check whether a format character is doubled + lookAhead = function( match ) { + var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match ); + if ( matches ) { + iFormat++; + } + return matches; + }, + + // Format a number, with leading zero if necessary + formatNumber = function( match, value, len ) { + var num = "" + value; + if ( lookAhead( match ) ) { + while ( num.length < len ) { + num = "0" + num; + } + } + return num; + }, + + // Format a name, short or long as requested + formatName = function( match, value, shortNames, longNames ) { + return ( lookAhead( match ) ? longNames[ value ] : shortNames[ value ] ); + }, + output = "", + literal = false; + + if ( date ) { + for ( iFormat = 0; iFormat < format.length; iFormat++ ) { + if ( literal ) { + if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) { + literal = false; + } else { + output += format.charAt( iFormat ); + } + } else { + switch ( format.charAt( iFormat ) ) { + case "d": + output += formatNumber( "d", date.getDate(), 2 ); + break; + case "D": + output += formatName( "D", date.getDay(), dayNamesShort, dayNames ); + break; + case "o": + output += formatNumber( "o", + Math.round( ( new Date( date.getFullYear(), date.getMonth(), date.getDate() ).getTime() - new Date( date.getFullYear(), 0, 0 ).getTime() ) / 86400000 ), 3 ); + break; + case "m": + output += formatNumber( "m", date.getMonth() + 1, 2 ); + break; + case "M": + output += formatName( "M", date.getMonth(), monthNamesShort, monthNames ); + break; + case "y": + output += ( lookAhead( "y" ) ? date.getFullYear() : + ( date.getFullYear() % 100 < 10 ? "0" : "" ) + date.getFullYear() % 100 ); + break; + case "@": + output += date.getTime(); + break; + case "!": + output += date.getTime() * 10000 + this._ticksTo1970; + break; + case "'": + if ( lookAhead( "'" ) ) { + output += "'"; + } else { + literal = true; + } + break; + default: + output += format.charAt( iFormat ); + } + } + } + } + return output; + }, + + /* Extract all possible characters from the date format. */ + _possibleChars: function( format ) { + var iFormat, + chars = "", + literal = false, + + // Check whether a format character is doubled + lookAhead = function( match ) { + var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match ); + if ( matches ) { + iFormat++; + } + return matches; + }; + + for ( iFormat = 0; iFormat < format.length; iFormat++ ) { + if ( literal ) { + if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) { + literal = false; + } else { + chars += format.charAt( iFormat ); + } + } else { + switch ( format.charAt( iFormat ) ) { + case "d": case "m": case "y": case "@": + chars += "0123456789"; + break; + case "D": case "M": + return null; // Accept anything + case "'": + if ( lookAhead( "'" ) ) { + chars += "'"; + } else { + literal = true; + } + break; + default: + chars += format.charAt( iFormat ); + } + } + } + return chars; + }, + + /* Get a setting value, defaulting if necessary. */ + _get: function( inst, name ) { + return inst.settings[ name ] !== undefined ? + inst.settings[ name ] : this._defaults[ name ]; + }, + + /* Parse existing date and initialise date picker. */ + _setDateFromField: function( inst, noDefault ) { + if ( inst.input.val() === inst.lastVal ) { + return; + } + + var dateFormat = this._get( inst, "dateFormat" ), + dates = inst.lastVal = inst.input ? inst.input.val() : null, + defaultDate = this._getDefaultDate( inst ), + date = defaultDate, + settings = this._getFormatConfig( inst ); + + try { + date = this.parseDate( dateFormat, dates, settings ) || defaultDate; + } catch ( event ) { + dates = ( noDefault ? "" : dates ); + } + inst.selectedDay = date.getDate(); + inst.drawMonth = inst.selectedMonth = date.getMonth(); + inst.drawYear = inst.selectedYear = date.getFullYear(); + inst.currentDay = ( dates ? date.getDate() : 0 ); + inst.currentMonth = ( dates ? date.getMonth() : 0 ); + inst.currentYear = ( dates ? date.getFullYear() : 0 ); + this._adjustInstDate( inst ); + }, + + /* Retrieve the default date shown on opening. */ + _getDefaultDate: function( inst ) { + return this._restrictMinMax( inst, + this._determineDate( inst, this._get( inst, "defaultDate" ), new Date() ) ); + }, + + /* A date may be specified as an exact value or a relative one. */ + _determineDate: function( inst, date, defaultDate ) { + var offsetNumeric = function( offset ) { + var date = new Date(); + date.setDate( date.getDate() + offset ); + return date; + }, + offsetString = function( offset ) { + try { + return $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ), + offset, $.datepicker._getFormatConfig( inst ) ); + } catch ( e ) { + + // Ignore + } + + var date = ( offset.toLowerCase().match( /^c/ ) ? + $.datepicker._getDate( inst ) : null ) || new Date(), + year = date.getFullYear(), + month = date.getMonth(), + day = date.getDate(), + pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g, + matches = pattern.exec( offset ); + + while ( matches ) { + switch ( matches[ 2 ] || "d" ) { + case "d" : case "D" : + day += parseInt( matches[ 1 ], 10 ); break; + case "w" : case "W" : + day += parseInt( matches[ 1 ], 10 ) * 7; break; + case "m" : case "M" : + month += parseInt( matches[ 1 ], 10 ); + day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) ); + break; + case "y": case "Y" : + year += parseInt( matches[ 1 ], 10 ); + day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) ); + break; + } + matches = pattern.exec( offset ); + } + return new Date( year, month, day ); + }, + newDate = ( date == null || date === "" ? defaultDate : ( typeof date === "string" ? offsetString( date ) : + ( typeof date === "number" ? ( isNaN( date ) ? defaultDate : offsetNumeric( date ) ) : new Date( date.getTime() ) ) ) ); + + newDate = ( newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate ); + if ( newDate ) { + newDate.setHours( 0 ); + newDate.setMinutes( 0 ); + newDate.setSeconds( 0 ); + newDate.setMilliseconds( 0 ); + } + return this._daylightSavingAdjust( newDate ); + }, + + /* Handle switch to/from daylight saving. + * Hours may be non-zero on daylight saving cut-over: + * > 12 when midnight changeover, but then cannot generate + * midnight datetime, so jump to 1AM, otherwise reset. + * @param date (Date) the date to check + * @return (Date) the corrected date + */ + _daylightSavingAdjust: function( date ) { + if ( !date ) { + return null; + } + date.setHours( date.getHours() > 12 ? date.getHours() + 2 : 0 ); + return date; + }, + + /* Set the date(s) directly. */ + _setDate: function( inst, date, noChange ) { + var clear = !date, + origMonth = inst.selectedMonth, + origYear = inst.selectedYear, + newDate = this._restrictMinMax( inst, this._determineDate( inst, date, new Date() ) ); + + inst.selectedDay = inst.currentDay = newDate.getDate(); + inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth(); + inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear(); + if ( ( origMonth !== inst.selectedMonth || origYear !== inst.selectedYear ) && !noChange ) { + this._notifyChange( inst ); + } + this._adjustInstDate( inst ); + if ( inst.input ) { + inst.input.val( clear ? "" : this._formatDate( inst ) ); + } + }, + + /* Retrieve the date(s) directly. */ + _getDate: function( inst ) { + var startDate = ( !inst.currentYear || ( inst.input && inst.input.val() === "" ) ? null : + this._daylightSavingAdjust( new Date( + inst.currentYear, inst.currentMonth, inst.currentDay ) ) ); + return startDate; + }, + + /* Attach the onxxx handlers. These are declared statically so + * they work with static code transformers like Caja. + */ + _attachHandlers: function( inst ) { + var stepMonths = this._get( inst, "stepMonths" ), + id = "#" + inst.id.replace( /\\\\/g, "\\" ); + inst.dpDiv.find( "[data-handler]" ).map( function() { + var handler = { + prev: function() { + $.datepicker._adjustDate( id, -stepMonths, "M" ); + }, + next: function() { + $.datepicker._adjustDate( id, +stepMonths, "M" ); + }, + hide: function() { + $.datepicker._hideDatepicker(); + }, + today: function() { + $.datepicker._gotoToday( id ); + }, + selectDay: function() { + $.datepicker._selectDay( id, +this.getAttribute( "data-month" ), +this.getAttribute( "data-year" ), this ); + return false; + }, + selectMonth: function() { + $.datepicker._selectMonthYear( id, this, "M" ); + return false; + }, + selectYear: function() { + $.datepicker._selectMonthYear( id, this, "Y" ); + return false; + } + }; + $( this ).on( this.getAttribute( "data-event" ), handler[ this.getAttribute( "data-handler" ) ] ); + } ); + }, + + /* Generate the HTML for the current state of the date picker. */ + _generateHTML: function( inst ) { + var maxDraw, prevText, prev, nextText, next, currentText, gotoDate, + controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin, + monthNames, monthNamesShort, beforeShowDay, showOtherMonths, + selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate, + cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows, + printDate, dRow, tbody, daySettings, otherMonth, unselectable, + tempDate = new Date(), + today = this._daylightSavingAdjust( + new Date( tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate() ) ), // clear time + isRTL = this._get( inst, "isRTL" ), + showButtonPanel = this._get( inst, "showButtonPanel" ), + hideIfNoPrevNext = this._get( inst, "hideIfNoPrevNext" ), + navigationAsDateFormat = this._get( inst, "navigationAsDateFormat" ), + numMonths = this._getNumberOfMonths( inst ), + showCurrentAtPos = this._get( inst, "showCurrentAtPos" ), + stepMonths = this._get( inst, "stepMonths" ), + isMultiMonth = ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ), + currentDate = this._daylightSavingAdjust( ( !inst.currentDay ? new Date( 9999, 9, 9 ) : + new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ), + minDate = this._getMinMaxDate( inst, "min" ), + maxDate = this._getMinMaxDate( inst, "max" ), + drawMonth = inst.drawMonth - showCurrentAtPos, + drawYear = inst.drawYear; + + if ( drawMonth < 0 ) { + drawMonth += 12; + drawYear--; + } + if ( maxDate ) { + maxDraw = this._daylightSavingAdjust( new Date( maxDate.getFullYear(), + maxDate.getMonth() - ( numMonths[ 0 ] * numMonths[ 1 ] ) + 1, maxDate.getDate() ) ); + maxDraw = ( minDate && maxDraw < minDate ? minDate : maxDraw ); + while ( this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 ) ) > maxDraw ) { + drawMonth--; + if ( drawMonth < 0 ) { + drawMonth = 11; + drawYear--; + } + } + } + inst.drawMonth = drawMonth; + inst.drawYear = drawYear; + + prevText = this._get( inst, "prevText" ); + prevText = ( !navigationAsDateFormat ? prevText : this.formatDate( prevText, + this._daylightSavingAdjust( new Date( drawYear, drawMonth - stepMonths, 1 ) ), + this._getFormatConfig( inst ) ) ); + + if ( this._canAdjustMonth( inst, -1, drawYear, drawMonth ) ) { + prev = $( "<a>" ) + .attr( { + "class": "ui-datepicker-prev ui-corner-all", + "data-handler": "prev", + "data-event": "click", + title: prevText + } ) + .append( + $( "<span>" ) + .addClass( "ui-icon ui-icon-circle-triangle-" + + ( isRTL ? "e" : "w" ) ) + .text( prevText ) + )[ 0 ].outerHTML; + } else if ( hideIfNoPrevNext ) { + prev = ""; + } else { + prev = $( "<a>" ) + .attr( { + "class": "ui-datepicker-prev ui-corner-all ui-state-disabled", + title: prevText + } ) + .append( + $( "<span>" ) + .addClass( "ui-icon ui-icon-circle-triangle-" + + ( isRTL ? "e" : "w" ) ) + .text( prevText ) + )[ 0 ].outerHTML; + } + + nextText = this._get( inst, "nextText" ); + nextText = ( !navigationAsDateFormat ? nextText : this.formatDate( nextText, + this._daylightSavingAdjust( new Date( drawYear, drawMonth + stepMonths, 1 ) ), + this._getFormatConfig( inst ) ) ); + + if ( this._canAdjustMonth( inst, +1, drawYear, drawMonth ) ) { + next = $( "<a>" ) + .attr( { + "class": "ui-datepicker-next ui-corner-all", + "data-handler": "next", + "data-event": "click", + title: nextText + } ) + .append( + $( "<span>" ) + .addClass( "ui-icon ui-icon-circle-triangle-" + + ( isRTL ? "w" : "e" ) ) + .text( nextText ) + )[ 0 ].outerHTML; + } else if ( hideIfNoPrevNext ) { + next = ""; + } else { + next = $( "<a>" ) + .attr( { + "class": "ui-datepicker-next ui-corner-all ui-state-disabled", + title: nextText + } ) + .append( + $( "<span>" ) + .attr( "class", "ui-icon ui-icon-circle-triangle-" + + ( isRTL ? "w" : "e" ) ) + .text( nextText ) + )[ 0 ].outerHTML; + } + + currentText = this._get( inst, "currentText" ); + gotoDate = ( this._get( inst, "gotoCurrent" ) && inst.currentDay ? currentDate : today ); + currentText = ( !navigationAsDateFormat ? currentText : + this.formatDate( currentText, gotoDate, this._getFormatConfig( inst ) ) ); + + controls = ""; + if ( !inst.inline ) { + controls = $( "<button>" ) + .attr( { + type: "button", + "class": "ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all", + "data-handler": "hide", + "data-event": "click" + } ) + .text( this._get( inst, "closeText" ) )[ 0 ].outerHTML; + } + + buttonPanel = ""; + if ( showButtonPanel ) { + buttonPanel = $( "<div class='ui-datepicker-buttonpane ui-widget-content'>" ) + .append( isRTL ? controls : "" ) + .append( this._isInRange( inst, gotoDate ) ? + $( "<button>" ) + .attr( { + type: "button", + "class": "ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all", + "data-handler": "today", + "data-event": "click" + } ) + .text( currentText ) : + "" ) + .append( isRTL ? "" : controls )[ 0 ].outerHTML; + } + + firstDay = parseInt( this._get( inst, "firstDay" ), 10 ); + firstDay = ( isNaN( firstDay ) ? 0 : firstDay ); + + showWeek = this._get( inst, "showWeek" ); + dayNames = this._get( inst, "dayNames" ); + dayNamesMin = this._get( inst, "dayNamesMin" ); + monthNames = this._get( inst, "monthNames" ); + monthNamesShort = this._get( inst, "monthNamesShort" ); + beforeShowDay = this._get( inst, "beforeShowDay" ); + showOtherMonths = this._get( inst, "showOtherMonths" ); + selectOtherMonths = this._get( inst, "selectOtherMonths" ); + defaultDate = this._getDefaultDate( inst ); + html = ""; + + for ( row = 0; row < numMonths[ 0 ]; row++ ) { + group = ""; + this.maxRows = 4; + for ( col = 0; col < numMonths[ 1 ]; col++ ) { + selectedDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, inst.selectedDay ) ); + cornerClass = " ui-corner-all"; + calender = ""; + if ( isMultiMonth ) { + calender += "<div class='ui-datepicker-group"; + if ( numMonths[ 1 ] > 1 ) { + switch ( col ) { + case 0: calender += " ui-datepicker-group-first"; + cornerClass = " ui-corner-" + ( isRTL ? "right" : "left" ); break; + case numMonths[ 1 ] - 1: calender += " ui-datepicker-group-last"; + cornerClass = " ui-corner-" + ( isRTL ? "left" : "right" ); break; + default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break; + } + } + calender += "'>"; + } + calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" + + ( /all|left/.test( cornerClass ) && row === 0 ? ( isRTL ? next : prev ) : "" ) + + ( /all|right/.test( cornerClass ) && row === 0 ? ( isRTL ? prev : next ) : "" ) + + this._generateMonthYearHeader( inst, drawMonth, drawYear, minDate, maxDate, + row > 0 || col > 0, monthNames, monthNamesShort ) + // draw month headers + "</div><table class='ui-datepicker-calendar'><thead>" + + "<tr>"; + thead = ( showWeek ? "<th class='ui-datepicker-week-col'>" + this._get( inst, "weekHeader" ) + "</th>" : "" ); + for ( dow = 0; dow < 7; dow++ ) { // days of the week + day = ( dow + firstDay ) % 7; + thead += "<th scope='col'" + ( ( dow + firstDay + 6 ) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "" ) + ">" + + "<span title='" + dayNames[ day ] + "'>" + dayNamesMin[ day ] + "</span></th>"; + } + calender += thead + "</tr></thead><tbody>"; + daysInMonth = this._getDaysInMonth( drawYear, drawMonth ); + if ( drawYear === inst.selectedYear && drawMonth === inst.selectedMonth ) { + inst.selectedDay = Math.min( inst.selectedDay, daysInMonth ); + } + leadDays = ( this._getFirstDayOfMonth( drawYear, drawMonth ) - firstDay + 7 ) % 7; + curRows = Math.ceil( ( leadDays + daysInMonth ) / 7 ); // calculate the number of rows to generate + numRows = ( isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows ); //If multiple months, use the higher number of rows (see #7043) + this.maxRows = numRows; + printDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 - leadDays ) ); + for ( dRow = 0; dRow < numRows; dRow++ ) { // create date picker rows + calender += "<tr>"; + tbody = ( !showWeek ? "" : "<td class='ui-datepicker-week-col'>" + + this._get( inst, "calculateWeek" )( printDate ) + "</td>" ); + for ( dow = 0; dow < 7; dow++ ) { // create date picker days + daySettings = ( beforeShowDay ? + beforeShowDay.apply( ( inst.input ? inst.input[ 0 ] : null ), [ printDate ] ) : [ true, "" ] ); + otherMonth = ( printDate.getMonth() !== drawMonth ); + unselectable = ( otherMonth && !selectOtherMonths ) || !daySettings[ 0 ] || + ( minDate && printDate < minDate ) || ( maxDate && printDate > maxDate ); + tbody += "<td class='" + + ( ( dow + firstDay + 6 ) % 7 >= 5 ? " ui-datepicker-week-end" : "" ) + // highlight weekends + ( otherMonth ? " ui-datepicker-other-month" : "" ) + // highlight days from other months + ( ( printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent ) || // user pressed key + ( defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime() ) ? + + // or defaultDate is current printedDate and defaultDate is selectedDate + " " + this._dayOverClass : "" ) + // highlight selected day + ( unselectable ? " " + this._unselectableClass + " ui-state-disabled" : "" ) + // highlight unselectable days + ( otherMonth && !showOtherMonths ? "" : " " + daySettings[ 1 ] + // highlight custom dates + ( printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "" ) + // highlight selected day + ( printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "" ) ) + "'" + // highlight today (if different) + ( ( !otherMonth || showOtherMonths ) && daySettings[ 2 ] ? " title='" + daySettings[ 2 ].replace( /'/g, "'" ) + "'" : "" ) + // cell title + ( unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'" ) + ">" + // actions + ( otherMonth && !showOtherMonths ? " " : // display for other months + ( unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" + + ( printDate.getTime() === today.getTime() ? " ui-state-highlight" : "" ) + + ( printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "" ) + // highlight selected day + ( otherMonth ? " ui-priority-secondary" : "" ) + // distinguish dates from other months + "' href='#' aria-current='" + ( printDate.getTime() === currentDate.getTime() ? "true" : "false" ) + // mark date as selected for screen reader + "' data-date='" + printDate.getDate() + // store date as data + "'>" + printDate.getDate() + "</a>" ) ) + "</td>"; // display selectable date + printDate.setDate( printDate.getDate() + 1 ); + printDate = this._daylightSavingAdjust( printDate ); + } + calender += tbody + "</tr>"; + } + drawMonth++; + if ( drawMonth > 11 ) { + drawMonth = 0; + drawYear++; + } + calender += "</tbody></table>" + ( isMultiMonth ? "</div>" + + ( ( numMonths[ 0 ] > 0 && col === numMonths[ 1 ] - 1 ) ? "<div class='ui-datepicker-row-break'></div>" : "" ) : "" ); + group += calender; + } + html += group; + } + html += buttonPanel; + inst._keyEvent = false; + return html; + }, + + /* Generate the month and year header. */ + _generateMonthYearHeader: function( inst, drawMonth, drawYear, minDate, maxDate, + secondary, monthNames, monthNamesShort ) { + + var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear, + changeMonth = this._get( inst, "changeMonth" ), + changeYear = this._get( inst, "changeYear" ), + showMonthAfterYear = this._get( inst, "showMonthAfterYear" ), + selectMonthLabel = this._get( inst, "selectMonthLabel" ), + selectYearLabel = this._get( inst, "selectYearLabel" ), + html = "<div class='ui-datepicker-title'>", + monthHtml = ""; + + // Month selection + if ( secondary || !changeMonth ) { + monthHtml += "<span class='ui-datepicker-month'>" + monthNames[ drawMonth ] + "</span>"; + } else { + inMinYear = ( minDate && minDate.getFullYear() === drawYear ); + inMaxYear = ( maxDate && maxDate.getFullYear() === drawYear ); + monthHtml += "<select class='ui-datepicker-month' aria-label='" + selectMonthLabel + "' data-handler='selectMonth' data-event='change'>"; + for ( month = 0; month < 12; month++ ) { + if ( ( !inMinYear || month >= minDate.getMonth() ) && ( !inMaxYear || month <= maxDate.getMonth() ) ) { + monthHtml += "<option value='" + month + "'" + + ( month === drawMonth ? " selected='selected'" : "" ) + + ">" + monthNamesShort[ month ] + "</option>"; + } + } + monthHtml += "</select>"; + } + + if ( !showMonthAfterYear ) { + html += monthHtml + ( secondary || !( changeMonth && changeYear ) ? " " : "" ); + } + + // Year selection + if ( !inst.yearshtml ) { + inst.yearshtml = ""; + if ( secondary || !changeYear ) { + html += "<span class='ui-datepicker-year'>" + drawYear + "</span>"; + } else { + + // determine range of years to display + years = this._get( inst, "yearRange" ).split( ":" ); + thisYear = new Date().getFullYear(); + determineYear = function( value ) { + var year = ( value.match( /c[+\-].*/ ) ? drawYear + parseInt( value.substring( 1 ), 10 ) : + ( value.match( /[+\-].*/ ) ? thisYear + parseInt( value, 10 ) : + parseInt( value, 10 ) ) ); + return ( isNaN( year ) ? thisYear : year ); + }; + year = determineYear( years[ 0 ] ); + endYear = Math.max( year, determineYear( years[ 1 ] || "" ) ); + year = ( minDate ? Math.max( year, minDate.getFullYear() ) : year ); + endYear = ( maxDate ? Math.min( endYear, maxDate.getFullYear() ) : endYear ); + inst.yearshtml += "<select class='ui-datepicker-year' aria-label='" + selectYearLabel + "' data-handler='selectYear' data-event='change'>"; + for ( ; year <= endYear; year++ ) { + inst.yearshtml += "<option value='" + year + "'" + + ( year === drawYear ? " selected='selected'" : "" ) + + ">" + year + "</option>"; + } + inst.yearshtml += "</select>"; + + html += inst.yearshtml; + inst.yearshtml = null; + } + } + + html += this._get( inst, "yearSuffix" ); + if ( showMonthAfterYear ) { + html += ( secondary || !( changeMonth && changeYear ) ? " " : "" ) + monthHtml; + } + html += "</div>"; // Close datepicker_header + return html; + }, + + /* Adjust one of the date sub-fields. */ + _adjustInstDate: function( inst, offset, period ) { + var year = inst.selectedYear + ( period === "Y" ? offset : 0 ), + month = inst.selectedMonth + ( period === "M" ? offset : 0 ), + day = Math.min( inst.selectedDay, this._getDaysInMonth( year, month ) ) + ( period === "D" ? offset : 0 ), + date = this._restrictMinMax( inst, this._daylightSavingAdjust( new Date( year, month, day ) ) ); + + inst.selectedDay = date.getDate(); + inst.drawMonth = inst.selectedMonth = date.getMonth(); + inst.drawYear = inst.selectedYear = date.getFullYear(); + if ( period === "M" || period === "Y" ) { + this._notifyChange( inst ); + } + }, + + /* Ensure a date is within any min/max bounds. */ + _restrictMinMax: function( inst, date ) { + var minDate = this._getMinMaxDate( inst, "min" ), + maxDate = this._getMinMaxDate( inst, "max" ), + newDate = ( minDate && date < minDate ? minDate : date ); + return ( maxDate && newDate > maxDate ? maxDate : newDate ); + }, + + /* Notify change of month/year. */ + _notifyChange: function( inst ) { + var onChange = this._get( inst, "onChangeMonthYear" ); + if ( onChange ) { + onChange.apply( ( inst.input ? inst.input[ 0 ] : null ), + [ inst.selectedYear, inst.selectedMonth + 1, inst ] ); + } + }, + + /* Determine the number of months to show. */ + _getNumberOfMonths: function( inst ) { + var numMonths = this._get( inst, "numberOfMonths" ); + return ( numMonths == null ? [ 1, 1 ] : ( typeof numMonths === "number" ? [ 1, numMonths ] : numMonths ) ); + }, + + /* Determine the current maximum date - ensure no time components are set. */ + _getMinMaxDate: function( inst, minMax ) { + return this._determineDate( inst, this._get( inst, minMax + "Date" ), null ); + }, + + /* Find the number of days in a given month. */ + _getDaysInMonth: function( year, month ) { + return 32 - this._daylightSavingAdjust( new Date( year, month, 32 ) ).getDate(); + }, + + /* Find the day of the week of the first of a month. */ + _getFirstDayOfMonth: function( year, month ) { + return new Date( year, month, 1 ).getDay(); + }, + + /* Determines if we should allow a "next/prev" month display change. */ + _canAdjustMonth: function( inst, offset, curYear, curMonth ) { + var numMonths = this._getNumberOfMonths( inst ), + date = this._daylightSavingAdjust( new Date( curYear, + curMonth + ( offset < 0 ? offset : numMonths[ 0 ] * numMonths[ 1 ] ), 1 ) ); + + if ( offset < 0 ) { + date.setDate( this._getDaysInMonth( date.getFullYear(), date.getMonth() ) ); + } + return this._isInRange( inst, date ); + }, + + /* Is the given date in the accepted range? */ + _isInRange: function( inst, date ) { + var yearSplit, currentYear, + minDate = this._getMinMaxDate( inst, "min" ), + maxDate = this._getMinMaxDate( inst, "max" ), + minYear = null, + maxYear = null, + years = this._get( inst, "yearRange" ); + if ( years ) { + yearSplit = years.split( ":" ); + currentYear = new Date().getFullYear(); + minYear = parseInt( yearSplit[ 0 ], 10 ); + maxYear = parseInt( yearSplit[ 1 ], 10 ); + if ( yearSplit[ 0 ].match( /[+\-].*/ ) ) { + minYear += currentYear; + } + if ( yearSplit[ 1 ].match( /[+\-].*/ ) ) { + maxYear += currentYear; + } + } + + return ( ( !minDate || date.getTime() >= minDate.getTime() ) && + ( !maxDate || date.getTime() <= maxDate.getTime() ) && + ( !minYear || date.getFullYear() >= minYear ) && + ( !maxYear || date.getFullYear() <= maxYear ) ); + }, + + /* Provide the configuration settings for formatting/parsing. */ + _getFormatConfig: function( inst ) { + var shortYearCutoff = this._get( inst, "shortYearCutoff" ); + shortYearCutoff = ( typeof shortYearCutoff !== "string" ? shortYearCutoff : + new Date().getFullYear() % 100 + parseInt( shortYearCutoff, 10 ) ); + return { shortYearCutoff: shortYearCutoff, + dayNamesShort: this._get( inst, "dayNamesShort" ), dayNames: this._get( inst, "dayNames" ), + monthNamesShort: this._get( inst, "monthNamesShort" ), monthNames: this._get( inst, "monthNames" ) }; + }, + + /* Format the given date for display. */ + _formatDate: function( inst, day, month, year ) { + if ( !day ) { + inst.currentDay = inst.selectedDay; + inst.currentMonth = inst.selectedMonth; + inst.currentYear = inst.selectedYear; + } + var date = ( day ? ( typeof day === "object" ? day : + this._daylightSavingAdjust( new Date( year, month, day ) ) ) : + this._daylightSavingAdjust( new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ); + return this.formatDate( this._get( inst, "dateFormat" ), date, this._getFormatConfig( inst ) ); + } + } ); + + /* + * Bind hover events for datepicker elements. + * Done via delegate so the binding only occurs once in the lifetime of the parent div. + * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. + */ + function datepicker_bindHover( dpDiv ) { + var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a"; + return dpDiv.on( "mouseout", selector, function() { + $( this ).removeClass( "ui-state-hover" ); + if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) { + $( this ).removeClass( "ui-datepicker-prev-hover" ); + } + if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) { + $( this ).removeClass( "ui-datepicker-next-hover" ); + } + } ) + .on( "mouseover", selector, datepicker_handleMouseover ); + } + + function datepicker_handleMouseover() { + if ( !$.datepicker._isDisabledDatepicker( datepicker_instActive.inline ? datepicker_instActive.dpDiv.parent()[ 0 ] : datepicker_instActive.input[ 0 ] ) ) { + $( this ).parents( ".ui-datepicker-calendar" ).find( "a" ).removeClass( "ui-state-hover" ); + $( this ).addClass( "ui-state-hover" ); + if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) { + $( this ).addClass( "ui-datepicker-prev-hover" ); + } + if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) { + $( this ).addClass( "ui-datepicker-next-hover" ); + } + } + } + + /* jQuery extend now ignores nulls! */ + function datepicker_extendRemove( target, props ) { + $.extend( target, props ); + for ( var name in props ) { + if ( props[ name ] == null ) { + target[ name ] = props[ name ]; + } + } + return target; + } + + /* Invoke the datepicker functionality. + @param options string - a command, optionally followed by additional parameters or + Object - settings for attaching new datepicker functionality + @return jQuery object */ + $.fn.datepicker = function( options ) { + + /* Verify an empty collection wasn't passed - Fixes #6976 */ + if ( !this.length ) { + return this; + } + + /* Initialise the date picker. */ + if ( !$.datepicker.initialized ) { + $( document ).on( "mousedown", $.datepicker._checkExternalClick ); + $.datepicker.initialized = true; + } + + /* Append datepicker main container to body if not exist. */ + if ( $( "#" + $.datepicker._mainDivId ).length === 0 ) { + $( "body" ).append( $.datepicker.dpDiv ); + } + + var otherArgs = Array.prototype.slice.call( arguments, 1 ); + if ( typeof options === "string" && ( options === "isDisabled" || options === "getDate" || options === "widget" ) ) { + return $.datepicker[ "_" + options + "Datepicker" ]. + apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) ); + } + if ( options === "option" && arguments.length === 2 && typeof arguments[ 1 ] === "string" ) { + return $.datepicker[ "_" + options + "Datepicker" ]. + apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) ); + } + return this.each( function() { + if ( typeof options === "string" ) { + $.datepicker[ "_" + options + "Datepicker" ] + .apply( $.datepicker, [ this ].concat( otherArgs ) ); + } else { + $.datepicker._attachDatepicker( this, options ); + } + } ); + }; + + $.datepicker = new Datepicker(); // singleton instance + $.datepicker.initialized = false; + $.datepicker.uuid = new Date().getTime(); + $.datepicker.version = "1.13.2"; + + return $.datepicker; } ); diff --git a/lib/web/jquery/ui-modules/widgets/dialog.js b/lib/web/jquery/ui-modules/widgets/dialog.js index 88a6c384ed0c7..d267e2b567dbb 100644 --- a/lib/web/jquery/ui-modules/widgets/dialog.js +++ b/lib/web/jquery/ui-modules/widgets/dialog.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Dialog 1.13.1 + * jQuery UI Dialog 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -17,938 +17,938 @@ //>>css.theme: ../../themes/base/theme.css ( function( factory ) { - "use strict"; - - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define( [ - "jquery", - "./button", - "./draggable", - "./mouse", - "./resizable", - "../focusable", - "../keycode", - "../position", - "../safe-active-element", - "../safe-blur", - "../tabbable", - "../unique-id", - "../version", - "../widget" - ], factory ); - } else { - - // Browser globals - factory( jQuery ); - } + "use strict"; + + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ + "jquery", + "./button", + "./draggable", + "./mouse", + "./resizable", + "../focusable", + "../keycode", + "../position", + "../safe-active-element", + "../safe-blur", + "../tabbable", + "../unique-id", + "../version", + "../widget" + ], factory ); + } else { + + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; - -$.widget( "ui.dialog", { - version: "1.13.1", - options: { - appendTo: "body", - autoOpen: true, - buttons: [], - classes: { - "ui-dialog": "ui-corner-all", - "ui-dialog-titlebar": "ui-corner-all" - }, - closeOnEscape: true, - closeText: "Close", - draggable: true, - hide: null, - height: "auto", - maxHeight: null, - maxWidth: null, - minHeight: 150, - minWidth: 150, - modal: false, - position: { - my: "center", - at: "center", - of: window, - collision: "fit", - - // Ensure the titlebar is always visible - using: function( pos ) { - var topOffset = $( this ).css( pos ).offset().top; - if ( topOffset < 0 ) { - $( this ).css( "top", pos.top - topOffset ); - } - } - }, - resizable: true, - show: null, - title: null, - width: 300, - - // Callbacks - beforeClose: null, - close: null, - drag: null, - dragStart: null, - dragStop: null, - focus: null, - open: null, - resize: null, - resizeStart: null, - resizeStop: null - }, - - sizeRelatedOptions: { - buttons: true, - height: true, - maxHeight: true, - maxWidth: true, - minHeight: true, - minWidth: true, - width: true - }, - - resizableRelatedOptions: { - maxHeight: true, - maxWidth: true, - minHeight: true, - minWidth: true - }, - - _create: function() { - this.originalCss = { - display: this.element[ 0 ].style.display, - width: this.element[ 0 ].style.width, - minHeight: this.element[ 0 ].style.minHeight, - maxHeight: this.element[ 0 ].style.maxHeight, - height: this.element[ 0 ].style.height - }; - this.originalPosition = { - parent: this.element.parent(), - index: this.element.parent().children().index( this.element ) - }; - this.originalTitle = this.element.attr( "title" ); - if ( this.options.title == null && this.originalTitle != null ) { - this.options.title = this.originalTitle; - } - - // Dialogs can't be disabled - if ( this.options.disabled ) { - this.options.disabled = false; - } - - this._createWrapper(); - - this.element - .show() - .removeAttr( "title" ) - .appendTo( this.uiDialog ); - - this._addClass( "ui-dialog-content", "ui-widget-content" ); - - this._createTitlebar(); - this._createButtonPane(); - - if ( this.options.draggable && $.fn.draggable ) { - this._makeDraggable(); - } - if ( this.options.resizable && $.fn.resizable ) { - this._makeResizable(); - } - - this._isOpen = false; - - this._trackFocus(); - }, - - _init: function() { - if ( this.options.autoOpen ) { - this.open(); - } - }, - - _appendTo: function() { - var element = this.options.appendTo; - if ( element && ( element.jquery || element.nodeType ) ) { - return $( element ); - } - return this.document.find( element || "body" ).eq( 0 ); - }, - - _destroy: function() { - var next, - originalPosition = this.originalPosition; - - this._untrackInstance(); - this._destroyOverlay(); - - this.element - .removeUniqueId() - .css( this.originalCss ) - - // Without detaching first, the following becomes really slow - .detach(); - - this.uiDialog.remove(); - - if ( this.originalTitle ) { - this.element.attr( "title", this.originalTitle ); - } - - next = originalPosition.parent.children().eq( originalPosition.index ); - - // Don't try to place the dialog next to itself (#8613) - if ( next.length && next[ 0 ] !== this.element[ 0 ] ) { - next.before( this.element ); - } else { - originalPosition.parent.append( this.element ); - } - }, - - widget: function() { - return this.uiDialog; - }, - - disable: $.noop, - enable: $.noop, - - close: function( event ) { - var that = this; - - if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) { - return; - } - - this._isOpen = false; - this._focusedElement = null; - this._destroyOverlay(); - this._untrackInstance(); - - if ( !this.opener.filter( ":focusable" ).trigger( "focus" ).length ) { - - // Hiding a focused element doesn't trigger blur in WebKit - // so in case we have nothing to focus on, explicitly blur the active element - // https://bugs.webkit.org/show_bug.cgi?id=47182 - $.ui.safeBlur( $.ui.safeActiveElement( this.document[ 0 ] ) ); - } - - this._hide( this.uiDialog, this.options.hide, function() { - that._trigger( "close", event ); - } ); - }, - - isOpen: function() { - return this._isOpen; - }, - - moveToTop: function() { - this._moveToTop(); - }, - - _moveToTop: function( event, silent ) { - var moved = false, - zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map( function() { - return +$( this ).css( "z-index" ); - } ).get(), - zIndexMax = Math.max.apply( null, zIndices ); - - if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) { - this.uiDialog.css( "z-index", zIndexMax + 1 ); - moved = true; - } - - if ( moved && !silent ) { - this._trigger( "focus", event ); - } - return moved; - }, - - open: function() { - var that = this; - if ( this._isOpen ) { - if ( this._moveToTop() ) { - this._focusTabbable(); - } - return; - } - - this._isOpen = true; - this.opener = $( $.ui.safeActiveElement( this.document[ 0 ] ) ); - - this._size(); - this._position(); - this._createOverlay(); - this._moveToTop( null, true ); - - // Ensure the overlay is moved to the top with the dialog, but only when - // opening. The overlay shouldn't move after the dialog is open so that - // modeless dialogs opened after the modal dialog stack properly. - if ( this.overlay ) { - this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 ); - } - - this._show( this.uiDialog, this.options.show, function() { - that._focusTabbable(); - that._trigger( "focus" ); - } ); - - // Track the dialog immediately upon opening in case a focus event - // somehow occurs outside of the dialog before an element inside the - // dialog is focused (#10152) - this._makeFocusTarget(); - - this._trigger( "open" ); - }, - - _focusTabbable: function() { - - // Set focus to the first match: - // 1. An element that was focused previously - // 2. First element inside the dialog matching [autofocus] - // 3. Tabbable element inside the content element - // 4. Tabbable element inside the buttonpane - // 5. The close button - // 6. The dialog itself - var hasFocus = this._focusedElement; - if ( !hasFocus ) { - hasFocus = this.element.find( "[autofocus]" ); - } - if ( !hasFocus.length ) { - hasFocus = this.element.find( ":tabbable" ); - } - if ( !hasFocus.length ) { - hasFocus = this.uiDialogButtonPane.find( ":tabbable" ); - } - if ( !hasFocus.length ) { - hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" ); - } - if ( !hasFocus.length ) { - hasFocus = this.uiDialog; - } - hasFocus.eq( 0 ).trigger( "focus" ); - }, - - _restoreTabbableFocus: function() { - var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ), - isActive = this.uiDialog[ 0 ] === activeElement || - $.contains( this.uiDialog[ 0 ], activeElement ); - if ( !isActive ) { - this._focusTabbable(); - } - }, - - _keepFocus: function( event ) { - event.preventDefault(); - this._restoreTabbableFocus(); - - // support: IE - // IE <= 8 doesn't prevent moving focus even with event.preventDefault() - // so we check again later - this._delay( this._restoreTabbableFocus ); - }, - - _createWrapper: function() { - this.uiDialog = $( "<div>" ) - .hide() - .attr( { - - // Setting tabIndex makes the div focusable - tabIndex: -1, - role: "dialog" - } ) - .appendTo( this._appendTo() ); - - this._addClass( this.uiDialog, "ui-dialog", "ui-widget ui-widget-content ui-front" ); - this._on( this.uiDialog, { - keydown: function( event ) { - if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && - event.keyCode === $.ui.keyCode.ESCAPE ) { - event.preventDefault(); - this.close( event ); - return; - } - - // Prevent tabbing out of dialogs - if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) { - return; - } - var tabbables = this.uiDialog.find( ":tabbable" ), - first = tabbables.first(), - last = tabbables.last(); - - if ( ( event.target === last[ 0 ] || event.target === this.uiDialog[ 0 ] ) && - !event.shiftKey ) { - this._delay( function() { - first.trigger( "focus" ); - } ); - event.preventDefault(); - } else if ( ( event.target === first[ 0 ] || - event.target === this.uiDialog[ 0 ] ) && event.shiftKey ) { - this._delay( function() { - last.trigger( "focus" ); - } ); - event.preventDefault(); - } - }, - mousedown: function( event ) { - if ( this._moveToTop( event ) ) { - this._focusTabbable(); - } - } - } ); - - // We assume that any existing aria-describedby attribute means - // that the dialog content is marked up properly - // otherwise we brute force the content as the description - if ( !this.element.find( "[aria-describedby]" ).length ) { - this.uiDialog.attr( { - "aria-describedby": this.element.uniqueId().attr( "id" ) - } ); - } - }, - - _createTitlebar: function() { - var uiDialogTitle; - - this.uiDialogTitlebar = $( "<div>" ); - this._addClass( this.uiDialogTitlebar, - "ui-dialog-titlebar", "ui-widget-header ui-helper-clearfix" ); - this._on( this.uiDialogTitlebar, { - mousedown: function( event ) { - - // Don't prevent click on close button (#8838) - // Focusing a dialog that is partially scrolled out of view - // causes the browser to scroll it into view, preventing the click event - if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) { - - // Dialog isn't getting focus when dragging (#8063) - this.uiDialog.trigger( "focus" ); - } - } - } ); - - // Support: IE - // Use type="button" to prevent enter keypresses in textboxes from closing the - // dialog in IE (#9312) - this.uiDialogTitlebarClose = $( "<button type='button'></button>" ) - .button( { - label: $( "<a>" ).text( this.options.closeText ).html(), - icon: "ui-icon-closethick", - showLabel: false - } ) - .appendTo( this.uiDialogTitlebar ); - - this._addClass( this.uiDialogTitlebarClose, "ui-dialog-titlebar-close" ); - this._on( this.uiDialogTitlebarClose, { - click: function( event ) { - event.preventDefault(); - this.close( event ); - } - } ); - - uiDialogTitle = $( "<span>" ).uniqueId().prependTo( this.uiDialogTitlebar ); - this._addClass( uiDialogTitle, "ui-dialog-title" ); - this._title( uiDialogTitle ); - - this.uiDialogTitlebar.prependTo( this.uiDialog ); - - this.uiDialog.attr( { - "aria-labelledby": uiDialogTitle.attr( "id" ) - } ); - }, - - _title: function( title ) { - if ( this.options.title ) { - title.text( this.options.title ); - } else { - title.html( " " ); - } - }, - - _createButtonPane: function() { - this.uiDialogButtonPane = $( "<div>" ); - this._addClass( this.uiDialogButtonPane, "ui-dialog-buttonpane", - "ui-widget-content ui-helper-clearfix" ); - - this.uiButtonSet = $( "<div>" ) - .appendTo( this.uiDialogButtonPane ); - this._addClass( this.uiButtonSet, "ui-dialog-buttonset" ); - - this._createButtons(); - }, - - _createButtons: function() { - var that = this, - buttons = this.options.buttons; - - // If we already have a button pane, remove it - this.uiDialogButtonPane.remove(); - this.uiButtonSet.empty(); - - if ( $.isEmptyObject( buttons ) || ( Array.isArray( buttons ) && !buttons.length ) ) { - this._removeClass( this.uiDialog, "ui-dialog-buttons" ); - return; - } - - $.each( buttons, function( name, props ) { - var click, buttonOptions; - props = typeof props === "function" ? - { click: props, text: name } : - props; - - // Default to a non-submitting button - props = $.extend( { type: "button" }, props ); - - // Change the context for the click callback to be the main element - click = props.click; - buttonOptions = { - icon: props.icon, - iconPosition: props.iconPosition, - showLabel: props.showLabel, - - // Deprecated options - icons: props.icons, - text: props.text - }; - - delete props.click; - delete props.icon; - delete props.iconPosition; - delete props.showLabel; - - // Deprecated options - delete props.icons; - if ( typeof props.text === "boolean" ) { - delete props.text; - } - - $( "<button></button>", props ) - .button( buttonOptions ) - .appendTo( that.uiButtonSet ) - .on( "click", function() { - click.apply( that.element[ 0 ], arguments ); - } ); - } ); - this._addClass( this.uiDialog, "ui-dialog-buttons" ); - this.uiDialogButtonPane.appendTo( this.uiDialog ); - }, - - _makeDraggable: function() { - var that = this, - options = this.options; - - function filteredUi( ui ) { - return { - position: ui.position, - offset: ui.offset - }; - } - - this.uiDialog.draggable( { - cancel: ".ui-dialog-content, .ui-dialog-titlebar-close", - handle: ".ui-dialog-titlebar", - containment: "document", - start: function( event, ui ) { - that._addClass( $( this ), "ui-dialog-dragging" ); - that._blockFrames(); - that._trigger( "dragStart", event, filteredUi( ui ) ); - }, - drag: function( event, ui ) { - that._trigger( "drag", event, filteredUi( ui ) ); - }, - stop: function( event, ui ) { - var left = ui.offset.left - that.document.scrollLeft(), - top = ui.offset.top - that.document.scrollTop(); - - options.position = { - my: "left top", - at: "left" + ( left >= 0 ? "+" : "" ) + left + " " + - "top" + ( top >= 0 ? "+" : "" ) + top, - of: that.window - }; - that._removeClass( $( this ), "ui-dialog-dragging" ); - that._unblockFrames(); - that._trigger( "dragStop", event, filteredUi( ui ) ); - } - } ); - }, - - _makeResizable: function() { - var that = this, - options = this.options, - handles = options.resizable, - - // .ui-resizable has position: relative defined in the stylesheet - // but dialogs have to use absolute or fixed positioning - position = this.uiDialog.css( "position" ), - resizeHandles = typeof handles === "string" ? - handles : - "n,e,s,w,se,sw,ne,nw"; - - function filteredUi( ui ) { - return { - originalPosition: ui.originalPosition, - originalSize: ui.originalSize, - position: ui.position, - size: ui.size - }; - } - - this.uiDialog.resizable( { - cancel: ".ui-dialog-content", - containment: "document", - alsoResize: this.element, - maxWidth: options.maxWidth, - maxHeight: options.maxHeight, - minWidth: options.minWidth, - minHeight: this._minHeight(), - handles: resizeHandles, - start: function( event, ui ) { - that._addClass( $( this ), "ui-dialog-resizing" ); - that._blockFrames(); - that._trigger( "resizeStart", event, filteredUi( ui ) ); - }, - resize: function( event, ui ) { - that._trigger( "resize", event, filteredUi( ui ) ); - }, - stop: function( event, ui ) { - var offset = that.uiDialog.offset(), - left = offset.left - that.document.scrollLeft(), - top = offset.top - that.document.scrollTop(); - - options.height = that.uiDialog.height(); - options.width = that.uiDialog.width(); - options.position = { - my: "left top", - at: "left" + ( left >= 0 ? "+" : "" ) + left + " " + - "top" + ( top >= 0 ? "+" : "" ) + top, - of: that.window - }; - that._removeClass( $( this ), "ui-dialog-resizing" ); - that._unblockFrames(); - that._trigger( "resizeStop", event, filteredUi( ui ) ); - } - } ) - .css( "position", position ); - }, - - _trackFocus: function() { - this._on( this.widget(), { - focusin: function( event ) { - this._makeFocusTarget(); - this._focusedElement = $( event.target ); - } - } ); - }, - - _makeFocusTarget: function() { - this._untrackInstance(); - this._trackingInstances().unshift( this ); - }, - - _untrackInstance: function() { - var instances = this._trackingInstances(), - exists = $.inArray( this, instances ); - if ( exists !== -1 ) { - instances.splice( exists, 1 ); - } - }, - - _trackingInstances: function() { - var instances = this.document.data( "ui-dialog-instances" ); - if ( !instances ) { - instances = []; - this.document.data( "ui-dialog-instances", instances ); - } - return instances; - }, - - _minHeight: function() { - var options = this.options; - - return options.height === "auto" ? - options.minHeight : - Math.min( options.minHeight, options.height ); - }, - - _position: function() { - - // Need to show the dialog to get the actual offset in the position plugin - var isVisible = this.uiDialog.is( ":visible" ); - if ( !isVisible ) { - this.uiDialog.show(); - } - this.uiDialog.position( this.options.position ); - if ( !isVisible ) { - this.uiDialog.hide(); - } - }, - - _setOptions: function( options ) { - var that = this, - resize = false, - resizableOptions = {}; - - $.each( options, function( key, value ) { - that._setOption( key, value ); - - if ( key in that.sizeRelatedOptions ) { - resize = true; - } - if ( key in that.resizableRelatedOptions ) { - resizableOptions[ key ] = value; - } - } ); - - if ( resize ) { - this._size(); - this._position(); - } - if ( this.uiDialog.is( ":data(ui-resizable)" ) ) { - this.uiDialog.resizable( "option", resizableOptions ); - } - }, - - _setOption: function( key, value ) { - var isDraggable, isResizable, - uiDialog = this.uiDialog; - - if ( key === "disabled" ) { - return; - } - - this._super( key, value ); - - if ( key === "appendTo" ) { - this.uiDialog.appendTo( this._appendTo() ); - } - - if ( key === "buttons" ) { - this._createButtons(); - } - - if ( key === "closeText" ) { - this.uiDialogTitlebarClose.button( { - - // Ensure that we always pass a string - label: $( "<a>" ).text( "" + this.options.closeText ).html() - } ); - } - - if ( key === "draggable" ) { - isDraggable = uiDialog.is( ":data(ui-draggable)" ); - if ( isDraggable && !value ) { - uiDialog.draggable( "destroy" ); - } - - if ( !isDraggable && value ) { - this._makeDraggable(); - } - } - - if ( key === "position" ) { - this._position(); - } - - if ( key === "resizable" ) { - - // currently resizable, becoming non-resizable - isResizable = uiDialog.is( ":data(ui-resizable)" ); - if ( isResizable && !value ) { - uiDialog.resizable( "destroy" ); - } - - // Currently resizable, changing handles - if ( isResizable && typeof value === "string" ) { - uiDialog.resizable( "option", "handles", value ); - } - - // Currently non-resizable, becoming resizable - if ( !isResizable && value !== false ) { - this._makeResizable(); - } - } - - if ( key === "title" ) { - this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) ); - } - }, - - _size: function() { - - // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content - // divs will both have width and height set, so we need to reset them - var nonContentHeight, minContentHeight, maxContentHeight, - options = this.options; - - // Reset content sizing - this.element.show().css( { - width: "auto", - minHeight: 0, - maxHeight: "none", - height: 0 - } ); - - if ( options.minWidth > options.width ) { - options.width = options.minWidth; - } - - // Reset wrapper sizing - // determine the height of all the non-content elements - nonContentHeight = this.uiDialog.css( { - height: "auto", - width: options.width - } ) - .outerHeight(); - minContentHeight = Math.max( 0, options.minHeight - nonContentHeight ); - maxContentHeight = typeof options.maxHeight === "number" ? - Math.max( 0, options.maxHeight - nonContentHeight ) : - "none"; - - if ( options.height === "auto" ) { - this.element.css( { - minHeight: minContentHeight, - maxHeight: maxContentHeight, - height: "auto" - } ); - } else { - this.element.height( Math.max( 0, options.height - nonContentHeight ) ); - } - - if ( this.uiDialog.is( ":data(ui-resizable)" ) ) { - this.uiDialog.resizable( "option", "minHeight", this._minHeight() ); - } - }, - - _blockFrames: function() { - this.iframeBlocks = this.document.find( "iframe" ).map( function() { - var iframe = $( this ); - - return $( "<div>" ) - .css( { - position: "absolute", - width: iframe.outerWidth(), - height: iframe.outerHeight() - } ) - .appendTo( iframe.parent() ) - .offset( iframe.offset() )[ 0 ]; - } ); - }, - - _unblockFrames: function() { - if ( this.iframeBlocks ) { - this.iframeBlocks.remove(); - delete this.iframeBlocks; - } - }, - - _allowInteraction: function( event ) { - if ( $( event.target ).closest( ".ui-dialog" ).length ) { - return true; - } - - // TODO: Remove hack when datepicker implements - // the .ui-front logic (#8989) - return !!$( event.target ).closest( ".ui-datepicker" ).length; - }, - - _createOverlay: function() { - if ( !this.options.modal ) { - return; - } - - var jqMinor = $.fn.jquery.substring( 0, 4 ); - - // We use a delay in case the overlay is created from an - // event that we're going to be cancelling (#2804) - var isOpening = true; - this._delay( function() { - isOpening = false; - } ); - - if ( !this.document.data( "ui-dialog-overlays" ) ) { - - // Prevent use of anchors and inputs - // This doesn't use `_on()` because it is a shared event handler - // across all open modal dialogs. - this.document.on( "focusin.ui-dialog", function( event ) { - if ( isOpening ) { - return; - } - - var instance = this._trackingInstances()[ 0 ]; - if ( !instance._allowInteraction( event ) ) { - event.preventDefault(); - instance._focusTabbable(); - - // Support: jQuery >=3.4 <3.6 only - // Focus re-triggering in jQuery 3.4/3.5 makes the original element - // have its focus event propagated last, breaking the re-targeting. - // Trigger focus in a delay in addition if needed to avoid the issue - // See https://github.com/jquery/jquery/issues/4382 - if ( jqMinor === "3.4." || jqMinor === "3.5." ) { - instance._delay( instance._restoreTabbableFocus ); - } - } - }.bind( this ) ); - } - - this.overlay = $( "<div>" ) - .appendTo( this._appendTo() ); - - this._addClass( this.overlay, null, "ui-widget-overlay ui-front" ); - this._on( this.overlay, { - mousedown: "_keepFocus" - } ); - this.document.data( "ui-dialog-overlays", - ( this.document.data( "ui-dialog-overlays" ) || 0 ) + 1 ); - }, - - _destroyOverlay: function() { - if ( !this.options.modal ) { - return; - } - - if ( this.overlay ) { - var overlays = this.document.data( "ui-dialog-overlays" ) - 1; - - if ( !overlays ) { - this.document.off( "focusin.ui-dialog" ); - this.document.removeData( "ui-dialog-overlays" ); - } else { - this.document.data( "ui-dialog-overlays", overlays ); - } - - this.overlay.remove(); - this.overlay = null; - } - } -} ); + "use strict"; + + $.widget( "ui.dialog", { + version: "1.13.2", + options: { + appendTo: "body", + autoOpen: true, + buttons: [], + classes: { + "ui-dialog": "ui-corner-all", + "ui-dialog-titlebar": "ui-corner-all" + }, + closeOnEscape: true, + closeText: "Close", + draggable: true, + hide: null, + height: "auto", + maxHeight: null, + maxWidth: null, + minHeight: 150, + minWidth: 150, + modal: false, + position: { + my: "center", + at: "center", + of: window, + collision: "fit", + + // Ensure the titlebar is always visible + using: function( pos ) { + var topOffset = $( this ).css( pos ).offset().top; + if ( topOffset < 0 ) { + $( this ).css( "top", pos.top - topOffset ); + } + } + }, + resizable: true, + show: null, + title: null, + width: 300, + + // Callbacks + beforeClose: null, + close: null, + drag: null, + dragStart: null, + dragStop: null, + focus: null, + open: null, + resize: null, + resizeStart: null, + resizeStop: null + }, + + sizeRelatedOptions: { + buttons: true, + height: true, + maxHeight: true, + maxWidth: true, + minHeight: true, + minWidth: true, + width: true + }, + + resizableRelatedOptions: { + maxHeight: true, + maxWidth: true, + minHeight: true, + minWidth: true + }, + + _create: function() { + this.originalCss = { + display: this.element[ 0 ].style.display, + width: this.element[ 0 ].style.width, + minHeight: this.element[ 0 ].style.minHeight, + maxHeight: this.element[ 0 ].style.maxHeight, + height: this.element[ 0 ].style.height + }; + this.originalPosition = { + parent: this.element.parent(), + index: this.element.parent().children().index( this.element ) + }; + this.originalTitle = this.element.attr( "title" ); + if ( this.options.title == null && this.originalTitle != null ) { + this.options.title = this.originalTitle; + } + + // Dialogs can't be disabled + if ( this.options.disabled ) { + this.options.disabled = false; + } + + this._createWrapper(); + + this.element + .show() + .removeAttr( "title" ) + .appendTo( this.uiDialog ); + + this._addClass( "ui-dialog-content", "ui-widget-content" ); + + this._createTitlebar(); + this._createButtonPane(); + + if ( this.options.draggable && $.fn.draggable ) { + this._makeDraggable(); + } + if ( this.options.resizable && $.fn.resizable ) { + this._makeResizable(); + } + + this._isOpen = false; + + this._trackFocus(); + }, + + _init: function() { + if ( this.options.autoOpen ) { + this.open(); + } + }, + + _appendTo: function() { + var element = this.options.appendTo; + if ( element && ( element.jquery || element.nodeType ) ) { + return $( element ); + } + return this.document.find( element || "body" ).eq( 0 ); + }, + + _destroy: function() { + var next, + originalPosition = this.originalPosition; + + this._untrackInstance(); + this._destroyOverlay(); + + this.element + .removeUniqueId() + .css( this.originalCss ) + + // Without detaching first, the following becomes really slow + .detach(); + + this.uiDialog.remove(); + + if ( this.originalTitle ) { + this.element.attr( "title", this.originalTitle ); + } + + next = originalPosition.parent.children().eq( originalPosition.index ); + + // Don't try to place the dialog next to itself (#8613) + if ( next.length && next[ 0 ] !== this.element[ 0 ] ) { + next.before( this.element ); + } else { + originalPosition.parent.append( this.element ); + } + }, + + widget: function() { + return this.uiDialog; + }, + + disable: $.noop, + enable: $.noop, + + close: function( event ) { + var that = this; + + if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) { + return; + } + + this._isOpen = false; + this._focusedElement = null; + this._destroyOverlay(); + this._untrackInstance(); + + if ( !this.opener.filter( ":focusable" ).trigger( "focus" ).length ) { + + // Hiding a focused element doesn't trigger blur in WebKit + // so in case we have nothing to focus on, explicitly blur the active element + // https://bugs.webkit.org/show_bug.cgi?id=47182 + $.ui.safeBlur( $.ui.safeActiveElement( this.document[ 0 ] ) ); + } + + this._hide( this.uiDialog, this.options.hide, function() { + that._trigger( "close", event ); + } ); + }, + + isOpen: function() { + return this._isOpen; + }, + + moveToTop: function() { + this._moveToTop(); + }, + + _moveToTop: function( event, silent ) { + var moved = false, + zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map( function() { + return +$( this ).css( "z-index" ); + } ).get(), + zIndexMax = Math.max.apply( null, zIndices ); + + if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) { + this.uiDialog.css( "z-index", zIndexMax + 1 ); + moved = true; + } + + if ( moved && !silent ) { + this._trigger( "focus", event ); + } + return moved; + }, + + open: function() { + var that = this; + if ( this._isOpen ) { + if ( this._moveToTop() ) { + this._focusTabbable(); + } + return; + } + + this._isOpen = true; + this.opener = $( $.ui.safeActiveElement( this.document[ 0 ] ) ); + + this._size(); + this._position(); + this._createOverlay(); + this._moveToTop( null, true ); + + // Ensure the overlay is moved to the top with the dialog, but only when + // opening. The overlay shouldn't move after the dialog is open so that + // modeless dialogs opened after the modal dialog stack properly. + if ( this.overlay ) { + this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 ); + } + + this._show( this.uiDialog, this.options.show, function() { + that._focusTabbable(); + that._trigger( "focus" ); + } ); + + // Track the dialog immediately upon opening in case a focus event + // somehow occurs outside of the dialog before an element inside the + // dialog is focused (#10152) + this._makeFocusTarget(); + + this._trigger( "open" ); + }, + + _focusTabbable: function() { + + // Set focus to the first match: + // 1. An element that was focused previously + // 2. First element inside the dialog matching [autofocus] + // 3. Tabbable element inside the content element + // 4. Tabbable element inside the buttonpane + // 5. The close button + // 6. The dialog itself + var hasFocus = this._focusedElement; + if ( !hasFocus ) { + hasFocus = this.element.find( "[autofocus]" ); + } + if ( !hasFocus.length ) { + hasFocus = this.element.find( ":tabbable" ); + } + if ( !hasFocus.length ) { + hasFocus = this.uiDialogButtonPane.find( ":tabbable" ); + } + if ( !hasFocus.length ) { + hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" ); + } + if ( !hasFocus.length ) { + hasFocus = this.uiDialog; + } + hasFocus.eq( 0 ).trigger( "focus" ); + }, + + _restoreTabbableFocus: function() { + var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ), + isActive = this.uiDialog[ 0 ] === activeElement || + $.contains( this.uiDialog[ 0 ], activeElement ); + if ( !isActive ) { + this._focusTabbable(); + } + }, + + _keepFocus: function( event ) { + event.preventDefault(); + this._restoreTabbableFocus(); + + // support: IE + // IE <= 8 doesn't prevent moving focus even with event.preventDefault() + // so we check again later + this._delay( this._restoreTabbableFocus ); + }, + + _createWrapper: function() { + this.uiDialog = $( "<div>" ) + .hide() + .attr( { + + // Setting tabIndex makes the div focusable + tabIndex: -1, + role: "dialog" + } ) + .appendTo( this._appendTo() ); + + this._addClass( this.uiDialog, "ui-dialog", "ui-widget ui-widget-content ui-front" ); + this._on( this.uiDialog, { + keydown: function( event ) { + if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && + event.keyCode === $.ui.keyCode.ESCAPE ) { + event.preventDefault(); + this.close( event ); + return; + } + + // Prevent tabbing out of dialogs + if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) { + return; + } + var tabbables = this.uiDialog.find( ":tabbable" ), + first = tabbables.first(), + last = tabbables.last(); + + if ( ( event.target === last[ 0 ] || event.target === this.uiDialog[ 0 ] ) && + !event.shiftKey ) { + this._delay( function() { + first.trigger( "focus" ); + } ); + event.preventDefault(); + } else if ( ( event.target === first[ 0 ] || + event.target === this.uiDialog[ 0 ] ) && event.shiftKey ) { + this._delay( function() { + last.trigger( "focus" ); + } ); + event.preventDefault(); + } + }, + mousedown: function( event ) { + if ( this._moveToTop( event ) ) { + this._focusTabbable(); + } + } + } ); + + // We assume that any existing aria-describedby attribute means + // that the dialog content is marked up properly + // otherwise we brute force the content as the description + if ( !this.element.find( "[aria-describedby]" ).length ) { + this.uiDialog.attr( { + "aria-describedby": this.element.uniqueId().attr( "id" ) + } ); + } + }, + + _createTitlebar: function() { + var uiDialogTitle; + + this.uiDialogTitlebar = $( "<div>" ); + this._addClass( this.uiDialogTitlebar, + "ui-dialog-titlebar", "ui-widget-header ui-helper-clearfix" ); + this._on( this.uiDialogTitlebar, { + mousedown: function( event ) { + + // Don't prevent click on close button (#8838) + // Focusing a dialog that is partially scrolled out of view + // causes the browser to scroll it into view, preventing the click event + if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) { + + // Dialog isn't getting focus when dragging (#8063) + this.uiDialog.trigger( "focus" ); + } + } + } ); + + // Support: IE + // Use type="button" to prevent enter keypresses in textboxes from closing the + // dialog in IE (#9312) + this.uiDialogTitlebarClose = $( "<button type='button'></button>" ) + .button( { + label: $( "<a>" ).text( this.options.closeText ).html(), + icon: "ui-icon-closethick", + showLabel: false + } ) + .appendTo( this.uiDialogTitlebar ); + + this._addClass( this.uiDialogTitlebarClose, "ui-dialog-titlebar-close" ); + this._on( this.uiDialogTitlebarClose, { + click: function( event ) { + event.preventDefault(); + this.close( event ); + } + } ); + + uiDialogTitle = $( "<span>" ).uniqueId().prependTo( this.uiDialogTitlebar ); + this._addClass( uiDialogTitle, "ui-dialog-title" ); + this._title( uiDialogTitle ); + + this.uiDialogTitlebar.prependTo( this.uiDialog ); + + this.uiDialog.attr( { + "aria-labelledby": uiDialogTitle.attr( "id" ) + } ); + }, + + _title: function( title ) { + if ( this.options.title ) { + title.text( this.options.title ); + } else { + title.html( " " ); + } + }, + + _createButtonPane: function() { + this.uiDialogButtonPane = $( "<div>" ); + this._addClass( this.uiDialogButtonPane, "ui-dialog-buttonpane", + "ui-widget-content ui-helper-clearfix" ); + + this.uiButtonSet = $( "<div>" ) + .appendTo( this.uiDialogButtonPane ); + this._addClass( this.uiButtonSet, "ui-dialog-buttonset" ); + + this._createButtons(); + }, + + _createButtons: function() { + var that = this, + buttons = this.options.buttons; + + // If we already have a button pane, remove it + this.uiDialogButtonPane.remove(); + this.uiButtonSet.empty(); + + if ( $.isEmptyObject( buttons ) || ( Array.isArray( buttons ) && !buttons.length ) ) { + this._removeClass( this.uiDialog, "ui-dialog-buttons" ); + return; + } + + $.each( buttons, function( name, props ) { + var click, buttonOptions; + props = typeof props === "function" ? + { click: props, text: name } : + props; + + // Default to a non-submitting button + props = $.extend( { type: "button" }, props ); + + // Change the context for the click callback to be the main element + click = props.click; + buttonOptions = { + icon: props.icon, + iconPosition: props.iconPosition, + showLabel: props.showLabel, + + // Deprecated options + icons: props.icons, + text: props.text + }; + + delete props.click; + delete props.icon; + delete props.iconPosition; + delete props.showLabel; + + // Deprecated options + delete props.icons; + if ( typeof props.text === "boolean" ) { + delete props.text; + } + + $( "<button></button>", props ) + .button( buttonOptions ) + .appendTo( that.uiButtonSet ) + .on( "click", function() { + click.apply( that.element[ 0 ], arguments ); + } ); + } ); + this._addClass( this.uiDialog, "ui-dialog-buttons" ); + this.uiDialogButtonPane.appendTo( this.uiDialog ); + }, + + _makeDraggable: function() { + var that = this, + options = this.options; + + function filteredUi( ui ) { + return { + position: ui.position, + offset: ui.offset + }; + } + + this.uiDialog.draggable( { + cancel: ".ui-dialog-content, .ui-dialog-titlebar-close", + handle: ".ui-dialog-titlebar", + containment: "document", + start: function( event, ui ) { + that._addClass( $( this ), "ui-dialog-dragging" ); + that._blockFrames(); + that._trigger( "dragStart", event, filteredUi( ui ) ); + }, + drag: function( event, ui ) { + that._trigger( "drag", event, filteredUi( ui ) ); + }, + stop: function( event, ui ) { + var left = ui.offset.left - that.document.scrollLeft(), + top = ui.offset.top - that.document.scrollTop(); + + options.position = { + my: "left top", + at: "left" + ( left >= 0 ? "+" : "" ) + left + " " + + "top" + ( top >= 0 ? "+" : "" ) + top, + of: that.window + }; + that._removeClass( $( this ), "ui-dialog-dragging" ); + that._unblockFrames(); + that._trigger( "dragStop", event, filteredUi( ui ) ); + } + } ); + }, + + _makeResizable: function() { + var that = this, + options = this.options, + handles = options.resizable, + + // .ui-resizable has position: relative defined in the stylesheet + // but dialogs have to use absolute or fixed positioning + position = this.uiDialog.css( "position" ), + resizeHandles = typeof handles === "string" ? + handles : + "n,e,s,w,se,sw,ne,nw"; + + function filteredUi( ui ) { + return { + originalPosition: ui.originalPosition, + originalSize: ui.originalSize, + position: ui.position, + size: ui.size + }; + } + + this.uiDialog.resizable( { + cancel: ".ui-dialog-content", + containment: "document", + alsoResize: this.element, + maxWidth: options.maxWidth, + maxHeight: options.maxHeight, + minWidth: options.minWidth, + minHeight: this._minHeight(), + handles: resizeHandles, + start: function( event, ui ) { + that._addClass( $( this ), "ui-dialog-resizing" ); + that._blockFrames(); + that._trigger( "resizeStart", event, filteredUi( ui ) ); + }, + resize: function( event, ui ) { + that._trigger( "resize", event, filteredUi( ui ) ); + }, + stop: function( event, ui ) { + var offset = that.uiDialog.offset(), + left = offset.left - that.document.scrollLeft(), + top = offset.top - that.document.scrollTop(); + + options.height = that.uiDialog.height(); + options.width = that.uiDialog.width(); + options.position = { + my: "left top", + at: "left" + ( left >= 0 ? "+" : "" ) + left + " " + + "top" + ( top >= 0 ? "+" : "" ) + top, + of: that.window + }; + that._removeClass( $( this ), "ui-dialog-resizing" ); + that._unblockFrames(); + that._trigger( "resizeStop", event, filteredUi( ui ) ); + } + } ) + .css( "position", position ); + }, + + _trackFocus: function() { + this._on( this.widget(), { + focusin: function( event ) { + this._makeFocusTarget(); + this._focusedElement = $( event.target ); + } + } ); + }, + + _makeFocusTarget: function() { + this._untrackInstance(); + this._trackingInstances().unshift( this ); + }, + + _untrackInstance: function() { + var instances = this._trackingInstances(), + exists = $.inArray( this, instances ); + if ( exists !== -1 ) { + instances.splice( exists, 1 ); + } + }, + + _trackingInstances: function() { + var instances = this.document.data( "ui-dialog-instances" ); + if ( !instances ) { + instances = []; + this.document.data( "ui-dialog-instances", instances ); + } + return instances; + }, + + _minHeight: function() { + var options = this.options; + + return options.height === "auto" ? + options.minHeight : + Math.min( options.minHeight, options.height ); + }, + + _position: function() { + + // Need to show the dialog to get the actual offset in the position plugin + var isVisible = this.uiDialog.is( ":visible" ); + if ( !isVisible ) { + this.uiDialog.show(); + } + this.uiDialog.position( this.options.position ); + if ( !isVisible ) { + this.uiDialog.hide(); + } + }, + + _setOptions: function( options ) { + var that = this, + resize = false, + resizableOptions = {}; + + $.each( options, function( key, value ) { + that._setOption( key, value ); + + if ( key in that.sizeRelatedOptions ) { + resize = true; + } + if ( key in that.resizableRelatedOptions ) { + resizableOptions[ key ] = value; + } + } ); + + if ( resize ) { + this._size(); + this._position(); + } + if ( this.uiDialog.is( ":data(ui-resizable)" ) ) { + this.uiDialog.resizable( "option", resizableOptions ); + } + }, + + _setOption: function( key, value ) { + var isDraggable, isResizable, + uiDialog = this.uiDialog; + + if ( key === "disabled" ) { + return; + } + + this._super( key, value ); + + if ( key === "appendTo" ) { + this.uiDialog.appendTo( this._appendTo() ); + } + + if ( key === "buttons" ) { + this._createButtons(); + } + + if ( key === "closeText" ) { + this.uiDialogTitlebarClose.button( { + + // Ensure that we always pass a string + label: $( "<a>" ).text( "" + this.options.closeText ).html() + } ); + } + + if ( key === "draggable" ) { + isDraggable = uiDialog.is( ":data(ui-draggable)" ); + if ( isDraggable && !value ) { + uiDialog.draggable( "destroy" ); + } + + if ( !isDraggable && value ) { + this._makeDraggable(); + } + } + + if ( key === "position" ) { + this._position(); + } + + if ( key === "resizable" ) { + + // currently resizable, becoming non-resizable + isResizable = uiDialog.is( ":data(ui-resizable)" ); + if ( isResizable && !value ) { + uiDialog.resizable( "destroy" ); + } + + // Currently resizable, changing handles + if ( isResizable && typeof value === "string" ) { + uiDialog.resizable( "option", "handles", value ); + } + + // Currently non-resizable, becoming resizable + if ( !isResizable && value !== false ) { + this._makeResizable(); + } + } + + if ( key === "title" ) { + this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) ); + } + }, + + _size: function() { + + // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content + // divs will both have width and height set, so we need to reset them + var nonContentHeight, minContentHeight, maxContentHeight, + options = this.options; + + // Reset content sizing + this.element.show().css( { + width: "auto", + minHeight: 0, + maxHeight: "none", + height: 0 + } ); + + if ( options.minWidth > options.width ) { + options.width = options.minWidth; + } + + // Reset wrapper sizing + // determine the height of all the non-content elements + nonContentHeight = this.uiDialog.css( { + height: "auto", + width: options.width + } ) + .outerHeight(); + minContentHeight = Math.max( 0, options.minHeight - nonContentHeight ); + maxContentHeight = typeof options.maxHeight === "number" ? + Math.max( 0, options.maxHeight - nonContentHeight ) : + "none"; + + if ( options.height === "auto" ) { + this.element.css( { + minHeight: minContentHeight, + maxHeight: maxContentHeight, + height: "auto" + } ); + } else { + this.element.height( Math.max( 0, options.height - nonContentHeight ) ); + } + + if ( this.uiDialog.is( ":data(ui-resizable)" ) ) { + this.uiDialog.resizable( "option", "minHeight", this._minHeight() ); + } + }, + + _blockFrames: function() { + this.iframeBlocks = this.document.find( "iframe" ).map( function() { + var iframe = $( this ); + + return $( "<div>" ) + .css( { + position: "absolute", + width: iframe.outerWidth(), + height: iframe.outerHeight() + } ) + .appendTo( iframe.parent() ) + .offset( iframe.offset() )[ 0 ]; + } ); + }, + + _unblockFrames: function() { + if ( this.iframeBlocks ) { + this.iframeBlocks.remove(); + delete this.iframeBlocks; + } + }, + + _allowInteraction: function( event ) { + if ( $( event.target ).closest( ".ui-dialog" ).length ) { + return true; + } + + // TODO: Remove hack when datepicker implements + // the .ui-front logic (#8989) + return !!$( event.target ).closest( ".ui-datepicker" ).length; + }, + + _createOverlay: function() { + if ( !this.options.modal ) { + return; + } + + var jqMinor = $.fn.jquery.substring( 0, 4 ); + + // We use a delay in case the overlay is created from an + // event that we're going to be cancelling (#2804) + var isOpening = true; + this._delay( function() { + isOpening = false; + } ); + + if ( !this.document.data( "ui-dialog-overlays" ) ) { + + // Prevent use of anchors and inputs + // This doesn't use `_on()` because it is a shared event handler + // across all open modal dialogs. + this.document.on( "focusin.ui-dialog", function( event ) { + if ( isOpening ) { + return; + } + + var instance = this._trackingInstances()[ 0 ]; + if ( !instance._allowInteraction( event ) ) { + event.preventDefault(); + instance._focusTabbable(); + + // Support: jQuery >=3.4 <3.6 only + // Focus re-triggering in jQuery 3.4/3.5 makes the original element + // have its focus event propagated last, breaking the re-targeting. + // Trigger focus in a delay in addition if needed to avoid the issue + // See https://github.com/jquery/jquery/issues/4382 + if ( jqMinor === "3.4." || jqMinor === "3.5." ) { + instance._delay( instance._restoreTabbableFocus ); + } + } + }.bind( this ) ); + } + + this.overlay = $( "<div>" ) + .appendTo( this._appendTo() ); + + this._addClass( this.overlay, null, "ui-widget-overlay ui-front" ); + this._on( this.overlay, { + mousedown: "_keepFocus" + } ); + this.document.data( "ui-dialog-overlays", + ( this.document.data( "ui-dialog-overlays" ) || 0 ) + 1 ); + }, + + _destroyOverlay: function() { + if ( !this.options.modal ) { + return; + } + + if ( this.overlay ) { + var overlays = this.document.data( "ui-dialog-overlays" ) - 1; + + if ( !overlays ) { + this.document.off( "focusin.ui-dialog" ); + this.document.removeData( "ui-dialog-overlays" ); + } else { + this.document.data( "ui-dialog-overlays", overlays ); + } + + this.overlay.remove(); + this.overlay = null; + } + } + } ); // DEPRECATED // TODO: switch return back to widget declaration at top of file when this is removed -if ( $.uiBackCompat !== false ) { - - // Backcompat for dialogClass option - $.widget( "ui.dialog", $.ui.dialog, { - options: { - dialogClass: "" - }, - _createWrapper: function() { - this._super(); - this.uiDialog.addClass( this.options.dialogClass ); - }, - _setOption: function( key, value ) { - if ( key === "dialogClass" ) { - this.uiDialog - .removeClass( this.options.dialogClass ) - .addClass( value ); - } - this._superApply( arguments ); - } - } ); -} - -return $.ui.dialog; + if ( $.uiBackCompat !== false ) { + + // Backcompat for dialogClass option + $.widget( "ui.dialog", $.ui.dialog, { + options: { + dialogClass: "" + }, + _createWrapper: function() { + this._super(); + this.uiDialog.addClass( this.options.dialogClass ); + }, + _setOption: function( key, value ) { + if ( key === "dialogClass" ) { + this.uiDialog + .removeClass( this.options.dialogClass ) + .addClass( value ); + } + this._superApply( arguments ); + } + } ); + } + + return $.ui.dialog; } ); diff --git a/lib/web/jquery/ui-modules/widgets/draggable.js b/lib/web/jquery/ui-modules/widgets/draggable.js index c3469e17721ce..badc68630c606 100644 --- a/lib/web/jquery/ui-modules/widgets/draggable.js +++ b/lib/web/jquery/ui-modules/widgets/draggable.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Draggable 1.13.1 + * jQuery UI Draggable 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -15,1245 +15,1245 @@ //>>css.structure: ../../themes/base/draggable.css ( function( factory ) { - "use strict"; - - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define( [ - "jquery", - "./mouse", - "../data", - "../plugin", - "../safe-active-element", - "../safe-blur", - "../scroll-parent", - "../version", - "../widget" - ], factory ); - } else { - - // Browser globals - factory( jQuery ); - } + "use strict"; + + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ + "jquery", + "./mouse", + "../data", + "../plugin", + "../safe-active-element", + "../safe-blur", + "../scroll-parent", + "../version", + "../widget" + ], factory ); + } else { + + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; - -$.widget( "ui.draggable", $.ui.mouse, { - version: "1.13.1", - widgetEventPrefix: "drag", - options: { - addClasses: true, - appendTo: "parent", - axis: false, - connectToSortable: false, - containment: false, - cursor: "auto", - cursorAt: false, - grid: false, - handle: false, - helper: "original", - iframeFix: false, - opacity: false, - refreshPositions: false, - revert: false, - revertDuration: 500, - scope: "default", - scroll: true, - scrollSensitivity: 20, - scrollSpeed: 20, - snap: false, - snapMode: "both", - snapTolerance: 20, - stack: false, - zIndex: false, - - // Callbacks - drag: null, - start: null, - stop: null - }, - _create: function() { - - if ( this.options.helper === "original" ) { - this._setPositionRelative(); - } - if ( this.options.addClasses ) { - this._addClass( "ui-draggable" ); - } - this._setHandleClassName(); - - this._mouseInit(); - }, - - _setOption: function( key, value ) { - this._super( key, value ); - if ( key === "handle" ) { - this._removeHandleClassName(); - this._setHandleClassName(); - } - }, - - _destroy: function() { - if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) { - this.destroyOnClear = true; - return; - } - this._removeHandleClassName(); - this._mouseDestroy(); - }, - - _mouseCapture: function( event ) { - var o = this.options; - - // Among others, prevent a drag on a resizable-handle - if ( this.helper || o.disabled || - $( event.target ).closest( ".ui-resizable-handle" ).length > 0 ) { - return false; - } - - //Quit if we're not on a valid handle - this.handle = this._getHandle( event ); - if ( !this.handle ) { - return false; - } - - this._blurActiveElement( event ); - - this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix ); - - return true; - - }, - - _blockFrames: function( selector ) { - this.iframeBlocks = this.document.find( selector ).map( function() { - var iframe = $( this ); - - return $( "<div>" ) - .css( "position", "absolute" ) - .appendTo( iframe.parent() ) - .outerWidth( iframe.outerWidth() ) - .outerHeight( iframe.outerHeight() ) - .offset( iframe.offset() )[ 0 ]; - } ); - }, - - _unblockFrames: function() { - if ( this.iframeBlocks ) { - this.iframeBlocks.remove(); - delete this.iframeBlocks; - } - }, - - _blurActiveElement: function( event ) { - var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ), - target = $( event.target ); - - // Don't blur if the event occurred on an element that is within - // the currently focused element - // See #10527, #12472 - if ( target.closest( activeElement ).length ) { - return; - } - - // Blur any element that currently has focus, see #4261 - $.ui.safeBlur( activeElement ); - }, - - _mouseStart: function( event ) { - - var o = this.options; - - //Create and append the visible helper - this.helper = this._createHelper( event ); - - this._addClass( this.helper, "ui-draggable-dragging" ); - - //Cache the helper size - this._cacheHelperProportions(); - - //If ddmanager is used for droppables, set the global draggable - if ( $.ui.ddmanager ) { - $.ui.ddmanager.current = this; - } - - /* - * - Position generation - - * This block generates everything position related - it's the core of draggables. - */ - - //Cache the margins of the original element - this._cacheMargins(); - - //Store the helper's css position - this.cssPosition = this.helper.css( "position" ); - this.scrollParent = this.helper.scrollParent( true ); - this.offsetParent = this.helper.offsetParent(); - this.hasFixedAncestor = this.helper.parents().filter( function() { - return $( this ).css( "position" ) === "fixed"; - } ).length > 0; - - //The element's absolute position on the page minus margins - this.positionAbs = this.element.offset(); - this._refreshOffsets( event ); - - //Generate the original position - this.originalPosition = this.position = this._generatePosition( event, false ); - this.originalPageX = event.pageX; - this.originalPageY = event.pageY; - - //Adjust the mouse offset relative to the helper if "cursorAt" is supplied - if ( o.cursorAt ) { - this._adjustOffsetFromHelper( o.cursorAt ); - } - - //Set a containment if given in the options - this._setContainment(); - - //Trigger event + callbacks - if ( this._trigger( "start", event ) === false ) { - this._clear(); - return false; - } - - //Recache the helper size - this._cacheHelperProportions(); - - //Prepare the droppable offsets - if ( $.ui.ddmanager && !o.dropBehaviour ) { - $.ui.ddmanager.prepareOffsets( this, event ); - } - - // Execute the drag once - this causes the helper not to be visible before getting its - // correct position - this._mouseDrag( event, true ); - - // If the ddmanager is used for droppables, inform the manager that dragging has started - // (see #5003) - if ( $.ui.ddmanager ) { - $.ui.ddmanager.dragStart( this, event ); - } - - return true; - }, - - _refreshOffsets: function( event ) { - this.offset = { - top: this.positionAbs.top - this.margins.top, - left: this.positionAbs.left - this.margins.left, - scroll: false, - parent: this._getParentOffset(), - relative: this._getRelativeOffset() - }; - - this.offset.click = { - left: event.pageX - this.offset.left, - top: event.pageY - this.offset.top - }; - }, - - _mouseDrag: function( event, noPropagation ) { - - // reset any necessary cached properties (see #5009) - if ( this.hasFixedAncestor ) { - this.offset.parent = this._getParentOffset(); - } - - //Compute the helpers position - this.position = this._generatePosition( event, true ); - this.positionAbs = this._convertPositionTo( "absolute" ); - - //Call plugins and callbacks and use the resulting position if something is returned - if ( !noPropagation ) { - var ui = this._uiHash(); - if ( this._trigger( "drag", event, ui ) === false ) { - this._mouseUp( new $.Event( "mouseup", event ) ); - return false; - } - this.position = ui.position; - } - - this.helper[ 0 ].style.left = this.position.left + "px"; - this.helper[ 0 ].style.top = this.position.top + "px"; - - if ( $.ui.ddmanager ) { - $.ui.ddmanager.drag( this, event ); - } - - return false; - }, - - _mouseStop: function( event ) { - - //If we are using droppables, inform the manager about the drop - var that = this, - dropped = false; - if ( $.ui.ddmanager && !this.options.dropBehaviour ) { - dropped = $.ui.ddmanager.drop( this, event ); - } - - //if a drop comes from outside (a sortable) - if ( this.dropped ) { - dropped = this.dropped; - this.dropped = false; - } - - if ( ( this.options.revert === "invalid" && !dropped ) || - ( this.options.revert === "valid" && dropped ) || - this.options.revert === true || ( typeof this.options.revert === "function" && - this.options.revert.call( this.element, dropped ) ) - ) { - $( this.helper ).animate( - this.originalPosition, - parseInt( this.options.revertDuration, 10 ), - function() { - if ( that._trigger( "stop", event ) !== false ) { - that._clear(); - } - } - ); - } else { - if ( this._trigger( "stop", event ) !== false ) { - this._clear(); - } - } - - return false; - }, - - _mouseUp: function( event ) { - this._unblockFrames(); - - // If the ddmanager is used for droppables, inform the manager that dragging has stopped - // (see #5003) - if ( $.ui.ddmanager ) { - $.ui.ddmanager.dragStop( this, event ); - } - - // Only need to focus if the event occurred on the draggable itself, see #10527 - if ( this.handleElement.is( event.target ) ) { - - // The interaction is over; whether or not the click resulted in a drag, - // focus the element - this.element.trigger( "focus" ); - } - - return $.ui.mouse.prototype._mouseUp.call( this, event ); - }, - - cancel: function() { - - if ( this.helper.is( ".ui-draggable-dragging" ) ) { - this._mouseUp( new $.Event( "mouseup", { target: this.element[ 0 ] } ) ); - } else { - this._clear(); - } - - return this; - - }, - - _getHandle: function( event ) { - return this.options.handle ? - !!$( event.target ).closest( this.element.find( this.options.handle ) ).length : - true; - }, - - _setHandleClassName: function() { - this.handleElement = this.options.handle ? - this.element.find( this.options.handle ) : this.element; - this._addClass( this.handleElement, "ui-draggable-handle" ); - }, - - _removeHandleClassName: function() { - this._removeClass( this.handleElement, "ui-draggable-handle" ); - }, - - _createHelper: function( event ) { - - var o = this.options, - helperIsFunction = typeof o.helper === "function", - helper = helperIsFunction ? - $( o.helper.apply( this.element[ 0 ], [ event ] ) ) : - ( o.helper === "clone" ? - this.element.clone().removeAttr( "id" ) : - this.element ); - - if ( !helper.parents( "body" ).length ) { - helper.appendTo( ( o.appendTo === "parent" ? - this.element[ 0 ].parentNode : - o.appendTo ) ); - } - - // Http://bugs.jqueryui.com/ticket/9446 - // a helper function can return the original element - // which wouldn't have been set to relative in _create - if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) { - this._setPositionRelative(); - } - - if ( helper[ 0 ] !== this.element[ 0 ] && - !( /(fixed|absolute)/ ).test( helper.css( "position" ) ) ) { - helper.css( "position", "absolute" ); - } - - return helper; - - }, - - _setPositionRelative: function() { - if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) { - this.element[ 0 ].style.position = "relative"; - } - }, - - _adjustOffsetFromHelper: function( obj ) { - if ( typeof obj === "string" ) { - obj = obj.split( " " ); - } - if ( Array.isArray( obj ) ) { - obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 }; - } - if ( "left" in obj ) { - this.offset.click.left = obj.left + this.margins.left; - } - if ( "right" in obj ) { - this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; - } - if ( "top" in obj ) { - this.offset.click.top = obj.top + this.margins.top; - } - if ( "bottom" in obj ) { - this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; - } - }, - - _isRootNode: function( element ) { - return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ]; - }, - - _getParentOffset: function() { - - //Get the offsetParent and cache its position - var po = this.offsetParent.offset(), - document = this.document[ 0 ]; - - // This is a special case where we need to modify a offset calculated on start, since the - // following happened: - // 1. The position of the helper is absolute, so it's position is calculated based on the - // next positioned parent - // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't - // the document, which means that the scroll is included in the initial calculation of the - // offset of the parent, and never recalculated upon drag - if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== document && - $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) { - po.left += this.scrollParent.scrollLeft(); - po.top += this.scrollParent.scrollTop(); - } - - if ( this._isRootNode( this.offsetParent[ 0 ] ) ) { - po = { top: 0, left: 0 }; - } - - return { - top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ), - left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 ) - }; - - }, - - _getRelativeOffset: function() { - if ( this.cssPosition !== "relative" ) { - return { top: 0, left: 0 }; - } - - var p = this.element.position(), - scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ); - - return { - top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) + - ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ), - left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) + - ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 ) - }; - - }, - - _cacheMargins: function() { - this.margins = { - left: ( parseInt( this.element.css( "marginLeft" ), 10 ) || 0 ), - top: ( parseInt( this.element.css( "marginTop" ), 10 ) || 0 ), - right: ( parseInt( this.element.css( "marginRight" ), 10 ) || 0 ), - bottom: ( parseInt( this.element.css( "marginBottom" ), 10 ) || 0 ) - }; - }, - - _cacheHelperProportions: function() { - this.helperProportions = { - width: this.helper.outerWidth(), - height: this.helper.outerHeight() - }; - }, - - _setContainment: function() { - - var isUserScrollable, c, ce, - o = this.options, - document = this.document[ 0 ]; - - this.relativeContainer = null; - - if ( !o.containment ) { - this.containment = null; - return; - } - - if ( o.containment === "window" ) { - this.containment = [ - $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left, - $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top, - $( window ).scrollLeft() + $( window ).width() - - this.helperProportions.width - this.margins.left, - $( window ).scrollTop() + - ( $( window ).height() || document.body.parentNode.scrollHeight ) - - this.helperProportions.height - this.margins.top - ]; - return; - } - - if ( o.containment === "document" ) { - this.containment = [ - 0, - 0, - $( document ).width() - this.helperProportions.width - this.margins.left, - ( $( document ).height() || document.body.parentNode.scrollHeight ) - - this.helperProportions.height - this.margins.top - ]; - return; - } - - if ( o.containment.constructor === Array ) { - this.containment = o.containment; - return; - } - - if ( o.containment === "parent" ) { - o.containment = this.helper[ 0 ].parentNode; - } - - c = $( o.containment ); - ce = c[ 0 ]; - - if ( !ce ) { - return; - } - - isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) ); - - this.containment = [ - ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + - ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ), - ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + - ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ), - ( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - - ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) - - ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) - - this.helperProportions.width - - this.margins.left - - this.margins.right, - ( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - - ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) - - ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) - - this.helperProportions.height - - this.margins.top - - this.margins.bottom - ]; - this.relativeContainer = c; - }, - - _convertPositionTo: function( d, pos ) { - - if ( !pos ) { - pos = this.position; - } - - var mod = d === "absolute" ? 1 : -1, - scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ); - - return { - top: ( - - // The absolute mouse position - pos.top + - - // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.relative.top * mod + - - // The offsetParent's offset without borders (offset + border) - this.offset.parent.top * mod - - ( ( this.cssPosition === "fixed" ? - -this.offset.scroll.top : - ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod ) - ), - left: ( - - // The absolute mouse position - pos.left + - - // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.relative.left * mod + - - // The offsetParent's offset without borders (offset + border) - this.offset.parent.left * mod - - ( ( this.cssPosition === "fixed" ? - -this.offset.scroll.left : - ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod ) - ) - }; - - }, - - _generatePosition: function( event, constrainPosition ) { - - var containment, co, top, left, - o = this.options, - scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ), - pageX = event.pageX, - pageY = event.pageY; - - // Cache the scroll - if ( !scrollIsRootNode || !this.offset.scroll ) { - this.offset.scroll = { - top: this.scrollParent.scrollTop(), - left: this.scrollParent.scrollLeft() - }; - } - - /* - * - Position constraining - - * Constrain the position to a mix of grid, containment. - */ - - // If we are not dragging yet, we won't check for options - if ( constrainPosition ) { - if ( this.containment ) { - if ( this.relativeContainer ) { - co = this.relativeContainer.offset(); - containment = [ - this.containment[ 0 ] + co.left, - this.containment[ 1 ] + co.top, - this.containment[ 2 ] + co.left, - this.containment[ 3 ] + co.top - ]; - } else { - containment = this.containment; - } - - if ( event.pageX - this.offset.click.left < containment[ 0 ] ) { - pageX = containment[ 0 ] + this.offset.click.left; - } - if ( event.pageY - this.offset.click.top < containment[ 1 ] ) { - pageY = containment[ 1 ] + this.offset.click.top; - } - if ( event.pageX - this.offset.click.left > containment[ 2 ] ) { - pageX = containment[ 2 ] + this.offset.click.left; - } - if ( event.pageY - this.offset.click.top > containment[ 3 ] ) { - pageY = containment[ 3 ] + this.offset.click.top; - } - } - - if ( o.grid ) { - - //Check for grid elements set to 0 to prevent divide by 0 error causing invalid - // argument errors in IE (see ticket #6950) - top = o.grid[ 1 ] ? this.originalPageY + Math.round( ( pageY - - this.originalPageY ) / o.grid[ 1 ] ) * o.grid[ 1 ] : this.originalPageY; - pageY = containment ? ( ( top - this.offset.click.top >= containment[ 1 ] || - top - this.offset.click.top > containment[ 3 ] ) ? - top : - ( ( top - this.offset.click.top >= containment[ 1 ] ) ? - top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : top; - - left = o.grid[ 0 ] ? this.originalPageX + - Math.round( ( pageX - this.originalPageX ) / o.grid[ 0 ] ) * o.grid[ 0 ] : - this.originalPageX; - pageX = containment ? ( ( left - this.offset.click.left >= containment[ 0 ] || - left - this.offset.click.left > containment[ 2 ] ) ? - left : - ( ( left - this.offset.click.left >= containment[ 0 ] ) ? - left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : left; - } - - if ( o.axis === "y" ) { - pageX = this.originalPageX; - } - - if ( o.axis === "x" ) { - pageY = this.originalPageY; - } - } - - return { - top: ( - - // The absolute mouse position - pageY - - - // Click offset (relative to the element) - this.offset.click.top - - - // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.relative.top - - - // The offsetParent's offset without borders (offset + border) - this.offset.parent.top + - ( this.cssPosition === "fixed" ? - -this.offset.scroll.top : - ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) - ), - left: ( - - // The absolute mouse position - pageX - - - // Click offset (relative to the element) - this.offset.click.left - - - // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.relative.left - - - // The offsetParent's offset without borders (offset + border) - this.offset.parent.left + - ( this.cssPosition === "fixed" ? - -this.offset.scroll.left : - ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) - ) - }; - - }, - - _clear: function() { - this._removeClass( this.helper, "ui-draggable-dragging" ); - if ( this.helper[ 0 ] !== this.element[ 0 ] && !this.cancelHelperRemoval ) { - this.helper.remove(); - } - this.helper = null; - this.cancelHelperRemoval = false; - if ( this.destroyOnClear ) { - this.destroy(); - } - }, - - // From now on bulk stuff - mainly helpers - - _trigger: function( type, event, ui ) { - ui = ui || this._uiHash(); - $.ui.plugin.call( this, type, [ event, ui, this ], true ); - - // Absolute position and offset (see #6884 ) have to be recalculated after plugins - if ( /^(drag|start|stop)/.test( type ) ) { - this.positionAbs = this._convertPositionTo( "absolute" ); - ui.offset = this.positionAbs; - } - return $.Widget.prototype._trigger.call( this, type, event, ui ); - }, - - plugins: {}, - - _uiHash: function() { - return { - helper: this.helper, - position: this.position, - originalPosition: this.originalPosition, - offset: this.positionAbs - }; - } - -} ); - -$.ui.plugin.add( "draggable", "connectToSortable", { - start: function( event, ui, draggable ) { - var uiSortable = $.extend( {}, ui, { - item: draggable.element - } ); - - draggable.sortables = []; - $( draggable.options.connectToSortable ).each( function() { - var sortable = $( this ).sortable( "instance" ); - - if ( sortable && !sortable.options.disabled ) { - draggable.sortables.push( sortable ); - - // RefreshPositions is called at drag start to refresh the containerCache - // which is used in drag. This ensures it's initialized and synchronized - // with any changes that might have happened on the page since initialization. - sortable.refreshPositions(); - sortable._trigger( "activate", event, uiSortable ); - } - } ); - }, - stop: function( event, ui, draggable ) { - var uiSortable = $.extend( {}, ui, { - item: draggable.element - } ); - - draggable.cancelHelperRemoval = false; - - $.each( draggable.sortables, function() { - var sortable = this; - - if ( sortable.isOver ) { - sortable.isOver = 0; - - // Allow this sortable to handle removing the helper - draggable.cancelHelperRemoval = true; - sortable.cancelHelperRemoval = false; - - // Use _storedCSS To restore properties in the sortable, - // as this also handles revert (#9675) since the draggable - // may have modified them in unexpected ways (#8809) - sortable._storedCSS = { - position: sortable.placeholder.css( "position" ), - top: sortable.placeholder.css( "top" ), - left: sortable.placeholder.css( "left" ) - }; - - sortable._mouseStop( event ); - - // Once drag has ended, the sortable should return to using - // its original helper, not the shared helper from draggable - sortable.options.helper = sortable.options._helper; - } else { - - // Prevent this Sortable from removing the helper. - // However, don't set the draggable to remove the helper - // either as another connected Sortable may yet handle the removal. - sortable.cancelHelperRemoval = true; - - sortable._trigger( "deactivate", event, uiSortable ); - } - } ); - }, - drag: function( event, ui, draggable ) { - $.each( draggable.sortables, function() { - var innermostIntersecting = false, - sortable = this; - - // Copy over variables that sortable's _intersectsWith uses - sortable.positionAbs = draggable.positionAbs; - sortable.helperProportions = draggable.helperProportions; - sortable.offset.click = draggable.offset.click; - - if ( sortable._intersectsWith( sortable.containerCache ) ) { - innermostIntersecting = true; - - $.each( draggable.sortables, function() { - - // Copy over variables that sortable's _intersectsWith uses - this.positionAbs = draggable.positionAbs; - this.helperProportions = draggable.helperProportions; - this.offset.click = draggable.offset.click; - - if ( this !== sortable && - this._intersectsWith( this.containerCache ) && - $.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) { - innermostIntersecting = false; - } - - return innermostIntersecting; - } ); - } - - if ( innermostIntersecting ) { - - // If it intersects, we use a little isOver variable and set it once, - // so that the move-in stuff gets fired only once. - if ( !sortable.isOver ) { - sortable.isOver = 1; - - // Store draggable's parent in case we need to reappend to it later. - draggable._parent = ui.helper.parent(); - - sortable.currentItem = ui.helper - .appendTo( sortable.element ) - .data( "ui-sortable-item", true ); - - // Store helper option to later restore it - sortable.options._helper = sortable.options.helper; - - sortable.options.helper = function() { - return ui.helper[ 0 ]; - }; - - // Fire the start events of the sortable with our passed browser event, - // and our own helper (so it doesn't create a new one) - event.target = sortable.currentItem[ 0 ]; - sortable._mouseCapture( event, true ); - sortable._mouseStart( event, true, true ); - - // Because the browser event is way off the new appended portlet, - // modify necessary variables to reflect the changes - sortable.offset.click.top = draggable.offset.click.top; - sortable.offset.click.left = draggable.offset.click.left; - sortable.offset.parent.left -= draggable.offset.parent.left - - sortable.offset.parent.left; - sortable.offset.parent.top -= draggable.offset.parent.top - - sortable.offset.parent.top; - - draggable._trigger( "toSortable", event ); - - // Inform draggable that the helper is in a valid drop zone, - // used solely in the revert option to handle "valid/invalid". - draggable.dropped = sortable.element; - - // Need to refreshPositions of all sortables in the case that - // adding to one sortable changes the location of the other sortables (#9675) - $.each( draggable.sortables, function() { - this.refreshPositions(); - } ); - - // Hack so receive/update callbacks work (mostly) - draggable.currentItem = draggable.element; - sortable.fromOutside = draggable; - } - - if ( sortable.currentItem ) { - sortable._mouseDrag( event ); - - // Copy the sortable's position because the draggable's can potentially reflect - // a relative position, while sortable is always absolute, which the dragged - // element has now become. (#8809) - ui.position = sortable.position; - } - } else { - - // If it doesn't intersect with the sortable, and it intersected before, - // we fake the drag stop of the sortable, but make sure it doesn't remove - // the helper by using cancelHelperRemoval. - if ( sortable.isOver ) { - - sortable.isOver = 0; - sortable.cancelHelperRemoval = true; - - // Calling sortable's mouseStop would trigger a revert, - // so revert must be temporarily false until after mouseStop is called. - sortable.options._revert = sortable.options.revert; - sortable.options.revert = false; - - sortable._trigger( "out", event, sortable._uiHash( sortable ) ); - sortable._mouseStop( event, true ); - - // Restore sortable behaviors that were modfied - // when the draggable entered the sortable area (#9481) - sortable.options.revert = sortable.options._revert; - sortable.options.helper = sortable.options._helper; - - if ( sortable.placeholder ) { - sortable.placeholder.remove(); - } - - // Restore and recalculate the draggable's offset considering the sortable - // may have modified them in unexpected ways. (#8809, #10669) - ui.helper.appendTo( draggable._parent ); - draggable._refreshOffsets( event ); - ui.position = draggable._generatePosition( event, true ); - - draggable._trigger( "fromSortable", event ); - - // Inform draggable that the helper is no longer in a valid drop zone - draggable.dropped = false; - - // Need to refreshPositions of all sortables just in case removing - // from one sortable changes the location of other sortables (#9675) - $.each( draggable.sortables, function() { - this.refreshPositions(); - } ); - } - } - } ); - } -} ); - -$.ui.plugin.add( "draggable", "cursor", { - start: function( event, ui, instance ) { - var t = $( "body" ), - o = instance.options; - - if ( t.css( "cursor" ) ) { - o._cursor = t.css( "cursor" ); - } - t.css( "cursor", o.cursor ); - }, - stop: function( event, ui, instance ) { - var o = instance.options; - if ( o._cursor ) { - $( "body" ).css( "cursor", o._cursor ); - } - } -} ); - -$.ui.plugin.add( "draggable", "opacity", { - start: function( event, ui, instance ) { - var t = $( ui.helper ), - o = instance.options; - if ( t.css( "opacity" ) ) { - o._opacity = t.css( "opacity" ); - } - t.css( "opacity", o.opacity ); - }, - stop: function( event, ui, instance ) { - var o = instance.options; - if ( o._opacity ) { - $( ui.helper ).css( "opacity", o._opacity ); - } - } -} ); - -$.ui.plugin.add( "draggable", "scroll", { - start: function( event, ui, i ) { - if ( !i.scrollParentNotHidden ) { - i.scrollParentNotHidden = i.helper.scrollParent( false ); - } - - if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && - i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) { - i.overflowOffset = i.scrollParentNotHidden.offset(); - } - }, - drag: function( event, ui, i ) { - - var o = i.options, - scrolled = false, - scrollParent = i.scrollParentNotHidden[ 0 ], - document = i.document[ 0 ]; - - if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) { - if ( !o.axis || o.axis !== "x" ) { - if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < - o.scrollSensitivity ) { - scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed; - } else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) { - scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed; - } - } - - if ( !o.axis || o.axis !== "y" ) { - if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < - o.scrollSensitivity ) { - scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed; - } else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) { - scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed; - } - } - - } else { - - if ( !o.axis || o.axis !== "x" ) { - if ( event.pageY - $( document ).scrollTop() < o.scrollSensitivity ) { - scrolled = $( document ).scrollTop( $( document ).scrollTop() - o.scrollSpeed ); - } else if ( $( window ).height() - ( event.pageY - $( document ).scrollTop() ) < - o.scrollSensitivity ) { - scrolled = $( document ).scrollTop( $( document ).scrollTop() + o.scrollSpeed ); - } - } - - if ( !o.axis || o.axis !== "y" ) { - if ( event.pageX - $( document ).scrollLeft() < o.scrollSensitivity ) { - scrolled = $( document ).scrollLeft( - $( document ).scrollLeft() - o.scrollSpeed - ); - } else if ( $( window ).width() - ( event.pageX - $( document ).scrollLeft() ) < - o.scrollSensitivity ) { - scrolled = $( document ).scrollLeft( - $( document ).scrollLeft() + o.scrollSpeed - ); - } - } - - } - - if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) { - $.ui.ddmanager.prepareOffsets( i, event ); - } - - } -} ); - -$.ui.plugin.add( "draggable", "snap", { - start: function( event, ui, i ) { - - var o = i.options; - - i.snapElements = []; - - $( o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap ) - .each( function() { - var $t = $( this ), - $o = $t.offset(); - if ( this !== i.element[ 0 ] ) { - i.snapElements.push( { - item: this, - width: $t.outerWidth(), height: $t.outerHeight(), - top: $o.top, left: $o.left - } ); - } - } ); - - }, - drag: function( event, ui, inst ) { - - var ts, bs, ls, rs, l, r, t, b, i, first, - o = inst.options, - d = o.snapTolerance, - x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width, - y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height; - - for ( i = inst.snapElements.length - 1; i >= 0; i-- ) { - - l = inst.snapElements[ i ].left - inst.margins.left; - r = l + inst.snapElements[ i ].width; - t = inst.snapElements[ i ].top - inst.margins.top; - b = t + inst.snapElements[ i ].height; - - if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || - !$.contains( inst.snapElements[ i ].item.ownerDocument, - inst.snapElements[ i ].item ) ) { - if ( inst.snapElements[ i ].snapping ) { - if ( inst.options.snap.release ) { - inst.options.snap.release.call( - inst.element, - event, - $.extend( inst._uiHash(), { snapItem: inst.snapElements[ i ].item } ) - ); - } - } - inst.snapElements[ i ].snapping = false; - continue; - } - - if ( o.snapMode !== "inner" ) { - ts = Math.abs( t - y2 ) <= d; - bs = Math.abs( b - y1 ) <= d; - ls = Math.abs( l - x2 ) <= d; - rs = Math.abs( r - x1 ) <= d; - if ( ts ) { - ui.position.top = inst._convertPositionTo( "relative", { - top: t - inst.helperProportions.height, - left: 0 - } ).top; - } - if ( bs ) { - ui.position.top = inst._convertPositionTo( "relative", { - top: b, - left: 0 - } ).top; - } - if ( ls ) { - ui.position.left = inst._convertPositionTo( "relative", { - top: 0, - left: l - inst.helperProportions.width - } ).left; - } - if ( rs ) { - ui.position.left = inst._convertPositionTo( "relative", { - top: 0, - left: r - } ).left; - } - } - - first = ( ts || bs || ls || rs ); - - if ( o.snapMode !== "outer" ) { - ts = Math.abs( t - y1 ) <= d; - bs = Math.abs( b - y2 ) <= d; - ls = Math.abs( l - x1 ) <= d; - rs = Math.abs( r - x2 ) <= d; - if ( ts ) { - ui.position.top = inst._convertPositionTo( "relative", { - top: t, - left: 0 - } ).top; - } - if ( bs ) { - ui.position.top = inst._convertPositionTo( "relative", { - top: b - inst.helperProportions.height, - left: 0 - } ).top; - } - if ( ls ) { - ui.position.left = inst._convertPositionTo( "relative", { - top: 0, - left: l - } ).left; - } - if ( rs ) { - ui.position.left = inst._convertPositionTo( "relative", { - top: 0, - left: r - inst.helperProportions.width - } ).left; - } - } - - if ( !inst.snapElements[ i ].snapping && ( ts || bs || ls || rs || first ) ) { - if ( inst.options.snap.snap ) { - inst.options.snap.snap.call( - inst.element, - event, - $.extend( inst._uiHash(), { - snapItem: inst.snapElements[ i ].item - } ) ); - } - } - inst.snapElements[ i ].snapping = ( ts || bs || ls || rs || first ); - - } - - } -} ); - -$.ui.plugin.add( "draggable", "stack", { - start: function( event, ui, instance ) { - var min, - o = instance.options, - group = $.makeArray( $( o.stack ) ).sort( function( a, b ) { - return ( parseInt( $( a ).css( "zIndex" ), 10 ) || 0 ) - - ( parseInt( $( b ).css( "zIndex" ), 10 ) || 0 ); - } ); - - if ( !group.length ) { - return; - } - - min = parseInt( $( group[ 0 ] ).css( "zIndex" ), 10 ) || 0; - $( group ).each( function( i ) { - $( this ).css( "zIndex", min + i ); - } ); - this.css( "zIndex", ( min + group.length ) ); - } -} ); - -$.ui.plugin.add( "draggable", "zIndex", { - start: function( event, ui, instance ) { - var t = $( ui.helper ), - o = instance.options; - - if ( t.css( "zIndex" ) ) { - o._zIndex = t.css( "zIndex" ); - } - t.css( "zIndex", o.zIndex ); - }, - stop: function( event, ui, instance ) { - var o = instance.options; - - if ( o._zIndex ) { - $( ui.helper ).css( "zIndex", o._zIndex ); - } - } -} ); - -return $.ui.draggable; + "use strict"; + + $.widget( "ui.draggable", $.ui.mouse, { + version: "1.13.2", + widgetEventPrefix: "drag", + options: { + addClasses: true, + appendTo: "parent", + axis: false, + connectToSortable: false, + containment: false, + cursor: "auto", + cursorAt: false, + grid: false, + handle: false, + helper: "original", + iframeFix: false, + opacity: false, + refreshPositions: false, + revert: false, + revertDuration: 500, + scope: "default", + scroll: true, + scrollSensitivity: 20, + scrollSpeed: 20, + snap: false, + snapMode: "both", + snapTolerance: 20, + stack: false, + zIndex: false, + + // Callbacks + drag: null, + start: null, + stop: null + }, + _create: function() { + + if ( this.options.helper === "original" ) { + this._setPositionRelative(); + } + if ( this.options.addClasses ) { + this._addClass( "ui-draggable" ); + } + this._setHandleClassName(); + + this._mouseInit(); + }, + + _setOption: function( key, value ) { + this._super( key, value ); + if ( key === "handle" ) { + this._removeHandleClassName(); + this._setHandleClassName(); + } + }, + + _destroy: function() { + if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) { + this.destroyOnClear = true; + return; + } + this._removeHandleClassName(); + this._mouseDestroy(); + }, + + _mouseCapture: function( event ) { + var o = this.options; + + // Among others, prevent a drag on a resizable-handle + if ( this.helper || o.disabled || + $( event.target ).closest( ".ui-resizable-handle" ).length > 0 ) { + return false; + } + + //Quit if we're not on a valid handle + this.handle = this._getHandle( event ); + if ( !this.handle ) { + return false; + } + + this._blurActiveElement( event ); + + this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix ); + + return true; + + }, + + _blockFrames: function( selector ) { + this.iframeBlocks = this.document.find( selector ).map( function() { + var iframe = $( this ); + + return $( "<div>" ) + .css( "position", "absolute" ) + .appendTo( iframe.parent() ) + .outerWidth( iframe.outerWidth() ) + .outerHeight( iframe.outerHeight() ) + .offset( iframe.offset() )[ 0 ]; + } ); + }, + + _unblockFrames: function() { + if ( this.iframeBlocks ) { + this.iframeBlocks.remove(); + delete this.iframeBlocks; + } + }, + + _blurActiveElement: function( event ) { + var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ), + target = $( event.target ); + + // Don't blur if the event occurred on an element that is within + // the currently focused element + // See #10527, #12472 + if ( target.closest( activeElement ).length ) { + return; + } + + // Blur any element that currently has focus, see #4261 + $.ui.safeBlur( activeElement ); + }, + + _mouseStart: function( event ) { + + var o = this.options; + + //Create and append the visible helper + this.helper = this._createHelper( event ); + + this._addClass( this.helper, "ui-draggable-dragging" ); + + //Cache the helper size + this._cacheHelperProportions(); + + //If ddmanager is used for droppables, set the global draggable + if ( $.ui.ddmanager ) { + $.ui.ddmanager.current = this; + } + + /* + * - Position generation - + * This block generates everything position related - it's the core of draggables. + */ + + //Cache the margins of the original element + this._cacheMargins(); + + //Store the helper's css position + this.cssPosition = this.helper.css( "position" ); + this.scrollParent = this.helper.scrollParent( true ); + this.offsetParent = this.helper.offsetParent(); + this.hasFixedAncestor = this.helper.parents().filter( function() { + return $( this ).css( "position" ) === "fixed"; + } ).length > 0; + + //The element's absolute position on the page minus margins + this.positionAbs = this.element.offset(); + this._refreshOffsets( event ); + + //Generate the original position + this.originalPosition = this.position = this._generatePosition( event, false ); + this.originalPageX = event.pageX; + this.originalPageY = event.pageY; + + //Adjust the mouse offset relative to the helper if "cursorAt" is supplied + if ( o.cursorAt ) { + this._adjustOffsetFromHelper( o.cursorAt ); + } + + //Set a containment if given in the options + this._setContainment(); + + //Trigger event + callbacks + if ( this._trigger( "start", event ) === false ) { + this._clear(); + return false; + } + + //Recache the helper size + this._cacheHelperProportions(); + + //Prepare the droppable offsets + if ( $.ui.ddmanager && !o.dropBehaviour ) { + $.ui.ddmanager.prepareOffsets( this, event ); + } + + // Execute the drag once - this causes the helper not to be visible before getting its + // correct position + this._mouseDrag( event, true ); + + // If the ddmanager is used for droppables, inform the manager that dragging has started + // (see #5003) + if ( $.ui.ddmanager ) { + $.ui.ddmanager.dragStart( this, event ); + } + + return true; + }, + + _refreshOffsets: function( event ) { + this.offset = { + top: this.positionAbs.top - this.margins.top, + left: this.positionAbs.left - this.margins.left, + scroll: false, + parent: this._getParentOffset(), + relative: this._getRelativeOffset() + }; + + this.offset.click = { + left: event.pageX - this.offset.left, + top: event.pageY - this.offset.top + }; + }, + + _mouseDrag: function( event, noPropagation ) { + + // reset any necessary cached properties (see #5009) + if ( this.hasFixedAncestor ) { + this.offset.parent = this._getParentOffset(); + } + + //Compute the helpers position + this.position = this._generatePosition( event, true ); + this.positionAbs = this._convertPositionTo( "absolute" ); + + //Call plugins and callbacks and use the resulting position if something is returned + if ( !noPropagation ) { + var ui = this._uiHash(); + if ( this._trigger( "drag", event, ui ) === false ) { + this._mouseUp( new $.Event( "mouseup", event ) ); + return false; + } + this.position = ui.position; + } + + this.helper[ 0 ].style.left = this.position.left + "px"; + this.helper[ 0 ].style.top = this.position.top + "px"; + + if ( $.ui.ddmanager ) { + $.ui.ddmanager.drag( this, event ); + } + + return false; + }, + + _mouseStop: function( event ) { + + //If we are using droppables, inform the manager about the drop + var that = this, + dropped = false; + if ( $.ui.ddmanager && !this.options.dropBehaviour ) { + dropped = $.ui.ddmanager.drop( this, event ); + } + + //if a drop comes from outside (a sortable) + if ( this.dropped ) { + dropped = this.dropped; + this.dropped = false; + } + + if ( ( this.options.revert === "invalid" && !dropped ) || + ( this.options.revert === "valid" && dropped ) || + this.options.revert === true || ( typeof this.options.revert === "function" && + this.options.revert.call( this.element, dropped ) ) + ) { + $( this.helper ).animate( + this.originalPosition, + parseInt( this.options.revertDuration, 10 ), + function() { + if ( that._trigger( "stop", event ) !== false ) { + that._clear(); + } + } + ); + } else { + if ( this._trigger( "stop", event ) !== false ) { + this._clear(); + } + } + + return false; + }, + + _mouseUp: function( event ) { + this._unblockFrames(); + + // If the ddmanager is used for droppables, inform the manager that dragging has stopped + // (see #5003) + if ( $.ui.ddmanager ) { + $.ui.ddmanager.dragStop( this, event ); + } + + // Only need to focus if the event occurred on the draggable itself, see #10527 + if ( this.handleElement.is( event.target ) ) { + + // The interaction is over; whether or not the click resulted in a drag, + // focus the element + this.element.trigger( "focus" ); + } + + return $.ui.mouse.prototype._mouseUp.call( this, event ); + }, + + cancel: function() { + + if ( this.helper.is( ".ui-draggable-dragging" ) ) { + this._mouseUp( new $.Event( "mouseup", { target: this.element[ 0 ] } ) ); + } else { + this._clear(); + } + + return this; + + }, + + _getHandle: function( event ) { + return this.options.handle ? + !!$( event.target ).closest( this.element.find( this.options.handle ) ).length : + true; + }, + + _setHandleClassName: function() { + this.handleElement = this.options.handle ? + this.element.find( this.options.handle ) : this.element; + this._addClass( this.handleElement, "ui-draggable-handle" ); + }, + + _removeHandleClassName: function() { + this._removeClass( this.handleElement, "ui-draggable-handle" ); + }, + + _createHelper: function( event ) { + + var o = this.options, + helperIsFunction = typeof o.helper === "function", + helper = helperIsFunction ? + $( o.helper.apply( this.element[ 0 ], [ event ] ) ) : + ( o.helper === "clone" ? + this.element.clone().removeAttr( "id" ) : + this.element ); + + if ( !helper.parents( "body" ).length ) { + helper.appendTo( ( o.appendTo === "parent" ? + this.element[ 0 ].parentNode : + o.appendTo ) ); + } + + // Http://bugs.jqueryui.com/ticket/9446 + // a helper function can return the original element + // which wouldn't have been set to relative in _create + if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) { + this._setPositionRelative(); + } + + if ( helper[ 0 ] !== this.element[ 0 ] && + !( /(fixed|absolute)/ ).test( helper.css( "position" ) ) ) { + helper.css( "position", "absolute" ); + } + + return helper; + + }, + + _setPositionRelative: function() { + if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) { + this.element[ 0 ].style.position = "relative"; + } + }, + + _adjustOffsetFromHelper: function( obj ) { + if ( typeof obj === "string" ) { + obj = obj.split( " " ); + } + if ( Array.isArray( obj ) ) { + obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 }; + } + if ( "left" in obj ) { + this.offset.click.left = obj.left + this.margins.left; + } + if ( "right" in obj ) { + this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; + } + if ( "top" in obj ) { + this.offset.click.top = obj.top + this.margins.top; + } + if ( "bottom" in obj ) { + this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; + } + }, + + _isRootNode: function( element ) { + return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ]; + }, + + _getParentOffset: function() { + + //Get the offsetParent and cache its position + var po = this.offsetParent.offset(), + document = this.document[ 0 ]; + + // This is a special case where we need to modify a offset calculated on start, since the + // following happened: + // 1. The position of the helper is absolute, so it's position is calculated based on the + // next positioned parent + // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't + // the document, which means that the scroll is included in the initial calculation of the + // offset of the parent, and never recalculated upon drag + if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== document && + $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) { + po.left += this.scrollParent.scrollLeft(); + po.top += this.scrollParent.scrollTop(); + } + + if ( this._isRootNode( this.offsetParent[ 0 ] ) ) { + po = { top: 0, left: 0 }; + } + + return { + top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ), + left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 ) + }; + + }, + + _getRelativeOffset: function() { + if ( this.cssPosition !== "relative" ) { + return { top: 0, left: 0 }; + } + + var p = this.element.position(), + scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ); + + return { + top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) + + ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ), + left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) + + ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 ) + }; + + }, + + _cacheMargins: function() { + this.margins = { + left: ( parseInt( this.element.css( "marginLeft" ), 10 ) || 0 ), + top: ( parseInt( this.element.css( "marginTop" ), 10 ) || 0 ), + right: ( parseInt( this.element.css( "marginRight" ), 10 ) || 0 ), + bottom: ( parseInt( this.element.css( "marginBottom" ), 10 ) || 0 ) + }; + }, + + _cacheHelperProportions: function() { + this.helperProportions = { + width: this.helper.outerWidth(), + height: this.helper.outerHeight() + }; + }, + + _setContainment: function() { + + var isUserScrollable, c, ce, + o = this.options, + document = this.document[ 0 ]; + + this.relativeContainer = null; + + if ( !o.containment ) { + this.containment = null; + return; + } + + if ( o.containment === "window" ) { + this.containment = [ + $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left, + $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top, + $( window ).scrollLeft() + $( window ).width() - + this.helperProportions.width - this.margins.left, + $( window ).scrollTop() + + ( $( window ).height() || document.body.parentNode.scrollHeight ) - + this.helperProportions.height - this.margins.top + ]; + return; + } + + if ( o.containment === "document" ) { + this.containment = [ + 0, + 0, + $( document ).width() - this.helperProportions.width - this.margins.left, + ( $( document ).height() || document.body.parentNode.scrollHeight ) - + this.helperProportions.height - this.margins.top + ]; + return; + } + + if ( o.containment.constructor === Array ) { + this.containment = o.containment; + return; + } + + if ( o.containment === "parent" ) { + o.containment = this.helper[ 0 ].parentNode; + } + + c = $( o.containment ); + ce = c[ 0 ]; + + if ( !ce ) { + return; + } + + isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) ); + + this.containment = [ + ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ), + ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ), + ( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - + ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) - + ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) - + this.helperProportions.width - + this.margins.left - + this.margins.right, + ( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - + ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) - + ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) - + this.helperProportions.height - + this.margins.top - + this.margins.bottom + ]; + this.relativeContainer = c; + }, + + _convertPositionTo: function( d, pos ) { + + if ( !pos ) { + pos = this.position; + } + + var mod = d === "absolute" ? 1 : -1, + scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ); + + return { + top: ( + + // The absolute mouse position + pos.top + + + // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.relative.top * mod + + + // The offsetParent's offset without borders (offset + border) + this.offset.parent.top * mod - + ( ( this.cssPosition === "fixed" ? + -this.offset.scroll.top : + ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod ) + ), + left: ( + + // The absolute mouse position + pos.left + + + // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.relative.left * mod + + + // The offsetParent's offset without borders (offset + border) + this.offset.parent.left * mod - + ( ( this.cssPosition === "fixed" ? + -this.offset.scroll.left : + ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod ) + ) + }; + + }, + + _generatePosition: function( event, constrainPosition ) { + + var containment, co, top, left, + o = this.options, + scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ), + pageX = event.pageX, + pageY = event.pageY; + + // Cache the scroll + if ( !scrollIsRootNode || !this.offset.scroll ) { + this.offset.scroll = { + top: this.scrollParent.scrollTop(), + left: this.scrollParent.scrollLeft() + }; + } + + /* + * - Position constraining - + * Constrain the position to a mix of grid, containment. + */ + + // If we are not dragging yet, we won't check for options + if ( constrainPosition ) { + if ( this.containment ) { + if ( this.relativeContainer ) { + co = this.relativeContainer.offset(); + containment = [ + this.containment[ 0 ] + co.left, + this.containment[ 1 ] + co.top, + this.containment[ 2 ] + co.left, + this.containment[ 3 ] + co.top + ]; + } else { + containment = this.containment; + } + + if ( event.pageX - this.offset.click.left < containment[ 0 ] ) { + pageX = containment[ 0 ] + this.offset.click.left; + } + if ( event.pageY - this.offset.click.top < containment[ 1 ] ) { + pageY = containment[ 1 ] + this.offset.click.top; + } + if ( event.pageX - this.offset.click.left > containment[ 2 ] ) { + pageX = containment[ 2 ] + this.offset.click.left; + } + if ( event.pageY - this.offset.click.top > containment[ 3 ] ) { + pageY = containment[ 3 ] + this.offset.click.top; + } + } + + if ( o.grid ) { + + //Check for grid elements set to 0 to prevent divide by 0 error causing invalid + // argument errors in IE (see ticket #6950) + top = o.grid[ 1 ] ? this.originalPageY + Math.round( ( pageY - + this.originalPageY ) / o.grid[ 1 ] ) * o.grid[ 1 ] : this.originalPageY; + pageY = containment ? ( ( top - this.offset.click.top >= containment[ 1 ] || + top - this.offset.click.top > containment[ 3 ] ) ? + top : + ( ( top - this.offset.click.top >= containment[ 1 ] ) ? + top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : top; + + left = o.grid[ 0 ] ? this.originalPageX + + Math.round( ( pageX - this.originalPageX ) / o.grid[ 0 ] ) * o.grid[ 0 ] : + this.originalPageX; + pageX = containment ? ( ( left - this.offset.click.left >= containment[ 0 ] || + left - this.offset.click.left > containment[ 2 ] ) ? + left : + ( ( left - this.offset.click.left >= containment[ 0 ] ) ? + left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : left; + } + + if ( o.axis === "y" ) { + pageX = this.originalPageX; + } + + if ( o.axis === "x" ) { + pageY = this.originalPageY; + } + } + + return { + top: ( + + // The absolute mouse position + pageY - + + // Click offset (relative to the element) + this.offset.click.top - + + // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.relative.top - + + // The offsetParent's offset without borders (offset + border) + this.offset.parent.top + + ( this.cssPosition === "fixed" ? + -this.offset.scroll.top : + ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) + ), + left: ( + + // The absolute mouse position + pageX - + + // Click offset (relative to the element) + this.offset.click.left - + + // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.relative.left - + + // The offsetParent's offset without borders (offset + border) + this.offset.parent.left + + ( this.cssPosition === "fixed" ? + -this.offset.scroll.left : + ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) + ) + }; + + }, + + _clear: function() { + this._removeClass( this.helper, "ui-draggable-dragging" ); + if ( this.helper[ 0 ] !== this.element[ 0 ] && !this.cancelHelperRemoval ) { + this.helper.remove(); + } + this.helper = null; + this.cancelHelperRemoval = false; + if ( this.destroyOnClear ) { + this.destroy(); + } + }, + + // From now on bulk stuff - mainly helpers + + _trigger: function( type, event, ui ) { + ui = ui || this._uiHash(); + $.ui.plugin.call( this, type, [ event, ui, this ], true ); + + // Absolute position and offset (see #6884 ) have to be recalculated after plugins + if ( /^(drag|start|stop)/.test( type ) ) { + this.positionAbs = this._convertPositionTo( "absolute" ); + ui.offset = this.positionAbs; + } + return $.Widget.prototype._trigger.call( this, type, event, ui ); + }, + + plugins: {}, + + _uiHash: function() { + return { + helper: this.helper, + position: this.position, + originalPosition: this.originalPosition, + offset: this.positionAbs + }; + } + + } ); + + $.ui.plugin.add( "draggable", "connectToSortable", { + start: function( event, ui, draggable ) { + var uiSortable = $.extend( {}, ui, { + item: draggable.element + } ); + + draggable.sortables = []; + $( draggable.options.connectToSortable ).each( function() { + var sortable = $( this ).sortable( "instance" ); + + if ( sortable && !sortable.options.disabled ) { + draggable.sortables.push( sortable ); + + // RefreshPositions is called at drag start to refresh the containerCache + // which is used in drag. This ensures it's initialized and synchronized + // with any changes that might have happened on the page since initialization. + sortable.refreshPositions(); + sortable._trigger( "activate", event, uiSortable ); + } + } ); + }, + stop: function( event, ui, draggable ) { + var uiSortable = $.extend( {}, ui, { + item: draggable.element + } ); + + draggable.cancelHelperRemoval = false; + + $.each( draggable.sortables, function() { + var sortable = this; + + if ( sortable.isOver ) { + sortable.isOver = 0; + + // Allow this sortable to handle removing the helper + draggable.cancelHelperRemoval = true; + sortable.cancelHelperRemoval = false; + + // Use _storedCSS To restore properties in the sortable, + // as this also handles revert (#9675) since the draggable + // may have modified them in unexpected ways (#8809) + sortable._storedCSS = { + position: sortable.placeholder.css( "position" ), + top: sortable.placeholder.css( "top" ), + left: sortable.placeholder.css( "left" ) + }; + + sortable._mouseStop( event ); + + // Once drag has ended, the sortable should return to using + // its original helper, not the shared helper from draggable + sortable.options.helper = sortable.options._helper; + } else { + + // Prevent this Sortable from removing the helper. + // However, don't set the draggable to remove the helper + // either as another connected Sortable may yet handle the removal. + sortable.cancelHelperRemoval = true; + + sortable._trigger( "deactivate", event, uiSortable ); + } + } ); + }, + drag: function( event, ui, draggable ) { + $.each( draggable.sortables, function() { + var innermostIntersecting = false, + sortable = this; + + // Copy over variables that sortable's _intersectsWith uses + sortable.positionAbs = draggable.positionAbs; + sortable.helperProportions = draggable.helperProportions; + sortable.offset.click = draggable.offset.click; + + if ( sortable._intersectsWith( sortable.containerCache ) ) { + innermostIntersecting = true; + + $.each( draggable.sortables, function() { + + // Copy over variables that sortable's _intersectsWith uses + this.positionAbs = draggable.positionAbs; + this.helperProportions = draggable.helperProportions; + this.offset.click = draggable.offset.click; + + if ( this !== sortable && + this._intersectsWith( this.containerCache ) && + $.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) { + innermostIntersecting = false; + } + + return innermostIntersecting; + } ); + } + + if ( innermostIntersecting ) { + + // If it intersects, we use a little isOver variable and set it once, + // so that the move-in stuff gets fired only once. + if ( !sortable.isOver ) { + sortable.isOver = 1; + + // Store draggable's parent in case we need to reappend to it later. + draggable._parent = ui.helper.parent(); + + sortable.currentItem = ui.helper + .appendTo( sortable.element ) + .data( "ui-sortable-item", true ); + + // Store helper option to later restore it + sortable.options._helper = sortable.options.helper; + + sortable.options.helper = function() { + return ui.helper[ 0 ]; + }; + + // Fire the start events of the sortable with our passed browser event, + // and our own helper (so it doesn't create a new one) + event.target = sortable.currentItem[ 0 ]; + sortable._mouseCapture( event, true ); + sortable._mouseStart( event, true, true ); + + // Because the browser event is way off the new appended portlet, + // modify necessary variables to reflect the changes + sortable.offset.click.top = draggable.offset.click.top; + sortable.offset.click.left = draggable.offset.click.left; + sortable.offset.parent.left -= draggable.offset.parent.left - + sortable.offset.parent.left; + sortable.offset.parent.top -= draggable.offset.parent.top - + sortable.offset.parent.top; + + draggable._trigger( "toSortable", event ); + + // Inform draggable that the helper is in a valid drop zone, + // used solely in the revert option to handle "valid/invalid". + draggable.dropped = sortable.element; + + // Need to refreshPositions of all sortables in the case that + // adding to one sortable changes the location of the other sortables (#9675) + $.each( draggable.sortables, function() { + this.refreshPositions(); + } ); + + // Hack so receive/update callbacks work (mostly) + draggable.currentItem = draggable.element; + sortable.fromOutside = draggable; + } + + if ( sortable.currentItem ) { + sortable._mouseDrag( event ); + + // Copy the sortable's position because the draggable's can potentially reflect + // a relative position, while sortable is always absolute, which the dragged + // element has now become. (#8809) + ui.position = sortable.position; + } + } else { + + // If it doesn't intersect with the sortable, and it intersected before, + // we fake the drag stop of the sortable, but make sure it doesn't remove + // the helper by using cancelHelperRemoval. + if ( sortable.isOver ) { + + sortable.isOver = 0; + sortable.cancelHelperRemoval = true; + + // Calling sortable's mouseStop would trigger a revert, + // so revert must be temporarily false until after mouseStop is called. + sortable.options._revert = sortable.options.revert; + sortable.options.revert = false; + + sortable._trigger( "out", event, sortable._uiHash( sortable ) ); + sortable._mouseStop( event, true ); + + // Restore sortable behaviors that were modfied + // when the draggable entered the sortable area (#9481) + sortable.options.revert = sortable.options._revert; + sortable.options.helper = sortable.options._helper; + + if ( sortable.placeholder ) { + sortable.placeholder.remove(); + } + + // Restore and recalculate the draggable's offset considering the sortable + // may have modified them in unexpected ways. (#8809, #10669) + ui.helper.appendTo( draggable._parent ); + draggable._refreshOffsets( event ); + ui.position = draggable._generatePosition( event, true ); + + draggable._trigger( "fromSortable", event ); + + // Inform draggable that the helper is no longer in a valid drop zone + draggable.dropped = false; + + // Need to refreshPositions of all sortables just in case removing + // from one sortable changes the location of other sortables (#9675) + $.each( draggable.sortables, function() { + this.refreshPositions(); + } ); + } + } + } ); + } + } ); + + $.ui.plugin.add( "draggable", "cursor", { + start: function( event, ui, instance ) { + var t = $( "body" ), + o = instance.options; + + if ( t.css( "cursor" ) ) { + o._cursor = t.css( "cursor" ); + } + t.css( "cursor", o.cursor ); + }, + stop: function( event, ui, instance ) { + var o = instance.options; + if ( o._cursor ) { + $( "body" ).css( "cursor", o._cursor ); + } + } + } ); + + $.ui.plugin.add( "draggable", "opacity", { + start: function( event, ui, instance ) { + var t = $( ui.helper ), + o = instance.options; + if ( t.css( "opacity" ) ) { + o._opacity = t.css( "opacity" ); + } + t.css( "opacity", o.opacity ); + }, + stop: function( event, ui, instance ) { + var o = instance.options; + if ( o._opacity ) { + $( ui.helper ).css( "opacity", o._opacity ); + } + } + } ); + + $.ui.plugin.add( "draggable", "scroll", { + start: function( event, ui, i ) { + if ( !i.scrollParentNotHidden ) { + i.scrollParentNotHidden = i.helper.scrollParent( false ); + } + + if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && + i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) { + i.overflowOffset = i.scrollParentNotHidden.offset(); + } + }, + drag: function( event, ui, i ) { + + var o = i.options, + scrolled = false, + scrollParent = i.scrollParentNotHidden[ 0 ], + document = i.document[ 0 ]; + + if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) { + if ( !o.axis || o.axis !== "x" ) { + if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < + o.scrollSensitivity ) { + scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed; + } else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) { + scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed; + } + } + + if ( !o.axis || o.axis !== "y" ) { + if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < + o.scrollSensitivity ) { + scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed; + } else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) { + scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed; + } + } + + } else { + + if ( !o.axis || o.axis !== "x" ) { + if ( event.pageY - $( document ).scrollTop() < o.scrollSensitivity ) { + scrolled = $( document ).scrollTop( $( document ).scrollTop() - o.scrollSpeed ); + } else if ( $( window ).height() - ( event.pageY - $( document ).scrollTop() ) < + o.scrollSensitivity ) { + scrolled = $( document ).scrollTop( $( document ).scrollTop() + o.scrollSpeed ); + } + } + + if ( !o.axis || o.axis !== "y" ) { + if ( event.pageX - $( document ).scrollLeft() < o.scrollSensitivity ) { + scrolled = $( document ).scrollLeft( + $( document ).scrollLeft() - o.scrollSpeed + ); + } else if ( $( window ).width() - ( event.pageX - $( document ).scrollLeft() ) < + o.scrollSensitivity ) { + scrolled = $( document ).scrollLeft( + $( document ).scrollLeft() + o.scrollSpeed + ); + } + } + + } + + if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) { + $.ui.ddmanager.prepareOffsets( i, event ); + } + + } + } ); + + $.ui.plugin.add( "draggable", "snap", { + start: function( event, ui, i ) { + + var o = i.options; + + i.snapElements = []; + + $( o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap ) + .each( function() { + var $t = $( this ), + $o = $t.offset(); + if ( this !== i.element[ 0 ] ) { + i.snapElements.push( { + item: this, + width: $t.outerWidth(), height: $t.outerHeight(), + top: $o.top, left: $o.left + } ); + } + } ); + + }, + drag: function( event, ui, inst ) { + + var ts, bs, ls, rs, l, r, t, b, i, first, + o = inst.options, + d = o.snapTolerance, + x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width, + y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height; + + for ( i = inst.snapElements.length - 1; i >= 0; i-- ) { + + l = inst.snapElements[ i ].left - inst.margins.left; + r = l + inst.snapElements[ i ].width; + t = inst.snapElements[ i ].top - inst.margins.top; + b = t + inst.snapElements[ i ].height; + + if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || + !$.contains( inst.snapElements[ i ].item.ownerDocument, + inst.snapElements[ i ].item ) ) { + if ( inst.snapElements[ i ].snapping ) { + if ( inst.options.snap.release ) { + inst.options.snap.release.call( + inst.element, + event, + $.extend( inst._uiHash(), { snapItem: inst.snapElements[ i ].item } ) + ); + } + } + inst.snapElements[ i ].snapping = false; + continue; + } + + if ( o.snapMode !== "inner" ) { + ts = Math.abs( t - y2 ) <= d; + bs = Math.abs( b - y1 ) <= d; + ls = Math.abs( l - x2 ) <= d; + rs = Math.abs( r - x1 ) <= d; + if ( ts ) { + ui.position.top = inst._convertPositionTo( "relative", { + top: t - inst.helperProportions.height, + left: 0 + } ).top; + } + if ( bs ) { + ui.position.top = inst._convertPositionTo( "relative", { + top: b, + left: 0 + } ).top; + } + if ( ls ) { + ui.position.left = inst._convertPositionTo( "relative", { + top: 0, + left: l - inst.helperProportions.width + } ).left; + } + if ( rs ) { + ui.position.left = inst._convertPositionTo( "relative", { + top: 0, + left: r + } ).left; + } + } + + first = ( ts || bs || ls || rs ); + + if ( o.snapMode !== "outer" ) { + ts = Math.abs( t - y1 ) <= d; + bs = Math.abs( b - y2 ) <= d; + ls = Math.abs( l - x1 ) <= d; + rs = Math.abs( r - x2 ) <= d; + if ( ts ) { + ui.position.top = inst._convertPositionTo( "relative", { + top: t, + left: 0 + } ).top; + } + if ( bs ) { + ui.position.top = inst._convertPositionTo( "relative", { + top: b - inst.helperProportions.height, + left: 0 + } ).top; + } + if ( ls ) { + ui.position.left = inst._convertPositionTo( "relative", { + top: 0, + left: l + } ).left; + } + if ( rs ) { + ui.position.left = inst._convertPositionTo( "relative", { + top: 0, + left: r - inst.helperProportions.width + } ).left; + } + } + + if ( !inst.snapElements[ i ].snapping && ( ts || bs || ls || rs || first ) ) { + if ( inst.options.snap.snap ) { + inst.options.snap.snap.call( + inst.element, + event, + $.extend( inst._uiHash(), { + snapItem: inst.snapElements[ i ].item + } ) ); + } + } + inst.snapElements[ i ].snapping = ( ts || bs || ls || rs || first ); + + } + + } + } ); + + $.ui.plugin.add( "draggable", "stack", { + start: function( event, ui, instance ) { + var min, + o = instance.options, + group = $.makeArray( $( o.stack ) ).sort( function( a, b ) { + return ( parseInt( $( a ).css( "zIndex" ), 10 ) || 0 ) - + ( parseInt( $( b ).css( "zIndex" ), 10 ) || 0 ); + } ); + + if ( !group.length ) { + return; + } + + min = parseInt( $( group[ 0 ] ).css( "zIndex" ), 10 ) || 0; + $( group ).each( function( i ) { + $( this ).css( "zIndex", min + i ); + } ); + this.css( "zIndex", ( min + group.length ) ); + } + } ); + + $.ui.plugin.add( "draggable", "zIndex", { + start: function( event, ui, instance ) { + var t = $( ui.helper ), + o = instance.options; + + if ( t.css( "zIndex" ) ) { + o._zIndex = t.css( "zIndex" ); + } + t.css( "zIndex", o.zIndex ); + }, + stop: function( event, ui, instance ) { + var o = instance.options; + + if ( o._zIndex ) { + $( ui.helper ).css( "zIndex", o._zIndex ); + } + } + } ); + + return $.ui.draggable; } ); diff --git a/lib/web/jquery/ui-modules/widgets/droppable.js b/lib/web/jquery/ui-modules/widgets/droppable.js index e52c6d707ab62..12b635021b8a0 100644 --- a/lib/web/jquery/ui-modules/widgets/droppable.js +++ b/lib/web/jquery/ui-modules/widgets/droppable.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Droppable 1.13.1 + * jQuery UI Droppable 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -14,490 +14,490 @@ //>>demos: http://jqueryui.com/droppable/ ( function( factory ) { - "use strict"; - - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define( [ - "jquery", - "./draggable", - "./mouse", - "../version", - "../widget" - ], factory ); - } else { - - // Browser globals - factory( jQuery ); - } + "use strict"; + + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ + "jquery", + "./draggable", + "./mouse", + "../version", + "../widget" + ], factory ); + } else { + + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; - -$.widget( "ui.droppable", { - version: "1.13.1", - widgetEventPrefix: "drop", - options: { - accept: "*", - addClasses: true, - greedy: false, - scope: "default", - tolerance: "intersect", - - // Callbacks - activate: null, - deactivate: null, - drop: null, - out: null, - over: null - }, - _create: function() { - - var proportions, - o = this.options, - accept = o.accept; - - this.isover = false; - this.isout = true; - - this.accept = typeof accept === "function" ? accept : function( d ) { - return d.is( accept ); - }; - - this.proportions = function( /* valueToWrite */ ) { - if ( arguments.length ) { - - // Store the droppable's proportions - proportions = arguments[ 0 ]; - } else { - - // Retrieve or derive the droppable's proportions - return proportions ? - proportions : - proportions = { - width: this.element[ 0 ].offsetWidth, - height: this.element[ 0 ].offsetHeight - }; - } - }; - - this._addToManager( o.scope ); - - if ( o.addClasses ) { - this._addClass( "ui-droppable" ); - } - - }, - - _addToManager: function( scope ) { - - // Add the reference and positions to the manager - $.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || []; - $.ui.ddmanager.droppables[ scope ].push( this ); - }, - - _splice: function( drop ) { - var i = 0; - for ( ; i < drop.length; i++ ) { - if ( drop[ i ] === this ) { - drop.splice( i, 1 ); - } - } - }, - - _destroy: function() { - var drop = $.ui.ddmanager.droppables[ this.options.scope ]; - - this._splice( drop ); - }, - - _setOption: function( key, value ) { - - if ( key === "accept" ) { - this.accept = typeof value === "function" ? value : function( d ) { - return d.is( value ); - }; - } else if ( key === "scope" ) { - var drop = $.ui.ddmanager.droppables[ this.options.scope ]; - - this._splice( drop ); - this._addToManager( value ); - } - - this._super( key, value ); - }, - - _activate: function( event ) { - var draggable = $.ui.ddmanager.current; - - this._addActiveClass(); - if ( draggable ) { - this._trigger( "activate", event, this.ui( draggable ) ); - } - }, - - _deactivate: function( event ) { - var draggable = $.ui.ddmanager.current; - - this._removeActiveClass(); - if ( draggable ) { - this._trigger( "deactivate", event, this.ui( draggable ) ); - } - }, - - _over: function( event ) { - - var draggable = $.ui.ddmanager.current; - - // Bail if draggable and droppable are same element - if ( !draggable || ( draggable.currentItem || - draggable.element )[ 0 ] === this.element[ 0 ] ) { - return; - } - - if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || - draggable.element ) ) ) { - this._addHoverClass(); - this._trigger( "over", event, this.ui( draggable ) ); - } - - }, - - _out: function( event ) { - - var draggable = $.ui.ddmanager.current; - - // Bail if draggable and droppable are same element - if ( !draggable || ( draggable.currentItem || - draggable.element )[ 0 ] === this.element[ 0 ] ) { - return; - } - - if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || - draggable.element ) ) ) { - this._removeHoverClass(); - this._trigger( "out", event, this.ui( draggable ) ); - } - - }, - - _drop: function( event, custom ) { - - var draggable = custom || $.ui.ddmanager.current, - childrenIntersection = false; - - // Bail if draggable and droppable are same element - if ( !draggable || ( draggable.currentItem || - draggable.element )[ 0 ] === this.element[ 0 ] ) { - return false; - } - - this.element - .find( ":data(ui-droppable)" ) - .not( ".ui-draggable-dragging" ) - .each( function() { - var inst = $( this ).droppable( "instance" ); - if ( - inst.options.greedy && - !inst.options.disabled && - inst.options.scope === draggable.options.scope && - inst.accept.call( - inst.element[ 0 ], ( draggable.currentItem || draggable.element ) - ) && - $.ui.intersect( - draggable, - $.extend( inst, { offset: inst.element.offset() } ), - inst.options.tolerance, event - ) - ) { - childrenIntersection = true; - return false; - } - } ); - if ( childrenIntersection ) { - return false; - } - - if ( this.accept.call( this.element[ 0 ], - ( draggable.currentItem || draggable.element ) ) ) { - this._removeActiveClass(); - this._removeHoverClass(); - - this._trigger( "drop", event, this.ui( draggable ) ); - return this.element; - } - - return false; - - }, - - ui: function( c ) { - return { - draggable: ( c.currentItem || c.element ), - helper: c.helper, - position: c.position, - offset: c.positionAbs - }; - }, - - // Extension points just to make backcompat sane and avoid duplicating logic - // TODO: Remove in 1.14 along with call to it below - _addHoverClass: function() { - this._addClass( "ui-droppable-hover" ); - }, - - _removeHoverClass: function() { - this._removeClass( "ui-droppable-hover" ); - }, - - _addActiveClass: function() { - this._addClass( "ui-droppable-active" ); - }, - - _removeActiveClass: function() { - this._removeClass( "ui-droppable-active" ); - } -} ); - -$.ui.intersect = ( function() { - function isOverAxis( x, reference, size ) { - return ( x >= reference ) && ( x < ( reference + size ) ); - } - - return function( draggable, droppable, toleranceMode, event ) { - - if ( !droppable.offset ) { - return false; - } - - var x1 = ( draggable.positionAbs || - draggable.position.absolute ).left + draggable.margins.left, - y1 = ( draggable.positionAbs || - draggable.position.absolute ).top + draggable.margins.top, - x2 = x1 + draggable.helperProportions.width, - y2 = y1 + draggable.helperProportions.height, - l = droppable.offset.left, - t = droppable.offset.top, - r = l + droppable.proportions().width, - b = t + droppable.proportions().height; - - switch ( toleranceMode ) { - case "fit": - return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b ); - case "intersect": - return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half - x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half - t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half - y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half - case "pointer": - return isOverAxis( event.pageY, t, droppable.proportions().height ) && - isOverAxis( event.pageX, l, droppable.proportions().width ); - case "touch": - return ( - ( y1 >= t && y1 <= b ) || // Top edge touching - ( y2 >= t && y2 <= b ) || // Bottom edge touching - ( y1 < t && y2 > b ) // Surrounded vertically - ) && ( - ( x1 >= l && x1 <= r ) || // Left edge touching - ( x2 >= l && x2 <= r ) || // Right edge touching - ( x1 < l && x2 > r ) // Surrounded horizontally - ); - default: - return false; - } - }; -} )(); - -/* - This manager tracks offsets of draggables and droppables -*/ -$.ui.ddmanager = { - current: null, - droppables: { "default": [] }, - prepareOffsets: function( t, event ) { - - var i, j, - m = $.ui.ddmanager.droppables[ t.options.scope ] || [], - type = event ? event.type : null, // workaround for #2317 - list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack(); - - droppablesLoop: for ( i = 0; i < m.length; i++ ) { - - // No disabled and non-accepted - if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ], - ( t.currentItem || t.element ) ) ) ) { - continue; - } - - // Filter out elements in the current dragged item - for ( j = 0; j < list.length; j++ ) { - if ( list[ j ] === m[ i ].element[ 0 ] ) { - m[ i ].proportions().height = 0; - continue droppablesLoop; - } - } - - m[ i ].visible = m[ i ].element.css( "display" ) !== "none"; - if ( !m[ i ].visible ) { - continue; - } - - // Activate the droppable if used directly from draggables - if ( type === "mousedown" ) { - m[ i ]._activate.call( m[ i ], event ); - } - - m[ i ].offset = m[ i ].element.offset(); - m[ i ].proportions( { - width: m[ i ].element[ 0 ].offsetWidth, - height: m[ i ].element[ 0 ].offsetHeight - } ); - - } - - }, - drop: function( draggable, event ) { - - var dropped = false; - - // Create a copy of the droppables in case the list changes during the drop (#9116) - $.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() { - - if ( !this.options ) { - return; - } - if ( !this.options.disabled && this.visible && - $.ui.intersect( draggable, this, this.options.tolerance, event ) ) { - dropped = this._drop.call( this, event ) || dropped; - } - - if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ], - ( draggable.currentItem || draggable.element ) ) ) { - this.isout = true; - this.isover = false; - this._deactivate.call( this, event ); - } - - } ); - return dropped; - - }, - dragStart: function( draggable, event ) { - - // Listen for scrolling so that if the dragging causes scrolling the position of the - // droppables can be recalculated (see #5003) - draggable.element.parentsUntil( "body" ).on( "scroll.droppable", function() { - if ( !draggable.options.refreshPositions ) { - $.ui.ddmanager.prepareOffsets( draggable, event ); - } - } ); - }, - drag: function( draggable, event ) { - - // If you have a highly dynamic page, you might try this option. It renders positions - // every time you move the mouse. - if ( draggable.options.refreshPositions ) { - $.ui.ddmanager.prepareOffsets( draggable, event ); - } - - // Run through all droppables and check their positions based on specific tolerance options - $.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() { - - if ( this.options.disabled || this.greedyChild || !this.visible ) { - return; - } - - var parentInstance, scope, parent, - intersects = $.ui.intersect( draggable, this, this.options.tolerance, event ), - c = !intersects && this.isover ? - "isout" : - ( intersects && !this.isover ? "isover" : null ); - if ( !c ) { - return; - } - - if ( this.options.greedy ) { - - // find droppable parents with same scope - scope = this.options.scope; - parent = this.element.parents( ":data(ui-droppable)" ).filter( function() { - return $( this ).droppable( "instance" ).options.scope === scope; - } ); - - if ( parent.length ) { - parentInstance = $( parent[ 0 ] ).droppable( "instance" ); - parentInstance.greedyChild = ( c === "isover" ); - } - } - - // We just moved into a greedy child - if ( parentInstance && c === "isover" ) { - parentInstance.isover = false; - parentInstance.isout = true; - parentInstance._out.call( parentInstance, event ); - } - - this[ c ] = true; - this[ c === "isout" ? "isover" : "isout" ] = false; - this[ c === "isover" ? "_over" : "_out" ].call( this, event ); - - // We just moved out of a greedy child - if ( parentInstance && c === "isout" ) { - parentInstance.isout = false; - parentInstance.isover = true; - parentInstance._over.call( parentInstance, event ); - } - } ); - - }, - dragStop: function( draggable, event ) { - draggable.element.parentsUntil( "body" ).off( "scroll.droppable" ); - - // Call prepareOffsets one final time since IE does not fire return scroll events when - // overflow was caused by drag (see #5003) - if ( !draggable.options.refreshPositions ) { - $.ui.ddmanager.prepareOffsets( draggable, event ); - } - } -}; + "use strict"; + + $.widget( "ui.droppable", { + version: "1.13.2", + widgetEventPrefix: "drop", + options: { + accept: "*", + addClasses: true, + greedy: false, + scope: "default", + tolerance: "intersect", + + // Callbacks + activate: null, + deactivate: null, + drop: null, + out: null, + over: null + }, + _create: function() { + + var proportions, + o = this.options, + accept = o.accept; + + this.isover = false; + this.isout = true; + + this.accept = typeof accept === "function" ? accept : function( d ) { + return d.is( accept ); + }; + + this.proportions = function( /* valueToWrite */ ) { + if ( arguments.length ) { + + // Store the droppable's proportions + proportions = arguments[ 0 ]; + } else { + + // Retrieve or derive the droppable's proportions + return proportions ? + proportions : + proportions = { + width: this.element[ 0 ].offsetWidth, + height: this.element[ 0 ].offsetHeight + }; + } + }; + + this._addToManager( o.scope ); + + if ( o.addClasses ) { + this._addClass( "ui-droppable" ); + } + + }, + + _addToManager: function( scope ) { + + // Add the reference and positions to the manager + $.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || []; + $.ui.ddmanager.droppables[ scope ].push( this ); + }, + + _splice: function( drop ) { + var i = 0; + for ( ; i < drop.length; i++ ) { + if ( drop[ i ] === this ) { + drop.splice( i, 1 ); + } + } + }, + + _destroy: function() { + var drop = $.ui.ddmanager.droppables[ this.options.scope ]; + + this._splice( drop ); + }, + + _setOption: function( key, value ) { + + if ( key === "accept" ) { + this.accept = typeof value === "function" ? value : function( d ) { + return d.is( value ); + }; + } else if ( key === "scope" ) { + var drop = $.ui.ddmanager.droppables[ this.options.scope ]; + + this._splice( drop ); + this._addToManager( value ); + } + + this._super( key, value ); + }, + + _activate: function( event ) { + var draggable = $.ui.ddmanager.current; + + this._addActiveClass(); + if ( draggable ) { + this._trigger( "activate", event, this.ui( draggable ) ); + } + }, + + _deactivate: function( event ) { + var draggable = $.ui.ddmanager.current; + + this._removeActiveClass(); + if ( draggable ) { + this._trigger( "deactivate", event, this.ui( draggable ) ); + } + }, + + _over: function( event ) { + + var draggable = $.ui.ddmanager.current; + + // Bail if draggable and droppable are same element + if ( !draggable || ( draggable.currentItem || + draggable.element )[ 0 ] === this.element[ 0 ] ) { + return; + } + + if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || + draggable.element ) ) ) { + this._addHoverClass(); + this._trigger( "over", event, this.ui( draggable ) ); + } + + }, + + _out: function( event ) { + + var draggable = $.ui.ddmanager.current; + + // Bail if draggable and droppable are same element + if ( !draggable || ( draggable.currentItem || + draggable.element )[ 0 ] === this.element[ 0 ] ) { + return; + } + + if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || + draggable.element ) ) ) { + this._removeHoverClass(); + this._trigger( "out", event, this.ui( draggable ) ); + } + + }, + + _drop: function( event, custom ) { + + var draggable = custom || $.ui.ddmanager.current, + childrenIntersection = false; + + // Bail if draggable and droppable are same element + if ( !draggable || ( draggable.currentItem || + draggable.element )[ 0 ] === this.element[ 0 ] ) { + return false; + } + + this.element + .find( ":data(ui-droppable)" ) + .not( ".ui-draggable-dragging" ) + .each( function() { + var inst = $( this ).droppable( "instance" ); + if ( + inst.options.greedy && + !inst.options.disabled && + inst.options.scope === draggable.options.scope && + inst.accept.call( + inst.element[ 0 ], ( draggable.currentItem || draggable.element ) + ) && + $.ui.intersect( + draggable, + $.extend( inst, { offset: inst.element.offset() } ), + inst.options.tolerance, event + ) + ) { + childrenIntersection = true; + return false; + } + } ); + if ( childrenIntersection ) { + return false; + } + + if ( this.accept.call( this.element[ 0 ], + ( draggable.currentItem || draggable.element ) ) ) { + this._removeActiveClass(); + this._removeHoverClass(); + + this._trigger( "drop", event, this.ui( draggable ) ); + return this.element; + } + + return false; + + }, + + ui: function( c ) { + return { + draggable: ( c.currentItem || c.element ), + helper: c.helper, + position: c.position, + offset: c.positionAbs + }; + }, + + // Extension points just to make backcompat sane and avoid duplicating logic + // TODO: Remove in 1.14 along with call to it below + _addHoverClass: function() { + this._addClass( "ui-droppable-hover" ); + }, + + _removeHoverClass: function() { + this._removeClass( "ui-droppable-hover" ); + }, + + _addActiveClass: function() { + this._addClass( "ui-droppable-active" ); + }, + + _removeActiveClass: function() { + this._removeClass( "ui-droppable-active" ); + } + } ); + + $.ui.intersect = ( function() { + function isOverAxis( x, reference, size ) { + return ( x >= reference ) && ( x < ( reference + size ) ); + } + + return function( draggable, droppable, toleranceMode, event ) { + + if ( !droppable.offset ) { + return false; + } + + var x1 = ( draggable.positionAbs || + draggable.position.absolute ).left + draggable.margins.left, + y1 = ( draggable.positionAbs || + draggable.position.absolute ).top + draggable.margins.top, + x2 = x1 + draggable.helperProportions.width, + y2 = y1 + draggable.helperProportions.height, + l = droppable.offset.left, + t = droppable.offset.top, + r = l + droppable.proportions().width, + b = t + droppable.proportions().height; + + switch ( toleranceMode ) { + case "fit": + return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b ); + case "intersect": + return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half + x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half + t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half + y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half + case "pointer": + return isOverAxis( event.pageY, t, droppable.proportions().height ) && + isOverAxis( event.pageX, l, droppable.proportions().width ); + case "touch": + return ( + ( y1 >= t && y1 <= b ) || // Top edge touching + ( y2 >= t && y2 <= b ) || // Bottom edge touching + ( y1 < t && y2 > b ) // Surrounded vertically + ) && ( + ( x1 >= l && x1 <= r ) || // Left edge touching + ( x2 >= l && x2 <= r ) || // Right edge touching + ( x1 < l && x2 > r ) // Surrounded horizontally + ); + default: + return false; + } + }; + } )(); + + /* + This manager tracks offsets of draggables and droppables + */ + $.ui.ddmanager = { + current: null, + droppables: { "default": [] }, + prepareOffsets: function( t, event ) { + + var i, j, + m = $.ui.ddmanager.droppables[ t.options.scope ] || [], + type = event ? event.type : null, // workaround for #2317 + list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack(); + + droppablesLoop: for ( i = 0; i < m.length; i++ ) { + + // No disabled and non-accepted + if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ], + ( t.currentItem || t.element ) ) ) ) { + continue; + } + + // Filter out elements in the current dragged item + for ( j = 0; j < list.length; j++ ) { + if ( list[ j ] === m[ i ].element[ 0 ] ) { + m[ i ].proportions().height = 0; + continue droppablesLoop; + } + } + + m[ i ].visible = m[ i ].element.css( "display" ) !== "none"; + if ( !m[ i ].visible ) { + continue; + } + + // Activate the droppable if used directly from draggables + if ( type === "mousedown" ) { + m[ i ]._activate.call( m[ i ], event ); + } + + m[ i ].offset = m[ i ].element.offset(); + m[ i ].proportions( { + width: m[ i ].element[ 0 ].offsetWidth, + height: m[ i ].element[ 0 ].offsetHeight + } ); + + } + + }, + drop: function( draggable, event ) { + + var dropped = false; + + // Create a copy of the droppables in case the list changes during the drop (#9116) + $.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() { + + if ( !this.options ) { + return; + } + if ( !this.options.disabled && this.visible && + $.ui.intersect( draggable, this, this.options.tolerance, event ) ) { + dropped = this._drop.call( this, event ) || dropped; + } + + if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ], + ( draggable.currentItem || draggable.element ) ) ) { + this.isout = true; + this.isover = false; + this._deactivate.call( this, event ); + } + + } ); + return dropped; + + }, + dragStart: function( draggable, event ) { + + // Listen for scrolling so that if the dragging causes scrolling the position of the + // droppables can be recalculated (see #5003) + draggable.element.parentsUntil( "body" ).on( "scroll.droppable", function() { + if ( !draggable.options.refreshPositions ) { + $.ui.ddmanager.prepareOffsets( draggable, event ); + } + } ); + }, + drag: function( draggable, event ) { + + // If you have a highly dynamic page, you might try this option. It renders positions + // every time you move the mouse. + if ( draggable.options.refreshPositions ) { + $.ui.ddmanager.prepareOffsets( draggable, event ); + } + + // Run through all droppables and check their positions based on specific tolerance options + $.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() { + + if ( this.options.disabled || this.greedyChild || !this.visible ) { + return; + } + + var parentInstance, scope, parent, + intersects = $.ui.intersect( draggable, this, this.options.tolerance, event ), + c = !intersects && this.isover ? + "isout" : + ( intersects && !this.isover ? "isover" : null ); + if ( !c ) { + return; + } + + if ( this.options.greedy ) { + + // find droppable parents with same scope + scope = this.options.scope; + parent = this.element.parents( ":data(ui-droppable)" ).filter( function() { + return $( this ).droppable( "instance" ).options.scope === scope; + } ); + + if ( parent.length ) { + parentInstance = $( parent[ 0 ] ).droppable( "instance" ); + parentInstance.greedyChild = ( c === "isover" ); + } + } + + // We just moved into a greedy child + if ( parentInstance && c === "isover" ) { + parentInstance.isover = false; + parentInstance.isout = true; + parentInstance._out.call( parentInstance, event ); + } + + this[ c ] = true; + this[ c === "isout" ? "isover" : "isout" ] = false; + this[ c === "isover" ? "_over" : "_out" ].call( this, event ); + + // We just moved out of a greedy child + if ( parentInstance && c === "isout" ) { + parentInstance.isout = false; + parentInstance.isover = true; + parentInstance._over.call( parentInstance, event ); + } + } ); + + }, + dragStop: function( draggable, event ) { + draggable.element.parentsUntil( "body" ).off( "scroll.droppable" ); + + // Call prepareOffsets one final time since IE does not fire return scroll events when + // overflow was caused by drag (see #5003) + if ( !draggable.options.refreshPositions ) { + $.ui.ddmanager.prepareOffsets( draggable, event ); + } + } + }; // DEPRECATED // TODO: switch return back to widget declaration at top of file when this is removed -if ( $.uiBackCompat !== false ) { - - // Backcompat for activeClass and hoverClass options - $.widget( "ui.droppable", $.ui.droppable, { - options: { - hoverClass: false, - activeClass: false - }, - _addActiveClass: function() { - this._super(); - if ( this.options.activeClass ) { - this.element.addClass( this.options.activeClass ); - } - }, - _removeActiveClass: function() { - this._super(); - if ( this.options.activeClass ) { - this.element.removeClass( this.options.activeClass ); - } - }, - _addHoverClass: function() { - this._super(); - if ( this.options.hoverClass ) { - this.element.addClass( this.options.hoverClass ); - } - }, - _removeHoverClass: function() { - this._super(); - if ( this.options.hoverClass ) { - this.element.removeClass( this.options.hoverClass ); - } - } - } ); -} - -return $.ui.droppable; + if ( $.uiBackCompat !== false ) { + + // Backcompat for activeClass and hoverClass options + $.widget( "ui.droppable", $.ui.droppable, { + options: { + hoverClass: false, + activeClass: false + }, + _addActiveClass: function() { + this._super(); + if ( this.options.activeClass ) { + this.element.addClass( this.options.activeClass ); + } + }, + _removeActiveClass: function() { + this._super(); + if ( this.options.activeClass ) { + this.element.removeClass( this.options.activeClass ); + } + }, + _addHoverClass: function() { + this._super(); + if ( this.options.hoverClass ) { + this.element.addClass( this.options.hoverClass ); + } + }, + _removeHoverClass: function() { + this._super(); + if ( this.options.hoverClass ) { + this.element.removeClass( this.options.hoverClass ); + } + } + } ); + } + + return $.ui.droppable; } ); diff --git a/lib/web/jquery/ui-modules/widgets/menu.js b/lib/web/jquery/ui-modules/widgets/menu.js index ea72e03edc7b7..268b4b5fb0b73 100644 --- a/lib/web/jquery/ui-modules/widgets/menu.js +++ b/lib/web/jquery/ui-modules/widgets/menu.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Menu 1.13.1 + * jQuery UI Menu 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -17,697 +17,697 @@ //>>css.theme: ../../themes/base/theme.css ( function( factory ) { - "use strict"; - - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define( [ - "jquery", - "../keycode", - "../position", - "../safe-active-element", - "../unique-id", - "../version", - "../widget" - ], factory ); - } else { - - // Browser globals - factory( jQuery ); - } + "use strict"; + + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ + "jquery", + "../keycode", + "../position", + "../safe-active-element", + "../unique-id", + "../version", + "../widget" + ], factory ); + } else { + + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; - -return $.widget( "ui.menu", { - version: "1.13.1", - defaultElement: "<ul>", - delay: 300, - options: { - icons: { - submenu: "ui-icon-caret-1-e" - }, - items: "> *", - menus: "ul", - position: { - my: "left top", - at: "right top" - }, - role: "menu", - - // Callbacks - blur: null, - focus: null, - select: null - }, - - _create: function() { - this.activeMenu = this.element; - - // Flag used to prevent firing of the click handler - // as the event bubbles up through nested menus - this.mouseHandled = false; - this.lastMousePosition = { x: null, y: null }; - this.element - .uniqueId() - .attr( { - role: this.options.role, - tabIndex: 0 - } ); - - this._addClass( "ui-menu", "ui-widget ui-widget-content" ); - this._on( { - - // Prevent focus from sticking to links inside menu after clicking - // them (focus should always stay on UL during navigation). - "mousedown .ui-menu-item": function( event ) { - event.preventDefault(); - - this._activateItem( event ); - }, - "click .ui-menu-item": function( event ) { - var target = $( event.target ); - var active = $( $.ui.safeActiveElement( this.document[ 0 ] ) ); - if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) { - this.select( event ); - - // Only set the mouseHandled flag if the event will bubble, see #9469. - if ( !event.isPropagationStopped() ) { - this.mouseHandled = true; - } - - // Open submenu on click - if ( target.has( ".ui-menu" ).length ) { - this.expand( event ); - } else if ( !this.element.is( ":focus" ) && - active.closest( ".ui-menu" ).length ) { - - // Redirect focus to the menu - this.element.trigger( "focus", [ true ] ); - - // If the active item is on the top level, let it stay active. - // Otherwise, blur the active item since it is no longer visible. - if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) { - clearTimeout( this.timer ); - } - } - } - }, - "mouseenter .ui-menu-item": "_activateItem", - "mousemove .ui-menu-item": "_activateItem", - mouseleave: "collapseAll", - "mouseleave .ui-menu": "collapseAll", - focus: function( event, keepActiveItem ) { - - // If there's already an active item, keep it active - // If not, activate the first item - var item = this.active || this._menuItems().first(); - - if ( !keepActiveItem ) { - this.focus( event, item ); - } - }, - blur: function( event ) { - this._delay( function() { - var notContained = !$.contains( - this.element[ 0 ], - $.ui.safeActiveElement( this.document[ 0 ] ) - ); - if ( notContained ) { - this.collapseAll( event ); - } - } ); - }, - keydown: "_keydown" - } ); - - this.refresh(); - - // Clicks outside of a menu collapse any open menus - this._on( this.document, { - click: function( event ) { - if ( this._closeOnDocumentClick( event ) ) { - this.collapseAll( event, true ); - } - - // Reset the mouseHandled flag - this.mouseHandled = false; - } - } ); - }, - - _activateItem: function( event ) { - - // Ignore mouse events while typeahead is active, see #10458. - // Prevents focusing the wrong item when typeahead causes a scroll while the mouse - // is over an item in the menu - if ( this.previousFilter ) { - return; - } - - // If the mouse didn't actually move, but the page was scrolled, ignore the event (#9356) - if ( event.clientX === this.lastMousePosition.x && - event.clientY === this.lastMousePosition.y ) { - return; - } - - this.lastMousePosition = { - x: event.clientX, - y: event.clientY - }; - - var actualTarget = $( event.target ).closest( ".ui-menu-item" ), - target = $( event.currentTarget ); - - // Ignore bubbled events on parent items, see #11641 - if ( actualTarget[ 0 ] !== target[ 0 ] ) { - return; - } - - // If the item is already active, there's nothing to do - if ( target.is( ".ui-state-active" ) ) { - return; - } - - // Remove ui-state-active class from siblings of the newly focused menu item - // to avoid a jump caused by adjacent elements both having a class with a border - this._removeClass( target.siblings().children( ".ui-state-active" ), - null, "ui-state-active" ); - this.focus( event, target ); - }, - - _destroy: function() { - var items = this.element.find( ".ui-menu-item" ) - .removeAttr( "role aria-disabled" ), - submenus = items.children( ".ui-menu-item-wrapper" ) - .removeUniqueId() - .removeAttr( "tabIndex role aria-haspopup" ); - - // Destroy (sub)menus - this.element - .removeAttr( "aria-activedescendant" ) - .find( ".ui-menu" ).addBack() - .removeAttr( "role aria-labelledby aria-expanded aria-hidden aria-disabled " + - "tabIndex" ) - .removeUniqueId() - .show(); - - submenus.children().each( function() { - var elem = $( this ); - if ( elem.data( "ui-menu-submenu-caret" ) ) { - elem.remove(); - } - } ); - }, - - _keydown: function( event ) { - var match, prev, character, skip, - preventDefault = true; - - switch ( event.keyCode ) { - case $.ui.keyCode.PAGE_UP: - this.previousPage( event ); - break; - case $.ui.keyCode.PAGE_DOWN: - this.nextPage( event ); - break; - case $.ui.keyCode.HOME: - this._move( "first", "first", event ); - break; - case $.ui.keyCode.END: - this._move( "last", "last", event ); - break; - case $.ui.keyCode.UP: - this.previous( event ); - break; - case $.ui.keyCode.DOWN: - this.next( event ); - break; - case $.ui.keyCode.LEFT: - this.collapse( event ); - break; - case $.ui.keyCode.RIGHT: - if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { - this.expand( event ); - } - break; - case $.ui.keyCode.ENTER: - case $.ui.keyCode.SPACE: - this._activate( event ); - break; - case $.ui.keyCode.ESCAPE: - this.collapse( event ); - break; - default: - preventDefault = false; - prev = this.previousFilter || ""; - skip = false; - - // Support number pad values - character = event.keyCode >= 96 && event.keyCode <= 105 ? - ( event.keyCode - 96 ).toString() : String.fromCharCode( event.keyCode ); - - clearTimeout( this.filterTimer ); - - if ( character === prev ) { - skip = true; - } else { - character = prev + character; - } - - match = this._filterMenuItems( character ); - match = skip && match.index( this.active.next() ) !== -1 ? - this.active.nextAll( ".ui-menu-item" ) : - match; - - // If no matches on the current filter, reset to the last character pressed - // to move down the menu to the first item that starts with that character - if ( !match.length ) { - character = String.fromCharCode( event.keyCode ); - match = this._filterMenuItems( character ); - } - - if ( match.length ) { - this.focus( event, match ); - this.previousFilter = character; - this.filterTimer = this._delay( function() { - delete this.previousFilter; - }, 1000 ); - } else { - delete this.previousFilter; - } - } - - if ( preventDefault ) { - event.preventDefault(); - } - }, - - _activate: function( event ) { - if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { - if ( this.active.children( "[aria-haspopup='true']" ).length ) { - this.expand( event ); - } else { - this.select( event ); - } - } - }, - - refresh: function() { - var menus, items, newSubmenus, newItems, newWrappers, - that = this, - icon = this.options.icons.submenu, - submenus = this.element.find( this.options.menus ); - - this._toggleClass( "ui-menu-icons", null, !!this.element.find( ".ui-icon" ).length ); - - // Initialize nested menus - newSubmenus = submenus.filter( ":not(.ui-menu)" ) - .hide() - .attr( { - role: this.options.role, - "aria-hidden": "true", - "aria-expanded": "false" - } ) - .each( function() { - var menu = $( this ), - item = menu.prev(), - submenuCaret = $( "<span>" ).data( "ui-menu-submenu-caret", true ); - - that._addClass( submenuCaret, "ui-menu-icon", "ui-icon " + icon ); - item - .attr( "aria-haspopup", "true" ) - .prepend( submenuCaret ); - menu.attr( "aria-labelledby", item.attr( "id" ) ); - } ); - - this._addClass( newSubmenus, "ui-menu", "ui-widget ui-widget-content ui-front" ); - - menus = submenus.add( this.element ); - items = menus.find( this.options.items ); - - // Initialize menu-items containing spaces and/or dashes only as dividers - items.not( ".ui-menu-item" ).each( function() { - var item = $( this ); - if ( that._isDivider( item ) ) { - that._addClass( item, "ui-menu-divider", "ui-widget-content" ); - } - } ); - - // Don't refresh list items that are already adapted - newItems = items.not( ".ui-menu-item, .ui-menu-divider" ); - newWrappers = newItems.children() - .not( ".ui-menu" ) - .uniqueId() - .attr( { - tabIndex: -1, - role: this._itemRole() - } ); - this._addClass( newItems, "ui-menu-item" ) - ._addClass( newWrappers, "ui-menu-item-wrapper" ); - - // Add aria-disabled attribute to any disabled menu item - items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" ); - - // If the active item has been removed, blur the menu - if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { - this.blur(); - } - }, - - _itemRole: function() { - return { - menu: "menuitem", - listbox: "option" - }[ this.options.role ]; - }, - - _setOption: function( key, value ) { - if ( key === "icons" ) { - var icons = this.element.find( ".ui-menu-icon" ); - this._removeClass( icons, null, this.options.icons.submenu ) - ._addClass( icons, null, value.submenu ); - } - this._super( key, value ); - }, - - _setOptionDisabled: function( value ) { - this._super( value ); - - this.element.attr( "aria-disabled", String( value ) ); - this._toggleClass( null, "ui-state-disabled", !!value ); - }, - - focus: function( event, item ) { - var nested, focused, activeParent; - this.blur( event, event && event.type === "focus" ); - - this._scrollIntoView( item ); - - this.active = item.first(); - - focused = this.active.children( ".ui-menu-item-wrapper" ); - this._addClass( focused, null, "ui-state-active" ); - - // Only update aria-activedescendant if there's a role - // otherwise we assume focus is managed elsewhere - if ( this.options.role ) { - this.element.attr( "aria-activedescendant", focused.attr( "id" ) ); - } - - // Highlight active parent menu item, if any - activeParent = this.active - .parent() - .closest( ".ui-menu-item" ) - .children( ".ui-menu-item-wrapper" ); - this._addClass( activeParent, null, "ui-state-active" ); - - if ( event && event.type === "keydown" ) { - this._close(); - } else { - this.timer = this._delay( function() { - this._close(); - }, this.delay ); - } - - nested = item.children( ".ui-menu" ); - if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) { - this._startOpening( nested ); - } - this.activeMenu = item.parent(); - - this._trigger( "focus", event, { item: item } ); - }, - - _scrollIntoView: function( item ) { - var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight; - if ( this._hasScroll() ) { - borderTop = parseFloat( $.css( this.activeMenu[ 0 ], "borderTopWidth" ) ) || 0; - paddingTop = parseFloat( $.css( this.activeMenu[ 0 ], "paddingTop" ) ) || 0; - offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop; - scroll = this.activeMenu.scrollTop(); - elementHeight = this.activeMenu.height(); - itemHeight = item.outerHeight(); - - if ( offset < 0 ) { - this.activeMenu.scrollTop( scroll + offset ); - } else if ( offset + itemHeight > elementHeight ) { - this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight ); - } - } - }, - - blur: function( event, fromFocus ) { - if ( !fromFocus ) { - clearTimeout( this.timer ); - } - - if ( !this.active ) { - return; - } - - this._removeClass( this.active.children( ".ui-menu-item-wrapper" ), - null, "ui-state-active" ); - - this._trigger( "blur", event, { item: this.active } ); - this.active = null; - }, - - _startOpening: function( submenu ) { - clearTimeout( this.timer ); - - // Don't open if already open fixes a Firefox bug that caused a .5 pixel - // shift in the submenu position when mousing over the caret icon - if ( submenu.attr( "aria-hidden" ) !== "true" ) { - return; - } - - this.timer = this._delay( function() { - this._close(); - this._open( submenu ); - }, this.delay ); - }, - - _open: function( submenu ) { - var position = $.extend( { - of: this.active - }, this.options.position ); - - clearTimeout( this.timer ); - this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) ) - .hide() - .attr( "aria-hidden", "true" ); - - submenu - .show() - .removeAttr( "aria-hidden" ) - .attr( "aria-expanded", "true" ) - .position( position ); - }, - - collapseAll: function( event, all ) { - clearTimeout( this.timer ); - this.timer = this._delay( function() { - - // If we were passed an event, look for the submenu that contains the event - var currentMenu = all ? this.element : - $( event && event.target ).closest( this.element.find( ".ui-menu" ) ); - - // If we found no valid submenu ancestor, use the main menu to close all - // sub menus anyway - if ( !currentMenu.length ) { - currentMenu = this.element; - } - - this._close( currentMenu ); - - this.blur( event ); - - // Work around active item staying active after menu is blurred - this._removeClass( currentMenu.find( ".ui-state-active" ), null, "ui-state-active" ); - - this.activeMenu = currentMenu; - }, all ? 0 : this.delay ); - }, - - // With no arguments, closes the currently active menu - if nothing is active - // it closes all menus. If passed an argument, it will search for menus BELOW - _close: function( startMenu ) { - if ( !startMenu ) { - startMenu = this.active ? this.active.parent() : this.element; - } - - startMenu.find( ".ui-menu" ) - .hide() - .attr( "aria-hidden", "true" ) - .attr( "aria-expanded", "false" ); - }, - - _closeOnDocumentClick: function( event ) { - return !$( event.target ).closest( ".ui-menu" ).length; - }, - - _isDivider: function( item ) { - - // Match hyphen, em dash, en dash - return !/[^\-\u2014\u2013\s]/.test( item.text() ); - }, - - collapse: function( event ) { - var newItem = this.active && - this.active.parent().closest( ".ui-menu-item", this.element ); - if ( newItem && newItem.length ) { - this._close(); - this.focus( event, newItem ); - } - }, - - expand: function( event ) { - var newItem = this.active && this._menuItems( this.active.children( ".ui-menu" ) ).first(); - - if ( newItem && newItem.length ) { - this._open( newItem.parent() ); - - // Delay so Firefox will not hide activedescendant change in expanding submenu from AT - this._delay( function() { - this.focus( event, newItem ); - } ); - } - }, - - next: function( event ) { - this._move( "next", "first", event ); - }, - - previous: function( event ) { - this._move( "prev", "last", event ); - }, - - isFirstItem: function() { - return this.active && !this.active.prevAll( ".ui-menu-item" ).length; - }, - - isLastItem: function() { - return this.active && !this.active.nextAll( ".ui-menu-item" ).length; - }, - - _menuItems: function( menu ) { - return ( menu || this.element ) - .find( this.options.items ) - .filter( ".ui-menu-item" ); - }, - - _move: function( direction, filter, event ) { - var next; - if ( this.active ) { - if ( direction === "first" || direction === "last" ) { - next = this.active - [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" ) - .last(); - } else { - next = this.active - [ direction + "All" ]( ".ui-menu-item" ) - .first(); - } - } - if ( !next || !next.length || !this.active ) { - next = this._menuItems( this.activeMenu )[ filter ](); - } - - this.focus( event, next ); - }, - - nextPage: function( event ) { - var item, base, height; - - if ( !this.active ) { - this.next( event ); - return; - } - if ( this.isLastItem() ) { - return; - } - if ( this._hasScroll() ) { - base = this.active.offset().top; - height = this.element.innerHeight(); - - // jQuery 3.2 doesn't include scrollbars in innerHeight, add it back. - if ( $.fn.jquery.indexOf( "3.2." ) === 0 ) { - height += this.element[ 0 ].offsetHeight - this.element.outerHeight(); - } - - this.active.nextAll( ".ui-menu-item" ).each( function() { - item = $( this ); - return item.offset().top - base - height < 0; - } ); - - this.focus( event, item ); - } else { - this.focus( event, this._menuItems( this.activeMenu ) - [ !this.active ? "first" : "last" ]() ); - } - }, - - previousPage: function( event ) { - var item, base, height; - if ( !this.active ) { - this.next( event ); - return; - } - if ( this.isFirstItem() ) { - return; - } - if ( this._hasScroll() ) { - base = this.active.offset().top; - height = this.element.innerHeight(); - - // jQuery 3.2 doesn't include scrollbars in innerHeight, add it back. - if ( $.fn.jquery.indexOf( "3.2." ) === 0 ) { - height += this.element[ 0 ].offsetHeight - this.element.outerHeight(); - } - - this.active.prevAll( ".ui-menu-item" ).each( function() { - item = $( this ); - return item.offset().top - base + height > 0; - } ); - - this.focus( event, item ); - } else { - this.focus( event, this._menuItems( this.activeMenu ).first() ); - } - }, - - _hasScroll: function() { - return this.element.outerHeight() < this.element.prop( "scrollHeight" ); - }, - - select: function( event ) { - - // TODO: It should never be possible to not have an active item at this - // point, but the tests don't trigger mouseenter before click. - this.active = this.active || $( event.target ).closest( ".ui-menu-item" ); - var ui = { item: this.active }; - if ( !this.active.has( ".ui-menu" ).length ) { - this.collapseAll( event, true ); - } - this._trigger( "select", event, ui ); - }, - - _filterMenuItems: function( character ) { - var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ), - regex = new RegExp( "^" + escapedCharacter, "i" ); - - return this.activeMenu - .find( this.options.items ) - - // Only match on items, not dividers or other content (#10571) - .filter( ".ui-menu-item" ) - .filter( function() { - return regex.test( - String.prototype.trim.call( - $( this ).children( ".ui-menu-item-wrapper" ).text() ) ); - } ); - } -} ); + "use strict"; + + return $.widget( "ui.menu", { + version: "1.13.2", + defaultElement: "<ul>", + delay: 300, + options: { + icons: { + submenu: "ui-icon-caret-1-e" + }, + items: "> *", + menus: "ul", + position: { + my: "left top", + at: "right top" + }, + role: "menu", + + // Callbacks + blur: null, + focus: null, + select: null + }, + + _create: function() { + this.activeMenu = this.element; + + // Flag used to prevent firing of the click handler + // as the event bubbles up through nested menus + this.mouseHandled = false; + this.lastMousePosition = { x: null, y: null }; + this.element + .uniqueId() + .attr( { + role: this.options.role, + tabIndex: 0 + } ); + + this._addClass( "ui-menu", "ui-widget ui-widget-content" ); + this._on( { + + // Prevent focus from sticking to links inside menu after clicking + // them (focus should always stay on UL during navigation). + "mousedown .ui-menu-item": function( event ) { + event.preventDefault(); + + this._activateItem( event ); + }, + "click .ui-menu-item": function( event ) { + var target = $( event.target ); + var active = $( $.ui.safeActiveElement( this.document[ 0 ] ) ); + if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) { + this.select( event ); + + // Only set the mouseHandled flag if the event will bubble, see #9469. + if ( !event.isPropagationStopped() ) { + this.mouseHandled = true; + } + + // Open submenu on click + if ( target.has( ".ui-menu" ).length ) { + this.expand( event ); + } else if ( !this.element.is( ":focus" ) && + active.closest( ".ui-menu" ).length ) { + + // Redirect focus to the menu + this.element.trigger( "focus", [ true ] ); + + // If the active item is on the top level, let it stay active. + // Otherwise, blur the active item since it is no longer visible. + if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) { + clearTimeout( this.timer ); + } + } + } + }, + "mouseenter .ui-menu-item": "_activateItem", + "mousemove .ui-menu-item": "_activateItem", + mouseleave: "collapseAll", + "mouseleave .ui-menu": "collapseAll", + focus: function( event, keepActiveItem ) { + + // If there's already an active item, keep it active + // If not, activate the first item + var item = this.active || this._menuItems().first(); + + if ( !keepActiveItem ) { + this.focus( event, item ); + } + }, + blur: function( event ) { + this._delay( function() { + var notContained = !$.contains( + this.element[ 0 ], + $.ui.safeActiveElement( this.document[ 0 ] ) + ); + if ( notContained ) { + this.collapseAll( event ); + } + } ); + }, + keydown: "_keydown" + } ); + + this.refresh(); + + // Clicks outside of a menu collapse any open menus + this._on( this.document, { + click: function( event ) { + if ( this._closeOnDocumentClick( event ) ) { + this.collapseAll( event, true ); + } + + // Reset the mouseHandled flag + this.mouseHandled = false; + } + } ); + }, + + _activateItem: function( event ) { + + // Ignore mouse events while typeahead is active, see #10458. + // Prevents focusing the wrong item when typeahead causes a scroll while the mouse + // is over an item in the menu + if ( this.previousFilter ) { + return; + } + + // If the mouse didn't actually move, but the page was scrolled, ignore the event (#9356) + if ( event.clientX === this.lastMousePosition.x && + event.clientY === this.lastMousePosition.y ) { + return; + } + + this.lastMousePosition = { + x: event.clientX, + y: event.clientY + }; + + var actualTarget = $( event.target ).closest( ".ui-menu-item" ), + target = $( event.currentTarget ); + + // Ignore bubbled events on parent items, see #11641 + if ( actualTarget[ 0 ] !== target[ 0 ] ) { + return; + } + + // If the item is already active, there's nothing to do + if ( target.is( ".ui-state-active" ) ) { + return; + } + + // Remove ui-state-active class from siblings of the newly focused menu item + // to avoid a jump caused by adjacent elements both having a class with a border + this._removeClass( target.siblings().children( ".ui-state-active" ), + null, "ui-state-active" ); + this.focus( event, target ); + }, + + _destroy: function() { + var items = this.element.find( ".ui-menu-item" ) + .removeAttr( "role aria-disabled" ), + submenus = items.children( ".ui-menu-item-wrapper" ) + .removeUniqueId() + .removeAttr( "tabIndex role aria-haspopup" ); + + // Destroy (sub)menus + this.element + .removeAttr( "aria-activedescendant" ) + .find( ".ui-menu" ).addBack() + .removeAttr( "role aria-labelledby aria-expanded aria-hidden aria-disabled " + + "tabIndex" ) + .removeUniqueId() + .show(); + + submenus.children().each( function() { + var elem = $( this ); + if ( elem.data( "ui-menu-submenu-caret" ) ) { + elem.remove(); + } + } ); + }, + + _keydown: function( event ) { + var match, prev, character, skip, + preventDefault = true; + + switch ( event.keyCode ) { + case $.ui.keyCode.PAGE_UP: + this.previousPage( event ); + break; + case $.ui.keyCode.PAGE_DOWN: + this.nextPage( event ); + break; + case $.ui.keyCode.HOME: + this._move( "first", "first", event ); + break; + case $.ui.keyCode.END: + this._move( "last", "last", event ); + break; + case $.ui.keyCode.UP: + this.previous( event ); + break; + case $.ui.keyCode.DOWN: + this.next( event ); + break; + case $.ui.keyCode.LEFT: + this.collapse( event ); + break; + case $.ui.keyCode.RIGHT: + if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { + this.expand( event ); + } + break; + case $.ui.keyCode.ENTER: + case $.ui.keyCode.SPACE: + this._activate( event ); + break; + case $.ui.keyCode.ESCAPE: + this.collapse( event ); + break; + default: + preventDefault = false; + prev = this.previousFilter || ""; + skip = false; + + // Support number pad values + character = event.keyCode >= 96 && event.keyCode <= 105 ? + ( event.keyCode - 96 ).toString() : String.fromCharCode( event.keyCode ); + + clearTimeout( this.filterTimer ); + + if ( character === prev ) { + skip = true; + } else { + character = prev + character; + } + + match = this._filterMenuItems( character ); + match = skip && match.index( this.active.next() ) !== -1 ? + this.active.nextAll( ".ui-menu-item" ) : + match; + + // If no matches on the current filter, reset to the last character pressed + // to move down the menu to the first item that starts with that character + if ( !match.length ) { + character = String.fromCharCode( event.keyCode ); + match = this._filterMenuItems( character ); + } + + if ( match.length ) { + this.focus( event, match ); + this.previousFilter = character; + this.filterTimer = this._delay( function() { + delete this.previousFilter; + }, 1000 ); + } else { + delete this.previousFilter; + } + } + + if ( preventDefault ) { + event.preventDefault(); + } + }, + + _activate: function( event ) { + if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { + if ( this.active.children( "[aria-haspopup='true']" ).length ) { + this.expand( event ); + } else { + this.select( event ); + } + } + }, + + refresh: function() { + var menus, items, newSubmenus, newItems, newWrappers, + that = this, + icon = this.options.icons.submenu, + submenus = this.element.find( this.options.menus ); + + this._toggleClass( "ui-menu-icons", null, !!this.element.find( ".ui-icon" ).length ); + + // Initialize nested menus + newSubmenus = submenus.filter( ":not(.ui-menu)" ) + .hide() + .attr( { + role: this.options.role, + "aria-hidden": "true", + "aria-expanded": "false" + } ) + .each( function() { + var menu = $( this ), + item = menu.prev(), + submenuCaret = $( "<span>" ).data( "ui-menu-submenu-caret", true ); + + that._addClass( submenuCaret, "ui-menu-icon", "ui-icon " + icon ); + item + .attr( "aria-haspopup", "true" ) + .prepend( submenuCaret ); + menu.attr( "aria-labelledby", item.attr( "id" ) ); + } ); + + this._addClass( newSubmenus, "ui-menu", "ui-widget ui-widget-content ui-front" ); + + menus = submenus.add( this.element ); + items = menus.find( this.options.items ); + + // Initialize menu-items containing spaces and/or dashes only as dividers + items.not( ".ui-menu-item" ).each( function() { + var item = $( this ); + if ( that._isDivider( item ) ) { + that._addClass( item, "ui-menu-divider", "ui-widget-content" ); + } + } ); + + // Don't refresh list items that are already adapted + newItems = items.not( ".ui-menu-item, .ui-menu-divider" ); + newWrappers = newItems.children() + .not( ".ui-menu" ) + .uniqueId() + .attr( { + tabIndex: -1, + role: this._itemRole() + } ); + this._addClass( newItems, "ui-menu-item" ) + ._addClass( newWrappers, "ui-menu-item-wrapper" ); + + // Add aria-disabled attribute to any disabled menu item + items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" ); + + // If the active item has been removed, blur the menu + if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { + this.blur(); + } + }, + + _itemRole: function() { + return { + menu: "menuitem", + listbox: "option" + }[ this.options.role ]; + }, + + _setOption: function( key, value ) { + if ( key === "icons" ) { + var icons = this.element.find( ".ui-menu-icon" ); + this._removeClass( icons, null, this.options.icons.submenu ) + ._addClass( icons, null, value.submenu ); + } + this._super( key, value ); + }, + + _setOptionDisabled: function( value ) { + this._super( value ); + + this.element.attr( "aria-disabled", String( value ) ); + this._toggleClass( null, "ui-state-disabled", !!value ); + }, + + focus: function( event, item ) { + var nested, focused, activeParent; + this.blur( event, event && event.type === "focus" ); + + this._scrollIntoView( item ); + + this.active = item.first(); + + focused = this.active.children( ".ui-menu-item-wrapper" ); + this._addClass( focused, null, "ui-state-active" ); + + // Only update aria-activedescendant if there's a role + // otherwise we assume focus is managed elsewhere + if ( this.options.role ) { + this.element.attr( "aria-activedescendant", focused.attr( "id" ) ); + } + + // Highlight active parent menu item, if any + activeParent = this.active + .parent() + .closest( ".ui-menu-item" ) + .children( ".ui-menu-item-wrapper" ); + this._addClass( activeParent, null, "ui-state-active" ); + + if ( event && event.type === "keydown" ) { + this._close(); + } else { + this.timer = this._delay( function() { + this._close(); + }, this.delay ); + } + + nested = item.children( ".ui-menu" ); + if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) { + this._startOpening( nested ); + } + this.activeMenu = item.parent(); + + this._trigger( "focus", event, { item: item } ); + }, + + _scrollIntoView: function( item ) { + var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight; + if ( this._hasScroll() ) { + borderTop = parseFloat( $.css( this.activeMenu[ 0 ], "borderTopWidth" ) ) || 0; + paddingTop = parseFloat( $.css( this.activeMenu[ 0 ], "paddingTop" ) ) || 0; + offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop; + scroll = this.activeMenu.scrollTop(); + elementHeight = this.activeMenu.height(); + itemHeight = item.outerHeight(); + + if ( offset < 0 ) { + this.activeMenu.scrollTop( scroll + offset ); + } else if ( offset + itemHeight > elementHeight ) { + this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight ); + } + } + }, + + blur: function( event, fromFocus ) { + if ( !fromFocus ) { + clearTimeout( this.timer ); + } + + if ( !this.active ) { + return; + } + + this._removeClass( this.active.children( ".ui-menu-item-wrapper" ), + null, "ui-state-active" ); + + this._trigger( "blur", event, { item: this.active } ); + this.active = null; + }, + + _startOpening: function( submenu ) { + clearTimeout( this.timer ); + + // Don't open if already open fixes a Firefox bug that caused a .5 pixel + // shift in the submenu position when mousing over the caret icon + if ( submenu.attr( "aria-hidden" ) !== "true" ) { + return; + } + + this.timer = this._delay( function() { + this._close(); + this._open( submenu ); + }, this.delay ); + }, + + _open: function( submenu ) { + var position = $.extend( { + of: this.active + }, this.options.position ); + + clearTimeout( this.timer ); + this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) ) + .hide() + .attr( "aria-hidden", "true" ); + + submenu + .show() + .removeAttr( "aria-hidden" ) + .attr( "aria-expanded", "true" ) + .position( position ); + }, + + collapseAll: function( event, all ) { + clearTimeout( this.timer ); + this.timer = this._delay( function() { + + // If we were passed an event, look for the submenu that contains the event + var currentMenu = all ? this.element : + $( event && event.target ).closest( this.element.find( ".ui-menu" ) ); + + // If we found no valid submenu ancestor, use the main menu to close all + // sub menus anyway + if ( !currentMenu.length ) { + currentMenu = this.element; + } + + this._close( currentMenu ); + + this.blur( event ); + + // Work around active item staying active after menu is blurred + this._removeClass( currentMenu.find( ".ui-state-active" ), null, "ui-state-active" ); + + this.activeMenu = currentMenu; + }, all ? 0 : this.delay ); + }, + + // With no arguments, closes the currently active menu - if nothing is active + // it closes all menus. If passed an argument, it will search for menus BELOW + _close: function( startMenu ) { + if ( !startMenu ) { + startMenu = this.active ? this.active.parent() : this.element; + } + + startMenu.find( ".ui-menu" ) + .hide() + .attr( "aria-hidden", "true" ) + .attr( "aria-expanded", "false" ); + }, + + _closeOnDocumentClick: function( event ) { + return !$( event.target ).closest( ".ui-menu" ).length; + }, + + _isDivider: function( item ) { + + // Match hyphen, em dash, en dash + return !/[^\-\u2014\u2013\s]/.test( item.text() ); + }, + + collapse: function( event ) { + var newItem = this.active && + this.active.parent().closest( ".ui-menu-item", this.element ); + if ( newItem && newItem.length ) { + this._close(); + this.focus( event, newItem ); + } + }, + + expand: function( event ) { + var newItem = this.active && this._menuItems( this.active.children( ".ui-menu" ) ).first(); + + if ( newItem && newItem.length ) { + this._open( newItem.parent() ); + + // Delay so Firefox will not hide activedescendant change in expanding submenu from AT + this._delay( function() { + this.focus( event, newItem ); + } ); + } + }, + + next: function( event ) { + this._move( "next", "first", event ); + }, + + previous: function( event ) { + this._move( "prev", "last", event ); + }, + + isFirstItem: function() { + return this.active && !this.active.prevAll( ".ui-menu-item" ).length; + }, + + isLastItem: function() { + return this.active && !this.active.nextAll( ".ui-menu-item" ).length; + }, + + _menuItems: function( menu ) { + return ( menu || this.element ) + .find( this.options.items ) + .filter( ".ui-menu-item" ); + }, + + _move: function( direction, filter, event ) { + var next; + if ( this.active ) { + if ( direction === "first" || direction === "last" ) { + next = this.active + [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" ) + .last(); + } else { + next = this.active + [ direction + "All" ]( ".ui-menu-item" ) + .first(); + } + } + if ( !next || !next.length || !this.active ) { + next = this._menuItems( this.activeMenu )[ filter ](); + } + + this.focus( event, next ); + }, + + nextPage: function( event ) { + var item, base, height; + + if ( !this.active ) { + this.next( event ); + return; + } + if ( this.isLastItem() ) { + return; + } + if ( this._hasScroll() ) { + base = this.active.offset().top; + height = this.element.innerHeight(); + + // jQuery 3.2 doesn't include scrollbars in innerHeight, add it back. + if ( $.fn.jquery.indexOf( "3.2." ) === 0 ) { + height += this.element[ 0 ].offsetHeight - this.element.outerHeight(); + } + + this.active.nextAll( ".ui-menu-item" ).each( function() { + item = $( this ); + return item.offset().top - base - height < 0; + } ); + + this.focus( event, item ); + } else { + this.focus( event, this._menuItems( this.activeMenu ) + [ !this.active ? "first" : "last" ]() ); + } + }, + + previousPage: function( event ) { + var item, base, height; + if ( !this.active ) { + this.next( event ); + return; + } + if ( this.isFirstItem() ) { + return; + } + if ( this._hasScroll() ) { + base = this.active.offset().top; + height = this.element.innerHeight(); + + // jQuery 3.2 doesn't include scrollbars in innerHeight, add it back. + if ( $.fn.jquery.indexOf( "3.2." ) === 0 ) { + height += this.element[ 0 ].offsetHeight - this.element.outerHeight(); + } + + this.active.prevAll( ".ui-menu-item" ).each( function() { + item = $( this ); + return item.offset().top - base + height > 0; + } ); + + this.focus( event, item ); + } else { + this.focus( event, this._menuItems( this.activeMenu ).first() ); + } + }, + + _hasScroll: function() { + return this.element.outerHeight() < this.element.prop( "scrollHeight" ); + }, + + select: function( event ) { + + // TODO: It should never be possible to not have an active item at this + // point, but the tests don't trigger mouseenter before click. + this.active = this.active || $( event.target ).closest( ".ui-menu-item" ); + var ui = { item: this.active }; + if ( !this.active.has( ".ui-menu" ).length ) { + this.collapseAll( event, true ); + } + this._trigger( "select", event, ui ); + }, + + _filterMenuItems: function( character ) { + var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ), + regex = new RegExp( "^" + escapedCharacter, "i" ); + + return this.activeMenu + .find( this.options.items ) + + // Only match on items, not dividers or other content (#10571) + .filter( ".ui-menu-item" ) + .filter( function() { + return regex.test( + String.prototype.trim.call( + $( this ).children( ".ui-menu-item-wrapper" ).text() ) ); + } ); + } + } ); } ); diff --git a/lib/web/jquery/ui-modules/widgets/mouse.js b/lib/web/jquery/ui-modules/widgets/mouse.js index 8a9b7b75ba076..83a0e028fd763 100644 --- a/lib/web/jquery/ui-modules/widgets/mouse.js +++ b/lib/web/jquery/ui-modules/widgets/mouse.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Mouse 1.13.1 + * jQuery UI Mouse 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -13,225 +13,225 @@ //>>docs: http://api.jqueryui.com/mouse/ ( function( factory ) { - "use strict"; - - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define( [ - "jquery", - "../ie", - "../version", - "../widget" - ], factory ); - } else { - - // Browser globals - factory( jQuery ); - } + "use strict"; + + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ + "jquery", + "../ie", + "../version", + "../widget" + ], factory ); + } else { + + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; - -var mouseHandled = false; -$( document ).on( "mouseup", function() { - mouseHandled = false; -} ); - -return $.widget( "ui.mouse", { - version: "1.13.1", - options: { - cancel: "input, textarea, button, select, option", - distance: 1, - delay: 0 - }, - _mouseInit: function() { - var that = this; - - this.element - .on( "mousedown." + this.widgetName, function( event ) { - return that._mouseDown( event ); - } ) - .on( "click." + this.widgetName, function( event ) { - if ( true === $.data( event.target, that.widgetName + ".preventClickEvent" ) ) { - $.removeData( event.target, that.widgetName + ".preventClickEvent" ); - event.stopImmediatePropagation(); - return false; - } - } ); - - this.started = false; - }, - - // TODO: make sure destroying one instance of mouse doesn't mess with - // other instances of mouse - _mouseDestroy: function() { - this.element.off( "." + this.widgetName ); - if ( this._mouseMoveDelegate ) { - this.document - .off( "mousemove." + this.widgetName, this._mouseMoveDelegate ) - .off( "mouseup." + this.widgetName, this._mouseUpDelegate ); - } - }, - - _mouseDown: function( event ) { - - // don't let more than one widget handle mouseStart - if ( mouseHandled ) { - return; - } - - this._mouseMoved = false; - - // We may have missed mouseup (out of window) - if ( this._mouseStarted ) { - this._mouseUp( event ); - } - - this._mouseDownEvent = event; - - var that = this, - btnIsLeft = ( event.which === 1 ), - - // event.target.nodeName works around a bug in IE 8 with - // disabled inputs (#7620) - elIsCancel = ( typeof this.options.cancel === "string" && event.target.nodeName ? - $( event.target ).closest( this.options.cancel ).length : false ); - if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) { - return true; - } - - this.mouseDelayMet = !this.options.delay; - if ( !this.mouseDelayMet ) { - this._mouseDelayTimer = setTimeout( function() { - that.mouseDelayMet = true; - }, this.options.delay ); - } - - if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) { - this._mouseStarted = ( this._mouseStart( event ) !== false ); - if ( !this._mouseStarted ) { - event.preventDefault(); - return true; - } - } - - // Click event may never have fired (Gecko & Opera) - if ( true === $.data( event.target, this.widgetName + ".preventClickEvent" ) ) { - $.removeData( event.target, this.widgetName + ".preventClickEvent" ); - } - - // These delegates are required to keep context - this._mouseMoveDelegate = function( event ) { - return that._mouseMove( event ); - }; - this._mouseUpDelegate = function( event ) { - return that._mouseUp( event ); - }; - - this.document - .on( "mousemove." + this.widgetName, this._mouseMoveDelegate ) - .on( "mouseup." + this.widgetName, this._mouseUpDelegate ); - - event.preventDefault(); - - mouseHandled = true; - return true; - }, - - _mouseMove: function( event ) { - - // Only check for mouseups outside the document if you've moved inside the document - // at least once. This prevents the firing of mouseup in the case of IE<9, which will - // fire a mousemove event if content is placed under the cursor. See #7778 - // Support: IE <9 - if ( this._mouseMoved ) { - - // IE mouseup check - mouseup happened when mouse was out of window - if ( $.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && - !event.button ) { - return this._mouseUp( event ); - - // Iframe mouseup check - mouseup occurred in another document - } else if ( !event.which ) { - - // Support: Safari <=8 - 9 - // Safari sets which to 0 if you press any of the following keys - // during a drag (#14461) - if ( event.originalEvent.altKey || event.originalEvent.ctrlKey || - event.originalEvent.metaKey || event.originalEvent.shiftKey ) { - this.ignoreMissingWhich = true; - } else if ( !this.ignoreMissingWhich ) { - return this._mouseUp( event ); - } - } - } - - if ( event.which || event.button ) { - this._mouseMoved = true; - } - - if ( this._mouseStarted ) { - this._mouseDrag( event ); - return event.preventDefault(); - } - - if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) { - this._mouseStarted = - ( this._mouseStart( this._mouseDownEvent, event ) !== false ); - if ( this._mouseStarted ) { - this._mouseDrag( event ); - } else { - this._mouseUp( event ); - } - } - - return !this._mouseStarted; - }, - - _mouseUp: function( event ) { - this.document - .off( "mousemove." + this.widgetName, this._mouseMoveDelegate ) - .off( "mouseup." + this.widgetName, this._mouseUpDelegate ); - - if ( this._mouseStarted ) { - this._mouseStarted = false; - - if ( event.target === this._mouseDownEvent.target ) { - $.data( event.target, this.widgetName + ".preventClickEvent", true ); - } - - this._mouseStop( event ); - } - - if ( this._mouseDelayTimer ) { - clearTimeout( this._mouseDelayTimer ); - delete this._mouseDelayTimer; - } - - this.ignoreMissingWhich = false; - mouseHandled = false; - event.preventDefault(); - }, - - _mouseDistanceMet: function( event ) { - return ( Math.max( - Math.abs( this._mouseDownEvent.pageX - event.pageX ), - Math.abs( this._mouseDownEvent.pageY - event.pageY ) - ) >= this.options.distance - ); - }, - - _mouseDelayMet: function( /* event */ ) { - return this.mouseDelayMet; - }, - - // These are placeholder methods, to be overriden by extending plugin - _mouseStart: function( /* event */ ) {}, - _mouseDrag: function( /* event */ ) {}, - _mouseStop: function( /* event */ ) {}, - _mouseCapture: function( /* event */ ) { - return true; - } -} ); + "use strict"; + + var mouseHandled = false; + $( document ).on( "mouseup", function() { + mouseHandled = false; + } ); + + return $.widget( "ui.mouse", { + version: "1.13.2", + options: { + cancel: "input, textarea, button, select, option", + distance: 1, + delay: 0 + }, + _mouseInit: function() { + var that = this; + + this.element + .on( "mousedown." + this.widgetName, function( event ) { + return that._mouseDown( event ); + } ) + .on( "click." + this.widgetName, function( event ) { + if ( true === $.data( event.target, that.widgetName + ".preventClickEvent" ) ) { + $.removeData( event.target, that.widgetName + ".preventClickEvent" ); + event.stopImmediatePropagation(); + return false; + } + } ); + + this.started = false; + }, + + // TODO: make sure destroying one instance of mouse doesn't mess with + // other instances of mouse + _mouseDestroy: function() { + this.element.off( "." + this.widgetName ); + if ( this._mouseMoveDelegate ) { + this.document + .off( "mousemove." + this.widgetName, this._mouseMoveDelegate ) + .off( "mouseup." + this.widgetName, this._mouseUpDelegate ); + } + }, + + _mouseDown: function( event ) { + + // don't let more than one widget handle mouseStart + if ( mouseHandled ) { + return; + } + + this._mouseMoved = false; + + // We may have missed mouseup (out of window) + if ( this._mouseStarted ) { + this._mouseUp( event ); + } + + this._mouseDownEvent = event; + + var that = this, + btnIsLeft = ( event.which === 1 ), + + // event.target.nodeName works around a bug in IE 8 with + // disabled inputs (#7620) + elIsCancel = ( typeof this.options.cancel === "string" && event.target.nodeName ? + $( event.target ).closest( this.options.cancel ).length : false ); + if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) { + return true; + } + + this.mouseDelayMet = !this.options.delay; + if ( !this.mouseDelayMet ) { + this._mouseDelayTimer = setTimeout( function() { + that.mouseDelayMet = true; + }, this.options.delay ); + } + + if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) { + this._mouseStarted = ( this._mouseStart( event ) !== false ); + if ( !this._mouseStarted ) { + event.preventDefault(); + return true; + } + } + + // Click event may never have fired (Gecko & Opera) + if ( true === $.data( event.target, this.widgetName + ".preventClickEvent" ) ) { + $.removeData( event.target, this.widgetName + ".preventClickEvent" ); + } + + // These delegates are required to keep context + this._mouseMoveDelegate = function( event ) { + return that._mouseMove( event ); + }; + this._mouseUpDelegate = function( event ) { + return that._mouseUp( event ); + }; + + this.document + .on( "mousemove." + this.widgetName, this._mouseMoveDelegate ) + .on( "mouseup." + this.widgetName, this._mouseUpDelegate ); + + event.preventDefault(); + + mouseHandled = true; + return true; + }, + + _mouseMove: function( event ) { + + // Only check for mouseups outside the document if you've moved inside the document + // at least once. This prevents the firing of mouseup in the case of IE<9, which will + // fire a mousemove event if content is placed under the cursor. See #7778 + // Support: IE <9 + if ( this._mouseMoved ) { + + // IE mouseup check - mouseup happened when mouse was out of window + if ( $.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && + !event.button ) { + return this._mouseUp( event ); + + // Iframe mouseup check - mouseup occurred in another document + } else if ( !event.which ) { + + // Support: Safari <=8 - 9 + // Safari sets which to 0 if you press any of the following keys + // during a drag (#14461) + if ( event.originalEvent.altKey || event.originalEvent.ctrlKey || + event.originalEvent.metaKey || event.originalEvent.shiftKey ) { + this.ignoreMissingWhich = true; + } else if ( !this.ignoreMissingWhich ) { + return this._mouseUp( event ); + } + } + } + + if ( event.which || event.button ) { + this._mouseMoved = true; + } + + if ( this._mouseStarted ) { + this._mouseDrag( event ); + return event.preventDefault(); + } + + if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) { + this._mouseStarted = + ( this._mouseStart( this._mouseDownEvent, event ) !== false ); + if ( this._mouseStarted ) { + this._mouseDrag( event ); + } else { + this._mouseUp( event ); + } + } + + return !this._mouseStarted; + }, + + _mouseUp: function( event ) { + this.document + .off( "mousemove." + this.widgetName, this._mouseMoveDelegate ) + .off( "mouseup." + this.widgetName, this._mouseUpDelegate ); + + if ( this._mouseStarted ) { + this._mouseStarted = false; + + if ( event.target === this._mouseDownEvent.target ) { + $.data( event.target, this.widgetName + ".preventClickEvent", true ); + } + + this._mouseStop( event ); + } + + if ( this._mouseDelayTimer ) { + clearTimeout( this._mouseDelayTimer ); + delete this._mouseDelayTimer; + } + + this.ignoreMissingWhich = false; + mouseHandled = false; + event.preventDefault(); + }, + + _mouseDistanceMet: function( event ) { + return ( Math.max( + Math.abs( this._mouseDownEvent.pageX - event.pageX ), + Math.abs( this._mouseDownEvent.pageY - event.pageY ) + ) >= this.options.distance + ); + }, + + _mouseDelayMet: function( /* event */ ) { + return this.mouseDelayMet; + }, + + // These are placeholder methods, to be overriden by extending plugin + _mouseStart: function( /* event */ ) {}, + _mouseDrag: function( /* event */ ) {}, + _mouseStop: function( /* event */ ) {}, + _mouseCapture: function( /* event */ ) { + return true; + } + } ); } ); diff --git a/lib/web/jquery/ui-modules/widgets/progressbar.js b/lib/web/jquery/ui-modules/widgets/progressbar.js index 0dfac693cc85c..27d1689c2e4cc 100644 --- a/lib/web/jquery/ui-modules/widgets/progressbar.js +++ b/lib/web/jquery/ui-modules/widgets/progressbar.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Progressbar 1.13.1 + * jQuery UI Progressbar 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -19,163 +19,163 @@ //>>css.theme: ../../themes/base/theme.css ( function( factory ) { - "use strict"; + "use strict"; - if ( typeof define === "function" && define.amd ) { + if ( typeof define === "function" && define.amd ) { - // AMD. Register as an anonymous module. - define( [ - "jquery", - "../version", - "../widget" - ], factory ); - } else { + // AMD. Register as an anonymous module. + define( [ + "jquery", + "../version", + "../widget" + ], factory ); + } else { - // Browser globals - factory( jQuery ); - } + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; + "use strict"; -return $.widget( "ui.progressbar", { - version: "1.13.1", - options: { - classes: { - "ui-progressbar": "ui-corner-all", - "ui-progressbar-value": "ui-corner-left", - "ui-progressbar-complete": "ui-corner-right" - }, - max: 100, - value: 0, + return $.widget( "ui.progressbar", { + version: "1.13.2", + options: { + classes: { + "ui-progressbar": "ui-corner-all", + "ui-progressbar-value": "ui-corner-left", + "ui-progressbar-complete": "ui-corner-right" + }, + max: 100, + value: 0, - change: null, - complete: null - }, + change: null, + complete: null + }, - min: 0, + min: 0, - _create: function() { - - // Constrain initial value - this.oldValue = this.options.value = this._constrainedValue(); - - this.element.attr( { - - // Only set static values; aria-valuenow and aria-valuemax are - // set inside _refreshValue() - role: "progressbar", - "aria-valuemin": this.min - } ); - this._addClass( "ui-progressbar", "ui-widget ui-widget-content" ); - - this.valueDiv = $( "<div>" ).appendTo( this.element ); - this._addClass( this.valueDiv, "ui-progressbar-value", "ui-widget-header" ); - this._refreshValue(); - }, - - _destroy: function() { - this.element.removeAttr( "role aria-valuemin aria-valuemax aria-valuenow" ); - - this.valueDiv.remove(); - }, - - value: function( newValue ) { - if ( newValue === undefined ) { - return this.options.value; - } - - this.options.value = this._constrainedValue( newValue ); - this._refreshValue(); - }, - - _constrainedValue: function( newValue ) { - if ( newValue === undefined ) { - newValue = this.options.value; - } - - this.indeterminate = newValue === false; - - // Sanitize value - if ( typeof newValue !== "number" ) { - newValue = 0; - } - - return this.indeterminate ? false : - Math.min( this.options.max, Math.max( this.min, newValue ) ); - }, - - _setOptions: function( options ) { - - // Ensure "value" option is set after other values (like max) - var value = options.value; - delete options.value; - - this._super( options ); - - this.options.value = this._constrainedValue( value ); - this._refreshValue(); - }, - - _setOption: function( key, value ) { - if ( key === "max" ) { - - // Don't allow a max less than min - value = Math.max( this.min, value ); - } - this._super( key, value ); - }, - - _setOptionDisabled: function( value ) { - this._super( value ); - - this.element.attr( "aria-disabled", value ); - this._toggleClass( null, "ui-state-disabled", !!value ); - }, - - _percentage: function() { - return this.indeterminate ? - 100 : - 100 * ( this.options.value - this.min ) / ( this.options.max - this.min ); - }, - - _refreshValue: function() { - var value = this.options.value, - percentage = this._percentage(); - - this.valueDiv - .toggle( this.indeterminate || value > this.min ) - .width( percentage.toFixed( 0 ) + "%" ); - - this - ._toggleClass( this.valueDiv, "ui-progressbar-complete", null, - value === this.options.max ) - ._toggleClass( "ui-progressbar-indeterminate", null, this.indeterminate ); - - if ( this.indeterminate ) { - this.element.removeAttr( "aria-valuenow" ); - if ( !this.overlayDiv ) { - this.overlayDiv = $( "<div>" ).appendTo( this.valueDiv ); - this._addClass( this.overlayDiv, "ui-progressbar-overlay" ); - } - } else { - this.element.attr( { - "aria-valuemax": this.options.max, - "aria-valuenow": value - } ); - if ( this.overlayDiv ) { - this.overlayDiv.remove(); - this.overlayDiv = null; - } - } - - if ( this.oldValue !== value ) { - this.oldValue = value; - this._trigger( "change" ); - } - if ( value === this.options.max ) { - this._trigger( "complete" ); - } - } -} ); + _create: function() { + + // Constrain initial value + this.oldValue = this.options.value = this._constrainedValue(); + + this.element.attr( { + + // Only set static values; aria-valuenow and aria-valuemax are + // set inside _refreshValue() + role: "progressbar", + "aria-valuemin": this.min + } ); + this._addClass( "ui-progressbar", "ui-widget ui-widget-content" ); + + this.valueDiv = $( "<div>" ).appendTo( this.element ); + this._addClass( this.valueDiv, "ui-progressbar-value", "ui-widget-header" ); + this._refreshValue(); + }, + + _destroy: function() { + this.element.removeAttr( "role aria-valuemin aria-valuemax aria-valuenow" ); + + this.valueDiv.remove(); + }, + + value: function( newValue ) { + if ( newValue === undefined ) { + return this.options.value; + } + + this.options.value = this._constrainedValue( newValue ); + this._refreshValue(); + }, + + _constrainedValue: function( newValue ) { + if ( newValue === undefined ) { + newValue = this.options.value; + } + + this.indeterminate = newValue === false; + + // Sanitize value + if ( typeof newValue !== "number" ) { + newValue = 0; + } + + return this.indeterminate ? false : + Math.min( this.options.max, Math.max( this.min, newValue ) ); + }, + + _setOptions: function( options ) { + + // Ensure "value" option is set after other values (like max) + var value = options.value; + delete options.value; + + this._super( options ); + + this.options.value = this._constrainedValue( value ); + this._refreshValue(); + }, + + _setOption: function( key, value ) { + if ( key === "max" ) { + + // Don't allow a max less than min + value = Math.max( this.min, value ); + } + this._super( key, value ); + }, + + _setOptionDisabled: function( value ) { + this._super( value ); + + this.element.attr( "aria-disabled", value ); + this._toggleClass( null, "ui-state-disabled", !!value ); + }, + + _percentage: function() { + return this.indeterminate ? + 100 : + 100 * ( this.options.value - this.min ) / ( this.options.max - this.min ); + }, + + _refreshValue: function() { + var value = this.options.value, + percentage = this._percentage(); + + this.valueDiv + .toggle( this.indeterminate || value > this.min ) + .width( percentage.toFixed( 0 ) + "%" ); + + this + ._toggleClass( this.valueDiv, "ui-progressbar-complete", null, + value === this.options.max ) + ._toggleClass( "ui-progressbar-indeterminate", null, this.indeterminate ); + + if ( this.indeterminate ) { + this.element.removeAttr( "aria-valuenow" ); + if ( !this.overlayDiv ) { + this.overlayDiv = $( "<div>" ).appendTo( this.valueDiv ); + this._addClass( this.overlayDiv, "ui-progressbar-overlay" ); + } + } else { + this.element.attr( { + "aria-valuemax": this.options.max, + "aria-valuenow": value + } ); + if ( this.overlayDiv ) { + this.overlayDiv.remove(); + this.overlayDiv = null; + } + } + + if ( this.oldValue !== value ) { + this.oldValue = value; + this._trigger( "change" ); + } + if ( value === this.options.max ) { + this._trigger( "complete" ); + } + } + } ); } ); diff --git a/lib/web/jquery/ui-modules/widgets/resizable.js b/lib/web/jquery/ui-modules/widgets/resizable.js index 3763065666f7c..b35ddd4619f42 100644 --- a/lib/web/jquery/ui-modules/widgets/resizable.js +++ b/lib/web/jquery/ui-modules/widgets/resizable.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Resizable 1.13.1 + * jQuery UI Resizable 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -17,1203 +17,1203 @@ //>>css.theme: ../../themes/base/theme.css ( function( factory ) { - "use strict"; - - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define( [ - "jquery", - "./mouse", - "../disable-selection", - "../plugin", - "../version", - "../widget" - ], factory ); - } else { - - // Browser globals - factory( jQuery ); - } + "use strict"; + + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ + "jquery", + "./mouse", + "../disable-selection", + "../plugin", + "../version", + "../widget" + ], factory ); + } else { + + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; - -$.widget( "ui.resizable", $.ui.mouse, { - version: "1.13.1", - widgetEventPrefix: "resize", - options: { - alsoResize: false, - animate: false, - animateDuration: "slow", - animateEasing: "swing", - aspectRatio: false, - autoHide: false, - classes: { - "ui-resizable-se": "ui-icon ui-icon-gripsmall-diagonal-se" - }, - containment: false, - ghost: false, - grid: false, - handles: "e,s,se", - helper: false, - maxHeight: null, - maxWidth: null, - minHeight: 10, - minWidth: 10, - - // See #7960 - zIndex: 90, - - // Callbacks - resize: null, - start: null, - stop: null - }, - - _num: function( value ) { - return parseFloat( value ) || 0; - }, - - _isNumber: function( value ) { - return !isNaN( parseFloat( value ) ); - }, - - _hasScroll: function( el, a ) { - - if ( $( el ).css( "overflow" ) === "hidden" ) { - return false; - } - - var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop", - has = false; - - if ( el[ scroll ] > 0 ) { - return true; - } - - // TODO: determine which cases actually cause this to happen - // if the element doesn't have the scroll set, see if it's possible to - // set the scroll - try { - el[ scroll ] = 1; - has = ( el[ scroll ] > 0 ); - el[ scroll ] = 0; - } catch ( e ) { - - // `el` might be a string, then setting `scroll` will throw - // an error in strict mode; ignore it. - } - return has; - }, - - _create: function() { - - var margins, - o = this.options, - that = this; - this._addClass( "ui-resizable" ); - - $.extend( this, { - _aspectRatio: !!( o.aspectRatio ), - aspectRatio: o.aspectRatio, - originalElement: this.element, - _proportionallyResizeElements: [], - _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null - } ); - - // Wrap the element if it cannot hold child nodes - if ( this.element[ 0 ].nodeName.match( /^(canvas|textarea|input|select|button|img)$/i ) ) { - - this.element.wrap( - $( "<div class='ui-wrapper'></div>" ).css( { - overflow: "hidden", - position: this.element.css( "position" ), - width: this.element.outerWidth(), - height: this.element.outerHeight(), - top: this.element.css( "top" ), - left: this.element.css( "left" ) - } ) - ); - - this.element = this.element.parent().data( - "ui-resizable", this.element.resizable( "instance" ) - ); - - this.elementIsWrapper = true; - - margins = { - marginTop: this.originalElement.css( "marginTop" ), - marginRight: this.originalElement.css( "marginRight" ), - marginBottom: this.originalElement.css( "marginBottom" ), - marginLeft: this.originalElement.css( "marginLeft" ) - }; - - this.element.css( margins ); - this.originalElement.css( "margin", 0 ); - - // support: Safari - // Prevent Safari textarea resize - this.originalResizeStyle = this.originalElement.css( "resize" ); - this.originalElement.css( "resize", "none" ); - - this._proportionallyResizeElements.push( this.originalElement.css( { - position: "static", - zoom: 1, - display: "block" - } ) ); - - // Support: IE9 - // avoid IE jump (hard set the margin) - this.originalElement.css( margins ); - - this._proportionallyResize(); - } - - this._setupHandles(); - - if ( o.autoHide ) { - $( this.element ) - .on( "mouseenter", function() { - if ( o.disabled ) { - return; - } - that._removeClass( "ui-resizable-autohide" ); - that._handles.show(); - } ) - .on( "mouseleave", function() { - if ( o.disabled ) { - return; - } - if ( !that.resizing ) { - that._addClass( "ui-resizable-autohide" ); - that._handles.hide(); - } - } ); - } - - this._mouseInit(); - }, - - _destroy: function() { - - this._mouseDestroy(); - this._addedHandles.remove(); - - var wrapper, - _destroy = function( exp ) { - $( exp ) - .removeData( "resizable" ) - .removeData( "ui-resizable" ) - .off( ".resizable" ); - }; - - // TODO: Unwrap at same DOM position - if ( this.elementIsWrapper ) { - _destroy( this.element ); - wrapper = this.element; - this.originalElement.css( { - position: wrapper.css( "position" ), - width: wrapper.outerWidth(), - height: wrapper.outerHeight(), - top: wrapper.css( "top" ), - left: wrapper.css( "left" ) - } ).insertAfter( wrapper ); - wrapper.remove(); - } - - this.originalElement.css( "resize", this.originalResizeStyle ); - _destroy( this.originalElement ); - - return this; - }, - - _setOption: function( key, value ) { - this._super( key, value ); - - switch ( key ) { - case "handles": - this._removeHandles(); - this._setupHandles(); - break; - case "aspectRatio": - this._aspectRatio = !!value; - break; - default: - break; - } - }, - - _setupHandles: function() { - var o = this.options, handle, i, n, hname, axis, that = this; - this.handles = o.handles || - ( !$( ".ui-resizable-handle", this.element ).length ? - "e,s,se" : { - n: ".ui-resizable-n", - e: ".ui-resizable-e", - s: ".ui-resizable-s", - w: ".ui-resizable-w", - se: ".ui-resizable-se", - sw: ".ui-resizable-sw", - ne: ".ui-resizable-ne", - nw: ".ui-resizable-nw" - } ); - - this._handles = $(); - this._addedHandles = $(); - if ( this.handles.constructor === String ) { - - if ( this.handles === "all" ) { - this.handles = "n,e,s,w,se,sw,ne,nw"; - } - - n = this.handles.split( "," ); - this.handles = {}; - - for ( i = 0; i < n.length; i++ ) { - - handle = String.prototype.trim.call( n[ i ] ); - hname = "ui-resizable-" + handle; - axis = $( "<div>" ); - this._addClass( axis, "ui-resizable-handle " + hname ); - - axis.css( { zIndex: o.zIndex } ); - - this.handles[ handle ] = ".ui-resizable-" + handle; - if ( !this.element.children( this.handles[ handle ] ).length ) { - this.element.append( axis ); - this._addedHandles = this._addedHandles.add( axis ); - } - } - - } - - this._renderAxis = function( target ) { - - var i, axis, padPos, padWrapper; - - target = target || this.element; - - for ( i in this.handles ) { - - if ( this.handles[ i ].constructor === String ) { - this.handles[ i ] = this.element.children( this.handles[ i ] ).first().show(); - } else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) { - this.handles[ i ] = $( this.handles[ i ] ); - this._on( this.handles[ i ], { "mousedown": that._mouseDown } ); - } - - if ( this.elementIsWrapper && - this.originalElement[ 0 ] - .nodeName - .match( /^(textarea|input|select|button)$/i ) ) { - axis = $( this.handles[ i ], this.element ); - - padWrapper = /sw|ne|nw|se|n|s/.test( i ) ? - axis.outerHeight() : - axis.outerWidth(); - - padPos = [ "padding", - /ne|nw|n/.test( i ) ? "Top" : - /se|sw|s/.test( i ) ? "Bottom" : - /^e$/.test( i ) ? "Right" : "Left" ].join( "" ); - - target.css( padPos, padWrapper ); - - this._proportionallyResize(); - } - - this._handles = this._handles.add( this.handles[ i ] ); - } - }; - - // TODO: make renderAxis a prototype function - this._renderAxis( this.element ); - - this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) ); - this._handles.disableSelection(); - - this._handles.on( "mouseover", function() { - if ( !that.resizing ) { - if ( this.className ) { - axis = this.className.match( /ui-resizable-(se|sw|ne|nw|n|e|s|w)/i ); - } - that.axis = axis && axis[ 1 ] ? axis[ 1 ] : "se"; - } - } ); - - if ( o.autoHide ) { - this._handles.hide(); - this._addClass( "ui-resizable-autohide" ); - } - }, - - _removeHandles: function() { - this._addedHandles.remove(); - }, + "use strict"; + + $.widget( "ui.resizable", $.ui.mouse, { + version: "1.13.2", + widgetEventPrefix: "resize", + options: { + alsoResize: false, + animate: false, + animateDuration: "slow", + animateEasing: "swing", + aspectRatio: false, + autoHide: false, + classes: { + "ui-resizable-se": "ui-icon ui-icon-gripsmall-diagonal-se" + }, + containment: false, + ghost: false, + grid: false, + handles: "e,s,se", + helper: false, + maxHeight: null, + maxWidth: null, + minHeight: 10, + minWidth: 10, + + // See #7960 + zIndex: 90, + + // Callbacks + resize: null, + start: null, + stop: null + }, + + _num: function( value ) { + return parseFloat( value ) || 0; + }, + + _isNumber: function( value ) { + return !isNaN( parseFloat( value ) ); + }, + + _hasScroll: function( el, a ) { + + if ( $( el ).css( "overflow" ) === "hidden" ) { + return false; + } + + var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop", + has = false; + + if ( el[ scroll ] > 0 ) { + return true; + } + + // TODO: determine which cases actually cause this to happen + // if the element doesn't have the scroll set, see if it's possible to + // set the scroll + try { + el[ scroll ] = 1; + has = ( el[ scroll ] > 0 ); + el[ scroll ] = 0; + } catch ( e ) { + + // `el` might be a string, then setting `scroll` will throw + // an error in strict mode; ignore it. + } + return has; + }, + + _create: function() { + + var margins, + o = this.options, + that = this; + this._addClass( "ui-resizable" ); + + $.extend( this, { + _aspectRatio: !!( o.aspectRatio ), + aspectRatio: o.aspectRatio, + originalElement: this.element, + _proportionallyResizeElements: [], + _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null + } ); + + // Wrap the element if it cannot hold child nodes + if ( this.element[ 0 ].nodeName.match( /^(canvas|textarea|input|select|button|img)$/i ) ) { + + this.element.wrap( + $( "<div class='ui-wrapper'></div>" ).css( { + overflow: "hidden", + position: this.element.css( "position" ), + width: this.element.outerWidth(), + height: this.element.outerHeight(), + top: this.element.css( "top" ), + left: this.element.css( "left" ) + } ) + ); + + this.element = this.element.parent().data( + "ui-resizable", this.element.resizable( "instance" ) + ); + + this.elementIsWrapper = true; + + margins = { + marginTop: this.originalElement.css( "marginTop" ), + marginRight: this.originalElement.css( "marginRight" ), + marginBottom: this.originalElement.css( "marginBottom" ), + marginLeft: this.originalElement.css( "marginLeft" ) + }; + + this.element.css( margins ); + this.originalElement.css( "margin", 0 ); + + // support: Safari + // Prevent Safari textarea resize + this.originalResizeStyle = this.originalElement.css( "resize" ); + this.originalElement.css( "resize", "none" ); + + this._proportionallyResizeElements.push( this.originalElement.css( { + position: "static", + zoom: 1, + display: "block" + } ) ); + + // Support: IE9 + // avoid IE jump (hard set the margin) + this.originalElement.css( margins ); + + this._proportionallyResize(); + } + + this._setupHandles(); + + if ( o.autoHide ) { + $( this.element ) + .on( "mouseenter", function() { + if ( o.disabled ) { + return; + } + that._removeClass( "ui-resizable-autohide" ); + that._handles.show(); + } ) + .on( "mouseleave", function() { + if ( o.disabled ) { + return; + } + if ( !that.resizing ) { + that._addClass( "ui-resizable-autohide" ); + that._handles.hide(); + } + } ); + } + + this._mouseInit(); + }, + + _destroy: function() { + + this._mouseDestroy(); + this._addedHandles.remove(); + + var wrapper, + _destroy = function( exp ) { + $( exp ) + .removeData( "resizable" ) + .removeData( "ui-resizable" ) + .off( ".resizable" ); + }; + + // TODO: Unwrap at same DOM position + if ( this.elementIsWrapper ) { + _destroy( this.element ); + wrapper = this.element; + this.originalElement.css( { + position: wrapper.css( "position" ), + width: wrapper.outerWidth(), + height: wrapper.outerHeight(), + top: wrapper.css( "top" ), + left: wrapper.css( "left" ) + } ).insertAfter( wrapper ); + wrapper.remove(); + } + + this.originalElement.css( "resize", this.originalResizeStyle ); + _destroy( this.originalElement ); + + return this; + }, + + _setOption: function( key, value ) { + this._super( key, value ); + + switch ( key ) { + case "handles": + this._removeHandles(); + this._setupHandles(); + break; + case "aspectRatio": + this._aspectRatio = !!value; + break; + default: + break; + } + }, + + _setupHandles: function() { + var o = this.options, handle, i, n, hname, axis, that = this; + this.handles = o.handles || + ( !$( ".ui-resizable-handle", this.element ).length ? + "e,s,se" : { + n: ".ui-resizable-n", + e: ".ui-resizable-e", + s: ".ui-resizable-s", + w: ".ui-resizable-w", + se: ".ui-resizable-se", + sw: ".ui-resizable-sw", + ne: ".ui-resizable-ne", + nw: ".ui-resizable-nw" + } ); + + this._handles = $(); + this._addedHandles = $(); + if ( this.handles.constructor === String ) { + + if ( this.handles === "all" ) { + this.handles = "n,e,s,w,se,sw,ne,nw"; + } + + n = this.handles.split( "," ); + this.handles = {}; + + for ( i = 0; i < n.length; i++ ) { + + handle = String.prototype.trim.call( n[ i ] ); + hname = "ui-resizable-" + handle; + axis = $( "<div>" ); + this._addClass( axis, "ui-resizable-handle " + hname ); + + axis.css( { zIndex: o.zIndex } ); + + this.handles[ handle ] = ".ui-resizable-" + handle; + if ( !this.element.children( this.handles[ handle ] ).length ) { + this.element.append( axis ); + this._addedHandles = this._addedHandles.add( axis ); + } + } + + } + + this._renderAxis = function( target ) { + + var i, axis, padPos, padWrapper; + + target = target || this.element; + + for ( i in this.handles ) { + + if ( this.handles[ i ].constructor === String ) { + this.handles[ i ] = this.element.children( this.handles[ i ] ).first().show(); + } else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) { + this.handles[ i ] = $( this.handles[ i ] ); + this._on( this.handles[ i ], { "mousedown": that._mouseDown } ); + } + + if ( this.elementIsWrapper && + this.originalElement[ 0 ] + .nodeName + .match( /^(textarea|input|select|button)$/i ) ) { + axis = $( this.handles[ i ], this.element ); + + padWrapper = /sw|ne|nw|se|n|s/.test( i ) ? + axis.outerHeight() : + axis.outerWidth(); + + padPos = [ "padding", + /ne|nw|n/.test( i ) ? "Top" : + /se|sw|s/.test( i ) ? "Bottom" : + /^e$/.test( i ) ? "Right" : "Left" ].join( "" ); + + target.css( padPos, padWrapper ); + + this._proportionallyResize(); + } + + this._handles = this._handles.add( this.handles[ i ] ); + } + }; + + // TODO: make renderAxis a prototype function + this._renderAxis( this.element ); + + this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) ); + this._handles.disableSelection(); + + this._handles.on( "mouseover", function() { + if ( !that.resizing ) { + if ( this.className ) { + axis = this.className.match( /ui-resizable-(se|sw|ne|nw|n|e|s|w)/i ); + } + that.axis = axis && axis[ 1 ] ? axis[ 1 ] : "se"; + } + } ); + + if ( o.autoHide ) { + this._handles.hide(); + this._addClass( "ui-resizable-autohide" ); + } + }, + + _removeHandles: function() { + this._addedHandles.remove(); + }, - _mouseCapture: function( event ) { - var i, handle, - capture = false; + _mouseCapture: function( event ) { + var i, handle, + capture = false; - for ( i in this.handles ) { - handle = $( this.handles[ i ] )[ 0 ]; - if ( handle === event.target || $.contains( handle, event.target ) ) { - capture = true; - } - } + for ( i in this.handles ) { + handle = $( this.handles[ i ] )[ 0 ]; + if ( handle === event.target || $.contains( handle, event.target ) ) { + capture = true; + } + } - return !this.options.disabled && capture; - }, + return !this.options.disabled && capture; + }, - _mouseStart: function( event ) { + _mouseStart: function( event ) { - var curleft, curtop, cursor, - o = this.options, - el = this.element; + var curleft, curtop, cursor, + o = this.options, + el = this.element; - this.resizing = true; + this.resizing = true; - this._renderProxy(); + this._renderProxy(); - curleft = this._num( this.helper.css( "left" ) ); - curtop = this._num( this.helper.css( "top" ) ); + curleft = this._num( this.helper.css( "left" ) ); + curtop = this._num( this.helper.css( "top" ) ); - if ( o.containment ) { - curleft += $( o.containment ).scrollLeft() || 0; - curtop += $( o.containment ).scrollTop() || 0; - } + if ( o.containment ) { + curleft += $( o.containment ).scrollLeft() || 0; + curtop += $( o.containment ).scrollTop() || 0; + } - this.offset = this.helper.offset(); - this.position = { left: curleft, top: curtop }; + this.offset = this.helper.offset(); + this.position = { left: curleft, top: curtop }; - this.size = this._helper ? { - width: this.helper.width(), - height: this.helper.height() - } : { - width: el.width(), - height: el.height() - }; + this.size = this._helper ? { + width: this.helper.width(), + height: this.helper.height() + } : { + width: el.width(), + height: el.height() + }; - this.originalSize = this._helper ? { - width: el.outerWidth(), - height: el.outerHeight() - } : { - width: el.width(), - height: el.height() - }; + this.originalSize = this._helper ? { + width: el.outerWidth(), + height: el.outerHeight() + } : { + width: el.width(), + height: el.height() + }; - this.sizeDiff = { - width: el.outerWidth() - el.width(), - height: el.outerHeight() - el.height() - }; + this.sizeDiff = { + width: el.outerWidth() - el.width(), + height: el.outerHeight() - el.height() + }; - this.originalPosition = { left: curleft, top: curtop }; - this.originalMousePosition = { left: event.pageX, top: event.pageY }; + this.originalPosition = { left: curleft, top: curtop }; + this.originalMousePosition = { left: event.pageX, top: event.pageY }; - this.aspectRatio = ( typeof o.aspectRatio === "number" ) ? - o.aspectRatio : - ( ( this.originalSize.width / this.originalSize.height ) || 1 ); + this.aspectRatio = ( typeof o.aspectRatio === "number" ) ? + o.aspectRatio : + ( ( this.originalSize.width / this.originalSize.height ) || 1 ); - cursor = $( ".ui-resizable-" + this.axis ).css( "cursor" ); - $( "body" ).css( "cursor", cursor === "auto" ? this.axis + "-resize" : cursor ); + cursor = $( ".ui-resizable-" + this.axis ).css( "cursor" ); + $( "body" ).css( "cursor", cursor === "auto" ? this.axis + "-resize" : cursor ); - this._addClass( "ui-resizable-resizing" ); - this._propagate( "start", event ); - return true; - }, + this._addClass( "ui-resizable-resizing" ); + this._propagate( "start", event ); + return true; + }, - _mouseDrag: function( event ) { + _mouseDrag: function( event ) { - var data, props, - smp = this.originalMousePosition, - a = this.axis, - dx = ( event.pageX - smp.left ) || 0, - dy = ( event.pageY - smp.top ) || 0, - trigger = this._change[ a ]; + var data, props, + smp = this.originalMousePosition, + a = this.axis, + dx = ( event.pageX - smp.left ) || 0, + dy = ( event.pageY - smp.top ) || 0, + trigger = this._change[ a ]; - this._updatePrevProperties(); - - if ( !trigger ) { - return false; - } - - data = trigger.apply( this, [ event, dx, dy ] ); - - this._updateVirtualBoundaries( event.shiftKey ); - if ( this._aspectRatio || event.shiftKey ) { - data = this._updateRatio( data, event ); - } + this._updatePrevProperties(); + + if ( !trigger ) { + return false; + } + + data = trigger.apply( this, [ event, dx, dy ] ); + + this._updateVirtualBoundaries( event.shiftKey ); + if ( this._aspectRatio || event.shiftKey ) { + data = this._updateRatio( data, event ); + } - data = this._respectSize( data, event ); + data = this._respectSize( data, event ); - this._updateCache( data ); + this._updateCache( data ); - this._propagate( "resize", event ); + this._propagate( "resize", event ); - props = this._applyChanges(); + props = this._applyChanges(); - if ( !this._helper && this._proportionallyResizeElements.length ) { - this._proportionallyResize(); - } + if ( !this._helper && this._proportionallyResizeElements.length ) { + this._proportionallyResize(); + } - if ( !$.isEmptyObject( props ) ) { - this._updatePrevProperties(); - this._trigger( "resize", event, this.ui() ); - this._applyChanges(); - } + if ( !$.isEmptyObject( props ) ) { + this._updatePrevProperties(); + this._trigger( "resize", event, this.ui() ); + this._applyChanges(); + } - return false; - }, + return false; + }, - _mouseStop: function( event ) { - - this.resizing = false; - var pr, ista, soffseth, soffsetw, s, left, top, - o = this.options, that = this; - - if ( this._helper ) { - - pr = this._proportionallyResizeElements; - ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ); - soffseth = ista && this._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height; - soffsetw = ista ? 0 : that.sizeDiff.width; - - s = { - width: ( that.helper.width() - soffsetw ), - height: ( that.helper.height() - soffseth ) - }; - left = ( parseFloat( that.element.css( "left" ) ) + - ( that.position.left - that.originalPosition.left ) ) || null; - top = ( parseFloat( that.element.css( "top" ) ) + - ( that.position.top - that.originalPosition.top ) ) || null; - - if ( !o.animate ) { - this.element.css( $.extend( s, { top: top, left: left } ) ); - } - - that.helper.height( that.size.height ); - that.helper.width( that.size.width ); - - if ( this._helper && !o.animate ) { - this._proportionallyResize(); - } - } - - $( "body" ).css( "cursor", "auto" ); - - this._removeClass( "ui-resizable-resizing" ); - - this._propagate( "stop", event ); - - if ( this._helper ) { - this.helper.remove(); - } - - return false; - - }, - - _updatePrevProperties: function() { - this.prevPosition = { - top: this.position.top, - left: this.position.left - }; - this.prevSize = { - width: this.size.width, - height: this.size.height - }; - }, - - _applyChanges: function() { - var props = {}; - - if ( this.position.top !== this.prevPosition.top ) { - props.top = this.position.top + "px"; - } - if ( this.position.left !== this.prevPosition.left ) { - props.left = this.position.left + "px"; - } - if ( this.size.width !== this.prevSize.width ) { - props.width = this.size.width + "px"; - } - if ( this.size.height !== this.prevSize.height ) { - props.height = this.size.height + "px"; - } - - this.helper.css( props ); - - return props; - }, - - _updateVirtualBoundaries: function( forceAspectRatio ) { - var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b, - o = this.options; - - b = { - minWidth: this._isNumber( o.minWidth ) ? o.minWidth : 0, - maxWidth: this._isNumber( o.maxWidth ) ? o.maxWidth : Infinity, - minHeight: this._isNumber( o.minHeight ) ? o.minHeight : 0, - maxHeight: this._isNumber( o.maxHeight ) ? o.maxHeight : Infinity - }; - - if ( this._aspectRatio || forceAspectRatio ) { - pMinWidth = b.minHeight * this.aspectRatio; - pMinHeight = b.minWidth / this.aspectRatio; - pMaxWidth = b.maxHeight * this.aspectRatio; - pMaxHeight = b.maxWidth / this.aspectRatio; - - if ( pMinWidth > b.minWidth ) { - b.minWidth = pMinWidth; - } - if ( pMinHeight > b.minHeight ) { - b.minHeight = pMinHeight; - } - if ( pMaxWidth < b.maxWidth ) { - b.maxWidth = pMaxWidth; - } - if ( pMaxHeight < b.maxHeight ) { - b.maxHeight = pMaxHeight; - } - } - this._vBoundaries = b; - }, - - _updateCache: function( data ) { - this.offset = this.helper.offset(); - if ( this._isNumber( data.left ) ) { - this.position.left = data.left; - } - if ( this._isNumber( data.top ) ) { - this.position.top = data.top; - } - if ( this._isNumber( data.height ) ) { - this.size.height = data.height; - } - if ( this._isNumber( data.width ) ) { - this.size.width = data.width; - } - }, - - _updateRatio: function( data ) { - - var cpos = this.position, - csize = this.size, - a = this.axis; - - if ( this._isNumber( data.height ) ) { - data.width = ( data.height * this.aspectRatio ); - } else if ( this._isNumber( data.width ) ) { - data.height = ( data.width / this.aspectRatio ); - } - - if ( a === "sw" ) { - data.left = cpos.left + ( csize.width - data.width ); - data.top = null; - } - if ( a === "nw" ) { - data.top = cpos.top + ( csize.height - data.height ); - data.left = cpos.left + ( csize.width - data.width ); - } - - return data; - }, - - _respectSize: function( data ) { - - var o = this._vBoundaries, - a = this.axis, - ismaxw = this._isNumber( data.width ) && o.maxWidth && ( o.maxWidth < data.width ), - ismaxh = this._isNumber( data.height ) && o.maxHeight && ( o.maxHeight < data.height ), - isminw = this._isNumber( data.width ) && o.minWidth && ( o.minWidth > data.width ), - isminh = this._isNumber( data.height ) && o.minHeight && ( o.minHeight > data.height ), - dw = this.originalPosition.left + this.originalSize.width, - dh = this.originalPosition.top + this.originalSize.height, - cw = /sw|nw|w/.test( a ), ch = /nw|ne|n/.test( a ); - if ( isminw ) { - data.width = o.minWidth; - } - if ( isminh ) { - data.height = o.minHeight; - } - if ( ismaxw ) { - data.width = o.maxWidth; - } - if ( ismaxh ) { - data.height = o.maxHeight; - } - - if ( isminw && cw ) { - data.left = dw - o.minWidth; - } - if ( ismaxw && cw ) { - data.left = dw - o.maxWidth; - } - if ( isminh && ch ) { - data.top = dh - o.minHeight; - } - if ( ismaxh && ch ) { - data.top = dh - o.maxHeight; - } - - // Fixing jump error on top/left - bug #2330 - if ( !data.width && !data.height && !data.left && data.top ) { - data.top = null; - } else if ( !data.width && !data.height && !data.top && data.left ) { - data.left = null; - } - - return data; - }, - - _getPaddingPlusBorderDimensions: function( element ) { - var i = 0, - widths = [], - borders = [ - element.css( "borderTopWidth" ), - element.css( "borderRightWidth" ), - element.css( "borderBottomWidth" ), - element.css( "borderLeftWidth" ) - ], - paddings = [ - element.css( "paddingTop" ), - element.css( "paddingRight" ), - element.css( "paddingBottom" ), - element.css( "paddingLeft" ) - ]; - - for ( ; i < 4; i++ ) { - widths[ i ] = ( parseFloat( borders[ i ] ) || 0 ); - widths[ i ] += ( parseFloat( paddings[ i ] ) || 0 ); - } - - return { - height: widths[ 0 ] + widths[ 2 ], - width: widths[ 1 ] + widths[ 3 ] - }; - }, - - _proportionallyResize: function() { - - if ( !this._proportionallyResizeElements.length ) { - return; - } - - var prel, - i = 0, - element = this.helper || this.element; - - for ( ; i < this._proportionallyResizeElements.length; i++ ) { - - prel = this._proportionallyResizeElements[ i ]; - - // TODO: Seems like a bug to cache this.outerDimensions - // considering that we are in a loop. - if ( !this.outerDimensions ) { - this.outerDimensions = this._getPaddingPlusBorderDimensions( prel ); - } - - prel.css( { - height: ( element.height() - this.outerDimensions.height ) || 0, - width: ( element.width() - this.outerDimensions.width ) || 0 - } ); - - } - - }, - - _renderProxy: function() { - - var el = this.element, o = this.options; - this.elementOffset = el.offset(); - - if ( this._helper ) { - - this.helper = this.helper || $( "<div></div>" ).css( { overflow: "hidden" } ); - - this._addClass( this.helper, this._helper ); - this.helper.css( { - width: this.element.outerWidth(), - height: this.element.outerHeight(), - position: "absolute", - left: this.elementOffset.left + "px", - top: this.elementOffset.top + "px", - zIndex: ++o.zIndex //TODO: Don't modify option - } ); - - this.helper - .appendTo( "body" ) - .disableSelection(); - - } else { - this.helper = this.element; - } - - }, - - _change: { - e: function( event, dx ) { - return { width: this.originalSize.width + dx }; - }, - w: function( event, dx ) { - var cs = this.originalSize, sp = this.originalPosition; - return { left: sp.left + dx, width: cs.width - dx }; - }, - n: function( event, dx, dy ) { - var cs = this.originalSize, sp = this.originalPosition; - return { top: sp.top + dy, height: cs.height - dy }; - }, - s: function( event, dx, dy ) { - return { height: this.originalSize.height + dy }; - }, - se: function( event, dx, dy ) { - return $.extend( this._change.s.apply( this, arguments ), - this._change.e.apply( this, [ event, dx, dy ] ) ); - }, - sw: function( event, dx, dy ) { - return $.extend( this._change.s.apply( this, arguments ), - this._change.w.apply( this, [ event, dx, dy ] ) ); - }, - ne: function( event, dx, dy ) { - return $.extend( this._change.n.apply( this, arguments ), - this._change.e.apply( this, [ event, dx, dy ] ) ); - }, - nw: function( event, dx, dy ) { - return $.extend( this._change.n.apply( this, arguments ), - this._change.w.apply( this, [ event, dx, dy ] ) ); - } - }, - - _propagate: function( n, event ) { - $.ui.plugin.call( this, n, [ event, this.ui() ] ); - if ( n !== "resize" ) { - this._trigger( n, event, this.ui() ); - } - }, - - plugins: {}, - - ui: function() { - return { - originalElement: this.originalElement, - element: this.element, - helper: this.helper, - position: this.position, - size: this.size, - originalSize: this.originalSize, - originalPosition: this.originalPosition - }; - } - -} ); - -/* - * Resizable Extensions - */ - -$.ui.plugin.add( "resizable", "animate", { - - stop: function( event ) { - var that = $( this ).resizable( "instance" ), - o = that.options, - pr = that._proportionallyResizeElements, - ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ), - soffseth = ista && that._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height, - soffsetw = ista ? 0 : that.sizeDiff.width, - style = { - width: ( that.size.width - soffsetw ), - height: ( that.size.height - soffseth ) - }, - left = ( parseFloat( that.element.css( "left" ) ) + - ( that.position.left - that.originalPosition.left ) ) || null, - top = ( parseFloat( that.element.css( "top" ) ) + - ( that.position.top - that.originalPosition.top ) ) || null; - - that.element.animate( - $.extend( style, top && left ? { top: top, left: left } : {} ), { - duration: o.animateDuration, - easing: o.animateEasing, - step: function() { - - var data = { - width: parseFloat( that.element.css( "width" ) ), - height: parseFloat( that.element.css( "height" ) ), - top: parseFloat( that.element.css( "top" ) ), - left: parseFloat( that.element.css( "left" ) ) - }; - - if ( pr && pr.length ) { - $( pr[ 0 ] ).css( { width: data.width, height: data.height } ); - } - - // Propagating resize, and updating values for each animation step - that._updateCache( data ); - that._propagate( "resize", event ); - - } - } - ); - } - -} ); - -$.ui.plugin.add( "resizable", "containment", { - - start: function() { - var element, p, co, ch, cw, width, height, - that = $( this ).resizable( "instance" ), - o = that.options, - el = that.element, - oc = o.containment, - ce = ( oc instanceof $ ) ? - oc.get( 0 ) : - ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc; - - if ( !ce ) { - return; - } - - that.containerElement = $( ce ); - - if ( /document/.test( oc ) || oc === document ) { - that.containerOffset = { - left: 0, - top: 0 - }; - that.containerPosition = { - left: 0, - top: 0 - }; - - that.parentData = { - element: $( document ), - left: 0, - top: 0, - width: $( document ).width(), - height: $( document ).height() || document.body.parentNode.scrollHeight - }; - } else { - element = $( ce ); - p = []; - $( [ "Top", "Right", "Left", "Bottom" ] ).each( function( i, name ) { - p[ i ] = that._num( element.css( "padding" + name ) ); - } ); - - that.containerOffset = element.offset(); - that.containerPosition = element.position(); - that.containerSize = { - height: ( element.innerHeight() - p[ 3 ] ), - width: ( element.innerWidth() - p[ 1 ] ) - }; - - co = that.containerOffset; - ch = that.containerSize.height; - cw = that.containerSize.width; - width = ( that._hasScroll( ce, "left" ) ? ce.scrollWidth : cw ); - height = ( that._hasScroll( ce ) ? ce.scrollHeight : ch ); - - that.parentData = { - element: ce, - left: co.left, - top: co.top, - width: width, - height: height - }; - } - }, - - resize: function( event ) { - var woset, hoset, isParent, isOffsetRelative, - that = $( this ).resizable( "instance" ), - o = that.options, - co = that.containerOffset, - cp = that.position, - pRatio = that._aspectRatio || event.shiftKey, - cop = { - top: 0, - left: 0 - }, - ce = that.containerElement, - continueResize = true; - - if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) { - cop = co; - } - - if ( cp.left < ( that._helper ? co.left : 0 ) ) { - that.size.width = that.size.width + - ( that._helper ? - ( that.position.left - co.left ) : - ( that.position.left - cop.left ) ); - - if ( pRatio ) { - that.size.height = that.size.width / that.aspectRatio; - continueResize = false; - } - that.position.left = o.helper ? co.left : 0; - } - - if ( cp.top < ( that._helper ? co.top : 0 ) ) { - that.size.height = that.size.height + - ( that._helper ? - ( that.position.top - co.top ) : - that.position.top ); - - if ( pRatio ) { - that.size.width = that.size.height * that.aspectRatio; - continueResize = false; - } - that.position.top = that._helper ? co.top : 0; - } - - isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 ); - isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) ); - - if ( isParent && isOffsetRelative ) { - that.offset.left = that.parentData.left + that.position.left; - that.offset.top = that.parentData.top + that.position.top; - } else { - that.offset.left = that.element.offset().left; - that.offset.top = that.element.offset().top; - } - - woset = Math.abs( that.sizeDiff.width + - ( that._helper ? - that.offset.left - cop.left : - ( that.offset.left - co.left ) ) ); - - hoset = Math.abs( that.sizeDiff.height + - ( that._helper ? - that.offset.top - cop.top : - ( that.offset.top - co.top ) ) ); - - if ( woset + that.size.width >= that.parentData.width ) { - that.size.width = that.parentData.width - woset; - if ( pRatio ) { - that.size.height = that.size.width / that.aspectRatio; - continueResize = false; - } - } - - if ( hoset + that.size.height >= that.parentData.height ) { - that.size.height = that.parentData.height - hoset; - if ( pRatio ) { - that.size.width = that.size.height * that.aspectRatio; - continueResize = false; - } - } - - if ( !continueResize ) { - that.position.left = that.prevPosition.left; - that.position.top = that.prevPosition.top; - that.size.width = that.prevSize.width; - that.size.height = that.prevSize.height; - } - }, - - stop: function() { - var that = $( this ).resizable( "instance" ), - o = that.options, - co = that.containerOffset, - cop = that.containerPosition, - ce = that.containerElement, - helper = $( that.helper ), - ho = helper.offset(), - w = helper.outerWidth() - that.sizeDiff.width, - h = helper.outerHeight() - that.sizeDiff.height; - - if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) { - $( this ).css( { - left: ho.left - cop.left - co.left, - width: w, - height: h - } ); - } - - if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) { - $( this ).css( { - left: ho.left - cop.left - co.left, - width: w, - height: h - } ); - } - } -} ); - -$.ui.plugin.add( "resizable", "alsoResize", { - - start: function() { - var that = $( this ).resizable( "instance" ), - o = that.options; - - $( o.alsoResize ).each( function() { - var el = $( this ); - el.data( "ui-resizable-alsoresize", { - width: parseFloat( el.width() ), height: parseFloat( el.height() ), - left: parseFloat( el.css( "left" ) ), top: parseFloat( el.css( "top" ) ) - } ); - } ); - }, - - resize: function( event, ui ) { - var that = $( this ).resizable( "instance" ), - o = that.options, - os = that.originalSize, - op = that.originalPosition, - delta = { - height: ( that.size.height - os.height ) || 0, - width: ( that.size.width - os.width ) || 0, - top: ( that.position.top - op.top ) || 0, - left: ( that.position.left - op.left ) || 0 - }; - - $( o.alsoResize ).each( function() { - var el = $( this ), start = $( this ).data( "ui-resizable-alsoresize" ), style = {}, - css = el.parents( ui.originalElement[ 0 ] ).length ? - [ "width", "height" ] : - [ "width", "height", "top", "left" ]; - - $.each( css, function( i, prop ) { - var sum = ( start[ prop ] || 0 ) + ( delta[ prop ] || 0 ); - if ( sum && sum >= 0 ) { - style[ prop ] = sum || null; - } - } ); - - el.css( style ); - } ); - }, - - stop: function() { - $( this ).removeData( "ui-resizable-alsoresize" ); - } -} ); - -$.ui.plugin.add( "resizable", "ghost", { - - start: function() { - - var that = $( this ).resizable( "instance" ), cs = that.size; - - that.ghost = that.originalElement.clone(); - that.ghost.css( { - opacity: 0.25, - display: "block", - position: "relative", - height: cs.height, - width: cs.width, - margin: 0, - left: 0, - top: 0 - } ); - - that._addClass( that.ghost, "ui-resizable-ghost" ); - - // DEPRECATED - // TODO: remove after 1.12 - if ( $.uiBackCompat !== false && typeof that.options.ghost === "string" ) { - - // Ghost option - that.ghost.addClass( this.options.ghost ); - } - - that.ghost.appendTo( that.helper ); - - }, - - resize: function() { - var that = $( this ).resizable( "instance" ); - if ( that.ghost ) { - that.ghost.css( { - position: "relative", - height: that.size.height, - width: that.size.width - } ); - } - }, - - stop: function() { - var that = $( this ).resizable( "instance" ); - if ( that.ghost && that.helper ) { - that.helper.get( 0 ).removeChild( that.ghost.get( 0 ) ); - } - } - -} ); - -$.ui.plugin.add( "resizable", "grid", { - - resize: function() { - var outerDimensions, - that = $( this ).resizable( "instance" ), - o = that.options, - cs = that.size, - os = that.originalSize, - op = that.originalPosition, - a = that.axis, - grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid, - gridX = ( grid[ 0 ] || 1 ), - gridY = ( grid[ 1 ] || 1 ), - ox = Math.round( ( cs.width - os.width ) / gridX ) * gridX, - oy = Math.round( ( cs.height - os.height ) / gridY ) * gridY, - newWidth = os.width + ox, - newHeight = os.height + oy, - isMaxWidth = o.maxWidth && ( o.maxWidth < newWidth ), - isMaxHeight = o.maxHeight && ( o.maxHeight < newHeight ), - isMinWidth = o.minWidth && ( o.minWidth > newWidth ), - isMinHeight = o.minHeight && ( o.minHeight > newHeight ); - - o.grid = grid; - - if ( isMinWidth ) { - newWidth += gridX; - } - if ( isMinHeight ) { - newHeight += gridY; - } - if ( isMaxWidth ) { - newWidth -= gridX; - } - if ( isMaxHeight ) { - newHeight -= gridY; - } - - if ( /^(se|s|e)$/.test( a ) ) { - that.size.width = newWidth; - that.size.height = newHeight; - } else if ( /^(ne)$/.test( a ) ) { - that.size.width = newWidth; - that.size.height = newHeight; - that.position.top = op.top - oy; - } else if ( /^(sw)$/.test( a ) ) { - that.size.width = newWidth; - that.size.height = newHeight; - that.position.left = op.left - ox; - } else { - if ( newHeight - gridY <= 0 || newWidth - gridX <= 0 ) { - outerDimensions = that._getPaddingPlusBorderDimensions( this ); - } - - if ( newHeight - gridY > 0 ) { - that.size.height = newHeight; - that.position.top = op.top - oy; - } else { - newHeight = gridY - outerDimensions.height; - that.size.height = newHeight; - that.position.top = op.top + os.height - newHeight; - } - if ( newWidth - gridX > 0 ) { - that.size.width = newWidth; - that.position.left = op.left - ox; - } else { - newWidth = gridX - outerDimensions.width; - that.size.width = newWidth; - that.position.left = op.left + os.width - newWidth; - } - } - } - -} ); - -return $.ui.resizable; + _mouseStop: function( event ) { + + this.resizing = false; + var pr, ista, soffseth, soffsetw, s, left, top, + o = this.options, that = this; + + if ( this._helper ) { + + pr = this._proportionallyResizeElements; + ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ); + soffseth = ista && this._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height; + soffsetw = ista ? 0 : that.sizeDiff.width; + + s = { + width: ( that.helper.width() - soffsetw ), + height: ( that.helper.height() - soffseth ) + }; + left = ( parseFloat( that.element.css( "left" ) ) + + ( that.position.left - that.originalPosition.left ) ) || null; + top = ( parseFloat( that.element.css( "top" ) ) + + ( that.position.top - that.originalPosition.top ) ) || null; + + if ( !o.animate ) { + this.element.css( $.extend( s, { top: top, left: left } ) ); + } + + that.helper.height( that.size.height ); + that.helper.width( that.size.width ); + + if ( this._helper && !o.animate ) { + this._proportionallyResize(); + } + } + + $( "body" ).css( "cursor", "auto" ); + + this._removeClass( "ui-resizable-resizing" ); + + this._propagate( "stop", event ); + + if ( this._helper ) { + this.helper.remove(); + } + + return false; + + }, + + _updatePrevProperties: function() { + this.prevPosition = { + top: this.position.top, + left: this.position.left + }; + this.prevSize = { + width: this.size.width, + height: this.size.height + }; + }, + + _applyChanges: function() { + var props = {}; + + if ( this.position.top !== this.prevPosition.top ) { + props.top = this.position.top + "px"; + } + if ( this.position.left !== this.prevPosition.left ) { + props.left = this.position.left + "px"; + } + if ( this.size.width !== this.prevSize.width ) { + props.width = this.size.width + "px"; + } + if ( this.size.height !== this.prevSize.height ) { + props.height = this.size.height + "px"; + } + + this.helper.css( props ); + + return props; + }, + + _updateVirtualBoundaries: function( forceAspectRatio ) { + var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b, + o = this.options; + + b = { + minWidth: this._isNumber( o.minWidth ) ? o.minWidth : 0, + maxWidth: this._isNumber( o.maxWidth ) ? o.maxWidth : Infinity, + minHeight: this._isNumber( o.minHeight ) ? o.minHeight : 0, + maxHeight: this._isNumber( o.maxHeight ) ? o.maxHeight : Infinity + }; + + if ( this._aspectRatio || forceAspectRatio ) { + pMinWidth = b.minHeight * this.aspectRatio; + pMinHeight = b.minWidth / this.aspectRatio; + pMaxWidth = b.maxHeight * this.aspectRatio; + pMaxHeight = b.maxWidth / this.aspectRatio; + + if ( pMinWidth > b.minWidth ) { + b.minWidth = pMinWidth; + } + if ( pMinHeight > b.minHeight ) { + b.minHeight = pMinHeight; + } + if ( pMaxWidth < b.maxWidth ) { + b.maxWidth = pMaxWidth; + } + if ( pMaxHeight < b.maxHeight ) { + b.maxHeight = pMaxHeight; + } + } + this._vBoundaries = b; + }, + + _updateCache: function( data ) { + this.offset = this.helper.offset(); + if ( this._isNumber( data.left ) ) { + this.position.left = data.left; + } + if ( this._isNumber( data.top ) ) { + this.position.top = data.top; + } + if ( this._isNumber( data.height ) ) { + this.size.height = data.height; + } + if ( this._isNumber( data.width ) ) { + this.size.width = data.width; + } + }, + + _updateRatio: function( data ) { + + var cpos = this.position, + csize = this.size, + a = this.axis; + + if ( this._isNumber( data.height ) ) { + data.width = ( data.height * this.aspectRatio ); + } else if ( this._isNumber( data.width ) ) { + data.height = ( data.width / this.aspectRatio ); + } + + if ( a === "sw" ) { + data.left = cpos.left + ( csize.width - data.width ); + data.top = null; + } + if ( a === "nw" ) { + data.top = cpos.top + ( csize.height - data.height ); + data.left = cpos.left + ( csize.width - data.width ); + } + + return data; + }, + + _respectSize: function( data ) { + + var o = this._vBoundaries, + a = this.axis, + ismaxw = this._isNumber( data.width ) && o.maxWidth && ( o.maxWidth < data.width ), + ismaxh = this._isNumber( data.height ) && o.maxHeight && ( o.maxHeight < data.height ), + isminw = this._isNumber( data.width ) && o.minWidth && ( o.minWidth > data.width ), + isminh = this._isNumber( data.height ) && o.minHeight && ( o.minHeight > data.height ), + dw = this.originalPosition.left + this.originalSize.width, + dh = this.originalPosition.top + this.originalSize.height, + cw = /sw|nw|w/.test( a ), ch = /nw|ne|n/.test( a ); + if ( isminw ) { + data.width = o.minWidth; + } + if ( isminh ) { + data.height = o.minHeight; + } + if ( ismaxw ) { + data.width = o.maxWidth; + } + if ( ismaxh ) { + data.height = o.maxHeight; + } + + if ( isminw && cw ) { + data.left = dw - o.minWidth; + } + if ( ismaxw && cw ) { + data.left = dw - o.maxWidth; + } + if ( isminh && ch ) { + data.top = dh - o.minHeight; + } + if ( ismaxh && ch ) { + data.top = dh - o.maxHeight; + } + + // Fixing jump error on top/left - bug #2330 + if ( !data.width && !data.height && !data.left && data.top ) { + data.top = null; + } else if ( !data.width && !data.height && !data.top && data.left ) { + data.left = null; + } + + return data; + }, + + _getPaddingPlusBorderDimensions: function( element ) { + var i = 0, + widths = [], + borders = [ + element.css( "borderTopWidth" ), + element.css( "borderRightWidth" ), + element.css( "borderBottomWidth" ), + element.css( "borderLeftWidth" ) + ], + paddings = [ + element.css( "paddingTop" ), + element.css( "paddingRight" ), + element.css( "paddingBottom" ), + element.css( "paddingLeft" ) + ]; + + for ( ; i < 4; i++ ) { + widths[ i ] = ( parseFloat( borders[ i ] ) || 0 ); + widths[ i ] += ( parseFloat( paddings[ i ] ) || 0 ); + } + + return { + height: widths[ 0 ] + widths[ 2 ], + width: widths[ 1 ] + widths[ 3 ] + }; + }, + + _proportionallyResize: function() { + + if ( !this._proportionallyResizeElements.length ) { + return; + } + + var prel, + i = 0, + element = this.helper || this.element; + + for ( ; i < this._proportionallyResizeElements.length; i++ ) { + + prel = this._proportionallyResizeElements[ i ]; + + // TODO: Seems like a bug to cache this.outerDimensions + // considering that we are in a loop. + if ( !this.outerDimensions ) { + this.outerDimensions = this._getPaddingPlusBorderDimensions( prel ); + } + + prel.css( { + height: ( element.height() - this.outerDimensions.height ) || 0, + width: ( element.width() - this.outerDimensions.width ) || 0 + } ); + + } + + }, + + _renderProxy: function() { + + var el = this.element, o = this.options; + this.elementOffset = el.offset(); + + if ( this._helper ) { + + this.helper = this.helper || $( "<div></div>" ).css( { overflow: "hidden" } ); + + this._addClass( this.helper, this._helper ); + this.helper.css( { + width: this.element.outerWidth(), + height: this.element.outerHeight(), + position: "absolute", + left: this.elementOffset.left + "px", + top: this.elementOffset.top + "px", + zIndex: ++o.zIndex //TODO: Don't modify option + } ); + + this.helper + .appendTo( "body" ) + .disableSelection(); + + } else { + this.helper = this.element; + } + + }, + + _change: { + e: function( event, dx ) { + return { width: this.originalSize.width + dx }; + }, + w: function( event, dx ) { + var cs = this.originalSize, sp = this.originalPosition; + return { left: sp.left + dx, width: cs.width - dx }; + }, + n: function( event, dx, dy ) { + var cs = this.originalSize, sp = this.originalPosition; + return { top: sp.top + dy, height: cs.height - dy }; + }, + s: function( event, dx, dy ) { + return { height: this.originalSize.height + dy }; + }, + se: function( event, dx, dy ) { + return $.extend( this._change.s.apply( this, arguments ), + this._change.e.apply( this, [ event, dx, dy ] ) ); + }, + sw: function( event, dx, dy ) { + return $.extend( this._change.s.apply( this, arguments ), + this._change.w.apply( this, [ event, dx, dy ] ) ); + }, + ne: function( event, dx, dy ) { + return $.extend( this._change.n.apply( this, arguments ), + this._change.e.apply( this, [ event, dx, dy ] ) ); + }, + nw: function( event, dx, dy ) { + return $.extend( this._change.n.apply( this, arguments ), + this._change.w.apply( this, [ event, dx, dy ] ) ); + } + }, + + _propagate: function( n, event ) { + $.ui.plugin.call( this, n, [ event, this.ui() ] ); + if ( n !== "resize" ) { + this._trigger( n, event, this.ui() ); + } + }, + + plugins: {}, + + ui: function() { + return { + originalElement: this.originalElement, + element: this.element, + helper: this.helper, + position: this.position, + size: this.size, + originalSize: this.originalSize, + originalPosition: this.originalPosition + }; + } + + } ); + + /* + * Resizable Extensions + */ + + $.ui.plugin.add( "resizable", "animate", { + + stop: function( event ) { + var that = $( this ).resizable( "instance" ), + o = that.options, + pr = that._proportionallyResizeElements, + ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ), + soffseth = ista && that._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height, + soffsetw = ista ? 0 : that.sizeDiff.width, + style = { + width: ( that.size.width - soffsetw ), + height: ( that.size.height - soffseth ) + }, + left = ( parseFloat( that.element.css( "left" ) ) + + ( that.position.left - that.originalPosition.left ) ) || null, + top = ( parseFloat( that.element.css( "top" ) ) + + ( that.position.top - that.originalPosition.top ) ) || null; + + that.element.animate( + $.extend( style, top && left ? { top: top, left: left } : {} ), { + duration: o.animateDuration, + easing: o.animateEasing, + step: function() { + + var data = { + width: parseFloat( that.element.css( "width" ) ), + height: parseFloat( that.element.css( "height" ) ), + top: parseFloat( that.element.css( "top" ) ), + left: parseFloat( that.element.css( "left" ) ) + }; + + if ( pr && pr.length ) { + $( pr[ 0 ] ).css( { width: data.width, height: data.height } ); + } + + // Propagating resize, and updating values for each animation step + that._updateCache( data ); + that._propagate( "resize", event ); + + } + } + ); + } + + } ); + + $.ui.plugin.add( "resizable", "containment", { + + start: function() { + var element, p, co, ch, cw, width, height, + that = $( this ).resizable( "instance" ), + o = that.options, + el = that.element, + oc = o.containment, + ce = ( oc instanceof $ ) ? + oc.get( 0 ) : + ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc; + + if ( !ce ) { + return; + } + + that.containerElement = $( ce ); + + if ( /document/.test( oc ) || oc === document ) { + that.containerOffset = { + left: 0, + top: 0 + }; + that.containerPosition = { + left: 0, + top: 0 + }; + + that.parentData = { + element: $( document ), + left: 0, + top: 0, + width: $( document ).width(), + height: $( document ).height() || document.body.parentNode.scrollHeight + }; + } else { + element = $( ce ); + p = []; + $( [ "Top", "Right", "Left", "Bottom" ] ).each( function( i, name ) { + p[ i ] = that._num( element.css( "padding" + name ) ); + } ); + + that.containerOffset = element.offset(); + that.containerPosition = element.position(); + that.containerSize = { + height: ( element.innerHeight() - p[ 3 ] ), + width: ( element.innerWidth() - p[ 1 ] ) + }; + + co = that.containerOffset; + ch = that.containerSize.height; + cw = that.containerSize.width; + width = ( that._hasScroll( ce, "left" ) ? ce.scrollWidth : cw ); + height = ( that._hasScroll( ce ) ? ce.scrollHeight : ch ); + + that.parentData = { + element: ce, + left: co.left, + top: co.top, + width: width, + height: height + }; + } + }, + + resize: function( event ) { + var woset, hoset, isParent, isOffsetRelative, + that = $( this ).resizable( "instance" ), + o = that.options, + co = that.containerOffset, + cp = that.position, + pRatio = that._aspectRatio || event.shiftKey, + cop = { + top: 0, + left: 0 + }, + ce = that.containerElement, + continueResize = true; + + if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) { + cop = co; + } + + if ( cp.left < ( that._helper ? co.left : 0 ) ) { + that.size.width = that.size.width + + ( that._helper ? + ( that.position.left - co.left ) : + ( that.position.left - cop.left ) ); + + if ( pRatio ) { + that.size.height = that.size.width / that.aspectRatio; + continueResize = false; + } + that.position.left = o.helper ? co.left : 0; + } + + if ( cp.top < ( that._helper ? co.top : 0 ) ) { + that.size.height = that.size.height + + ( that._helper ? + ( that.position.top - co.top ) : + that.position.top ); + + if ( pRatio ) { + that.size.width = that.size.height * that.aspectRatio; + continueResize = false; + } + that.position.top = that._helper ? co.top : 0; + } + + isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 ); + isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) ); + + if ( isParent && isOffsetRelative ) { + that.offset.left = that.parentData.left + that.position.left; + that.offset.top = that.parentData.top + that.position.top; + } else { + that.offset.left = that.element.offset().left; + that.offset.top = that.element.offset().top; + } + + woset = Math.abs( that.sizeDiff.width + + ( that._helper ? + that.offset.left - cop.left : + ( that.offset.left - co.left ) ) ); + + hoset = Math.abs( that.sizeDiff.height + + ( that._helper ? + that.offset.top - cop.top : + ( that.offset.top - co.top ) ) ); + + if ( woset + that.size.width >= that.parentData.width ) { + that.size.width = that.parentData.width - woset; + if ( pRatio ) { + that.size.height = that.size.width / that.aspectRatio; + continueResize = false; + } + } + + if ( hoset + that.size.height >= that.parentData.height ) { + that.size.height = that.parentData.height - hoset; + if ( pRatio ) { + that.size.width = that.size.height * that.aspectRatio; + continueResize = false; + } + } + + if ( !continueResize ) { + that.position.left = that.prevPosition.left; + that.position.top = that.prevPosition.top; + that.size.width = that.prevSize.width; + that.size.height = that.prevSize.height; + } + }, + + stop: function() { + var that = $( this ).resizable( "instance" ), + o = that.options, + co = that.containerOffset, + cop = that.containerPosition, + ce = that.containerElement, + helper = $( that.helper ), + ho = helper.offset(), + w = helper.outerWidth() - that.sizeDiff.width, + h = helper.outerHeight() - that.sizeDiff.height; + + if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) { + $( this ).css( { + left: ho.left - cop.left - co.left, + width: w, + height: h + } ); + } + + if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) { + $( this ).css( { + left: ho.left - cop.left - co.left, + width: w, + height: h + } ); + } + } + } ); + + $.ui.plugin.add( "resizable", "alsoResize", { + + start: function() { + var that = $( this ).resizable( "instance" ), + o = that.options; + + $( o.alsoResize ).each( function() { + var el = $( this ); + el.data( "ui-resizable-alsoresize", { + width: parseFloat( el.width() ), height: parseFloat( el.height() ), + left: parseFloat( el.css( "left" ) ), top: parseFloat( el.css( "top" ) ) + } ); + } ); + }, + + resize: function( event, ui ) { + var that = $( this ).resizable( "instance" ), + o = that.options, + os = that.originalSize, + op = that.originalPosition, + delta = { + height: ( that.size.height - os.height ) || 0, + width: ( that.size.width - os.width ) || 0, + top: ( that.position.top - op.top ) || 0, + left: ( that.position.left - op.left ) || 0 + }; + + $( o.alsoResize ).each( function() { + var el = $( this ), start = $( this ).data( "ui-resizable-alsoresize" ), style = {}, + css = el.parents( ui.originalElement[ 0 ] ).length ? + [ "width", "height" ] : + [ "width", "height", "top", "left" ]; + + $.each( css, function( i, prop ) { + var sum = ( start[ prop ] || 0 ) + ( delta[ prop ] || 0 ); + if ( sum && sum >= 0 ) { + style[ prop ] = sum || null; + } + } ); + + el.css( style ); + } ); + }, + + stop: function() { + $( this ).removeData( "ui-resizable-alsoresize" ); + } + } ); + + $.ui.plugin.add( "resizable", "ghost", { + + start: function() { + + var that = $( this ).resizable( "instance" ), cs = that.size; + + that.ghost = that.originalElement.clone(); + that.ghost.css( { + opacity: 0.25, + display: "block", + position: "relative", + height: cs.height, + width: cs.width, + margin: 0, + left: 0, + top: 0 + } ); + + that._addClass( that.ghost, "ui-resizable-ghost" ); + + // DEPRECATED + // TODO: remove after 1.12 + if ( $.uiBackCompat !== false && typeof that.options.ghost === "string" ) { + + // Ghost option + that.ghost.addClass( this.options.ghost ); + } + + that.ghost.appendTo( that.helper ); + + }, + + resize: function() { + var that = $( this ).resizable( "instance" ); + if ( that.ghost ) { + that.ghost.css( { + position: "relative", + height: that.size.height, + width: that.size.width + } ); + } + }, + + stop: function() { + var that = $( this ).resizable( "instance" ); + if ( that.ghost && that.helper ) { + that.helper.get( 0 ).removeChild( that.ghost.get( 0 ) ); + } + } + + } ); + + $.ui.plugin.add( "resizable", "grid", { + + resize: function() { + var outerDimensions, + that = $( this ).resizable( "instance" ), + o = that.options, + cs = that.size, + os = that.originalSize, + op = that.originalPosition, + a = that.axis, + grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid, + gridX = ( grid[ 0 ] || 1 ), + gridY = ( grid[ 1 ] || 1 ), + ox = Math.round( ( cs.width - os.width ) / gridX ) * gridX, + oy = Math.round( ( cs.height - os.height ) / gridY ) * gridY, + newWidth = os.width + ox, + newHeight = os.height + oy, + isMaxWidth = o.maxWidth && ( o.maxWidth < newWidth ), + isMaxHeight = o.maxHeight && ( o.maxHeight < newHeight ), + isMinWidth = o.minWidth && ( o.minWidth > newWidth ), + isMinHeight = o.minHeight && ( o.minHeight > newHeight ); + + o.grid = grid; + + if ( isMinWidth ) { + newWidth += gridX; + } + if ( isMinHeight ) { + newHeight += gridY; + } + if ( isMaxWidth ) { + newWidth -= gridX; + } + if ( isMaxHeight ) { + newHeight -= gridY; + } + + if ( /^(se|s|e)$/.test( a ) ) { + that.size.width = newWidth; + that.size.height = newHeight; + } else if ( /^(ne)$/.test( a ) ) { + that.size.width = newWidth; + that.size.height = newHeight; + that.position.top = op.top - oy; + } else if ( /^(sw)$/.test( a ) ) { + that.size.width = newWidth; + that.size.height = newHeight; + that.position.left = op.left - ox; + } else { + if ( newHeight - gridY <= 0 || newWidth - gridX <= 0 ) { + outerDimensions = that._getPaddingPlusBorderDimensions( this ); + } + + if ( newHeight - gridY > 0 ) { + that.size.height = newHeight; + that.position.top = op.top - oy; + } else { + newHeight = gridY - outerDimensions.height; + that.size.height = newHeight; + that.position.top = op.top + os.height - newHeight; + } + if ( newWidth - gridX > 0 ) { + that.size.width = newWidth; + that.position.left = op.left - ox; + } else { + newWidth = gridX - outerDimensions.width; + that.size.width = newWidth; + that.position.left = op.left + os.width - newWidth; + } + } + } + + } ); + + return $.ui.resizable; } ); diff --git a/lib/web/jquery/ui-modules/widgets/selectable.js b/lib/web/jquery/ui-modules/widgets/selectable.js index 250fed432e51b..004156d3f2799 100644 --- a/lib/web/jquery/ui-modules/widgets/selectable.js +++ b/lib/web/jquery/ui-modules/widgets/selectable.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Selectable 1.13.1 + * jQuery UI Selectable 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -15,303 +15,303 @@ //>>css.structure: ../../themes/base/selectable.css ( function( factory ) { - "use strict"; - - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define( [ - "jquery", - "./mouse", - "../version", - "../widget" - ], factory ); - } else { - - // Browser globals - factory( jQuery ); - } + "use strict"; + + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ + "jquery", + "./mouse", + "../version", + "../widget" + ], factory ); + } else { + + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; - -return $.widget( "ui.selectable", $.ui.mouse, { - version: "1.13.1", - options: { - appendTo: "body", - autoRefresh: true, - distance: 0, - filter: "*", - tolerance: "touch", - - // Callbacks - selected: null, - selecting: null, - start: null, - stop: null, - unselected: null, - unselecting: null - }, - _create: function() { - var that = this; - - this._addClass( "ui-selectable" ); - - this.dragged = false; - - // Cache selectee children based on filter - this.refresh = function() { - that.elementPos = $( that.element[ 0 ] ).offset(); - that.selectees = $( that.options.filter, that.element[ 0 ] ); - that._addClass( that.selectees, "ui-selectee" ); - that.selectees.each( function() { - var $this = $( this ), - selecteeOffset = $this.offset(), - pos = { - left: selecteeOffset.left - that.elementPos.left, - top: selecteeOffset.top - that.elementPos.top - }; - $.data( this, "selectable-item", { - element: this, - $element: $this, - left: pos.left, - top: pos.top, - right: pos.left + $this.outerWidth(), - bottom: pos.top + $this.outerHeight(), - startselected: false, - selected: $this.hasClass( "ui-selected" ), - selecting: $this.hasClass( "ui-selecting" ), - unselecting: $this.hasClass( "ui-unselecting" ) - } ); - } ); - }; - this.refresh(); - - this._mouseInit(); - - this.helper = $( "<div>" ); - this._addClass( this.helper, "ui-selectable-helper" ); - }, - - _destroy: function() { - this.selectees.removeData( "selectable-item" ); - this._mouseDestroy(); - }, - - _mouseStart: function( event ) { - var that = this, - options = this.options; - - this.opos = [ event.pageX, event.pageY ]; - this.elementPos = $( this.element[ 0 ] ).offset(); - - if ( this.options.disabled ) { - return; - } - - this.selectees = $( options.filter, this.element[ 0 ] ); - - this._trigger( "start", event ); - - $( options.appendTo ).append( this.helper ); - - // position helper (lasso) - this.helper.css( { - "left": event.pageX, - "top": event.pageY, - "width": 0, - "height": 0 - } ); - - if ( options.autoRefresh ) { - this.refresh(); - } - - this.selectees.filter( ".ui-selected" ).each( function() { - var selectee = $.data( this, "selectable-item" ); - selectee.startselected = true; - if ( !event.metaKey && !event.ctrlKey ) { - that._removeClass( selectee.$element, "ui-selected" ); - selectee.selected = false; - that._addClass( selectee.$element, "ui-unselecting" ); - selectee.unselecting = true; - - // selectable UNSELECTING callback - that._trigger( "unselecting", event, { - unselecting: selectee.element - } ); - } - } ); - - $( event.target ).parents().addBack().each( function() { - var doSelect, - selectee = $.data( this, "selectable-item" ); - if ( selectee ) { - doSelect = ( !event.metaKey && !event.ctrlKey ) || - !selectee.$element.hasClass( "ui-selected" ); - that._removeClass( selectee.$element, doSelect ? "ui-unselecting" : "ui-selected" ) - ._addClass( selectee.$element, doSelect ? "ui-selecting" : "ui-unselecting" ); - selectee.unselecting = !doSelect; - selectee.selecting = doSelect; - selectee.selected = doSelect; - - // selectable (UN)SELECTING callback - if ( doSelect ) { - that._trigger( "selecting", event, { - selecting: selectee.element - } ); - } else { - that._trigger( "unselecting", event, { - unselecting: selectee.element - } ); - } - return false; - } - } ); - - }, - - _mouseDrag: function( event ) { - - this.dragged = true; - - if ( this.options.disabled ) { - return; - } - - var tmp, - that = this, - options = this.options, - x1 = this.opos[ 0 ], - y1 = this.opos[ 1 ], - x2 = event.pageX, - y2 = event.pageY; - - if ( x1 > x2 ) { - tmp = x2; x2 = x1; x1 = tmp; - } - if ( y1 > y2 ) { - tmp = y2; y2 = y1; y1 = tmp; - } - this.helper.css( { left: x1, top: y1, width: x2 - x1, height: y2 - y1 } ); - - this.selectees.each( function() { - var selectee = $.data( this, "selectable-item" ), - hit = false, - offset = {}; - - //prevent helper from being selected if appendTo: selectable - if ( !selectee || selectee.element === that.element[ 0 ] ) { - return; - } - - offset.left = selectee.left + that.elementPos.left; - offset.right = selectee.right + that.elementPos.left; - offset.top = selectee.top + that.elementPos.top; - offset.bottom = selectee.bottom + that.elementPos.top; - - if ( options.tolerance === "touch" ) { - hit = ( !( offset.left > x2 || offset.right < x1 || offset.top > y2 || - offset.bottom < y1 ) ); - } else if ( options.tolerance === "fit" ) { - hit = ( offset.left > x1 && offset.right < x2 && offset.top > y1 && - offset.bottom < y2 ); - } - - if ( hit ) { - - // SELECT - if ( selectee.selected ) { - that._removeClass( selectee.$element, "ui-selected" ); - selectee.selected = false; - } - if ( selectee.unselecting ) { - that._removeClass( selectee.$element, "ui-unselecting" ); - selectee.unselecting = false; - } - if ( !selectee.selecting ) { - that._addClass( selectee.$element, "ui-selecting" ); - selectee.selecting = true; - - // selectable SELECTING callback - that._trigger( "selecting", event, { - selecting: selectee.element - } ); - } - } else { - - // UNSELECT - if ( selectee.selecting ) { - if ( ( event.metaKey || event.ctrlKey ) && selectee.startselected ) { - that._removeClass( selectee.$element, "ui-selecting" ); - selectee.selecting = false; - that._addClass( selectee.$element, "ui-selected" ); - selectee.selected = true; - } else { - that._removeClass( selectee.$element, "ui-selecting" ); - selectee.selecting = false; - if ( selectee.startselected ) { - that._addClass( selectee.$element, "ui-unselecting" ); - selectee.unselecting = true; - } - - // selectable UNSELECTING callback - that._trigger( "unselecting", event, { - unselecting: selectee.element - } ); - } - } - if ( selectee.selected ) { - if ( !event.metaKey && !event.ctrlKey && !selectee.startselected ) { - that._removeClass( selectee.$element, "ui-selected" ); - selectee.selected = false; - - that._addClass( selectee.$element, "ui-unselecting" ); - selectee.unselecting = true; - - // selectable UNSELECTING callback - that._trigger( "unselecting", event, { - unselecting: selectee.element - } ); - } - } - } - } ); - - return false; - }, - - _mouseStop: function( event ) { - var that = this; - - this.dragged = false; - - $( ".ui-unselecting", this.element[ 0 ] ).each( function() { - var selectee = $.data( this, "selectable-item" ); - that._removeClass( selectee.$element, "ui-unselecting" ); - selectee.unselecting = false; - selectee.startselected = false; - that._trigger( "unselected", event, { - unselected: selectee.element - } ); - } ); - $( ".ui-selecting", this.element[ 0 ] ).each( function() { - var selectee = $.data( this, "selectable-item" ); - that._removeClass( selectee.$element, "ui-selecting" ) - ._addClass( selectee.$element, "ui-selected" ); - selectee.selecting = false; - selectee.selected = true; - selectee.startselected = true; - that._trigger( "selected", event, { - selected: selectee.element - } ); - } ); - this._trigger( "stop", event ); - - this.helper.remove(); - - return false; - } - -} ); + "use strict"; + + return $.widget( "ui.selectable", $.ui.mouse, { + version: "1.13.2", + options: { + appendTo: "body", + autoRefresh: true, + distance: 0, + filter: "*", + tolerance: "touch", + + // Callbacks + selected: null, + selecting: null, + start: null, + stop: null, + unselected: null, + unselecting: null + }, + _create: function() { + var that = this; + + this._addClass( "ui-selectable" ); + + this.dragged = false; + + // Cache selectee children based on filter + this.refresh = function() { + that.elementPos = $( that.element[ 0 ] ).offset(); + that.selectees = $( that.options.filter, that.element[ 0 ] ); + that._addClass( that.selectees, "ui-selectee" ); + that.selectees.each( function() { + var $this = $( this ), + selecteeOffset = $this.offset(), + pos = { + left: selecteeOffset.left - that.elementPos.left, + top: selecteeOffset.top - that.elementPos.top + }; + $.data( this, "selectable-item", { + element: this, + $element: $this, + left: pos.left, + top: pos.top, + right: pos.left + $this.outerWidth(), + bottom: pos.top + $this.outerHeight(), + startselected: false, + selected: $this.hasClass( "ui-selected" ), + selecting: $this.hasClass( "ui-selecting" ), + unselecting: $this.hasClass( "ui-unselecting" ) + } ); + } ); + }; + this.refresh(); + + this._mouseInit(); + + this.helper = $( "<div>" ); + this._addClass( this.helper, "ui-selectable-helper" ); + }, + + _destroy: function() { + this.selectees.removeData( "selectable-item" ); + this._mouseDestroy(); + }, + + _mouseStart: function( event ) { + var that = this, + options = this.options; + + this.opos = [ event.pageX, event.pageY ]; + this.elementPos = $( this.element[ 0 ] ).offset(); + + if ( this.options.disabled ) { + return; + } + + this.selectees = $( options.filter, this.element[ 0 ] ); + + this._trigger( "start", event ); + + $( options.appendTo ).append( this.helper ); + + // position helper (lasso) + this.helper.css( { + "left": event.pageX, + "top": event.pageY, + "width": 0, + "height": 0 + } ); + + if ( options.autoRefresh ) { + this.refresh(); + } + + this.selectees.filter( ".ui-selected" ).each( function() { + var selectee = $.data( this, "selectable-item" ); + selectee.startselected = true; + if ( !event.metaKey && !event.ctrlKey ) { + that._removeClass( selectee.$element, "ui-selected" ); + selectee.selected = false; + that._addClass( selectee.$element, "ui-unselecting" ); + selectee.unselecting = true; + + // selectable UNSELECTING callback + that._trigger( "unselecting", event, { + unselecting: selectee.element + } ); + } + } ); + + $( event.target ).parents().addBack().each( function() { + var doSelect, + selectee = $.data( this, "selectable-item" ); + if ( selectee ) { + doSelect = ( !event.metaKey && !event.ctrlKey ) || + !selectee.$element.hasClass( "ui-selected" ); + that._removeClass( selectee.$element, doSelect ? "ui-unselecting" : "ui-selected" ) + ._addClass( selectee.$element, doSelect ? "ui-selecting" : "ui-unselecting" ); + selectee.unselecting = !doSelect; + selectee.selecting = doSelect; + selectee.selected = doSelect; + + // selectable (UN)SELECTING callback + if ( doSelect ) { + that._trigger( "selecting", event, { + selecting: selectee.element + } ); + } else { + that._trigger( "unselecting", event, { + unselecting: selectee.element + } ); + } + return false; + } + } ); + + }, + + _mouseDrag: function( event ) { + + this.dragged = true; + + if ( this.options.disabled ) { + return; + } + + var tmp, + that = this, + options = this.options, + x1 = this.opos[ 0 ], + y1 = this.opos[ 1 ], + x2 = event.pageX, + y2 = event.pageY; + + if ( x1 > x2 ) { + tmp = x2; x2 = x1; x1 = tmp; + } + if ( y1 > y2 ) { + tmp = y2; y2 = y1; y1 = tmp; + } + this.helper.css( { left: x1, top: y1, width: x2 - x1, height: y2 - y1 } ); + + this.selectees.each( function() { + var selectee = $.data( this, "selectable-item" ), + hit = false, + offset = {}; + + //prevent helper from being selected if appendTo: selectable + if ( !selectee || selectee.element === that.element[ 0 ] ) { + return; + } + + offset.left = selectee.left + that.elementPos.left; + offset.right = selectee.right + that.elementPos.left; + offset.top = selectee.top + that.elementPos.top; + offset.bottom = selectee.bottom + that.elementPos.top; + + if ( options.tolerance === "touch" ) { + hit = ( !( offset.left > x2 || offset.right < x1 || offset.top > y2 || + offset.bottom < y1 ) ); + } else if ( options.tolerance === "fit" ) { + hit = ( offset.left > x1 && offset.right < x2 && offset.top > y1 && + offset.bottom < y2 ); + } + + if ( hit ) { + + // SELECT + if ( selectee.selected ) { + that._removeClass( selectee.$element, "ui-selected" ); + selectee.selected = false; + } + if ( selectee.unselecting ) { + that._removeClass( selectee.$element, "ui-unselecting" ); + selectee.unselecting = false; + } + if ( !selectee.selecting ) { + that._addClass( selectee.$element, "ui-selecting" ); + selectee.selecting = true; + + // selectable SELECTING callback + that._trigger( "selecting", event, { + selecting: selectee.element + } ); + } + } else { + + // UNSELECT + if ( selectee.selecting ) { + if ( ( event.metaKey || event.ctrlKey ) && selectee.startselected ) { + that._removeClass( selectee.$element, "ui-selecting" ); + selectee.selecting = false; + that._addClass( selectee.$element, "ui-selected" ); + selectee.selected = true; + } else { + that._removeClass( selectee.$element, "ui-selecting" ); + selectee.selecting = false; + if ( selectee.startselected ) { + that._addClass( selectee.$element, "ui-unselecting" ); + selectee.unselecting = true; + } + + // selectable UNSELECTING callback + that._trigger( "unselecting", event, { + unselecting: selectee.element + } ); + } + } + if ( selectee.selected ) { + if ( !event.metaKey && !event.ctrlKey && !selectee.startselected ) { + that._removeClass( selectee.$element, "ui-selected" ); + selectee.selected = false; + + that._addClass( selectee.$element, "ui-unselecting" ); + selectee.unselecting = true; + + // selectable UNSELECTING callback + that._trigger( "unselecting", event, { + unselecting: selectee.element + } ); + } + } + } + } ); + + return false; + }, + + _mouseStop: function( event ) { + var that = this; + + this.dragged = false; + + $( ".ui-unselecting", this.element[ 0 ] ).each( function() { + var selectee = $.data( this, "selectable-item" ); + that._removeClass( selectee.$element, "ui-unselecting" ); + selectee.unselecting = false; + selectee.startselected = false; + that._trigger( "unselected", event, { + unselected: selectee.element + } ); + } ); + $( ".ui-selecting", this.element[ 0 ] ).each( function() { + var selectee = $.data( this, "selectable-item" ); + that._removeClass( selectee.$element, "ui-selecting" ) + ._addClass( selectee.$element, "ui-selected" ); + selectee.selecting = false; + selectee.selected = true; + selectee.startselected = true; + that._trigger( "selected", event, { + selected: selectee.element + } ); + } ); + this._trigger( "stop", event ); + + this.helper.remove(); + + return false; + } + + } ); } ); diff --git a/lib/web/jquery/ui-modules/widgets/selectmenu.js b/lib/web/jquery/ui-modules/widgets/selectmenu.js index 1e2373b5c92e5..fd19753eb0f91 100644 --- a/lib/web/jquery/ui-modules/widgets/selectmenu.js +++ b/lib/web/jquery/ui-modules/widgets/selectmenu.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Selectmenu 1.13.1 + * jQuery UI Selectmenu 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -19,675 +19,675 @@ //>>css.theme: ../../themes/base/theme.css ( function( factory ) { - "use strict"; - - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define( [ - "jquery", - "./menu", - "../form-reset-mixin", - "../keycode", - "../labels", - "../position", - "../unique-id", - "../version", - "../widget" - ], factory ); - } else { - - // Browser globals - factory( jQuery ); - } + "use strict"; + + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ + "jquery", + "./menu", + "../form-reset-mixin", + "../keycode", + "../labels", + "../position", + "../unique-id", + "../version", + "../widget" + ], factory ); + } else { + + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; - -return $.widget( "ui.selectmenu", [ $.ui.formResetMixin, { - version: "1.13.1", - defaultElement: "<select>", - options: { - appendTo: null, - classes: { - "ui-selectmenu-button-open": "ui-corner-top", - "ui-selectmenu-button-closed": "ui-corner-all" - }, - disabled: null, - icons: { - button: "ui-icon-triangle-1-s" - }, - position: { - my: "left top", - at: "left bottom", - collision: "none" - }, - width: false, - - // Callbacks - change: null, - close: null, - focus: null, - open: null, - select: null - }, - - _create: function() { - var selectmenuId = this.element.uniqueId().attr( "id" ); - this.ids = { - element: selectmenuId, - button: selectmenuId + "-button", - menu: selectmenuId + "-menu" - }; - - this._drawButton(); - this._drawMenu(); - this._bindFormResetHandler(); - - this._rendered = false; - this.menuItems = $(); - }, - - _drawButton: function() { - var icon, - that = this, - item = this._parseOption( - this.element.find( "option:selected" ), - this.element[ 0 ].selectedIndex - ); - - // Associate existing label with the new button - this.labels = this.element.labels().attr( "for", this.ids.button ); - this._on( this.labels, { - click: function( event ) { - this.button.trigger( "focus" ); - event.preventDefault(); - } - } ); - - // Hide original select element - this.element.hide(); - - // Create button - this.button = $( "<span>", { - tabindex: this.options.disabled ? -1 : 0, - id: this.ids.button, - role: "combobox", - "aria-expanded": "false", - "aria-autocomplete": "list", - "aria-owns": this.ids.menu, - "aria-haspopup": "true", - title: this.element.attr( "title" ) - } ) - .insertAfter( this.element ); - - this._addClass( this.button, "ui-selectmenu-button ui-selectmenu-button-closed", - "ui-button ui-widget" ); - - icon = $( "<span>" ).appendTo( this.button ); - this._addClass( icon, "ui-selectmenu-icon", "ui-icon " + this.options.icons.button ); - this.buttonItem = this._renderButtonItem( item ) - .appendTo( this.button ); - - if ( this.options.width !== false ) { - this._resizeButton(); - } - - this._on( this.button, this._buttonEvents ); - this.button.one( "focusin", function() { - - // Delay rendering the menu items until the button receives focus. - // The menu may have already been rendered via a programmatic open. - if ( !that._rendered ) { - that._refreshMenu(); - } - } ); - }, - - _drawMenu: function() { - var that = this; - - // Create menu - this.menu = $( "<ul>", { - "aria-hidden": "true", - "aria-labelledby": this.ids.button, - id: this.ids.menu - } ); - - // Wrap menu - this.menuWrap = $( "<div>" ).append( this.menu ); - this._addClass( this.menuWrap, "ui-selectmenu-menu", "ui-front" ); - this.menuWrap.appendTo( this._appendTo() ); - - // Initialize menu widget - this.menuInstance = this.menu - .menu( { - classes: { - "ui-menu": "ui-corner-bottom" - }, - role: "listbox", - select: function( event, ui ) { - event.preventDefault(); - - // Support: IE8 - // If the item was selected via a click, the text selection - // will be destroyed in IE - that._setSelection(); - - that._select( ui.item.data( "ui-selectmenu-item" ), event ); - }, - focus: function( event, ui ) { - var item = ui.item.data( "ui-selectmenu-item" ); - - // Prevent inital focus from firing and check if its a newly focused item - if ( that.focusIndex != null && item.index !== that.focusIndex ) { - that._trigger( "focus", event, { item: item } ); - if ( !that.isOpen ) { - that._select( item, event ); - } - } - that.focusIndex = item.index; - - that.button.attr( "aria-activedescendant", - that.menuItems.eq( item.index ).attr( "id" ) ); - } - } ) - .menu( "instance" ); - - // Don't close the menu on mouseleave - this.menuInstance._off( this.menu, "mouseleave" ); - - // Cancel the menu's collapseAll on document click - this.menuInstance._closeOnDocumentClick = function() { - return false; - }; - - // Selects often contain empty items, but never contain dividers - this.menuInstance._isDivider = function() { - return false; - }; - }, - - refresh: function() { - this._refreshMenu(); - this.buttonItem.replaceWith( - this.buttonItem = this._renderButtonItem( - - // Fall back to an empty object in case there are no options - this._getSelectedItem().data( "ui-selectmenu-item" ) || {} - ) - ); - if ( this.options.width === null ) { - this._resizeButton(); - } - }, - - _refreshMenu: function() { - var item, - options = this.element.find( "option" ); - - this.menu.empty(); - - this._parseOptions( options ); - this._renderMenu( this.menu, this.items ); - - this.menuInstance.refresh(); - this.menuItems = this.menu.find( "li" ) - .not( ".ui-selectmenu-optgroup" ) - .find( ".ui-menu-item-wrapper" ); - - this._rendered = true; - - if ( !options.length ) { - return; - } - - item = this._getSelectedItem(); - - // Update the menu to have the correct item focused - this.menuInstance.focus( null, item ); - this._setAria( item.data( "ui-selectmenu-item" ) ); - - // Set disabled state - this._setOption( "disabled", this.element.prop( "disabled" ) ); - }, - - open: function( event ) { - if ( this.options.disabled ) { - return; - } - - // If this is the first time the menu is being opened, render the items - if ( !this._rendered ) { - this._refreshMenu(); - } else { - - // Menu clears focus on close, reset focus to selected item - this._removeClass( this.menu.find( ".ui-state-active" ), null, "ui-state-active" ); - this.menuInstance.focus( null, this._getSelectedItem() ); - } - - // If there are no options, don't open the menu - if ( !this.menuItems.length ) { - return; - } - - this.isOpen = true; - this._toggleAttr(); - this._resizeMenu(); - this._position(); - - this._on( this.document, this._documentClick ); - - this._trigger( "open", event ); - }, - - _position: function() { - this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) ); - }, - - close: function( event ) { - if ( !this.isOpen ) { - return; - } - - this.isOpen = false; - this._toggleAttr(); - - this.range = null; - this._off( this.document ); - - this._trigger( "close", event ); - }, - - widget: function() { - return this.button; - }, - - menuWidget: function() { - return this.menu; - }, - - _renderButtonItem: function( item ) { - var buttonItem = $( "<span>" ); - - this._setText( buttonItem, item.label ); - this._addClass( buttonItem, "ui-selectmenu-text" ); - - return buttonItem; - }, - - _renderMenu: function( ul, items ) { - var that = this, - currentOptgroup = ""; - - $.each( items, function( index, item ) { - var li; - - if ( item.optgroup !== currentOptgroup ) { - li = $( "<li>", { - text: item.optgroup - } ); - that._addClass( li, "ui-selectmenu-optgroup", "ui-menu-divider" + - ( item.element.parent( "optgroup" ).prop( "disabled" ) ? - " ui-state-disabled" : - "" ) ); - - li.appendTo( ul ); - - currentOptgroup = item.optgroup; - } - - that._renderItemData( ul, item ); - } ); - }, - - _renderItemData: function( ul, item ) { - return this._renderItem( ul, item ).data( "ui-selectmenu-item", item ); - }, - - _renderItem: function( ul, item ) { - var li = $( "<li>" ), - wrapper = $( "<div>", { - title: item.element.attr( "title" ) - } ); - - if ( item.disabled ) { - this._addClass( li, null, "ui-state-disabled" ); - } - this._setText( wrapper, item.label ); - - return li.append( wrapper ).appendTo( ul ); - }, - - _setText: function( element, value ) { - if ( value ) { - element.text( value ); - } else { - element.html( " " ); - } - }, - - _move: function( direction, event ) { - var item, next, - filter = ".ui-menu-item"; - - if ( this.isOpen ) { - item = this.menuItems.eq( this.focusIndex ).parent( "li" ); - } else { - item = this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" ); - filter += ":not(.ui-state-disabled)"; - } - - if ( direction === "first" || direction === "last" ) { - next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 ); - } else { - next = item[ direction + "All" ]( filter ).eq( 0 ); - } - - if ( next.length ) { - this.menuInstance.focus( event, next ); - } - }, - - _getSelectedItem: function() { - return this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" ); - }, - - _toggle: function( event ) { - this[ this.isOpen ? "close" : "open" ]( event ); - }, - - _setSelection: function() { - var selection; - - if ( !this.range ) { - return; - } - - if ( window.getSelection ) { - selection = window.getSelection(); - selection.removeAllRanges(); - selection.addRange( this.range ); - - // Support: IE8 - } else { - this.range.select(); - } - - // Support: IE - // Setting the text selection kills the button focus in IE, but - // restoring the focus doesn't kill the selection. - this.button.focus(); - }, - - _documentClick: { - mousedown: function( event ) { - if ( !this.isOpen ) { - return; - } - - if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" + - $.escapeSelector( this.ids.button ) ).length ) { - this.close( event ); - } - } - }, - - _buttonEvents: { - - // Prevent text selection from being reset when interacting with the selectmenu (#10144) - mousedown: function() { - var selection; - - if ( window.getSelection ) { - selection = window.getSelection(); - if ( selection.rangeCount ) { - this.range = selection.getRangeAt( 0 ); - } - - // Support: IE8 - } else { - this.range = document.selection.createRange(); - } - }, - - click: function( event ) { - this._setSelection(); - this._toggle( event ); - }, - - keydown: function( event ) { - var preventDefault = true; - switch ( event.keyCode ) { - case $.ui.keyCode.TAB: - case $.ui.keyCode.ESCAPE: - this.close( event ); - preventDefault = false; - break; - case $.ui.keyCode.ENTER: - if ( this.isOpen ) { - this._selectFocusedItem( event ); - } - break; - case $.ui.keyCode.UP: - if ( event.altKey ) { - this._toggle( event ); - } else { - this._move( "prev", event ); - } - break; - case $.ui.keyCode.DOWN: - if ( event.altKey ) { - this._toggle( event ); - } else { - this._move( "next", event ); - } - break; - case $.ui.keyCode.SPACE: - if ( this.isOpen ) { - this._selectFocusedItem( event ); - } else { - this._toggle( event ); - } - break; - case $.ui.keyCode.LEFT: - this._move( "prev", event ); - break; - case $.ui.keyCode.RIGHT: - this._move( "next", event ); - break; - case $.ui.keyCode.HOME: - case $.ui.keyCode.PAGE_UP: - this._move( "first", event ); - break; - case $.ui.keyCode.END: - case $.ui.keyCode.PAGE_DOWN: - this._move( "last", event ); - break; - default: - this.menu.trigger( event ); - preventDefault = false; - } - - if ( preventDefault ) { - event.preventDefault(); - } - } - }, - - _selectFocusedItem: function( event ) { - var item = this.menuItems.eq( this.focusIndex ).parent( "li" ); - if ( !item.hasClass( "ui-state-disabled" ) ) { - this._select( item.data( "ui-selectmenu-item" ), event ); - } - }, - - _select: function( item, event ) { - var oldIndex = this.element[ 0 ].selectedIndex; - - // Change native select element - this.element[ 0 ].selectedIndex = item.index; - this.buttonItem.replaceWith( this.buttonItem = this._renderButtonItem( item ) ); - this._setAria( item ); - this._trigger( "select", event, { item: item } ); - - if ( item.index !== oldIndex ) { - this._trigger( "change", event, { item: item } ); - } - - this.close( event ); - }, - - _setAria: function( item ) { - var id = this.menuItems.eq( item.index ).attr( "id" ); - - this.button.attr( { - "aria-labelledby": id, - "aria-activedescendant": id - } ); - this.menu.attr( "aria-activedescendant", id ); - }, - - _setOption: function( key, value ) { - if ( key === "icons" ) { - var icon = this.button.find( "span.ui-icon" ); - this._removeClass( icon, null, this.options.icons.button ) - ._addClass( icon, null, value.button ); - } - - this._super( key, value ); - - if ( key === "appendTo" ) { - this.menuWrap.appendTo( this._appendTo() ); - } - - if ( key === "width" ) { - this._resizeButton(); - } - }, - - _setOptionDisabled: function( value ) { - this._super( value ); - - this.menuInstance.option( "disabled", value ); - this.button.attr( "aria-disabled", value ); - this._toggleClass( this.button, null, "ui-state-disabled", value ); - - this.element.prop( "disabled", value ); - if ( value ) { - this.button.attr( "tabindex", -1 ); - this.close(); - } else { - this.button.attr( "tabindex", 0 ); - } - }, - - _appendTo: function() { - var element = this.options.appendTo; - - if ( element ) { - element = element.jquery || element.nodeType ? - $( element ) : - this.document.find( element ).eq( 0 ); - } - - if ( !element || !element[ 0 ] ) { - element = this.element.closest( ".ui-front, dialog" ); - } - - if ( !element.length ) { - element = this.document[ 0 ].body; - } - - return element; - }, - - _toggleAttr: function() { - this.button.attr( "aria-expanded", this.isOpen ); - - // We can't use two _toggleClass() calls here, because we need to make sure - // we always remove classes first and add them second, otherwise if both classes have the - // same theme class, it will be removed after we add it. - this._removeClass( this.button, "ui-selectmenu-button-" + - ( this.isOpen ? "closed" : "open" ) ) - ._addClass( this.button, "ui-selectmenu-button-" + - ( this.isOpen ? "open" : "closed" ) ) - ._toggleClass( this.menuWrap, "ui-selectmenu-open", null, this.isOpen ); - - this.menu.attr( "aria-hidden", !this.isOpen ); - }, - - _resizeButton: function() { - var width = this.options.width; - - // For `width: false`, just remove inline style and stop - if ( width === false ) { - this.button.css( "width", "" ); - return; - } - - // For `width: null`, match the width of the original element - if ( width === null ) { - width = this.element.show().outerWidth(); - this.element.hide(); - } - - this.button.outerWidth( width ); - }, - - _resizeMenu: function() { - this.menu.outerWidth( Math.max( - this.button.outerWidth(), - - // Support: IE10 - // IE10 wraps long text (possibly a rounding bug) - // so we add 1px to avoid the wrapping - this.menu.width( "" ).outerWidth() + 1 - ) ); - }, - - _getCreateOptions: function() { - var options = this._super(); - - options.disabled = this.element.prop( "disabled" ); - - return options; - }, - - _parseOptions: function( options ) { - var that = this, - data = []; - options.each( function( index, item ) { - if ( item.hidden ) { - return; - } - - data.push( that._parseOption( $( item ), index ) ); - } ); - this.items = data; - }, - - _parseOption: function( option, index ) { - var optgroup = option.parent( "optgroup" ); - - return { - element: option, - index: index, - value: option.val(), - label: option.text(), - optgroup: optgroup.attr( "label" ) || "", - disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" ) - }; - }, - - _destroy: function() { - this._unbindFormResetHandler(); - this.menuWrap.remove(); - this.button.remove(); - this.element.show(); - this.element.removeUniqueId(); - this.labels.attr( "for", this.ids.element ); - } -} ] ); + "use strict"; + + return $.widget( "ui.selectmenu", [ $.ui.formResetMixin, { + version: "1.13.2", + defaultElement: "<select>", + options: { + appendTo: null, + classes: { + "ui-selectmenu-button-open": "ui-corner-top", + "ui-selectmenu-button-closed": "ui-corner-all" + }, + disabled: null, + icons: { + button: "ui-icon-triangle-1-s" + }, + position: { + my: "left top", + at: "left bottom", + collision: "none" + }, + width: false, + + // Callbacks + change: null, + close: null, + focus: null, + open: null, + select: null + }, + + _create: function() { + var selectmenuId = this.element.uniqueId().attr( "id" ); + this.ids = { + element: selectmenuId, + button: selectmenuId + "-button", + menu: selectmenuId + "-menu" + }; + + this._drawButton(); + this._drawMenu(); + this._bindFormResetHandler(); + + this._rendered = false; + this.menuItems = $(); + }, + + _drawButton: function() { + var icon, + that = this, + item = this._parseOption( + this.element.find( "option:selected" ), + this.element[ 0 ].selectedIndex + ); + + // Associate existing label with the new button + this.labels = this.element.labels().attr( "for", this.ids.button ); + this._on( this.labels, { + click: function( event ) { + this.button.trigger( "focus" ); + event.preventDefault(); + } + } ); + + // Hide original select element + this.element.hide(); + + // Create button + this.button = $( "<span>", { + tabindex: this.options.disabled ? -1 : 0, + id: this.ids.button, + role: "combobox", + "aria-expanded": "false", + "aria-autocomplete": "list", + "aria-owns": this.ids.menu, + "aria-haspopup": "true", + title: this.element.attr( "title" ) + } ) + .insertAfter( this.element ); + + this._addClass( this.button, "ui-selectmenu-button ui-selectmenu-button-closed", + "ui-button ui-widget" ); + + icon = $( "<span>" ).appendTo( this.button ); + this._addClass( icon, "ui-selectmenu-icon", "ui-icon " + this.options.icons.button ); + this.buttonItem = this._renderButtonItem( item ) + .appendTo( this.button ); + + if ( this.options.width !== false ) { + this._resizeButton(); + } + + this._on( this.button, this._buttonEvents ); + this.button.one( "focusin", function() { + + // Delay rendering the menu items until the button receives focus. + // The menu may have already been rendered via a programmatic open. + if ( !that._rendered ) { + that._refreshMenu(); + } + } ); + }, + + _drawMenu: function() { + var that = this; + + // Create menu + this.menu = $( "<ul>", { + "aria-hidden": "true", + "aria-labelledby": this.ids.button, + id: this.ids.menu + } ); + + // Wrap menu + this.menuWrap = $( "<div>" ).append( this.menu ); + this._addClass( this.menuWrap, "ui-selectmenu-menu", "ui-front" ); + this.menuWrap.appendTo( this._appendTo() ); + + // Initialize menu widget + this.menuInstance = this.menu + .menu( { + classes: { + "ui-menu": "ui-corner-bottom" + }, + role: "listbox", + select: function( event, ui ) { + event.preventDefault(); + + // Support: IE8 + // If the item was selected via a click, the text selection + // will be destroyed in IE + that._setSelection(); + + that._select( ui.item.data( "ui-selectmenu-item" ), event ); + }, + focus: function( event, ui ) { + var item = ui.item.data( "ui-selectmenu-item" ); + + // Prevent inital focus from firing and check if its a newly focused item + if ( that.focusIndex != null && item.index !== that.focusIndex ) { + that._trigger( "focus", event, { item: item } ); + if ( !that.isOpen ) { + that._select( item, event ); + } + } + that.focusIndex = item.index; + + that.button.attr( "aria-activedescendant", + that.menuItems.eq( item.index ).attr( "id" ) ); + } + } ) + .menu( "instance" ); + + // Don't close the menu on mouseleave + this.menuInstance._off( this.menu, "mouseleave" ); + + // Cancel the menu's collapseAll on document click + this.menuInstance._closeOnDocumentClick = function() { + return false; + }; + + // Selects often contain empty items, but never contain dividers + this.menuInstance._isDivider = function() { + return false; + }; + }, + + refresh: function() { + this._refreshMenu(); + this.buttonItem.replaceWith( + this.buttonItem = this._renderButtonItem( + + // Fall back to an empty object in case there are no options + this._getSelectedItem().data( "ui-selectmenu-item" ) || {} + ) + ); + if ( this.options.width === null ) { + this._resizeButton(); + } + }, + + _refreshMenu: function() { + var item, + options = this.element.find( "option" ); + + this.menu.empty(); + + this._parseOptions( options ); + this._renderMenu( this.menu, this.items ); + + this.menuInstance.refresh(); + this.menuItems = this.menu.find( "li" ) + .not( ".ui-selectmenu-optgroup" ) + .find( ".ui-menu-item-wrapper" ); + + this._rendered = true; + + if ( !options.length ) { + return; + } + + item = this._getSelectedItem(); + + // Update the menu to have the correct item focused + this.menuInstance.focus( null, item ); + this._setAria( item.data( "ui-selectmenu-item" ) ); + + // Set disabled state + this._setOption( "disabled", this.element.prop( "disabled" ) ); + }, + + open: function( event ) { + if ( this.options.disabled ) { + return; + } + + // If this is the first time the menu is being opened, render the items + if ( !this._rendered ) { + this._refreshMenu(); + } else { + + // Menu clears focus on close, reset focus to selected item + this._removeClass( this.menu.find( ".ui-state-active" ), null, "ui-state-active" ); + this.menuInstance.focus( null, this._getSelectedItem() ); + } + + // If there are no options, don't open the menu + if ( !this.menuItems.length ) { + return; + } + + this.isOpen = true; + this._toggleAttr(); + this._resizeMenu(); + this._position(); + + this._on( this.document, this._documentClick ); + + this._trigger( "open", event ); + }, + + _position: function() { + this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) ); + }, + + close: function( event ) { + if ( !this.isOpen ) { + return; + } + + this.isOpen = false; + this._toggleAttr(); + + this.range = null; + this._off( this.document ); + + this._trigger( "close", event ); + }, + + widget: function() { + return this.button; + }, + + menuWidget: function() { + return this.menu; + }, + + _renderButtonItem: function( item ) { + var buttonItem = $( "<span>" ); + + this._setText( buttonItem, item.label ); + this._addClass( buttonItem, "ui-selectmenu-text" ); + + return buttonItem; + }, + + _renderMenu: function( ul, items ) { + var that = this, + currentOptgroup = ""; + + $.each( items, function( index, item ) { + var li; + + if ( item.optgroup !== currentOptgroup ) { + li = $( "<li>", { + text: item.optgroup + } ); + that._addClass( li, "ui-selectmenu-optgroup", "ui-menu-divider" + + ( item.element.parent( "optgroup" ).prop( "disabled" ) ? + " ui-state-disabled" : + "" ) ); + + li.appendTo( ul ); + + currentOptgroup = item.optgroup; + } + + that._renderItemData( ul, item ); + } ); + }, + + _renderItemData: function( ul, item ) { + return this._renderItem( ul, item ).data( "ui-selectmenu-item", item ); + }, + + _renderItem: function( ul, item ) { + var li = $( "<li>" ), + wrapper = $( "<div>", { + title: item.element.attr( "title" ) + } ); + + if ( item.disabled ) { + this._addClass( li, null, "ui-state-disabled" ); + } + this._setText( wrapper, item.label ); + + return li.append( wrapper ).appendTo( ul ); + }, + + _setText: function( element, value ) { + if ( value ) { + element.text( value ); + } else { + element.html( " " ); + } + }, + + _move: function( direction, event ) { + var item, next, + filter = ".ui-menu-item"; + + if ( this.isOpen ) { + item = this.menuItems.eq( this.focusIndex ).parent( "li" ); + } else { + item = this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" ); + filter += ":not(.ui-state-disabled)"; + } + + if ( direction === "first" || direction === "last" ) { + next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 ); + } else { + next = item[ direction + "All" ]( filter ).eq( 0 ); + } + + if ( next.length ) { + this.menuInstance.focus( event, next ); + } + }, + + _getSelectedItem: function() { + return this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" ); + }, + + _toggle: function( event ) { + this[ this.isOpen ? "close" : "open" ]( event ); + }, + + _setSelection: function() { + var selection; + + if ( !this.range ) { + return; + } + + if ( window.getSelection ) { + selection = window.getSelection(); + selection.removeAllRanges(); + selection.addRange( this.range ); + + // Support: IE8 + } else { + this.range.select(); + } + + // Support: IE + // Setting the text selection kills the button focus in IE, but + // restoring the focus doesn't kill the selection. + this.button.trigger( "focus" ); + }, + + _documentClick: { + mousedown: function( event ) { + if ( !this.isOpen ) { + return; + } + + if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" + + $.escapeSelector( this.ids.button ) ).length ) { + this.close( event ); + } + } + }, + + _buttonEvents: { + + // Prevent text selection from being reset when interacting with the selectmenu (#10144) + mousedown: function() { + var selection; + + if ( window.getSelection ) { + selection = window.getSelection(); + if ( selection.rangeCount ) { + this.range = selection.getRangeAt( 0 ); + } + + // Support: IE8 + } else { + this.range = document.selection.createRange(); + } + }, + + click: function( event ) { + this._setSelection(); + this._toggle( event ); + }, + + keydown: function( event ) { + var preventDefault = true; + switch ( event.keyCode ) { + case $.ui.keyCode.TAB: + case $.ui.keyCode.ESCAPE: + this.close( event ); + preventDefault = false; + break; + case $.ui.keyCode.ENTER: + if ( this.isOpen ) { + this._selectFocusedItem( event ); + } + break; + case $.ui.keyCode.UP: + if ( event.altKey ) { + this._toggle( event ); + } else { + this._move( "prev", event ); + } + break; + case $.ui.keyCode.DOWN: + if ( event.altKey ) { + this._toggle( event ); + } else { + this._move( "next", event ); + } + break; + case $.ui.keyCode.SPACE: + if ( this.isOpen ) { + this._selectFocusedItem( event ); + } else { + this._toggle( event ); + } + break; + case $.ui.keyCode.LEFT: + this._move( "prev", event ); + break; + case $.ui.keyCode.RIGHT: + this._move( "next", event ); + break; + case $.ui.keyCode.HOME: + case $.ui.keyCode.PAGE_UP: + this._move( "first", event ); + break; + case $.ui.keyCode.END: + case $.ui.keyCode.PAGE_DOWN: + this._move( "last", event ); + break; + default: + this.menu.trigger( event ); + preventDefault = false; + } + + if ( preventDefault ) { + event.preventDefault(); + } + } + }, + + _selectFocusedItem: function( event ) { + var item = this.menuItems.eq( this.focusIndex ).parent( "li" ); + if ( !item.hasClass( "ui-state-disabled" ) ) { + this._select( item.data( "ui-selectmenu-item" ), event ); + } + }, + + _select: function( item, event ) { + var oldIndex = this.element[ 0 ].selectedIndex; + + // Change native select element + this.element[ 0 ].selectedIndex = item.index; + this.buttonItem.replaceWith( this.buttonItem = this._renderButtonItem( item ) ); + this._setAria( item ); + this._trigger( "select", event, { item: item } ); + + if ( item.index !== oldIndex ) { + this._trigger( "change", event, { item: item } ); + } + + this.close( event ); + }, + + _setAria: function( item ) { + var id = this.menuItems.eq( item.index ).attr( "id" ); + + this.button.attr( { + "aria-labelledby": id, + "aria-activedescendant": id + } ); + this.menu.attr( "aria-activedescendant", id ); + }, + + _setOption: function( key, value ) { + if ( key === "icons" ) { + var icon = this.button.find( "span.ui-icon" ); + this._removeClass( icon, null, this.options.icons.button ) + ._addClass( icon, null, value.button ); + } + + this._super( key, value ); + + if ( key === "appendTo" ) { + this.menuWrap.appendTo( this._appendTo() ); + } + + if ( key === "width" ) { + this._resizeButton(); + } + }, + + _setOptionDisabled: function( value ) { + this._super( value ); + + this.menuInstance.option( "disabled", value ); + this.button.attr( "aria-disabled", value ); + this._toggleClass( this.button, null, "ui-state-disabled", value ); + + this.element.prop( "disabled", value ); + if ( value ) { + this.button.attr( "tabindex", -1 ); + this.close(); + } else { + this.button.attr( "tabindex", 0 ); + } + }, + + _appendTo: function() { + var element = this.options.appendTo; + + if ( element ) { + element = element.jquery || element.nodeType ? + $( element ) : + this.document.find( element ).eq( 0 ); + } + + if ( !element || !element[ 0 ] ) { + element = this.element.closest( ".ui-front, dialog" ); + } + + if ( !element.length ) { + element = this.document[ 0 ].body; + } + + return element; + }, + + _toggleAttr: function() { + this.button.attr( "aria-expanded", this.isOpen ); + + // We can't use two _toggleClass() calls here, because we need to make sure + // we always remove classes first and add them second, otherwise if both classes have the + // same theme class, it will be removed after we add it. + this._removeClass( this.button, "ui-selectmenu-button-" + + ( this.isOpen ? "closed" : "open" ) ) + ._addClass( this.button, "ui-selectmenu-button-" + + ( this.isOpen ? "open" : "closed" ) ) + ._toggleClass( this.menuWrap, "ui-selectmenu-open", null, this.isOpen ); + + this.menu.attr( "aria-hidden", !this.isOpen ); + }, + + _resizeButton: function() { + var width = this.options.width; + + // For `width: false`, just remove inline style and stop + if ( width === false ) { + this.button.css( "width", "" ); + return; + } + + // For `width: null`, match the width of the original element + if ( width === null ) { + width = this.element.show().outerWidth(); + this.element.hide(); + } + + this.button.outerWidth( width ); + }, + + _resizeMenu: function() { + this.menu.outerWidth( Math.max( + this.button.outerWidth(), + + // Support: IE10 + // IE10 wraps long text (possibly a rounding bug) + // so we add 1px to avoid the wrapping + this.menu.width( "" ).outerWidth() + 1 + ) ); + }, + + _getCreateOptions: function() { + var options = this._super(); + + options.disabled = this.element.prop( "disabled" ); + + return options; + }, + + _parseOptions: function( options ) { + var that = this, + data = []; + options.each( function( index, item ) { + if ( item.hidden ) { + return; + } + + data.push( that._parseOption( $( item ), index ) ); + } ); + this.items = data; + }, + + _parseOption: function( option, index ) { + var optgroup = option.parent( "optgroup" ); + + return { + element: option, + index: index, + value: option.val(), + label: option.text(), + optgroup: optgroup.attr( "label" ) || "", + disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" ) + }; + }, + + _destroy: function() { + this._unbindFormResetHandler(); + this.menuWrap.remove(); + this.button.remove(); + this.element.show(); + this.element.removeUniqueId(); + this.labels.attr( "for", this.ids.element ); + } + } ] ); } ); diff --git a/lib/web/jquery/ui-modules/widgets/slider.js b/lib/web/jquery/ui-modules/widgets/slider.js index e1a3d27387bd1..e9208b1707bb1 100644 --- a/lib/web/jquery/ui-modules/widgets/slider.js +++ b/lib/web/jquery/ui-modules/widgets/slider.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Slider 1.13.1 + * jQuery UI Slider 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -17,739 +17,739 @@ //>>css.theme: ../../themes/base/theme.css ( function( factory ) { - "use strict"; - - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define( [ - "jquery", - "./mouse", - "../keycode", - "../version", - "../widget" - ], factory ); - } else { - - // Browser globals - factory( jQuery ); - } + "use strict"; + + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ + "jquery", + "./mouse", + "../keycode", + "../version", + "../widget" + ], factory ); + } else { + + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; - -return $.widget( "ui.slider", $.ui.mouse, { - version: "1.13.1", - widgetEventPrefix: "slide", - - options: { - animate: false, - classes: { - "ui-slider": "ui-corner-all", - "ui-slider-handle": "ui-corner-all", - - // Note: ui-widget-header isn't the most fittingly semantic framework class for this - // element, but worked best visually with a variety of themes - "ui-slider-range": "ui-corner-all ui-widget-header" - }, - distance: 0, - max: 100, - min: 0, - orientation: "horizontal", - range: false, - step: 1, - value: 0, - values: null, - - // Callbacks - change: null, - slide: null, - start: null, - stop: null - }, - - // Number of pages in a slider - // (how many times can you page up/down to go through the whole range) - numPages: 5, - - _create: function() { - this._keySliding = false; - this._mouseSliding = false; - this._animateOff = true; - this._handleIndex = null; - this._detectOrientation(); - this._mouseInit(); - this._calculateNewMax(); - - this._addClass( "ui-slider ui-slider-" + this.orientation, - "ui-widget ui-widget-content" ); - - this._refresh(); - - this._animateOff = false; - }, - - _refresh: function() { - this._createRange(); - this._createHandles(); - this._setupEvents(); - this._refreshValue(); - }, - - _createHandles: function() { - var i, handleCount, - options = this.options, - existingHandles = this.element.find( ".ui-slider-handle" ), - handle = "<span tabindex='0'></span>", - handles = []; - - handleCount = ( options.values && options.values.length ) || 1; - - if ( existingHandles.length > handleCount ) { - existingHandles.slice( handleCount ).remove(); - existingHandles = existingHandles.slice( 0, handleCount ); - } - - for ( i = existingHandles.length; i < handleCount; i++ ) { - handles.push( handle ); - } - - this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) ); - - this._addClass( this.handles, "ui-slider-handle", "ui-state-default" ); - - this.handle = this.handles.eq( 0 ); - - this.handles.each( function( i ) { - $( this ) - .data( "ui-slider-handle-index", i ) - .attr( "tabIndex", 0 ); - } ); - }, - - _createRange: function() { - var options = this.options; - - if ( options.range ) { - if ( options.range === true ) { - if ( !options.values ) { - options.values = [ this._valueMin(), this._valueMin() ]; - } else if ( options.values.length && options.values.length !== 2 ) { - options.values = [ options.values[ 0 ], options.values[ 0 ] ]; - } else if ( Array.isArray( options.values ) ) { - options.values = options.values.slice( 0 ); - } - } - - if ( !this.range || !this.range.length ) { - this.range = $( "<div>" ) - .appendTo( this.element ); - - this._addClass( this.range, "ui-slider-range" ); - } else { - this._removeClass( this.range, "ui-slider-range-min ui-slider-range-max" ); - - // Handle range switching from true to min/max - this.range.css( { - "left": "", - "bottom": "" - } ); - } - if ( options.range === "min" || options.range === "max" ) { - this._addClass( this.range, "ui-slider-range-" + options.range ); - } - } else { - if ( this.range ) { - this.range.remove(); - } - this.range = null; - } - }, - - _setupEvents: function() { - this._off( this.handles ); - this._on( this.handles, this._handleEvents ); - this._hoverable( this.handles ); - this._focusable( this.handles ); - }, - - _destroy: function() { - this.handles.remove(); - if ( this.range ) { - this.range.remove(); - } - - this._mouseDestroy(); - }, - - _mouseCapture: function( event ) { - var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle, - that = this, - o = this.options; - - if ( o.disabled ) { - return false; - } - - this.elementSize = { - width: this.element.outerWidth(), - height: this.element.outerHeight() - }; - this.elementOffset = this.element.offset(); - - position = { x: event.pageX, y: event.pageY }; - normValue = this._normValueFromMouse( position ); - distance = this._valueMax() - this._valueMin() + 1; - this.handles.each( function( i ) { - var thisDistance = Math.abs( normValue - that.values( i ) ); - if ( ( distance > thisDistance ) || - ( distance === thisDistance && - ( i === that._lastChangedValue || that.values( i ) === o.min ) ) ) { - distance = thisDistance; - closestHandle = $( this ); - index = i; - } - } ); - - allowed = this._start( event, index ); - if ( allowed === false ) { - return false; - } - this._mouseSliding = true; - - this._handleIndex = index; - - this._addClass( closestHandle, null, "ui-state-active" ); - closestHandle.trigger( "focus" ); - - offset = closestHandle.offset(); - mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" ); - this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : { - left: event.pageX - offset.left - ( closestHandle.width() / 2 ), - top: event.pageY - offset.top - - ( closestHandle.height() / 2 ) - - ( parseInt( closestHandle.css( "borderTopWidth" ), 10 ) || 0 ) - - ( parseInt( closestHandle.css( "borderBottomWidth" ), 10 ) || 0 ) + - ( parseInt( closestHandle.css( "marginTop" ), 10 ) || 0 ) - }; - - if ( !this.handles.hasClass( "ui-state-hover" ) ) { - this._slide( event, index, normValue ); - } - this._animateOff = true; - return true; - }, - - _mouseStart: function() { - return true; - }, - - _mouseDrag: function( event ) { - var position = { x: event.pageX, y: event.pageY }, - normValue = this._normValueFromMouse( position ); - - this._slide( event, this._handleIndex, normValue ); - - return false; - }, - - _mouseStop: function( event ) { - this._removeClass( this.handles, null, "ui-state-active" ); - this._mouseSliding = false; - - this._stop( event, this._handleIndex ); - this._change( event, this._handleIndex ); - - this._handleIndex = null; - this._clickOffset = null; - this._animateOff = false; - - return false; - }, - - _detectOrientation: function() { - this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal"; - }, - - _normValueFromMouse: function( position ) { - var pixelTotal, - pixelMouse, - percentMouse, - valueTotal, - valueMouse; - - if ( this.orientation === "horizontal" ) { - pixelTotal = this.elementSize.width; - pixelMouse = position.x - this.elementOffset.left - - ( this._clickOffset ? this._clickOffset.left : 0 ); - } else { - pixelTotal = this.elementSize.height; - pixelMouse = position.y - this.elementOffset.top - - ( this._clickOffset ? this._clickOffset.top : 0 ); - } - - percentMouse = ( pixelMouse / pixelTotal ); - if ( percentMouse > 1 ) { - percentMouse = 1; - } - if ( percentMouse < 0 ) { - percentMouse = 0; - } - if ( this.orientation === "vertical" ) { - percentMouse = 1 - percentMouse; - } - - valueTotal = this._valueMax() - this._valueMin(); - valueMouse = this._valueMin() + percentMouse * valueTotal; - - return this._trimAlignValue( valueMouse ); - }, - - _uiHash: function( index, value, values ) { - var uiHash = { - handle: this.handles[ index ], - handleIndex: index, - value: value !== undefined ? value : this.value() - }; - - if ( this._hasMultipleValues() ) { - uiHash.value = value !== undefined ? value : this.values( index ); - uiHash.values = values || this.values(); - } - - return uiHash; - }, - - _hasMultipleValues: function() { - return this.options.values && this.options.values.length; - }, - - _start: function( event, index ) { - return this._trigger( "start", event, this._uiHash( index ) ); - }, - - _slide: function( event, index, newVal ) { - var allowed, otherVal, - currentValue = this.value(), - newValues = this.values(); - - if ( this._hasMultipleValues() ) { - otherVal = this.values( index ? 0 : 1 ); - currentValue = this.values( index ); - - if ( this.options.values.length === 2 && this.options.range === true ) { - newVal = index === 0 ? Math.min( otherVal, newVal ) : Math.max( otherVal, newVal ); - } - - newValues[ index ] = newVal; - } - - if ( newVal === currentValue ) { - return; - } - - allowed = this._trigger( "slide", event, this._uiHash( index, newVal, newValues ) ); - - // A slide can be canceled by returning false from the slide callback - if ( allowed === false ) { - return; - } - - if ( this._hasMultipleValues() ) { - this.values( index, newVal ); - } else { - this.value( newVal ); - } - }, - - _stop: function( event, index ) { - this._trigger( "stop", event, this._uiHash( index ) ); - }, - - _change: function( event, index ) { - if ( !this._keySliding && !this._mouseSliding ) { - - //store the last changed value index for reference when handles overlap - this._lastChangedValue = index; - this._trigger( "change", event, this._uiHash( index ) ); - } - }, - - value: function( newValue ) { - if ( arguments.length ) { - this.options.value = this._trimAlignValue( newValue ); - this._refreshValue(); - this._change( null, 0 ); - return; - } - - return this._value(); - }, - - values: function( index, newValue ) { - var vals, - newValues, - i; - - if ( arguments.length > 1 ) { - this.options.values[ index ] = this._trimAlignValue( newValue ); - this._refreshValue(); - this._change( null, index ); - return; - } - - if ( arguments.length ) { - if ( Array.isArray( arguments[ 0 ] ) ) { - vals = this.options.values; - newValues = arguments[ 0 ]; - for ( i = 0; i < vals.length; i += 1 ) { - vals[ i ] = this._trimAlignValue( newValues[ i ] ); - this._change( null, i ); - } - this._refreshValue(); - } else { - if ( this._hasMultipleValues() ) { - return this._values( index ); - } else { - return this.value(); - } - } - } else { - return this._values(); - } - }, - - _setOption: function( key, value ) { - var i, - valsLength = 0; - - if ( key === "range" && this.options.range === true ) { - if ( value === "min" ) { - this.options.value = this._values( 0 ); - this.options.values = null; - } else if ( value === "max" ) { - this.options.value = this._values( this.options.values.length - 1 ); - this.options.values = null; - } - } - - if ( Array.isArray( this.options.values ) ) { - valsLength = this.options.values.length; - } - - this._super( key, value ); - - switch ( key ) { - case "orientation": - this._detectOrientation(); - this._removeClass( "ui-slider-horizontal ui-slider-vertical" ) - ._addClass( "ui-slider-" + this.orientation ); - this._refreshValue(); - if ( this.options.range ) { - this._refreshRange( value ); - } - - // Reset positioning from previous orientation - this.handles.css( value === "horizontal" ? "bottom" : "left", "" ); - break; - case "value": - this._animateOff = true; - this._refreshValue(); - this._change( null, 0 ); - this._animateOff = false; - break; - case "values": - this._animateOff = true; - this._refreshValue(); - - // Start from the last handle to prevent unreachable handles (#9046) - for ( i = valsLength - 1; i >= 0; i-- ) { - this._change( null, i ); - } - this._animateOff = false; - break; - case "step": - case "min": - case "max": - this._animateOff = true; - this._calculateNewMax(); - this._refreshValue(); - this._animateOff = false; - break; - case "range": - this._animateOff = true; - this._refresh(); - this._animateOff = false; - break; - } - }, - - _setOptionDisabled: function( value ) { - this._super( value ); - - this._toggleClass( null, "ui-state-disabled", !!value ); - }, - - //internal value getter - // _value() returns value trimmed by min and max, aligned by step - _value: function() { - var val = this.options.value; - val = this._trimAlignValue( val ); - - return val; - }, - - //internal values getter - // _values() returns array of values trimmed by min and max, aligned by step - // _values( index ) returns single value trimmed by min and max, aligned by step - _values: function( index ) { - var val, - vals, - i; - - if ( arguments.length ) { - val = this.options.values[ index ]; - val = this._trimAlignValue( val ); - - return val; - } else if ( this._hasMultipleValues() ) { - - // .slice() creates a copy of the array - // this copy gets trimmed by min and max and then returned - vals = this.options.values.slice(); - for ( i = 0; i < vals.length; i += 1 ) { - vals[ i ] = this._trimAlignValue( vals[ i ] ); - } - - return vals; - } else { - return []; - } - }, - - // Returns the step-aligned value that val is closest to, between (inclusive) min and max - _trimAlignValue: function( val ) { - if ( val <= this._valueMin() ) { - return this._valueMin(); - } - if ( val >= this._valueMax() ) { - return this._valueMax(); - } - var step = ( this.options.step > 0 ) ? this.options.step : 1, - valModStep = ( val - this._valueMin() ) % step, - alignValue = val - valModStep; - - if ( Math.abs( valModStep ) * 2 >= step ) { - alignValue += ( valModStep > 0 ) ? step : ( -step ); - } - - // Since JavaScript has problems with large floats, round - // the final value to 5 digits after the decimal point (see #4124) - return parseFloat( alignValue.toFixed( 5 ) ); - }, - - _calculateNewMax: function() { - var max = this.options.max, - min = this._valueMin(), - step = this.options.step, - aboveMin = Math.round( ( max - min ) / step ) * step; - max = aboveMin + min; - if ( max > this.options.max ) { - - //If max is not divisible by step, rounding off may increase its value - max -= step; - } - this.max = parseFloat( max.toFixed( this._precision() ) ); - }, - - _precision: function() { - var precision = this._precisionOf( this.options.step ); - if ( this.options.min !== null ) { - precision = Math.max( precision, this._precisionOf( this.options.min ) ); - } - return precision; - }, - - _precisionOf: function( num ) { - var str = num.toString(), - decimal = str.indexOf( "." ); - return decimal === -1 ? 0 : str.length - decimal - 1; - }, - - _valueMin: function() { - return this.options.min; - }, - - _valueMax: function() { - return this.max; - }, - - _refreshRange: function( orientation ) { - if ( orientation === "vertical" ) { - this.range.css( { "width": "", "left": "" } ); - } - if ( orientation === "horizontal" ) { - this.range.css( { "height": "", "bottom": "" } ); - } - }, - - _refreshValue: function() { - var lastValPercent, valPercent, value, valueMin, valueMax, - oRange = this.options.range, - o = this.options, - that = this, - animate = ( !this._animateOff ) ? o.animate : false, - _set = {}; - - if ( this._hasMultipleValues() ) { - this.handles.each( function( i ) { - valPercent = ( that.values( i ) - that._valueMin() ) / ( that._valueMax() - - that._valueMin() ) * 100; - _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; - $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); - if ( that.options.range === true ) { - if ( that.orientation === "horizontal" ) { - if ( i === 0 ) { - that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { - left: valPercent + "%" - }, o.animate ); - } - if ( i === 1 ) { - that.range[ animate ? "animate" : "css" ]( { - width: ( valPercent - lastValPercent ) + "%" - }, { - queue: false, - duration: o.animate - } ); - } - } else { - if ( i === 0 ) { - that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { - bottom: ( valPercent ) + "%" - }, o.animate ); - } - if ( i === 1 ) { - that.range[ animate ? "animate" : "css" ]( { - height: ( valPercent - lastValPercent ) + "%" - }, { - queue: false, - duration: o.animate - } ); - } - } - } - lastValPercent = valPercent; - } ); - } else { - value = this.value(); - valueMin = this._valueMin(); - valueMax = this._valueMax(); - valPercent = ( valueMax !== valueMin ) ? - ( value - valueMin ) / ( valueMax - valueMin ) * 100 : - 0; - _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; - this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); - - if ( oRange === "min" && this.orientation === "horizontal" ) { - this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { - width: valPercent + "%" - }, o.animate ); - } - if ( oRange === "max" && this.orientation === "horizontal" ) { - this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { - width: ( 100 - valPercent ) + "%" - }, o.animate ); - } - if ( oRange === "min" && this.orientation === "vertical" ) { - this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { - height: valPercent + "%" - }, o.animate ); - } - if ( oRange === "max" && this.orientation === "vertical" ) { - this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { - height: ( 100 - valPercent ) + "%" - }, o.animate ); - } - } - }, - - _handleEvents: { - keydown: function( event ) { - var allowed, curVal, newVal, step, - index = $( event.target ).data( "ui-slider-handle-index" ); - - switch ( event.keyCode ) { - case $.ui.keyCode.HOME: - case $.ui.keyCode.END: - case $.ui.keyCode.PAGE_UP: - case $.ui.keyCode.PAGE_DOWN: - case $.ui.keyCode.UP: - case $.ui.keyCode.RIGHT: - case $.ui.keyCode.DOWN: - case $.ui.keyCode.LEFT: - event.preventDefault(); - if ( !this._keySliding ) { - this._keySliding = true; - this._addClass( $( event.target ), null, "ui-state-active" ); - allowed = this._start( event, index ); - if ( allowed === false ) { - return; - } - } - break; - } - - step = this.options.step; - if ( this._hasMultipleValues() ) { - curVal = newVal = this.values( index ); - } else { - curVal = newVal = this.value(); - } - - switch ( event.keyCode ) { - case $.ui.keyCode.HOME: - newVal = this._valueMin(); - break; - case $.ui.keyCode.END: - newVal = this._valueMax(); - break; - case $.ui.keyCode.PAGE_UP: - newVal = this._trimAlignValue( - curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages ) - ); - break; - case $.ui.keyCode.PAGE_DOWN: - newVal = this._trimAlignValue( - curVal - ( ( this._valueMax() - this._valueMin() ) / this.numPages ) ); - break; - case $.ui.keyCode.UP: - case $.ui.keyCode.RIGHT: - if ( curVal === this._valueMax() ) { - return; - } - newVal = this._trimAlignValue( curVal + step ); - break; - case $.ui.keyCode.DOWN: - case $.ui.keyCode.LEFT: - if ( curVal === this._valueMin() ) { - return; - } - newVal = this._trimAlignValue( curVal - step ); - break; - } - - this._slide( event, index, newVal ); - }, - keyup: function( event ) { - var index = $( event.target ).data( "ui-slider-handle-index" ); - - if ( this._keySliding ) { - this._keySliding = false; - this._stop( event, index ); - this._change( event, index ); - this._removeClass( $( event.target ), null, "ui-state-active" ); - } - } - } -} ); + "use strict"; + + return $.widget( "ui.slider", $.ui.mouse, { + version: "1.13.2", + widgetEventPrefix: "slide", + + options: { + animate: false, + classes: { + "ui-slider": "ui-corner-all", + "ui-slider-handle": "ui-corner-all", + + // Note: ui-widget-header isn't the most fittingly semantic framework class for this + // element, but worked best visually with a variety of themes + "ui-slider-range": "ui-corner-all ui-widget-header" + }, + distance: 0, + max: 100, + min: 0, + orientation: "horizontal", + range: false, + step: 1, + value: 0, + values: null, + + // Callbacks + change: null, + slide: null, + start: null, + stop: null + }, + + // Number of pages in a slider + // (how many times can you page up/down to go through the whole range) + numPages: 5, + + _create: function() { + this._keySliding = false; + this._mouseSliding = false; + this._animateOff = true; + this._handleIndex = null; + this._detectOrientation(); + this._mouseInit(); + this._calculateNewMax(); + + this._addClass( "ui-slider ui-slider-" + this.orientation, + "ui-widget ui-widget-content" ); + + this._refresh(); + + this._animateOff = false; + }, + + _refresh: function() { + this._createRange(); + this._createHandles(); + this._setupEvents(); + this._refreshValue(); + }, + + _createHandles: function() { + var i, handleCount, + options = this.options, + existingHandles = this.element.find( ".ui-slider-handle" ), + handle = "<span tabindex='0'></span>", + handles = []; + + handleCount = ( options.values && options.values.length ) || 1; + + if ( existingHandles.length > handleCount ) { + existingHandles.slice( handleCount ).remove(); + existingHandles = existingHandles.slice( 0, handleCount ); + } + + for ( i = existingHandles.length; i < handleCount; i++ ) { + handles.push( handle ); + } + + this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) ); + + this._addClass( this.handles, "ui-slider-handle", "ui-state-default" ); + + this.handle = this.handles.eq( 0 ); + + this.handles.each( function( i ) { + $( this ) + .data( "ui-slider-handle-index", i ) + .attr( "tabIndex", 0 ); + } ); + }, + + _createRange: function() { + var options = this.options; + + if ( options.range ) { + if ( options.range === true ) { + if ( !options.values ) { + options.values = [ this._valueMin(), this._valueMin() ]; + } else if ( options.values.length && options.values.length !== 2 ) { + options.values = [ options.values[ 0 ], options.values[ 0 ] ]; + } else if ( Array.isArray( options.values ) ) { + options.values = options.values.slice( 0 ); + } + } + + if ( !this.range || !this.range.length ) { + this.range = $( "<div>" ) + .appendTo( this.element ); + + this._addClass( this.range, "ui-slider-range" ); + } else { + this._removeClass( this.range, "ui-slider-range-min ui-slider-range-max" ); + + // Handle range switching from true to min/max + this.range.css( { + "left": "", + "bottom": "" + } ); + } + if ( options.range === "min" || options.range === "max" ) { + this._addClass( this.range, "ui-slider-range-" + options.range ); + } + } else { + if ( this.range ) { + this.range.remove(); + } + this.range = null; + } + }, + + _setupEvents: function() { + this._off( this.handles ); + this._on( this.handles, this._handleEvents ); + this._hoverable( this.handles ); + this._focusable( this.handles ); + }, + + _destroy: function() { + this.handles.remove(); + if ( this.range ) { + this.range.remove(); + } + + this._mouseDestroy(); + }, + + _mouseCapture: function( event ) { + var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle, + that = this, + o = this.options; + + if ( o.disabled ) { + return false; + } + + this.elementSize = { + width: this.element.outerWidth(), + height: this.element.outerHeight() + }; + this.elementOffset = this.element.offset(); + + position = { x: event.pageX, y: event.pageY }; + normValue = this._normValueFromMouse( position ); + distance = this._valueMax() - this._valueMin() + 1; + this.handles.each( function( i ) { + var thisDistance = Math.abs( normValue - that.values( i ) ); + if ( ( distance > thisDistance ) || + ( distance === thisDistance && + ( i === that._lastChangedValue || that.values( i ) === o.min ) ) ) { + distance = thisDistance; + closestHandle = $( this ); + index = i; + } + } ); + + allowed = this._start( event, index ); + if ( allowed === false ) { + return false; + } + this._mouseSliding = true; + + this._handleIndex = index; + + this._addClass( closestHandle, null, "ui-state-active" ); + closestHandle.trigger( "focus" ); + + offset = closestHandle.offset(); + mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" ); + this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : { + left: event.pageX - offset.left - ( closestHandle.width() / 2 ), + top: event.pageY - offset.top - + ( closestHandle.height() / 2 ) - + ( parseInt( closestHandle.css( "borderTopWidth" ), 10 ) || 0 ) - + ( parseInt( closestHandle.css( "borderBottomWidth" ), 10 ) || 0 ) + + ( parseInt( closestHandle.css( "marginTop" ), 10 ) || 0 ) + }; + + if ( !this.handles.hasClass( "ui-state-hover" ) ) { + this._slide( event, index, normValue ); + } + this._animateOff = true; + return true; + }, + + _mouseStart: function() { + return true; + }, + + _mouseDrag: function( event ) { + var position = { x: event.pageX, y: event.pageY }, + normValue = this._normValueFromMouse( position ); + + this._slide( event, this._handleIndex, normValue ); + + return false; + }, + + _mouseStop: function( event ) { + this._removeClass( this.handles, null, "ui-state-active" ); + this._mouseSliding = false; + + this._stop( event, this._handleIndex ); + this._change( event, this._handleIndex ); + + this._handleIndex = null; + this._clickOffset = null; + this._animateOff = false; + + return false; + }, + + _detectOrientation: function() { + this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal"; + }, + + _normValueFromMouse: function( position ) { + var pixelTotal, + pixelMouse, + percentMouse, + valueTotal, + valueMouse; + + if ( this.orientation === "horizontal" ) { + pixelTotal = this.elementSize.width; + pixelMouse = position.x - this.elementOffset.left - + ( this._clickOffset ? this._clickOffset.left : 0 ); + } else { + pixelTotal = this.elementSize.height; + pixelMouse = position.y - this.elementOffset.top - + ( this._clickOffset ? this._clickOffset.top : 0 ); + } + + percentMouse = ( pixelMouse / pixelTotal ); + if ( percentMouse > 1 ) { + percentMouse = 1; + } + if ( percentMouse < 0 ) { + percentMouse = 0; + } + if ( this.orientation === "vertical" ) { + percentMouse = 1 - percentMouse; + } + + valueTotal = this._valueMax() - this._valueMin(); + valueMouse = this._valueMin() + percentMouse * valueTotal; + + return this._trimAlignValue( valueMouse ); + }, + + _uiHash: function( index, value, values ) { + var uiHash = { + handle: this.handles[ index ], + handleIndex: index, + value: value !== undefined ? value : this.value() + }; + + if ( this._hasMultipleValues() ) { + uiHash.value = value !== undefined ? value : this.values( index ); + uiHash.values = values || this.values(); + } + + return uiHash; + }, + + _hasMultipleValues: function() { + return this.options.values && this.options.values.length; + }, + + _start: function( event, index ) { + return this._trigger( "start", event, this._uiHash( index ) ); + }, + + _slide: function( event, index, newVal ) { + var allowed, otherVal, + currentValue = this.value(), + newValues = this.values(); + + if ( this._hasMultipleValues() ) { + otherVal = this.values( index ? 0 : 1 ); + currentValue = this.values( index ); + + if ( this.options.values.length === 2 && this.options.range === true ) { + newVal = index === 0 ? Math.min( otherVal, newVal ) : Math.max( otherVal, newVal ); + } + + newValues[ index ] = newVal; + } + + if ( newVal === currentValue ) { + return; + } + + allowed = this._trigger( "slide", event, this._uiHash( index, newVal, newValues ) ); + + // A slide can be canceled by returning false from the slide callback + if ( allowed === false ) { + return; + } + + if ( this._hasMultipleValues() ) { + this.values( index, newVal ); + } else { + this.value( newVal ); + } + }, + + _stop: function( event, index ) { + this._trigger( "stop", event, this._uiHash( index ) ); + }, + + _change: function( event, index ) { + if ( !this._keySliding && !this._mouseSliding ) { + + //store the last changed value index for reference when handles overlap + this._lastChangedValue = index; + this._trigger( "change", event, this._uiHash( index ) ); + } + }, + + value: function( newValue ) { + if ( arguments.length ) { + this.options.value = this._trimAlignValue( newValue ); + this._refreshValue(); + this._change( null, 0 ); + return; + } + + return this._value(); + }, + + values: function( index, newValue ) { + var vals, + newValues, + i; + + if ( arguments.length > 1 ) { + this.options.values[ index ] = this._trimAlignValue( newValue ); + this._refreshValue(); + this._change( null, index ); + return; + } + + if ( arguments.length ) { + if ( Array.isArray( arguments[ 0 ] ) ) { + vals = this.options.values; + newValues = arguments[ 0 ]; + for ( i = 0; i < vals.length; i += 1 ) { + vals[ i ] = this._trimAlignValue( newValues[ i ] ); + this._change( null, i ); + } + this._refreshValue(); + } else { + if ( this._hasMultipleValues() ) { + return this._values( index ); + } else { + return this.value(); + } + } + } else { + return this._values(); + } + }, + + _setOption: function( key, value ) { + var i, + valsLength = 0; + + if ( key === "range" && this.options.range === true ) { + if ( value === "min" ) { + this.options.value = this._values( 0 ); + this.options.values = null; + } else if ( value === "max" ) { + this.options.value = this._values( this.options.values.length - 1 ); + this.options.values = null; + } + } + + if ( Array.isArray( this.options.values ) ) { + valsLength = this.options.values.length; + } + + this._super( key, value ); + + switch ( key ) { + case "orientation": + this._detectOrientation(); + this._removeClass( "ui-slider-horizontal ui-slider-vertical" ) + ._addClass( "ui-slider-" + this.orientation ); + this._refreshValue(); + if ( this.options.range ) { + this._refreshRange( value ); + } + + // Reset positioning from previous orientation + this.handles.css( value === "horizontal" ? "bottom" : "left", "" ); + break; + case "value": + this._animateOff = true; + this._refreshValue(); + this._change( null, 0 ); + this._animateOff = false; + break; + case "values": + this._animateOff = true; + this._refreshValue(); + + // Start from the last handle to prevent unreachable handles (#9046) + for ( i = valsLength - 1; i >= 0; i-- ) { + this._change( null, i ); + } + this._animateOff = false; + break; + case "step": + case "min": + case "max": + this._animateOff = true; + this._calculateNewMax(); + this._refreshValue(); + this._animateOff = false; + break; + case "range": + this._animateOff = true; + this._refresh(); + this._animateOff = false; + break; + } + }, + + _setOptionDisabled: function( value ) { + this._super( value ); + + this._toggleClass( null, "ui-state-disabled", !!value ); + }, + + //internal value getter + // _value() returns value trimmed by min and max, aligned by step + _value: function() { + var val = this.options.value; + val = this._trimAlignValue( val ); + + return val; + }, + + //internal values getter + // _values() returns array of values trimmed by min and max, aligned by step + // _values( index ) returns single value trimmed by min and max, aligned by step + _values: function( index ) { + var val, + vals, + i; + + if ( arguments.length ) { + val = this.options.values[ index ]; + val = this._trimAlignValue( val ); + + return val; + } else if ( this._hasMultipleValues() ) { + + // .slice() creates a copy of the array + // this copy gets trimmed by min and max and then returned + vals = this.options.values.slice(); + for ( i = 0; i < vals.length; i += 1 ) { + vals[ i ] = this._trimAlignValue( vals[ i ] ); + } + + return vals; + } else { + return []; + } + }, + + // Returns the step-aligned value that val is closest to, between (inclusive) min and max + _trimAlignValue: function( val ) { + if ( val <= this._valueMin() ) { + return this._valueMin(); + } + if ( val >= this._valueMax() ) { + return this._valueMax(); + } + var step = ( this.options.step > 0 ) ? this.options.step : 1, + valModStep = ( val - this._valueMin() ) % step, + alignValue = val - valModStep; + + if ( Math.abs( valModStep ) * 2 >= step ) { + alignValue += ( valModStep > 0 ) ? step : ( -step ); + } + + // Since JavaScript has problems with large floats, round + // the final value to 5 digits after the decimal point (see #4124) + return parseFloat( alignValue.toFixed( 5 ) ); + }, + + _calculateNewMax: function() { + var max = this.options.max, + min = this._valueMin(), + step = this.options.step, + aboveMin = Math.round( ( max - min ) / step ) * step; + max = aboveMin + min; + if ( max > this.options.max ) { + + //If max is not divisible by step, rounding off may increase its value + max -= step; + } + this.max = parseFloat( max.toFixed( this._precision() ) ); + }, + + _precision: function() { + var precision = this._precisionOf( this.options.step ); + if ( this.options.min !== null ) { + precision = Math.max( precision, this._precisionOf( this.options.min ) ); + } + return precision; + }, + + _precisionOf: function( num ) { + var str = num.toString(), + decimal = str.indexOf( "." ); + return decimal === -1 ? 0 : str.length - decimal - 1; + }, + + _valueMin: function() { + return this.options.min; + }, + + _valueMax: function() { + return this.max; + }, + + _refreshRange: function( orientation ) { + if ( orientation === "vertical" ) { + this.range.css( { "width": "", "left": "" } ); + } + if ( orientation === "horizontal" ) { + this.range.css( { "height": "", "bottom": "" } ); + } + }, + + _refreshValue: function() { + var lastValPercent, valPercent, value, valueMin, valueMax, + oRange = this.options.range, + o = this.options, + that = this, + animate = ( !this._animateOff ) ? o.animate : false, + _set = {}; + + if ( this._hasMultipleValues() ) { + this.handles.each( function( i ) { + valPercent = ( that.values( i ) - that._valueMin() ) / ( that._valueMax() - + that._valueMin() ) * 100; + _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; + $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); + if ( that.options.range === true ) { + if ( that.orientation === "horizontal" ) { + if ( i === 0 ) { + that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { + left: valPercent + "%" + }, o.animate ); + } + if ( i === 1 ) { + that.range[ animate ? "animate" : "css" ]( { + width: ( valPercent - lastValPercent ) + "%" + }, { + queue: false, + duration: o.animate + } ); + } + } else { + if ( i === 0 ) { + that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { + bottom: ( valPercent ) + "%" + }, o.animate ); + } + if ( i === 1 ) { + that.range[ animate ? "animate" : "css" ]( { + height: ( valPercent - lastValPercent ) + "%" + }, { + queue: false, + duration: o.animate + } ); + } + } + } + lastValPercent = valPercent; + } ); + } else { + value = this.value(); + valueMin = this._valueMin(); + valueMax = this._valueMax(); + valPercent = ( valueMax !== valueMin ) ? + ( value - valueMin ) / ( valueMax - valueMin ) * 100 : + 0; + _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; + this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); + + if ( oRange === "min" && this.orientation === "horizontal" ) { + this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { + width: valPercent + "%" + }, o.animate ); + } + if ( oRange === "max" && this.orientation === "horizontal" ) { + this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { + width: ( 100 - valPercent ) + "%" + }, o.animate ); + } + if ( oRange === "min" && this.orientation === "vertical" ) { + this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { + height: valPercent + "%" + }, o.animate ); + } + if ( oRange === "max" && this.orientation === "vertical" ) { + this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { + height: ( 100 - valPercent ) + "%" + }, o.animate ); + } + } + }, + + _handleEvents: { + keydown: function( event ) { + var allowed, curVal, newVal, step, + index = $( event.target ).data( "ui-slider-handle-index" ); + + switch ( event.keyCode ) { + case $.ui.keyCode.HOME: + case $.ui.keyCode.END: + case $.ui.keyCode.PAGE_UP: + case $.ui.keyCode.PAGE_DOWN: + case $.ui.keyCode.UP: + case $.ui.keyCode.RIGHT: + case $.ui.keyCode.DOWN: + case $.ui.keyCode.LEFT: + event.preventDefault(); + if ( !this._keySliding ) { + this._keySliding = true; + this._addClass( $( event.target ), null, "ui-state-active" ); + allowed = this._start( event, index ); + if ( allowed === false ) { + return; + } + } + break; + } + + step = this.options.step; + if ( this._hasMultipleValues() ) { + curVal = newVal = this.values( index ); + } else { + curVal = newVal = this.value(); + } + + switch ( event.keyCode ) { + case $.ui.keyCode.HOME: + newVal = this._valueMin(); + break; + case $.ui.keyCode.END: + newVal = this._valueMax(); + break; + case $.ui.keyCode.PAGE_UP: + newVal = this._trimAlignValue( + curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages ) + ); + break; + case $.ui.keyCode.PAGE_DOWN: + newVal = this._trimAlignValue( + curVal - ( ( this._valueMax() - this._valueMin() ) / this.numPages ) ); + break; + case $.ui.keyCode.UP: + case $.ui.keyCode.RIGHT: + if ( curVal === this._valueMax() ) { + return; + } + newVal = this._trimAlignValue( curVal + step ); + break; + case $.ui.keyCode.DOWN: + case $.ui.keyCode.LEFT: + if ( curVal === this._valueMin() ) { + return; + } + newVal = this._trimAlignValue( curVal - step ); + break; + } + + this._slide( event, index, newVal ); + }, + keyup: function( event ) { + var index = $( event.target ).data( "ui-slider-handle-index" ); + + if ( this._keySliding ) { + this._keySliding = false; + this._stop( event, index ); + this._change( event, index ); + this._removeClass( $( event.target ), null, "ui-state-active" ); + } + } + } + } ); } ); diff --git a/lib/web/jquery/ui-modules/widgets/sortable.js b/lib/web/jquery/ui-modules/widgets/sortable.js index 50cec89b7bb68..5df5bb175bc88 100644 --- a/lib/web/jquery/ui-modules/widgets/sortable.js +++ b/lib/web/jquery/ui-modules/widgets/sortable.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Sortable 1.13.1 + * jQuery UI Sortable 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -15,1601 +15,1601 @@ //>>css.structure: ../../themes/base/sortable.css ( function( factory ) { - "use strict"; - - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define( [ - "jquery", - "./mouse", - "../data", - "../ie", - "../scroll-parent", - "../version", - "../widget" - ], factory ); - } else { - - // Browser globals - factory( jQuery ); - } + "use strict"; + + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ + "jquery", + "./mouse", + "../data", + "../ie", + "../scroll-parent", + "../version", + "../widget" + ], factory ); + } else { + + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; - -return $.widget( "ui.sortable", $.ui.mouse, { - version: "1.13.1", - widgetEventPrefix: "sort", - ready: false, - options: { - appendTo: "parent", - axis: false, - connectWith: false, - containment: false, - cursor: "auto", - cursorAt: false, - dropOnEmpty: true, - forcePlaceholderSize: false, - forceHelperSize: false, - grid: false, - handle: false, - helper: "original", - items: "> *", - opacity: false, - placeholder: false, - revert: false, - scroll: true, - scrollSensitivity: 20, - scrollSpeed: 20, - scope: "default", - tolerance: "intersect", - zIndex: 1000, - - // Callbacks - activate: null, - beforeStop: null, - change: null, - deactivate: null, - out: null, - over: null, - receive: null, - remove: null, - sort: null, - start: null, - stop: null, - update: null - }, - - _isOverAxis: function( x, reference, size ) { - return ( x >= reference ) && ( x < ( reference + size ) ); - }, - - _isFloating: function( item ) { - return ( /left|right/ ).test( item.css( "float" ) ) || - ( /inline|table-cell/ ).test( item.css( "display" ) ); - }, - - _create: function() { - this.containerCache = {}; - this._addClass( "ui-sortable" ); - - //Get the items - this.refresh(); - - //Let's determine the parent's offset - this.offset = this.element.offset(); - - //Initialize mouse events for interaction - this._mouseInit(); - - this._setHandleClassName(); - - //We're ready to go - this.ready = true; - - }, - - _setOption: function( key, value ) { - this._super( key, value ); - - if ( key === "handle" ) { - this._setHandleClassName(); - } - }, - - _setHandleClassName: function() { - var that = this; - this._removeClass( this.element.find( ".ui-sortable-handle" ), "ui-sortable-handle" ); - $.each( this.items, function() { - that._addClass( - this.instance.options.handle ? - this.item.find( this.instance.options.handle ) : - this.item, - "ui-sortable-handle" - ); - } ); - }, - - _destroy: function() { - this._mouseDestroy(); - - for ( var i = this.items.length - 1; i >= 0; i-- ) { - this.items[ i ].item.removeData( this.widgetName + "-item" ); - } - - return this; - }, - - _mouseCapture: function( event, overrideHandle ) { - var currentItem = null, - validHandle = false, - that = this; - - if ( this.reverting ) { - return false; - } - - if ( this.options.disabled || this.options.type === "static" ) { - return false; - } - - //We have to refresh the items data once first - this._refreshItems( event ); - - //Find out if the clicked node (or one of its parents) is a actual item in this.items - $( event.target ).parents().each( function() { - if ( $.data( this, that.widgetName + "-item" ) === that ) { - currentItem = $( this ); - return false; - } - } ); - if ( $.data( event.target, that.widgetName + "-item" ) === that ) { - currentItem = $( event.target ); - } - - if ( !currentItem ) { - return false; - } - if ( this.options.handle && !overrideHandle ) { - $( this.options.handle, currentItem ).find( "*" ).addBack().each( function() { - if ( this === event.target ) { - validHandle = true; - } - } ); - if ( !validHandle ) { - return false; - } - } - - this.currentItem = currentItem; - this._removeCurrentsFromItems(); - return true; - - }, - - _mouseStart: function( event, overrideHandle, noActivation ) { - - var i, body, - o = this.options; - - this.currentContainer = this; - - //We only need to call refreshPositions, because the refreshItems call has been moved to - // mouseCapture - this.refreshPositions(); - - //Prepare the dragged items parent - this.appendTo = $( o.appendTo !== "parent" ? - o.appendTo : - this.currentItem.parent() ); - - //Create and append the visible helper - this.helper = this._createHelper( event ); - - //Cache the helper size - this._cacheHelperProportions(); - - /* - * - Position generation - - * This block generates everything position related - it's the core of draggables. - */ - - //Cache the margins of the original element - this._cacheMargins(); - - //The element's absolute position on the page minus margins - this.offset = this.currentItem.offset(); - this.offset = { - top: this.offset.top - this.margins.top, - left: this.offset.left - this.margins.left - }; - - $.extend( this.offset, { - click: { //Where the click happened, relative to the element - left: event.pageX - this.offset.left, - top: event.pageY - this.offset.top - }, - - // This is a relative to absolute position minus the actual position calculation - - // only used for relative positioned helper - relative: this._getRelativeOffset() - } ); - - // After we get the helper offset, but before we get the parent offset we can - // change the helper's position to absolute - // TODO: Still need to figure out a way to make relative sorting possible - this.helper.css( "position", "absolute" ); - this.cssPosition = this.helper.css( "position" ); - - //Adjust the mouse offset relative to the helper if "cursorAt" is supplied - if ( o.cursorAt ) { - this._adjustOffsetFromHelper( o.cursorAt ); - } - - //Cache the former DOM position - this.domPosition = { - prev: this.currentItem.prev()[ 0 ], - parent: this.currentItem.parent()[ 0 ] - }; - - // If the helper is not the original, hide the original so it's not playing any role during - // the drag, won't cause anything bad this way - if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) { - this.currentItem.hide(); - } - - //Create the placeholder - this._createPlaceholder(); - - //Get the next scrolling parent - this.scrollParent = this.placeholder.scrollParent(); - - $.extend( this.offset, { - parent: this._getParentOffset() - } ); - - //Set a containment if given in the options - if ( o.containment ) { - this._setContainment(); - } - - if ( o.cursor && o.cursor !== "auto" ) { // cursor option - body = this.document.find( "body" ); - - // Support: IE - this.storedCursor = body.css( "cursor" ); - body.css( "cursor", o.cursor ); - - this.storedStylesheet = - $( "<style>*{ cursor: " + o.cursor + " !important; }</style>" ).appendTo( body ); - } - - // We need to make sure to grab the zIndex before setting the - // opacity, because setting the opacity to anything lower than 1 - // causes the zIndex to change from "auto" to 0. - if ( o.zIndex ) { // zIndex option - if ( this.helper.css( "zIndex" ) ) { - this._storedZIndex = this.helper.css( "zIndex" ); - } - this.helper.css( "zIndex", o.zIndex ); - } - - if ( o.opacity ) { // opacity option - if ( this.helper.css( "opacity" ) ) { - this._storedOpacity = this.helper.css( "opacity" ); - } - this.helper.css( "opacity", o.opacity ); - } - - //Prepare scrolling - if ( this.scrollParent[ 0 ] !== this.document[ 0 ] && - this.scrollParent[ 0 ].tagName !== "HTML" ) { - this.overflowOffset = this.scrollParent.offset(); - } - - //Call callbacks - this._trigger( "start", event, this._uiHash() ); - - //Recache the helper size - if ( !this._preserveHelperProportions ) { - this._cacheHelperProportions(); - } - - //Post "activate" events to possible containers - if ( !noActivation ) { - for ( i = this.containers.length - 1; i >= 0; i-- ) { - this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) ); - } - } - - //Prepare possible droppables - if ( $.ui.ddmanager ) { - $.ui.ddmanager.current = this; - } - - if ( $.ui.ddmanager && !o.dropBehaviour ) { - $.ui.ddmanager.prepareOffsets( this, event ); - } - - this.dragging = true; - - this._addClass( this.helper, "ui-sortable-helper" ); - - //Move the helper, if needed - if ( !this.helper.parent().is( this.appendTo ) ) { - this.helper.detach().appendTo( this.appendTo ); - - //Update position - this.offset.parent = this._getParentOffset(); - } - - //Generate the original position - this.position = this.originalPosition = this._generatePosition( event ); - this.originalPageX = event.pageX; - this.originalPageY = event.pageY; - this.lastPositionAbs = this.positionAbs = this._convertPositionTo( "absolute" ); - - this._mouseDrag( event ); - - return true; - - }, - - _scroll: function( event ) { - var o = this.options, - scrolled = false; - - if ( this.scrollParent[ 0 ] !== this.document[ 0 ] && - this.scrollParent[ 0 ].tagName !== "HTML" ) { - - if ( ( this.overflowOffset.top + this.scrollParent[ 0 ].offsetHeight ) - - event.pageY < o.scrollSensitivity ) { - this.scrollParent[ 0 ].scrollTop = - scrolled = this.scrollParent[ 0 ].scrollTop + o.scrollSpeed; - } else if ( event.pageY - this.overflowOffset.top < o.scrollSensitivity ) { - this.scrollParent[ 0 ].scrollTop = - scrolled = this.scrollParent[ 0 ].scrollTop - o.scrollSpeed; - } - - if ( ( this.overflowOffset.left + this.scrollParent[ 0 ].offsetWidth ) - - event.pageX < o.scrollSensitivity ) { - this.scrollParent[ 0 ].scrollLeft = scrolled = - this.scrollParent[ 0 ].scrollLeft + o.scrollSpeed; - } else if ( event.pageX - this.overflowOffset.left < o.scrollSensitivity ) { - this.scrollParent[ 0 ].scrollLeft = scrolled = - this.scrollParent[ 0 ].scrollLeft - o.scrollSpeed; - } - - } else { - - if ( event.pageY - this.document.scrollTop() < o.scrollSensitivity ) { - scrolled = this.document.scrollTop( this.document.scrollTop() - o.scrollSpeed ); - } else if ( this.window.height() - ( event.pageY - this.document.scrollTop() ) < - o.scrollSensitivity ) { - scrolled = this.document.scrollTop( this.document.scrollTop() + o.scrollSpeed ); - } - - if ( event.pageX - this.document.scrollLeft() < o.scrollSensitivity ) { - scrolled = this.document.scrollLeft( - this.document.scrollLeft() - o.scrollSpeed - ); - } else if ( this.window.width() - ( event.pageX - this.document.scrollLeft() ) < - o.scrollSensitivity ) { - scrolled = this.document.scrollLeft( - this.document.scrollLeft() + o.scrollSpeed - ); - } - - } - - return scrolled; - }, - - _mouseDrag: function( event ) { - var i, item, itemElement, intersection, - o = this.options; - - //Compute the helpers position - this.position = this._generatePosition( event ); - this.positionAbs = this._convertPositionTo( "absolute" ); - - //Set the helper position - if ( !this.options.axis || this.options.axis !== "y" ) { - this.helper[ 0 ].style.left = this.position.left + "px"; - } - if ( !this.options.axis || this.options.axis !== "x" ) { - this.helper[ 0 ].style.top = this.position.top + "px"; - } - - //Do scrolling - if ( o.scroll ) { - if ( this._scroll( event ) !== false ) { - - //Update item positions used in position checks - this._refreshItemPositions( true ); - - if ( $.ui.ddmanager && !o.dropBehaviour ) { - $.ui.ddmanager.prepareOffsets( this, event ); - } - } - } - - this.dragDirection = { - vertical: this._getDragVerticalDirection(), - horizontal: this._getDragHorizontalDirection() - }; - - //Rearrange - for ( i = this.items.length - 1; i >= 0; i-- ) { - - //Cache variables and intersection, continue if no intersection - item = this.items[ i ]; - itemElement = item.item[ 0 ]; - intersection = this._intersectsWithPointer( item ); - if ( !intersection ) { - continue; - } - - // Only put the placeholder inside the current Container, skip all - // items from other containers. This works because when moving - // an item from one container to another the - // currentContainer is switched before the placeholder is moved. - // - // Without this, moving items in "sub-sortables" can cause - // the placeholder to jitter between the outer and inner container. - if ( item.instance !== this.currentContainer ) { - continue; - } - - // Cannot intersect with itself - // no useless actions that have been done before - // no action if the item moved is the parent of the item checked - if ( itemElement !== this.currentItem[ 0 ] && - this.placeholder[ intersection === 1 ? - "next" : "prev" ]()[ 0 ] !== itemElement && - !$.contains( this.placeholder[ 0 ], itemElement ) && - ( this.options.type === "semi-dynamic" ? - !$.contains( this.element[ 0 ], itemElement ) : - true - ) - ) { - - this.direction = intersection === 1 ? "down" : "up"; - - if ( this.options.tolerance === "pointer" || - this._intersectsWithSides( item ) ) { - this._rearrange( event, item ); - } else { - break; - } - - this._trigger( "change", event, this._uiHash() ); - break; - } - } - - //Post events to containers - this._contactContainers( event ); - - //Interconnect with droppables - if ( $.ui.ddmanager ) { - $.ui.ddmanager.drag( this, event ); - } - - //Call callbacks - this._trigger( "sort", event, this._uiHash() ); - - this.lastPositionAbs = this.positionAbs; - return false; - - }, - - _mouseStop: function( event, noPropagation ) { - - if ( !event ) { - return; - } - - //If we are using droppables, inform the manager about the drop - if ( $.ui.ddmanager && !this.options.dropBehaviour ) { - $.ui.ddmanager.drop( this, event ); - } - - if ( this.options.revert ) { - var that = this, - cur = this.placeholder.offset(), - axis = this.options.axis, - animation = {}; - - if ( !axis || axis === "x" ) { - animation.left = cur.left - this.offset.parent.left - this.margins.left + - ( this.offsetParent[ 0 ] === this.document[ 0 ].body ? - 0 : - this.offsetParent[ 0 ].scrollLeft - ); - } - if ( !axis || axis === "y" ) { - animation.top = cur.top - this.offset.parent.top - this.margins.top + - ( this.offsetParent[ 0 ] === this.document[ 0 ].body ? - 0 : - this.offsetParent[ 0 ].scrollTop - ); - } - this.reverting = true; - $( this.helper ).animate( - animation, - parseInt( this.options.revert, 10 ) || 500, - function() { - that._clear( event ); - } - ); - } else { - this._clear( event, noPropagation ); - } - - return false; - - }, - - cancel: function() { - - if ( this.dragging ) { - - this._mouseUp( new $.Event( "mouseup", { target: null } ) ); - - if ( this.options.helper === "original" ) { - this.currentItem.css( this._storedCSS ); - this._removeClass( this.currentItem, "ui-sortable-helper" ); - } else { - this.currentItem.show(); - } - - //Post deactivating events to containers - for ( var i = this.containers.length - 1; i >= 0; i-- ) { - this.containers[ i ]._trigger( "deactivate", null, this._uiHash( this ) ); - if ( this.containers[ i ].containerCache.over ) { - this.containers[ i ]._trigger( "out", null, this._uiHash( this ) ); - this.containers[ i ].containerCache.over = 0; - } - } - - } - - if ( this.placeholder ) { - - //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, - // it unbinds ALL events from the original node! - if ( this.placeholder[ 0 ].parentNode ) { - this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] ); - } - if ( this.options.helper !== "original" && this.helper && - this.helper[ 0 ].parentNode ) { - this.helper.remove(); - } - - $.extend( this, { - helper: null, - dragging: false, - reverting: false, - _noFinalSort: null - } ); - - if ( this.domPosition.prev ) { - $( this.domPosition.prev ).after( this.currentItem ); - } else { - $( this.domPosition.parent ).prepend( this.currentItem ); - } - } - - return this; - - }, - - serialize: function( o ) { - - var items = this._getItemsAsjQuery( o && o.connected ), - str = []; - o = o || {}; - - $( items ).each( function() { - var res = ( $( o.item || this ).attr( o.attribute || "id" ) || "" ) - .match( o.expression || ( /(.+)[\-=_](.+)/ ) ); - if ( res ) { - str.push( - ( o.key || res[ 1 ] + "[]" ) + - "=" + ( o.key && o.expression ? res[ 1 ] : res[ 2 ] ) ); - } - } ); - - if ( !str.length && o.key ) { - str.push( o.key + "=" ); - } - - return str.join( "&" ); - - }, - - toArray: function( o ) { - - var items = this._getItemsAsjQuery( o && o.connected ), - ret = []; - - o = o || {}; - - items.each( function() { - ret.push( $( o.item || this ).attr( o.attribute || "id" ) || "" ); - } ); - return ret; - - }, - - /* Be careful with the following core functions */ - _intersectsWith: function( item ) { - - var x1 = this.positionAbs.left, - x2 = x1 + this.helperProportions.width, - y1 = this.positionAbs.top, - y2 = y1 + this.helperProportions.height, - l = item.left, - r = l + item.width, - t = item.top, - b = t + item.height, - dyClick = this.offset.click.top, - dxClick = this.offset.click.left, - isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && - ( y1 + dyClick ) < b ), - isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && - ( x1 + dxClick ) < r ), - isOverElement = isOverElementHeight && isOverElementWidth; - - if ( this.options.tolerance === "pointer" || - this.options.forcePointerForContainers || - ( this.options.tolerance !== "pointer" && - this.helperProportions[ this.floating ? "width" : "height" ] > - item[ this.floating ? "width" : "height" ] ) - ) { - return isOverElement; - } else { - - return ( l < x1 + ( this.helperProportions.width / 2 ) && // Right Half - x2 - ( this.helperProportions.width / 2 ) < r && // Left Half - t < y1 + ( this.helperProportions.height / 2 ) && // Bottom Half - y2 - ( this.helperProportions.height / 2 ) < b ); // Top Half - - } - }, - - _intersectsWithPointer: function( item ) { - var verticalDirection, horizontalDirection, - isOverElementHeight = ( this.options.axis === "x" ) || - this._isOverAxis( - this.positionAbs.top + this.offset.click.top, item.top, item.height ), - isOverElementWidth = ( this.options.axis === "y" ) || - this._isOverAxis( - this.positionAbs.left + this.offset.click.left, item.left, item.width ), - isOverElement = isOverElementHeight && isOverElementWidth; - - if ( !isOverElement ) { - return false; - } - - verticalDirection = this.dragDirection.vertical; - horizontalDirection = this.dragDirection.horizontal; - - return this.floating ? - ( ( horizontalDirection === "right" || verticalDirection === "down" ) ? 2 : 1 ) : - ( verticalDirection && ( verticalDirection === "down" ? 2 : 1 ) ); - - }, - - _intersectsWithSides: function( item ) { - - var isOverBottomHalf = this._isOverAxis( this.positionAbs.top + - this.offset.click.top, item.top + ( item.height / 2 ), item.height ), - isOverRightHalf = this._isOverAxis( this.positionAbs.left + - this.offset.click.left, item.left + ( item.width / 2 ), item.width ), - verticalDirection = this.dragDirection.vertical, - horizontalDirection = this.dragDirection.horizontal; - - if ( this.floating && horizontalDirection ) { - return ( ( horizontalDirection === "right" && isOverRightHalf ) || - ( horizontalDirection === "left" && !isOverRightHalf ) ); - } else { - return verticalDirection && ( ( verticalDirection === "down" && isOverBottomHalf ) || - ( verticalDirection === "up" && !isOverBottomHalf ) ); - } - - }, - - _getDragVerticalDirection: function() { - var delta = this.positionAbs.top - this.lastPositionAbs.top; - return delta !== 0 && ( delta > 0 ? "down" : "up" ); - }, - - _getDragHorizontalDirection: function() { - var delta = this.positionAbs.left - this.lastPositionAbs.left; - return delta !== 0 && ( delta > 0 ? "right" : "left" ); - }, - - refresh: function( event ) { - this._refreshItems( event ); - this._setHandleClassName(); - this.refreshPositions(); - return this; - }, - - _connectWith: function() { - var options = this.options; - return options.connectWith.constructor === String ? - [ options.connectWith ] : - options.connectWith; - }, - - _getItemsAsjQuery: function( connected ) { - - var i, j, cur, inst, - items = [], - queries = [], - connectWith = this._connectWith(); - - if ( connectWith && connected ) { - for ( i = connectWith.length - 1; i >= 0; i-- ) { - cur = $( connectWith[ i ], this.document[ 0 ] ); - for ( j = cur.length - 1; j >= 0; j-- ) { - inst = $.data( cur[ j ], this.widgetFullName ); - if ( inst && inst !== this && !inst.options.disabled ) { - queries.push( [ typeof inst.options.items === "function" ? - inst.options.items.call( inst.element ) : - $( inst.options.items, inst.element ) - .not( ".ui-sortable-helper" ) - .not( ".ui-sortable-placeholder" ), inst ] ); - } - } - } - } - - queries.push( [ typeof this.options.items === "function" ? - this.options.items - .call( this.element, null, { options: this.options, item: this.currentItem } ) : - $( this.options.items, this.element ) - .not( ".ui-sortable-helper" ) - .not( ".ui-sortable-placeholder" ), this ] ); - - function addItems() { - items.push( this ); - } - for ( i = queries.length - 1; i >= 0; i-- ) { - queries[ i ][ 0 ].each( addItems ); - } - - return $( items ); - - }, - - _removeCurrentsFromItems: function() { - - var list = this.currentItem.find( ":data(" + this.widgetName + "-item)" ); - - this.items = $.grep( this.items, function( item ) { - for ( var j = 0; j < list.length; j++ ) { - if ( list[ j ] === item.item[ 0 ] ) { - return false; - } - } - return true; - } ); - - }, - - _refreshItems: function( event ) { - - this.items = []; - this.containers = [ this ]; - - var i, j, cur, inst, targetData, _queries, item, queriesLength, - items = this.items, - queries = [ [ typeof this.options.items === "function" ? - this.options.items.call( this.element[ 0 ], event, { item: this.currentItem } ) : - $( this.options.items, this.element ), this ] ], - connectWith = this._connectWith(); - - //Shouldn't be run the first time through due to massive slow-down - if ( connectWith && this.ready ) { - for ( i = connectWith.length - 1; i >= 0; i-- ) { - cur = $( connectWith[ i ], this.document[ 0 ] ); - for ( j = cur.length - 1; j >= 0; j-- ) { - inst = $.data( cur[ j ], this.widgetFullName ); - if ( inst && inst !== this && !inst.options.disabled ) { - queries.push( [ typeof inst.options.items === "function" ? - inst.options.items - .call( inst.element[ 0 ], event, { item: this.currentItem } ) : - $( inst.options.items, inst.element ), inst ] ); - this.containers.push( inst ); - } - } - } - } - - for ( i = queries.length - 1; i >= 0; i-- ) { - targetData = queries[ i ][ 1 ]; - _queries = queries[ i ][ 0 ]; - - for ( j = 0, queriesLength = _queries.length; j < queriesLength; j++ ) { - item = $( _queries[ j ] ); - - // Data for target checking (mouse manager) - item.data( this.widgetName + "-item", targetData ); - - items.push( { - item: item, - instance: targetData, - width: 0, height: 0, - left: 0, top: 0 - } ); - } - } - - }, - - _refreshItemPositions: function( fast ) { - var i, item, t, p; - - for ( i = this.items.length - 1; i >= 0; i-- ) { - item = this.items[ i ]; - - //We ignore calculating positions of all connected containers when we're not over them - if ( this.currentContainer && item.instance !== this.currentContainer && - item.item[ 0 ] !== this.currentItem[ 0 ] ) { - continue; - } - - t = this.options.toleranceElement ? - $( this.options.toleranceElement, item.item ) : - item.item; - - if ( !fast ) { - item.width = t.outerWidth(); - item.height = t.outerHeight(); - } - - p = t.offset(); - item.left = p.left; - item.top = p.top; - } - }, - - refreshPositions: function( fast ) { - - // Determine whether items are being displayed horizontally - this.floating = this.items.length ? - this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) : - false; - - // This has to be redone because due to the item being moved out/into the offsetParent, - // the offsetParent's position will change - if ( this.offsetParent && this.helper ) { - this.offset.parent = this._getParentOffset(); - } - - this._refreshItemPositions( fast ); - - var i, p; - - if ( this.options.custom && this.options.custom.refreshContainers ) { - this.options.custom.refreshContainers.call( this ); - } else { - for ( i = this.containers.length - 1; i >= 0; i-- ) { - p = this.containers[ i ].element.offset(); - this.containers[ i ].containerCache.left = p.left; - this.containers[ i ].containerCache.top = p.top; - this.containers[ i ].containerCache.width = - this.containers[ i ].element.outerWidth(); - this.containers[ i ].containerCache.height = - this.containers[ i ].element.outerHeight(); - } - } - - return this; - }, - - _createPlaceholder: function( that ) { - that = that || this; - var className, nodeName, - o = that.options; - - if ( !o.placeholder || o.placeholder.constructor === String ) { - className = o.placeholder; - nodeName = that.currentItem[ 0 ].nodeName.toLowerCase(); - o.placeholder = { - element: function() { - - var element = $( "<" + nodeName + ">", that.document[ 0 ] ); - - that._addClass( element, "ui-sortable-placeholder", - className || that.currentItem[ 0 ].className ) - ._removeClass( element, "ui-sortable-helper" ); - - if ( nodeName === "tbody" ) { - that._createTrPlaceholder( - that.currentItem.find( "tr" ).eq( 0 ), - $( "<tr>", that.document[ 0 ] ).appendTo( element ) - ); - } else if ( nodeName === "tr" ) { - that._createTrPlaceholder( that.currentItem, element ); - } else if ( nodeName === "img" ) { - element.attr( "src", that.currentItem.attr( "src" ) ); - } - - if ( !className ) { - element.css( "visibility", "hidden" ); - } - - return element; - }, - update: function( container, p ) { - - // 1. If a className is set as 'placeholder option, we don't force sizes - - // the class is responsible for that - // 2. The option 'forcePlaceholderSize can be enabled to force it even if a - // class name is specified - if ( className && !o.forcePlaceholderSize ) { - return; - } - - // If the element doesn't have a actual height or width by itself (without - // styles coming from a stylesheet), it receives the inline height and width - // from the dragged item. Or, if it's a tbody or tr, it's going to have a height - // anyway since we're populating them with <td>s above, but they're unlikely to - // be the correct height on their own if the row heights are dynamic, so we'll - // always assign the height of the dragged item given forcePlaceholderSize - // is true. - if ( !p.height() || ( o.forcePlaceholderSize && - ( nodeName === "tbody" || nodeName === "tr" ) ) ) { - p.height( - that.currentItem.innerHeight() - - parseInt( that.currentItem.css( "paddingTop" ) || 0, 10 ) - - parseInt( that.currentItem.css( "paddingBottom" ) || 0, 10 ) ); - } - if ( !p.width() ) { - p.width( - that.currentItem.innerWidth() - - parseInt( that.currentItem.css( "paddingLeft" ) || 0, 10 ) - - parseInt( that.currentItem.css( "paddingRight" ) || 0, 10 ) ); - } - } - }; - } - - //Create the placeholder - that.placeholder = $( o.placeholder.element.call( that.element, that.currentItem ) ); - - //Append it after the actual current item - that.currentItem.after( that.placeholder ); - - //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) - o.placeholder.update( that, that.placeholder ); - - }, - - _createTrPlaceholder: function( sourceTr, targetTr ) { - var that = this; - - sourceTr.children().each( function() { - $( "<td> </td>", that.document[ 0 ] ) - .attr( "colspan", $( this ).attr( "colspan" ) || 1 ) - .appendTo( targetTr ); - } ); - }, - - _contactContainers: function( event ) { - var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom, - floating, axis, - innermostContainer = null, - innermostIndex = null; - - // Get innermost container that intersects with item - for ( i = this.containers.length - 1; i >= 0; i-- ) { - - // Never consider a container that's located within the item itself - if ( $.contains( this.currentItem[ 0 ], this.containers[ i ].element[ 0 ] ) ) { - continue; - } - - if ( this._intersectsWith( this.containers[ i ].containerCache ) ) { - - // If we've already found a container and it's more "inner" than this, then continue - if ( innermostContainer && - $.contains( - this.containers[ i ].element[ 0 ], - innermostContainer.element[ 0 ] ) ) { - continue; - } - - innermostContainer = this.containers[ i ]; - innermostIndex = i; - - } else { - - // container doesn't intersect. trigger "out" event if necessary - if ( this.containers[ i ].containerCache.over ) { - this.containers[ i ]._trigger( "out", event, this._uiHash( this ) ); - this.containers[ i ].containerCache.over = 0; - } - } - - } - - // If no intersecting containers found, return - if ( !innermostContainer ) { - return; - } - - // Move the item into the container if it's not there already - if ( this.containers.length === 1 ) { - if ( !this.containers[ innermostIndex ].containerCache.over ) { - this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) ); - this.containers[ innermostIndex ].containerCache.over = 1; - } - } else { - - // When entering a new container, we will find the item with the least distance and - // append our item near it - dist = 10000; - itemWithLeastDistance = null; - floating = innermostContainer.floating || this._isFloating( this.currentItem ); - posProperty = floating ? "left" : "top"; - sizeProperty = floating ? "width" : "height"; - axis = floating ? "pageX" : "pageY"; - - for ( j = this.items.length - 1; j >= 0; j-- ) { - if ( !$.contains( - this.containers[ innermostIndex ].element[ 0 ], this.items[ j ].item[ 0 ] ) - ) { - continue; - } - if ( this.items[ j ].item[ 0 ] === this.currentItem[ 0 ] ) { - continue; - } - - cur = this.items[ j ].item.offset()[ posProperty ]; - nearBottom = false; - if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) { - nearBottom = true; - } - - if ( Math.abs( event[ axis ] - cur ) < dist ) { - dist = Math.abs( event[ axis ] - cur ); - itemWithLeastDistance = this.items[ j ]; - this.direction = nearBottom ? "up" : "down"; - } - } - - //Check if dropOnEmpty is enabled - if ( !itemWithLeastDistance && !this.options.dropOnEmpty ) { - return; - } - - if ( this.currentContainer === this.containers[ innermostIndex ] ) { - if ( !this.currentContainer.containerCache.over ) { - this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() ); - this.currentContainer.containerCache.over = 1; - } - return; - } - - if ( itemWithLeastDistance ) { - this._rearrange( event, itemWithLeastDistance, null, true ); - } else { - this._rearrange( event, null, this.containers[ innermostIndex ].element, true ); - } - this._trigger( "change", event, this._uiHash() ); - this.containers[ innermostIndex ]._trigger( "change", event, this._uiHash( this ) ); - this.currentContainer = this.containers[ innermostIndex ]; - - //Update the placeholder - this.options.placeholder.update( this.currentContainer, this.placeholder ); - - //Update scrollParent - this.scrollParent = this.placeholder.scrollParent(); - - //Update overflowOffset - if ( this.scrollParent[ 0 ] !== this.document[ 0 ] && - this.scrollParent[ 0 ].tagName !== "HTML" ) { - this.overflowOffset = this.scrollParent.offset(); - } - - this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) ); - this.containers[ innermostIndex ].containerCache.over = 1; - } - - }, - - _createHelper: function( event ) { - - var o = this.options, - helper = typeof o.helper === "function" ? - $( o.helper.apply( this.element[ 0 ], [ event, this.currentItem ] ) ) : - ( o.helper === "clone" ? this.currentItem.clone() : this.currentItem ); - - //Add the helper to the DOM if that didn't happen already - if ( !helper.parents( "body" ).length ) { - this.appendTo[ 0 ].appendChild( helper[ 0 ] ); - } - - if ( helper[ 0 ] === this.currentItem[ 0 ] ) { - this._storedCSS = { - width: this.currentItem[ 0 ].style.width, - height: this.currentItem[ 0 ].style.height, - position: this.currentItem.css( "position" ), - top: this.currentItem.css( "top" ), - left: this.currentItem.css( "left" ) - }; - } - - if ( !helper[ 0 ].style.width || o.forceHelperSize ) { - helper.width( this.currentItem.width() ); - } - if ( !helper[ 0 ].style.height || o.forceHelperSize ) { - helper.height( this.currentItem.height() ); - } - - return helper; - - }, - - _adjustOffsetFromHelper: function( obj ) { - if ( typeof obj === "string" ) { - obj = obj.split( " " ); - } - if ( Array.isArray( obj ) ) { - obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 }; - } - if ( "left" in obj ) { - this.offset.click.left = obj.left + this.margins.left; - } - if ( "right" in obj ) { - this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; - } - if ( "top" in obj ) { - this.offset.click.top = obj.top + this.margins.top; - } - if ( "bottom" in obj ) { - this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; - } - }, - - _getParentOffset: function() { - - //Get the offsetParent and cache its position - this.offsetParent = this.helper.offsetParent(); - var po = this.offsetParent.offset(); - - // This is a special case where we need to modify a offset calculated on start, since the - // following happened: - // 1. The position of the helper is absolute, so it's position is calculated based on the - // next positioned parent - // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't - // the document, which means that the scroll is included in the initial calculation of the - // offset of the parent, and never recalculated upon drag - if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== this.document[ 0 ] && - $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) { - po.left += this.scrollParent.scrollLeft(); - po.top += this.scrollParent.scrollTop(); - } - - // This needs to be actually done for all browsers, since pageX/pageY includes this - // information with an ugly IE fix - if ( this.offsetParent[ 0 ] === this.document[ 0 ].body || - ( this.offsetParent[ 0 ].tagName && - this.offsetParent[ 0 ].tagName.toLowerCase() === "html" && $.ui.ie ) ) { - po = { top: 0, left: 0 }; - } - - return { - top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ), - left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 ) - }; - - }, - - _getRelativeOffset: function() { - - if ( this.cssPosition === "relative" ) { - var p = this.currentItem.position(); - return { - top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) + - this.scrollParent.scrollTop(), - left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) + - this.scrollParent.scrollLeft() - }; - } else { - return { top: 0, left: 0 }; - } - - }, - - _cacheMargins: function() { - this.margins = { - left: ( parseInt( this.currentItem.css( "marginLeft" ), 10 ) || 0 ), - top: ( parseInt( this.currentItem.css( "marginTop" ), 10 ) || 0 ) - }; - }, - - _cacheHelperProportions: function() { - this.helperProportions = { - width: this.helper.outerWidth(), - height: this.helper.outerHeight() - }; - }, - - _setContainment: function() { - - var ce, co, over, - o = this.options; - if ( o.containment === "parent" ) { - o.containment = this.helper[ 0 ].parentNode; - } - if ( o.containment === "document" || o.containment === "window" ) { - this.containment = [ - 0 - this.offset.relative.left - this.offset.parent.left, - 0 - this.offset.relative.top - this.offset.parent.top, - o.containment === "document" ? - this.document.width() : - this.window.width() - this.helperProportions.width - this.margins.left, - ( o.containment === "document" ? - ( this.document.height() || document.body.parentNode.scrollHeight ) : - this.window.height() || this.document[ 0 ].body.parentNode.scrollHeight - ) - this.helperProportions.height - this.margins.top - ]; - } - - if ( !( /^(document|window|parent)$/ ).test( o.containment ) ) { - ce = $( o.containment )[ 0 ]; - co = $( o.containment ).offset(); - over = ( $( ce ).css( "overflow" ) !== "hidden" ); - - this.containment = [ - co.left + ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) + - ( parseInt( $( ce ).css( "paddingLeft" ), 10 ) || 0 ) - this.margins.left, - co.top + ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) + - ( parseInt( $( ce ).css( "paddingTop" ), 10 ) || 0 ) - this.margins.top, - co.left + ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - - ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) - - ( parseInt( $( ce ).css( "paddingRight" ), 10 ) || 0 ) - - this.helperProportions.width - this.margins.left, - co.top + ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - - ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) - - ( parseInt( $( ce ).css( "paddingBottom" ), 10 ) || 0 ) - - this.helperProportions.height - this.margins.top - ]; - } - - }, - - _convertPositionTo: function( d, pos ) { - - if ( !pos ) { - pos = this.position; - } - var mod = d === "absolute" ? 1 : -1, - scroll = this.cssPosition === "absolute" && - !( this.scrollParent[ 0 ] !== this.document[ 0 ] && - $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? - this.offsetParent : - this.scrollParent, - scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName ); - - return { - top: ( - - // The absolute mouse position - pos.top + - - // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.relative.top * mod + - - // The offsetParent's offset without borders (offset + border) - this.offset.parent.top * mod - - ( ( this.cssPosition === "fixed" ? - -this.scrollParent.scrollTop() : - ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod ) - ), - left: ( - - // The absolute mouse position - pos.left + - - // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.relative.left * mod + - - // The offsetParent's offset without borders (offset + border) - this.offset.parent.left * mod - - ( ( this.cssPosition === "fixed" ? - -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : - scroll.scrollLeft() ) * mod ) - ) - }; - - }, - - _generatePosition: function( event ) { - - var top, left, - o = this.options, - pageX = event.pageX, - pageY = event.pageY, - scroll = this.cssPosition === "absolute" && - !( this.scrollParent[ 0 ] !== this.document[ 0 ] && - $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? - this.offsetParent : - this.scrollParent, - scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName ); - - // This is another very weird special case that only happens for relative elements: - // 1. If the css position is relative - // 2. and the scroll parent is the document or similar to the offset parent - // we have to refresh the relative offset during the scroll so there are no jumps - if ( this.cssPosition === "relative" && !( this.scrollParent[ 0 ] !== this.document[ 0 ] && - this.scrollParent[ 0 ] !== this.offsetParent[ 0 ] ) ) { - this.offset.relative = this._getRelativeOffset(); - } - - /* - * - Position constraining - - * Constrain the position to a mix of grid, containment. - */ - - if ( this.originalPosition ) { //If we are not dragging yet, we won't check for options - - if ( this.containment ) { - if ( event.pageX - this.offset.click.left < this.containment[ 0 ] ) { - pageX = this.containment[ 0 ] + this.offset.click.left; - } - if ( event.pageY - this.offset.click.top < this.containment[ 1 ] ) { - pageY = this.containment[ 1 ] + this.offset.click.top; - } - if ( event.pageX - this.offset.click.left > this.containment[ 2 ] ) { - pageX = this.containment[ 2 ] + this.offset.click.left; - } - if ( event.pageY - this.offset.click.top > this.containment[ 3 ] ) { - pageY = this.containment[ 3 ] + this.offset.click.top; - } - } - - if ( o.grid ) { - top = this.originalPageY + Math.round( ( pageY - this.originalPageY ) / - o.grid[ 1 ] ) * o.grid[ 1 ]; - pageY = this.containment ? - ( ( top - this.offset.click.top >= this.containment[ 1 ] && - top - this.offset.click.top <= this.containment[ 3 ] ) ? - top : - ( ( top - this.offset.click.top >= this.containment[ 1 ] ) ? - top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : - top; - - left = this.originalPageX + Math.round( ( pageX - this.originalPageX ) / - o.grid[ 0 ] ) * o.grid[ 0 ]; - pageX = this.containment ? - ( ( left - this.offset.click.left >= this.containment[ 0 ] && - left - this.offset.click.left <= this.containment[ 2 ] ) ? - left : - ( ( left - this.offset.click.left >= this.containment[ 0 ] ) ? - left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : - left; - } - - } - - return { - top: ( - - // The absolute mouse position - pageY - - - // Click offset (relative to the element) - this.offset.click.top - - - // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.relative.top - - - // The offsetParent's offset without borders (offset + border) - this.offset.parent.top + - ( ( this.cssPosition === "fixed" ? - -this.scrollParent.scrollTop() : - ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) ) - ), - left: ( - - // The absolute mouse position - pageX - - - // Click offset (relative to the element) - this.offset.click.left - - - // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.relative.left - - - // The offsetParent's offset without borders (offset + border) - this.offset.parent.left + - ( ( this.cssPosition === "fixed" ? - -this.scrollParent.scrollLeft() : - scrollIsRootNode ? 0 : scroll.scrollLeft() ) ) - ) - }; - - }, - - _rearrange: function( event, i, a, hardRefresh ) { - - if ( a ) { - a[ 0 ].appendChild( this.placeholder[ 0 ] ); - } else { - i.item[ 0 ].parentNode.insertBefore( this.placeholder[ 0 ], - ( this.direction === "down" ? i.item[ 0 ] : i.item[ 0 ].nextSibling ) ); - } - - //Various things done here to improve the performance: - // 1. we create a setTimeout, that calls refreshPositions - // 2. on the instance, we have a counter variable, that get's higher after every append - // 3. on the local scope, we copy the counter variable, and check in the timeout, - // if it's still the same - // 4. this lets only the last addition to the timeout stack through - this.counter = this.counter ? ++this.counter : 1; - var counter = this.counter; - - this._delay( function() { - if ( counter === this.counter ) { - - //Precompute after each DOM insertion, NOT on mousemove - this.refreshPositions( !hardRefresh ); - } - } ); - - }, - - _clear: function( event, noPropagation ) { - - this.reverting = false; - - // We delay all events that have to be triggered to after the point where the placeholder - // has been removed and everything else normalized again - var i, - delayedTriggers = []; - - // We first have to update the dom position of the actual currentItem - // Note: don't do it if the current item is already removed (by a user), or it gets - // reappended (see #4088) - if ( !this._noFinalSort && this.currentItem.parent().length ) { - this.placeholder.before( this.currentItem ); - } - this._noFinalSort = null; - - if ( this.helper[ 0 ] === this.currentItem[ 0 ] ) { - for ( i in this._storedCSS ) { - if ( this._storedCSS[ i ] === "auto" || this._storedCSS[ i ] === "static" ) { - this._storedCSS[ i ] = ""; - } - } - this.currentItem.css( this._storedCSS ); - this._removeClass( this.currentItem, "ui-sortable-helper" ); - } else { - this.currentItem.show(); - } - - if ( this.fromOutside && !noPropagation ) { - delayedTriggers.push( function( event ) { - this._trigger( "receive", event, this._uiHash( this.fromOutside ) ); - } ); - } - if ( ( this.fromOutside || - this.domPosition.prev !== - this.currentItem.prev().not( ".ui-sortable-helper" )[ 0 ] || - this.domPosition.parent !== this.currentItem.parent()[ 0 ] ) && !noPropagation ) { - - // Trigger update callback if the DOM position has changed - delayedTriggers.push( function( event ) { - this._trigger( "update", event, this._uiHash() ); - } ); - } - - // Check if the items Container has Changed and trigger appropriate - // events. - if ( this !== this.currentContainer ) { - if ( !noPropagation ) { - delayedTriggers.push( function( event ) { - this._trigger( "remove", event, this._uiHash() ); - } ); - delayedTriggers.push( ( function( c ) { - return function( event ) { - c._trigger( "receive", event, this._uiHash( this ) ); - }; - } ).call( this, this.currentContainer ) ); - delayedTriggers.push( ( function( c ) { - return function( event ) { - c._trigger( "update", event, this._uiHash( this ) ); - }; - } ).call( this, this.currentContainer ) ); - } - } - - //Post events to containers - function delayEvent( type, instance, container ) { - return function( event ) { - container._trigger( type, event, instance._uiHash( instance ) ); - }; - } - for ( i = this.containers.length - 1; i >= 0; i-- ) { - if ( !noPropagation ) { - delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) ); - } - if ( this.containers[ i ].containerCache.over ) { - delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) ); - this.containers[ i ].containerCache.over = 0; - } - } - - //Do what was originally in plugins - if ( this.storedCursor ) { - this.document.find( "body" ).css( "cursor", this.storedCursor ); - this.storedStylesheet.remove(); - } - if ( this._storedOpacity ) { - this.helper.css( "opacity", this._storedOpacity ); - } - if ( this._storedZIndex ) { - this.helper.css( "zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex ); - } - - this.dragging = false; - - if ( !noPropagation ) { - this._trigger( "beforeStop", event, this._uiHash() ); - } - - //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, - // it unbinds ALL events from the original node! - this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] ); - - if ( !this.cancelHelperRemoval ) { - if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) { - this.helper.remove(); - } - this.helper = null; - } - - if ( !noPropagation ) { - for ( i = 0; i < delayedTriggers.length; i++ ) { - - // Trigger all delayed events - delayedTriggers[ i ].call( this, event ); - } - this._trigger( "stop", event, this._uiHash() ); - } - - this.fromOutside = false; - return !this.cancelHelperRemoval; - - }, - - _trigger: function() { - if ( $.Widget.prototype._trigger.apply( this, arguments ) === false ) { - this.cancel(); - } - }, - - _uiHash: function( _inst ) { - var inst = _inst || this; - return { - helper: inst.helper, - placeholder: inst.placeholder || $( [] ), - position: inst.position, - originalPosition: inst.originalPosition, - offset: inst.positionAbs, - item: inst.currentItem, - sender: _inst ? _inst.element : null - }; - } - -} ); + "use strict"; + + return $.widget( "ui.sortable", $.ui.mouse, { + version: "1.13.2", + widgetEventPrefix: "sort", + ready: false, + options: { + appendTo: "parent", + axis: false, + connectWith: false, + containment: false, + cursor: "auto", + cursorAt: false, + dropOnEmpty: true, + forcePlaceholderSize: false, + forceHelperSize: false, + grid: false, + handle: false, + helper: "original", + items: "> *", + opacity: false, + placeholder: false, + revert: false, + scroll: true, + scrollSensitivity: 20, + scrollSpeed: 20, + scope: "default", + tolerance: "intersect", + zIndex: 1000, + + // Callbacks + activate: null, + beforeStop: null, + change: null, + deactivate: null, + out: null, + over: null, + receive: null, + remove: null, + sort: null, + start: null, + stop: null, + update: null + }, + + _isOverAxis: function( x, reference, size ) { + return ( x >= reference ) && ( x < ( reference + size ) ); + }, + + _isFloating: function( item ) { + return ( /left|right/ ).test( item.css( "float" ) ) || + ( /inline|table-cell/ ).test( item.css( "display" ) ); + }, + + _create: function() { + this.containerCache = {}; + this._addClass( "ui-sortable" ); + + //Get the items + this.refresh(); + + //Let's determine the parent's offset + this.offset = this.element.offset(); + + //Initialize mouse events for interaction + this._mouseInit(); + + this._setHandleClassName(); + + //We're ready to go + this.ready = true; + + }, + + _setOption: function( key, value ) { + this._super( key, value ); + + if ( key === "handle" ) { + this._setHandleClassName(); + } + }, + + _setHandleClassName: function() { + var that = this; + this._removeClass( this.element.find( ".ui-sortable-handle" ), "ui-sortable-handle" ); + $.each( this.items, function() { + that._addClass( + this.instance.options.handle ? + this.item.find( this.instance.options.handle ) : + this.item, + "ui-sortable-handle" + ); + } ); + }, + + _destroy: function() { + this._mouseDestroy(); + + for ( var i = this.items.length - 1; i >= 0; i-- ) { + this.items[ i ].item.removeData( this.widgetName + "-item" ); + } + + return this; + }, + + _mouseCapture: function( event, overrideHandle ) { + var currentItem = null, + validHandle = false, + that = this; + + if ( this.reverting ) { + return false; + } + + if ( this.options.disabled || this.options.type === "static" ) { + return false; + } + + //We have to refresh the items data once first + this._refreshItems( event ); + + //Find out if the clicked node (or one of its parents) is a actual item in this.items + $( event.target ).parents().each( function() { + if ( $.data( this, that.widgetName + "-item" ) === that ) { + currentItem = $( this ); + return false; + } + } ); + if ( $.data( event.target, that.widgetName + "-item" ) === that ) { + currentItem = $( event.target ); + } + + if ( !currentItem ) { + return false; + } + if ( this.options.handle && !overrideHandle ) { + $( this.options.handle, currentItem ).find( "*" ).addBack().each( function() { + if ( this === event.target ) { + validHandle = true; + } + } ); + if ( !validHandle ) { + return false; + } + } + + this.currentItem = currentItem; + this._removeCurrentsFromItems(); + return true; + + }, + + _mouseStart: function( event, overrideHandle, noActivation ) { + + var i, body, + o = this.options; + + this.currentContainer = this; + + //We only need to call refreshPositions, because the refreshItems call has been moved to + // mouseCapture + this.refreshPositions(); + + //Prepare the dragged items parent + this.appendTo = $( o.appendTo !== "parent" ? + o.appendTo : + this.currentItem.parent() ); + + //Create and append the visible helper + this.helper = this._createHelper( event ); + + //Cache the helper size + this._cacheHelperProportions(); + + /* + * - Position generation - + * This block generates everything position related - it's the core of draggables. + */ + + //Cache the margins of the original element + this._cacheMargins(); + + //The element's absolute position on the page minus margins + this.offset = this.currentItem.offset(); + this.offset = { + top: this.offset.top - this.margins.top, + left: this.offset.left - this.margins.left + }; + + $.extend( this.offset, { + click: { //Where the click happened, relative to the element + left: event.pageX - this.offset.left, + top: event.pageY - this.offset.top + }, + + // This is a relative to absolute position minus the actual position calculation - + // only used for relative positioned helper + relative: this._getRelativeOffset() + } ); + + // After we get the helper offset, but before we get the parent offset we can + // change the helper's position to absolute + // TODO: Still need to figure out a way to make relative sorting possible + this.helper.css( "position", "absolute" ); + this.cssPosition = this.helper.css( "position" ); + + //Adjust the mouse offset relative to the helper if "cursorAt" is supplied + if ( o.cursorAt ) { + this._adjustOffsetFromHelper( o.cursorAt ); + } + + //Cache the former DOM position + this.domPosition = { + prev: this.currentItem.prev()[ 0 ], + parent: this.currentItem.parent()[ 0 ] + }; + + // If the helper is not the original, hide the original so it's not playing any role during + // the drag, won't cause anything bad this way + if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) { + this.currentItem.hide(); + } + + //Create the placeholder + this._createPlaceholder(); + + //Get the next scrolling parent + this.scrollParent = this.placeholder.scrollParent(); + + $.extend( this.offset, { + parent: this._getParentOffset() + } ); + + //Set a containment if given in the options + if ( o.containment ) { + this._setContainment(); + } + + if ( o.cursor && o.cursor !== "auto" ) { // cursor option + body = this.document.find( "body" ); + + // Support: IE + this.storedCursor = body.css( "cursor" ); + body.css( "cursor", o.cursor ); + + this.storedStylesheet = + $( "<style>*{ cursor: " + o.cursor + " !important; }</style>" ).appendTo( body ); + } + + // We need to make sure to grab the zIndex before setting the + // opacity, because setting the opacity to anything lower than 1 + // causes the zIndex to change from "auto" to 0. + if ( o.zIndex ) { // zIndex option + if ( this.helper.css( "zIndex" ) ) { + this._storedZIndex = this.helper.css( "zIndex" ); + } + this.helper.css( "zIndex", o.zIndex ); + } + + if ( o.opacity ) { // opacity option + if ( this.helper.css( "opacity" ) ) { + this._storedOpacity = this.helper.css( "opacity" ); + } + this.helper.css( "opacity", o.opacity ); + } + + //Prepare scrolling + if ( this.scrollParent[ 0 ] !== this.document[ 0 ] && + this.scrollParent[ 0 ].tagName !== "HTML" ) { + this.overflowOffset = this.scrollParent.offset(); + } + + //Call callbacks + this._trigger( "start", event, this._uiHash() ); + + //Recache the helper size + if ( !this._preserveHelperProportions ) { + this._cacheHelperProportions(); + } + + //Post "activate" events to possible containers + if ( !noActivation ) { + for ( i = this.containers.length - 1; i >= 0; i-- ) { + this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) ); + } + } + + //Prepare possible droppables + if ( $.ui.ddmanager ) { + $.ui.ddmanager.current = this; + } + + if ( $.ui.ddmanager && !o.dropBehaviour ) { + $.ui.ddmanager.prepareOffsets( this, event ); + } + + this.dragging = true; + + this._addClass( this.helper, "ui-sortable-helper" ); + + //Move the helper, if needed + if ( !this.helper.parent().is( this.appendTo ) ) { + this.helper.detach().appendTo( this.appendTo ); + + //Update position + this.offset.parent = this._getParentOffset(); + } + + //Generate the original position + this.position = this.originalPosition = this._generatePosition( event ); + this.originalPageX = event.pageX; + this.originalPageY = event.pageY; + this.lastPositionAbs = this.positionAbs = this._convertPositionTo( "absolute" ); + + this._mouseDrag( event ); + + return true; + + }, + + _scroll: function( event ) { + var o = this.options, + scrolled = false; + + if ( this.scrollParent[ 0 ] !== this.document[ 0 ] && + this.scrollParent[ 0 ].tagName !== "HTML" ) { + + if ( ( this.overflowOffset.top + this.scrollParent[ 0 ].offsetHeight ) - + event.pageY < o.scrollSensitivity ) { + this.scrollParent[ 0 ].scrollTop = + scrolled = this.scrollParent[ 0 ].scrollTop + o.scrollSpeed; + } else if ( event.pageY - this.overflowOffset.top < o.scrollSensitivity ) { + this.scrollParent[ 0 ].scrollTop = + scrolled = this.scrollParent[ 0 ].scrollTop - o.scrollSpeed; + } + + if ( ( this.overflowOffset.left + this.scrollParent[ 0 ].offsetWidth ) - + event.pageX < o.scrollSensitivity ) { + this.scrollParent[ 0 ].scrollLeft = scrolled = + this.scrollParent[ 0 ].scrollLeft + o.scrollSpeed; + } else if ( event.pageX - this.overflowOffset.left < o.scrollSensitivity ) { + this.scrollParent[ 0 ].scrollLeft = scrolled = + this.scrollParent[ 0 ].scrollLeft - o.scrollSpeed; + } + + } else { + + if ( event.pageY - this.document.scrollTop() < o.scrollSensitivity ) { + scrolled = this.document.scrollTop( this.document.scrollTop() - o.scrollSpeed ); + } else if ( this.window.height() - ( event.pageY - this.document.scrollTop() ) < + o.scrollSensitivity ) { + scrolled = this.document.scrollTop( this.document.scrollTop() + o.scrollSpeed ); + } + + if ( event.pageX - this.document.scrollLeft() < o.scrollSensitivity ) { + scrolled = this.document.scrollLeft( + this.document.scrollLeft() - o.scrollSpeed + ); + } else if ( this.window.width() - ( event.pageX - this.document.scrollLeft() ) < + o.scrollSensitivity ) { + scrolled = this.document.scrollLeft( + this.document.scrollLeft() + o.scrollSpeed + ); + } + + } + + return scrolled; + }, + + _mouseDrag: function( event ) { + var i, item, itemElement, intersection, + o = this.options; + + //Compute the helpers position + this.position = this._generatePosition( event ); + this.positionAbs = this._convertPositionTo( "absolute" ); + + //Set the helper position + if ( !this.options.axis || this.options.axis !== "y" ) { + this.helper[ 0 ].style.left = this.position.left + "px"; + } + if ( !this.options.axis || this.options.axis !== "x" ) { + this.helper[ 0 ].style.top = this.position.top + "px"; + } + + //Do scrolling + if ( o.scroll ) { + if ( this._scroll( event ) !== false ) { + + //Update item positions used in position checks + this._refreshItemPositions( true ); + + if ( $.ui.ddmanager && !o.dropBehaviour ) { + $.ui.ddmanager.prepareOffsets( this, event ); + } + } + } + + this.dragDirection = { + vertical: this._getDragVerticalDirection(), + horizontal: this._getDragHorizontalDirection() + }; + + //Rearrange + for ( i = this.items.length - 1; i >= 0; i-- ) { + + //Cache variables and intersection, continue if no intersection + item = this.items[ i ]; + itemElement = item.item[ 0 ]; + intersection = this._intersectsWithPointer( item ); + if ( !intersection ) { + continue; + } + + // Only put the placeholder inside the current Container, skip all + // items from other containers. This works because when moving + // an item from one container to another the + // currentContainer is switched before the placeholder is moved. + // + // Without this, moving items in "sub-sortables" can cause + // the placeholder to jitter between the outer and inner container. + if ( item.instance !== this.currentContainer ) { + continue; + } + + // Cannot intersect with itself + // no useless actions that have been done before + // no action if the item moved is the parent of the item checked + if ( itemElement !== this.currentItem[ 0 ] && + this.placeholder[ intersection === 1 ? + "next" : "prev" ]()[ 0 ] !== itemElement && + !$.contains( this.placeholder[ 0 ], itemElement ) && + ( this.options.type === "semi-dynamic" ? + !$.contains( this.element[ 0 ], itemElement ) : + true + ) + ) { + + this.direction = intersection === 1 ? "down" : "up"; + + if ( this.options.tolerance === "pointer" || + this._intersectsWithSides( item ) ) { + this._rearrange( event, item ); + } else { + break; + } + + this._trigger( "change", event, this._uiHash() ); + break; + } + } + + //Post events to containers + this._contactContainers( event ); + + //Interconnect with droppables + if ( $.ui.ddmanager ) { + $.ui.ddmanager.drag( this, event ); + } + + //Call callbacks + this._trigger( "sort", event, this._uiHash() ); + + this.lastPositionAbs = this.positionAbs; + return false; + + }, + + _mouseStop: function( event, noPropagation ) { + + if ( !event ) { + return; + } + + //If we are using droppables, inform the manager about the drop + if ( $.ui.ddmanager && !this.options.dropBehaviour ) { + $.ui.ddmanager.drop( this, event ); + } + + if ( this.options.revert ) { + var that = this, + cur = this.placeholder.offset(), + axis = this.options.axis, + animation = {}; + + if ( !axis || axis === "x" ) { + animation.left = cur.left - this.offset.parent.left - this.margins.left + + ( this.offsetParent[ 0 ] === this.document[ 0 ].body ? + 0 : + this.offsetParent[ 0 ].scrollLeft + ); + } + if ( !axis || axis === "y" ) { + animation.top = cur.top - this.offset.parent.top - this.margins.top + + ( this.offsetParent[ 0 ] === this.document[ 0 ].body ? + 0 : + this.offsetParent[ 0 ].scrollTop + ); + } + this.reverting = true; + $( this.helper ).animate( + animation, + parseInt( this.options.revert, 10 ) || 500, + function() { + that._clear( event ); + } + ); + } else { + this._clear( event, noPropagation ); + } + + return false; + + }, + + cancel: function() { + + if ( this.dragging ) { + + this._mouseUp( new $.Event( "mouseup", { target: null } ) ); + + if ( this.options.helper === "original" ) { + this.currentItem.css( this._storedCSS ); + this._removeClass( this.currentItem, "ui-sortable-helper" ); + } else { + this.currentItem.show(); + } + + //Post deactivating events to containers + for ( var i = this.containers.length - 1; i >= 0; i-- ) { + this.containers[ i ]._trigger( "deactivate", null, this._uiHash( this ) ); + if ( this.containers[ i ].containerCache.over ) { + this.containers[ i ]._trigger( "out", null, this._uiHash( this ) ); + this.containers[ i ].containerCache.over = 0; + } + } + + } + + if ( this.placeholder ) { + + //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, + // it unbinds ALL events from the original node! + if ( this.placeholder[ 0 ].parentNode ) { + this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] ); + } + if ( this.options.helper !== "original" && this.helper && + this.helper[ 0 ].parentNode ) { + this.helper.remove(); + } + + $.extend( this, { + helper: null, + dragging: false, + reverting: false, + _noFinalSort: null + } ); + + if ( this.domPosition.prev ) { + $( this.domPosition.prev ).after( this.currentItem ); + } else { + $( this.domPosition.parent ).prepend( this.currentItem ); + } + } + + return this; + + }, + + serialize: function( o ) { + + var items = this._getItemsAsjQuery( o && o.connected ), + str = []; + o = o || {}; + + $( items ).each( function() { + var res = ( $( o.item || this ).attr( o.attribute || "id" ) || "" ) + .match( o.expression || ( /(.+)[\-=_](.+)/ ) ); + if ( res ) { + str.push( + ( o.key || res[ 1 ] + "[]" ) + + "=" + ( o.key && o.expression ? res[ 1 ] : res[ 2 ] ) ); + } + } ); + + if ( !str.length && o.key ) { + str.push( o.key + "=" ); + } + + return str.join( "&" ); + + }, + + toArray: function( o ) { + + var items = this._getItemsAsjQuery( o && o.connected ), + ret = []; + + o = o || {}; + + items.each( function() { + ret.push( $( o.item || this ).attr( o.attribute || "id" ) || "" ); + } ); + return ret; + + }, + + /* Be careful with the following core functions */ + _intersectsWith: function( item ) { + + var x1 = this.positionAbs.left, + x2 = x1 + this.helperProportions.width, + y1 = this.positionAbs.top, + y2 = y1 + this.helperProportions.height, + l = item.left, + r = l + item.width, + t = item.top, + b = t + item.height, + dyClick = this.offset.click.top, + dxClick = this.offset.click.left, + isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && + ( y1 + dyClick ) < b ), + isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && + ( x1 + dxClick ) < r ), + isOverElement = isOverElementHeight && isOverElementWidth; + + if ( this.options.tolerance === "pointer" || + this.options.forcePointerForContainers || + ( this.options.tolerance !== "pointer" && + this.helperProportions[ this.floating ? "width" : "height" ] > + item[ this.floating ? "width" : "height" ] ) + ) { + return isOverElement; + } else { + + return ( l < x1 + ( this.helperProportions.width / 2 ) && // Right Half + x2 - ( this.helperProportions.width / 2 ) < r && // Left Half + t < y1 + ( this.helperProportions.height / 2 ) && // Bottom Half + y2 - ( this.helperProportions.height / 2 ) < b ); // Top Half + + } + }, + + _intersectsWithPointer: function( item ) { + var verticalDirection, horizontalDirection, + isOverElementHeight = ( this.options.axis === "x" ) || + this._isOverAxis( + this.positionAbs.top + this.offset.click.top, item.top, item.height ), + isOverElementWidth = ( this.options.axis === "y" ) || + this._isOverAxis( + this.positionAbs.left + this.offset.click.left, item.left, item.width ), + isOverElement = isOverElementHeight && isOverElementWidth; + + if ( !isOverElement ) { + return false; + } + + verticalDirection = this.dragDirection.vertical; + horizontalDirection = this.dragDirection.horizontal; + + return this.floating ? + ( ( horizontalDirection === "right" || verticalDirection === "down" ) ? 2 : 1 ) : + ( verticalDirection && ( verticalDirection === "down" ? 2 : 1 ) ); + + }, + + _intersectsWithSides: function( item ) { + + var isOverBottomHalf = this._isOverAxis( this.positionAbs.top + + this.offset.click.top, item.top + ( item.height / 2 ), item.height ), + isOverRightHalf = this._isOverAxis( this.positionAbs.left + + this.offset.click.left, item.left + ( item.width / 2 ), item.width ), + verticalDirection = this.dragDirection.vertical, + horizontalDirection = this.dragDirection.horizontal; + + if ( this.floating && horizontalDirection ) { + return ( ( horizontalDirection === "right" && isOverRightHalf ) || + ( horizontalDirection === "left" && !isOverRightHalf ) ); + } else { + return verticalDirection && ( ( verticalDirection === "down" && isOverBottomHalf ) || + ( verticalDirection === "up" && !isOverBottomHalf ) ); + } + + }, + + _getDragVerticalDirection: function() { + var delta = this.positionAbs.top - this.lastPositionAbs.top; + return delta !== 0 && ( delta > 0 ? "down" : "up" ); + }, + + _getDragHorizontalDirection: function() { + var delta = this.positionAbs.left - this.lastPositionAbs.left; + return delta !== 0 && ( delta > 0 ? "right" : "left" ); + }, + + refresh: function( event ) { + this._refreshItems( event ); + this._setHandleClassName(); + this.refreshPositions(); + return this; + }, + + _connectWith: function() { + var options = this.options; + return options.connectWith.constructor === String ? + [ options.connectWith ] : + options.connectWith; + }, + + _getItemsAsjQuery: function( connected ) { + + var i, j, cur, inst, + items = [], + queries = [], + connectWith = this._connectWith(); + + if ( connectWith && connected ) { + for ( i = connectWith.length - 1; i >= 0; i-- ) { + cur = $( connectWith[ i ], this.document[ 0 ] ); + for ( j = cur.length - 1; j >= 0; j-- ) { + inst = $.data( cur[ j ], this.widgetFullName ); + if ( inst && inst !== this && !inst.options.disabled ) { + queries.push( [ typeof inst.options.items === "function" ? + inst.options.items.call( inst.element ) : + $( inst.options.items, inst.element ) + .not( ".ui-sortable-helper" ) + .not( ".ui-sortable-placeholder" ), inst ] ); + } + } + } + } + + queries.push( [ typeof this.options.items === "function" ? + this.options.items + .call( this.element, null, { options: this.options, item: this.currentItem } ) : + $( this.options.items, this.element ) + .not( ".ui-sortable-helper" ) + .not( ".ui-sortable-placeholder" ), this ] ); + + function addItems() { + items.push( this ); + } + for ( i = queries.length - 1; i >= 0; i-- ) { + queries[ i ][ 0 ].each( addItems ); + } + + return $( items ); + + }, + + _removeCurrentsFromItems: function() { + + var list = this.currentItem.find( ":data(" + this.widgetName + "-item)" ); + + this.items = $.grep( this.items, function( item ) { + for ( var j = 0; j < list.length; j++ ) { + if ( list[ j ] === item.item[ 0 ] ) { + return false; + } + } + return true; + } ); + + }, + + _refreshItems: function( event ) { + + this.items = []; + this.containers = [ this ]; + + var i, j, cur, inst, targetData, _queries, item, queriesLength, + items = this.items, + queries = [ [ typeof this.options.items === "function" ? + this.options.items.call( this.element[ 0 ], event, { item: this.currentItem } ) : + $( this.options.items, this.element ), this ] ], + connectWith = this._connectWith(); + + //Shouldn't be run the first time through due to massive slow-down + if ( connectWith && this.ready ) { + for ( i = connectWith.length - 1; i >= 0; i-- ) { + cur = $( connectWith[ i ], this.document[ 0 ] ); + for ( j = cur.length - 1; j >= 0; j-- ) { + inst = $.data( cur[ j ], this.widgetFullName ); + if ( inst && inst !== this && !inst.options.disabled ) { + queries.push( [ typeof inst.options.items === "function" ? + inst.options.items + .call( inst.element[ 0 ], event, { item: this.currentItem } ) : + $( inst.options.items, inst.element ), inst ] ); + this.containers.push( inst ); + } + } + } + } + + for ( i = queries.length - 1; i >= 0; i-- ) { + targetData = queries[ i ][ 1 ]; + _queries = queries[ i ][ 0 ]; + + for ( j = 0, queriesLength = _queries.length; j < queriesLength; j++ ) { + item = $( _queries[ j ] ); + + // Data for target checking (mouse manager) + item.data( this.widgetName + "-item", targetData ); + + items.push( { + item: item, + instance: targetData, + width: 0, height: 0, + left: 0, top: 0 + } ); + } + } + + }, + + _refreshItemPositions: function( fast ) { + var i, item, t, p; + + for ( i = this.items.length - 1; i >= 0; i-- ) { + item = this.items[ i ]; + + //We ignore calculating positions of all connected containers when we're not over them + if ( this.currentContainer && item.instance !== this.currentContainer && + item.item[ 0 ] !== this.currentItem[ 0 ] ) { + continue; + } + + t = this.options.toleranceElement ? + $( this.options.toleranceElement, item.item ) : + item.item; + + if ( !fast ) { + item.width = t.outerWidth(); + item.height = t.outerHeight(); + } + + p = t.offset(); + item.left = p.left; + item.top = p.top; + } + }, + + refreshPositions: function( fast ) { + + // Determine whether items are being displayed horizontally + this.floating = this.items.length ? + this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) : + false; + + // This has to be redone because due to the item being moved out/into the offsetParent, + // the offsetParent's position will change + if ( this.offsetParent && this.helper ) { + this.offset.parent = this._getParentOffset(); + } + + this._refreshItemPositions( fast ); + + var i, p; + + if ( this.options.custom && this.options.custom.refreshContainers ) { + this.options.custom.refreshContainers.call( this ); + } else { + for ( i = this.containers.length - 1; i >= 0; i-- ) { + p = this.containers[ i ].element.offset(); + this.containers[ i ].containerCache.left = p.left; + this.containers[ i ].containerCache.top = p.top; + this.containers[ i ].containerCache.width = + this.containers[ i ].element.outerWidth(); + this.containers[ i ].containerCache.height = + this.containers[ i ].element.outerHeight(); + } + } + + return this; + }, + + _createPlaceholder: function( that ) { + that = that || this; + var className, nodeName, + o = that.options; + + if ( !o.placeholder || o.placeholder.constructor === String ) { + className = o.placeholder; + nodeName = that.currentItem[ 0 ].nodeName.toLowerCase(); + o.placeholder = { + element: function() { + + var element = $( "<" + nodeName + ">", that.document[ 0 ] ); + + that._addClass( element, "ui-sortable-placeholder", + className || that.currentItem[ 0 ].className ) + ._removeClass( element, "ui-sortable-helper" ); + + if ( nodeName === "tbody" ) { + that._createTrPlaceholder( + that.currentItem.find( "tr" ).eq( 0 ), + $( "<tr>", that.document[ 0 ] ).appendTo( element ) + ); + } else if ( nodeName === "tr" ) { + that._createTrPlaceholder( that.currentItem, element ); + } else if ( nodeName === "img" ) { + element.attr( "src", that.currentItem.attr( "src" ) ); + } + + if ( !className ) { + element.css( "visibility", "hidden" ); + } + + return element; + }, + update: function( container, p ) { + + // 1. If a className is set as 'placeholder option, we don't force sizes - + // the class is responsible for that + // 2. The option 'forcePlaceholderSize can be enabled to force it even if a + // class name is specified + if ( className && !o.forcePlaceholderSize ) { + return; + } + + // If the element doesn't have a actual height or width by itself (without + // styles coming from a stylesheet), it receives the inline height and width + // from the dragged item. Or, if it's a tbody or tr, it's going to have a height + // anyway since we're populating them with <td>s above, but they're unlikely to + // be the correct height on their own if the row heights are dynamic, so we'll + // always assign the height of the dragged item given forcePlaceholderSize + // is true. + if ( !p.height() || ( o.forcePlaceholderSize && + ( nodeName === "tbody" || nodeName === "tr" ) ) ) { + p.height( + that.currentItem.innerHeight() - + parseInt( that.currentItem.css( "paddingTop" ) || 0, 10 ) - + parseInt( that.currentItem.css( "paddingBottom" ) || 0, 10 ) ); + } + if ( !p.width() ) { + p.width( + that.currentItem.innerWidth() - + parseInt( that.currentItem.css( "paddingLeft" ) || 0, 10 ) - + parseInt( that.currentItem.css( "paddingRight" ) || 0, 10 ) ); + } + } + }; + } + + //Create the placeholder + that.placeholder = $( o.placeholder.element.call( that.element, that.currentItem ) ); + + //Append it after the actual current item + that.currentItem.after( that.placeholder ); + + //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) + o.placeholder.update( that, that.placeholder ); + + }, + + _createTrPlaceholder: function( sourceTr, targetTr ) { + var that = this; + + sourceTr.children().each( function() { + $( "<td> </td>", that.document[ 0 ] ) + .attr( "colspan", $( this ).attr( "colspan" ) || 1 ) + .appendTo( targetTr ); + } ); + }, + + _contactContainers: function( event ) { + var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom, + floating, axis, + innermostContainer = null, + innermostIndex = null; + + // Get innermost container that intersects with item + for ( i = this.containers.length - 1; i >= 0; i-- ) { + + // Never consider a container that's located within the item itself + if ( $.contains( this.currentItem[ 0 ], this.containers[ i ].element[ 0 ] ) ) { + continue; + } + + if ( this._intersectsWith( this.containers[ i ].containerCache ) ) { + + // If we've already found a container and it's more "inner" than this, then continue + if ( innermostContainer && + $.contains( + this.containers[ i ].element[ 0 ], + innermostContainer.element[ 0 ] ) ) { + continue; + } + + innermostContainer = this.containers[ i ]; + innermostIndex = i; + + } else { + + // container doesn't intersect. trigger "out" event if necessary + if ( this.containers[ i ].containerCache.over ) { + this.containers[ i ]._trigger( "out", event, this._uiHash( this ) ); + this.containers[ i ].containerCache.over = 0; + } + } + + } + + // If no intersecting containers found, return + if ( !innermostContainer ) { + return; + } + + // Move the item into the container if it's not there already + if ( this.containers.length === 1 ) { + if ( !this.containers[ innermostIndex ].containerCache.over ) { + this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) ); + this.containers[ innermostIndex ].containerCache.over = 1; + } + } else { + + // When entering a new container, we will find the item with the least distance and + // append our item near it + dist = 10000; + itemWithLeastDistance = null; + floating = innermostContainer.floating || this._isFloating( this.currentItem ); + posProperty = floating ? "left" : "top"; + sizeProperty = floating ? "width" : "height"; + axis = floating ? "pageX" : "pageY"; + + for ( j = this.items.length - 1; j >= 0; j-- ) { + if ( !$.contains( + this.containers[ innermostIndex ].element[ 0 ], this.items[ j ].item[ 0 ] ) + ) { + continue; + } + if ( this.items[ j ].item[ 0 ] === this.currentItem[ 0 ] ) { + continue; + } + + cur = this.items[ j ].item.offset()[ posProperty ]; + nearBottom = false; + if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) { + nearBottom = true; + } + + if ( Math.abs( event[ axis ] - cur ) < dist ) { + dist = Math.abs( event[ axis ] - cur ); + itemWithLeastDistance = this.items[ j ]; + this.direction = nearBottom ? "up" : "down"; + } + } + + //Check if dropOnEmpty is enabled + if ( !itemWithLeastDistance && !this.options.dropOnEmpty ) { + return; + } + + if ( this.currentContainer === this.containers[ innermostIndex ] ) { + if ( !this.currentContainer.containerCache.over ) { + this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() ); + this.currentContainer.containerCache.over = 1; + } + return; + } + + if ( itemWithLeastDistance ) { + this._rearrange( event, itemWithLeastDistance, null, true ); + } else { + this._rearrange( event, null, this.containers[ innermostIndex ].element, true ); + } + this._trigger( "change", event, this._uiHash() ); + this.containers[ innermostIndex ]._trigger( "change", event, this._uiHash( this ) ); + this.currentContainer = this.containers[ innermostIndex ]; + + //Update the placeholder + this.options.placeholder.update( this.currentContainer, this.placeholder ); + + //Update scrollParent + this.scrollParent = this.placeholder.scrollParent(); + + //Update overflowOffset + if ( this.scrollParent[ 0 ] !== this.document[ 0 ] && + this.scrollParent[ 0 ].tagName !== "HTML" ) { + this.overflowOffset = this.scrollParent.offset(); + } + + this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) ); + this.containers[ innermostIndex ].containerCache.over = 1; + } + + }, + + _createHelper: function( event ) { + + var o = this.options, + helper = typeof o.helper === "function" ? + $( o.helper.apply( this.element[ 0 ], [ event, this.currentItem ] ) ) : + ( o.helper === "clone" ? this.currentItem.clone() : this.currentItem ); + + //Add the helper to the DOM if that didn't happen already + if ( !helper.parents( "body" ).length ) { + this.appendTo[ 0 ].appendChild( helper[ 0 ] ); + } + + if ( helper[ 0 ] === this.currentItem[ 0 ] ) { + this._storedCSS = { + width: this.currentItem[ 0 ].style.width, + height: this.currentItem[ 0 ].style.height, + position: this.currentItem.css( "position" ), + top: this.currentItem.css( "top" ), + left: this.currentItem.css( "left" ) + }; + } + + if ( !helper[ 0 ].style.width || o.forceHelperSize ) { + helper.width( this.currentItem.width() ); + } + if ( !helper[ 0 ].style.height || o.forceHelperSize ) { + helper.height( this.currentItem.height() ); + } + + return helper; + + }, + + _adjustOffsetFromHelper: function( obj ) { + if ( typeof obj === "string" ) { + obj = obj.split( " " ); + } + if ( Array.isArray( obj ) ) { + obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 }; + } + if ( "left" in obj ) { + this.offset.click.left = obj.left + this.margins.left; + } + if ( "right" in obj ) { + this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; + } + if ( "top" in obj ) { + this.offset.click.top = obj.top + this.margins.top; + } + if ( "bottom" in obj ) { + this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; + } + }, + + _getParentOffset: function() { + + //Get the offsetParent and cache its position + this.offsetParent = this.helper.offsetParent(); + var po = this.offsetParent.offset(); + + // This is a special case where we need to modify a offset calculated on start, since the + // following happened: + // 1. The position of the helper is absolute, so it's position is calculated based on the + // next positioned parent + // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't + // the document, which means that the scroll is included in the initial calculation of the + // offset of the parent, and never recalculated upon drag + if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== this.document[ 0 ] && + $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) { + po.left += this.scrollParent.scrollLeft(); + po.top += this.scrollParent.scrollTop(); + } + + // This needs to be actually done for all browsers, since pageX/pageY includes this + // information with an ugly IE fix + if ( this.offsetParent[ 0 ] === this.document[ 0 ].body || + ( this.offsetParent[ 0 ].tagName && + this.offsetParent[ 0 ].tagName.toLowerCase() === "html" && $.ui.ie ) ) { + po = { top: 0, left: 0 }; + } + + return { + top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ), + left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 ) + }; + + }, + + _getRelativeOffset: function() { + + if ( this.cssPosition === "relative" ) { + var p = this.currentItem.position(); + return { + top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) + + this.scrollParent.scrollTop(), + left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) + + this.scrollParent.scrollLeft() + }; + } else { + return { top: 0, left: 0 }; + } + + }, + + _cacheMargins: function() { + this.margins = { + left: ( parseInt( this.currentItem.css( "marginLeft" ), 10 ) || 0 ), + top: ( parseInt( this.currentItem.css( "marginTop" ), 10 ) || 0 ) + }; + }, + + _cacheHelperProportions: function() { + this.helperProportions = { + width: this.helper.outerWidth(), + height: this.helper.outerHeight() + }; + }, + + _setContainment: function() { + + var ce, co, over, + o = this.options; + if ( o.containment === "parent" ) { + o.containment = this.helper[ 0 ].parentNode; + } + if ( o.containment === "document" || o.containment === "window" ) { + this.containment = [ + 0 - this.offset.relative.left - this.offset.parent.left, + 0 - this.offset.relative.top - this.offset.parent.top, + o.containment === "document" ? + this.document.width() : + this.window.width() - this.helperProportions.width - this.margins.left, + ( o.containment === "document" ? + ( this.document.height() || document.body.parentNode.scrollHeight ) : + this.window.height() || this.document[ 0 ].body.parentNode.scrollHeight + ) - this.helperProportions.height - this.margins.top + ]; + } + + if ( !( /^(document|window|parent)$/ ).test( o.containment ) ) { + ce = $( o.containment )[ 0 ]; + co = $( o.containment ).offset(); + over = ( $( ce ).css( "overflow" ) !== "hidden" ); + + this.containment = [ + co.left + ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) + + ( parseInt( $( ce ).css( "paddingLeft" ), 10 ) || 0 ) - this.margins.left, + co.top + ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) + + ( parseInt( $( ce ).css( "paddingTop" ), 10 ) || 0 ) - this.margins.top, + co.left + ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - + ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) - + ( parseInt( $( ce ).css( "paddingRight" ), 10 ) || 0 ) - + this.helperProportions.width - this.margins.left, + co.top + ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - + ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) - + ( parseInt( $( ce ).css( "paddingBottom" ), 10 ) || 0 ) - + this.helperProportions.height - this.margins.top + ]; + } + + }, + + _convertPositionTo: function( d, pos ) { + + if ( !pos ) { + pos = this.position; + } + var mod = d === "absolute" ? 1 : -1, + scroll = this.cssPosition === "absolute" && + !( this.scrollParent[ 0 ] !== this.document[ 0 ] && + $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? + this.offsetParent : + this.scrollParent, + scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName ); + + return { + top: ( + + // The absolute mouse position + pos.top + + + // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.relative.top * mod + + + // The offsetParent's offset without borders (offset + border) + this.offset.parent.top * mod - + ( ( this.cssPosition === "fixed" ? + -this.scrollParent.scrollTop() : + ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod ) + ), + left: ( + + // The absolute mouse position + pos.left + + + // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.relative.left * mod + + + // The offsetParent's offset without borders (offset + border) + this.offset.parent.left * mod - + ( ( this.cssPosition === "fixed" ? + -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : + scroll.scrollLeft() ) * mod ) + ) + }; + + }, + + _generatePosition: function( event ) { + + var top, left, + o = this.options, + pageX = event.pageX, + pageY = event.pageY, + scroll = this.cssPosition === "absolute" && + !( this.scrollParent[ 0 ] !== this.document[ 0 ] && + $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? + this.offsetParent : + this.scrollParent, + scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName ); + + // This is another very weird special case that only happens for relative elements: + // 1. If the css position is relative + // 2. and the scroll parent is the document or similar to the offset parent + // we have to refresh the relative offset during the scroll so there are no jumps + if ( this.cssPosition === "relative" && !( this.scrollParent[ 0 ] !== this.document[ 0 ] && + this.scrollParent[ 0 ] !== this.offsetParent[ 0 ] ) ) { + this.offset.relative = this._getRelativeOffset(); + } + + /* + * - Position constraining - + * Constrain the position to a mix of grid, containment. + */ + + if ( this.originalPosition ) { //If we are not dragging yet, we won't check for options + + if ( this.containment ) { + if ( event.pageX - this.offset.click.left < this.containment[ 0 ] ) { + pageX = this.containment[ 0 ] + this.offset.click.left; + } + if ( event.pageY - this.offset.click.top < this.containment[ 1 ] ) { + pageY = this.containment[ 1 ] + this.offset.click.top; + } + if ( event.pageX - this.offset.click.left > this.containment[ 2 ] ) { + pageX = this.containment[ 2 ] + this.offset.click.left; + } + if ( event.pageY - this.offset.click.top > this.containment[ 3 ] ) { + pageY = this.containment[ 3 ] + this.offset.click.top; + } + } + + if ( o.grid ) { + top = this.originalPageY + Math.round( ( pageY - this.originalPageY ) / + o.grid[ 1 ] ) * o.grid[ 1 ]; + pageY = this.containment ? + ( ( top - this.offset.click.top >= this.containment[ 1 ] && + top - this.offset.click.top <= this.containment[ 3 ] ) ? + top : + ( ( top - this.offset.click.top >= this.containment[ 1 ] ) ? + top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : + top; + + left = this.originalPageX + Math.round( ( pageX - this.originalPageX ) / + o.grid[ 0 ] ) * o.grid[ 0 ]; + pageX = this.containment ? + ( ( left - this.offset.click.left >= this.containment[ 0 ] && + left - this.offset.click.left <= this.containment[ 2 ] ) ? + left : + ( ( left - this.offset.click.left >= this.containment[ 0 ] ) ? + left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : + left; + } + + } + + return { + top: ( + + // The absolute mouse position + pageY - + + // Click offset (relative to the element) + this.offset.click.top - + + // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.relative.top - + + // The offsetParent's offset without borders (offset + border) + this.offset.parent.top + + ( ( this.cssPosition === "fixed" ? + -this.scrollParent.scrollTop() : + ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) ) + ), + left: ( + + // The absolute mouse position + pageX - + + // Click offset (relative to the element) + this.offset.click.left - + + // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.relative.left - + + // The offsetParent's offset without borders (offset + border) + this.offset.parent.left + + ( ( this.cssPosition === "fixed" ? + -this.scrollParent.scrollLeft() : + scrollIsRootNode ? 0 : scroll.scrollLeft() ) ) + ) + }; + + }, + + _rearrange: function( event, i, a, hardRefresh ) { + + if ( a ) { + a[ 0 ].appendChild( this.placeholder[ 0 ] ); + } else { + i.item[ 0 ].parentNode.insertBefore( this.placeholder[ 0 ], + ( this.direction === "down" ? i.item[ 0 ] : i.item[ 0 ].nextSibling ) ); + } + + //Various things done here to improve the performance: + // 1. we create a setTimeout, that calls refreshPositions + // 2. on the instance, we have a counter variable, that get's higher after every append + // 3. on the local scope, we copy the counter variable, and check in the timeout, + // if it's still the same + // 4. this lets only the last addition to the timeout stack through + this.counter = this.counter ? ++this.counter : 1; + var counter = this.counter; + + this._delay( function() { + if ( counter === this.counter ) { + + //Precompute after each DOM insertion, NOT on mousemove + this.refreshPositions( !hardRefresh ); + } + } ); + + }, + + _clear: function( event, noPropagation ) { + + this.reverting = false; + + // We delay all events that have to be triggered to after the point where the placeholder + // has been removed and everything else normalized again + var i, + delayedTriggers = []; + + // We first have to update the dom position of the actual currentItem + // Note: don't do it if the current item is already removed (by a user), or it gets + // reappended (see #4088) + if ( !this._noFinalSort && this.currentItem.parent().length ) { + this.placeholder.before( this.currentItem ); + } + this._noFinalSort = null; + + if ( this.helper[ 0 ] === this.currentItem[ 0 ] ) { + for ( i in this._storedCSS ) { + if ( this._storedCSS[ i ] === "auto" || this._storedCSS[ i ] === "static" ) { + this._storedCSS[ i ] = ""; + } + } + this.currentItem.css( this._storedCSS ); + this._removeClass( this.currentItem, "ui-sortable-helper" ); + } else { + this.currentItem.show(); + } + + if ( this.fromOutside && !noPropagation ) { + delayedTriggers.push( function( event ) { + this._trigger( "receive", event, this._uiHash( this.fromOutside ) ); + } ); + } + if ( ( this.fromOutside || + this.domPosition.prev !== + this.currentItem.prev().not( ".ui-sortable-helper" )[ 0 ] || + this.domPosition.parent !== this.currentItem.parent()[ 0 ] ) && !noPropagation ) { + + // Trigger update callback if the DOM position has changed + delayedTriggers.push( function( event ) { + this._trigger( "update", event, this._uiHash() ); + } ); + } + + // Check if the items Container has Changed and trigger appropriate + // events. + if ( this !== this.currentContainer ) { + if ( !noPropagation ) { + delayedTriggers.push( function( event ) { + this._trigger( "remove", event, this._uiHash() ); + } ); + delayedTriggers.push( ( function( c ) { + return function( event ) { + c._trigger( "receive", event, this._uiHash( this ) ); + }; + } ).call( this, this.currentContainer ) ); + delayedTriggers.push( ( function( c ) { + return function( event ) { + c._trigger( "update", event, this._uiHash( this ) ); + }; + } ).call( this, this.currentContainer ) ); + } + } + + //Post events to containers + function delayEvent( type, instance, container ) { + return function( event ) { + container._trigger( type, event, instance._uiHash( instance ) ); + }; + } + for ( i = this.containers.length - 1; i >= 0; i-- ) { + if ( !noPropagation ) { + delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) ); + } + if ( this.containers[ i ].containerCache.over ) { + delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) ); + this.containers[ i ].containerCache.over = 0; + } + } + + //Do what was originally in plugins + if ( this.storedCursor ) { + this.document.find( "body" ).css( "cursor", this.storedCursor ); + this.storedStylesheet.remove(); + } + if ( this._storedOpacity ) { + this.helper.css( "opacity", this._storedOpacity ); + } + if ( this._storedZIndex ) { + this.helper.css( "zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex ); + } + + this.dragging = false; + + if ( !noPropagation ) { + this._trigger( "beforeStop", event, this._uiHash() ); + } + + //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, + // it unbinds ALL events from the original node! + this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] ); + + if ( !this.cancelHelperRemoval ) { + if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) { + this.helper.remove(); + } + this.helper = null; + } + + if ( !noPropagation ) { + for ( i = 0; i < delayedTriggers.length; i++ ) { + + // Trigger all delayed events + delayedTriggers[ i ].call( this, event ); + } + this._trigger( "stop", event, this._uiHash() ); + } + + this.fromOutside = false; + return !this.cancelHelperRemoval; + + }, + + _trigger: function() { + if ( $.Widget.prototype._trigger.apply( this, arguments ) === false ) { + this.cancel(); + } + }, + + _uiHash: function( _inst ) { + var inst = _inst || this; + return { + helper: inst.helper, + placeholder: inst.placeholder || $( [] ), + position: inst.position, + originalPosition: inst.originalPosition, + offset: inst.positionAbs, + item: inst.currentItem, + sender: _inst ? _inst.element : null + }; + } + + } ); } ); diff --git a/lib/web/jquery/ui-modules/widgets/spinner.js b/lib/web/jquery/ui-modules/widgets/spinner.js index 1d535a20134ae..d0cf8b49aa191 100644 --- a/lib/web/jquery/ui-modules/widgets/spinner.js +++ b/lib/web/jquery/ui-modules/widgets/spinner.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Spinner 1.13.1 + * jQuery UI Spinner 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -17,566 +17,566 @@ //>>css.theme: ../../themes/base/theme.css ( function( factory ) { - "use strict"; - - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define( [ - "jquery", - "./button", - "../version", - "../keycode", - "../safe-active-element", - "../widget" - ], factory ); - } else { - - // Browser globals - factory( jQuery ); - } + "use strict"; + + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ + "jquery", + "./button", + "../version", + "../keycode", + "../safe-active-element", + "../widget" + ], factory ); + } else { + + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; - -function spinnerModifier( fn ) { - return function() { - var previous = this.element.val(); - fn.apply( this, arguments ); - this._refresh(); - if ( previous !== this.element.val() ) { - this._trigger( "change" ); - } - }; -} - -$.widget( "ui.spinner", { - version: "1.13.1", - defaultElement: "<input>", - widgetEventPrefix: "spin", - options: { - classes: { - "ui-spinner": "ui-corner-all", - "ui-spinner-down": "ui-corner-br", - "ui-spinner-up": "ui-corner-tr" - }, - culture: null, - icons: { - down: "ui-icon-triangle-1-s", - up: "ui-icon-triangle-1-n" - }, - incremental: true, - max: null, - min: null, - numberFormat: null, - page: 10, - step: 1, - - change: null, - spin: null, - start: null, - stop: null - }, - - _create: function() { - - // handle string values that need to be parsed - this._setOption( "max", this.options.max ); - this._setOption( "min", this.options.min ); - this._setOption( "step", this.options.step ); - - // Only format if there is a value, prevents the field from being marked - // as invalid in Firefox, see #9573. - if ( this.value() !== "" ) { - - // Format the value, but don't constrain. - this._value( this.element.val(), true ); - } - - this._draw(); - this._on( this._events ); - this._refresh(); - - // Turning off autocomplete prevents the browser from remembering the - // value when navigating through history, so we re-enable autocomplete - // if the page is unloaded before the widget is destroyed. #7790 - this._on( this.window, { - beforeunload: function() { - this.element.removeAttr( "autocomplete" ); - } - } ); - }, - - _getCreateOptions: function() { - var options = this._super(); - var element = this.element; - - $.each( [ "min", "max", "step" ], function( i, option ) { - var value = element.attr( option ); - if ( value != null && value.length ) { - options[ option ] = value; - } - } ); - - return options; - }, - - _events: { - keydown: function( event ) { - if ( this._start( event ) && this._keydown( event ) ) { - event.preventDefault(); - } - }, - keyup: "_stop", - focus: function() { - this.previous = this.element.val(); - }, - blur: function( event ) { - if ( this.cancelBlur ) { - delete this.cancelBlur; - return; - } - - this._stop(); - this._refresh(); - if ( this.previous !== this.element.val() ) { - this._trigger( "change", event ); - } - }, - mousewheel: function( event, delta ) { - var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ); - var isActive = this.element[ 0 ] === activeElement; - - if ( !isActive || !delta ) { - return; - } - - if ( !this.spinning && !this._start( event ) ) { - return false; - } - - this._spin( ( delta > 0 ? 1 : -1 ) * this.options.step, event ); - clearTimeout( this.mousewheelTimer ); - this.mousewheelTimer = this._delay( function() { - if ( this.spinning ) { - this._stop( event ); - } - }, 100 ); - event.preventDefault(); - }, - "mousedown .ui-spinner-button": function( event ) { - var previous; - - // We never want the buttons to have focus; whenever the user is - // interacting with the spinner, the focus should be on the input. - // If the input is focused then this.previous is properly set from - // when the input first received focus. If the input is not focused - // then we need to set this.previous based on the value before spinning. - previous = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] ) ? - this.previous : this.element.val(); - function checkFocus() { - var isActive = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] ); - if ( !isActive ) { - this.element.trigger( "focus" ); - this.previous = previous; - - // support: IE - // IE sets focus asynchronously, so we need to check if focus - // moved off of the input because the user clicked on the button. - this._delay( function() { - this.previous = previous; - } ); - } - } - - // Ensure focus is on (or stays on) the text field - event.preventDefault(); - checkFocus.call( this ); - - // Support: IE - // IE doesn't prevent moving focus even with event.preventDefault() - // so we set a flag to know when we should ignore the blur event - // and check (again) if focus moved off of the input. - this.cancelBlur = true; - this._delay( function() { - delete this.cancelBlur; - checkFocus.call( this ); - } ); - - if ( this._start( event ) === false ) { - return; - } - - this._repeat( null, $( event.currentTarget ) - .hasClass( "ui-spinner-up" ) ? 1 : -1, event ); - }, - "mouseup .ui-spinner-button": "_stop", - "mouseenter .ui-spinner-button": function( event ) { - - // button will add ui-state-active if mouse was down while mouseleave and kept down - if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) { - return; - } - - if ( this._start( event ) === false ) { - return false; - } - this._repeat( null, $( event.currentTarget ) - .hasClass( "ui-spinner-up" ) ? 1 : -1, event ); - }, - - // TODO: do we really want to consider this a stop? - // shouldn't we just stop the repeater and wait until mouseup before - // we trigger the stop event? - "mouseleave .ui-spinner-button": "_stop" - }, - - // Support mobile enhanced option and make backcompat more sane - _enhance: function() { - this.uiSpinner = this.element - .attr( "autocomplete", "off" ) - .wrap( "<span>" ) - .parent() - - // Add buttons - .append( - "<a></a><a></a>" - ); - }, - - _draw: function() { - this._enhance(); - - this._addClass( this.uiSpinner, "ui-spinner", "ui-widget ui-widget-content" ); - this._addClass( "ui-spinner-input" ); - - this.element.attr( "role", "spinbutton" ); - - // Button bindings - this.buttons = this.uiSpinner.children( "a" ) - .attr( "tabIndex", -1 ) - .attr( "aria-hidden", true ) - .button( { - classes: { - "ui-button": "" - } - } ); - - // TODO: Right now button does not support classes this is already updated in button PR - this._removeClass( this.buttons, "ui-corner-all" ); - - this._addClass( this.buttons.first(), "ui-spinner-button ui-spinner-up" ); - this._addClass( this.buttons.last(), "ui-spinner-button ui-spinner-down" ); - this.buttons.first().button( { - "icon": this.options.icons.up, - "showLabel": false - } ); - this.buttons.last().button( { - "icon": this.options.icons.down, - "showLabel": false - } ); - - // IE 6 doesn't understand height: 50% for the buttons - // unless the wrapper has an explicit height - if ( this.buttons.height() > Math.ceil( this.uiSpinner.height() * 0.5 ) && - this.uiSpinner.height() > 0 ) { - this.uiSpinner.height( this.uiSpinner.height() ); - } - }, - - _keydown: function( event ) { - var options = this.options, - keyCode = $.ui.keyCode; - - switch ( event.keyCode ) { - case keyCode.UP: - this._repeat( null, 1, event ); - return true; - case keyCode.DOWN: - this._repeat( null, -1, event ); - return true; - case keyCode.PAGE_UP: - this._repeat( null, options.page, event ); - return true; - case keyCode.PAGE_DOWN: - this._repeat( null, -options.page, event ); - return true; - } - - return false; - }, - - _start: function( event ) { - if ( !this.spinning && this._trigger( "start", event ) === false ) { - return false; - } - - if ( !this.counter ) { - this.counter = 1; - } - this.spinning = true; - return true; - }, - - _repeat: function( i, steps, event ) { - i = i || 500; - - clearTimeout( this.timer ); - this.timer = this._delay( function() { - this._repeat( 40, steps, event ); - }, i ); - - this._spin( steps * this.options.step, event ); - }, - - _spin: function( step, event ) { - var value = this.value() || 0; - - if ( !this.counter ) { - this.counter = 1; - } - - value = this._adjustValue( value + step * this._increment( this.counter ) ); - - if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false ) { - this._value( value ); - this.counter++; - } - }, - - _increment: function( i ) { - var incremental = this.options.incremental; - - if ( incremental ) { - return typeof incremental === "function" ? - incremental( i ) : - Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 ); - } - - return 1; - }, - - _precision: function() { - var precision = this._precisionOf( this.options.step ); - if ( this.options.min !== null ) { - precision = Math.max( precision, this._precisionOf( this.options.min ) ); - } - return precision; - }, - - _precisionOf: function( num ) { - var str = num.toString(), - decimal = str.indexOf( "." ); - return decimal === -1 ? 0 : str.length - decimal - 1; - }, - - _adjustValue: function( value ) { - var base, aboveMin, - options = this.options; - - // Make sure we're at a valid step - // - find out where we are relative to the base (min or 0) - base = options.min !== null ? options.min : 0; - aboveMin = value - base; - - // - round to the nearest step - aboveMin = Math.round( aboveMin / options.step ) * options.step; - - // - rounding is based on 0, so adjust back to our base - value = base + aboveMin; - - // Fix precision from bad JS floating point math - value = parseFloat( value.toFixed( this._precision() ) ); - - // Clamp the value - if ( options.max !== null && value > options.max ) { - return options.max; - } - if ( options.min !== null && value < options.min ) { - return options.min; - } - - return value; - }, - - _stop: function( event ) { - if ( !this.spinning ) { - return; - } - - clearTimeout( this.timer ); - clearTimeout( this.mousewheelTimer ); - this.counter = 0; - this.spinning = false; - this._trigger( "stop", event ); - }, - - _setOption: function( key, value ) { - var prevValue, first, last; - - if ( key === "culture" || key === "numberFormat" ) { - prevValue = this._parse( this.element.val() ); - this.options[ key ] = value; - this.element.val( this._format( prevValue ) ); - return; - } - - if ( key === "max" || key === "min" || key === "step" ) { - if ( typeof value === "string" ) { - value = this._parse( value ); - } - } - if ( key === "icons" ) { - first = this.buttons.first().find( ".ui-icon" ); - this._removeClass( first, null, this.options.icons.up ); - this._addClass( first, null, value.up ); - last = this.buttons.last().find( ".ui-icon" ); - this._removeClass( last, null, this.options.icons.down ); - this._addClass( last, null, value.down ); - } - - this._super( key, value ); - }, - - _setOptionDisabled: function( value ) { - this._super( value ); - - this._toggleClass( this.uiSpinner, null, "ui-state-disabled", !!value ); - this.element.prop( "disabled", !!value ); - this.buttons.button( value ? "disable" : "enable" ); - }, - - _setOptions: spinnerModifier( function( options ) { - this._super( options ); - } ), - - _parse: function( val ) { - if ( typeof val === "string" && val !== "" ) { - val = window.Globalize && this.options.numberFormat ? - Globalize.parseFloat( val, 10, this.options.culture ) : +val; - } - return val === "" || isNaN( val ) ? null : val; - }, - - _format: function( value ) { - if ( value === "" ) { - return ""; - } - return window.Globalize && this.options.numberFormat ? - Globalize.format( value, this.options.numberFormat, this.options.culture ) : - value; - }, - - _refresh: function() { - this.element.attr( { - "aria-valuemin": this.options.min, - "aria-valuemax": this.options.max, - - // TODO: what should we do with values that can't be parsed? - "aria-valuenow": this._parse( this.element.val() ) - } ); - }, - - isValid: function() { - var value = this.value(); - - // Null is invalid - if ( value === null ) { - return false; - } - - // If value gets adjusted, it's invalid - return value === this._adjustValue( value ); - }, - - // Update the value without triggering change - _value: function( value, allowAny ) { - var parsed; - if ( value !== "" ) { - parsed = this._parse( value ); - if ( parsed !== null ) { - if ( !allowAny ) { - parsed = this._adjustValue( parsed ); - } - value = this._format( parsed ); - } - } - this.element.val( value ); - this._refresh(); - }, - - _destroy: function() { - this.element - .prop( "disabled", false ) - .removeAttr( "autocomplete role aria-valuemin aria-valuemax aria-valuenow" ); - - this.uiSpinner.replaceWith( this.element ); - }, - - stepUp: spinnerModifier( function( steps ) { - this._stepUp( steps ); - } ), - _stepUp: function( steps ) { - if ( this._start() ) { - this._spin( ( steps || 1 ) * this.options.step ); - this._stop(); - } - }, - - stepDown: spinnerModifier( function( steps ) { - this._stepDown( steps ); - } ), - _stepDown: function( steps ) { - if ( this._start() ) { - this._spin( ( steps || 1 ) * -this.options.step ); - this._stop(); - } - }, - - pageUp: spinnerModifier( function( pages ) { - this._stepUp( ( pages || 1 ) * this.options.page ); - } ), - - pageDown: spinnerModifier( function( pages ) { - this._stepDown( ( pages || 1 ) * this.options.page ); - } ), - - value: function( newVal ) { - if ( !arguments.length ) { - return this._parse( this.element.val() ); - } - spinnerModifier( this._value ).call( this, newVal ); - }, - - widget: function() { - return this.uiSpinner; - } -} ); + "use strict"; + + function spinnerModifier( fn ) { + return function() { + var previous = this.element.val(); + fn.apply( this, arguments ); + this._refresh(); + if ( previous !== this.element.val() ) { + this._trigger( "change" ); + } + }; + } + + $.widget( "ui.spinner", { + version: "1.13.2", + defaultElement: "<input>", + widgetEventPrefix: "spin", + options: { + classes: { + "ui-spinner": "ui-corner-all", + "ui-spinner-down": "ui-corner-br", + "ui-spinner-up": "ui-corner-tr" + }, + culture: null, + icons: { + down: "ui-icon-triangle-1-s", + up: "ui-icon-triangle-1-n" + }, + incremental: true, + max: null, + min: null, + numberFormat: null, + page: 10, + step: 1, + + change: null, + spin: null, + start: null, + stop: null + }, + + _create: function() { + + // handle string values that need to be parsed + this._setOption( "max", this.options.max ); + this._setOption( "min", this.options.min ); + this._setOption( "step", this.options.step ); + + // Only format if there is a value, prevents the field from being marked + // as invalid in Firefox, see #9573. + if ( this.value() !== "" ) { + + // Format the value, but don't constrain. + this._value( this.element.val(), true ); + } + + this._draw(); + this._on( this._events ); + this._refresh(); + + // Turning off autocomplete prevents the browser from remembering the + // value when navigating through history, so we re-enable autocomplete + // if the page is unloaded before the widget is destroyed. #7790 + this._on( this.window, { + beforeunload: function() { + this.element.removeAttr( "autocomplete" ); + } + } ); + }, + + _getCreateOptions: function() { + var options = this._super(); + var element = this.element; + + $.each( [ "min", "max", "step" ], function( i, option ) { + var value = element.attr( option ); + if ( value != null && value.length ) { + options[ option ] = value; + } + } ); + + return options; + }, + + _events: { + keydown: function( event ) { + if ( this._start( event ) && this._keydown( event ) ) { + event.preventDefault(); + } + }, + keyup: "_stop", + focus: function() { + this.previous = this.element.val(); + }, + blur: function( event ) { + if ( this.cancelBlur ) { + delete this.cancelBlur; + return; + } + + this._stop(); + this._refresh(); + if ( this.previous !== this.element.val() ) { + this._trigger( "change", event ); + } + }, + mousewheel: function( event, delta ) { + var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ); + var isActive = this.element[ 0 ] === activeElement; + + if ( !isActive || !delta ) { + return; + } + + if ( !this.spinning && !this._start( event ) ) { + return false; + } + + this._spin( ( delta > 0 ? 1 : -1 ) * this.options.step, event ); + clearTimeout( this.mousewheelTimer ); + this.mousewheelTimer = this._delay( function() { + if ( this.spinning ) { + this._stop( event ); + } + }, 100 ); + event.preventDefault(); + }, + "mousedown .ui-spinner-button": function( event ) { + var previous; + + // We never want the buttons to have focus; whenever the user is + // interacting with the spinner, the focus should be on the input. + // If the input is focused then this.previous is properly set from + // when the input first received focus. If the input is not focused + // then we need to set this.previous based on the value before spinning. + previous = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] ) ? + this.previous : this.element.val(); + function checkFocus() { + var isActive = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] ); + if ( !isActive ) { + this.element.trigger( "focus" ); + this.previous = previous; + + // support: IE + // IE sets focus asynchronously, so we need to check if focus + // moved off of the input because the user clicked on the button. + this._delay( function() { + this.previous = previous; + } ); + } + } + + // Ensure focus is on (or stays on) the text field + event.preventDefault(); + checkFocus.call( this ); + + // Support: IE + // IE doesn't prevent moving focus even with event.preventDefault() + // so we set a flag to know when we should ignore the blur event + // and check (again) if focus moved off of the input. + this.cancelBlur = true; + this._delay( function() { + delete this.cancelBlur; + checkFocus.call( this ); + } ); + + if ( this._start( event ) === false ) { + return; + } + + this._repeat( null, $( event.currentTarget ) + .hasClass( "ui-spinner-up" ) ? 1 : -1, event ); + }, + "mouseup .ui-spinner-button": "_stop", + "mouseenter .ui-spinner-button": function( event ) { + + // button will add ui-state-active if mouse was down while mouseleave and kept down + if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) { + return; + } + + if ( this._start( event ) === false ) { + return false; + } + this._repeat( null, $( event.currentTarget ) + .hasClass( "ui-spinner-up" ) ? 1 : -1, event ); + }, + + // TODO: do we really want to consider this a stop? + // shouldn't we just stop the repeater and wait until mouseup before + // we trigger the stop event? + "mouseleave .ui-spinner-button": "_stop" + }, + + // Support mobile enhanced option and make backcompat more sane + _enhance: function() { + this.uiSpinner = this.element + .attr( "autocomplete", "off" ) + .wrap( "<span>" ) + .parent() + + // Add buttons + .append( + "<a></a><a></a>" + ); + }, + + _draw: function() { + this._enhance(); + + this._addClass( this.uiSpinner, "ui-spinner", "ui-widget ui-widget-content" ); + this._addClass( "ui-spinner-input" ); + + this.element.attr( "role", "spinbutton" ); + + // Button bindings + this.buttons = this.uiSpinner.children( "a" ) + .attr( "tabIndex", -1 ) + .attr( "aria-hidden", true ) + .button( { + classes: { + "ui-button": "" + } + } ); + + // TODO: Right now button does not support classes this is already updated in button PR + this._removeClass( this.buttons, "ui-corner-all" ); + + this._addClass( this.buttons.first(), "ui-spinner-button ui-spinner-up" ); + this._addClass( this.buttons.last(), "ui-spinner-button ui-spinner-down" ); + this.buttons.first().button( { + "icon": this.options.icons.up, + "showLabel": false + } ); + this.buttons.last().button( { + "icon": this.options.icons.down, + "showLabel": false + } ); + + // IE 6 doesn't understand height: 50% for the buttons + // unless the wrapper has an explicit height + if ( this.buttons.height() > Math.ceil( this.uiSpinner.height() * 0.5 ) && + this.uiSpinner.height() > 0 ) { + this.uiSpinner.height( this.uiSpinner.height() ); + } + }, + + _keydown: function( event ) { + var options = this.options, + keyCode = $.ui.keyCode; + + switch ( event.keyCode ) { + case keyCode.UP: + this._repeat( null, 1, event ); + return true; + case keyCode.DOWN: + this._repeat( null, -1, event ); + return true; + case keyCode.PAGE_UP: + this._repeat( null, options.page, event ); + return true; + case keyCode.PAGE_DOWN: + this._repeat( null, -options.page, event ); + return true; + } + + return false; + }, + + _start: function( event ) { + if ( !this.spinning && this._trigger( "start", event ) === false ) { + return false; + } + + if ( !this.counter ) { + this.counter = 1; + } + this.spinning = true; + return true; + }, + + _repeat: function( i, steps, event ) { + i = i || 500; + + clearTimeout( this.timer ); + this.timer = this._delay( function() { + this._repeat( 40, steps, event ); + }, i ); + + this._spin( steps * this.options.step, event ); + }, + + _spin: function( step, event ) { + var value = this.value() || 0; + + if ( !this.counter ) { + this.counter = 1; + } + + value = this._adjustValue( value + step * this._increment( this.counter ) ); + + if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false ) { + this._value( value ); + this.counter++; + } + }, + + _increment: function( i ) { + var incremental = this.options.incremental; + + if ( incremental ) { + return typeof incremental === "function" ? + incremental( i ) : + Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 ); + } + + return 1; + }, + + _precision: function() { + var precision = this._precisionOf( this.options.step ); + if ( this.options.min !== null ) { + precision = Math.max( precision, this._precisionOf( this.options.min ) ); + } + return precision; + }, + + _precisionOf: function( num ) { + var str = num.toString(), + decimal = str.indexOf( "." ); + return decimal === -1 ? 0 : str.length - decimal - 1; + }, + + _adjustValue: function( value ) { + var base, aboveMin, + options = this.options; + + // Make sure we're at a valid step + // - find out where we are relative to the base (min or 0) + base = options.min !== null ? options.min : 0; + aboveMin = value - base; + + // - round to the nearest step + aboveMin = Math.round( aboveMin / options.step ) * options.step; + + // - rounding is based on 0, so adjust back to our base + value = base + aboveMin; + + // Fix precision from bad JS floating point math + value = parseFloat( value.toFixed( this._precision() ) ); + + // Clamp the value + if ( options.max !== null && value > options.max ) { + return options.max; + } + if ( options.min !== null && value < options.min ) { + return options.min; + } + + return value; + }, + + _stop: function( event ) { + if ( !this.spinning ) { + return; + } + + clearTimeout( this.timer ); + clearTimeout( this.mousewheelTimer ); + this.counter = 0; + this.spinning = false; + this._trigger( "stop", event ); + }, + + _setOption: function( key, value ) { + var prevValue, first, last; + + if ( key === "culture" || key === "numberFormat" ) { + prevValue = this._parse( this.element.val() ); + this.options[ key ] = value; + this.element.val( this._format( prevValue ) ); + return; + } + + if ( key === "max" || key === "min" || key === "step" ) { + if ( typeof value === "string" ) { + value = this._parse( value ); + } + } + if ( key === "icons" ) { + first = this.buttons.first().find( ".ui-icon" ); + this._removeClass( first, null, this.options.icons.up ); + this._addClass( first, null, value.up ); + last = this.buttons.last().find( ".ui-icon" ); + this._removeClass( last, null, this.options.icons.down ); + this._addClass( last, null, value.down ); + } + + this._super( key, value ); + }, + + _setOptionDisabled: function( value ) { + this._super( value ); + + this._toggleClass( this.uiSpinner, null, "ui-state-disabled", !!value ); + this.element.prop( "disabled", !!value ); + this.buttons.button( value ? "disable" : "enable" ); + }, + + _setOptions: spinnerModifier( function( options ) { + this._super( options ); + } ), + + _parse: function( val ) { + if ( typeof val === "string" && val !== "" ) { + val = window.Globalize && this.options.numberFormat ? + Globalize.parseFloat( val, 10, this.options.culture ) : +val; + } + return val === "" || isNaN( val ) ? null : val; + }, + + _format: function( value ) { + if ( value === "" ) { + return ""; + } + return window.Globalize && this.options.numberFormat ? + Globalize.format( value, this.options.numberFormat, this.options.culture ) : + value; + }, + + _refresh: function() { + this.element.attr( { + "aria-valuemin": this.options.min, + "aria-valuemax": this.options.max, + + // TODO: what should we do with values that can't be parsed? + "aria-valuenow": this._parse( this.element.val() ) + } ); + }, + + isValid: function() { + var value = this.value(); + + // Null is invalid + if ( value === null ) { + return false; + } + + // If value gets adjusted, it's invalid + return value === this._adjustValue( value ); + }, + + // Update the value without triggering change + _value: function( value, allowAny ) { + var parsed; + if ( value !== "" ) { + parsed = this._parse( value ); + if ( parsed !== null ) { + if ( !allowAny ) { + parsed = this._adjustValue( parsed ); + } + value = this._format( parsed ); + } + } + this.element.val( value ); + this._refresh(); + }, + + _destroy: function() { + this.element + .prop( "disabled", false ) + .removeAttr( "autocomplete role aria-valuemin aria-valuemax aria-valuenow" ); + + this.uiSpinner.replaceWith( this.element ); + }, + + stepUp: spinnerModifier( function( steps ) { + this._stepUp( steps ); + } ), + _stepUp: function( steps ) { + if ( this._start() ) { + this._spin( ( steps || 1 ) * this.options.step ); + this._stop(); + } + }, + + stepDown: spinnerModifier( function( steps ) { + this._stepDown( steps ); + } ), + _stepDown: function( steps ) { + if ( this._start() ) { + this._spin( ( steps || 1 ) * -this.options.step ); + this._stop(); + } + }, + + pageUp: spinnerModifier( function( pages ) { + this._stepUp( ( pages || 1 ) * this.options.page ); + } ), + + pageDown: spinnerModifier( function( pages ) { + this._stepDown( ( pages || 1 ) * this.options.page ); + } ), + + value: function( newVal ) { + if ( !arguments.length ) { + return this._parse( this.element.val() ); + } + spinnerModifier( this._value ).call( this, newVal ); + }, + + widget: function() { + return this.uiSpinner; + } + } ); // DEPRECATED // TODO: switch return back to widget declaration at top of file when this is removed -if ( $.uiBackCompat !== false ) { - - // Backcompat for spinner html extension points - $.widget( "ui.spinner", $.ui.spinner, { - _enhance: function() { - this.uiSpinner = this.element - .attr( "autocomplete", "off" ) - .wrap( this._uiSpinnerHtml() ) - .parent() - - // Add buttons - .append( this._buttonHtml() ); - }, - _uiSpinnerHtml: function() { - return "<span>"; - }, - - _buttonHtml: function() { - return "<a></a><a></a>"; - } - } ); -} - -return $.ui.spinner; + if ( $.uiBackCompat !== false ) { + + // Backcompat for spinner html extension points + $.widget( "ui.spinner", $.ui.spinner, { + _enhance: function() { + this.uiSpinner = this.element + .attr( "autocomplete", "off" ) + .wrap( this._uiSpinnerHtml() ) + .parent() + + // Add buttons + .append( this._buttonHtml() ); + }, + _uiSpinnerHtml: function() { + return "<span>"; + }, + + _buttonHtml: function() { + return "<a></a><a></a>"; + } + } ); + } + + return $.ui.spinner; } ); diff --git a/lib/web/jquery/ui-modules/widgets/tabs.js b/lib/web/jquery/ui-modules/widgets/tabs.js index a4a552d5ef2fe..b6e9c40454409 100644 --- a/lib/web/jquery/ui-modules/widgets/tabs.js +++ b/lib/web/jquery/ui-modules/widgets/tabs.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Tabs 1.13.1 + * jQuery UI Tabs 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -17,909 +17,909 @@ //>>css.theme: ../../themes/base/theme.css ( function( factory ) { - "use strict"; - - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define( [ - "jquery", - "../keycode", - "../safe-active-element", - "../unique-id", - "../version", - "../widget" - ], factory ); - } else { - - // Browser globals - factory( jQuery ); - } + "use strict"; + + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ + "jquery", + "../keycode", + "../safe-active-element", + "../unique-id", + "../version", + "../widget" + ], factory ); + } else { + + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; - -$.widget( "ui.tabs", { - version: "1.13.1", - delay: 300, - options: { - active: null, - classes: { - "ui-tabs": "ui-corner-all", - "ui-tabs-nav": "ui-corner-all", - "ui-tabs-panel": "ui-corner-bottom", - "ui-tabs-tab": "ui-corner-top" - }, - collapsible: false, - event: "click", - heightStyle: "content", - hide: null, - show: null, - - // Callbacks - activate: null, - beforeActivate: null, - beforeLoad: null, - load: null - }, - - _isLocal: ( function() { - var rhash = /#.*$/; - - return function( anchor ) { - var anchorUrl, locationUrl; - - anchorUrl = anchor.href.replace( rhash, "" ); - locationUrl = location.href.replace( rhash, "" ); - - // Decoding may throw an error if the URL isn't UTF-8 (#9518) - try { - anchorUrl = decodeURIComponent( anchorUrl ); - } catch ( error ) {} - try { - locationUrl = decodeURIComponent( locationUrl ); - } catch ( error ) {} - - return anchor.hash.length > 1 && anchorUrl === locationUrl; - }; - } )(), - - _create: function() { - var that = this, - options = this.options; - - this.running = false; - - this._addClass( "ui-tabs", "ui-widget ui-widget-content" ); - this._toggleClass( "ui-tabs-collapsible", null, options.collapsible ); - - this._processTabs(); - options.active = this._initialActive(); - - // Take disabling tabs via class attribute from HTML - // into account and update option properly. - if ( Array.isArray( options.disabled ) ) { - options.disabled = $.uniqueSort( options.disabled.concat( - $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) { - return that.tabs.index( li ); - } ) - ) ).sort(); - } - - // Check for length avoids error when initializing empty list - if ( this.options.active !== false && this.anchors.length ) { - this.active = this._findActive( options.active ); - } else { - this.active = $(); - } - - this._refresh(); - - if ( this.active.length ) { - this.load( options.active ); - } - }, - - _initialActive: function() { - var active = this.options.active, - collapsible = this.options.collapsible, - locationHash = location.hash.substring( 1 ); - - if ( active === null ) { - - // check the fragment identifier in the URL - if ( locationHash ) { - this.tabs.each( function( i, tab ) { - if ( $( tab ).attr( "aria-controls" ) === locationHash ) { - active = i; - return false; - } - } ); - } - - // Check for a tab marked active via a class - if ( active === null ) { - active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) ); - } - - // No active tab, set to false - if ( active === null || active === -1 ) { - active = this.tabs.length ? 0 : false; - } - } - - // Handle numbers: negative, out of range - if ( active !== false ) { - active = this.tabs.index( this.tabs.eq( active ) ); - if ( active === -1 ) { - active = collapsible ? false : 0; - } - } - - // Don't allow collapsible: false and active: false - if ( !collapsible && active === false && this.anchors.length ) { - active = 0; - } - - return active; - }, - - _getCreateEventData: function() { - return { - tab: this.active, - panel: !this.active.length ? $() : this._getPanelForTab( this.active ) - }; - }, - - _tabKeydown: function( event ) { - var focusedTab = $( $.ui.safeActiveElement( this.document[ 0 ] ) ).closest( "li" ), - selectedIndex = this.tabs.index( focusedTab ), - goingForward = true; - - if ( this._handlePageNav( event ) ) { - return; - } - - switch ( event.keyCode ) { - case $.ui.keyCode.RIGHT: - case $.ui.keyCode.DOWN: - selectedIndex++; - break; - case $.ui.keyCode.UP: - case $.ui.keyCode.LEFT: - goingForward = false; - selectedIndex--; - break; - case $.ui.keyCode.END: - selectedIndex = this.anchors.length - 1; - break; - case $.ui.keyCode.HOME: - selectedIndex = 0; - break; - case $.ui.keyCode.SPACE: - - // Activate only, no collapsing - event.preventDefault(); - clearTimeout( this.activating ); - this._activate( selectedIndex ); - return; - case $.ui.keyCode.ENTER: - - // Toggle (cancel delayed activation, allow collapsing) - event.preventDefault(); - clearTimeout( this.activating ); - - // Determine if we should collapse or activate - this._activate( selectedIndex === this.options.active ? false : selectedIndex ); - return; - default: - return; - } - - // Focus the appropriate tab, based on which key was pressed - event.preventDefault(); - clearTimeout( this.activating ); - selectedIndex = this._focusNextTab( selectedIndex, goingForward ); - - // Navigating with control/command key will prevent automatic activation - if ( !event.ctrlKey && !event.metaKey ) { - - // Update aria-selected immediately so that AT think the tab is already selected. - // Otherwise AT may confuse the user by stating that they need to activate the tab, - // but the tab will already be activated by the time the announcement finishes. - focusedTab.attr( "aria-selected", "false" ); - this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" ); - - this.activating = this._delay( function() { - this.option( "active", selectedIndex ); - }, this.delay ); - } - }, - - _panelKeydown: function( event ) { - if ( this._handlePageNav( event ) ) { - return; - } - - // Ctrl+up moves focus to the current tab - if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) { - event.preventDefault(); - this.active.trigger( "focus" ); - } - }, - - // Alt+page up/down moves focus to the previous/next tab (and activates) - _handlePageNav: function( event ) { - if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) { - this._activate( this._focusNextTab( this.options.active - 1, false ) ); - return true; - } - if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) { - this._activate( this._focusNextTab( this.options.active + 1, true ) ); - return true; - } - }, - - _findNextTab: function( index, goingForward ) { - var lastTabIndex = this.tabs.length - 1; - - function constrain() { - if ( index > lastTabIndex ) { - index = 0; - } - if ( index < 0 ) { - index = lastTabIndex; - } - return index; - } - - while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) { - index = goingForward ? index + 1 : index - 1; - } - - return index; - }, - - _focusNextTab: function( index, goingForward ) { - index = this._findNextTab( index, goingForward ); - this.tabs.eq( index ).trigger( "focus" ); - return index; - }, - - _setOption: function( key, value ) { - if ( key === "active" ) { - - // _activate() will handle invalid values and update this.options - this._activate( value ); - return; - } - - this._super( key, value ); - - if ( key === "collapsible" ) { - this._toggleClass( "ui-tabs-collapsible", null, value ); - - // Setting collapsible: false while collapsed; open first panel - if ( !value && this.options.active === false ) { - this._activate( 0 ); - } - } - - if ( key === "event" ) { - this._setupEvents( value ); - } - - if ( key === "heightStyle" ) { - this._setupHeightStyle( value ); - } - }, - - _sanitizeSelector: function( hash ) { - return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : ""; - }, - - refresh: function() { - var options = this.options, - lis = this.tablist.children( ":has(a[href])" ); - - // Get disabled tabs from class attribute from HTML - // this will get converted to a boolean if needed in _refresh() - options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) { - return lis.index( tab ); - } ); - - this._processTabs(); - - // Was collapsed or no tabs - if ( options.active === false || !this.anchors.length ) { - options.active = false; - this.active = $(); - - // was active, but active tab is gone - } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) { - - // all remaining tabs are disabled - if ( this.tabs.length === options.disabled.length ) { - options.active = false; - this.active = $(); - - // activate previous tab - } else { - this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) ); - } - - // was active, active tab still exists - } else { - - // make sure active index is correct - options.active = this.tabs.index( this.active ); - } - - this._refresh(); - }, - - _refresh: function() { - this._setOptionDisabled( this.options.disabled ); - this._setupEvents( this.options.event ); - this._setupHeightStyle( this.options.heightStyle ); - - this.tabs.not( this.active ).attr( { - "aria-selected": "false", - "aria-expanded": "false", - tabIndex: -1 - } ); - this.panels.not( this._getPanelForTab( this.active ) ) - .hide() - .attr( { - "aria-hidden": "true" - } ); - - // Make sure one tab is in the tab order - if ( !this.active.length ) { - this.tabs.eq( 0 ).attr( "tabIndex", 0 ); - } else { - this.active - .attr( { - "aria-selected": "true", - "aria-expanded": "true", - tabIndex: 0 - } ); - this._addClass( this.active, "ui-tabs-active", "ui-state-active" ); - this._getPanelForTab( this.active ) - .show() - .attr( { - "aria-hidden": "false" - } ); - } - }, - - _processTabs: function() { - var that = this, - prevTabs = this.tabs, - prevAnchors = this.anchors, - prevPanels = this.panels; - - this.tablist = this._getList().attr( "role", "tablist" ); - this._addClass( this.tablist, "ui-tabs-nav", - "ui-helper-reset ui-helper-clearfix ui-widget-header" ); - - // Prevent users from focusing disabled tabs via click - this.tablist - .on( "mousedown" + this.eventNamespace, "> li", function( event ) { - if ( $( this ).is( ".ui-state-disabled" ) ) { - event.preventDefault(); - } - } ) - - // Support: IE <9 - // Preventing the default action in mousedown doesn't prevent IE - // from focusing the element, so if the anchor gets focused, blur. - // We don't have to worry about focusing the previously focused - // element since clicking on a non-focusable element should focus - // the body anyway. - .on( "focus" + this.eventNamespace, ".ui-tabs-anchor", function() { - if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) { - this.blur(); - } - } ); - - this.tabs = this.tablist.find( "> li:has(a[href])" ) - .attr( { - role: "tab", - tabIndex: -1 - } ); - this._addClass( this.tabs, "ui-tabs-tab", "ui-state-default" ); - - this.anchors = this.tabs.map( function() { - return $( "a", this )[ 0 ]; - } ) - .attr( { - tabIndex: -1 - } ); - this._addClass( this.anchors, "ui-tabs-anchor" ); - - this.panels = $(); - - this.anchors.each( function( i, anchor ) { - var selector, panel, panelId, - anchorId = $( anchor ).uniqueId().attr( "id" ), - tab = $( anchor ).closest( "li" ), - originalAriaControls = tab.attr( "aria-controls" ); - - // Inline tab - if ( that._isLocal( anchor ) ) { - selector = anchor.hash; - panelId = selector.substring( 1 ); - panel = that.element.find( that._sanitizeSelector( selector ) ); - - // remote tab - } else { - - // If the tab doesn't already have aria-controls, - // generate an id by using a throw-away element - panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id; - selector = "#" + panelId; - panel = that.element.find( selector ); - if ( !panel.length ) { - panel = that._createPanel( panelId ); - panel.insertAfter( that.panels[ i - 1 ] || that.tablist ); - } - panel.attr( "aria-live", "polite" ); - } - - if ( panel.length ) { - that.panels = that.panels.add( panel ); - } - if ( originalAriaControls ) { - tab.data( "ui-tabs-aria-controls", originalAriaControls ); - } - tab.attr( { - "aria-controls": panelId, - "aria-labelledby": anchorId - } ); - panel.attr( "aria-labelledby", anchorId ); - } ); - - this.panels.attr( "role", "tabpanel" ); - this._addClass( this.panels, "ui-tabs-panel", "ui-widget-content" ); - - // Avoid memory leaks (#10056) - if ( prevTabs ) { - this._off( prevTabs.not( this.tabs ) ); - this._off( prevAnchors.not( this.anchors ) ); - this._off( prevPanels.not( this.panels ) ); - } - }, - - // Allow overriding how to find the list for rare usage scenarios (#7715) - _getList: function() { - return this.tablist || this.element.find( "ol, ul" ).eq( 0 ); - }, - - _createPanel: function( id ) { - return $( "<div>" ) - .attr( "id", id ) - .data( "ui-tabs-destroy", true ); - }, - - _setOptionDisabled: function( disabled ) { - var currentItem, li, i; - - if ( Array.isArray( disabled ) ) { - if ( !disabled.length ) { - disabled = false; - } else if ( disabled.length === this.anchors.length ) { - disabled = true; - } - } - - // Disable tabs - for ( i = 0; ( li = this.tabs[ i ] ); i++ ) { - currentItem = $( li ); - if ( disabled === true || $.inArray( i, disabled ) !== -1 ) { - currentItem.attr( "aria-disabled", "true" ); - this._addClass( currentItem, null, "ui-state-disabled" ); - } else { - currentItem.removeAttr( "aria-disabled" ); - this._removeClass( currentItem, null, "ui-state-disabled" ); - } - } - - this.options.disabled = disabled; - - this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, - disabled === true ); - }, - - _setupEvents: function( event ) { - var events = {}; - if ( event ) { - $.each( event.split( " " ), function( index, eventName ) { - events[ eventName ] = "_eventHandler"; - } ); - } - - this._off( this.anchors.add( this.tabs ).add( this.panels ) ); - - // Always prevent the default action, even when disabled - this._on( true, this.anchors, { - click: function( event ) { - event.preventDefault(); - } - } ); - this._on( this.anchors, events ); - this._on( this.tabs, { keydown: "_tabKeydown" } ); - this._on( this.panels, { keydown: "_panelKeydown" } ); - - this._focusable( this.tabs ); - this._hoverable( this.tabs ); - }, - - _setupHeightStyle: function( heightStyle ) { - var maxHeight, - parent = this.element.parent(); - - if ( heightStyle === "fill" ) { - maxHeight = parent.height(); - maxHeight -= this.element.outerHeight() - this.element.height(); - - this.element.siblings( ":visible" ).each( function() { - var elem = $( this ), - position = elem.css( "position" ); - - if ( position === "absolute" || position === "fixed" ) { - return; - } - maxHeight -= elem.outerHeight( true ); - } ); - - this.element.children().not( this.panels ).each( function() { - maxHeight -= $( this ).outerHeight( true ); - } ); - - this.panels.each( function() { - $( this ).height( Math.max( 0, maxHeight - - $( this ).innerHeight() + $( this ).height() ) ); - } ) - .css( "overflow", "auto" ); - } else if ( heightStyle === "auto" ) { - maxHeight = 0; - this.panels.each( function() { - maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); - } ).height( maxHeight ); - } - }, - - _eventHandler: function( event ) { - var options = this.options, - active = this.active, - anchor = $( event.currentTarget ), - tab = anchor.closest( "li" ), - clickedIsActive = tab[ 0 ] === active[ 0 ], - collapsing = clickedIsActive && options.collapsible, - toShow = collapsing ? $() : this._getPanelForTab( tab ), - toHide = !active.length ? $() : this._getPanelForTab( active ), - eventData = { - oldTab: active, - oldPanel: toHide, - newTab: collapsing ? $() : tab, - newPanel: toShow - }; - - event.preventDefault(); - - if ( tab.hasClass( "ui-state-disabled" ) || - - // tab is already loading - tab.hasClass( "ui-tabs-loading" ) || - - // can't switch durning an animation - this.running || - - // click on active header, but not collapsible - ( clickedIsActive && !options.collapsible ) || - - // allow canceling activation - ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { - return; - } - - options.active = collapsing ? false : this.tabs.index( tab ); - - this.active = clickedIsActive ? $() : tab; - if ( this.xhr ) { - this.xhr.abort(); - } - - if ( !toHide.length && !toShow.length ) { - $.error( "jQuery UI Tabs: Mismatching fragment identifier." ); - } - - if ( toShow.length ) { - this.load( this.tabs.index( tab ), event ); - } - this._toggle( event, eventData ); - }, - - // Handles show/hide for selecting tabs - _toggle: function( event, eventData ) { - var that = this, - toShow = eventData.newPanel, - toHide = eventData.oldPanel; - - this.running = true; - - function complete() { - that.running = false; - that._trigger( "activate", event, eventData ); - } - - function show() { - that._addClass( eventData.newTab.closest( "li" ), "ui-tabs-active", "ui-state-active" ); - - if ( toShow.length && that.options.show ) { - that._show( toShow, that.options.show, complete ); - } else { - toShow.show(); - complete(); - } - } - - // Start out by hiding, then showing, then completing - if ( toHide.length && this.options.hide ) { - this._hide( toHide, this.options.hide, function() { - that._removeClass( eventData.oldTab.closest( "li" ), - "ui-tabs-active", "ui-state-active" ); - show(); - } ); - } else { - this._removeClass( eventData.oldTab.closest( "li" ), - "ui-tabs-active", "ui-state-active" ); - toHide.hide(); - show(); - } - - toHide.attr( "aria-hidden", "true" ); - eventData.oldTab.attr( { - "aria-selected": "false", - "aria-expanded": "false" - } ); - - // If we're switching tabs, remove the old tab from the tab order. - // If we're opening from collapsed state, remove the previous tab from the tab order. - // If we're collapsing, then keep the collapsing tab in the tab order. - if ( toShow.length && toHide.length ) { - eventData.oldTab.attr( "tabIndex", -1 ); - } else if ( toShow.length ) { - this.tabs.filter( function() { - return $( this ).attr( "tabIndex" ) === 0; - } ) - .attr( "tabIndex", -1 ); - } - - toShow.attr( "aria-hidden", "false" ); - eventData.newTab.attr( { - "aria-selected": "true", - "aria-expanded": "true", - tabIndex: 0 - } ); - }, - - _activate: function( index ) { - var anchor, - active = this._findActive( index ); - - // Trying to activate the already active panel - if ( active[ 0 ] === this.active[ 0 ] ) { - return; - } - - // Trying to collapse, simulate a click on the current active header - if ( !active.length ) { - active = this.active; - } - - anchor = active.find( ".ui-tabs-anchor" )[ 0 ]; - this._eventHandler( { - target: anchor, - currentTarget: anchor, - preventDefault: $.noop - } ); - }, - - _findActive: function( index ) { - return index === false ? $() : this.tabs.eq( index ); - }, - - _getIndex: function( index ) { - - // meta-function to give users option to provide a href string instead of a numerical index. - if ( typeof index === "string" ) { - index = this.anchors.index( this.anchors.filter( "[href$='" + - $.escapeSelector( index ) + "']" ) ); - } - - return index; - }, - - _destroy: function() { - if ( this.xhr ) { - this.xhr.abort(); - } - - this.tablist - .removeAttr( "role" ) - .off( this.eventNamespace ); - - this.anchors - .removeAttr( "role tabIndex" ) - .removeUniqueId(); - - this.tabs.add( this.panels ).each( function() { - if ( $.data( this, "ui-tabs-destroy" ) ) { - $( this ).remove(); - } else { - $( this ).removeAttr( "role tabIndex " + - "aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded" ); - } - } ); - - this.tabs.each( function() { - var li = $( this ), - prev = li.data( "ui-tabs-aria-controls" ); - if ( prev ) { - li - .attr( "aria-controls", prev ) - .removeData( "ui-tabs-aria-controls" ); - } else { - li.removeAttr( "aria-controls" ); - } - } ); - - this.panels.show(); - - if ( this.options.heightStyle !== "content" ) { - this.panels.css( "height", "" ); - } - }, - - enable: function( index ) { - var disabled = this.options.disabled; - if ( disabled === false ) { - return; - } - - if ( index === undefined ) { - disabled = false; - } else { - index = this._getIndex( index ); - if ( Array.isArray( disabled ) ) { - disabled = $.map( disabled, function( num ) { - return num !== index ? num : null; - } ); - } else { - disabled = $.map( this.tabs, function( li, num ) { - return num !== index ? num : null; - } ); - } - } - this._setOptionDisabled( disabled ); - }, - - disable: function( index ) { - var disabled = this.options.disabled; - if ( disabled === true ) { - return; - } - - if ( index === undefined ) { - disabled = true; - } else { - index = this._getIndex( index ); - if ( $.inArray( index, disabled ) !== -1 ) { - return; - } - if ( Array.isArray( disabled ) ) { - disabled = $.merge( [ index ], disabled ).sort(); - } else { - disabled = [ index ]; - } - } - this._setOptionDisabled( disabled ); - }, - - load: function( index, event ) { - index = this._getIndex( index ); - var that = this, - tab = this.tabs.eq( index ), - anchor = tab.find( ".ui-tabs-anchor" ), - panel = this._getPanelForTab( tab ), - eventData = { - tab: tab, - panel: panel - }, - complete = function( jqXHR, status ) { - if ( status === "abort" ) { - that.panels.stop( false, true ); - } - - that._removeClass( tab, "ui-tabs-loading" ); - panel.removeAttr( "aria-busy" ); - - if ( jqXHR === that.xhr ) { - delete that.xhr; - } - }; - - // Not remote - if ( this._isLocal( anchor[ 0 ] ) ) { - return; - } - - this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) ); - - // Support: jQuery <1.8 - // jQuery <1.8 returns false if the request is canceled in beforeSend, - // but as of 1.8, $.ajax() always returns a jqXHR object. - if ( this.xhr && this.xhr.statusText !== "canceled" ) { - this._addClass( tab, "ui-tabs-loading" ); - panel.attr( "aria-busy", "true" ); - - this.xhr - .done( function( response, status, jqXHR ) { - - // support: jQuery <1.8 - // http://bugs.jquery.com/ticket/11778 - setTimeout( function() { - panel.html( response ); - that._trigger( "load", event, eventData ); - - complete( jqXHR, status ); - }, 1 ); - } ) - .fail( function( jqXHR, status ) { - - // support: jQuery <1.8 - // http://bugs.jquery.com/ticket/11778 - setTimeout( function() { - complete( jqXHR, status ); - }, 1 ); - } ); - } - }, - - _ajaxSettings: function( anchor, event, eventData ) { - var that = this; - return { - - // Support: IE <11 only - // Strip any hash that exists to prevent errors with the Ajax request - url: anchor.attr( "href" ).replace( /#.*$/, "" ), - beforeSend: function( jqXHR, settings ) { - return that._trigger( "beforeLoad", event, - $.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) ); - } - }; - }, - - _getPanelForTab: function( tab ) { - var id = $( tab ).attr( "aria-controls" ); - return this.element.find( this._sanitizeSelector( "#" + id ) ); - } -} ); + "use strict"; + + $.widget( "ui.tabs", { + version: "1.13.2", + delay: 300, + options: { + active: null, + classes: { + "ui-tabs": "ui-corner-all", + "ui-tabs-nav": "ui-corner-all", + "ui-tabs-panel": "ui-corner-bottom", + "ui-tabs-tab": "ui-corner-top" + }, + collapsible: false, + event: "click", + heightStyle: "content", + hide: null, + show: null, + + // Callbacks + activate: null, + beforeActivate: null, + beforeLoad: null, + load: null + }, + + _isLocal: ( function() { + var rhash = /#.*$/; + + return function( anchor ) { + var anchorUrl, locationUrl; + + anchorUrl = anchor.href.replace( rhash, "" ); + locationUrl = location.href.replace( rhash, "" ); + + // Decoding may throw an error if the URL isn't UTF-8 (#9518) + try { + anchorUrl = decodeURIComponent( anchorUrl ); + } catch ( error ) {} + try { + locationUrl = decodeURIComponent( locationUrl ); + } catch ( error ) {} + + return anchor.hash.length > 1 && anchorUrl === locationUrl; + }; + } )(), + + _create: function() { + var that = this, + options = this.options; + + this.running = false; + + this._addClass( "ui-tabs", "ui-widget ui-widget-content" ); + this._toggleClass( "ui-tabs-collapsible", null, options.collapsible ); + + this._processTabs(); + options.active = this._initialActive(); + + // Take disabling tabs via class attribute from HTML + // into account and update option properly. + if ( Array.isArray( options.disabled ) ) { + options.disabled = $.uniqueSort( options.disabled.concat( + $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) { + return that.tabs.index( li ); + } ) + ) ).sort(); + } + + // Check for length avoids error when initializing empty list + if ( this.options.active !== false && this.anchors.length ) { + this.active = this._findActive( options.active ); + } else { + this.active = $(); + } + + this._refresh(); + + if ( this.active.length ) { + this.load( options.active ); + } + }, + + _initialActive: function() { + var active = this.options.active, + collapsible = this.options.collapsible, + locationHash = location.hash.substring( 1 ); + + if ( active === null ) { + + // check the fragment identifier in the URL + if ( locationHash ) { + this.tabs.each( function( i, tab ) { + if ( $( tab ).attr( "aria-controls" ) === locationHash ) { + active = i; + return false; + } + } ); + } + + // Check for a tab marked active via a class + if ( active === null ) { + active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) ); + } + + // No active tab, set to false + if ( active === null || active === -1 ) { + active = this.tabs.length ? 0 : false; + } + } + + // Handle numbers: negative, out of range + if ( active !== false ) { + active = this.tabs.index( this.tabs.eq( active ) ); + if ( active === -1 ) { + active = collapsible ? false : 0; + } + } + + // Don't allow collapsible: false and active: false + if ( !collapsible && active === false && this.anchors.length ) { + active = 0; + } + + return active; + }, + + _getCreateEventData: function() { + return { + tab: this.active, + panel: !this.active.length ? $() : this._getPanelForTab( this.active ) + }; + }, + + _tabKeydown: function( event ) { + var focusedTab = $( $.ui.safeActiveElement( this.document[ 0 ] ) ).closest( "li" ), + selectedIndex = this.tabs.index( focusedTab ), + goingForward = true; + + if ( this._handlePageNav( event ) ) { + return; + } + + switch ( event.keyCode ) { + case $.ui.keyCode.RIGHT: + case $.ui.keyCode.DOWN: + selectedIndex++; + break; + case $.ui.keyCode.UP: + case $.ui.keyCode.LEFT: + goingForward = false; + selectedIndex--; + break; + case $.ui.keyCode.END: + selectedIndex = this.anchors.length - 1; + break; + case $.ui.keyCode.HOME: + selectedIndex = 0; + break; + case $.ui.keyCode.SPACE: + + // Activate only, no collapsing + event.preventDefault(); + clearTimeout( this.activating ); + this._activate( selectedIndex ); + return; + case $.ui.keyCode.ENTER: + + // Toggle (cancel delayed activation, allow collapsing) + event.preventDefault(); + clearTimeout( this.activating ); + + // Determine if we should collapse or activate + this._activate( selectedIndex === this.options.active ? false : selectedIndex ); + return; + default: + return; + } + + // Focus the appropriate tab, based on which key was pressed + event.preventDefault(); + clearTimeout( this.activating ); + selectedIndex = this._focusNextTab( selectedIndex, goingForward ); + + // Navigating with control/command key will prevent automatic activation + if ( !event.ctrlKey && !event.metaKey ) { + + // Update aria-selected immediately so that AT think the tab is already selected. + // Otherwise AT may confuse the user by stating that they need to activate the tab, + // but the tab will already be activated by the time the announcement finishes. + focusedTab.attr( "aria-selected", "false" ); + this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" ); + + this.activating = this._delay( function() { + this.option( "active", selectedIndex ); + }, this.delay ); + } + }, + + _panelKeydown: function( event ) { + if ( this._handlePageNav( event ) ) { + return; + } + + // Ctrl+up moves focus to the current tab + if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) { + event.preventDefault(); + this.active.trigger( "focus" ); + } + }, + + // Alt+page up/down moves focus to the previous/next tab (and activates) + _handlePageNav: function( event ) { + if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) { + this._activate( this._focusNextTab( this.options.active - 1, false ) ); + return true; + } + if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) { + this._activate( this._focusNextTab( this.options.active + 1, true ) ); + return true; + } + }, + + _findNextTab: function( index, goingForward ) { + var lastTabIndex = this.tabs.length - 1; + + function constrain() { + if ( index > lastTabIndex ) { + index = 0; + } + if ( index < 0 ) { + index = lastTabIndex; + } + return index; + } + + while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) { + index = goingForward ? index + 1 : index - 1; + } + + return index; + }, + + _focusNextTab: function( index, goingForward ) { + index = this._findNextTab( index, goingForward ); + this.tabs.eq( index ).trigger( "focus" ); + return index; + }, + + _setOption: function( key, value ) { + if ( key === "active" ) { + + // _activate() will handle invalid values and update this.options + this._activate( value ); + return; + } + + this._super( key, value ); + + if ( key === "collapsible" ) { + this._toggleClass( "ui-tabs-collapsible", null, value ); + + // Setting collapsible: false while collapsed; open first panel + if ( !value && this.options.active === false ) { + this._activate( 0 ); + } + } + + if ( key === "event" ) { + this._setupEvents( value ); + } + + if ( key === "heightStyle" ) { + this._setupHeightStyle( value ); + } + }, + + _sanitizeSelector: function( hash ) { + return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : ""; + }, + + refresh: function() { + var options = this.options, + lis = this.tablist.children( ":has(a[href])" ); + + // Get disabled tabs from class attribute from HTML + // this will get converted to a boolean if needed in _refresh() + options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) { + return lis.index( tab ); + } ); + + this._processTabs(); + + // Was collapsed or no tabs + if ( options.active === false || !this.anchors.length ) { + options.active = false; + this.active = $(); + + // was active, but active tab is gone + } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) { + + // all remaining tabs are disabled + if ( this.tabs.length === options.disabled.length ) { + options.active = false; + this.active = $(); + + // activate previous tab + } else { + this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) ); + } + + // was active, active tab still exists + } else { + + // make sure active index is correct + options.active = this.tabs.index( this.active ); + } + + this._refresh(); + }, + + _refresh: function() { + this._setOptionDisabled( this.options.disabled ); + this._setupEvents( this.options.event ); + this._setupHeightStyle( this.options.heightStyle ); + + this.tabs.not( this.active ).attr( { + "aria-selected": "false", + "aria-expanded": "false", + tabIndex: -1 + } ); + this.panels.not( this._getPanelForTab( this.active ) ) + .hide() + .attr( { + "aria-hidden": "true" + } ); + + // Make sure one tab is in the tab order + if ( !this.active.length ) { + this.tabs.eq( 0 ).attr( "tabIndex", 0 ); + } else { + this.active + .attr( { + "aria-selected": "true", + "aria-expanded": "true", + tabIndex: 0 + } ); + this._addClass( this.active, "ui-tabs-active", "ui-state-active" ); + this._getPanelForTab( this.active ) + .show() + .attr( { + "aria-hidden": "false" + } ); + } + }, + + _processTabs: function() { + var that = this, + prevTabs = this.tabs, + prevAnchors = this.anchors, + prevPanels = this.panels; + + this.tablist = this._getList().attr( "role", "tablist" ); + this._addClass( this.tablist, "ui-tabs-nav", + "ui-helper-reset ui-helper-clearfix ui-widget-header" ); + + // Prevent users from focusing disabled tabs via click + this.tablist + .on( "mousedown" + this.eventNamespace, "> li", function( event ) { + if ( $( this ).is( ".ui-state-disabled" ) ) { + event.preventDefault(); + } + } ) + + // Support: IE <9 + // Preventing the default action in mousedown doesn't prevent IE + // from focusing the element, so if the anchor gets focused, blur. + // We don't have to worry about focusing the previously focused + // element since clicking on a non-focusable element should focus + // the body anyway. + .on( "focus" + this.eventNamespace, ".ui-tabs-anchor", function() { + if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) { + this.blur(); + } + } ); + + this.tabs = this.tablist.find( "> li:has(a[href])" ) + .attr( { + role: "tab", + tabIndex: -1 + } ); + this._addClass( this.tabs, "ui-tabs-tab", "ui-state-default" ); + + this.anchors = this.tabs.map( function() { + return $( "a", this )[ 0 ]; + } ) + .attr( { + tabIndex: -1 + } ); + this._addClass( this.anchors, "ui-tabs-anchor" ); + + this.panels = $(); + + this.anchors.each( function( i, anchor ) { + var selector, panel, panelId, + anchorId = $( anchor ).uniqueId().attr( "id" ), + tab = $( anchor ).closest( "li" ), + originalAriaControls = tab.attr( "aria-controls" ); + + // Inline tab + if ( that._isLocal( anchor ) ) { + selector = anchor.hash; + panelId = selector.substring( 1 ); + panel = that.element.find( that._sanitizeSelector( selector ) ); + + // remote tab + } else { + + // If the tab doesn't already have aria-controls, + // generate an id by using a throw-away element + panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id; + selector = "#" + panelId; + panel = that.element.find( selector ); + if ( !panel.length ) { + panel = that._createPanel( panelId ); + panel.insertAfter( that.panels[ i - 1 ] || that.tablist ); + } + panel.attr( "aria-live", "polite" ); + } + + if ( panel.length ) { + that.panels = that.panels.add( panel ); + } + if ( originalAriaControls ) { + tab.data( "ui-tabs-aria-controls", originalAriaControls ); + } + tab.attr( { + "aria-controls": panelId, + "aria-labelledby": anchorId + } ); + panel.attr( "aria-labelledby", anchorId ); + } ); + + this.panels.attr( "role", "tabpanel" ); + this._addClass( this.panels, "ui-tabs-panel", "ui-widget-content" ); + + // Avoid memory leaks (#10056) + if ( prevTabs ) { + this._off( prevTabs.not( this.tabs ) ); + this._off( prevAnchors.not( this.anchors ) ); + this._off( prevPanels.not( this.panels ) ); + } + }, + + // Allow overriding how to find the list for rare usage scenarios (#7715) + _getList: function() { + return this.tablist || this.element.find( "ol, ul" ).eq( 0 ); + }, + + _createPanel: function( id ) { + return $( "<div>" ) + .attr( "id", id ) + .data( "ui-tabs-destroy", true ); + }, + + _setOptionDisabled: function( disabled ) { + var currentItem, li, i; + + if ( Array.isArray( disabled ) ) { + if ( !disabled.length ) { + disabled = false; + } else if ( disabled.length === this.anchors.length ) { + disabled = true; + } + } + + // Disable tabs + for ( i = 0; ( li = this.tabs[ i ] ); i++ ) { + currentItem = $( li ); + if ( disabled === true || $.inArray( i, disabled ) !== -1 ) { + currentItem.attr( "aria-disabled", "true" ); + this._addClass( currentItem, null, "ui-state-disabled" ); + } else { + currentItem.removeAttr( "aria-disabled" ); + this._removeClass( currentItem, null, "ui-state-disabled" ); + } + } + + this.options.disabled = disabled; + + this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, + disabled === true ); + }, + + _setupEvents: function( event ) { + var events = {}; + if ( event ) { + $.each( event.split( " " ), function( index, eventName ) { + events[ eventName ] = "_eventHandler"; + } ); + } + + this._off( this.anchors.add( this.tabs ).add( this.panels ) ); + + // Always prevent the default action, even when disabled + this._on( true, this.anchors, { + click: function( event ) { + event.preventDefault(); + } + } ); + this._on( this.anchors, events ); + this._on( this.tabs, { keydown: "_tabKeydown" } ); + this._on( this.panels, { keydown: "_panelKeydown" } ); + + this._focusable( this.tabs ); + this._hoverable( this.tabs ); + }, + + _setupHeightStyle: function( heightStyle ) { + var maxHeight, + parent = this.element.parent(); + + if ( heightStyle === "fill" ) { + maxHeight = parent.height(); + maxHeight -= this.element.outerHeight() - this.element.height(); + + this.element.siblings( ":visible" ).each( function() { + var elem = $( this ), + position = elem.css( "position" ); + + if ( position === "absolute" || position === "fixed" ) { + return; + } + maxHeight -= elem.outerHeight( true ); + } ); + + this.element.children().not( this.panels ).each( function() { + maxHeight -= $( this ).outerHeight( true ); + } ); + + this.panels.each( function() { + $( this ).height( Math.max( 0, maxHeight - + $( this ).innerHeight() + $( this ).height() ) ); + } ) + .css( "overflow", "auto" ); + } else if ( heightStyle === "auto" ) { + maxHeight = 0; + this.panels.each( function() { + maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); + } ).height( maxHeight ); + } + }, + + _eventHandler: function( event ) { + var options = this.options, + active = this.active, + anchor = $( event.currentTarget ), + tab = anchor.closest( "li" ), + clickedIsActive = tab[ 0 ] === active[ 0 ], + collapsing = clickedIsActive && options.collapsible, + toShow = collapsing ? $() : this._getPanelForTab( tab ), + toHide = !active.length ? $() : this._getPanelForTab( active ), + eventData = { + oldTab: active, + oldPanel: toHide, + newTab: collapsing ? $() : tab, + newPanel: toShow + }; + + event.preventDefault(); + + if ( tab.hasClass( "ui-state-disabled" ) || + + // tab is already loading + tab.hasClass( "ui-tabs-loading" ) || + + // can't switch durning an animation + this.running || + + // click on active header, but not collapsible + ( clickedIsActive && !options.collapsible ) || + + // allow canceling activation + ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { + return; + } + + options.active = collapsing ? false : this.tabs.index( tab ); + + this.active = clickedIsActive ? $() : tab; + if ( this.xhr ) { + this.xhr.abort(); + } + + if ( !toHide.length && !toShow.length ) { + $.error( "jQuery UI Tabs: Mismatching fragment identifier." ); + } + + if ( toShow.length ) { + this.load( this.tabs.index( tab ), event ); + } + this._toggle( event, eventData ); + }, + + // Handles show/hide for selecting tabs + _toggle: function( event, eventData ) { + var that = this, + toShow = eventData.newPanel, + toHide = eventData.oldPanel; + + this.running = true; + + function complete() { + that.running = false; + that._trigger( "activate", event, eventData ); + } + + function show() { + that._addClass( eventData.newTab.closest( "li" ), "ui-tabs-active", "ui-state-active" ); + + if ( toShow.length && that.options.show ) { + that._show( toShow, that.options.show, complete ); + } else { + toShow.show(); + complete(); + } + } + + // Start out by hiding, then showing, then completing + if ( toHide.length && this.options.hide ) { + this._hide( toHide, this.options.hide, function() { + that._removeClass( eventData.oldTab.closest( "li" ), + "ui-tabs-active", "ui-state-active" ); + show(); + } ); + } else { + this._removeClass( eventData.oldTab.closest( "li" ), + "ui-tabs-active", "ui-state-active" ); + toHide.hide(); + show(); + } + + toHide.attr( "aria-hidden", "true" ); + eventData.oldTab.attr( { + "aria-selected": "false", + "aria-expanded": "false" + } ); + + // If we're switching tabs, remove the old tab from the tab order. + // If we're opening from collapsed state, remove the previous tab from the tab order. + // If we're collapsing, then keep the collapsing tab in the tab order. + if ( toShow.length && toHide.length ) { + eventData.oldTab.attr( "tabIndex", -1 ); + } else if ( toShow.length ) { + this.tabs.filter( function() { + return $( this ).attr( "tabIndex" ) === 0; + } ) + .attr( "tabIndex", -1 ); + } + + toShow.attr( "aria-hidden", "false" ); + eventData.newTab.attr( { + "aria-selected": "true", + "aria-expanded": "true", + tabIndex: 0 + } ); + }, + + _activate: function( index ) { + var anchor, + active = this._findActive( index ); + + // Trying to activate the already active panel + if ( active[ 0 ] === this.active[ 0 ] ) { + return; + } + + // Trying to collapse, simulate a click on the current active header + if ( !active.length ) { + active = this.active; + } + + anchor = active.find( ".ui-tabs-anchor" )[ 0 ]; + this._eventHandler( { + target: anchor, + currentTarget: anchor, + preventDefault: $.noop + } ); + }, + + _findActive: function( index ) { + return index === false ? $() : this.tabs.eq( index ); + }, + + _getIndex: function( index ) { + + // meta-function to give users option to provide a href string instead of a numerical index. + if ( typeof index === "string" ) { + index = this.anchors.index( this.anchors.filter( "[href$='" + + $.escapeSelector( index ) + "']" ) ); + } + + return index; + }, + + _destroy: function() { + if ( this.xhr ) { + this.xhr.abort(); + } + + this.tablist + .removeAttr( "role" ) + .off( this.eventNamespace ); + + this.anchors + .removeAttr( "role tabIndex" ) + .removeUniqueId(); + + this.tabs.add( this.panels ).each( function() { + if ( $.data( this, "ui-tabs-destroy" ) ) { + $( this ).remove(); + } else { + $( this ).removeAttr( "role tabIndex " + + "aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded" ); + } + } ); + + this.tabs.each( function() { + var li = $( this ), + prev = li.data( "ui-tabs-aria-controls" ); + if ( prev ) { + li + .attr( "aria-controls", prev ) + .removeData( "ui-tabs-aria-controls" ); + } else { + li.removeAttr( "aria-controls" ); + } + } ); + + this.panels.show(); + + if ( this.options.heightStyle !== "content" ) { + this.panels.css( "height", "" ); + } + }, + + enable: function( index ) { + var disabled = this.options.disabled; + if ( disabled === false ) { + return; + } + + if ( index === undefined ) { + disabled = false; + } else { + index = this._getIndex( index ); + if ( Array.isArray( disabled ) ) { + disabled = $.map( disabled, function( num ) { + return num !== index ? num : null; + } ); + } else { + disabled = $.map( this.tabs, function( li, num ) { + return num !== index ? num : null; + } ); + } + } + this._setOptionDisabled( disabled ); + }, + + disable: function( index ) { + var disabled = this.options.disabled; + if ( disabled === true ) { + return; + } + + if ( index === undefined ) { + disabled = true; + } else { + index = this._getIndex( index ); + if ( $.inArray( index, disabled ) !== -1 ) { + return; + } + if ( Array.isArray( disabled ) ) { + disabled = $.merge( [ index ], disabled ).sort(); + } else { + disabled = [ index ]; + } + } + this._setOptionDisabled( disabled ); + }, + + load: function( index, event ) { + index = this._getIndex( index ); + var that = this, + tab = this.tabs.eq( index ), + anchor = tab.find( ".ui-tabs-anchor" ), + panel = this._getPanelForTab( tab ), + eventData = { + tab: tab, + panel: panel + }, + complete = function( jqXHR, status ) { + if ( status === "abort" ) { + that.panels.stop( false, true ); + } + + that._removeClass( tab, "ui-tabs-loading" ); + panel.removeAttr( "aria-busy" ); + + if ( jqXHR === that.xhr ) { + delete that.xhr; + } + }; + + // Not remote + if ( this._isLocal( anchor[ 0 ] ) ) { + return; + } + + this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) ); + + // Support: jQuery <1.8 + // jQuery <1.8 returns false if the request is canceled in beforeSend, + // but as of 1.8, $.ajax() always returns a jqXHR object. + if ( this.xhr && this.xhr.statusText !== "canceled" ) { + this._addClass( tab, "ui-tabs-loading" ); + panel.attr( "aria-busy", "true" ); + + this.xhr + .done( function( response, status, jqXHR ) { + + // support: jQuery <1.8 + // http://bugs.jquery.com/ticket/11778 + setTimeout( function() { + panel.html( response ); + that._trigger( "load", event, eventData ); + + complete( jqXHR, status ); + }, 1 ); + } ) + .fail( function( jqXHR, status ) { + + // support: jQuery <1.8 + // http://bugs.jquery.com/ticket/11778 + setTimeout( function() { + complete( jqXHR, status ); + }, 1 ); + } ); + } + }, + + _ajaxSettings: function( anchor, event, eventData ) { + var that = this; + return { + + // Support: IE <11 only + // Strip any hash that exists to prevent errors with the Ajax request + url: anchor.attr( "href" ).replace( /#.*$/, "" ), + beforeSend: function( jqXHR, settings ) { + return that._trigger( "beforeLoad", event, + $.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) ); + } + }; + }, + + _getPanelForTab: function( tab ) { + var id = $( tab ).attr( "aria-controls" ); + return this.element.find( this._sanitizeSelector( "#" + id ) ); + } + } ); // DEPRECATED // TODO: Switch return back to widget declaration at top of file when this is removed -if ( $.uiBackCompat !== false ) { - - // Backcompat for ui-tab class (now ui-tabs-tab) - $.widget( "ui.tabs", $.ui.tabs, { - _processTabs: function() { - this._superApply( arguments ); - this._addClass( this.tabs, "ui-tab" ); - } - } ); -} - -return $.ui.tabs; + if ( $.uiBackCompat !== false ) { + + // Backcompat for ui-tab class (now ui-tabs-tab) + $.widget( "ui.tabs", $.ui.tabs, { + _processTabs: function() { + this._superApply( arguments ); + this._addClass( this.tabs, "ui-tab" ); + } + } ); + } + + return $.ui.tabs; } ); diff --git a/lib/web/jquery/ui-modules/widgets/tooltip.js b/lib/web/jquery/ui-modules/widgets/tooltip.js index d6c0b8043cd25..5240bf12a15c6 100644 --- a/lib/web/jquery/ui-modules/widgets/tooltip.js +++ b/lib/web/jquery/ui-modules/widgets/tooltip.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Tooltip 1.13.1 + * jQuery UI Tooltip 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -17,511 +17,511 @@ //>>css.theme: ../../themes/base/theme.css ( function( factory ) { - "use strict"; - - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define( [ - "jquery", - "../keycode", - "../position", - "../unique-id", - "../version", - "../widget" - ], factory ); - } else { - - // Browser globals - factory( jQuery ); - } + "use strict"; + + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ + "jquery", + "../keycode", + "../position", + "../unique-id", + "../version", + "../widget" + ], factory ); + } else { + + // Browser globals + factory( jQuery ); + } } )( function( $ ) { -"use strict"; - -$.widget( "ui.tooltip", { - version: "1.13.1", - options: { - classes: { - "ui-tooltip": "ui-corner-all ui-widget-shadow" - }, - content: function() { - var title = $( this ).attr( "title" ); - - // Escape title, since we're going from an attribute to raw HTML - return $( "<a>" ).text( title ).html(); - }, - hide: true, - - // Disabled elements have inconsistent behavior across browsers (#8661) - items: "[title]:not([disabled])", - position: { - my: "left top+15", - at: "left bottom", - collision: "flipfit flip" - }, - show: true, - track: false, - - // Callbacks - close: null, - open: null - }, - - _addDescribedBy: function( elem, id ) { - var describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ); - describedby.push( id ); - elem - .data( "ui-tooltip-id", id ) - .attr( "aria-describedby", String.prototype.trim.call( describedby.join( " " ) ) ); - }, - - _removeDescribedBy: function( elem ) { - var id = elem.data( "ui-tooltip-id" ), - describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ), - index = $.inArray( id, describedby ); - - if ( index !== -1 ) { - describedby.splice( index, 1 ); - } - - elem.removeData( "ui-tooltip-id" ); - describedby = String.prototype.trim.call( describedby.join( " " ) ); - if ( describedby ) { - elem.attr( "aria-describedby", describedby ); - } else { - elem.removeAttr( "aria-describedby" ); - } - }, - - _create: function() { - this._on( { - mouseover: "open", - focusin: "open" - } ); - - // IDs of generated tooltips, needed for destroy - this.tooltips = {}; - - // IDs of parent tooltips where we removed the title attribute - this.parents = {}; - - // Append the aria-live region so tooltips announce correctly - this.liveRegion = $( "<div>" ) - .attr( { - role: "log", - "aria-live": "assertive", - "aria-relevant": "additions" - } ) - .appendTo( this.document[ 0 ].body ); - this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" ); - - this.disabledTitles = $( [] ); - }, - - _setOption: function( key, value ) { - var that = this; - - this._super( key, value ); - - if ( key === "content" ) { - $.each( this.tooltips, function( id, tooltipData ) { - that._updateContent( tooltipData.element ); - } ); - } - }, - - _setOptionDisabled: function( value ) { - this[ value ? "_disable" : "_enable" ](); - }, - - _disable: function() { - var that = this; - - // Close open tooltips - $.each( this.tooltips, function( id, tooltipData ) { - var event = $.Event( "blur" ); - event.target = event.currentTarget = tooltipData.element[ 0 ]; - that.close( event, true ); - } ); - - // Remove title attributes to prevent native tooltips - this.disabledTitles = this.disabledTitles.add( - this.element.find( this.options.items ).addBack() - .filter( function() { - var element = $( this ); - if ( element.is( "[title]" ) ) { - return element - .data( "ui-tooltip-title", element.attr( "title" ) ) - .removeAttr( "title" ); - } - } ) - ); - }, - - _enable: function() { - - // restore title attributes - this.disabledTitles.each( function() { - var element = $( this ); - if ( element.data( "ui-tooltip-title" ) ) { - element.attr( "title", element.data( "ui-tooltip-title" ) ); - } - } ); - this.disabledTitles = $( [] ); - }, - - open: function( event ) { - var that = this, - target = $( event ? event.target : this.element ) - - // we need closest here due to mouseover bubbling, - // but always pointing at the same event target - .closest( this.options.items ); - - // No element to show a tooltip for or the tooltip is already open - if ( !target.length || target.data( "ui-tooltip-id" ) ) { - return; - } - - if ( target.attr( "title" ) ) { - target.data( "ui-tooltip-title", target.attr( "title" ) ); - } - - target.data( "ui-tooltip-open", true ); - - // Kill parent tooltips, custom or native, for hover - if ( event && event.type === "mouseover" ) { - target.parents().each( function() { - var parent = $( this ), - blurEvent; - if ( parent.data( "ui-tooltip-open" ) ) { - blurEvent = $.Event( "blur" ); - blurEvent.target = blurEvent.currentTarget = this; - that.close( blurEvent, true ); - } - if ( parent.attr( "title" ) ) { - parent.uniqueId(); - that.parents[ this.id ] = { - element: this, - title: parent.attr( "title" ) - }; - parent.attr( "title", "" ); - } - } ); - } - - this._registerCloseHandlers( event, target ); - this._updateContent( target, event ); - }, - - _updateContent: function( target, event ) { - var content, - contentOption = this.options.content, - that = this, - eventType = event ? event.type : null; - - if ( typeof contentOption === "string" || contentOption.nodeType || - contentOption.jquery ) { - return this._open( event, target, contentOption ); - } - - content = contentOption.call( target[ 0 ], function( response ) { - - // IE may instantly serve a cached response for ajax requests - // delay this call to _open so the other call to _open runs first - that._delay( function() { - - // Ignore async response if tooltip was closed already - if ( !target.data( "ui-tooltip-open" ) ) { - return; - } - - // JQuery creates a special event for focusin when it doesn't - // exist natively. To improve performance, the native event - // object is reused and the type is changed. Therefore, we can't - // rely on the type being correct after the event finished - // bubbling, so we set it back to the previous value. (#8740) - if ( event ) { - event.type = eventType; - } - this._open( event, target, response ); - } ); - } ); - if ( content ) { - this._open( event, target, content ); - } - }, - - _open: function( event, target, content ) { - var tooltipData, tooltip, delayedShow, a11yContent, - positionOption = $.extend( {}, this.options.position ); - - if ( !content ) { - return; - } - - // Content can be updated multiple times. If the tooltip already - // exists, then just update the content and bail. - tooltipData = this._find( target ); - if ( tooltipData ) { - tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content ); - return; - } - - // If we have a title, clear it to prevent the native tooltip - // we have to check first to avoid defining a title if none exists - // (we don't want to cause an element to start matching [title]) - // - // We use removeAttr only for key events, to allow IE to export the correct - // accessible attributes. For mouse events, set to empty string to avoid - // native tooltip showing up (happens only when removing inside mouseover). - if ( target.is( "[title]" ) ) { - if ( event && event.type === "mouseover" ) { - target.attr( "title", "" ); - } else { - target.removeAttr( "title" ); - } - } - - tooltipData = this._tooltip( target ); - tooltip = tooltipData.tooltip; - this._addDescribedBy( target, tooltip.attr( "id" ) ); - tooltip.find( ".ui-tooltip-content" ).html( content ); - - // Support: Voiceover on OS X, JAWS on IE <= 9 - // JAWS announces deletions even when aria-relevant="additions" - // Voiceover will sometimes re-read the entire log region's contents from the beginning - this.liveRegion.children().hide(); - a11yContent = $( "<div>" ).html( tooltip.find( ".ui-tooltip-content" ).html() ); - a11yContent.removeAttr( "name" ).find( "[name]" ).removeAttr( "name" ); - a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" ); - a11yContent.appendTo( this.liveRegion ); - - function position( event ) { - positionOption.of = event; - if ( tooltip.is( ":hidden" ) ) { - return; - } - tooltip.position( positionOption ); - } - if ( this.options.track && event && /^mouse/.test( event.type ) ) { - this._on( this.document, { - mousemove: position - } ); - - // trigger once to override element-relative positioning - position( event ); - } else { - tooltip.position( $.extend( { - of: target - }, this.options.position ) ); - } - - tooltip.hide(); - - this._show( tooltip, this.options.show ); - - // Handle tracking tooltips that are shown with a delay (#8644). As soon - // as the tooltip is visible, position the tooltip using the most recent - // event. - // Adds the check to add the timers only when both delay and track options are set (#14682) - if ( this.options.track && this.options.show && this.options.show.delay ) { - delayedShow = this.delayedShow = setInterval( function() { - if ( tooltip.is( ":visible" ) ) { - position( positionOption.of ); - clearInterval( delayedShow ); - } - }, 13 ); - } - - this._trigger( "open", event, { tooltip: tooltip } ); - }, - - _registerCloseHandlers: function( event, target ) { - var events = { - keyup: function( event ) { - if ( event.keyCode === $.ui.keyCode.ESCAPE ) { - var fakeEvent = $.Event( event ); - fakeEvent.currentTarget = target[ 0 ]; - this.close( fakeEvent, true ); - } - } - }; - - // Only bind remove handler for delegated targets. Non-delegated - // tooltips will handle this in destroy. - if ( target[ 0 ] !== this.element[ 0 ] ) { - events.remove = function() { - var targetElement = this._find( target ); - if ( targetElement ) { - this._removeTooltip( targetElement.tooltip ); - } - }; - } - - if ( !event || event.type === "mouseover" ) { - events.mouseleave = "close"; - } - if ( !event || event.type === "focusin" ) { - events.focusout = "close"; - } - this._on( true, target, events ); - }, - - close: function( event ) { - var tooltip, - that = this, - target = $( event ? event.currentTarget : this.element ), - tooltipData = this._find( target ); - - // The tooltip may already be closed - if ( !tooltipData ) { - - // We set ui-tooltip-open immediately upon open (in open()), but only set the - // additional data once there's actually content to show (in _open()). So even if the - // tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in - // the period between open() and _open(). - target.removeData( "ui-tooltip-open" ); - return; - } - - tooltip = tooltipData.tooltip; - - // Disabling closes the tooltip, so we need to track when we're closing - // to avoid an infinite loop in case the tooltip becomes disabled on close - if ( tooltipData.closing ) { - return; - } - - // Clear the interval for delayed tracking tooltips - clearInterval( this.delayedShow ); - - // Only set title if we had one before (see comment in _open()) - // If the title attribute has changed since open(), don't restore - if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) { - target.attr( "title", target.data( "ui-tooltip-title" ) ); - } - - this._removeDescribedBy( target ); - - tooltipData.hiding = true; - tooltip.stop( true ); - this._hide( tooltip, this.options.hide, function() { - that._removeTooltip( $( this ) ); - } ); - - target.removeData( "ui-tooltip-open" ); - this._off( target, "mouseleave focusout keyup" ); - - // Remove 'remove' binding only on delegated targets - if ( target[ 0 ] !== this.element[ 0 ] ) { - this._off( target, "remove" ); - } - this._off( this.document, "mousemove" ); - - if ( event && event.type === "mouseleave" ) { - $.each( this.parents, function( id, parent ) { - $( parent.element ).attr( "title", parent.title ); - delete that.parents[ id ]; - } ); - } - - tooltipData.closing = true; - this._trigger( "close", event, { tooltip: tooltip } ); - if ( !tooltipData.hiding ) { - tooltipData.closing = false; - } - }, - - _tooltip: function( element ) { - var tooltip = $( "<div>" ).attr( "role", "tooltip" ), - content = $( "<div>" ).appendTo( tooltip ), - id = tooltip.uniqueId().attr( "id" ); - - this._addClass( content, "ui-tooltip-content" ); - this._addClass( tooltip, "ui-tooltip", "ui-widget ui-widget-content" ); - - tooltip.appendTo( this._appendTo( element ) ); - - return this.tooltips[ id ] = { - element: element, - tooltip: tooltip - }; - }, - - _find: function( target ) { - var id = target.data( "ui-tooltip-id" ); - return id ? this.tooltips[ id ] : null; - }, - - _removeTooltip: function( tooltip ) { - - // Clear the interval for delayed tracking tooltips - clearInterval( this.delayedShow ); - - tooltip.remove(); - delete this.tooltips[ tooltip.attr( "id" ) ]; - }, - - _appendTo: function( target ) { - var element = target.closest( ".ui-front, dialog" ); - - if ( !element.length ) { - element = this.document[ 0 ].body; - } - - return element; - }, - - _destroy: function() { - var that = this; - - // Close open tooltips - $.each( this.tooltips, function( id, tooltipData ) { - - // Delegate to close method to handle common cleanup - var event = $.Event( "blur" ), - element = tooltipData.element; - event.target = event.currentTarget = element[ 0 ]; - that.close( event, true ); - - // Remove immediately; destroying an open tooltip doesn't use the - // hide animation - $( "#" + id ).remove(); - - // Restore the title - if ( element.data( "ui-tooltip-title" ) ) { - - // If the title attribute has changed since open(), don't restore - if ( !element.attr( "title" ) ) { - element.attr( "title", element.data( "ui-tooltip-title" ) ); - } - element.removeData( "ui-tooltip-title" ); - } - } ); - this.liveRegion.remove(); - } -} ); + "use strict"; + + $.widget( "ui.tooltip", { + version: "1.13.2", + options: { + classes: { + "ui-tooltip": "ui-corner-all ui-widget-shadow" + }, + content: function() { + var title = $( this ).attr( "title" ); + + // Escape title, since we're going from an attribute to raw HTML + return $( "<a>" ).text( title ).html(); + }, + hide: true, + + // Disabled elements have inconsistent behavior across browsers (#8661) + items: "[title]:not([disabled])", + position: { + my: "left top+15", + at: "left bottom", + collision: "flipfit flip" + }, + show: true, + track: false, + + // Callbacks + close: null, + open: null + }, + + _addDescribedBy: function( elem, id ) { + var describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ); + describedby.push( id ); + elem + .data( "ui-tooltip-id", id ) + .attr( "aria-describedby", String.prototype.trim.call( describedby.join( " " ) ) ); + }, + + _removeDescribedBy: function( elem ) { + var id = elem.data( "ui-tooltip-id" ), + describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ), + index = $.inArray( id, describedby ); + + if ( index !== -1 ) { + describedby.splice( index, 1 ); + } + + elem.removeData( "ui-tooltip-id" ); + describedby = String.prototype.trim.call( describedby.join( " " ) ); + if ( describedby ) { + elem.attr( "aria-describedby", describedby ); + } else { + elem.removeAttr( "aria-describedby" ); + } + }, + + _create: function() { + this._on( { + mouseover: "open", + focusin: "open" + } ); + + // IDs of generated tooltips, needed for destroy + this.tooltips = {}; + + // IDs of parent tooltips where we removed the title attribute + this.parents = {}; + + // Append the aria-live region so tooltips announce correctly + this.liveRegion = $( "<div>" ) + .attr( { + role: "log", + "aria-live": "assertive", + "aria-relevant": "additions" + } ) + .appendTo( this.document[ 0 ].body ); + this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" ); + + this.disabledTitles = $( [] ); + }, + + _setOption: function( key, value ) { + var that = this; + + this._super( key, value ); + + if ( key === "content" ) { + $.each( this.tooltips, function( id, tooltipData ) { + that._updateContent( tooltipData.element ); + } ); + } + }, + + _setOptionDisabled: function( value ) { + this[ value ? "_disable" : "_enable" ](); + }, + + _disable: function() { + var that = this; + + // Close open tooltips + $.each( this.tooltips, function( id, tooltipData ) { + var event = $.Event( "blur" ); + event.target = event.currentTarget = tooltipData.element[ 0 ]; + that.close( event, true ); + } ); + + // Remove title attributes to prevent native tooltips + this.disabledTitles = this.disabledTitles.add( + this.element.find( this.options.items ).addBack() + .filter( function() { + var element = $( this ); + if ( element.is( "[title]" ) ) { + return element + .data( "ui-tooltip-title", element.attr( "title" ) ) + .removeAttr( "title" ); + } + } ) + ); + }, + + _enable: function() { + + // restore title attributes + this.disabledTitles.each( function() { + var element = $( this ); + if ( element.data( "ui-tooltip-title" ) ) { + element.attr( "title", element.data( "ui-tooltip-title" ) ); + } + } ); + this.disabledTitles = $( [] ); + }, + + open: function( event ) { + var that = this, + target = $( event ? event.target : this.element ) + + // we need closest here due to mouseover bubbling, + // but always pointing at the same event target + .closest( this.options.items ); + + // No element to show a tooltip for or the tooltip is already open + if ( !target.length || target.data( "ui-tooltip-id" ) ) { + return; + } + + if ( target.attr( "title" ) ) { + target.data( "ui-tooltip-title", target.attr( "title" ) ); + } + + target.data( "ui-tooltip-open", true ); + + // Kill parent tooltips, custom or native, for hover + if ( event && event.type === "mouseover" ) { + target.parents().each( function() { + var parent = $( this ), + blurEvent; + if ( parent.data( "ui-tooltip-open" ) ) { + blurEvent = $.Event( "blur" ); + blurEvent.target = blurEvent.currentTarget = this; + that.close( blurEvent, true ); + } + if ( parent.attr( "title" ) ) { + parent.uniqueId(); + that.parents[ this.id ] = { + element: this, + title: parent.attr( "title" ) + }; + parent.attr( "title", "" ); + } + } ); + } + + this._registerCloseHandlers( event, target ); + this._updateContent( target, event ); + }, + + _updateContent: function( target, event ) { + var content, + contentOption = this.options.content, + that = this, + eventType = event ? event.type : null; + + if ( typeof contentOption === "string" || contentOption.nodeType || + contentOption.jquery ) { + return this._open( event, target, contentOption ); + } + + content = contentOption.call( target[ 0 ], function( response ) { + + // IE may instantly serve a cached response for ajax requests + // delay this call to _open so the other call to _open runs first + that._delay( function() { + + // Ignore async response if tooltip was closed already + if ( !target.data( "ui-tooltip-open" ) ) { + return; + } + + // JQuery creates a special event for focusin when it doesn't + // exist natively. To improve performance, the native event + // object is reused and the type is changed. Therefore, we can't + // rely on the type being correct after the event finished + // bubbling, so we set it back to the previous value. (#8740) + if ( event ) { + event.type = eventType; + } + this._open( event, target, response ); + } ); + } ); + if ( content ) { + this._open( event, target, content ); + } + }, + + _open: function( event, target, content ) { + var tooltipData, tooltip, delayedShow, a11yContent, + positionOption = $.extend( {}, this.options.position ); + + if ( !content ) { + return; + } + + // Content can be updated multiple times. If the tooltip already + // exists, then just update the content and bail. + tooltipData = this._find( target ); + if ( tooltipData ) { + tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content ); + return; + } + + // If we have a title, clear it to prevent the native tooltip + // we have to check first to avoid defining a title if none exists + // (we don't want to cause an element to start matching [title]) + // + // We use removeAttr only for key events, to allow IE to export the correct + // accessible attributes. For mouse events, set to empty string to avoid + // native tooltip showing up (happens only when removing inside mouseover). + if ( target.is( "[title]" ) ) { + if ( event && event.type === "mouseover" ) { + target.attr( "title", "" ); + } else { + target.removeAttr( "title" ); + } + } + + tooltipData = this._tooltip( target ); + tooltip = tooltipData.tooltip; + this._addDescribedBy( target, tooltip.attr( "id" ) ); + tooltip.find( ".ui-tooltip-content" ).html( content ); + + // Support: Voiceover on OS X, JAWS on IE <= 9 + // JAWS announces deletions even when aria-relevant="additions" + // Voiceover will sometimes re-read the entire log region's contents from the beginning + this.liveRegion.children().hide(); + a11yContent = $( "<div>" ).html( tooltip.find( ".ui-tooltip-content" ).html() ); + a11yContent.removeAttr( "name" ).find( "[name]" ).removeAttr( "name" ); + a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" ); + a11yContent.appendTo( this.liveRegion ); + + function position( event ) { + positionOption.of = event; + if ( tooltip.is( ":hidden" ) ) { + return; + } + tooltip.position( positionOption ); + } + if ( this.options.track && event && /^mouse/.test( event.type ) ) { + this._on( this.document, { + mousemove: position + } ); + + // trigger once to override element-relative positioning + position( event ); + } else { + tooltip.position( $.extend( { + of: target + }, this.options.position ) ); + } + + tooltip.hide(); + + this._show( tooltip, this.options.show ); + + // Handle tracking tooltips that are shown with a delay (#8644). As soon + // as the tooltip is visible, position the tooltip using the most recent + // event. + // Adds the check to add the timers only when both delay and track options are set (#14682) + if ( this.options.track && this.options.show && this.options.show.delay ) { + delayedShow = this.delayedShow = setInterval( function() { + if ( tooltip.is( ":visible" ) ) { + position( positionOption.of ); + clearInterval( delayedShow ); + } + }, 13 ); + } + + this._trigger( "open", event, { tooltip: tooltip } ); + }, + + _registerCloseHandlers: function( event, target ) { + var events = { + keyup: function( event ) { + if ( event.keyCode === $.ui.keyCode.ESCAPE ) { + var fakeEvent = $.Event( event ); + fakeEvent.currentTarget = target[ 0 ]; + this.close( fakeEvent, true ); + } + } + }; + + // Only bind remove handler for delegated targets. Non-delegated + // tooltips will handle this in destroy. + if ( target[ 0 ] !== this.element[ 0 ] ) { + events.remove = function() { + var targetElement = this._find( target ); + if ( targetElement ) { + this._removeTooltip( targetElement.tooltip ); + } + }; + } + + if ( !event || event.type === "mouseover" ) { + events.mouseleave = "close"; + } + if ( !event || event.type === "focusin" ) { + events.focusout = "close"; + } + this._on( true, target, events ); + }, + + close: function( event ) { + var tooltip, + that = this, + target = $( event ? event.currentTarget : this.element ), + tooltipData = this._find( target ); + + // The tooltip may already be closed + if ( !tooltipData ) { + + // We set ui-tooltip-open immediately upon open (in open()), but only set the + // additional data once there's actually content to show (in _open()). So even if the + // tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in + // the period between open() and _open(). + target.removeData( "ui-tooltip-open" ); + return; + } + + tooltip = tooltipData.tooltip; + + // Disabling closes the tooltip, so we need to track when we're closing + // to avoid an infinite loop in case the tooltip becomes disabled on close + if ( tooltipData.closing ) { + return; + } + + // Clear the interval for delayed tracking tooltips + clearInterval( this.delayedShow ); + + // Only set title if we had one before (see comment in _open()) + // If the title attribute has changed since open(), don't restore + if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) { + target.attr( "title", target.data( "ui-tooltip-title" ) ); + } + + this._removeDescribedBy( target ); + + tooltipData.hiding = true; + tooltip.stop( true ); + this._hide( tooltip, this.options.hide, function() { + that._removeTooltip( $( this ) ); + } ); + + target.removeData( "ui-tooltip-open" ); + this._off( target, "mouseleave focusout keyup" ); + + // Remove 'remove' binding only on delegated targets + if ( target[ 0 ] !== this.element[ 0 ] ) { + this._off( target, "remove" ); + } + this._off( this.document, "mousemove" ); + + if ( event && event.type === "mouseleave" ) { + $.each( this.parents, function( id, parent ) { + $( parent.element ).attr( "title", parent.title ); + delete that.parents[ id ]; + } ); + } + + tooltipData.closing = true; + this._trigger( "close", event, { tooltip: tooltip } ); + if ( !tooltipData.hiding ) { + tooltipData.closing = false; + } + }, + + _tooltip: function( element ) { + var tooltip = $( "<div>" ).attr( "role", "tooltip" ), + content = $( "<div>" ).appendTo( tooltip ), + id = tooltip.uniqueId().attr( "id" ); + + this._addClass( content, "ui-tooltip-content" ); + this._addClass( tooltip, "ui-tooltip", "ui-widget ui-widget-content" ); + + tooltip.appendTo( this._appendTo( element ) ); + + return this.tooltips[ id ] = { + element: element, + tooltip: tooltip + }; + }, + + _find: function( target ) { + var id = target.data( "ui-tooltip-id" ); + return id ? this.tooltips[ id ] : null; + }, + + _removeTooltip: function( tooltip ) { + + // Clear the interval for delayed tracking tooltips + clearInterval( this.delayedShow ); + + tooltip.remove(); + delete this.tooltips[ tooltip.attr( "id" ) ]; + }, + + _appendTo: function( target ) { + var element = target.closest( ".ui-front, dialog" ); + + if ( !element.length ) { + element = this.document[ 0 ].body; + } + + return element; + }, + + _destroy: function() { + var that = this; + + // Close open tooltips + $.each( this.tooltips, function( id, tooltipData ) { + + // Delegate to close method to handle common cleanup + var event = $.Event( "blur" ), + element = tooltipData.element; + event.target = event.currentTarget = element[ 0 ]; + that.close( event, true ); + + // Remove immediately; destroying an open tooltip doesn't use the + // hide animation + $( "#" + id ).remove(); + + // Restore the title + if ( element.data( "ui-tooltip-title" ) ) { + + // If the title attribute has changed since open(), don't restore + if ( !element.attr( "title" ) ) { + element.attr( "title", element.data( "ui-tooltip-title" ) ); + } + element.removeData( "ui-tooltip-title" ); + } + } ); + this.liveRegion.remove(); + } + } ); // DEPRECATED // TODO: Switch return back to widget declaration at top of file when this is removed -if ( $.uiBackCompat !== false ) { - - // Backcompat for tooltipClass option - $.widget( "ui.tooltip", $.ui.tooltip, { - options: { - tooltipClass: null - }, - _tooltip: function() { - var tooltipData = this._superApply( arguments ); - if ( this.options.tooltipClass ) { - tooltipData.tooltip.addClass( this.options.tooltipClass ); - } - return tooltipData; - } - } ); -} - -return $.ui.tooltip; + if ( $.uiBackCompat !== false ) { + + // Backcompat for tooltipClass option + $.widget( "ui.tooltip", $.ui.tooltip, { + options: { + tooltipClass: null + }, + _tooltip: function() { + var tooltipData = this._superApply( arguments ); + if ( this.options.tooltipClass ) { + tooltipData.tooltip.addClass( this.options.tooltipClass ); + } + return tooltipData; + } + } ); + } + + return $.ui.tooltip; } ); diff --git a/lib/web/moment.js b/lib/web/moment.js index aa5cc383efc66..498eeefe841c8 100644 --- a/lib/web/moment.js +++ b/lib/web/moment.js @@ -1,6 +1,7 @@ //! moment.js -//! version : 2.29.1 +//! version : 2.29.4 //! authors : Tim Wood, Iskren Chernev, Moment.js contributors //! license : MIT //! momentjs.com -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.moment=t()}(this,function(){"use strict";var e,i;function f(){return e.apply(null,arguments)}function o(e){return e instanceof Array||"[object Array]"===Object.prototype.toString.call(e)}function u(e){return null!=e&&"[object Object]"===Object.prototype.toString.call(e)}function m(e,t){return Object.prototype.hasOwnProperty.call(e,t)}function l(e){if(Object.getOwnPropertyNames)return 0===Object.getOwnPropertyNames(e).length;for(var t in e)if(m(e,t))return;return 1}function r(e){return void 0===e}function h(e){return"number"==typeof e||"[object Number]"===Object.prototype.toString.call(e)}function a(e){return e instanceof Date||"[object Date]"===Object.prototype.toString.call(e)}function d(e,t){for(var n=[],s=0;s<e.length;++s)n.push(t(e[s],s));return n}function c(e,t){for(var n in t)m(t,n)&&(e[n]=t[n]);return m(t,"toString")&&(e.toString=t.toString),m(t,"valueOf")&&(e.valueOf=t.valueOf),e}function _(e,t,n,s){return xt(e,t,n,s,!0).utc()}function y(e){return null==e._pf&&(e._pf={empty:!1,unusedTokens:[],unusedInput:[],overflow:-2,charsLeftOver:0,nullInput:!1,invalidEra:null,invalidMonth:null,invalidFormat:!1,userInvalidated:!1,iso:!1,parsedDateParts:[],era:null,meridiem:null,rfc2822:!1,weekdayMismatch:!1}),e._pf}function g(e){if(null==e._isValid){var t=y(e),n=i.call(t.parsedDateParts,function(e){return null!=e}),s=!isNaN(e._d.getTime())&&t.overflow<0&&!t.empty&&!t.invalidEra&&!t.invalidMonth&&!t.invalidWeekday&&!t.weekdayMismatch&&!t.nullInput&&!t.invalidFormat&&!t.userInvalidated&&(!t.meridiem||t.meridiem&&n);if(e._strict&&(s=s&&0===t.charsLeftOver&&0===t.unusedTokens.length&&void 0===t.bigHour),null!=Object.isFrozen&&Object.isFrozen(e))return s;e._isValid=s}return e._isValid}function w(e){var t=_(NaN);return null!=e?c(y(t),e):y(t).userInvalidated=!0,t}i=Array.prototype.some?Array.prototype.some:function(e){for(var t=Object(this),n=t.length>>>0,s=0;s<n;s++)if(s in t&&e.call(this,t[s],s,t))return!0;return!1};var p=f.momentProperties=[],t=!1;function v(e,t){var n,s,i;if(r(t._isAMomentObject)||(e._isAMomentObject=t._isAMomentObject),r(t._i)||(e._i=t._i),r(t._f)||(e._f=t._f),r(t._l)||(e._l=t._l),r(t._strict)||(e._strict=t._strict),r(t._tzm)||(e._tzm=t._tzm),r(t._isUTC)||(e._isUTC=t._isUTC),r(t._offset)||(e._offset=t._offset),r(t._pf)||(e._pf=y(t)),r(t._locale)||(e._locale=t._locale),0<p.length)for(n=0;n<p.length;n++)r(i=t[s=p[n]])||(e[s]=i);return e}function k(e){v(this,e),this._d=new Date(null!=e._d?e._d.getTime():NaN),this.isValid()||(this._d=new Date(NaN)),!1===t&&(t=!0,f.updateOffset(this),t=!1)}function M(e){return e instanceof k||null!=e&&null!=e._isAMomentObject}function D(e){!1===f.suppressDeprecationWarnings&&"undefined"!=typeof console&&console.warn&&console.warn("Deprecation warning: "+e)}function n(i,r){var a=!0;return c(function(){if(null!=f.deprecationHandler&&f.deprecationHandler(null,i),a){for(var e,t,n=[],s=0;s<arguments.length;s++){if(e="","object"==typeof arguments[s]){for(t in e+="\n["+s+"] ",arguments[0])m(arguments[0],t)&&(e+=t+": "+arguments[0][t]+", ");e=e.slice(0,-2)}else e=arguments[s];n.push(e)}D(i+"\nArguments: "+Array.prototype.slice.call(n).join("")+"\n"+(new Error).stack),a=!1}return r.apply(this,arguments)},r)}var s,S={};function Y(e,t){null!=f.deprecationHandler&&f.deprecationHandler(e,t),S[e]||(D(t),S[e]=!0)}function O(e){return"undefined"!=typeof Function&&e instanceof Function||"[object Function]"===Object.prototype.toString.call(e)}function b(e,t){var n,s=c({},e);for(n in t)m(t,n)&&(u(e[n])&&u(t[n])?(s[n]={},c(s[n],e[n]),c(s[n],t[n])):null!=t[n]?s[n]=t[n]:delete s[n]);for(n in e)m(e,n)&&!m(t,n)&&u(e[n])&&(s[n]=c({},s[n]));return s}function x(e){null!=e&&this.set(e)}f.suppressDeprecationWarnings=!1,f.deprecationHandler=null,s=Object.keys?Object.keys:function(e){var t,n=[];for(t in e)m(e,t)&&n.push(t);return n};function T(e,t,n){var s=""+Math.abs(e),i=t-s.length;return(0<=e?n?"+":"":"-")+Math.pow(10,Math.max(0,i)).toString().substr(1)+s}var N=/(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|N{1,5}|YYYYYY|YYYYY|YYYY|YY|y{2,4}|yo?|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,P=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,R={},W={};function C(e,t,n,s){var i="string"==typeof s?function(){return this[s]()}:s;e&&(W[e]=i),t&&(W[t[0]]=function(){return T(i.apply(this,arguments),t[1],t[2])}),n&&(W[n]=function(){return this.localeData().ordinal(i.apply(this,arguments),e)})}function U(e,t){return e.isValid()?(t=H(t,e.localeData()),R[t]=R[t]||function(s){for(var e,i=s.match(N),t=0,r=i.length;t<r;t++)W[i[t]]?i[t]=W[i[t]]:i[t]=(e=i[t]).match(/\[[\s\S]/)?e.replace(/^\[|\]$/g,""):e.replace(/\\/g,"");return function(e){for(var t="",n=0;n<r;n++)t+=O(i[n])?i[n].call(e,s):i[n];return t}}(t),R[t](e)):e.localeData().invalidDate()}function H(e,t){var n=5;function s(e){return t.longDateFormat(e)||e}for(P.lastIndex=0;0<=n&&P.test(e);)e=e.replace(P,s),P.lastIndex=0,--n;return e}var F={};function L(e,t){var n=e.toLowerCase();F[n]=F[n+"s"]=F[t]=e}function V(e){return"string"==typeof e?F[e]||F[e.toLowerCase()]:void 0}function G(e){var t,n,s={};for(n in e)m(e,n)&&(t=V(n))&&(s[t]=e[n]);return s}var E={};function A(e,t){E[e]=t}function j(e){return e%4==0&&e%100!=0||e%400==0}function I(e){return e<0?Math.ceil(e)||0:Math.floor(e)}function Z(e){var t=+e,n=0;return 0!=t&&isFinite(t)&&(n=I(t)),n}function z(t,n){return function(e){return null!=e?(q(this,t,e),f.updateOffset(this,n),this):$(this,t)}}function $(e,t){return e.isValid()?e._d["get"+(e._isUTC?"UTC":"")+t]():NaN}function q(e,t,n){e.isValid()&&!isNaN(n)&&("FullYear"===t&&j(e.year())&&1===e.month()&&29===e.date()?(n=Z(n),e._d["set"+(e._isUTC?"UTC":"")+t](n,e.month(),xe(n,e.month()))):e._d["set"+(e._isUTC?"UTC":"")+t](n))}var B,J=/\d/,Q=/\d\d/,X=/\d{3}/,K=/\d{4}/,ee=/[+-]?\d{6}/,te=/\d\d?/,ne=/\d\d\d\d?/,se=/\d\d\d\d\d\d?/,ie=/\d{1,3}/,re=/\d{1,4}/,ae=/[+-]?\d{1,6}/,oe=/\d+/,ue=/[+-]?\d+/,le=/Z|[+-]\d\d:?\d\d/gi,he=/Z|[+-]\d\d(?::?\d\d)?/gi,de=/[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i;function ce(e,n,s){B[e]=O(n)?n:function(e,t){return e&&s?s:n}}function fe(e,t){return m(B,e)?B[e](t._strict,t._locale):new RegExp(me(e.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(e,t,n,s,i){return t||n||s||i})))}function me(e){return e.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}B={};var _e={};function ye(e,n){var t,s=n;for("string"==typeof e&&(e=[e]),h(n)&&(s=function(e,t){t[n]=Z(e)}),t=0;t<e.length;t++)_e[e[t]]=s}function ge(e,i){ye(e,function(e,t,n,s){n._w=n._w||{},i(e,n._w,n,s)})}var we,pe=0,ve=1,ke=2,Me=3,De=4,Se=5,Ye=6,Oe=7,be=8;function xe(e,t){if(isNaN(e)||isNaN(t))return NaN;var n,s=(t%(n=12)+n)%n;return e+=(t-s)/12,1==s?j(e)?29:28:31-s%7%2}we=Array.prototype.indexOf?Array.prototype.indexOf:function(e){for(var t=0;t<this.length;++t)if(this[t]===e)return t;return-1},C("M",["MM",2],"Mo",function(){return this.month()+1}),C("MMM",0,0,function(e){return this.localeData().monthsShort(this,e)}),C("MMMM",0,0,function(e){return this.localeData().months(this,e)}),L("month","M"),A("month",8),ce("M",te),ce("MM",te,Q),ce("MMM",function(e,t){return t.monthsShortRegex(e)}),ce("MMMM",function(e,t){return t.monthsRegex(e)}),ye(["M","MM"],function(e,t){t[ve]=Z(e)-1}),ye(["MMM","MMMM"],function(e,t,n,s){var i=n._locale.monthsParse(e,s,n._strict);null!=i?t[ve]=i:y(n).invalidMonth=e});var Te="January_February_March_April_May_June_July_August_September_October_November_December".split("_"),Ne="Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),Pe=/D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/,Re=de,We=de;function Ce(e,t){var n;if(!e.isValid())return e;if("string"==typeof t)if(/^\d+$/.test(t))t=Z(t);else if(!h(t=e.localeData().monthsParse(t)))return e;return n=Math.min(e.date(),xe(e.year(),t)),e._d["set"+(e._isUTC?"UTC":"")+"Month"](t,n),e}function Ue(e){return null!=e?(Ce(this,e),f.updateOffset(this,!0),this):$(this,"Month")}function He(){function e(e,t){return t.length-e.length}for(var t,n=[],s=[],i=[],r=0;r<12;r++)t=_([2e3,r]),n.push(this.monthsShort(t,"")),s.push(this.months(t,"")),i.push(this.months(t,"")),i.push(this.monthsShort(t,""));for(n.sort(e),s.sort(e),i.sort(e),r=0;r<12;r++)n[r]=me(n[r]),s[r]=me(s[r]);for(r=0;r<24;r++)i[r]=me(i[r]);this._monthsRegex=new RegExp("^("+i.join("|")+")","i"),this._monthsShortRegex=this._monthsRegex,this._monthsStrictRegex=new RegExp("^("+s.join("|")+")","i"),this._monthsShortStrictRegex=new RegExp("^("+n.join("|")+")","i")}function Fe(e){return j(e)?366:365}C("Y",0,0,function(){var e=this.year();return e<=9999?T(e,4):"+"+e}),C(0,["YY",2],0,function(){return this.year()%100}),C(0,["YYYY",4],0,"year"),C(0,["YYYYY",5],0,"year"),C(0,["YYYYYY",6,!0],0,"year"),L("year","y"),A("year",1),ce("Y",ue),ce("YY",te,Q),ce("YYYY",re,K),ce("YYYYY",ae,ee),ce("YYYYYY",ae,ee),ye(["YYYYY","YYYYYY"],pe),ye("YYYY",function(e,t){t[pe]=2===e.length?f.parseTwoDigitYear(e):Z(e)}),ye("YY",function(e,t){t[pe]=f.parseTwoDigitYear(e)}),ye("Y",function(e,t){t[pe]=parseInt(e,10)}),f.parseTwoDigitYear=function(e){return Z(e)+(68<Z(e)?1900:2e3)};var Le=z("FullYear",!0);function Ve(e){var t,n;return e<100&&0<=e?((n=Array.prototype.slice.call(arguments))[0]=e+400,t=new Date(Date.UTC.apply(null,n)),isFinite(t.getUTCFullYear())&&t.setUTCFullYear(e)):t=new Date(Date.UTC.apply(null,arguments)),t}function Ge(e,t,n){var s=7+t-n;return s-(7+Ve(e,0,s).getUTCDay()-t)%7-1}function Ee(e,t,n,s,i){var r,a=1+7*(t-1)+(7+n-s)%7+Ge(e,s,i),o=a<=0?Fe(r=e-1)+a:a>Fe(e)?(r=e+1,a-Fe(e)):(r=e,a);return{year:r,dayOfYear:o}}function Ae(e,t,n){var s,i,r=Ge(e.year(),t,n),a=Math.floor((e.dayOfYear()-r-1)/7)+1;return a<1?s=a+je(i=e.year()-1,t,n):a>je(e.year(),t,n)?(s=a-je(e.year(),t,n),i=e.year()+1):(i=e.year(),s=a),{week:s,year:i}}function je(e,t,n){var s=Ge(e,t,n),i=Ge(e+1,t,n);return(Fe(e)-s+i)/7}C("w",["ww",2],"wo","week"),C("W",["WW",2],"Wo","isoWeek"),L("week","w"),L("isoWeek","W"),A("week",5),A("isoWeek",5),ce("w",te),ce("ww",te,Q),ce("W",te),ce("WW",te,Q),ge(["w","ww","W","WW"],function(e,t,n,s){t[s.substr(0,1)]=Z(e)});function Ie(e,t){return e.slice(t,7).concat(e.slice(0,t))}C("d",0,"do","day"),C("dd",0,0,function(e){return this.localeData().weekdaysMin(this,e)}),C("ddd",0,0,function(e){return this.localeData().weekdaysShort(this,e)}),C("dddd",0,0,function(e){return this.localeData().weekdays(this,e)}),C("e",0,0,"weekday"),C("E",0,0,"isoWeekday"),L("day","d"),L("weekday","e"),L("isoWeekday","E"),A("day",11),A("weekday",11),A("isoWeekday",11),ce("d",te),ce("e",te),ce("E",te),ce("dd",function(e,t){return t.weekdaysMinRegex(e)}),ce("ddd",function(e,t){return t.weekdaysShortRegex(e)}),ce("dddd",function(e,t){return t.weekdaysRegex(e)}),ge(["dd","ddd","dddd"],function(e,t,n,s){var i=n._locale.weekdaysParse(e,s,n._strict);null!=i?t.d=i:y(n).invalidWeekday=e}),ge(["d","e","E"],function(e,t,n,s){t[s]=Z(e)});var Ze="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),ze="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),$e="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),qe=de,Be=de,Je=de;function Qe(){function e(e,t){return t.length-e.length}for(var t,n,s,i,r=[],a=[],o=[],u=[],l=0;l<7;l++)t=_([2e3,1]).day(l),n=me(this.weekdaysMin(t,"")),s=me(this.weekdaysShort(t,"")),i=me(this.weekdays(t,"")),r.push(n),a.push(s),o.push(i),u.push(n),u.push(s),u.push(i);r.sort(e),a.sort(e),o.sort(e),u.sort(e),this._weekdaysRegex=new RegExp("^("+u.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+o.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+a.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+r.join("|")+")","i")}function Xe(){return this.hours()%12||12}function Ke(e,t){C(e,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),t)})}function et(e,t){return t._meridiemParse}C("H",["HH",2],0,"hour"),C("h",["hh",2],0,Xe),C("k",["kk",2],0,function(){return this.hours()||24}),C("hmm",0,0,function(){return""+Xe.apply(this)+T(this.minutes(),2)}),C("hmmss",0,0,function(){return""+Xe.apply(this)+T(this.minutes(),2)+T(this.seconds(),2)}),C("Hmm",0,0,function(){return""+this.hours()+T(this.minutes(),2)}),C("Hmmss",0,0,function(){return""+this.hours()+T(this.minutes(),2)+T(this.seconds(),2)}),Ke("a",!0),Ke("A",!1),L("hour","h"),A("hour",13),ce("a",et),ce("A",et),ce("H",te),ce("h",te),ce("k",te),ce("HH",te,Q),ce("hh",te,Q),ce("kk",te,Q),ce("hmm",ne),ce("hmmss",se),ce("Hmm",ne),ce("Hmmss",se),ye(["H","HH"],Me),ye(["k","kk"],function(e,t,n){var s=Z(e);t[Me]=24===s?0:s}),ye(["a","A"],function(e,t,n){n._isPm=n._locale.isPM(e),n._meridiem=e}),ye(["h","hh"],function(e,t,n){t[Me]=Z(e),y(n).bigHour=!0}),ye("hmm",function(e,t,n){var s=e.length-2;t[Me]=Z(e.substr(0,s)),t[De]=Z(e.substr(s)),y(n).bigHour=!0}),ye("hmmss",function(e,t,n){var s=e.length-4,i=e.length-2;t[Me]=Z(e.substr(0,s)),t[De]=Z(e.substr(s,2)),t[Se]=Z(e.substr(i)),y(n).bigHour=!0}),ye("Hmm",function(e,t,n){var s=e.length-2;t[Me]=Z(e.substr(0,s)),t[De]=Z(e.substr(s))}),ye("Hmmss",function(e,t,n){var s=e.length-4,i=e.length-2;t[Me]=Z(e.substr(0,s)),t[De]=Z(e.substr(s,2)),t[Se]=Z(e.substr(i))});var tt=z("Hours",!0);var nt,st={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",w:"a week",ww:"%d weeks",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:Te,monthsShort:Ne,week:{dow:0,doy:6},weekdays:Ze,weekdaysMin:$e,weekdaysShort:ze,meridiemParse:/[ap]\.?m?\.?/i},it={},rt={};function at(e){return e?e.toLowerCase().replace("_","-"):e}function ot(e){for(var t,n,s,i,r=0;r<e.length;){for(t=(i=at(e[r]).split("-")).length,n=(n=at(e[r+1]))?n.split("-"):null;0<t;){if(s=ut(i.slice(0,t).join("-")))return s;if(n&&n.length>=t&&function(e,t){for(var n=Math.min(e.length,t.length),s=0;s<n;s+=1)if(e[s]!==t[s])return s;return n}(i,n)>=t-1)break;t--}r++}return nt}function ut(t){var e;if(void 0===it[t]&&"undefined"!=typeof module&&module&&module.exports)try{e=nt._abbr,require("./locale/"+t),lt(e)}catch(e){it[t]=null}return it[t]}function lt(e,t){var n;return e&&((n=r(t)?dt(e):ht(e,t))?nt=n:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+e+" not found. Did you forget to load it?")),nt._abbr}function ht(e,t){if(null===t)return delete it[e],null;var n,s=st;if(t.abbr=e,null!=it[e])Y("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),s=it[e]._config;else if(null!=t.parentLocale)if(null!=it[t.parentLocale])s=it[t.parentLocale]._config;else{if(null==(n=ut(t.parentLocale)))return rt[t.parentLocale]||(rt[t.parentLocale]=[]),rt[t.parentLocale].push({name:e,config:t}),null;s=n._config}return it[e]=new x(b(s,t)),rt[e]&&rt[e].forEach(function(e){ht(e.name,e.config)}),lt(e),it[e]}function dt(e){var t;if(e&&e._locale&&e._locale._abbr&&(e=e._locale._abbr),!e)return nt;if(!o(e)){if(t=ut(e))return t;e=[e]}return ot(e)}function ct(e){var t,n=e._a;return n&&-2===y(e).overflow&&(t=n[ve]<0||11<n[ve]?ve:n[ke]<1||n[ke]>xe(n[pe],n[ve])?ke:n[Me]<0||24<n[Me]||24===n[Me]&&(0!==n[De]||0!==n[Se]||0!==n[Ye])?Me:n[De]<0||59<n[De]?De:n[Se]<0||59<n[Se]?Se:n[Ye]<0||999<n[Ye]?Ye:-1,y(e)._overflowDayOfYear&&(t<pe||ke<t)&&(t=ke),y(e)._overflowWeeks&&-1===t&&(t=Oe),y(e)._overflowWeekday&&-1===t&&(t=be),y(e).overflow=t),e}var ft=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([+-]\d\d(?::?\d\d)?|\s*Z)?)?$/,mt=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d|))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([+-]\d\d(?::?\d\d)?|\s*Z)?)?$/,_t=/Z|[+-]\d\d(?::?\d\d)?/,yt=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/],["YYYYMM",/\d{6}/,!1],["YYYY",/\d{4}/,!1]],gt=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],wt=/^\/?Date\((-?\d+)/i,pt=/^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/,vt={UT:0,GMT:0,EDT:-240,EST:-300,CDT:-300,CST:-360,MDT:-360,MST:-420,PDT:-420,PST:-480};function kt(e){var t,n,s,i,r,a,o=e._i,u=ft.exec(o)||mt.exec(o);if(u){for(y(e).iso=!0,t=0,n=yt.length;t<n;t++)if(yt[t][1].exec(u[1])){i=yt[t][0],s=!1!==yt[t][2];break}if(null==i)return void(e._isValid=!1);if(u[3]){for(t=0,n=gt.length;t<n;t++)if(gt[t][1].exec(u[3])){r=(u[2]||" ")+gt[t][0];break}if(null==r)return void(e._isValid=!1)}if(!s&&null!=r)return void(e._isValid=!1);if(u[4]){if(!_t.exec(u[4]))return void(e._isValid=!1);a="Z"}e._f=i+(r||"")+(a||""),Ot(e)}else e._isValid=!1}function Mt(e,t,n,s,i,r){var a=[function(e){var t=parseInt(e,10);{if(t<=49)return 2e3+t;if(t<=999)return 1900+t}return t}(e),Ne.indexOf(t),parseInt(n,10),parseInt(s,10),parseInt(i,10)];return r&&a.push(parseInt(r,10)),a}function Dt(e){var t,n,s,i,r=pt.exec(e._i.replace(/\([^)]*\)|[\n\t]/g," ").replace(/(\s\s+)/g," ").replace(/^\s\s*/,"").replace(/\s\s*$/,""));if(r){if(t=Mt(r[4],r[3],r[2],r[5],r[6],r[7]),n=r[1],s=t,i=e,n&&ze.indexOf(n)!==new Date(s[0],s[1],s[2]).getDay()&&(y(i).weekdayMismatch=!0,!void(i._isValid=!1)))return;e._a=t,e._tzm=function(e,t,n){if(e)return vt[e];if(t)return 0;var s=parseInt(n,10),i=s%100;return 60*((s-i)/100)+i}(r[8],r[9],r[10]),e._d=Ve.apply(null,e._a),e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),y(e).rfc2822=!0}else e._isValid=!1}function St(e,t,n){return null!=e?e:null!=t?t:n}function Yt(e){var t,n,s,i,r,a,o,u=[];if(!e._d){for(a=e,o=new Date(f.now()),s=a._useUTC?[o.getUTCFullYear(),o.getUTCMonth(),o.getUTCDate()]:[o.getFullYear(),o.getMonth(),o.getDate()],e._w&&null==e._a[ke]&&null==e._a[ve]&&function(e){var t,n,s,i,r,a,o,u,l;null!=(t=e._w).GG||null!=t.W||null!=t.E?(r=1,a=4,n=St(t.GG,e._a[pe],Ae(Tt(),1,4).year),s=St(t.W,1),((i=St(t.E,1))<1||7<i)&&(u=!0)):(r=e._locale._week.dow,a=e._locale._week.doy,l=Ae(Tt(),r,a),n=St(t.gg,e._a[pe],l.year),s=St(t.w,l.week),null!=t.d?((i=t.d)<0||6<i)&&(u=!0):null!=t.e?(i=t.e+r,(t.e<0||6<t.e)&&(u=!0)):i=r);s<1||s>je(n,r,a)?y(e)._overflowWeeks=!0:null!=u?y(e)._overflowWeekday=!0:(o=Ee(n,s,i,r,a),e._a[pe]=o.year,e._dayOfYear=o.dayOfYear)}(e),null!=e._dayOfYear&&(r=St(e._a[pe],s[pe]),(e._dayOfYear>Fe(r)||0===e._dayOfYear)&&(y(e)._overflowDayOfYear=!0),n=Ve(r,0,e._dayOfYear),e._a[ve]=n.getUTCMonth(),e._a[ke]=n.getUTCDate()),t=0;t<3&&null==e._a[t];++t)e._a[t]=u[t]=s[t];for(;t<7;t++)e._a[t]=u[t]=null==e._a[t]?2===t?1:0:e._a[t];24===e._a[Me]&&0===e._a[De]&&0===e._a[Se]&&0===e._a[Ye]&&(e._nextDay=!0,e._a[Me]=0),e._d=(e._useUTC?Ve:function(e,t,n,s,i,r,a){var o;return e<100&&0<=e?(o=new Date(e+400,t,n,s,i,r,a),isFinite(o.getFullYear())&&o.setFullYear(e)):o=new Date(e,t,n,s,i,r,a),o}).apply(null,u),i=e._useUTC?e._d.getUTCDay():e._d.getDay(),null!=e._tzm&&e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),e._nextDay&&(e._a[Me]=24),e._w&&void 0!==e._w.d&&e._w.d!==i&&(y(e).weekdayMismatch=!0)}}function Ot(e){if(e._f!==f.ISO_8601)if(e._f!==f.RFC_2822){e._a=[],y(e).empty=!0;for(var t,n,s,i,r,a,o,u=""+e._i,l=u.length,h=0,d=H(e._f,e._locale).match(N)||[],c=0;c<d.length;c++)n=d[c],(t=(u.match(fe(n,e))||[])[0])&&(0<(s=u.substr(0,u.indexOf(t))).length&&y(e).unusedInput.push(s),u=u.slice(u.indexOf(t)+t.length),h+=t.length),W[n]?(t?y(e).empty=!1:y(e).unusedTokens.push(n),r=n,o=e,null!=(a=t)&&m(_e,r)&&_e[r](a,o._a,o,r)):e._strict&&!t&&y(e).unusedTokens.push(n);y(e).charsLeftOver=l-h,0<u.length&&y(e).unusedInput.push(u),e._a[Me]<=12&&!0===y(e).bigHour&&0<e._a[Me]&&(y(e).bigHour=void 0),y(e).parsedDateParts=e._a.slice(0),y(e).meridiem=e._meridiem,e._a[Me]=function(e,t,n){var s;if(null==n)return t;return null!=e.meridiemHour?e.meridiemHour(t,n):(null!=e.isPM&&((s=e.isPM(n))&&t<12&&(t+=12),s||12!==t||(t=0)),t)}(e._locale,e._a[Me],e._meridiem),null!==(i=y(e).era)&&(e._a[pe]=e._locale.erasConvertYear(i,e._a[pe])),Yt(e),ct(e)}else Dt(e);else kt(e)}function bt(e){var t,n,s=e._i,i=e._f;return e._locale=e._locale||dt(e._l),null===s||void 0===i&&""===s?w({nullInput:!0}):("string"==typeof s&&(e._i=s=e._locale.preparse(s)),M(s)?new k(ct(s)):(a(s)?e._d=s:o(i)?function(e){var t,n,s,i,r,a,o=!1;if(0===e._f.length)return y(e).invalidFormat=!0,e._d=new Date(NaN);for(i=0;i<e._f.length;i++)r=0,a=!1,t=v({},e),null!=e._useUTC&&(t._useUTC=e._useUTC),t._f=e._f[i],Ot(t),g(t)&&(a=!0),r+=y(t).charsLeftOver,r+=10*y(t).unusedTokens.length,y(t).score=r,o?r<s&&(s=r,n=t):(null==s||r<s||a)&&(s=r,n=t,a&&(o=!0));c(e,n||t)}(e):i?Ot(e):r(n=(t=e)._i)?t._d=new Date(f.now()):a(n)?t._d=new Date(n.valueOf()):"string"==typeof n?function(e){var t=wt.exec(e._i);null===t?(kt(e),!1===e._isValid&&(delete e._isValid,Dt(e),!1===e._isValid&&(delete e._isValid,e._strict?e._isValid=!1:f.createFromInputFallback(e)))):e._d=new Date(+t[1])}(t):o(n)?(t._a=d(n.slice(0),function(e){return parseInt(e,10)}),Yt(t)):u(n)?function(e){var t,n;e._d||(n=void 0===(t=G(e._i)).day?t.date:t.day,e._a=d([t.year,t.month,n,t.hour,t.minute,t.second,t.millisecond],function(e){return e&&parseInt(e,10)}),Yt(e))}(t):h(n)?t._d=new Date(n):f.createFromInputFallback(t),g(e)||(e._d=null),e))}function xt(e,t,n,s,i){var r,a={};return!0!==t&&!1!==t||(s=t,t=void 0),!0!==n&&!1!==n||(s=n,n=void 0),(u(e)&&l(e)||o(e)&&0===e.length)&&(e=void 0),a._isAMomentObject=!0,a._useUTC=a._isUTC=i,a._l=n,a._i=e,a._f=t,a._strict=s,(r=new k(ct(bt(a))))._nextDay&&(r.add(1,"d"),r._nextDay=void 0),r}function Tt(e,t,n,s){return xt(e,t,n,s,!1)}f.createFromInputFallback=n("value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are discouraged. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.",function(e){e._d=new Date(e._i+(e._useUTC?" UTC":""))}),f.ISO_8601=function(){},f.RFC_2822=function(){};var Nt=n("moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var e=Tt.apply(null,arguments);return this.isValid()&&e.isValid()?e<this?this:e:w()}),Pt=n("moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var e=Tt.apply(null,arguments);return this.isValid()&&e.isValid()?this<e?this:e:w()});function Rt(e,t){var n,s;if(1===t.length&&o(t[0])&&(t=t[0]),!t.length)return Tt();for(n=t[0],s=1;s<t.length;++s)t[s].isValid()&&!t[s][e](n)||(n=t[s]);return n}var Wt=["year","quarter","month","week","day","hour","minute","second","millisecond"];function Ct(e){var t=G(e),n=t.year||0,s=t.quarter||0,i=t.month||0,r=t.week||t.isoWeek||0,a=t.day||0,o=t.hour||0,u=t.minute||0,l=t.second||0,h=t.millisecond||0;this._isValid=function(e){var t,n,s=!1;for(t in e)if(m(e,t)&&(-1===we.call(Wt,t)||null!=e[t]&&isNaN(e[t])))return!1;for(n=0;n<Wt.length;++n)if(e[Wt[n]]){if(s)return!1;parseFloat(e[Wt[n]])!==Z(e[Wt[n]])&&(s=!0)}return!0}(t),this._milliseconds=+h+1e3*l+6e4*u+1e3*o*60*60,this._days=+a+7*r,this._months=+i+3*s+12*n,this._data={},this._locale=dt(),this._bubble()}function Ut(e){return e instanceof Ct}function Ht(e){return e<0?-1*Math.round(-1*e):Math.round(e)}function Ft(e,n){C(e,0,0,function(){var e=this.utcOffset(),t="+";return e<0&&(e=-e,t="-"),t+T(~~(e/60),2)+n+T(~~e%60,2)})}Ft("Z",":"),Ft("ZZ",""),ce("Z",he),ce("ZZ",he),ye(["Z","ZZ"],function(e,t,n){n._useUTC=!0,n._tzm=Vt(he,e)});var Lt=/([\+\-]|\d\d)/gi;function Vt(e,t){var n,s,i=(t||"").match(e);return null===i?null:0===(s=60*(n=((i[i.length-1]||[])+"").match(Lt)||["-",0,0])[1]+Z(n[2]))?0:"+"===n[0]?s:-s}function Gt(e,t){var n,s;return t._isUTC?(n=t.clone(),s=(M(e)||a(e)?e.valueOf():Tt(e).valueOf())-n.valueOf(),n._d.setTime(n._d.valueOf()+s),f.updateOffset(n,!1),n):Tt(e).local()}function Et(e){return-Math.round(e._d.getTimezoneOffset())}function At(){return!!this.isValid()&&(this._isUTC&&0===this._offset)}f.updateOffset=function(){};var jt=/^(-|\+)?(?:(\d*)[. ])?(\d+):(\d+)(?::(\d+)(\.\d*)?)?$/,It=/^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/;function Zt(e,t){var n,s,i,r=e,a=null;return Ut(e)?r={ms:e._milliseconds,d:e._days,M:e._months}:h(e)||!isNaN(+e)?(r={},t?r[t]=+e:r.milliseconds=+e):(a=jt.exec(e))?(n="-"===a[1]?-1:1,r={y:0,d:Z(a[ke])*n,h:Z(a[Me])*n,m:Z(a[De])*n,s:Z(a[Se])*n,ms:Z(Ht(1e3*a[Ye]))*n}):(a=It.exec(e))?(n="-"===a[1]?-1:1,r={y:zt(a[2],n),M:zt(a[3],n),w:zt(a[4],n),d:zt(a[5],n),h:zt(a[6],n),m:zt(a[7],n),s:zt(a[8],n)}):null==r?r={}:"object"==typeof r&&("from"in r||"to"in r)&&(i=function(e,t){var n;if(!e.isValid()||!t.isValid())return{milliseconds:0,months:0};t=Gt(t,e),e.isBefore(t)?n=$t(e,t):((n=$t(t,e)).milliseconds=-n.milliseconds,n.months=-n.months);return n}(Tt(r.from),Tt(r.to)),(r={}).ms=i.milliseconds,r.M=i.months),s=new Ct(r),Ut(e)&&m(e,"_locale")&&(s._locale=e._locale),Ut(e)&&m(e,"_isValid")&&(s._isValid=e._isValid),s}function zt(e,t){var n=e&&parseFloat(e.replace(",","."));return(isNaN(n)?0:n)*t}function $t(e,t){var n={};return n.months=t.month()-e.month()+12*(t.year()-e.year()),e.clone().add(n.months,"M").isAfter(t)&&--n.months,n.milliseconds=t-e.clone().add(n.months,"M"),n}function qt(s,i){return function(e,t){var n;return null===t||isNaN(+t)||(Y(i,"moment()."+i+"(period, number) is deprecated. Please use moment()."+i+"(number, period). See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info."),n=e,e=t,t=n),Bt(this,Zt(e,t),s),this}}function Bt(e,t,n,s){var i=t._milliseconds,r=Ht(t._days),a=Ht(t._months);e.isValid()&&(s=null==s||s,a&&Ce(e,$(e,"Month")+a*n),r&&q(e,"Date",$(e,"Date")+r*n),i&&e._d.setTime(e._d.valueOf()+i*n),s&&f.updateOffset(e,r||a))}Zt.fn=Ct.prototype,Zt.invalid=function(){return Zt(NaN)};var Jt=qt(1,"add"),Qt=qt(-1,"subtract");function Xt(e){return"string"==typeof e||e instanceof String}function Kt(e){return M(e)||a(e)||Xt(e)||h(e)||function(t){var e=o(t),n=!1;e&&(n=0===t.filter(function(e){return!h(e)&&Xt(t)}).length);return e&&n}(e)||function(e){var t,n,s=u(e)&&!l(e),i=!1,r=["years","year","y","months","month","M","days","day","d","dates","date","D","hours","hour","h","minutes","minute","m","seconds","second","s","milliseconds","millisecond","ms"];for(t=0;t<r.length;t+=1)n=r[t],i=i||m(e,n);return s&&i}(e)||null==e}function en(e,t){if(e.date()<t.date())return-en(t,e);var n=12*(t.year()-e.year())+(t.month()-e.month()),s=e.clone().add(n,"months"),i=t-s<0?(t-s)/(s-e.clone().add(n-1,"months")):(t-s)/(e.clone().add(1+n,"months")-s);return-(n+i)||0}function tn(e){var t;return void 0===e?this._locale._abbr:(null!=(t=dt(e))&&(this._locale=t),this)}f.defaultFormat="YYYY-MM-DDTHH:mm:ssZ",f.defaultFormatUtc="YYYY-MM-DDTHH:mm:ss[Z]";var nn=n("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(e){return void 0===e?this.localeData():this.locale(e)});function sn(){return this._locale}var rn=126227808e5;function an(e,t){return(e%t+t)%t}function on(e,t,n){return e<100&&0<=e?new Date(e+400,t,n)-rn:new Date(e,t,n).valueOf()}function un(e,t,n){return e<100&&0<=e?Date.UTC(e+400,t,n)-rn:Date.UTC(e,t,n)}function ln(e,t){return t.erasAbbrRegex(e)}function hn(){for(var e=[],t=[],n=[],s=[],i=this.eras(),r=0,a=i.length;r<a;++r)t.push(me(i[r].name)),e.push(me(i[r].abbr)),n.push(me(i[r].narrow)),s.push(me(i[r].name)),s.push(me(i[r].abbr)),s.push(me(i[r].narrow));this._erasRegex=new RegExp("^("+s.join("|")+")","i"),this._erasNameRegex=new RegExp("^("+t.join("|")+")","i"),this._erasAbbrRegex=new RegExp("^("+e.join("|")+")","i"),this._erasNarrowRegex=new RegExp("^("+n.join("|")+")","i")}function dn(e,t){C(0,[e,e.length],0,t)}function cn(e,t,n,s,i){var r;return null==e?Ae(this,s,i).year:((r=je(e,s,i))<t&&(t=r),function(e,t,n,s,i){var r=Ee(e,t,n,s,i),a=Ve(r.year,0,r.dayOfYear);return this.year(a.getUTCFullYear()),this.month(a.getUTCMonth()),this.date(a.getUTCDate()),this}.call(this,e,t,n,s,i))}C("N",0,0,"eraAbbr"),C("NN",0,0,"eraAbbr"),C("NNN",0,0,"eraAbbr"),C("NNNN",0,0,"eraName"),C("NNNNN",0,0,"eraNarrow"),C("y",["y",1],"yo","eraYear"),C("y",["yy",2],0,"eraYear"),C("y",["yyy",3],0,"eraYear"),C("y",["yyyy",4],0,"eraYear"),ce("N",ln),ce("NN",ln),ce("NNN",ln),ce("NNNN",function(e,t){return t.erasNameRegex(e)}),ce("NNNNN",function(e,t){return t.erasNarrowRegex(e)}),ye(["N","NN","NNN","NNNN","NNNNN"],function(e,t,n,s){var i=n._locale.erasParse(e,s,n._strict);i?y(n).era=i:y(n).invalidEra=e}),ce("y",oe),ce("yy",oe),ce("yyy",oe),ce("yyyy",oe),ce("yo",function(e,t){return t._eraYearOrdinalRegex||oe}),ye(["y","yy","yyy","yyyy"],pe),ye(["yo"],function(e,t,n,s){var i;n._locale._eraYearOrdinalRegex&&(i=e.match(n._locale._eraYearOrdinalRegex)),n._locale.eraYearOrdinalParse?t[pe]=n._locale.eraYearOrdinalParse(e,i):t[pe]=parseInt(e,10)}),C(0,["gg",2],0,function(){return this.weekYear()%100}),C(0,["GG",2],0,function(){return this.isoWeekYear()%100}),dn("gggg","weekYear"),dn("ggggg","weekYear"),dn("GGGG","isoWeekYear"),dn("GGGGG","isoWeekYear"),L("weekYear","gg"),L("isoWeekYear","GG"),A("weekYear",1),A("isoWeekYear",1),ce("G",ue),ce("g",ue),ce("GG",te,Q),ce("gg",te,Q),ce("GGGG",re,K),ce("gggg",re,K),ce("GGGGG",ae,ee),ce("ggggg",ae,ee),ge(["gggg","ggggg","GGGG","GGGGG"],function(e,t,n,s){t[s.substr(0,2)]=Z(e)}),ge(["gg","GG"],function(e,t,n,s){t[s]=f.parseTwoDigitYear(e)}),C("Q",0,"Qo","quarter"),L("quarter","Q"),A("quarter",7),ce("Q",J),ye("Q",function(e,t){t[ve]=3*(Z(e)-1)}),C("D",["DD",2],"Do","date"),L("date","D"),A("date",9),ce("D",te),ce("DD",te,Q),ce("Do",function(e,t){return e?t._dayOfMonthOrdinalParse||t._ordinalParse:t._dayOfMonthOrdinalParseLenient}),ye(["D","DD"],ke),ye("Do",function(e,t){t[ke]=Z(e.match(te)[0])});var fn=z("Date",!0);C("DDD",["DDDD",3],"DDDo","dayOfYear"),L("dayOfYear","DDD"),A("dayOfYear",4),ce("DDD",ie),ce("DDDD",X),ye(["DDD","DDDD"],function(e,t,n){n._dayOfYear=Z(e)}),C("m",["mm",2],0,"minute"),L("minute","m"),A("minute",14),ce("m",te),ce("mm",te,Q),ye(["m","mm"],De);var mn=z("Minutes",!1);C("s",["ss",2],0,"second"),L("second","s"),A("second",15),ce("s",te),ce("ss",te,Q),ye(["s","ss"],Se);var _n,yn,gn=z("Seconds",!1);for(C("S",0,0,function(){return~~(this.millisecond()/100)}),C(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),C(0,["SSS",3],0,"millisecond"),C(0,["SSSS",4],0,function(){return 10*this.millisecond()}),C(0,["SSSSS",5],0,function(){return 100*this.millisecond()}),C(0,["SSSSSS",6],0,function(){return 1e3*this.millisecond()}),C(0,["SSSSSSS",7],0,function(){return 1e4*this.millisecond()}),C(0,["SSSSSSSS",8],0,function(){return 1e5*this.millisecond()}),C(0,["SSSSSSSSS",9],0,function(){return 1e6*this.millisecond()}),L("millisecond","ms"),A("millisecond",16),ce("S",ie,J),ce("SS",ie,Q),ce("SSS",ie,X),_n="SSSS";_n.length<=9;_n+="S")ce(_n,oe);function wn(e,t){t[Ye]=Z(1e3*("0."+e))}for(_n="S";_n.length<=9;_n+="S")ye(_n,wn);yn=z("Milliseconds",!1),C("z",0,0,"zoneAbbr"),C("zz",0,0,"zoneName");var pn=k.prototype;function vn(e){return e}pn.add=Jt,pn.calendar=function(e,t){1===arguments.length&&(arguments[0]?Kt(arguments[0])?(e=arguments[0],t=void 0):function(e){for(var t=u(e)&&!l(e),n=!1,s=["sameDay","nextDay","lastDay","nextWeek","lastWeek","sameElse"],i=0;i<s.length;i+=1)n=n||m(e,s[i]);return t&&n}(arguments[0])&&(t=arguments[0],e=void 0):t=e=void 0);var n=e||Tt(),s=Gt(n,this).startOf("day"),i=f.calendarFormat(this,s)||"sameElse",r=t&&(O(t[i])?t[i].call(this,n):t[i]);return this.format(r||this.localeData().calendar(i,this,Tt(n)))},pn.clone=function(){return new k(this)},pn.diff=function(e,t,n){var s,i,r;if(!this.isValid())return NaN;if(!(s=Gt(e,this)).isValid())return NaN;switch(i=6e4*(s.utcOffset()-this.utcOffset()),t=V(t)){case"year":r=en(this,s)/12;break;case"month":r=en(this,s);break;case"quarter":r=en(this,s)/3;break;case"second":r=(this-s)/1e3;break;case"minute":r=(this-s)/6e4;break;case"hour":r=(this-s)/36e5;break;case"day":r=(this-s-i)/864e5;break;case"week":r=(this-s-i)/6048e5;break;default:r=this-s}return n?r:I(r)},pn.endOf=function(e){var t,n;if(void 0===(e=V(e))||"millisecond"===e||!this.isValid())return this;switch(n=this._isUTC?un:on,e){case"year":t=n(this.year()+1,0,1)-1;break;case"quarter":t=n(this.year(),this.month()-this.month()%3+3,1)-1;break;case"month":t=n(this.year(),this.month()+1,1)-1;break;case"week":t=n(this.year(),this.month(),this.date()-this.weekday()+7)-1;break;case"isoWeek":t=n(this.year(),this.month(),this.date()-(this.isoWeekday()-1)+7)-1;break;case"day":case"date":t=n(this.year(),this.month(),this.date()+1)-1;break;case"hour":t=this._d.valueOf(),t+=36e5-an(t+(this._isUTC?0:6e4*this.utcOffset()),36e5)-1;break;case"minute":t=this._d.valueOf(),t+=6e4-an(t,6e4)-1;break;case"second":t=this._d.valueOf(),t+=1e3-an(t,1e3)-1;break}return this._d.setTime(t),f.updateOffset(this,!0),this},pn.format=function(e){e=e||(this.isUtc()?f.defaultFormatUtc:f.defaultFormat);var t=U(this,e);return this.localeData().postformat(t)},pn.from=function(e,t){return this.isValid()&&(M(e)&&e.isValid()||Tt(e).isValid())?Zt({to:this,from:e}).locale(this.locale()).humanize(!t):this.localeData().invalidDate()},pn.fromNow=function(e){return this.from(Tt(),e)},pn.to=function(e,t){return this.isValid()&&(M(e)&&e.isValid()||Tt(e).isValid())?Zt({from:this,to:e}).locale(this.locale()).humanize(!t):this.localeData().invalidDate()},pn.toNow=function(e){return this.to(Tt(),e)},pn.get=function(e){return O(this[e=V(e)])?this[e]():this},pn.invalidAt=function(){return y(this).overflow},pn.isAfter=function(e,t){var n=M(e)?e:Tt(e);return!(!this.isValid()||!n.isValid())&&("millisecond"===(t=V(t)||"millisecond")?this.valueOf()>n.valueOf():n.valueOf()<this.clone().startOf(t).valueOf())},pn.isBefore=function(e,t){var n=M(e)?e:Tt(e);return!(!this.isValid()||!n.isValid())&&("millisecond"===(t=V(t)||"millisecond")?this.valueOf()<n.valueOf():this.clone().endOf(t).valueOf()<n.valueOf())},pn.isBetween=function(e,t,n,s){var i=M(e)?e:Tt(e),r=M(t)?t:Tt(t);return!!(this.isValid()&&i.isValid()&&r.isValid())&&(("("===(s=s||"()")[0]?this.isAfter(i,n):!this.isBefore(i,n))&&(")"===s[1]?this.isBefore(r,n):!this.isAfter(r,n)))},pn.isSame=function(e,t){var n,s=M(e)?e:Tt(e);return!(!this.isValid()||!s.isValid())&&("millisecond"===(t=V(t)||"millisecond")?this.valueOf()===s.valueOf():(n=s.valueOf(),this.clone().startOf(t).valueOf()<=n&&n<=this.clone().endOf(t).valueOf()))},pn.isSameOrAfter=function(e,t){return this.isSame(e,t)||this.isAfter(e,t)},pn.isSameOrBefore=function(e,t){return this.isSame(e,t)||this.isBefore(e,t)},pn.isValid=function(){return g(this)},pn.lang=nn,pn.locale=tn,pn.localeData=sn,pn.max=Pt,pn.min=Nt,pn.parsingFlags=function(){return c({},y(this))},pn.set=function(e,t){if("object"==typeof e)for(var n=function(e){var t,n=[];for(t in e)m(e,t)&&n.push({unit:t,priority:E[t]});return n.sort(function(e,t){return e.priority-t.priority}),n}(e=G(e)),s=0;s<n.length;s++)this[n[s].unit](e[n[s].unit]);else if(O(this[e=V(e)]))return this[e](t);return this},pn.startOf=function(e){var t,n;if(void 0===(e=V(e))||"millisecond"===e||!this.isValid())return this;switch(n=this._isUTC?un:on,e){case"year":t=n(this.year(),0,1);break;case"quarter":t=n(this.year(),this.month()-this.month()%3,1);break;case"month":t=n(this.year(),this.month(),1);break;case"week":t=n(this.year(),this.month(),this.date()-this.weekday());break;case"isoWeek":t=n(this.year(),this.month(),this.date()-(this.isoWeekday()-1));break;case"day":case"date":t=n(this.year(),this.month(),this.date());break;case"hour":t=this._d.valueOf(),t-=an(t+(this._isUTC?0:6e4*this.utcOffset()),36e5);break;case"minute":t=this._d.valueOf(),t-=an(t,6e4);break;case"second":t=this._d.valueOf(),t-=an(t,1e3);break}return this._d.setTime(t),f.updateOffset(this,!0),this},pn.subtract=Qt,pn.toArray=function(){var e=this;return[e.year(),e.month(),e.date(),e.hour(),e.minute(),e.second(),e.millisecond()]},pn.toObject=function(){var e=this;return{years:e.year(),months:e.month(),date:e.date(),hours:e.hours(),minutes:e.minutes(),seconds:e.seconds(),milliseconds:e.milliseconds()}},pn.toDate=function(){return new Date(this.valueOf())},pn.toISOString=function(e){if(!this.isValid())return null;var t=!0!==e,n=t?this.clone().utc():this;return n.year()<0||9999<n.year()?U(n,t?"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYYYY-MM-DD[T]HH:mm:ss.SSSZ"):O(Date.prototype.toISOString)?t?this.toDate().toISOString():new Date(this.valueOf()+60*this.utcOffset()*1e3).toISOString().replace("Z",U(n,"Z")):U(n,t?"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYY-MM-DD[T]HH:mm:ss.SSSZ")},pn.inspect=function(){if(!this.isValid())return"moment.invalid(/* "+this._i+" */)";var e,t,n,s="moment",i="";return this.isLocal()||(s=0===this.utcOffset()?"moment.utc":"moment.parseZone",i="Z"),e="["+s+'("]',t=0<=this.year()&&this.year()<=9999?"YYYY":"YYYYYY",n=i+'[")]',this.format(e+t+"-MM-DD[T]HH:mm:ss.SSS"+n)},"undefined"!=typeof Symbol&&null!=Symbol.for&&(pn[Symbol.for("nodejs.util.inspect.custom")]=function(){return"Moment<"+this.format()+">"}),pn.toJSON=function(){return this.isValid()?this.toISOString():null},pn.toString=function(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},pn.unix=function(){return Math.floor(this.valueOf()/1e3)},pn.valueOf=function(){return this._d.valueOf()-6e4*(this._offset||0)},pn.creationData=function(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}},pn.eraName=function(){for(var e,t=this.localeData().eras(),n=0,s=t.length;n<s;++n){if(e=this.clone().startOf("day").valueOf(),t[n].since<=e&&e<=t[n].until)return t[n].name;if(t[n].until<=e&&e<=t[n].since)return t[n].name}return""},pn.eraNarrow=function(){for(var e,t=this.localeData().eras(),n=0,s=t.length;n<s;++n){if(e=this.clone().startOf("day").valueOf(),t[n].since<=e&&e<=t[n].until)return t[n].narrow;if(t[n].until<=e&&e<=t[n].since)return t[n].narrow}return""},pn.eraAbbr=function(){for(var e,t=this.localeData().eras(),n=0,s=t.length;n<s;++n){if(e=this.clone().startOf("day").valueOf(),t[n].since<=e&&e<=t[n].until)return t[n].abbr;if(t[n].until<=e&&e<=t[n].since)return t[n].abbr}return""},pn.eraYear=function(){for(var e,t,n=this.localeData().eras(),s=0,i=n.length;s<i;++s)if(e=n[s].since<=n[s].until?1:-1,t=this.clone().startOf("day").valueOf(),n[s].since<=t&&t<=n[s].until||n[s].until<=t&&t<=n[s].since)return(this.year()-f(n[s].since).year())*e+n[s].offset;return this.year()},pn.year=Le,pn.isLeapYear=function(){return j(this.year())},pn.weekYear=function(e){return cn.call(this,e,this.week(),this.weekday(),this.localeData()._week.dow,this.localeData()._week.doy)},pn.isoWeekYear=function(e){return cn.call(this,e,this.isoWeek(),this.isoWeekday(),1,4)},pn.quarter=pn.quarters=function(e){return null==e?Math.ceil((this.month()+1)/3):this.month(3*(e-1)+this.month()%3)},pn.month=Ue,pn.daysInMonth=function(){return xe(this.year(),this.month())},pn.week=pn.weeks=function(e){var t=this.localeData().week(this);return null==e?t:this.add(7*(e-t),"d")},pn.isoWeek=pn.isoWeeks=function(e){var t=Ae(this,1,4).week;return null==e?t:this.add(7*(e-t),"d")},pn.weeksInYear=function(){var e=this.localeData()._week;return je(this.year(),e.dow,e.doy)},pn.weeksInWeekYear=function(){var e=this.localeData()._week;return je(this.weekYear(),e.dow,e.doy)},pn.isoWeeksInYear=function(){return je(this.year(),1,4)},pn.isoWeeksInISOWeekYear=function(){return je(this.isoWeekYear(),1,4)},pn.date=fn,pn.day=pn.days=function(e){if(!this.isValid())return null!=e?this:NaN;var t,n,s=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=e?(t=e,n=this.localeData(),e="string"!=typeof t?t:isNaN(t)?"number"==typeof(t=n.weekdaysParse(t))?t:null:parseInt(t,10),this.add(e-s,"d")):s},pn.weekday=function(e){if(!this.isValid())return null!=e?this:NaN;var t=(this.day()+7-this.localeData()._week.dow)%7;return null==e?t:this.add(e-t,"d")},pn.isoWeekday=function(e){if(!this.isValid())return null!=e?this:NaN;if(null==e)return this.day()||7;var t,n,s=(t=e,n=this.localeData(),"string"==typeof t?n.weekdaysParse(t)%7||7:isNaN(t)?null:t);return this.day(this.day()%7?s:s-7)},pn.dayOfYear=function(e){var t=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==e?t:this.add(e-t,"d")},pn.hour=pn.hours=tt,pn.minute=pn.minutes=mn,pn.second=pn.seconds=gn,pn.millisecond=pn.milliseconds=yn,pn.utcOffset=function(e,t,n){var s,i=this._offset||0;if(!this.isValid())return null!=e?this:NaN;if(null==e)return this._isUTC?i:Et(this);if("string"==typeof e){if(null===(e=Vt(he,e)))return this}else Math.abs(e)<16&&!n&&(e*=60);return!this._isUTC&&t&&(s=Et(this)),this._offset=e,this._isUTC=!0,null!=s&&this.add(s,"m"),i!==e&&(!t||this._changeInProgress?Bt(this,Zt(e-i,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,f.updateOffset(this,!0),this._changeInProgress=null)),this},pn.utc=function(e){return this.utcOffset(0,e)},pn.local=function(e){return this._isUTC&&(this.utcOffset(0,e),this._isUTC=!1,e&&this.subtract(Et(this),"m")),this},pn.parseZone=function(){var e;return null!=this._tzm?this.utcOffset(this._tzm,!1,!0):"string"==typeof this._i&&(null!=(e=Vt(le,this._i))?this.utcOffset(e):this.utcOffset(0,!0)),this},pn.hasAlignedHourOffset=function(e){return!!this.isValid()&&(e=e?Tt(e).utcOffset():0,(this.utcOffset()-e)%60==0)},pn.isDST=function(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},pn.isLocal=function(){return!!this.isValid()&&!this._isUTC},pn.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},pn.isUtc=At,pn.isUTC=At,pn.zoneAbbr=function(){return this._isUTC?"UTC":""},pn.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},pn.dates=n("dates accessor is deprecated. Use date instead.",fn),pn.months=n("months accessor is deprecated. Use month instead",Ue),pn.years=n("years accessor is deprecated. Use year instead",Le),pn.zone=n("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",function(e,t){return null!=e?("string"!=typeof e&&(e=-e),this.utcOffset(e,t),this):-this.utcOffset()}),pn.isDSTShifted=n("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",function(){if(!r(this._isDSTShifted))return this._isDSTShifted;var e,t={};return v(t,this),(t=bt(t))._a?(e=(t._isUTC?_:Tt)(t._a),this._isDSTShifted=this.isValid()&&0<function(e,t,n){for(var s=Math.min(e.length,t.length),i=Math.abs(e.length-t.length),r=0,a=0;a<s;a++)(n&&e[a]!==t[a]||!n&&Z(e[a])!==Z(t[a]))&&r++;return r+i}(t._a,e.toArray())):this._isDSTShifted=!1,this._isDSTShifted});var kn=x.prototype;function Mn(e,t,n,s){var i=dt(),r=_().set(s,t);return i[n](r,e)}function Dn(e,t,n){if(h(e)&&(t=e,e=void 0),e=e||"",null!=t)return Mn(e,t,n,"month");for(var s=[],i=0;i<12;i++)s[i]=Mn(e,i,n,"month");return s}function Sn(e,t,n,s){t=("boolean"==typeof e?h(t)&&(n=t,t=void 0):(t=e,e=!1,h(n=t)&&(n=t,t=void 0)),t||"");var i,r=dt(),a=e?r._week.dow:0,o=[];if(null!=n)return Mn(t,(n+a)%7,s,"day");for(i=0;i<7;i++)o[i]=Mn(t,(i+a)%7,s,"day");return o}kn.calendar=function(e,t,n){var s=this._calendar[e]||this._calendar.sameElse;return O(s)?s.call(t,n):s},kn.longDateFormat=function(e){var t=this._longDateFormat[e],n=this._longDateFormat[e.toUpperCase()];return t||!n?t:(this._longDateFormat[e]=n.match(N).map(function(e){return"MMMM"===e||"MM"===e||"DD"===e||"dddd"===e?e.slice(1):e}).join(""),this._longDateFormat[e])},kn.invalidDate=function(){return this._invalidDate},kn.ordinal=function(e){return this._ordinal.replace("%d",e)},kn.preparse=vn,kn.postformat=vn,kn.relativeTime=function(e,t,n,s){var i=this._relativeTime[n];return O(i)?i(e,t,n,s):i.replace(/%d/i,e)},kn.pastFuture=function(e,t){var n=this._relativeTime[0<e?"future":"past"];return O(n)?n(t):n.replace(/%s/i,t)},kn.set=function(e){var t,n;for(n in e)m(e,n)&&(O(t=e[n])?this[n]=t:this["_"+n]=t);this._config=e,this._dayOfMonthOrdinalParseLenient=new RegExp((this._dayOfMonthOrdinalParse.source||this._ordinalParse.source)+"|"+/\d{1,2}/.source)},kn.eras=function(e,t){for(var n,s=this._eras||dt("en")._eras,i=0,r=s.length;i<r;++i){switch(typeof s[i].since){case"string":n=f(s[i].since).startOf("day"),s[i].since=n.valueOf();break}switch(typeof s[i].until){case"undefined":s[i].until=1/0;break;case"string":n=f(s[i].until).startOf("day").valueOf(),s[i].until=n.valueOf();break}}return s},kn.erasParse=function(e,t,n){var s,i,r,a,o,u=this.eras();for(e=e.toUpperCase(),s=0,i=u.length;s<i;++s)if(r=u[s].name.toUpperCase(),a=u[s].abbr.toUpperCase(),o=u[s].narrow.toUpperCase(),n)switch(t){case"N":case"NN":case"NNN":if(a===e)return u[s];break;case"NNNN":if(r===e)return u[s];break;case"NNNNN":if(o===e)return u[s];break}else if(0<=[r,a,o].indexOf(e))return u[s]},kn.erasConvertYear=function(e,t){var n=e.since<=e.until?1:-1;return void 0===t?f(e.since).year():f(e.since).year()+(t-e.offset)*n},kn.erasAbbrRegex=function(e){return m(this,"_erasAbbrRegex")||hn.call(this),e?this._erasAbbrRegex:this._erasRegex},kn.erasNameRegex=function(e){return m(this,"_erasNameRegex")||hn.call(this),e?this._erasNameRegex:this._erasRegex},kn.erasNarrowRegex=function(e){return m(this,"_erasNarrowRegex")||hn.call(this),e?this._erasNarrowRegex:this._erasRegex},kn.months=function(e,t){return e?o(this._months)?this._months[e.month()]:this._months[(this._months.isFormat||Pe).test(t)?"format":"standalone"][e.month()]:o(this._months)?this._months:this._months.standalone},kn.monthsShort=function(e,t){return e?o(this._monthsShort)?this._monthsShort[e.month()]:this._monthsShort[Pe.test(t)?"format":"standalone"][e.month()]:o(this._monthsShort)?this._monthsShort:this._monthsShort.standalone},kn.monthsParse=function(e,t,n){var s,i,r;if(this._monthsParseExact)return function(e,t,n){var s,i,r,a=e.toLocaleLowerCase();if(!this._monthsParse)for(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[],s=0;s<12;++s)r=_([2e3,s]),this._shortMonthsParse[s]=this.monthsShort(r,"").toLocaleLowerCase(),this._longMonthsParse[s]=this.months(r,"").toLocaleLowerCase();return n?"MMM"===t?-1!==(i=we.call(this._shortMonthsParse,a))?i:null:-1!==(i=we.call(this._longMonthsParse,a))?i:null:"MMM"===t?-1!==(i=we.call(this._shortMonthsParse,a))||-1!==(i=we.call(this._longMonthsParse,a))?i:null:-1!==(i=we.call(this._longMonthsParse,a))||-1!==(i=we.call(this._shortMonthsParse,a))?i:null}.call(this,e,t,n);for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),s=0;s<12;s++){if(i=_([2e3,s]),n&&!this._longMonthsParse[s]&&(this._longMonthsParse[s]=new RegExp("^"+this.months(i,"").replace(".","")+"$","i"),this._shortMonthsParse[s]=new RegExp("^"+this.monthsShort(i,"").replace(".","")+"$","i")),n||this._monthsParse[s]||(r="^"+this.months(i,"")+"|^"+this.monthsShort(i,""),this._monthsParse[s]=new RegExp(r.replace(".",""),"i")),n&&"MMMM"===t&&this._longMonthsParse[s].test(e))return s;if(n&&"MMM"===t&&this._shortMonthsParse[s].test(e))return s;if(!n&&this._monthsParse[s].test(e))return s}},kn.monthsRegex=function(e){return this._monthsParseExact?(m(this,"_monthsRegex")||He.call(this),e?this._monthsStrictRegex:this._monthsRegex):(m(this,"_monthsRegex")||(this._monthsRegex=We),this._monthsStrictRegex&&e?this._monthsStrictRegex:this._monthsRegex)},kn.monthsShortRegex=function(e){return this._monthsParseExact?(m(this,"_monthsRegex")||He.call(this),e?this._monthsShortStrictRegex:this._monthsShortRegex):(m(this,"_monthsShortRegex")||(this._monthsShortRegex=Re),this._monthsShortStrictRegex&&e?this._monthsShortStrictRegex:this._monthsShortRegex)},kn.week=function(e){return Ae(e,this._week.dow,this._week.doy).week},kn.firstDayOfYear=function(){return this._week.doy},kn.firstDayOfWeek=function(){return this._week.dow},kn.weekdays=function(e,t){var n=o(this._weekdays)?this._weekdays:this._weekdays[e&&!0!==e&&this._weekdays.isFormat.test(t)?"format":"standalone"];return!0===e?Ie(n,this._week.dow):e?n[e.day()]:n},kn.weekdaysMin=function(e){return!0===e?Ie(this._weekdaysMin,this._week.dow):e?this._weekdaysMin[e.day()]:this._weekdaysMin},kn.weekdaysShort=function(e){return!0===e?Ie(this._weekdaysShort,this._week.dow):e?this._weekdaysShort[e.day()]:this._weekdaysShort},kn.weekdaysParse=function(e,t,n){var s,i,r;if(this._weekdaysParseExact)return function(e,t,n){var s,i,r,a=e.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],s=0;s<7;++s)r=_([2e3,1]).day(s),this._minWeekdaysParse[s]=this.weekdaysMin(r,"").toLocaleLowerCase(),this._shortWeekdaysParse[s]=this.weekdaysShort(r,"").toLocaleLowerCase(),this._weekdaysParse[s]=this.weekdays(r,"").toLocaleLowerCase();return n?"dddd"===t?-1!==(i=we.call(this._weekdaysParse,a))?i:null:"ddd"===t?-1!==(i=we.call(this._shortWeekdaysParse,a))?i:null:-1!==(i=we.call(this._minWeekdaysParse,a))?i:null:"dddd"===t?-1!==(i=we.call(this._weekdaysParse,a))||-1!==(i=we.call(this._shortWeekdaysParse,a))||-1!==(i=we.call(this._minWeekdaysParse,a))?i:null:"ddd"===t?-1!==(i=we.call(this._shortWeekdaysParse,a))||-1!==(i=we.call(this._weekdaysParse,a))||-1!==(i=we.call(this._minWeekdaysParse,a))?i:null:-1!==(i=we.call(this._minWeekdaysParse,a))||-1!==(i=we.call(this._weekdaysParse,a))||-1!==(i=we.call(this._shortWeekdaysParse,a))?i:null}.call(this,e,t,n);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),s=0;s<7;s++){if(i=_([2e3,1]).day(s),n&&!this._fullWeekdaysParse[s]&&(this._fullWeekdaysParse[s]=new RegExp("^"+this.weekdays(i,"").replace(".","\\.?")+"$","i"),this._shortWeekdaysParse[s]=new RegExp("^"+this.weekdaysShort(i,"").replace(".","\\.?")+"$","i"),this._minWeekdaysParse[s]=new RegExp("^"+this.weekdaysMin(i,"").replace(".","\\.?")+"$","i")),this._weekdaysParse[s]||(r="^"+this.weekdays(i,"")+"|^"+this.weekdaysShort(i,"")+"|^"+this.weekdaysMin(i,""),this._weekdaysParse[s]=new RegExp(r.replace(".",""),"i")),n&&"dddd"===t&&this._fullWeekdaysParse[s].test(e))return s;if(n&&"ddd"===t&&this._shortWeekdaysParse[s].test(e))return s;if(n&&"dd"===t&&this._minWeekdaysParse[s].test(e))return s;if(!n&&this._weekdaysParse[s].test(e))return s}},kn.weekdaysRegex=function(e){return this._weekdaysParseExact?(m(this,"_weekdaysRegex")||Qe.call(this),e?this._weekdaysStrictRegex:this._weekdaysRegex):(m(this,"_weekdaysRegex")||(this._weekdaysRegex=qe),this._weekdaysStrictRegex&&e?this._weekdaysStrictRegex:this._weekdaysRegex)},kn.weekdaysShortRegex=function(e){return this._weekdaysParseExact?(m(this,"_weekdaysRegex")||Qe.call(this),e?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):(m(this,"_weekdaysShortRegex")||(this._weekdaysShortRegex=Be),this._weekdaysShortStrictRegex&&e?this._weekdaysShortStrictRegex:this._weekdaysShortRegex)},kn.weekdaysMinRegex=function(e){return this._weekdaysParseExact?(m(this,"_weekdaysRegex")||Qe.call(this),e?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):(m(this,"_weekdaysMinRegex")||(this._weekdaysMinRegex=Je),this._weekdaysMinStrictRegex&&e?this._weekdaysMinStrictRegex:this._weekdaysMinRegex)},kn.isPM=function(e){return"p"===(e+"").toLowerCase().charAt(0)},kn.meridiem=function(e,t,n){return 11<e?n?"pm":"PM":n?"am":"AM"},lt("en",{eras:[{since:"0001-01-01",until:1/0,offset:1,name:"Anno Domini",narrow:"AD",abbr:"AD"},{since:"0000-12-31",until:-1/0,offset:1,name:"Before Christ",narrow:"BC",abbr:"BC"}],dayOfMonthOrdinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(e){var t=e%10;return e+(1===Z(e%100/10)?"th":1==t?"st":2==t?"nd":3==t?"rd":"th")}}),f.lang=n("moment.lang is deprecated. Use moment.locale instead.",lt),f.langData=n("moment.langData is deprecated. Use moment.localeData instead.",dt);var Yn=Math.abs;function On(e,t,n,s){var i=Zt(t,n);return e._milliseconds+=s*i._milliseconds,e._days+=s*i._days,e._months+=s*i._months,e._bubble()}function bn(e){return e<0?Math.floor(e):Math.ceil(e)}function xn(e){return 4800*e/146097}function Tn(e){return 146097*e/4800}function Nn(e){return function(){return this.as(e)}}var Pn=Nn("ms"),Rn=Nn("s"),Wn=Nn("m"),Cn=Nn("h"),Un=Nn("d"),Hn=Nn("w"),Fn=Nn("M"),Ln=Nn("Q"),Vn=Nn("y");function Gn(e){return function(){return this.isValid()?this._data[e]:NaN}}var En=Gn("milliseconds"),An=Gn("seconds"),jn=Gn("minutes"),In=Gn("hours"),Zn=Gn("days"),zn=Gn("months"),$n=Gn("years");var qn=Math.round,Bn={ss:44,s:45,m:45,h:22,d:26,w:null,M:11};function Jn(e,t,n,s){var i=Zt(e).abs(),r=qn(i.as("s")),a=qn(i.as("m")),o=qn(i.as("h")),u=qn(i.as("d")),l=qn(i.as("M")),h=qn(i.as("w")),d=qn(i.as("y")),c=(r<=n.ss?["s",r]:r<n.s&&["ss",r])||a<=1&&["m"]||a<n.m&&["mm",a]||o<=1&&["h"]||o<n.h&&["hh",o]||u<=1&&["d"]||u<n.d&&["dd",u];return null!=n.w&&(c=c||h<=1&&["w"]||h<n.w&&["ww",h]),(c=c||l<=1&&["M"]||l<n.M&&["MM",l]||d<=1&&["y"]||["yy",d])[2]=t,c[3]=0<+e,c[4]=s,function(e,t,n,s,i){return i.relativeTime(t||1,!!n,e,s)}.apply(null,c)}var Qn=Math.abs;function Xn(e){return(0<e)-(e<0)||+e}function Kn(){if(!this.isValid())return this.localeData().invalidDate();var e,t,n,s,i,r,a,o,u=Qn(this._milliseconds)/1e3,l=Qn(this._days),h=Qn(this._months),d=this.asSeconds();return d?(e=I(u/60),t=I(e/60),u%=60,e%=60,n=I(h/12),h%=12,s=u?u.toFixed(3).replace(/\.?0+$/,""):"",i=d<0?"-":"",r=Xn(this._months)!==Xn(d)?"-":"",a=Xn(this._days)!==Xn(d)?"-":"",o=Xn(this._milliseconds)!==Xn(d)?"-":"",i+"P"+(n?r+n+"Y":"")+(h?r+h+"M":"")+(l?a+l+"D":"")+(t||e||u?"T":"")+(t?o+t+"H":"")+(e?o+e+"M":"")+(u?o+s+"S":"")):"P0D"}var es=Ct.prototype;return es.isValid=function(){return this._isValid},es.abs=function(){var e=this._data;return this._milliseconds=Yn(this._milliseconds),this._days=Yn(this._days),this._months=Yn(this._months),e.milliseconds=Yn(e.milliseconds),e.seconds=Yn(e.seconds),e.minutes=Yn(e.minutes),e.hours=Yn(e.hours),e.months=Yn(e.months),e.years=Yn(e.years),this},es.add=function(e,t){return On(this,e,t,1)},es.subtract=function(e,t){return On(this,e,t,-1)},es.as=function(e){if(!this.isValid())return NaN;var t,n,s=this._milliseconds;if("month"===(e=V(e))||"quarter"===e||"year"===e)switch(t=this._days+s/864e5,n=this._months+xn(t),e){case"month":return n;case"quarter":return n/3;case"year":return n/12}else switch(t=this._days+Math.round(Tn(this._months)),e){case"week":return t/7+s/6048e5;case"day":return t+s/864e5;case"hour":return 24*t+s/36e5;case"minute":return 1440*t+s/6e4;case"second":return 86400*t+s/1e3;case"millisecond":return Math.floor(864e5*t)+s;default:throw new Error("Unknown unit "+e)}},es.asMilliseconds=Pn,es.asSeconds=Rn,es.asMinutes=Wn,es.asHours=Cn,es.asDays=Un,es.asWeeks=Hn,es.asMonths=Fn,es.asQuarters=Ln,es.asYears=Vn,es.valueOf=function(){return this.isValid()?this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*Z(this._months/12):NaN},es._bubble=function(){var e,t,n,s,i,r=this._milliseconds,a=this._days,o=this._months,u=this._data;return 0<=r&&0<=a&&0<=o||r<=0&&a<=0&&o<=0||(r+=864e5*bn(Tn(o)+a),o=a=0),u.milliseconds=r%1e3,e=I(r/1e3),u.seconds=e%60,t=I(e/60),u.minutes=t%60,n=I(t/60),u.hours=n%24,a+=I(n/24),o+=i=I(xn(a)),a-=bn(Tn(i)),s=I(o/12),o%=12,u.days=a,u.months=o,u.years=s,this},es.clone=function(){return Zt(this)},es.get=function(e){return e=V(e),this.isValid()?this[e+"s"]():NaN},es.milliseconds=En,es.seconds=An,es.minutes=jn,es.hours=In,es.days=Zn,es.weeks=function(){return I(this.days()/7)},es.months=zn,es.years=$n,es.humanize=function(e,t){if(!this.isValid())return this.localeData().invalidDate();var n,s,i=!1,r=Bn;return"object"==typeof e&&(t=e,e=!1),"boolean"==typeof e&&(i=e),"object"==typeof t&&(r=Object.assign({},Bn,t),null!=t.s&&null==t.ss&&(r.ss=t.s-1)),n=this.localeData(),s=Jn(this,!i,r,n),i&&(s=n.pastFuture(+this,s)),n.postformat(s)},es.toISOString=Kn,es.toString=Kn,es.toJSON=Kn,es.locale=tn,es.localeData=sn,es.toIsoString=n("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",Kn),es.lang=nn,C("X",0,0,"unix"),C("x",0,0,"valueOf"),ce("x",ue),ce("X",/[+-]?\d+(\.\d{1,3})?/),ye("X",function(e,t,n){n._d=new Date(1e3*parseFloat(e))}),ye("x",function(e,t,n){n._d=new Date(Z(e))}),f.version="2.29.1",e=Tt,f.fn=pn,f.min=function(){return Rt("isBefore",[].slice.call(arguments,0))},f.max=function(){return Rt("isAfter",[].slice.call(arguments,0))},f.now=function(){return Date.now?Date.now():+new Date},f.utc=_,f.unix=function(e){return Tt(1e3*e)},f.months=function(e,t){return Dn(e,t,"months")},f.isDate=a,f.locale=lt,f.invalid=w,f.duration=Zt,f.isMoment=M,f.weekdays=function(e,t,n){return Sn(e,t,n,"weekdays")},f.parseZone=function(){return Tt.apply(null,arguments).parseZone()},f.localeData=dt,f.isDuration=Ut,f.monthsShort=function(e,t){return Dn(e,t,"monthsShort")},f.weekdaysMin=function(e,t,n){return Sn(e,t,n,"weekdaysMin")},f.defineLocale=ht,f.updateLocale=function(e,t){var n,s,i;return null!=t?(i=st,null!=it[e]&&null!=it[e].parentLocale?it[e].set(b(it[e]._config,t)):(null!=(s=ut(e))&&(i=s._config),t=b(i,t),null==s&&(t.abbr=e),(n=new x(t)).parentLocale=it[e],it[e]=n),lt(e)):null!=it[e]&&(null!=it[e].parentLocale?(it[e]=it[e].parentLocale,e===lt()&<(e)):null!=it[e]&&delete it[e]),it[e]},f.locales=function(){return s(it)},f.weekdaysShort=function(e,t,n){return Sn(e,t,n,"weekdaysShort")},f.normalizeUnits=V,f.relativeTimeRounding=function(e){return void 0===e?qn:"function"==typeof e&&(qn=e,!0)},f.relativeTimeThreshold=function(e,t){return void 0!==Bn[e]&&(void 0===t?Bn[e]:(Bn[e]=t,"s"===e&&(Bn.ss=t-1),!0))},f.calendarFormat=function(e,t){var n=e.diff(t,"days",!0);return n<-6?"sameElse":n<-1?"lastWeek":n<0?"lastDay":n<1?"sameDay":n<2?"nextDay":n<7?"nextWeek":"sameElse"},f.prototype=pn,f.HTML5_FMT={DATETIME_LOCAL:"YYYY-MM-DDTHH:mm",DATETIME_LOCAL_SECONDS:"YYYY-MM-DDTHH:mm:ss",DATETIME_LOCAL_MS:"YYYY-MM-DDTHH:mm:ss.SSS",DATE:"YYYY-MM-DD",TIME:"HH:mm",TIME_SECONDS:"HH:mm:ss",TIME_MS:"HH:mm:ss.SSS",WEEK:"GGGG-[W]WW",MONTH:"YYYY-MM"},f}); +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.moment=t()}(this,function(){"use strict";var H;function f(){return H.apply(null,arguments)}function a(e){return e instanceof Array||"[object Array]"===Object.prototype.toString.call(e)}function F(e){return null!=e&&"[object Object]"===Object.prototype.toString.call(e)}function c(e,t){return Object.prototype.hasOwnProperty.call(e,t)}function L(e){if(Object.getOwnPropertyNames)return 0===Object.getOwnPropertyNames(e).length;for(var t in e)if(c(e,t))return;return 1}function o(e){return void 0===e}function u(e){return"number"==typeof e||"[object Number]"===Object.prototype.toString.call(e)}function V(e){return e instanceof Date||"[object Date]"===Object.prototype.toString.call(e)}function G(e,t){for(var n=[],s=e.length,i=0;i<s;++i)n.push(t(e[i],i));return n}function E(e,t){for(var n in t)c(t,n)&&(e[n]=t[n]);return c(t,"toString")&&(e.toString=t.toString),c(t,"valueOf")&&(e.valueOf=t.valueOf),e}function l(e,t,n,s){return Pt(e,t,n,s,!0).utc()}function m(e){return null==e._pf&&(e._pf={empty:!1,unusedTokens:[],unusedInput:[],overflow:-2,charsLeftOver:0,nullInput:!1,invalidEra:null,invalidMonth:null,invalidFormat:!1,userInvalidated:!1,iso:!1,parsedDateParts:[],era:null,meridiem:null,rfc2822:!1,weekdayMismatch:!1}),e._pf}function A(e){if(null==e._isValid){var t=m(e),n=j.call(t.parsedDateParts,function(e){return null!=e}),n=!isNaN(e._d.getTime())&&t.overflow<0&&!t.empty&&!t.invalidEra&&!t.invalidMonth&&!t.invalidWeekday&&!t.weekdayMismatch&&!t.nullInput&&!t.invalidFormat&&!t.userInvalidated&&(!t.meridiem||t.meridiem&&n);if(e._strict&&(n=n&&0===t.charsLeftOver&&0===t.unusedTokens.length&&void 0===t.bigHour),null!=Object.isFrozen&&Object.isFrozen(e))return n;e._isValid=n}return e._isValid}function I(e){var t=l(NaN);return null!=e?E(m(t),e):m(t).userInvalidated=!0,t}var j=Array.prototype.some||function(e){for(var t=Object(this),n=t.length>>>0,s=0;s<n;s++)if(s in t&&e.call(this,t[s],s,t))return!0;return!1},Z=f.momentProperties=[],z=!1;function $(e,t){var n,s,i,r=Z.length;if(o(t._isAMomentObject)||(e._isAMomentObject=t._isAMomentObject),o(t._i)||(e._i=t._i),o(t._f)||(e._f=t._f),o(t._l)||(e._l=t._l),o(t._strict)||(e._strict=t._strict),o(t._tzm)||(e._tzm=t._tzm),o(t._isUTC)||(e._isUTC=t._isUTC),o(t._offset)||(e._offset=t._offset),o(t._pf)||(e._pf=m(t)),o(t._locale)||(e._locale=t._locale),0<r)for(n=0;n<r;n++)o(i=t[s=Z[n]])||(e[s]=i);return e}function q(e){$(this,e),this._d=new Date(null!=e._d?e._d.getTime():NaN),this.isValid()||(this._d=new Date(NaN)),!1===z&&(z=!0,f.updateOffset(this),z=!1)}function h(e){return e instanceof q||null!=e&&null!=e._isAMomentObject}function B(e){!1===f.suppressDeprecationWarnings&&"undefined"!=typeof console&&console.warn&&console.warn("Deprecation warning: "+e)}function e(r,a){var o=!0;return E(function(){if(null!=f.deprecationHandler&&f.deprecationHandler(null,r),o){for(var e,t,n=[],s=arguments.length,i=0;i<s;i++){if(e="","object"==typeof arguments[i]){for(t in e+="\n["+i+"] ",arguments[0])c(arguments[0],t)&&(e+=t+": "+arguments[0][t]+", ");e=e.slice(0,-2)}else e=arguments[i];n.push(e)}B(r+"\nArguments: "+Array.prototype.slice.call(n).join("")+"\n"+(new Error).stack),o=!1}return a.apply(this,arguments)},a)}var J={};function Q(e,t){null!=f.deprecationHandler&&f.deprecationHandler(e,t),J[e]||(B(t),J[e]=!0)}function d(e){return"undefined"!=typeof Function&&e instanceof Function||"[object Function]"===Object.prototype.toString.call(e)}function X(e,t){var n,s=E({},e);for(n in t)c(t,n)&&(F(e[n])&&F(t[n])?(s[n]={},E(s[n],e[n]),E(s[n],t[n])):null!=t[n]?s[n]=t[n]:delete s[n]);for(n in e)c(e,n)&&!c(t,n)&&F(e[n])&&(s[n]=E({},s[n]));return s}function K(e){null!=e&&this.set(e)}f.suppressDeprecationWarnings=!1,f.deprecationHandler=null;var ee=Object.keys||function(e){var t,n=[];for(t in e)c(e,t)&&n.push(t);return n};function r(e,t,n){var s=""+Math.abs(e);return(0<=e?n?"+":"":"-")+Math.pow(10,Math.max(0,t-s.length)).toString().substr(1)+s}var te=/(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|N{1,5}|YYYYYY|YYYYY|YYYY|YY|y{2,4}|yo?|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,ne=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,se={},ie={};function s(e,t,n,s){var i="string"==typeof s?function(){return this[s]()}:s;e&&(ie[e]=i),t&&(ie[t[0]]=function(){return r(i.apply(this,arguments),t[1],t[2])}),n&&(ie[n]=function(){return this.localeData().ordinal(i.apply(this,arguments),e)})}function re(e,t){return e.isValid()?(t=ae(t,e.localeData()),se[t]=se[t]||function(s){for(var e,i=s.match(te),t=0,r=i.length;t<r;t++)ie[i[t]]?i[t]=ie[i[t]]:i[t]=(e=i[t]).match(/\[[\s\S]/)?e.replace(/^\[|\]$/g,""):e.replace(/\\/g,"");return function(e){for(var t="",n=0;n<r;n++)t+=d(i[n])?i[n].call(e,s):i[n];return t}}(t),se[t](e)):e.localeData().invalidDate()}function ae(e,t){var n=5;function s(e){return t.longDateFormat(e)||e}for(ne.lastIndex=0;0<=n&&ne.test(e);)e=e.replace(ne,s),ne.lastIndex=0,--n;return e}var oe={};function t(e,t){var n=e.toLowerCase();oe[n]=oe[n+"s"]=oe[t]=e}function _(e){return"string"==typeof e?oe[e]||oe[e.toLowerCase()]:void 0}function ue(e){var t,n,s={};for(n in e)c(e,n)&&(t=_(n))&&(s[t]=e[n]);return s}var le={};function n(e,t){le[e]=t}function he(e){return e%4==0&&e%100!=0||e%400==0}function y(e){return e<0?Math.ceil(e)||0:Math.floor(e)}function g(e){var e=+e,t=0;return t=0!=e&&isFinite(e)?y(e):t}function de(t,n){return function(e){return null!=e?(fe(this,t,e),f.updateOffset(this,n),this):ce(this,t)}}function ce(e,t){return e.isValid()?e._d["get"+(e._isUTC?"UTC":"")+t]():NaN}function fe(e,t,n){e.isValid()&&!isNaN(n)&&("FullYear"===t&&he(e.year())&&1===e.month()&&29===e.date()?(n=g(n),e._d["set"+(e._isUTC?"UTC":"")+t](n,e.month(),We(n,e.month()))):e._d["set"+(e._isUTC?"UTC":"")+t](n))}var i=/\d/,w=/\d\d/,me=/\d{3}/,_e=/\d{4}/,ye=/[+-]?\d{6}/,p=/\d\d?/,ge=/\d\d\d\d?/,we=/\d\d\d\d\d\d?/,pe=/\d{1,3}/,ke=/\d{1,4}/,ve=/[+-]?\d{1,6}/,Me=/\d+/,De=/[+-]?\d+/,Se=/Z|[+-]\d\d:?\d\d/gi,Ye=/Z|[+-]\d\d(?::?\d\d)?/gi,k=/[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i;function v(e,n,s){be[e]=d(n)?n:function(e,t){return e&&s?s:n}}function Oe(e,t){return c(be,e)?be[e](t._strict,t._locale):new RegExp(M(e.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(e,t,n,s,i){return t||n||s||i})))}function M(e){return e.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}var be={},xe={};function D(e,n){var t,s,i=n;for("string"==typeof e&&(e=[e]),u(n)&&(i=function(e,t){t[n]=g(e)}),s=e.length,t=0;t<s;t++)xe[e[t]]=i}function Te(e,i){D(e,function(e,t,n,s){n._w=n._w||{},i(e,n._w,n,s)})}var S,Y=0,O=1,b=2,x=3,T=4,N=5,Ne=6,Pe=7,Re=8;function We(e,t){if(isNaN(e)||isNaN(t))return NaN;var n=(t%(n=12)+n)%n;return e+=(t-n)/12,1==n?he(e)?29:28:31-n%7%2}S=Array.prototype.indexOf||function(e){for(var t=0;t<this.length;++t)if(this[t]===e)return t;return-1},s("M",["MM",2],"Mo",function(){return this.month()+1}),s("MMM",0,0,function(e){return this.localeData().monthsShort(this,e)}),s("MMMM",0,0,function(e){return this.localeData().months(this,e)}),t("month","M"),n("month",8),v("M",p),v("MM",p,w),v("MMM",function(e,t){return t.monthsShortRegex(e)}),v("MMMM",function(e,t){return t.monthsRegex(e)}),D(["M","MM"],function(e,t){t[O]=g(e)-1}),D(["MMM","MMMM"],function(e,t,n,s){s=n._locale.monthsParse(e,s,n._strict);null!=s?t[O]=s:m(n).invalidMonth=e});var Ce="January_February_March_April_May_June_July_August_September_October_November_December".split("_"),Ue="Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),He=/D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/,Fe=k,Le=k;function Ve(e,t){var n;if(e.isValid()){if("string"==typeof t)if(/^\d+$/.test(t))t=g(t);else if(!u(t=e.localeData().monthsParse(t)))return;n=Math.min(e.date(),We(e.year(),t)),e._d["set"+(e._isUTC?"UTC":"")+"Month"](t,n)}}function Ge(e){return null!=e?(Ve(this,e),f.updateOffset(this,!0),this):ce(this,"Month")}function Ee(){function e(e,t){return t.length-e.length}for(var t,n=[],s=[],i=[],r=0;r<12;r++)t=l([2e3,r]),n.push(this.monthsShort(t,"")),s.push(this.months(t,"")),i.push(this.months(t,"")),i.push(this.monthsShort(t,""));for(n.sort(e),s.sort(e),i.sort(e),r=0;r<12;r++)n[r]=M(n[r]),s[r]=M(s[r]);for(r=0;r<24;r++)i[r]=M(i[r]);this._monthsRegex=new RegExp("^("+i.join("|")+")","i"),this._monthsShortRegex=this._monthsRegex,this._monthsStrictRegex=new RegExp("^("+s.join("|")+")","i"),this._monthsShortStrictRegex=new RegExp("^("+n.join("|")+")","i")}function Ae(e){return he(e)?366:365}s("Y",0,0,function(){var e=this.year();return e<=9999?r(e,4):"+"+e}),s(0,["YY",2],0,function(){return this.year()%100}),s(0,["YYYY",4],0,"year"),s(0,["YYYYY",5],0,"year"),s(0,["YYYYYY",6,!0],0,"year"),t("year","y"),n("year",1),v("Y",De),v("YY",p,w),v("YYYY",ke,_e),v("YYYYY",ve,ye),v("YYYYYY",ve,ye),D(["YYYYY","YYYYYY"],Y),D("YYYY",function(e,t){t[Y]=2===e.length?f.parseTwoDigitYear(e):g(e)}),D("YY",function(e,t){t[Y]=f.parseTwoDigitYear(e)}),D("Y",function(e,t){t[Y]=parseInt(e,10)}),f.parseTwoDigitYear=function(e){return g(e)+(68<g(e)?1900:2e3)};var Ie=de("FullYear",!0);function je(e,t,n,s,i,r,a){var o;return e<100&&0<=e?(o=new Date(e+400,t,n,s,i,r,a),isFinite(o.getFullYear())&&o.setFullYear(e)):o=new Date(e,t,n,s,i,r,a),o}function Ze(e){var t;return e<100&&0<=e?((t=Array.prototype.slice.call(arguments))[0]=e+400,t=new Date(Date.UTC.apply(null,t)),isFinite(t.getUTCFullYear())&&t.setUTCFullYear(e)):t=new Date(Date.UTC.apply(null,arguments)),t}function ze(e,t,n){n=7+t-n;return n-(7+Ze(e,0,n).getUTCDay()-t)%7-1}function $e(e,t,n,s,i){var r,t=1+7*(t-1)+(7+n-s)%7+ze(e,s,i),n=t<=0?Ae(r=e-1)+t:t>Ae(e)?(r=e+1,t-Ae(e)):(r=e,t);return{year:r,dayOfYear:n}}function qe(e,t,n){var s,i,r=ze(e.year(),t,n),r=Math.floor((e.dayOfYear()-r-1)/7)+1;return r<1?s=r+P(i=e.year()-1,t,n):r>P(e.year(),t,n)?(s=r-P(e.year(),t,n),i=e.year()+1):(i=e.year(),s=r),{week:s,year:i}}function P(e,t,n){var s=ze(e,t,n),t=ze(e+1,t,n);return(Ae(e)-s+t)/7}s("w",["ww",2],"wo","week"),s("W",["WW",2],"Wo","isoWeek"),t("week","w"),t("isoWeek","W"),n("week",5),n("isoWeek",5),v("w",p),v("ww",p,w),v("W",p),v("WW",p,w),Te(["w","ww","W","WW"],function(e,t,n,s){t[s.substr(0,1)]=g(e)});function Be(e,t){return e.slice(t,7).concat(e.slice(0,t))}s("d",0,"do","day"),s("dd",0,0,function(e){return this.localeData().weekdaysMin(this,e)}),s("ddd",0,0,function(e){return this.localeData().weekdaysShort(this,e)}),s("dddd",0,0,function(e){return this.localeData().weekdays(this,e)}),s("e",0,0,"weekday"),s("E",0,0,"isoWeekday"),t("day","d"),t("weekday","e"),t("isoWeekday","E"),n("day",11),n("weekday",11),n("isoWeekday",11),v("d",p),v("e",p),v("E",p),v("dd",function(e,t){return t.weekdaysMinRegex(e)}),v("ddd",function(e,t){return t.weekdaysShortRegex(e)}),v("dddd",function(e,t){return t.weekdaysRegex(e)}),Te(["dd","ddd","dddd"],function(e,t,n,s){s=n._locale.weekdaysParse(e,s,n._strict);null!=s?t.d=s:m(n).invalidWeekday=e}),Te(["d","e","E"],function(e,t,n,s){t[s]=g(e)});var Je="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),Qe="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),Xe="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),Ke=k,et=k,tt=k;function nt(){function e(e,t){return t.length-e.length}for(var t,n,s,i=[],r=[],a=[],o=[],u=0;u<7;u++)s=l([2e3,1]).day(u),t=M(this.weekdaysMin(s,"")),n=M(this.weekdaysShort(s,"")),s=M(this.weekdays(s,"")),i.push(t),r.push(n),a.push(s),o.push(t),o.push(n),o.push(s);i.sort(e),r.sort(e),a.sort(e),o.sort(e),this._weekdaysRegex=new RegExp("^("+o.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+a.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+r.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+i.join("|")+")","i")}function st(){return this.hours()%12||12}function it(e,t){s(e,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),t)})}function rt(e,t){return t._meridiemParse}s("H",["HH",2],0,"hour"),s("h",["hh",2],0,st),s("k",["kk",2],0,function(){return this.hours()||24}),s("hmm",0,0,function(){return""+st.apply(this)+r(this.minutes(),2)}),s("hmmss",0,0,function(){return""+st.apply(this)+r(this.minutes(),2)+r(this.seconds(),2)}),s("Hmm",0,0,function(){return""+this.hours()+r(this.minutes(),2)}),s("Hmmss",0,0,function(){return""+this.hours()+r(this.minutes(),2)+r(this.seconds(),2)}),it("a",!0),it("A",!1),t("hour","h"),n("hour",13),v("a",rt),v("A",rt),v("H",p),v("h",p),v("k",p),v("HH",p,w),v("hh",p,w),v("kk",p,w),v("hmm",ge),v("hmmss",we),v("Hmm",ge),v("Hmmss",we),D(["H","HH"],x),D(["k","kk"],function(e,t,n){e=g(e);t[x]=24===e?0:e}),D(["a","A"],function(e,t,n){n._isPm=n._locale.isPM(e),n._meridiem=e}),D(["h","hh"],function(e,t,n){t[x]=g(e),m(n).bigHour=!0}),D("hmm",function(e,t,n){var s=e.length-2;t[x]=g(e.substr(0,s)),t[T]=g(e.substr(s)),m(n).bigHour=!0}),D("hmmss",function(e,t,n){var s=e.length-4,i=e.length-2;t[x]=g(e.substr(0,s)),t[T]=g(e.substr(s,2)),t[N]=g(e.substr(i)),m(n).bigHour=!0}),D("Hmm",function(e,t,n){var s=e.length-2;t[x]=g(e.substr(0,s)),t[T]=g(e.substr(s))}),D("Hmmss",function(e,t,n){var s=e.length-4,i=e.length-2;t[x]=g(e.substr(0,s)),t[T]=g(e.substr(s,2)),t[N]=g(e.substr(i))});k=de("Hours",!0);var at,ot={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",w:"a week",ww:"%d weeks",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:Ce,monthsShort:Ue,week:{dow:0,doy:6},weekdays:Je,weekdaysMin:Xe,weekdaysShort:Qe,meridiemParse:/[ap]\.?m?\.?/i},R={},ut={};function lt(e){return e&&e.toLowerCase().replace("_","-")}function ht(e){for(var t,n,s,i,r=0;r<e.length;){for(t=(i=lt(e[r]).split("-")).length,n=(n=lt(e[r+1]))?n.split("-"):null;0<t;){if(s=dt(i.slice(0,t).join("-")))return s;if(n&&n.length>=t&&function(e,t){for(var n=Math.min(e.length,t.length),s=0;s<n;s+=1)if(e[s]!==t[s])return s;return n}(i,n)>=t-1)break;t--}r++}return at}function dt(t){var e;if(void 0===R[t]&&"undefined"!=typeof module&&module&&module.exports&&null!=t.match("^[^/\\\\]*$"))try{e=at._abbr,require("./locale/"+t),ct(e)}catch(e){R[t]=null}return R[t]}function ct(e,t){return e&&((t=o(t)?mt(e):ft(e,t))?at=t:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+e+" not found. Did you forget to load it?")),at._abbr}function ft(e,t){if(null===t)return delete R[e],null;var n,s=ot;if(t.abbr=e,null!=R[e])Q("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),s=R[e]._config;else if(null!=t.parentLocale)if(null!=R[t.parentLocale])s=R[t.parentLocale]._config;else{if(null==(n=dt(t.parentLocale)))return ut[t.parentLocale]||(ut[t.parentLocale]=[]),ut[t.parentLocale].push({name:e,config:t}),null;s=n._config}return R[e]=new K(X(s,t)),ut[e]&&ut[e].forEach(function(e){ft(e.name,e.config)}),ct(e),R[e]}function mt(e){var t;if(!(e=e&&e._locale&&e._locale._abbr?e._locale._abbr:e))return at;if(!a(e)){if(t=dt(e))return t;e=[e]}return ht(e)}function _t(e){var t=e._a;return t&&-2===m(e).overflow&&(t=t[O]<0||11<t[O]?O:t[b]<1||t[b]>We(t[Y],t[O])?b:t[x]<0||24<t[x]||24===t[x]&&(0!==t[T]||0!==t[N]||0!==t[Ne])?x:t[T]<0||59<t[T]?T:t[N]<0||59<t[N]?N:t[Ne]<0||999<t[Ne]?Ne:-1,m(e)._overflowDayOfYear&&(t<Y||b<t)&&(t=b),m(e)._overflowWeeks&&-1===t&&(t=Pe),m(e)._overflowWeekday&&-1===t&&(t=Re),m(e).overflow=t),e}var yt=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([+-]\d\d(?::?\d\d)?|\s*Z)?)?$/,gt=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d|))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([+-]\d\d(?::?\d\d)?|\s*Z)?)?$/,wt=/Z|[+-]\d\d(?::?\d\d)?/,pt=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/],["YYYYMM",/\d{6}/,!1],["YYYY",/\d{4}/,!1]],kt=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],vt=/^\/?Date\((-?\d+)/i,Mt=/^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/,Dt={UT:0,GMT:0,EDT:-240,EST:-300,CDT:-300,CST:-360,MDT:-360,MST:-420,PDT:-420,PST:-480};function St(e){var t,n,s,i,r,a,o=e._i,u=yt.exec(o)||gt.exec(o),o=pt.length,l=kt.length;if(u){for(m(e).iso=!0,t=0,n=o;t<n;t++)if(pt[t][1].exec(u[1])){i=pt[t][0],s=!1!==pt[t][2];break}if(null==i)e._isValid=!1;else{if(u[3]){for(t=0,n=l;t<n;t++)if(kt[t][1].exec(u[3])){r=(u[2]||" ")+kt[t][0];break}if(null==r)return void(e._isValid=!1)}if(s||null==r){if(u[4]){if(!wt.exec(u[4]))return void(e._isValid=!1);a="Z"}e._f=i+(r||"")+(a||""),Tt(e)}else e._isValid=!1}}else e._isValid=!1}function Yt(e,t,n,s,i,r){e=[function(e){e=parseInt(e,10);{if(e<=49)return 2e3+e;if(e<=999)return 1900+e}return e}(e),Ue.indexOf(t),parseInt(n,10),parseInt(s,10),parseInt(i,10)];return r&&e.push(parseInt(r,10)),e}function Ot(e){var t,n,s,i,r=Mt.exec(e._i.replace(/\([^()]*\)|[\n\t]/g," ").replace(/(\s\s+)/g," ").replace(/^\s\s*/,"").replace(/\s\s*$/,""));r?(t=Yt(r[4],r[3],r[2],r[5],r[6],r[7]),n=r[1],s=t,i=e,n&&Qe.indexOf(n)!==new Date(s[0],s[1],s[2]).getDay()?(m(i).weekdayMismatch=!0,i._isValid=!1):(e._a=t,e._tzm=(n=r[8],s=r[9],i=r[10],n?Dt[n]:s?0:60*(((n=parseInt(i,10))-(s=n%100))/100)+s),e._d=Ze.apply(null,e._a),e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),m(e).rfc2822=!0)):e._isValid=!1}function bt(e,t,n){return null!=e?e:null!=t?t:n}function xt(e){var t,n,s,i,r,a,o,u,l,h,d,c=[];if(!e._d){for(s=e,i=new Date(f.now()),n=s._useUTC?[i.getUTCFullYear(),i.getUTCMonth(),i.getUTCDate()]:[i.getFullYear(),i.getMonth(),i.getDate()],e._w&&null==e._a[b]&&null==e._a[O]&&(null!=(i=(s=e)._w).GG||null!=i.W||null!=i.E?(u=1,l=4,r=bt(i.GG,s._a[Y],qe(W(),1,4).year),a=bt(i.W,1),((o=bt(i.E,1))<1||7<o)&&(h=!0)):(u=s._locale._week.dow,l=s._locale._week.doy,d=qe(W(),u,l),r=bt(i.gg,s._a[Y],d.year),a=bt(i.w,d.week),null!=i.d?((o=i.d)<0||6<o)&&(h=!0):null!=i.e?(o=i.e+u,(i.e<0||6<i.e)&&(h=!0)):o=u),a<1||a>P(r,u,l)?m(s)._overflowWeeks=!0:null!=h?m(s)._overflowWeekday=!0:(d=$e(r,a,o,u,l),s._a[Y]=d.year,s._dayOfYear=d.dayOfYear)),null!=e._dayOfYear&&(i=bt(e._a[Y],n[Y]),(e._dayOfYear>Ae(i)||0===e._dayOfYear)&&(m(e)._overflowDayOfYear=!0),h=Ze(i,0,e._dayOfYear),e._a[O]=h.getUTCMonth(),e._a[b]=h.getUTCDate()),t=0;t<3&&null==e._a[t];++t)e._a[t]=c[t]=n[t];for(;t<7;t++)e._a[t]=c[t]=null==e._a[t]?2===t?1:0:e._a[t];24===e._a[x]&&0===e._a[T]&&0===e._a[N]&&0===e._a[Ne]&&(e._nextDay=!0,e._a[x]=0),e._d=(e._useUTC?Ze:je).apply(null,c),r=e._useUTC?e._d.getUTCDay():e._d.getDay(),null!=e._tzm&&e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),e._nextDay&&(e._a[x]=24),e._w&&void 0!==e._w.d&&e._w.d!==r&&(m(e).weekdayMismatch=!0)}}function Tt(e){if(e._f===f.ISO_8601)St(e);else if(e._f===f.RFC_2822)Ot(e);else{e._a=[],m(e).empty=!0;for(var t,n,s,i,r,a=""+e._i,o=a.length,u=0,l=ae(e._f,e._locale).match(te)||[],h=l.length,d=0;d<h;d++)n=l[d],(t=(a.match(Oe(n,e))||[])[0])&&(0<(s=a.substr(0,a.indexOf(t))).length&&m(e).unusedInput.push(s),a=a.slice(a.indexOf(t)+t.length),u+=t.length),ie[n]?(t?m(e).empty=!1:m(e).unusedTokens.push(n),s=n,r=e,null!=(i=t)&&c(xe,s)&&xe[s](i,r._a,r,s)):e._strict&&!t&&m(e).unusedTokens.push(n);m(e).charsLeftOver=o-u,0<a.length&&m(e).unusedInput.push(a),e._a[x]<=12&&!0===m(e).bigHour&&0<e._a[x]&&(m(e).bigHour=void 0),m(e).parsedDateParts=e._a.slice(0),m(e).meridiem=e._meridiem,e._a[x]=function(e,t,n){if(null==n)return t;return null!=e.meridiemHour?e.meridiemHour(t,n):null!=e.isPM?((e=e.isPM(n))&&t<12&&(t+=12),t=e||12!==t?t:0):t}(e._locale,e._a[x],e._meridiem),null!==(o=m(e).era)&&(e._a[Y]=e._locale.erasConvertYear(o,e._a[Y])),xt(e),_t(e)}}function Nt(e){var t,n,s,i=e._i,r=e._f;if(e._locale=e._locale||mt(e._l),null===i||void 0===r&&""===i)return I({nullInput:!0});if("string"==typeof i&&(e._i=i=e._locale.preparse(i)),h(i))return new q(_t(i));if(V(i))e._d=i;else if(a(r))!function(e){var t,n,s,i,r,a,o=!1,u=e._f.length;if(0===u)return m(e).invalidFormat=!0,e._d=new Date(NaN);for(i=0;i<u;i++)r=0,a=!1,t=$({},e),null!=e._useUTC&&(t._useUTC=e._useUTC),t._f=e._f[i],Tt(t),A(t)&&(a=!0),r=(r+=m(t).charsLeftOver)+10*m(t).unusedTokens.length,m(t).score=r,o?r<s&&(s=r,n=t):(null==s||r<s||a)&&(s=r,n=t,a&&(o=!0));E(e,n||t)}(e);else if(r)Tt(e);else if(o(r=(i=e)._i))i._d=new Date(f.now());else V(r)?i._d=new Date(r.valueOf()):"string"==typeof r?(n=i,null!==(t=vt.exec(n._i))?n._d=new Date(+t[1]):(St(n),!1===n._isValid&&(delete n._isValid,Ot(n),!1===n._isValid&&(delete n._isValid,n._strict?n._isValid=!1:f.createFromInputFallback(n))))):a(r)?(i._a=G(r.slice(0),function(e){return parseInt(e,10)}),xt(i)):F(r)?(t=i)._d||(s=void 0===(n=ue(t._i)).day?n.date:n.day,t._a=G([n.year,n.month,s,n.hour,n.minute,n.second,n.millisecond],function(e){return e&&parseInt(e,10)}),xt(t)):u(r)?i._d=new Date(r):f.createFromInputFallback(i);return A(e)||(e._d=null),e}function Pt(e,t,n,s,i){var r={};return!0!==t&&!1!==t||(s=t,t=void 0),!0!==n&&!1!==n||(s=n,n=void 0),(F(e)&&L(e)||a(e)&&0===e.length)&&(e=void 0),r._isAMomentObject=!0,r._useUTC=r._isUTC=i,r._l=n,r._i=e,r._f=t,r._strict=s,(i=new q(_t(Nt(i=r))))._nextDay&&(i.add(1,"d"),i._nextDay=void 0),i}function W(e,t,n,s){return Pt(e,t,n,s,!1)}f.createFromInputFallback=e("value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are discouraged. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.",function(e){e._d=new Date(e._i+(e._useUTC?" UTC":""))}),f.ISO_8601=function(){},f.RFC_2822=function(){};ge=e("moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var e=W.apply(null,arguments);return this.isValid()&&e.isValid()?e<this?this:e:I()}),we=e("moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var e=W.apply(null,arguments);return this.isValid()&&e.isValid()?this<e?this:e:I()});function Rt(e,t){var n,s;if(!(t=1===t.length&&a(t[0])?t[0]:t).length)return W();for(n=t[0],s=1;s<t.length;++s)t[s].isValid()&&!t[s][e](n)||(n=t[s]);return n}var Wt=["year","quarter","month","week","day","hour","minute","second","millisecond"];function Ct(e){var e=ue(e),t=e.year||0,n=e.quarter||0,s=e.month||0,i=e.week||e.isoWeek||0,r=e.day||0,a=e.hour||0,o=e.minute||0,u=e.second||0,l=e.millisecond||0;this._isValid=function(e){var t,n,s=!1,i=Wt.length;for(t in e)if(c(e,t)&&(-1===S.call(Wt,t)||null!=e[t]&&isNaN(e[t])))return!1;for(n=0;n<i;++n)if(e[Wt[n]]){if(s)return!1;parseFloat(e[Wt[n]])!==g(e[Wt[n]])&&(s=!0)}return!0}(e),this._milliseconds=+l+1e3*u+6e4*o+1e3*a*60*60,this._days=+r+7*i,this._months=+s+3*n+12*t,this._data={},this._locale=mt(),this._bubble()}function Ut(e){return e instanceof Ct}function Ht(e){return e<0?-1*Math.round(-1*e):Math.round(e)}function Ft(e,n){s(e,0,0,function(){var e=this.utcOffset(),t="+";return e<0&&(e=-e,t="-"),t+r(~~(e/60),2)+n+r(~~e%60,2)})}Ft("Z",":"),Ft("ZZ",""),v("Z",Ye),v("ZZ",Ye),D(["Z","ZZ"],function(e,t,n){n._useUTC=!0,n._tzm=Vt(Ye,e)});var Lt=/([\+\-]|\d\d)/gi;function Vt(e,t){var t=(t||"").match(e);return null===t?null:0===(t=60*(e=((t[t.length-1]||[])+"").match(Lt)||["-",0,0])[1]+g(e[2]))?0:"+"===e[0]?t:-t}function Gt(e,t){var n;return t._isUTC?(t=t.clone(),n=(h(e)||V(e)?e:W(e)).valueOf()-t.valueOf(),t._d.setTime(t._d.valueOf()+n),f.updateOffset(t,!1),t):W(e).local()}function Et(e){return-Math.round(e._d.getTimezoneOffset())}function At(){return!!this.isValid()&&(this._isUTC&&0===this._offset)}f.updateOffset=function(){};var It=/^(-|\+)?(?:(\d*)[. ])?(\d+):(\d+)(?::(\d+)(\.\d*)?)?$/,jt=/^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/;function C(e,t){var n,s=e,i=null;return Ut(e)?s={ms:e._milliseconds,d:e._days,M:e._months}:u(e)||!isNaN(+e)?(s={},t?s[t]=+e:s.milliseconds=+e):(i=It.exec(e))?(n="-"===i[1]?-1:1,s={y:0,d:g(i[b])*n,h:g(i[x])*n,m:g(i[T])*n,s:g(i[N])*n,ms:g(Ht(1e3*i[Ne]))*n}):(i=jt.exec(e))?(n="-"===i[1]?-1:1,s={y:Zt(i[2],n),M:Zt(i[3],n),w:Zt(i[4],n),d:Zt(i[5],n),h:Zt(i[6],n),m:Zt(i[7],n),s:Zt(i[8],n)}):null==s?s={}:"object"==typeof s&&("from"in s||"to"in s)&&(t=function(e,t){var n;if(!e.isValid()||!t.isValid())return{milliseconds:0,months:0};t=Gt(t,e),e.isBefore(t)?n=zt(e,t):((n=zt(t,e)).milliseconds=-n.milliseconds,n.months=-n.months);return n}(W(s.from),W(s.to)),(s={}).ms=t.milliseconds,s.M=t.months),i=new Ct(s),Ut(e)&&c(e,"_locale")&&(i._locale=e._locale),Ut(e)&&c(e,"_isValid")&&(i._isValid=e._isValid),i}function Zt(e,t){e=e&&parseFloat(e.replace(",","."));return(isNaN(e)?0:e)*t}function zt(e,t){var n={};return n.months=t.month()-e.month()+12*(t.year()-e.year()),e.clone().add(n.months,"M").isAfter(t)&&--n.months,n.milliseconds=+t-+e.clone().add(n.months,"M"),n}function $t(s,i){return function(e,t){var n;return null===t||isNaN(+t)||(Q(i,"moment()."+i+"(period, number) is deprecated. Please use moment()."+i+"(number, period). See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info."),n=e,e=t,t=n),qt(this,C(e,t),s),this}}function qt(e,t,n,s){var i=t._milliseconds,r=Ht(t._days),t=Ht(t._months);e.isValid()&&(s=null==s||s,t&&Ve(e,ce(e,"Month")+t*n),r&&fe(e,"Date",ce(e,"Date")+r*n),i&&e._d.setTime(e._d.valueOf()+i*n),s&&f.updateOffset(e,r||t))}C.fn=Ct.prototype,C.invalid=function(){return C(NaN)};Ce=$t(1,"add"),Je=$t(-1,"subtract");function Bt(e){return"string"==typeof e||e instanceof String}function Jt(e){return h(e)||V(e)||Bt(e)||u(e)||function(t){var e=a(t),n=!1;e&&(n=0===t.filter(function(e){return!u(e)&&Bt(t)}).length);return e&&n}(e)||function(e){var t,n,s=F(e)&&!L(e),i=!1,r=["years","year","y","months","month","M","days","day","d","dates","date","D","hours","hour","h","minutes","minute","m","seconds","second","s","milliseconds","millisecond","ms"],a=r.length;for(t=0;t<a;t+=1)n=r[t],i=i||c(e,n);return s&&i}(e)||null==e}function Qt(e,t){if(e.date()<t.date())return-Qt(t,e);var n=12*(t.year()-e.year())+(t.month()-e.month()),s=e.clone().add(n,"months"),t=t-s<0?(t-s)/(s-e.clone().add(n-1,"months")):(t-s)/(e.clone().add(1+n,"months")-s);return-(n+t)||0}function Xt(e){return void 0===e?this._locale._abbr:(null!=(e=mt(e))&&(this._locale=e),this)}f.defaultFormat="YYYY-MM-DDTHH:mm:ssZ",f.defaultFormatUtc="YYYY-MM-DDTHH:mm:ss[Z]";Xe=e("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(e){return void 0===e?this.localeData():this.locale(e)});function Kt(){return this._locale}var en=126227808e5;function tn(e,t){return(e%t+t)%t}function nn(e,t,n){return e<100&&0<=e?new Date(e+400,t,n)-en:new Date(e,t,n).valueOf()}function sn(e,t,n){return e<100&&0<=e?Date.UTC(e+400,t,n)-en:Date.UTC(e,t,n)}function rn(e,t){return t.erasAbbrRegex(e)}function an(){for(var e=[],t=[],n=[],s=[],i=this.eras(),r=0,a=i.length;r<a;++r)t.push(M(i[r].name)),e.push(M(i[r].abbr)),n.push(M(i[r].narrow)),s.push(M(i[r].name)),s.push(M(i[r].abbr)),s.push(M(i[r].narrow));this._erasRegex=new RegExp("^("+s.join("|")+")","i"),this._erasNameRegex=new RegExp("^("+t.join("|")+")","i"),this._erasAbbrRegex=new RegExp("^("+e.join("|")+")","i"),this._erasNarrowRegex=new RegExp("^("+n.join("|")+")","i")}function on(e,t){s(0,[e,e.length],0,t)}function un(e,t,n,s,i){var r;return null==e?qe(this,s,i).year:(r=P(e,s,i),function(e,t,n,s,i){e=$e(e,t,n,s,i),t=Ze(e.year,0,e.dayOfYear);return this.year(t.getUTCFullYear()),this.month(t.getUTCMonth()),this.date(t.getUTCDate()),this}.call(this,e,t=r<t?r:t,n,s,i))}s("N",0,0,"eraAbbr"),s("NN",0,0,"eraAbbr"),s("NNN",0,0,"eraAbbr"),s("NNNN",0,0,"eraName"),s("NNNNN",0,0,"eraNarrow"),s("y",["y",1],"yo","eraYear"),s("y",["yy",2],0,"eraYear"),s("y",["yyy",3],0,"eraYear"),s("y",["yyyy",4],0,"eraYear"),v("N",rn),v("NN",rn),v("NNN",rn),v("NNNN",function(e,t){return t.erasNameRegex(e)}),v("NNNNN",function(e,t){return t.erasNarrowRegex(e)}),D(["N","NN","NNN","NNNN","NNNNN"],function(e,t,n,s){s=n._locale.erasParse(e,s,n._strict);s?m(n).era=s:m(n).invalidEra=e}),v("y",Me),v("yy",Me),v("yyy",Me),v("yyyy",Me),v("yo",function(e,t){return t._eraYearOrdinalRegex||Me}),D(["y","yy","yyy","yyyy"],Y),D(["yo"],function(e,t,n,s){var i;n._locale._eraYearOrdinalRegex&&(i=e.match(n._locale._eraYearOrdinalRegex)),n._locale.eraYearOrdinalParse?t[Y]=n._locale.eraYearOrdinalParse(e,i):t[Y]=parseInt(e,10)}),s(0,["gg",2],0,function(){return this.weekYear()%100}),s(0,["GG",2],0,function(){return this.isoWeekYear()%100}),on("gggg","weekYear"),on("ggggg","weekYear"),on("GGGG","isoWeekYear"),on("GGGGG","isoWeekYear"),t("weekYear","gg"),t("isoWeekYear","GG"),n("weekYear",1),n("isoWeekYear",1),v("G",De),v("g",De),v("GG",p,w),v("gg",p,w),v("GGGG",ke,_e),v("gggg",ke,_e),v("GGGGG",ve,ye),v("ggggg",ve,ye),Te(["gggg","ggggg","GGGG","GGGGG"],function(e,t,n,s){t[s.substr(0,2)]=g(e)}),Te(["gg","GG"],function(e,t,n,s){t[s]=f.parseTwoDigitYear(e)}),s("Q",0,"Qo","quarter"),t("quarter","Q"),n("quarter",7),v("Q",i),D("Q",function(e,t){t[O]=3*(g(e)-1)}),s("D",["DD",2],"Do","date"),t("date","D"),n("date",9),v("D",p),v("DD",p,w),v("Do",function(e,t){return e?t._dayOfMonthOrdinalParse||t._ordinalParse:t._dayOfMonthOrdinalParseLenient}),D(["D","DD"],b),D("Do",function(e,t){t[b]=g(e.match(p)[0])});ke=de("Date",!0);s("DDD",["DDDD",3],"DDDo","dayOfYear"),t("dayOfYear","DDD"),n("dayOfYear",4),v("DDD",pe),v("DDDD",me),D(["DDD","DDDD"],function(e,t,n){n._dayOfYear=g(e)}),s("m",["mm",2],0,"minute"),t("minute","m"),n("minute",14),v("m",p),v("mm",p,w),D(["m","mm"],T);var ln,_e=de("Minutes",!1),ve=(s("s",["ss",2],0,"second"),t("second","s"),n("second",15),v("s",p),v("ss",p,w),D(["s","ss"],N),de("Seconds",!1));for(s("S",0,0,function(){return~~(this.millisecond()/100)}),s(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),s(0,["SSS",3],0,"millisecond"),s(0,["SSSS",4],0,function(){return 10*this.millisecond()}),s(0,["SSSSS",5],0,function(){return 100*this.millisecond()}),s(0,["SSSSSS",6],0,function(){return 1e3*this.millisecond()}),s(0,["SSSSSSS",7],0,function(){return 1e4*this.millisecond()}),s(0,["SSSSSSSS",8],0,function(){return 1e5*this.millisecond()}),s(0,["SSSSSSSSS",9],0,function(){return 1e6*this.millisecond()}),t("millisecond","ms"),n("millisecond",16),v("S",pe,i),v("SS",pe,w),v("SSS",pe,me),ln="SSSS";ln.length<=9;ln+="S")v(ln,Me);function hn(e,t){t[Ne]=g(1e3*("0."+e))}for(ln="S";ln.length<=9;ln+="S")D(ln,hn);ye=de("Milliseconds",!1),s("z",0,0,"zoneAbbr"),s("zz",0,0,"zoneName");i=q.prototype;function dn(e){return e}i.add=Ce,i.calendar=function(e,t){1===arguments.length&&(arguments[0]?Jt(arguments[0])?(e=arguments[0],t=void 0):function(e){for(var t=F(e)&&!L(e),n=!1,s=["sameDay","nextDay","lastDay","nextWeek","lastWeek","sameElse"],i=0;i<s.length;i+=1)n=n||c(e,s[i]);return t&&n}(arguments[0])&&(t=arguments[0],e=void 0):t=e=void 0);var e=e||W(),n=Gt(e,this).startOf("day"),n=f.calendarFormat(this,n)||"sameElse",t=t&&(d(t[n])?t[n].call(this,e):t[n]);return this.format(t||this.localeData().calendar(n,this,W(e)))},i.clone=function(){return new q(this)},i.diff=function(e,t,n){var s,i,r;if(!this.isValid())return NaN;if(!(s=Gt(e,this)).isValid())return NaN;switch(i=6e4*(s.utcOffset()-this.utcOffset()),t=_(t)){case"year":r=Qt(this,s)/12;break;case"month":r=Qt(this,s);break;case"quarter":r=Qt(this,s)/3;break;case"second":r=(this-s)/1e3;break;case"minute":r=(this-s)/6e4;break;case"hour":r=(this-s)/36e5;break;case"day":r=(this-s-i)/864e5;break;case"week":r=(this-s-i)/6048e5;break;default:r=this-s}return n?r:y(r)},i.endOf=function(e){var t,n;if(void 0===(e=_(e))||"millisecond"===e||!this.isValid())return this;switch(n=this._isUTC?sn:nn,e){case"year":t=n(this.year()+1,0,1)-1;break;case"quarter":t=n(this.year(),this.month()-this.month()%3+3,1)-1;break;case"month":t=n(this.year(),this.month()+1,1)-1;break;case"week":t=n(this.year(),this.month(),this.date()-this.weekday()+7)-1;break;case"isoWeek":t=n(this.year(),this.month(),this.date()-(this.isoWeekday()-1)+7)-1;break;case"day":case"date":t=n(this.year(),this.month(),this.date()+1)-1;break;case"hour":t=this._d.valueOf(),t+=36e5-tn(t+(this._isUTC?0:6e4*this.utcOffset()),36e5)-1;break;case"minute":t=this._d.valueOf(),t+=6e4-tn(t,6e4)-1;break;case"second":t=this._d.valueOf(),t+=1e3-tn(t,1e3)-1;break}return this._d.setTime(t),f.updateOffset(this,!0),this},i.format=function(e){return e=e||(this.isUtc()?f.defaultFormatUtc:f.defaultFormat),e=re(this,e),this.localeData().postformat(e)},i.from=function(e,t){return this.isValid()&&(h(e)&&e.isValid()||W(e).isValid())?C({to:this,from:e}).locale(this.locale()).humanize(!t):this.localeData().invalidDate()},i.fromNow=function(e){return this.from(W(),e)},i.to=function(e,t){return this.isValid()&&(h(e)&&e.isValid()||W(e).isValid())?C({from:this,to:e}).locale(this.locale()).humanize(!t):this.localeData().invalidDate()},i.toNow=function(e){return this.to(W(),e)},i.get=function(e){return d(this[e=_(e)])?this[e]():this},i.invalidAt=function(){return m(this).overflow},i.isAfter=function(e,t){return e=h(e)?e:W(e),!(!this.isValid()||!e.isValid())&&("millisecond"===(t=_(t)||"millisecond")?this.valueOf()>e.valueOf():e.valueOf()<this.clone().startOf(t).valueOf())},i.isBefore=function(e,t){return e=h(e)?e:W(e),!(!this.isValid()||!e.isValid())&&("millisecond"===(t=_(t)||"millisecond")?this.valueOf()<e.valueOf():this.clone().endOf(t).valueOf()<e.valueOf())},i.isBetween=function(e,t,n,s){return e=h(e)?e:W(e),t=h(t)?t:W(t),!!(this.isValid()&&e.isValid()&&t.isValid())&&(("("===(s=s||"()")[0]?this.isAfter(e,n):!this.isBefore(e,n))&&(")"===s[1]?this.isBefore(t,n):!this.isAfter(t,n)))},i.isSame=function(e,t){var e=h(e)?e:W(e);return!(!this.isValid()||!e.isValid())&&("millisecond"===(t=_(t)||"millisecond")?this.valueOf()===e.valueOf():(e=e.valueOf(),this.clone().startOf(t).valueOf()<=e&&e<=this.clone().endOf(t).valueOf()))},i.isSameOrAfter=function(e,t){return this.isSame(e,t)||this.isAfter(e,t)},i.isSameOrBefore=function(e,t){return this.isSame(e,t)||this.isBefore(e,t)},i.isValid=function(){return A(this)},i.lang=Xe,i.locale=Xt,i.localeData=Kt,i.max=we,i.min=ge,i.parsingFlags=function(){return E({},m(this))},i.set=function(e,t){if("object"==typeof e)for(var n=function(e){var t,n=[];for(t in e)c(e,t)&&n.push({unit:t,priority:le[t]});return n.sort(function(e,t){return e.priority-t.priority}),n}(e=ue(e)),s=n.length,i=0;i<s;i++)this[n[i].unit](e[n[i].unit]);else if(d(this[e=_(e)]))return this[e](t);return this},i.startOf=function(e){var t,n;if(void 0===(e=_(e))||"millisecond"===e||!this.isValid())return this;switch(n=this._isUTC?sn:nn,e){case"year":t=n(this.year(),0,1);break;case"quarter":t=n(this.year(),this.month()-this.month()%3,1);break;case"month":t=n(this.year(),this.month(),1);break;case"week":t=n(this.year(),this.month(),this.date()-this.weekday());break;case"isoWeek":t=n(this.year(),this.month(),this.date()-(this.isoWeekday()-1));break;case"day":case"date":t=n(this.year(),this.month(),this.date());break;case"hour":t=this._d.valueOf(),t-=tn(t+(this._isUTC?0:6e4*this.utcOffset()),36e5);break;case"minute":t=this._d.valueOf(),t-=tn(t,6e4);break;case"second":t=this._d.valueOf(),t-=tn(t,1e3);break}return this._d.setTime(t),f.updateOffset(this,!0),this},i.subtract=Je,i.toArray=function(){var e=this;return[e.year(),e.month(),e.date(),e.hour(),e.minute(),e.second(),e.millisecond()]},i.toObject=function(){var e=this;return{years:e.year(),months:e.month(),date:e.date(),hours:e.hours(),minutes:e.minutes(),seconds:e.seconds(),milliseconds:e.milliseconds()}},i.toDate=function(){return new Date(this.valueOf())},i.toISOString=function(e){if(!this.isValid())return null;var t=(e=!0!==e)?this.clone().utc():this;return t.year()<0||9999<t.year()?re(t,e?"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYYYY-MM-DD[T]HH:mm:ss.SSSZ"):d(Date.prototype.toISOString)?e?this.toDate().toISOString():new Date(this.valueOf()+60*this.utcOffset()*1e3).toISOString().replace("Z",re(t,"Z")):re(t,e?"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYY-MM-DD[T]HH:mm:ss.SSSZ")},i.inspect=function(){if(!this.isValid())return"moment.invalid(/* "+this._i+" */)";var e,t="moment",n="";return this.isLocal()||(t=0===this.utcOffset()?"moment.utc":"moment.parseZone",n="Z"),t="["+t+'("]',e=0<=this.year()&&this.year()<=9999?"YYYY":"YYYYYY",this.format(t+e+"-MM-DD[T]HH:mm:ss.SSS"+(n+'[")]'))},"undefined"!=typeof Symbol&&null!=Symbol.for&&(i[Symbol.for("nodejs.util.inspect.custom")]=function(){return"Moment<"+this.format()+">"}),i.toJSON=function(){return this.isValid()?this.toISOString():null},i.toString=function(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},i.unix=function(){return Math.floor(this.valueOf()/1e3)},i.valueOf=function(){return this._d.valueOf()-6e4*(this._offset||0)},i.creationData=function(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}},i.eraName=function(){for(var e,t=this.localeData().eras(),n=0,s=t.length;n<s;++n){if(e=this.clone().startOf("day").valueOf(),t[n].since<=e&&e<=t[n].until)return t[n].name;if(t[n].until<=e&&e<=t[n].since)return t[n].name}return""},i.eraNarrow=function(){for(var e,t=this.localeData().eras(),n=0,s=t.length;n<s;++n){if(e=this.clone().startOf("day").valueOf(),t[n].since<=e&&e<=t[n].until)return t[n].narrow;if(t[n].until<=e&&e<=t[n].since)return t[n].narrow}return""},i.eraAbbr=function(){for(var e,t=this.localeData().eras(),n=0,s=t.length;n<s;++n){if(e=this.clone().startOf("day").valueOf(),t[n].since<=e&&e<=t[n].until)return t[n].abbr;if(t[n].until<=e&&e<=t[n].since)return t[n].abbr}return""},i.eraYear=function(){for(var e,t,n=this.localeData().eras(),s=0,i=n.length;s<i;++s)if(e=n[s].since<=n[s].until?1:-1,t=this.clone().startOf("day").valueOf(),n[s].since<=t&&t<=n[s].until||n[s].until<=t&&t<=n[s].since)return(this.year()-f(n[s].since).year())*e+n[s].offset;return this.year()},i.year=Ie,i.isLeapYear=function(){return he(this.year())},i.weekYear=function(e){return un.call(this,e,this.week(),this.weekday(),this.localeData()._week.dow,this.localeData()._week.doy)},i.isoWeekYear=function(e){return un.call(this,e,this.isoWeek(),this.isoWeekday(),1,4)},i.quarter=i.quarters=function(e){return null==e?Math.ceil((this.month()+1)/3):this.month(3*(e-1)+this.month()%3)},i.month=Ge,i.daysInMonth=function(){return We(this.year(),this.month())},i.week=i.weeks=function(e){var t=this.localeData().week(this);return null==e?t:this.add(7*(e-t),"d")},i.isoWeek=i.isoWeeks=function(e){var t=qe(this,1,4).week;return null==e?t:this.add(7*(e-t),"d")},i.weeksInYear=function(){var e=this.localeData()._week;return P(this.year(),e.dow,e.doy)},i.weeksInWeekYear=function(){var e=this.localeData()._week;return P(this.weekYear(),e.dow,e.doy)},i.isoWeeksInYear=function(){return P(this.year(),1,4)},i.isoWeeksInISOWeekYear=function(){return P(this.isoWeekYear(),1,4)},i.date=ke,i.day=i.days=function(e){if(!this.isValid())return null!=e?this:NaN;var t,n,s=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=e?(t=e,n=this.localeData(),e="string"!=typeof t?t:isNaN(t)?"number"==typeof(t=n.weekdaysParse(t))?t:null:parseInt(t,10),this.add(e-s,"d")):s},i.weekday=function(e){if(!this.isValid())return null!=e?this:NaN;var t=(this.day()+7-this.localeData()._week.dow)%7;return null==e?t:this.add(e-t,"d")},i.isoWeekday=function(e){return this.isValid()?null!=e?(t=e,n=this.localeData(),n="string"==typeof t?n.weekdaysParse(t)%7||7:isNaN(t)?null:t,this.day(this.day()%7?n:n-7)):this.day()||7:null!=e?this:NaN;var t,n},i.dayOfYear=function(e){var t=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==e?t:this.add(e-t,"d")},i.hour=i.hours=k,i.minute=i.minutes=_e,i.second=i.seconds=ve,i.millisecond=i.milliseconds=ye,i.utcOffset=function(e,t,n){var s,i=this._offset||0;if(!this.isValid())return null!=e?this:NaN;if(null==e)return this._isUTC?i:Et(this);if("string"==typeof e){if(null===(e=Vt(Ye,e)))return this}else Math.abs(e)<16&&!n&&(e*=60);return!this._isUTC&&t&&(s=Et(this)),this._offset=e,this._isUTC=!0,null!=s&&this.add(s,"m"),i!==e&&(!t||this._changeInProgress?qt(this,C(e-i,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,f.updateOffset(this,!0),this._changeInProgress=null)),this},i.utc=function(e){return this.utcOffset(0,e)},i.local=function(e){return this._isUTC&&(this.utcOffset(0,e),this._isUTC=!1,e&&this.subtract(Et(this),"m")),this},i.parseZone=function(){var e;return null!=this._tzm?this.utcOffset(this._tzm,!1,!0):"string"==typeof this._i&&(null!=(e=Vt(Se,this._i))?this.utcOffset(e):this.utcOffset(0,!0)),this},i.hasAlignedHourOffset=function(e){return!!this.isValid()&&(e=e?W(e).utcOffset():0,(this.utcOffset()-e)%60==0)},i.isDST=function(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},i.isLocal=function(){return!!this.isValid()&&!this._isUTC},i.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},i.isUtc=At,i.isUTC=At,i.zoneAbbr=function(){return this._isUTC?"UTC":""},i.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},i.dates=e("dates accessor is deprecated. Use date instead.",ke),i.months=e("months accessor is deprecated. Use month instead",Ge),i.years=e("years accessor is deprecated. Use year instead",Ie),i.zone=e("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",function(e,t){return null!=e?(this.utcOffset(e="string"!=typeof e?-e:e,t),this):-this.utcOffset()}),i.isDSTShifted=e("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",function(){if(!o(this._isDSTShifted))return this._isDSTShifted;var e,t={};return $(t,this),(t=Nt(t))._a?(e=(t._isUTC?l:W)(t._a),this._isDSTShifted=this.isValid()&&0<function(e,t,n){for(var s=Math.min(e.length,t.length),i=Math.abs(e.length-t.length),r=0,a=0;a<s;a++)(n&&e[a]!==t[a]||!n&&g(e[a])!==g(t[a]))&&r++;return r+i}(t._a,e.toArray())):this._isDSTShifted=!1,this._isDSTShifted});w=K.prototype;function cn(e,t,n,s){var i=mt(),s=l().set(s,t);return i[n](s,e)}function fn(e,t,n){if(u(e)&&(t=e,e=void 0),e=e||"",null!=t)return cn(e,t,n,"month");for(var s=[],i=0;i<12;i++)s[i]=cn(e,i,n,"month");return s}function mn(e,t,n,s){t=("boolean"==typeof e?u(t)&&(n=t,t=void 0):(t=e,e=!1,u(n=t)&&(n=t,t=void 0)),t||"");var i,r=mt(),a=e?r._week.dow:0,o=[];if(null!=n)return cn(t,(n+a)%7,s,"day");for(i=0;i<7;i++)o[i]=cn(t,(i+a)%7,s,"day");return o}w.calendar=function(e,t,n){return d(e=this._calendar[e]||this._calendar.sameElse)?e.call(t,n):e},w.longDateFormat=function(e){var t=this._longDateFormat[e],n=this._longDateFormat[e.toUpperCase()];return t||!n?t:(this._longDateFormat[e]=n.match(te).map(function(e){return"MMMM"===e||"MM"===e||"DD"===e||"dddd"===e?e.slice(1):e}).join(""),this._longDateFormat[e])},w.invalidDate=function(){return this._invalidDate},w.ordinal=function(e){return this._ordinal.replace("%d",e)},w.preparse=dn,w.postformat=dn,w.relativeTime=function(e,t,n,s){var i=this._relativeTime[n];return d(i)?i(e,t,n,s):i.replace(/%d/i,e)},w.pastFuture=function(e,t){return d(e=this._relativeTime[0<e?"future":"past"])?e(t):e.replace(/%s/i,t)},w.set=function(e){var t,n;for(n in e)c(e,n)&&(d(t=e[n])?this[n]=t:this["_"+n]=t);this._config=e,this._dayOfMonthOrdinalParseLenient=new RegExp((this._dayOfMonthOrdinalParse.source||this._ordinalParse.source)+"|"+/\d{1,2}/.source)},w.eras=function(e,t){for(var n,s=this._eras||mt("en")._eras,i=0,r=s.length;i<r;++i){switch(typeof s[i].since){case"string":n=f(s[i].since).startOf("day"),s[i].since=n.valueOf();break}switch(typeof s[i].until){case"undefined":s[i].until=1/0;break;case"string":n=f(s[i].until).startOf("day").valueOf(),s[i].until=n.valueOf();break}}return s},w.erasParse=function(e,t,n){var s,i,r,a,o,u=this.eras();for(e=e.toUpperCase(),s=0,i=u.length;s<i;++s)if(r=u[s].name.toUpperCase(),a=u[s].abbr.toUpperCase(),o=u[s].narrow.toUpperCase(),n)switch(t){case"N":case"NN":case"NNN":if(a===e)return u[s];break;case"NNNN":if(r===e)return u[s];break;case"NNNNN":if(o===e)return u[s];break}else if(0<=[r,a,o].indexOf(e))return u[s]},w.erasConvertYear=function(e,t){var n=e.since<=e.until?1:-1;return void 0===t?f(e.since).year():f(e.since).year()+(t-e.offset)*n},w.erasAbbrRegex=function(e){return c(this,"_erasAbbrRegex")||an.call(this),e?this._erasAbbrRegex:this._erasRegex},w.erasNameRegex=function(e){return c(this,"_erasNameRegex")||an.call(this),e?this._erasNameRegex:this._erasRegex},w.erasNarrowRegex=function(e){return c(this,"_erasNarrowRegex")||an.call(this),e?this._erasNarrowRegex:this._erasRegex},w.months=function(e,t){return e?(a(this._months)?this._months:this._months[(this._months.isFormat||He).test(t)?"format":"standalone"])[e.month()]:a(this._months)?this._months:this._months.standalone},w.monthsShort=function(e,t){return e?(a(this._monthsShort)?this._monthsShort:this._monthsShort[He.test(t)?"format":"standalone"])[e.month()]:a(this._monthsShort)?this._monthsShort:this._monthsShort.standalone},w.monthsParse=function(e,t,n){var s,i;if(this._monthsParseExact)return function(e,t,n){var s,i,r,e=e.toLocaleLowerCase();if(!this._monthsParse)for(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[],s=0;s<12;++s)r=l([2e3,s]),this._shortMonthsParse[s]=this.monthsShort(r,"").toLocaleLowerCase(),this._longMonthsParse[s]=this.months(r,"").toLocaleLowerCase();return n?"MMM"===t?-1!==(i=S.call(this._shortMonthsParse,e))?i:null:-1!==(i=S.call(this._longMonthsParse,e))?i:null:"MMM"===t?-1!==(i=S.call(this._shortMonthsParse,e))||-1!==(i=S.call(this._longMonthsParse,e))?i:null:-1!==(i=S.call(this._longMonthsParse,e))||-1!==(i=S.call(this._shortMonthsParse,e))?i:null}.call(this,e,t,n);for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),s=0;s<12;s++){if(i=l([2e3,s]),n&&!this._longMonthsParse[s]&&(this._longMonthsParse[s]=new RegExp("^"+this.months(i,"").replace(".","")+"$","i"),this._shortMonthsParse[s]=new RegExp("^"+this.monthsShort(i,"").replace(".","")+"$","i")),n||this._monthsParse[s]||(i="^"+this.months(i,"")+"|^"+this.monthsShort(i,""),this._monthsParse[s]=new RegExp(i.replace(".",""),"i")),n&&"MMMM"===t&&this._longMonthsParse[s].test(e))return s;if(n&&"MMM"===t&&this._shortMonthsParse[s].test(e))return s;if(!n&&this._monthsParse[s].test(e))return s}},w.monthsRegex=function(e){return this._monthsParseExact?(c(this,"_monthsRegex")||Ee.call(this),e?this._monthsStrictRegex:this._monthsRegex):(c(this,"_monthsRegex")||(this._monthsRegex=Le),this._monthsStrictRegex&&e?this._monthsStrictRegex:this._monthsRegex)},w.monthsShortRegex=function(e){return this._monthsParseExact?(c(this,"_monthsRegex")||Ee.call(this),e?this._monthsShortStrictRegex:this._monthsShortRegex):(c(this,"_monthsShortRegex")||(this._monthsShortRegex=Fe),this._monthsShortStrictRegex&&e?this._monthsShortStrictRegex:this._monthsShortRegex)},w.week=function(e){return qe(e,this._week.dow,this._week.doy).week},w.firstDayOfYear=function(){return this._week.doy},w.firstDayOfWeek=function(){return this._week.dow},w.weekdays=function(e,t){return t=a(this._weekdays)?this._weekdays:this._weekdays[e&&!0!==e&&this._weekdays.isFormat.test(t)?"format":"standalone"],!0===e?Be(t,this._week.dow):e?t[e.day()]:t},w.weekdaysMin=function(e){return!0===e?Be(this._weekdaysMin,this._week.dow):e?this._weekdaysMin[e.day()]:this._weekdaysMin},w.weekdaysShort=function(e){return!0===e?Be(this._weekdaysShort,this._week.dow):e?this._weekdaysShort[e.day()]:this._weekdaysShort},w.weekdaysParse=function(e,t,n){var s,i;if(this._weekdaysParseExact)return function(e,t,n){var s,i,r,e=e.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],s=0;s<7;++s)r=l([2e3,1]).day(s),this._minWeekdaysParse[s]=this.weekdaysMin(r,"").toLocaleLowerCase(),this._shortWeekdaysParse[s]=this.weekdaysShort(r,"").toLocaleLowerCase(),this._weekdaysParse[s]=this.weekdays(r,"").toLocaleLowerCase();return n?"dddd"===t?-1!==(i=S.call(this._weekdaysParse,e))?i:null:"ddd"===t?-1!==(i=S.call(this._shortWeekdaysParse,e))?i:null:-1!==(i=S.call(this._minWeekdaysParse,e))?i:null:"dddd"===t?-1!==(i=S.call(this._weekdaysParse,e))||-1!==(i=S.call(this._shortWeekdaysParse,e))||-1!==(i=S.call(this._minWeekdaysParse,e))?i:null:"ddd"===t?-1!==(i=S.call(this._shortWeekdaysParse,e))||-1!==(i=S.call(this._weekdaysParse,e))||-1!==(i=S.call(this._minWeekdaysParse,e))?i:null:-1!==(i=S.call(this._minWeekdaysParse,e))||-1!==(i=S.call(this._weekdaysParse,e))||-1!==(i=S.call(this._shortWeekdaysParse,e))?i:null}.call(this,e,t,n);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),s=0;s<7;s++){if(i=l([2e3,1]).day(s),n&&!this._fullWeekdaysParse[s]&&(this._fullWeekdaysParse[s]=new RegExp("^"+this.weekdays(i,"").replace(".","\\.?")+"$","i"),this._shortWeekdaysParse[s]=new RegExp("^"+this.weekdaysShort(i,"").replace(".","\\.?")+"$","i"),this._minWeekdaysParse[s]=new RegExp("^"+this.weekdaysMin(i,"").replace(".","\\.?")+"$","i")),this._weekdaysParse[s]||(i="^"+this.weekdays(i,"")+"|^"+this.weekdaysShort(i,"")+"|^"+this.weekdaysMin(i,""),this._weekdaysParse[s]=new RegExp(i.replace(".",""),"i")),n&&"dddd"===t&&this._fullWeekdaysParse[s].test(e))return s;if(n&&"ddd"===t&&this._shortWeekdaysParse[s].test(e))return s;if(n&&"dd"===t&&this._minWeekdaysParse[s].test(e))return s;if(!n&&this._weekdaysParse[s].test(e))return s}},w.weekdaysRegex=function(e){return this._weekdaysParseExact?(c(this,"_weekdaysRegex")||nt.call(this),e?this._weekdaysStrictRegex:this._weekdaysRegex):(c(this,"_weekdaysRegex")||(this._weekdaysRegex=Ke),this._weekdaysStrictRegex&&e?this._weekdaysStrictRegex:this._weekdaysRegex)},w.weekdaysShortRegex=function(e){return this._weekdaysParseExact?(c(this,"_weekdaysRegex")||nt.call(this),e?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):(c(this,"_weekdaysShortRegex")||(this._weekdaysShortRegex=et),this._weekdaysShortStrictRegex&&e?this._weekdaysShortStrictRegex:this._weekdaysShortRegex)},w.weekdaysMinRegex=function(e){return this._weekdaysParseExact?(c(this,"_weekdaysRegex")||nt.call(this),e?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):(c(this,"_weekdaysMinRegex")||(this._weekdaysMinRegex=tt),this._weekdaysMinStrictRegex&&e?this._weekdaysMinStrictRegex:this._weekdaysMinRegex)},w.isPM=function(e){return"p"===(e+"").toLowerCase().charAt(0)},w.meridiem=function(e,t,n){return 11<e?n?"pm":"PM":n?"am":"AM"},ct("en",{eras:[{since:"0001-01-01",until:1/0,offset:1,name:"Anno Domini",narrow:"AD",abbr:"AD"},{since:"0000-12-31",until:-1/0,offset:1,name:"Before Christ",narrow:"BC",abbr:"BC"}],dayOfMonthOrdinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(e){var t=e%10;return e+(1===g(e%100/10)?"th":1==t?"st":2==t?"nd":3==t?"rd":"th")}}),f.lang=e("moment.lang is deprecated. Use moment.locale instead.",ct),f.langData=e("moment.langData is deprecated. Use moment.localeData instead.",mt);var _n=Math.abs;function yn(e,t,n,s){t=C(t,n);return e._milliseconds+=s*t._milliseconds,e._days+=s*t._days,e._months+=s*t._months,e._bubble()}function gn(e){return e<0?Math.floor(e):Math.ceil(e)}function wn(e){return 4800*e/146097}function pn(e){return 146097*e/4800}function kn(e){return function(){return this.as(e)}}pe=kn("ms"),me=kn("s"),Ce=kn("m"),we=kn("h"),ge=kn("d"),Je=kn("w"),k=kn("M"),_e=kn("Q"),ve=kn("y");function vn(e){return function(){return this.isValid()?this._data[e]:NaN}}var ye=vn("milliseconds"),ke=vn("seconds"),Ie=vn("minutes"),w=vn("hours"),Mn=vn("days"),Dn=vn("months"),Sn=vn("years");var Yn=Math.round,On={ss:44,s:45,m:45,h:22,d:26,w:null,M:11};function bn(e,t,n,s){var i=C(e).abs(),r=Yn(i.as("s")),a=Yn(i.as("m")),o=Yn(i.as("h")),u=Yn(i.as("d")),l=Yn(i.as("M")),h=Yn(i.as("w")),i=Yn(i.as("y")),r=(r<=n.ss?["s",r]:r<n.s&&["ss",r])||a<=1&&["m"]||a<n.m&&["mm",a]||o<=1&&["h"]||o<n.h&&["hh",o]||u<=1&&["d"]||u<n.d&&["dd",u];return(r=(r=null!=n.w?r||h<=1&&["w"]||h<n.w&&["ww",h]:r)||l<=1&&["M"]||l<n.M&&["MM",l]||i<=1&&["y"]||["yy",i])[2]=t,r[3]=0<+e,r[4]=s,function(e,t,n,s,i){return i.relativeTime(t||1,!!n,e,s)}.apply(null,r)}var xn=Math.abs;function Tn(e){return(0<e)-(e<0)||+e}function Nn(){if(!this.isValid())return this.localeData().invalidDate();var e,t,n,s,i,r,a,o=xn(this._milliseconds)/1e3,u=xn(this._days),l=xn(this._months),h=this.asSeconds();return h?(e=y(o/60),t=y(e/60),o%=60,e%=60,n=y(l/12),l%=12,s=o?o.toFixed(3).replace(/\.?0+$/,""):"",i=Tn(this._months)!==Tn(h)?"-":"",r=Tn(this._days)!==Tn(h)?"-":"",a=Tn(this._milliseconds)!==Tn(h)?"-":"",(h<0?"-":"")+"P"+(n?i+n+"Y":"")+(l?i+l+"M":"")+(u?r+u+"D":"")+(t||e||o?"T":"")+(t?a+t+"H":"")+(e?a+e+"M":"")+(o?a+s+"S":"")):"P0D"}var U=Ct.prototype;return U.isValid=function(){return this._isValid},U.abs=function(){var e=this._data;return this._milliseconds=_n(this._milliseconds),this._days=_n(this._days),this._months=_n(this._months),e.milliseconds=_n(e.milliseconds),e.seconds=_n(e.seconds),e.minutes=_n(e.minutes),e.hours=_n(e.hours),e.months=_n(e.months),e.years=_n(e.years),this},U.add=function(e,t){return yn(this,e,t,1)},U.subtract=function(e,t){return yn(this,e,t,-1)},U.as=function(e){if(!this.isValid())return NaN;var t,n,s=this._milliseconds;if("month"===(e=_(e))||"quarter"===e||"year"===e)switch(t=this._days+s/864e5,n=this._months+wn(t),e){case"month":return n;case"quarter":return n/3;case"year":return n/12}else switch(t=this._days+Math.round(pn(this._months)),e){case"week":return t/7+s/6048e5;case"day":return t+s/864e5;case"hour":return 24*t+s/36e5;case"minute":return 1440*t+s/6e4;case"second":return 86400*t+s/1e3;case"millisecond":return Math.floor(864e5*t)+s;default:throw new Error("Unknown unit "+e)}},U.asMilliseconds=pe,U.asSeconds=me,U.asMinutes=Ce,U.asHours=we,U.asDays=ge,U.asWeeks=Je,U.asMonths=k,U.asQuarters=_e,U.asYears=ve,U.valueOf=function(){return this.isValid()?this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*g(this._months/12):NaN},U._bubble=function(){var e=this._milliseconds,t=this._days,n=this._months,s=this._data;return 0<=e&&0<=t&&0<=n||e<=0&&t<=0&&n<=0||(e+=864e5*gn(pn(n)+t),n=t=0),s.milliseconds=e%1e3,e=y(e/1e3),s.seconds=e%60,e=y(e/60),s.minutes=e%60,e=y(e/60),s.hours=e%24,t+=y(e/24),n+=e=y(wn(t)),t-=gn(pn(e)),e=y(n/12),n%=12,s.days=t,s.months=n,s.years=e,this},U.clone=function(){return C(this)},U.get=function(e){return e=_(e),this.isValid()?this[e+"s"]():NaN},U.milliseconds=ye,U.seconds=ke,U.minutes=Ie,U.hours=w,U.days=Mn,U.weeks=function(){return y(this.days()/7)},U.months=Dn,U.years=Sn,U.humanize=function(e,t){if(!this.isValid())return this.localeData().invalidDate();var n=!1,s=On;return"object"==typeof e&&(t=e,e=!1),"boolean"==typeof e&&(n=e),"object"==typeof t&&(s=Object.assign({},On,t),null!=t.s&&null==t.ss&&(s.ss=t.s-1)),e=this.localeData(),t=bn(this,!n,s,e),n&&(t=e.pastFuture(+this,t)),e.postformat(t)},U.toISOString=Nn,U.toString=Nn,U.toJSON=Nn,U.locale=Xt,U.localeData=Kt,U.toIsoString=e("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",Nn),U.lang=Xe,s("X",0,0,"unix"),s("x",0,0,"valueOf"),v("x",De),v("X",/[+-]?\d+(\.\d{1,3})?/),D("X",function(e,t,n){n._d=new Date(1e3*parseFloat(e))}),D("x",function(e,t,n){n._d=new Date(g(e))}),f.version="2.29.4",H=W,f.fn=i,f.min=function(){return Rt("isBefore",[].slice.call(arguments,0))},f.max=function(){return Rt("isAfter",[].slice.call(arguments,0))},f.now=function(){return Date.now?Date.now():+new Date},f.utc=l,f.unix=function(e){return W(1e3*e)},f.months=function(e,t){return fn(e,t,"months")},f.isDate=V,f.locale=ct,f.invalid=I,f.duration=C,f.isMoment=h,f.weekdays=function(e,t,n){return mn(e,t,n,"weekdays")},f.parseZone=function(){return W.apply(null,arguments).parseZone()},f.localeData=mt,f.isDuration=Ut,f.monthsShort=function(e,t){return fn(e,t,"monthsShort")},f.weekdaysMin=function(e,t,n){return mn(e,t,n,"weekdaysMin")},f.defineLocale=ft,f.updateLocale=function(e,t){var n,s;return null!=t?(s=ot,null!=R[e]&&null!=R[e].parentLocale?R[e].set(X(R[e]._config,t)):(t=X(s=null!=(n=dt(e))?n._config:s,t),null==n&&(t.abbr=e),(s=new K(t)).parentLocale=R[e],R[e]=s),ct(e)):null!=R[e]&&(null!=R[e].parentLocale?(R[e]=R[e].parentLocale,e===ct()&&ct(e)):null!=R[e]&&delete R[e]),R[e]},f.locales=function(){return ee(R)},f.weekdaysShort=function(e,t,n){return mn(e,t,n,"weekdaysShort")},f.normalizeUnits=_,f.relativeTimeRounding=function(e){return void 0===e?Yn:"function"==typeof e&&(Yn=e,!0)},f.relativeTimeThreshold=function(e,t){return void 0!==On[e]&&(void 0===t?On[e]:(On[e]=t,"s"===e&&(On.ss=t-1),!0))},f.calendarFormat=function(e,t){return(e=e.diff(t,"days",!0))<-6?"sameElse":e<-1?"lastWeek":e<0?"lastDay":e<1?"sameDay":e<2?"nextDay":e<7?"nextWeek":"sameElse"},f.prototype=i,f.HTML5_FMT={DATETIME_LOCAL:"YYYY-MM-DDTHH:mm",DATETIME_LOCAL_SECONDS:"YYYY-MM-DDTHH:mm:ss",DATETIME_LOCAL_MS:"YYYY-MM-DDTHH:mm:ss.SSS",DATE:"YYYY-MM-DD",TIME:"HH:mm",TIME_SECONDS:"HH:mm:ss",TIME_MS:"HH:mm:ss.SSS",WEEK:"GGGG-[W]WW",MONTH:"YYYY-MM"},f}); +//# sourceMappingURL=moment.min.js.map