From 12054f2b51603d91fd89c7076d91ac36c8748a8a Mon Sep 17 00:00:00 2001 From: Stas Kozar Date: Mon, 24 Jun 2019 16:17:17 +0300 Subject: [PATCH 001/191] MC-17753: Authorize.net Cannot read property 'length' of null --- .../web/js/view/payment/method-renderer/authorizenet-accept.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/AuthorizenetAcceptjs/view/frontend/web/js/view/payment/method-renderer/authorizenet-accept.js b/app/code/Magento/AuthorizenetAcceptjs/view/frontend/web/js/view/payment/method-renderer/authorizenet-accept.js index 983318c4cdaa..8d674187c377 100644 --- a/app/code/Magento/AuthorizenetAcceptjs/view/frontend/web/js/view/payment/method-renderer/authorizenet-accept.js +++ b/app/code/Magento/AuthorizenetAcceptjs/view/frontend/web/js/view/payment/method-renderer/authorizenet-accept.js @@ -91,7 +91,8 @@ define([ return; } - authData.clientKey = window.checkoutConfig.payment[this.getCode()].clientKey; + authData.clientKey = window.checkoutConfig.payment[this.getCode()].clientKey ? + window.checkoutConfig.payment[this.getCode()].clientKey : 0; authData.apiLoginID = window.checkoutConfig.payment[this.getCode()].apiLoginID; cardData.cardNumber = this.creditCardNumber(); From 7c89e8ce27924bfe0019ab9d6d6209508cea5bde Mon Sep 17 00:00:00 2001 From: Stas Kozar Date: Tue, 25 Jun 2019 16:52:11 +0300 Subject: [PATCH 002/191] MC-17753: Authorize.net Cannot read property 'length' of null --- .../js/view/payment/method-renderer/authorizenet-accept.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/AuthorizenetAcceptjs/view/frontend/web/js/view/payment/method-renderer/authorizenet-accept.js b/app/code/Magento/AuthorizenetAcceptjs/view/frontend/web/js/view/payment/method-renderer/authorizenet-accept.js index 8d674187c377..bba1290a9eed 100644 --- a/app/code/Magento/AuthorizenetAcceptjs/view/frontend/web/js/view/payment/method-renderer/authorizenet-accept.js +++ b/app/code/Magento/AuthorizenetAcceptjs/view/frontend/web/js/view/payment/method-renderer/authorizenet-accept.js @@ -91,9 +91,10 @@ define([ return; } - authData.clientKey = window.checkoutConfig.payment[this.getCode()].clientKey ? - window.checkoutConfig.payment[this.getCode()].clientKey : 0; - authData.apiLoginID = window.checkoutConfig.payment[this.getCode()].apiLoginID; + authData.clientKey = window.checkoutConfig.payment[this.getCode()].clientKey !== null ? + window.checkoutConfig.payment[this.getCode()].clientKey : ''; + authData.apiLoginID = window.checkoutConfig.payment[this.getCode()].apiLoginID !== null ? + window.checkoutConfig.payment[this.getCode()].apiLoginID : ''; cardData.cardNumber = this.creditCardNumber(); cardData.month = this.creditCardExpMonth(); From 5409b1f6ef99bb2fbbe1a10c32774cff66782cac Mon Sep 17 00:00:00 2001 From: Stas Kozar Date: Wed, 26 Jun 2019 12:39:56 +0300 Subject: [PATCH 003/191] MC-17753: Authorize.net Cannot read property 'length' of null --- .../etc/adminhtml/system.xml | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/AuthorizenetAcceptjs/etc/adminhtml/system.xml b/app/code/Magento/AuthorizenetAcceptjs/etc/adminhtml/system.xml index 279a904d916a..f3c3cced0cd9 100644 --- a/app/code/Magento/AuthorizenetAcceptjs/etc/adminhtml/system.xml +++ b/app/code/Magento/AuthorizenetAcceptjs/etc/adminhtml/system.xml @@ -17,7 +17,7 @@ - + 1 Magento\Config\Block\System\Config\Form\Fieldset @@ -39,25 +39,44 @@ Magento\Config\Model\Config\Backend\Encrypted payment/authorizenet_acceptjs/login + required-entry + + 1 + Magento\Config\Model\Config\Backend\Encrypted payment/authorizenet_acceptjs/trans_key + required-entry + + 1 + payment/authorizenet_acceptjs/public_client_key + required-entry + + 1 + Magento\Config\Model\Config\Backend\Encrypted payment/authorizenet_acceptjs/trans_signature_key + required-entry + + 1 + Magento\Config\Model\Config\Backend\Encrypted payment/authorizenet_acceptjs/trans_md5 + + 1 + From 85728edb75f35e1acf0e966607d32ecaa911ad3a Mon Sep 17 00:00:00 2001 From: Stas Kozar Date: Wed, 26 Jun 2019 18:10:59 +0300 Subject: [PATCH 004/191] MC-17753: Authorize.net Cannot read property 'length' of null --- ...nfigureAuthorizenetAcceptjsActionGroup.xml | 53 ++++++++++--------- ...thorizenetAcceptjsConfigurationSection.xml | 4 ++ ...enetAcceptjsWithoutRequiredOptionsTest.xml | 31 +++++++++++ .../FullCaptureAuthorizenetAcceptjsTest.xml | 3 ++ ...VirtualProductAuthorizenetAcceptjsTest.xml | 3 ++ 5 files changed, 69 insertions(+), 25 deletions(-) create mode 100644 app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/Test/ConfigureAuthorizenetAcceptjsWithoutRequiredOptionsTest.xml diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/ActionGroup/ConfigureAuthorizenetAcceptjsActionGroup.xml b/app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/ActionGroup/ConfigureAuthorizenetAcceptjsActionGroup.xml index e9a194435e3e..e3e1a6f2e3d0 100644 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/ActionGroup/ConfigureAuthorizenetAcceptjsActionGroup.xml +++ b/app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/ActionGroup/ConfigureAuthorizenetAcceptjsActionGroup.xml @@ -7,40 +7,43 @@ --> - + - - - - - - - - - - - - - - - - + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/Section/AuthorizenetAcceptjsConfigurationSection.xml b/app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/Section/AuthorizenetAcceptjsConfigurationSection.xml index 31be865ea267..4e5d917bbf2e 100644 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/Section/AuthorizenetAcceptjsConfigurationSection.xml +++ b/app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/Section/AuthorizenetAcceptjsConfigurationSection.xml @@ -20,5 +20,9 @@ + + + + diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/Test/ConfigureAuthorizenetAcceptjsWithoutRequiredOptionsTest.xml b/app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/Test/ConfigureAuthorizenetAcceptjsWithoutRequiredOptionsTest.xml new file mode 100644 index 000000000000..df8787837414 --- /dev/null +++ b/app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/Test/ConfigureAuthorizenetAcceptjsWithoutRequiredOptionsTest.xml @@ -0,0 +1,31 @@ + + + + + + + + + <description value="Unable to configure Authorize.net Accept.js without required options"/> + <severity value="CRITICAL"/> + <testCaseId value="MC-17805"/> + <useCaseId value="MC-17753"/> + <group value="AuthorizenetAcceptjs"/> + </annotations> + <before> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + </before> + <after> + <actionGroup ref="logout" stepKey="logout"/> + </after> + <amOnPage url="{{AdminConfigPaymentMethodsPage.url}}" stepKey="navigateToPaymentConfigurationPage"/> + <actionGroup ref="EnableAuthorizenetAcceptjs" stepKey="enableAuthorizenetAcceptjs"/> + <actionGroup ref="AssertAuthorizenetAcceptjsRequiredFieldsValidationArePresentOnSave" stepKey="assertErrorMessages"/> + </test> +</tests> diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/Test/FullCaptureAuthorizenetAcceptjsTest.xml b/app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/Test/FullCaptureAuthorizenetAcceptjsTest.xml index 6aa6792e0e0d..a973b9bee9cb 100644 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/Test/FullCaptureAuthorizenetAcceptjsTest.xml +++ b/app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/Test/FullCaptureAuthorizenetAcceptjsTest.xml @@ -31,9 +31,12 @@ </createData> <!--Configure Auth.net--> + <amOnPage url="{{AdminConfigPaymentMethodsPage.url}}" stepKey="navigateToPaymentConfigurationPage"/> + <actionGroup ref="EnableAuthorizenetAcceptjs" stepKey="enableAuthorizenetAcceptjs"/> <actionGroup ref="ConfigureAuthorizenetAcceptjs" stepKey="configureAuthorizenetAcceptjs"> <argument name="paymentAction" value="Authorize Only"/> </actionGroup> + <actionGroup ref="AdminSaveConfigActionGroup" stepKey="saveConfig"/> </before> <after> diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/Test/GuestCheckoutVirtualProductAuthorizenetAcceptjsTest.xml b/app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/Test/GuestCheckoutVirtualProductAuthorizenetAcceptjsTest.xml index 6f71bd180766..1c2f1425028c 100644 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/Test/GuestCheckoutVirtualProductAuthorizenetAcceptjsTest.xml +++ b/app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/Test/GuestCheckoutVirtualProductAuthorizenetAcceptjsTest.xml @@ -36,9 +36,12 @@ <actionGroup ref="saveProductForm" stepKey="saveProductForm"/> <!--Configure Auth.net--> + <amOnPage url="{{AdminConfigPaymentMethodsPage.url}}" stepKey="navigateToPaymentConfigurationPage"/> + <actionGroup ref="EnableAuthorizenetAcceptjs" stepKey="enableAuthorizenetAcceptjs"/> <actionGroup ref="ConfigureAuthorizenetAcceptjs" stepKey="configureAuthorizenetAcceptjs"> <argument name="paymentAction" value="Authorize and Capture"/> </actionGroup> + <actionGroup ref="AdminSaveConfigActionGroup" stepKey="saveConfig"/> </before> <after> From d2719e406507ab0cf975bea6e349201dab46f6a0 Mon Sep 17 00:00:00 2001 From: Stas Kozar <stas.kozar@transoftgroup.com> Date: Thu, 27 Jun 2019 10:23:11 +0300 Subject: [PATCH 005/191] MC-17753: Authorize.net Cannot read property 'length' of null --- .../AuthorizenetAcceptjs/etc/adminhtml/system.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/AuthorizenetAcceptjs/etc/adminhtml/system.xml b/app/code/Magento/AuthorizenetAcceptjs/etc/adminhtml/system.xml index f3c3cced0cd9..60064857a9ee 100644 --- a/app/code/Magento/AuthorizenetAcceptjs/etc/adminhtml/system.xml +++ b/app/code/Magento/AuthorizenetAcceptjs/etc/adminhtml/system.xml @@ -41,7 +41,7 @@ <config_path>payment/authorizenet_acceptjs/login</config_path> <validate>required-entry</validate> <depends> - <field id="*/*/active">1</field> + <field id="*/authorizenet_acceptjs/active">1</field> </depends> </field> <field id="trans_key" translate="label" type="obscure" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="0"> @@ -50,7 +50,7 @@ <config_path>payment/authorizenet_acceptjs/trans_key</config_path> <validate>required-entry</validate> <depends> - <field id="*/*/active">1</field> + <field id="*/authorizenet_acceptjs/active">1</field> </depends> </field> <field id="public_client_key" translate="label" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="0"> @@ -58,7 +58,7 @@ <config_path>payment/authorizenet_acceptjs/public_client_key</config_path> <validate>required-entry</validate> <depends> - <field id="*/*/active">1</field> + <field id="*/authorizenet_acceptjs/active">1</field> </depends> </field> <field id="trans_signature_key" translate="label" type="obscure" sortOrder="60" showInDefault="1" showInWebsite="1" showInStore="0"> @@ -67,7 +67,7 @@ <config_path>payment/authorizenet_acceptjs/trans_signature_key</config_path> <validate>required-entry</validate> <depends> - <field id="*/*/active">1</field> + <field id="*/authorizenet_acceptjs/active">1</field> </depends> </field> <field id="trans_md5" translate="label" type="obscure" sortOrder="70" showInDefault="1" showInWebsite="1" showInStore="0"> @@ -75,7 +75,7 @@ <backend_model>Magento\Config\Model\Config\Backend\Encrypted</backend_model> <config_path>payment/authorizenet_acceptjs/trans_md5</config_path> <depends> - <field id="*/*/active">1</field> + <field id="*/authorizenet_acceptjs/active">1</field> </depends> </field> </group> From 358257883682de01a0fa5aeaa9d8c2c27e6bee21 Mon Sep 17 00:00:00 2001 From: Stas Kozar <stas.kozar@transoftgroup.com> Date: Thu, 27 Jun 2019 16:22:25 +0300 Subject: [PATCH 006/191] MC-17753: Authorize.net Cannot read property 'length' of null --- .../ConfigureAuthorizenetAcceptjsActionGroup.xml | 8 ++++---- .../Section/AuthorizenetAcceptjsConfigurationSection.xml | 4 ---- .../Config/Test/Mftf/Section/AdminConfigSection.xml | 3 ++- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/ActionGroup/ConfigureAuthorizenetAcceptjsActionGroup.xml b/app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/ActionGroup/ConfigureAuthorizenetAcceptjsActionGroup.xml index e3e1a6f2e3d0..b8020129d487 100644 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/ActionGroup/ConfigureAuthorizenetAcceptjsActionGroup.xml +++ b/app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/ActionGroup/ConfigureAuthorizenetAcceptjsActionGroup.xml @@ -38,12 +38,12 @@ <scrollToTopOfPage stepKey="scrollToTop"/> <click selector="{{AdminMainActionsSection.save}}" stepKey="clickSave"/> <scrollTo selector="{{AuthorizenetAcceptjsConfigurationSection.apiLoginIdField}}" stepKey="scrollToApiLoginIdField"/> - <seeElement selector="{{AuthorizenetAcceptjsConfigurationSection.apiLoginIdFieldRequiredMessage}}" stepKey="seeApiLoginIdRequiredErrorMessage"/> + <see selector="{{AuthorizenetAcceptjsConfigurationSection.apiLoginIdField}} + {{AdminConfigSection.fieldError}}" userInput="This is a required field." stepKey="seeApiLoginIdRequiredMessage"/> <scrollTo selector="{{AuthorizenetAcceptjsConfigurationSection.publicClientKeyField}}" stepKey="scrollToPublicClientKeyField"/> - <seeElement selector="{{AuthorizenetAcceptjsConfigurationSection.publicClientKeyFieldRequiredMessage}}" stepKey="seePublicClientKeyRequiredErrorMessage"/> + <see selector="{{AuthorizenetAcceptjsConfigurationSection.publicClientKeyField}} + {{AdminConfigSection.fieldError}}" userInput="This is a required field." stepKey="seePublicClientKeyRequiredErrorMessage"/> <scrollTo selector="{{AuthorizenetAcceptjsConfigurationSection.transactionKeyField}}" stepKey="scrollTransactionKeyField"/> - <seeElement selector="{{AuthorizenetAcceptjsConfigurationSection.transactionKeyFieldRequiredMessage}}" stepKey="seeTransactionKeyRequiredErrorMessage"/> + <see selector="{{AuthorizenetAcceptjsConfigurationSection.transactionKeyField}} + {{AdminConfigSection.fieldError}}" userInput="This is a required field." stepKey="seeTransactionKeyRequiredErrorMessage"/> <scrollTo selector="{{AuthorizenetAcceptjsConfigurationSection.signatureKeyField}}" stepKey="scrollToSignatureKeyField"/> - <seeElement selector="{{AuthorizenetAcceptjsConfigurationSection.signatureKeyFieldRequiredMessage}}" stepKey="seeSignatureKeyRequiredErrorMessage"/> + <see selector="{{AuthorizenetAcceptjsConfigurationSection.signatureKeyField}} + {{AdminConfigSection.fieldError}}" userInput="This is a required field." stepKey="seeSignatureKeyRequiredErrorMessage"/> </actionGroup> </actionGroups> diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/Section/AuthorizenetAcceptjsConfigurationSection.xml b/app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/Section/AuthorizenetAcceptjsConfigurationSection.xml index 4e5d917bbf2e..31be865ea267 100644 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/Section/AuthorizenetAcceptjsConfigurationSection.xml +++ b/app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/Section/AuthorizenetAcceptjsConfigurationSection.xml @@ -20,9 +20,5 @@ <element name="paymentActionCheckbox" type="input" selector="#payment_us_authorizenet_acceptjs_required_payment_action_inherit"/> <element name="paymentActionSelect" type="select" selector="#payment_us_authorizenet_acceptjs_required_payment_action"/> <element name="paymentActionSelectDisabled" type="select" selector="#payment_us_authorizenet_acceptjs_required_payment_action[disabled='disabled']"/> - <element name="apiLoginIdFieldRequiredMessage" type="text" selector="//input[@name='groups[authorizenet_acceptjs][groups][required][fields][login][value]']/../label[contains(.,'This is a required field.')]"/> - <element name="publicClientKeyFieldRequiredMessage" type="text" selector="//input[@name='groups[authorizenet_acceptjs][groups][required][fields][public_client_key][value]']/../label[contains(.,'This is a required field.')]"/> - <element name="transactionKeyFieldRequiredMessage" type="text" selector="//input[@name='groups[authorizenet_acceptjs][groups][required][fields][trans_key][value]']/../label[contains(.,'This is a required field.')]"/> - <element name="signatureKeyFieldRequiredMessage" type="text" selector="//input[@name='groups[authorizenet_acceptjs][groups][required][fields][trans_signature_key][value]']/../label[contains(.,'This is a required field.')]"/> </section> </sections> diff --git a/app/code/Magento/Config/Test/Mftf/Section/AdminConfigSection.xml b/app/code/Magento/Config/Test/Mftf/Section/AdminConfigSection.xml index b5bfe9cc2ea0..fd49c1482c13 100644 --- a/app/code/Magento/Config/Test/Mftf/Section/AdminConfigSection.xml +++ b/app/code/Magento/Config/Test/Mftf/Section/AdminConfigSection.xml @@ -13,5 +13,6 @@ <element name="generalTabOpened" type="text" selector="//div[@class='admin__page-nav-title title _collapsible' and @aria-expanded='true' or @aria-expanded='1']//strong[text()='General']"/> <element name="defaultConfigButton" type="button" selector="#store-change-button" timeout="30"/> <element name="defaultConfigDropdown" type="button" selector="//ul[@class='dropdown-menu']" timeout="30"/> + <element name="fieldError" type="text" selector="label.mage-error"/> </section> -</sections> \ No newline at end of file +</sections> From 4ebb8524248517f350f49e3b87b02bcaa465a953 Mon Sep 17 00:00:00 2001 From: Stas Kozar <stas.kozar@transoftgroup.com> Date: Thu, 27 Jun 2019 16:28:21 +0300 Subject: [PATCH 007/191] MC-17753: Authorize.net Cannot read property 'length' of null --- .../ActionGroup/ConfigureAuthorizenetAcceptjsActionGroup.xml | 2 +- .../Test/Mftf/Test/FullCaptureAuthorizenetAcceptjsTest.xml | 1 - .../GuestCheckoutVirtualProductAuthorizenetAcceptjsTest.xml | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/ActionGroup/ConfigureAuthorizenetAcceptjsActionGroup.xml b/app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/ActionGroup/ConfigureAuthorizenetAcceptjsActionGroup.xml index b8020129d487..eac4affcb9db 100644 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/ActionGroup/ConfigureAuthorizenetAcceptjsActionGroup.xml +++ b/app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/ActionGroup/ConfigureAuthorizenetAcceptjsActionGroup.xml @@ -34,7 +34,7 @@ <selectOption selector="{{AuthorizenetAcceptjsConfigurationSection.enabledDefaultSelect}}" userInput="Yes" stepKey="enablePayment"/> </actionGroup> - <actionGroup name="AssertAuthorizenetAcceptjsRequiredFieldsValidationArePresentOnSave"> + <actionGroup name="AssertAuthorizenetAcceptjsRequiredFieldsValidationIsPresentOnSave"> <scrollToTopOfPage stepKey="scrollToTop"/> <click selector="{{AdminMainActionsSection.save}}" stepKey="clickSave"/> <scrollTo selector="{{AuthorizenetAcceptjsConfigurationSection.apiLoginIdField}}" stepKey="scrollToApiLoginIdField"/> diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/Test/FullCaptureAuthorizenetAcceptjsTest.xml b/app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/Test/FullCaptureAuthorizenetAcceptjsTest.xml index a973b9bee9cb..7f25482d627e 100644 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/Test/FullCaptureAuthorizenetAcceptjsTest.xml +++ b/app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/Test/FullCaptureAuthorizenetAcceptjsTest.xml @@ -32,7 +32,6 @@ <!--Configure Auth.net--> <amOnPage url="{{AdminConfigPaymentMethodsPage.url}}" stepKey="navigateToPaymentConfigurationPage"/> - <actionGroup ref="EnableAuthorizenetAcceptjs" stepKey="enableAuthorizenetAcceptjs"/> <actionGroup ref="ConfigureAuthorizenetAcceptjs" stepKey="configureAuthorizenetAcceptjs"> <argument name="paymentAction" value="Authorize Only"/> </actionGroup> diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/Test/GuestCheckoutVirtualProductAuthorizenetAcceptjsTest.xml b/app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/Test/GuestCheckoutVirtualProductAuthorizenetAcceptjsTest.xml index 1c2f1425028c..919c32d8f70d 100644 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/Test/GuestCheckoutVirtualProductAuthorizenetAcceptjsTest.xml +++ b/app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/Test/GuestCheckoutVirtualProductAuthorizenetAcceptjsTest.xml @@ -37,7 +37,6 @@ <!--Configure Auth.net--> <amOnPage url="{{AdminConfigPaymentMethodsPage.url}}" stepKey="navigateToPaymentConfigurationPage"/> - <actionGroup ref="EnableAuthorizenetAcceptjs" stepKey="enableAuthorizenetAcceptjs"/> <actionGroup ref="ConfigureAuthorizenetAcceptjs" stepKey="configureAuthorizenetAcceptjs"> <argument name="paymentAction" value="Authorize and Capture"/> </actionGroup> From fc7059fd5f9ef058338a3291817ae03ea471da03 Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Thu, 27 Jun 2019 17:25:40 -0500 Subject: [PATCH 008/191] MC-17868: Break jQuery UI into widgets and make a prototype --- .../Theme/view/frontend/requirejs-config.js | 3 +- lib/web/jquery/composite.js | 48 + lib/web/jquery/ui-modules/accordion.js | 570 +++++ lib/web/jquery/ui-modules/autocomplete.js | 590 +++++ lib/web/jquery/ui-modules/button.js | 381 +++ lib/web/jquery/ui-modules/core.js | 822 +++++++ lib/web/jquery/ui-modules/datepicker.js | 2025 ++++++++++++++++ lib/web/jquery/ui-modules/dialog.js | 804 ++++++ lib/web/jquery/ui-modules/draggable.js | 943 +++++++ lib/web/jquery/ui-modules/droppable.js | 373 +++ lib/web/jquery/ui-modules/effect-blind.js | 69 + lib/web/jquery/ui-modules/effect-bounce.js | 100 + lib/web/jquery/ui-modules/effect-clip.js | 54 + lib/web/jquery/ui-modules/effect-drop.js | 52 + lib/web/jquery/ui-modules/effect-explode.js | 84 + lib/web/jquery/ui-modules/effect-fade.js | 17 + lib/web/jquery/ui-modules/effect-fold.js | 63 + lib/web/jquery/ui-modules/effect-highlight.js | 37 + lib/web/jquery/ui-modules/effect-puff.js | 305 +++ lib/web/jquery/ui-modules/effect-pulsate.js | 50 + lib/web/jquery/ui-modules/effect-shake.js | 61 + lib/web/jquery/ui-modules/effect-slide.js | 51 + lib/web/jquery/ui-modules/effect-transfer.js | 34 + lib/web/jquery/ui-modules/effect.js | 1279 ++++++++++ lib/web/jquery/ui-modules/menu.js | 612 +++++ lib/web/jquery/ui-modules/mouse.js | 156 ++ lib/web/jquery/ui-modules/position.js | 491 ++++ lib/web/jquery/ui-modules/progressbar.js | 131 + lib/web/jquery/ui-modules/resizable.js | 963 ++++++++ lib/web/jquery/ui-modules/selectable.js | 262 ++ lib/web/jquery/ui-modules/slider.js | 661 +++++ lib/web/jquery/ui-modules/sortable.js | 1274 ++++++++++ lib/web/jquery/ui-modules/spinner.js | 482 ++++ lib/web/jquery/ui-modules/tabs.js | 835 +++++++ lib/web/jquery/ui-modules/timepicker.js | 2158 +++++++++++++++++ lib/web/jquery/ui-modules/tooltip.js | 387 +++ 36 files changed, 17226 insertions(+), 1 deletion(-) create mode 100644 lib/web/jquery/composite.js create mode 100644 lib/web/jquery/ui-modules/accordion.js create mode 100644 lib/web/jquery/ui-modules/autocomplete.js create mode 100644 lib/web/jquery/ui-modules/button.js create mode 100644 lib/web/jquery/ui-modules/core.js create mode 100644 lib/web/jquery/ui-modules/datepicker.js create mode 100644 lib/web/jquery/ui-modules/dialog.js create mode 100644 lib/web/jquery/ui-modules/draggable.js create mode 100644 lib/web/jquery/ui-modules/droppable.js create mode 100644 lib/web/jquery/ui-modules/effect-blind.js create mode 100644 lib/web/jquery/ui-modules/effect-bounce.js create mode 100644 lib/web/jquery/ui-modules/effect-clip.js create mode 100644 lib/web/jquery/ui-modules/effect-drop.js create mode 100644 lib/web/jquery/ui-modules/effect-explode.js create mode 100644 lib/web/jquery/ui-modules/effect-fade.js create mode 100644 lib/web/jquery/ui-modules/effect-fold.js create mode 100644 lib/web/jquery/ui-modules/effect-highlight.js create mode 100644 lib/web/jquery/ui-modules/effect-puff.js create mode 100644 lib/web/jquery/ui-modules/effect-pulsate.js create mode 100644 lib/web/jquery/ui-modules/effect-shake.js create mode 100644 lib/web/jquery/ui-modules/effect-slide.js create mode 100644 lib/web/jquery/ui-modules/effect-transfer.js create mode 100644 lib/web/jquery/ui-modules/effect.js create mode 100644 lib/web/jquery/ui-modules/menu.js create mode 100644 lib/web/jquery/ui-modules/mouse.js create mode 100644 lib/web/jquery/ui-modules/position.js create mode 100644 lib/web/jquery/ui-modules/progressbar.js create mode 100644 lib/web/jquery/ui-modules/resizable.js create mode 100644 lib/web/jquery/ui-modules/selectable.js create mode 100644 lib/web/jquery/ui-modules/slider.js create mode 100644 lib/web/jquery/ui-modules/sortable.js create mode 100644 lib/web/jquery/ui-modules/spinner.js create mode 100644 lib/web/jquery/ui-modules/tabs.js create mode 100644 lib/web/jquery/ui-modules/timepicker.js create mode 100644 lib/web/jquery/ui-modules/tooltip.js diff --git a/app/code/Magento/Theme/view/frontend/requirejs-config.js b/app/code/Magento/Theme/view/frontend/requirejs-config.js index aacec30edf18..0e63158ae191 100644 --- a/app/code/Magento/Theme/view/frontend/requirejs-config.js +++ b/app/code/Magento/Theme/view/frontend/requirejs-config.js @@ -33,7 +33,8 @@ var config = { } }, paths: { - 'jquery/ui': 'jquery/jquery-ui' + 'jquery/ui': 'jquery/jquery-ui', + 'jquery-ui-modules': 'jquery/ui-modules' }, deps: [ 'jquery/jquery.mobile.custom', diff --git a/lib/web/jquery/composite.js b/lib/web/jquery/composite.js new file mode 100644 index 000000000000..dba06a485ae4 --- /dev/null +++ b/lib/web/jquery/composite.js @@ -0,0 +1,48 @@ +// Import every plugin under the sun. Bad for performance, +// but prevents the store from breaking in situations +// where a dependency was missed during the migration from +// a monolith build of jQueryUI to a modular one + +define([ + 'jquery-ui-modules/core', + 'jquery-ui-modules/accordion', + 'jquery-ui-modules/autocomplete', + 'jquery-ui-modules/button', + 'jquery-ui-modules/datepicker', + 'jquery-ui-modules/dialog', + 'jquery-ui-modules/draggable', + 'jquery-ui-modules/droppable', + 'jquery-ui-modules/effect-blind', + 'jquery-ui-modules/effect-bounce', + 'jquery-ui-modules/effect-clip', + 'jquery-ui-modules/effect-drop', + 'jquery-ui-modules/effect-explode', + 'jquery-ui-modules/effect-fade', + 'jquery-ui-modules/effect-fold', + 'jquery-ui-modules/effect-highlight', + 'jquery-ui-modules/effect-puff', + 'jquery-ui-modules/effect-pulsate', + 'jquery-ui-modules/effect-shake', + 'jquery-ui-modules/effect-slide', + 'jquery-ui-modules/effect-transfer', + 'jquery-ui-modules/effect', + 'jquery-ui-modules/menu', + 'jquery-ui-modules/mouse', + 'jquery-ui-modules/position', + 'jquery-ui-modules/progressbar', + 'jquery-ui-modules/resizable', + 'jquery-ui-modules/selectable', + 'jquery-ui-modules/slider', + 'jquery-ui-modules/sortable', + 'jquery-ui-modules/spinner', + 'jquery-ui-modules/tabs', + 'jquery-ui-modules/timepicker', + 'jquery-ui-modules/tooltip' +], function() { + console.warn( + 'Fallback to JQueryUI Compat activated. ' + + 'Your store is missing a dependency for a ' + + 'jQueryUI widget. Identifying and addressing the dependency ' + + 'will drastically improve the performance of your site' + ) +}); \ No newline at end of file diff --git a/lib/web/jquery/ui-modules/accordion.js b/lib/web/jquery/ui-modules/accordion.js new file mode 100644 index 000000000000..c9d6b4b46aa5 --- /dev/null +++ b/lib/web/jquery/ui-modules/accordion.js @@ -0,0 +1,570 @@ +/*! + * jQuery UI Accordion + * http://jqueryui.com + * + * Copyright 2014 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/accordion/ + * + * Depends: + * jquery.ui.core.js + * jquery.ui.widget.js + */ +(function( $, undefined ) { + + var uid = 0, + hideProps = {}, + showProps = {}; + + hideProps.height = hideProps.paddingTop = hideProps.paddingBottom = + hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide"; + showProps.height = showProps.paddingTop = showProps.paddingBottom = + showProps.borderTopWidth = showProps.borderBottomWidth = "show"; + + $.widget( "ui.accordion", { + version: "1.10.4", + options: { + active: 0, + animate: {}, + collapsible: false, + event: "click", + header: "> li > :first-child,> :not(li):even", + heightStyle: "auto", + icons: { + activeHeader: "ui-icon-triangle-1-s", + header: "ui-icon-triangle-1-e" + }, + + // callbacks + activate: null, + beforeActivate: null + }, + + _create: function() { + var options = this.options; + this.prevShow = this.prevHide = $(); + this.element.addClass( "ui-accordion ui-widget ui-helper-reset" ) + // ARIA + .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(), + content: !this.active.length ? $() : this.active.next() + }; + }, + + _createIcons: function() { + var icons = this.options.icons; + if ( icons ) { + $( "<span>" ) + .addClass( "ui-accordion-header-icon ui-icon " + icons.header ) + .prependTo( this.headers ); + this.active.children( ".ui-accordion-header-icon" ) + .removeClass( icons.header ) + .addClass( icons.activeHeader ); + this.headers.addClass( "ui-accordion-icons" ); + } + }, + + _destroyIcons: function() { + this.headers + .removeClass( "ui-accordion-icons" ) + .children( ".ui-accordion-header-icon" ) + .remove(); + }, + + _destroy: function() { + var contents; + + // clean up main element + this.element + .removeClass( "ui-accordion ui-widget ui-helper-reset" ) + .removeAttr( "role" ); + + // clean up headers + this.headers + .removeClass( "ui-accordion-header ui-accordion-header-active ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top" ) + .removeAttr( "role" ) + .removeAttr( "aria-expanded" ) + .removeAttr( "aria-selected" ) + .removeAttr( "aria-controls" ) + .removeAttr( "tabIndex" ) + .each(function() { + if ( /^ui-accordion/.test( this.id ) ) { + this.removeAttribute( "id" ); + } + }); + this._destroyIcons(); + + // clean up content panels + contents = this.headers.next() + .css( "display", "" ) + .removeAttr( "role" ) + .removeAttr( "aria-hidden" ) + .removeAttr( "aria-labelledby" ) + .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled" ) + .each(function() { + if ( /^ui-accordion/.test( this.id ) ) { + this.removeAttribute( "id" ); + } + }); + 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(); + } + } + + // #5332 - opacity doesn't cascade to positioned elements in IE + // so we need to add the disabled class to the headers and panels + if ( key === "disabled" ) { + this.headers.add( this.headers.next() ) + .toggleClass( "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.focus(); + event.preventDefault(); + } + }, + + _panelKeyDown : function( event ) { + if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) { + $( event.currentTarget ).prev().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() { + this.headers = this.element.find( this.options.header ) + .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" ); + + this.headers.next() + .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" ) + .filter(":not(.ui-accordion-content-active)") + .hide(); + }, + + _refresh: function() { + var maxHeight, + options = this.options, + heightStyle = options.heightStyle, + parent = this.element.parent(), + accordionId = this.accordionId = "ui-accordion-" + + (this.element.attr( "id" ) || ++uid); + + this.active = this._findActive( options.active ) + .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ) + .removeClass( "ui-corner-all" ); + this.active.next() + .addClass( "ui-accordion-content-active" ) + .show(); + + this.headers + .attr( "role", "tab" ) + .each(function( i ) { + var header = $( this ), + headerId = header.attr( "id" ), + panel = header.next(), + panelId = panel.attr( "id" ); + if ( !headerId ) { + headerId = accordionId + "-header-" + i; + header.attr( "id", headerId ); + } + if ( !panelId ) { + panelId = accordionId + "-panel-" + i; + panel.attr( "id", panelId ); + } + 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() { + maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() ); + }) + .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 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 + active.removeClass( "ui-accordion-header-active ui-state-active" ); + if ( options.icons ) { + active.children( ".ui-accordion-header-icon" ) + .removeClass( options.icons.activeHeader ) + .addClass( options.icons.header ); + } + + if ( !clickedIsActive ) { + clicked + .removeClass( "ui-corner-all" ) + .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ); + if ( options.icons ) { + clicked.children( ".ui-accordion-header-icon" ) + .removeClass( options.icons.header ) + .addClass( options.icons.activeHeader ); + } + + clicked + .next() + .addClass( "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" ); + // 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 $( this ).attr( "tabIndex" ) === 0; + }) + .attr( "tabIndex", -1 ); + } + + toShow + .attr( "aria-hidden", "false" ) + .prev() + .attr({ + "aria-selected": "true", + tabIndex: 0, + "aria-expanded": "true" + }); + }, + + _animate: function( toShow, toHide, data ) { + var total, easing, duration, + that = this, + adjust = 0, + 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( showProps, duration, easing, complete ); + } + if ( !toShow.length ) { + return toHide.animate( hideProps, duration, easing, complete ); + } + + total = toShow.show().outerHeight(); + toHide.animate( hideProps, { + duration: duration, + easing: easing, + step: function( now, fx ) { + fx.now = Math.round( now ); + } + }); + toShow + .hide() + .animate( showProps, { + duration: duration, + easing: easing, + complete: complete, + step: function( now, fx ) { + fx.now = Math.round( now ); + if ( fx.prop !== "height" ) { + 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; + + toHide + .removeClass( "ui-accordion-content-active" ) + .prev() + .removeClass( "ui-corner-top" ) + .addClass( "ui-corner-all" ); + + // Work around for rendering bug in IE (#5421) + if ( toHide.length ) { + toHide.parent()[0].className = toHide.parent()[0].className; + } + this._trigger( "activate", null, data ); + } + }); + +})( jQuery ); diff --git a/lib/web/jquery/ui-modules/autocomplete.js b/lib/web/jquery/ui-modules/autocomplete.js new file mode 100644 index 000000000000..af2e43503498 --- /dev/null +++ b/lib/web/jquery/ui-modules/autocomplete.js @@ -0,0 +1,590 @@ +(function( $, undefined ) { + + $.widget( "ui.autocomplete", { + version: "1.10.4", + 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, + + _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"; + + this.isMultiLine = + // Textareas are always multi-line + isTextarea ? true : + // Inputs are always single-line, even if inside a contentEditable element + // IE also treats inputs as contentEditable + isInput ? false : + // All other element types are determined by whether or not they're contentEditable + this.element.prop( "isContentEditable" ); + + this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ]; + this.isNewMenu = true; + + this.element + .addClass( "ui-autocomplete-input" ) + .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: + case keyCode.NUMPAD_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" ) ) { + 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 ) { + if ( this.cancelBlur ) { + delete this.cancelBlur; + return; + } + + clearTimeout( this.searching ); + this.close( event ); + this._change( event ); + } + }); + + this._initSource(); + this.menu = $( "<ul>" ) + .addClass( "ui-autocomplete ui-front" ) + .appendTo( this._appendTo() ) + .menu({ + // disable ARIA support, the live region takes care of that + role: null + }) + .hide() + .data( "ui-menu" ); + + this._on( this.menu.element, { + mousedown: function( event ) { + // prevent moving focus out of the text field + event.preventDefault(); + + // IE doesn't prevent moving focus even with event.preventDefault() + // so we set a flag to know when we should ignore the blur event + this.cancelBlur = true; + this._delay(function() { + delete this.cancelBlur; + }); + + // clicking on the scrollbar causes focus to shift to the body + // but we can't detect a mouseup or a click immediately afterward + // so we have to track the next mousedown and close the menu if + // the user clicks somewhere outside of the autocomplete + var menuElement = this.menu.element[ 0 ]; + if ( !$( event.target ).closest( ".ui-menu-item" ).length ) { + this._delay(function() { + var that = this; + this.document.one( "mousedown", function( event ) { + if ( event.target !== that.element[ 0 ] && + event.target !== menuElement && + !$.contains( menuElement, event.target ) ) { + that.close(); + } + }); + }); + } + }, + menufocus: function( event, ui ) { + // 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; + } + } + + var 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 ); + } + } else { + // Normally the input is populated with the item's value as the + // menu is navigated, causing screen readers to notice a change and + // announce the item. Since the focus event was canceled, this doesn't + // happen, so we update the live region so that screen readers can + // still notice the change and announce it. + this.liveRegion.text( item.value ); + } + }, + 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] !== this.document[0].activeElement ) { + this.element.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 = $( "<span>", { + role: "status", + "aria-live": "polite" + }) + .addClass( "ui-helper-hidden-accessible" ) + .insertBefore( this.element ); + + // 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 + .removeClass( "ui-autocomplete-input" ) + .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(); + } + }, + + _appendTo: function() { + var element = this.options.appendTo; + + if ( element ) { + element = element.jquery || element.nodeType ? + $( element ) : + this.document.find( element ).eq( 0 ); + } + + if ( !element ) { + element = this.element.closest( ".ui-front" ); + } + + if ( !element.length ) { + element = this.document[0].body; + } + + return element; + }, + + _initSource: function() { + var array, url, + that = this; + if ( $.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() { + // only search if the value has changed + if ( this.term !== this._value() ) { + 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.element.addClass( "ui-autocomplete-loading" ); + this.cancelSearch = false; + + this.source( { term: value }, this._response() ); + }, + + _response: function() { + var index = ++this.requestIndex; + + return $.proxy(function( content ) { + if ( index === this.requestIndex ) { + this.__response( content ); + } + + this.pending--; + if ( !this.pending ) { + this.element.removeClass( "ui-autocomplete-loading" ); + } + }, 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 ) { + 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({ + label: item.label || item.value, + value: item.value || item.label + }, item ); + }); + }, + + _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(); + } + }, + + _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( $( "<a>" ).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 ) ) { + 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(); + } + } + }); + + $.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; + } + this.liveRegion.text( message ); + } + }); + +}( jQuery )); diff --git a/lib/web/jquery/ui-modules/button.js b/lib/web/jquery/ui-modules/button.js new file mode 100644 index 000000000000..6be8dcaaa3ef --- /dev/null +++ b/lib/web/jquery/ui-modules/button.js @@ -0,0 +1,381 @@ +(function( $, undefined ) { + + var lastActive, + baseClasses = "ui-button ui-widget ui-state-default ui-corner-all", + typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only", + formResetHandler = function() { + var form = $( this ); + setTimeout(function() { + form.find( ":ui-button" ).button( "refresh" ); + }, 1 ); + }, + radioGroup = function( radio ) { + var name = radio.name, + form = radio.form, + radios = $( [] ); + if ( name ) { + name = name.replace( /'/g, "\\'" ); + if ( form ) { + radios = $( form ).find( "[name='" + name + "']" ); + } else { + radios = $( "[name='" + name + "']", radio.ownerDocument ) + .filter(function() { + return !this.form; + }); + } + } + return radios; + }; + + $.widget( "ui.button", { + version: "1.10.4", + defaultElement: "<button>", + options: { + disabled: null, + text: true, + label: null, + icons: { + primary: null, + secondary: null + } + }, + _create: function() { + this.element.closest( "form" ) + .unbind( "reset" + this.eventNamespace ) + .bind( "reset" + this.eventNamespace, formResetHandler ); + + if ( typeof this.options.disabled !== "boolean" ) { + this.options.disabled = !!this.element.prop( "disabled" ); + } else { + this.element.prop( "disabled", this.options.disabled ); + } + + this._determineButtonType(); + this.hasTitle = !!this.buttonElement.attr( "title" ); + + var that = this, + options = this.options, + toggleButton = this.type === "checkbox" || this.type === "radio", + activeClass = !toggleButton ? "ui-state-active" : ""; + + if ( options.label === null ) { + options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html()); + } + + this._hoverable( this.buttonElement ); + + this.buttonElement + .addClass( baseClasses ) + .attr( "role", "button" ) + .bind( "mouseenter" + this.eventNamespace, function() { + if ( options.disabled ) { + return; + } + if ( this === lastActive ) { + $( this ).addClass( "ui-state-active" ); + } + }) + .bind( "mouseleave" + this.eventNamespace, function() { + if ( options.disabled ) { + return; + } + $( this ).removeClass( activeClass ); + }) + .bind( "click" + this.eventNamespace, function( event ) { + if ( options.disabled ) { + event.preventDefault(); + event.stopImmediatePropagation(); + } + }); + + // Can't use _focusable() because the element that receives focus + // and the element that gets the ui-state-focus class are different + this._on({ + focus: function() { + this.buttonElement.addClass( "ui-state-focus" ); + }, + blur: function() { + this.buttonElement.removeClass( "ui-state-focus" ); + } + }); + + if ( toggleButton ) { + this.element.bind( "change" + this.eventNamespace, function() { + that.refresh(); + }); + } + + if ( this.type === "checkbox" ) { + this.buttonElement.bind( "click" + this.eventNamespace, function() { + if ( options.disabled ) { + return false; + } + }); + } else if ( this.type === "radio" ) { + this.buttonElement.bind( "click" + this.eventNamespace, function() { + if ( options.disabled ) { + return false; + } + $( this ).addClass( "ui-state-active" ); + that.buttonElement.attr( "aria-pressed", "true" ); + + var radio = that.element[ 0 ]; + radioGroup( radio ) + .not( radio ) + .map(function() { + return $( this ).button( "widget" )[ 0 ]; + }) + .removeClass( "ui-state-active" ) + .attr( "aria-pressed", "false" ); + }); + } else { + this.buttonElement + .bind( "mousedown" + this.eventNamespace, function() { + if ( options.disabled ) { + return false; + } + $( this ).addClass( "ui-state-active" ); + lastActive = this; + that.document.one( "mouseup", function() { + lastActive = null; + }); + }) + .bind( "mouseup" + this.eventNamespace, function() { + if ( options.disabled ) { + return false; + } + $( this ).removeClass( "ui-state-active" ); + }) + .bind( "keydown" + this.eventNamespace, function(event) { + if ( options.disabled ) { + return false; + } + if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) { + $( this ).addClass( "ui-state-active" ); + } + }) + // see #8559, we bind to blur here in case the button element loses + // focus between keydown and keyup, it would be left in an "active" state + .bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() { + $( this ).removeClass( "ui-state-active" ); + }); + + if ( this.buttonElement.is("a") ) { + this.buttonElement.keyup(function(event) { + if ( event.keyCode === $.ui.keyCode.SPACE ) { + // TODO pass through original event correctly (just as 2nd argument doesn't work) + $( this ).click(); + } + }); + } + } + + // TODO: pull out $.Widget's handling for the disabled option into + // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can + // be overridden by individual plugins + this._setOption( "disabled", options.disabled ); + this._resetButton(); + }, + + _determineButtonType: function() { + var ancestor, labelSelector, checked; + + if ( this.element.is("[type=checkbox]") ) { + this.type = "checkbox"; + } else if ( this.element.is("[type=radio]") ) { + this.type = "radio"; + } else if ( this.element.is("input") ) { + this.type = "input"; + } else { + this.type = "button"; + } + + if ( this.type === "checkbox" || this.type === "radio" ) { + // we don't search against the document in case the element + // is disconnected from the DOM + ancestor = this.element.parents().last(); + labelSelector = "label[for='" + this.element.attr("id") + "']"; + this.buttonElement = ancestor.find( labelSelector ); + if ( !this.buttonElement.length ) { + ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings(); + this.buttonElement = ancestor.filter( labelSelector ); + if ( !this.buttonElement.length ) { + this.buttonElement = ancestor.find( labelSelector ); + } + } + this.element.addClass( "ui-helper-hidden-accessible" ); + + checked = this.element.is( ":checked" ); + if ( checked ) { + this.buttonElement.addClass( "ui-state-active" ); + } + this.buttonElement.prop( "aria-pressed", checked ); + } else { + this.buttonElement = this.element; + } + }, + + widget: function() { + return this.buttonElement; + }, + + _destroy: function() { + this.element + .removeClass( "ui-helper-hidden-accessible" ); + this.buttonElement + .removeClass( baseClasses + " ui-state-active " + typeClasses ) + .removeAttr( "role" ) + .removeAttr( "aria-pressed" ) + .html( this.buttonElement.find(".ui-button-text").html() ); + + if ( !this.hasTitle ) { + this.buttonElement.removeAttr( "title" ); + } + }, + + _setOption: function( key, value ) { + this._super( key, value ); + if ( key === "disabled" ) { + this.element.prop( "disabled", !!value ); + if ( value ) { + this.buttonElement.removeClass( "ui-state-focus" ); + } + return; + } + this._resetButton(); + }, + + refresh: function() { + //See #8237 & #8828 + var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" ); + + if ( isDisabled !== this.options.disabled ) { + this._setOption( "disabled", isDisabled ); + } + if ( this.type === "radio" ) { + radioGroup( this.element[0] ).each(function() { + if ( $( this ).is( ":checked" ) ) { + $( this ).button( "widget" ) + .addClass( "ui-state-active" ) + .attr( "aria-pressed", "true" ); + } else { + $( this ).button( "widget" ) + .removeClass( "ui-state-active" ) + .attr( "aria-pressed", "false" ); + } + }); + } else if ( this.type === "checkbox" ) { + if ( this.element.is( ":checked" ) ) { + this.buttonElement + .addClass( "ui-state-active" ) + .attr( "aria-pressed", "true" ); + } else { + this.buttonElement + .removeClass( "ui-state-active" ) + .attr( "aria-pressed", "false" ); + } + } + }, + + _resetButton: function() { + if ( this.type === "input" ) { + if ( this.options.label ) { + this.element.val( this.options.label ); + } + return; + } + var buttonElement = this.buttonElement.removeClass( typeClasses ), + buttonText = $( "<span></span>", this.document[0] ) + .addClass( "ui-button-text" ) + .html( this.options.label ) + .appendTo( buttonElement.empty() ) + .text(), + icons = this.options.icons, + multipleIcons = icons.primary && icons.secondary, + buttonClasses = []; + + if ( icons.primary || icons.secondary ) { + if ( this.options.text ) { + buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) ); + } + + if ( icons.primary ) { + buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" ); + } + + if ( icons.secondary ) { + buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" ); + } + + if ( !this.options.text ) { + buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" ); + + if ( !this.hasTitle ) { + buttonElement.attr( "title", $.trim( buttonText ) ); + } + } + } else { + buttonClasses.push( "ui-button-text-only" ); + } + buttonElement.addClass( buttonClasses.join( " " ) ); + } + }); + + $.widget( "ui.buttonset", { + version: "1.10.4", + options: { + items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)" + }, + + _create: function() { + this.element.addClass( "ui-buttonset" ); + }, + + _init: function() { + this.refresh(); + }, + + _setOption: function( key, value ) { + if ( key === "disabled" ) { + this.buttons.button( "option", key, value ); + } + + this._super( key, value ); + }, + + refresh: function() { + var rtl = this.element.css( "direction" ) === "rtl"; + + this.buttons = this.element.find( this.options.items ) + .filter( ":ui-button" ) + .button( "refresh" ) + .end() + .not( ":ui-button" ) + .button() + .end() + .map(function() { + return $( this ).button( "widget" )[ 0 ]; + }) + .removeClass( "ui-corner-all ui-corner-left ui-corner-right" ) + .filter( ":first" ) + .addClass( rtl ? "ui-corner-right" : "ui-corner-left" ) + .end() + .filter( ":last" ) + .addClass( rtl ? "ui-corner-left" : "ui-corner-right" ) + .end() + .end(); + }, + + _destroy: function() { + this.element.removeClass( "ui-buttonset" ); + this.buttons + .map(function() { + return $( this ).button( "widget" )[ 0 ]; + }) + .removeClass( "ui-corner-left ui-corner-right" ) + .end() + .button( "destroy" ); + } + }); + +}( jQuery ) ); diff --git a/lib/web/jquery/ui-modules/core.js b/lib/web/jquery/ui-modules/core.js new file mode 100644 index 000000000000..3a0f1c32cbe4 --- /dev/null +++ b/lib/web/jquery/ui-modules/core.js @@ -0,0 +1,822 @@ +(function( $, undefined ) { + + var uuid = 0, + runiqueId = /^ui-id-\d+$/; + +// $.ui might exist from components with no dependencies, e.g., $.ui.position + $.ui = $.ui || {}; + + $.extend( $.ui, { + version: "1.10.4", + + keyCode: { + BACKSPACE: 8, + COMMA: 188, + DELETE: 46, + DOWN: 40, + END: 35, + ENTER: 13, + ESCAPE: 27, + HOME: 36, + LEFT: 37, + NUMPAD_ADD: 107, + NUMPAD_DECIMAL: 110, + NUMPAD_DIVIDE: 111, + NUMPAD_ENTER: 108, + NUMPAD_MULTIPLY: 106, + NUMPAD_SUBTRACT: 109, + PAGE_DOWN: 34, + PAGE_UP: 33, + PERIOD: 190, + RIGHT: 39, + SPACE: 32, + TAB: 9, + UP: 38 + } + }); + +// plugins + $.fn.extend({ + focus: (function( orig ) { + return function( delay, fn ) { + return typeof delay === "number" ? + this.each(function() { + var elem = this; + setTimeout(function() { + $( elem ).focus(); + if ( fn ) { + fn.call( elem ); + } + }, delay ); + }) : + orig.apply( this, arguments ); + }; + })( $.fn.focus ), + + scrollParent: function() { + var scrollParent; + if (($.ui.ie && (/(static|relative)/).test(this.css("position"))) || (/absolute/).test(this.css("position"))) { + scrollParent = this.parents().filter(function() { + return (/(relative|absolute|fixed)/).test($.css(this,"position")) && (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x")); + }).eq(0); + } else { + scrollParent = this.parents().filter(function() { + return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x")); + }).eq(0); + } + + return (/fixed/).test(this.css("position")) || !scrollParent.length ? $(document) : scrollParent; + }, + + zIndex: function( zIndex ) { + if ( zIndex !== undefined ) { + return this.css( "zIndex", zIndex ); + } + + if ( this.length ) { + var elem = $( this[ 0 ] ), 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; + }, + + uniqueId: function() { + return this.each(function() { + if ( !this.id ) { + this.id = "ui-id-" + (++uuid); + } + }); + }, + + removeUniqueId: function() { + return this.each(function() { + if ( runiqueId.test( this.id ) ) { + $( this ).removeAttr( "id" ); + } + }); + } + }); + +// selectors + function focusable( element, isTabIndexNotNaN ) { + var map, mapName, img, + 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 + "]" )[0]; + return !!img && visible( img ); + } + return ( /input|select|textarea|button|object/.test( nodeName ) ? + !element.disabled : + "a" === nodeName ? + element.href || isTabIndexNotNaN : + isTabIndexNotNaN) && + // the element and all of its ancestors must be visible + visible( element ); + } + + function visible( element ) { + return $.expr.filters.visible( element ) && + !$( element ).parents().addBack().filter(function() { + return $.css( this, "visibility" ) === "hidden"; + }).length; + } + + $.extend( $.expr[ ":" ], { + 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 ] ); + }, + + focusable: function( element ) { + return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) ); + }, + + tabbable: function( element ) { + var tabIndex = $.attr( element, "tabindex" ), + isTabIndexNaN = isNaN( tabIndex ); + return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN ); + } + }); + +// support: jQuery <1.8 + if ( !$( "<a>" ).outerWidth( 1 ).jquery ) { + $.each( [ "Width", "Height" ], function( i, name ) { + var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ], + type = name.toLowerCase(), + orig = { + innerWidth: $.fn.innerWidth, + innerHeight: $.fn.innerHeight, + outerWidth: $.fn.outerWidth, + outerHeight: $.fn.outerHeight + }; + + function reduce( elem, size, border, margin ) { + $.each( side, function() { + size -= parseFloat( $.css( elem, "padding" + this ) ) || 0; + if ( border ) { + size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0; + } + if ( margin ) { + size -= parseFloat( $.css( elem, "margin" + this ) ) || 0; + } + }); + return size; + } + + $.fn[ "inner" + name ] = function( size ) { + if ( size === undefined ) { + return orig[ "inner" + name ].call( this ); + } + + return this.each(function() { + $( this ).css( type, reduce( this, size ) + "px" ); + }); + }; + + $.fn[ "outer" + name] = function( size, margin ) { + if ( typeof size !== "number" ) { + return orig[ "outer" + name ].call( this, size ); + } + + return this.each(function() { + $( this).css( type, reduce( this, size, true, margin ) + "px" ); + }); + }; + }); + } + +// support: jQuery <1.8 + if ( !$.fn.addBack ) { + $.fn.addBack = function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter( selector ) + ); + }; + } + +// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413) + if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) { + $.fn.removeData = (function( removeData ) { + return function( key ) { + if ( arguments.length ) { + return removeData.call( this, $.camelCase( key ) ); + } else { + return removeData.call( this ); + } + }; + })( $.fn.removeData ); + } + + + + + +// deprecated + $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() ); + + $.support.selectstart = "onselectstart" in document.createElement( "div" ); + $.fn.extend({ + disableSelection: function() { + return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) + + ".ui-disableSelection", function( event ) { + event.preventDefault(); + }); + }, + + enableSelection: function() { + return this.unbind( ".ui-disableSelection" ); + } + }); + + $.extend( $.ui, { + // $.ui.plugin is deprecated. Use $.widget() extensions instead. + 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 ) { + var i, + set = instance.plugins[ name ]; + if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) { + return; + } + + for ( i = 0; i < set.length; i++ ) { + if ( instance.options[ set[ i ][ 0 ] ] ) { + set[ i ][ 1 ].apply( instance.element, args ); + } + } + } + }, + + // only used by resizable + hasScroll: function( el, a ) { + + //If overflow is hidden, the element might have extra content, but the user wants to hide it + 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 + el[ scroll ] = 1; + has = ( el[ scroll ] > 0 ); + el[ scroll ] = 0; + return has; + } + }); + +})( jQuery ); + +(function( $, undefined ) { + + var uuid = 0, + slice = Array.prototype.slice, + _cleanData = $.cleanData; + $.cleanData = function( elems ) { + for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { + try { + $( elem ).triggerHandler( "remove" ); + // http://bugs.jquery.com/ticket/8235 + } catch( e ) {} + } + _cleanData( elems ); + }; + + $.widget = function( name, base, prototype ) { + var fullName, existingConstructor, constructor, basePrototype, + // proxiedPrototype allows the provided prototype to remain unmodified + // so that it can be used as a mixin for multiple widgets (#8876) + proxiedPrototype = {}, + namespace = name.split( "." )[ 0 ]; + + name = name.split( "." )[ 1 ]; + fullName = namespace + "-" + name; + + if ( !prototype ) { + prototype = base; + base = $.Widget; + } + + // create selector for plugin + $.expr[ ":" ][ 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._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 ( !$.isFunction( value ) ) { + proxiedPrototype[ prop ] = value; + return; + } + proxiedPrototype[ prop ] = (function() { + var _super = function() { + return base.prototype[ prop ].apply( this, arguments ); + }, + _superApply = function( args ) { + return base.prototype[ prop ].apply( this, args ); + }; + return function() { + var __super = this._super, + __superApply = this._superApply, + 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 ); + }; + + $.widget.extend = function( target ) { + var input = slice.call( arguments, 1 ), + inputIndex = 0, + inputLength = input.length, + key, + value; + for ( ; inputIndex < inputLength; inputIndex++ ) { + for ( key in input[ inputIndex ] ) { + value = input[ inputIndex ][ key ]; + if ( input[ inputIndex ].hasOwnProperty( 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", + args = slice.call( arguments, 1 ), + returnValue = this; + + // allow multiple hashes to be passed on init + options = !isMethodCall && args.length ? + $.widget.extend.apply( null, [ options ].concat(args) ) : + options; + + if ( isMethodCall ) { + this.each(function() { + var methodValue, + instance = $.data( this, fullName ); + if ( !instance ) { + return $.error( "cannot call methods on " + name + " prior to initialization; " + + "attempted to call method '" + options + "'" ); + } + if ( !$.isFunction( instance[options] ) || 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 { + this.each(function() { + var instance = $.data( this, fullName ); + if ( instance ) { + instance.option( options || {} )._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: { + disabled: false, + + // callbacks + create: null + }, + _createWidget: function( options, element ) { + element = $( element || this.defaultElement || this )[ 0 ]; + this.element = $( element ); + this.uuid = uuid++; + this.eventNamespace = "." + this.widgetName + this.uuid; + this.options = $.widget.extend( {}, + this.options, + this._getCreateOptions(), + options ); + + this.bindings = $(); + this.hoverable = $(); + this.focusable = $(); + + 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._create(); + this._trigger( "create", null, this._getCreateEventData() ); + this._init(); + }, + _getCreateOptions: $.noop, + _getCreateEventData: $.noop, + _create: $.noop, + _init: $.noop, + + destroy: function() { + this._destroy(); + // we can probably remove the unbind calls in 2.0 + // all event bindings should go through this._on() + this.element + .unbind( this.eventNamespace ) + // 1.9 BC for #7810 + // TODO remove dual storage + .removeData( this.widgetName ) + .removeData( this.widgetFullName ) + // support: jquery <1.6.3 + // http://bugs.jquery.com/ticket/9413 + .removeData( $.camelCase( this.widgetFullName ) ); + this.widget() + .unbind( this.eventNamespace ) + .removeAttr( "aria-disabled" ) + .removeClass( + this.widgetFullName + "-disabled " + + "ui-state-disabled" ); + + // clean up events and states + this.bindings.unbind( this.eventNamespace ); + this.hoverable.removeClass( "ui-state-hover" ); + this.focusable.removeClass( "ui-state-focus" ); + }, + _destroy: $.noop, + + widget: function() { + return this.element; + }, + + option: function( key, value ) { + var options = key, + parts, + curOption, + 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 ) { + this.options[ key ] = value; + + if ( key === "disabled" ) { + this.widget() + .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value ) + .attr( "aria-disabled", value ); + this.hoverable.removeClass( "ui-state-hover" ); + this.focusable.removeClass( "ui-state-focus" ); + } + + return this; + }, + + enable: function() { + return this._setOption( "disabled", false ); + }, + disable: function() { + return this._setOption( "disabled", true ); + }, + + _on: function( suppressDisabledCheck, element, handlers ) { + var delegateElement, + 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 { + // accept selectors, DOM elements + 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*(.*)$/ ), + eventName = match[1] + instance.eventNamespace, + selector = match[2]; + if ( selector ) { + delegateElement.delegate( selector, eventName, handlerProxy ); + } else { + element.bind( eventName, handlerProxy ); + } + }); + }, + + _off: function( element, eventName ) { + eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace; + element.unbind( eventName ).undelegate( eventName ); + }, + + _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 ) { + $( event.currentTarget ).addClass( "ui-state-hover" ); + }, + mouseleave: function( event ) { + $( event.currentTarget ).removeClass( "ui-state-hover" ); + } + }); + }, + + _focusable: function( element ) { + this.focusable = this.focusable.add( element ); + this._on( element, { + focusin: function( event ) { + $( event.currentTarget ).addClass( "ui-state-focus" ); + }, + focusout: function( event ) { + $( event.currentTarget ).removeClass( "ui-state-focus" ); + } + }); + }, + + _trigger: function( type, event, data ) { + var prop, orig, + 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 !( $.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, + 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(); + }); + } + }; + }); + +})( jQuery ); diff --git a/lib/web/jquery/ui-modules/datepicker.js b/lib/web/jquery/ui-modules/datepicker.js new file mode 100644 index 000000000000..21f9f5ccdd3b --- /dev/null +++ b/lib/web/jquery/ui-modules/datepicker.js @@ -0,0 +1,2025 @@ +(function( $, undefined ) { + + $.extend($.ui, { datepicker: { version: "1.10.4" } }); + + var PROP_NAME = "datepicker", + instActive; + + /* 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 + }; + 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 + 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.dpDiv = 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) { + 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 + 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).keydown(this._doKeyDown). + keypress(this._doKeyPress).keyup(this._doKeyUp); + this._autoSize(inst); + $.data(target, PROP_NAME, 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 class='" + this._appendClass + "'>" + appendText + "</span>"); + input[isRTL ? "before" : "after"](inst.append); + } + + input.unbind("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.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"); + inst.trigger = $(this._get(inst, "buttonImageOnly") ? + $("<img/>").addClass(this._triggerClass). + attr({ src: buttonImage, alt: buttonText, title: buttonText }) : + $("<button type='button'></button>").addClass(this._triggerClass). + html(!buttonImage ? buttonText : $("<img/>").attr( + { src:buttonImage, alt:buttonText, title:buttonText }))); + input[isRTL ? "before" : "after"](inst.trigger); + inst.trigger.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, PROP_NAME, 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.keydown(this._doKeyDown); + $("body").append(this._dialogInput); + inst = this._dialogInst = this._newInst(this._dialogInput, false); + inst.settings = {}; + $.data(this._dialogInput[0], PROP_NAME, inst); + } + 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], PROP_NAME, 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, PROP_NAME); + + if (!$target.hasClass(this.markerClassName)) { + return; + } + + nodeName = target.nodeName.toLowerCase(); + $.removeData(target, PROP_NAME); + if (nodeName === "input") { + inst.append.remove(); + inst.trigger.remove(); + $target.removeClass(this.markerClassName). + unbind("focus", this._showDatepicker). + unbind("keydown", this._doKeyDown). + unbind("keypress", this._doKeyPress). + unbind("keyup", this._doKeyUp); + } else if (nodeName === "div" || nodeName === "span") { + $target.removeClass(this.markerClassName).empty(); + } + }, + + /* 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, PROP_NAME); + + 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, + function(value) { return (value === target ? null : value); }); // delete entry + }, + + /* 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, PROP_NAME); + + 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, + function(value) { return (value === target ? null : value); }); // delete entry + 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, PROP_NAME); + } + 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"); + 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; + } + 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.zIndex($(input).zIndex()+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.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) + instActive = inst; // for delegate hover events + inst.dpDiv.empty().append(this._generateHTML(inst)); + this._attachHandlers(inst); + inst.dpDiv.find("." + this._dayOverClass + " a").mouseover(); + + var origyearshtml, + numMonths = this._getNumberOfMonths(inst), + cols = numMonths[1], + width = 17; + + 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.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); + } + }, + + // #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.filters.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, PROP_NAME))) { + 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).unbind(".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 === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning + 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 = $("a", td).html(); + 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.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)); + $(altField).each(function() { $(this).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)))), + digits = new RegExp("^\\d{1," + 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.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 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).bind(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))); + + prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ? + "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" + + " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" : + (hideIfNoPrevNext ? "" : "<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='"+ prevText +"'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>")); + + nextText = this._get(inst, "nextText"); + nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText, + this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)), + this._getFormatConfig(inst))); + + next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ? + "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" + + " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" : + (hideIfNoPrevNext ? "" : "<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='"+ nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>")); + + 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 = (!inst.inline ? "<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>" + + this._get(inst, "closeText") + "</button>" : ""); + + buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") + + (this._isInRange(inst, gotoDate) ? "<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'" + + ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : ""; + + 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 = ""; + dow; + 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" + ((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='#'>" + 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"), + 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' 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' 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.drawYear + (period === "Y" ? offset : 0), + month = inst.drawMonth + (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 instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. + */ + function bindHover(dpDiv) { + var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a"; + return dpDiv.delegate(selector, "mouseout", 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"); + } + }) + .delegate(selector, "mouseover", function(){ + if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : 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 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).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() { + typeof options === "string" ? + $.datepicker["_" + options + "Datepicker"]. + apply($.datepicker, [this].concat(otherArgs)) : + $.datepicker._attachDatepicker(this, options); + }); + }; + + $.datepicker = new Datepicker(); // singleton instance + $.datepicker.initialized = false; + $.datepicker.uuid = new Date().getTime(); + $.datepicker.version = "1.10.4"; + +})(jQuery); diff --git a/lib/web/jquery/ui-modules/dialog.js b/lib/web/jquery/ui-modules/dialog.js new file mode 100644 index 000000000000..94d7a36111b0 --- /dev/null +++ b/lib/web/jquery/ui-modules/dialog.js @@ -0,0 +1,804 @@ +(function( $, undefined ) { + + var sizeRelatedOptions = { + buttons: true, + height: true, + maxHeight: true, + maxWidth: true, + minHeight: true, + minWidth: true, + width: true + }, + resizableRelatedOptions = { + maxHeight: true, + maxWidth: true, + minHeight: true, + minWidth: true + }; + + $.widget( "ui.dialog", { + version: "1.10.4", + options: { + appendTo: "body", + autoOpen: true, + buttons: [], + closeOnEscape: true, + closeText: "close", + dialogClass: "", + 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 + }, + + _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"); + this.options.title = this.options.title || this.originalTitle; + + this._createWrapper(); + + this.element + .show() + .removeAttr("title") + .addClass("ui-dialog-content ui-widget-content") + .appendTo( this.uiDialog ); + + this._createTitlebar(); + this._createButtonPane(); + + if ( this.options.draggable && $.fn.draggable ) { + this._makeDraggable(); + } + if ( this.options.resizable && $.fn.resizable ) { + this._makeResizable(); + } + + this._isOpen = false; + }, + + _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._destroyOverlay(); + + this.element + .removeUniqueId() + .removeClass("ui-dialog-content ui-widget-content") + .css( this.originalCss ) + // Without detaching first, the following becomes really slow + .detach(); + + this.uiDialog.stop( true, true ).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 activeElement, + that = this; + + if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) { + return; + } + + this._isOpen = false; + this._destroyOverlay(); + + if ( !this.opener.filter(":focusable").focus().length ) { + + // support: IE9 + // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe> + try { + activeElement = this.document[ 0 ].activeElement; + + // Support: IE9, IE10 + // If the <body> is blurred, IE will switch windows, see #4520 + if ( activeElement && activeElement.nodeName.toLowerCase() !== "body" ) { + + // 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 + $( activeElement ).blur(); + } + } catch ( error ) {} + } + + 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 = !!this.uiDialog.nextAll(":visible").insertBefore( this.uiDialog ).length; + 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 = $( this.document[0].activeElement ); + + this._size(); + this._position(); + this._createOverlay(); + this._moveToTop( null, true ); + this._show( this.uiDialog, this.options.show, function() { + that._focusTabbable(); + that._trigger("focus"); + }); + + this._trigger("open"); + }, + + _focusTabbable: function() { + // Set focus to the first match: + // 1. First element inside the dialog matching [autofocus] + // 2. Tabbable element inside the content element + // 3. Tabbable element inside the buttonpane + // 4. The close button + // 5. The dialog itself + var 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 ).focus(); + }, + + _keepFocus: function( event ) { + function checkFocus() { + var activeElement = this.document[0].activeElement, + isActive = this.uiDialog[0] === activeElement || + $.contains( this.uiDialog[0], activeElement ); + if ( !isActive ) { + this._focusTabbable(); + } + } + event.preventDefault(); + checkFocus.call( this ); + // support: IE + // IE <= 8 doesn't prevent moving focus even with event.preventDefault() + // so we check again later + this._delay( checkFocus ); + }, + + _createWrapper: function() { + this.uiDialog = $("<div>") + .addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " + + this.options.dialogClass ) + .hide() + .attr({ + // Setting tabIndex makes the div focusable + tabIndex: -1, + role: "dialog" + }) + .appendTo( this._appendTo() ); + + 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 ) { + return; + } + var tabbables = this.uiDialog.find(":tabbable"), + first = tabbables.filter(":first"), + last = tabbables.filter(":last"); + + if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) { + first.focus( 1 ); + event.preventDefault(); + } else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) { + last.focus( 1 ); + 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>") + .addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix") + .prependTo( this.uiDialog ); + 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.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: this.options.closeText, + icons: { + primary: "ui-icon-closethick" + }, + text: false + }) + .addClass("ui-dialog-titlebar-close") + .appendTo( this.uiDialogTitlebar ); + this._on( this.uiDialogTitlebarClose, { + click: function( event ) { + event.preventDefault(); + this.close( event ); + } + }); + + uiDialogTitle = $("<span>") + .uniqueId() + .addClass("ui-dialog-title") + .prependTo( this.uiDialogTitlebar ); + this._title( uiDialogTitle ); + + this.uiDialog.attr({ + "aria-labelledby": uiDialogTitle.attr("id") + }); + }, + + _title: function( title ) { + if ( !this.options.title ) { + title.html(" "); + } + title.text( this.options.title ); + }, + + _createButtonPane: function() { + this.uiDialogButtonPane = $("<div>") + .addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"); + + this.uiButtonSet = $("<div>") + .addClass("ui-dialog-buttonset") + .appendTo( this.uiDialogButtonPane ); + + 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 ) || ($.isArray( buttons ) && !buttons.length) ) { + this.uiDialog.removeClass("ui-dialog-buttons"); + return; + } + + $.each( buttons, function( name, props ) { + var click, buttonOptions; + props = $.isFunction( props ) ? + { 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; + props.click = function() { + click.apply( that.element[0], arguments ); + }; + buttonOptions = { + icons: props.icons, + text: props.showText + }; + delete props.icons; + delete props.showText; + $( "<button></button>", props ) + .button( buttonOptions ) + .appendTo( that.uiButtonSet ); + }); + this.uiDialog.addClass("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 ) { + $( this ).addClass("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 ) { + options.position = [ + ui.position.left - that.document.scrollLeft(), + ui.position.top - that.document.scrollTop() + ]; + $( this ).removeClass("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 ) { + $( this ).addClass("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 ) { + options.height = $( this ).height(); + options.width = $( this ).width(); + $( this ).removeClass("ui-dialog-resizing"); + that._unblockFrames(); + that._trigger( "resizeStop", event, filteredUi( ui ) ); + } + }) + .css( "position", position ); + }, + + _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 sizeRelatedOptions ) { + resize = true; + } + if ( key in 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 === "dialogClass" ) { + uiDialog + .removeClass( this.options.dialogClass ) + .addClass( value ); + } + + 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: "" + value + }); + } + + 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 that = this, + widgetFullName = this.widgetFullName; + if ( !$.ui.dialog.overlayInstances ) { + // Prevent use of anchors and inputs. + // We use a delay in case the overlay is created from an + // event that we're going to be cancelling. (#2804) + this._delay(function() { + // Handle .dialog().dialog("close") (#4065) + if ( $.ui.dialog.overlayInstances ) { + this.document.bind( "focusin.dialog", function( event ) { + if ( !that._allowInteraction( event ) ) { + event.preventDefault(); + $(".ui-dialog:visible:last .ui-dialog-content") + .data( widgetFullName )._focusTabbable(); + } + }); + } + }); + } + + this.overlay = $("<div>") + .addClass("ui-widget-overlay ui-front") + .appendTo( this._appendTo() ); + this._on( this.overlay, { + mousedown: "_keepFocus" + }); + $.ui.dialog.overlayInstances++; + }, + + _destroyOverlay: function() { + if ( !this.options.modal ) { + return; + } + + if ( this.overlay ) { + $.ui.dialog.overlayInstances--; + + if ( !$.ui.dialog.overlayInstances ) { + this.document.unbind( "focusin.dialog" ); + } + this.overlay.remove(); + this.overlay = null; + } + } + }); + + $.ui.dialog.overlayInstances = 0; + +// DEPRECATED + if ( $.uiBackCompat !== false ) { + // position option with array notation + // just override with old implementation + $.widget( "ui.dialog", $.ui.dialog, { + _position: function() { + var position = this.options.position, + myAt = [], + offset = [ 0, 0 ], + isVisible; + + if ( position ) { + if ( typeof position === "string" || (typeof position === "object" && "0" in position ) ) { + myAt = position.split ? position.split(" ") : [ position[0], position[1] ]; + if ( myAt.length === 1 ) { + myAt[1] = myAt[0]; + } + + $.each( [ "left", "top" ], function( i, offsetPosition ) { + if ( +myAt[ i ] === myAt[ i ] ) { + offset[ i ] = myAt[ i ]; + myAt[ i ] = offsetPosition; + } + }); + + position = { + my: myAt[0] + (offset[0] < 0 ? offset[0] : "+" + offset[0]) + " " + + myAt[1] + (offset[1] < 0 ? offset[1] : "+" + offset[1]), + at: myAt.join(" ") + }; + } + + position = $.extend( {}, $.ui.dialog.prototype.options.position, position ); + } else { + position = $.ui.dialog.prototype.options.position; + } + + // need to show the dialog to get the actual offset in the position plugin + isVisible = this.uiDialog.is(":visible"); + if ( !isVisible ) { + this.uiDialog.show(); + } + this.uiDialog.position( position ); + if ( !isVisible ) { + this.uiDialog.hide(); + } + } + }); + } + +}( jQuery ) ); diff --git a/lib/web/jquery/ui-modules/draggable.js b/lib/web/jquery/ui-modules/draggable.js new file mode 100644 index 000000000000..43c378a0d425 --- /dev/null +++ b/lib/web/jquery/ui-modules/draggable.js @@ -0,0 +1,943 @@ +(function( $, undefined ) { + + $.widget("ui.draggable", $.ui.mouse, { + version: "1.10.4", + 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" && !(/^(?:r|a|f)/).test(this.element.css("position"))) { + this.element[0].style.position = "relative"; + } + if (this.options.addClasses){ + this.element.addClass("ui-draggable"); + } + if (this.options.disabled){ + this.element.addClass("ui-draggable-disabled"); + } + + this._mouseInit(); + + }, + + _destroy: function() { + this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" ); + 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; + } + + $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() { + $("<div class='ui-draggable-iframeFix' style='background: #fff;'></div>") + .css({ + width: this.offsetWidth+"px", height: this.offsetHeight+"px", + position: "absolute", opacity: "0.001", zIndex: 1000 + }) + .css($(this).offset()) + .appendTo("body"); + }); + + return true; + + }, + + _mouseStart: function(event) { + + var o = this.options; + + //Create and append the visible helper + this.helper = this._createHelper(event); + + this.helper.addClass("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(); + this.offsetParent = this.helper.offsetParent(); + this.offsetParentCssPosition = this.offsetParent.css( "position" ); + + //The element's absolute position on the page minus margins + this.offset = this.positionAbs = this.element.offset(); + this.offset = { + top: this.offset.top - this.margins.top, + left: this.offset.left - this.margins.left + }; + + //Reset scroll cache + this.offset.scroll = false; + + $.extend(this.offset, { + click: { //Where the click happened, relative to the element + left: event.pageX - this.offset.left, + top: event.pageY - this.offset.top + }, + parent: this._getParentOffset(), + relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper + }); + + //Generate the original position + this.originalPosition = this.position = this._generatePosition(event); + this.originalPageX = event.pageX; + this.originalPageY = event.pageY; + + //Adjust the mouse offset relative to the helper if "cursorAt" is supplied + (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); + } + + + this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position + + //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; + }, + + _mouseDrag: function(event, noPropagation) { + // reset any necessary cached properties (see #5009) + if ( this.offsetParentCssPosition === "fixed" ) { + this.offset.parent = this._getParentOffset(); + } + + //Compute the helpers position + this.position = this._generatePosition(event); + 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({}); + return false; + } + this.position = ui.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"; + } + 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 the original element is no longer in the DOM don't bother to continue (see #8269) + if ( this.options.helper === "original" && !$.contains( this.element[ 0 ].ownerDocument, this.element[ 0 ] ) ) { + return false; + } + + if((this.options.revert === "invalid" && !dropped) || (this.options.revert === "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && 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) { + //Remove frame helpers + $("div.ui-draggable-iframeFix").each(function() { + this.parentNode.removeChild(this); + }); + + //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003) + if( $.ui.ddmanager ) { + $.ui.ddmanager.dragStop(this, event); + } + + return $.ui.mouse.prototype._mouseUp.call(this, event); + }, + + cancel: function() { + + if(this.helper.is(".ui-draggable-dragging")) { + this._mouseUp({}); + } else { + this._clear(); + } + + return this; + + }, + + _getHandle: function(event) { + return this.options.handle ? + !!$( event.target ).closest( this.element.find( this.options.handle ) ).length : + true; + }, + + _createHelper: function(event) { + + var o = this.options, + helper = $.isFunction(o.helper) ? $(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)); + } + + if(helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) { + helper.css("position", "absolute"); + } + + return helper; + + }, + + _adjustOffsetFromHelper: function(obj) { + if (typeof obj === "string") { + obj = obj.split(" "); + } + if ($.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 + 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] !== document && $.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 + //Ugly IE fix + if((this.offsetParent[0] === document.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.element.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.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 over, c, ce, + o = this.options; + + 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; + } + + over = c.css( "overflow" ) !== "hidden"; + + 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 ) , + ( over ? 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, + ( over ? 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.relative_container = c; + }, + + _convertPositionTo: function(d, pos) { + + if(!pos) { + pos = this.position; + } + + var mod = d === "absolute" ? 1 : -1, + scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent; + + //Cache the scroll + if (!this.offset.scroll) { + this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()}; + } + + return { + top: ( + pos.top + // The absolute mouse position + this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border) + ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top ) * mod ) + ), + left: ( + pos.left + // The absolute mouse position + this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) + ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left ) * mod ) + ) + }; + + }, + + _generatePosition: function(event) { + + var containment, co, top, left, + o = this.options, + scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent, + pageX = event.pageX, + pageY = event.pageY; + + //Cache the scroll + if (!this.offset.scroll) { + this.offset.scroll = {top : scroll.scrollTop(), left : scroll.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 ( this.originalPosition ) { + if ( this.containment ) { + if ( this.relative_container ){ + co = this.relative_container.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; + } + + } + + return { + top: ( + pageY - // The absolute mouse position + this.offset.click.top - // Click offset (relative to the element) + this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.parent.top + // The offsetParent's offset without borders (offset + border) + ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top ) + ), + left: ( + pageX - // The absolute mouse position + this.offset.click.left - // Click offset (relative to the element) + this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.parent.left + // The offsetParent's offset without borders (offset + border) + ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left ) + ) + }; + + }, + + _clear: function() { + this.helper.removeClass("ui-draggable-dragging"); + if(this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) { + this.helper.remove(); + } + this.helper = null; + this.cancelHelperRemoval = false; + }, + + // From now on bulk stuff - mainly helpers + + _trigger: function(type, event, ui) { + ui = ui || this._uiHash(); + $.ui.plugin.call(this, type, [event, ui]); + //The absolute position has to be recalculated after plugins + if(type === "drag") { + this.positionAbs = this._convertPositionTo("absolute"); + } + 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) { + + var inst = $(this).data("ui-draggable"), o = inst.options, + uiSortable = $.extend({}, ui, { item: inst.element }); + inst.sortables = []; + $(o.connectToSortable).each(function() { + var sortable = $.data(this, "ui-sortable"); + if (sortable && !sortable.options.disabled) { + inst.sortables.push({ + instance: sortable, + shouldRevert: sortable.options.revert + }); + sortable.refreshPositions(); // Call the sortable's refreshPositions at drag start to refresh the containerCache since the sortable container cache is used in drag and needs to be up to date (this will ensure it's initialised as well as being kept in step with any changes that might have happened on the page). + sortable._trigger("activate", event, uiSortable); + } + }); + + }, + stop: function(event, ui) { + + //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper + var inst = $(this).data("ui-draggable"), + uiSortable = $.extend({}, ui, { item: inst.element }); + + $.each(inst.sortables, function() { + if(this.instance.isOver) { + + this.instance.isOver = 0; + + inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance + this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work) + + //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: "valid/invalid" + if(this.shouldRevert) { + this.instance.options.revert = this.shouldRevert; + } + + //Trigger the stop of the sortable + this.instance._mouseStop(event); + + this.instance.options.helper = this.instance.options._helper; + + //If the helper has been the original item, restore properties in the sortable + if(inst.options.helper === "original") { + this.instance.currentItem.css({ top: "auto", left: "auto" }); + } + + } else { + this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance + this.instance._trigger("deactivate", event, uiSortable); + } + + }); + + }, + drag: function(event, ui) { + + var inst = $(this).data("ui-draggable"), that = this; + + $.each(inst.sortables, function() { + + var innermostIntersecting = false, + thisSortable = this; + + //Copy over some variables to allow calling the sortable's native _intersectsWith + this.instance.positionAbs = inst.positionAbs; + this.instance.helperProportions = inst.helperProportions; + this.instance.offset.click = inst.offset.click; + + if(this.instance._intersectsWith(this.instance.containerCache)) { + innermostIntersecting = true; + $.each(inst.sortables, function () { + this.instance.positionAbs = inst.positionAbs; + this.instance.helperProportions = inst.helperProportions; + this.instance.offset.click = inst.offset.click; + if (this !== thisSortable && + this.instance._intersectsWith(this.instance.containerCache) && + $.contains(thisSortable.instance.element[0], this.instance.element[0]) + ) { + innermostIntersecting = false; + } + return innermostIntersecting; + }); + } + + + if(innermostIntersecting) { + //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once + if(!this.instance.isOver) { + + this.instance.isOver = 1; + //Now we fake the start of dragging for the sortable instance, + //by cloning the list group item, appending it to the sortable and using it as inst.currentItem + //We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one) + this.instance.currentItem = $(that).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item", true); + this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it + this.instance.options.helper = function() { return ui.helper[0]; }; + + event.target = this.instance.currentItem[0]; + this.instance._mouseCapture(event, true); + this.instance._mouseStart(event, true, true); + + //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes + this.instance.offset.click.top = inst.offset.click.top; + this.instance.offset.click.left = inst.offset.click.left; + this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left; + this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top; + + inst._trigger("toSortable", event); + inst.dropped = this.instance.element; //draggable revert needs that + //hack so receive/update callbacks work (mostly) + inst.currentItem = inst.element; + this.instance.fromOutside = inst; + + } + + //Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable + if(this.instance.currentItem) { + this.instance._mouseDrag(event); + } + + } 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(this.instance.isOver) { + + this.instance.isOver = 0; + this.instance.cancelHelperRemoval = true; + + //Prevent reverting on this forced stop + this.instance.options.revert = false; + + // The out event needs to be triggered independently + this.instance._trigger("out", event, this.instance._uiHash(this.instance)); + + this.instance._mouseStop(event, true); + this.instance.options.helper = this.instance.options._helper; + + //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size + this.instance.currentItem.remove(); + if(this.instance.placeholder) { + this.instance.placeholder.remove(); + } + + inst._trigger("fromSortable", event); + inst.dropped = false; //draggable revert needs that + } + + } + + }); + + } + }); + + $.ui.plugin.add("draggable", "cursor", { + start: function() { + var t = $("body"), o = $(this).data("ui-draggable").options; + if (t.css("cursor")) { + o._cursor = t.css("cursor"); + } + t.css("cursor", o.cursor); + }, + stop: function() { + var o = $(this).data("ui-draggable").options; + if (o._cursor) { + $("body").css("cursor", o._cursor); + } + } + }); + + $.ui.plugin.add("draggable", "opacity", { + start: function(event, ui) { + var t = $(ui.helper), o = $(this).data("ui-draggable").options; + if(t.css("opacity")) { + o._opacity = t.css("opacity"); + } + t.css("opacity", o.opacity); + }, + stop: function(event, ui) { + var o = $(this).data("ui-draggable").options; + if(o._opacity) { + $(ui.helper).css("opacity", o._opacity); + } + } + }); + + $.ui.plugin.add("draggable", "scroll", { + start: function() { + var i = $(this).data("ui-draggable"); + if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") { + i.overflowOffset = i.scrollParent.offset(); + } + }, + drag: function( event ) { + + var i = $(this).data("ui-draggable"), o = i.options, scrolled = false; + + if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") { + + if(!o.axis || o.axis !== "x") { + if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) { + i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed; + } else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) { + i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed; + } + } + + if(!o.axis || o.axis !== "y") { + if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) { + i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed; + } else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) { + i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].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() { + + var i = $(this).data("ui-draggable"), + 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) { + + var ts, bs, ls, rs, l, r, t, b, i, first, + inst = $(this).data("ui-draggable"), + 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; + r = l + inst.snapElements[i].width; + t = inst.snapElements[i].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) { + (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 - inst.margins.top; + } + if(bs) { + ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top; + } + if(ls) { + ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left; + } + if(rs) { + ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.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 - inst.margins.top; + } + if(bs) { + ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top; + } + if(ls) { + ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left; + } + if(rs) { + ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left; + } + } + + if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) { + (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() { + var min, + o = this.data("ui-draggable").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) { + var t = $(ui.helper), o = $(this).data("ui-draggable").options; + if(t.css("zIndex")) { + o._zIndex = t.css("zIndex"); + } + t.css("zIndex", o.zIndex); + }, + stop: function(event, ui) { + var o = $(this).data("ui-draggable").options; + if(o._zIndex) { + $(ui.helper).css("zIndex", o._zIndex); + } + } + }); + +})(jQuery); diff --git a/lib/web/jquery/ui-modules/droppable.js b/lib/web/jquery/ui-modules/droppable.js new file mode 100644 index 000000000000..fd8694f9910d --- /dev/null +++ b/lib/web/jquery/ui-modules/droppable.js @@ -0,0 +1,373 @@ +(function( $, undefined ) { + + function isOverAxis( x, reference, size ) { + return ( x > reference ) && ( x < ( reference + size ) ); + } + + $.widget("ui.droppable", { + version: "1.10.4", + widgetEventPrefix: "drop", + options: { + accept: "*", + activeClass: false, + addClasses: true, + greedy: false, + hoverClass: 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 = $.isFunction(accept) ? 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 + }; + } + }; + + // Add the reference and positions to the manager + $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || []; + $.ui.ddmanager.droppables[o.scope].push(this); + + (o.addClasses && this.element.addClass("ui-droppable")); + + }, + + _destroy: function() { + var i = 0, + drop = $.ui.ddmanager.droppables[this.options.scope]; + + for ( ; i < drop.length; i++ ) { + if ( drop[i] === this ) { + drop.splice(i, 1); + } + } + + this.element.removeClass("ui-droppable ui-droppable-disabled"); + }, + + _setOption: function(key, value) { + + if(key === "accept") { + this.accept = $.isFunction(value) ? value : function(d) { + return d.is(value); + }; + } + $.Widget.prototype._setOption.apply(this, arguments); + }, + + _activate: function(event) { + var draggable = $.ui.ddmanager.current; + if(this.options.activeClass) { + this.element.addClass(this.options.activeClass); + } + if(draggable){ + this._trigger("activate", event, this.ui(draggable)); + } + }, + + _deactivate: function(event) { + var draggable = $.ui.ddmanager.current; + if(this.options.activeClass) { + this.element.removeClass(this.options.activeClass); + } + 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))) { + if(this.options.hoverClass) { + this.element.addClass(this.options.hoverClass); + } + 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))) { + if(this.options.hoverClass) { + this.element.removeClass(this.options.hoverClass); + } + 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 = $.data(this, "ui-droppable"); + 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) + ) { childrenIntersection = true; return false; } + }); + if(childrenIntersection) { + return false; + } + + if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { + if(this.options.activeClass) { + this.element.removeClass(this.options.activeClass); + } + if(this.options.hoverClass) { + this.element.removeClass(this.options.hoverClass); + } + 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 + }; + } + + }); + + $.ui.intersect = function(draggable, droppable, toleranceMode) { + + if (!droppable.offset) { + return false; + } + + var draggableLeft, draggableTop, + x1 = (draggable.positionAbs || draggable.position.absolute).left, + y1 = (draggable.positionAbs || draggable.position.absolute).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": + draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left); + draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top); + return isOverAxis( draggableTop, t, droppable.proportions().height ) && isOverAxis( draggableLeft, 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)) { + 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" ).bind( "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), + 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 $.data(this, "ui-droppable").options.scope === scope; + }); + + if (parent.length) { + parentInstance = $.data(parent[0], "ui-droppable"); + 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" ).unbind( "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 ); + } + } + }; + +})(jQuery); diff --git a/lib/web/jquery/ui-modules/effect-blind.js b/lib/web/jquery/ui-modules/effect-blind.js new file mode 100644 index 000000000000..d2234df6046b --- /dev/null +++ b/lib/web/jquery/ui-modules/effect-blind.js @@ -0,0 +1,69 @@ +(function( $, undefined ) { + + var rvertical = /up|down|vertical/, + rpositivemotion = /up|left|vertical|horizontal/; + + $.effects.effect.blind = function( o, done ) { + // Create element + var el = $( this ), + props = [ "position", "top", "bottom", "left", "right", "height", "width" ], + mode = $.effects.setMode( el, o.mode || "hide" ), + direction = o.direction || "up", + vertical = rvertical.test( direction ), + ref = vertical ? "height" : "width", + ref2 = vertical ? "top" : "left", + motion = rpositivemotion.test( direction ), + animation = {}, + show = mode === "show", + wrapper, distance, margin; + + // if already wrapped, the wrapper's properties are my property. #6245 + if ( el.parent().is( ".ui-effects-wrapper" ) ) { + $.effects.save( el.parent(), props ); + } else { + $.effects.save( el, props ); + } + el.show(); + wrapper = $.effects.createWrapper( el ).css({ + overflow: "hidden" + }); + + distance = wrapper[ ref ](); + margin = parseFloat( wrapper.css( ref2 ) ) || 0; + + animation[ ref ] = show ? distance : 0; + if ( !motion ) { + el + .css( vertical ? "bottom" : "right", 0 ) + .css( vertical ? "top" : "left", "auto" ) + .css({ position: "absolute" }); + + animation[ ref2 ] = show ? margin : distance + margin; + } + + // start at 0 if we are showing + if ( show ) { + wrapper.css( ref, 0 ); + if ( ! motion ) { + wrapper.css( ref2, margin + distance ); + } + } + + // Animate + wrapper.animate( animation, { + duration: o.duration, + easing: o.easing, + queue: false, + complete: function() { + if ( mode === "hide" ) { + el.hide(); + } + $.effects.restore( el, props ); + $.effects.removeWrapper( el ); + done(); + } + }); + + }; + +})(jQuery); diff --git a/lib/web/jquery/ui-modules/effect-bounce.js b/lib/web/jquery/ui-modules/effect-bounce.js new file mode 100644 index 000000000000..7073c892d4e9 --- /dev/null +++ b/lib/web/jquery/ui-modules/effect-bounce.js @@ -0,0 +1,100 @@ +(function( $, undefined ) { + + $.effects.effect.bounce = function( o, done ) { + var el = $( this ), + props = [ "position", "top", "bottom", "left", "right", "height", "width" ], + + // defaults: + mode = $.effects.setMode( el, o.mode || "effect" ), + hide = mode === "hide", + show = mode === "show", + direction = o.direction || "up", + distance = o.distance, + times = o.times || 5, + + // number of internal animations + anims = times * 2 + ( show || hide ? 1 : 0 ), + speed = o.duration / anims, + easing = o.easing, + + // utility: + ref = ( direction === "up" || direction === "down" ) ? "top" : "left", + motion = ( direction === "up" || direction === "left" ), + i, + upAnim, + downAnim, + + // we will need to re-assemble the queue to stack our animations in place + queue = el.queue(), + queuelen = queue.length; + + // Avoid touching opacity to prevent clearType and PNG issues in IE + if ( show || hide ) { + props.push( "opacity" ); + } + + $.effects.save( el, props ); + el.show(); + $.effects.createWrapper( el ); // Create Wrapper + + // default distance for the BIGGEST bounce is the outer Distance / 3 + if ( !distance ) { + distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3; + } + + if ( show ) { + downAnim = { opacity: 1 }; + downAnim[ ref ] = 0; + + // if we are showing, force opacity 0 and set the initial position + // then do the "first" animation + el.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 ); + } + + downAnim = {}; + downAnim[ ref ] = 0; + // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here + for ( i = 0; i < times; i++ ) { + upAnim = {}; + upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; + + el.animate( upAnim, speed, easing ) + .animate( downAnim, speed, easing ); + + distance = hide ? distance * 2 : distance / 2; + } + + // Last Bounce when Hiding + if ( hide ) { + upAnim = { opacity: 0 }; + upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; + + el.animate( upAnim, speed, easing ); + } + + el.queue(function() { + if ( hide ) { + el.hide(); + } + $.effects.restore( el, props ); + $.effects.removeWrapper( el ); + done(); + }); + + // inject all the animations we just queued to be first in line (after "inprogress") + if ( queuelen > 1) { + queue.splice.apply( queue, + [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); + } + el.dequeue(); + + }; + +})(jQuery); diff --git a/lib/web/jquery/ui-modules/effect-clip.js b/lib/web/jquery/ui-modules/effect-clip.js new file mode 100644 index 000000000000..38ef30c96bbf --- /dev/null +++ b/lib/web/jquery/ui-modules/effect-clip.js @@ -0,0 +1,54 @@ +(function( $, undefined ) { + + $.effects.effect.clip = function( o, done ) { + // Create element + var el = $( this ), + props = [ "position", "top", "bottom", "left", "right", "height", "width" ], + mode = $.effects.setMode( el, o.mode || "hide" ), + show = mode === "show", + direction = o.direction || "vertical", + vert = direction === "vertical", + size = vert ? "height" : "width", + position = vert ? "top" : "left", + animation = {}, + wrapper, animate, distance; + + // Save & Show + $.effects.save( el, props ); + el.show(); + + // Create Wrapper + wrapper = $.effects.createWrapper( el ).css({ + overflow: "hidden" + }); + animate = ( el[0].tagName === "IMG" ) ? wrapper : el; + distance = animate[ size ](); + + // Shift + if ( show ) { + animate.css( size, 0 ); + animate.css( position, distance / 2 ); + } + + // Create Animation Object: + animation[ size ] = show ? distance : 0; + animation[ position ] = show ? 0 : distance / 2; + + // Animate + animate.animate( animation, { + queue: false, + duration: o.duration, + easing: o.easing, + complete: function() { + if ( !show ) { + el.hide(); + } + $.effects.restore( el, props ); + $.effects.removeWrapper( el ); + done(); + } + }); + + }; + +})(jQuery); diff --git a/lib/web/jquery/ui-modules/effect-drop.js b/lib/web/jquery/ui-modules/effect-drop.js new file mode 100644 index 000000000000..8d3b930fa285 --- /dev/null +++ b/lib/web/jquery/ui-modules/effect-drop.js @@ -0,0 +1,52 @@ +(function( $, undefined ) { + + $.effects.effect.drop = function( o, done ) { + + var el = $( this ), + props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ], + mode = $.effects.setMode( el, o.mode || "hide" ), + show = mode === "show", + direction = o.direction || "left", + ref = ( direction === "up" || direction === "down" ) ? "top" : "left", + motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg", + animation = { + opacity: show ? 1 : 0 + }, + distance; + + // Adjust + $.effects.save( el, props ); + el.show(); + $.effects.createWrapper( el ); + + distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2; + + if ( show ) { + el + .css( "opacity", 0 ) + .css( ref, motion === "pos" ? -distance : distance ); + } + + // Animation + animation[ ref ] = ( show ? + ( motion === "pos" ? "+=" : "-=" ) : + ( motion === "pos" ? "-=" : "+=" ) ) + + distance; + + // Animate + el.animate( animation, { + queue: false, + duration: o.duration, + easing: o.easing, + complete: function() { + if ( mode === "hide" ) { + el.hide(); + } + $.effects.restore( el, props ); + $.effects.removeWrapper( el ); + done(); + } + }); + }; + +})(jQuery); diff --git a/lib/web/jquery/ui-modules/effect-explode.js b/lib/web/jquery/ui-modules/effect-explode.js new file mode 100644 index 000000000000..0d2291020cf9 --- /dev/null +++ b/lib/web/jquery/ui-modules/effect-explode.js @@ -0,0 +1,84 @@ +(function( $, undefined ) { + + $.effects.effect.explode = function( o, done ) { + + var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3, + cells = rows, + el = $( this ), + mode = $.effects.setMode( el, o.mode || "hide" ), + show = mode === "show", + + // show and then visibility:hidden the element before calculating offset + offset = el.show().css( "visibility", "hidden" ).offset(), + + // width and height of a piece + width = Math.ceil( el.outerWidth() / cells ), + height = Math.ceil( el.outerHeight() / rows ), + pieces = [], + + // loop + i, j, left, top, mx, my; + + // 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 + el + .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 + }, o.duration || 500, o.easing, childComplete ); + } + } + + function animComplete() { + el.css({ + visibility: "visible" + }); + $( pieces ).remove(); + if ( !show ) { + el.hide(); + } + done(); + } + }; + +})(jQuery); diff --git a/lib/web/jquery/ui-modules/effect-fade.js b/lib/web/jquery/ui-modules/effect-fade.js new file mode 100644 index 000000000000..62af799ac2fe --- /dev/null +++ b/lib/web/jquery/ui-modules/effect-fade.js @@ -0,0 +1,17 @@ +(function( $, undefined ) { + + $.effects.effect.fade = function( o, done ) { + var el = $( this ), + mode = $.effects.setMode( el, o.mode || "toggle" ); + + el.animate({ + opacity: mode + }, { + queue: false, + duration: o.duration, + easing: o.easing, + complete: done + }); + }; + +})( jQuery ); diff --git a/lib/web/jquery/ui-modules/effect-fold.js b/lib/web/jquery/ui-modules/effect-fold.js new file mode 100644 index 000000000000..041b5bd50e6f --- /dev/null +++ b/lib/web/jquery/ui-modules/effect-fold.js @@ -0,0 +1,63 @@ +(function( $, undefined ) { + + $.effects.effect.fold = function( o, done ) { + + // Create element + var el = $( this ), + props = [ "position", "top", "bottom", "left", "right", "height", "width" ], + mode = $.effects.setMode( el, o.mode || "hide" ), + show = mode === "show", + hide = mode === "hide", + size = o.size || 15, + percent = /([0-9]+)%/.exec( size ), + horizFirst = !!o.horizFirst, + widthFirst = show !== horizFirst, + ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ], + duration = o.duration / 2, + wrapper, distance, + animation1 = {}, + animation2 = {}; + + $.effects.save( el, props ); + el.show(); + + // Create Wrapper + wrapper = $.effects.createWrapper( el ).css({ + overflow: "hidden" + }); + distance = widthFirst ? + [ wrapper.width(), wrapper.height() ] : + [ wrapper.height(), wrapper.width() ]; + + if ( percent ) { + size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ]; + } + if ( show ) { + wrapper.css( horizFirst ? { + height: 0, + width: size + } : { + height: size, + width: 0 + }); + } + + // Animation + animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size; + animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0; + + // Animate + wrapper + .animate( animation1, duration, o.easing ) + .animate( animation2, duration, o.easing, function() { + if ( hide ) { + el.hide(); + } + $.effects.restore( el, props ); + $.effects.removeWrapper( el ); + done(); + }); + + }; + +})(jQuery); diff --git a/lib/web/jquery/ui-modules/effect-highlight.js b/lib/web/jquery/ui-modules/effect-highlight.js new file mode 100644 index 000000000000..f364ccd2fdb9 --- /dev/null +++ b/lib/web/jquery/ui-modules/effect-highlight.js @@ -0,0 +1,37 @@ +(function( $, undefined ) { + + $.effects.effect.highlight = function( o, done ) { + var elem = $( this ), + props = [ "backgroundImage", "backgroundColor", "opacity" ], + mode = $.effects.setMode( elem, o.mode || "show" ), + animation = { + backgroundColor: elem.css( "backgroundColor" ) + }; + + if (mode === "hide") { + animation.opacity = 0; + } + + $.effects.save( elem, props ); + + elem + .show() + .css({ + backgroundImage: "none", + backgroundColor: o.color || "#ffff99" + }) + .animate( animation, { + queue: false, + duration: o.duration, + easing: o.easing, + complete: function() { + if ( mode === "hide" ) { + elem.hide(); + } + $.effects.restore( elem, props ); + done(); + } + }); + }; + +})(jQuery); diff --git a/lib/web/jquery/ui-modules/effect-puff.js b/lib/web/jquery/ui-modules/effect-puff.js new file mode 100644 index 000000000000..309f44ca8482 --- /dev/null +++ b/lib/web/jquery/ui-modules/effect-puff.js @@ -0,0 +1,305 @@ +(function( $, undefined ) { + + $.effects.effect.puff = function( o, done ) { + var elem = $( this ), + mode = $.effects.setMode( elem, o.mode || "hide" ), + hide = mode === "hide", + percent = parseInt( o.percent, 10 ) || 150, + factor = percent / 100, + original = { + height: elem.height(), + width: elem.width(), + outerHeight: elem.outerHeight(), + outerWidth: elem.outerWidth() + }; + + $.extend( o, { + effect: "scale", + queue: false, + fade: true, + mode: mode, + complete: done, + percent: hide ? percent : 100, + from: hide ? + original : + { + height: original.height * factor, + width: original.width * factor, + outerHeight: original.outerHeight * factor, + outerWidth: original.outerWidth * factor + } + }); + + elem.effect( o ); + }; + + $.effects.effect.scale = function( o, done ) { + + // Create element + var el = $( this ), + options = $.extend( true, {}, o ), + mode = $.effects.setMode( el, o.mode || "effect" ), + percent = parseInt( o.percent, 10 ) || + ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ), + direction = o.direction || "both", + origin = o.origin, + original = { + height: el.height(), + width: el.width(), + outerHeight: el.outerHeight(), + outerWidth: el.outerWidth() + }, + factor = { + y: direction !== "horizontal" ? (percent / 100) : 1, + x: direction !== "vertical" ? (percent / 100) : 1 + }; + + // We are going to pass this effect to the size effect: + options.effect = "size"; + options.queue = false; + options.complete = done; + + // Set default origin and restore for show/hide + if ( mode !== "effect" ) { + options.origin = origin || ["middle","center"]; + options.restore = true; + } + + options.from = o.from || ( mode === "show" ? { + height: 0, + width: 0, + outerHeight: 0, + outerWidth: 0 + } : original ); + options.to = { + height: original.height * factor.y, + width: original.width * factor.x, + outerHeight: original.outerHeight * factor.y, + outerWidth: original.outerWidth * factor.x + }; + + // Fade option to support puff + if ( options.fade ) { + if ( mode === "show" ) { + options.from.opacity = 0; + options.to.opacity = 1; + } + if ( mode === "hide" ) { + options.from.opacity = 1; + options.to.opacity = 0; + } + } + + // Animate + el.effect( options ); + + }; + + $.effects.effect.size = function( o, done ) { + + // Create element + var original, baseline, factor, + el = $( this ), + props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ], + + // Always restore + props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ], + + // Copy for children + props2 = [ "width", "height", "overflow" ], + cProps = [ "fontSize" ], + vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ], + hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ], + + // Set options + mode = $.effects.setMode( el, o.mode || "effect" ), + restore = o.restore || mode !== "effect", + scale = o.scale || "both", + origin = o.origin || [ "middle", "center" ], + position = el.css( "position" ), + props = restore ? props0 : props1, + zero = { + height: 0, + width: 0, + outerHeight: 0, + outerWidth: 0 + }; + + if ( mode === "show" ) { + el.show(); + } + original = { + height: el.height(), + width: el.width(), + outerHeight: el.outerHeight(), + outerWidth: el.outerWidth() + }; + + if ( o.mode === "toggle" && mode === "show" ) { + el.from = o.to || zero; + el.to = o.from || original; + } else { + el.from = o.from || ( mode === "show" ? zero : original ); + el.to = o.to || ( mode === "hide" ? zero : original ); + } + + // Set scaling factor + factor = { + from: { + y: el.from.height / original.height, + x: el.from.width / original.width + }, + to: { + y: el.to.height / original.height, + x: el.to.width / original.width + } + }; + + // Scale the css box + if ( scale === "box" || scale === "both" ) { + + // Vertical props scaling + if ( factor.from.y !== factor.to.y ) { + props = props.concat( vProps ); + el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from ); + el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to ); + } + + // Horizontal props scaling + if ( factor.from.x !== factor.to.x ) { + props = props.concat( hProps ); + el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from ); + el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to ); + } + } + + // Scale the content + if ( scale === "content" || scale === "both" ) { + + // Vertical props scaling + if ( factor.from.y !== factor.to.y ) { + props = props.concat( cProps ).concat( props2 ); + el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from ); + el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to ); + } + } + + $.effects.save( el, props ); + el.show(); + $.effects.createWrapper( el ); + el.css( "overflow", "hidden" ).css( el.from ); + + // Adjust + if (origin) { // Calculate baseline shifts + baseline = $.effects.getBaseline( origin, original ); + el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y; + el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x; + el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y; + el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x; + } + el.css( el.from ); // set top & left + + // Animate + if ( scale === "content" || scale === "both" ) { // Scale the children + + // Add margins/font-size + vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps); + hProps = hProps.concat([ "marginLeft", "marginRight" ]); + props2 = props0.concat(vProps).concat(hProps); + + el.find( "*[width]" ).each( function(){ + var child = $( this ), + c_original = { + height: child.height(), + width: child.width(), + outerHeight: child.outerHeight(), + outerWidth: child.outerWidth() + }; + if (restore) { + $.effects.save(child, props2); + } + + child.from = { + height: c_original.height * factor.from.y, + width: c_original.width * factor.from.x, + outerHeight: c_original.outerHeight * factor.from.y, + outerWidth: c_original.outerWidth * factor.from.x + }; + child.to = { + height: c_original.height * factor.to.y, + width: c_original.width * factor.to.x, + outerHeight: c_original.height * factor.to.y, + outerWidth: c_original.width * factor.to.x + }; + + // Vertical props scaling + if ( factor.from.y !== factor.to.y ) { + child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from ); + child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to ); + } + + // Horizontal props scaling + if ( factor.from.x !== factor.to.x ) { + child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from ); + child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to ); + } + + // Animate children + child.css( child.from ); + child.animate( child.to, o.duration, o.easing, function() { + + // Restore children + if ( restore ) { + $.effects.restore( child, props2 ); + } + }); + }); + } + + // Animate + el.animate( el.to, { + queue: false, + duration: o.duration, + easing: o.easing, + complete: function() { + if ( el.to.opacity === 0 ) { + el.css( "opacity", el.from.opacity ); + } + if( mode === "hide" ) { + el.hide(); + } + $.effects.restore( el, props ); + if ( !restore ) { + + // we need to calculate our new positioning based on the scaling + if ( position === "static" ) { + el.css({ + position: "relative", + top: el.to.top, + left: el.to.left + }); + } else { + $.each([ "top", "left" ], function( idx, pos ) { + el.css( pos, function( _, str ) { + var val = parseInt( str, 10 ), + toRef = idx ? el.to.left : el.to.top; + + // if original was "auto", recalculate the new value from wrapper + if ( str === "auto" ) { + return toRef + "px"; + } + + return val + toRef + "px"; + }); + }); + } + } + + $.effects.removeWrapper( el ); + done(); + } + }); + + }; + +})(jQuery); diff --git a/lib/web/jquery/ui-modules/effect-pulsate.js b/lib/web/jquery/ui-modules/effect-pulsate.js new file mode 100644 index 000000000000..20796970d097 --- /dev/null +++ b/lib/web/jquery/ui-modules/effect-pulsate.js @@ -0,0 +1,50 @@ +(function( $, undefined ) { + + $.effects.effect.pulsate = function( o, done ) { + var elem = $( this ), + mode = $.effects.setMode( elem, o.mode || "show" ), + show = mode === "show", + hide = mode === "hide", + showhide = ( show || mode === "hide" ), + + // showing or hiding leaves of the "last" animation + anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ), + duration = o.duration / anims, + animateTo = 0, + queue = elem.queue(), + queuelen = queue.length, + i; + + if ( show || !elem.is(":visible")) { + elem.css( "opacity", 0 ).show(); + animateTo = 1; + } + + // anims - 1 opacity "toggles" + for ( i = 1; i < anims; i++ ) { + elem.animate({ + opacity: animateTo + }, duration, o.easing ); + animateTo = 1 - animateTo; + } + + elem.animate({ + opacity: animateTo + }, duration, o.easing); + + elem.queue(function() { + if ( hide ) { + elem.hide(); + } + done(); + }); + + // We just queued up "anims" animations, we need to put them next in the queue + if ( queuelen > 1 ) { + queue.splice.apply( queue, + [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); + } + elem.dequeue(); + }; + +})(jQuery); diff --git a/lib/web/jquery/ui-modules/effect-shake.js b/lib/web/jquery/ui-modules/effect-shake.js new file mode 100644 index 000000000000..61924c24b5bd --- /dev/null +++ b/lib/web/jquery/ui-modules/effect-shake.js @@ -0,0 +1,61 @@ +(function( $, undefined ) { + + $.effects.effect.shake = function( o, done ) { + + var el = $( this ), + props = [ "position", "top", "bottom", "left", "right", "height", "width" ], + mode = $.effects.setMode( el, o.mode || "effect" ), + direction = o.direction || "left", + distance = o.distance || 20, + times = o.times || 3, + anims = times * 2 + 1, + speed = Math.round(o.duration/anims), + ref = (direction === "up" || direction === "down") ? "top" : "left", + positiveMotion = (direction === "up" || direction === "left"), + animation = {}, + animation1 = {}, + animation2 = {}, + i, + + // we will need to re-assemble the queue to stack our animations in place + queue = el.queue(), + queuelen = queue.length; + + $.effects.save( el, props ); + el.show(); + $.effects.createWrapper( el ); + + // Animation + animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance; + animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2; + animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2; + + // Animate + el.animate( animation, speed, o.easing ); + + // Shakes + for ( i = 1; i < times; i++ ) { + el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing ); + } + el + .animate( animation1, speed, o.easing ) + .animate( animation, speed / 2, o.easing ) + .queue(function() { + if ( mode === "hide" ) { + el.hide(); + } + $.effects.restore( el, props ); + $.effects.removeWrapper( el ); + done(); + }); + + // inject all the animations we just queued to be first in line (after "inprogress") + if ( queuelen > 1) { + queue.splice.apply( queue, + [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); + } + el.dequeue(); + + }; + +})(jQuery); diff --git a/lib/web/jquery/ui-modules/effect-slide.js b/lib/web/jquery/ui-modules/effect-slide.js new file mode 100644 index 000000000000..582e9bc0728e --- /dev/null +++ b/lib/web/jquery/ui-modules/effect-slide.js @@ -0,0 +1,51 @@ +(function( $, undefined ) { + + $.effects.effect.slide = function( o, done ) { + + // Create element + var el = $( this ), + props = [ "position", "top", "bottom", "left", "right", "width", "height" ], + mode = $.effects.setMode( el, o.mode || "show" ), + show = mode === "show", + direction = o.direction || "left", + ref = (direction === "up" || direction === "down") ? "top" : "left", + positiveMotion = (direction === "up" || direction === "left"), + distance, + animation = {}; + + // Adjust + $.effects.save( el, props ); + el.show(); + distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ); + + $.effects.createWrapper( el ).css({ + overflow: "hidden" + }); + + if ( show ) { + el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance ); + } + + // Animation + animation[ ref ] = ( show ? + ( positiveMotion ? "+=" : "-=") : + ( positiveMotion ? "-=" : "+=")) + + distance; + + // Animate + el.animate( animation, { + queue: false, + duration: o.duration, + easing: o.easing, + complete: function() { + if ( mode === "hide" ) { + el.hide(); + } + $.effects.restore( el, props ); + $.effects.removeWrapper( el ); + done(); + } + }); + }; + +})(jQuery); diff --git a/lib/web/jquery/ui-modules/effect-transfer.js b/lib/web/jquery/ui-modules/effect-transfer.js new file mode 100644 index 000000000000..f87cfb65ebbc --- /dev/null +++ b/lib/web/jquery/ui-modules/effect-transfer.js @@ -0,0 +1,34 @@ +(function( $, undefined ) { + + $.effects.effect.transfer = function( o, done ) { + var elem = $( this ), + target = $( o.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 = elem.offset(), + transfer = $( "<div class='ui-effects-transfer'></div>" ) + .appendTo( document.body ) + .addClass( o.className ) + .css({ + top: startPosition.top - fixTop , + left: startPosition.left - fixLeft , + height: elem.innerHeight(), + width: elem.innerWidth(), + position: targetFixed ? "fixed" : "absolute" + }) + .animate( animation, o.duration, o.easing, function() { + transfer.remove(); + done(); + }); + }; + +})(jQuery); diff --git a/lib/web/jquery/ui-modules/effect.js b/lib/web/jquery/ui-modules/effect.js new file mode 100644 index 000000000000..54cbcde54d10 --- /dev/null +++ b/lib/web/jquery/ui-modules/effect.js @@ -0,0 +1,1279 @@ +(function($, undefined) { + + var dataSpace = "ui-effects-"; + + $.effects = { + effect: {} + }; + + /*! + * jQuery Color Animations v2.1.2 + * https://github.com/jquery/jquery-color + * + * Copyright 2013 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * Date: Wed Jan 16 08:47:09 2013 -0600 + */ + (function( jQuery, undefined ) { + + var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor", + + // plusequals test for += 100 -= 100 + rplusequals = /^([\-+])=\s*(\d+\.?\d*)/, + // 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 ] + ]; + } + }, { + // 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})/, + parse: function( execResult ) { + return [ + parseInt( execResult[ 1 ], 16 ), + parseInt( execResult[ 2 ], 16 ), + parseInt( execResult[ 3 ], 16 ) + ]; + } + }, { + // this regex ignores A-F because it's compared against an already lowercased string + re: /#([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 ) + ]; + } + }, { + 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 ] + ]; + } + }], + + // 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" + } + } + }, + + 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 = {}, + + // element for support tests + supportElem = jQuery( "<p>" )[ 0 ], + + // colors = jQuery.Color.names + colors, + + // local aliases of functions called often + each = jQuery.each; + +// 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 + }; + }); + + function clamp( value, prop, allowEmpty ) { + var type = propTypes[ prop.type ] || {}; + + if ( value == null ) { + return (allowEmpty || !prop.def) ? null : prop.def; + } + + // ~~ is an short way of doing floor for positive numbers + value = type.floor ? ~~value : parseFloat( value ); + + // IE will pass in empty strings as value for alpha, + // which will hit this case + if ( isNaN( value ) ) { + return prop.def; + } + + 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; + } + + // for now all property types without mod have min and max + return 0 > value ? 0 : type.max < value ? type.max : value; + } + + function stringParse( string ) { + var inst = color(), + rgba = inst._rgba = []; + + string = string.toLowerCase(); + + each( stringParsers, function( i, parser ) { + var parsed, + match = parser.re.exec( string ), + values = match && parser.parse( match ), + spaceName = parser.space || "rgba"; + + if ( values ) { + parsed = inst[ spaceName ]( values ); + + // 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; + + // exit each( stringParsers ) here because we matched + return false; + } + }); + + // Found a stringParser that handled it + if ( rgba.length ) { + + // 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; + } + + // 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 inst = this, + type = jQuery.type( red ), + rgba = this._rgba = []; + + // more than 1 argument specified - assume ( red, green, blue, alpha ) + if ( green !== undefined ) { + red = [ red, green, blue, alpha ]; + type = "array"; + } + + if ( type === "string" ) { + return this.parse( stringParse( red ) || colors._default ); + } + + 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 ) { + + // if the cache doesn't exist, and we know how to convert + if ( !inst[ cache ] && space.to ) { + + // 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 ); + } + + // 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 ); + }); + + // everything defined but alpha? + if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) { + // use the default of 1 + inst[ cache ][ 3 ] = 1; + if ( space.from ) { + inst._rgba = space.from( inst[ cache ] ); + } + } + }); + } + return this; + } + }, + 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 ] || {}; + + // if null, don't override start value + if ( endValue === null ) { + return; + } + // 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 ) { + // if we are already opaque - return ourself + if ( this._rgba[ 3 ] === 1 ) { + return this; + } + + 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 ) { + return v == null ? ( i > 2 ? 1 : 0 ) : v; + }); + + if ( rgba[ 3 ] === 1 ) { + rgba.pop(); + prefix = "rgb("; + } + + 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; + }); + + if ( hsla[ 3 ] === 1 ) { + hsla.pop(); + prefix = "hsl("; + } + return prefix + hsla.join() + ")"; + }, + toHexString: function( includeAlpha ) { + var rgba = this._rgba.slice(), + alpha = rgba.pop(); + + if ( includeAlpha ) { + rgba.push( ~~( alpha * 255 ) ); + } + + 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(""); + }, + 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 + + 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; + } + + 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; + } + + // 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 ]; + }; + + 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 [ + 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 + ]; + }; + + + each( spaces, function( spaceName, space ) { + var props = space.props, + cache = space.cache, + to = space.to, + from = space.from; + + // makes rgba() and hsla() + color.fn[ spaceName ] = function( value ) { + + // 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(); + } + + var ret, + type = jQuery.type( value ), + arr = ( type === "array" || type === "object" ) ? value : arguments, + local = this[ cache ].slice(); + + 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 ); + } + }; + + // 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 vtype = jQuery.type( value ), + fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ), + local = this[ fn ](), + cur = local[ prop.idx ], + match; + + if ( vtype === "undefined" ) { + return cur; + } + + if ( vtype === "function" ) { + value = value.call( this, cur ); + vtype = jQuery.type( 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 ); + }; + }); + }); + +// 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 ( value !== "transparent" && ( jQuery.type( 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" ); + } + + value = value.toRgbaString(); + } + try { + elem.style[ hook ] = value; + } catch( e ) { + // 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 ) ); + }; + }); + + }; + + color.hook( stepHooks ); + + jQuery.cssHooks.borderColor = { + expand: function( value ) { + var expanded = {}; + + each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) { + expanded[ "border" + part + "Color" ] = value; + }); + return expanded; + } + }; + +// 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", + + // 4.2.3. "transparent" color keyword + transparent: [ null, null, null, 0 ], + + _default: "#ffffff" + }; + + })( jQuery ); + + + /******************************************************************************/ + /****************************** 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 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() { + + $.extend( $.effects, { + version: "1.10.4", + + // Saves a set of properties in a data storage + save: function( element, set ) { + for( var i=0; i < set.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; + for( i=0; i < set.length; i++ ) { + if ( set[ i ] !== null ) { + val = element.data( dataSpace + set[ i ] ); + // support: jQuery 1.6.2 + // http://bugs.jquery.com/ticket/9917 + // jQuery 1.6.2 incorrectly returns undefined for any falsy value. + // We can't differentiate between "" and 0 here, so we just assume + // empty string since it's likely to be a more common value... + if ( val === undefined ) { + val = ""; + } + element.css( set[ i ], val ); + } + } + }, + + setMode: function( el, mode ) { + if (mode === "toggle") { + mode = el.is( ":hidden" ) ? "show" : "hide"; + } + return mode; + }, + + // Translates a [top,left] array into a baseline value + // this should be a little more flexible in the future to handle a string & hash + 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 + }; + }, + + // 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 { + 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 ).focus(); + } + + wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element + + // 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 ).focus(); + } + } + + + return 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 ( $.isFunction( options ) ) { + 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 ( $.isFunction( speed ) ) { + 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 ( $.isFunction( option ) ) { + 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 ), + mode = args.mode, + queue = args.queue, + effectMethod = $.effects.effect[ args.effect ]; + + if ( $.fx.off || !effectMethod ) { + // delegate to the original method (e.g., .show()) if possible + if ( mode ) { + return this[ mode ]( args.duration, args.complete ); + } else { + return this.each( function() { + if ( args.complete ) { + args.complete.call( this ); + } + }); + } + } + + function run( next ) { + var elem = $( this ), + complete = args.complete, + mode = args.mode; + + function done() { + if ( $.isFunction( complete ) ) { + complete.call( elem[0] ); + } + if ( $.isFunction( next ) ) { + next(); + } + } + + // If the element already has the correct final state, delegate to + // the core methods so the internal tracking of "olddisplay" works. + if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { + elem[ mode ](); + done(); + } else { + effectMethod.call( elem[0], args, done ); + } + } + + return queue === false ? this.each( run ) : this.queue( queue || "fx", 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 ), + + // helper functions + 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; + } + }); + + })(); + + /******************************************************************************/ + /*********************************** 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; + }; + }); + + })(); + +})(jQuery); diff --git a/lib/web/jquery/ui-modules/menu.js b/lib/web/jquery/ui-modules/menu.js new file mode 100644 index 000000000000..08248dd3dd44 --- /dev/null +++ b/lib/web/jquery/ui-modules/menu.js @@ -0,0 +1,612 @@ +(function( $, undefined ) { + + $.widget( "ui.menu", { + version: "1.10.4", + defaultElement: "<ul>", + delay: 300, + options: { + icons: { + submenu: "ui-icon-carat-1-e" + }, + 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.element + .uniqueId() + .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) + .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length ) + .attr({ + role: this.options.role, + tabIndex: 0 + }) + // need to catch all clicks on disabled menu + // not possible through _on + .bind( "click" + this.eventNamespace, $.proxy(function( event ) { + if ( this.options.disabled ) { + event.preventDefault(); + } + }, this )); + + if ( this.options.disabled ) { + this.element + .addClass( "ui-state-disabled" ) + .attr( "aria-disabled", "true" ); + } + + 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 > a": function( event ) { + event.preventDefault(); + }, + "click .ui-state-disabled > a": function( event ) { + event.preventDefault(); + }, + "click .ui-menu-item:has(a)": function( event ) { + var target = $( event.target ).closest( ".ui-menu-item" ); + 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" ) && $( this.document[ 0 ].activeElement ).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": function( event ) { + var target = $( event.currentTarget ); + // 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 + target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" ); + this.focus( event, target ); + }, + 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.element.children( ".ui-menu-item" ).eq( 0 ); + + if ( !keepActiveItem ) { + this.focus( event, item ); + } + }, + blur: function( event ) { + this._delay(function() { + if ( !$.contains( this.element[0], this.document[0].activeElement ) ) { + this.collapseAll( event ); + } + }); + }, + keydown: "_keydown" + }); + + this.refresh(); + + // Clicks outside of a menu collapse any open menus + this._on( this.document, { + click: function( event ) { + if ( !$( event.target ).closest( ".ui-menu" ).length ) { + this.collapseAll( event ); + } + + // Reset the mouseHandled flag + this.mouseHandled = false; + } + }); + }, + + _destroy: function() { + // Destroy (sub)menus + this.element + .removeAttr( "aria-activedescendant" ) + .find( ".ui-menu" ).addBack() + .removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" ) + .removeAttr( "role" ) + .removeAttr( "tabIndex" ) + .removeAttr( "aria-labelledby" ) + .removeAttr( "aria-expanded" ) + .removeAttr( "aria-hidden" ) + .removeAttr( "aria-disabled" ) + .removeUniqueId() + .show(); + + // Destroy menu items + this.element.find( ".ui-menu-item" ) + .removeClass( "ui-menu-item" ) + .removeAttr( "role" ) + .removeAttr( "aria-disabled" ) + .children( "a" ) + .removeUniqueId() + .removeClass( "ui-corner-all ui-state-hover" ) + .removeAttr( "tabIndex" ) + .removeAttr( "role" ) + .removeAttr( "aria-haspopup" ) + .children().each( function() { + var elem = $( this ); + if ( elem.data( "ui-menu-submenu-carat" ) ) { + elem.remove(); + } + }); + + // Destroy menu dividers + this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" ); + }, + + _keydown: function( event ) { + var match, prev, character, skip, regex, + preventDefault = true; + + function escape( value ) { + return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ); + } + + 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 || ""; + character = String.fromCharCode( event.keyCode ); + skip = false; + + clearTimeout( this.filterTimer ); + + if ( character === prev ) { + skip = true; + } else { + character = prev + character; + } + + regex = new RegExp( "^" + escape( character ), "i" ); + match = this.activeMenu.children( ".ui-menu-item" ).filter(function() { + return regex.test( $( this ).children( "a" ).text() ); + }); + 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 ); + regex = new RegExp( "^" + escape( character ), "i" ); + match = this.activeMenu.children( ".ui-menu-item" ).filter(function() { + return regex.test( $( this ).children( "a" ).text() ); + }); + } + + if ( match.length ) { + this.focus( event, match ); + if ( match.length > 1 ) { + this.previousFilter = character; + this.filterTimer = this._delay(function() { + delete this.previousFilter; + }, 1000 ); + } else { + delete this.previousFilter; + } + } else { + delete this.previousFilter; + } + } + + if ( preventDefault ) { + event.preventDefault(); + } + }, + + _activate: function( event ) { + if ( !this.active.is( ".ui-state-disabled" ) ) { + if ( this.active.children( "a[aria-haspopup='true']" ).length ) { + this.expand( event ); + } else { + this.select( event ); + } + } + }, + + refresh: function() { + var menus, + icon = this.options.icons.submenu, + submenus = this.element.find( this.options.menus ); + + this.element.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length ); + + // Initialize nested menus + submenus.filter( ":not(.ui-menu)" ) + .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) + .hide() + .attr({ + role: this.options.role, + "aria-hidden": "true", + "aria-expanded": "false" + }) + .each(function() { + var menu = $( this ), + item = menu.prev( "a" ), + submenuCarat = $( "<span>" ) + .addClass( "ui-menu-icon ui-icon " + icon ) + .data( "ui-menu-submenu-carat", true ); + + item + .attr( "aria-haspopup", "true" ) + .prepend( submenuCarat ); + menu.attr( "aria-labelledby", item.attr( "id" ) ); + }); + + menus = submenus.add( this.element ); + + // Don't refresh list items that are already adapted + menus.children( ":not(.ui-menu-item):has(a)" ) + .addClass( "ui-menu-item" ) + .attr( "role", "presentation" ) + .children( "a" ) + .uniqueId() + .addClass( "ui-corner-all" ) + .attr({ + tabIndex: -1, + role: this._itemRole() + }); + + // Initialize unlinked menu-items containing spaces and/or dashes only as dividers + menus.children( ":not(.ui-menu-item)" ).each(function() { + var item = $( this ); + // hyphen, em dash, en dash + if ( !/[^\-\u2014\u2013\s]/.test( item.text() ) ) { + item.addClass( "ui-widget-content ui-menu-divider" ); + } + }); + + // Add aria-disabled attribute to any disabled menu item + menus.children( ".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" ) { + this.element.find( ".ui-menu-icon" ) + .removeClass( this.options.icons.submenu ) + .addClass( value.submenu ); + } + this._super( key, value ); + }, + + focus: function( event, item ) { + var nested, focused; + this.blur( event, event && event.type === "focus" ); + + this._scrollIntoView( item ); + + this.active = item.first(); + focused = this.active.children( "a" ).addClass( "ui-state-focus" ); + // 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 + this.active + .parent() + .closest( ".ui-menu-item" ) + .children( "a:first" ) + .addClass( "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.height(); + + 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.active.children( "a" ).removeClass( "ui-state-focus" ); + this.active = null; + + this._trigger( "blur", event, { item: this.active } ); + }, + + _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 carat 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 ); + this.activeMenu = currentMenu; + }, 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" ) + .end() + .find( "a.ui-state-active" ) + .removeClass( "ui-state-active" ); + }, + + 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.active + .children( ".ui-menu " ) + .children( ".ui-menu-item" ) + .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; + }, + + _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" ) + .eq( -1 ); + } else { + next = this.active + [ direction + "All" ]( ".ui-menu-item" ) + .eq( 0 ); + } + } + if ( !next || !next.length || !this.active ) { + next = this.activeMenu.children( ".ui-menu-item" )[ 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.height(); + 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.activeMenu.children( ".ui-menu-item" ) + [ !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.height(); + 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.activeMenu.children( ".ui-menu-item" ).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 ); + } + }); + +}( jQuery )); diff --git a/lib/web/jquery/ui-modules/mouse.js b/lib/web/jquery/ui-modules/mouse.js new file mode 100644 index 000000000000..9e41e60a783c --- /dev/null +++ b/lib/web/jquery/ui-modules/mouse.js @@ -0,0 +1,156 @@ +(function( $, undefined ) { + + var mouseHandled = false; + $( document ).mouseup( function() { + mouseHandled = false; + }); + + $.widget("ui.mouse", { + version: "1.10.4", + options: { + cancel: "input,textarea,button,select,option", + distance: 1, + delay: 0 + }, + _mouseInit: function() { + var that = this; + + this.element + .bind("mousedown."+this.widgetName, function(event) { + return that._mouseDown(event); + }) + .bind("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.unbind("."+this.widgetName); + if ( this._mouseMoveDelegate ) { + $(document) + .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate) + .unbind("mouseup."+this.widgetName, this._mouseUpDelegate); + } + }, + + _mouseDown: function(event) { + // don't let more than one widget handle mouseStart + if( mouseHandled ) { return; } + + // we may have missed mouseup (out of window) + (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); + }; + $(document) + .bind("mousemove."+this.widgetName, this._mouseMoveDelegate) + .bind("mouseup."+this.widgetName, this._mouseUpDelegate); + + event.preventDefault(); + + mouseHandled = true; + return true; + }, + + _mouseMove: function(event) { + // 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); + } + + if (this._mouseStarted) { + this._mouseDrag(event); + return event.preventDefault(); + } + + if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { + this._mouseStarted = + (this._mouseStart(this._mouseDownEvent, event) !== false); + (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event)); + } + + return !this._mouseStarted; + }, + + _mouseUp: function(event) { + $(document) + .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate) + .unbind("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); + } + + return false; + }, + + _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 overridden by extending plugin + _mouseStart: function(/* event */) {}, + _mouseDrag: function(/* event */) {}, + _mouseStop: function(/* event */) {}, + _mouseCapture: function(/* event */) { return true; } + }); + +})(jQuery); \ No newline at end of file diff --git a/lib/web/jquery/ui-modules/position.js b/lib/web/jquery/ui-modules/position.js new file mode 100644 index 000000000000..730acba51efd --- /dev/null +++ b/lib/web/jquery/ui-modules/position.js @@ -0,0 +1,491 @@ +(function( $, undefined ) { + + $.ui = $.ui || {}; + + var cachedScrollbarWidth, + max = Math.max, + abs = Math.abs, + round = Math.round, + 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 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:50px;height:50px;overflow:hidden;'><div style='height:100px;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 ), + isWindow = $.isWindow( withinElement[0] ), + isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9; + return { + element: withinElement, + isWindow: isWindow, + isDocument: isDocument, + offset: withinElement.offset() || { left: 0, top: 0 }, + scrollLeft: withinElement.scrollLeft(), + scrollTop: withinElement.scrollTop(), + width: isWindow ? withinElement.width() : withinElement.outerWidth(), + height: isWindow ? withinElement.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, + target = $( 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 ]; + + // if the browser doesn't support fractions, then round for consistent results + if ( !$.support.offsetFractions ) { + position.left = round( position.left ); + position.top = round( position.top ); + } + + 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 ( ( position.top + myOffset + atOffset + offset) > overTop && ( 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 ( ( position.top + myOffset + atOffset + offset) > overBottom && ( 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 ); + } + } + }; + +// fraction support test + (function () { + var testElement, testElementParent, testElementStyle, offsetLeft, i, + body = document.getElementsByTagName( "body" )[ 0 ], + div = document.createElement( "div" ); + + //Create a "fake body" for testing based on method used in jQuery.support + testElement = document.createElement( body ? "div" : "body" ); + testElementStyle = { + visibility: "hidden", + width: 0, + height: 0, + border: 0, + margin: 0, + background: "none" + }; + if ( body ) { + $.extend( testElementStyle, { + position: "absolute", + left: "-1000px", + top: "-1000px" + }); + } + for ( i in testElementStyle ) { + testElement.style[ i ] = testElementStyle[ i ]; + } + testElement.appendChild( div ); + testElementParent = body || document.documentElement; + testElementParent.insertBefore( testElement, testElementParent.firstChild ); + + div.style.cssText = "position: absolute; left: 10.7432222px;"; + + offsetLeft = $( div ).offset().left; + $.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11; + + testElement.innerHTML = ""; + testElementParent.removeChild( testElement ); + })(); + +}( jQuery ) ); diff --git a/lib/web/jquery/ui-modules/progressbar.js b/lib/web/jquery/ui-modules/progressbar.js new file mode 100644 index 000000000000..692de2dc3e93 --- /dev/null +++ b/lib/web/jquery/ui-modules/progressbar.js @@ -0,0 +1,131 @@ +(function( $, undefined ) { + + $.widget( "ui.progressbar", { + version: "1.10.4", + options: { + max: 100, + value: 0, + + change: null, + complete: null + }, + + min: 0, + + _create: function() { + // Constrain initial value + this.oldValue = this.options.value = this._constrainedValue(); + + this.element + .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) + .attr({ + // Only set static values, aria-valuenow and aria-valuemax are + // set inside _refreshValue() + role: "progressbar", + "aria-valuemin": this.min + }); + + this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" ) + .appendTo( this.element ); + + this._refreshValue(); + }, + + _destroy: function() { + this.element + .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) + .removeAttr( "role" ) + .removeAttr( "aria-valuemin" ) + .removeAttr( "aria-valuemax" ) + .removeAttr( "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 ); + }, + + _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 ) + .toggleClass( "ui-corner-right", value === this.options.max ) + .width( percentage.toFixed(0) + "%" ); + + this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate ); + + if ( this.indeterminate ) { + this.element.removeAttr( "aria-valuenow" ); + if ( !this.overlayDiv ) { + this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv ); + } + } 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" ); + } + } + }); + +})( jQuery ); diff --git a/lib/web/jquery/ui-modules/resizable.js b/lib/web/jquery/ui-modules/resizable.js new file mode 100644 index 000000000000..448df0c3d895 --- /dev/null +++ b/lib/web/jquery/ui-modules/resizable.js @@ -0,0 +1,963 @@ +(function( $, undefined ) { + + function num(v) { + return parseInt(v, 10) || 0; + } + + function isNumber(value) { + return !isNaN(parseInt(value, 10)); + } + + $.widget("ui.resizable", $.ui.mouse, { + version: "1.10.4", + widgetEventPrefix: "resize", + options: { + alsoResize: false, + animate: false, + animateDuration: "slow", + animateEasing: "swing", + aspectRatio: false, + autoHide: false, + 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 + }, + _create: function() { + + var n, i, handle, axis, hname, + that = this, + o = this.options; + this.element.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)) { + + //Create a wrapper element and set the wrapper to the new current internal element + this.element.wrap( + $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({ + position: this.element.css("position"), + width: this.element.outerWidth(), + height: this.element.outerHeight(), + top: this.element.css("top"), + left: this.element.css("left") + }) + ); + + //Overwrite the original this.element + this.element = this.element.parent().data( + "ui-resizable", this.element.data("ui-resizable") + ); + + this.elementIsWrapper = true; + + //Move margins to the wrapper + this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") }); + this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0}); + + //Prevent Safari textarea resize + this.originalResizeStyle = this.originalElement.css("resize"); + this.originalElement.css("resize", "none"); + + //Push the actual element to our proportionallyResize internal array + this._proportionallyResizeElements.push(this.originalElement.css({ position: "static", zoom: 1, display: "block" })); + + // avoid IE jump (hard set the margin) + this.originalElement.css({ margin: this.originalElement.css("margin") }); + + // fix handlers offset + this._proportionallyResize(); + + } + + 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" }); + 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 = $.trim(n[i]); + hname = "ui-resizable-"+handle; + axis = $("<div class='ui-resizable-handle " + hname + "'></div>"); + + // Apply zIndex to all handles - see #7960 + axis.css({ zIndex: o.zIndex }); + + //TODO : What's going on here? + if ("se" === handle) { + axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se"); + } + + //Insert into internal handles object and append to element + this.handles[handle] = ".ui-resizable-"+handle; + this.element.append(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.handles[i], this.element).show(); + } + + //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls) + if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) { + + axis = $(this.handles[i], this.element); + + //Checking the correct pad and border + padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth(); + + //The padding type i have to apply... + 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(); + + } + + //TODO: What's that good for? There's not anything to be executed left + if(!$(this.handles[i]).length) { + continue; + } + } + }; + + //TODO: make renderAxis a prototype function + this._renderAxis(this.element); + + this._handles = $(".ui-resizable-handle", this.element) + .disableSelection(); + + //Matching axis name + this._handles.mouseover(function() { + if (!that.resizing) { + if (this.className) { + axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i); + } + //Axis, default = se + that.axis = axis && axis[1] ? axis[1] : "se"; + } + }); + + //If we want to auto hide the elements + if (o.autoHide) { + this._handles.hide(); + $(this.element) + .addClass("ui-resizable-autohide") + .mouseenter(function() { + if (o.disabled) { + return; + } + $(this).removeClass("ui-resizable-autohide"); + that._handles.show(); + }) + .mouseleave(function(){ + if (o.disabled) { + return; + } + if (!that.resizing) { + $(this).addClass("ui-resizable-autohide"); + that._handles.hide(); + } + }); + } + + //Initialize the mouse interaction + this._mouseInit(); + + }, + + _destroy: function() { + + this._mouseDestroy(); + + var wrapper, + _destroy = function(exp) { + $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing") + .removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove(); + }; + + //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; + }, + + _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; + } + } + + return !this.options.disabled && capture; + }, + + _mouseStart: function(event) { + + var curleft, curtop, cursor, + o = this.options, + iniPos = this.element.position(), + el = this.element; + + this.resizing = true; + + // bugfix for http://dev.jquery.com/ticket/1749 + if ( (/absolute/).test( el.css("position") ) ) { + el.css({ position: "absolute", top: el.css("top"), left: el.css("left") }); + } else if (el.is(".ui-draggable")) { + el.css({ position: "absolute", top: iniPos.top, left: iniPos.left }); + } + + this._renderProxy(); + + curleft = num(this.helper.css("left")); + curtop = num(this.helper.css("top")); + + if (o.containment) { + curleft += $(o.containment).scrollLeft() || 0; + curtop += $(o.containment).scrollTop() || 0; + } + + //Store needed variables + 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.originalPosition = { left: curleft, top: curtop }; + this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() }; + this.originalMousePosition = { left: event.pageX, top: event.pageY }; + + //Aspect Ratio + 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); + + el.addClass("ui-resizable-resizing"); + this._propagate("start", event); + return true; + }, + + _mouseDrag: function(event) { + + //Increase performance, avoid regex + var data, + el = this.helper, props = {}, + smp = this.originalMousePosition, + a = this.axis, + prevTop = this.position.top, + prevLeft = this.position.left, + prevWidth = this.size.width, + prevHeight = this.size.height, + dx = (event.pageX-smp.left)||0, + dy = (event.pageY-smp.top)||0, + trigger = this._change[a]; + + if (!trigger) { + return false; + } + + // Calculate the attrs that will be change + data = trigger.apply(this, [event, dx, dy]); + + // Put this in the mouseDrag handler since the user can start pressing shift while resizing + this._updateVirtualBoundaries(event.shiftKey); + if (this._aspectRatio || event.shiftKey) { + data = this._updateRatio(data, event); + } + + data = this._respectSize(data, event); + + this._updateCache(data); + + // plugins callbacks need to be called first + this._propagate("resize", event); + + if (this.position.top !== prevTop) { + props.top = this.position.top + "px"; + } + if (this.position.left !== prevLeft) { + props.left = this.position.left + "px"; + } + if (this.size.width !== prevWidth) { + props.width = this.size.width + "px"; + } + if (this.size.height !== prevHeight) { + props.height = this.size.height + "px"; + } + el.css(props); + + if (!this._helper && this._proportionallyResizeElements.length) { + this._proportionallyResize(); + } + + // Call the user callback if the element was resized + if ( ! $.isEmptyObject(props) ) { + this._trigger("resize", event, this.ui()); + } + + 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 && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height; + soffsetw = ista ? 0 : that.sizeDiff.width; + + s = { width: (that.helper.width() - soffsetw), height: (that.helper.height() - soffseth) }; + left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null; + top = (parseInt(that.element.css("top"), 10) + (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.element.removeClass("ui-resizable-resizing"); + + this._propagate("stop", event); + + if (this._helper) { + this.helper.remove(); + } + + return false; + + }, + + _updateVirtualBoundaries: function(forceAspectRatio) { + var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b, + o = this.options; + + b = { + minWidth: isNumber(o.minWidth) ? o.minWidth : 0, + maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity, + minHeight: isNumber(o.minHeight) ? o.minHeight : 0, + maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity + }; + + if(this._aspectRatio || forceAspectRatio) { + // We want to create an enclosing box whose aspect ration is the requested one + // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension + 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 (isNumber(data.left)) { + this.position.left = data.left; + } + if (isNumber(data.top)) { + this.position.top = data.top; + } + if (isNumber(data.height)) { + this.size.height = data.height; + } + if (isNumber(data.width)) { + this.size.width = data.width; + } + }, + + _updateRatio: function( data ) { + + var cpos = this.position, + csize = this.size, + a = this.axis; + + if (isNumber(data.height)) { + data.width = (data.height * this.aspectRatio); + } else if (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 = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height), + isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height), + dw = this.originalPosition.left + this.originalSize.width, + dh = this.position.top + this.size.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; + }, + + _proportionallyResize: function() { + + if (!this._proportionallyResizeElements.length) { + return; + } + + var i, j, borders, paddings, prel, + element = this.helper || this.element; + + for ( i=0; i < this._proportionallyResizeElements.length; i++) { + + prel = this._proportionallyResizeElements[i]; + + if (!this.borderDif) { + this.borderDif = []; + borders = [prel.css("borderTopWidth"), prel.css("borderRightWidth"), prel.css("borderBottomWidth"), prel.css("borderLeftWidth")]; + paddings = [prel.css("paddingTop"), prel.css("paddingRight"), prel.css("paddingBottom"), prel.css("paddingLeft")]; + + for ( j = 0; j < borders.length; j++ ) { + this.borderDif[ j ] = ( parseInt( borders[ j ], 10 ) || 0 ) + ( parseInt( paddings[ j ], 10 ) || 0 ); + } + } + + prel.css({ + height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0, + width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0 + }); + + } + + }, + + _renderProxy: function() { + + var el = this.element, o = this.options; + this.elementOffset = el.offset(); + + if(this._helper) { + + this.helper = this.helper || $("<div style='overflow:hidden;'></div>"); + + this.helper.addClass(this._helper).css({ + width: this.element.outerWidth() - 1, + height: this.element.outerHeight() - 1, + 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()]); + (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).data("ui-resizable"), + o = that.options, + pr = that._proportionallyResizeElements, + ista = pr.length && (/textarea/i).test(pr[0].nodeName), + soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height, + soffsetw = ista ? 0 : that.sizeDiff.width, + style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) }, + left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null, + top = (parseInt(that.element.css("top"), 10) + (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: parseInt(that.element.css("width"), 10), + height: parseInt(that.element.css("height"), 10), + top: parseInt(that.element.css("top"), 10), + left: parseInt(that.element.css("left"), 10) + }; + + 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).data("ui-resizable"), + 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 + }; + } + + // i'm a node, so compute top, left, right, bottom + else { + element = $(ce); + p = []; + $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = 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 = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ); + height = ($.ui.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).data("ui-resizable"), + o = that.options, + co = that.containerOffset, cp = that.position, + pRatio = that._aspectRatio || event.shiftKey, + cop = { top:0, left:0 }, ce = that.containerElement; + + 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; + } + 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; + } + that.position.top = that._helper ? co.top : 0; + } + + that.offset.left = that.parentData.left+that.position.left; + that.offset.top = that.parentData.top+that.position.top; + + woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width ); + hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height ); + + isParent = that.containerElement.get(0) === that.element.parent().get(0); + isOffsetRelative = /relative|absolute/.test(that.containerElement.css("position")); + + if ( isParent && isOffsetRelative ) { + woset -= Math.abs( that.parentData.left ); + } + + 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; + } + } + + 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; + } + } + }, + + stop: function(){ + var that = $(this).data("ui-resizable"), + 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).data("ui-resizable"), + o = that.options, + _store = function (exp) { + $(exp).each(function() { + var el = $(this); + el.data("ui-resizable-alsoresize", { + width: parseInt(el.width(), 10), height: parseInt(el.height(), 10), + left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10) + }); + }); + }; + + if (typeof(o.alsoResize) === "object" && !o.alsoResize.parentNode) { + if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); } + else { $.each(o.alsoResize, function (exp) { _store(exp); }); } + }else{ + _store(o.alsoResize); + } + }, + + resize: function (event, ui) { + var that = $(this).data("ui-resizable"), + 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 + }, + + _alsoResize = function (exp, c) { + $(exp).each(function() { + var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {}, + css = c && c.length ? c : 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); + }); + }; + + if (typeof(o.alsoResize) === "object" && !o.alsoResize.nodeType) { + $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); }); + }else{ + _alsoResize(o.alsoResize); + } + }, + + stop: function () { + $(this).removeData("resizable-alsoresize"); + } + }); + + $.ui.plugin.add("resizable", "ghost", { + + start: function() { + + var that = $(this).data("ui-resizable"), o = that.options, 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 }) + .addClass("ui-resizable-ghost") + .addClass(typeof o.ghost === "string" ? o.ghost : ""); + + that.ghost.appendTo(that.helper); + + }, + + resize: function(){ + var that = $(this).data("ui-resizable"); + if (that.ghost) { + that.ghost.css({ position: "relative", height: that.size.height, width: that.size.width }); + } + }, + + stop: function() { + var that = $(this).data("ui-resizable"); + if (that.ghost && that.helper) { + that.helper.get(0).removeChild(that.ghost.get(0)); + } + } + + }); + + $.ui.plugin.add("resizable", "grid", { + + resize: function() { + var that = $(this).data("ui-resizable"), + 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 = newWidth + gridX; + } + if (isMinHeight) { + newHeight = newHeight + gridY; + } + if (isMaxWidth) { + newWidth = newWidth - gridX; + } + if (isMaxHeight) { + newHeight = 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 ) { + that.size.height = newHeight; + that.position.top = op.top - oy; + } else { + that.size.height = gridY; + that.position.top = op.top + os.height - gridY; + } + if ( newWidth - gridX > 0 ) { + that.size.width = newWidth; + that.position.left = op.left - ox; + } else { + that.size.width = gridX; + that.position.left = op.left + os.width - gridX; + } + } + } + + }); + +})(jQuery); diff --git a/lib/web/jquery/ui-modules/selectable.js b/lib/web/jquery/ui-modules/selectable.js new file mode 100644 index 000000000000..3cf94e5bfae8 --- /dev/null +++ b/lib/web/jquery/ui-modules/selectable.js @@ -0,0 +1,262 @@ +(function( $, undefined ) { + + $.widget("ui.selectable", $.ui.mouse, { + version: "1.10.4", + 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 selectees, + that = this; + + this.element.addClass("ui-selectable"); + + this.dragged = false; + + // cache selectee children based on filter + this.refresh = function() { + selectees = $(that.options.filter, that.element[0]); + selectees.addClass("ui-selectee"); + selectees.each(function() { + var $this = $(this), + pos = $this.offset(); + $.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.selectees = selectees.addClass("ui-selectee"); + + this._mouseInit(); + + this.helper = $("<div class='ui-selectable-helper'></div>"); + }, + + _destroy: function() { + this.selectees + .removeClass("ui-selectee") + .removeData("selectable-item"); + this.element + .removeClass("ui-selectable ui-selectable-disabled"); + this._mouseDestroy(); + }, + + _mouseStart: function(event) { + var that = this, + options = this.options; + + this.opos = [event.pageX, event.pageY]; + + 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) { + selectee.$element.removeClass("ui-selected"); + selectee.selected = false; + selectee.$element.addClass("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"); + selectee.$element + .removeClass(doSelect ? "ui-unselecting" : "ui-selected") + .addClass(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; + + //prevent helper from being selected if appendTo: selectable + if (!selectee || selectee.element === that.element[0]) { + return; + } + + if (options.tolerance === "touch") { + hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) ); + } else if (options.tolerance === "fit") { + hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2); + } + + if (hit) { + // SELECT + if (selectee.selected) { + selectee.$element.removeClass("ui-selected"); + selectee.selected = false; + } + if (selectee.unselecting) { + selectee.$element.removeClass("ui-unselecting"); + selectee.unselecting = false; + } + if (!selectee.selecting) { + selectee.$element.addClass("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) { + selectee.$element.removeClass("ui-selecting"); + selectee.selecting = false; + selectee.$element.addClass("ui-selected"); + selectee.selected = true; + } else { + selectee.$element.removeClass("ui-selecting"); + selectee.selecting = false; + if (selectee.startselected) { + selectee.$element.addClass("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) { + selectee.$element.removeClass("ui-selected"); + selectee.selected = false; + + selectee.$element.addClass("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"); + selectee.$element.removeClass("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"); + selectee.$element.removeClass("ui-selecting").addClass("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); diff --git a/lib/web/jquery/ui-modules/slider.js b/lib/web/jquery/ui-modules/slider.js new file mode 100644 index 000000000000..34434e1a978a --- /dev/null +++ b/lib/web/jquery/ui-modules/slider.js @@ -0,0 +1,661 @@ +(function( $, undefined ) { + +// number of pages in a slider +// (how many times can you page up/down to go through the whole range) + var numPages = 5; + + $.widget( "ui.slider", $.ui.mouse, { + version: "1.10.4", + widgetEventPrefix: "slide", + + options: { + animate: false, + 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 + }, + + _create: function() { + this._keySliding = false; + this._mouseSliding = false; + this._animateOff = true; + this._handleIndex = null; + this._detectOrientation(); + this._mouseInit(); + + this.element + .addClass( "ui-slider" + + " ui-slider-" + this.orientation + + " ui-widget" + + " ui-widget-content" + + " ui-corner-all"); + + this._refresh(); + this._setOption( "disabled", this.options.disabled ); + + 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" ).addClass( "ui-state-default ui-corner-all" ), + handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>", + 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.handle = this.handles.eq( 0 ); + + this.handles.each(function( i ) { + $( this ).data( "ui-slider-handle-index", i ); + }); + }, + + _createRange: function() { + var options = this.options, + classes = ""; + + 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 ( $.isArray( options.values ) ) { + options.values = options.values.slice(0); + } + } + + if ( !this.range || !this.range.length ) { + this.range = $( "<div></div>" ) + .appendTo( this.element ); + + classes = "ui-slider-range" + + // note: this isn't the most fittingly semantic framework class for this element, + // but worked best visually with a variety of themes + " ui-widget-header ui-corner-all"; + } else { + this.range.removeClass( "ui-slider-range-min ui-slider-range-max" ) + // Handle range switching from true to min/max + .css({ + "left": "", + "bottom": "" + }); + } + + this.range.addClass( classes + + ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) ); + } else { + if ( this.range ) { + this.range.remove(); + } + this.range = null; + } + }, + + _setupEvents: function() { + var elements = this.handles.add( this.range ).filter( "a" ); + this._off( elements ); + this._on( elements, this._handleEvents ); + this._hoverable( elements ); + this._focusable( elements ); + }, + + _destroy: function() { + this.handles.remove(); + if ( this.range ) { + this.range.remove(); + } + + this.element + .removeClass( "ui-slider" + + " ui-slider-horizontal" + + " ui-slider-vertical" + + " ui-widget" + + " ui-widget-content" + + " ui-corner-all" ); + + 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; + + closestHandle + .addClass( "ui-state-active" ) + .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.handles.removeClass( "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 ); + }, + + _start: function( event, index ) { + var uiHash = { + handle: this.handles[ index ], + value: this.value() + }; + if ( this.options.values && this.options.values.length ) { + uiHash.value = this.values( index ); + uiHash.values = this.values(); + } + return this._trigger( "start", event, uiHash ); + }, + + _slide: function( event, index, newVal ) { + var otherVal, + newValues, + allowed; + + if ( this.options.values && this.options.values.length ) { + otherVal = this.values( index ? 0 : 1 ); + + if ( ( this.options.values.length === 2 && this.options.range === true ) && + ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) ) + ) { + newVal = otherVal; + } + + if ( newVal !== this.values( index ) ) { + newValues = this.values(); + newValues[ index ] = newVal; + // A slide can be canceled by returning false from the slide callback + allowed = this._trigger( "slide", event, { + handle: this.handles[ index ], + value: newVal, + values: newValues + } ); + otherVal = this.values( index ? 0 : 1 ); + if ( allowed !== false ) { + this.values( index, newVal ); + } + } + } else { + if ( newVal !== this.value() ) { + // A slide can be canceled by returning false from the slide callback + allowed = this._trigger( "slide", event, { + handle: this.handles[ index ], + value: newVal + } ); + if ( allowed !== false ) { + this.value( newVal ); + } + } + } + }, + + _stop: function( event, index ) { + var uiHash = { + handle: this.handles[ index ], + value: this.value() + }; + if ( this.options.values && this.options.values.length ) { + uiHash.value = this.values( index ); + uiHash.values = this.values(); + } + + this._trigger( "stop", event, uiHash ); + }, + + _change: function( event, index ) { + if ( !this._keySliding && !this._mouseSliding ) { + var uiHash = { + handle: this.handles[ index ], + value: this.value() + }; + if ( this.options.values && this.options.values.length ) { + uiHash.value = this.values( index ); + uiHash.values = this.values(); + } + + //store the last changed value index for reference when handles overlap + this._lastChangedValue = index; + + this._trigger( "change", event, uiHash ); + } + }, + + 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 ( $.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.options.values && this.options.values.length ) { + 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 ( $.isArray( this.options.values ) ) { + valsLength = this.options.values.length; + } + + $.Widget.prototype._setOption.apply( this, arguments ); + + switch ( key ) { + case "orientation": + this._detectOrientation(); + this.element + .removeClass( "ui-slider-horizontal ui-slider-vertical" ) + .addClass( "ui-slider-" + this.orientation ); + this._refreshValue(); + break; + case "value": + this._animateOff = true; + this._refreshValue(); + this._change( null, 0 ); + this._animateOff = false; + break; + case "values": + this._animateOff = true; + this._refreshValue(); + for ( i = 0; i < valsLength; i += 1 ) { + this._change( null, i ); + } + this._animateOff = false; + break; + case "min": + case "max": + this._animateOff = true; + this._refreshValue(); + this._animateOff = false; + break; + case "range": + this._animateOff = true; + this._refresh(); + this._animateOff = false; + break; + } + }, + + //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.options.values && this.options.values.length ) { + // .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) ); + }, + + _valueMin: function() { + return this.options.min; + }, + + _valueMax: function() { + return this.options.max; + }, + + _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.options.values && this.options.values.length ) { + 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[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: 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[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: 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; + $( event.target ).addClass( "ui-state-active" ); + allowed = this._start( event, index ); + if ( allowed === false ) { + return; + } + } + break; + } + + step = this.options.step; + if ( this.options.values && this.options.values.length ) { + 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()) / numPages ) ); + break; + case $.ui.keyCode.PAGE_DOWN: + newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / 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 ); + }, + click: function( event ) { + event.preventDefault(); + }, + 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 ); + $( event.target ).removeClass( "ui-state-active" ); + } + } + } + + }); + +}(jQuery)); diff --git a/lib/web/jquery/ui-modules/sortable.js b/lib/web/jquery/ui-modules/sortable.js new file mode 100644 index 000000000000..53ceb3c99df6 --- /dev/null +++ b/lib/web/jquery/ui-modules/sortable.js @@ -0,0 +1,1274 @@ +(function( $, undefined ) { + + function isOverAxis( x, reference, size ) { + return ( x > reference ) && ( x < ( reference + size ) ); + } + + function isFloating(item) { + return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display")); + } + + $.widget("ui.sortable", $.ui.mouse, { + version: "1.10.4", + 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 + }, + _create: function() { + + var o = this.options; + this.containerCache = {}; + this.element.addClass("ui-sortable"); + + //Get the items + this.refresh(); + + //Let's determine if the items are being displayed horizontally + this.floating = this.items.length ? o.axis === "x" || isFloating(this.items[0].item) : false; + + //Let's determine the parent's offset + this.offset = this.element.offset(); + + //Initialize mouse events for interaction + this._mouseInit(); + + //We're ready to go + this.ready = true; + + }, + + _destroy: function() { + this.element + .removeClass("ui-sortable ui-sortable-disabled"); + this._mouseDestroy(); + + for ( var i = this.items.length - 1; i >= 0; i-- ) { + this.items[i].item.removeData(this.widgetName + "-item"); + } + + return this; + }, + + _setOption: function(key, value){ + if ( key === "disabled" ) { + this.options[ key ] = value; + + this.widget().toggleClass( "ui-sortable-disabled", !!value ); + } else { + // Don't call widget base _setOption for disable as it adds ui-state-disabled class + $.Widget.prototype._setOption.apply(this, arguments); + } + }, + + _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(); + + //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(); + + //Get the next scrolling parent + this.scrollParent = this.helper.scrollParent(); + + //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 + }, + parent: this._getParentOffset(), + relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper + }); + + // Only after we got the 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"); + + //Generate the original position + this.originalPosition = this._generatePosition(event); + this.originalPageX = event.pageX; + this.originalPageY = event.pageY; + + //Adjust the mouse offset relative to the helper if "cursorAt" is supplied + (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(); + + //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 ); + } + + if(o.opacity) { // opacity option + if (this.helper.css("opacity")) { + this._storedOpacity = this.helper.css("opacity"); + } + this.helper.css("opacity", o.opacity); + } + + if(o.zIndex) { // zIndex option + if (this.helper.css("zIndex")) { + this._storedZIndex = this.helper.css("zIndex"); + } + this.helper.css("zIndex", o.zIndex); + } + + //Prepare scrolling + if(this.scrollParent[0] !== document && 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.helper.addClass("ui-sortable-helper"); + this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position + return true; + + }, + + _mouseDrag: function(event) { + var i, item, itemElement, intersection, + o = this.options, + scrolled = false; + + //Compute the helpers position + this.position = this._generatePosition(event); + this.positionAbs = this._convertPositionTo("absolute"); + + if (!this.lastPositionAbs) { + this.lastPositionAbs = this.positionAbs; + } + + //Do scrolling + if(this.options.scroll) { + if(this.scrollParent[0] !== document && 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 - $(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(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(this, event); + } + } + + //Regenerate the absolute position used for position checks + 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"; + } + + //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 beetween 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] === document.body ? 0 : this.offsetParent[0].scrollLeft); + } + if ( !axis || axis === "y" ) { + animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.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({ target: null }); + + if(this.options.helper === "original") { + this.currentItem.css(this._storedCSS).removeClass("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 isOverElementHeight = (this.options.axis === "x") || isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height), + isOverElementWidth = (this.options.axis === "y") || isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width), + isOverElement = isOverElementHeight && isOverElementWidth, + verticalDirection = this._getDragVerticalDirection(), + horizontalDirection = this._getDragHorizontalDirection(); + + if (!isOverElement) { + return false; + } + + return this.floating ? + ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 ) + : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) ); + + }, + + _intersectsWithSides: function(item) { + + var isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height), + isOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width), + verticalDirection = this._getDragVerticalDirection(), + horizontalDirection = this._getDragHorizontalDirection(); + + 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.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]); + for ( j = cur.length - 1; j >= 0; j--){ + inst = $.data(cur[j], this.widgetFullName); + if(inst && inst !== this && !inst.options.disabled) { + queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), inst]); + } + } + } + } + + queries.push([$.isFunction(this.options.items) ? 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 = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]], + connectWith = this._connectWith(); + + if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down + for (i = connectWith.length - 1; i >= 0; i--){ + cur = $(connectWith[i]); + for (j = cur.length - 1; j >= 0; j--){ + inst = $.data(cur[j], this.widgetFullName); + if(inst && inst !== this && !inst.options.disabled) { + queries.push([$.isFunction(inst.options.items) ? 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]); + + item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager) + + items.push({ + item: item, + instance: targetData, + width: 0, height: 0, + left: 0, top: 0 + }); + } + } + + }, + + refreshPositions: function(fast) { + + //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(); + } + + 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(item.instance !== this.currentContainer && 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; + } + + 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, + o = that.options; + + if(!o.placeholder || o.placeholder.constructor === String) { + className = o.placeholder; + o.placeholder = { + element: function() { + + var nodeName = that.currentItem[0].nodeName.toLowerCase(), + element = $( "<" + nodeName + ">", that.document[0] ) + .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder") + .removeClass("ui-sortable-helper"); + + if ( nodeName === "tr" ) { + that.currentItem.children().each(function() { + $( "<td> </td>", that.document[0] ) + .attr( "colspan", $( this ).attr( "colspan" ) || 1 ) + .appendTo( 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 by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item + if(!p.height()) { 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); + + }, + + _contactContainers: function(event) { + var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, base, cur, nearBottom, floating, + 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 || isFloating(this.currentItem); + posProperty = floating ? "left" : "top"; + sizeProperty = floating ? "width" : "height"; + base = this.positionAbs[posProperty] + this.offset.click[posProperty]; + 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 (floating && !isOverAxis(this.positionAbs.top + this.offset.click.top, this.items[j].top, this.items[j].height)) { + continue; + } + cur = this.items[j].item.offset()[posProperty]; + nearBottom = false; + if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){ + nearBottom = true; + cur += this.items[j][sizeProperty]; + } + + if(Math.abs(cur - base) < dist) { + dist = Math.abs(cur - base); 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]) { + return; + } + + itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : 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); + + this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); + this.containers[innermostIndex].containerCache.over = 1; + } + + + }, + + _createHelper: function(event) { + + var o = this.options, + helper = $.isFunction(o.helper) ? $(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) { + $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[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 ($.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] !== document && $.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] === document.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" ? document : window).width() - this.helperProportions.width - this.margins.left, + ($(o.containment === "document" ? document : window).height() || document.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] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, + scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); + + return { + top: ( + pos.top + // The absolute mouse position + this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border) + ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) + ), + left: ( + pos.left + // The absolute mouse position + this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) + ( ( 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] !== document && $.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] !== document && 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: ( + pageY - // The absolute mouse position + this.offset.click.top - // Click offset (relative to the element) + this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.parent.top + // The offsetParent's offset without borders (offset + border) + ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) + ), + left: ( + pageX - // The absolute mouse position + this.offset.click.left - // Click offset (relative to the element) + this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.parent.left + // The offsetParent's offset without borders (offset + border) + ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) + ) + }; + + }, + + _rearrange: function(event, i, a, hardRefresh) { + + a ? a[0].appendChild(this.placeholder[0]) : 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) { + this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove + } + }); + + }, + + _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).removeClass("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) { + delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed + } + + // 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(this.cancelHelperRemoval) { + if(!noPropagation) { + this._trigger("beforeStop", event, this._uiHash()); + for (i=0; i < delayedTriggers.length; i++) { + delayedTriggers[i].call(this, event); + } //Trigger all delayed events + this._trigger("stop", event, this._uiHash()); + } + + this.fromOutside = false; + return 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.helper[0] !== this.currentItem[0]) { + this.helper.remove(); + } + this.helper = null; + + if(!noPropagation) { + for (i=0; i < delayedTriggers.length; i++) { + delayedTriggers[i].call(this, event); + } //Trigger all delayed events + this._trigger("stop", event, this._uiHash()); + } + + this.fromOutside = false; + return true; + + }, + + _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 + }; + } + + }); + +})(jQuery); diff --git a/lib/web/jquery/ui-modules/spinner.js b/lib/web/jquery/ui-modules/spinner.js new file mode 100644 index 000000000000..d087279828a1 --- /dev/null +++ b/lib/web/jquery/ui-modules/spinner.js @@ -0,0 +1,482 @@ +(function( $ ) { + + function modifier( 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.10.4", + defaultElement: "<input>", + widgetEventPrefix: "spin", + options: { + 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 = {}, + element = this.element; + + $.each( [ "min", "max", "step" ], function( i, option ) { + var value = element.attr( option ); + if ( value !== undefined && 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 ) { + if ( !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] === this.document[0].activeElement ? + this.previous : this.element.val(); + function checkFocus() { + var isActive = this.element[0] === this.document[0].activeElement; + if ( !isActive ) { + this.element.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" + }, + + _draw: function() { + var uiSpinner = this.uiSpinner = this.element + .addClass( "ui-spinner-input" ) + .attr( "autocomplete", "off" ) + .wrap( this._uiSpinnerHtml() ) + .parent() + // add buttons + .append( this._buttonHtml() ); + + this.element.attr( "role", "spinbutton" ); + + // button bindings + this.buttons = uiSpinner.find( ".ui-spinner-button" ) + .attr( "tabIndex", -1 ) + .button() + .removeClass( "ui-corner-all" ); + + // IE 6 doesn't understand height: 50% for the buttons + // unless the wrapper has an explicit height + if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) && + uiSpinner.height() > 0 ) { + uiSpinner.height( uiSpinner.height() ); + } + + // disable spinner if element was already disabled + if ( this.options.disabled ) { + this.disable(); + } + }, + + _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; + }, + + _uiSpinnerHtml: function() { + return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>"; + }, + + _buttonHtml: function() { + return "" + + "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" + + "<span class='ui-icon " + this.options.icons.up + "'>▲</span>" + + "</a>" + + "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" + + "<span class='ui-icon " + this.options.icons.down + "'>▼</span>" + + "</a>"; + }, + + _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 $.isFunction( incremental ) ? + 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 ) { + if ( key === "culture" || key === "numberFormat" ) { + var 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" ) { + this.buttons.first().find( ".ui-icon" ) + .removeClass( this.options.icons.up ) + .addClass( value.up ); + this.buttons.last().find( ".ui-icon" ) + .removeClass( this.options.icons.down ) + .addClass( value.down ); + } + + this._super( key, value ); + + if ( key === "disabled" ) { + if ( value ) { + this.element.prop( "disabled", true ); + this.buttons.button( "disable" ); + } else { + this.element.prop( "disabled", false ); + this.buttons.button( "enable" ); + } + } + }, + + _setOptions: modifier(function( options ) { + this._super( options ); + this._value( this.element.val() ); + }), + + _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() ) + }); + }, + + // 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 + .removeClass( "ui-spinner-input" ) + .prop( "disabled", false ) + .removeAttr( "autocomplete" ) + .removeAttr( "role" ) + .removeAttr( "aria-valuemin" ) + .removeAttr( "aria-valuemax" ) + .removeAttr( "aria-valuenow" ); + this.uiSpinner.replaceWith( this.element ); + }, + + stepUp: modifier(function( steps ) { + this._stepUp( steps ); + }), + _stepUp: function( steps ) { + if ( this._start() ) { + this._spin( (steps || 1) * this.options.step ); + this._stop(); + } + }, + + stepDown: modifier(function( steps ) { + this._stepDown( steps ); + }), + _stepDown: function( steps ) { + if ( this._start() ) { + this._spin( (steps || 1) * -this.options.step ); + this._stop(); + } + }, + + pageUp: modifier(function( pages ) { + this._stepUp( (pages || 1) * this.options.page ); + }), + + pageDown: modifier(function( pages ) { + this._stepDown( (pages || 1) * this.options.page ); + }), + + value: function( newVal ) { + if ( !arguments.length ) { + return this._parse( this.element.val() ); + } + modifier( this._value ).call( this, newVal ); + }, + + widget: function() { + return this.uiSpinner; + } + }); + +}( jQuery ) ); diff --git a/lib/web/jquery/ui-modules/tabs.js b/lib/web/jquery/ui-modules/tabs.js new file mode 100644 index 000000000000..37bbb8cf83d8 --- /dev/null +++ b/lib/web/jquery/ui-modules/tabs.js @@ -0,0 +1,835 @@ +(function( $, undefined ) { + + var tabId = 0, + rhash = /#.*$/; + + function getNextTabId() { + return ++tabId; + } + + function isLocal( anchor ) { + // support: IE7 + // IE7 doesn't normalize the href property when set via script (#9317) + anchor = anchor.cloneNode( false ); + + return anchor.hash.length > 1 && + decodeURIComponent( anchor.href.replace( rhash, "" ) ) === + decodeURIComponent( location.href.replace( rhash, "" ) ); + } + + $.widget( "ui.tabs", { + version: "1.10.4", + delay: 300, + options: { + active: null, + collapsible: false, + event: "click", + heightStyle: "content", + hide: null, + show: null, + + // callbacks + activate: null, + beforeActivate: null, + beforeLoad: null, + load: null + }, + + _create: function() { + var that = this, + options = this.options; + + this.running = false; + + this.element + .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" ) + .toggleClass( "ui-tabs-collapsible", options.collapsible ) + // Prevent users from focusing disabled tabs via click + .delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, 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. + .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() { + if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) { + this.blur(); + } + }); + + this._processTabs(); + options.active = this._initialActive(); + + // Take disabling tabs via class attribute from HTML + // into account and update option properly. + if ( $.isArray( options.disabled ) ) { + options.disabled = $.unique( 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 = $( this.document[0].activeElement ).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 key will prevent automatic activation + if ( !event.ctrlKey ) { + // 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.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 ).focus(); + return index; + }, + + _setOption: function( key, value ) { + if ( key === "active" ) { + // _activate() will handle invalid values and update this.options + this._activate( value ); + return; + } + + if ( key === "disabled" ) { + // don't use the widget factory's disabled handling + this._setupDisabled( value ); + return; + } + + this._super( key, value); + + if ( key === "collapsible" ) { + this.element.toggleClass( "ui-tabs-collapsible", 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 ); + } + }, + + _tabId: function( tab ) { + return tab.attr( "aria-controls" ) || "ui-tabs-" + getNextTabId(); + }, + + _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._setupDisabled( this.options.disabled ); + this._setupEvents( this.options.event ); + this._setupHeightStyle( this.options.heightStyle ); + + this.tabs.not( this.active ).attr({ + "aria-selected": "false", + tabIndex: -1 + }); + this.panels.not( this._getPanelForTab( this.active ) ) + .hide() + .attr({ + "aria-expanded": "false", + "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 + .addClass( "ui-tabs-active ui-state-active" ) + .attr({ + "aria-selected": "true", + tabIndex: 0 + }); + this._getPanelForTab( this.active ) + .show() + .attr({ + "aria-expanded": "true", + "aria-hidden": "false" + }); + } + }, + + _processTabs: function() { + var that = this; + + this.tablist = this._getList() + .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) + .attr( "role", "tablist" ); + + this.tabs = this.tablist.find( "> li:has(a[href])" ) + .addClass( "ui-state-default ui-corner-top" ) + .attr({ + role: "tab", + tabIndex: -1 + }); + + this.anchors = this.tabs.map(function() { + return $( "a", this )[ 0 ]; + }) + .addClass( "ui-tabs-anchor" ) + .attr({ + role: "presentation", + tabIndex: -1 + }); + + 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 ( isLocal( anchor ) ) { + selector = anchor.hash; + panel = that.element.find( that._sanitizeSelector( selector ) ); + // remote tab + } else { + panelId = that._tabId( tab ); + 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": selector.substring( 1 ), + "aria-labelledby": anchorId + }); + panel.attr( "aria-labelledby", anchorId ); + }); + + this.panels + .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) + .attr( "role", "tabpanel" ); + }, + + // 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 ) + .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) + .data( "ui-tabs-destroy", true ); + }, + + _setupDisabled: function( disabled ) { + if ( $.isArray( disabled ) ) { + if ( !disabled.length ) { + disabled = false; + } else if ( disabled.length === this.anchors.length ) { + disabled = true; + } + } + + // disable tabs + for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) { + if ( disabled === true || $.inArray( i, disabled ) !== -1 ) { + $( li ) + .addClass( "ui-state-disabled" ) + .attr( "aria-disabled", "true" ); + } else { + $( li ) + .removeClass( "ui-state-disabled" ) + .removeAttr( "aria-disabled" ); + } + } + + this.options.disabled = disabled; + }, + + _setupEvents: function( event ) { + var events = { + click: function( event ) { + event.preventDefault(); + } + }; + if ( event ) { + $.each( event.split(" "), function( index, eventName ) { + events[ eventName ] = "_eventHandler"; + }); + } + + this._off( this.anchors.add( this.tabs ).add( this.panels ) ); + 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() { + eventData.newTab.closest( "li" ).addClass( "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() { + eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); + show(); + }); + } else { + eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); + toHide.hide(); + show(); + } + + toHide.attr({ + "aria-expanded": "false", + "aria-hidden": "true" + }); + eventData.oldTab.attr( "aria-selected", "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-expanded": "true", + "aria-hidden": "false" + }); + eventData.newTab.attr({ + "aria-selected": "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$='" + index + "']" ) ); + } + + return index; + }, + + _destroy: function() { + if ( this.xhr ) { + this.xhr.abort(); + } + + this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" ); + + this.tablist + .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) + .removeAttr( "role" ); + + this.anchors + .removeClass( "ui-tabs-anchor" ) + .removeAttr( "role" ) + .removeAttr( "tabIndex" ) + .removeUniqueId(); + + this.tabs.add( this.panels ).each(function() { + if ( $.data( this, "ui-tabs-destroy" ) ) { + $( this ).remove(); + } else { + $( this ) + .removeClass( "ui-state-default ui-state-active ui-state-disabled " + + "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" ) + .removeAttr( "tabIndex" ) + .removeAttr( "aria-live" ) + .removeAttr( "aria-busy" ) + .removeAttr( "aria-selected" ) + .removeAttr( "aria-labelledby" ) + .removeAttr( "aria-hidden" ) + .removeAttr( "aria-expanded" ) + .removeAttr( "role" ); + } + }); + + 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 ( $.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._setupDisabled( 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 ( $.isArray( disabled ) ) { + disabled = $.merge( [ index ], disabled ).sort(); + } else { + disabled = [ index ]; + } + } + this._setupDisabled( 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 + }; + + // not remote + if ( 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" ) { + tab.addClass( "ui-tabs-loading" ); + panel.attr( "aria-busy", "true" ); + + this.xhr + .success(function( response ) { + // support: jQuery <1.8 + // http://bugs.jquery.com/ticket/11778 + setTimeout(function() { + panel.html( response ); + that._trigger( "load", event, eventData ); + }, 1 ); + }) + .complete(function( jqXHR, status ) { + // support: jQuery <1.8 + // http://bugs.jquery.com/ticket/11778 + setTimeout(function() { + if ( status === "abort" ) { + that.panels.stop( false, true ); + } + + tab.removeClass( "ui-tabs-loading" ); + panel.removeAttr( "aria-busy" ); + + if ( jqXHR === that.xhr ) { + delete that.xhr; + } + }, 1 ); + }); + } + }, + + _ajaxSettings: function( anchor, event, eventData ) { + var that = this; + return { + url: anchor.attr( "href" ), + 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 ) ); + } + }); + +})( jQuery ); diff --git a/lib/web/jquery/ui-modules/timepicker.js b/lib/web/jquery/ui-modules/timepicker.js new file mode 100644 index 000000000000..3b4bd59facad --- /dev/null +++ b/lib/web/jquery/ui-modules/timepicker.js @@ -0,0 +1,2158 @@ +/*! jQuery Timepicker Addon - v1.4.3 - 2013-11-30 +* http://trentrichardson.com/examples/timepicker +* Copyright (c) 2013 Trent Richardson; Licensed MIT */ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define([ + "jquery", + // @TODO: define correct deps + // Change 'jquery/ui' to core & datepicker + // "jquery-ui-modules/core", + // "jquery-ui-modules/datepicker" + "jquery/ui" + ], factory); + } else { + factory(jQuery); + } +}(function ($) { + + /* + * Lets not redefine timepicker, Prevent "Uncaught RangeError: Maximum call stack size exceeded" + */ + $.ui.timepicker = $.ui.timepicker || {}; + if ($.ui.timepicker.version) { + return; + } + + /* + * Extend jQueryUI, get it started with our version number + */ + $.extend($.ui, { + timepicker: { + version: "1.4.3" + } + }); + + /* + * Timepicker manager. + * Use the singleton instance of this class, $.timepicker, to interact with the time picker. + * Settings for (groups of) time pickers are maintained in an instance object, + * allowing multiple different settings on the same page. + */ + var Timepicker = function () { + this.regional = []; // Available regional settings, indexed by language code + this.regional[''] = { // Default regional settings + currentText: 'Now', + closeText: 'Done', + amNames: ['AM', 'A'], + pmNames: ['PM', 'P'], + timeFormat: 'HH:mm', + timeSuffix: '', + timeOnlyTitle: 'Choose Time', + timeText: 'Time', + hourText: 'Hour', + minuteText: 'Minute', + secondText: 'Second', + millisecText: 'Millisecond', + microsecText: 'Microsecond', + timezoneText: 'Time Zone', + isRTL: false + }; + this._defaults = { // Global defaults for all the datetime picker instances + showButtonPanel: true, + timeOnly: false, + showHour: null, + showMinute: null, + showSecond: null, + showMillisec: null, + showMicrosec: null, + showTimezone: null, + showTime: true, + stepHour: 1, + stepMinute: 1, + stepSecond: 1, + stepMillisec: 1, + stepMicrosec: 1, + hour: 0, + minute: 0, + second: 0, + millisec: 0, + microsec: 0, + timezone: null, + hourMin: 0, + minuteMin: 0, + secondMin: 0, + millisecMin: 0, + microsecMin: 0, + hourMax: 23, + minuteMax: 59, + secondMax: 59, + millisecMax: 999, + microsecMax: 999, + minDateTime: null, + maxDateTime: null, + onSelect: null, + hourGrid: 0, + minuteGrid: 0, + secondGrid: 0, + millisecGrid: 0, + microsecGrid: 0, + alwaysSetTime: true, + separator: ' ', + altFieldTimeOnly: true, + altTimeFormat: null, + altSeparator: null, + altTimeSuffix: null, + pickerTimeFormat: null, + pickerTimeSuffix: null, + showTimepicker: true, + timezoneList: null, + addSliderAccess: false, + sliderAccessArgs: null, + controlType: 'slider', + defaultValue: null, + parse: 'strict' + }; + $.extend(this._defaults, this.regional['']); + }; + + $.extend(Timepicker.prototype, { + $input: null, + $altInput: null, + $timeObj: null, + inst: null, + hour_slider: null, + minute_slider: null, + second_slider: null, + millisec_slider: null, + microsec_slider: null, + timezone_select: null, + hour: 0, + minute: 0, + second: 0, + millisec: 0, + microsec: 0, + timezone: null, + hourMinOriginal: null, + minuteMinOriginal: null, + secondMinOriginal: null, + millisecMinOriginal: null, + microsecMinOriginal: null, + hourMaxOriginal: null, + minuteMaxOriginal: null, + secondMaxOriginal: null, + millisecMaxOriginal: null, + microsecMaxOriginal: null, + ampm: '', + formattedDate: '', + formattedTime: '', + formattedDateTime: '', + timezoneList: null, + units: ['hour', 'minute', 'second', 'millisec', 'microsec'], + support: {}, + control: null, + + /* + * Override the default settings for all instances of the time picker. + * @param {Object} settings object - the new settings to use as defaults (anonymous object) + * @return {Object} the manager object + */ + setDefaults: function (settings) { + extendRemove(this._defaults, settings || {}); + return this; + }, + + /* + * Create a new Timepicker instance + */ + _newInst: function ($input, opts) { + var tp_inst = new Timepicker(), + inlineSettings = {}, + fns = {}, + overrides, i; + + for (var attrName in this._defaults) { + if (this._defaults.hasOwnProperty(attrName)) { + var attrValue = $input.attr('time:' + attrName); + if (attrValue) { + try { + inlineSettings[attrName] = eval(attrValue); + } catch (err) { + inlineSettings[attrName] = attrValue; + } + } + } + } + + overrides = { + beforeShow: function (input, dp_inst) { + if ($.isFunction(tp_inst._defaults.evnts.beforeShow)) { + return tp_inst._defaults.evnts.beforeShow.call($input[0], input, dp_inst, tp_inst); + } + }, + onChangeMonthYear: function (year, month, dp_inst) { + // Update the time as well : this prevents the time from disappearing from the $input field. + tp_inst._updateDateTime(dp_inst); + if ($.isFunction(tp_inst._defaults.evnts.onChangeMonthYear)) { + tp_inst._defaults.evnts.onChangeMonthYear.call($input[0], year, month, dp_inst, tp_inst); + } + }, + onClose: function (dateText, dp_inst) { + if (tp_inst.timeDefined === true && $input.val() !== '') { + tp_inst._updateDateTime(dp_inst); + } + if ($.isFunction(tp_inst._defaults.evnts.onClose)) { + tp_inst._defaults.evnts.onClose.call($input[0], dateText, dp_inst, tp_inst); + } + } + }; + for (i in overrides) { + if (overrides.hasOwnProperty(i)) { + fns[i] = opts[i] || null; + } + } + + tp_inst._defaults = $.extend({}, this._defaults, inlineSettings, opts, overrides, { + evnts: fns, + timepicker: tp_inst // add timepicker as a property of datepicker: $.datepicker._get(dp_inst, 'timepicker'); + }); + tp_inst.amNames = $.map(tp_inst._defaults.amNames, function (val) { + return val.toUpperCase(); + }); + tp_inst.pmNames = $.map(tp_inst._defaults.pmNames, function (val) { + return val.toUpperCase(); + }); + + // detect which units are supported + tp_inst.support = detectSupport( + tp_inst._defaults.timeFormat + + (tp_inst._defaults.pickerTimeFormat ? tp_inst._defaults.pickerTimeFormat : '') + + (tp_inst._defaults.altTimeFormat ? tp_inst._defaults.altTimeFormat : '')); + + // controlType is string - key to our this._controls + if (typeof(tp_inst._defaults.controlType) === 'string') { + if (tp_inst._defaults.controlType === 'slider' && typeof($.ui.slider) === 'undefined') { + tp_inst._defaults.controlType = 'select'; + } + tp_inst.control = tp_inst._controls[tp_inst._defaults.controlType]; + } + // controlType is an object and must implement create, options, value methods + else { + tp_inst.control = tp_inst._defaults.controlType; + } + + // prep the timezone options + var timezoneList = [-720, -660, -600, -570, -540, -480, -420, -360, -300, -270, -240, -210, -180, -120, -60, + 0, 60, 120, 180, 210, 240, 270, 300, 330, 345, 360, 390, 420, 480, 525, 540, 570, 600, 630, 660, 690, 720, 765, 780, 840]; + if (tp_inst._defaults.timezoneList !== null) { + timezoneList = tp_inst._defaults.timezoneList; + } + var tzl = timezoneList.length, tzi = 0, tzv = null; + if (tzl > 0 && typeof timezoneList[0] !== 'object') { + for (; tzi < tzl; tzi++) { + tzv = timezoneList[tzi]; + timezoneList[tzi] = { value: tzv, label: $.timepicker.timezoneOffsetString(tzv, tp_inst.support.iso8601) }; + } + } + tp_inst._defaults.timezoneList = timezoneList; + + // set the default units + tp_inst.timezone = tp_inst._defaults.timezone !== null ? $.timepicker.timezoneOffsetNumber(tp_inst._defaults.timezone) : + ((new Date()).getTimezoneOffset() * -1); + tp_inst.hour = tp_inst._defaults.hour < tp_inst._defaults.hourMin ? tp_inst._defaults.hourMin : + tp_inst._defaults.hour > tp_inst._defaults.hourMax ? tp_inst._defaults.hourMax : tp_inst._defaults.hour; + tp_inst.minute = tp_inst._defaults.minute < tp_inst._defaults.minuteMin ? tp_inst._defaults.minuteMin : + tp_inst._defaults.minute > tp_inst._defaults.minuteMax ? tp_inst._defaults.minuteMax : tp_inst._defaults.minute; + tp_inst.second = tp_inst._defaults.second < tp_inst._defaults.secondMin ? tp_inst._defaults.secondMin : + tp_inst._defaults.second > tp_inst._defaults.secondMax ? tp_inst._defaults.secondMax : tp_inst._defaults.second; + tp_inst.millisec = tp_inst._defaults.millisec < tp_inst._defaults.millisecMin ? tp_inst._defaults.millisecMin : + tp_inst._defaults.millisec > tp_inst._defaults.millisecMax ? tp_inst._defaults.millisecMax : tp_inst._defaults.millisec; + tp_inst.microsec = tp_inst._defaults.microsec < tp_inst._defaults.microsecMin ? tp_inst._defaults.microsecMin : + tp_inst._defaults.microsec > tp_inst._defaults.microsecMax ? tp_inst._defaults.microsecMax : tp_inst._defaults.microsec; + tp_inst.ampm = ''; + tp_inst.$input = $input; + + if (tp_inst._defaults.altField) { + tp_inst.$altInput = $(tp_inst._defaults.altField).css({ + cursor: 'pointer' + }).focus(function () { + $input.trigger("focus"); + }); + } + + if (tp_inst._defaults.minDate === 0 || tp_inst._defaults.minDateTime === 0) { + tp_inst._defaults.minDate = new Date(); + } + if (tp_inst._defaults.maxDate === 0 || tp_inst._defaults.maxDateTime === 0) { + tp_inst._defaults.maxDate = new Date(); + } + + // datepicker needs minDate/maxDate, timepicker needs minDateTime/maxDateTime.. + if (tp_inst._defaults.minDate !== undefined && tp_inst._defaults.minDate instanceof Date) { + tp_inst._defaults.minDateTime = new Date(tp_inst._defaults.minDate.getTime()); + } + if (tp_inst._defaults.minDateTime !== undefined && tp_inst._defaults.minDateTime instanceof Date) { + tp_inst._defaults.minDate = new Date(tp_inst._defaults.minDateTime.getTime()); + } + if (tp_inst._defaults.maxDate !== undefined && tp_inst._defaults.maxDate instanceof Date) { + tp_inst._defaults.maxDateTime = new Date(tp_inst._defaults.maxDate.getTime()); + } + if (tp_inst._defaults.maxDateTime !== undefined && tp_inst._defaults.maxDateTime instanceof Date) { + tp_inst._defaults.maxDate = new Date(tp_inst._defaults.maxDateTime.getTime()); + } + tp_inst.$input.bind('focus', function () { + tp_inst._onFocus(); + }); + + return tp_inst; + }, + + /* + * add our sliders to the calendar + */ + _addTimePicker: function (dp_inst) { + var currDT = (this.$altInput && this._defaults.altFieldTimeOnly) ? this.$input.val() + ' ' + this.$altInput.val() : this.$input.val(); + + this.timeDefined = this._parseTime(currDT); + this._limitMinMaxDateTime(dp_inst, false); + this._injectTimePicker(); + }, + + /* + * parse the time string from input value or _setTime + */ + _parseTime: function (timeString, withDate) { + if (!this.inst) { + this.inst = $.datepicker._getInst(this.$input[0]); + } + + if (withDate || !this._defaults.timeOnly) { + var dp_dateFormat = $.datepicker._get(this.inst, 'dateFormat'); + try { + var parseRes = parseDateTimeInternal(dp_dateFormat, this._defaults.timeFormat, timeString, $.datepicker._getFormatConfig(this.inst), this._defaults); + if (!parseRes.timeObj) { + return false; + } + $.extend(this, parseRes.timeObj); + } catch (err) { + $.timepicker.log("Error parsing the date/time string: " + err + + "\ndate/time string = " + timeString + + "\ntimeFormat = " + this._defaults.timeFormat + + "\ndateFormat = " + dp_dateFormat); + return false; + } + return true; + } else { + var timeObj = $.datepicker.parseTime(this._defaults.timeFormat, timeString, this._defaults); + if (!timeObj) { + return false; + } + $.extend(this, timeObj); + return true; + } + }, + + /* + * generate and inject html for timepicker into ui datepicker + */ + _injectTimePicker: function () { + var $dp = this.inst.dpDiv, + o = this.inst.settings, + tp_inst = this, + litem = '', + uitem = '', + show = null, + max = {}, + gridSize = {}, + size = null, + i = 0, + l = 0; + + // Prevent displaying twice + if ($dp.find("div.ui-timepicker-div").length === 0 && o.showTimepicker) { + var noDisplay = ' style="display:none;"', + html = '<div class="ui-timepicker-div' + (o.isRTL ? ' ui-timepicker-rtl' : '') + '"><dl>' + '<dt class="ui_tpicker_time_label"' + ((o.showTime) ? '' : noDisplay) + '>' + o.timeText + '</dt>' + + '<dd class="ui_tpicker_time"' + ((o.showTime) ? '' : noDisplay) + '></dd>'; + + // Create the markup + for (i = 0, l = this.units.length; i < l; i++) { + litem = this.units[i]; + uitem = litem.substr(0, 1).toUpperCase() + litem.substr(1); + show = o['show' + uitem] !== null ? o['show' + uitem] : this.support[litem]; + + // Added by Peter Medeiros: + // - Figure out what the hour/minute/second max should be based on the step values. + // - Example: if stepMinute is 15, then minMax is 45. + max[litem] = parseInt((o[litem + 'Max'] - ((o[litem + 'Max'] - o[litem + 'Min']) % o['step' + uitem])), 10); + gridSize[litem] = 0; + + html += '<dt class="ui_tpicker_' + litem + '_label"' + (show ? '' : noDisplay) + '>' + o[litem + 'Text'] + '</dt>' + + '<dd class="ui_tpicker_' + litem + '"><div class="ui_tpicker_' + litem + '_slider"' + (show ? '' : noDisplay) + '></div>'; + + if (show && o[litem + 'Grid'] > 0) { + html += '<div style="padding-left: 1px"><table class="ui-tpicker-grid-label"><tr>'; + + if (litem === 'hour') { + for (var h = o[litem + 'Min']; h <= max[litem]; h += parseInt(o[litem + 'Grid'], 10)) { + gridSize[litem]++; + var tmph = $.datepicker.formatTime(this.support.ampm ? 'hht' : 'HH', {hour: h}, o); + html += '<td data-for="' + litem + '">' + tmph + '</td>'; + } + } + else { + for (var m = o[litem + 'Min']; m <= max[litem]; m += parseInt(o[litem + 'Grid'], 10)) { + gridSize[litem]++; + html += '<td data-for="' + litem + '">' + ((m < 10) ? '0' : '') + m + '</td>'; + } + } + + html += '</tr></table></div>'; + } + html += '</dd>'; + } + + // Timezone + var showTz = o.showTimezone !== null ? o.showTimezone : this.support.timezone; + html += '<dt class="ui_tpicker_timezone_label"' + (showTz ? '' : noDisplay) + '>' + o.timezoneText + '</dt>'; + html += '<dd class="ui_tpicker_timezone" ' + (showTz ? '' : noDisplay) + '></dd>'; + + // Create the elements from string + html += '</dl></div>'; + var $tp = $(html); + + // if we only want time picker... + if (o.timeOnly === true) { + $tp.prepend('<div class="ui-widget-header ui-helper-clearfix ui-corner-all">' + '<div class="ui-datepicker-title">' + o.timeOnlyTitle + '</div>' + '</div>'); + $dp.find('.ui-datepicker-header, .ui-datepicker-calendar').hide(); + } + + // add sliders, adjust grids, add events + for (i = 0, l = tp_inst.units.length; i < l; i++) { + litem = tp_inst.units[i]; + uitem = litem.substr(0, 1).toUpperCase() + litem.substr(1); + show = o['show' + uitem] !== null ? o['show' + uitem] : this.support[litem]; + + // add the slider + tp_inst[litem + '_slider'] = tp_inst.control.create(tp_inst, $tp.find('.ui_tpicker_' + litem + '_slider'), litem, tp_inst[litem], o[litem + 'Min'], max[litem], o['step' + uitem]); + + // adjust the grid and add click event + if (show && o[litem + 'Grid'] > 0) { + size = 100 * gridSize[litem] * o[litem + 'Grid'] / (max[litem] - o[litem + 'Min']); + $tp.find('.ui_tpicker_' + litem + ' table').css({ + width: size + "%", + marginLeft: o.isRTL ? '0' : ((size / (-2 * gridSize[litem])) + "%"), + marginRight: o.isRTL ? ((size / (-2 * gridSize[litem])) + "%") : '0', + borderCollapse: 'collapse' + }).find("td").click(function (e) { + var $t = $(this), + h = $t.html(), + n = parseInt(h.replace(/[^0-9]/g), 10), + ap = h.replace(/[^apm]/ig), + f = $t.data('for'); // loses scope, so we use data-for + + if (f === 'hour') { + if (ap.indexOf('p') !== -1 && n < 12) { + n += 12; + } + else { + if (ap.indexOf('a') !== -1 && n === 12) { + n = 0; + } + } + } + + tp_inst.control.value(tp_inst, tp_inst[f + '_slider'], litem, n); + + tp_inst._onTimeChange(); + tp_inst._onSelectHandler(); + }).css({ + cursor: 'pointer', + width: (100 / gridSize[litem]) + '%', + textAlign: 'center', + overflow: 'hidden' + }); + } // end if grid > 0 + } // end for loop + + // Add timezone options + this.timezone_select = $tp.find('.ui_tpicker_timezone').append('<select></select>').find("select"); + $.fn.append.apply(this.timezone_select, + $.map(o.timezoneList, function (val, idx) { + return $("<option />").val(typeof val === "object" ? val.value : val).text(typeof val === "object" ? val.label : val); + })); + if (typeof(this.timezone) !== "undefined" && this.timezone !== null && this.timezone !== "") { + var local_timezone = (new Date(this.inst.selectedYear, this.inst.selectedMonth, this.inst.selectedDay, 12)).getTimezoneOffset() * -1; + if (local_timezone === this.timezone) { + selectLocalTimezone(tp_inst); + } else { + this.timezone_select.val(this.timezone); + } + } else { + if (typeof(this.hour) !== "undefined" && this.hour !== null && this.hour !== "") { + this.timezone_select.val(o.timezone); + } else { + selectLocalTimezone(tp_inst); + } + } + this.timezone_select.change(function () { + tp_inst._onTimeChange(); + tp_inst._onSelectHandler(); + }); + // End timezone options + + // inject timepicker into datepicker + var $buttonPanel = $dp.find('.ui-datepicker-buttonpane'); + if ($buttonPanel.length) { + $buttonPanel.before($tp); + } else { + $dp.append($tp); + } + + this.$timeObj = $tp.find('.ui_tpicker_time'); + + if (this.inst !== null) { + var timeDefined = this.timeDefined; + this._onTimeChange(); + this.timeDefined = timeDefined; + } + + // slideAccess integration: http://trentrichardson.com/2011/11/11/jquery-ui-sliders-and-touch-accessibility/ + if (this._defaults.addSliderAccess) { + var sliderAccessArgs = this._defaults.sliderAccessArgs, + rtl = this._defaults.isRTL; + sliderAccessArgs.isRTL = rtl; + + setTimeout(function () { // fix for inline mode + if ($tp.find('.ui-slider-access').length === 0) { + $tp.find('.ui-slider:visible').sliderAccess(sliderAccessArgs); + + // fix any grids since sliders are shorter + var sliderAccessWidth = $tp.find('.ui-slider-access:eq(0)').outerWidth(true); + if (sliderAccessWidth) { + $tp.find('table:visible').each(function () { + var $g = $(this), + oldWidth = $g.outerWidth(), + oldMarginLeft = $g.css(rtl ? 'marginRight' : 'marginLeft').toString().replace('%', ''), + newWidth = oldWidth - sliderAccessWidth, + newMarginLeft = ((oldMarginLeft * newWidth) / oldWidth) + '%', + css = { width: newWidth, marginRight: 0, marginLeft: 0 }; + css[rtl ? 'marginRight' : 'marginLeft'] = newMarginLeft; + $g.css(css); + }); + } + } + }, 10); + } + // end slideAccess integration + + tp_inst._limitMinMaxDateTime(this.inst, true); + } + }, + + /* + * This function tries to limit the ability to go outside the + * min/max date range + */ + _limitMinMaxDateTime: function (dp_inst, adjustSliders) { + var o = this._defaults, + dp_date = new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay); + + if (!this._defaults.showTimepicker) { + return; + } // No time so nothing to check here + + if ($.datepicker._get(dp_inst, 'minDateTime') !== null && $.datepicker._get(dp_inst, 'minDateTime') !== undefined && dp_date) { + var minDateTime = $.datepicker._get(dp_inst, 'minDateTime'), + minDateTimeDate = new Date(minDateTime.getFullYear(), minDateTime.getMonth(), minDateTime.getDate(), 0, 0, 0, 0); + + if (this.hourMinOriginal === null || this.minuteMinOriginal === null || this.secondMinOriginal === null || this.millisecMinOriginal === null || this.microsecMinOriginal === null) { + this.hourMinOriginal = o.hourMin; + this.minuteMinOriginal = o.minuteMin; + this.secondMinOriginal = o.secondMin; + this.millisecMinOriginal = o.millisecMin; + this.microsecMinOriginal = o.microsecMin; + } + + if (dp_inst.settings.timeOnly || minDateTimeDate.getTime() === dp_date.getTime()) { + this._defaults.hourMin = minDateTime.getHours(); + if (this.hour <= this._defaults.hourMin) { + this.hour = this._defaults.hourMin; + this._defaults.minuteMin = minDateTime.getMinutes(); + if (this.minute <= this._defaults.minuteMin) { + this.minute = this._defaults.minuteMin; + this._defaults.secondMin = minDateTime.getSeconds(); + if (this.second <= this._defaults.secondMin) { + this.second = this._defaults.secondMin; + this._defaults.millisecMin = minDateTime.getMilliseconds(); + if (this.millisec <= this._defaults.millisecMin) { + this.millisec = this._defaults.millisecMin; + this._defaults.microsecMin = minDateTime.getMicroseconds(); + } else { + if (this.microsec < this._defaults.microsecMin) { + this.microsec = this._defaults.microsecMin; + } + this._defaults.microsecMin = this.microsecMinOriginal; + } + } else { + this._defaults.millisecMin = this.millisecMinOriginal; + this._defaults.microsecMin = this.microsecMinOriginal; + } + } else { + this._defaults.secondMin = this.secondMinOriginal; + this._defaults.millisecMin = this.millisecMinOriginal; + this._defaults.microsecMin = this.microsecMinOriginal; + } + } else { + this._defaults.minuteMin = this.minuteMinOriginal; + this._defaults.secondMin = this.secondMinOriginal; + this._defaults.millisecMin = this.millisecMinOriginal; + this._defaults.microsecMin = this.microsecMinOriginal; + } + } else { + this._defaults.hourMin = this.hourMinOriginal; + this._defaults.minuteMin = this.minuteMinOriginal; + this._defaults.secondMin = this.secondMinOriginal; + this._defaults.millisecMin = this.millisecMinOriginal; + this._defaults.microsecMin = this.microsecMinOriginal; + } + } + + if ($.datepicker._get(dp_inst, 'maxDateTime') !== null && $.datepicker._get(dp_inst, 'maxDateTime') !== undefined && dp_date) { + var maxDateTime = $.datepicker._get(dp_inst, 'maxDateTime'), + maxDateTimeDate = new Date(maxDateTime.getFullYear(), maxDateTime.getMonth(), maxDateTime.getDate(), 0, 0, 0, 0); + + if (this.hourMaxOriginal === null || this.minuteMaxOriginal === null || this.secondMaxOriginal === null || this.millisecMaxOriginal === null) { + this.hourMaxOriginal = o.hourMax; + this.minuteMaxOriginal = o.minuteMax; + this.secondMaxOriginal = o.secondMax; + this.millisecMaxOriginal = o.millisecMax; + this.microsecMaxOriginal = o.microsecMax; + } + + if (dp_inst.settings.timeOnly || maxDateTimeDate.getTime() === dp_date.getTime()) { + this._defaults.hourMax = maxDateTime.getHours(); + if (this.hour >= this._defaults.hourMax) { + this.hour = this._defaults.hourMax; + this._defaults.minuteMax = maxDateTime.getMinutes(); + if (this.minute >= this._defaults.minuteMax) { + this.minute = this._defaults.minuteMax; + this._defaults.secondMax = maxDateTime.getSeconds(); + if (this.second >= this._defaults.secondMax) { + this.second = this._defaults.secondMax; + this._defaults.millisecMax = maxDateTime.getMilliseconds(); + if (this.millisec >= this._defaults.millisecMax) { + this.millisec = this._defaults.millisecMax; + this._defaults.microsecMax = maxDateTime.getMicroseconds(); + } else { + if (this.microsec > this._defaults.microsecMax) { + this.microsec = this._defaults.microsecMax; + } + this._defaults.microsecMax = this.microsecMaxOriginal; + } + } else { + this._defaults.millisecMax = this.millisecMaxOriginal; + this._defaults.microsecMax = this.microsecMaxOriginal; + } + } else { + this._defaults.secondMax = this.secondMaxOriginal; + this._defaults.millisecMax = this.millisecMaxOriginal; + this._defaults.microsecMax = this.microsecMaxOriginal; + } + } else { + this._defaults.minuteMax = this.minuteMaxOriginal; + this._defaults.secondMax = this.secondMaxOriginal; + this._defaults.millisecMax = this.millisecMaxOriginal; + this._defaults.microsecMax = this.microsecMaxOriginal; + } + } else { + this._defaults.hourMax = this.hourMaxOriginal; + this._defaults.minuteMax = this.minuteMaxOriginal; + this._defaults.secondMax = this.secondMaxOriginal; + this._defaults.millisecMax = this.millisecMaxOriginal; + this._defaults.microsecMax = this.microsecMaxOriginal; + } + } + + if (adjustSliders !== undefined && adjustSliders === true) { + var hourMax = parseInt((this._defaults.hourMax - ((this._defaults.hourMax - this._defaults.hourMin) % this._defaults.stepHour)), 10), + minMax = parseInt((this._defaults.minuteMax - ((this._defaults.minuteMax - this._defaults.minuteMin) % this._defaults.stepMinute)), 10), + secMax = parseInt((this._defaults.secondMax - ((this._defaults.secondMax - this._defaults.secondMin) % this._defaults.stepSecond)), 10), + millisecMax = parseInt((this._defaults.millisecMax - ((this._defaults.millisecMax - this._defaults.millisecMin) % this._defaults.stepMillisec)), 10), + microsecMax = parseInt((this._defaults.microsecMax - ((this._defaults.microsecMax - this._defaults.microsecMin) % this._defaults.stepMicrosec)), 10); + + if (this.hour_slider) { + this.control.options(this, this.hour_slider, 'hour', { min: this._defaults.hourMin, max: hourMax }); + this.control.value(this, this.hour_slider, 'hour', this.hour - (this.hour % this._defaults.stepHour)); + } + if (this.minute_slider) { + this.control.options(this, this.minute_slider, 'minute', { min: this._defaults.minuteMin, max: minMax }); + this.control.value(this, this.minute_slider, 'minute', this.minute - (this.minute % this._defaults.stepMinute)); + } + if (this.second_slider) { + this.control.options(this, this.second_slider, 'second', { min: this._defaults.secondMin, max: secMax }); + this.control.value(this, this.second_slider, 'second', this.second - (this.second % this._defaults.stepSecond)); + } + if (this.millisec_slider) { + this.control.options(this, this.millisec_slider, 'millisec', { min: this._defaults.millisecMin, max: millisecMax }); + this.control.value(this, this.millisec_slider, 'millisec', this.millisec - (this.millisec % this._defaults.stepMillisec)); + } + if (this.microsec_slider) { + this.control.options(this, this.microsec_slider, 'microsec', { min: this._defaults.microsecMin, max: microsecMax }); + this.control.value(this, this.microsec_slider, 'microsec', this.microsec - (this.microsec % this._defaults.stepMicrosec)); + } + } + + }, + + /* + * when a slider moves, set the internal time... + * on time change is also called when the time is updated in the text field + */ + _onTimeChange: function () { + if (!this._defaults.showTimepicker) { + return; + } + var hour = (this.hour_slider) ? this.control.value(this, this.hour_slider, 'hour') : false, + minute = (this.minute_slider) ? this.control.value(this, this.minute_slider, 'minute') : false, + second = (this.second_slider) ? this.control.value(this, this.second_slider, 'second') : false, + millisec = (this.millisec_slider) ? this.control.value(this, this.millisec_slider, 'millisec') : false, + microsec = (this.microsec_slider) ? this.control.value(this, this.microsec_slider, 'microsec') : false, + timezone = (this.timezone_select) ? this.timezone_select.val() : false, + o = this._defaults, + pickerTimeFormat = o.pickerTimeFormat || o.timeFormat, + pickerTimeSuffix = o.pickerTimeSuffix || o.timeSuffix; + + if (typeof(hour) === 'object') { + hour = false; + } + if (typeof(minute) === 'object') { + minute = false; + } + if (typeof(second) === 'object') { + second = false; + } + if (typeof(millisec) === 'object') { + millisec = false; + } + if (typeof(microsec) === 'object') { + microsec = false; + } + if (typeof(timezone) === 'object') { + timezone = false; + } + + if (hour !== false) { + hour = parseInt(hour, 10); + } + if (minute !== false) { + minute = parseInt(minute, 10); + } + if (second !== false) { + second = parseInt(second, 10); + } + if (millisec !== false) { + millisec = parseInt(millisec, 10); + } + if (microsec !== false) { + microsec = parseInt(microsec, 10); + } + if (timezone !== false) { + timezone = timezone.toString(); + } + + var ampm = o[hour < 12 ? 'amNames' : 'pmNames'][0]; + + // If the update was done in the input field, the input field should not be updated. + // If the update was done using the sliders, update the input field. + var hasChanged = ( + hour !== parseInt(this.hour,10) || // sliders should all be numeric + minute !== parseInt(this.minute,10) || + second !== parseInt(this.second,10) || + millisec !== parseInt(this.millisec,10) || + microsec !== parseInt(this.microsec,10) || + (this.ampm.length > 0 && (hour < 12) !== ($.inArray(this.ampm.toUpperCase(), this.amNames) !== -1)) || + (this.timezone !== null && timezone !== this.timezone.toString()) // could be numeric or "EST" format, so use toString() + ); + + if (hasChanged) { + + if (hour !== false) { + this.hour = hour; + } + if (minute !== false) { + this.minute = minute; + } + if (second !== false) { + this.second = second; + } + if (millisec !== false) { + this.millisec = millisec; + } + if (microsec !== false) { + this.microsec = microsec; + } + if (timezone !== false) { + this.timezone = timezone; + } + + if (!this.inst) { + this.inst = $.datepicker._getInst(this.$input[0]); + } + + this._limitMinMaxDateTime(this.inst, true); + } + if (this.support.ampm) { + this.ampm = ampm; + } + + // Updates the time within the timepicker + this.formattedTime = $.datepicker.formatTime(o.timeFormat, this, o); + if (this.$timeObj) { + if (pickerTimeFormat === o.timeFormat) { + this.$timeObj.text(this.formattedTime + pickerTimeSuffix); + } + else { + this.$timeObj.text($.datepicker.formatTime(pickerTimeFormat, this, o) + pickerTimeSuffix); + } + } + + this.timeDefined = true; + if (hasChanged) { + this._updateDateTime(); + this.$input.focus(); + } + }, + + /* + * call custom onSelect. + * bind to sliders slidestop, and grid click. + */ + _onSelectHandler: function () { + var onSelect = this._defaults.onSelect || this.inst.settings.onSelect; + var inputEl = this.$input ? this.$input[0] : null; + if (onSelect && inputEl) { + onSelect.apply(inputEl, [this.formattedDateTime, this]); + } + }, + + /* + * update our input with the new date time.. + */ + _updateDateTime: function (dp_inst) { + dp_inst = this.inst || dp_inst; + var dtTmp = (dp_inst.currentYear > 0? + new Date(dp_inst.currentYear, dp_inst.currentMonth, dp_inst.currentDay) : + new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay)), + dt = $.datepicker._daylightSavingAdjust(dtTmp), + //dt = $.datepicker._daylightSavingAdjust(new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay)), + //dt = $.datepicker._daylightSavingAdjust(new Date(dp_inst.currentYear, dp_inst.currentMonth, dp_inst.currentDay)), + dateFmt = $.datepicker._get(dp_inst, 'dateFormat'), + formatCfg = $.datepicker._getFormatConfig(dp_inst), + timeAvailable = dt !== null && this.timeDefined; + this.formattedDate = $.datepicker.formatDate(dateFmt, (dt === null ? new Date() : dt), formatCfg); + var formattedDateTime = this.formattedDate; + + // if a slider was changed but datepicker doesn't have a value yet, set it + if (dp_inst.lastVal === "") { + dp_inst.currentYear = dp_inst.selectedYear; + dp_inst.currentMonth = dp_inst.selectedMonth; + dp_inst.currentDay = dp_inst.selectedDay; + } + + /* + * remove following lines to force every changes in date picker to change the input value + * Bug descriptions: when an input field has a default value, and click on the field to pop up the date picker. + * If the user manually empty the value in the input field, the date picker will never change selected value. + */ + //if (dp_inst.lastVal !== undefined && (dp_inst.lastVal.length > 0 && this.$input.val().length === 0)) { + // return; + //} + + if (this._defaults.timeOnly === true) { + formattedDateTime = this.formattedTime; + } else if (this._defaults.timeOnly !== true && (this._defaults.alwaysSetTime || timeAvailable)) { + formattedDateTime += this._defaults.separator + this.formattedTime + this._defaults.timeSuffix; + } + + this.formattedDateTime = formattedDateTime; + + if (!this._defaults.showTimepicker) { + this.$input.val(this.formattedDate); + } else if (this.$altInput && this._defaults.timeOnly === false && this._defaults.altFieldTimeOnly === true) { + this.$altInput.val(this.formattedTime); + this.$input.val(this.formattedDate); + } else if (this.$altInput) { + this.$input.val(formattedDateTime); + var altFormattedDateTime = '', + altSeparator = this._defaults.altSeparator ? this._defaults.altSeparator : this._defaults.separator, + altTimeSuffix = this._defaults.altTimeSuffix ? this._defaults.altTimeSuffix : this._defaults.timeSuffix; + + if (!this._defaults.timeOnly) { + if (this._defaults.altFormat) { + altFormattedDateTime = $.datepicker.formatDate(this._defaults.altFormat, (dt === null ? new Date() : dt), formatCfg); + } + else { + altFormattedDateTime = this.formattedDate; + } + + if (altFormattedDateTime) { + altFormattedDateTime += altSeparator; + } + } + + if (this._defaults.altTimeFormat) { + altFormattedDateTime += $.datepicker.formatTime(this._defaults.altTimeFormat, this, this._defaults) + altTimeSuffix; + } + else { + altFormattedDateTime += this.formattedTime + altTimeSuffix; + } + this.$altInput.val(altFormattedDateTime); + } else { + this.$input.val(formattedDateTime); + } + + this.$input.trigger("change"); + }, + + _onFocus: function () { + if (!this.$input.val() && this._defaults.defaultValue) { + this.$input.val(this._defaults.defaultValue); + var inst = $.datepicker._getInst(this.$input.get(0)), + tp_inst = $.datepicker._get(inst, 'timepicker'); + if (tp_inst) { + if (tp_inst._defaults.timeOnly && (inst.input.val() !== inst.lastVal)) { + try { + $.datepicker._updateDatepicker(inst); + } catch (err) { + $.timepicker.log(err); + } + } + } + } + }, + + /* + * Small abstraction to control types + * We can add more, just be sure to follow the pattern: create, options, value + */ + _controls: { + // slider methods + slider: { + create: function (tp_inst, obj, unit, val, min, max, step) { + var rtl = tp_inst._defaults.isRTL; // if rtl go -60->0 instead of 0->60 + return obj.prop('slide', null).slider({ + orientation: "horizontal", + value: rtl ? val * -1 : val, + min: rtl ? max * -1 : min, + max: rtl ? min * -1 : max, + step: step, + slide: function (event, ui) { + tp_inst.control.value(tp_inst, $(this), unit, rtl ? ui.value * -1 : ui.value); + tp_inst._onTimeChange(); + }, + stop: function (event, ui) { + tp_inst._onSelectHandler(); + } + }); + }, + options: function (tp_inst, obj, unit, opts, val) { + if (tp_inst._defaults.isRTL) { + if (typeof(opts) === 'string') { + if (opts === 'min' || opts === 'max') { + if (val !== undefined) { + return obj.slider(opts, val * -1); + } + return Math.abs(obj.slider(opts)); + } + return obj.slider(opts); + } + var min = opts.min, + max = opts.max; + opts.min = opts.max = null; + if (min !== undefined) { + opts.max = min * -1; + } + if (max !== undefined) { + opts.min = max * -1; + } + return obj.slider(opts); + } + if (typeof(opts) === 'string' && val !== undefined) { + return obj.slider(opts, val); + } + return obj.slider(opts); + }, + value: function (tp_inst, obj, unit, val) { + if (tp_inst._defaults.isRTL) { + if (val !== undefined) { + return obj.slider('value', val * -1); + } + return Math.abs(obj.slider('value')); + } + if (val !== undefined) { + return obj.slider('value', val); + } + return obj.slider('value'); + } + }, + // select methods + select: { + create: function (tp_inst, obj, unit, val, min, max, step) { + var sel = '<select class="ui-timepicker-select" data-unit="' + unit + '" data-min="' + min + '" data-max="' + max + '" data-step="' + step + '">', + format = tp_inst._defaults.pickerTimeFormat || tp_inst._defaults.timeFormat; + + for (var i = min; i <= max; i += step) { + sel += '<option value="' + i + '"' + (i === val ? ' selected' : '') + '>'; + if (unit === 'hour') { + sel += $.datepicker.formatTime($.trim(format.replace(/[^ht ]/ig, '')), {hour: i}, tp_inst._defaults); + } + else if (unit === 'millisec' || unit === 'microsec' || i >= 10) { sel += i; } + else {sel += '0' + i.toString(); } + sel += '</option>'; + } + sel += '</select>'; + + obj.children('select').remove(); + + $(sel).appendTo(obj).change(function (e) { + tp_inst._onTimeChange(); + tp_inst._onSelectHandler(); + }); + + return obj; + }, + options: function (tp_inst, obj, unit, opts, val) { + var o = {}, + $t = obj.children('select'); + if (typeof(opts) === 'string') { + if (val === undefined) { + return $t.data(opts); + } + o[opts] = val; + } + else { o = opts; } + return tp_inst.control.create(tp_inst, obj, $t.data('unit'), $t.val(), o.min || $t.data('min'), o.max || $t.data('max'), o.step || $t.data('step')); + }, + value: function (tp_inst, obj, unit, val) { + var $t = obj.children('select'); + if (val !== undefined) { + return $t.val(val); + } + return $t.val(); + } + } + } // end _controls + + }); + + $.fn.extend({ + /* + * shorthand just to use timepicker. + */ + timepicker: function (o) { + o = o || {}; + var tmp_args = Array.prototype.slice.call(arguments); + + if (typeof o === 'object') { + tmp_args[0] = $.extend(o, { + timeOnly: true + }); + } + + return $(this).each(function () { + $.fn.datetimepicker.apply($(this), tmp_args); + }); + }, + + /* + * extend timepicker to datepicker + */ + datetimepicker: function (o) { + o = o || {}; + var tmp_args = arguments; + + if (typeof(o) === 'string') { + if (o === 'getDate') { + return $.fn.datepicker.apply($(this[0]), tmp_args); + } else { + return this.each(function () { + var $t = $(this); + $t.datepicker.apply($t, tmp_args); + }); + } + } else { + return this.each(function () { + var $t = $(this); + $t.datepicker($.timepicker._newInst($t, o)._defaults); + }); + } + } + }); + + /* + * Public Utility to parse date and time + */ + $.datepicker.parseDateTime = function (dateFormat, timeFormat, dateTimeString, dateSettings, timeSettings) { + var parseRes = parseDateTimeInternal(dateFormat, timeFormat, dateTimeString, dateSettings, timeSettings); + if (parseRes.timeObj) { + var t = parseRes.timeObj; + parseRes.date.setHours(t.hour, t.minute, t.second, t.millisec); + parseRes.date.setMicroseconds(t.microsec); + } + + return parseRes.date; + }; + + /* + * Public utility to parse time + */ + $.datepicker.parseTime = function (timeFormat, timeString, options) { + var o = extendRemove(extendRemove({}, $.timepicker._defaults), options || {}), + iso8601 = (timeFormat.replace(/\'.*?\'/g, '').indexOf('Z') !== -1); + + // Strict parse requires the timeString to match the timeFormat exactly + var strictParse = function (f, s, o) { + + // pattern for standard and localized AM/PM markers + var getPatternAmpm = function (amNames, pmNames) { + var markers = []; + if (amNames) { + $.merge(markers, amNames); + } + if (pmNames) { + $.merge(markers, pmNames); + } + markers = $.map(markers, function (val) { + return val.replace(/[.*+?|()\[\]{}\\]/g, '\\$&'); + }); + return '(' + markers.join('|') + ')?'; + }; + + // figure out position of time elements.. cause js cant do named captures + var getFormatPositions = function (timeFormat) { + var finds = timeFormat.toLowerCase().match(/(h{1,2}|m{1,2}|s{1,2}|l{1}|c{1}|t{1,2}|z|'.*?')/g), + orders = { + h: -1, + m: -1, + s: -1, + l: -1, + c: -1, + t: -1, + z: -1 + }; + + if (finds) { + for (var i = 0; i < finds.length; i++) { + if (orders[finds[i].toString().charAt(0)] === -1) { + orders[finds[i].toString().charAt(0)] = i + 1; + } + } + } + return orders; + }; + + var regstr = '^' + f.toString() + .replace(/([hH]{1,2}|mm?|ss?|[tT]{1,2}|[zZ]|[lc]|'.*?')/g, function (match) { + var ml = match.length; + switch (match.charAt(0).toLowerCase()) { + case 'h': + return ml === 1 ? '(\\d?\\d)' : '(\\d{' + ml + '})'; + case 'm': + return ml === 1 ? '(\\d?\\d)' : '(\\d{' + ml + '})'; + case 's': + return ml === 1 ? '(\\d?\\d)' : '(\\d{' + ml + '})'; + case 'l': + return '(\\d?\\d?\\d)'; + case 'c': + return '(\\d?\\d?\\d)'; + case 'z': + return '(z|[-+]\\d\\d:?\\d\\d|\\S+)?'; + case 't': + return getPatternAmpm(o.amNames, o.pmNames); + default: // literal escaped in quotes + return '(' + match.replace(/\'/g, "").replace(/(\.|\$|\^|\\|\/|\(|\)|\[|\]|\?|\+|\*)/g, function (m) { return "\\" + m; }) + ')?'; + } + }) + .replace(/\s/g, '\\s?') + + o.timeSuffix + '$', + order = getFormatPositions(f), + ampm = '', + treg; + + treg = s.match(new RegExp(regstr, 'i')); + + var resTime = { + hour: 0, + minute: 0, + second: 0, + millisec: 0, + microsec: 0 + }; + + if (treg) { + if (order.t !== -1) { + if (treg[order.t] === undefined || treg[order.t].length === 0) { + ampm = ''; + resTime.ampm = ''; + } else { + ampm = $.inArray(treg[order.t].toUpperCase(), o.amNames) !== -1 ? 'AM' : 'PM'; + resTime.ampm = o[ampm === 'AM' ? 'amNames' : 'pmNames'][0]; + } + } + + if (order.h !== -1) { + if (ampm === 'AM' && treg[order.h] === '12') { + resTime.hour = 0; // 12am = 0 hour + } else { + if (ampm === 'PM' && treg[order.h] !== '12') { + resTime.hour = parseInt(treg[order.h], 10) + 12; // 12pm = 12 hour, any other pm = hour + 12 + } else { + resTime.hour = Number(treg[order.h]); + } + } + } + + if (order.m !== -1) { + resTime.minute = Number(treg[order.m]); + } + if (order.s !== -1) { + resTime.second = Number(treg[order.s]); + } + if (order.l !== -1) { + resTime.millisec = Number(treg[order.l]); + } + if (order.c !== -1) { + resTime.microsec = Number(treg[order.c]); + } + if (order.z !== -1 && treg[order.z] !== undefined) { + resTime.timezone = $.timepicker.timezoneOffsetNumber(treg[order.z]); + } + + + return resTime; + } + return false; + };// end strictParse + + // First try JS Date, if that fails, use strictParse + var looseParse = function (f, s, o) { + try { + var d = new Date('2012-01-01 ' + s); + if (isNaN(d.getTime())) { + d = new Date('2012-01-01T' + s); + if (isNaN(d.getTime())) { + d = new Date('01/01/2012 ' + s); + if (isNaN(d.getTime())) { + throw "Unable to parse time with native Date: " + s; + } + } + } + + return { + hour: d.getHours(), + minute: d.getMinutes(), + second: d.getSeconds(), + millisec: d.getMilliseconds(), + microsec: d.getMicroseconds(), + timezone: d.getTimezoneOffset() * -1 + }; + } + catch (err) { + try { + return strictParse(f, s, o); + } + catch (err2) { + $.timepicker.log("Unable to parse \ntimeString: " + s + "\ntimeFormat: " + f); + } + } + return false; + }; // end looseParse + + if (typeof o.parse === "function") { + return o.parse(timeFormat, timeString, o); + } + if (o.parse === 'loose') { + return looseParse(timeFormat, timeString, o); + } + return strictParse(timeFormat, timeString, o); + }; + + /** + * Public utility to format the time + * @param {string} format format of the time + * @param {Object} time Object not a Date for timezones + * @param {Object} [options] essentially the regional[].. amNames, pmNames, ampm + * @returns {string} the formatted time + */ + $.datepicker.formatTime = function (format, time, options) { + options = options || {}; + options = $.extend({}, $.timepicker._defaults, options); + time = $.extend({ + hour: 0, + minute: 0, + second: 0, + millisec: 0, + microsec: 0, + timezone: null + }, time); + + var tmptime = format, + ampmName = options.amNames[0], + hour = parseInt(time.hour, 10); + + if (hour > 11) { + ampmName = options.pmNames[0]; + } + + tmptime = tmptime.replace(/(?:HH?|hh?|mm?|ss?|[tT]{1,2}|[zZ]|[lc]|'.*?')/g, function (match) { + switch (match) { + case 'HH': + return ('0' + hour).slice(-2); + case 'H': + return hour; + case 'hh': + return ('0' + convert24to12(hour)).slice(-2); + case 'h': + return convert24to12(hour); + case 'mm': + return ('0' + time.minute).slice(-2); + case 'm': + return time.minute; + case 'ss': + return ('0' + time.second).slice(-2); + case 's': + return time.second; + case 'l': + return ('00' + time.millisec).slice(-3); + case 'c': + return ('00' + time.microsec).slice(-3); + case 'z': + return $.timepicker.timezoneOffsetString(time.timezone === null ? options.timezone : time.timezone, false); + case 'Z': + return $.timepicker.timezoneOffsetString(time.timezone === null ? options.timezone : time.timezone, true); + case 'T': + return ampmName.charAt(0).toUpperCase(); + case 'TT': + return ampmName.toUpperCase(); + case 't': + return ampmName.charAt(0).toLowerCase(); + case 'tt': + return ampmName.toLowerCase(); + default: + return match.replace(/'/g, ""); + } + }); + + return tmptime; + }; + + /* + * the bad hack :/ override datepicker so it doesn't close on select + // inspired: http://stackoverflow.com/questions/1252512/jquery-datepicker-prevent-closing-picker-when-clicking-a-date/1762378#1762378 + */ + $.datepicker._base_selectDate = $.datepicker._selectDate; + $.datepicker._selectDate = function (id, dateStr) { + var inst = this._getInst($(id)[0]), + tp_inst = this._get(inst, 'timepicker'); + + if (tp_inst) { + tp_inst._limitMinMaxDateTime(inst, true); + inst.inline = inst.stay_open = true; + //This way the onSelect handler called from calendarpicker get the full dateTime + this._base_selectDate(id, dateStr); + inst.inline = inst.stay_open = false; + this._notifyChange(inst); + this._updateDatepicker(inst); + } else { + this._base_selectDate(id, dateStr); + } + }; + + /* + * second bad hack :/ override datepicker so it triggers an event when changing the input field + * and does not redraw the datepicker on every selectDate event + */ + $.datepicker._base_updateDatepicker = $.datepicker._updateDatepicker; + $.datepicker._updateDatepicker = function (inst) { + + // don't popup the datepicker if there is another instance already opened + var input = inst.input[0]; + if ($.datepicker._curInst && $.datepicker._curInst !== inst && $.datepicker._datepickerShowing && $.datepicker._lastInput !== input) { + return; + } + + if (typeof(inst.stay_open) !== 'boolean' || inst.stay_open === false) { + + this._base_updateDatepicker(inst); + + // Reload the time control when changing something in the input text field. + var tp_inst = this._get(inst, 'timepicker'); + if (tp_inst) { + tp_inst._addTimePicker(inst); + } + } + }; + + /* + * third bad hack :/ override datepicker so it allows spaces and colon in the input field + */ + $.datepicker._base_doKeyPress = $.datepicker._doKeyPress; + $.datepicker._doKeyPress = function (event) { + var inst = $.datepicker._getInst(event.target), + tp_inst = $.datepicker._get(inst, 'timepicker'); + + if (tp_inst) { + if ($.datepicker._get(inst, 'constrainInput')) { + var ampm = tp_inst.support.ampm, + tz = tp_inst._defaults.showTimezone !== null ? tp_inst._defaults.showTimezone : tp_inst.support.timezone, + dateChars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat')), + datetimeChars = tp_inst._defaults.timeFormat.toString() + .replace(/[hms]/g, '') + .replace(/TT/g, ampm ? 'APM' : '') + .replace(/Tt/g, ampm ? 'AaPpMm' : '') + .replace(/tT/g, ampm ? 'AaPpMm' : '') + .replace(/T/g, ampm ? 'AP' : '') + .replace(/tt/g, ampm ? 'apm' : '') + .replace(/t/g, ampm ? 'ap' : '') + + " " + tp_inst._defaults.separator + + tp_inst._defaults.timeSuffix + + (tz ? tp_inst._defaults.timezoneList.join('') : '') + + (tp_inst._defaults.amNames.join('')) + (tp_inst._defaults.pmNames.join('')) + + dateChars, + chr = String.fromCharCode(event.charCode === undefined ? event.keyCode : event.charCode); + return event.ctrlKey || (chr < ' ' || !dateChars || datetimeChars.indexOf(chr) > -1); + } + } + + return $.datepicker._base_doKeyPress(event); + }; + + /* + * Fourth bad hack :/ override _updateAlternate function used in inline mode to init altField + * Update any alternate field to synchronise with the main field. + */ + $.datepicker._base_updateAlternate = $.datepicker._updateAlternate; + $.datepicker._updateAlternate = function (inst) { + var tp_inst = this._get(inst, 'timepicker'); + if (tp_inst) { + var altField = tp_inst._defaults.altField; + if (altField) { // update alternate field too + var altFormat = tp_inst._defaults.altFormat || tp_inst._defaults.dateFormat, + date = this._getDate(inst), + formatCfg = $.datepicker._getFormatConfig(inst), + altFormattedDateTime = '', + altSeparator = tp_inst._defaults.altSeparator ? tp_inst._defaults.altSeparator : tp_inst._defaults.separator, + altTimeSuffix = tp_inst._defaults.altTimeSuffix ? tp_inst._defaults.altTimeSuffix : tp_inst._defaults.timeSuffix, + altTimeFormat = tp_inst._defaults.altTimeFormat !== null ? tp_inst._defaults.altTimeFormat : tp_inst._defaults.timeFormat; + + altFormattedDateTime += $.datepicker.formatTime(altTimeFormat, tp_inst, tp_inst._defaults) + altTimeSuffix; + if (!tp_inst._defaults.timeOnly && !tp_inst._defaults.altFieldTimeOnly && date !== null) { + if (tp_inst._defaults.altFormat) { + altFormattedDateTime = $.datepicker.formatDate(tp_inst._defaults.altFormat, date, formatCfg) + altSeparator + altFormattedDateTime; + } + else { + altFormattedDateTime = tp_inst.formattedDate + altSeparator + altFormattedDateTime; + } + } + $(altField).val(altFormattedDateTime); + } + } + else { + $.datepicker._base_updateAlternate(inst); + } + }; + + /* + * Override key up event to sync manual input changes. + */ + $.datepicker._base_doKeyUp = $.datepicker._doKeyUp; + $.datepicker._doKeyUp = function (event) { + var inst = $.datepicker._getInst(event.target), + tp_inst = $.datepicker._get(inst, 'timepicker'); + + if (tp_inst) { + if (tp_inst._defaults.timeOnly && (inst.input.val() !== inst.lastVal)) { + try { + $.datepicker._updateDatepicker(inst); + } catch (err) { + $.timepicker.log(err); + } + } + } + + return $.datepicker._base_doKeyUp(event); + }; + + /* + * override "Today" button to also grab the time. + */ + $.datepicker._base_gotoToday = $.datepicker._gotoToday; + $.datepicker._gotoToday = function (id) { + var inst = this._getInst($(id)[0]), + $dp = inst.dpDiv; + this._base_gotoToday(id); + var tp_inst = this._get(inst, 'timepicker'); + selectLocalTimezone(tp_inst); + var now = new Date(); + this._setTime(inst, now); + $('.ui-datepicker-today', $dp).click(); + }; + + /* + * Disable & enable the Time in the datetimepicker + */ + $.datepicker._disableTimepickerDatepicker = function (target) { + var inst = this._getInst(target); + if (!inst) { + return; + } + + var tp_inst = this._get(inst, 'timepicker'); + $(target).datepicker('getDate'); // Init selected[Year|Month|Day] + if (tp_inst) { + inst.settings.showTimepicker = false; + tp_inst._defaults.showTimepicker = false; + tp_inst._updateDateTime(inst); + } + }; + + $.datepicker._enableTimepickerDatepicker = function (target) { + var inst = this._getInst(target); + if (!inst) { + return; + } + + var tp_inst = this._get(inst, 'timepicker'); + $(target).datepicker('getDate'); // Init selected[Year|Month|Day] + if (tp_inst) { + inst.settings.showTimepicker = true; + tp_inst._defaults.showTimepicker = true; + tp_inst._addTimePicker(inst); // Could be disabled on page load + tp_inst._updateDateTime(inst); + } + }; + + /* + * Create our own set time function + */ + $.datepicker._setTime = function (inst, date) { + var tp_inst = this._get(inst, 'timepicker'); + if (tp_inst) { + var defaults = tp_inst._defaults; + + // calling _setTime with no date sets time to defaults + tp_inst.hour = date ? date.getHours() : defaults.hour; + tp_inst.minute = date ? date.getMinutes() : defaults.minute; + tp_inst.second = date ? date.getSeconds() : defaults.second; + tp_inst.millisec = date ? date.getMilliseconds() : defaults.millisec; + tp_inst.microsec = date ? date.getMicroseconds() : defaults.microsec; + + //check if within min/max times.. + tp_inst._limitMinMaxDateTime(inst, true); + + tp_inst._onTimeChange(); + tp_inst._updateDateTime(inst); + } + }; + + /* + * Create new public method to set only time, callable as $().datepicker('setTime', date) + */ + $.datepicker._setTimeDatepicker = function (target, date, withDate) { + var inst = this._getInst(target); + if (!inst) { + return; + } + + var tp_inst = this._get(inst, 'timepicker'); + + if (tp_inst) { + this._setDateFromField(inst); + var tp_date; + if (date) { + if (typeof date === "string") { + tp_inst._parseTime(date, withDate); + tp_date = new Date(); + tp_date.setHours(tp_inst.hour, tp_inst.minute, tp_inst.second, tp_inst.millisec); + tp_date.setMicroseconds(tp_inst.microsec); + } else { + tp_date = new Date(date.getTime()); + tp_date.setMicroseconds(date.getMicroseconds()); + } + if (tp_date.toString() === 'Invalid Date') { + tp_date = undefined; + } + this._setTime(inst, tp_date); + } + } + + }; + + /* + * override setDate() to allow setting time too within Date object + */ + $.datepicker._base_setDateDatepicker = $.datepicker._setDateDatepicker; + $.datepicker._setDateDatepicker = function (target, date) { + var inst = this._getInst(target); + if (!inst) { + return; + } + + if (typeof(date) === 'string') { + date = new Date(date); + if (!date.getTime()) { + $.timepicker.log("Error creating Date object from string."); + } + } + + var tp_inst = this._get(inst, 'timepicker'); + var tp_date; + if (date instanceof Date) { + tp_date = new Date(date.getTime()); + tp_date.setMicroseconds(date.getMicroseconds()); + } else { + tp_date = date; + } + + // This is important if you are using the timezone option, javascript's Date + // object will only return the timezone offset for the current locale, so we + // adjust it accordingly. If not using timezone option this won't matter.. + // If a timezone is different in tp, keep the timezone as is + if (tp_inst && tp_date) { + // look out for DST if tz wasn't specified + if (!tp_inst.support.timezone && tp_inst._defaults.timezone === null) { + tp_inst.timezone = tp_date.getTimezoneOffset() * -1; + } + date = $.timepicker.timezoneAdjust(date, tp_inst.timezone); + tp_date = $.timepicker.timezoneAdjust(tp_date, tp_inst.timezone); + } + + this._updateDatepicker(inst); + this._base_setDateDatepicker.apply(this, arguments); + this._setTimeDatepicker(target, tp_date, true); + }; + + /* + * override getDate() to allow getting time too within Date object + */ + $.datepicker._base_getDateDatepicker = $.datepicker._getDateDatepicker; + $.datepicker._getDateDatepicker = function (target, noDefault) { + var inst = this._getInst(target); + if (!inst) { + return; + } + + var tp_inst = this._get(inst, 'timepicker'); + + if (tp_inst) { + // if it hasn't yet been defined, grab from field + if (inst.lastVal === undefined) { + this._setDateFromField(inst, noDefault); + } + + var date = this._getDate(inst); + if (date && tp_inst._parseTime($(target).val(), tp_inst.timeOnly)) { + date.setHours(tp_inst.hour, tp_inst.minute, tp_inst.second, tp_inst.millisec); + date.setMicroseconds(tp_inst.microsec); + + // This is important if you are using the timezone option, javascript's Date + // object will only return the timezone offset for the current locale, so we + // adjust it accordingly. If not using timezone option this won't matter.. + if (tp_inst.timezone != null) { + // look out for DST if tz wasn't specified + if (!tp_inst.support.timezone && tp_inst._defaults.timezone === null) { + tp_inst.timezone = date.getTimezoneOffset() * -1; + } + date = $.timepicker.timezoneAdjust(date, tp_inst.timezone); + } + } + return date; + } + return this._base_getDateDatepicker(target, noDefault); + }; + + /* + * override parseDate() because UI 1.8.14 throws an error about "Extra characters" + * An option in datapicker to ignore extra format characters would be nicer. + */ + $.datepicker._base_parseDate = $.datepicker.parseDate; + $.datepicker.parseDate = function (format, value, settings) { + var date; + try { + date = this._base_parseDate(format, value, settings); + } catch (err) { + // Hack! The error message ends with a colon, a space, and + // the "extra" characters. We rely on that instead of + // attempting to perfectly reproduce the parsing algorithm. + if (err.indexOf(":") >= 0) { + date = this._base_parseDate(format, value.substring(0, value.length - (err.length - err.indexOf(':') - 2)), settings); + $.timepicker.log("Error parsing the date string: " + err + "\ndate string = " + value + "\ndate format = " + format); + } else { + throw err; + } + } + return date; + }; + + /* + * override formatDate to set date with time to the input + */ + $.datepicker._base_formatDate = $.datepicker._formatDate; + $.datepicker._formatDate = function (inst, day, month, year) { + var tp_inst = this._get(inst, 'timepicker'); + if (tp_inst) { + tp_inst._updateDateTime(inst); + return tp_inst.$input.val(); + } + return this._base_formatDate(inst); + }; + + /* + * override options setter to add time to maxDate(Time) and minDate(Time). MaxDate + */ + $.datepicker._base_optionDatepicker = $.datepicker._optionDatepicker; + $.datepicker._optionDatepicker = function (target, name, value) { + var inst = this._getInst(target), + name_clone; + if (!inst) { + return null; + } + + var tp_inst = this._get(inst, 'timepicker'); + if (tp_inst) { + var min = null, + max = null, + onselect = null, + overrides = tp_inst._defaults.evnts, + fns = {}, + prop; + if (typeof name === 'string') { // if min/max was set with the string + if (name === 'minDate' || name === 'minDateTime') { + min = value; + } else if (name === 'maxDate' || name === 'maxDateTime') { + max = value; + } else if (name === 'onSelect') { + onselect = value; + } else if (overrides.hasOwnProperty(name)) { + if (typeof (value) === 'undefined') { + return overrides[name]; + } + fns[name] = value; + name_clone = {}; //empty results in exiting function after overrides updated + } + } else if (typeof name === 'object') { //if min/max was set with the JSON + if (name.minDate) { + min = name.minDate; + } else if (name.minDateTime) { + min = name.minDateTime; + } else if (name.maxDate) { + max = name.maxDate; + } else if (name.maxDateTime) { + max = name.maxDateTime; + } + for (prop in overrides) { + if (overrides.hasOwnProperty(prop) && name[prop]) { + fns[prop] = name[prop]; + } + } + } + for (prop in fns) { + if (fns.hasOwnProperty(prop)) { + overrides[prop] = fns[prop]; + if (!name_clone) { name_clone = $.extend({}, name); } + delete name_clone[prop]; + } + } + if (name_clone && isEmptyObject(name_clone)) { return; } + if (min) { //if min was set + if (min === 0) { + min = new Date(); + } else { + min = new Date(min); + } + tp_inst._defaults.minDate = min; + tp_inst._defaults.minDateTime = min; + } else if (max) { //if max was set + if (max === 0) { + max = new Date(); + } else { + max = new Date(max); + } + tp_inst._defaults.maxDate = max; + tp_inst._defaults.maxDateTime = max; + } else if (onselect) { + tp_inst._defaults.onSelect = onselect; + } + } + if (value === undefined) { + return this._base_optionDatepicker.call($.datepicker, target, name); + } + return this._base_optionDatepicker.call($.datepicker, target, name_clone || name, value); + }; + + /* + * jQuery isEmptyObject does not check hasOwnProperty - if someone has added to the object prototype, + * it will return false for all objects + */ + var isEmptyObject = function (obj) { + var prop; + for (prop in obj) { + if (obj.hasOwnProperty(prop)) { + return false; + } + } + return true; + }; + + /* + * jQuery extend now ignores nulls! + */ + var extendRemove = function (target, props) { + $.extend(target, props); + for (var name in props) { + if (props[name] === null || props[name] === undefined) { + target[name] = props[name]; + } + } + return target; + }; + + /* + * Determine by the time format which units are supported + * Returns an object of booleans for each unit + */ + var detectSupport = function (timeFormat) { + var tf = timeFormat.replace(/'.*?'/g, '').toLowerCase(), // removes literals + isIn = function (f, t) { // does the format contain the token? + return f.indexOf(t) !== -1 ? true : false; + }; + return { + hour: isIn(tf, 'h'), + minute: isIn(tf, 'm'), + second: isIn(tf, 's'), + millisec: isIn(tf, 'l'), + microsec: isIn(tf, 'c'), + timezone: isIn(tf, 'z'), + ampm: isIn(tf, 't') && isIn(timeFormat, 'h'), + iso8601: isIn(timeFormat, 'Z') + }; + }; + + /* + * Converts 24 hour format into 12 hour + * Returns 12 hour without leading 0 + */ + var convert24to12 = function (hour) { + hour %= 12; + + if (hour === 0) { + hour = 12; + } + + return String(hour); + }; + + var computeEffectiveSetting = function (settings, property) { + return settings && settings[property] ? settings[property] : $.timepicker._defaults[property]; + }; + + /* + * Splits datetime string into date and time substrings. + * Throws exception when date can't be parsed + * Returns {dateString: dateString, timeString: timeString} + */ + var splitDateTime = function (dateTimeString, timeSettings) { + // The idea is to get the number separator occurrences in datetime and the time format requested (since time has + // fewer unknowns, mostly numbers and am/pm). We will use the time pattern to split. + var separator = computeEffectiveSetting(timeSettings, 'separator'), + format = computeEffectiveSetting(timeSettings, 'timeFormat'), + timeParts = format.split(separator), // how many occurrences of separator may be in our format? + timePartsLen = timeParts.length, + allParts = dateTimeString.split(separator), + allPartsLen = allParts.length; + + if (allPartsLen > 1) { + return { + dateString: allParts.splice(0, allPartsLen - timePartsLen).join(separator), + timeString: allParts.splice(0, timePartsLen).join(separator) + }; + } + + return { + dateString: dateTimeString, + timeString: '' + }; + }; + + /* + * Internal function to parse datetime interval + * Returns: {date: Date, timeObj: Object}, where + * date - parsed date without time (type Date) + * timeObj = {hour: , minute: , second: , millisec: , microsec: } - parsed time. Optional + */ + var parseDateTimeInternal = function (dateFormat, timeFormat, dateTimeString, dateSettings, timeSettings) { + var date, + parts, + parsedTime; + + parts = splitDateTime(dateTimeString, timeSettings); + date = $.datepicker._base_parseDate(dateFormat, parts.dateString, dateSettings); + + if (parts.timeString === '') { + return { + date: date + }; + } + + parsedTime = $.datepicker.parseTime(timeFormat, parts.timeString, timeSettings); + + if (!parsedTime) { + throw 'Wrong time format'; + } + + return { + date: date, + timeObj: parsedTime + }; + }; + + /* + * Internal function to set timezone_select to the local timezone + */ + var selectLocalTimezone = function (tp_inst, date) { + if (tp_inst && tp_inst.timezone_select) { + var now = date || new Date(); + tp_inst.timezone_select.val(-now.getTimezoneOffset()); + } + }; + + /* + * Create a Singleton Instance + */ + $.timepicker = new Timepicker(); + + /** + * Get the timezone offset as string from a date object (eg '+0530' for UTC+5.5) + * @param {number} tzMinutes if not a number, less than -720 (-1200), or greater than 840 (+1400) this value is returned + * @param {boolean} iso8601 if true formats in accordance to iso8601 "+12:45" + * @return {string} + */ + $.timepicker.timezoneOffsetString = function (tzMinutes, iso8601) { + if (isNaN(tzMinutes) || tzMinutes > 840 || tzMinutes < -720) { + return tzMinutes; + } + + var off = tzMinutes, + minutes = off % 60, + hours = (off - minutes) / 60, + iso = iso8601 ? ':' : '', + tz = (off >= 0 ? '+' : '-') + ('0' + Math.abs(hours)).slice(-2) + iso + ('0' + Math.abs(minutes)).slice(-2); + + if (tz === '+00:00') { + return 'Z'; + } + return tz; + }; + + /** + * Get the number in minutes that represents a timezone string + * @param {string} tzString formatted like "+0500", "-1245", "Z" + * @return {number} the offset minutes or the original string if it doesn't match expectations + */ + $.timepicker.timezoneOffsetNumber = function (tzString) { + var normalized = tzString.toString().replace(':', ''); // excuse any iso8601, end up with "+1245" + + if (normalized.toUpperCase() === 'Z') { // if iso8601 with Z, its 0 minute offset + return 0; + } + + if (!/^(\-|\+)\d{4}$/.test(normalized)) { // possibly a user defined tz, so just give it back + return tzString; + } + + return ((normalized.substr(0, 1) === '-' ? -1 : 1) * // plus or minus + ((parseInt(normalized.substr(1, 2), 10) * 60) + // hours (converted to minutes) + parseInt(normalized.substr(3, 2), 10))); // minutes + }; + + /** + * No way to set timezone in js Date, so we must adjust the minutes to compensate. (think setDate, getDate) + * @param {Date} date + * @param {string} toTimezone formatted like "+0500", "-1245" + * @return {Date} + */ + $.timepicker.timezoneAdjust = function (date, toTimezone) { + var toTz = $.timepicker.timezoneOffsetNumber(toTimezone); + if (!isNaN(toTz)) { + date.setMinutes(date.getMinutes() + -date.getTimezoneOffset() - toTz); + } + return date; + }; + + /** + * Calls `timepicker()` on the `startTime` and `endTime` elements, and configures them to + * enforce date range limits. + * n.b. The input value must be correctly formatted (reformatting is not supported) + * @param {Element} startTime + * @param {Element} endTime + * @param {Object} options Options for the timepicker() call + * @return {jQuery} + */ + $.timepicker.timeRange = function (startTime, endTime, options) { + return $.timepicker.handleRange('timepicker', startTime, endTime, options); + }; + + /** + * Calls `datetimepicker` on the `startTime` and `endTime` elements, and configures them to + * enforce date range limits. + * @param {Element} startTime + * @param {Element} endTime + * @param {Object} options Options for the `timepicker()` call. Also supports `reformat`, + * a boolean value that can be used to reformat the input values to the `dateFormat`. + * @param {string} method Can be used to specify the type of picker to be added + * @return {jQuery} + */ + $.timepicker.datetimeRange = function (startTime, endTime, options) { + $.timepicker.handleRange('datetimepicker', startTime, endTime, options); + }; + + /** + * Calls `datepicker` on the `startTime` and `endTime` elements, and configures them to + * enforce date range limits. + * @param {Element} startTime + * @param {Element} endTime + * @param {Object} options Options for the `timepicker()` call. Also supports `reformat`, + * a boolean value that can be used to reformat the input values to the `dateFormat`. + * @return {jQuery} + */ + $.timepicker.dateRange = function (startTime, endTime, options) { + $.timepicker.handleRange('datepicker', startTime, endTime, options); + }; + + /** + * Calls `method` on the `startTime` and `endTime` elements, and configures them to + * enforce date range limits. + * @param {string} method Can be used to specify the type of picker to be added + * @param {Element} startTime + * @param {Element} endTime + * @param {Object} options Options for the `timepicker()` call. Also supports `reformat`, + * a boolean value that can be used to reformat the input values to the `dateFormat`. + * @return {jQuery} + */ + $.timepicker.handleRange = function (method, startTime, endTime, options) { + options = $.extend({}, { + minInterval: 0, // min allowed interval in milliseconds + maxInterval: 0, // max allowed interval in milliseconds + start: {}, // options for start picker + end: {} // options for end picker + }, options); + + function checkDates(changed, other) { + var startdt = startTime[method]('getDate'), + enddt = endTime[method]('getDate'), + changeddt = changed[method]('getDate'); + + if (startdt !== null) { + var minDate = new Date(startdt.getTime()), + maxDate = new Date(startdt.getTime()); + + minDate.setMilliseconds(minDate.getMilliseconds() + options.minInterval); + maxDate.setMilliseconds(maxDate.getMilliseconds() + options.maxInterval); + + if (options.minInterval > 0 && minDate > enddt) { // minInterval check + endTime[method]('setDate', minDate); + } + else if (options.maxInterval > 0 && maxDate < enddt) { // max interval check + endTime[method]('setDate', maxDate); + } + else if (startdt > enddt) { + other[method]('setDate', changeddt); + } + } + } + + function selected(changed, other, option) { + if (!changed.val()) { + return; + } + var date = changed[method].call(changed, 'getDate'); + if (date !== null && options.minInterval > 0) { + if (option === 'minDate') { + date.setMilliseconds(date.getMilliseconds() + options.minInterval); + } + if (option === 'maxDate') { + date.setMilliseconds(date.getMilliseconds() - options.minInterval); + } + } + if (date.getTime) { + other[method].call(other, 'option', option, date); + } + } + + $.fn[method].call(startTime, $.extend({ + onClose: function (dateText, inst) { + checkDates($(this), endTime); + }, + onSelect: function (selectedDateTime) { + selected($(this), endTime, 'minDate'); + } + }, options, options.start)); + $.fn[method].call(endTime, $.extend({ + onClose: function (dateText, inst) { + checkDates($(this), startTime); + }, + onSelect: function (selectedDateTime) { + selected($(this), startTime, 'maxDate'); + } + }, options, options.end)); + + checkDates(startTime, endTime); + selected(startTime, endTime, 'minDate'); + selected(endTime, startTime, 'maxDate'); + return $([startTime.get(0), endTime.get(0)]); + }; + + /** + * Log error or data to the console during error or debugging + * @param {Object} err pass any type object to log to the console during error or debugging + * @return {void} + */ + $.timepicker.log = function (err) { + if (window.console) { + window.console.log(err); + } + }; + + /* + * Add util object to allow access to private methods for testability. + */ + $.timepicker._util = { + _extendRemove: extendRemove, + _isEmptyObject: isEmptyObject, + _convert24to12: convert24to12, + _detectSupport: detectSupport, + _selectLocalTimezone: selectLocalTimezone, + _computeEffectiveSetting: computeEffectiveSetting, + _splitDateTime: splitDateTime, + _parseDateTimeInternal: parseDateTimeInternal + }; + + /* + * Microsecond support + */ + if (!Date.prototype.getMicroseconds) { + Date.prototype.microseconds = 0; + Date.prototype.getMicroseconds = function () { return this.microseconds; }; + Date.prototype.setMicroseconds = function (m) { + this.setMilliseconds(this.getMilliseconds() + Math.floor(m / 1000)); + this.microseconds = m % 1000; + return this; + }; + } + + /* + * Keep up with the version + */ + $.timepicker.version = "1.4.3"; + +})); diff --git a/lib/web/jquery/ui-modules/tooltip.js b/lib/web/jquery/ui-modules/tooltip.js new file mode 100644 index 000000000000..2d0431711dcd --- /dev/null +++ b/lib/web/jquery/ui-modules/tooltip.js @@ -0,0 +1,387 @@ +(function( $ ) { + + var increments = 0; + + function addDescribedBy( elem, id ) { + var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ); + describedby.push( id ); + elem + .data( "ui-tooltip-id", id ) + .attr( "aria-describedby", $.trim( describedby.join( " " ) ) ); + } + + function removeDescribedBy( 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 = $.trim( describedby.join( " " ) ); + if ( describedby ) { + elem.attr( "aria-describedby", describedby ); + } else { + elem.removeAttr( "aria-describedby" ); + } + } + + $.widget( "ui.tooltip", { + version: "1.10.4", + options: { + content: function() { + // support: IE<9, Opera in jQuery <1.7 + // .text() can't accept undefined, so coerce to a string + 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, + tooltipClass: null, + track: false, + + // callbacks + close: null, + open: null + }, + + _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 = {}; + + if ( this.options.disabled ) { + this._disable(); + } + }, + + _setOption: function( key, value ) { + var that = this; + + if ( key === "disabled" ) { + this[ value ? "_disable" : "_enable" ](); + this.options[ key ] = value; + // disable element style changes + return; + } + + this._super( key, value ); + + if ( key === "content" ) { + $.each( this.tooltips, function( id, element ) { + that._updateContent( element ); + }); + } + }, + + _disable: function() { + var that = this; + + // close open tooltips + $.each( this.tooltips, function( id, element ) { + var event = $.Event( "blur" ); + event.target = event.currentTarget = element[0]; + that.close( event, true ); + }); + + // remove title attributes to prevent native tooltips + this.element.find( this.options.items ).addBack().each(function() { + var element = $( this ); + if ( element.is( "[title]" ) ) { + element + .data( "ui-tooltip-title", element.attr( "title" ) ) + .attr( "title", "" ); + } + }); + }, + + _enable: function() { + // restore title attributes + this.element.find( this.options.items ).addBack().each(function() { + var element = $( this ); + if ( element.data( "ui-tooltip-title" ) ) { + element.attr( "title", element.data( "ui-tooltip-title" ) ); + } + }); + }, + + 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._updateContent( target, event ); + }, + + _updateContent: function( target, event ) { + var content, + contentOption = this.options.content, + that = this, + eventType = event ? event.type : null; + + if ( typeof contentOption === "string" ) { + return this._open( event, target, contentOption ); + } + + content = contentOption.call( target[0], function( response ) { + // ignore async response if tooltip was closed already + if ( !target.data( "ui-tooltip-open" ) ) { + return; + } + // 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() { + // 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 tooltip, events, delayedShow, + 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. + tooltip = this._find( target ); + if ( tooltip.length ) { + 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" ); + } + } + + tooltip = this._tooltip( target ); + addDescribedBy( target, tooltip.attr( "id" ) ); + tooltip.find( ".ui-tooltip-content" ).html( content ); + + 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. + if ( this.options.show && this.options.show.delay ) { + delayedShow = this.delayedShow = setInterval(function() { + if ( tooltip.is( ":visible" ) ) { + position( positionOption.of ); + clearInterval( delayedShow ); + } + }, $.fx.interval ); + } + + this._trigger( "open", event, { tooltip: tooltip } ); + + events = { + keyup: function( event ) { + if ( event.keyCode === $.ui.keyCode.ESCAPE ) { + var fakeEvent = $.Event(event); + fakeEvent.currentTarget = target[0]; + this.close( fakeEvent, true ); + } + }, + remove: function() { + this._removeTooltip( 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 that = this, + target = $( event ? event.currentTarget : this.element ), + tooltip = this._find( target ); + + // 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 ( this.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 ( target.data( "ui-tooltip-title" ) ) { + target.attr( "title", target.data( "ui-tooltip-title" ) ); + } + + removeDescribedBy( target ); + + 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 ]; + }); + } + + this.closing = true; + this._trigger( "close", event, { tooltip: tooltip } ); + this.closing = false; + }, + + _tooltip: function( element ) { + var id = "ui-tooltip-" + increments++, + tooltip = $( "<div>" ) + .attr({ + id: id, + role: "tooltip" + }) + .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " + + ( this.options.tooltipClass || "" ) ); + $( "<div>" ) + .addClass( "ui-tooltip-content" ) + .appendTo( tooltip ); + tooltip.appendTo( this.document[0].body ); + this.tooltips[ id ] = element; + return tooltip; + }, + + _find: function( target ) { + var id = target.data( "ui-tooltip-id" ); + return id ? $( "#" + id ) : $(); + }, + + _removeTooltip: function( tooltip ) { + tooltip.remove(); + delete this.tooltips[ tooltip.attr( "id" ) ]; + }, + + _destroy: function() { + var that = this; + + // close open tooltips + $.each( this.tooltips, function( id, element ) { + // Delegate to close method to handle common cleanup + var event = $.Event( "blur" ); + 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" ) ) { + element.attr( "title", element.data( "ui-tooltip-title" ) ); + element.removeData( "ui-tooltip-title" ); + } + }); + } + }); + +}( jQuery ) ); From c3b94947f49360befd0105b8c5efed563b441246 Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Thu, 27 Jun 2019 18:12:23 -0500 Subject: [PATCH 009/191] MC-17868: Break jQuery UI into widgets and make a prototype - Add widget module; --- lib/web/jquery/ui-modules/core.js | 512 ---------------------------- lib/web/jquery/ui-modules/widget.js | 511 +++++++++++++++++++++++++++ 2 files changed, 511 insertions(+), 512 deletions(-) create mode 100644 lib/web/jquery/ui-modules/widget.js diff --git a/lib/web/jquery/ui-modules/core.js b/lib/web/jquery/ui-modules/core.js index 3a0f1c32cbe4..d4d325c51a4e 100644 --- a/lib/web/jquery/ui-modules/core.js +++ b/lib/web/jquery/ui-modules/core.js @@ -308,515 +308,3 @@ }); })( jQuery ); - -(function( $, undefined ) { - - var uuid = 0, - slice = Array.prototype.slice, - _cleanData = $.cleanData; - $.cleanData = function( elems ) { - for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { - try { - $( elem ).triggerHandler( "remove" ); - // http://bugs.jquery.com/ticket/8235 - } catch( e ) {} - } - _cleanData( elems ); - }; - - $.widget = function( name, base, prototype ) { - var fullName, existingConstructor, constructor, basePrototype, - // proxiedPrototype allows the provided prototype to remain unmodified - // so that it can be used as a mixin for multiple widgets (#8876) - proxiedPrototype = {}, - namespace = name.split( "." )[ 0 ]; - - name = name.split( "." )[ 1 ]; - fullName = namespace + "-" + name; - - if ( !prototype ) { - prototype = base; - base = $.Widget; - } - - // create selector for plugin - $.expr[ ":" ][ 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._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 ( !$.isFunction( value ) ) { - proxiedPrototype[ prop ] = value; - return; - } - proxiedPrototype[ prop ] = (function() { - var _super = function() { - return base.prototype[ prop ].apply( this, arguments ); - }, - _superApply = function( args ) { - return base.prototype[ prop ].apply( this, args ); - }; - return function() { - var __super = this._super, - __superApply = this._superApply, - 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 ); - }; - - $.widget.extend = function( target ) { - var input = slice.call( arguments, 1 ), - inputIndex = 0, - inputLength = input.length, - key, - value; - for ( ; inputIndex < inputLength; inputIndex++ ) { - for ( key in input[ inputIndex ] ) { - value = input[ inputIndex ][ key ]; - if ( input[ inputIndex ].hasOwnProperty( 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", - args = slice.call( arguments, 1 ), - returnValue = this; - - // allow multiple hashes to be passed on init - options = !isMethodCall && args.length ? - $.widget.extend.apply( null, [ options ].concat(args) ) : - options; - - if ( isMethodCall ) { - this.each(function() { - var methodValue, - instance = $.data( this, fullName ); - if ( !instance ) { - return $.error( "cannot call methods on " + name + " prior to initialization; " + - "attempted to call method '" + options + "'" ); - } - if ( !$.isFunction( instance[options] ) || 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 { - this.each(function() { - var instance = $.data( this, fullName ); - if ( instance ) { - instance.option( options || {} )._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: { - disabled: false, - - // callbacks - create: null - }, - _createWidget: function( options, element ) { - element = $( element || this.defaultElement || this )[ 0 ]; - this.element = $( element ); - this.uuid = uuid++; - this.eventNamespace = "." + this.widgetName + this.uuid; - this.options = $.widget.extend( {}, - this.options, - this._getCreateOptions(), - options ); - - this.bindings = $(); - this.hoverable = $(); - this.focusable = $(); - - 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._create(); - this._trigger( "create", null, this._getCreateEventData() ); - this._init(); - }, - _getCreateOptions: $.noop, - _getCreateEventData: $.noop, - _create: $.noop, - _init: $.noop, - - destroy: function() { - this._destroy(); - // we can probably remove the unbind calls in 2.0 - // all event bindings should go through this._on() - this.element - .unbind( this.eventNamespace ) - // 1.9 BC for #7810 - // TODO remove dual storage - .removeData( this.widgetName ) - .removeData( this.widgetFullName ) - // support: jquery <1.6.3 - // http://bugs.jquery.com/ticket/9413 - .removeData( $.camelCase( this.widgetFullName ) ); - this.widget() - .unbind( this.eventNamespace ) - .removeAttr( "aria-disabled" ) - .removeClass( - this.widgetFullName + "-disabled " + - "ui-state-disabled" ); - - // clean up events and states - this.bindings.unbind( this.eventNamespace ); - this.hoverable.removeClass( "ui-state-hover" ); - this.focusable.removeClass( "ui-state-focus" ); - }, - _destroy: $.noop, - - widget: function() { - return this.element; - }, - - option: function( key, value ) { - var options = key, - parts, - curOption, - 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 ) { - this.options[ key ] = value; - - if ( key === "disabled" ) { - this.widget() - .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value ) - .attr( "aria-disabled", value ); - this.hoverable.removeClass( "ui-state-hover" ); - this.focusable.removeClass( "ui-state-focus" ); - } - - return this; - }, - - enable: function() { - return this._setOption( "disabled", false ); - }, - disable: function() { - return this._setOption( "disabled", true ); - }, - - _on: function( suppressDisabledCheck, element, handlers ) { - var delegateElement, - 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 { - // accept selectors, DOM elements - 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*(.*)$/ ), - eventName = match[1] + instance.eventNamespace, - selector = match[2]; - if ( selector ) { - delegateElement.delegate( selector, eventName, handlerProxy ); - } else { - element.bind( eventName, handlerProxy ); - } - }); - }, - - _off: function( element, eventName ) { - eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace; - element.unbind( eventName ).undelegate( eventName ); - }, - - _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 ) { - $( event.currentTarget ).addClass( "ui-state-hover" ); - }, - mouseleave: function( event ) { - $( event.currentTarget ).removeClass( "ui-state-hover" ); - } - }); - }, - - _focusable: function( element ) { - this.focusable = this.focusable.add( element ); - this._on( element, { - focusin: function( event ) { - $( event.currentTarget ).addClass( "ui-state-focus" ); - }, - focusout: function( event ) { - $( event.currentTarget ).removeClass( "ui-state-focus" ); - } - }); - }, - - _trigger: function( type, event, data ) { - var prop, orig, - 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 !( $.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, - 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(); - }); - } - }; - }); - -})( jQuery ); diff --git a/lib/web/jquery/ui-modules/widget.js b/lib/web/jquery/ui-modules/widget.js new file mode 100644 index 000000000000..a86c587ad81c --- /dev/null +++ b/lib/web/jquery/ui-modules/widget.js @@ -0,0 +1,511 @@ +(function( $, undefined ) { + + var uuid = 0, + slice = Array.prototype.slice, + _cleanData = $.cleanData; + $.cleanData = function( elems ) { + for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { + try { + $( elem ).triggerHandler( "remove" ); + // http://bugs.jquery.com/ticket/8235 + } catch( e ) {} + } + _cleanData( elems ); + }; + + $.widget = function( name, base, prototype ) { + var fullName, existingConstructor, constructor, basePrototype, + // proxiedPrototype allows the provided prototype to remain unmodified + // so that it can be used as a mixin for multiple widgets (#8876) + proxiedPrototype = {}, + namespace = name.split( "." )[ 0 ]; + + name = name.split( "." )[ 1 ]; + fullName = namespace + "-" + name; + + if ( !prototype ) { + prototype = base; + base = $.Widget; + } + + // create selector for plugin + $.expr[ ":" ][ 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._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 ( !$.isFunction( value ) ) { + proxiedPrototype[ prop ] = value; + return; + } + proxiedPrototype[ prop ] = (function() { + var _super = function() { + return base.prototype[ prop ].apply( this, arguments ); + }, + _superApply = function( args ) { + return base.prototype[ prop ].apply( this, args ); + }; + return function() { + var __super = this._super, + __superApply = this._superApply, + 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 ); + }; + + $.widget.extend = function( target ) { + var input = slice.call( arguments, 1 ), + inputIndex = 0, + inputLength = input.length, + key, + value; + for ( ; inputIndex < inputLength; inputIndex++ ) { + for ( key in input[ inputIndex ] ) { + value = input[ inputIndex ][ key ]; + if ( input[ inputIndex ].hasOwnProperty( 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", + args = slice.call( arguments, 1 ), + returnValue = this; + + // allow multiple hashes to be passed on init + options = !isMethodCall && args.length ? + $.widget.extend.apply( null, [ options ].concat(args) ) : + options; + + if ( isMethodCall ) { + this.each(function() { + var methodValue, + instance = $.data( this, fullName ); + if ( !instance ) { + return $.error( "cannot call methods on " + name + " prior to initialization; " + + "attempted to call method '" + options + "'" ); + } + if ( !$.isFunction( instance[options] ) || 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 { + this.each(function() { + var instance = $.data( this, fullName ); + if ( instance ) { + instance.option( options || {} )._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: { + disabled: false, + + // callbacks + create: null + }, + _createWidget: function( options, element ) { + element = $( element || this.defaultElement || this )[ 0 ]; + this.element = $( element ); + this.uuid = uuid++; + this.eventNamespace = "." + this.widgetName + this.uuid; + this.options = $.widget.extend( {}, + this.options, + this._getCreateOptions(), + options ); + + this.bindings = $(); + this.hoverable = $(); + this.focusable = $(); + + 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._create(); + this._trigger( "create", null, this._getCreateEventData() ); + this._init(); + }, + _getCreateOptions: $.noop, + _getCreateEventData: $.noop, + _create: $.noop, + _init: $.noop, + + destroy: function() { + this._destroy(); + // we can probably remove the unbind calls in 2.0 + // all event bindings should go through this._on() + this.element + .unbind( this.eventNamespace ) + // 1.9 BC for #7810 + // TODO remove dual storage + .removeData( this.widgetName ) + .removeData( this.widgetFullName ) + // support: jquery <1.6.3 + // http://bugs.jquery.com/ticket/9413 + .removeData( $.camelCase( this.widgetFullName ) ); + this.widget() + .unbind( this.eventNamespace ) + .removeAttr( "aria-disabled" ) + .removeClass( + this.widgetFullName + "-disabled " + + "ui-state-disabled" ); + + // clean up events and states + this.bindings.unbind( this.eventNamespace ); + this.hoverable.removeClass( "ui-state-hover" ); + this.focusable.removeClass( "ui-state-focus" ); + }, + _destroy: $.noop, + + widget: function() { + return this.element; + }, + + option: function( key, value ) { + var options = key, + parts, + curOption, + 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 ) { + this.options[ key ] = value; + + if ( key === "disabled" ) { + this.widget() + .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value ) + .attr( "aria-disabled", value ); + this.hoverable.removeClass( "ui-state-hover" ); + this.focusable.removeClass( "ui-state-focus" ); + } + + return this; + }, + + enable: function() { + return this._setOption( "disabled", false ); + }, + disable: function() { + return this._setOption( "disabled", true ); + }, + + _on: function( suppressDisabledCheck, element, handlers ) { + var delegateElement, + 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 { + // accept selectors, DOM elements + 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*(.*)$/ ), + eventName = match[1] + instance.eventNamespace, + selector = match[2]; + if ( selector ) { + delegateElement.delegate( selector, eventName, handlerProxy ); + } else { + element.bind( eventName, handlerProxy ); + } + }); + }, + + _off: function( element, eventName ) { + eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace; + element.unbind( eventName ).undelegate( eventName ); + }, + + _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 ) { + $( event.currentTarget ).addClass( "ui-state-hover" ); + }, + mouseleave: function( event ) { + $( event.currentTarget ).removeClass( "ui-state-hover" ); + } + }); + }, + + _focusable: function( element ) { + this.focusable = this.focusable.add( element ); + this._on( element, { + focusin: function( event ) { + $( event.currentTarget ).addClass( "ui-state-focus" ); + }, + focusout: function( event ) { + $( event.currentTarget ).removeClass( "ui-state-focus" ); + } + }); + }, + + _trigger: function( type, event, data ) { + var prop, orig, + 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 !( $.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, + 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(); + }); + } + }; + }); + +})( jQuery ); From 1c5f3a1f5c4f0c5ee63c9ecae41171720cff33ad Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Fri, 28 Jun 2019 14:51:57 -0500 Subject: [PATCH 010/191] MC-17868: Break jQuery UI into widgets and make a prototype - Require dependencies in ui widgets; --- lib/web/jquery/ui-modules/accordion.js | 400 ++++---- lib/web/jquery/ui-modules/autocomplete.js | 412 ++++---- lib/web/jquery/ui-modules/button.js | 364 +++---- lib/web/jquery/ui-modules/core.js | 245 ++--- lib/web/jquery/ui-modules/datepicker.js | 482 ++++----- lib/web/jquery/ui-modules/dialog.js | 456 ++++----- lib/web/jquery/ui-modules/draggable.js | 422 ++++---- lib/web/jquery/ui-modules/droppable.js | 158 +-- lib/web/jquery/ui-modules/effect-blind.js | 72 +- lib/web/jquery/ui-modules/effect-bounce.js | 96 +- lib/web/jquery/ui-modules/effect-clip.js | 53 +- lib/web/jquery/ui-modules/effect-drop.js | 58 +- lib/web/jquery/ui-modules/effect-explode.js | 64 +- lib/web/jquery/ui-modules/effect-fade.js | 27 +- lib/web/jquery/ui-modules/effect-fold.js | 61 +- lib/web/jquery/ui-modules/effect-highlight.js | 38 +- lib/web/jquery/ui-modules/effect-puff.js | 192 ++-- lib/web/jquery/ui-modules/effect-pulsate.js | 46 +- lib/web/jquery/ui-modules/effect-shake.js | 62 +- lib/web/jquery/ui-modules/effect-slide.js | 52 +- lib/web/jquery/ui-modules/effect-transfer.js | 42 +- lib/web/jquery/ui-modules/effect.js | 914 +++++++++--------- lib/web/jquery/ui-modules/menu.js | 520 +++++----- lib/web/jquery/ui-modules/mouse.js | 82 +- lib/web/jquery/ui-modules/position.js | 316 +++--- lib/web/jquery/ui-modules/progressbar.js | 103 +- lib/web/jquery/ui-modules/resizable.js | 303 +++--- lib/web/jquery/ui-modules/selectable.js | 60 +- lib/web/jquery/ui-modules/slider.js | 472 ++++----- lib/web/jquery/ui-modules/sortable.js | 529 +++++----- lib/web/jquery/ui-modules/spinner.js | 371 +++---- lib/web/jquery/ui-modules/tabs.js | 627 ++++++------ lib/web/jquery/ui-modules/timepicker.js | 140 +-- lib/web/jquery/ui-modules/tooltip.js | 325 ++++--- lib/web/jquery/ui-modules/widget.js | 408 ++++---- 35 files changed, 4829 insertions(+), 4143 deletions(-) diff --git a/lib/web/jquery/ui-modules/accordion.js b/lib/web/jquery/ui-modules/accordion.js index c9d6b4b46aa5..7da6ace8d896 100644 --- a/lib/web/jquery/ui-modules/accordion.js +++ b/lib/web/jquery/ui-modules/accordion.js @@ -7,12 +7,13 @@ * http://jquery.org/license * * http://api.jqueryui.com/accordion/ - * - * Depends: - * jquery.ui.core.js - * jquery.ui.widget.js */ -(function( $, undefined ) { + +define([ + 'jquery', + 'jquery-ui-modules/core', + 'jquery-ui-modules/widget' +], function ($, undefined) { var uid = 0, hideProps = {}, @@ -23,7 +24,7 @@ showProps.height = showProps.paddingTop = showProps.paddingBottom = showProps.borderTopWidth = showProps.borderBottomWidth = "show"; - $.widget( "ui.accordion", { + $.widget("ui.accordion", { version: "1.10.4", options: { active: 0, @@ -42,27 +43,27 @@ beforeActivate: null }, - _create: function() { + _create: function () { var options = this.options; this.prevShow = this.prevHide = $(); - this.element.addClass( "ui-accordion ui-widget ui-helper-reset" ) + this.element.addClass("ui-accordion ui-widget ui-helper-reset") // ARIA - .attr( "role", "tablist" ); + .attr("role", "tablist"); // don't allow collapsible: false and active: false / null - if ( !options.collapsible && (options.active === false || options.active == null) ) { + if (!options.collapsible && (options.active === false || options.active == null)) { options.active = 0; } this._processPanels(); // handle negative values - if ( options.active < 0 ) { + if (options.active < 0) { options.active += this.headers.length; } this._refresh(); }, - _getCreateEventData: function() { + _getCreateEventData: function () { return { header: this.active, panel: !this.active.length ? $() : this.active.next(), @@ -70,172 +71,172 @@ }; }, - _createIcons: function() { + _createIcons: function () { var icons = this.options.icons; - if ( icons ) { - $( "<span>" ) - .addClass( "ui-accordion-header-icon ui-icon " + icons.header ) - .prependTo( this.headers ); - this.active.children( ".ui-accordion-header-icon" ) - .removeClass( icons.header ) - .addClass( icons.activeHeader ); - this.headers.addClass( "ui-accordion-icons" ); + if (icons) { + $("<span>") + .addClass("ui-accordion-header-icon ui-icon " + icons.header) + .prependTo(this.headers); + this.active.children(".ui-accordion-header-icon") + .removeClass(icons.header) + .addClass(icons.activeHeader); + this.headers.addClass("ui-accordion-icons"); } }, - _destroyIcons: function() { + _destroyIcons: function () { this.headers - .removeClass( "ui-accordion-icons" ) - .children( ".ui-accordion-header-icon" ) + .removeClass("ui-accordion-icons") + .children(".ui-accordion-header-icon") .remove(); }, - _destroy: function() { + _destroy: function () { var contents; // clean up main element this.element - .removeClass( "ui-accordion ui-widget ui-helper-reset" ) - .removeAttr( "role" ); + .removeClass("ui-accordion ui-widget ui-helper-reset") + .removeAttr("role"); // clean up headers this.headers - .removeClass( "ui-accordion-header ui-accordion-header-active ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top" ) - .removeAttr( "role" ) - .removeAttr( "aria-expanded" ) - .removeAttr( "aria-selected" ) - .removeAttr( "aria-controls" ) - .removeAttr( "tabIndex" ) - .each(function() { - if ( /^ui-accordion/.test( this.id ) ) { - this.removeAttribute( "id" ); + .removeClass("ui-accordion-header ui-accordion-header-active ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top") + .removeAttr("role") + .removeAttr("aria-expanded") + .removeAttr("aria-selected") + .removeAttr("aria-controls") + .removeAttr("tabIndex") + .each(function () { + if (/^ui-accordion/.test(this.id)) { + this.removeAttribute("id"); } }); this._destroyIcons(); // clean up content panels contents = this.headers.next() - .css( "display", "" ) - .removeAttr( "role" ) - .removeAttr( "aria-hidden" ) - .removeAttr( "aria-labelledby" ) - .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled" ) - .each(function() { - if ( /^ui-accordion/.test( this.id ) ) { - this.removeAttribute( "id" ); + .css("display", "") + .removeAttr("role") + .removeAttr("aria-hidden") + .removeAttr("aria-labelledby") + .removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled") + .each(function () { + if (/^ui-accordion/.test(this.id)) { + this.removeAttribute("id"); } }); - if ( this.options.heightStyle !== "content" ) { - contents.css( "height", "" ); + if (this.options.heightStyle !== "content") { + contents.css("height", ""); } }, - _setOption: function( key, value ) { - if ( key === "active" ) { + _setOption: function (key, value) { + if (key === "active") { // _activate() will handle invalid values and update this.options - this._activate( value ); + this._activate(value); return; } - if ( key === "event" ) { - if ( this.options.event ) { - this._off( this.headers, this.options.event ); + if (key === "event") { + if (this.options.event) { + this._off(this.headers, this.options.event); } - this._setupEvents( value ); + this._setupEvents(value); } - this._super( key, 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 === "collapsible" && !value && this.options.active === false) { + this._activate(0); } - if ( key === "icons" ) { + if (key === "icons") { this._destroyIcons(); - if ( value ) { + if (value) { this._createIcons(); } } // #5332 - opacity doesn't cascade to positioned elements in IE // so we need to add the disabled class to the headers and panels - if ( key === "disabled" ) { - this.headers.add( this.headers.next() ) - .toggleClass( "ui-state-disabled", !!value ); + if (key === "disabled") { + this.headers.add(this.headers.next()) + .toggleClass("ui-state-disabled", !!value); } }, - _keydown: function( event ) { - if ( event.altKey || event.ctrlKey ) { + _keydown: function (event) { + if (event.altKey || event.ctrlKey) { return; } var keyCode = $.ui.keyCode, length = this.headers.length, - currentIndex = this.headers.index( event.target ), + currentIndex = this.headers.index(event.target), toFocus = false; - switch ( event.keyCode ) { + switch (event.keyCode) { case keyCode.RIGHT: case keyCode.DOWN: - toFocus = this.headers[ ( currentIndex + 1 ) % length ]; + toFocus = this.headers[(currentIndex + 1) % length]; break; case keyCode.LEFT: case keyCode.UP: - toFocus = this.headers[ ( currentIndex - 1 + length ) % length ]; + toFocus = this.headers[(currentIndex - 1 + length) % length]; break; case keyCode.SPACE: case keyCode.ENTER: - this._eventHandler( event ); + this._eventHandler(event); break; case keyCode.HOME: - toFocus = this.headers[ 0 ]; + toFocus = this.headers[0]; break; case keyCode.END: - toFocus = this.headers[ length - 1 ]; + toFocus = this.headers[length - 1]; break; } - if ( toFocus ) { - $( event.target ).attr( "tabIndex", -1 ); - $( toFocus ).attr( "tabIndex", 0 ); + if (toFocus) { + $(event.target).attr("tabIndex", -1); + $(toFocus).attr("tabIndex", 0); toFocus.focus(); event.preventDefault(); } }, - _panelKeyDown : function( event ) { - if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) { - $( event.currentTarget ).prev().focus(); + _panelKeyDown: function (event) { + if (event.keyCode === $.ui.keyCode.UP && event.ctrlKey) { + $(event.currentTarget).prev().focus(); } }, - refresh: function() { + refresh: function () { var options = this.options; this._processPanels(); // was collapsed or no panel - if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) { + 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 ); + } 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 ] ) ) { + } 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 ) { + 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 ) ); + 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 ); + options.active = this.headers.index(this.active); } this._destroyIcons(); @@ -243,54 +244,54 @@ this._refresh(); }, - _processPanels: function() { - this.headers = this.element.find( this.options.header ) - .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" ); + _processPanels: function () { + this.headers = this.element.find(this.options.header) + .addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all"); this.headers.next() - .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" ) + .addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom") .filter(":not(.ui-accordion-content-active)") .hide(); }, - _refresh: function() { + _refresh: function () { var maxHeight, options = this.options, heightStyle = options.heightStyle, parent = this.element.parent(), accordionId = this.accordionId = "ui-accordion-" + - (this.element.attr( "id" ) || ++uid); + (this.element.attr("id") || ++uid); - this.active = this._findActive( options.active ) - .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ) - .removeClass( "ui-corner-all" ); + this.active = this._findActive(options.active) + .addClass("ui-accordion-header-active ui-state-active ui-corner-top") + .removeClass("ui-corner-all"); this.active.next() - .addClass( "ui-accordion-content-active" ) + .addClass("ui-accordion-content-active") .show(); this.headers - .attr( "role", "tab" ) - .each(function( i ) { - var header = $( this ), - headerId = header.attr( "id" ), + .attr("role", "tab") + .each(function (i) { + var header = $(this), + headerId = header.attr("id"), panel = header.next(), - panelId = panel.attr( "id" ); - if ( !headerId ) { + panelId = panel.attr("id"); + if (!headerId) { headerId = accordionId + "-header-" + i; - header.attr( "id", headerId ); + header.attr("id", headerId); } - if ( !panelId ) { + if (!panelId) { panelId = accordionId + "-panel-" + i; - panel.attr( "id", panelId ); + panel.attr("id", panelId); } - header.attr( "aria-controls", panelId ); - panel.attr( "aria-labelledby", headerId ); + header.attr("aria-controls", panelId); + panel.attr("aria-labelledby", headerId); }) .next() - .attr( "role", "tabpanel" ); + .attr("role", "tabpanel"); this.headers - .not( this.active ) + .not(this.active) .attr({ "aria-selected": "false", "aria-expanded": "false", @@ -303,8 +304,8 @@ .hide(); // make sure at least one header is in the tab order - if ( !this.active.length ) { - this.headers.eq( 0 ).attr( "tabIndex", 0 ); + if (!this.active.length) { + this.headers.eq(0).attr("tabIndex", 0); } else { this.active.attr({ "aria-selected": "true", @@ -319,50 +320,50 @@ this._createIcons(); - this._setupEvents( options.event ); + this._setupEvents(options.event); - if ( heightStyle === "fill" ) { + if (heightStyle === "fill") { maxHeight = parent.height(); - this.element.siblings( ":visible" ).each(function() { - var elem = $( this ), - position = elem.css( "position" ); + this.element.siblings(":visible").each(function () { + var elem = $(this), + position = elem.css("position"); - if ( position === "absolute" || position === "fixed" ) { + if (position === "absolute" || position === "fixed") { return; } - maxHeight -= elem.outerHeight( true ); + maxHeight -= elem.outerHeight(true); }); - this.headers.each(function() { - maxHeight -= $( this ).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() ) ); + .each(function () { + $(this).height(Math.max(0, maxHeight - + $(this).innerHeight() + $(this).height())); }) - .css( "overflow", "auto" ); - } else if ( heightStyle === "auto" ) { + .css("overflow", "auto"); + } else if (heightStyle === "auto") { maxHeight = 0; this.headers.next() - .each(function() { - maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() ); + .each(function () { + maxHeight = Math.max(maxHeight, $(this).css("height", "").height()); }) - .height( maxHeight ); + .height(maxHeight); } }, - _activate: function( index ) { - var active = this._findActive( index )[ 0 ]; + _activate: function (index) { + var active = this._findActive(index)[0]; // trying to activate the already active panel - if ( active === this.active[ 0 ] ) { + if (active === this.active[0]) { return; } // trying to collapse, simulate a click on the currently active header - active = active || this.active[ 0 ]; + active = active || this.active[0]; this._eventHandler({ target: active, @@ -371,32 +372,32 @@ }); }, - _findActive: function( selector ) { - return typeof selector === "number" ? this.headers.eq( selector ) : $(); + _findActive: function (selector) { + return typeof selector === "number" ? this.headers.eq(selector) : $(); }, - _setupEvents: function( event ) { + _setupEvents: function (event) { var events = { keydown: "_keydown" }; - if ( event ) { - $.each( event.split(" "), function( index, eventName ) { - events[ eventName ] = "_eventHandler"; + 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 ); + 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 ) { + _eventHandler: function (event) { var options = this.options, active = this.active, - clicked = $( event.currentTarget ), - clickedIsActive = clicked[ 0 ] === active[ 0 ], + clicked = $(event.currentTarget), + clickedIsActive = clicked[0] === active[0], collapsing = clickedIsActive && options.collapsible, toShow = collapsing ? $() : clicked.next(), toHide = active.next(), @@ -411,82 +412,82 @@ if ( // click on active header, but not collapsible - ( clickedIsActive && !options.collapsible ) || + (clickedIsActive && !options.collapsible) || // allow canceling activation - ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { + (this._trigger("beforeActivate", event, eventData) === false)) { return; } - options.active = collapsing ? false : this.headers.index( clicked ); + 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 ); + this._toggle(eventData); // switch classes // corner classes on the previously active header stay after the animation - active.removeClass( "ui-accordion-header-active ui-state-active" ); - if ( options.icons ) { - active.children( ".ui-accordion-header-icon" ) - .removeClass( options.icons.activeHeader ) - .addClass( options.icons.header ); + active.removeClass("ui-accordion-header-active ui-state-active"); + if (options.icons) { + active.children(".ui-accordion-header-icon") + .removeClass(options.icons.activeHeader) + .addClass(options.icons.header); } - if ( !clickedIsActive ) { + if (!clickedIsActive) { clicked - .removeClass( "ui-corner-all" ) - .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ); - if ( options.icons ) { - clicked.children( ".ui-accordion-header-icon" ) - .removeClass( options.icons.header ) - .addClass( options.icons.activeHeader ); + .removeClass("ui-corner-all") + .addClass("ui-accordion-header-active ui-state-active ui-corner-top"); + if (options.icons) { + clicked.children(".ui-accordion-header-icon") + .removeClass(options.icons.header) + .addClass(options.icons.activeHeader); } clicked .next() - .addClass( "ui-accordion-content-active" ); + .addClass("ui-accordion-content-active"); } }, - _toggle: function( data ) { + _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.add(this.prevHide).stop(true, true); this.prevShow = toShow; this.prevHide = toHide; - if ( this.options.animate ) { - this._animate( toShow, toHide, data ); + if (this.options.animate) { + this._animate(toShow, toHide, data); } else { toHide.hide(); toShow.show(); - this._toggleComplete( data ); + this._toggleComplete(data); } toHide.attr({ "aria-hidden": "true" }); - toHide.prev().attr( "aria-selected", "false" ); + toHide.prev().attr("aria-selected", "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 ) { + if (toShow.length && toHide.length) { toHide.prev().attr({ "tabIndex": -1, "aria-expanded": "false" }); - } else if ( toShow.length ) { - this.headers.filter(function() { - return $( this ).attr( "tabIndex" ) === 0; + } else if (toShow.length) { + this.headers.filter(function () { + return $(this).attr("tabIndex") === 0; }) - .attr( "tabIndex", -1 ); + .attr("tabIndex", -1); } toShow - .attr( "aria-hidden", "false" ) + .attr("aria-hidden", "false") .prev() .attr({ "aria-selected": "true", @@ -495,76 +496,75 @@ }); }, - _animate: function( toShow, toHide, data ) { + _animate: function (toShow, toHide, data) { var total, easing, duration, that = this, adjust = 0, down = toShow.length && - ( !toHide.length || ( toShow.index() < toHide.index() ) ), + (!toHide.length || (toShow.index() < toHide.index())), animate = this.options.animate || {}, options = down && animate.down || animate, - complete = function() { - that._toggleComplete( data ); + complete = function () { + that._toggleComplete(data); }; - if ( typeof options === "number" ) { + if (typeof options === "number") { duration = options; } - if ( typeof options === "string" ) { + 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( showProps, duration, easing, complete ); + if (!toHide.length) { + return toShow.animate(showProps, duration, easing, complete); } - if ( !toShow.length ) { - return toHide.animate( hideProps, duration, easing, complete ); + if (!toShow.length) { + return toHide.animate(hideProps, duration, easing, complete); } total = toShow.show().outerHeight(); - toHide.animate( hideProps, { + toHide.animate(hideProps, { duration: duration, easing: easing, - step: function( now, fx ) { - fx.now = Math.round( now ); + step: function (now, fx) { + fx.now = Math.round(now); } }); toShow .hide() - .animate( showProps, { + .animate(showProps, { duration: duration, easing: easing, complete: complete, - step: function( now, fx ) { - fx.now = Math.round( now ); - if ( fx.prop !== "height" ) { + step: function (now, fx) { + fx.now = Math.round(now); + if (fx.prop !== "height") { adjust += fx.now; - } else if ( that.options.heightStyle !== "content" ) { - fx.now = Math.round( total - toHide.outerHeight() - adjust ); + } else if (that.options.heightStyle !== "content") { + fx.now = Math.round(total - toHide.outerHeight() - adjust); adjust = 0; } } }); }, - _toggleComplete: function( data ) { + _toggleComplete: function (data) { var toHide = data.oldPanel; toHide - .removeClass( "ui-accordion-content-active" ) + .removeClass("ui-accordion-content-active") .prev() - .removeClass( "ui-corner-top" ) - .addClass( "ui-corner-all" ); + .removeClass("ui-corner-top") + .addClass("ui-corner-all"); // Work around for rendering bug in IE (#5421) - if ( toHide.length ) { + if (toHide.length) { toHide.parent()[0].className = toHide.parent()[0].className; } - this._trigger( "activate", null, data ); + this._trigger("activate", null, data); } }); - -})( jQuery ); +}); diff --git a/lib/web/jquery/ui-modules/autocomplete.js b/lib/web/jquery/ui-modules/autocomplete.js index af2e43503498..34f9d1b150c2 100644 --- a/lib/web/jquery/ui-modules/autocomplete.js +++ b/lib/web/jquery/ui-modules/autocomplete.js @@ -1,6 +1,23 @@ -(function( $, undefined ) { - - $.widget( "ui.autocomplete", { +/*! + * jQuery UI Autocomplete + * http://jqueryui.com + * + * Copyright 2014 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/autocomplete/ + */ + +define([ + 'jquery', + 'jquery-ui-modules/core', + 'jquery-ui-modules/widget', + 'jquery-ui-modules/position', + 'jquery-ui-modules/menu' +], function ($, undefined) { + + $.widget("ui.autocomplete", { version: "1.10.4", defaultElement: "<input>", options: { @@ -28,7 +45,7 @@ requestIndex: 0, pending: 0, - _create: function() { + _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 @@ -48,18 +65,18 @@ // IE also treats inputs as contentEditable isInput ? false : // All other element types are determined by whether or not they're contentEditable - this.element.prop( "isContentEditable" ); + this.element.prop("isContentEditable"); - this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ]; + this.valueMethod = this.element[isTextarea || isInput ? "val" : "text"]; this.isNewMenu = true; this.element - .addClass( "ui-autocomplete-input" ) - .attr( "autocomplete", "off" ); + .addClass("ui-autocomplete-input") + .attr("autocomplete", "off"); - this._on( this.element, { - keydown: function( event ) { - if ( this.element.prop( "readOnly" ) ) { + this._on(this.element, { + keydown: function (event) { + if (this.element.prop("readOnly")) { suppressKeyPress = true; suppressInput = true; suppressKeyPressRepeat = true; @@ -70,43 +87,43 @@ suppressInput = false; suppressKeyPressRepeat = false; var keyCode = $.ui.keyCode; - switch( event.keyCode ) { + switch (event.keyCode) { case keyCode.PAGE_UP: suppressKeyPress = true; - this._move( "previousPage", event ); + this._move("previousPage", event); break; case keyCode.PAGE_DOWN: suppressKeyPress = true; - this._move( "nextPage", event ); + this._move("nextPage", event); break; case keyCode.UP: suppressKeyPress = true; - this._keyEvent( "previous", event ); + this._keyEvent("previous", event); break; case keyCode.DOWN: suppressKeyPress = true; - this._keyEvent( "next", event ); + this._keyEvent("next", event); break; case keyCode.ENTER: case keyCode.NUMPAD_ENTER: // when menu is open and has focus - if ( this.menu.active ) { + 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 ); + this.menu.select(event); } break; case keyCode.TAB: - if ( this.menu.active ) { - this.menu.select( event ); + if (this.menu.active) { + this.menu.select(event); } break; case keyCode.ESCAPE: - if ( this.menu.element.is( ":visible" ) ) { - this._value( this.term ); - this.close( event ); + if (this.menu.element.is(":visible")) { + 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 @@ -116,83 +133,83 @@ default: suppressKeyPressRepeat = true; // search timeout should be triggered before the input value is changed - this._searchTimeout( event ); + this._searchTimeout(event); break; } }, - keypress: function( event ) { - if ( suppressKeyPress ) { + keypress: function (event) { + if (suppressKeyPress) { suppressKeyPress = false; - if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { + if (!this.isMultiLine || this.menu.element.is(":visible")) { event.preventDefault(); } return; } - if ( suppressKeyPressRepeat ) { + if (suppressKeyPressRepeat) { return; } // replicate some key handlers to allow them to repeat in Firefox and Opera var keyCode = $.ui.keyCode; - switch( event.keyCode ) { + switch (event.keyCode) { case keyCode.PAGE_UP: - this._move( "previousPage", event ); + this._move("previousPage", event); break; case keyCode.PAGE_DOWN: - this._move( "nextPage", event ); + this._move("nextPage", event); break; case keyCode.UP: - this._keyEvent( "previous", event ); + this._keyEvent("previous", event); break; case keyCode.DOWN: - this._keyEvent( "next", event ); + this._keyEvent("next", event); break; } }, - input: function( event ) { - if ( suppressInput ) { + input: function (event) { + if (suppressInput) { suppressInput = false; event.preventDefault(); return; } - this._searchTimeout( event ); + this._searchTimeout(event); }, - focus: function() { + focus: function () { this.selectedItem = null; this.previous = this._value(); }, - blur: function( event ) { - if ( this.cancelBlur ) { + blur: function (event) { + if (this.cancelBlur) { delete this.cancelBlur; return; } - clearTimeout( this.searching ); - this.close( event ); - this._change( event ); + clearTimeout(this.searching); + this.close(event); + this._change(event); } }); this._initSource(); - this.menu = $( "<ul>" ) - .addClass( "ui-autocomplete ui-front" ) - .appendTo( this._appendTo() ) + this.menu = $("<ul>") + .addClass("ui-autocomplete ui-front") + .appendTo(this._appendTo()) .menu({ // disable ARIA support, the live region takes care of that role: null }) .hide() - .data( "ui-menu" ); + .data("ui-menu"); - this._on( this.menu.element, { - mousedown: function( event ) { + this._on(this.menu.element, { + mousedown: function (event) { // prevent moving focus out of the text field event.preventDefault(); // IE doesn't prevent moving focus even with event.preventDefault() // so we set a flag to know when we should ignore the blur event this.cancelBlur = true; - this._delay(function() { + this._delay(function () { delete this.cancelBlur; }); @@ -200,41 +217,41 @@ // but we can't detect a mouseup or a click immediately afterward // so we have to track the next mousedown and close the menu if // the user clicks somewhere outside of the autocomplete - var menuElement = this.menu.element[ 0 ]; - if ( !$( event.target ).closest( ".ui-menu-item" ).length ) { - this._delay(function() { + var menuElement = this.menu.element[0]; + if (!$(event.target).closest(".ui-menu-item").length) { + this._delay(function () { var that = this; - this.document.one( "mousedown", function( event ) { - if ( event.target !== that.element[ 0 ] && + this.document.one("mousedown", function (event) { + if (event.target !== that.element[0] && event.target !== menuElement && - !$.contains( menuElement, event.target ) ) { + !$.contains(menuElement, event.target)) { that.close(); } }); }); } }, - menufocus: function( event, ui ) { + menufocus: function (event, ui) { // support: Firefox // Prevent accidental activation of menu items in Firefox (#7024 #9118) - if ( this.isNewMenu ) { + if (this.isNewMenu) { this.isNewMenu = false; - if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) { + if (event.originalEvent && /^mouse/.test(event.originalEvent.type)) { this.menu.blur(); - this.document.one( "mousemove", function() { - $( event.target ).trigger( event.originalEvent ); + this.document.one("mousemove", function () { + $(event.target).trigger(event.originalEvent); }); return; } } - var item = ui.item.data( "ui-autocomplete-item" ); - if ( false !== this._trigger( "focus", event, { item: item } ) ) { + var 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 ); + if (event.originalEvent && /^key/.test(event.originalEvent.type)) { + this._value(item.value); } } else { // Normally the input is populated with the item's value as the @@ -242,120 +259,120 @@ // announce the item. Since the focus event was canceled, this doesn't // happen, so we update the live region so that screen readers can // still notice the change and announce it. - this.liveRegion.text( item.value ); + this.liveRegion.text(item.value); } }, - menuselect: function( event, ui ) { - var item = ui.item.data( "ui-autocomplete-item" ), + 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] !== this.document[0].activeElement ) { + if (this.element[0] !== this.document[0].activeElement) { this.element.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._delay(function () { this.previous = previous; this.selectedItem = item; }); } - if ( false !== this._trigger( "select", event, { item: item } ) ) { - this._value( item.value ); + 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.close(event); this.selectedItem = item; } }); - this.liveRegion = $( "<span>", { + this.liveRegion = $("<span>", { role: "status", "aria-live": "polite" }) - .addClass( "ui-helper-hidden-accessible" ) - .insertBefore( this.element ); + .addClass("ui-helper-hidden-accessible") + .insertBefore(this.element); // 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" ); + this._on(this.window, { + beforeunload: function () { + this.element.removeAttr("autocomplete"); } }); }, - _destroy: function() { - clearTimeout( this.searching ); + _destroy: function () { + clearTimeout(this.searching); this.element - .removeClass( "ui-autocomplete-input" ) - .removeAttr( "autocomplete" ); + .removeClass("ui-autocomplete-input") + .removeAttr("autocomplete"); this.menu.element.remove(); this.liveRegion.remove(); }, - _setOption: function( key, value ) { - this._super( key, value ); - if ( key === "source" ) { + _setOption: function (key, value) { + this._super(key, value); + if (key === "source") { this._initSource(); } - if ( key === "appendTo" ) { - this.menu.element.appendTo( this._appendTo() ); + if (key === "appendTo") { + this.menu.element.appendTo(this._appendTo()); } - if ( key === "disabled" && value && this.xhr ) { + if (key === "disabled" && value && this.xhr) { this.xhr.abort(); } }, - _appendTo: function() { + _appendTo: function () { var element = this.options.appendTo; - if ( element ) { + if (element) { element = element.jquery || element.nodeType ? - $( element ) : - this.document.find( element ).eq( 0 ); + $(element) : + this.document.find(element).eq(0); } - if ( !element ) { - element = this.element.closest( ".ui-front" ); + if (!element) { + element = this.element.closest(".ui-front"); } - if ( !element.length ) { + if (!element.length) { element = this.document[0].body; } return element; }, - _initSource: function() { + _initSource: function () { var array, url, that = this; - if ( $.isArray(this.options.source) ) { + if ($.isArray(this.options.source)) { array = this.options.source; - this.source = function( request, response ) { - response( $.ui.autocomplete.filter( array, request.term ) ); + this.source = function (request, response) { + response($.ui.autocomplete.filter(array, request.term)); }; - } else if ( typeof this.options.source === "string" ) { + } else if (typeof this.options.source === "string") { url = this.options.source; - this.source = function( request, response ) { - if ( that.xhr ) { + 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 ); + success: function (data) { + response(data); }, - error: function() { - response( [] ); + error: function () { + response([]); } }); }; @@ -364,98 +381,98 @@ } }, - _searchTimeout: function( event ) { - clearTimeout( this.searching ); - this.searching = this._delay(function() { + _searchTimeout: function (event) { + clearTimeout(this.searching); + this.searching = this._delay(function () { // only search if the value has changed - if ( this.term !== this._value() ) { + if (this.term !== this._value()) { this.selectedItem = null; - this.search( null, event ); + this.search(null, event); } - }, this.options.delay ); + }, this.options.delay); }, - search: function( value, event ) { + 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 (value.length < this.options.minLength) { + return this.close(event); } - if ( this._trigger( "search", event ) === false ) { + if (this._trigger("search", event) === false) { return; } - return this._search( value ); + return this._search(value); }, - _search: function( value ) { + _search: function (value) { this.pending++; - this.element.addClass( "ui-autocomplete-loading" ); + this.element.addClass("ui-autocomplete-loading"); this.cancelSearch = false; - this.source( { term: value }, this._response() ); + this.source({term: value}, this._response()); }, - _response: function() { + _response: function () { var index = ++this.requestIndex; - return $.proxy(function( content ) { - if ( index === this.requestIndex ) { - this.__response( content ); + return $.proxy(function (content) { + if (index === this.requestIndex) { + this.__response(content); } this.pending--; - if ( !this.pending ) { - this.element.removeClass( "ui-autocomplete-loading" ); + if (!this.pending) { + this.element.removeClass("ui-autocomplete-loading"); } - }, this ); + }, this); }, - __response: function( content ) { - if ( content ) { - content = this._normalize( content ); + __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" ); + 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 ) { + close: function (event) { this.cancelSearch = true; - this._close( event ); + this._close(event); }, - _close: function( event ) { - if ( this.menu.element.is( ":visible" ) ) { + _close: function (event) { + if (this.menu.element.is(":visible")) { this.menu.element.hide(); this.menu.blur(); this.isNewMenu = true; - this._trigger( "close", event ); + this._trigger("close", event); } }, - _change: function( event ) { - if ( this.previous !== this._value() ) { - this._trigger( "change", event, { item: this.selectedItem } ); + _change: function (event) { + if (this.previous !== this._value()) { + this._trigger("change", event, {item: this.selectedItem}); } }, - _normalize: function( items ) { + _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 ) { + if (items.length && items[0].label && items[0].value) { return items; } - return $.map( items, function( item ) { - if ( typeof item === "string" ) { + return $.map(items, function (item) { + if (typeof item === "string") { return { label: item, value: item @@ -464,80 +481,80 @@ return $.extend({ label: item.label || item.value, value: item.value || item.label - }, item ); + }, item); }); }, - _suggest: function( items ) { + _suggest: function (items) { var ul = this.menu.element.empty(); - this._renderMenu( ul, items ); + this._renderMenu(ul, items); this.isNewMenu = true; this.menu.refresh(); // size and position menu ul.show(); this._resizeMenu(); - ul.position( $.extend({ + ul.position($.extend({ of: this.element - }, this.options.position )); + }, this.options.position)); - if ( this.options.autoFocus ) { + if (this.options.autoFocus) { this.menu.next(); } }, - _resizeMenu: function() { + _resizeMenu: function () { var ul = this.menu.element; - ul.outerWidth( Math.max( + 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, + ul.width("").outerWidth() + 1, this.element.outerWidth() - ) ); + )); }, - _renderMenu: function( ul, items ) { + _renderMenu: function (ul, items) { var that = this; - $.each( items, function( index, item ) { - that._renderItemData( ul, item ); + $.each(items, function (index, item) { + that._renderItemData(ul, item); }); }, - _renderItemData: function( ul, item ) { - return this._renderItem( ul, item ).data( "ui-autocomplete-item", item ); + _renderItemData: function (ul, item) { + return this._renderItem(ul, item).data("ui-autocomplete-item", item); }, - _renderItem: function( ul, item ) { - return $( "<li>" ) - .append( $( "<a>" ).text( item.label ) ) - .appendTo( ul ); + _renderItem: function (ul, item) { + return $("<li>") + .append($("<a>").text(item.label)) + .appendTo(ul); }, - _move: function( direction, event ) { - if ( !this.menu.element.is( ":visible" ) ) { - this.search( null, event ); + _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 ) ) { - this._value( this.term ); + if (this.menu.isFirstItem() && /^previous/.test(direction) || + this.menu.isLastItem() && /^next/.test(direction)) { + this._value(this.term); this.menu.blur(); return; } - this.menu[ direction ]( event ); + this.menu[direction](event); }, - widget: function() { + widget: function () { return this.menu.element; }, - _value: function() { - return this.valueMethod.apply( this.element, arguments ); + _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 ); + _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(); @@ -545,46 +562,45 @@ } }); - $.extend( $.ui.autocomplete, { - escapeRegex: function( value ) { + $.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 ); + 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, { + // 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" ) + + results: function (amount) { + return amount + (amount > 1 ? " results are" : " result is") + " available, use up and down arrow keys to navigate."; } } }, - __response: function( content ) { + __response: function (content) { var message; - this._superApply( arguments ); - if ( this.options.disabled || this.cancelSearch ) { + this._superApply(arguments); + if (this.options.disabled || this.cancelSearch) { return; } - if ( content && content.length ) { - message = this.options.messages.results( content.length ); + if (content && content.length) { + message = this.options.messages.results(content.length); } else { message = this.options.messages.noResults; } - this.liveRegion.text( message ); + this.liveRegion.text(message); } }); - -}( jQuery )); +}); diff --git a/lib/web/jquery/ui-modules/button.js b/lib/web/jquery/ui-modules/button.js index 6be8dcaaa3ef..36f93d752c02 100644 --- a/lib/web/jquery/ui-modules/button.js +++ b/lib/web/jquery/ui-modules/button.js @@ -1,25 +1,39 @@ -(function( $, undefined ) { +/*! + * jQuery UI Button + * http://jqueryui.com + * + * Copyright 2014 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/button/ + */ +define([ + 'jquery', + 'jquery-ui-modules/core', + 'jquery-ui-modules/widget' +], function ($, undefined) { var lastActive, baseClasses = "ui-button ui-widget ui-state-default ui-corner-all", typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only", - formResetHandler = function() { - var form = $( this ); - setTimeout(function() { - form.find( ":ui-button" ).button( "refresh" ); - }, 1 ); + formResetHandler = function () { + var form = $(this); + setTimeout(function () { + form.find(":ui-button").button("refresh"); + }, 1); }, - radioGroup = function( radio ) { + radioGroup = function (radio) { var name = radio.name, form = radio.form, - radios = $( [] ); - if ( name ) { - name = name.replace( /'/g, "\\'" ); - if ( form ) { - radios = $( form ).find( "[name='" + name + "']" ); + radios = $([]); + if (name) { + name = name.replace(/'/g, "\\'"); + if (form) { + radios = $(form).find("[name='" + name + "']"); } else { - radios = $( "[name='" + name + "']", radio.ownerDocument ) - .filter(function() { + radios = $("[name='" + name + "']", radio.ownerDocument) + .filter(function () { return !this.form; }); } @@ -27,7 +41,7 @@ return radios; }; - $.widget( "ui.button", { + $.widget("ui.button", { version: "1.10.4", defaultElement: "<button>", options: { @@ -39,50 +53,50 @@ secondary: null } }, - _create: function() { - this.element.closest( "form" ) - .unbind( "reset" + this.eventNamespace ) - .bind( "reset" + this.eventNamespace, formResetHandler ); + _create: function () { + this.element.closest("form") + .unbind("reset" + this.eventNamespace) + .bind("reset" + this.eventNamespace, formResetHandler); - if ( typeof this.options.disabled !== "boolean" ) { - this.options.disabled = !!this.element.prop( "disabled" ); + if (typeof this.options.disabled !== "boolean") { + this.options.disabled = !!this.element.prop("disabled"); } else { - this.element.prop( "disabled", this.options.disabled ); + this.element.prop("disabled", this.options.disabled); } this._determineButtonType(); - this.hasTitle = !!this.buttonElement.attr( "title" ); + this.hasTitle = !!this.buttonElement.attr("title"); var that = this, options = this.options, toggleButton = this.type === "checkbox" || this.type === "radio", activeClass = !toggleButton ? "ui-state-active" : ""; - if ( options.label === null ) { + if (options.label === null) { options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html()); } - this._hoverable( this.buttonElement ); + this._hoverable(this.buttonElement); this.buttonElement - .addClass( baseClasses ) - .attr( "role", "button" ) - .bind( "mouseenter" + this.eventNamespace, function() { - if ( options.disabled ) { + .addClass(baseClasses) + .attr("role", "button") + .bind("mouseenter" + this.eventNamespace, function () { + if (options.disabled) { return; } - if ( this === lastActive ) { - $( this ).addClass( "ui-state-active" ); + if (this === lastActive) { + $(this).addClass("ui-state-active"); } }) - .bind( "mouseleave" + this.eventNamespace, function() { - if ( options.disabled ) { + .bind("mouseleave" + this.eventNamespace, function () { + if (options.disabled) { return; } - $( this ).removeClass( activeClass ); + $(this).removeClass(activeClass); }) - .bind( "click" + this.eventNamespace, function( event ) { - if ( options.disabled ) { + .bind("click" + this.eventNamespace, function (event) { + if (options.disabled) { event.preventDefault(); event.stopImmediatePropagation(); } @@ -91,80 +105,80 @@ // Can't use _focusable() because the element that receives focus // and the element that gets the ui-state-focus class are different this._on({ - focus: function() { - this.buttonElement.addClass( "ui-state-focus" ); + focus: function () { + this.buttonElement.addClass("ui-state-focus"); }, - blur: function() { - this.buttonElement.removeClass( "ui-state-focus" ); + blur: function () { + this.buttonElement.removeClass("ui-state-focus"); } }); - if ( toggleButton ) { - this.element.bind( "change" + this.eventNamespace, function() { + if (toggleButton) { + this.element.bind("change" + this.eventNamespace, function () { that.refresh(); }); } - if ( this.type === "checkbox" ) { - this.buttonElement.bind( "click" + this.eventNamespace, function() { - if ( options.disabled ) { + if (this.type === "checkbox") { + this.buttonElement.bind("click" + this.eventNamespace, function () { + if (options.disabled) { return false; } }); - } else if ( this.type === "radio" ) { - this.buttonElement.bind( "click" + this.eventNamespace, function() { - if ( options.disabled ) { + } else if (this.type === "radio") { + this.buttonElement.bind("click" + this.eventNamespace, function () { + if (options.disabled) { return false; } - $( this ).addClass( "ui-state-active" ); - that.buttonElement.attr( "aria-pressed", "true" ); - - var radio = that.element[ 0 ]; - radioGroup( radio ) - .not( radio ) - .map(function() { - return $( this ).button( "widget" )[ 0 ]; + $(this).addClass("ui-state-active"); + that.buttonElement.attr("aria-pressed", "true"); + + var radio = that.element[0]; + radioGroup(radio) + .not(radio) + .map(function () { + return $(this).button("widget")[0]; }) - .removeClass( "ui-state-active" ) - .attr( "aria-pressed", "false" ); + .removeClass("ui-state-active") + .attr("aria-pressed", "false"); }); } else { this.buttonElement - .bind( "mousedown" + this.eventNamespace, function() { - if ( options.disabled ) { + .bind("mousedown" + this.eventNamespace, function () { + if (options.disabled) { return false; } - $( this ).addClass( "ui-state-active" ); + $(this).addClass("ui-state-active"); lastActive = this; - that.document.one( "mouseup", function() { + that.document.one("mouseup", function () { lastActive = null; }); }) - .bind( "mouseup" + this.eventNamespace, function() { - if ( options.disabled ) { + .bind("mouseup" + this.eventNamespace, function () { + if (options.disabled) { return false; } - $( this ).removeClass( "ui-state-active" ); + $(this).removeClass("ui-state-active"); }) - .bind( "keydown" + this.eventNamespace, function(event) { - if ( options.disabled ) { + .bind("keydown" + this.eventNamespace, function (event) { + if (options.disabled) { return false; } - if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) { - $( this ).addClass( "ui-state-active" ); + if (event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER) { + $(this).addClass("ui-state-active"); } }) // see #8559, we bind to blur here in case the button element loses // focus between keydown and keyup, it would be left in an "active" state - .bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() { - $( this ).removeClass( "ui-state-active" ); + .bind("keyup" + this.eventNamespace + " blur" + this.eventNamespace, function () { + $(this).removeClass("ui-state-active"); }); - if ( this.buttonElement.is("a") ) { - this.buttonElement.keyup(function(event) { - if ( event.keyCode === $.ui.keyCode.SPACE ) { + if (this.buttonElement.is("a")) { + this.buttonElement.keyup(function (event) { + if (event.keyCode === $.ui.keyCode.SPACE) { // TODO pass through original event correctly (just as 2nd argument doesn't work) - $( this ).click(); + $(this).click(); } }); } @@ -173,209 +187,209 @@ // TODO: pull out $.Widget's handling for the disabled option into // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can // be overridden by individual plugins - this._setOption( "disabled", options.disabled ); + this._setOption("disabled", options.disabled); this._resetButton(); }, - _determineButtonType: function() { + _determineButtonType: function () { var ancestor, labelSelector, checked; - if ( this.element.is("[type=checkbox]") ) { + if (this.element.is("[type=checkbox]")) { this.type = "checkbox"; - } else if ( this.element.is("[type=radio]") ) { + } else if (this.element.is("[type=radio]")) { this.type = "radio"; - } else if ( this.element.is("input") ) { + } else if (this.element.is("input")) { this.type = "input"; } else { this.type = "button"; } - if ( this.type === "checkbox" || this.type === "radio" ) { + if (this.type === "checkbox" || this.type === "radio") { // we don't search against the document in case the element // is disconnected from the DOM ancestor = this.element.parents().last(); labelSelector = "label[for='" + this.element.attr("id") + "']"; - this.buttonElement = ancestor.find( labelSelector ); - if ( !this.buttonElement.length ) { + this.buttonElement = ancestor.find(labelSelector); + if (!this.buttonElement.length) { ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings(); - this.buttonElement = ancestor.filter( labelSelector ); - if ( !this.buttonElement.length ) { - this.buttonElement = ancestor.find( labelSelector ); + this.buttonElement = ancestor.filter(labelSelector); + if (!this.buttonElement.length) { + this.buttonElement = ancestor.find(labelSelector); } } - this.element.addClass( "ui-helper-hidden-accessible" ); + this.element.addClass("ui-helper-hidden-accessible"); - checked = this.element.is( ":checked" ); - if ( checked ) { - this.buttonElement.addClass( "ui-state-active" ); + checked = this.element.is(":checked"); + if (checked) { + this.buttonElement.addClass("ui-state-active"); } - this.buttonElement.prop( "aria-pressed", checked ); + this.buttonElement.prop("aria-pressed", checked); } else { this.buttonElement = this.element; } }, - widget: function() { + widget: function () { return this.buttonElement; }, - _destroy: function() { + _destroy: function () { this.element - .removeClass( "ui-helper-hidden-accessible" ); + .removeClass("ui-helper-hidden-accessible"); this.buttonElement - .removeClass( baseClasses + " ui-state-active " + typeClasses ) - .removeAttr( "role" ) - .removeAttr( "aria-pressed" ) - .html( this.buttonElement.find(".ui-button-text").html() ); + .removeClass(baseClasses + " ui-state-active " + typeClasses) + .removeAttr("role") + .removeAttr("aria-pressed") + .html(this.buttonElement.find(".ui-button-text").html()); - if ( !this.hasTitle ) { - this.buttonElement.removeAttr( "title" ); + if (!this.hasTitle) { + this.buttonElement.removeAttr("title"); } }, - _setOption: function( key, value ) { - this._super( key, value ); - if ( key === "disabled" ) { - this.element.prop( "disabled", !!value ); - if ( value ) { - this.buttonElement.removeClass( "ui-state-focus" ); + _setOption: function (key, value) { + this._super(key, value); + if (key === "disabled") { + this.element.prop("disabled", !!value); + if (value) { + this.buttonElement.removeClass("ui-state-focus"); } return; } this._resetButton(); }, - refresh: function() { + refresh: function () { //See #8237 & #8828 - var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" ); + var isDisabled = this.element.is("input, button") ? this.element.is(":disabled") : this.element.hasClass("ui-button-disabled"); - if ( isDisabled !== this.options.disabled ) { - this._setOption( "disabled", isDisabled ); + if (isDisabled !== this.options.disabled) { + this._setOption("disabled", isDisabled); } - if ( this.type === "radio" ) { - radioGroup( this.element[0] ).each(function() { - if ( $( this ).is( ":checked" ) ) { - $( this ).button( "widget" ) - .addClass( "ui-state-active" ) - .attr( "aria-pressed", "true" ); + if (this.type === "radio") { + radioGroup(this.element[0]).each(function () { + if ($(this).is(":checked")) { + $(this).button("widget") + .addClass("ui-state-active") + .attr("aria-pressed", "true"); } else { - $( this ).button( "widget" ) - .removeClass( "ui-state-active" ) - .attr( "aria-pressed", "false" ); + $(this).button("widget") + .removeClass("ui-state-active") + .attr("aria-pressed", "false"); } }); - } else if ( this.type === "checkbox" ) { - if ( this.element.is( ":checked" ) ) { + } else if (this.type === "checkbox") { + if (this.element.is(":checked")) { this.buttonElement - .addClass( "ui-state-active" ) - .attr( "aria-pressed", "true" ); + .addClass("ui-state-active") + .attr("aria-pressed", "true"); } else { this.buttonElement - .removeClass( "ui-state-active" ) - .attr( "aria-pressed", "false" ); + .removeClass("ui-state-active") + .attr("aria-pressed", "false"); } } }, - _resetButton: function() { - if ( this.type === "input" ) { - if ( this.options.label ) { - this.element.val( this.options.label ); + _resetButton: function () { + if (this.type === "input") { + if (this.options.label) { + this.element.val(this.options.label); } return; } - var buttonElement = this.buttonElement.removeClass( typeClasses ), - buttonText = $( "<span></span>", this.document[0] ) - .addClass( "ui-button-text" ) - .html( this.options.label ) - .appendTo( buttonElement.empty() ) + var buttonElement = this.buttonElement.removeClass(typeClasses), + buttonText = $("<span></span>", this.document[0]) + .addClass("ui-button-text") + .html(this.options.label) + .appendTo(buttonElement.empty()) .text(), icons = this.options.icons, multipleIcons = icons.primary && icons.secondary, buttonClasses = []; - if ( icons.primary || icons.secondary ) { - if ( this.options.text ) { - buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) ); + if (icons.primary || icons.secondary) { + if (this.options.text) { + buttonClasses.push("ui-button-text-icon" + (multipleIcons ? "s" : (icons.primary ? "-primary" : "-secondary"))); } - if ( icons.primary ) { - buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" ); + if (icons.primary) { + buttonElement.prepend("<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>"); } - if ( icons.secondary ) { - buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" ); + if (icons.secondary) { + buttonElement.append("<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>"); } - if ( !this.options.text ) { - buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" ); + if (!this.options.text) { + buttonClasses.push(multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only"); - if ( !this.hasTitle ) { - buttonElement.attr( "title", $.trim( buttonText ) ); + if (!this.hasTitle) { + buttonElement.attr("title", $.trim(buttonText)); } } } else { - buttonClasses.push( "ui-button-text-only" ); + buttonClasses.push("ui-button-text-only"); } - buttonElement.addClass( buttonClasses.join( " " ) ); + buttonElement.addClass(buttonClasses.join(" ")); } }); - $.widget( "ui.buttonset", { + $.widget("ui.buttonset", { version: "1.10.4", options: { items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)" }, - _create: function() { - this.element.addClass( "ui-buttonset" ); + _create: function () { + this.element.addClass("ui-buttonset"); }, - _init: function() { + _init: function () { this.refresh(); }, - _setOption: function( key, value ) { - if ( key === "disabled" ) { - this.buttons.button( "option", key, value ); + _setOption: function (key, value) { + if (key === "disabled") { + this.buttons.button("option", key, value); } - this._super( key, value ); + this._super(key, value); }, - refresh: function() { - var rtl = this.element.css( "direction" ) === "rtl"; + refresh: function () { + var rtl = this.element.css("direction") === "rtl"; - this.buttons = this.element.find( this.options.items ) - .filter( ":ui-button" ) - .button( "refresh" ) + this.buttons = this.element.find(this.options.items) + .filter(":ui-button") + .button("refresh") .end() - .not( ":ui-button" ) + .not(":ui-button") .button() .end() - .map(function() { - return $( this ).button( "widget" )[ 0 ]; + .map(function () { + return $(this).button("widget")[0]; }) - .removeClass( "ui-corner-all ui-corner-left ui-corner-right" ) - .filter( ":first" ) - .addClass( rtl ? "ui-corner-right" : "ui-corner-left" ) + .removeClass("ui-corner-all ui-corner-left ui-corner-right") + .filter(":first") + .addClass(rtl ? "ui-corner-right" : "ui-corner-left") .end() - .filter( ":last" ) - .addClass( rtl ? "ui-corner-left" : "ui-corner-right" ) + .filter(":last") + .addClass(rtl ? "ui-corner-left" : "ui-corner-right") .end() .end(); }, - _destroy: function() { - this.element.removeClass( "ui-buttonset" ); + _destroy: function () { + this.element.removeClass("ui-buttonset"); this.buttons - .map(function() { - return $( this ).button( "widget" )[ 0 ]; + .map(function () { + return $(this).button("widget")[0]; }) - .removeClass( "ui-corner-left ui-corner-right" ) + .removeClass("ui-corner-left ui-corner-right") .end() - .button( "destroy" ); + .button("destroy"); } }); -}( jQuery ) ); +}); diff --git a/lib/web/jquery/ui-modules/core.js b/lib/web/jquery/ui-modules/core.js index d4d325c51a4e..fdd91cd38d30 100644 --- a/lib/web/jquery/ui-modules/core.js +++ b/lib/web/jquery/ui-modules/core.js @@ -1,4 +1,16 @@ -(function( $, undefined ) { +/*! + * jQuery UI Core + * http://jqueryui.com + * + * Copyright 2014 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/category/ui-core/ + */ +define([ + 'jquery' +], function ($, undefined) { var uuid = 0, runiqueId = /^ui-id-\d+$/; @@ -6,7 +18,7 @@ // $.ui might exist from components with no dependencies, e.g., $.ui.position $.ui = $.ui || {}; - $.extend( $.ui, { + $.extend($.ui, { version: "1.10.4", keyCode: { @@ -37,56 +49,56 @@ // plugins $.fn.extend({ - focus: (function( orig ) { - return function( delay, fn ) { + focus: (function (orig) { + return function (delay, fn) { return typeof delay === "number" ? - this.each(function() { + this.each(function () { var elem = this; - setTimeout(function() { - $( elem ).focus(); - if ( fn ) { - fn.call( elem ); + setTimeout(function () { + $(elem).focus(); + if (fn) { + fn.call(elem); } - }, delay ); + }, delay); }) : - orig.apply( this, arguments ); + orig.apply(this, arguments); }; - })( $.fn.focus ), + })($.fn.focus), - scrollParent: function() { + scrollParent: function () { var scrollParent; if (($.ui.ie && (/(static|relative)/).test(this.css("position"))) || (/absolute/).test(this.css("position"))) { - scrollParent = this.parents().filter(function() { - return (/(relative|absolute|fixed)/).test($.css(this,"position")) && (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x")); + scrollParent = this.parents().filter(function () { + return (/(relative|absolute|fixed)/).test($.css(this, "position")) && (/(auto|scroll)/).test($.css(this, "overflow") + $.css(this, "overflow-y") + $.css(this, "overflow-x")); }).eq(0); } else { - scrollParent = this.parents().filter(function() { - return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x")); + scrollParent = this.parents().filter(function () { + return (/(auto|scroll)/).test($.css(this, "overflow") + $.css(this, "overflow-y") + $.css(this, "overflow-x")); }).eq(0); } return (/fixed/).test(this.css("position")) || !scrollParent.length ? $(document) : scrollParent; }, - zIndex: function( zIndex ) { - if ( zIndex !== undefined ) { - return this.css( "zIndex", zIndex ); + zIndex: function (zIndex) { + if (zIndex !== undefined) { + return this.css("zIndex", zIndex); } - if ( this.length ) { - var elem = $( this[ 0 ] ), position, value; - while ( elem.length && elem[ 0 ] !== document ) { + if (this.length) { + var elem = $(this[0]), 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" ) { + 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 ) { + value = parseInt(elem.css("zIndex"), 10); + if (!isNaN(value) && value !== 0) { return value; } } @@ -97,79 +109,79 @@ return 0; }, - uniqueId: function() { - return this.each(function() { - if ( !this.id ) { + uniqueId: function () { + return this.each(function () { + if (!this.id) { this.id = "ui-id-" + (++uuid); } }); }, - removeUniqueId: function() { - return this.each(function() { - if ( runiqueId.test( this.id ) ) { - $( this ).removeAttr( "id" ); + removeUniqueId: function () { + return this.each(function () { + if (runiqueId.test(this.id)) { + $(this).removeAttr("id"); } }); } }); // selectors - function focusable( element, isTabIndexNotNaN ) { + function focusable(element, isTabIndexNotNaN) { var map, mapName, img, nodeName = element.nodeName.toLowerCase(); - if ( "area" === nodeName ) { + if ("area" === nodeName) { map = element.parentNode; mapName = map.name; - if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { + if (!element.href || !mapName || map.nodeName.toLowerCase() !== "map") { return false; } - img = $( "img[usemap=#" + mapName + "]" )[0]; - return !!img && visible( img ); + img = $("img[usemap=#" + mapName + "]")[0]; + return !!img && visible(img); } - return ( /input|select|textarea|button|object/.test( nodeName ) ? + return (/input|select|textarea|button|object/.test(nodeName) ? !element.disabled : "a" === nodeName ? element.href || isTabIndexNotNaN : isTabIndexNotNaN) && // the element and all of its ancestors must be visible - visible( element ); + visible(element); } - function visible( element ) { - return $.expr.filters.visible( element ) && - !$( element ).parents().addBack().filter(function() { - return $.css( this, "visibility" ) === "hidden"; + function visible(element) { + return $.expr.filters.visible(element) && + !$(element).parents().addBack().filter(function () { + return $.css(this, "visibility") === "hidden"; }).length; } - $.extend( $.expr[ ":" ], { + $.extend($.expr[":"], { data: $.expr.createPseudo ? - $.expr.createPseudo(function( dataName ) { - return function( elem ) { - return !!$.data( elem, dataName ); + $.expr.createPseudo(function (dataName) { + return function (elem) { + return !!$.data(elem, dataName); }; }) : // support: jQuery <1.8 - function( elem, i, match ) { - return !!$.data( elem, match[ 3 ] ); + function (elem, i, match) { + return !!$.data(elem, match[3]); }, - focusable: function( element ) { - return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) ); + focusable: function (element) { + return focusable(element, !isNaN($.attr(element, "tabindex"))); }, - tabbable: function( element ) { - var tabIndex = $.attr( element, "tabindex" ), - isTabIndexNaN = isNaN( tabIndex ); - return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN ); + tabbable: function (element) { + var tabIndex = $.attr(element, "tabindex"), + isTabIndexNaN = isNaN(tabIndex); + return (isTabIndexNaN || tabIndex >= 0) && focusable(element, !isTabIndexNaN); } }); // support: jQuery <1.8 - if ( !$( "<a>" ).outerWidth( 1 ).jquery ) { - $.each( [ "Width", "Height" ], function( i, name ) { - var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ], + if (!$("<a>").outerWidth(1).jquery) { + $.each(["Width", "Height"], function (i, name) { + var side = name === "Width" ? ["Left", "Right"] : ["Top", "Bottom"], type = name.toLowerCase(), orig = { innerWidth: $.fn.innerWidth, @@ -178,133 +190,130 @@ outerHeight: $.fn.outerHeight }; - function reduce( elem, size, border, margin ) { - $.each( side, function() { - size -= parseFloat( $.css( elem, "padding" + this ) ) || 0; - if ( border ) { - size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0; + function reduce(elem, size, border, margin) { + $.each(side, function () { + size -= parseFloat($.css(elem, "padding" + this)) || 0; + if (border) { + size -= parseFloat($.css(elem, "border" + this + "Width")) || 0; } - if ( margin ) { - size -= parseFloat( $.css( elem, "margin" + this ) ) || 0; + if (margin) { + size -= parseFloat($.css(elem, "margin" + this)) || 0; } }); return size; } - $.fn[ "inner" + name ] = function( size ) { - if ( size === undefined ) { - return orig[ "inner" + name ].call( this ); + $.fn["inner" + name] = function (size) { + if (size === undefined) { + return orig["inner" + name].call(this); } - return this.each(function() { - $( this ).css( type, reduce( this, size ) + "px" ); + return this.each(function () { + $(this).css(type, reduce(this, size) + "px"); }); }; - $.fn[ "outer" + name] = function( size, margin ) { - if ( typeof size !== "number" ) { - return orig[ "outer" + name ].call( this, size ); + $.fn["outer" + name] = function (size, margin) { + if (typeof size !== "number") { + return orig["outer" + name].call(this, size); } - return this.each(function() { - $( this).css( type, reduce( this, size, true, margin ) + "px" ); + return this.each(function () { + $(this).css(type, reduce(this, size, true, margin) + "px"); }); }; }); } // support: jQuery <1.8 - if ( !$.fn.addBack ) { - $.fn.addBack = function( selector ) { - return this.add( selector == null ? - this.prevObject : this.prevObject.filter( selector ) + if (!$.fn.addBack) { + $.fn.addBack = function (selector) { + return this.add(selector == null ? + this.prevObject : this.prevObject.filter(selector) ); }; } // support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413) - if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) { - $.fn.removeData = (function( removeData ) { - return function( key ) { - if ( arguments.length ) { - return removeData.call( this, $.camelCase( key ) ); + if ($("<a>").data("a-b", "a").removeData("a-b").data("a-b")) { + $.fn.removeData = (function (removeData) { + return function (key) { + if (arguments.length) { + return removeData.call(this, $.camelCase(key)); } else { - return removeData.call( this ); + return removeData.call(this); } }; - })( $.fn.removeData ); + })($.fn.removeData); } - - - // deprecated - $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() ); + $.ui.ie = !!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase()); - $.support.selectstart = "onselectstart" in document.createElement( "div" ); + $.support.selectstart = "onselectstart" in document.createElement("div"); $.fn.extend({ - disableSelection: function() { - return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) + - ".ui-disableSelection", function( event ) { + disableSelection: function () { + return this.bind(($.support.selectstart ? "selectstart" : "mousedown") + + ".ui-disableSelection", function (event) { event.preventDefault(); }); }, - enableSelection: function() { - return this.unbind( ".ui-disableSelection" ); + enableSelection: function () { + return this.unbind(".ui-disableSelection"); } }); - $.extend( $.ui, { + $.extend($.ui, { // $.ui.plugin is deprecated. Use $.widget() extensions instead. plugin: { - add: function( module, option, set ) { + 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 ] ] ); + 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 ) { + call: function (instance, name, args) { var i, - set = instance.plugins[ name ]; - if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) { + set = instance.plugins[name]; + if (!set || !instance.element[0].parentNode || instance.element[0].parentNode.nodeType === 11) { return; } - for ( i = 0; i < set.length; i++ ) { - if ( instance.options[ set[ i ][ 0 ] ] ) { - set[ i ][ 1 ].apply( instance.element, args ); + for (i = 0; i < set.length; i++) { + if (instance.options[set[i][0]]) { + set[i][1].apply(instance.element, args); } } } }, // only used by resizable - hasScroll: function( el, a ) { + hasScroll: function (el, a) { //If overflow is hidden, the element might have extra content, but the user wants to hide it - if ( $( el ).css( "overflow" ) === "hidden") { + if ($(el).css("overflow") === "hidden") { return false; } - var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop", + var scroll = (a && a === "left") ? "scrollLeft" : "scrollTop", has = false; - if ( el[ scroll ] > 0 ) { + 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 - el[ scroll ] = 1; - has = ( el[ scroll ] > 0 ); - el[ scroll ] = 0; + el[scroll] = 1; + has = (el[scroll] > 0); + el[scroll] = 0; return has; } }); -})( jQuery ); +}); diff --git a/lib/web/jquery/ui-modules/datepicker.js b/lib/web/jquery/ui-modules/datepicker.js index 21f9f5ccdd3b..e3e725d1f3b7 100644 --- a/lib/web/jquery/ui-modules/datepicker.js +++ b/lib/web/jquery/ui-modules/datepicker.js @@ -1,6 +1,20 @@ -(function( $, undefined ) { - - $.extend($.ui, { datepicker: { version: "1.10.4" } }); +/*! + * jQuery UI Datepicker + * http://jqueryui.com + * + * Copyright 2014 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/datepicker/ + */ + +define([ + 'jquery', + 'jquery-ui-modules/core', +], function ($, undefined) { + + $.extend($.ui, {datepicker: {version: "1.10.4"}}); var PROP_NAME = "datepicker", instActive; @@ -31,12 +45,12 @@ 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 + 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 + 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, ... @@ -106,7 +120,7 @@ maxRows: 4, // TODO rename to "widget" when switching to widget factory - _widgetDatepicker: function() { + _widgetDatepicker: function () { return this.dpDiv; }, @@ -114,7 +128,7 @@ * @param settings object - the new settings to use as defaults (anonymous object) * @return the manager object */ - setDefaults: function(settings) { + setDefaults: function (settings) { extendRemove(this._defaults, settings || {}); return this; }, @@ -123,7 +137,7 @@ * @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) { + _attachDatepicker: function (target, settings) { var nodeName, inline, inst; nodeName = target.nodeName.toLowerCase(); inline = (nodeName === "div" || nodeName === "span"); @@ -141,18 +155,20 @@ }, /* Create a new instance object. */ - _newInst: function(target, inline) { + _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 + 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 - bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))}; + 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) { + _connectDatepicker: function (target, inst) { var input = $(target); inst.append = $([]); inst.trigger = $([]); @@ -160,18 +176,17 @@ return; } this._attachments(input, inst); - input.addClass(this.markerClassName).keydown(this._doKeyDown). - keypress(this._doKeyPress).keyup(this._doKeyUp); + input.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp); this._autoSize(inst); $.data(target, PROP_NAME, 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 ); + if (inst.settings.disabled) { + this._disableDatepicker(target); } }, /* Make attachments based on settings. */ - _attachments: function(input, inst) { + _attachments: function (input, inst) { var showOn, buttonText, buttonImage, appendText = this._get(inst, "appendText"), isRTL = this._get(inst, "isRTL"); @@ -198,13 +213,15 @@ buttonText = this._get(inst, "buttonText"); buttonImage = this._get(inst, "buttonImage"); inst.trigger = $(this._get(inst, "buttonImageOnly") ? - $("<img/>").addClass(this._triggerClass). - attr({ src: buttonImage, alt: buttonText, title: buttonText }) : - $("<button type='button'></button>").addClass(this._triggerClass). - html(!buttonImage ? buttonText : $("<img/>").attr( - { src:buttonImage, alt:buttonText, title:buttonText }))); + $("<img/>").addClass(this._triggerClass).attr({ + src: buttonImage, + alt: buttonText, + title: buttonText + }) : + $("<button type='button'></button>").addClass(this._triggerClass).html(!buttonImage ? buttonText : $("<img/>").attr( + {src: buttonImage, alt: buttonText, title: buttonText}))); input[isRTL ? "before" : "after"](inst.trigger); - inst.trigger.click(function() { + inst.trigger.click(function () { if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) { $.datepicker._hideDatepicker(); } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) { @@ -219,14 +236,14 @@ }, /* Apply the maximum length for the date format. */ - _autoSize: function(inst) { + _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) { + findMax = function (names) { max = 0; maxI = 0; for (i = 0; i < names.length; i++) { @@ -247,7 +264,7 @@ }, /* Attach an inline date picker to a div. */ - _inlineDatepicker: function(target, inst) { + _inlineDatepicker: function (target, inst) { var divSpan = $(target); if (divSpan.hasClass(this.markerClassName)) { return; @@ -258,12 +275,12 @@ 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 (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" ); + inst.dpDiv.css("display", "block"); }, /* Pop-up the date picker in a "dialog" box. @@ -276,7 +293,7 @@ * leave empty for default (screen centre) * @return the manager object */ - _dialogDatepicker: function(input, date, onSelect, settings, pos) { + _dialogDatepicker: function (input, date, onSelect, settings, pos) { var id, browserWidth, browserHeight, scrollX, scrollY, inst = this._dialogInst; // internal instance @@ -321,7 +338,7 @@ /* Detach a datepicker from its control. * @param target element - the target input field or division or span */ - _destroyDatepicker: function(target) { + _destroyDatepicker: function (target) { var nodeName, $target = $(target), inst = $.data(target, PROP_NAME); @@ -335,11 +352,7 @@ if (nodeName === "input") { inst.append.remove(); inst.trigger.remove(); - $target.removeClass(this.markerClassName). - unbind("focus", this._showDatepicker). - unbind("keydown", this._doKeyDown). - unbind("keypress", this._doKeyPress). - unbind("keyup", this._doKeyUp); + $target.removeClass(this.markerClassName).unbind("focus", this._showDatepicker).unbind("keydown", this._doKeyDown).unbind("keypress", this._doKeyPress).unbind("keyup", this._doKeyUp); } else if (nodeName === "div" || nodeName === "span") { $target.removeClass(this.markerClassName).empty(); } @@ -348,7 +361,7 @@ /* Enable the date picker to a jQuery selection. * @param target element - the target input field or division or span */ - _enableDatepicker: function(target) { + _enableDatepicker: function (target) { var nodeName, inline, $target = $(target), inst = $.data(target, PROP_NAME); @@ -360,23 +373,24 @@ 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: ""}); + 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); + inline.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled", false); } this._disabledInputs = $.map(this._disabledInputs, - function(value) { return (value === target ? null : value); }); // delete entry + function (value) { + return (value === target ? null : value); + }); // delete entry }, /* Disable the date picker to a jQuery selection. * @param target element - the target input field or division or span */ - _disableDatepicker: function(target) { + _disableDatepicker: function (target) { var nodeName, inline, $target = $(target), inst = $.data(target, PROP_NAME); @@ -388,17 +402,18 @@ 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"}); + 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); + inline.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled", true); } this._disabledInputs = $.map(this._disabledInputs, - function(value) { return (value === target ? null : value); }); // delete entry + function (value) { + return (value === target ? null : value); + }); // delete entry this._disabledInputs[this._disabledInputs.length] = target; }, @@ -406,7 +421,7 @@ * @param target element - the target input field or division or span * @return boolean - true if disabled, false if enabled */ - _isDisabledDatepicker: function(target) { + _isDisabledDatepicker: function (target) { if (!target) { return false; } @@ -423,11 +438,10 @@ * @return object - the associated instance data * @throws error if a jQuery problem getting data */ - _getInst: function(target) { + _getInst: function (target) { try { return $.data(target, PROP_NAME); - } - catch (err) { + } catch (err) { throw "Missing instance data for this datepicker"; } }, @@ -441,7 +455,7 @@ * @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) { + _optionDatepicker: function (target, name, value) { var settings, date, minDate, maxDate, inst = this._getInst(target); @@ -473,8 +487,8 @@ if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) { inst.settings.maxDate = this._formatDate(inst, maxDate); } - if ( "disabled" in settings ) { - if ( settings.disabled ) { + if ("disabled" in settings) { + if (settings.disabled) { this._disableDatepicker(target); } else { this._enableDatepicker(target); @@ -489,14 +503,14 @@ }, // change method deprecated - _changeDatepicker: function(target, name, value) { + _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) { + _refreshDatepicker: function (target) { var inst = this._getInst(target); if (inst) { this._updateDatepicker(inst); @@ -507,7 +521,7 @@ * @param target element - the target input field or division or span * @param date Date - the new date */ - _setDateDatepicker: function(target, date) { + _setDateDatepicker: function (target, date) { var inst = this._getInst(target); if (inst) { this._setDate(inst, date); @@ -521,7 +535,7 @@ * @param noDefault boolean - true if no default date is to be used * @return Date - the current date */ - _getDateDatepicker: function(target, noDefault) { + _getDateDatepicker: function (target, noDefault) { var inst = this._getInst(target); if (inst && !inst.inline) { this._setDateFromField(inst, noDefault); @@ -530,7 +544,7 @@ }, /* Handle keystrokes. */ - _doKeyDown: function(event) { + _doKeyDown: function (event) { var onSelect, dateStr, sel, inst = $.datepicker._getInst(event.target), handled = true, @@ -539,11 +553,13 @@ inst._keyEvent = true; if ($.datepicker._datepickerShowing) { switch (event.keyCode) { - case 9: $.datepicker._hideDatepicker(); + case 9: + $.datepicker._hideDatepicker(); handled = false; break; // hide on tab out - case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." + - $.datepicker._currentClass + ")", inst.dpDiv); + case 13: + sel = $("td." + $.datepicker._dayOverClass + ":not(." + + $.datepicker._currentClass + ")", inst.dpDiv); if (sel[0]) { $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]); } @@ -559,29 +575,35 @@ } return false; // don't submit the form - case 27: $.datepicker._hideDatepicker(); + 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"); + 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"); + 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); - } + 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); - } + 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"); - } + 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) { @@ -591,14 +613,16 @@ } // next month/year on alt +left on Mac break; - case 38: if (event.ctrlKey || event.metaKey) { - $.datepicker._adjustDate(event.target, -7, "D"); - } + 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"); - } + 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) { @@ -608,12 +632,14 @@ } // next month/year on alt +right break; - case 40: if (event.ctrlKey || event.metaKey) { - $.datepicker._adjustDate(event.target, +7, "D"); - } + 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; + default: + handled = false; } } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home $.datepicker._showDatepicker(this); @@ -628,7 +654,7 @@ }, /* Filter entered characters - based on date format. */ - _doKeyPress: function(event) { + _doKeyPress: function (event) { var chars, chr, inst = $.datepicker._getInst(event.target); @@ -640,7 +666,7 @@ }, /* Synchronise manual entry and field/alternate field. */ - _doKeyUp: function(event) { + _doKeyUp: function (event) { var date, inst = $.datepicker._getInst(event.target); @@ -655,8 +681,7 @@ $.datepicker._updateAlternate(inst); $.datepicker._updateDatepicker(inst); } - } - catch (err) { + } catch (err) { } } return true; @@ -667,7 +692,7 @@ * @param input element - the input field attached to the date picker or * event - if triggered by focus */ - _showDatepicker: function(input) { + _showDatepicker: function (input) { input = input.target || input; if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger input = $("input", input.parentNode)[0]; @@ -683,14 +708,14 @@ 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 (inst && $.datepicker._datepickerShowing) { + $.datepicker._hideDatepicker($.datepicker._curInst.input[0]); } } beforeShow = $.datepicker._get(inst, "beforeShow"); beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {}; - if(beforeShowSettings === false){ + if (beforeShowSettings === false) { return; } extendRemove(inst.settings, beforeShowSettings); @@ -708,7 +733,7 @@ } isFixed = false; - $(input).parents().each(function() { + $(input).parents().each(function () { isFixed |= $(this).css("position") === "fixed"; return !isFixed; }); @@ -723,23 +748,25 @@ // 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 ? + inst.dpDiv.css({ + position: ($.datepicker._inDialog && $.blockUI ? "static" : (isFixed ? "fixed" : "absolute")), display: "none", - left: offset.left + "px", top: offset.top + "px"}); + left: offset.left + "px", top: offset.top + "px" + }); if (!inst.inline) { showAnim = $.datepicker._get(inst, "showAnim"); duration = $.datepicker._get(inst, "duration"); - inst.dpDiv.zIndex($(input).zIndex()+1); + inst.dpDiv.zIndex($(input).zIndex() + 1); $.datepicker._datepickerShowing = true; - if ( $.effects && $.effects.effect[ showAnim ] ) { + 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 ) ) { + if ($.datepicker._shouldFocusInput(inst)) { inst.input.focus(); } @@ -748,7 +775,7 @@ }, /* Generate the date picker content. */ - _updateDatepicker: function(inst) { + _updateDatepicker: function (inst) { this.maxRows = 4; //Reset the max number of rows being displayed (see #7043) instActive = inst; // for delegate hover events inst.dpDiv.empty().append(this._generateHTML(inst)); @@ -769,16 +796,16 @@ inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") + "Class"]("ui-datepicker-rtl"); - if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) { + if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput(inst)) { inst.input.focus(); } // deffered render of the years select (to avoid flashes on Firefox) - if( inst.yearshtml ){ + if (inst.yearshtml) { origyearshtml = inst.yearshtml; - setTimeout(function(){ + setTimeout(function () { //assure that inst.yearshtml didn't change. - if( origyearshtml === inst.yearshtml && inst.yearshtml ){ + if (origyearshtml === inst.yearshtml && inst.yearshtml) { inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml); } origyearshtml = inst.yearshtml = null; @@ -789,12 +816,12 @@ // #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" ); + _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) { + _checkOffset: function (inst, offset, isFixed) { var dpWidth = inst.dpDiv.outerWidth(), dpHeight = inst.dpDiv.outerHeight(), inputWidth = inst.input ? inst.input.outerWidth() : 0, @@ -816,7 +843,7 @@ }, /* Find an object's position on the screen. */ - _findPos: function(obj) { + _findPos: function (obj) { var position, inst = this._getInst(obj), isRTL = this._get(inst, "isRTL"); @@ -832,7 +859,7 @@ /* Hide the date picker from view. * @param input element - the input field attached to the date picker */ - _hideDatepicker: function(input) { + _hideDatepicker: function (input) { var showAnim, duration, postProcess, onClose, inst = this._curInst; @@ -843,12 +870,12 @@ if (this._datepickerShowing) { showAnim = this._get(inst, "showAnim"); duration = this._get(inst, "duration"); - postProcess = function() { + postProcess = function () { $.datepicker._tidyDialog(inst); }; // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed - if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) { + if ($.effects && ($.effects.effect[showAnim] || $.effects[showAnim])) { inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess); } else { inst.dpDiv[(showAnim === "slideDown" ? "slideUp" : @@ -867,7 +894,7 @@ this._lastInput = null; if (this._inDialog) { - this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" }); + this._dialogInput.css({position: "absolute", left: "0", top: "-100px"}); if ($.blockUI) { $.unblockUI(); $("body").append(this.dpDiv); @@ -878,12 +905,12 @@ }, /* Tidy up after a dialog display. */ - _tidyDialog: function(inst) { + _tidyDialog: function (inst) { inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar"); }, /* Close date picker if clicked elsewhere. */ - _checkExternalClick: function(event) { + _checkExternalClick: function (event) { if (!$.datepicker._curInst) { return; } @@ -891,18 +918,18 @@ var $target = $(event.target), inst = $.datepicker._getInst($target[0]); - if ( ( ( $target[0].id !== $.datepicker._mainDivId && + 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._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) { + _adjustDate: function (id, offset, period) { var target = $(id), inst = this._getInst(target[0]); @@ -916,7 +943,7 @@ }, /* Action for current link. */ - _gotoToday: function(id) { + _gotoToday: function (id) { var date, target = $(id), inst = this._getInst(target[0]); @@ -936,20 +963,20 @@ }, /* Action for selecting a new month/year. */ - _selectMonthYear: function(id, select, period) { + _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); + parseInt(select.options[select.selectedIndex].value, 10); this._notifyChange(inst); this._adjustDate(target); }, /* Action for selecting a day. */ - _selectDay: function(id, month, year, td) { + _selectDay: function (id, month, year, td) { var inst, target = $(id); @@ -966,13 +993,13 @@ }, /* Erase the input field and hide the date picker. */ - _clearDate: function(id) { + _clearDate: function (id) { var target = $(id); this._selectDate(target, ""); }, /* Update the input field with the selected date. */ - _selectDate: function(id, dateStr) { + _selectDate: function (id, dateStr) { var onSelect, target = $(id), inst = this._getInst(target[0]); @@ -990,12 +1017,12 @@ inst.input.trigger("change"); // fire the change event } - if (inst.inline){ + if (inst.inline) { this._updateDatepicker(inst); } else { this._hideDatepicker(); this._lastInput = inst.input[0]; - if (typeof(inst.input[0]) !== "object") { + if (typeof (inst.input[0]) !== "object") { inst.input.focus(); // restore focus } this._lastInput = null; @@ -1003,7 +1030,7 @@ }, /* Update any alternate field to synchronise with the main field. */ - _updateAlternate: function(inst) { + _updateAlternate: function (inst) { var altFormat, date, dateStr, altField = this._get(inst, "altField"); @@ -1011,7 +1038,9 @@ altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat"); date = this._getDate(inst); dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst)); - $(altField).each(function() { $(this).val(dateStr); }); + $(altField).each(function () { + $(this).val(dateStr); + }); } }, @@ -1019,7 +1048,7 @@ * @param date Date - the date to customise * @return [boolean, string] - is this date selectable?, what is its CSS class? */ - noWeekends: function(date) { + noWeekends: function (date) { var day = date.getDay(); return [(day > 0 && day < 6), ""]; }, @@ -1028,7 +1057,7 @@ * @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) { + iso8601Week: function (date) { var time, checkDate = new Date(date.getTime()); @@ -1080,7 +1109,7 @@ literal = false, date, // Check whether a format character is doubled - lookAhead = function(match) { + lookAhead = function (match) { var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); if (matches) { iFormat++; @@ -1088,7 +1117,7 @@ return matches; }, // Extract a number from the string value - getNumber = function(match) { + getNumber = function (match) { var isDoubled = lookAhead(match), size = (match === "@" ? 14 : (match === "!" ? 20 : (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))), @@ -1101,10 +1130,10 @@ return parseInt(num[0], 10); }, // Extract a name from the string value and convert to an index - getName = function(match, shortNames, longNames) { + getName = function (match, shortNames, longNames) { var index = -1, names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) { - return [ [k, v] ]; + return [[k, v]]; }).sort(function (a, b) { return -(a[1].length - b[1].length); }); @@ -1124,7 +1153,7 @@ } }, // Confirm that a literal character matches the string value - checkLiteral = function() { + checkLiteral = function () { if (value.charAt(iValue) !== format.charAt(iFormat)) { throw "Unexpected literal at position " + iValue; } @@ -1171,7 +1200,7 @@ day = date.getDate(); break; case "'": - if (lookAhead("'")){ + if (lookAhead("'")) { checkLiteral(); } else { literal = true; @@ -1183,7 +1212,7 @@ } } - if (iValue < value.length){ + if (iValue < value.length) { extra = value.substr(iValue); if (!/^\s+/.test(extra)) { throw "Extra/unparsed characters found in date: " + extra; @@ -1273,7 +1302,7 @@ 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) { + lookAhead = function (match) { var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); if (matches) { iFormat++; @@ -1281,7 +1310,7 @@ return matches; }, // Format a number, with leading zero if necessary - formatNumber = function(match, value, len) { + formatNumber = function (match, value, len) { var num = "" + value; if (lookAhead(match)) { while (num.length < len) { @@ -1291,7 +1320,7 @@ return num; }, // Format a name, short or long as requested - formatName = function(match, value, shortNames, longNames) { + formatName = function (match, value, shortNames, longNames) { return (lookAhead(match) ? longNames[value] : shortNames[value]); }, output = "", @@ -1355,7 +1384,7 @@ chars = "", literal = false, // Check whether a format character is doubled - lookAhead = function(match) { + lookAhead = function (match) { var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); if (matches) { iFormat++; @@ -1372,10 +1401,14 @@ } } else { switch (format.charAt(iFormat)) { - case "d": case "m": case "y": case "@": + case "d": + case "m": + case "y": + case "@": chars += "0123456789"; break; - case "D": case "M": + case "D": + case "M": return null; // Accept anything case "'": if (lookAhead("'")) { @@ -1393,13 +1426,13 @@ }, /* Get a setting value, defaulting if necessary. */ - _get: function(inst, name) { + _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) { + _setDateFromField: function (inst, noDefault) { if (inst.input.val() === inst.lastVal) { return; } @@ -1425,24 +1458,23 @@ }, /* Retrieve the default date shown on opening. */ - _getDefaultDate: function(inst) { + _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) { + _determineDate: function (inst, date, defaultDate) { + var offsetNumeric = function (offset) { var date = new Date(); date.setDate(date.getDate() + offset); return date; }, - offsetString = function(offset) { + offsetString = function (offset) { try { return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), offset, $.datepicker._getFormatConfig(inst)); - } - catch (e) { + } catch (e) { // Ignore } @@ -1456,16 +1488,22 @@ 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); + 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); + case "y": + case "Y" : + year += parseInt(matches[1], 10); day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); break; } @@ -1493,7 +1531,7 @@ * @param date (Date) the date to check * @return (Date) the corrected date */ - _daylightSavingAdjust: function(date) { + _daylightSavingAdjust: function (date) { if (!date) { return null; } @@ -1502,7 +1540,7 @@ }, /* Set the date(s) directly. */ - _setDate: function(inst, date, noChange) { + _setDate: function (inst, date, noChange) { var clear = !date, origMonth = inst.selectedMonth, origYear = inst.selectedYear, @@ -1521,7 +1559,7 @@ }, /* Retrieve the date(s) directly. */ - _getDate: function(inst) { + _getDate: function (inst) { var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null : this._daylightSavingAdjust(new Date( inst.currentYear, inst.currentMonth, inst.currentDay))); @@ -1531,9 +1569,9 @@ /* Attach the onxxx handlers. These are declared statically so * they work with static code transformers like Caja. */ - _attachHandlers: function(inst) { + _attachHandlers: function (inst) { var stepMonths = this._get(inst, "stepMonths"), - id = "#" + inst.id.replace( /\\\\/g, "\\" ); + id = "#" + inst.id.replace(/\\\\/g, "\\"); inst.dpDiv.find("[data-handler]").map(function () { var handler = { prev: function () { @@ -1566,7 +1604,7 @@ }, /* Generate the HTML for the current state of the date picker. */ - _generateHTML: function(inst) { + _generateHTML: function (inst) { var maxDraw, prevText, prev, nextText, next, currentText, gotoDate, controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin, monthNames, monthNamesShort, beforeShowDay, showOtherMonths, @@ -1617,8 +1655,8 @@ prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ? "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" + - " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" : - (hideIfNoPrevNext ? "" : "<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='"+ prevText +"'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>")); + " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + (isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" : + (hideIfNoPrevNext ? "" : "<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + (isRTL ? "e" : "w") + "'>" + prevText + "</span></a>")); nextText = this._get(inst, "nextText"); nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText, @@ -1627,8 +1665,8 @@ next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ? "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" + - " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" : - (hideIfNoPrevNext ? "" : "<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='"+ nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>")); + " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + (isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" : + (hideIfNoPrevNext ? "" : "<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + (isRTL ? "w" : "e") + "'>" + nextText + "</span></a>")); currentText = this._get(inst, "currentText"); gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today); @@ -1642,7 +1680,7 @@ (this._isInRange(inst, gotoDate) ? "<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'" + ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : ""; - firstDay = parseInt(this._get(inst, "firstDay"),10); + firstDay = parseInt(this._get(inst, "firstDay"), 10); firstDay = (isNaN(firstDay) ? 0 : firstDay); showWeek = this._get(inst, "showWeek"); @@ -1667,11 +1705,18 @@ 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; + 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 += "'>"; @@ -1716,7 +1761,7 @@ (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 + (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) @@ -1739,7 +1784,7 @@ drawYear++; } calender += "</tbody></table>" + (isMultiMonth ? "</div>" + - ((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : ""); + ((numMonths[0] > 0 && col === numMonths[1] - 1) ? "<div class='ui-datepicker-row-break'></div>" : "") : ""); group += calender; } html += group; @@ -1750,8 +1795,8 @@ }, /* Generate the month and year header. */ - _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate, - secondary, monthNames, monthNamesShort) { + _generateMonthYearHeader: function (inst, drawMonth, drawYear, minDate, maxDate, + secondary, monthNames, monthNamesShort) { var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear, changeMonth = this._get(inst, "changeMonth"), @@ -1767,7 +1812,7 @@ inMinYear = (minDate && minDate.getFullYear() === drawYear); inMaxYear = (maxDate && maxDate.getFullYear() === drawYear); monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>"; - for ( month = 0; month < 12; month++) { + for (month = 0; month < 12; month++) { if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) { monthHtml += "<option value='" + month + "'" + (month === drawMonth ? " selected='selected'" : "") + @@ -1782,7 +1827,7 @@ } // year selection - if ( !inst.yearshtml ) { + if (!inst.yearshtml) { inst.yearshtml = ""; if (secondary || !changeYear) { html += "<span class='ui-datepicker-year'>" + drawYear + "</span>"; @@ -1790,7 +1835,7 @@ // determine range of years to display years = this._get(inst, "yearRange").split(":"); thisYear = new Date().getFullYear(); - determineYear = function(value) { + determineYear = function (value) { var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) : (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) : parseInt(value, 10))); @@ -1822,7 +1867,7 @@ }, /* Adjust one of the date sub-fields. */ - _adjustInstDate: function(inst, offset, period) { + _adjustInstDate: function (inst, offset, period) { var year = inst.drawYear + (period === "Y" ? offset : 0), month = inst.drawMonth + (period === "M" ? offset : 0), day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0), @@ -1837,7 +1882,7 @@ }, /* Ensure a date is within any min/max bounds. */ - _restrictMinMax: function(inst, date) { + _restrictMinMax: function (inst, date) { var minDate = this._getMinMaxDate(inst, "min"), maxDate = this._getMinMaxDate(inst, "max"), newDate = (minDate && date < minDate ? minDate : date); @@ -1845,7 +1890,7 @@ }, /* Notify change of month/year. */ - _notifyChange: function(inst) { + _notifyChange: function (inst) { var onChange = this._get(inst, "onChangeMonthYear"); if (onChange) { onChange.apply((inst.input ? inst.input[0] : null), @@ -1854,28 +1899,28 @@ }, /* Determine the number of months to show. */ - _getNumberOfMonths: function(inst) { + _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) { + _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) { + _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) { + _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) { + _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)); @@ -1887,22 +1932,22 @@ }, /* Is the given date in the accepted range? */ - _isInRange: function(inst, date) { + _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){ + if (years) { yearSplit = years.split(":"); currentYear = new Date().getFullYear(); minYear = parseInt(yearSplit[0], 10); maxYear = parseInt(yearSplit[1], 10); - if ( yearSplit[0].match(/[+\-].*/) ) { + if (yearSplit[0].match(/[+\-].*/)) { minYear += currentYear; } - if ( yearSplit[1].match(/[+\-].*/) ) { + if (yearSplit[1].match(/[+\-].*/)) { maxYear += currentYear; } } @@ -1914,17 +1959,19 @@ }, /* Provide the configuration settings for formatting/parsing. */ - _getFormatConfig: function(inst) { + _getFormatConfig: function (inst) { var shortYearCutoff = this._get(inst, "shortYearCutoff"); shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff : new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); - return {shortYearCutoff: shortYearCutoff, + return { + shortYearCutoff: shortYearCutoff, dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"), - monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")}; + monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames") + }; }, /* Format the given date for display. */ - _formatDate: function(inst, day, month, year) { + _formatDate: function (inst, day, month, year) { if (!day) { inst.currentDay = inst.selectedDay; inst.currentMonth = inst.selectedMonth; @@ -1944,7 +1991,7 @@ */ function bindHover(dpDiv) { var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a"; - return dpDiv.delegate(selector, "mouseout", function() { + return dpDiv.delegate(selector, "mouseout", function () { $(this).removeClass("ui-state-hover"); if (this.className.indexOf("ui-datepicker-prev") !== -1) { $(this).removeClass("ui-datepicker-prev-hover"); @@ -1953,8 +2000,8 @@ $(this).removeClass("ui-datepicker-next-hover"); } }) - .delegate(selector, "mouseover", function(){ - if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) { + .delegate(selector, "mouseover", function () { + if (!$.datepicker._isDisabledDatepicker(instActive.inline ? dpDiv.parent()[0] : 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) { @@ -1982,10 +2029,10 @@ @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){ + $.fn.datepicker = function (options) { /* Verify an empty collection wasn't passed - Fixes #6976 */ - if ( !this.length ) { + if (!this.length) { return this; } @@ -1996,23 +2043,20 @@ } /* Append datepicker main container to body if not exist. */ - if ($("#"+$.datepicker._mainDivId).length === 0) { + 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)); + 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 $.datepicker["_" + options + "Datepicker"].apply($.datepicker, [this[0]].concat(otherArgs)); } - return this.each(function() { + return this.each(function () { typeof options === "string" ? - $.datepicker["_" + options + "Datepicker"]. - apply($.datepicker, [this].concat(otherArgs)) : + $.datepicker["_" + options + "Datepicker"].apply($.datepicker, [this].concat(otherArgs)) : $.datepicker._attachDatepicker(this, options); }); }; @@ -2022,4 +2066,4 @@ $.datepicker.uuid = new Date().getTime(); $.datepicker.version = "1.10.4"; -})(jQuery); +}); diff --git a/lib/web/jquery/ui-modules/dialog.js b/lib/web/jquery/ui-modules/dialog.js index 94d7a36111b0..bd9a60a8fbe2 100644 --- a/lib/web/jquery/ui-modules/dialog.js +++ b/lib/web/jquery/ui-modules/dialog.js @@ -1,4 +1,24 @@ -(function( $, undefined ) { +/*! + * jQuery UI Dialog + * http://jqueryui.com + * + * Copyright 2014 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/dialog/ + */ + +define([ + 'jquery', + 'jquery-ui-modules/core', + 'jquery-ui-modules/widget', + 'jquery-ui-modules/button', + 'jquery-ui-modules/draggable', + 'jquery-ui-modules/mouse', + 'jquery-ui-modules/position', + 'jquery-ui-modules/resizable' +], function ($, undefined) { var sizeRelatedOptions = { buttons: true, @@ -16,7 +36,7 @@ minWidth: true }; - $.widget( "ui.dialog", { + $.widget("ui.dialog", { version: "1.10.4", options: { appendTo: "body", @@ -39,10 +59,10 @@ 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 ); + using: function (pos) { + var topOffset = $(this).css(pos).offset().top; + if (topOffset < 0) { + $(this).css("top", pos.top - topOffset); } } }, @@ -64,7 +84,7 @@ resizeStop: null }, - _create: function() { + _create: function () { this.originalCss = { display: this.element[0].style.display, width: this.element[0].style.width, @@ -74,7 +94,7 @@ }; this.originalPosition = { parent: this.element.parent(), - index: this.element.parent().children().index( this.element ) + index: this.element.parent().children().index(this.element) }; this.originalTitle = this.element.attr("title"); this.options.title = this.options.title || this.originalTitle; @@ -85,36 +105,36 @@ .show() .removeAttr("title") .addClass("ui-dialog-content ui-widget-content") - .appendTo( this.uiDialog ); + .appendTo(this.uiDialog); this._createTitlebar(); this._createButtonPane(); - if ( this.options.draggable && $.fn.draggable ) { + if (this.options.draggable && $.fn.draggable) { this._makeDraggable(); } - if ( this.options.resizable && $.fn.resizable ) { + if (this.options.resizable && $.fn.resizable) { this._makeResizable(); } this._isOpen = false; }, - _init: function() { - if ( this.options.autoOpen ) { + _init: function () { + if (this.options.autoOpen) { this.open(); } }, - _appendTo: function() { + _appendTo: function () { var element = this.options.appendTo; - if ( element && (element.jquery || element.nodeType) ) { - return $( element ); + if (element && (element.jquery || element.nodeType)) { + return $(element); } - return this.document.find( element || "body" ).eq( 0 ); + return this.document.find(element || "body").eq(0); }, - _destroy: function() { + _destroy: function () { var next, originalPosition = this.originalPosition; @@ -123,100 +143,101 @@ this.element .removeUniqueId() .removeClass("ui-dialog-content ui-widget-content") - .css( this.originalCss ) + .css(this.originalCss) // Without detaching first, the following becomes really slow .detach(); - this.uiDialog.stop( true, true ).remove(); + this.uiDialog.stop(true, true).remove(); - if ( this.originalTitle ) { - this.element.attr( "title", this.originalTitle ); + if (this.originalTitle) { + this.element.attr("title", this.originalTitle); } - next = originalPosition.parent.children().eq( originalPosition.index ); + 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 ); + if (next.length && next[0] !== this.element[0]) { + next.before(this.element); } else { - originalPosition.parent.append( this.element ); + originalPosition.parent.append(this.element); } }, - widget: function() { + widget: function () { return this.uiDialog; }, disable: $.noop, enable: $.noop, - close: function( event ) { + close: function (event) { var activeElement, that = this; - if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) { + if (!this._isOpen || this._trigger("beforeClose", event) === false) { return; } this._isOpen = false; this._destroyOverlay(); - if ( !this.opener.filter(":focusable").focus().length ) { + if (!this.opener.filter(":focusable").focus().length) { // support: IE9 // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe> try { - activeElement = this.document[ 0 ].activeElement; + activeElement = this.document[0].activeElement; // Support: IE9, IE10 // If the <body> is blurred, IE will switch windows, see #4520 - if ( activeElement && activeElement.nodeName.toLowerCase() !== "body" ) { + if (activeElement && activeElement.nodeName.toLowerCase() !== "body") { // 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 - $( activeElement ).blur(); + $(activeElement).blur(); } - } catch ( error ) {} + } catch (error) { + } } - this._hide( this.uiDialog, this.options.hide, function() { - that._trigger( "close", event ); + this._hide(this.uiDialog, this.options.hide, function () { + that._trigger("close", event); }); }, - isOpen: function() { + isOpen: function () { return this._isOpen; }, - moveToTop: function() { + moveToTop: function () { this._moveToTop(); }, - _moveToTop: function( event, silent ) { - var moved = !!this.uiDialog.nextAll(":visible").insertBefore( this.uiDialog ).length; - if ( moved && !silent ) { - this._trigger( "focus", event ); + _moveToTop: function (event, silent) { + var moved = !!this.uiDialog.nextAll(":visible").insertBefore(this.uiDialog).length; + if (moved && !silent) { + this._trigger("focus", event); } return moved; }, - open: function() { + open: function () { var that = this; - if ( this._isOpen ) { - if ( this._moveToTop() ) { + if (this._isOpen) { + if (this._moveToTop()) { this._focusTabbable(); } return; } this._isOpen = true; - this.opener = $( this.document[0].activeElement ); + this.opener = $(this.document[0].activeElement); this._size(); this._position(); this._createOverlay(); - this._moveToTop( null, true ); - this._show( this.uiDialog, this.options.show, function() { + this._moveToTop(null, true); + this._show(this.uiDialog, this.options.show, function () { that._focusTabbable(); that._trigger("focus"); }); @@ -224,7 +245,7 @@ this._trigger("open"); }, - _focusTabbable: function() { + _focusTabbable: function () { // Set focus to the first match: // 1. First element inside the dialog matching [autofocus] // 2. Tabbable element inside the content element @@ -232,77 +253,78 @@ // 4. The close button // 5. The dialog itself var hasFocus = this.element.find("[autofocus]"); - if ( !hasFocus.length ) { + if (!hasFocus.length) { hasFocus = this.element.find(":tabbable"); } - if ( !hasFocus.length ) { + if (!hasFocus.length) { hasFocus = this.uiDialogButtonPane.find(":tabbable"); } - if ( !hasFocus.length ) { + if (!hasFocus.length) { hasFocus = this.uiDialogTitlebarClose.filter(":tabbable"); } - if ( !hasFocus.length ) { + if (!hasFocus.length) { hasFocus = this.uiDialog; } - hasFocus.eq( 0 ).focus(); + hasFocus.eq(0).focus(); }, - _keepFocus: function( event ) { + _keepFocus: function (event) { function checkFocus() { var activeElement = this.document[0].activeElement, isActive = this.uiDialog[0] === activeElement || - $.contains( this.uiDialog[0], activeElement ); - if ( !isActive ) { + $.contains(this.uiDialog[0], activeElement); + if (!isActive) { this._focusTabbable(); } } + event.preventDefault(); - checkFocus.call( this ); + checkFocus.call(this); // support: IE // IE <= 8 doesn't prevent moving focus even with event.preventDefault() // so we check again later - this._delay( checkFocus ); + this._delay(checkFocus); }, - _createWrapper: function() { + _createWrapper: function () { this.uiDialog = $("<div>") - .addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " + - this.options.dialogClass ) + .addClass("ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " + + this.options.dialogClass) .hide() .attr({ // Setting tabIndex makes the div focusable tabIndex: -1, role: "dialog" }) - .appendTo( this._appendTo() ); + .appendTo(this._appendTo()); - this._on( this.uiDialog, { - keydown: function( event ) { - if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && - event.keyCode === $.ui.keyCode.ESCAPE ) { + 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 ); + this.close(event); return; } // prevent tabbing out of dialogs - if ( event.keyCode !== $.ui.keyCode.TAB ) { + if (event.keyCode !== $.ui.keyCode.TAB) { return; } var tabbables = this.uiDialog.find(":tabbable"), first = tabbables.filter(":first"), - last = tabbables.filter(":last"); + last = tabbables.filter(":last"); - if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) { - first.focus( 1 ); + if ((event.target === last[0] || event.target === this.uiDialog[0]) && !event.shiftKey) { + first.focus(1); event.preventDefault(); - } else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) { - last.focus( 1 ); + } else if ((event.target === first[0] || event.target === this.uiDialog[0]) && event.shiftKey) { + last.focus(1); event.preventDefault(); } }, - mousedown: function( event ) { - if ( this._moveToTop( event ) ) { + mousedown: function (event) { + if (this._moveToTop(event)) { this._focusTabbable(); } } @@ -311,25 +333,25 @@ // 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 ) { + if (!this.element.find("[aria-describedby]").length) { this.uiDialog.attr({ "aria-describedby": this.element.uniqueId().attr("id") }); } }, - _createTitlebar: function() { + _createTitlebar: function () { var uiDialogTitle; this.uiDialogTitlebar = $("<div>") .addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix") - .prependTo( this.uiDialog ); - this._on( this.uiDialogTitlebar, { - mousedown: function( event ) { + .prependTo(this.uiDialog); + 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") ) { + if (!$(event.target).closest(".ui-dialog-titlebar-close")) { // Dialog isn't getting focus when dragging (#8063) this.uiDialog.focus(); } @@ -339,7 +361,7 @@ // support: IE // Use type="button" to prevent enter keypresses in textboxes from closing the // dialog in IE (#9312) - this.uiDialogTitlebarClose = $( "<button type='button'></button>" ) + this.uiDialogTitlebarClose = $("<button type='button'></button>") .button({ label: this.options.closeText, icons: { @@ -348,44 +370,44 @@ text: false }) .addClass("ui-dialog-titlebar-close") - .appendTo( this.uiDialogTitlebar ); - this._on( this.uiDialogTitlebarClose, { - click: function( event ) { + .appendTo(this.uiDialogTitlebar); + this._on(this.uiDialogTitlebarClose, { + click: function (event) { event.preventDefault(); - this.close( event ); + this.close(event); } }); uiDialogTitle = $("<span>") .uniqueId() .addClass("ui-dialog-title") - .prependTo( this.uiDialogTitlebar ); - this._title( uiDialogTitle ); + .prependTo(this.uiDialogTitlebar); + this._title(uiDialogTitle); this.uiDialog.attr({ "aria-labelledby": uiDialogTitle.attr("id") }); }, - _title: function( title ) { - if ( !this.options.title ) { + _title: function (title) { + if (!this.options.title) { title.html(" "); } - title.text( this.options.title ); + title.text(this.options.title); }, - _createButtonPane: function() { + _createButtonPane: function () { this.uiDialogButtonPane = $("<div>") .addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"); this.uiButtonSet = $("<div>") .addClass("ui-dialog-buttonset") - .appendTo( this.uiDialogButtonPane ); + .appendTo(this.uiDialogButtonPane); this._createButtons(); }, - _createButtons: function() { + _createButtons: function () { var that = this, buttons = this.options.buttons; @@ -393,22 +415,22 @@ this.uiDialogButtonPane.remove(); this.uiButtonSet.empty(); - if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) { + if ($.isEmptyObject(buttons) || ($.isArray(buttons) && !buttons.length)) { this.uiDialog.removeClass("ui-dialog-buttons"); return; } - $.each( buttons, function( name, props ) { + $.each(buttons, function (name, props) { var click, buttonOptions; - props = $.isFunction( props ) ? - { click: props, text: name } : + props = $.isFunction(props) ? + {click: props, text: name} : props; // Default to a non-submitting button - props = $.extend( { type: "button" }, props ); + props = $.extend({type: "button"}, props); // Change the context for the click callback to be the main element click = props.click; - props.click = function() { - click.apply( that.element[0], arguments ); + props.click = function () { + click.apply(that.element[0], arguments); }; buttonOptions = { icons: props.icons, @@ -416,19 +438,19 @@ }; delete props.icons; delete props.showText; - $( "<button></button>", props ) - .button( buttonOptions ) - .appendTo( that.uiButtonSet ); + $("<button></button>", props) + .button(buttonOptions) + .appendTo(that.uiButtonSet); }); this.uiDialog.addClass("ui-dialog-buttons"); - this.uiDialogButtonPane.appendTo( this.uiDialog ); + this.uiDialogButtonPane.appendTo(this.uiDialog); }, - _makeDraggable: function() { + _makeDraggable: function () { var that = this, options = this.options; - function filteredUi( ui ) { + function filteredUi(ui) { return { position: ui.position, offset: ui.offset @@ -439,27 +461,27 @@ cancel: ".ui-dialog-content, .ui-dialog-titlebar-close", handle: ".ui-dialog-titlebar", containment: "document", - start: function( event, ui ) { - $( this ).addClass("ui-dialog-dragging"); + start: function (event, ui) { + $(this).addClass("ui-dialog-dragging"); that._blockFrames(); - that._trigger( "dragStart", event, filteredUi( ui ) ); + that._trigger("dragStart", event, filteredUi(ui)); }, - drag: function( event, ui ) { - that._trigger( "drag", event, filteredUi( ui ) ); + drag: function (event, ui) { + that._trigger("drag", event, filteredUi(ui)); }, - stop: function( event, ui ) { + stop: function (event, ui) { options.position = [ ui.position.left - that.document.scrollLeft(), ui.position.top - that.document.scrollTop() ]; - $( this ).removeClass("ui-dialog-dragging"); + $(this).removeClass("ui-dialog-dragging"); that._unblockFrames(); - that._trigger( "dragStop", event, filteredUi( ui ) ); + that._trigger("dragStop", event, filteredUi(ui)); } }); }, - _makeResizable: function() { + _makeResizable: function () { var that = this, options = this.options, handles = options.resizable, @@ -467,10 +489,10 @@ // but dialogs have to use absolute or fixed positioning position = this.uiDialog.css("position"), resizeHandles = typeof handles === "string" ? - handles : + handles : "n,e,s,w,se,sw,ne,nw"; - function filteredUi( ui ) { + function filteredUi(ui) { return { originalPosition: ui.originalPosition, originalSize: ui.originalSize, @@ -488,140 +510,140 @@ minWidth: options.minWidth, minHeight: this._minHeight(), handles: resizeHandles, - start: function( event, ui ) { - $( this ).addClass("ui-dialog-resizing"); + start: function (event, ui) { + $(this).addClass("ui-dialog-resizing"); that._blockFrames(); - that._trigger( "resizeStart", event, filteredUi( ui ) ); + that._trigger("resizeStart", event, filteredUi(ui)); }, - resize: function( event, ui ) { - that._trigger( "resize", event, filteredUi( ui ) ); + resize: function (event, ui) { + that._trigger("resize", event, filteredUi(ui)); }, - stop: function( event, ui ) { - options.height = $( this ).height(); - options.width = $( this ).width(); - $( this ).removeClass("ui-dialog-resizing"); + stop: function (event, ui) { + options.height = $(this).height(); + options.width = $(this).width(); + $(this).removeClass("ui-dialog-resizing"); that._unblockFrames(); - that._trigger( "resizeStop", event, filteredUi( ui ) ); + that._trigger("resizeStop", event, filteredUi(ui)); } }) - .css( "position", position ); + .css("position", position); }, - _minHeight: function() { + _minHeight: function () { var options = this.options; return options.height === "auto" ? options.minHeight : - Math.min( options.minHeight, options.height ); + Math.min(options.minHeight, options.height); }, - _position: function() { + _position: function () { // Need to show the dialog to get the actual offset in the position plugin var isVisible = this.uiDialog.is(":visible"); - if ( !isVisible ) { + if (!isVisible) { this.uiDialog.show(); } - this.uiDialog.position( this.options.position ); - if ( !isVisible ) { + this.uiDialog.position(this.options.position); + if (!isVisible) { this.uiDialog.hide(); } }, - _setOptions: function( options ) { + _setOptions: function (options) { var that = this, resize = false, resizableOptions = {}; - $.each( options, function( key, value ) { - that._setOption( key, value ); + $.each(options, function (key, value) { + that._setOption(key, value); - if ( key in sizeRelatedOptions ) { + if (key in sizeRelatedOptions) { resize = true; } - if ( key in resizableRelatedOptions ) { - resizableOptions[ key ] = value; + if (key in resizableRelatedOptions) { + resizableOptions[key] = value; } }); - if ( resize ) { + if (resize) { this._size(); this._position(); } - if ( this.uiDialog.is(":data(ui-resizable)") ) { - this.uiDialog.resizable( "option", resizableOptions ); + if (this.uiDialog.is(":data(ui-resizable)")) { + this.uiDialog.resizable("option", resizableOptions); } }, - _setOption: function( key, value ) { + _setOption: function (key, value) { var isDraggable, isResizable, uiDialog = this.uiDialog; - if ( key === "dialogClass" ) { + if (key === "dialogClass") { uiDialog - .removeClass( this.options.dialogClass ) - .addClass( value ); + .removeClass(this.options.dialogClass) + .addClass(value); } - if ( key === "disabled" ) { + if (key === "disabled") { return; } - this._super( key, value ); + this._super(key, value); - if ( key === "appendTo" ) { - this.uiDialog.appendTo( this._appendTo() ); + if (key === "appendTo") { + this.uiDialog.appendTo(this._appendTo()); } - if ( key === "buttons" ) { + if (key === "buttons") { this._createButtons(); } - if ( key === "closeText" ) { + if (key === "closeText") { this.uiDialogTitlebarClose.button({ // Ensure that we always pass a string label: "" + value }); } - if ( key === "draggable" ) { + if (key === "draggable") { isDraggable = uiDialog.is(":data(ui-draggable)"); - if ( isDraggable && !value ) { + if (isDraggable && !value) { uiDialog.draggable("destroy"); } - if ( !isDraggable && value ) { + if (!isDraggable && value) { this._makeDraggable(); } } - if ( key === "position" ) { + if (key === "position") { this._position(); } - if ( key === "resizable" ) { + if (key === "resizable") { // currently resizable, becoming non-resizable isResizable = uiDialog.is(":data(ui-resizable)"); - if ( isResizable && !value ) { + if (isResizable && !value) { uiDialog.resizable("destroy"); } // currently resizable, changing handles - if ( isResizable && typeof value === "string" ) { - uiDialog.resizable( "option", "handles", value ); + if (isResizable && typeof value === "string") { + uiDialog.resizable("option", "handles", value); } // currently non-resizable, becoming resizable - if ( !isResizable && value !== false ) { + if (!isResizable && value !== false) { this._makeResizable(); } } - if ( key === "title" ) { - this._title( this.uiDialogTitlebar.find(".ui-dialog-title") ); + if (key === "title") { + this._title(this.uiDialogTitlebar.find(".ui-dialog-title")); } }, - _size: function() { + _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, @@ -635,7 +657,7 @@ height: 0 }); - if ( options.minWidth > options.width ) { + if (options.minWidth > options.width) { options.width = options.minWidth; } @@ -646,77 +668,77 @@ width: options.width }) .outerHeight(); - minContentHeight = Math.max( 0, options.minHeight - nonContentHeight ); + minContentHeight = Math.max(0, options.minHeight - nonContentHeight); maxContentHeight = typeof options.maxHeight === "number" ? - Math.max( 0, options.maxHeight - nonContentHeight ) : + Math.max(0, options.maxHeight - nonContentHeight) : "none"; - if ( options.height === "auto" ) { + if (options.height === "auto") { this.element.css({ minHeight: minContentHeight, maxHeight: maxContentHeight, height: "auto" }); } else { - this.element.height( Math.max( 0, options.height - nonContentHeight ) ); + this.element.height(Math.max(0, options.height - nonContentHeight)); } - if (this.uiDialog.is(":data(ui-resizable)") ) { - this.uiDialog.resizable( "option", "minHeight", this._minHeight() ); + 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 ); + _blockFrames: function () { + this.iframeBlocks = this.document.find("iframe").map(function () { + var iframe = $(this); - return $( "<div>" ) + return $("<div>") .css({ position: "absolute", width: iframe.outerWidth(), height: iframe.outerHeight() }) - .appendTo( iframe.parent() ) - .offset( iframe.offset() )[0]; + .appendTo(iframe.parent()) + .offset(iframe.offset())[0]; }); }, - _unblockFrames: function() { - if ( this.iframeBlocks ) { + _unblockFrames: function () { + if (this.iframeBlocks) { this.iframeBlocks.remove(); delete this.iframeBlocks; } }, - _allowInteraction: function( event ) { - if ( $( event.target ).closest(".ui-dialog").length ) { + _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; + return !!$(event.target).closest(".ui-datepicker").length; }, - _createOverlay: function() { - if ( !this.options.modal ) { + _createOverlay: function () { + if (!this.options.modal) { return; } var that = this, widgetFullName = this.widgetFullName; - if ( !$.ui.dialog.overlayInstances ) { + if (!$.ui.dialog.overlayInstances) { // Prevent use of anchors and inputs. // We use a delay in case the overlay is created from an // event that we're going to be cancelling. (#2804) - this._delay(function() { + this._delay(function () { // Handle .dialog().dialog("close") (#4065) - if ( $.ui.dialog.overlayInstances ) { - this.document.bind( "focusin.dialog", function( event ) { - if ( !that._allowInteraction( event ) ) { + if ($.ui.dialog.overlayInstances) { + this.document.bind("focusin.dialog", function (event) { + if (!that._allowInteraction(event)) { event.preventDefault(); $(".ui-dialog:visible:last .ui-dialog-content") - .data( widgetFullName )._focusTabbable(); + .data(widgetFullName)._focusTabbable(); } }); } @@ -725,23 +747,23 @@ this.overlay = $("<div>") .addClass("ui-widget-overlay ui-front") - .appendTo( this._appendTo() ); - this._on( this.overlay, { + .appendTo(this._appendTo()); + this._on(this.overlay, { mousedown: "_keepFocus" }); $.ui.dialog.overlayInstances++; }, - _destroyOverlay: function() { - if ( !this.options.modal ) { + _destroyOverlay: function () { + if (!this.options.modal) { return; } - if ( this.overlay ) { + if (this.overlay) { $.ui.dialog.overlayInstances--; - if ( !$.ui.dialog.overlayInstances ) { - this.document.unbind( "focusin.dialog" ); + if (!$.ui.dialog.overlayInstances) { + this.document.unbind("focusin.dialog"); } this.overlay.remove(); this.overlay = null; @@ -752,27 +774,27 @@ $.ui.dialog.overlayInstances = 0; // DEPRECATED - if ( $.uiBackCompat !== false ) { + if ($.uiBackCompat !== false) { // position option with array notation // just override with old implementation - $.widget( "ui.dialog", $.ui.dialog, { - _position: function() { + $.widget("ui.dialog", $.ui.dialog, { + _position: function () { var position = this.options.position, myAt = [], - offset = [ 0, 0 ], + offset = [0, 0], isVisible; - if ( position ) { - if ( typeof position === "string" || (typeof position === "object" && "0" in position ) ) { - myAt = position.split ? position.split(" ") : [ position[0], position[1] ]; - if ( myAt.length === 1 ) { + if (position) { + if (typeof position === "string" || (typeof position === "object" && "0" in position)) { + myAt = position.split ? position.split(" ") : [position[0], position[1]]; + if (myAt.length === 1) { myAt[1] = myAt[0]; } - $.each( [ "left", "top" ], function( i, offsetPosition ) { - if ( +myAt[ i ] === myAt[ i ] ) { - offset[ i ] = myAt[ i ]; - myAt[ i ] = offsetPosition; + $.each(["left", "top"], function (i, offsetPosition) { + if (+myAt[i] === myAt[i]) { + offset[i] = myAt[i]; + myAt[i] = offsetPosition; } }); @@ -783,22 +805,22 @@ }; } - position = $.extend( {}, $.ui.dialog.prototype.options.position, position ); + position = $.extend({}, $.ui.dialog.prototype.options.position, position); } else { position = $.ui.dialog.prototype.options.position; } // need to show the dialog to get the actual offset in the position plugin isVisible = this.uiDialog.is(":visible"); - if ( !isVisible ) { + if (!isVisible) { this.uiDialog.show(); } - this.uiDialog.position( position ); - if ( !isVisible ) { + this.uiDialog.position(position); + if (!isVisible) { this.uiDialog.hide(); } } }); } -}( jQuery ) ); +}); diff --git a/lib/web/jquery/ui-modules/draggable.js b/lib/web/jquery/ui-modules/draggable.js index 43c378a0d425..b17ca262c5ec 100644 --- a/lib/web/jquery/ui-modules/draggable.js +++ b/lib/web/jquery/ui-modules/draggable.js @@ -1,4 +1,21 @@ -(function( $, undefined ) { +/*! + * jQuery UI Draggable + * http://jqueryui.com + * + * Copyright 2014 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/draggable/ + * + */ + +define([ + 'jquery', + 'jquery-ui-modules/core', + 'jquery-ui-modules/widget', + 'jquery-ui-modules/mouse' +], function ($, undefined) { $.widget("ui.draggable", $.ui.mouse, { version: "1.10.4", @@ -34,15 +51,15 @@ start: null, stop: null }, - _create: function() { + _create: function () { if (this.options.helper === "original" && !(/^(?:r|a|f)/).test(this.element.css("position"))) { this.element[0].style.position = "relative"; } - if (this.options.addClasses){ + if (this.options.addClasses) { this.element.addClass("ui-draggable"); } - if (this.options.disabled){ + if (this.options.disabled) { this.element.addClass("ui-draggable-disabled"); } @@ -50,12 +67,12 @@ }, - _destroy: function() { - this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" ); + _destroy: function () { + this.element.removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled"); this._mouseDestroy(); }, - _mouseCapture: function(event) { + _mouseCapture: function (event) { var o = this.options; @@ -70,10 +87,10 @@ return false; } - $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() { + $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function () { $("<div class='ui-draggable-iframeFix' style='background: #fff;'></div>") .css({ - width: this.offsetWidth+"px", height: this.offsetHeight+"px", + width: this.offsetWidth + "px", height: this.offsetHeight + "px", position: "absolute", opacity: "0.001", zIndex: 1000 }) .css($(this).offset()) @@ -84,7 +101,7 @@ }, - _mouseStart: function(event) { + _mouseStart: function (event) { var o = this.options; @@ -97,7 +114,7 @@ this._cacheHelperProportions(); //If ddmanager is used for droppables, set the global draggable - if($.ui.ddmanager) { + if ($.ui.ddmanager) { $.ui.ddmanager.current = this; } @@ -110,10 +127,10 @@ this._cacheMargins(); //Store the helper's css position - this.cssPosition = this.helper.css( "position" ); + this.cssPosition = this.helper.css("position"); this.scrollParent = this.helper.scrollParent(); this.offsetParent = this.helper.offsetParent(); - this.offsetParentCssPosition = this.offsetParent.css( "position" ); + this.offsetParentCssPosition = this.offsetParent.css("position"); //The element's absolute position on the page minus margins this.offset = this.positionAbs = this.element.offset(); @@ -146,7 +163,7 @@ this._setContainment(); //Trigger event + callbacks - if(this._trigger("start", event) === false) { + if (this._trigger("start", event) === false) { this._clear(); return false; } @@ -163,16 +180,16 @@ this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003) - if ( $.ui.ddmanager ) { + if ($.ui.ddmanager) { $.ui.ddmanager.dragStart(this, event); } return true; }, - _mouseDrag: function(event, noPropagation) { + _mouseDrag: function (event, noPropagation) { // reset any necessary cached properties (see #5009) - if ( this.offsetParentCssPosition === "fixed" ) { + if (this.offsetParentCssPosition === "fixed") { this.offset.parent = this._getParentOffset(); } @@ -183,27 +200,27 @@ //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) { + if (this._trigger("drag", event, ui) === false) { this._mouseUp({}); return false; } this.position = ui.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 !== "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"; + if (!this.options.axis || this.options.axis !== "x") { + this.helper[0].style.top = this.position.top + "px"; } - if($.ui.ddmanager) { + if ($.ui.ddmanager) { $.ui.ddmanager.drag(this, event); } return false; }, - _mouseStop: function(event) { + _mouseStop: function (event) { //If we are using droppables, inform the manager about the drop var that = this, @@ -213,24 +230,24 @@ } //if a drop comes from outside (a sortable) - if(this.dropped) { + if (this.dropped) { dropped = this.dropped; this.dropped = false; } //if the original element is no longer in the DOM don't bother to continue (see #8269) - if ( this.options.helper === "original" && !$.contains( this.element[ 0 ].ownerDocument, this.element[ 0 ] ) ) { + if (this.options.helper === "original" && !$.contains(this.element[0].ownerDocument, this.element[0])) { return false; } - if((this.options.revert === "invalid" && !dropped) || (this.options.revert === "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) { - $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() { - if(that._trigger("stop", event) !== false) { + if ((this.options.revert === "invalid" && !dropped) || (this.options.revert === "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && 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) { + if (this._trigger("stop", event) !== false) { this._clear(); } } @@ -238,23 +255,23 @@ return false; }, - _mouseUp: function(event) { + _mouseUp: function (event) { //Remove frame helpers - $("div.ui-draggable-iframeFix").each(function() { + $("div.ui-draggable-iframeFix").each(function () { this.parentNode.removeChild(this); }); //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003) - if( $.ui.ddmanager ) { + if ($.ui.ddmanager) { $.ui.ddmanager.dragStop(this, event); } return $.ui.mouse.prototype._mouseUp.call(this, event); }, - cancel: function() { + cancel: function () { - if(this.helper.is(".ui-draggable-dragging")) { + if (this.helper.is(".ui-draggable-dragging")) { this._mouseUp({}); } else { this._clear(); @@ -264,22 +281,22 @@ }, - _getHandle: function(event) { + _getHandle: function (event) { return this.options.handle ? - !!$( event.target ).closest( this.element.find( this.options.handle ) ).length : + !!$(event.target).closest(this.element.find(this.options.handle)).length : true; }, - _createHelper: function(event) { + _createHelper: function (event) { var o = this.options, helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper === "clone" ? this.element.clone().removeAttr("id") : this.element); - if(!helper.parents("body").length) { + if (!helper.parents("body").length) { helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo)); } - if(helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) { + if (helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) { helper.css("position", "absolute"); } @@ -287,7 +304,7 @@ }, - _adjustOffsetFromHelper: function(obj) { + _adjustOffsetFromHelper: function (obj) { if (typeof obj === "string") { obj = obj.split(" "); } @@ -308,7 +325,7 @@ } }, - _getParentOffset: function() { + _getParentOffset: function () { //Get the offsetParent and cache its position var po = this.offsetParent.offset(); @@ -317,154 +334,154 @@ // 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])) { + 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(); } //This needs to be actually done for all browsers, since pageX/pageY includes this information //Ugly IE fix - if((this.offsetParent[0] === document.body) || + if ((this.offsetParent[0] === document.body) || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) { - po = { top: 0, left: 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) + top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"), 10) || 0), + left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"), 10) || 0) }; }, - _getRelativeOffset: function() { + _getRelativeOffset: function () { - if(this.cssPosition === "relative") { + if (this.cssPosition === "relative") { var p = this.element.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() + 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 {top: 0, left: 0}; } }, - _cacheMargins: function() { + _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) + 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() { + _cacheHelperProportions: function () { this.helperProportions = { width: this.helper.outerWidth(), height: this.helper.outerHeight() }; }, - _setContainment: function() { + _setContainment: function () { var over, c, ce, o = this.options; - if ( !o.containment ) { + if (!o.containment) { this.containment = null; return; } - if ( o.containment === "window" ) { + 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 + $(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") { + 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 + $(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 ) { + if (o.containment.constructor === Array) { this.containment = o.containment; return; } - if ( o.containment === "parent" ) { - o.containment = this.helper[ 0 ].parentNode; + if (o.containment === "parent") { + o.containment = this.helper[0].parentNode; } - c = $( o.containment ); - ce = c[ 0 ]; + c = $(o.containment); + ce = c[0]; - if( !ce ) { + if (!ce) { return; } - over = c.css( "overflow" ) !== "hidden"; + over = c.css("overflow") !== "hidden"; 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 ) , - ( over ? 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, - ( over ? 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 + (parseInt(c.css("borderLeftWidth"), 10) || 0) + (parseInt(c.css("paddingLeft"), 10) || 0), + (parseInt(c.css("borderTopWidth"), 10) || 0) + (parseInt(c.css("paddingTop"), 10) || 0), + (over ? 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, + (over ? 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.relative_container = c; }, - _convertPositionTo: function(d, pos) { + _convertPositionTo: function (d, pos) { - if(!pos) { + if (!pos) { pos = this.position; } var mod = d === "absolute" ? 1 : -1, - scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent; + scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent; //Cache the scroll if (!this.offset.scroll) { - this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()}; + this.offset.scroll = {top: scroll.scrollTop(), left: scroll.scrollLeft()}; } return { top: ( - pos.top + // The absolute mouse position + pos.top + // The absolute mouse position this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border) - ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top ) * mod ) + ((this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top) * mod) ), left: ( pos.left + // The absolute mouse position this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) - ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left ) * mod ) + this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) + ((this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left) * mod) ) }; }, - _generatePosition: function(event) { + _generatePosition: function (event) { var containment, co, top, left, o = this.options, - scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent, + scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, pageX = event.pageX, pageY = event.pageY; //Cache the scroll if (!this.offset.scroll) { - this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()}; + this.offset.scroll = {top: scroll.scrollTop(), left: scroll.scrollLeft()}; } /* @@ -473,36 +490,35 @@ */ // If we are not dragging yet, we won't check for options - if ( this.originalPosition ) { - if ( this.containment ) { - if ( this.relative_container ){ + if (this.originalPosition) { + if (this.containment) { + if (this.relative_container) { co = this.relative_container.offset(); containment = [ - this.containment[ 0 ] + co.left, - this.containment[ 1 ] + co.top, - this.containment[ 2 ] + co.left, - this.containment[ 3 ] + co.top + this.containment[0] + co.left, + this.containment[1] + co.top, + this.containment[2] + co.left, + this.containment[3] + co.top ]; - } - else { + } else { containment = this.containment; } - if(event.pageX - this.offset.click.left < containment[0]) { + 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]) { + 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]) { + 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]) { + if (event.pageY - this.offset.click.top > containment[3]) { pageY = containment[3] + this.offset.click.top; } } - if(o.grid) { + 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; @@ -516,25 +532,25 @@ return { top: ( pageY - // The absolute mouse position - this.offset.click.top - // Click offset (relative to the element) + this.offset.click.top - // Click offset (relative to the element) this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent this.offset.parent.top + // The offsetParent's offset without borders (offset + border) - ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top ) + (this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top) ), left: ( pageX - // The absolute mouse position this.offset.click.left - // Click offset (relative to the element) this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent this.offset.parent.left + // The offsetParent's offset without borders (offset + border) - ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left ) + (this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left) ) }; }, - _clear: function() { + _clear: function () { this.helper.removeClass("ui-draggable-dragging"); - if(this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) { + if (this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) { this.helper.remove(); } this.helper = null; @@ -543,11 +559,11 @@ // From now on bulk stuff - mainly helpers - _trigger: function(type, event, ui) { + _trigger: function (type, event, ui) { ui = ui || this._uiHash(); $.ui.plugin.call(this, type, [event, ui]); //The absolute position has to be recalculated after plugins - if(type === "drag") { + if (type === "drag") { this.positionAbs = this._convertPositionTo("absolute"); } return $.Widget.prototype._trigger.call(this, type, event, ui); @@ -555,7 +571,7 @@ plugins: {}, - _uiHash: function() { + _uiHash: function () { return { helper: this.helper, position: this.position, @@ -567,12 +583,12 @@ }); $.ui.plugin.add("draggable", "connectToSortable", { - start: function(event, ui) { + start: function (event, ui) { var inst = $(this).data("ui-draggable"), o = inst.options, - uiSortable = $.extend({}, ui, { item: inst.element }); + uiSortable = $.extend({}, ui, {item: inst.element}); inst.sortables = []; - $(o.connectToSortable).each(function() { + $(o.connectToSortable).each(function () { var sortable = $.data(this, "ui-sortable"); if (sortable && !sortable.options.disabled) { inst.sortables.push({ @@ -585,14 +601,14 @@ }); }, - stop: function(event, ui) { + stop: function (event, ui) { //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper var inst = $(this).data("ui-draggable"), - uiSortable = $.extend({}, ui, { item: inst.element }); + uiSortable = $.extend({}, ui, {item: inst.element}); - $.each(inst.sortables, function() { - if(this.instance.isOver) { + $.each(inst.sortables, function () { + if (this.instance.isOver) { this.instance.isOver = 0; @@ -600,7 +616,7 @@ this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work) //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: "valid/invalid" - if(this.shouldRevert) { + if (this.shouldRevert) { this.instance.options.revert = this.shouldRevert; } @@ -610,8 +626,8 @@ this.instance.options.helper = this.instance.options._helper; //If the helper has been the original item, restore properties in the sortable - if(inst.options.helper === "original") { - this.instance.currentItem.css({ top: "auto", left: "auto" }); + if (inst.options.helper === "original") { + this.instance.currentItem.css({top: "auto", left: "auto"}); } } else { @@ -622,11 +638,11 @@ }); }, - drag: function(event, ui) { + drag: function (event, ui) { var inst = $(this).data("ui-draggable"), that = this; - $.each(inst.sortables, function() { + $.each(inst.sortables, function () { var innermostIntersecting = false, thisSortable = this; @@ -636,7 +652,7 @@ this.instance.helperProportions = inst.helperProportions; this.instance.offset.click = inst.offset.click; - if(this.instance._intersectsWith(this.instance.containerCache)) { + if (this.instance._intersectsWith(this.instance.containerCache)) { innermostIntersecting = true; $.each(inst.sortables, function () { this.instance.positionAbs = inst.positionAbs; @@ -653,9 +669,9 @@ } - if(innermostIntersecting) { + if (innermostIntersecting) { //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once - if(!this.instance.isOver) { + if (!this.instance.isOver) { this.instance.isOver = 1; //Now we fake the start of dragging for the sortable instance, @@ -663,7 +679,9 @@ //We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one) this.instance.currentItem = $(that).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item", true); this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it - this.instance.options.helper = function() { return ui.helper[0]; }; + this.instance.options.helper = function () { + return ui.helper[0]; + }; event.target = this.instance.currentItem[0]; this.instance._mouseCapture(event, true); @@ -684,7 +702,7 @@ } //Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable - if(this.instance.currentItem) { + if (this.instance.currentItem) { this.instance._mouseDrag(event); } @@ -692,7 +710,7 @@ //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(this.instance.isOver) { + if (this.instance.isOver) { this.instance.isOver = 0; this.instance.cancelHelperRemoval = true; @@ -708,7 +726,7 @@ //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size this.instance.currentItem.remove(); - if(this.instance.placeholder) { + if (this.instance.placeholder) { this.instance.placeholder.remove(); } @@ -724,14 +742,14 @@ }); $.ui.plugin.add("draggable", "cursor", { - start: function() { + start: function () { var t = $("body"), o = $(this).data("ui-draggable").options; if (t.css("cursor")) { o._cursor = t.css("cursor"); } t.css("cursor", o.cursor); }, - stop: function() { + stop: function () { var o = $(this).data("ui-draggable").options; if (o._cursor) { $("body").css("cursor", o._cursor); @@ -740,71 +758,71 @@ }); $.ui.plugin.add("draggable", "opacity", { - start: function(event, ui) { + start: function (event, ui) { var t = $(ui.helper), o = $(this).data("ui-draggable").options; - if(t.css("opacity")) { + if (t.css("opacity")) { o._opacity = t.css("opacity"); } t.css("opacity", o.opacity); }, - stop: function(event, ui) { + stop: function (event, ui) { var o = $(this).data("ui-draggable").options; - if(o._opacity) { + if (o._opacity) { $(ui.helper).css("opacity", o._opacity); } } }); $.ui.plugin.add("draggable", "scroll", { - start: function() { + start: function () { var i = $(this).data("ui-draggable"); - if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") { + if (i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") { i.overflowOffset = i.scrollParent.offset(); } }, - drag: function( event ) { + drag: function (event) { var i = $(this).data("ui-draggable"), o = i.options, scrolled = false; - if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") { + if (i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") { - if(!o.axis || o.axis !== "x") { - if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) { + if (!o.axis || o.axis !== "x") { + if ((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) { i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed; - } else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) { + } else if (event.pageY - i.overflowOffset.top < o.scrollSensitivity) { i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed; } } - if(!o.axis || o.axis !== "y") { - if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) { + if (!o.axis || o.axis !== "y") { + if ((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) { i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed; - } else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) { + } else if (event.pageX - i.overflowOffset.left < o.scrollSensitivity) { i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed; } } } else { - if(!o.axis || o.axis !== "x") { - if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) { + 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) { + } 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) { + 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) { + } else if ($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) { scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); } } } - if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { + if (scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { $.ui.ddmanager.prepareOffsets(i, event); } @@ -812,17 +830,17 @@ }); $.ui.plugin.add("draggable", "snap", { - start: function() { + start: function () { var i = $(this).data("ui-draggable"), o = i.options; i.snapElements = []; - $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() { + $(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]) { + if (this !== i.element[0]) { i.snapElements.push({ item: this, width: $t.outerWidth(), height: $t.outerHeight(), @@ -832,7 +850,7 @@ }); }, - drag: function(event, ui) { + drag: function (event, ui) { var ts, bs, ls, rs, l, r, t, b, i, first, inst = $(this).data("ui-draggable"), @@ -841,63 +859,81 @@ 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--){ + for (i = inst.snapElements.length - 1; i >= 0; i--) { l = inst.snapElements[i].left; r = l + inst.snapElements[i].width; t = inst.snapElements[i].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) { - (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); + 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) { + (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") { + 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 - inst.margins.top; + if (ts) { + ui.position.top = inst._convertPositionTo("relative", { + top: t - inst.helperProportions.height, + left: 0 + }).top - inst.margins.top; } - if(bs) { - ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top; + if (bs) { + ui.position.top = inst._convertPositionTo("relative", {top: b, left: 0}).top - inst.margins.top; } - if(ls) { - ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left; + if (ls) { + ui.position.left = inst._convertPositionTo("relative", { + top: 0, + left: l - inst.helperProportions.width + }).left - inst.margins.left; } - if(rs) { - ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left; + if (rs) { + ui.position.left = inst._convertPositionTo("relative", { + top: 0, + left: r + }).left - inst.margins.left; } } first = (ts || bs || ls || rs); - if(o.snapMode !== "outer") { + 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 - inst.margins.top; + if (ts) { + ui.position.top = inst._convertPositionTo("relative", {top: t, left: 0}).top - inst.margins.top; } - if(bs) { - ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top; + if (bs) { + ui.position.top = inst._convertPositionTo("relative", { + top: b - inst.helperProportions.height, + left: 0 + }).top - inst.margins.top; } - if(ls) { - ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left; + if (ls) { + ui.position.left = inst._convertPositionTo("relative", { + top: 0, + left: l + }).left - inst.margins.left; } - if(rs) { - ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left; + if (rs) { + ui.position.left = inst._convertPositionTo("relative", { + top: 0, + left: r - inst.helperProportions.width + }).left - inst.margins.left; } } - if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) { - (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); + if (!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) { + (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); @@ -907,17 +943,19 @@ }); $.ui.plugin.add("draggable", "stack", { - start: function() { + start: function () { var min, o = this.data("ui-draggable").options, - group = $.makeArray($(o.stack)).sort(function(a,b) { - return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0); + 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; } + if (!group.length) { + return; + } min = parseInt($(group[0]).css("zIndex"), 10) || 0; - $(group).each(function(i) { + $(group).each(function (i) { $(this).css("zIndex", min + i); }); this.css("zIndex", (min + group.length)); @@ -925,19 +963,19 @@ }); $.ui.plugin.add("draggable", "zIndex", { - start: function(event, ui) { + start: function (event, ui) { var t = $(ui.helper), o = $(this).data("ui-draggable").options; - if(t.css("zIndex")) { + if (t.css("zIndex")) { o._zIndex = t.css("zIndex"); } t.css("zIndex", o.zIndex); }, - stop: function(event, ui) { + stop: function (event, ui) { var o = $(this).data("ui-draggable").options; - if(o._zIndex) { + if (o._zIndex) { $(ui.helper).css("zIndex", o._zIndex); } } }); -})(jQuery); +}); diff --git a/lib/web/jquery/ui-modules/droppable.js b/lib/web/jquery/ui-modules/droppable.js index fd8694f9910d..4231f31ff4d5 100644 --- a/lib/web/jquery/ui-modules/droppable.js +++ b/lib/web/jquery/ui-modules/droppable.js @@ -1,7 +1,24 @@ -(function( $, undefined ) { - - function isOverAxis( x, reference, size ) { - return ( x > reference ) && ( x < ( reference + size ) ); +/*! + * jQuery UI Droppable + * http://jqueryui.com + * + * Copyright 2014 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/droppable/ + */ + +define([ + 'jquery', + 'jquery-ui-modules/core', + 'jquery-ui-modules/widget', + 'jquery-ui-modules/mouse', + 'jquery-ui-modules/draggable' +], function ($, undefined) { + + function isOverAxis(x, reference, size) { + return (x > reference) && (x < (reference + size)); } $.widget("ui.droppable", { @@ -23,7 +40,7 @@ out: null, over: null }, - _create: function() { + _create: function () { var proportions, o = this.options, @@ -32,21 +49,21 @@ this.isover = false; this.isout = true; - this.accept = $.isFunction(accept) ? accept : function(d) { + this.accept = $.isFunction(accept) ? accept : function (d) { return d.is(accept); }; - this.proportions = function( /* valueToWrite */ ) { - if ( arguments.length ) { + this.proportions = function ( /* valueToWrite */) { + if (arguments.length) { // Store the droppable's proportions - proportions = arguments[ 0 ]; + 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 + width: this.element[0].offsetWidth, + height: this.element[0].offsetHeight }; } }; @@ -59,12 +76,12 @@ }, - _destroy: function() { + _destroy: function () { var i = 0, drop = $.ui.ddmanager.droppables[this.options.scope]; - for ( ; i < drop.length; i++ ) { - if ( drop[i] === this ) { + for (; i < drop.length; i++) { + if (drop[i] === this) { drop.splice(i, 1); } } @@ -72,37 +89,37 @@ this.element.removeClass("ui-droppable ui-droppable-disabled"); }, - _setOption: function(key, value) { + _setOption: function (key, value) { - if(key === "accept") { - this.accept = $.isFunction(value) ? value : function(d) { + if (key === "accept") { + this.accept = $.isFunction(value) ? value : function (d) { return d.is(value); }; } $.Widget.prototype._setOption.apply(this, arguments); }, - _activate: function(event) { + _activate: function (event) { var draggable = $.ui.ddmanager.current; - if(this.options.activeClass) { + if (this.options.activeClass) { this.element.addClass(this.options.activeClass); } - if(draggable){ + if (draggable) { this._trigger("activate", event, this.ui(draggable)); } }, - _deactivate: function(event) { + _deactivate: function (event) { var draggable = $.ui.ddmanager.current; - if(this.options.activeClass) { + if (this.options.activeClass) { this.element.removeClass(this.options.activeClass); } - if(draggable){ + if (draggable) { this._trigger("deactivate", event, this.ui(draggable)); } }, - _over: function(event) { + _over: function (event) { var draggable = $.ui.ddmanager.current; @@ -111,8 +128,8 @@ return; } - if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { - if(this.options.hoverClass) { + if (this.accept.call(this.element[0], (draggable.currentItem || draggable.element))) { + if (this.options.hoverClass) { this.element.addClass(this.options.hoverClass); } this._trigger("over", event, this.ui(draggable)); @@ -120,7 +137,7 @@ }, - _out: function(event) { + _out: function (event) { var draggable = $.ui.ddmanager.current; @@ -129,8 +146,8 @@ return; } - if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { - if(this.options.hoverClass) { + if (this.accept.call(this.element[0], (draggable.currentItem || draggable.element))) { + if (this.options.hoverClass) { this.element.removeClass(this.options.hoverClass); } this._trigger("out", event, this.ui(draggable)); @@ -138,7 +155,7 @@ }, - _drop: function(event,custom) { + _drop: function (event, custom) { var draggable = custom || $.ui.ddmanager.current, childrenIntersection = false; @@ -148,25 +165,28 @@ return false; } - this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function() { + this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function () { var inst = $.data(this, "ui-droppable"); - if( + 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) - ) { childrenIntersection = true; return false; } + $.ui.intersect(draggable, $.extend(inst, {offset: inst.element.offset()}), inst.options.tolerance) + ) { + childrenIntersection = true; + return false; + } }); - if(childrenIntersection) { + if (childrenIntersection) { return false; } - if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { - if(this.options.activeClass) { + if (this.accept.call(this.element[0], (draggable.currentItem || draggable.element))) { + if (this.options.activeClass) { this.element.removeClass(this.options.activeClass); } - if(this.options.hoverClass) { + if (this.options.hoverClass) { this.element.removeClass(this.options.hoverClass); } this._trigger("drop", event, this.ui(draggable)); @@ -177,7 +197,7 @@ }, - ui: function(c) { + ui: function (c) { return { draggable: (c.currentItem || c.element), helper: c.helper, @@ -188,7 +208,7 @@ }); - $.ui.intersect = function(draggable, droppable, toleranceMode) { + $.ui.intersect = function (draggable, droppable, toleranceMode) { if (!droppable.offset) { return false; @@ -211,11 +231,11 @@ 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 + y2 - (draggable.helperProportions.height / 2) < b); // Top Half case "pointer": draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left); draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top); - return isOverAxis( draggableTop, t, droppable.proportions().height ) && isOverAxis( draggableLeft, l, droppable.proportions().width ); + return isOverAxis(draggableTop, t, droppable.proportions().height) && isOverAxis(draggableLeft, l, droppable.proportions().width); case "touch": return ( (y1 >= t && y1 <= b) || // Top edge touching @@ -237,8 +257,8 @@ */ $.ui.ddmanager = { current: null, - droppables: { "default": [] }, - prepareOffsets: function(t, event) { + droppables: {"default": []}, + prepareOffsets: function (t, event) { var i, j, m = $.ui.ddmanager.droppables[t.options.scope] || [], @@ -248,48 +268,48 @@ 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)))) { + 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]) { + 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) { + if (!m[i].visible) { continue; } //Activate the droppable if used directly from draggables - if(type === "mousedown") { + 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 }); + 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) { + 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() { + $.each(($.ui.ddmanager.droppables[draggable.options.scope] || []).slice(), function () { - if(!this.options) { + if (!this.options) { return; } if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) { dropped = this._drop.call(this, event) || dropped; } - if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { + 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); @@ -299,32 +319,32 @@ return dropped; }, - dragStart: function( draggable, event ) { + 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" ).bind( "scroll.droppable", function() { - if( !draggable.options.refreshPositions ) { - $.ui.ddmanager.prepareOffsets( draggable, event ); + draggable.element.parentsUntil("body").bind("scroll.droppable", function () { + if (!draggable.options.refreshPositions) { + $.ui.ddmanager.prepareOffsets(draggable, event); } }); }, - drag: function(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) { + 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() { + $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function () { - if(this.options.disabled || this.greedyChild || !this.visible) { + if (this.options.disabled || this.greedyChild || !this.visible) { return; } var parentInstance, scope, parent, intersects = $.ui.intersect(draggable, this, this.options.tolerance), c = !intersects && this.isover ? "isout" : (intersects && !this.isover ? "isover" : null); - if(!c) { + if (!c) { return; } @@ -361,13 +381,13 @@ }); }, - dragStop: function( draggable, event ) { - draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" ); + dragStop: function (draggable, event) { + draggable.element.parentsUntil("body").unbind("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 ); + if (!draggable.options.refreshPositions) { + $.ui.ddmanager.prepareOffsets(draggable, event); } } }; -})(jQuery); +}); diff --git a/lib/web/jquery/ui-modules/effect-blind.js b/lib/web/jquery/ui-modules/effect-blind.js index d2234df6046b..89b2069b82e1 100644 --- a/lib/web/jquery/ui-modules/effect-blind.js +++ b/lib/web/jquery/ui-modules/effect-blind.js @@ -1,69 +1,83 @@ -(function( $, undefined ) { +/*! + * jQuery UI Effects Blind + * http://jqueryui.com + * + * Copyright 2014 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/blind-effect/ + */ + +define([ + 'jquery', + 'jquery-ui-modules/effect' +], function ($, undefined) { var rvertical = /up|down|vertical/, rpositivemotion = /up|left|vertical|horizontal/; - $.effects.effect.blind = function( o, done ) { + $.effects.effect.blind = function (o, done) { // Create element - var el = $( this ), - props = [ "position", "top", "bottom", "left", "right", "height", "width" ], - mode = $.effects.setMode( el, o.mode || "hide" ), + var el = $(this), + props = ["position", "top", "bottom", "left", "right", "height", "width"], + mode = $.effects.setMode(el, o.mode || "hide"), direction = o.direction || "up", - vertical = rvertical.test( direction ), + vertical = rvertical.test(direction), ref = vertical ? "height" : "width", ref2 = vertical ? "top" : "left", - motion = rpositivemotion.test( direction ), + motion = rpositivemotion.test(direction), animation = {}, show = mode === "show", wrapper, distance, margin; // if already wrapped, the wrapper's properties are my property. #6245 - if ( el.parent().is( ".ui-effects-wrapper" ) ) { - $.effects.save( el.parent(), props ); + if (el.parent().is(".ui-effects-wrapper")) { + $.effects.save(el.parent(), props); } else { - $.effects.save( el, props ); + $.effects.save(el, props); } el.show(); - wrapper = $.effects.createWrapper( el ).css({ + wrapper = $.effects.createWrapper(el).css({ overflow: "hidden" }); - distance = wrapper[ ref ](); - margin = parseFloat( wrapper.css( ref2 ) ) || 0; + distance = wrapper[ref](); + margin = parseFloat(wrapper.css(ref2)) || 0; - animation[ ref ] = show ? distance : 0; - if ( !motion ) { + animation[ref] = show ? distance : 0; + if (!motion) { el - .css( vertical ? "bottom" : "right", 0 ) - .css( vertical ? "top" : "left", "auto" ) - .css({ position: "absolute" }); + .css(vertical ? "bottom" : "right", 0) + .css(vertical ? "top" : "left", "auto") + .css({position: "absolute"}); - animation[ ref2 ] = show ? margin : distance + margin; + animation[ref2] = show ? margin : distance + margin; } // start at 0 if we are showing - if ( show ) { - wrapper.css( ref, 0 ); - if ( ! motion ) { - wrapper.css( ref2, margin + distance ); + if (show) { + wrapper.css(ref, 0); + if (!motion) { + wrapper.css(ref2, margin + distance); } } // Animate - wrapper.animate( animation, { + wrapper.animate(animation, { duration: o.duration, easing: o.easing, queue: false, - complete: function() { - if ( mode === "hide" ) { + complete: function () { + if (mode === "hide") { el.hide(); } - $.effects.restore( el, props ); - $.effects.removeWrapper( el ); + $.effects.restore(el, props); + $.effects.removeWrapper(el); done(); } }); }; -})(jQuery); +}); diff --git a/lib/web/jquery/ui-modules/effect-bounce.js b/lib/web/jquery/ui-modules/effect-bounce.js index 7073c892d4e9..62a079752660 100644 --- a/lib/web/jquery/ui-modules/effect-bounce.js +++ b/lib/web/jquery/ui-modules/effect-bounce.js @@ -1,11 +1,27 @@ -(function( $, undefined ) { - - $.effects.effect.bounce = function( o, done ) { - var el = $( this ), - props = [ "position", "top", "bottom", "left", "right", "height", "width" ], +/*! + * jQuery UI Effects Bounce + * http://jqueryui.com + * + * Copyright 2014 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/bounce-effect/ + * + * Depends: + * jquery.ui.effect.js + */ +define([ + 'jquery', + 'jquery-ui-modules/effect' +], function ($, undefined) { + + $.effects.effect.bounce = function (o, done) { + var el = $(this), + props = ["position", "top", "bottom", "left", "right", "height", "width"], // defaults: - mode = $.effects.setMode( el, o.mode || "effect" ), + mode = $.effects.setMode(el, o.mode || "effect"), hide = mode === "hide", show = mode === "show", direction = o.direction || "up", @@ -13,13 +29,13 @@ times = o.times || 5, // number of internal animations - anims = times * 2 + ( show || hide ? 1 : 0 ), + anims = times * 2 + (show || hide ? 1 : 0), speed = o.duration / anims, easing = o.easing, // utility: - ref = ( direction === "up" || direction === "down" ) ? "top" : "left", - motion = ( direction === "up" || direction === "left" ), + ref = (direction === "up" || direction === "down") ? "top" : "left", + motion = (direction === "up" || direction === "left"), i, upAnim, downAnim, @@ -29,72 +45,72 @@ queuelen = queue.length; // Avoid touching opacity to prevent clearType and PNG issues in IE - if ( show || hide ) { - props.push( "opacity" ); + if (show || hide) { + props.push("opacity"); } - $.effects.save( el, props ); + $.effects.save(el, props); el.show(); - $.effects.createWrapper( el ); // Create Wrapper + $.effects.createWrapper(el); // Create Wrapper // default distance for the BIGGEST bounce is the outer Distance / 3 - if ( !distance ) { - distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3; + if (!distance) { + distance = el[ref === "top" ? "outerHeight" : "outerWidth"]() / 3; } - if ( show ) { - downAnim = { opacity: 1 }; - downAnim[ ref ] = 0; + if (show) { + downAnim = {opacity: 1}; + downAnim[ref] = 0; // if we are showing, force opacity 0 and set the initial position // then do the "first" animation - el.css( "opacity", 0 ) - .css( ref, motion ? -distance * 2 : distance * 2 ) - .animate( downAnim, speed, easing ); + el.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 ); + if (hide) { + distance = distance / Math.pow(2, times - 1); } downAnim = {}; - downAnim[ ref ] = 0; + downAnim[ref] = 0; // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here - for ( i = 0; i < times; i++ ) { + for (i = 0; i < times; i++) { upAnim = {}; - upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; + upAnim[ref] = (motion ? "-=" : "+=") + distance; - el.animate( upAnim, speed, easing ) - .animate( downAnim, speed, easing ); + el.animate(upAnim, speed, easing) + .animate(downAnim, speed, easing); distance = hide ? distance * 2 : distance / 2; } // Last Bounce when Hiding - if ( hide ) { - upAnim = { opacity: 0 }; - upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; + if (hide) { + upAnim = {opacity: 0}; + upAnim[ref] = (motion ? "-=" : "+=") + distance; - el.animate( upAnim, speed, easing ); + el.animate(upAnim, speed, easing); } - el.queue(function() { - if ( hide ) { + el.queue(function () { + if (hide) { el.hide(); } - $.effects.restore( el, props ); - $.effects.removeWrapper( el ); + $.effects.restore(el, props); + $.effects.removeWrapper(el); done(); }); // inject all the animations we just queued to be first in line (after "inprogress") - if ( queuelen > 1) { - queue.splice.apply( queue, - [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); + if (queuelen > 1) { + queue.splice.apply(queue, + [1, 0].concat(queue.splice(queuelen, anims + 1))); } el.dequeue(); }; -})(jQuery); +}); diff --git a/lib/web/jquery/ui-modules/effect-clip.js b/lib/web/jquery/ui-modules/effect-clip.js index 38ef30c96bbf..2463757151a2 100644 --- a/lib/web/jquery/ui-modules/effect-clip.js +++ b/lib/web/jquery/ui-modules/effect-clip.js @@ -1,10 +1,23 @@ -(function( $, undefined ) { +/*! + * jQuery UI Effects Clip + * http://jqueryui.com + * + * Copyright 2014 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/clip-effect/ + */ +define([ + 'jquery', + 'jquery-ui-modules/effect' +], function ($, undefined) { - $.effects.effect.clip = function( o, done ) { + $.effects.effect.clip = function (o, done) { // Create element - var el = $( this ), - props = [ "position", "top", "bottom", "left", "right", "height", "width" ], - mode = $.effects.setMode( el, o.mode || "hide" ), + var el = $(this), + props = ["position", "top", "bottom", "left", "right", "height", "width"], + mode = $.effects.setMode(el, o.mode || "hide"), show = mode === "show", direction = o.direction || "vertical", vert = direction === "vertical", @@ -14,41 +27,41 @@ wrapper, animate, distance; // Save & Show - $.effects.save( el, props ); + $.effects.save(el, props); el.show(); // Create Wrapper - wrapper = $.effects.createWrapper( el ).css({ + wrapper = $.effects.createWrapper(el).css({ overflow: "hidden" }); - animate = ( el[0].tagName === "IMG" ) ? wrapper : el; - distance = animate[ size ](); + animate = (el[0].tagName === "IMG") ? wrapper : el; + distance = animate[size](); // Shift - if ( show ) { - animate.css( size, 0 ); - animate.css( position, distance / 2 ); + if (show) { + animate.css(size, 0); + animate.css(position, distance / 2); } // Create Animation Object: - animation[ size ] = show ? distance : 0; - animation[ position ] = show ? 0 : distance / 2; + animation[size] = show ? distance : 0; + animation[position] = show ? 0 : distance / 2; // Animate - animate.animate( animation, { + animate.animate(animation, { queue: false, duration: o.duration, easing: o.easing, - complete: function() { - if ( !show ) { + complete: function () { + if (!show) { el.hide(); } - $.effects.restore( el, props ); - $.effects.removeWrapper( el ); + $.effects.restore(el, props); + $.effects.removeWrapper(el); done(); } }); }; -})(jQuery); +}); diff --git a/lib/web/jquery/ui-modules/effect-drop.js b/lib/web/jquery/ui-modules/effect-drop.js index 8d3b930fa285..45058916b759 100644 --- a/lib/web/jquery/ui-modules/effect-drop.js +++ b/lib/web/jquery/ui-modules/effect-drop.js @@ -1,52 +1,66 @@ -(function( $, undefined ) { +/*! + * jQuery UI Effects Drop + * http://jqueryui.com + * + * Copyright 2014 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/drop-effect/ + */ - $.effects.effect.drop = function( o, done ) { +define([ + 'jquery', + 'jquery-ui-modules/effect' +], function ($, undefined) { - var el = $( this ), - props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ], - mode = $.effects.setMode( el, o.mode || "hide" ), + $.effects.effect.drop = function (o, done) { + + var el = $(this), + props = ["position", "top", "bottom", "left", "right", "opacity", "height", "width"], + mode = $.effects.setMode(el, o.mode || "hide"), show = mode === "show", direction = o.direction || "left", - ref = ( direction === "up" || direction === "down" ) ? "top" : "left", - motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg", + ref = (direction === "up" || direction === "down") ? "top" : "left", + motion = (direction === "up" || direction === "left") ? "pos" : "neg", animation = { opacity: show ? 1 : 0 }, distance; // Adjust - $.effects.save( el, props ); + $.effects.save(el, props); el.show(); - $.effects.createWrapper( el ); + $.effects.createWrapper(el); - distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2; + distance = o.distance || el[ref === "top" ? "outerHeight" : "outerWidth"](true) / 2; - if ( show ) { + if (show) { el - .css( "opacity", 0 ) - .css( ref, motion === "pos" ? -distance : distance ); + .css("opacity", 0) + .css(ref, motion === "pos" ? -distance : distance); } // Animation - animation[ ref ] = ( show ? - ( motion === "pos" ? "+=" : "-=" ) : - ( motion === "pos" ? "-=" : "+=" ) ) + + animation[ref] = (show ? + (motion === "pos" ? "+=" : "-=") : + (motion === "pos" ? "-=" : "+=")) + distance; // Animate - el.animate( animation, { + el.animate(animation, { queue: false, duration: o.duration, easing: o.easing, - complete: function() { - if ( mode === "hide" ) { + complete: function () { + if (mode === "hide") { el.hide(); } - $.effects.restore( el, props ); - $.effects.removeWrapper( el ); + $.effects.restore(el, props); + $.effects.removeWrapper(el); done(); } }); }; -})(jQuery); +}); diff --git a/lib/web/jquery/ui-modules/effect-explode.js b/lib/web/jquery/ui-modules/effect-explode.js index 0d2291020cf9..e902ae654e2f 100644 --- a/lib/web/jquery/ui-modules/effect-explode.js +++ b/lib/web/jquery/ui-modules/effect-explode.js @@ -1,19 +1,33 @@ -(function( $, undefined ) { +/*! + * jQuery UI Effects Explode + * http://jqueryui.com + * + * Copyright 2014 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/explode-effect/ + */ - $.effects.effect.explode = function( o, done ) { +define([ + 'jquery', + 'jquery-ui-modules/effect' +], function ($, undefined) { - var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3, + $.effects.effect.explode = function (o, done) { + + var rows = o.pieces ? Math.round(Math.sqrt(o.pieces)) : 3, cells = rows, - el = $( this ), - mode = $.effects.setMode( el, o.mode || "hide" ), + el = $(this), + mode = $.effects.setMode(el, o.mode || "hide"), show = mode === "show", // show and then visibility:hidden the element before calculating offset - offset = el.show().css( "visibility", "hidden" ).offset(), + offset = el.show().css("visibility", "hidden").offset(), // width and height of a piece - width = Math.ceil( el.outerWidth() / cells ), - height = Math.ceil( el.outerHeight() / rows ), + width = Math.ceil(el.outerWidth() / cells), + height = Math.ceil(el.outerHeight() / rows), pieces = [], // loop @@ -21,27 +35,27 @@ // children animate complete: function childComplete() { - pieces.push( this ); - if ( pieces.length === rows * cells ) { + pieces.push(this); + if (pieces.length === rows * cells) { animComplete(); } } // clone the element for each row and cell. - for( i = 0; i < rows ; i++ ) { // ===> + for (i = 0; i < rows; i++) { // ===> top = offset.top + i * height; - my = i - ( rows - 1 ) / 2 ; + my = i - (rows - 1) / 2; - for( j = 0; j < cells ; j++ ) { // ||| + for (j = 0; j < cells; j++) { // ||| left = offset.left + j * width; - mx = j - ( cells - 1 ) / 2 ; + 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 el .clone() - .appendTo( "body" ) - .wrap( "<div></div>" ) + .appendTo("body") + .wrap("<div></div>") .css({ position: "absolute", visibility: "visible", @@ -52,20 +66,20 @@ // 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" ) + .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 ), + 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 ), + left: left + (show ? 0 : mx * width), + top: top + (show ? 0 : my * height), opacity: show ? 1 : 0 - }, o.duration || 500, o.easing, childComplete ); + }, o.duration || 500, o.easing, childComplete); } } @@ -73,12 +87,12 @@ el.css({ visibility: "visible" }); - $( pieces ).remove(); - if ( !show ) { + $(pieces).remove(); + if (!show) { el.hide(); } done(); } }; -})(jQuery); +}); diff --git a/lib/web/jquery/ui-modules/effect-fade.js b/lib/web/jquery/ui-modules/effect-fade.js index 62af799ac2fe..71d2ac769abd 100644 --- a/lib/web/jquery/ui-modules/effect-fade.js +++ b/lib/web/jquery/ui-modules/effect-fade.js @@ -1,8 +1,25 @@ -(function( $, undefined ) { +/*! + * jQuery UI Effects Fade + * http://jqueryui.com + * + * Copyright 2014 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/fade-effect/ + * + * Depends: + * jquery.ui.effect.js + */ - $.effects.effect.fade = function( o, done ) { - var el = $( this ), - mode = $.effects.setMode( el, o.mode || "toggle" ); +define([ + 'jquery', + 'jquery-ui-modules/effect' +], function ($, undefined) { + + $.effects.effect.fade = function (o, done) { + var el = $(this), + mode = $.effects.setMode(el, o.mode || "toggle"); el.animate({ opacity: mode @@ -14,4 +31,4 @@ }); }; -})( jQuery ); +}); diff --git a/lib/web/jquery/ui-modules/effect-fold.js b/lib/web/jquery/ui-modules/effect-fold.js index 041b5bd50e6f..ece8ade1a02c 100644 --- a/lib/web/jquery/ui-modules/effect-fold.js +++ b/lib/web/jquery/ui-modules/effect-fold.js @@ -1,39 +1,53 @@ -(function( $, undefined ) { +/*! + * jQuery UI Effects Fold + * http://jqueryui.com + * + * Copyright 2014 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/fold-effect/ + */ - $.effects.effect.fold = function( o, done ) { +define([ + 'jquery', + 'jquery-ui-modules/effect' +], function ($, undefined) { + + $.effects.effect.fold = function (o, done) { // Create element - var el = $( this ), - props = [ "position", "top", "bottom", "left", "right", "height", "width" ], - mode = $.effects.setMode( el, o.mode || "hide" ), + var el = $(this), + props = ["position", "top", "bottom", "left", "right", "height", "width"], + mode = $.effects.setMode(el, o.mode || "hide"), show = mode === "show", hide = mode === "hide", size = o.size || 15, - percent = /([0-9]+)%/.exec( size ), + percent = /([0-9]+)%/.exec(size), horizFirst = !!o.horizFirst, widthFirst = show !== horizFirst, - ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ], + ref = widthFirst ? ["width", "height"] : ["height", "width"], duration = o.duration / 2, wrapper, distance, animation1 = {}, animation2 = {}; - $.effects.save( el, props ); + $.effects.save(el, props); el.show(); // Create Wrapper - wrapper = $.effects.createWrapper( el ).css({ + wrapper = $.effects.createWrapper(el).css({ overflow: "hidden" }); distance = widthFirst ? - [ wrapper.width(), wrapper.height() ] : - [ wrapper.height(), wrapper.width() ]; + [wrapper.width(), wrapper.height()] : + [wrapper.height(), wrapper.width()]; - if ( percent ) { - size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ]; + if (percent) { + size = parseInt(percent[1], 10) / 100 * distance[hide ? 0 : 1]; } - if ( show ) { - wrapper.css( horizFirst ? { + if (show) { + wrapper.css(horizFirst ? { height: 0, width: size } : { @@ -43,21 +57,20 @@ } // Animation - animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size; - animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0; + animation1[ref[0]] = show ? distance[0] : size; + animation2[ref[1]] = show ? distance[1] : 0; // Animate wrapper - .animate( animation1, duration, o.easing ) - .animate( animation2, duration, o.easing, function() { - if ( hide ) { + .animate(animation1, duration, o.easing) + .animate(animation2, duration, o.easing, function () { + if (hide) { el.hide(); } - $.effects.restore( el, props ); - $.effects.removeWrapper( el ); + $.effects.restore(el, props); + $.effects.removeWrapper(el); done(); }); - }; -})(jQuery); +}); diff --git a/lib/web/jquery/ui-modules/effect-highlight.js b/lib/web/jquery/ui-modules/effect-highlight.js index f364ccd2fdb9..a852b51efb4a 100644 --- a/lib/web/jquery/ui-modules/effect-highlight.js +++ b/lib/web/jquery/ui-modules/effect-highlight.js @@ -1,18 +1,32 @@ -(function( $, undefined ) { +/*! + * jQuery UI Effects Highlight + * http://jqueryui.com + * + * Copyright 2014 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/highlight-effect/ + */ - $.effects.effect.highlight = function( o, done ) { - var elem = $( this ), - props = [ "backgroundImage", "backgroundColor", "opacity" ], - mode = $.effects.setMode( elem, o.mode || "show" ), +define([ + 'jquery', + 'jquery-ui-modules/effect' +], function ($, undefined) { + + $.effects.effect.highlight = function (o, done) { + var elem = $(this), + props = ["backgroundImage", "backgroundColor", "opacity"], + mode = $.effects.setMode(elem, o.mode || "show"), animation = { - backgroundColor: elem.css( "backgroundColor" ) + backgroundColor: elem.css("backgroundColor") }; if (mode === "hide") { animation.opacity = 0; } - $.effects.save( elem, props ); + $.effects.save(elem, props); elem .show() @@ -20,18 +34,18 @@ backgroundImage: "none", backgroundColor: o.color || "#ffff99" }) - .animate( animation, { + .animate(animation, { queue: false, duration: o.duration, easing: o.easing, - complete: function() { - if ( mode === "hide" ) { + complete: function () { + if (mode === "hide") { elem.hide(); } - $.effects.restore( elem, props ); + $.effects.restore(elem, props); done(); } }); }; -})(jQuery); +}); diff --git a/lib/web/jquery/ui-modules/effect-puff.js b/lib/web/jquery/ui-modules/effect-puff.js index 309f44ca8482..b3c6675b460b 100644 --- a/lib/web/jquery/ui-modules/effect-puff.js +++ b/lib/web/jquery/ui-modules/effect-puff.js @@ -1,10 +1,24 @@ -(function( $, undefined ) { - - $.effects.effect.puff = function( o, done ) { - var elem = $( this ), - mode = $.effects.setMode( elem, o.mode || "hide" ), +/*! + * jQuery UI Effects Scale + * http://jqueryui.com + * + * Copyright 2014 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/scale-effect/ + */ + +define([ + 'jquery', + 'jquery-ui-modules/effect' +], function ($, undefined) { + + $.effects.effect.puff = function (o, done) { + var elem = $(this), + mode = $.effects.setMode(elem, o.mode || "hide"), hide = mode === "hide", - percent = parseInt( o.percent, 10 ) || 150, + percent = parseInt(o.percent, 10) || 150, factor = percent / 100, original = { height: elem.height(), @@ -13,7 +27,7 @@ outerWidth: elem.outerWidth() }; - $.extend( o, { + $.extend(o, { effect: "scale", queue: false, fade: true, @@ -30,17 +44,17 @@ } }); - elem.effect( o ); + elem.effect(o); }; - $.effects.effect.scale = function( o, done ) { + $.effects.effect.scale = function (o, done) { // Create element - var el = $( this ), - options = $.extend( true, {}, o ), - mode = $.effects.setMode( el, o.mode || "effect" ), - percent = parseInt( o.percent, 10 ) || - ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ), + var el = $(this), + options = $.extend(true, {}, o), + mode = $.effects.setMode(el, o.mode || "effect"), + percent = parseInt(o.percent, 10) || + (parseInt(o.percent, 10) === 0 ? 0 : (mode === "hide" ? 0 : 100)), direction = o.direction || "both", origin = o.origin, original = { @@ -60,17 +74,17 @@ options.complete = done; // Set default origin and restore for show/hide - if ( mode !== "effect" ) { - options.origin = origin || ["middle","center"]; + if (mode !== "effect") { + options.origin = origin || ["middle", "center"]; options.restore = true; } - options.from = o.from || ( mode === "show" ? { + options.from = o.from || (mode === "show" ? { height: 0, width: 0, outerHeight: 0, outerWidth: 0 - } : original ); + } : original); options.to = { height: original.height * factor.y, width: original.width * factor.x, @@ -79,44 +93,44 @@ }; // Fade option to support puff - if ( options.fade ) { - if ( mode === "show" ) { + if (options.fade) { + if (mode === "show") { options.from.opacity = 0; options.to.opacity = 1; } - if ( mode === "hide" ) { + if (mode === "hide") { options.from.opacity = 1; options.to.opacity = 0; } } // Animate - el.effect( options ); + el.effect(options); }; - $.effects.effect.size = function( o, done ) { + $.effects.effect.size = function (o, done) { // Create element var original, baseline, factor, - el = $( this ), - props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ], + el = $(this), + props0 = ["position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity"], // Always restore - props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ], + props1 = ["position", "top", "bottom", "left", "right", "overflow", "opacity"], // Copy for children - props2 = [ "width", "height", "overflow" ], - cProps = [ "fontSize" ], - vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ], - hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ], + props2 = ["width", "height", "overflow"], + cProps = ["fontSize"], + vProps = ["borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom"], + hProps = ["borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight"], // Set options - mode = $.effects.setMode( el, o.mode || "effect" ), + mode = $.effects.setMode(el, o.mode || "effect"), restore = o.restore || mode !== "effect", scale = o.scale || "both", - origin = o.origin || [ "middle", "center" ], - position = el.css( "position" ), + origin = o.origin || ["middle", "center"], + position = el.css("position"), props = restore ? props0 : props1, zero = { height: 0, @@ -125,7 +139,7 @@ outerWidth: 0 }; - if ( mode === "show" ) { + if (mode === "show") { el.show(); } original = { @@ -135,12 +149,12 @@ outerWidth: el.outerWidth() }; - if ( o.mode === "toggle" && mode === "show" ) { + if (o.mode === "toggle" && mode === "show") { el.from = o.to || zero; el.to = o.from || original; } else { - el.from = o.from || ( mode === "show" ? zero : original ); - el.to = o.to || ( mode === "hide" ? zero : original ); + el.from = o.from || (mode === "show" ? zero : original); + el.to = o.to || (mode === "hide" ? zero : original); } // Set scaling factor @@ -156,59 +170,59 @@ }; // Scale the css box - if ( scale === "box" || scale === "both" ) { + if (scale === "box" || scale === "both") { // Vertical props scaling - if ( factor.from.y !== factor.to.y ) { - props = props.concat( vProps ); - el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from ); - el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to ); + if (factor.from.y !== factor.to.y) { + props = props.concat(vProps); + el.from = $.effects.setTransition(el, vProps, factor.from.y, el.from); + el.to = $.effects.setTransition(el, vProps, factor.to.y, el.to); } // Horizontal props scaling - if ( factor.from.x !== factor.to.x ) { - props = props.concat( hProps ); - el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from ); - el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to ); + if (factor.from.x !== factor.to.x) { + props = props.concat(hProps); + el.from = $.effects.setTransition(el, hProps, factor.from.x, el.from); + el.to = $.effects.setTransition(el, hProps, factor.to.x, el.to); } } // Scale the content - if ( scale === "content" || scale === "both" ) { + if (scale === "content" || scale === "both") { // Vertical props scaling - if ( factor.from.y !== factor.to.y ) { - props = props.concat( cProps ).concat( props2 ); - el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from ); - el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to ); + if (factor.from.y !== factor.to.y) { + props = props.concat(cProps).concat(props2); + el.from = $.effects.setTransition(el, cProps, factor.from.y, el.from); + el.to = $.effects.setTransition(el, cProps, factor.to.y, el.to); } } - $.effects.save( el, props ); + $.effects.save(el, props); el.show(); - $.effects.createWrapper( el ); - el.css( "overflow", "hidden" ).css( el.from ); + $.effects.createWrapper(el); + el.css("overflow", "hidden").css(el.from); // Adjust if (origin) { // Calculate baseline shifts - baseline = $.effects.getBaseline( origin, original ); - el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y; - el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x; - el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y; - el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x; + baseline = $.effects.getBaseline(origin, original); + el.from.top = (original.outerHeight - el.outerHeight()) * baseline.y; + el.from.left = (original.outerWidth - el.outerWidth()) * baseline.x; + el.to.top = (original.outerHeight - el.to.outerHeight) * baseline.y; + el.to.left = (original.outerWidth - el.to.outerWidth) * baseline.x; } - el.css( el.from ); // set top & left + el.css(el.from); // set top & left // Animate - if ( scale === "content" || scale === "both" ) { // Scale the children + if (scale === "content" || scale === "both") { // Scale the children // Add margins/font-size - vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps); - hProps = hProps.concat([ "marginLeft", "marginRight" ]); + vProps = vProps.concat(["marginTop", "marginBottom"]).concat(cProps); + hProps = hProps.concat(["marginLeft", "marginRight"]); props2 = props0.concat(vProps).concat(hProps); - el.find( "*[width]" ).each( function(){ - var child = $( this ), + el.find("*[width]").each(function () { + var child = $(this), c_original = { height: child.height(), width: child.width(), @@ -233,59 +247,59 @@ }; // Vertical props scaling - if ( factor.from.y !== factor.to.y ) { - child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from ); - child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to ); + if (factor.from.y !== factor.to.y) { + child.from = $.effects.setTransition(child, vProps, factor.from.y, child.from); + child.to = $.effects.setTransition(child, vProps, factor.to.y, child.to); } // Horizontal props scaling - if ( factor.from.x !== factor.to.x ) { - child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from ); - child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to ); + if (factor.from.x !== factor.to.x) { + child.from = $.effects.setTransition(child, hProps, factor.from.x, child.from); + child.to = $.effects.setTransition(child, hProps, factor.to.x, child.to); } // Animate children - child.css( child.from ); - child.animate( child.to, o.duration, o.easing, function() { + child.css(child.from); + child.animate(child.to, o.duration, o.easing, function () { // Restore children - if ( restore ) { - $.effects.restore( child, props2 ); + if (restore) { + $.effects.restore(child, props2); } }); }); } // Animate - el.animate( el.to, { + el.animate(el.to, { queue: false, duration: o.duration, easing: o.easing, - complete: function() { - if ( el.to.opacity === 0 ) { - el.css( "opacity", el.from.opacity ); + complete: function () { + if (el.to.opacity === 0) { + el.css("opacity", el.from.opacity); } - if( mode === "hide" ) { + if (mode === "hide") { el.hide(); } - $.effects.restore( el, props ); - if ( !restore ) { + $.effects.restore(el, props); + if (!restore) { // we need to calculate our new positioning based on the scaling - if ( position === "static" ) { + if (position === "static") { el.css({ position: "relative", top: el.to.top, left: el.to.left }); } else { - $.each([ "top", "left" ], function( idx, pos ) { - el.css( pos, function( _, str ) { - var val = parseInt( str, 10 ), + $.each(["top", "left"], function (idx, pos) { + el.css(pos, function (_, str) { + var val = parseInt(str, 10), toRef = idx ? el.to.left : el.to.top; // if original was "auto", recalculate the new value from wrapper - if ( str === "auto" ) { + if (str === "auto") { return toRef + "px"; } @@ -295,11 +309,11 @@ } } - $.effects.removeWrapper( el ); + $.effects.removeWrapper(el); done(); } }); }; -})(jQuery); +}); diff --git a/lib/web/jquery/ui-modules/effect-pulsate.js b/lib/web/jquery/ui-modules/effect-pulsate.js index 20796970d097..c8dd9f7847aa 100644 --- a/lib/web/jquery/ui-modules/effect-pulsate.js +++ b/lib/web/jquery/ui-modules/effect-pulsate.js @@ -1,30 +1,44 @@ -(function( $, undefined ) { +/*! + * jQuery UI Effects Pulsate + * http://jqueryui.com + * + * Copyright 2014 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/pulsate-effect/ + */ - $.effects.effect.pulsate = function( o, done ) { - var elem = $( this ), - mode = $.effects.setMode( elem, o.mode || "show" ), +define([ + 'jquery', + 'jquery-ui-modules/effect' +], function ($, undefined) { + + $.effects.effect.pulsate = function (o, done) { + var elem = $(this), + mode = $.effects.setMode(elem, o.mode || "show"), show = mode === "show", hide = mode === "hide", - showhide = ( show || mode === "hide" ), + showhide = (show || mode === "hide"), // showing or hiding leaves of the "last" animation - anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ), + anims = ((o.times || 5) * 2) + (showhide ? 1 : 0), duration = o.duration / anims, animateTo = 0, queue = elem.queue(), queuelen = queue.length, i; - if ( show || !elem.is(":visible")) { - elem.css( "opacity", 0 ).show(); + if (show || !elem.is(":visible")) { + elem.css("opacity", 0).show(); animateTo = 1; } // anims - 1 opacity "toggles" - for ( i = 1; i < anims; i++ ) { + for (i = 1; i < anims; i++) { elem.animate({ opacity: animateTo - }, duration, o.easing ); + }, duration, o.easing); animateTo = 1 - animateTo; } @@ -32,19 +46,19 @@ opacity: animateTo }, duration, o.easing); - elem.queue(function() { - if ( hide ) { + elem.queue(function () { + if (hide) { elem.hide(); } done(); }); // We just queued up "anims" animations, we need to put them next in the queue - if ( queuelen > 1 ) { - queue.splice.apply( queue, - [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); + if (queuelen > 1) { + queue.splice.apply(queue, + [1, 0].concat(queue.splice(queuelen, anims + 1))); } elem.dequeue(); }; -})(jQuery); +}); diff --git a/lib/web/jquery/ui-modules/effect-shake.js b/lib/web/jquery/ui-modules/effect-shake.js index 61924c24b5bd..8a4d7c21d2be 100644 --- a/lib/web/jquery/ui-modules/effect-shake.js +++ b/lib/web/jquery/ui-modules/effect-shake.js @@ -1,15 +1,29 @@ -(function( $, undefined ) { +/*! + * jQuery UI Effects Shake + * http://jqueryui.com + * + * Copyright 2014 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/shake-effect/ + */ - $.effects.effect.shake = function( o, done ) { +define([ + 'jquery', + 'jquery-ui-modules/effect' +], function ($, undefined) { - var el = $( this ), - props = [ "position", "top", "bottom", "left", "right", "height", "width" ], - mode = $.effects.setMode( el, o.mode || "effect" ), + $.effects.effect.shake = function (o, done) { + + var el = $(this), + props = ["position", "top", "bottom", "left", "right", "height", "width"], + mode = $.effects.setMode(el, o.mode || "effect"), direction = o.direction || "left", distance = o.distance || 20, times = o.times || 3, anims = times * 2 + 1, - speed = Math.round(o.duration/anims), + speed = Math.round(o.duration / anims), ref = (direction === "up" || direction === "down") ? "top" : "left", positiveMotion = (direction === "up" || direction === "left"), animation = {}, @@ -21,41 +35,41 @@ queue = el.queue(), queuelen = queue.length; - $.effects.save( el, props ); + $.effects.save(el, props); el.show(); - $.effects.createWrapper( el ); + $.effects.createWrapper(el); // Animation - animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance; - animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2; - animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2; + animation[ref] = (positiveMotion ? "-=" : "+=") + distance; + animation1[ref] = (positiveMotion ? "+=" : "-=") + distance * 2; + animation2[ref] = (positiveMotion ? "-=" : "+=") + distance * 2; // Animate - el.animate( animation, speed, o.easing ); + el.animate(animation, speed, o.easing); // Shakes - for ( i = 1; i < times; i++ ) { - el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing ); + for (i = 1; i < times; i++) { + el.animate(animation1, speed, o.easing).animate(animation2, speed, o.easing); } el - .animate( animation1, speed, o.easing ) - .animate( animation, speed / 2, o.easing ) - .queue(function() { - if ( mode === "hide" ) { + .animate(animation1, speed, o.easing) + .animate(animation, speed / 2, o.easing) + .queue(function () { + if (mode === "hide") { el.hide(); } - $.effects.restore( el, props ); - $.effects.removeWrapper( el ); + $.effects.restore(el, props); + $.effects.removeWrapper(el); done(); }); // inject all the animations we just queued to be first in line (after "inprogress") - if ( queuelen > 1) { - queue.splice.apply( queue, - [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); + if (queuelen > 1) { + queue.splice.apply(queue, + [1, 0].concat(queue.splice(queuelen, anims + 1))); } el.dequeue(); }; -})(jQuery); +}); diff --git a/lib/web/jquery/ui-modules/effect-slide.js b/lib/web/jquery/ui-modules/effect-slide.js index 582e9bc0728e..0cdf366f3778 100644 --- a/lib/web/jquery/ui-modules/effect-slide.js +++ b/lib/web/jquery/ui-modules/effect-slide.js @@ -1,11 +1,25 @@ -(function( $, undefined ) { +/*! + * jQuery UI Effects Slide + * http://jqueryui.com + * + * Copyright 2014 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/slide-effect/ + */ - $.effects.effect.slide = function( o, done ) { +define([ + 'jquery', + 'jquery-ui-modules/effect' +], function ($, undefined) { + + $.effects.effect.slide = function (o, done) { // Create element - var el = $( this ), - props = [ "position", "top", "bottom", "left", "right", "width", "height" ], - mode = $.effects.setMode( el, o.mode || "show" ), + var el = $(this), + props = ["position", "top", "bottom", "left", "right", "width", "height"], + mode = $.effects.setMode(el, o.mode || "show"), show = mode === "show", direction = o.direction || "left", ref = (direction === "up" || direction === "down") ? "top" : "left", @@ -14,38 +28,38 @@ animation = {}; // Adjust - $.effects.save( el, props ); + $.effects.save(el, props); el.show(); - distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ); + distance = o.distance || el[ref === "top" ? "outerHeight" : "outerWidth"](true); - $.effects.createWrapper( el ).css({ + $.effects.createWrapper(el).css({ overflow: "hidden" }); - if ( show ) { - el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance ); + if (show) { + el.css(ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance); } // Animation - animation[ ref ] = ( show ? - ( positiveMotion ? "+=" : "-=") : - ( positiveMotion ? "-=" : "+=")) + + animation[ref] = (show ? + (positiveMotion ? "+=" : "-=") : + (positiveMotion ? "-=" : "+=")) + distance; // Animate - el.animate( animation, { + el.animate(animation, { queue: false, duration: o.duration, easing: o.easing, - complete: function() { - if ( mode === "hide" ) { + complete: function () { + if (mode === "hide") { el.hide(); } - $.effects.restore( el, props ); - $.effects.removeWrapper( el ); + $.effects.restore(el, props); + $.effects.removeWrapper(el); done(); } }); }; -})(jQuery); +}); diff --git a/lib/web/jquery/ui-modules/effect-transfer.js b/lib/web/jquery/ui-modules/effect-transfer.js index f87cfb65ebbc..2328edd79bce 100644 --- a/lib/web/jquery/ui-modules/effect-transfer.js +++ b/lib/web/jquery/ui-modules/effect-transfer.js @@ -1,34 +1,48 @@ -(function( $, undefined ) { +/*! + * jQuery UI Effects Transfer + * http://jqueryui.com + * + * Copyright 2014 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/transfer-effect/ + */ - $.effects.effect.transfer = function( o, done ) { - var elem = $( this ), - target = $( o.to ), - targetFixed = target.css( "position" ) === "fixed", +define([ + 'jquery', + 'jquery-ui-modules/effect' +], function ($, undefined) { + + $.effects.effect.transfer = function (o, done) { + var elem = $(this), + target = $(o.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 , + top: endPosition.top - fixTop, + left: endPosition.left - fixLeft, height: target.innerHeight(), width: target.innerWidth() }, startPosition = elem.offset(), - transfer = $( "<div class='ui-effects-transfer'></div>" ) - .appendTo( document.body ) - .addClass( o.className ) + transfer = $("<div class='ui-effects-transfer'></div>") + .appendTo(document.body) + .addClass(o.className) .css({ - top: startPosition.top - fixTop , - left: startPosition.left - fixLeft , + top: startPosition.top - fixTop, + left: startPosition.left - fixLeft, height: elem.innerHeight(), width: elem.innerWidth(), position: targetFixed ? "fixed" : "absolute" }) - .animate( animation, o.duration, o.easing, function() { + .animate(animation, o.duration, o.easing, function () { transfer.remove(); done(); }); }; -})(jQuery); +}); diff --git a/lib/web/jquery/ui-modules/effect.js b/lib/web/jquery/ui-modules/effect.js index 54cbcde54d10..f73a076f2a00 100644 --- a/lib/web/jquery/ui-modules/effect.js +++ b/lib/web/jquery/ui-modules/effect.js @@ -1,4 +1,17 @@ -(function($, undefined) { +/*! + * jQuery UI Effects + * http://jqueryui.com + * + * Copyright 2014 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/category/effects-core/ + */ + +define([ + 'jquery' +], function ($, undefined) { var dataSpace = "ui-effects-"; @@ -16,7 +29,7 @@ * * Date: Wed Jan 16 08:47:09 2013 -0600 */ - (function( jQuery, undefined ) { + (function (jQuery, undefined) { var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor", @@ -25,60 +38,60 @@ // 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 ) { + parse: function (execResult) { return [ - execResult[ 1 ], - execResult[ 2 ], - execResult[ 3 ], - execResult[ 4 ] + 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 ) { + parse: function (execResult) { return [ - execResult[ 1 ] * 2.55, - execResult[ 2 ] * 2.55, - execResult[ 3 ] * 2.55, - execResult[ 4 ] + execResult[1] * 2.55, + execResult[2] * 2.55, + execResult[3] * 2.55, + execResult[4] ]; } }, { // 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})/, - parse: function( execResult ) { + parse: function (execResult) { return [ - parseInt( execResult[ 1 ], 16 ), - parseInt( execResult[ 2 ], 16 ), - parseInt( execResult[ 3 ], 16 ) + parseInt(execResult[1], 16), + parseInt(execResult[2], 16), + parseInt(execResult[3], 16) ]; } }, { // this regex ignores A-F because it's compared against an already lowercased string re: /#([a-f0-9])([a-f0-9])([a-f0-9])/, - parse: function( execResult ) { + parse: function (execResult) { return [ - parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ), - parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ), - parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ) + parseInt(execResult[1] + execResult[1], 16), + parseInt(execResult[2] + execResult[2], 16), + parseInt(execResult[3] + execResult[3], 16) ]; } }, { re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, space: "hsla", - parse: function( execResult ) { + parse: function (execResult) { return [ - execResult[ 1 ], - execResult[ 2 ] / 100, - execResult[ 3 ] / 100, - execResult[ 4 ] + execResult[1], + execResult[2] / 100, + execResult[3] / 100, + execResult[4] ]; } }], // jQuery.Color( ) - color = jQuery.Color = function( color, green, blue, alpha ) { - return new jQuery.Color.fn.parse( color, green, blue, alpha ); + color = jQuery.Color = function (color, green, blue, alpha) { + return new jQuery.Color.fn.parse(color, green, blue, alpha); }, spaces = { rgba: { @@ -131,7 +144,7 @@ support = color.support = {}, // element for support tests - supportElem = jQuery( "<p>" )[ 0 ], + supportElem = jQuery("<p>")[0], // colors = jQuery.Color.names colors, @@ -141,11 +154,11 @@ // determine rgba support immediately supportElem.style.cssText = "background-color:rgba(1,1,1,.5)"; - support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1; + support.rgba = supportElem.style.backgroundColor.indexOf("rgba") > -1; // define cache name and alpha properties // for rgba and hsla spaces - each( spaces, function( spaceName, space ) { + each(spaces, function (spaceName, space) { space.cache = "_" + spaceName; space.props.alpha = { idx: 3, @@ -154,23 +167,23 @@ }; }); - function clamp( value, prop, allowEmpty ) { - var type = propTypes[ prop.type ] || {}; + function clamp(value, prop, allowEmpty) { + var type = propTypes[prop.type] || {}; - if ( value == null ) { + if (value == null) { return (allowEmpty || !prop.def) ? null : prop.def; } // ~~ is an short way of doing floor for positive numbers - value = type.floor ? ~~value : parseFloat( value ); + value = type.floor ? ~~value : parseFloat(value); // IE will pass in empty strings as value for alpha, // which will hit this case - if ( isNaN( value ) ) { + if (isNaN(value)) { return prop.def; } - if ( type.mod ) { + 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; @@ -180,24 +193,24 @@ return 0 > value ? 0 : type.max < value ? type.max : value; } - function stringParse( string ) { + function stringParse(string) { var inst = color(), rgba = inst._rgba = []; string = string.toLowerCase(); - each( stringParsers, function( i, parser ) { + each(stringParsers, function (i, parser) { var parsed, - match = parser.re.exec( string ), - values = match && parser.parse( match ), + match = parser.re.exec(string), + values = match && parser.parse(match), spaceName = parser.space || "rgba"; - if ( values ) { - parsed = inst[ spaceName ]( values ); + if (values) { + parsed = inst[spaceName](values); // if this was an rgba parse the assignment might happen twice // oh well.... - inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ]; + inst[spaces[spaceName].cache] = parsed[spaces[spaceName].cache]; rgba = inst._rgba = parsed._rgba; // exit each( stringParsers ) here because we matched @@ -206,86 +219,86 @@ }); // Found a stringParser that handled it - if ( rgba.length ) { + if (rgba.length) { // 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 ); + if (rgba.join() === "0,0,0,0") { + jQuery.extend(rgba, colors.transparent); } return inst; } // named colors - return colors[ string ]; + return colors[string]; } - color.fn = jQuery.extend( color.prototype, { - parse: function( red, green, blue, alpha ) { - if ( red === undefined ) { - this._rgba = [ null, null, null, null ]; + 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 ); + if (red.jquery || red.nodeType) { + red = jQuery(red).css(green); green = undefined; } var inst = this, - type = jQuery.type( red ), + type = jQuery.type(red), rgba = this._rgba = []; // more than 1 argument specified - assume ( red, green, blue, alpha ) - if ( green !== undefined ) { - red = [ red, green, blue, alpha ]; + if (green !== undefined) { + red = [red, green, blue, alpha]; type = "array"; } - if ( type === "string" ) { - return this.parse( stringParse( red ) || colors._default ); + if (type === "string") { + return this.parse(stringParse(red) || colors._default); } - if ( type === "array" ) { - each( spaces.rgba.props, function( key, prop ) { - rgba[ prop.idx ] = clamp( red[ prop.idx ], prop ); + 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(); + 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 ) { + each(spaces, function (spaceName, space) { var cache = space.cache; - each( space.props, function( key, prop ) { + each(space.props, function (key, prop) { // if the cache doesn't exist, and we know how to convert - if ( !inst[ cache ] && space.to ) { + if (!inst[cache] && space.to) { // 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 ) { + if (key === "alpha" || red[key] == null) { return; } - inst[ cache ] = space.to( inst._rgba ); + inst[cache] = space.to(inst._rgba); } // 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 ); + inst[cache][prop.idx] = clamp(red[key], prop, true); }); // everything defined but alpha? - if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) { + if (inst[cache] && jQuery.inArray(null, inst[cache].slice(0, 3)) < 0) { // use the default of 1 - inst[ cache ][ 3 ] = 1; - if ( space.from ) { - inst._rgba = space.from( inst[ cache ] ); + inst[cache][3] = 1; + if (space.from) { + inst._rgba = space.from(inst[cache]); } } }); @@ -293,19 +306,19 @@ return this; } }, - is: function( compare ) { - var is = color( compare ), + is: function (compare) { + var is = color(compare), same = true, inst = this; - each( spaces, function( _, space ) { + each(spaces, function (_, space) { var localCache, - isCache = is[ space.cache ]; + 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 ] ); + 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; } }); @@ -314,115 +327,115 @@ }); return same; }, - _space: function() { + _space: function () { var used = [], inst = this; - each( spaces, function( spaceName, space ) { - if ( inst[ space.cache ] ) { - used.push( spaceName ); + each(spaces, function (spaceName, space) { + if (inst[space.cache]) { + used.push(spaceName); } }); return used.pop(); }, - transition: function( other, distance ) { - var end = color( other ), + 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 ), + 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 ) { + end = end[space.cache]; + each(space.props, function (key, prop) { var index = prop.idx, - startValue = start[ index ], - endValue = end[ index ], - type = propTypes[ prop.type ] || {}; + startValue = start[index], + endValue = end[index], + type = propTypes[prop.type] || {}; // if null, don't override start value - if ( endValue === null ) { + if (endValue === null) { return; } // if null - use end - if ( startValue === null ) { - result[ index ] = endValue; + if (startValue === null) { + result[index] = endValue; } else { - if ( type.mod ) { - if ( endValue - startValue > type.mod / 2 ) { + if (type.mod) { + if (endValue - startValue > type.mod / 2) { startValue += type.mod; - } else if ( startValue - endValue > type.mod / 2 ) { + } else if (startValue - endValue > type.mod / 2) { startValue -= type.mod; } } - result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop ); + result[index] = clamp((endValue - startValue) * distance + startValue, prop); } }); - return this[ spaceName ]( result ); + return this[spaceName](result); }, - blend: function( opaque ) { + blend: function (opaque) { // if we are already opaque - return ourself - if ( this._rgba[ 3 ] === 1 ) { + if (this._rgba[3] === 1) { return this; } var rgb = this._rgba.slice(), a = rgb.pop(), - blend = color( opaque )._rgba; + blend = color(opaque)._rgba; - return color( jQuery.map( rgb, function( v, i ) { - return ( 1 - a ) * blend[ i ] + a * v; + return color(jQuery.map(rgb, function (v, i) { + return (1 - a) * blend[i] + a * v; })); }, - toRgbaString: function() { + toRgbaString: function () { var prefix = "rgba(", - rgba = jQuery.map( this._rgba, function( v, i ) { - return v == null ? ( i > 2 ? 1 : 0 ) : v; + rgba = jQuery.map(this._rgba, function (v, i) { + return v == null ? (i > 2 ? 1 : 0) : v; }); - if ( rgba[ 3 ] === 1 ) { + if (rgba[3] === 1) { rgba.pop(); prefix = "rgb("; } return prefix + rgba.join() + ")"; }, - toHslaString: function() { + toHslaString: function () { var prefix = "hsla(", - hsla = jQuery.map( this.hsla(), function( v, i ) { - if ( v == null ) { + 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 ) + "%"; + if (i && i < 3) { + v = Math.round(v * 100) + "%"; } return v; }); - if ( hsla[ 3 ] === 1 ) { + if (hsla[3] === 1) { hsla.pop(); prefix = "hsl("; } return prefix + hsla.join() + ")"; }, - toHexString: function( includeAlpha ) { + toHexString: function (includeAlpha) { var rgba = this._rgba.slice(), alpha = rgba.pop(); - if ( includeAlpha ) { - rgba.push( ~~( alpha * 255 ) ); + if (includeAlpha) { + rgba.push(~~(alpha * 255)); } - return "#" + jQuery.map( rgba, function( v ) { + return "#" + jQuery.map(rgba, function (v) { // default to 0 when nulls exist - v = ( v || 0 ).toString( 16 ); + v = (v || 0).toString(16); return v.length === 1 ? "0" + v : v; }).join(""); }, - toString: function() { - return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString(); + toString: function () { + return this._rgba[3] === 0 ? "transparent" : this.toRgbaString(); } }); color.fn.parse.prototype = color.fn; @@ -430,211 +443,211 @@ // hsla conversions adapted from: // https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021 - function hue2rgb( p, q, h ) { - h = ( h + 1 ) % 1; - if ( h * 6 < 1 ) { + function hue2rgb(p, q, h) { + h = (h + 1) % 1; + if (h * 6 < 1) { return p + (q - p) * h * 6; } - if ( h * 2 < 1) { + if (h * 2 < 1) { return q; } - if ( h * 3 < 2 ) { - return p + (q - p) * ((2/3) - h) * 6; + if (h * 3 < 2) { + return p + (q - p) * ((2 / 3) - h) * 6; } return p; } - spaces.hsla.to = function ( rgba ) { - if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) { - return [ null, null, null, rgba[ 3 ] ]; + 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 ), + 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 ) { + 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 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; + h = (60 * (r - g) / diff) + 240; } // 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 ) { + if (diff === 0) { s = 0; - } else if ( l <= 0.5 ) { + } else if (l <= 0.5) { s = diff / add; } else { - s = diff / ( 2 - add ); + s = diff / (2 - add); } - return [ Math.round(h) % 360, s, l, a == null ? 1 : a ]; + return [Math.round(h) % 360, s, l, a == null ? 1 : a]; }; - spaces.hsla.from = function ( hsla ) { - if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) { - return [ null, null, null, hsla[ 3 ] ]; + 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, + 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 [ - 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 ), + 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 ]; }; - each( spaces, function( spaceName, space ) { + each(spaces, function (spaceName, space) { var props = space.props, cache = space.cache, to = space.to, from = space.from; // makes rgba() and hsla() - color.fn[ spaceName ] = function( value ) { + color.fn[spaceName] = function (value) { // generate a cache for this space if it doesn't exist - if ( to && !this[ cache ] ) { - this[ cache ] = to( this._rgba ); + if (to && !this[cache]) { + this[cache] = to(this._rgba); } - if ( value === undefined ) { - return this[ cache ].slice(); + if (value === undefined) { + return this[cache].slice(); } var ret, - type = jQuery.type( value ), - arr = ( type === "array" || type === "object" ) ? value : arguments, - local = this[ cache ].slice(); - - each( props, function( key, prop ) { - var val = arr[ type === "object" ? key : prop.idx ]; - if ( val == null ) { - val = local[ prop.idx ]; + type = jQuery.type(value), + arr = (type === "array" || type === "object") ? value : arguments, + local = this[cache].slice(); + + 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 ); + local[prop.idx] = clamp(val, prop); }); - if ( from ) { - ret = color( from( local ) ); - ret[ cache ] = local; + if (from) { + ret = color(from(local)); + ret[cache] = local; return ret; } else { - return color( local ); + return color(local); } }; // makes red() green() blue() alpha() hue() saturation() lightness() - each( props, function( key, prop ) { + each(props, function (key, prop) { // alpha is included in more than one space - if ( color.fn[ key ] ) { + if (color.fn[key]) { return; } - color.fn[ key ] = function( value ) { - var vtype = jQuery.type( value ), - fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ), - local = this[ fn ](), - cur = local[ prop.idx ], + color.fn[key] = function (value) { + var vtype = jQuery.type(value), + fn = (key === "alpha" ? (this._hsla ? "hsla" : "rgba") : spaceName), + local = this[fn](), + cur = local[prop.idx], match; - if ( vtype === "undefined" ) { + if (vtype === "undefined") { return cur; } - if ( vtype === "function" ) { - value = value.call( this, cur ); - vtype = jQuery.type( value ); + if (vtype === "function") { + value = value.call(this, cur); + vtype = jQuery.type(value); } - if ( value == null && prop.empty ) { + 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 (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 ); + 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 ) { + 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 ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) { - value = color( parsed || value ); - if ( !support.rgba && value._rgba[ 3 ] !== 1 ) { + if (value !== "transparent" && (jQuery.type(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" ); + backgroundColor = jQuery.css(curElem, "backgroundColor"); curElem = curElem.parentNode; - } catch ( e ) { + } catch (e) { } } - value = value.blend( backgroundColor && backgroundColor !== "transparent" ? + value = value.blend(backgroundColor && backgroundColor !== "transparent" ? backgroundColor : - "_default" ); + "_default"); } value = value.toRgbaString(); } try { - elem.style[ hook ] = value; - } catch( e ) { + elem.style[hook] = value; + } catch (e) { // 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 ); + 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 ) ); + jQuery.cssHooks[hook].set(fx.elem, fx.start.transition(fx.end, fx.pos)); }; }); }; - color.hook( stepHooks ); + color.hook(stepHooks); jQuery.cssHooks.borderColor = { - expand: function( value ) { + expand: function (value) { var expanded = {}; - each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) { - expanded[ "border" + part + "Color" ] = value; + each(["Top", "Right", "Bottom", "Left"], function (i, part) { + expanded["border" + part + "Color"] = value; }); return expanded; } @@ -663,20 +676,20 @@ yellow: "#ffff00", // 4.2.3. "transparent" color keyword - transparent: [ null, null, null, 0 ], + transparent: [null, null, null, 0], _default: "#ffffff" }; - })( jQuery ); + })(jQuery); /******************************************************************************/ /****************************** CLASS ANIMATIONS ******************************/ /******************************************************************************/ - (function() { + (function () { - var classAnimationActions = [ "add", "remove", "toggle" ], + var classAnimationActions = ["add", "remove", "toggle"], shorthandStyles = { border: 1, borderBottom: 1, @@ -689,35 +702,35 @@ 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 ); + $.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 getElementStyles( elem ) { + function getElementStyles(elem) { var key, len, style = elem.ownerDocument.defaultView ? - elem.ownerDocument.defaultView.getComputedStyle( elem, null ) : + elem.ownerDocument.defaultView.getComputedStyle(elem, null) : elem.currentStyle, styles = {}; - if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) { + 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 ]; + 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 ]; + for (key in style) { + if (typeof style[key] === "string") { + styles[key] = style[key]; } } } @@ -726,16 +739,16 @@ } - function styleDifference( oldStyle, newStyle ) { + 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; + for (name in newStyle) { + value = newStyle[name]; + if (oldStyle[name] !== value) { + if (!shorthandStyles[name]) { + if ($.fx.step[name] || !isNaN(parseFloat(value))) { + diff[name] = value; } } } @@ -745,132 +758,132 @@ } // support: jQuery <1.8 - if ( !$.fn.addBack ) { - $.fn.addBack = function( selector ) { - return this.add( selector == null ? - this.prevObject : this.prevObject.filter( selector ) + 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 ); + $.effects.animateClass = function (value, duration, easing, callback) { + var o = $.speed(duration, easing, callback); - return this.queue( function() { - var animated = $( this ), - baseClass = animated.attr( "class" ) || "", + return this.queue(function () { + var animated = $(this), + baseClass = animated.attr("class") || "", applyClassChange, - allAnimations = o.children ? animated.find( "*" ).addBack() : animated; + allAnimations = o.children ? animated.find("*").addBack() : animated; // map the animated objects to store the original styles. - allAnimations = allAnimations.map(function() { - var el = $( this ); + allAnimations = allAnimations.map(function () { + var el = $(this); return { el: el, - start: getElementStyles( this ) + start: getElementStyles(this) }; }); // apply class change - applyClassChange = function() { - $.each( classAnimationActions, function(i, action) { - if ( value[ action ] ) { - animated[ action + "Class" ]( value[ action ] ); + 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 ); + 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 ); + animated.attr("class", baseClass); // map all animated objects again - this time collecting a promise - allAnimations = allAnimations.map(function() { + allAnimations = allAnimations.map(function () { var styleInfo = this, dfd = $.Deferred(), opts = $.extend({}, o, { queue: false, - complete: function() { - dfd.resolve( styleInfo ); + complete: function () { + dfd.resolve(styleInfo); } }); - this.el.animate( this.diff, opts ); + this.el.animate(this.diff, opts); return dfd.promise(); }); // once all animations have completed: - $.when.apply( $, allAnimations.get() ).done(function() { + $.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() { + $.each(arguments, function () { var el = this.el; - $.each( this.diff, function(key) { - el.css( key, "" ); + $.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 ] ); + o.complete.call(animated[0]); }); }); }; $.fn.extend({ - addClass: (function( orig ) { - return function( classNames, speed, easing, callback ) { + addClass: (function (orig) { + return function (classNames, speed, easing, callback) { return speed ? - $.effects.animateClass.call( this, - { add: classNames }, speed, easing, callback ) : - orig.apply( this, arguments ); + $.effects.animateClass.call(this, + {add: classNames}, speed, easing, callback) : + orig.apply(this, arguments); }; - })( $.fn.addClass ), + })($.fn.addClass), - removeClass: (function( orig ) { - return function( classNames, speed, easing, callback ) { + 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 ); + $.effects.animateClass.call(this, + {remove: classNames}, speed, easing, callback) : + orig.apply(this, arguments); }; - })( $.fn.removeClass ), + })($.fn.removeClass), - toggleClass: (function( orig ) { - return function( classNames, force, speed, easing, callback ) { - if ( typeof force === "boolean" || force === undefined ) { - if ( !speed ) { + 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 ); + return orig.apply(this, arguments); } else { - return $.effects.animateClass.call( this, - (force ? { add: classNames } : { remove: classNames }), - speed, easing, callback ); + 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 ); + return $.effects.animateClass.call(this, + {toggle: classNames}, force, speed, easing); } }; - })( $.fn.toggleClass ), + })($.fn.toggleClass), - switchClass: function( remove, add, speed, easing, callback) { - return $.effects.animateClass.call( this, { + switchClass: function (remove, add, speed, easing, callback) { + return $.effects.animateClass.call(this, { add: add, remove: remove - }, speed, easing, callback ); + }, speed, easing, callback); } }); @@ -880,61 +893,75 @@ /*********************************** EFFECTS **********************************/ /******************************************************************************/ - (function() { + (function () { - $.extend( $.effects, { + $.extend($.effects, { version: "1.10.4", // Saves a set of properties in a data storage - save: function( element, set ) { - for( var i=0; i < set.length; i++ ) { - if ( set[ i ] !== null ) { - element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); + save: function (element, set) { + for (var i = 0; i < set.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 ) { + restore: function (element, set) { var val, i; - for( i=0; i < set.length; i++ ) { - if ( set[ i ] !== null ) { - val = element.data( dataSpace + set[ i ] ); + for (i = 0; i < set.length; i++) { + if (set[i] !== null) { + val = element.data(dataSpace + set[i]); // support: jQuery 1.6.2 // http://bugs.jquery.com/ticket/9917 // jQuery 1.6.2 incorrectly returns undefined for any falsy value. // We can't differentiate between "" and 0 here, so we just assume // empty string since it's likely to be a more common value... - if ( val === undefined ) { + if (val === undefined) { val = ""; } - element.css( set[ i ], val ); + element.css(set[i], val); } } }, - setMode: function( el, mode ) { + setMode: function (el, mode) { if (mode === "toggle") { - mode = el.is( ":hidden" ) ? "show" : "hide"; + mode = el.is(":hidden") ? "show" : "hide"; } return mode; }, // Translates a [top,left] array into a baseline value // this should be a little more flexible in the future to handle a string & hash - getBaseline: function( origin, original ) { + 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[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; + 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, @@ -943,10 +970,10 @@ }, // Wraps the element around a wrapper that copies position properties - createWrapper: function( element ) { + createWrapper: function (element) { // if the element is already wrapped, return it - if ( element.parent().is( ".ui-effects-wrapper" )) { + if (element.parent().is(".ui-effects-wrapper")) { return element.parent(); } @@ -954,10 +981,10 @@ var props = { width: element.outerWidth(true), height: element.outerHeight(true), - "float": element.css( "float" ) + "float": element.css("float") }, - wrapper = $( "<div></div>" ) - .addClass( "ui-effects-wrapper" ) + wrapper = $("<div></div>") + .addClass("ui-effects-wrapper") .css({ fontSize: "100%", background: "transparent", @@ -977,32 +1004,32 @@ // https://bugzilla.mozilla.org/show_bug.cgi?id=561664 try { active.id; - } catch( e ) { + } catch (e) { active = document.body; } - element.wrap( wrapper ); + element.wrap(wrapper); // Fixes #7595 - Elements lose focus when wrapped. - if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { - $( active ).focus(); + if (element[0] === active || $.contains(element[0], active)) { + $(active).focus(); } wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element // transfer positioning properties to the wrapper - if ( element.css( "position" ) === "static" ) { - wrapper.css({ position: "relative" }); - element.css({ position: "relative" }); + 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" ) + $.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"; + $.each(["top", "left", "bottom", "right"], function (i, pos) { + props[pos] = element.css(pos); + if (isNaN(parseInt(props[pos], 10))) { + props[pos] = "auto"; } }); element.css({ @@ -1015,18 +1042,18 @@ } element.css(size); - return wrapper.css( props ).show(); + return wrapper.css(props).show(); }, - removeWrapper: function( element ) { + removeWrapper: function (element) { var active = document.activeElement; - if ( element.parent().is( ".ui-effects-wrapper" ) ) { - element.parent().replaceWith( element ); + 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 ).focus(); + if (element[0] === active || $.contains(element[0], active)) { + $(active).focus(); } } @@ -1034,12 +1061,12 @@ return element; }, - setTransition: function( element, list, factor, 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 ]; + $.each(list, function (i, x) { + var unit = element.cssUnit(x); + if (unit[0] > 0) { + value[x] = unit[0] * factor + unit[1]; } }); return value; @@ -1047,51 +1074,51 @@ }); // return an effect options object for the given parameters: - function _normalizeArguments( effect, options, speed, callback ) { + function _normalizeArguments(effect, options, speed, callback) { // allow passing all options as the first parameter - if ( $.isPlainObject( effect ) ) { + if ($.isPlainObject(effect)) { options = effect; effect = effect.effect; } // convert to an object - effect = { effect: effect }; + effect = {effect: effect}; // catch (effect, null, ...) - if ( options == null ) { + if (options == null) { options = {}; } // catch (effect, callback) - if ( $.isFunction( options ) ) { + if ($.isFunction(options)) { callback = options; speed = null; options = {}; } // catch (effect, speed, ?) - if ( typeof options === "number" || $.fx.speeds[ options ] ) { + if (typeof options === "number" || $.fx.speeds[options]) { callback = speed; speed = options; options = {}; } // catch (effect, options, callback) - if ( $.isFunction( speed ) ) { + if ($.isFunction(speed)) { callback = speed; speed = null; } // add options to effect - if ( options ) { - $.extend( effect, options ); + 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 ] : + speed in $.fx.speeds ? $.fx.speeds[speed] : $.fx.speeds._default; effect.complete = callback || options.complete; @@ -1099,24 +1126,24 @@ return effect; } - function standardAnimationOption( option ) { + function standardAnimationOption(option) { // Valid standard speeds (nothing, number, named speed) - if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) { + if (!option || typeof option === "number" || $.fx.speeds[option]) { return true; } // Invalid strings - treat as "normal" speed - if ( typeof option === "string" && !$.effects.effect[ option ] ) { + if (typeof option === "string" && !$.effects.effect[option]) { return true; } // Complete callback - if ( $.isFunction( option ) ) { + if ($.isFunction(option)) { return true; } // Options hash (but not naming an effect) - if ( typeof option === "object" && !option.effect ) { + if (typeof option === "object" && !option.effect) { return true; } @@ -1125,96 +1152,96 @@ } $.fn.extend({ - effect: function( /* effect, options, speed, callback */ ) { - var args = _normalizeArguments.apply( this, arguments ), + effect: function ( /* effect, options, speed, callback */) { + var args = _normalizeArguments.apply(this, arguments), mode = args.mode, queue = args.queue, - effectMethod = $.effects.effect[ args.effect ]; + effectMethod = $.effects.effect[args.effect]; - if ( $.fx.off || !effectMethod ) { + if ($.fx.off || !effectMethod) { // delegate to the original method (e.g., .show()) if possible - if ( mode ) { - return this[ mode ]( args.duration, args.complete ); + if (mode) { + return this[mode](args.duration, args.complete); } else { - return this.each( function() { - if ( args.complete ) { - args.complete.call( this ); + return this.each(function () { + if (args.complete) { + args.complete.call(this); } }); } } - function run( next ) { - var elem = $( this ), + function run(next) { + var elem = $(this), complete = args.complete, mode = args.mode; function done() { - if ( $.isFunction( complete ) ) { - complete.call( elem[0] ); + if ($.isFunction(complete)) { + complete.call(elem[0]); } - if ( $.isFunction( next ) ) { + if ($.isFunction(next)) { next(); } } // If the element already has the correct final state, delegate to // the core methods so the internal tracking of "olddisplay" works. - if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { - elem[ mode ](); + if (elem.is(":hidden") ? mode === "hide" : mode === "show") { + elem[mode](); done(); } else { - effectMethod.call( elem[0], args, done ); + effectMethod.call(elem[0], args, done); } } - return queue === false ? this.each( run ) : this.queue( queue || "fx", run ); + return queue === false ? this.each(run) : this.queue(queue || "fx", run); }, - show: (function( orig ) { - return function( option ) { - if ( standardAnimationOption( option ) ) { - return orig.apply( this, arguments ); + show: (function (orig) { + return function (option) { + if (standardAnimationOption(option)) { + return orig.apply(this, arguments); } else { - var args = _normalizeArguments.apply( this, arguments ); + var args = _normalizeArguments.apply(this, arguments); args.mode = "show"; - return this.effect.call( this, args ); + return this.effect.call(this, args); } }; - })( $.fn.show ), + })($.fn.show), - hide: (function( orig ) { - return function( option ) { - if ( standardAnimationOption( option ) ) { - return orig.apply( this, arguments ); + hide: (function (orig) { + return function (option) { + if (standardAnimationOption(option)) { + return orig.apply(this, arguments); } else { - var args = _normalizeArguments.apply( this, arguments ); + var args = _normalizeArguments.apply(this, arguments); args.mode = "hide"; - return this.effect.call( this, args ); + return this.effect.call(this, args); } }; - })( $.fn.hide ), + })($.fn.hide), - toggle: (function( orig ) { - return function( option ) { - if ( standardAnimationOption( option ) || typeof option === "boolean" ) { - return orig.apply( this, arguments ); + toggle: (function (orig) { + return function (option) { + if (standardAnimationOption(option) || typeof option === "boolean") { + return orig.apply(this, arguments); } else { - var args = _normalizeArguments.apply( this, arguments ); + var args = _normalizeArguments.apply(this, arguments); args.mode = "toggle"; - return this.effect.call( this, args ); + return this.effect.call(this, args); } }; - })( $.fn.toggle ), + })($.fn.toggle), // helper functions - cssUnit: function(key) { - var style = this.css( key ), + 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 ]; + $.each(["em", "px", "%", "pt"], function (i, unit) { + if (style.indexOf(unit) > 0) { + val = [parseFloat(style), unit]; } }); return val; @@ -1227,53 +1254,54 @@ /*********************************** EASING ***********************************/ /******************************************************************************/ - (function() { + (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 ); + $.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 ); + $.extend(baseEasings, { + Sine: function (p) { + return 1 - Math.cos(p * Math.PI / 2); }, - Circ: function ( p ) { - return 1 - Math.sqrt( 1 - p * p ); + Circ: function (p) { + return 1 - Math.sqrt(1 - p * p); }, - Elastic: function( 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 ); + -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 ); + Back: function (p) { + return p * p * (3 * p - 2); }, - Bounce: function ( p ) { + 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 ); + 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 ); + $.each(baseEasings, function (name, easeIn) { + $.easing["easeIn" + name] = easeIn; + $.easing["easeOut" + name] = function (p) { + return 1 - easeIn(1 - p); }; - $.easing[ "easeInOut" + name ] = function( p ) { + $.easing["easeInOut" + name] = function (p) { return p < 0.5 ? - easeIn( p * 2 ) / 2 : - 1 - easeIn( p * -2 + 2 ) / 2; + easeIn(p * 2) / 2 : + 1 - easeIn(p * -2 + 2) / 2; }; }); })(); -})(jQuery); +}); diff --git a/lib/web/jquery/ui-modules/menu.js b/lib/web/jquery/ui-modules/menu.js index 08248dd3dd44..b314075c5c4d 100644 --- a/lib/web/jquery/ui-modules/menu.js +++ b/lib/web/jquery/ui-modules/menu.js @@ -1,6 +1,22 @@ -(function( $, undefined ) { - - $.widget( "ui.menu", { +/*! + * jQuery UI Menu + * http://jqueryui.com + * + * Copyright 2014 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/menu/ + */ + +define([ + 'jquery', + 'jquery-ui-modules/core', + 'jquery-ui-modules/widget', + 'jquery-ui-modules/position' +], function ($, undefined) { + + $.widget("ui.menu", { version: "1.10.4", defaultElement: "<ul>", delay: 300, @@ -21,90 +37,90 @@ select: null }, - _create: function() { + _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.element .uniqueId() - .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) - .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length ) + .addClass("ui-menu ui-widget ui-widget-content ui-corner-all") + .toggleClass("ui-menu-icons", !!this.element.find(".ui-icon").length) .attr({ role: this.options.role, tabIndex: 0 }) // need to catch all clicks on disabled menu // not possible through _on - .bind( "click" + this.eventNamespace, $.proxy(function( event ) { - if ( this.options.disabled ) { + .bind("click" + this.eventNamespace, $.proxy(function (event) { + if (this.options.disabled) { event.preventDefault(); } - }, this )); + }, this)); - if ( this.options.disabled ) { + if (this.options.disabled) { this.element - .addClass( "ui-state-disabled" ) - .attr( "aria-disabled", "true" ); + .addClass("ui-state-disabled") + .attr("aria-disabled", "true"); } 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 > a": function( event ) { + "mousedown .ui-menu-item > a": function (event) { event.preventDefault(); }, - "click .ui-state-disabled > a": function( event ) { + "click .ui-state-disabled > a": function (event) { event.preventDefault(); }, - "click .ui-menu-item:has(a)": function( event ) { - var target = $( event.target ).closest( ".ui-menu-item" ); - if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) { - this.select( event ); + "click .ui-menu-item:has(a)": function (event) { + var target = $(event.target).closest(".ui-menu-item"); + 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() ) { + 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" ) && $( this.document[ 0 ].activeElement ).closest( ".ui-menu" ).length ) { + if (target.has(".ui-menu").length) { + this.expand(event); + } else if (!this.element.is(":focus") && $(this.document[0].activeElement).closest(".ui-menu").length) { // Redirect focus to the menu - this.element.trigger( "focus", [ true ] ); + 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 ); + if (this.active && this.active.parents(".ui-menu").length === 1) { + clearTimeout(this.timer); } } } }, - "mouseenter .ui-menu-item": function( event ) { - var target = $( event.currentTarget ); + "mouseenter .ui-menu-item": function (event) { + var target = $(event.currentTarget); // 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 - target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" ); - this.focus( event, target ); + target.siblings().children(".ui-state-active").removeClass("ui-state-active"); + this.focus(event, target); }, mouseleave: "collapseAll", "mouseleave .ui-menu": "collapseAll", - focus: function( event, keepActiveItem ) { + 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.element.children( ".ui-menu-item" ).eq( 0 ); + var item = this.active || this.element.children(".ui-menu-item").eq(0); - if ( !keepActiveItem ) { - this.focus( event, item ); + if (!keepActiveItem) { + this.focus(event, item); } }, - blur: function( event ) { - this._delay(function() { - if ( !$.contains( this.element[0], this.document[0].activeElement ) ) { - this.collapseAll( event ); + blur: function (event) { + this._delay(function () { + if (!$.contains(this.element[0], this.document[0].activeElement)) { + this.collapseAll(event); } }); }, @@ -114,10 +130,10 @@ this.refresh(); // Clicks outside of a menu collapse any open menus - this._on( this.document, { - click: function( event ) { - if ( !$( event.target ).closest( ".ui-menu" ).length ) { - this.collapseAll( event ); + this._on(this.document, { + click: function (event) { + if (!$(event.target).closest(".ui-menu").length) { + this.collapseAll(event); } // Reset the mouseHandled flag @@ -126,124 +142,124 @@ }); }, - _destroy: function() { + _destroy: function () { // Destroy (sub)menus this.element - .removeAttr( "aria-activedescendant" ) - .find( ".ui-menu" ).addBack() - .removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" ) - .removeAttr( "role" ) - .removeAttr( "tabIndex" ) - .removeAttr( "aria-labelledby" ) - .removeAttr( "aria-expanded" ) - .removeAttr( "aria-hidden" ) - .removeAttr( "aria-disabled" ) + .removeAttr("aria-activedescendant") + .find(".ui-menu").addBack() + .removeClass("ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons") + .removeAttr("role") + .removeAttr("tabIndex") + .removeAttr("aria-labelledby") + .removeAttr("aria-expanded") + .removeAttr("aria-hidden") + .removeAttr("aria-disabled") .removeUniqueId() .show(); // Destroy menu items - this.element.find( ".ui-menu-item" ) - .removeClass( "ui-menu-item" ) - .removeAttr( "role" ) - .removeAttr( "aria-disabled" ) - .children( "a" ) + this.element.find(".ui-menu-item") + .removeClass("ui-menu-item") + .removeAttr("role") + .removeAttr("aria-disabled") + .children("a") .removeUniqueId() - .removeClass( "ui-corner-all ui-state-hover" ) - .removeAttr( "tabIndex" ) - .removeAttr( "role" ) - .removeAttr( "aria-haspopup" ) - .children().each( function() { - var elem = $( this ); - if ( elem.data( "ui-menu-submenu-carat" ) ) { + .removeClass("ui-corner-all ui-state-hover") + .removeAttr("tabIndex") + .removeAttr("role") + .removeAttr("aria-haspopup") + .children().each(function () { + var elem = $(this); + if (elem.data("ui-menu-submenu-carat")) { elem.remove(); } }); // Destroy menu dividers - this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" ); + this.element.find(".ui-menu-divider").removeClass("ui-menu-divider ui-widget-content"); }, - _keydown: function( event ) { + _keydown: function (event) { var match, prev, character, skip, regex, preventDefault = true; - function escape( value ) { - return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ); + function escape(value) { + return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&"); } - switch ( event.keyCode ) { + switch (event.keyCode) { case $.ui.keyCode.PAGE_UP: - this.previousPage( event ); + this.previousPage(event); break; case $.ui.keyCode.PAGE_DOWN: - this.nextPage( event ); + this.nextPage(event); break; case $.ui.keyCode.HOME: - this._move( "first", "first", event ); + this._move("first", "first", event); break; case $.ui.keyCode.END: - this._move( "last", "last", event ); + this._move("last", "last", event); break; case $.ui.keyCode.UP: - this.previous( event ); + this.previous(event); break; case $.ui.keyCode.DOWN: - this.next( event ); + this.next(event); break; case $.ui.keyCode.LEFT: - this.collapse( event ); + this.collapse(event); break; case $.ui.keyCode.RIGHT: - if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { - this.expand( event ); + if (this.active && !this.active.is(".ui-state-disabled")) { + this.expand(event); } break; case $.ui.keyCode.ENTER: case $.ui.keyCode.SPACE: - this._activate( event ); + this._activate(event); break; case $.ui.keyCode.ESCAPE: - this.collapse( event ); + this.collapse(event); break; default: preventDefault = false; prev = this.previousFilter || ""; - character = String.fromCharCode( event.keyCode ); + character = String.fromCharCode(event.keyCode); skip = false; - clearTimeout( this.filterTimer ); + clearTimeout(this.filterTimer); - if ( character === prev ) { + if (character === prev) { skip = true; } else { character = prev + character; } - regex = new RegExp( "^" + escape( character ), "i" ); - match = this.activeMenu.children( ".ui-menu-item" ).filter(function() { - return regex.test( $( this ).children( "a" ).text() ); + regex = new RegExp("^" + escape(character), "i"); + match = this.activeMenu.children(".ui-menu-item").filter(function () { + return regex.test($(this).children("a").text()); }); - match = skip && match.index( this.active.next() ) !== -1 ? - this.active.nextAll( ".ui-menu-item" ) : + 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 ); - regex = new RegExp( "^" + escape( character ), "i" ); - match = this.activeMenu.children( ".ui-menu-item" ).filter(function() { - return regex.test( $( this ).children( "a" ).text() ); + if (!match.length) { + character = String.fromCharCode(event.keyCode); + regex = new RegExp("^" + escape(character), "i"); + match = this.activeMenu.children(".ui-menu-item").filter(function () { + return regex.test($(this).children("a").text()); }); } - if ( match.length ) { - this.focus( event, match ); - if ( match.length > 1 ) { + if (match.length) { + this.focus(event, match); + if (match.length > 1) { this.previousFilter = character; - this.filterTimer = this._delay(function() { + this.filterTimer = this._delay(function () { delete this.previousFilter; - }, 1000 ); + }, 1000); } else { delete this.previousFilter; } @@ -252,361 +268,361 @@ } } - if ( preventDefault ) { + if (preventDefault) { event.preventDefault(); } }, - _activate: function( event ) { - if ( !this.active.is( ".ui-state-disabled" ) ) { - if ( this.active.children( "a[aria-haspopup='true']" ).length ) { - this.expand( event ); + _activate: function (event) { + if (!this.active.is(".ui-state-disabled")) { + if (this.active.children("a[aria-haspopup='true']").length) { + this.expand(event); } else { - this.select( event ); + this.select(event); } } }, - refresh: function() { + refresh: function () { var menus, icon = this.options.icons.submenu, - submenus = this.element.find( this.options.menus ); + submenus = this.element.find(this.options.menus); - this.element.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length ); + this.element.toggleClass("ui-menu-icons", !!this.element.find(".ui-icon").length); // Initialize nested menus - submenus.filter( ":not(.ui-menu)" ) - .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) + submenus.filter(":not(.ui-menu)") + .addClass("ui-menu ui-widget ui-widget-content ui-corner-all") .hide() .attr({ role: this.options.role, "aria-hidden": "true", "aria-expanded": "false" }) - .each(function() { - var menu = $( this ), - item = menu.prev( "a" ), - submenuCarat = $( "<span>" ) - .addClass( "ui-menu-icon ui-icon " + icon ) - .data( "ui-menu-submenu-carat", true ); + .each(function () { + var menu = $(this), + item = menu.prev("a"), + submenuCarat = $("<span>") + .addClass("ui-menu-icon ui-icon " + icon) + .data("ui-menu-submenu-carat", true); item - .attr( "aria-haspopup", "true" ) - .prepend( submenuCarat ); - menu.attr( "aria-labelledby", item.attr( "id" ) ); + .attr("aria-haspopup", "true") + .prepend(submenuCarat); + menu.attr("aria-labelledby", item.attr("id")); }); - menus = submenus.add( this.element ); + menus = submenus.add(this.element); // Don't refresh list items that are already adapted - menus.children( ":not(.ui-menu-item):has(a)" ) - .addClass( "ui-menu-item" ) - .attr( "role", "presentation" ) - .children( "a" ) + menus.children(":not(.ui-menu-item):has(a)") + .addClass("ui-menu-item") + .attr("role", "presentation") + .children("a") .uniqueId() - .addClass( "ui-corner-all" ) + .addClass("ui-corner-all") .attr({ tabIndex: -1, role: this._itemRole() }); // Initialize unlinked menu-items containing spaces and/or dashes only as dividers - menus.children( ":not(.ui-menu-item)" ).each(function() { - var item = $( this ); + menus.children(":not(.ui-menu-item)").each(function () { + var item = $(this); // hyphen, em dash, en dash - if ( !/[^\-\u2014\u2013\s]/.test( item.text() ) ) { - item.addClass( "ui-widget-content ui-menu-divider" ); + if (!/[^\-\u2014\u2013\s]/.test(item.text())) { + item.addClass("ui-widget-content ui-menu-divider"); } }); // Add aria-disabled attribute to any disabled menu item - menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" ); + menus.children(".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 ] ) ) { + if (this.active && !$.contains(this.element[0], this.active[0])) { this.blur(); } }, - _itemRole: function() { + _itemRole: function () { return { menu: "menuitem", listbox: "option" - }[ this.options.role ]; + }[this.options.role]; }, - _setOption: function( key, value ) { - if ( key === "icons" ) { - this.element.find( ".ui-menu-icon" ) - .removeClass( this.options.icons.submenu ) - .addClass( value.submenu ); + _setOption: function (key, value) { + if (key === "icons") { + this.element.find(".ui-menu-icon") + .removeClass(this.options.icons.submenu) + .addClass(value.submenu); } - this._super( key, value ); + this._super(key, value); }, - focus: function( event, item ) { + focus: function (event, item) { var nested, focused; - this.blur( event, event && event.type === "focus" ); + this.blur(event, event && event.type === "focus"); - this._scrollIntoView( item ); + this._scrollIntoView(item); this.active = item.first(); - focused = this.active.children( "a" ).addClass( "ui-state-focus" ); + focused = this.active.children("a").addClass("ui-state-focus"); // 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" ) ); + if (this.options.role) { + this.element.attr("aria-activedescendant", focused.attr("id")); } // Highlight active parent menu item, if any this.active .parent() - .closest( ".ui-menu-item" ) - .children( "a:first" ) - .addClass( "ui-state-active" ); + .closest(".ui-menu-item") + .children("a:first") + .addClass("ui-state-active"); - if ( event && event.type === "keydown" ) { + if (event && event.type === "keydown") { this._close(); } else { - this.timer = this._delay(function() { + this.timer = this._delay(function () { this._close(); - }, this.delay ); + }, this.delay); } - nested = item.children( ".ui-menu" ); - if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) { + 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 } ); + this._trigger("focus", event, {item: item}); }, - _scrollIntoView: function( 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; + 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.height(); - if ( offset < 0 ) { - this.activeMenu.scrollTop( scroll + offset ); - } else if ( offset + itemHeight > elementHeight ) { - this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight ); + 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 ); + blur: function (event, fromFocus) { + if (!fromFocus) { + clearTimeout(this.timer); } - if ( !this.active ) { + if (!this.active) { return; } - this.active.children( "a" ).removeClass( "ui-state-focus" ); + this.active.children("a").removeClass("ui-state-focus"); this.active = null; - this._trigger( "blur", event, { item: this.active } ); + this._trigger("blur", event, {item: this.active}); }, - _startOpening: function( submenu ) { - clearTimeout( this.timer ); + _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 carat icon - if ( submenu.attr( "aria-hidden" ) !== "true" ) { + if (submenu.attr("aria-hidden") !== "true") { return; } - this.timer = this._delay(function() { + this.timer = this._delay(function () { this._close(); - this._open( submenu ); - }, this.delay ); + this._open(submenu); + }, this.delay); }, - _open: function( submenu ) { + _open: function (submenu) { var position = $.extend({ of: this.active - }, this.options.position ); + }, this.options.position); - clearTimeout( this.timer ); - this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) ) + clearTimeout(this.timer); + this.element.find(".ui-menu").not(submenu.parents(".ui-menu")) .hide() - .attr( "aria-hidden", "true" ); + .attr("aria-hidden", "true"); submenu .show() - .removeAttr( "aria-hidden" ) - .attr( "aria-expanded", "true" ) - .position( position ); + .removeAttr("aria-hidden") + .attr("aria-expanded", "true") + .position(position); }, - collapseAll: function( event, all ) { - clearTimeout( this.timer ); - this.timer = this._delay(function() { + 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" ) ); + $(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 ) { + if (!currentMenu.length) { currentMenu = this.element; } - this._close( currentMenu ); + this._close(currentMenu); - this.blur( event ); + this.blur(event); this.activeMenu = currentMenu; - }, this.delay ); + }, 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 ) { + _close: function (startMenu) { + if (!startMenu) { startMenu = this.active ? this.active.parent() : this.element; } startMenu - .find( ".ui-menu" ) + .find(".ui-menu") .hide() - .attr( "aria-hidden", "true" ) - .attr( "aria-expanded", "false" ) + .attr("aria-hidden", "true") + .attr("aria-expanded", "false") .end() - .find( "a.ui-state-active" ) - .removeClass( "ui-state-active" ); + .find("a.ui-state-active") + .removeClass("ui-state-active"); }, - collapse: function( event ) { + collapse: function (event) { var newItem = this.active && - this.active.parent().closest( ".ui-menu-item", this.element ); - if ( newItem && newItem.length ) { + this.active.parent().closest(".ui-menu-item", this.element); + if (newItem && newItem.length) { this._close(); - this.focus( event, newItem ); + this.focus(event, newItem); } }, - expand: function( event ) { + expand: function (event) { var newItem = this.active && this.active - .children( ".ui-menu " ) - .children( ".ui-menu-item" ) + .children(".ui-menu ") + .children(".ui-menu-item") .first(); - if ( newItem && newItem.length ) { - this._open( newItem.parent() ); + 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 ); + this._delay(function () { + this.focus(event, newItem); }); } }, - next: function( event ) { - this._move( "next", "first", event ); + next: function (event) { + this._move("next", "first", event); }, - previous: function( event ) { - this._move( "prev", "last", event ); + previous: function (event) { + this._move("prev", "last", event); }, - isFirstItem: function() { - return this.active && !this.active.prevAll( ".ui-menu-item" ).length; + isFirstItem: function () { + return this.active && !this.active.prevAll(".ui-menu-item").length; }, - isLastItem: function() { - return this.active && !this.active.nextAll( ".ui-menu-item" ).length; + isLastItem: function () { + return this.active && !this.active.nextAll(".ui-menu-item").length; }, - _move: function( direction, filter, event ) { + _move: function (direction, filter, event) { var next; - if ( this.active ) { - if ( direction === "first" || direction === "last" ) { + if (this.active) { + if (direction === "first" || direction === "last") { next = this.active - [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" ) - .eq( -1 ); + [direction === "first" ? "prevAll" : "nextAll"](".ui-menu-item") + .eq(-1); } else { next = this.active - [ direction + "All" ]( ".ui-menu-item" ) - .eq( 0 ); + [direction + "All"](".ui-menu-item") + .eq(0); } } - if ( !next || !next.length || !this.active ) { - next = this.activeMenu.children( ".ui-menu-item" )[ filter ](); + if (!next || !next.length || !this.active) { + next = this.activeMenu.children(".ui-menu-item")[filter](); } - this.focus( event, next ); + this.focus(event, next); }, - nextPage: function( event ) { + nextPage: function (event) { var item, base, height; - if ( !this.active ) { - this.next( event ); + if (!this.active) { + this.next(event); return; } - if ( this.isLastItem() ) { + if (this.isLastItem()) { return; } - if ( this._hasScroll() ) { + if (this._hasScroll()) { base = this.active.offset().top; height = this.element.height(); - this.active.nextAll( ".ui-menu-item" ).each(function() { - item = $( this ); + this.active.nextAll(".ui-menu-item").each(function () { + item = $(this); return item.offset().top - base - height < 0; }); - this.focus( event, item ); + this.focus(event, item); } else { - this.focus( event, this.activeMenu.children( ".ui-menu-item" ) - [ !this.active ? "first" : "last" ]() ); + this.focus(event, this.activeMenu.children(".ui-menu-item") + [!this.active ? "first" : "last"]()); } }, - previousPage: function( event ) { + previousPage: function (event) { var item, base, height; - if ( !this.active ) { - this.next( event ); + if (!this.active) { + this.next(event); return; } - if ( this.isFirstItem() ) { + if (this.isFirstItem()) { return; } - if ( this._hasScroll() ) { + if (this._hasScroll()) { base = this.active.offset().top; height = this.element.height(); - this.active.prevAll( ".ui-menu-item" ).each(function() { - item = $( this ); + this.active.prevAll(".ui-menu-item").each(function () { + item = $(this); return item.offset().top - base + height > 0; }); - this.focus( event, item ); + this.focus(event, item); } else { - this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() ); + this.focus(event, this.activeMenu.children(".ui-menu-item").first()); } }, - _hasScroll: function() { - return this.element.outerHeight() < this.element.prop( "scrollHeight" ); + _hasScroll: function () { + return this.element.outerHeight() < this.element.prop("scrollHeight"); }, - select: function( event ) { + 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.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 ); + this._trigger("select", event, ui); } }); -}( jQuery )); +}); diff --git a/lib/web/jquery/ui-modules/mouse.js b/lib/web/jquery/ui-modules/mouse.js index 9e41e60a783c..a45b92a5a11c 100644 --- a/lib/web/jquery/ui-modules/mouse.js +++ b/lib/web/jquery/ui-modules/mouse.js @@ -1,7 +1,24 @@ -(function( $, undefined ) { +/*! + * jQuery UI Mouse + * http://jqueryui.com + * + * Copyright 2014 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/mouse/ + * + * Depends: + * jquery.ui.widget.js + */ + +define([ + 'jquery', + 'jquery-ui-modules/widget' +], function ($, undefined) { var mouseHandled = false; - $( document ).mouseup( function() { + $(document).mouseup(function () { mouseHandled = false; }); @@ -12,14 +29,14 @@ distance: 1, delay: 0 }, - _mouseInit: function() { + _mouseInit: function () { var that = this; this.element - .bind("mousedown."+this.widgetName, function(event) { + .bind("mousedown." + this.widgetName, function (event) { return that._mouseDown(event); }) - .bind("click."+this.widgetName, function(event) { + .bind("click." + this.widgetName, function (event) { if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) { $.removeData(event.target, that.widgetName + ".preventClickEvent"); event.stopImmediatePropagation(); @@ -32,18 +49,20 @@ // TODO: make sure destroying one instance of mouse doesn't mess with // other instances of mouse - _mouseDestroy: function() { - this.element.unbind("."+this.widgetName); - if ( this._mouseMoveDelegate ) { + _mouseDestroy: function () { + this.element.unbind("." + this.widgetName); + if (this._mouseMoveDelegate) { $(document) - .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate) - .unbind("mouseup."+this.widgetName, this._mouseUpDelegate); + .unbind("mousemove." + this.widgetName, this._mouseMoveDelegate) + .unbind("mouseup." + this.widgetName, this._mouseUpDelegate); } }, - _mouseDown: function(event) { + _mouseDown: function (event) { // don't let more than one widget handle mouseStart - if( mouseHandled ) { return; } + if (mouseHandled) { + return; + } // we may have missed mouseup (out of window) (this._mouseStarted && this._mouseUp(event)); @@ -61,7 +80,7 @@ this.mouseDelayMet = !this.options.delay; if (!this.mouseDelayMet) { - this._mouseDelayTimer = setTimeout(function() { + this._mouseDelayTimer = setTimeout(function () { that.mouseDelayMet = true; }, this.options.delay); } @@ -80,15 +99,15 @@ } // these delegates are required to keep context - this._mouseMoveDelegate = function(event) { + this._mouseMoveDelegate = function (event) { return that._mouseMove(event); }; - this._mouseUpDelegate = function(event) { + this._mouseUpDelegate = function (event) { return that._mouseUp(event); }; $(document) - .bind("mousemove."+this.widgetName, this._mouseMoveDelegate) - .bind("mouseup."+this.widgetName, this._mouseUpDelegate); + .bind("mousemove." + this.widgetName, this._mouseMoveDelegate) + .bind("mouseup." + this.widgetName, this._mouseUpDelegate); event.preventDefault(); @@ -96,9 +115,9 @@ return true; }, - _mouseMove: function(event) { + _mouseMove: function (event) { // IE mouseup check - mouseup happened when mouse was out of window - if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) { + if ($.ui.ie && (!document.documentMode || document.documentMode < 9) && !event.button) { return this._mouseUp(event); } @@ -116,10 +135,10 @@ return !this._mouseStarted; }, - _mouseUp: function(event) { + _mouseUp: function (event) { $(document) - .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate) - .unbind("mouseup."+this.widgetName, this._mouseUpDelegate); + .unbind("mousemove." + this.widgetName, this._mouseMoveDelegate) + .unbind("mouseup." + this.widgetName, this._mouseUpDelegate); if (this._mouseStarted) { this._mouseStarted = false; @@ -134,7 +153,7 @@ return false; }, - _mouseDistanceMet: function(event) { + _mouseDistanceMet: function (event) { return (Math.max( Math.abs(this._mouseDownEvent.pageX - event.pageX), Math.abs(this._mouseDownEvent.pageY - event.pageY) @@ -142,15 +161,20 @@ ); }, - _mouseDelayMet: function(/* event */) { + _mouseDelayMet: function (/* event */) { return this.mouseDelayMet; }, // These are placeholder methods, to be overridden by extending plugin - _mouseStart: function(/* event */) {}, - _mouseDrag: function(/* event */) {}, - _mouseStop: function(/* event */) {}, - _mouseCapture: function(/* event */) { return true; } + _mouseStart: function (/* event */) { + }, + _mouseDrag: function (/* event */) { + }, + _mouseStop: function (/* event */) { + }, + _mouseCapture: function (/* event */) { + return true; + } }); -})(jQuery); \ No newline at end of file +}); diff --git a/lib/web/jquery/ui-modules/position.js b/lib/web/jquery/ui-modules/position.js index 730acba51efd..74f8df320d68 100644 --- a/lib/web/jquery/ui-modules/position.js +++ b/lib/web/jquery/ui-modules/position.js @@ -1,4 +1,16 @@ -(function( $, undefined ) { +/*! + * jQuery UI Position + * http://jqueryui.com + * + * Copyright 2014 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +define([ + 'jquery', + 'jquery-ui-modules/position' +], function ($, undefined) { $.ui = $.ui || {}; @@ -13,38 +25,38 @@ rpercent = /%$/, _position = $.fn.position; - function getOffsets( offsets, width, height ) { + 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 ) + 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 parseCss(element, property) { + return parseInt($.css(element, property), 10) || 0; } - function getDimensions( elem ) { + function getDimensions(elem) { var raw = elem[0]; - if ( raw.nodeType === 9 ) { + if (raw.nodeType === 9) { return { width: elem.width(), height: elem.height(), - offset: { top: 0, left: 0 } + offset: {top: 0, left: 0} }; } - if ( $.isWindow( raw ) ) { + if ($.isWindow(raw)) { return { width: elem.width(), height: elem.height(), - offset: { top: elem.scrollTop(), left: elem.scrollLeft() } + offset: {top: elem.scrollTop(), left: elem.scrollLeft()} }; } - if ( raw.preventDefault ) { + if (raw.preventDefault) { return { width: 0, height: 0, - offset: { top: raw.pageY, left: raw.pageX } + offset: {top: raw.pageY, left: raw.pageX} }; } return { @@ -55,21 +67,21 @@ } $.position = { - scrollbarWidth: function() { - if ( cachedScrollbarWidth !== undefined ) { + scrollbarWidth: function () { + if (cachedScrollbarWidth !== undefined) { return cachedScrollbarWidth; } var w1, w2, - div = $( "<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ), + div = $("<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>"), innerDiv = div.children()[0]; - $( "body" ).append( div ); + $("body").append(div); w1 = innerDiv.offsetWidth; - div.css( "overflow", "scroll" ); + div.css("overflow", "scroll"); w2 = innerDiv.offsetWidth; - if ( w1 === w2 ) { + if (w1 === w2) { w2 = div[0].clientWidth; } @@ -77,29 +89,29 @@ return (cachedScrollbarWidth = w1 - w2); }, - getScrollInfo: function( within ) { + getScrollInfo: function (within) { var overflowX = within.isWindow || within.isDocument ? "" : - within.element.css( "overflow-x" ), + within.element.css("overflow-x"), overflowY = within.isWindow || within.isDocument ? "" : - within.element.css( "overflow-y" ), + within.element.css("overflow-y"), hasOverflowX = overflowX === "scroll" || - ( overflowX === "auto" && within.width < within.element[0].scrollWidth ), + (overflowX === "auto" && within.width < within.element[0].scrollWidth), hasOverflowY = overflowY === "scroll" || - ( overflowY === "auto" && within.height < within.element[0].scrollHeight ); + (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 ), - isWindow = $.isWindow( withinElement[0] ), - isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9; + getWithinInfo: function (element) { + var withinElement = $(element || window), + isWindow = $.isWindow(withinElement[0]), + isDocument = !!withinElement[0] && withinElement[0].nodeType === 9; return { element: withinElement, isWindow: isWindow, isDocument: isDocument, - offset: withinElement.offset() || { left: 0, top: 0 }, + offset: withinElement.offset() || {left: 0, top: 0}, scrollLeft: withinElement.scrollLeft(), scrollTop: withinElement.scrollTop(), width: isWindow ? withinElement.width() : withinElement.outerWidth(), @@ -108,23 +120,23 @@ } }; - $.fn.position = function( options ) { - if ( !options || !options.of ) { - return _position.apply( this, arguments ); + $.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 ); + options = $.extend({}, options); var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, - target = $( options.of ), - within = $.position.getWithinInfo( options.within ), - scrollInfo = $.position.getScrollInfo( within ), - collision = ( options.collision || "flip" ).split( " " ), + target = $(options.of), + within = $.position.getWithinInfo(options.within), + scrollInfo = $.position.getScrollInfo(within), + collision = (options.collision || "flip").split(" "), offsets = {}; - dimensions = getDimensions( target ); - if ( target[0].preventDefault ) { + dimensions = getDimensions(target); + if (target[0].preventDefault) { // force left top to allow flipping options.at = "left top"; } @@ -132,92 +144,92 @@ targetHeight = dimensions.height; targetOffset = dimensions.offset; // clone to reuse original targetOffset later - basePosition = $.extend( {}, targetOffset ); + 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( " " ), + $.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" ]; + 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"; + 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 + 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 ] + options[this] = [ + rposition.exec(pos[0])[0], + rposition.exec(pos[1])[0] ]; }); // normalize collision option - if ( collision.length === 1 ) { - collision[ 1 ] = collision[ 0 ]; + if (collision.length === 1) { + collision[1] = collision[0]; } - if ( options.at[ 0 ] === "right" ) { + if (options.at[0] === "right") { basePosition.left += targetWidth; - } else if ( options.at[ 0 ] === "center" ) { + } else if (options.at[0] === "center") { basePosition.left += targetWidth / 2; } - if ( options.at[ 1 ] === "bottom" ) { + if (options.at[1] === "bottom") { basePosition.top += targetHeight; - } else if ( options.at[ 1 ] === "center" ) { + } else if (options.at[1] === "center") { basePosition.top += targetHeight / 2; } - atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); - basePosition.left += atOffset[ 0 ]; - basePosition.top += atOffset[ 1 ]; + atOffset = getOffsets(offsets.at, targetWidth, targetHeight); + basePosition.left += atOffset[0]; + basePosition.top += atOffset[1]; - return this.each(function() { + return this.each(function () { var collisionPosition, using, - elem = $( this ), + 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" ) { + 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" ) { + } else if (options.my[0] === "center") { position.left -= elemWidth / 2; } - if ( options.my[ 1 ] === "bottom" ) { + if (options.my[1] === "bottom") { position.top -= elemHeight; - } else if ( options.my[ 1 ] === "center" ) { + } else if (options.my[1] === "center") { position.top -= elemHeight / 2; } - position.left += myOffset[ 0 ]; - position.top += myOffset[ 1 ]; + position.left += myOffset[0]; + position.top += myOffset[1]; // if the browser doesn't support fractions, then round for consistent results - if ( !$.support.offsetFractions ) { - position.left = round( position.left ); - position.top = round( position.top ); + if (!$.support.offsetFractions) { + position.left = round(position.left); + position.top = round(position.top); } collisionPosition = { @@ -225,9 +237,9 @@ marginTop: marginTop }; - $.each( [ "left", "top" ], function( i, dir ) { - if ( $.ui.position[ collision[ i ] ] ) { - $.ui.position[ collision[ i ] ][ dir ]( position, { + $.each(["left", "top"], function (i, dir) { + if ($.ui.position[collision[i]]) { + $.ui.position[collision[i]][dir](position, { targetWidth: targetWidth, targetHeight: targetHeight, elemWidth: elemWidth, @@ -235,18 +247,18 @@ collisionPosition: collisionPosition, collisionWidth: collisionWidth, collisionHeight: collisionHeight, - offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], + offset: [atOffset[0] + myOffset[0], atOffset [1] + myOffset[1]], my: options.my, at: options.at, within: within, - elem : elem + elem: elem }); } }); - if ( options.using ) { + if (options.using) { // adds feedback as second argument to using callback, if present - using = function( props ) { + using = function (props) { var left = targetOffset.left - position.left, right = left + targetWidth - elemWidth, top = targetOffset.top - position.top, @@ -269,28 +281,28 @@ horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" }; - if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { + if (targetWidth < elemWidth && abs(left + right) < targetWidth) { feedback.horizontal = "center"; } - if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { + if (targetHeight < elemHeight && abs(top + bottom) < targetHeight) { feedback.vertical = "middle"; } - if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { + if (max(abs(left), abs(right)) > max(abs(top), abs(bottom))) { feedback.important = "horizontal"; } else { feedback.important = "vertical"; } - options.using.call( this, props, feedback ); + options.using.call(this, props, feedback); }; } - elem.offset( $.extend( position, { using: using } ) ); + elem.offset($.extend(position, {using: using})); }); }; $.ui.position = { fit: { - left: function( position, data ) { + left: function (position, data) { var within = data.within, withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, outerWidth = within.width, @@ -300,34 +312,34 @@ newOverRight; // element is wider than within - if ( data.collisionWidth > outerWidth ) { + if (data.collisionWidth > outerWidth) { // element is initially over the left side of within - if ( overLeft > 0 && overRight <= 0 ) { + 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 ) { + } else if (overRight > 0 && overLeft <= 0) { position.left = withinOffset; // element is initially over both left and right sides of within } else { - if ( overLeft > overRight ) { + if (overLeft > overRight) { position.left = withinOffset + outerWidth - data.collisionWidth; } else { position.left = withinOffset; } } // too far left -> align with left edge - } else if ( overLeft > 0 ) { + } else if (overLeft > 0) { position.left += overLeft; // too far right -> align with right edge - } else if ( overRight > 0 ) { + } else if (overRight > 0) { position.left -= overRight; // adjust based on position and margin } else { - position.left = max( position.left - collisionPosLeft, position.left ); + position.left = max(position.left - collisionPosLeft, position.left); } }, - top: function( position, data ) { + top: function (position, data) { var within = data.within, withinOffset = within.isWindow ? within.scrollTop : within.offset.top, outerHeight = data.within.height, @@ -337,36 +349,36 @@ newOverBottom; // element is taller than within - if ( data.collisionHeight > outerHeight ) { + if (data.collisionHeight > outerHeight) { // element is initially over the top of within - if ( overTop > 0 && overBottom <= 0 ) { + 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 ) { + } else if (overBottom > 0 && overTop <= 0) { position.top = withinOffset; // element is initially over both top and bottom of within } else { - if ( overTop > overBottom ) { + if (overTop > overBottom) { position.top = withinOffset + outerHeight - data.collisionHeight; } else { position.top = withinOffset; } } // too far up -> align with top - } else if ( overTop > 0 ) { + } else if (overTop > 0) { position.top += overTop; // too far down -> align with bottom edge - } else if ( overBottom > 0 ) { + } else if (overBottom > 0) { position.top -= overBottom; // adjust based on position and margin } else { - position.top = max( position.top - collisionPosTop, position.top ); + position.top = max(position.top - collisionPosTop, position.top); } } }, flip: { - left: function( position, data ) { + left: function (position, data) { var within = data.within, withinOffset = within.offset.left + within.scrollLeft, outerWidth = within.width, @@ -374,34 +386,33 @@ collisionPosLeft = position.left - data.collisionPosition.marginLeft, overLeft = collisionPosLeft - offsetLeft, overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, - myOffset = data.my[ 0 ] === "left" ? + myOffset = data.my[0] === "left" ? -data.elemWidth : - data.my[ 0 ] === "right" ? + data.my[0] === "right" ? data.elemWidth : 0, - atOffset = data.at[ 0 ] === "left" ? + atOffset = data.at[0] === "left" ? data.targetWidth : - data.at[ 0 ] === "right" ? + data.at[0] === "right" ? -data.targetWidth : 0, - offset = -2 * data.offset[ 0 ], + offset = -2 * data.offset[0], newOverRight, newOverLeft; - if ( overLeft < 0 ) { + if (overLeft < 0) { newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset; - if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { + if (newOverRight < 0 || newOverRight < abs(overLeft)) { position.left += myOffset + atOffset + offset; } - } - else if ( overRight > 0 ) { + } else if (overRight > 0) { newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft; - if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { + if (newOverLeft > 0 || abs(newOverLeft) < overRight) { position.left += myOffset + atOffset + offset; } } }, - top: function( position, data ) { + top: function (position, data) { var within = data.within, withinOffset = within.offset.top + within.scrollTop, outerHeight = within.height, @@ -409,42 +420,41 @@ collisionPosTop = position.top - data.collisionPosition.marginTop, overTop = collisionPosTop - offsetTop, overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, - top = data.my[ 1 ] === "top", + top = data.my[1] === "top", myOffset = top ? -data.elemHeight : - data.my[ 1 ] === "bottom" ? + data.my[1] === "bottom" ? data.elemHeight : 0, - atOffset = data.at[ 1 ] === "top" ? + atOffset = data.at[1] === "top" ? data.targetHeight : - data.at[ 1 ] === "bottom" ? + data.at[1] === "bottom" ? -data.targetHeight : 0, - offset = -2 * data.offset[ 1 ], + offset = -2 * data.offset[1], newOverTop, newOverBottom; - if ( overTop < 0 ) { + if (overTop < 0) { newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset; - if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) { + if ((position.top + myOffset + atOffset + offset) > overTop && (newOverBottom < 0 || newOverBottom < abs(overTop))) { position.top += myOffset + atOffset + offset; } - } - else if ( overBottom > 0 ) { + } else if (overBottom > 0) { newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop; - if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) { + if ((position.top + myOffset + atOffset + offset) > overBottom && (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 ); + 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 ); + top: function () { + $.ui.position.flip.top.apply(this, arguments); + $.ui.position.fit.top.apply(this, arguments); } } }; @@ -452,11 +462,11 @@ // fraction support test (function () { var testElement, testElementParent, testElementStyle, offsetLeft, i, - body = document.getElementsByTagName( "body" )[ 0 ], - div = document.createElement( "div" ); + body = document.getElementsByTagName("body")[0], + div = document.createElement("div"); //Create a "fake body" for testing based on method used in jQuery.support - testElement = document.createElement( body ? "div" : "body" ); + testElement = document.createElement(body ? "div" : "body"); testElementStyle = { visibility: "hidden", width: 0, @@ -465,27 +475,27 @@ margin: 0, background: "none" }; - if ( body ) { - $.extend( testElementStyle, { + if (body) { + $.extend(testElementStyle, { position: "absolute", left: "-1000px", top: "-1000px" }); } - for ( i in testElementStyle ) { - testElement.style[ i ] = testElementStyle[ i ]; + for (i in testElementStyle) { + testElement.style[i] = testElementStyle[i]; } - testElement.appendChild( div ); + testElement.appendChild(div); testElementParent = body || document.documentElement; - testElementParent.insertBefore( testElement, testElementParent.firstChild ); + testElementParent.insertBefore(testElement, testElementParent.firstChild); div.style.cssText = "position: absolute; left: 10.7432222px;"; - offsetLeft = $( div ).offset().left; + offsetLeft = $(div).offset().left; $.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11; testElement.innerHTML = ""; - testElementParent.removeChild( testElement ); + testElementParent.removeChild(testElement); })(); -}( jQuery ) ); +}); diff --git a/lib/web/jquery/ui-modules/progressbar.js b/lib/web/jquery/ui-modules/progressbar.js index 692de2dc3e93..0f177d19f696 100644 --- a/lib/web/jquery/ui-modules/progressbar.js +++ b/lib/web/jquery/ui-modules/progressbar.js @@ -1,6 +1,21 @@ -(function( $, undefined ) { - - $.widget( "ui.progressbar", { +/*! + * jQuery UI Progressbar + * http://jqueryui.com + * + * Copyright 2014 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/progressbar/ + */ + +define([ + 'jquery', + 'jquery-ui-modules/core', + 'jquery-ui-modules/widget' +], function ($, undefined) { + + $.widget("ui.progressbar", { version: "1.10.4", options: { max: 100, @@ -12,12 +27,12 @@ min: 0, - _create: function() { + _create: function () { // Constrain initial value this.oldValue = this.options.value = this._constrainedValue(); this.element - .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) + .addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all") .attr({ // Only set static values, aria-valuenow and aria-valuemax are // set inside _refreshValue() @@ -25,107 +40,107 @@ "aria-valuemin": this.min }); - this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" ) - .appendTo( this.element ); + this.valueDiv = $("<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>") + .appendTo(this.element); this._refreshValue(); }, - _destroy: function() { + _destroy: function () { this.element - .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) - .removeAttr( "role" ) - .removeAttr( "aria-valuemin" ) - .removeAttr( "aria-valuemax" ) - .removeAttr( "aria-valuenow" ); + .removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all") + .removeAttr("role") + .removeAttr("aria-valuemin") + .removeAttr("aria-valuemax") + .removeAttr("aria-valuenow"); this.valueDiv.remove(); }, - value: function( newValue ) { - if ( newValue === undefined ) { + value: function (newValue) { + if (newValue === undefined) { return this.options.value; } - this.options.value = this._constrainedValue( newValue ); + this.options.value = this._constrainedValue(newValue); this._refreshValue(); }, - _constrainedValue: function( newValue ) { - if ( newValue === undefined ) { + _constrainedValue: function (newValue) { + if (newValue === undefined) { newValue = this.options.value; } this.indeterminate = newValue === false; // sanitize value - if ( typeof newValue !== "number" ) { + if (typeof newValue !== "number") { newValue = 0; } return this.indeterminate ? false : - Math.min( this.options.max, Math.max( this.min, newValue ) ); + Math.min(this.options.max, Math.max(this.min, newValue)); }, - _setOptions: function( options ) { + _setOptions: function (options) { // Ensure "value" option is set after other values (like max) var value = options.value; delete options.value; - this._super( options ); + this._super(options); - this.options.value = this._constrainedValue( value ); + this.options.value = this._constrainedValue(value); this._refreshValue(); }, - _setOption: function( key, value ) { - if ( key === "max" ) { + _setOption: function (key, value) { + if (key === "max") { // Don't allow a max less than min - value = Math.max( this.min, value ); + value = Math.max(this.min, value); } - this._super( key, value ); + this._super(key, value); }, - _percentage: function() { - return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min ); + _percentage: function () { + return this.indeterminate ? 100 : 100 * (this.options.value - this.min) / (this.options.max - this.min); }, - _refreshValue: function() { + _refreshValue: function () { var value = this.options.value, percentage = this._percentage(); this.valueDiv - .toggle( this.indeterminate || value > this.min ) - .toggleClass( "ui-corner-right", value === this.options.max ) - .width( percentage.toFixed(0) + "%" ); + .toggle(this.indeterminate || value > this.min) + .toggleClass("ui-corner-right", value === this.options.max) + .width(percentage.toFixed(0) + "%"); - this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate ); + this.element.toggleClass("ui-progressbar-indeterminate", this.indeterminate); - if ( this.indeterminate ) { - this.element.removeAttr( "aria-valuenow" ); - if ( !this.overlayDiv ) { - this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv ); + if (this.indeterminate) { + this.element.removeAttr("aria-valuenow"); + if (!this.overlayDiv) { + this.overlayDiv = $("<div class='ui-progressbar-overlay'></div>").appendTo(this.valueDiv); } } else { this.element.attr({ "aria-valuemax": this.options.max, "aria-valuenow": value }); - if ( this.overlayDiv ) { + if (this.overlayDiv) { this.overlayDiv.remove(); this.overlayDiv = null; } } - if ( this.oldValue !== value ) { + if (this.oldValue !== value) { this.oldValue = value; - this._trigger( "change" ); + this._trigger("change"); } - if ( value === this.options.max ) { - this._trigger( "complete" ); + if (value === this.options.max) { + this._trigger("complete"); } } }); -})( jQuery ); +}); diff --git a/lib/web/jquery/ui-modules/resizable.js b/lib/web/jquery/ui-modules/resizable.js index 448df0c3d895..7758e30fee64 100644 --- a/lib/web/jquery/ui-modules/resizable.js +++ b/lib/web/jquery/ui-modules/resizable.js @@ -1,4 +1,20 @@ -(function( $, undefined ) { +/*! + * jQuery UI Resizable + * http://jqueryui.com + * + * Copyright 2014 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/resizable/ + */ + +define([ + 'jquery', + 'jquery-ui-modules/core', + 'jquery-ui-modules/mouse', + 'jquery-ui-modules/widget' +], function ($, undefined) { function num(v) { return parseInt(v, 10) || 0; @@ -35,7 +51,7 @@ start: null, stop: null }, - _create: function() { + _create: function () { var n, i, handle, axis, hname, that = this, @@ -51,7 +67,7 @@ }); //Wrap the element if it cannot hold child nodes - if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) { + if (this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) { //Create a wrapper element and set the wrapper to the new current internal element this.element.wrap( @@ -72,42 +88,60 @@ this.elementIsWrapper = true; //Move margins to the wrapper - this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") }); - this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0}); + this.element.css({ + marginLeft: this.originalElement.css("marginLeft"), + marginTop: this.originalElement.css("marginTop"), + marginRight: this.originalElement.css("marginRight"), + marginBottom: this.originalElement.css("marginBottom") + }); + this.originalElement.css({marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0}); //Prevent Safari textarea resize this.originalResizeStyle = this.originalElement.css("resize"); this.originalElement.css("resize", "none"); //Push the actual element to our proportionallyResize internal array - this._proportionallyResizeElements.push(this.originalElement.css({ position: "static", zoom: 1, display: "block" })); + this._proportionallyResizeElements.push(this.originalElement.css({ + position: "static", + zoom: 1, + display: "block" + })); // avoid IE jump (hard set the margin) - this.originalElement.css({ margin: this.originalElement.css("margin") }); + this.originalElement.css({margin: this.originalElement.css("margin")}); // fix handlers offset this._proportionallyResize(); } - 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" }); - if(this.handles.constructor === String) { + 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" + }); + if (this.handles.constructor === String) { - if ( this.handles === "all") { + 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++) { + for (i = 0; i < n.length; i++) { handle = $.trim(n[i]); - hname = "ui-resizable-"+handle; + hname = "ui-resizable-" + handle; axis = $("<div class='ui-resizable-handle " + hname + "'></div>"); // Apply zIndex to all handles - see #7960 - axis.css({ zIndex: o.zIndex }); + axis.css({zIndex: o.zIndex}); //TODO : What's going on here? if ("se" === handle) { @@ -115,21 +149,21 @@ } //Insert into internal handles object and append to element - this.handles[handle] = ".ui-resizable-"+handle; + this.handles[handle] = ".ui-resizable-" + handle; this.element.append(axis); } } - this._renderAxis = function(target) { + this._renderAxis = function (target) { var i, axis, padPos, padWrapper; target = target || this.element; - for(i in this.handles) { + for (i in this.handles) { - if(this.handles[i].constructor === String) { + if (this.handles[i].constructor === String) { this.handles[i] = $(this.handles[i], this.element).show(); } @@ -142,10 +176,10 @@ padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth(); //The padding type i have to apply... - padPos = [ "padding", + padPos = ["padding", /ne|nw|n/.test(i) ? "Top" : /se|sw|s/.test(i) ? "Bottom" : - /^e$/.test(i) ? "Right" : "Left" ].join(""); + /^e$/.test(i) ? "Right" : "Left"].join(""); target.css(padPos, padWrapper); @@ -154,7 +188,7 @@ } //TODO: What's that good for? There's not anything to be executed left - if(!$(this.handles[i]).length) { + if (!$(this.handles[i]).length) { continue; } } @@ -167,7 +201,7 @@ .disableSelection(); //Matching axis name - this._handles.mouseover(function() { + this._handles.mouseover(function () { if (!that.resizing) { if (this.className) { axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i); @@ -182,14 +216,14 @@ this._handles.hide(); $(this.element) .addClass("ui-resizable-autohide") - .mouseenter(function() { + .mouseenter(function () { if (o.disabled) { return; } $(this).removeClass("ui-resizable-autohide"); that._handles.show(); }) - .mouseleave(function(){ + .mouseleave(function () { if (o.disabled) { return; } @@ -205,12 +239,12 @@ }, - _destroy: function() { + _destroy: function () { this._mouseDestroy(); var wrapper, - _destroy = function(exp) { + _destroy = function (exp) { $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing") .removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove(); }; @@ -225,7 +259,7 @@ height: wrapper.outerHeight(), top: wrapper.css("top"), left: wrapper.css("left") - }).insertAfter( wrapper ); + }).insertAfter(wrapper); wrapper.remove(); } @@ -235,7 +269,7 @@ return this; }, - _mouseCapture: function(event) { + _mouseCapture: function (event) { var i, handle, capture = false; @@ -249,7 +283,7 @@ return !this.options.disabled && capture; }, - _mouseStart: function(event) { + _mouseStart: function (event) { var curleft, curtop, cursor, o = this.options, @@ -259,10 +293,10 @@ this.resizing = true; // bugfix for http://dev.jquery.com/ticket/1749 - if ( (/absolute/).test( el.css("position") ) ) { - el.css({ position: "absolute", top: el.css("top"), left: el.css("left") }); + if ((/absolute/).test(el.css("position"))) { + el.css({position: "absolute", top: el.css("top"), left: el.css("left")}); } else if (el.is(".ui-draggable")) { - el.css({ position: "absolute", top: iniPos.top, left: iniPos.left }); + el.css({position: "absolute", top: iniPos.top, left: iniPos.left}); } this._renderProxy(); @@ -277,12 +311,18 @@ //Store needed variables 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.originalPosition = { left: curleft, top: curtop }; - this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() }; - this.originalMousePosition = { left: event.pageX, top: event.pageY }; + 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.originalPosition = {left: curleft, top: curtop}; + this.sizeDiff = {width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height()}; + this.originalMousePosition = {left: event.pageX, top: event.pageY}; //Aspect Ratio this.aspectRatio = (typeof o.aspectRatio === "number") ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1); @@ -295,7 +335,7 @@ return true; }, - _mouseDrag: function(event) { + _mouseDrag: function (event) { //Increase performance, avoid regex var data, @@ -306,8 +346,8 @@ prevLeft = this.position.left, prevWidth = this.size.width, prevHeight = this.size.height, - dx = (event.pageX-smp.left)||0, - dy = (event.pageY-smp.top)||0, + dx = (event.pageX - smp.left) || 0, + dy = (event.pageY - smp.top) || 0, trigger = this._change[a]; if (!trigger) { @@ -349,32 +389,32 @@ } // Call the user callback if the element was resized - if ( ! $.isEmptyObject(props) ) { + if (!$.isEmptyObject(props)) { this._trigger("resize", event, this.ui()); } return false; }, - _mouseStop: function(event) { + _mouseStop: function (event) { this.resizing = false; var pr, ista, soffseth, soffsetw, s, left, top, o = this.options, that = this; - if(this._helper) { + if (this._helper) { pr = this._proportionallyResizeElements; ista = pr.length && (/textarea/i).test(pr[0].nodeName); soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height; soffsetw = ista ? 0 : that.sizeDiff.width; - s = { width: (that.helper.width() - soffsetw), height: (that.helper.height() - soffseth) }; + s = {width: (that.helper.width() - soffsetw), height: (that.helper.height() - soffseth)}; left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null; top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null; if (!o.animate) { - this.element.css($.extend(s, { top: top, left: left })); + this.element.css($.extend(s, {top: top, left: left})); } that.helper.height(that.size.height); @@ -399,7 +439,7 @@ }, - _updateVirtualBoundaries: function(forceAspectRatio) { + _updateVirtualBoundaries: function (forceAspectRatio) { var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b, o = this.options; @@ -410,7 +450,7 @@ maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity }; - if(this._aspectRatio || forceAspectRatio) { + if (this._aspectRatio || forceAspectRatio) { // We want to create an enclosing box whose aspect ration is the requested one // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension pMinWidth = b.minHeight * this.aspectRatio; @@ -418,23 +458,23 @@ pMaxWidth = b.maxHeight * this.aspectRatio; pMaxHeight = b.maxWidth / this.aspectRatio; - if(pMinWidth > b.minWidth) { + if (pMinWidth > b.minWidth) { b.minWidth = pMinWidth; } - if(pMinHeight > b.minHeight) { + if (pMinHeight > b.minHeight) { b.minHeight = pMinHeight; } - if(pMaxWidth < b.maxWidth) { + if (pMaxWidth < b.maxWidth) { b.maxWidth = pMaxWidth; } - if(pMaxHeight < b.maxHeight) { + if (pMaxHeight < b.maxHeight) { b.maxHeight = pMaxHeight; } } this._vBoundaries = b; }, - _updateCache: function(data) { + _updateCache: function (data) { this.offset = this.helper.offset(); if (isNumber(data.left)) { this.position.left = data.left; @@ -450,7 +490,7 @@ } }, - _updateRatio: function( data ) { + _updateRatio: function (data) { var cpos = this.position, csize = this.size, @@ -474,12 +514,14 @@ return data; }, - _respectSize: function( data ) { + _respectSize: function (data) { var o = this._vBoundaries, a = this.axis, - ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height), - isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height), + ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), + ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height), + isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), + isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height), dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height, cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a); @@ -519,7 +561,7 @@ return data; }, - _proportionallyResize: function() { + _proportionallyResize: function () { if (!this._proportionallyResizeElements.length) { return; @@ -528,7 +570,7 @@ var i, j, borders, paddings, prel, element = this.helper || this.element; - for ( i=0; i < this._proportionallyResizeElements.length; i++) { + for (i = 0; i < this._proportionallyResizeElements.length; i++) { prel = this._proportionallyResizeElements[i]; @@ -537,8 +579,8 @@ borders = [prel.css("borderTopWidth"), prel.css("borderRightWidth"), prel.css("borderBottomWidth"), prel.css("borderLeftWidth")]; paddings = [prel.css("paddingTop"), prel.css("paddingRight"), prel.css("paddingBottom"), prel.css("paddingLeft")]; - for ( j = 0; j < borders.length; j++ ) { - this.borderDif[ j ] = ( parseInt( borders[ j ], 10 ) || 0 ) + ( parseInt( paddings[ j ], 10 ) || 0 ); + for (j = 0; j < borders.length; j++) { + this.borderDif[j] = (parseInt(borders[j], 10) || 0) + (parseInt(paddings[j], 10) || 0); } } @@ -551,12 +593,12 @@ }, - _renderProxy: function() { + _renderProxy: function () { var el = this.element, o = this.options; this.elementOffset = el.offset(); - if(this._helper) { + if (this._helper) { this.helper = this.helper || $("<div style='overflow:hidden;'></div>"); @@ -564,8 +606,8 @@ width: this.element.outerWidth() - 1, height: this.element.outerHeight() - 1, position: "absolute", - left: this.elementOffset.left +"px", - top: this.elementOffset.top +"px", + left: this.elementOffset.left + "px", + top: this.elementOffset.top + "px", zIndex: ++o.zIndex //TODO: Don't modify option }); @@ -580,42 +622,42 @@ }, _change: { - e: function(event, dx) { - return { width: this.originalSize.width + dx }; + e: function (event, dx) { + return {width: this.originalSize.width + dx}; }, - w: function(event, dx) { + w: function (event, dx) { var cs = this.originalSize, sp = this.originalPosition; - return { left: sp.left + dx, width: cs.width - dx }; + return {left: sp.left + dx, width: cs.width - dx}; }, - n: function(event, dx, dy) { + n: function (event, dx, dy) { var cs = this.originalSize, sp = this.originalPosition; - return { top: sp.top + dy, height: cs.height - dy }; + return {top: sp.top + dy, height: cs.height - dy}; }, - s: function(event, dx, dy) { - return { height: this.originalSize.height + dy }; + s: function (event, dx, dy) { + return {height: this.originalSize.height + dy}; }, - se: function(event, dx, 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) { + 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) { + 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) { + 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) { + _propagate: function (n, event) { $.ui.plugin.call(this, n, [event, this.ui()]); (n !== "resize" && this._trigger(n, event, this.ui())); }, plugins: {}, - ui: function() { + ui: function () { return { originalElement: this.originalElement, element: this.element, @@ -635,22 +677,22 @@ $.ui.plugin.add("resizable", "animate", { - stop: function( event ) { + stop: function (event) { var that = $(this).data("ui-resizable"), o = that.options, pr = that._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName), soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height, soffsetw = ista ? 0 : that.sizeDiff.width, - style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) }, + style = {width: (that.size.width - soffsetw), height: (that.size.height - soffseth)}, left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null, top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null; that.element.animate( - $.extend(style, top && left ? { top: top, left: left } : {}), { + $.extend(style, top && left ? {top: top, left: left} : {}), { duration: o.animateDuration, easing: o.animateEasing, - step: function() { + step: function () { var data = { width: parseInt(that.element.css("width"), 10), @@ -660,7 +702,7 @@ }; if (pr && pr.length) { - $(pr[0]).css({ width: data.width, height: data.height }); + $(pr[0]).css({width: data.width, height: data.height}); } // propagating resize, and updating values for each animation step @@ -676,7 +718,7 @@ $.ui.plugin.add("resizable", "containment", { - start: function() { + start: function () { var element, p, co, ch, cw, width, height, that = $(this).data("ui-resizable"), o = that.options, @@ -691,8 +733,8 @@ that.containerElement = $(ce); if (/document/.test(oc) || oc === document) { - that.containerOffset = { left: 0, top: 0 }; - that.containerPosition = { left: 0, top: 0 }; + that.containerOffset = {left: 0, top: 0}; + that.containerPosition = {left: 0, top: 0}; that.parentData = { element: $(document), left: 0, top: 0, @@ -704,16 +746,18 @@ else { element = $(ce); p = []; - $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); }); + $(["Top", "Right", "Left", "Bottom"]).each(function (i, name) { + p[i] = 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]) }; + that.containerSize = {height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1])}; co = that.containerOffset; ch = that.containerSize.height; cw = that.containerSize.width; - width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ); + width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw); height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch); that.parentData = { @@ -722,13 +766,13 @@ } }, - resize: function( event ) { + resize: function (event) { var woset, hoset, isParent, isOffsetRelative, that = $(this).data("ui-resizable"), o = that.options, co = that.containerOffset, cp = that.position, pRatio = that._aspectRatio || event.shiftKey, - cop = { top:0, left:0 }, ce = that.containerElement; + cop = {top: 0, left: 0}, ce = that.containerElement; if (ce[0] !== document && (/static/).test(ce.css("position"))) { cop = co; @@ -750,17 +794,17 @@ that.position.top = that._helper ? co.top : 0; } - that.offset.left = that.parentData.left+that.position.left; - that.offset.top = that.parentData.top+that.position.top; + that.offset.left = that.parentData.left + that.position.left; + that.offset.top = that.parentData.top + that.position.top; - woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width ); - hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height ); + woset = Math.abs((that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width); + hoset = Math.abs((that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height); isParent = that.containerElement.get(0) === that.element.parent().get(0); isOffsetRelative = /relative|absolute/.test(that.containerElement.css("position")); - if ( isParent && isOffsetRelative ) { - woset -= Math.abs( that.parentData.left ); + if (isParent && isOffsetRelative) { + woset -= Math.abs(that.parentData.left); } if (woset + that.size.width >= that.parentData.width) { @@ -778,7 +822,7 @@ } }, - stop: function(){ + stop: function () { var that = $(this).data("ui-resizable"), o = that.options, co = that.containerOffset, @@ -790,11 +834,11 @@ 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 }); + $(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 }); + $(this).css({left: ho.left - cop.left - co.left, width: w, height: h}); } } @@ -806,7 +850,7 @@ var that = $(this).data("ui-resizable"), o = that.options, _store = function (exp) { - $(exp).each(function() { + $(exp).each(function () { var el = $(this); el.data("ui-resizable-alsoresize", { width: parseInt(el.width(), 10), height: parseInt(el.height(), 10), @@ -815,10 +859,16 @@ }); }; - if (typeof(o.alsoResize) === "object" && !o.alsoResize.parentNode) { - if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); } - else { $.each(o.alsoResize, function (exp) { _store(exp); }); } - }else{ + if (typeof (o.alsoResize) === "object" && !o.alsoResize.parentNode) { + if (o.alsoResize.length) { + o.alsoResize = o.alsoResize[0]; + _store(o.alsoResize); + } else { + $.each(o.alsoResize, function (exp) { + _store(exp); + }); + } + } else { _store(o.alsoResize); } }, @@ -834,12 +884,12 @@ }, _alsoResize = function (exp, c) { - $(exp).each(function() { + $(exp).each(function () { var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {}, css = c && c.length ? c : 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); + var sum = (start[prop] || 0) + (delta[prop] || 0); if (sum && sum >= 0) { style[prop] = sum || null; } @@ -849,9 +899,11 @@ }); }; - if (typeof(o.alsoResize) === "object" && !o.alsoResize.nodeType) { - $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); }); - }else{ + if (typeof (o.alsoResize) === "object" && !o.alsoResize.nodeType) { + $.each(o.alsoResize, function (exp, c) { + _alsoResize(exp, c); + }); + } else { _alsoResize(o.alsoResize); } }, @@ -863,13 +915,22 @@ $.ui.plugin.add("resizable", "ghost", { - start: function() { + start: function () { var that = $(this).data("ui-resizable"), o = that.options, 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 }) + .css({ + opacity: 0.25, + display: "block", + position: "relative", + height: cs.height, + width: cs.width, + margin: 0, + left: 0, + top: 0 + }) .addClass("ui-resizable-ghost") .addClass(typeof o.ghost === "string" ? o.ghost : ""); @@ -877,14 +938,14 @@ }, - resize: function(){ + resize: function () { var that = $(this).data("ui-resizable"); if (that.ghost) { - that.ghost.css({ position: "relative", height: that.size.height, width: that.size.width }); + that.ghost.css({position: "relative", height: that.size.height, width: that.size.width}); } }, - stop: function() { + stop: function () { var that = $(this).data("ui-resizable"); if (that.ghost && that.helper) { that.helper.get(0).removeChild(that.ghost.get(0)); @@ -895,7 +956,7 @@ $.ui.plugin.add("resizable", "grid", { - resize: function() { + resize: function () { var that = $(this).data("ui-resizable"), o = that.options, cs = that.size, @@ -903,8 +964,8 @@ 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), + 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, @@ -941,14 +1002,14 @@ that.size.height = newHeight; that.position.left = op.left - ox; } else { - if ( newHeight - gridY > 0 ) { + if (newHeight - gridY > 0) { that.size.height = newHeight; that.position.top = op.top - oy; } else { that.size.height = gridY; that.position.top = op.top + os.height - gridY; } - if ( newWidth - gridX > 0 ) { + if (newWidth - gridX > 0) { that.size.width = newWidth; that.position.left = op.left - ox; } else { @@ -960,4 +1021,4 @@ }); -})(jQuery); +}); diff --git a/lib/web/jquery/ui-modules/selectable.js b/lib/web/jquery/ui-modules/selectable.js index 3cf94e5bfae8..5ec60733b9b5 100644 --- a/lib/web/jquery/ui-modules/selectable.js +++ b/lib/web/jquery/ui-modules/selectable.js @@ -1,4 +1,20 @@ -(function( $, undefined ) { +/*! + * jQuery UI Selectable + * http://jqueryui.com + * + * Copyright 2014 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/selectable/ + */ + +define([ + 'jquery', + 'jquery-ui-modules/core', + 'jquery-ui-modules/mouse', + 'jquery-ui-modules/widget' +], function ($, undefined) { $.widget("ui.selectable", $.ui.mouse, { version: "1.10.4", @@ -17,7 +33,7 @@ unselected: null, unselecting: null }, - _create: function() { + _create: function () { var selectees, that = this; @@ -26,10 +42,10 @@ this.dragged = false; // cache selectee children based on filter - this.refresh = function() { + this.refresh = function () { selectees = $(that.options.filter, that.element[0]); selectees.addClass("ui-selectee"); - selectees.each(function() { + selectees.each(function () { var $this = $(this), pos = $this.offset(); $.data(this, "selectable-item", { @@ -55,7 +71,7 @@ this.helper = $("<div class='ui-selectable-helper'></div>"); }, - _destroy: function() { + _destroy: function () { this.selectees .removeClass("ui-selectee") .removeData("selectable-item"); @@ -64,7 +80,7 @@ this._mouseDestroy(); }, - _mouseStart: function(event) { + _mouseStart: function (event) { var that = this, options = this.options; @@ -91,7 +107,7 @@ this.refresh(); } - this.selectees.filter(".ui-selected").each(function() { + this.selectees.filter(".ui-selected").each(function () { var selectee = $.data(this, "selectable-item"); selectee.startselected = true; if (!event.metaKey && !event.ctrlKey) { @@ -106,7 +122,7 @@ } }); - $(event.target).parents().addBack().each(function() { + $(event.target).parents().addBack().each(function () { var doSelect, selectee = $.data(this, "selectable-item"); if (selectee) { @@ -133,7 +149,7 @@ }, - _mouseDrag: function(event) { + _mouseDrag: function (event) { this.dragged = true; @@ -149,11 +165,19 @@ 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}); + 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() { + this.selectees.each(function () { var selectee = $.data(this, "selectable-item"), hit = false; @@ -163,7 +187,7 @@ } if (options.tolerance === "touch") { - hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) ); + hit = (!(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1)); } else if (options.tolerance === "fit") { hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2); } @@ -226,12 +250,12 @@ return false; }, - _mouseStop: function(event) { + _mouseStop: function (event) { var that = this; this.dragged = false; - $(".ui-unselecting", this.element[0]).each(function() { + $(".ui-unselecting", this.element[0]).each(function () { var selectee = $.data(this, "selectable-item"); selectee.$element.removeClass("ui-unselecting"); selectee.unselecting = false; @@ -240,7 +264,7 @@ unselected: selectee.element }); }); - $(".ui-selecting", this.element[0]).each(function() { + $(".ui-selecting", this.element[0]).each(function () { var selectee = $.data(this, "selectable-item"); selectee.$element.removeClass("ui-selecting").addClass("ui-selected"); selectee.selecting = false; @@ -259,4 +283,4 @@ }); -})(jQuery); +}); diff --git a/lib/web/jquery/ui-modules/slider.js b/lib/web/jquery/ui-modules/slider.js index 34434e1a978a..963caf156d8f 100644 --- a/lib/web/jquery/ui-modules/slider.js +++ b/lib/web/jquery/ui-modules/slider.js @@ -1,10 +1,26 @@ -(function( $, undefined ) { +/*! + * jQuery UI Slider + * http://jqueryui.com + * + * Copyright 2014 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/slider/ + */ + +define([ + 'jquery', + 'jquery-ui-modules/core', + 'jquery-ui-modules/mouse', + 'jquery-ui-modules/widget' +], function ($, undefined) { // number of pages in a slider // (how many times can you page up/down to go through the whole range) var numPages = 5; - $.widget( "ui.slider", $.ui.mouse, { + $.widget("ui.slider", $.ui.mouse, { version: "1.10.4", widgetEventPrefix: "slide", @@ -26,7 +42,7 @@ stop: null }, - _create: function() { + _create: function () { this._keySliding = false; this._mouseSliding = false; this._animateOff = true; @@ -35,77 +51,77 @@ this._mouseInit(); this.element - .addClass( "ui-slider" + + .addClass("ui-slider" + " ui-slider-" + this.orientation + " ui-widget" + " ui-widget-content" + " ui-corner-all"); this._refresh(); - this._setOption( "disabled", this.options.disabled ); + this._setOption("disabled", this.options.disabled); this._animateOff = false; }, - _refresh: function() { + _refresh: function () { this._createRange(); this._createHandles(); this._setupEvents(); this._refreshValue(); }, - _createHandles: function() { + _createHandles: function () { var i, handleCount, options = this.options, - existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ), + existingHandles = this.element.find(".ui-slider-handle").addClass("ui-state-default ui-corner-all"), handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>", handles = []; - handleCount = ( options.values && options.values.length ) || 1; + handleCount = (options.values && options.values.length) || 1; - if ( existingHandles.length > handleCount ) { - existingHandles.slice( handleCount ).remove(); - existingHandles = existingHandles.slice( 0, handleCount ); + if (existingHandles.length > handleCount) { + existingHandles.slice(handleCount).remove(); + existingHandles = existingHandles.slice(0, handleCount); } - for ( i = existingHandles.length; i < handleCount; i++ ) { - handles.push( handle ); + for (i = existingHandles.length; i < handleCount; i++) { + handles.push(handle); } - this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) ); + this.handles = existingHandles.add($(handles.join("")).appendTo(this.element)); - this.handle = this.handles.eq( 0 ); + this.handle = this.handles.eq(0); - this.handles.each(function( i ) { - $( this ).data( "ui-slider-handle-index", i ); + this.handles.each(function (i) { + $(this).data("ui-slider-handle-index", i); }); }, - _createRange: function() { + _createRange: function () { var options = this.options, classes = ""; - 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 ( $.isArray( options.values ) ) { + 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 ($.isArray(options.values)) { options.values = options.values.slice(0); } } - if ( !this.range || !this.range.length ) { - this.range = $( "<div></div>" ) - .appendTo( this.element ); + if (!this.range || !this.range.length) { + this.range = $("<div></div>") + .appendTo(this.element); classes = "ui-slider-range" + // note: this isn't the most fittingly semantic framework class for this element, // but worked best visually with a variety of themes " ui-widget-header ui-corner-all"; } else { - this.range.removeClass( "ui-slider-range-min ui-slider-range-max" ) + this.range.removeClass("ui-slider-range-min ui-slider-range-max") // Handle range switching from true to min/max .css({ "left": "", @@ -113,47 +129,47 @@ }); } - this.range.addClass( classes + - ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) ); + this.range.addClass(classes + + ((options.range === "min" || options.range === "max") ? " ui-slider-range-" + options.range : "")); } else { - if ( this.range ) { + if (this.range) { this.range.remove(); } this.range = null; } }, - _setupEvents: function() { - var elements = this.handles.add( this.range ).filter( "a" ); - this._off( elements ); - this._on( elements, this._handleEvents ); - this._hoverable( elements ); - this._focusable( elements ); + _setupEvents: function () { + var elements = this.handles.add(this.range).filter("a"); + this._off(elements); + this._on(elements, this._handleEvents); + this._hoverable(elements); + this._focusable(elements); }, - _destroy: function() { + _destroy: function () { this.handles.remove(); - if ( this.range ) { + if (this.range) { this.range.remove(); } this.element - .removeClass( "ui-slider" + + .removeClass("ui-slider" + " ui-slider-horizontal" + " ui-slider-vertical" + " ui-widget" + " ui-widget-content" + - " ui-corner-all" ); + " ui-corner-all"); this._mouseDestroy(); }, - _mouseCapture: function( event ) { + _mouseCapture: function (event) { var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle, that = this, o = this.options; - if ( o.disabled ) { + if (o.disabled) { return false; } @@ -163,22 +179,22 @@ }; this.elementOffset = this.element.offset(); - position = { x: event.pageX, y: event.pageY }; - normValue = this._normValueFromMouse( position ); + 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 ))) { + 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 ); + closestHandle = $(this); index = i; } }); - allowed = this._start( event, index ); - if ( allowed === false ) { + allowed = this._start(event, index); + if (allowed === false) { return false; } this._mouseSliding = true; @@ -186,46 +202,46 @@ this._handleIndex = index; closestHandle - .addClass( "ui-state-active" ) + .addClass("ui-state-active") .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 ), + 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) + (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 ); + if (!this.handles.hasClass("ui-state-hover")) { + this._slide(event, index, normValue); } this._animateOff = true; return true; }, - _mouseStart: function() { + _mouseStart: function () { return true; }, - _mouseDrag: function( event ) { - var position = { x: event.pageX, y: event.pageY }, - normValue = this._normValueFromMouse( position ); + _mouseDrag: function (event) { + var position = {x: event.pageX, y: event.pageY}, + normValue = this._normValueFromMouse(position); - this._slide( event, this._handleIndex, normValue ); + this._slide(event, this._handleIndex, normValue); return false; }, - _mouseStop: function( event ) { - this.handles.removeClass( "ui-state-active" ); + _mouseStop: function (event) { + this.handles.removeClass("ui-state-active"); this._mouseSliding = false; - this._stop( event, this._handleIndex ); - this._change( event, this._handleIndex ); + this._stop(event, this._handleIndex); + this._change(event, this._handleIndex); this._handleIndex = null; this._clickOffset = null; @@ -234,162 +250,162 @@ return false; }, - _detectOrientation: function() { - this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal"; + _detectOrientation: function () { + this.orientation = (this.options.orientation === "vertical") ? "vertical" : "horizontal"; }, - _normValueFromMouse: function( position ) { + _normValueFromMouse: function (position) { var pixelTotal, pixelMouse, percentMouse, valueTotal, valueMouse; - if ( this.orientation === "horizontal" ) { + if (this.orientation === "horizontal") { pixelTotal = this.elementSize.width; - pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 ); + 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 ); + pixelMouse = position.y - this.elementOffset.top - (this._clickOffset ? this._clickOffset.top : 0); } - percentMouse = ( pixelMouse / pixelTotal ); - if ( percentMouse > 1 ) { + percentMouse = (pixelMouse / pixelTotal); + if (percentMouse > 1) { percentMouse = 1; } - if ( percentMouse < 0 ) { + if (percentMouse < 0) { percentMouse = 0; } - if ( this.orientation === "vertical" ) { + if (this.orientation === "vertical") { percentMouse = 1 - percentMouse; } valueTotal = this._valueMax() - this._valueMin(); valueMouse = this._valueMin() + percentMouse * valueTotal; - return this._trimAlignValue( valueMouse ); + return this._trimAlignValue(valueMouse); }, - _start: function( event, index ) { + _start: function (event, index) { var uiHash = { - handle: this.handles[ index ], + handle: this.handles[index], value: this.value() }; - if ( this.options.values && this.options.values.length ) { - uiHash.value = this.values( index ); + if (this.options.values && this.options.values.length) { + uiHash.value = this.values(index); uiHash.values = this.values(); } - return this._trigger( "start", event, uiHash ); + return this._trigger("start", event, uiHash); }, - _slide: function( event, index, newVal ) { + _slide: function (event, index, newVal) { var otherVal, newValues, allowed; - if ( this.options.values && this.options.values.length ) { - otherVal = this.values( index ? 0 : 1 ); + if (this.options.values && this.options.values.length) { + otherVal = this.values(index ? 0 : 1); - if ( ( this.options.values.length === 2 && this.options.range === true ) && - ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) ) + if ((this.options.values.length === 2 && this.options.range === true) && + ((index === 0 && newVal > otherVal) || (index === 1 && newVal < otherVal)) ) { newVal = otherVal; } - if ( newVal !== this.values( index ) ) { + if (newVal !== this.values(index)) { newValues = this.values(); - newValues[ index ] = newVal; + newValues[index] = newVal; // A slide can be canceled by returning false from the slide callback - allowed = this._trigger( "slide", event, { - handle: this.handles[ index ], + allowed = this._trigger("slide", event, { + handle: this.handles[index], value: newVal, values: newValues - } ); - otherVal = this.values( index ? 0 : 1 ); - if ( allowed !== false ) { - this.values( index, newVal ); + }); + otherVal = this.values(index ? 0 : 1); + if (allowed !== false) { + this.values(index, newVal); } } } else { - if ( newVal !== this.value() ) { + if (newVal !== this.value()) { // A slide can be canceled by returning false from the slide callback - allowed = this._trigger( "slide", event, { - handle: this.handles[ index ], + allowed = this._trigger("slide", event, { + handle: this.handles[index], value: newVal - } ); - if ( allowed !== false ) { - this.value( newVal ); + }); + if (allowed !== false) { + this.value(newVal); } } } }, - _stop: function( event, index ) { + _stop: function (event, index) { var uiHash = { - handle: this.handles[ index ], + handle: this.handles[index], value: this.value() }; - if ( this.options.values && this.options.values.length ) { - uiHash.value = this.values( index ); + if (this.options.values && this.options.values.length) { + uiHash.value = this.values(index); uiHash.values = this.values(); } - this._trigger( "stop", event, uiHash ); + this._trigger("stop", event, uiHash); }, - _change: function( event, index ) { - if ( !this._keySliding && !this._mouseSliding ) { + _change: function (event, index) { + if (!this._keySliding && !this._mouseSliding) { var uiHash = { - handle: this.handles[ index ], + handle: this.handles[index], value: this.value() }; - if ( this.options.values && this.options.values.length ) { - uiHash.value = this.values( index ); + if (this.options.values && this.options.values.length) { + uiHash.value = this.values(index); uiHash.values = this.values(); } //store the last changed value index for reference when handles overlap this._lastChangedValue = index; - this._trigger( "change", event, uiHash ); + this._trigger("change", event, uiHash); } }, - value: function( newValue ) { - if ( arguments.length ) { - this.options.value = this._trimAlignValue( newValue ); + value: function (newValue) { + if (arguments.length) { + this.options.value = this._trimAlignValue(newValue); this._refreshValue(); - this._change( null, 0 ); + this._change(null, 0); return; } return this._value(); }, - values: function( index, newValue ) { + values: function (index, newValue) { var vals, newValues, i; - if ( arguments.length > 1 ) { - this.options.values[ index ] = this._trimAlignValue( newValue ); + if (arguments.length > 1) { + this.options.values[index] = this._trimAlignValue(newValue); this._refreshValue(); - this._change( null, index ); + this._change(null, index); return; } - if ( arguments.length ) { - if ( $.isArray( arguments[ 0 ] ) ) { + if (arguments.length) { + if ($.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 ); + 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.options.values && this.options.values.length ) { - return this._values( index ); + if (this.options.values && this.options.values.length) { + return this._values(index); } else { return this.value(); } @@ -399,45 +415,45 @@ } }, - _setOption: function( key, value ) { + _setOption: function (key, value) { var i, valsLength = 0; - if ( key === "range" && this.options.range === true ) { - if ( value === "min" ) { - this.options.value = this._values( 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 ); + } else if (value === "max") { + this.options.value = this._values(this.options.values.length - 1); this.options.values = null; } } - if ( $.isArray( this.options.values ) ) { + if ($.isArray(this.options.values)) { valsLength = this.options.values.length; } - $.Widget.prototype._setOption.apply( this, arguments ); + $.Widget.prototype._setOption.apply(this, arguments); - switch ( key ) { + switch (key) { case "orientation": this._detectOrientation(); this.element - .removeClass( "ui-slider-horizontal ui-slider-vertical" ) - .addClass( "ui-slider-" + this.orientation ); + .removeClass("ui-slider-horizontal ui-slider-vertical") + .addClass("ui-slider-" + this.orientation); this._refreshValue(); break; case "value": this._animateOff = true; this._refreshValue(); - this._change( null, 0 ); + this._change(null, 0); this._animateOff = false; break; case "values": this._animateOff = true; this._refreshValue(); - for ( i = 0; i < valsLength; i += 1 ) { - this._change( null, i ); + for (i = 0; i < valsLength; i += 1) { + this._change(null, i); } this._animateOff = false; break; @@ -457,9 +473,9 @@ //internal value getter // _value() returns value trimmed by min and max, aligned by step - _value: function() { + _value: function () { var val = this.options.value; - val = this._trimAlignValue( val ); + val = this._trimAlignValue(val); return val; }, @@ -467,22 +483,22 @@ //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 ) { + _values: function (index) { var val, vals, i; - if ( arguments.length ) { - val = this.options.values[ index ]; - val = this._trimAlignValue( val ); + if (arguments.length) { + val = this.options.values[index]; + val = this._trimAlignValue(val); return val; - } else if ( this.options.values && this.options.values.length ) { + } else if (this.options.values && this.options.values.length) { // .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 ] ); + for (i = 0; i < vals.length; i += 1) { + vals[i] = this._trimAlignValue(vals[i]); } return vals; @@ -492,61 +508,67 @@ }, // returns the step-aligned value that val is closest to, between (inclusive) min and max - _trimAlignValue: function( val ) { - if ( val <= this._valueMin() ) { + _trimAlignValue: function (val) { + if (val <= this._valueMin()) { return this._valueMin(); } - if ( val >= this._valueMax() ) { + if (val >= this._valueMax()) { return this._valueMax(); } - var step = ( this.options.step > 0 ) ? this.options.step : 1, + 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 ); + 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) ); + return parseFloat(alignValue.toFixed(5)); }, - _valueMin: function() { + _valueMin: function () { return this.options.min; }, - _valueMax: function() { + _valueMax: function () { return this.options.max; }, - _refreshValue: function() { + _refreshValue: function () { var lastValPercent, valPercent, value, valueMin, valueMax, oRange = this.options.range, o = this.options, that = this, - animate = ( !this._animateOff ) ? o.animate : false, + animate = (!this._animateOff) ? o.animate : false, _set = {}; - if ( this.options.values && this.options.values.length ) { - 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 (this.options.values && this.options.values.length) { + 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 } ); + 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 === 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 } ); + if (i === 1) { + that.range[animate ? "animate" : "css"]({height: (valPercent - lastValPercent) + "%"}, { + queue: false, + duration: o.animate + }); } } } @@ -556,33 +578,39 @@ value = this.value(); valueMin = this._valueMin(); valueMax = this._valueMax(); - valPercent = ( valueMax !== valueMin ) ? - ( value - valueMin ) / ( valueMax - valueMin ) * 100 : + 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 ); + _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 === "min" && this.orientation === "horizontal") { + this.range.stop(1, 1)[animate ? "animate" : "css"]({width: valPercent + "%"}, o.animate); } - if ( oRange === "max" && this.orientation === "horizontal" ) { - this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); + if (oRange === "max" && this.orientation === "horizontal") { + this.range[animate ? "animate" : "css"]({width: (100 - valPercent) + "%"}, { + queue: false, + duration: o.animate + }); } - if ( oRange === "min" && this.orientation === "vertical" ) { - this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: 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[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); + if (oRange === "max" && this.orientation === "vertical") { + this.range[animate ? "animate" : "css"]({height: (100 - valPercent) + "%"}, { + queue: false, + duration: o.animate + }); } } }, _handleEvents: { - keydown: function( event ) { + keydown: function (event) { var allowed, curVal, newVal, step, - index = $( event.target ).data( "ui-slider-handle-index" ); + index = $(event.target).data("ui-slider-handle-index"); - switch ( event.keyCode ) { + switch (event.keyCode) { case $.ui.keyCode.HOME: case $.ui.keyCode.END: case $.ui.keyCode.PAGE_UP: @@ -592,11 +620,11 @@ case $.ui.keyCode.DOWN: case $.ui.keyCode.LEFT: event.preventDefault(); - if ( !this._keySliding ) { + if (!this._keySliding) { this._keySliding = true; - $( event.target ).addClass( "ui-state-active" ); - allowed = this._start( event, index ); - if ( allowed === false ) { + $(event.target).addClass("ui-state-active"); + allowed = this._start(event, index); + if (allowed === false) { return; } } @@ -604,13 +632,13 @@ } step = this.options.step; - if ( this.options.values && this.options.values.length ) { - curVal = newVal = this.values( index ); + if (this.options.values && this.options.values.length) { + curVal = newVal = this.values(index); } else { curVal = newVal = this.value(); } - switch ( event.keyCode ) { + switch (event.keyCode) { case $.ui.keyCode.HOME: newVal = this._valueMin(); break; @@ -618,44 +646,44 @@ newVal = this._valueMax(); break; case $.ui.keyCode.PAGE_UP: - newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) ); + newVal = this._trimAlignValue(curVal + ((this._valueMax() - this._valueMin()) / numPages)); break; case $.ui.keyCode.PAGE_DOWN: - newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) ); + newVal = this._trimAlignValue(curVal - ((this._valueMax() - this._valueMin()) / numPages)); break; case $.ui.keyCode.UP: case $.ui.keyCode.RIGHT: - if ( curVal === this._valueMax() ) { + if (curVal === this._valueMax()) { return; } - newVal = this._trimAlignValue( curVal + step ); + newVal = this._trimAlignValue(curVal + step); break; case $.ui.keyCode.DOWN: case $.ui.keyCode.LEFT: - if ( curVal === this._valueMin() ) { + if (curVal === this._valueMin()) { return; } - newVal = this._trimAlignValue( curVal - step ); + newVal = this._trimAlignValue(curVal - step); break; } - this._slide( event, index, newVal ); + this._slide(event, index, newVal); }, - click: function( event ) { + click: function (event) { event.preventDefault(); }, - keyup: function( event ) { - var index = $( event.target ).data( "ui-slider-handle-index" ); + keyup: function (event) { + var index = $(event.target).data("ui-slider-handle-index"); - if ( this._keySliding ) { + if (this._keySliding) { this._keySliding = false; - this._stop( event, index ); - this._change( event, index ); - $( event.target ).removeClass( "ui-state-active" ); + this._stop(event, index); + this._change(event, index); + $(event.target).removeClass("ui-state-active"); } } } }); -}(jQuery)); +}); diff --git a/lib/web/jquery/ui-modules/sortable.js b/lib/web/jquery/ui-modules/sortable.js index 53ceb3c99df6..026516597432 100644 --- a/lib/web/jquery/ui-modules/sortable.js +++ b/lib/web/jquery/ui-modules/sortable.js @@ -1,7 +1,23 @@ -(function( $, undefined ) { - - function isOverAxis( x, reference, size ) { - return ( x > reference ) && ( x < ( reference + size ) ); +/*! + * jQuery UI Sortable + * http://jqueryui.com + * + * Copyright 2014 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/sortable/ + */ + +define([ + 'jquery', + 'jquery-ui-modules/core', + 'jquery-ui-modules/mouse', + 'jquery-ui-modules/widget' +], function ($, undefined) { + + function isOverAxis(x, reference, size) { + return (x > reference) && (x < (reference + size)); } function isFloating(item) { @@ -50,7 +66,7 @@ stop: null, update: null }, - _create: function() { + _create: function () { var o = this.options; this.containerCache = {}; @@ -73,30 +89,30 @@ }, - _destroy: function() { + _destroy: function () { this.element .removeClass("ui-sortable ui-sortable-disabled"); this._mouseDestroy(); - for ( var i = this.items.length - 1; i >= 0; i-- ) { + for (var i = this.items.length - 1; i >= 0; i--) { this.items[i].item.removeData(this.widgetName + "-item"); } return this; }, - _setOption: function(key, value){ - if ( key === "disabled" ) { - this.options[ key ] = value; + _setOption: function (key, value) { + if (key === "disabled") { + this.options[key] = value; - this.widget().toggleClass( "ui-sortable-disabled", !!value ); + this.widget().toggleClass("ui-sortable-disabled", !!value); } else { // Don't call widget base _setOption for disable as it adds ui-state-disabled class $.Widget.prototype._setOption.apply(this, arguments); } }, - _mouseCapture: function(event, overrideHandle) { + _mouseCapture: function (event, overrideHandle) { var currentItem = null, validHandle = false, that = this; @@ -105,7 +121,7 @@ return false; } - if(this.options.disabled || this.options.type === "static") { + if (this.options.disabled || this.options.type === "static") { return false; } @@ -113,26 +129,26 @@ 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) { + $(event.target).parents().each(function () { + if ($.data(this, that.widgetName + "-item") === that) { currentItem = $(this); return false; } }); - if($.data(event.target, that.widgetName + "-item") === that) { + if ($.data(event.target, that.widgetName + "-item") === that) { currentItem = $(event.target); } - if(!currentItem) { + if (!currentItem) { return false; } - if(this.options.handle && !overrideHandle) { - $(this.options.handle, currentItem).find("*").addBack().each(function() { - if(this === event.target) { + if (this.options.handle && !overrideHandle) { + $(this.options.handle, currentItem).find("*").addBack().each(function () { + if (this === event.target) { validHandle = true; } }); - if(!validHandle) { + if (!validHandle) { return false; } } @@ -143,7 +159,7 @@ }, - _mouseStart: function(event, overrideHandle, noActivation) { + _mouseStart: function (event, overrideHandle, noActivation) { var i, body, o = this.options; @@ -200,10 +216,10 @@ (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); //Cache the former DOM position - this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] }; + 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]) { + if (this.helper[0] !== this.currentItem[0]) { this.currentItem.hide(); } @@ -211,28 +227,28 @@ this._createPlaceholder(); //Set a containment if given in the options - if(o.containment) { + if (o.containment) { this._setContainment(); } - if( o.cursor && o.cursor !== "auto" ) { // cursor option - body = this.document.find( "body" ); + 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.storedCursor = body.css("cursor"); + body.css("cursor", o.cursor); - this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body ); + this.storedStylesheet = $("<style>*{ cursor: " + o.cursor + " !important; }</style>").appendTo(body); } - if(o.opacity) { // opacity option + if (o.opacity) { // opacity option if (this.helper.css("opacity")) { this._storedOpacity = this.helper.css("opacity"); } this.helper.css("opacity", o.opacity); } - if(o.zIndex) { // zIndex option + if (o.zIndex) { // zIndex option if (this.helper.css("zIndex")) { this._storedZIndex = this.helper.css("zIndex"); } @@ -240,7 +256,7 @@ } //Prepare scrolling - if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") { + if (this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") { this.overflowOffset = this.scrollParent.offset(); } @@ -248,20 +264,20 @@ this._trigger("start", event, this._uiHash()); //Recache the helper size - if(!this._preserveHelperProportions) { + 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 ) ); + 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) { + if ($.ui.ddmanager) { $.ui.ddmanager.current = this; } @@ -277,7 +293,7 @@ }, - _mouseDrag: function(event) { + _mouseDrag: function (event) { var i, item, itemElement, intersection, o = this.options, scrolled = false; @@ -291,38 +307,38 @@ } //Do scrolling - if(this.options.scroll) { - if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") { + if (this.options.scroll) { + if (this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") { - if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) { + 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) { + } 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) { + 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) { + } else if (event.pageX - this.overflowOffset.left < o.scrollSensitivity) { this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed; } } else { - if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) { + if (event.pageY - $(document).scrollTop() < o.scrollSensitivity) { scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); - } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) { + } else if ($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) { scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); } - if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) { + if (event.pageX - $(document).scrollLeft() < o.scrollSensitivity) { scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); - } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) { + } else if ($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) { scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); } } - if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { + if (scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { $.ui.ddmanager.prepareOffsets(this, event); } } @@ -331,11 +347,11 @@ 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 !== "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"; + if (!this.options.axis || this.options.axis !== "x") { + this.helper[0].style.top = this.position.top + "px"; } //Rearrange @@ -386,7 +402,7 @@ this._contactContainers(event); //Interconnect with droppables - if($.ui.ddmanager) { + if ($.ui.ddmanager) { $.ui.ddmanager.drag(this, event); } @@ -398,9 +414,9 @@ }, - _mouseStop: function(event, noPropagation) { + _mouseStop: function (event, noPropagation) { - if(!event) { + if (!event) { return; } @@ -409,20 +425,20 @@ $.ui.ddmanager.drop(this, event); } - if(this.options.revert) { + if (this.options.revert) { var that = this, cur = this.placeholder.offset(), axis = this.options.axis, animation = {}; - if ( !axis || axis === "x" ) { + if (!axis || axis === "x") { animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft); } - if ( !axis || axis === "y" ) { + if (!axis || axis === "y") { animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop); } this.reverting = true; - $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() { + $(this.helper).animate(animation, parseInt(this.options.revert, 10) || 500, function () { that._clear(event); }); } else { @@ -433,22 +449,22 @@ }, - cancel: function() { + cancel: function () { - if(this.dragging) { + if (this.dragging) { - this._mouseUp({ target: null }); + this._mouseUp({target: null}); - if(this.options.helper === "original") { + if (this.options.helper === "original") { this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); } else { this.currentItem.show(); } //Post deactivating events to containers - for (var i = this.containers.length - 1; i >= 0; i--){ + 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) { + if (this.containers[i].containerCache.over) { this.containers[i]._trigger("out", null, this._uiHash(this)); this.containers[i].containerCache.over = 0; } @@ -458,10 +474,10 @@ 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) { + if (this.placeholder[0].parentNode) { this.placeholder[0].parentNode.removeChild(this.placeholder[0]); } - if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) { + if (this.options.helper !== "original" && this.helper && this.helper[0].parentNode) { this.helper.remove(); } @@ -472,7 +488,7 @@ _noFinalSort: null }); - if(this.domPosition.prev) { + if (this.domPosition.prev) { $(this.domPosition.prev).after(this.currentItem); } else { $(this.domPosition.parent).prepend(this.currentItem); @@ -483,20 +499,20 @@ }, - serialize: function(o) { + serialize: function (o) { var items = this._getItemsAsjQuery(o && o.connected), str = []; o = o || {}; - $(items).each(function() { + $(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])); + str.push((o.key || res[1] + "[]") + "=" + (o.key && o.expression ? res[1] : res[2])); } }); - if(!str.length && o.key) { + if (!str.length && o.key) { str.push(o.key + "="); } @@ -504,20 +520,22 @@ }, - toArray: function(o) { + 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") || ""); }); + items.each(function () { + ret.push($(o.item || this).attr(o.attribute || "id") || ""); + }); return ret; }, /* Be careful with the following core functions */ - _intersectsWith: function(item) { + _intersectsWith: function (item) { var x1 = this.positionAbs.left, x2 = x1 + this.helperProportions.width, @@ -529,11 +547,11 @@ 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 ), + 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" || + if (this.options.tolerance === "pointer" || this.options.forcePointerForContainers || (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"]) ) { @@ -543,12 +561,12 @@ 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 + y2 - (this.helperProportions.height / 2) < b); // Top Half } }, - _intersectsWithPointer: function(item) { + _intersectsWithPointer: function (item) { var isOverElementHeight = (this.options.axis === "x") || isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height), isOverElementWidth = (this.options.axis === "y") || isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width), @@ -561,15 +579,15 @@ } return this.floating ? - ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 ) - : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) ); + (((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1) + : (verticalDirection && (verticalDirection === "down" ? 2 : 1)); }, - _intersectsWithSides: function(item) { + _intersectsWithSides: function (item) { - var isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height), - isOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width), + var isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height / 2), item.height), + isOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width / 2), item.width), verticalDirection = this._getDragVerticalDirection(), horizontalDirection = this._getDragHorizontalDirection(); @@ -581,66 +599,70 @@ }, - _getDragVerticalDirection: function() { + _getDragVerticalDirection: function () { var delta = this.positionAbs.top - this.lastPositionAbs.top; return delta !== 0 && (delta > 0 ? "down" : "up"); }, - _getDragHorizontalDirection: function() { + _getDragHorizontalDirection: function () { var delta = this.positionAbs.left - this.lastPositionAbs.left; return delta !== 0 && (delta > 0 ? "right" : "left"); }, - refresh: function(event) { + refresh: function (event) { this._refreshItems(event); this.refreshPositions(); return this; }, - _connectWith: function() { + _connectWith: function () { var options = this.options; return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith; }, - _getItemsAsjQuery: function(connected) { + _getItemsAsjQuery: function (connected) { var i, j, cur, inst, items = [], queries = [], connectWith = this._connectWith(); - if(connectWith && connected) { - for (i = connectWith.length - 1; i >= 0; i--){ + if (connectWith && connected) { + for (i = connectWith.length - 1; i >= 0; i--) { cur = $(connectWith[i]); - for ( j = cur.length - 1; j >= 0; j--){ + for (j = cur.length - 1; j >= 0; j--) { inst = $.data(cur[j], this.widgetFullName); - if(inst && inst !== this && !inst.options.disabled) { + if (inst && inst !== this && !inst.options.disabled) { queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), inst]); } } } } - queries.push([$.isFunction(this.options.items) ? 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]); + queries.push([$.isFunction(this.options.items) ? 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 ); + items.push(this); } - for (i = queries.length - 1; i >= 0; i--){ - queries[i][0].each( addItems ); + + for (i = queries.length - 1; i >= 0; i--) { + queries[i][0].each(addItems); } return $(items); }, - _removeCurrentsFromItems: function() { + _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]) { + for (var j = 0; j < list.length; j++) { + if (list[j] === item.item[0]) { return false; } } @@ -649,23 +671,23 @@ }, - _refreshItems: function(event) { + _refreshItems: function (event) { this.items = []; this.containers = [this]; var i, j, cur, inst, targetData, _queries, item, queriesLength, items = this.items, - queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]], + queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, {item: this.currentItem}) : $(this.options.items, this.element), this]], connectWith = this._connectWith(); - if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down - for (i = connectWith.length - 1; i >= 0; i--){ + if (connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down + for (i = connectWith.length - 1; i >= 0; i--) { cur = $(connectWith[i]); - for (j = cur.length - 1; j >= 0; j--){ + for (j = cur.length - 1; j >= 0; j--) { inst = $.data(cur[j], this.widgetFullName); - if(inst && inst !== this && !inst.options.disabled) { - queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]); + if (inst && inst !== this && !inst.options.disabled) { + queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, {item: this.currentItem}) : $(inst.options.items, inst.element), inst]); this.containers.push(inst); } } @@ -676,7 +698,7 @@ targetData = queries[i][1]; _queries = queries[i][0]; - for (j=0, queriesLength = _queries.length; j < queriesLength; j++) { + for (j = 0, queriesLength = _queries.length; j < queriesLength; j++) { item = $(_queries[j]); item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager) @@ -692,20 +714,20 @@ }, - refreshPositions: function(fast) { + refreshPositions: function (fast) { //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) { + if (this.offsetParent && this.helper) { this.offset.parent = this._getParentOffset(); } var i, item, t, p; - for (i = this.items.length - 1; i >= 0; i--){ + 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(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) { + if (item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) { continue; } @@ -721,14 +743,14 @@ item.top = p.top; } - if(this.options.custom && this.options.custom.refreshContainers) { + if (this.options.custom && this.options.custom.refreshContainers) { this.options.custom.refreshContainers.call(this); } else { - for (i = this.containers.length - 1; i >= 0; i--){ + 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.width = this.containers[i].element.outerWidth(); this.containers[i].containerCache.height = this.containers[i].element.outerHeight(); } } @@ -736,48 +758,52 @@ return this; }, - _createPlaceholder: function(that) { + _createPlaceholder: function (that) { that = that || this; var className, o = that.options; - if(!o.placeholder || o.placeholder.constructor === String) { + if (!o.placeholder || o.placeholder.constructor === String) { className = o.placeholder; o.placeholder = { - element: function() { + element: function () { var nodeName = that.currentItem[0].nodeName.toLowerCase(), - element = $( "<" + nodeName + ">", that.document[0] ) - .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder") + element = $("<" + nodeName + ">", that.document[0]) + .addClass(className || that.currentItem[0].className + " ui-sortable-placeholder") .removeClass("ui-sortable-helper"); - if ( nodeName === "tr" ) { - that.currentItem.children().each(function() { - $( "<td> </td>", that.document[0] ) - .attr( "colspan", $( this ).attr( "colspan" ) || 1 ) - .appendTo( element ); + if (nodeName === "tr") { + that.currentItem.children().each(function () { + $("<td> </td>", that.document[0]) + .attr("colspan", $(this).attr("colspan") || 1) + .appendTo(element); }); - } else if ( nodeName === "img" ) { - element.attr( "src", that.currentItem.attr( "src" ) ); + } else if (nodeName === "img") { + element.attr("src", that.currentItem.attr("src")); } - if ( !className ) { - element.css( "visibility", "hidden" ); + if (!className) { + element.css("visibility", "hidden"); } return element; }, - update: function(container, p) { + 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) { + if (className && !o.forcePlaceholderSize) { return; } //If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item - if(!p.height()) { 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)); } + if (!p.height()) { + 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)); + } } }; } @@ -793,7 +819,7 @@ }, - _contactContainers: function(event) { + _contactContainers: function (event) { var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, base, cur, nearBottom, floating, innermostContainer = null, innermostIndex = null; @@ -802,14 +828,14 @@ 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])) { + if ($.contains(this.currentItem[0], this.containers[i].element[0])) { continue; } - if(this._intersectsWith(this.containers[i].containerCache)) { + 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])) { + if (innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) { continue; } @@ -818,7 +844,7 @@ } else { // container doesn't intersect. trigger "out" event if necessary - if(this.containers[i].containerCache.over) { + if (this.containers[i].containerCache.over) { this.containers[i]._trigger("out", event, this._uiHash(this)); this.containers[i].containerCache.over = 0; } @@ -827,12 +853,12 @@ } // if no intersecting containers found, return - if(!innermostContainer) { + if (!innermostContainer) { return; } // move the item into the container if it's not there already - if(this.containers.length === 1) { + 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; @@ -847,10 +873,10 @@ sizeProperty = floating ? "width" : "height"; base = this.positionAbs[posProperty] + this.offset.click[posProperty]; for (j = this.items.length - 1; j >= 0; j--) { - if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) { + if (!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) { continue; } - if(this.items[j].item[0] === this.currentItem[0]) { + if (this.items[j].item[0] === this.currentItem[0]) { continue; } if (floating && !isOverAxis(this.positionAbs.top + this.offset.click.top, this.items[j].top, this.items[j].height)) { @@ -858,23 +884,24 @@ } cur = this.items[j].item.offset()[posProperty]; nearBottom = false; - if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){ + if (Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)) { nearBottom = true; cur += this.items[j][sizeProperty]; } - if(Math.abs(cur - base) < dist) { - dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j]; - this.direction = nearBottom ? "up": "down"; + if (Math.abs(cur - base) < dist) { + dist = Math.abs(cur - base); + itemWithLeastDistance = this.items[j]; + this.direction = nearBottom ? "up" : "down"; } } //Check if dropOnEmpty is enabled - if(!itemWithLeastDistance && !this.options.dropOnEmpty) { + if (!itemWithLeastDistance && !this.options.dropOnEmpty) { return; } - if(this.currentContainer === this.containers[innermostIndex]) { + if (this.currentContainer === this.containers[innermostIndex]) { return; } @@ -893,24 +920,30 @@ }, - _createHelper: function(event) { + _createHelper: function (event) { var o = this.options, helper = $.isFunction(o.helper) ? $(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) { + if (!helper.parents("body").length) { $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[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] === 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) { + if (!helper[0].style.width || o.forceHelperSize) { helper.width(this.currentItem.width()); } - if(!helper[0].style.height || o.forceHelperSize) { + if (!helper[0].style.height || o.forceHelperSize) { helper.height(this.currentItem.height()); } @@ -918,7 +951,7 @@ }, - _adjustOffsetFromHelper: function(obj) { + _adjustOffsetFromHelper: function (obj) { if (typeof obj === "string") { obj = obj.split(" "); } @@ -939,7 +972,7 @@ } }, - _getParentOffset: function() { + _getParentOffset: function () { //Get the offsetParent and cache its position @@ -950,60 +983,60 @@ // 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])) { + 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(); } // This needs to be actually done for all browsers, since pageX/pageY includes this information // with an ugly IE fix - if( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) { - po = { top: 0, left: 0 }; + if (this.offsetParent[0] === document.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) + top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"), 10) || 0), + left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"), 10) || 0) }; }, - _getRelativeOffset: function() { + _getRelativeOffset: function () { - if(this.cssPosition === "relative") { + 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() + 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 {top: 0, left: 0}; } }, - _cacheMargins: function() { + _cacheMargins: function () { this.margins = { - left: (parseInt(this.currentItem.css("marginLeft"),10) || 0), - top: (parseInt(this.currentItem.css("marginTop"),10) || 0) + left: (parseInt(this.currentItem.css("marginLeft"), 10) || 0), + top: (parseInt(this.currentItem.css("marginTop"), 10) || 0) }; }, - _cacheHelperProportions: function() { + _cacheHelperProportions: function () { this.helperProportions = { width: this.helper.outerWidth(), height: this.helper.outerHeight() }; }, - _setContainment: function() { + _setContainment: function () { var ce, co, over, o = this.options; - if(o.containment === "parent") { + if (o.containment === "parent") { o.containment = this.helper[0].parentNode; } - if(o.containment === "document" || o.containment === "window") { + 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, @@ -1012,24 +1045,24 @@ ]; } - if(!(/^(document|window|parent)$/).test(o.containment)) { + 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 + 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) { + _convertPositionTo: function (d, pos) { - if(!pos) { + if (!pos) { pos = this.position; } var mod = d === "absolute" ? 1 : -1, @@ -1038,34 +1071,35 @@ return { top: ( - pos.top + // The absolute mouse position + pos.top + // The absolute mouse position this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border) - ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) + ((this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : (scrollIsRootNode ? 0 : scroll.scrollTop())) * mod) ), left: ( pos.left + // The absolute mouse position this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) - ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) + this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) + ((this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft()) * mod) ) }; }, - _generatePosition: function(event) { + _generatePosition: function (event) { var top, left, o = this.options, pageX = event.pageX, pageY = event.pageY, - scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); + scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.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] !== document && this.scrollParent[0] !== this.offsetParent[0])) { + if (this.cssPosition === "relative" && !(this.scrollParent[0] !== document && this.scrollParent[0] !== this.offsetParent[0])) { this.offset.relative = this._getRelativeOffset(); } @@ -1074,29 +1108,29 @@ * 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.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]) { + 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]) { + 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]) { + 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]) { + if (event.pageY - this.offset.click.top > this.containment[3]) { pageY = this.containment[3] + this.offset.click.top; } } - if(o.grid) { + 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; + 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; + 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; } } @@ -1105,22 +1139,22 @@ top: ( pageY - // The absolute mouse position this.offset.click.top - // Click offset (relative to the element) - this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent this.offset.parent.top + // The offsetParent's offset without borders (offset + border) - ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) + ((this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : (scrollIsRootNode ? 0 : scroll.scrollTop()))) ), left: ( pageX - // The absolute mouse position this.offset.click.left - // Click offset (relative to the element) - this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent this.offset.parent.left + // The offsetParent's offset without borders (offset + border) - ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) + ((this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft())) ) }; }, - _rearrange: function(event, i, a, hardRefresh) { + _rearrange: function (event, i, a, hardRefresh) { a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction === "down" ? i.item[0] : i.item[0].nextSibling)); @@ -1132,15 +1166,15 @@ this.counter = this.counter ? ++this.counter : 1; var counter = this.counter; - this._delay(function() { - if(counter === this.counter) { + this._delay(function () { + if (counter === this.counter) { this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove } }); }, - _clear: function(event, noPropagation) { + _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 @@ -1150,14 +1184,14 @@ // 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) { + 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") { + if (this.helper[0] === this.currentItem[0]) { + for (i in this._storedCSS) { + if (this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") { this._storedCSS[i] = ""; } } @@ -1166,57 +1200,72 @@ this.currentItem.show(); } - if(this.fromOutside && !noPropagation) { - delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); }); + 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) { - delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed + if ((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) { + delayedTriggers.push(function (event) { + this._trigger("update", event, this._uiHash()); + }); //Trigger update callback if the DOM position has changed } // 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)); + 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 ) ); + function delayEvent(type, instance, container) { + return function (event) { + container._trigger(type, event, instance._uiHash(instance)); }; } - for (i = this.containers.length - 1; i >= 0; i--){ + + for (i = this.containers.length - 1; i >= 0; i--) { if (!noPropagation) { - delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) ); + delayedTriggers.push(delayEvent("deactivate", this, this.containers[i])); } - if(this.containers[i].containerCache.over) { - delayedTriggers.push( delayEvent( "out", 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 ); + if (this.storedCursor) { + this.document.find("body").css("cursor", this.storedCursor); this.storedStylesheet.remove(); } - if(this._storedOpacity) { + if (this._storedOpacity) { this.helper.css("opacity", this._storedOpacity); } - if(this._storedZIndex) { + if (this._storedZIndex) { this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex); } this.dragging = false; - if(this.cancelHelperRemoval) { - if(!noPropagation) { + if (this.cancelHelperRemoval) { + if (!noPropagation) { this._trigger("beforeStop", event, this._uiHash()); - for (i=0; i < delayedTriggers.length; i++) { + for (i = 0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); } //Trigger all delayed events this._trigger("stop", event, this._uiHash()); @@ -1226,20 +1275,20 @@ return false; } - if(!noPropagation) { + 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.helper[0] !== this.currentItem[0]) { + if (this.helper[0] !== this.currentItem[0]) { this.helper.remove(); } this.helper = null; - if(!noPropagation) { - for (i=0; i < delayedTriggers.length; i++) { + if (!noPropagation) { + for (i = 0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); } //Trigger all delayed events this._trigger("stop", event, this._uiHash()); @@ -1250,13 +1299,13 @@ }, - _trigger: function() { + _trigger: function () { if ($.Widget.prototype._trigger.apply(this, arguments) === false) { this.cancel(); } }, - _uiHash: function(_inst) { + _uiHash: function (_inst) { var inst = _inst || this; return { helper: inst.helper, @@ -1271,4 +1320,4 @@ }); -})(jQuery); +}); diff --git a/lib/web/jquery/ui-modules/spinner.js b/lib/web/jquery/ui-modules/spinner.js index d087279828a1..cfa4cf1e3676 100644 --- a/lib/web/jquery/ui-modules/spinner.js +++ b/lib/web/jquery/ui-modules/spinner.js @@ -1,17 +1,33 @@ -(function( $ ) { - - function modifier( fn ) { - return function() { +/*! + * jQuery UI Spinner + * http://jqueryui.com + * + * Copyright 2014 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/spinner/ + */ + +define([ + 'jquery', + 'jquery-ui-modules/core', + 'jquery-ui-modules/widget', + 'jquery-ui-modules/button' +], function ($) { + + function modifier(fn) { + return function () { var previous = this.element.val(); - fn.apply( this, arguments ); + fn.apply(this, arguments); this._refresh(); - if ( previous !== this.element.val() ) { - this._trigger( "change" ); + if (previous !== this.element.val()) { + this._trigger("change"); } }; } - $.widget( "ui.spinner", { + $.widget("ui.spinner", { version: "1.10.4", defaultElement: "<input>", widgetEventPrefix: "spin", @@ -34,41 +50,41 @@ stop: null }, - _create: function() { + _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 ); + 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() !== "" ) { + if (this.value() !== "") { // Format the value, but don't constrain. - this._value( this.element.val(), true ); + this._value(this.element.val(), true); } this._draw(); - this._on( this._events ); + 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" ); + this._on(this.window, { + beforeunload: function () { + this.element.removeAttr("autocomplete"); } }); }, - _getCreateOptions: function() { + _getCreateOptions: function () { var options = {}, element = this.element; - $.each( [ "min", "max", "step" ], function( i, option ) { - var value = element.attr( option ); - if ( value !== undefined && value.length ) { - options[ option ] = value; + $.each(["min", "max", "step"], function (i, option) { + var value = element.attr(option); + if (value !== undefined && value.length) { + options[option] = value; } }); @@ -76,45 +92,45 @@ }, _events: { - keydown: function( event ) { - if ( this._start( event ) && this._keydown( event ) ) { + keydown: function (event) { + if (this._start(event) && this._keydown(event)) { event.preventDefault(); } }, keyup: "_stop", - focus: function() { + focus: function () { this.previous = this.element.val(); }, - blur: function( event ) { - if ( this.cancelBlur ) { + blur: function (event) { + if (this.cancelBlur) { delete this.cancelBlur; return; } this._stop(); this._refresh(); - if ( this.previous !== this.element.val() ) { - this._trigger( "change", event ); + if (this.previous !== this.element.val()) { + this._trigger("change", event); } }, - mousewheel: function( event, delta ) { - if ( !delta ) { + mousewheel: function (event, delta) { + if (!delta) { return; } - if ( !this.spinning && !this._start( event ) ) { + 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 ); + 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 ); + }, 100); event.preventDefault(); }, - "mousedown .ui-spinner-button": function( event ) { + "mousedown .ui-spinner-button": function (event) { var previous; // We never want the buttons to have focus; whenever the user is @@ -124,15 +140,16 @@ // then we need to set this.previous based on the value before spinning. previous = this.element[0] === this.document[0].activeElement ? this.previous : this.element.val(); + function checkFocus() { var isActive = this.element[0] === this.document[0].activeElement; - if ( !isActive ) { + if (!isActive) { this.element.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._delay(function () { this.previous = previous; }); } @@ -140,35 +157,35 @@ // ensure focus is on (or stays on) the text field event.preventDefault(); - checkFocus.call( this ); + 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() { + this._delay(function () { delete this.cancelBlur; - checkFocus.call( this ); + checkFocus.call(this); }); - if ( this._start( event ) === false ) { + if (this._start(event) === false) { return; } - this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); + this._repeat(null, $(event.currentTarget).hasClass("ui-spinner-up") ? 1 : -1, event); }, "mouseup .ui-spinner-button": "_stop", - "mouseenter .ui-spinner-button": function( event ) { + "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" ) ) { + if (!$(event.currentTarget).hasClass("ui-state-active")) { return; } - if ( this._start( event ) === false ) { + if (this._start(event) === false) { return false; } - this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); + 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 @@ -176,63 +193,63 @@ "mouseleave .ui-spinner-button": "_stop" }, - _draw: function() { + _draw: function () { var uiSpinner = this.uiSpinner = this.element - .addClass( "ui-spinner-input" ) - .attr( "autocomplete", "off" ) - .wrap( this._uiSpinnerHtml() ) + .addClass("ui-spinner-input") + .attr("autocomplete", "off") + .wrap(this._uiSpinnerHtml()) .parent() // add buttons - .append( this._buttonHtml() ); + .append(this._buttonHtml()); - this.element.attr( "role", "spinbutton" ); + this.element.attr("role", "spinbutton"); // button bindings - this.buttons = uiSpinner.find( ".ui-spinner-button" ) - .attr( "tabIndex", -1 ) + this.buttons = uiSpinner.find(".ui-spinner-button") + .attr("tabIndex", -1) .button() - .removeClass( "ui-corner-all" ); + .removeClass("ui-corner-all"); // IE 6 doesn't understand height: 50% for the buttons // unless the wrapper has an explicit height - if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) && - uiSpinner.height() > 0 ) { - uiSpinner.height( uiSpinner.height() ); + if (this.buttons.height() > Math.ceil(uiSpinner.height() * 0.5) && + uiSpinner.height() > 0) { + uiSpinner.height(uiSpinner.height()); } // disable spinner if element was already disabled - if ( this.options.disabled ) { + if (this.options.disabled) { this.disable(); } }, - _keydown: function( event ) { + _keydown: function (event) { var options = this.options, keyCode = $.ui.keyCode; - switch ( event.keyCode ) { + switch (event.keyCode) { case keyCode.UP: - this._repeat( null, 1, event ); + this._repeat(null, 1, event); return true; case keyCode.DOWN: - this._repeat( null, -1, event ); + this._repeat(null, -1, event); return true; case keyCode.PAGE_UP: - this._repeat( null, options.page, event ); + this._repeat(null, options.page, event); return true; case keyCode.PAGE_DOWN: - this._repeat( null, -options.page, event ); + this._repeat(null, -options.page, event); return true; } return false; }, - _uiSpinnerHtml: function() { + _uiSpinnerHtml: function () { return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>"; }, - _buttonHtml: function() { + _buttonHtml: function () { return "" + "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" + "<span class='ui-icon " + this.options.icons.up + "'>▲</span>" + @@ -242,71 +259,71 @@ "</a>"; }, - _start: function( event ) { - if ( !this.spinning && this._trigger( "start", event ) === false ) { + _start: function (event) { + if (!this.spinning && this._trigger("start", event) === false) { return false; } - if ( !this.counter ) { + if (!this.counter) { this.counter = 1; } this.spinning = true; return true; }, - _repeat: function( i, steps, event ) { + _repeat: function (i, steps, event) { i = i || 500; - clearTimeout( this.timer ); - this.timer = this._delay(function() { - this._repeat( 40, steps, event ); - }, i ); + clearTimeout(this.timer); + this.timer = this._delay(function () { + this._repeat(40, steps, event); + }, i); - this._spin( steps * this.options.step, event ); + this._spin(steps * this.options.step, event); }, - _spin: function( step, event ) { + _spin: function (step, event) { var value = this.value() || 0; - if ( !this.counter ) { + if (!this.counter) { this.counter = 1; } - value = this._adjustValue( value + step * this._increment( this.counter ) ); + value = this._adjustValue(value + step * this._increment(this.counter)); - if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) { - this._value( value ); + if (!this.spinning || this._trigger("spin", event, {value: value}) !== false) { + this._value(value); this.counter++; } }, - _increment: function( i ) { + _increment: function (i) { var incremental = this.options.incremental; - if ( incremental ) { - return $.isFunction( incremental ) ? - incremental( i ) : - Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 ); + if (incremental) { + return $.isFunction(incremental) ? + 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 ) ); + _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 ) { + _precisionOf: function (num) { var str = num.toString(), - decimal = str.indexOf( "." ); + decimal = str.indexOf("."); return decimal === -1 ? 0 : str.length - decimal - 1; }, - _adjustValue: function( value ) { + _adjustValue: function (value) { var base, aboveMin, options = this.options; @@ -320,163 +337,163 @@ value = base + aboveMin; // fix precision from bad JS floating point math - value = parseFloat( value.toFixed( this._precision() ) ); + value = parseFloat(value.toFixed(this._precision())); // clamp the value - if ( options.max !== null && value > options.max) { + if (options.max !== null && value > options.max) { return options.max; } - if ( options.min !== null && value < options.min ) { + if (options.min !== null && value < options.min) { return options.min; } return value; }, - _stop: function( event ) { - if ( !this.spinning ) { + _stop: function (event) { + if (!this.spinning) { return; } - clearTimeout( this.timer ); - clearTimeout( this.mousewheelTimer ); + clearTimeout(this.timer); + clearTimeout(this.mousewheelTimer); this.counter = 0; this.spinning = false; - this._trigger( "stop", event ); + this._trigger("stop", event); }, - _setOption: function( key, value ) { - if ( key === "culture" || key === "numberFormat" ) { - var prevValue = this._parse( this.element.val() ); - this.options[ key ] = value; - this.element.val( this._format( prevValue ) ); + _setOption: function (key, value) { + if (key === "culture" || key === "numberFormat") { + var 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 === "max" || key === "min" || key === "step") { + if (typeof value === "string") { + value = this._parse(value); } } - if ( key === "icons" ) { - this.buttons.first().find( ".ui-icon" ) - .removeClass( this.options.icons.up ) - .addClass( value.up ); - this.buttons.last().find( ".ui-icon" ) - .removeClass( this.options.icons.down ) - .addClass( value.down ); + if (key === "icons") { + this.buttons.first().find(".ui-icon") + .removeClass(this.options.icons.up) + .addClass(value.up); + this.buttons.last().find(".ui-icon") + .removeClass(this.options.icons.down) + .addClass(value.down); } - this._super( key, value ); + this._super(key, value); - if ( key === "disabled" ) { - if ( value ) { - this.element.prop( "disabled", true ); - this.buttons.button( "disable" ); + if (key === "disabled") { + if (value) { + this.element.prop("disabled", true); + this.buttons.button("disable"); } else { - this.element.prop( "disabled", false ); - this.buttons.button( "enable" ); + this.element.prop("disabled", false); + this.buttons.button("enable"); } } }, - _setOptions: modifier(function( options ) { - this._super( options ); - this._value( this.element.val() ); + _setOptions: modifier(function (options) { + this._super(options); + this._value(this.element.val()); }), - _parse: function( val ) { - if ( typeof val === "string" && val !== "" ) { + _parse: function (val) { + if (typeof val === "string" && val !== "") { val = window.Globalize && this.options.numberFormat ? - Globalize.parseFloat( val, 10, this.options.culture ) : +val; + Globalize.parseFloat(val, 10, this.options.culture) : +val; } - return val === "" || isNaN( val ) ? null : val; + return val === "" || isNaN(val) ? null : val; }, - _format: function( value ) { - if ( value === "" ) { + _format: function (value) { + if (value === "") { return ""; } return window.Globalize && this.options.numberFormat ? - Globalize.format( value, this.options.numberFormat, this.options.culture ) : + Globalize.format(value, this.options.numberFormat, this.options.culture) : value; }, - _refresh: function() { + _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() ) + "aria-valuenow": this._parse(this.element.val()) }); }, // update the value without triggering change - _value: function( value, allowAny ) { + _value: function (value, allowAny) { var parsed; - if ( value !== "" ) { - parsed = this._parse( value ); - if ( parsed !== null ) { - if ( !allowAny ) { - parsed = this._adjustValue( parsed ); + if (value !== "") { + parsed = this._parse(value); + if (parsed !== null) { + if (!allowAny) { + parsed = this._adjustValue(parsed); } - value = this._format( parsed ); + value = this._format(parsed); } } - this.element.val( value ); + this.element.val(value); this._refresh(); }, - _destroy: function() { + _destroy: function () { this.element - .removeClass( "ui-spinner-input" ) - .prop( "disabled", false ) - .removeAttr( "autocomplete" ) - .removeAttr( "role" ) - .removeAttr( "aria-valuemin" ) - .removeAttr( "aria-valuemax" ) - .removeAttr( "aria-valuenow" ); - this.uiSpinner.replaceWith( this.element ); + .removeClass("ui-spinner-input") + .prop("disabled", false) + .removeAttr("autocomplete") + .removeAttr("role") + .removeAttr("aria-valuemin") + .removeAttr("aria-valuemax") + .removeAttr("aria-valuenow"); + this.uiSpinner.replaceWith(this.element); }, - stepUp: modifier(function( steps ) { - this._stepUp( steps ); + stepUp: modifier(function (steps) { + this._stepUp(steps); }), - _stepUp: function( steps ) { - if ( this._start() ) { - this._spin( (steps || 1) * this.options.step ); + _stepUp: function (steps) { + if (this._start()) { + this._spin((steps || 1) * this.options.step); this._stop(); } }, - stepDown: modifier(function( steps ) { - this._stepDown( steps ); + stepDown: modifier(function (steps) { + this._stepDown(steps); }), - _stepDown: function( steps ) { - if ( this._start() ) { - this._spin( (steps || 1) * -this.options.step ); + _stepDown: function (steps) { + if (this._start()) { + this._spin((steps || 1) * -this.options.step); this._stop(); } }, - pageUp: modifier(function( pages ) { - this._stepUp( (pages || 1) * this.options.page ); + pageUp: modifier(function (pages) { + this._stepUp((pages || 1) * this.options.page); }), - pageDown: modifier(function( pages ) { - this._stepDown( (pages || 1) * this.options.page ); + pageDown: modifier(function (pages) { + this._stepDown((pages || 1) * this.options.page); }), - value: function( newVal ) { - if ( !arguments.length ) { - return this._parse( this.element.val() ); + value: function (newVal) { + if (!arguments.length) { + return this._parse(this.element.val()); } - modifier( this._value ).call( this, newVal ); + modifier(this._value).call(this, newVal); }, - widget: function() { + widget: function () { return this.uiSpinner; } }); -}( jQuery ) ); +}); diff --git a/lib/web/jquery/ui-modules/tabs.js b/lib/web/jquery/ui-modules/tabs.js index 37bbb8cf83d8..fe1dfbabee55 100644 --- a/lib/web/jquery/ui-modules/tabs.js +++ b/lib/web/jquery/ui-modules/tabs.js @@ -1,4 +1,23 @@ -(function( $, undefined ) { +/*! + * jQuery UI Tabs @VERSION + * http://jqueryui.com + * + * Copyright 2014 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/tabs/ + * + * Depends: + * jquery.ui.core.js + * jquery.ui.widget.js + */ + +define([ + 'jquery', + 'jquery-ui-modules/core', + 'jquery-ui-modules/widget' +], function ($, undefined) { var tabId = 0, rhash = /#.*$/; @@ -7,17 +26,17 @@ return ++tabId; } - function isLocal( anchor ) { + function isLocal(anchor) { // support: IE7 // IE7 doesn't normalize the href property when set via script (#9317) - anchor = anchor.cloneNode( false ); + anchor = anchor.cloneNode(false); return anchor.hash.length > 1 && - decodeURIComponent( anchor.href.replace( rhash, "" ) ) === - decodeURIComponent( location.href.replace( rhash, "" ) ); + decodeURIComponent(anchor.href.replace(rhash, "")) === + decodeURIComponent(location.href.replace(rhash, "")); } - $.widget( "ui.tabs", { + $.widget("ui.tabs", { version: "1.10.4", delay: 300, options: { @@ -35,18 +54,18 @@ load: null }, - _create: function() { + _create: function () { var that = this, options = this.options; this.running = false; this.element - .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" ) - .toggleClass( "ui-tabs-collapsible", options.collapsible ) + .addClass("ui-tabs ui-widget ui-widget-content ui-corner-all") + .toggleClass("ui-tabs-collapsible", options.collapsible) // Prevent users from focusing disabled tabs via click - .delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function( event ) { - if ( $( this ).is( ".ui-state-disabled" ) ) { + .delegate(".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function (event) { + if ($(this).is(".ui-state-disabled")) { event.preventDefault(); } }) @@ -56,8 +75,8 @@ // We don't have to worry about focusing the previously focused // element since clicking on a non-focusable element should focus // the body anyway. - .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() { - if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) { + .delegate(".ui-tabs-anchor", "focus" + this.eventNamespace, function () { + if ($(this).closest("li").is(".ui-state-disabled")) { this.blur(); } }); @@ -67,38 +86,38 @@ // Take disabling tabs via class attribute from HTML // into account and update option properly. - if ( $.isArray( options.disabled ) ) { - options.disabled = $.unique( options.disabled.concat( - $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) { - return that.tabs.index( li ); + if ($.isArray(options.disabled)) { + options.disabled = $.unique(options.disabled.concat( + $.map(this.tabs.filter(".ui-state-disabled"), function (li) { + return that.tabs.index(li); }) - ) ).sort(); + )).sort(); } // check for length avoids error when initializing empty list - if ( this.options.active !== false && this.anchors.length ) { - this.active = this._findActive( options.active ); + 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 ); + if (this.active.length) { + this.load(options.active); } }, - _initialActive: function() { + _initialActive: function () { var active = this.options.active, collapsible = this.options.collapsible, - locationHash = location.hash.substring( 1 ); + locationHash = location.hash.substring(1); - if ( active === null ) { + if (active === null) { // check the fragment identifier in the URL - if ( locationHash ) { - this.tabs.each(function( i, tab ) { - if ( $( tab ).attr( "aria-controls" ) === locationHash ) { + if (locationHash) { + this.tabs.each(function (i, tab) { + if ($(tab).attr("aria-controls") === locationHash) { active = i; return false; } @@ -106,49 +125,49 @@ } // check for a tab marked active via a class - if ( active === null ) { - active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) ); + if (active === null) { + active = this.tabs.index(this.tabs.filter(".ui-tabs-active")); } // no active tab, set to false - if ( active === null || active === -1 ) { + 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 ) { + 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 ) { + if (!collapsible && active === false && this.anchors.length) { active = 0; } return active; }, - _getCreateEventData: function() { + _getCreateEventData: function () { return { tab: this.active, - panel: !this.active.length ? $() : this._getPanelForTab( this.active ) + panel: !this.active.length ? $() : this._getPanelForTab(this.active) }; }, - _tabKeydown: function( event ) { - var focusedTab = $( this.document[0].activeElement ).closest( "li" ), - selectedIndex = this.tabs.index( focusedTab ), + _tabKeydown: function (event) { + var focusedTab = $(this.document[0].activeElement).closest("li"), + selectedIndex = this.tabs.index(focusedTab), goingForward = true; - if ( this._handlePageNav( event ) ) { + if (this._handlePageNav(event)) { return; } - switch ( event.keyCode ) { + switch (event.keyCode) { case $.ui.keyCode.RIGHT: case $.ui.keyCode.DOWN: selectedIndex++; @@ -167,15 +186,15 @@ case $.ui.keyCode.SPACE: // Activate only, no collapsing event.preventDefault(); - clearTimeout( this.activating ); - this._activate( selectedIndex ); + clearTimeout(this.activating); + this._activate(selectedIndex); return; case $.ui.keyCode.ENTER: // Toggle (cancel delayed activation, allow collapsing) event.preventDefault(); - clearTimeout( this.activating ); + clearTimeout(this.activating); // Determine if we should collapse or activate - this._activate( selectedIndex === this.options.active ? false : selectedIndex ); + this._activate(selectedIndex === this.options.active ? false : selectedIndex); return; default: return; @@ -183,158 +202,158 @@ // Focus the appropriate tab, based on which key was pressed event.preventDefault(); - clearTimeout( this.activating ); - selectedIndex = this._focusNextTab( selectedIndex, goingForward ); + clearTimeout(this.activating); + selectedIndex = this._focusNextTab(selectedIndex, goingForward); // Navigating with control key will prevent automatic activation - if ( !event.ctrlKey ) { + if (!event.ctrlKey) { // 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" ); + focusedTab.attr("aria-selected", "false"); + this.tabs.eq(selectedIndex).attr("aria-selected", "true"); - this.activating = this._delay(function() { - this.option( "active", selectedIndex ); - }, this.delay ); + this.activating = this._delay(function () { + this.option("active", selectedIndex); + }, this.delay); } }, - _panelKeydown: function( event ) { - if ( this._handlePageNav( event ) ) { + _panelKeydown: function (event) { + if (this._handlePageNav(event)) { return; } // Ctrl+up moves focus to the current tab - if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) { + if (event.ctrlKey && event.keyCode === $.ui.keyCode.UP) { event.preventDefault(); this.active.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 ) ); + _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 ) ); + if (event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN) { + this._activate(this._focusNextTab(this.options.active + 1, true)); return true; } }, - _findNextTab: function( index, goingForward ) { + _findNextTab: function (index, goingForward) { var lastTabIndex = this.tabs.length - 1; function constrain() { - if ( index > lastTabIndex ) { + if (index > lastTabIndex) { index = 0; } - if ( index < 0 ) { + if (index < 0) { index = lastTabIndex; } return index; } - while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) { + 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 ).focus(); + _focusNextTab: function (index, goingForward) { + index = this._findNextTab(index, goingForward); + this.tabs.eq(index).focus(); return index; }, - _setOption: function( key, value ) { - if ( key === "active" ) { + _setOption: function (key, value) { + if (key === "active") { // _activate() will handle invalid values and update this.options - this._activate( value ); + this._activate(value); return; } - if ( key === "disabled" ) { + if (key === "disabled") { // don't use the widget factory's disabled handling - this._setupDisabled( value ); + this._setupDisabled(value); return; } - this._super( key, value); + this._super(key, value); - if ( key === "collapsible" ) { - this.element.toggleClass( "ui-tabs-collapsible", value ); + if (key === "collapsible") { + this.element.toggleClass("ui-tabs-collapsible", value); // Setting collapsible: false while collapsed; open first panel - if ( !value && this.options.active === false ) { - this._activate( 0 ); + if (!value && this.options.active === false) { + this._activate(0); } } - if ( key === "event" ) { - this._setupEvents( value ); + if (key === "event") { + this._setupEvents(value); } - if ( key === "heightStyle" ) { - this._setupHeightStyle( value ); + if (key === "heightStyle") { + this._setupHeightStyle(value); } }, - _tabId: function( tab ) { - return tab.attr( "aria-controls" ) || "ui-tabs-" + getNextTabId(); + _tabId: function (tab) { + return tab.attr("aria-controls") || "ui-tabs-" + getNextTabId(); }, - _sanitizeSelector: function( hash ) { - return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : ""; + _sanitizeSelector: function (hash) { + return hash ? hash.replace(/[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&") : ""; }, - refresh: function() { + refresh: function () { var options = this.options, - lis = this.tablist.children( ":has(a[href])" ); + 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 ); + 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 ) { + 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 ] ) ) { + } else if (this.active.length && !$.contains(this.tablist[0], this.active[0])) { // all remaining tabs are disabled - if ( this.tabs.length === options.disabled.length ) { + 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 ) ); + 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 ); + options.active = this.tabs.index(this.active); } this._refresh(); }, - _refresh: function() { - this._setupDisabled( this.options.disabled ); - this._setupEvents( this.options.event ); - this._setupHeightStyle( this.options.heightStyle ); + _refresh: function () { + this._setupDisabled(this.options.disabled); + this._setupEvents(this.options.event); + this._setupHeightStyle(this.options.heightStyle); - this.tabs.not( this.active ).attr({ + this.tabs.not(this.active).attr({ "aria-selected": "false", tabIndex: -1 }); - this.panels.not( this._getPanelForTab( this.active ) ) + this.panels.not(this._getPanelForTab(this.active)) .hide() .attr({ "aria-expanded": "false", @@ -342,16 +361,16 @@ }); // Make sure one tab is in the tab order - if ( !this.active.length ) { - this.tabs.eq( 0 ).attr( "tabIndex", 0 ); + if (!this.active.length) { + this.tabs.eq(0).attr("tabIndex", 0); } else { this.active - .addClass( "ui-tabs-active ui-state-active" ) + .addClass("ui-tabs-active ui-state-active") .attr({ "aria-selected": "true", tabIndex: 0 }); - this._getPanelForTab( this.active ) + this._getPanelForTab(this.active) .show() .attr({ "aria-expanded": "true", @@ -360,24 +379,24 @@ } }, - _processTabs: function() { + _processTabs: function () { var that = this; this.tablist = this._getList() - .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) - .attr( "role", "tablist" ); + .addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all") + .attr("role", "tablist"); - this.tabs = this.tablist.find( "> li:has(a[href])" ) - .addClass( "ui-state-default ui-corner-top" ) + this.tabs = this.tablist.find("> li:has(a[href])") + .addClass("ui-state-default ui-corner-top") .attr({ role: "tab", tabIndex: -1 }); - this.anchors = this.tabs.map(function() { - return $( "a", this )[ 0 ]; + this.anchors = this.tabs.map(function () { + return $("a", this)[0]; }) - .addClass( "ui-tabs-anchor" ) + .addClass("ui-tabs-anchor") .attr({ role: "presentation", tabIndex: -1 @@ -385,148 +404,148 @@ this.panels = $(); - this.anchors.each(function( i, anchor ) { + this.anchors.each(function (i, anchor) { var selector, panel, panelId, - anchorId = $( anchor ).uniqueId().attr( "id" ), - tab = $( anchor ).closest( "li" ), - originalAriaControls = tab.attr( "aria-controls" ); + anchorId = $(anchor).uniqueId().attr("id"), + tab = $(anchor).closest("li"), + originalAriaControls = tab.attr("aria-controls"); // inline tab - if ( isLocal( anchor ) ) { + if (isLocal(anchor)) { selector = anchor.hash; - panel = that.element.find( that._sanitizeSelector( selector ) ); + panel = that.element.find(that._sanitizeSelector(selector)); // remote tab } else { - panelId = that._tabId( tab ); + panelId = that._tabId(tab); selector = "#" + panelId; - panel = that.element.find( selector ); - if ( !panel.length ) { - panel = that._createPanel( panelId ); - panel.insertAfter( that.panels[ i - 1 ] || that.tablist ); + 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" ); + panel.attr("aria-live", "polite"); } - if ( panel.length) { - that.panels = that.panels.add( panel ); + if (panel.length) { + that.panels = that.panels.add(panel); } - if ( originalAriaControls ) { - tab.data( "ui-tabs-aria-controls", originalAriaControls ); + if (originalAriaControls) { + tab.data("ui-tabs-aria-controls", originalAriaControls); } tab.attr({ - "aria-controls": selector.substring( 1 ), + "aria-controls": selector.substring(1), "aria-labelledby": anchorId }); - panel.attr( "aria-labelledby", anchorId ); + panel.attr("aria-labelledby", anchorId); }); this.panels - .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) - .attr( "role", "tabpanel" ); + .addClass("ui-tabs-panel ui-widget-content ui-corner-bottom") + .attr("role", "tabpanel"); }, // allow overriding how to find the list for rare usage scenarios (#7715) - _getList: function() { - return this.tablist || this.element.find( "ol,ul" ).eq( 0 ); + _getList: function () { + return this.tablist || this.element.find("ol,ul").eq(0); }, - _createPanel: function( id ) { - return $( "<div>" ) - .attr( "id", id ) - .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) - .data( "ui-tabs-destroy", true ); + _createPanel: function (id) { + return $("<div>") + .attr("id", id) + .addClass("ui-tabs-panel ui-widget-content ui-corner-bottom") + .data("ui-tabs-destroy", true); }, - _setupDisabled: function( disabled ) { - if ( $.isArray( disabled ) ) { - if ( !disabled.length ) { + _setupDisabled: function (disabled) { + if ($.isArray(disabled)) { + if (!disabled.length) { disabled = false; - } else if ( disabled.length === this.anchors.length ) { + } else if (disabled.length === this.anchors.length) { disabled = true; } } // disable tabs - for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) { - if ( disabled === true || $.inArray( i, disabled ) !== -1 ) { - $( li ) - .addClass( "ui-state-disabled" ) - .attr( "aria-disabled", "true" ); + for (var i = 0, li; (li = this.tabs[i]); i++) { + if (disabled === true || $.inArray(i, disabled) !== -1) { + $(li) + .addClass("ui-state-disabled") + .attr("aria-disabled", "true"); } else { - $( li ) - .removeClass( "ui-state-disabled" ) - .removeAttr( "aria-disabled" ); + $(li) + .removeClass("ui-state-disabled") + .removeAttr("aria-disabled"); } } this.options.disabled = disabled; }, - _setupEvents: function( event ) { + _setupEvents: function (event) { var events = { - click: function( event ) { + click: function (event) { event.preventDefault(); } }; - if ( event ) { - $.each( event.split(" "), function( index, eventName ) { - events[ eventName ] = "_eventHandler"; + if (event) { + $.each(event.split(" "), function (index, eventName) { + events[eventName] = "_eventHandler"; }); } - this._off( this.anchors.add( this.tabs ).add( this.panels ) ); - this._on( this.anchors, events ); - this._on( this.tabs, { keydown: "_tabKeydown" } ); - this._on( this.panels, { keydown: "_panelKeydown" } ); + this._off(this.anchors.add(this.tabs).add(this.panels)); + 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 ); + this._focusable(this.tabs); + this._hoverable(this.tabs); }, - _setupHeightStyle: function( heightStyle ) { + _setupHeightStyle: function (heightStyle) { var maxHeight, parent = this.element.parent(); - if ( heightStyle === "fill" ) { + 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" ); + this.element.siblings(":visible").each(function () { + var elem = $(this), + position = elem.css("position"); - if ( position === "absolute" || position === "fixed" ) { + if (position === "absolute" || position === "fixed") { return; } - maxHeight -= elem.outerHeight( true ); + maxHeight -= elem.outerHeight(true); }); - this.element.children().not( this.panels ).each(function() { - maxHeight -= $( this ).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() ) ); + this.panels.each(function () { + $(this).height(Math.max(0, maxHeight - + $(this).innerHeight() + $(this).height())); }) - .css( "overflow", "auto" ); - } else if ( heightStyle === "auto" ) { + .css("overflow", "auto"); + } else if (heightStyle === "auto") { maxHeight = 0; - this.panels.each(function() { - maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); - }).height( maxHeight ); + this.panels.each(function () { + maxHeight = Math.max(maxHeight, $(this).height("").height()); + }).height(maxHeight); } }, - _eventHandler: function( event ) { + _eventHandler: function (event) { var options = this.options, active = this.active, - anchor = $( event.currentTarget ), - tab = anchor.closest( "li" ), - clickedIsActive = tab[ 0 ] === active[ 0 ], + 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 ), + toShow = collapsing ? $() : this._getPanelForTab(tab), + toHide = !active.length ? $() : this._getPanelForTab(active), eventData = { oldTab: active, oldPanel: toHide, @@ -536,37 +555,37 @@ event.preventDefault(); - if ( tab.hasClass( "ui-state-disabled" ) || + if (tab.hasClass("ui-state-disabled") || // tab is already loading - tab.hasClass( "ui-tabs-loading" ) || + tab.hasClass("ui-tabs-loading") || // can't switch durning an animation this.running || // click on active header, but not collapsible - ( clickedIsActive && !options.collapsible ) || + (clickedIsActive && !options.collapsible) || // allow canceling activation - ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { + (this._trigger("beforeActivate", event, eventData) === false)) { return; } - options.active = collapsing ? false : this.tabs.index( tab ); + options.active = collapsing ? false : this.tabs.index(tab); this.active = clickedIsActive ? $() : tab; - if ( this.xhr ) { + if (this.xhr) { this.xhr.abort(); } - if ( !toHide.length && !toShow.length ) { - $.error( "jQuery UI Tabs: Mismatching fragment identifier." ); + if (!toHide.length && !toShow.length) { + $.error("jQuery UI Tabs: Mismatching fragment identifier."); } - if ( toShow.length ) { - this.load( this.tabs.index( tab ), event ); + if (toShow.length) { + this.load(this.tabs.index(tab), event); } - this._toggle( event, eventData ); + this._toggle(event, eventData); }, // handles show/hide for selecting tabs - _toggle: function( event, eventData ) { + _toggle: function (event, eventData) { var that = this, toShow = eventData.newPanel, toHide = eventData.oldPanel; @@ -575,14 +594,14 @@ function complete() { that.running = false; - that._trigger( "activate", event, eventData ); + that._trigger("activate", event, eventData); } function show() { - eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" ); + eventData.newTab.closest("li").addClass("ui-tabs-active ui-state-active"); - if ( toShow.length && that.options.show ) { - that._show( toShow, that.options.show, complete ); + if (toShow.length && that.options.show) { + that._show(toShow, that.options.show, complete); } else { toShow.show(); complete(); @@ -590,13 +609,13 @@ } // start out by hiding, then showing, then completing - if ( toHide.length && this.options.hide ) { - this._hide( toHide, this.options.hide, function() { - eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); + if (toHide.length && this.options.hide) { + this._hide(toHide, this.options.hide, function () { + eventData.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"); show(); }); } else { - eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); + eventData.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"); toHide.hide(); show(); } @@ -605,17 +624,17 @@ "aria-expanded": "false", "aria-hidden": "true" }); - eventData.oldTab.attr( "aria-selected", "false" ); + eventData.oldTab.attr("aria-selected", "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; + 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 ); + .attr("tabIndex", -1); } toShow.attr({ @@ -628,21 +647,21 @@ }); }, - _activate: function( index ) { + _activate: function (index) { var anchor, - active = this._findActive( index ); + active = this._findActive(index); // trying to activate the already active panel - if ( active[ 0 ] === this.active[ 0 ] ) { + if (active[0] === this.active[0]) { return; } // trying to collapse, simulate a click on the current active header - if ( !active.length ) { + if (!active.length) { active = this.active; } - anchor = active.find( ".ui-tabs-anchor" )[ 0 ]; + anchor = active.find(".ui-tabs-anchor")[0]; this._eventHandler({ target: anchor, currentTarget: anchor, @@ -650,186 +669,186 @@ }); }, - _findActive: function( index ) { - return index === false ? $() : this.tabs.eq( index ); + _findActive: function (index) { + return index === false ? $() : this.tabs.eq(index); }, - _getIndex: function( 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$='" + index + "']" ) ); + if (typeof index === "string") { + index = this.anchors.index(this.anchors.filter("[href$='" + index + "']")); } return index; }, - _destroy: function() { - if ( this.xhr ) { + _destroy: function () { + if (this.xhr) { this.xhr.abort(); } - this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" ); + this.element.removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible"); this.tablist - .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) - .removeAttr( "role" ); + .removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all") + .removeAttr("role"); this.anchors - .removeClass( "ui-tabs-anchor" ) - .removeAttr( "role" ) - .removeAttr( "tabIndex" ) + .removeClass("ui-tabs-anchor") + .removeAttr("role") + .removeAttr("tabIndex") .removeUniqueId(); - this.tabs.add( this.panels ).each(function() { - if ( $.data( this, "ui-tabs-destroy" ) ) { - $( this ).remove(); + this.tabs.add(this.panels).each(function () { + if ($.data(this, "ui-tabs-destroy")) { + $(this).remove(); } else { - $( this ) - .removeClass( "ui-state-default ui-state-active ui-state-disabled " + - "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" ) - .removeAttr( "tabIndex" ) - .removeAttr( "aria-live" ) - .removeAttr( "aria-busy" ) - .removeAttr( "aria-selected" ) - .removeAttr( "aria-labelledby" ) - .removeAttr( "aria-hidden" ) - .removeAttr( "aria-expanded" ) - .removeAttr( "role" ); + $(this) + .removeClass("ui-state-default ui-state-active ui-state-disabled " + + "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel") + .removeAttr("tabIndex") + .removeAttr("aria-live") + .removeAttr("aria-busy") + .removeAttr("aria-selected") + .removeAttr("aria-labelledby") + .removeAttr("aria-hidden") + .removeAttr("aria-expanded") + .removeAttr("role"); } }); - this.tabs.each(function() { - var li = $( this ), - prev = li.data( "ui-tabs-aria-controls" ); - if ( prev ) { + 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" ); + .attr("aria-controls", prev) + .removeData("ui-tabs-aria-controls"); } else { - li.removeAttr( "aria-controls" ); + li.removeAttr("aria-controls"); } }); this.panels.show(); - if ( this.options.heightStyle !== "content" ) { - this.panels.css( "height", "" ); + if (this.options.heightStyle !== "content") { + this.panels.css("height", ""); } }, - enable: function( index ) { + enable: function (index) { var disabled = this.options.disabled; - if ( disabled === false ) { + if (disabled === false) { return; } - if ( index === undefined ) { + if (index === undefined) { disabled = false; } else { - index = this._getIndex( index ); - if ( $.isArray( disabled ) ) { - disabled = $.map( disabled, function( num ) { + index = this._getIndex(index); + if ($.isArray(disabled)) { + disabled = $.map(disabled, function (num) { return num !== index ? num : null; }); } else { - disabled = $.map( this.tabs, function( li, num ) { + disabled = $.map(this.tabs, function (li, num) { return num !== index ? num : null; }); } } - this._setupDisabled( disabled ); + this._setupDisabled(disabled); }, - disable: function( index ) { + disable: function (index) { var disabled = this.options.disabled; - if ( disabled === true ) { + if (disabled === true) { return; } - if ( index === undefined ) { + if (index === undefined) { disabled = true; } else { - index = this._getIndex( index ); - if ( $.inArray( index, disabled ) !== -1 ) { + index = this._getIndex(index); + if ($.inArray(index, disabled) !== -1) { return; } - if ( $.isArray( disabled ) ) { - disabled = $.merge( [ index ], disabled ).sort(); + if ($.isArray(disabled)) { + disabled = $.merge([index], disabled).sort(); } else { - disabled = [ index ]; + disabled = [index]; } } - this._setupDisabled( disabled ); + this._setupDisabled(disabled); }, - load: function( index, event ) { - index = this._getIndex( index ); + 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 ), + tab = this.tabs.eq(index), + anchor = tab.find(".ui-tabs-anchor"), + panel = this._getPanelForTab(tab), eventData = { tab: tab, panel: panel }; // not remote - if ( isLocal( anchor[ 0 ] ) ) { + if (isLocal(anchor[0])) { return; } - this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) ); + 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" ) { - tab.addClass( "ui-tabs-loading" ); - panel.attr( "aria-busy", "true" ); + if (this.xhr && this.xhr.statusText !== "canceled") { + tab.addClass("ui-tabs-loading"); + panel.attr("aria-busy", "true"); this.xhr - .success(function( response ) { + .success(function (response) { // support: jQuery <1.8 // http://bugs.jquery.com/ticket/11778 - setTimeout(function() { - panel.html( response ); - that._trigger( "load", event, eventData ); - }, 1 ); + setTimeout(function () { + panel.html(response); + that._trigger("load", event, eventData); + }, 1); }) - .complete(function( jqXHR, status ) { + .complete(function (jqXHR, status) { // support: jQuery <1.8 // http://bugs.jquery.com/ticket/11778 - setTimeout(function() { - if ( status === "abort" ) { - that.panels.stop( false, true ); + setTimeout(function () { + if (status === "abort") { + that.panels.stop(false, true); } - tab.removeClass( "ui-tabs-loading" ); - panel.removeAttr( "aria-busy" ); + tab.removeClass("ui-tabs-loading"); + panel.removeAttr("aria-busy"); - if ( jqXHR === that.xhr ) { + if (jqXHR === that.xhr) { delete that.xhr; } - }, 1 ); + }, 1); }); } }, - _ajaxSettings: function( anchor, event, eventData ) { + _ajaxSettings: function (anchor, event, eventData) { var that = this; return { - url: anchor.attr( "href" ), - beforeSend: function( jqXHR, settings ) { - return that._trigger( "beforeLoad", event, - $.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) ); + url: anchor.attr("href"), + 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 ) ); + _getPanelForTab: function (tab) { + var id = $(tab).attr("aria-controls"); + return this.element.find(this._sanitizeSelector("#" + id)); } }); -})( jQuery ); +}); diff --git a/lib/web/jquery/ui-modules/timepicker.js b/lib/web/jquery/ui-modules/timepicker.js index 3b4bd59facad..eb5d038f0af4 100644 --- a/lib/web/jquery/ui-modules/timepicker.js +++ b/lib/web/jquery/ui-modules/timepicker.js @@ -5,11 +5,10 @@ if (typeof define === 'function' && define.amd) { define([ "jquery", - // @TODO: define correct deps - // Change 'jquery/ui' to core & datepicker - // "jquery-ui-modules/core", - // "jquery-ui-modules/datepicker" - "jquery/ui" + "jquery-ui-modules/core", + "jquery-ui-modules/widget", + "jquery-ui-modules/datepicker", + "jquery-ui-modules/slider" ], factory); } else { factory(jQuery); @@ -230,8 +229,8 @@ (tp_inst._defaults.altTimeFormat ? tp_inst._defaults.altTimeFormat : '')); // controlType is string - key to our this._controls - if (typeof(tp_inst._defaults.controlType) === 'string') { - if (tp_inst._defaults.controlType === 'slider' && typeof($.ui.slider) === 'undefined') { + if (typeof (tp_inst._defaults.controlType) === 'string') { + if (tp_inst._defaults.controlType === 'slider' && typeof ($.ui.slider) === 'undefined') { tp_inst._defaults.controlType = 'select'; } tp_inst.control = tp_inst._controls[tp_inst._defaults.controlType]; @@ -251,7 +250,10 @@ if (tzl > 0 && typeof timezoneList[0] !== 'object') { for (; tzi < tzl; tzi++) { tzv = timezoneList[tzi]; - timezoneList[tzi] = { value: tzv, label: $.timepicker.timezoneOffsetString(tzv, tp_inst.support.iso8601) }; + timezoneList[tzi] = { + value: tzv, + label: $.timepicker.timezoneOffsetString(tzv, tp_inst.support.iso8601) + }; } } tp_inst._defaults.timezoneList = timezoneList; @@ -398,8 +400,7 @@ var tmph = $.datepicker.formatTime(this.support.ampm ? 'hht' : 'HH', {hour: h}, o); html += '<td data-for="' + litem + '">' + tmph + '</td>'; } - } - else { + } else { for (var m = o[litem + 'Min']; m <= max[litem]; m += parseInt(o[litem + 'Grid'], 10)) { gridSize[litem]++; html += '<td data-for="' + litem + '">' + ((m < 10) ? '0' : '') + m + '</td>'; @@ -453,8 +454,7 @@ if (f === 'hour') { if (ap.indexOf('p') !== -1 && n < 12) { n += 12; - } - else { + } else { if (ap.indexOf('a') !== -1 && n === 12) { n = 0; } @@ -480,7 +480,7 @@ $.map(o.timezoneList, function (val, idx) { return $("<option />").val(typeof val === "object" ? val.value : val).text(typeof val === "object" ? val.label : val); })); - if (typeof(this.timezone) !== "undefined" && this.timezone !== null && this.timezone !== "") { + if (typeof (this.timezone) !== "undefined" && this.timezone !== null && this.timezone !== "") { var local_timezone = (new Date(this.inst.selectedYear, this.inst.selectedMonth, this.inst.selectedDay, 12)).getTimezoneOffset() * -1; if (local_timezone === this.timezone) { selectLocalTimezone(tp_inst); @@ -488,7 +488,7 @@ this.timezone_select.val(this.timezone); } } else { - if (typeof(this.hour) !== "undefined" && this.hour !== null && this.hour !== "") { + if (typeof (this.hour) !== "undefined" && this.hour !== null && this.hour !== "") { this.timezone_select.val(o.timezone); } else { selectLocalTimezone(tp_inst); @@ -535,7 +535,7 @@ oldMarginLeft = $g.css(rtl ? 'marginRight' : 'marginLeft').toString().replace('%', ''), newWidth = oldWidth - sliderAccessWidth, newMarginLeft = ((oldMarginLeft * newWidth) / oldWidth) + '%', - css = { width: newWidth, marginRight: 0, marginLeft: 0 }; + css = {width: newWidth, marginRight: 0, marginLeft: 0}; css[rtl ? 'marginRight' : 'marginLeft'] = newMarginLeft; $g.css(css); }); @@ -681,23 +681,35 @@ microsecMax = parseInt((this._defaults.microsecMax - ((this._defaults.microsecMax - this._defaults.microsecMin) % this._defaults.stepMicrosec)), 10); if (this.hour_slider) { - this.control.options(this, this.hour_slider, 'hour', { min: this._defaults.hourMin, max: hourMax }); + this.control.options(this, this.hour_slider, 'hour', {min: this._defaults.hourMin, max: hourMax}); this.control.value(this, this.hour_slider, 'hour', this.hour - (this.hour % this._defaults.stepHour)); } if (this.minute_slider) { - this.control.options(this, this.minute_slider, 'minute', { min: this._defaults.minuteMin, max: minMax }); + this.control.options(this, this.minute_slider, 'minute', { + min: this._defaults.minuteMin, + max: minMax + }); this.control.value(this, this.minute_slider, 'minute', this.minute - (this.minute % this._defaults.stepMinute)); } if (this.second_slider) { - this.control.options(this, this.second_slider, 'second', { min: this._defaults.secondMin, max: secMax }); + this.control.options(this, this.second_slider, 'second', { + min: this._defaults.secondMin, + max: secMax + }); this.control.value(this, this.second_slider, 'second', this.second - (this.second % this._defaults.stepSecond)); } if (this.millisec_slider) { - this.control.options(this, this.millisec_slider, 'millisec', { min: this._defaults.millisecMin, max: millisecMax }); + this.control.options(this, this.millisec_slider, 'millisec', { + min: this._defaults.millisecMin, + max: millisecMax + }); this.control.value(this, this.millisec_slider, 'millisec', this.millisec - (this.millisec % this._defaults.stepMillisec)); } if (this.microsec_slider) { - this.control.options(this, this.microsec_slider, 'microsec', { min: this._defaults.microsecMin, max: microsecMax }); + this.control.options(this, this.microsec_slider, 'microsec', { + min: this._defaults.microsecMin, + max: microsecMax + }); this.control.value(this, this.microsec_slider, 'microsec', this.microsec - (this.microsec % this._defaults.stepMicrosec)); } } @@ -722,22 +734,22 @@ pickerTimeFormat = o.pickerTimeFormat || o.timeFormat, pickerTimeSuffix = o.pickerTimeSuffix || o.timeSuffix; - if (typeof(hour) === 'object') { + if (typeof (hour) === 'object') { hour = false; } - if (typeof(minute) === 'object') { + if (typeof (minute) === 'object') { minute = false; } - if (typeof(second) === 'object') { + if (typeof (second) === 'object') { second = false; } - if (typeof(millisec) === 'object') { + if (typeof (millisec) === 'object') { millisec = false; } - if (typeof(microsec) === 'object') { + if (typeof (microsec) === 'object') { microsec = false; } - if (typeof(timezone) === 'object') { + if (typeof (timezone) === 'object') { timezone = false; } @@ -765,11 +777,11 @@ // If the update was done in the input field, the input field should not be updated. // If the update was done using the sliders, update the input field. var hasChanged = ( - hour !== parseInt(this.hour,10) || // sliders should all be numeric - minute !== parseInt(this.minute,10) || - second !== parseInt(this.second,10) || - millisec !== parseInt(this.millisec,10) || - microsec !== parseInt(this.microsec,10) || + hour !== parseInt(this.hour, 10) || // sliders should all be numeric + minute !== parseInt(this.minute, 10) || + second !== parseInt(this.second, 10) || + millisec !== parseInt(this.millisec, 10) || + microsec !== parseInt(this.microsec, 10) || (this.ampm.length > 0 && (hour < 12) !== ($.inArray(this.ampm.toUpperCase(), this.amNames) !== -1)) || (this.timezone !== null && timezone !== this.timezone.toString()) // could be numeric or "EST" format, so use toString() ); @@ -810,8 +822,7 @@ if (this.$timeObj) { if (pickerTimeFormat === o.timeFormat) { this.$timeObj.text(this.formattedTime + pickerTimeSuffix); - } - else { + } else { this.$timeObj.text($.datepicker.formatTime(pickerTimeFormat, this, o) + pickerTimeSuffix); } } @@ -840,7 +851,7 @@ */ _updateDateTime: function (dp_inst) { dp_inst = this.inst || dp_inst; - var dtTmp = (dp_inst.currentYear > 0? + var dtTmp = (dp_inst.currentYear > 0 ? new Date(dp_inst.currentYear, dp_inst.currentMonth, dp_inst.currentDay) : new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay)), dt = $.datepicker._daylightSavingAdjust(dtTmp), @@ -890,8 +901,7 @@ if (!this._defaults.timeOnly) { if (this._defaults.altFormat) { altFormattedDateTime = $.datepicker.formatDate(this._defaults.altFormat, (dt === null ? new Date() : dt), formatCfg); - } - else { + } else { altFormattedDateTime = this.formattedDate; } @@ -902,8 +912,7 @@ if (this._defaults.altTimeFormat) { altFormattedDateTime += $.datepicker.formatTime(this._defaults.altTimeFormat, this, this._defaults) + altTimeSuffix; - } - else { + } else { altFormattedDateTime += this.formattedTime + altTimeSuffix; } this.$altInput.val(altFormattedDateTime); @@ -957,7 +966,7 @@ }, options: function (tp_inst, obj, unit, opts, val) { if (tp_inst._defaults.isRTL) { - if (typeof(opts) === 'string') { + if (typeof (opts) === 'string') { if (opts === 'min' || opts === 'max') { if (val !== undefined) { return obj.slider(opts, val * -1); @@ -977,7 +986,7 @@ } return obj.slider(opts); } - if (typeof(opts) === 'string' && val !== undefined) { + if (typeof (opts) === 'string' && val !== undefined) { return obj.slider(opts, val); } return obj.slider(opts); @@ -1005,9 +1014,11 @@ sel += '<option value="' + i + '"' + (i === val ? ' selected' : '') + '>'; if (unit === 'hour') { sel += $.datepicker.formatTime($.trim(format.replace(/[^ht ]/ig, '')), {hour: i}, tp_inst._defaults); + } else if (unit === 'millisec' || unit === 'microsec' || i >= 10) { + sel += i; + } else { + sel += '0' + i.toString(); } - else if (unit === 'millisec' || unit === 'microsec' || i >= 10) { sel += i; } - else {sel += '0' + i.toString(); } sel += '</option>'; } sel += '</select>'; @@ -1024,13 +1035,14 @@ options: function (tp_inst, obj, unit, opts, val) { var o = {}, $t = obj.children('select'); - if (typeof(opts) === 'string') { + if (typeof (opts) === 'string') { if (val === undefined) { return $t.data(opts); } o[opts] = val; + } else { + o = opts; } - else { o = opts; } return tp_inst.control.create(tp_inst, obj, $t.data('unit'), $t.val(), o.min || $t.data('min'), o.max || $t.data('max'), o.step || $t.data('step')); }, value: function (tp_inst, obj, unit, val) { @@ -1071,7 +1083,7 @@ o = o || {}; var tmp_args = arguments; - if (typeof(o) === 'string') { + if (typeof (o) === 'string') { if (o === 'getDate') { return $.fn.datepicker.apply($(this[0]), tmp_args); } else { @@ -1170,7 +1182,9 @@ case 't': return getPatternAmpm(o.amNames, o.pmNames); default: // literal escaped in quotes - return '(' + match.replace(/\'/g, "").replace(/(\.|\$|\^|\\|\/|\(|\)|\[|\]|\?|\+|\*)/g, function (m) { return "\\" + m; }) + ')?'; + return '(' + match.replace(/\'/g, "").replace(/(\.|\$|\^|\\|\/|\(|\)|\[|\]|\?|\+|\*)/g, function (m) { + return "\\" + m; + }) + ')?'; } }) .replace(/\s/g, '\\s?') + @@ -1256,12 +1270,10 @@ microsec: d.getMicroseconds(), timezone: d.getTimezoneOffset() * -1 }; - } - catch (err) { + } catch (err) { try { return strictParse(f, s, o); - } - catch (err2) { + } catch (err2) { $.timepicker.log("Unable to parse \ntimeString: " + s + "\ntimeFormat: " + f); } } @@ -1381,7 +1393,7 @@ return; } - if (typeof(inst.stay_open) !== 'boolean' || inst.stay_open === false) { + if (typeof (inst.stay_open) !== 'boolean' || inst.stay_open === false) { this._base_updateDatepicker(inst); @@ -1449,15 +1461,13 @@ if (!tp_inst._defaults.timeOnly && !tp_inst._defaults.altFieldTimeOnly && date !== null) { if (tp_inst._defaults.altFormat) { altFormattedDateTime = $.datepicker.formatDate(tp_inst._defaults.altFormat, date, formatCfg) + altSeparator + altFormattedDateTime; - } - else { + } else { altFormattedDateTime = tp_inst.formattedDate + altSeparator + altFormattedDateTime; } } $(altField).val(altFormattedDateTime); } - } - else { + } else { $.datepicker._base_updateAlternate(inst); } }; @@ -1598,7 +1608,7 @@ return; } - if (typeof(date) === 'string') { + if (typeof (date) === 'string') { date = new Date(date); if (!date.getTime()) { $.timepicker.log("Error creating Date object from string."); @@ -1759,11 +1769,15 @@ for (prop in fns) { if (fns.hasOwnProperty(prop)) { overrides[prop] = fns[prop]; - if (!name_clone) { name_clone = $.extend({}, name); } + if (!name_clone) { + name_clone = $.extend({}, name); + } delete name_clone[prop]; } } - if (name_clone && isEmptyObject(name_clone)) { return; } + if (name_clone && isEmptyObject(name_clone)) { + return; + } if (min) { //if min was set if (min === 0) { min = new Date(); @@ -2061,11 +2075,9 @@ if (options.minInterval > 0 && minDate > enddt) { // minInterval check endTime[method]('setDate', minDate); - } - else if (options.maxInterval > 0 && maxDate < enddt) { // max interval check + } else if (options.maxInterval > 0 && maxDate < enddt) { // max interval check endTime[method]('setDate', maxDate); - } - else if (startdt > enddt) { + } else if (startdt > enddt) { other[method]('setDate', changeddt); } } @@ -2142,7 +2154,9 @@ */ if (!Date.prototype.getMicroseconds) { Date.prototype.microseconds = 0; - Date.prototype.getMicroseconds = function () { return this.microseconds; }; + Date.prototype.getMicroseconds = function () { + return this.microseconds; + }; Date.prototype.setMicroseconds = function (m) { this.setMilliseconds(this.getMilliseconds() + Math.floor(m / 1000)); this.microseconds = m % 1000; diff --git a/lib/web/jquery/ui-modules/tooltip.js b/lib/web/jquery/ui-modules/tooltip.js index 2d0431711dcd..17aaa49cdbde 100644 --- a/lib/web/jquery/ui-modules/tooltip.js +++ b/lib/web/jquery/ui-modules/tooltip.js @@ -1,41 +1,57 @@ -(function( $ ) { +/*! + * jQuery UI Tooltip + * http://jqueryui.com + * + * Copyright 2014 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/tooltip/ + */ + +define([ + 'jquery', + 'jquery-ui-modules/core', + 'jquery-ui-modules/widget', + 'jquery-ui-modules/position' +], function ($) { var increments = 0; - function addDescribedBy( elem, id ) { - var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ); - describedby.push( id ); + function addDescribedBy(elem, id) { + var describedby = (elem.attr("aria-describedby") || "").split(/\s+/); + describedby.push(id); elem - .data( "ui-tooltip-id", id ) - .attr( "aria-describedby", $.trim( describedby.join( " " ) ) ); + .data("ui-tooltip-id", id) + .attr("aria-describedby", $.trim(describedby.join(" "))); } - function removeDescribedBy( 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 ); + function removeDescribedBy(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 = $.trim( describedby.join( " " ) ); - if ( describedby ) { - elem.attr( "aria-describedby", describedby ); + elem.removeData("ui-tooltip-id"); + describedby = $.trim(describedby.join(" ")); + if (describedby) { + elem.attr("aria-describedby", describedby); } else { - elem.removeAttr( "aria-describedby" ); + elem.removeAttr("aria-describedby"); } } - $.widget( "ui.tooltip", { + $.widget("ui.tooltip", { version: "1.10.4", options: { - content: function() { + content: function () { // support: IE<9, Opera in jQuery <1.7 // .text() can't accept undefined, so coerce to a string - var title = $( this ).attr( "title" ) || ""; + var title = $(this).attr("title") || ""; // Escape title, since we're going from an attribute to raw HTML - return $( "<a>" ).text( title ).html(); + return $("<a>").text(title).html(); }, hide: true, // Disabled elements have inconsistent behavior across browsers (#8661) @@ -54,7 +70,7 @@ open: null }, - _create: function() { + _create: function () { this._on({ mouseover: "open", focusin: "open" @@ -65,150 +81,150 @@ // IDs of parent tooltips where we removed the title attribute this.parents = {}; - if ( this.options.disabled ) { + if (this.options.disabled) { this._disable(); } }, - _setOption: function( key, value ) { + _setOption: function (key, value) { var that = this; - if ( key === "disabled" ) { - this[ value ? "_disable" : "_enable" ](); - this.options[ key ] = value; + if (key === "disabled") { + this[value ? "_disable" : "_enable"](); + this.options[key] = value; // disable element style changes return; } - this._super( key, value ); + this._super(key, value); - if ( key === "content" ) { - $.each( this.tooltips, function( id, element ) { - that._updateContent( element ); + if (key === "content") { + $.each(this.tooltips, function (id, element) { + that._updateContent(element); }); } }, - _disable: function() { + _disable: function () { var that = this; // close open tooltips - $.each( this.tooltips, function( id, element ) { - var event = $.Event( "blur" ); + $.each(this.tooltips, function (id, element) { + var event = $.Event("blur"); event.target = event.currentTarget = element[0]; - that.close( event, true ); + that.close(event, true); }); // remove title attributes to prevent native tooltips - this.element.find( this.options.items ).addBack().each(function() { - var element = $( this ); - if ( element.is( "[title]" ) ) { + this.element.find(this.options.items).addBack().each(function () { + var element = $(this); + if (element.is("[title]")) { element - .data( "ui-tooltip-title", element.attr( "title" ) ) - .attr( "title", "" ); + .data("ui-tooltip-title", element.attr("title")) + .attr("title", ""); } }); }, - _enable: function() { + _enable: function () { // restore title attributes - this.element.find( this.options.items ).addBack().each(function() { - var element = $( this ); - if ( element.data( "ui-tooltip-title" ) ) { - element.attr( "title", element.data( "ui-tooltip-title" ) ); + this.element.find(this.options.items).addBack().each(function () { + var element = $(this); + if (element.data("ui-tooltip-title")) { + element.attr("title", element.data("ui-tooltip-title")); } }); }, - open: function( event ) { + open: function (event) { var that = this, - target = $( event ? event.target : this.element ) + 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 ); + .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" ) ) { + if (!target.length || target.data("ui-tooltip-id")) { return; } - if ( target.attr( "title" ) ) { - target.data( "ui-tooltip-title", target.attr( "title" ) ); + if (target.attr("title")) { + target.data("ui-tooltip-title", target.attr("title")); } - target.data( "ui-tooltip-open", true ); + 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 ), + if (event && event.type === "mouseover") { + target.parents().each(function () { + var parent = $(this), blurEvent; - if ( parent.data( "ui-tooltip-open" ) ) { - blurEvent = $.Event( "blur" ); + if (parent.data("ui-tooltip-open")) { + blurEvent = $.Event("blur"); blurEvent.target = blurEvent.currentTarget = this; - that.close( blurEvent, true ); + that.close(blurEvent, true); } - if ( parent.attr( "title" ) ) { + if (parent.attr("title")) { parent.uniqueId(); - that.parents[ this.id ] = { + that.parents[this.id] = { element: this, - title: parent.attr( "title" ) + title: parent.attr("title") }; - parent.attr( "title", "" ); + parent.attr("title", ""); } }); } - this._updateContent( target, event ); + this._updateContent(target, event); }, - _updateContent: function( target, event ) { + _updateContent: function (target, event) { var content, contentOption = this.options.content, that = this, eventType = event ? event.type : null; - if ( typeof contentOption === "string" ) { - return this._open( event, target, contentOption ); + if (typeof contentOption === "string") { + return this._open(event, target, contentOption); } - content = contentOption.call( target[0], function( response ) { + content = contentOption.call(target[0], function (response) { // ignore async response if tooltip was closed already - if ( !target.data( "ui-tooltip-open" ) ) { + if (!target.data("ui-tooltip-open")) { return; } // 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() { + that._delay(function () { // 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 ) { + if (event) { event.type = eventType; } - this._open( event, target, response ); + this._open(event, target, response); }); }); - if ( content ) { - this._open( event, target, content ); + if (content) { + this._open(event, target, content); } }, - _open: function( event, target, content ) { + _open: function (event, target, content) { var tooltip, events, delayedShow, - positionOption = $.extend( {}, this.options.position ); + positionOption = $.extend({}, this.options.position); - if ( !content ) { + if (!content) { return; } // Content can be updated multiple times. If the tooltip already // exists, then just update the content and bail. - tooltip = this._find( target ); - if ( tooltip.length ) { - tooltip.find( ".ui-tooltip-content" ).html( content ); + tooltip = this._find(target); + if (tooltip.length) { + tooltip.find(".ui-tooltip-content").html(content); return; } @@ -219,169 +235,170 @@ // 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 (target.is("[title]")) { + if (event && event.type === "mouseover") { + target.attr("title", ""); } else { - target.removeAttr( "title" ); + target.removeAttr("title"); } } - tooltip = this._tooltip( target ); - addDescribedBy( target, tooltip.attr( "id" ) ); - tooltip.find( ".ui-tooltip-content" ).html( content ); + tooltip = this._tooltip(target); + addDescribedBy(target, tooltip.attr("id")); + tooltip.find(".ui-tooltip-content").html(content); - function position( event ) { + function position(event) { positionOption.of = event; - if ( tooltip.is( ":hidden" ) ) { + if (tooltip.is(":hidden")) { return; } - tooltip.position( positionOption ); + tooltip.position(positionOption); } - if ( this.options.track && event && /^mouse/.test( event.type ) ) { - this._on( this.document, { + + if (this.options.track && event && /^mouse/.test(event.type)) { + this._on(this.document, { mousemove: position }); // trigger once to override element-relative positioning - position( event ); + position(event); } else { - tooltip.position( $.extend({ + tooltip.position($.extend({ of: target - }, this.options.position ) ); + }, this.options.position)); } tooltip.hide(); - this._show( tooltip, this.options.show ); + 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. - if ( this.options.show && this.options.show.delay ) { - delayedShow = this.delayedShow = setInterval(function() { - if ( tooltip.is( ":visible" ) ) { - position( positionOption.of ); - clearInterval( delayedShow ); + if (this.options.show && this.options.show.delay) { + delayedShow = this.delayedShow = setInterval(function () { + if (tooltip.is(":visible")) { + position(positionOption.of); + clearInterval(delayedShow); } - }, $.fx.interval ); + }, $.fx.interval); } - this._trigger( "open", event, { tooltip: tooltip } ); + this._trigger("open", event, {tooltip: tooltip}); events = { - keyup: function( event ) { - if ( event.keyCode === $.ui.keyCode.ESCAPE ) { + keyup: function (event) { + if (event.keyCode === $.ui.keyCode.ESCAPE) { var fakeEvent = $.Event(event); fakeEvent.currentTarget = target[0]; - this.close( fakeEvent, true ); + this.close(fakeEvent, true); } }, - remove: function() { - this._removeTooltip( tooltip ); + remove: function () { + this._removeTooltip(tooltip); } }; - if ( !event || event.type === "mouseover" ) { + if (!event || event.type === "mouseover") { events.mouseleave = "close"; } - if ( !event || event.type === "focusin" ) { + if (!event || event.type === "focusin") { events.focusout = "close"; } - this._on( true, target, events ); + this._on(true, target, events); }, - close: function( event ) { + close: function (event) { var that = this, - target = $( event ? event.currentTarget : this.element ), - tooltip = this._find( target ); + target = $(event ? event.currentTarget : this.element), + tooltip = this._find(target); // 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 ( this.closing ) { + if (this.closing) { return; } // Clear the interval for delayed tracking tooltips - clearInterval( this.delayedShow ); + clearInterval(this.delayedShow); // only set title if we had one before (see comment in _open()) - if ( target.data( "ui-tooltip-title" ) ) { - target.attr( "title", target.data( "ui-tooltip-title" ) ); + if (target.data("ui-tooltip-title")) { + target.attr("title", target.data("ui-tooltip-title")); } - removeDescribedBy( target ); + removeDescribedBy(target); - tooltip.stop( true ); - this._hide( tooltip, this.options.hide, function() { - that._removeTooltip( $( this ) ); + tooltip.stop(true); + this._hide(tooltip, this.options.hide, function () { + that._removeTooltip($(this)); }); - target.removeData( "ui-tooltip-open" ); - this._off( target, "mouseleave focusout keyup" ); + 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" ); + if (target[0] !== this.element[0]) { + this._off(target, "remove"); } - this._off( this.document, "mousemove" ); + 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 ]; + if (event && event.type === "mouseleave") { + $.each(this.parents, function (id, parent) { + $(parent.element).attr("title", parent.title); + delete that.parents[id]; }); } this.closing = true; - this._trigger( "close", event, { tooltip: tooltip } ); + this._trigger("close", event, {tooltip: tooltip}); this.closing = false; }, - _tooltip: function( element ) { + _tooltip: function (element) { var id = "ui-tooltip-" + increments++, - tooltip = $( "<div>" ) + tooltip = $("<div>") .attr({ id: id, role: "tooltip" }) - .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " + - ( this.options.tooltipClass || "" ) ); - $( "<div>" ) - .addClass( "ui-tooltip-content" ) - .appendTo( tooltip ); - tooltip.appendTo( this.document[0].body ); - this.tooltips[ id ] = element; + .addClass("ui-tooltip ui-widget ui-corner-all ui-widget-content " + + (this.options.tooltipClass || "")); + $("<div>") + .addClass("ui-tooltip-content") + .appendTo(tooltip); + tooltip.appendTo(this.document[0].body); + this.tooltips[id] = element; return tooltip; }, - _find: function( target ) { - var id = target.data( "ui-tooltip-id" ); - return id ? $( "#" + id ) : $(); + _find: function (target) { + var id = target.data("ui-tooltip-id"); + return id ? $("#" + id) : $(); }, - _removeTooltip: function( tooltip ) { + _removeTooltip: function (tooltip) { tooltip.remove(); - delete this.tooltips[ tooltip.attr( "id" ) ]; + delete this.tooltips[tooltip.attr("id")]; }, - _destroy: function() { + _destroy: function () { var that = this; // close open tooltips - $.each( this.tooltips, function( id, element ) { + $.each(this.tooltips, function (id, element) { // Delegate to close method to handle common cleanup - var event = $.Event( "blur" ); + var event = $.Event("blur"); event.target = event.currentTarget = element[0]; - that.close( event, true ); + that.close(event, true); // Remove immediately; destroying an open tooltip doesn't use the // hide animation - $( "#" + id ).remove(); + $("#" + id).remove(); // Restore the title - if ( element.data( "ui-tooltip-title" ) ) { - element.attr( "title", element.data( "ui-tooltip-title" ) ); - element.removeData( "ui-tooltip-title" ); + if (element.data("ui-tooltip-title")) { + element.attr("title", element.data("ui-tooltip-title")); + element.removeData("ui-tooltip-title"); } }); } }); -}( jQuery ) ); +}); diff --git a/lib/web/jquery/ui-modules/widget.js b/lib/web/jquery/ui-modules/widget.js index a86c587ad81c..ef8c1ef0e60f 100644 --- a/lib/web/jquery/ui-modules/widget.js +++ b/lib/web/jquery/ui-modules/widget.js @@ -1,58 +1,72 @@ -(function( $, undefined ) { +/*! + * jQuery UI Widget + * http://jqueryui.com + * + * Copyright 2014 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/jQuery.widget/ + */ + +define([ + 'jquery' +], function ($, undefined) { var uuid = 0, slice = Array.prototype.slice, _cleanData = $.cleanData; - $.cleanData = function( elems ) { - for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { + $.cleanData = function (elems) { + for (var i = 0, elem; (elem = elems[i]) != null; i++) { try { - $( elem ).triggerHandler( "remove" ); + $(elem).triggerHandler("remove"); // http://bugs.jquery.com/ticket/8235 - } catch( e ) {} + } catch (e) { + } } - _cleanData( elems ); + _cleanData(elems); }; - $.widget = function( name, base, prototype ) { + $.widget = function (name, base, prototype) { var fullName, existingConstructor, constructor, basePrototype, // proxiedPrototype allows the provided prototype to remain unmodified // so that it can be used as a mixin for multiple widgets (#8876) proxiedPrototype = {}, - namespace = name.split( "." )[ 0 ]; + namespace = name.split(".")[0]; - name = name.split( "." )[ 1 ]; + name = name.split(".")[1]; fullName = namespace + "-" + name; - if ( !prototype ) { + if (!prototype) { prototype = base; base = $.Widget; } // create selector for plugin - $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) { - return !!$.data( elem, fullName ); + $.expr[":"][fullName.toLowerCase()] = function (elem) { + return !!$.data(elem, fullName); }; - $[ namespace ] = $[ namespace ] || {}; - existingConstructor = $[ namespace ][ name ]; - constructor = $[ namespace ][ name ] = function( options, element ) { + $[namespace] = $[namespace] || {}; + existingConstructor = $[namespace][name]; + constructor = $[namespace][name] = function (options, element) { // allow instantiation without "new" keyword - if ( !this._createWidget ) { - return new constructor( options, element ); + 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 ); + if (arguments.length) { + this._createWidget(options, element); } }; // extend with the existing constructor to carry over any static properties - $.extend( constructor, existingConstructor, { + $.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 ), + _proto: $.extend({}, prototype), // track widgets that inherit from this widget in case this widget is // redefined after a widget inherits from it _childConstructors: [] @@ -62,20 +76,20 @@ // 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; + basePrototype.options = $.widget.extend({}, basePrototype.options); + $.each(prototype, function (prop, value) { + if (!$.isFunction(value)) { + proxiedPrototype[prop] = value; return; } - proxiedPrototype[ prop ] = (function() { - var _super = function() { - return base.prototype[ prop ].apply( this, arguments ); + proxiedPrototype[prop] = (function () { + var _super = function () { + return base.prototype[prop].apply(this, arguments); }, - _superApply = function( args ) { - return base.prototype[ prop ].apply( this, args ); + _superApply = function (args) { + return base.prototype[prop].apply(this, args); }; - return function() { + return function () { var __super = this._super, __superApply = this._superApply, returnValue; @@ -83,7 +97,7 @@ this._super = _super; this._superApply = _superApply; - returnValue = value.apply( this, arguments ); + returnValue = value.apply(this, arguments); this._super = __super; this._superApply = __superApply; @@ -92,7 +106,7 @@ }; })(); }); - constructor.prototype = $.widget.extend( basePrototype, { + 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 @@ -108,43 +122,43 @@ // 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 ) { + 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 ); + $.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 ); + base._childConstructors.push(constructor); } - $.widget.bridge( name, constructor ); + $.widget.bridge(name, constructor); }; - $.widget.extend = function( target ) { - var input = slice.call( arguments, 1 ), + $.widget.extend = function (target) { + var input = slice.call(arguments, 1), inputIndex = 0, inputLength = input.length, key, value; - for ( ; inputIndex < inputLength; inputIndex++ ) { - for ( key in input[ inputIndex ] ) { - value = input[ inputIndex ][ key ]; - if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) { + for (; inputIndex < inputLength; inputIndex++) { + for (key in input[inputIndex]) { + value = input[inputIndex][key]; + if (input[inputIndex].hasOwnProperty(key) && value !== undefined) { // Clone objects - if ( $.isPlainObject( value ) ) { - target[ key ] = $.isPlainObject( target[ key ] ) ? - $.widget.extend( {}, target[ key ], value ) : + if ($.isPlainObject(value)) { + target[key] = $.isPlainObject(target[key]) ? + $.widget.extend({}, target[key], value) : // Don't extend strings, arrays, etc. with objects - $.widget.extend( {}, value ); + $.widget.extend({}, value); // Copy everything else by reference } else { - target[ key ] = value; + target[key] = value; } } } @@ -152,44 +166,44 @@ return target; }; - $.widget.bridge = function( name, object ) { + $.widget.bridge = function (name, object) { var fullName = object.prototype.widgetFullName || name; - $.fn[ name ] = function( options ) { + $.fn[name] = function (options) { var isMethodCall = typeof options === "string", - args = slice.call( arguments, 1 ), + args = slice.call(arguments, 1), returnValue = this; // allow multiple hashes to be passed on init options = !isMethodCall && args.length ? - $.widget.extend.apply( null, [ options ].concat(args) ) : + $.widget.extend.apply(null, [options].concat(args)) : options; - if ( isMethodCall ) { - this.each(function() { + if (isMethodCall) { + this.each(function () { var methodValue, - instance = $.data( this, fullName ); - if ( !instance ) { - return $.error( "cannot call methods on " + name + " prior to initialization; " + - "attempted to call method '" + options + "'" ); + instance = $.data(this, fullName); + if (!instance) { + return $.error("cannot call methods on " + name + " prior to initialization; " + + "attempted to call method '" + options + "'"); } - if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) { - return $.error( "no such method '" + options + "' for " + name + " widget instance" ); + if (!$.isFunction(instance[options]) || options.charAt(0) === "_") { + return $.error("no such method '" + options + "' for " + name + " widget instance"); } - methodValue = instance[ options ].apply( instance, args ); - if ( methodValue !== instance && methodValue !== undefined ) { + methodValue = instance[options].apply(instance, args); + if (methodValue !== instance && methodValue !== undefined) { returnValue = methodValue && methodValue.jquery ? - returnValue.pushStack( methodValue.get() ) : + returnValue.pushStack(methodValue.get()) : methodValue; return false; } }); } else { - this.each(function() { - var instance = $.data( this, fullName ); - if ( instance ) { - instance.option( options || {} )._init(); + this.each(function () { + var instance = $.data(this, fullName); + if (instance) { + instance.option(options || {})._init(); } else { - $.data( this, fullName, new object( options, this ) ); + $.data(this, fullName, new object(options, this)); } }); } @@ -198,7 +212,8 @@ }; }; - $.Widget = function( /* options, element */ ) {}; + $.Widget = function ( /* options, element */) { + }; $.Widget._childConstructors = []; $.Widget.prototype = { @@ -211,39 +226,39 @@ // callbacks create: null }, - _createWidget: function( options, element ) { - element = $( element || this.defaultElement || this )[ 0 ]; - this.element = $( element ); + _createWidget: function (options, element) { + element = $(element || this.defaultElement || this)[0]; + this.element = $(element); this.uuid = uuid++; this.eventNamespace = "." + this.widgetName + this.uuid; - this.options = $.widget.extend( {}, + this.options = $.widget.extend({}, this.options, this._getCreateOptions(), - options ); + options); this.bindings = $(); this.hoverable = $(); this.focusable = $(); - if ( element !== this ) { - $.data( element, this.widgetFullName, this ); - this._on( true, this.element, { - remove: function( event ) { - if ( event.target === element ) { + 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 ? + 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 ); + element.document || element); + this.window = $(this.document[0].defaultView || this.document[0].parentWindow); } this._create(); - this._trigger( "create", null, this._getCreateEventData() ); + this._trigger("create", null, this._getCreateEventData()); this._init(); }, _getCreateOptions: $.noop, @@ -251,231 +266,232 @@ _create: $.noop, _init: $.noop, - destroy: function() { + destroy: function () { this._destroy(); // we can probably remove the unbind calls in 2.0 // all event bindings should go through this._on() this.element - .unbind( this.eventNamespace ) + .unbind(this.eventNamespace) // 1.9 BC for #7810 // TODO remove dual storage - .removeData( this.widgetName ) - .removeData( this.widgetFullName ) + .removeData(this.widgetName) + .removeData(this.widgetFullName) // support: jquery <1.6.3 // http://bugs.jquery.com/ticket/9413 - .removeData( $.camelCase( this.widgetFullName ) ); + .removeData($.camelCase(this.widgetFullName)); this.widget() - .unbind( this.eventNamespace ) - .removeAttr( "aria-disabled" ) + .unbind(this.eventNamespace) + .removeAttr("aria-disabled") .removeClass( this.widgetFullName + "-disabled " + - "ui-state-disabled" ); + "ui-state-disabled"); // clean up events and states - this.bindings.unbind( this.eventNamespace ); - this.hoverable.removeClass( "ui-state-hover" ); - this.focusable.removeClass( "ui-state-focus" ); + this.bindings.unbind(this.eventNamespace); + this.hoverable.removeClass("ui-state-hover"); + this.focusable.removeClass("ui-state-focus"); }, _destroy: $.noop, - widget: function() { + widget: function () { return this.element; }, - option: function( key, value ) { + option: function (key, value) { var options = key, parts, curOption, i; - if ( arguments.length === 0 ) { + if (arguments.length === 0) { // don't return a reference to the internal hash - return $.widget.extend( {}, this.options ); + return $.widget.extend({}, this.options); } - if ( typeof key === "string" ) { + if (typeof key === "string") { // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } options = {}; - parts = key.split( "." ); + 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 ] ]; + 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 ]; + if (arguments.length === 1) { + return curOption[key] === undefined ? null : curOption[key]; } - curOption[ key ] = value; + curOption[key] = value; } else { - if ( arguments.length === 1 ) { - return this.options[ key ] === undefined ? null : this.options[ key ]; + if (arguments.length === 1) { + return this.options[key] === undefined ? null : this.options[key]; } - options[ key ] = value; + options[key] = value; } } - this._setOptions( options ); + this._setOptions(options); return this; }, - _setOptions: function( options ) { + _setOptions: function (options) { var key; - for ( key in options ) { - this._setOption( key, options[ key ] ); + for (key in options) { + this._setOption(key, options[key]); } return this; }, - _setOption: function( key, value ) { - this.options[ key ] = value; + _setOption: function (key, value) { + this.options[key] = value; - if ( key === "disabled" ) { + if (key === "disabled") { this.widget() - .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value ) - .attr( "aria-disabled", value ); - this.hoverable.removeClass( "ui-state-hover" ); - this.focusable.removeClass( "ui-state-focus" ); + .toggleClass(this.widgetFullName + "-disabled ui-state-disabled", !!value) + .attr("aria-disabled", value); + this.hoverable.removeClass("ui-state-hover"); + this.focusable.removeClass("ui-state-focus"); } return this; }, - enable: function() { - return this._setOption( "disabled", false ); + enable: function () { + return this._setOption("disabled", false); }, - disable: function() { - return this._setOption( "disabled", true ); + disable: function () { + return this._setOption("disabled", true); }, - _on: function( suppressDisabledCheck, element, handlers ) { + _on: function (suppressDisabledCheck, element, handlers) { var delegateElement, instance = this; // no suppressDisabledCheck flag, shuffle arguments - if ( typeof suppressDisabledCheck !== "boolean" ) { + if (typeof suppressDisabledCheck !== "boolean") { handlers = element; element = suppressDisabledCheck; suppressDisabledCheck = false; } // no element argument, shuffle and use this.element - if ( !handlers ) { + if (!handlers) { handlers = element; element = this.element; delegateElement = this.widget(); } else { // accept selectors, DOM elements - element = delegateElement = $( element ); - this.bindings = this.bindings.add( element ); + element = delegateElement = $(element); + this.bindings = this.bindings.add(element); } - $.each( handlers, function( event, handler ) { + $.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" ) ) ) { + if (!suppressDisabledCheck && + (instance.options.disabled === true || + $(this).hasClass("ui-state-disabled"))) { return; } - return ( typeof handler === "string" ? instance[ handler ] : handler ) - .apply( instance, arguments ); + return (typeof handler === "string" ? instance[handler] : handler) + .apply(instance, arguments); } // copy the guid so direct unbinding works - if ( typeof handler !== "string" ) { + if (typeof handler !== "string") { handlerProxy.guid = handler.guid = handler.guid || handlerProxy.guid || $.guid++; } - var match = event.match( /^(\w+)\s*(.*)$/ ), + var match = event.match(/^(\w+)\s*(.*)$/), eventName = match[1] + instance.eventNamespace, selector = match[2]; - if ( selector ) { - delegateElement.delegate( selector, eventName, handlerProxy ); + if (selector) { + delegateElement.delegate(selector, eventName, handlerProxy); } else { - element.bind( eventName, handlerProxy ); + element.bind(eventName, handlerProxy); } }); }, - _off: function( element, eventName ) { - eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace; - element.unbind( eventName ).undelegate( eventName ); + _off: function (element, eventName) { + eventName = (eventName || "").split(" ").join(this.eventNamespace + " ") + this.eventNamespace; + element.unbind(eventName).undelegate(eventName); }, - _delay: function( handler, delay ) { + _delay: function (handler, delay) { function handlerProxy() { - return ( typeof handler === "string" ? instance[ handler ] : handler ) - .apply( instance, arguments ); + return (typeof handler === "string" ? instance[handler] : handler) + .apply(instance, arguments); } + var instance = this; - return setTimeout( handlerProxy, delay || 0 ); + return setTimeout(handlerProxy, delay || 0); }, - _hoverable: function( element ) { - this.hoverable = this.hoverable.add( element ); - this._on( element, { - mouseenter: function( event ) { - $( event.currentTarget ).addClass( "ui-state-hover" ); + _hoverable: function (element) { + this.hoverable = this.hoverable.add(element); + this._on(element, { + mouseenter: function (event) { + $(event.currentTarget).addClass("ui-state-hover"); }, - mouseleave: function( event ) { - $( event.currentTarget ).removeClass( "ui-state-hover" ); + mouseleave: function (event) { + $(event.currentTarget).removeClass("ui-state-hover"); } }); }, - _focusable: function( element ) { - this.focusable = this.focusable.add( element ); - this._on( element, { - focusin: function( event ) { - $( event.currentTarget ).addClass( "ui-state-focus" ); + _focusable: function (element) { + this.focusable = this.focusable.add(element); + this._on(element, { + focusin: function (event) { + $(event.currentTarget).addClass("ui-state-focus"); }, - focusout: function( event ) { - $( event.currentTarget ).removeClass( "ui-state-focus" ); + focusout: function (event) { + $(event.currentTarget).removeClass("ui-state-focus"); } }); }, - _trigger: function( type, event, data ) { + _trigger: function (type, event, data) { var prop, orig, - callback = this.options[ type ]; + callback = this.options[type]; data = data || {}; - event = $.Event( event ); - event.type = ( type === this.widgetEventPrefix ? + event = $.Event(event); + event.type = (type === this.widgetEventPrefix ? type : - this.widgetEventPrefix + type ).toLowerCase(); + 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 ]; + 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 ]; + if (orig) { + for (prop in orig) { + if (!(prop in event)) { + event[prop] = orig[prop]; } } } - this.element.trigger( event, data ); - return !( $.isFunction( callback ) && - 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 }; + $.each({show: "fadeIn", hide: "fadeOut"}, function (method, defaultEffect) { + $.Widget.prototype["_" + method] = function (element, options, callback) { + if (typeof options === "string") { + options = {effect: options}; } var hasOptions, effectName = !options ? @@ -484,23 +500,23 @@ defaultEffect : options.effect || defaultEffect; options = options || {}; - if ( typeof options === "number" ) { - options = { duration: options }; + if (typeof options === "number") { + options = {duration: options}; } - hasOptions = !$.isEmptyObject( options ); + hasOptions = !$.isEmptyObject(options); options.complete = callback; - if ( options.delay ) { - element.delay( options.delay ); + 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 ); + 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 ] ); + element.queue(function (next) { + $(this)[method](); + if (callback) { + callback.call(element[0]); } next(); }); @@ -508,4 +524,4 @@ }; }); -})( jQuery ); +}); From 0b94656cea8f327f80bb6b1d035df10401971043 Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Fri, 28 Jun 2019 16:54:00 -0500 Subject: [PATCH 011/191] MC-17868: Break jQuery UI into widgets and make a prototype - Swap jquery UI usage for separate jquery ui widgets; --- app/code/Magento/Captcha/view/frontend/web/js/captcha.js | 3 ++- .../Catalog/view/frontend/web/js/catalog-add-to-cart.js | 3 ++- app/code/Magento/Catalog/view/frontend/web/js/gallery.js | 3 ++- .../Catalog/view/frontend/web/product/view/validation.js | 3 ++- app/code/Magento/Checkout/view/frontend/web/js/sidebar.js | 3 ++- .../Magento/Cookie/view/frontend/web/js/require-cookie.js | 3 ++- app/code/Magento/Customer/view/frontend/web/js/address.js | 3 ++- .../Customer/view/frontend/web/js/addressValidation.js | 3 ++- .../Customer/view/frontend/web/js/change-email-password.js | 3 ++- .../Customer/view/frontend/web/js/checkout-balance.js | 3 ++- .../Downloadable/view/frontend/web/js/downloadable.js | 3 ++- .../Magento/PageCache/view/frontend/web/js/page-cache.js | 3 ++- .../view/frontend/web/js/fotorama-add-video-events.js | 3 ++- .../ProductVideo/view/frontend/web/js/load-player.js | 6 +++++- .../Magento/Review/view/frontend/web/js/validate-review.js | 3 ++- app/code/Magento/Search/view/frontend/web/js/form-mini.js | 3 ++- .../Swatches/view/frontend/web/js/swatch-renderer.js | 3 ++- app/code/Magento/Ui/view/base/web/js/modal/alert.js | 3 ++- app/code/Magento/Ui/view/base/web/js/modal/confirm.js | 3 ++- app/code/Magento/Ui/view/base/web/js/modal/modal.js | 3 ++- .../Wishlist/view/frontend/web/js/add-to-wishlist.js | 3 ++- .../Framework/Data/Form/Element/Editablemultiselect.php | 3 ++- lib/web/jquery/fileUploader/jquery.fileupload.js | 3 ++- lib/web/mage/calendar.js | 6 ++++-- lib/web/mage/collapsible.js | 3 ++- lib/web/mage/dataPost.js | 3 ++- lib/web/mage/deletable-item.js | 3 ++- lib/web/mage/dialog.js | 2 +- lib/web/mage/dropdown.js | 2 +- lib/web/mage/edit-trigger.js | 3 ++- lib/web/mage/fieldset-controls.js | 3 ++- lib/web/mage/item-table.js | 3 ++- lib/web/mage/list.js | 3 ++- lib/web/mage/loader.js | 3 ++- lib/web/mage/loader_old.js | 3 ++- lib/web/mage/menu.js | 2 +- lib/web/mage/multiselect.js | 3 ++- lib/web/mage/popup-window.js | 3 ++- lib/web/mage/redirect-url.js | 3 ++- lib/web/mage/sticky.js | 3 ++- lib/web/mage/tabs.js | 3 ++- lib/web/mage/toggle.js | 3 ++- lib/web/mage/tooltip.js | 2 +- lib/web/mage/translate-inline-vde.js | 3 ++- lib/web/mage/translate-inline.js | 2 +- lib/web/mage/validation.js | 3 ++- lib/web/mage/zoom.js | 3 ++- 47 files changed, 94 insertions(+), 48 deletions(-) diff --git a/app/code/Magento/Captcha/view/frontend/web/js/captcha.js b/app/code/Magento/Captcha/view/frontend/web/js/captcha.js index 0d4d4812f64c..aa173a8be671 100644 --- a/app/code/Magento/Captcha/view/frontend/web/js/captcha.js +++ b/app/code/Magento/Captcha/view/frontend/web/js/captcha.js @@ -5,7 +5,8 @@ define([ 'jquery', - 'jquery/ui' + 'jquery-ui-modules/widget', + 'jquery-ui-modules/core' ], function ($) { 'use strict'; diff --git a/app/code/Magento/Catalog/view/frontend/web/js/catalog-add-to-cart.js b/app/code/Magento/Catalog/view/frontend/web/js/catalog-add-to-cart.js index bcb7c668657d..6aa477141fe0 100644 --- a/app/code/Magento/Catalog/view/frontend/web/js/catalog-add-to-cart.js +++ b/app/code/Magento/Catalog/view/frontend/web/js/catalog-add-to-cart.js @@ -8,7 +8,8 @@ define([ 'mage/translate', 'underscore', 'Magento_Catalog/js/product/view/product-ids-resolver', - 'jquery/ui' + 'jquery-ui-modules/core', + 'jquery-ui-modules/widget' ], function ($, $t, _, idsResolver) { 'use strict'; diff --git a/app/code/Magento/Catalog/view/frontend/web/js/gallery.js b/app/code/Magento/Catalog/view/frontend/web/js/gallery.js index df503cb42287..5d3d27bf1051 100644 --- a/app/code/Magento/Catalog/view/frontend/web/js/gallery.js +++ b/app/code/Magento/Catalog/view/frontend/web/js/gallery.js @@ -9,7 +9,8 @@ if (typeof define === 'function' && define.amd) { define([ 'jquery', - 'jquery/ui' + 'jquery-ui-modules/widget', + 'jquery-ui-modules/core' ], factory); } else { factory(jQuery); diff --git a/app/code/Magento/Catalog/view/frontend/web/product/view/validation.js b/app/code/Magento/Catalog/view/frontend/web/product/view/validation.js index ad652b8ef36f..8c826411ce4c 100644 --- a/app/code/Magento/Catalog/view/frontend/web/product/view/validation.js +++ b/app/code/Magento/Catalog/view/frontend/web/product/view/validation.js @@ -9,7 +9,8 @@ if (typeof define === 'function' && define.amd) { define([ 'jquery', - 'jquery/ui', + 'jquery-ui-modules/widget', + 'jquery-ui-modules/core', 'mage/validation/validation' ], factory); } else { diff --git a/app/code/Magento/Checkout/view/frontend/web/js/sidebar.js b/app/code/Magento/Checkout/view/frontend/web/js/sidebar.js index e66c66006246..fc281ecc3497 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/sidebar.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/sidebar.js @@ -10,7 +10,8 @@ define([ 'Magento_Ui/js/modal/alert', 'Magento_Ui/js/modal/confirm', 'underscore', - 'jquery/ui', + 'jquery-ui-modules/widget', + 'jquery-ui-modules/core', 'mage/decorate', 'mage/collapsible', 'mage/cookies' diff --git a/app/code/Magento/Cookie/view/frontend/web/js/require-cookie.js b/app/code/Magento/Cookie/view/frontend/web/js/require-cookie.js index 8fd329ee0e0e..aa5b048ae507 100644 --- a/app/code/Magento/Cookie/view/frontend/web/js/require-cookie.js +++ b/app/code/Magento/Cookie/view/frontend/web/js/require-cookie.js @@ -8,7 +8,8 @@ */ define([ 'jquery', - 'jquery/ui' + 'jquery-ui-modules/widget', + 'jquery-ui-modules/core' ], function ($) { 'use strict'; diff --git a/app/code/Magento/Customer/view/frontend/web/js/address.js b/app/code/Magento/Customer/view/frontend/web/js/address.js index c6d05b51bdf0..4e0ddbc5b68e 100644 --- a/app/code/Magento/Customer/view/frontend/web/js/address.js +++ b/app/code/Magento/Customer/view/frontend/web/js/address.js @@ -6,7 +6,8 @@ define([ 'jquery', 'Magento_Ui/js/modal/confirm', - 'jquery/ui', + 'jquery-ui-modules/widget', + 'jquery-ui-modules/core', 'mage/translate' ], function ($, confirm) { 'use strict'; diff --git a/app/code/Magento/Customer/view/frontend/web/js/addressValidation.js b/app/code/Magento/Customer/view/frontend/web/js/addressValidation.js index c014b814ea98..20f61fc02db6 100644 --- a/app/code/Magento/Customer/view/frontend/web/js/addressValidation.js +++ b/app/code/Magento/Customer/view/frontend/web/js/addressValidation.js @@ -9,7 +9,8 @@ define([ 'mageUtils', 'mage/translate', 'Magento_Checkout/js/model/postcode-validator', - 'jquery/ui', + 'jquery-ui-modules/widget', + 'jquery-ui-modules/core', 'validation' ], function ($, __, utils, $t, postCodeValidator) { 'use strict'; diff --git a/app/code/Magento/Customer/view/frontend/web/js/change-email-password.js b/app/code/Magento/Customer/view/frontend/web/js/change-email-password.js index cf3ea48844b9..e790471710ea 100644 --- a/app/code/Magento/Customer/view/frontend/web/js/change-email-password.js +++ b/app/code/Magento/Customer/view/frontend/web/js/change-email-password.js @@ -4,7 +4,8 @@ */ define([ 'jquery', - 'jquery/ui' + 'jquery-ui-modules/widget', + 'jquery-ui-modules/core' ], function ($) { 'use strict'; diff --git a/app/code/Magento/Customer/view/frontend/web/js/checkout-balance.js b/app/code/Magento/Customer/view/frontend/web/js/checkout-balance.js index 8d5242e70379..5c7d59ce6753 100644 --- a/app/code/Magento/Customer/view/frontend/web/js/checkout-balance.js +++ b/app/code/Magento/Customer/view/frontend/web/js/checkout-balance.js @@ -5,7 +5,8 @@ define([ 'jquery', - 'jquery/ui' + 'jquery-ui-modules/widget', + 'jquery-ui-modules/core' ], function ($) { 'use strict'; diff --git a/app/code/Magento/Downloadable/view/frontend/web/js/downloadable.js b/app/code/Magento/Downloadable/view/frontend/web/js/downloadable.js index 64cca1efd8b0..a1abc47acfb3 100644 --- a/app/code/Magento/Downloadable/view/frontend/web/js/downloadable.js +++ b/app/code/Magento/Downloadable/view/frontend/web/js/downloadable.js @@ -7,7 +7,8 @@ */ define([ 'jquery', - 'jquery/ui', + 'jquery-ui-modules/widget', + 'jquery-ui-modules/core', 'Magento_Catalog/js/price-box' ], function ($) { 'use strict'; diff --git a/app/code/Magento/PageCache/view/frontend/web/js/page-cache.js b/app/code/Magento/PageCache/view/frontend/web/js/page-cache.js index 2e8a4769be10..e24d712f17ab 100644 --- a/app/code/Magento/PageCache/view/frontend/web/js/page-cache.js +++ b/app/code/Magento/PageCache/view/frontend/web/js/page-cache.js @@ -7,7 +7,8 @@ define([ 'jquery', 'domReady', 'consoleLogger', - 'jquery/ui', + 'jquery-ui-modules/widget', + 'jquery-ui-modules/core', 'mage/cookies' ], function ($, domReady, consoleLogger) { 'use strict'; diff --git a/app/code/Magento/ProductVideo/view/frontend/web/js/fotorama-add-video-events.js b/app/code/Magento/ProductVideo/view/frontend/web/js/fotorama-add-video-events.js index cd0f3b3d630a..8bfc4a08bb31 100644 --- a/app/code/Magento/ProductVideo/view/frontend/web/js/fotorama-add-video-events.js +++ b/app/code/Magento/ProductVideo/view/frontend/web/js/fotorama-add-video-events.js @@ -5,7 +5,8 @@ define([ 'jquery', - 'jquery/ui', + 'jquery-ui-modules/widget', + 'jquery-ui-modules/core', 'catalogGallery', 'loadPlayer' ], function ($) { diff --git a/app/code/Magento/ProductVideo/view/frontend/web/js/load-player.js b/app/code/Magento/ProductVideo/view/frontend/web/js/load-player.js index 75a2c1d75da1..70220875d716 100644 --- a/app/code/Magento/ProductVideo/view/frontend/web/js/load-player.js +++ b/app/code/Magento/ProductVideo/view/frontend/web/js/load-player.js @@ -7,7 +7,11 @@ @version 0.0.1 @requires jQuery & jQuery UI */ -define(['jquery', 'jquery/ui'], function ($) { +define([ + 'jquery', + 'jquery-ui-modules/widget', + 'jquery-ui-modules/core' +], function ($) { 'use strict'; var videoRegister = { diff --git a/app/code/Magento/Review/view/frontend/web/js/validate-review.js b/app/code/Magento/Review/view/frontend/web/js/validate-review.js index e3f57eaf8cd3..429424e4a187 100644 --- a/app/code/Magento/Review/view/frontend/web/js/validate-review.js +++ b/app/code/Magento/Review/view/frontend/web/js/validate-review.js @@ -5,7 +5,8 @@ define([ 'jquery', - 'jquery/ui', + 'jquery-ui-modules/widget', + 'jquery-ui-modules/core', 'jquery/validate', 'mage/translate' ], function ($) { diff --git a/app/code/Magento/Search/view/frontend/web/js/form-mini.js b/app/code/Magento/Search/view/frontend/web/js/form-mini.js index 3f3e64738d46..64e6eceb1eba 100644 --- a/app/code/Magento/Search/view/frontend/web/js/form-mini.js +++ b/app/code/Magento/Search/view/frontend/web/js/form-mini.js @@ -11,7 +11,8 @@ define([ 'underscore', 'mage/template', 'matchMedia', - 'jquery/ui', + 'jquery-ui-modules/widget', + 'jquery-ui-modules/core', 'mage/translate' ], function ($, _, mageTemplate, mediaCheck) { 'use strict'; diff --git a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js index 6e028ec53c12..23f890acd6f2 100644 --- a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js +++ b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js @@ -10,7 +10,8 @@ define([ 'mage/smart-keyboard-handler', 'mage/translate', 'priceUtils', - 'jquery/ui', + 'jquery-ui-modules/widget', + 'jquery-ui-modules/core', 'jquery/jquery.parsequery', 'mage/validation/validation' ], function ($, _, mageTemplate, keyboardHandler, $t, priceUtils) { diff --git a/app/code/Magento/Ui/view/base/web/js/modal/alert.js b/app/code/Magento/Ui/view/base/web/js/modal/alert.js index b63294e3d875..c32aee2a89d9 100644 --- a/app/code/Magento/Ui/view/base/web/js/modal/alert.js +++ b/app/code/Magento/Ui/view/base/web/js/modal/alert.js @@ -9,7 +9,8 @@ define([ 'jquery', 'underscore', - 'jquery/ui', + 'jquery-ui-modules/widget', + 'jquery-ui-modules/core', 'Magento_Ui/js/modal/confirm', 'mage/translate' ], function ($, _) { diff --git a/app/code/Magento/Ui/view/base/web/js/modal/confirm.js b/app/code/Magento/Ui/view/base/web/js/modal/confirm.js index eceab940d114..eb005b2f5d59 100644 --- a/app/code/Magento/Ui/view/base/web/js/modal/confirm.js +++ b/app/code/Magento/Ui/view/base/web/js/modal/confirm.js @@ -10,7 +10,8 @@ define([ 'jquery', 'underscore', 'mage/translate', - 'jquery/ui', + 'jquery-ui-modules/widget', + 'jquery-ui-modules/core', 'Magento_Ui/js/modal/modal' ], function ($, _, $t) { 'use strict'; diff --git a/app/code/Magento/Ui/view/base/web/js/modal/modal.js b/app/code/Magento/Ui/view/base/web/js/modal/modal.js index c81274337f41..7291d5f6ba2f 100644 --- a/app/code/Magento/Ui/view/base/web/js/modal/modal.js +++ b/app/code/Magento/Ui/view/base/web/js/modal/modal.js @@ -14,7 +14,8 @@ define([ 'text!ui/template/modal/modal-slide.html', 'text!ui/template/modal/modal-custom.html', 'Magento_Ui/js/lib/key-codes', - 'jquery/ui', + 'jquery-ui-modules/widget', + 'jquery-ui-modules/core', 'mage/translate' ], function ($, _, template, popupTpl, slideTpl, customTpl, keyCodes) { 'use strict'; diff --git a/app/code/Magento/Wishlist/view/frontend/web/js/add-to-wishlist.js b/app/code/Magento/Wishlist/view/frontend/web/js/add-to-wishlist.js index b38c5c2cda3a..b639e859766f 100644 --- a/app/code/Magento/Wishlist/view/frontend/web/js/add-to-wishlist.js +++ b/app/code/Magento/Wishlist/view/frontend/web/js/add-to-wishlist.js @@ -5,7 +5,8 @@ define([ 'jquery', - 'jquery/ui' + 'jquery-ui-modules/widget', + 'jquery-ui-modules/core' ], function ($) { 'use strict'; diff --git a/lib/internal/Magento/Framework/Data/Form/Element/Editablemultiselect.php b/lib/internal/Magento/Framework/Data/Form/Element/Editablemultiselect.php index 3c03155fb163..c89bf9e38d40 100644 --- a/lib/internal/Magento/Framework/Data/Form/Element/Editablemultiselect.php +++ b/lib/internal/Magento/Framework/Data/Form/Element/Editablemultiselect.php @@ -78,7 +78,8 @@ public function getElementHtml() <script type='text/javascript'> require([ 'jquery', - 'jquery/ui' + 'jquery-ui-modules/widget', + 'jquery-ui-modules/core' ], function( $ ){ function isResolved(){ diff --git a/lib/web/jquery/fileUploader/jquery.fileupload.js b/lib/web/jquery/fileUploader/jquery.fileupload.js index 8b73c9fbc45c..1aff55e986c5 100644 --- a/lib/web/jquery/fileUploader/jquery.fileupload.js +++ b/lib/web/jquery/fileUploader/jquery.fileupload.js @@ -18,7 +18,8 @@ // Register as an anonymous AMD module: define([ 'jquery', - 'jquery/ui', + 'jquery-ui-modules/widget', + 'jquery-ui-modules/core', 'jquery/fileUploader/jquery.iframe-transport' ], factory); } else { diff --git a/lib/web/mage/calendar.js b/lib/web/mage/calendar.js index a9ccf2cf787f..54bb55acc864 100644 --- a/lib/web/mage/calendar.js +++ b/lib/web/mage/calendar.js @@ -10,8 +10,10 @@ if (typeof define === 'function' && define.amd) { define([ 'jquery', - 'jquery/ui', - 'jquery/jquery-ui-timepicker-addon' + 'jquery-ui-modules/widget', + 'jquery-ui-modules/core', + 'jquery-ui-modules/datepicker', + 'jquery-ui-modules/timepicker' ], factory); } else { factory(window.jQuery); diff --git a/lib/web/mage/collapsible.js b/lib/web/mage/collapsible.js index 3d283d102e32..6ed315aaf4fa 100644 --- a/lib/web/mage/collapsible.js +++ b/lib/web/mage/collapsible.js @@ -5,7 +5,8 @@ define([ 'jquery', - 'jquery/ui', + 'jquery-ui-modules/widget', + 'jquery-ui-modules/core', 'jquery/jquery-storageapi', 'mage/mage' ], function ($) { diff --git a/lib/web/mage/dataPost.js b/lib/web/mage/dataPost.js index cc56ee266e08..e5691ab677fd 100644 --- a/lib/web/mage/dataPost.js +++ b/lib/web/mage/dataPost.js @@ -7,7 +7,8 @@ define([ 'jquery', 'mage/template', 'Magento_Ui/js/modal/confirm', - 'jquery/ui' + 'jquery-ui-modules/widget', + 'jquery-ui-modules/core' ], function ($, mageTemplate, uiConfirm) { 'use strict'; diff --git a/lib/web/mage/deletable-item.js b/lib/web/mage/deletable-item.js index 5b42500e21c3..268ffe53cea8 100644 --- a/lib/web/mage/deletable-item.js +++ b/lib/web/mage/deletable-item.js @@ -8,7 +8,8 @@ */ define([ 'jquery', - 'jquery/ui' + 'jquery-ui-modules/widget', + 'jquery-ui-modules/core' ], function ($) { 'use strict'; diff --git a/lib/web/mage/dialog.js b/lib/web/mage/dialog.js index d90d5d6960d9..360f8e83dab5 100644 --- a/lib/web/mage/dialog.js +++ b/lib/web/mage/dialog.js @@ -8,7 +8,7 @@ */ define([ 'jquery', - 'jquery/ui' + 'jquery-ui-modules/dialog' ], function ($) { 'use strict'; diff --git a/lib/web/mage/dropdown.js b/lib/web/mage/dropdown.js index 389c083e4b4c..1f67afa415a7 100644 --- a/lib/web/mage/dropdown.js +++ b/lib/web/mage/dropdown.js @@ -5,7 +5,7 @@ define([ 'jquery', - 'jquery/ui', + 'jquery-ui-modules/dialog', 'mage/translate' ], function ($) { 'use strict'; diff --git a/lib/web/mage/edit-trigger.js b/lib/web/mage/edit-trigger.js index c2009e78c15e..1171822e73a6 100644 --- a/lib/web/mage/edit-trigger.js +++ b/lib/web/mage/edit-trigger.js @@ -13,7 +13,8 @@ define([ 'jquery', 'mage/template', - 'jquery/ui' + 'jquery-ui-modules/widget', + 'jquery-ui-modules/core' ], factory); } else { factory(root.jQuery, root.mageTemplate); diff --git a/lib/web/mage/fieldset-controls.js b/lib/web/mage/fieldset-controls.js index a95218e32b4a..5fa455acb1b0 100644 --- a/lib/web/mage/fieldset-controls.js +++ b/lib/web/mage/fieldset-controls.js @@ -8,7 +8,8 @@ */ define([ 'jquery', - 'jquery/ui' + 'jquery-ui-modules/widget', + 'jquery-ui-modules/core' ], function ($) { 'use strict'; diff --git a/lib/web/mage/item-table.js b/lib/web/mage/item-table.js index 7c1cdf4e47d9..1ca395d3894e 100644 --- a/lib/web/mage/item-table.js +++ b/lib/web/mage/item-table.js @@ -9,7 +9,8 @@ define([ 'jquery', 'mage/template', - 'jquery/ui' + 'jquery-ui-modules/widget', + 'jquery-ui-modules/core' ], function ($, mageTemplate) { 'use strict'; diff --git a/lib/web/mage/list.js b/lib/web/mage/list.js index 41ae951237a3..087e21101ddd 100644 --- a/lib/web/mage/list.js +++ b/lib/web/mage/list.js @@ -9,7 +9,8 @@ define([ 'jquery', 'mage/template', - 'jquery/ui' + 'jquery-ui-modules/widget', + 'jquery-ui-modules/core' ], function ($, mageTemplate) { 'use strict'; diff --git a/lib/web/mage/loader.js b/lib/web/mage/loader.js index f0274a5347ff..b3753388d39f 100644 --- a/lib/web/mage/loader.js +++ b/lib/web/mage/loader.js @@ -6,7 +6,8 @@ define([ 'jquery', 'mage/template', - 'jquery/ui', + 'jquery-ui-modules/widget', + 'jquery-ui-modules/core', 'mage/translate' ], function ($, mageTemplate) { 'use strict'; diff --git a/lib/web/mage/loader_old.js b/lib/web/mage/loader_old.js index 5233586149d9..46248a576991 100644 --- a/lib/web/mage/loader_old.js +++ b/lib/web/mage/loader_old.js @@ -10,7 +10,8 @@ define([ 'jquery', 'mage/template', - 'jquery/ui', + 'jquery-ui-modules/widget', + 'jquery-ui-modules/core', 'mage/translate' ], factory); } else { diff --git a/lib/web/mage/menu.js b/lib/web/mage/menu.js index b1875947cd54..80dc0413bf6c 100644 --- a/lib/web/mage/menu.js +++ b/lib/web/mage/menu.js @@ -6,7 +6,7 @@ define([ 'jquery', 'matchMedia', - 'jquery/ui', + 'jquery-ui-modules/menu', 'jquery/jquery.mobile.custom', 'mage/translate' ], function ($, mediaCheck) { diff --git a/lib/web/mage/multiselect.js b/lib/web/mage/multiselect.js index d911bf094333..4cc6d8fb252f 100644 --- a/lib/web/mage/multiselect.js +++ b/lib/web/mage/multiselect.js @@ -8,7 +8,8 @@ define([ 'jquery', 'text!mage/multiselect.html', 'Magento_Ui/js/modal/alert', - 'jquery/ui', + 'jquery-ui-modules/widget', + 'jquery-ui-modules/core', 'jquery/editableMultiselect/js/jquery.multiselect' ], function (_, $, searchTemplate, alert) { 'use strict'; diff --git a/lib/web/mage/popup-window.js b/lib/web/mage/popup-window.js index 37c3b27a4510..9e2d64afbc6d 100644 --- a/lib/web/mage/popup-window.js +++ b/lib/web/mage/popup-window.js @@ -5,7 +5,8 @@ define([ 'jquery', - 'jquery/ui' + 'jquery-ui-modules/widget', + 'jquery-ui-modules/core' ], function ($) { 'use strict'; diff --git a/lib/web/mage/redirect-url.js b/lib/web/mage/redirect-url.js index 8407e56ea071..c53de1917f79 100644 --- a/lib/web/mage/redirect-url.js +++ b/lib/web/mage/redirect-url.js @@ -5,7 +5,8 @@ define([ 'jquery', - 'jquery/ui' + 'jquery-ui-modules/widget', + 'jquery-ui-modules/core' ], function ($) { 'use strict'; diff --git a/lib/web/mage/sticky.js b/lib/web/mage/sticky.js index f98774e203ea..c377939fde39 100644 --- a/lib/web/mage/sticky.js +++ b/lib/web/mage/sticky.js @@ -5,7 +5,8 @@ define([ 'jquery', - 'jquery/ui' + 'jquery-ui-modules/widget', + 'jquery-ui-modules/core' ], function ($) { 'use strict'; diff --git a/lib/web/mage/tabs.js b/lib/web/mage/tabs.js index 65c452d33bf1..496a271c631f 100644 --- a/lib/web/mage/tabs.js +++ b/lib/web/mage/tabs.js @@ -5,7 +5,8 @@ define([ 'jquery', - 'jquery/ui', + 'jquery-ui-modules/widget', + 'jquery-ui-modules/core', 'mage/mage', 'mage/collapsible' ], function ($) { diff --git a/lib/web/mage/toggle.js b/lib/web/mage/toggle.js index b49657b99d84..73c04290396a 100644 --- a/lib/web/mage/toggle.js +++ b/lib/web/mage/toggle.js @@ -5,7 +5,8 @@ define([ 'jquery', - 'jquery/ui' + 'jquery-ui-modules/widget', + 'jquery-ui-modules/core' ], function ($) { 'use strict'; diff --git a/lib/web/mage/tooltip.js b/lib/web/mage/tooltip.js index 7aad682da70d..6dc6114cc70a 100644 --- a/lib/web/mage/tooltip.js +++ b/lib/web/mage/tooltip.js @@ -8,7 +8,7 @@ */ define([ 'jquery', - 'jquery/ui' + 'jquery-ui-modules/tooltip' ], function ($) { 'use strict'; diff --git a/lib/web/mage/translate-inline-vde.js b/lib/web/mage/translate-inline-vde.js index 38413ade46cc..485413e3c928 100644 --- a/lib/web/mage/translate-inline-vde.js +++ b/lib/web/mage/translate-inline-vde.js @@ -13,7 +13,8 @@ define([ 'jquery', 'mage/template', - 'jquery/ui', + 'jquery-ui-modules/widget', + 'jquery-ui-modules/core', 'mage/translate-inline', 'mage/translate' ], factory); diff --git a/lib/web/mage/translate-inline.js b/lib/web/mage/translate-inline.js index 141af6e141c3..cdd2b8ad322f 100644 --- a/lib/web/mage/translate-inline.js +++ b/lib/web/mage/translate-inline.js @@ -10,7 +10,7 @@ define([ 'jquery', 'mage/template', - 'jquery/ui', + 'jquery-ui-modules/dialog', 'mage/translate' ], factory); } else { diff --git a/lib/web/mage/validation.js b/lib/web/mage/validation.js index 619ad3fa7261..9e49d99da61a 100644 --- a/lib/web/mage/validation.js +++ b/lib/web/mage/validation.js @@ -10,7 +10,8 @@ define([ 'jquery', 'moment', - 'jquery/ui', + 'jquery-ui-modules/widget', + 'jquery-ui-modules/core', 'jquery/validate', 'mage/translate' ], factory); diff --git a/lib/web/mage/zoom.js b/lib/web/mage/zoom.js index 0082de721971..e8b17e08a07d 100644 --- a/lib/web/mage/zoom.js +++ b/lib/web/mage/zoom.js @@ -13,7 +13,8 @@ define([ 'jquery', 'mage/template', - 'jquery/ui' + 'jquery-ui-modules/widget', + 'jquery-ui-modules/core' ], factory); } else { factory(root.jQuery, root.mageTemplate); From de60b4def4b19ab7ded540dff99a617759e68c61 Mon Sep 17 00:00:00 2001 From: Stas Kozar <stas.kozar@transoftgroup.com> Date: Mon, 1 Jul 2019 12:59:23 +0300 Subject: [PATCH 012/191] MC-17753: Authorize.net Cannot read property 'length' of null --- .../ConfigureAuthorizenetAcceptjsWithoutRequiredOptionsTest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/Test/ConfigureAuthorizenetAcceptjsWithoutRequiredOptionsTest.xml b/app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/Test/ConfigureAuthorizenetAcceptjsWithoutRequiredOptionsTest.xml index df8787837414..cbb702c26f17 100644 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/Test/ConfigureAuthorizenetAcceptjsWithoutRequiredOptionsTest.xml +++ b/app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/Test/ConfigureAuthorizenetAcceptjsWithoutRequiredOptionsTest.xml @@ -26,6 +26,6 @@ </after> <amOnPage url="{{AdminConfigPaymentMethodsPage.url}}" stepKey="navigateToPaymentConfigurationPage"/> <actionGroup ref="EnableAuthorizenetAcceptjs" stepKey="enableAuthorizenetAcceptjs"/> - <actionGroup ref="AssertAuthorizenetAcceptjsRequiredFieldsValidationArePresentOnSave" stepKey="assertErrorMessages"/> + <actionGroup ref="AssertAuthorizenetAcceptjsRequiredFieldsValidationIsPresentOnSave" stepKey="assertErrorMessages"/> </test> </tests> From e83fc73cbff9ffb5ed5726632097fbacdc419b34 Mon Sep 17 00:00:00 2001 From: Stas Kozar <stas.kozar@transoftgroup.com> Date: Mon, 1 Jul 2019 15:21:51 +0300 Subject: [PATCH 013/191] MC-17765: Category A image replaced by uploading to Category B --- .../Category/Attribute/Backend/Image.php | 28 +++++++++++- .../Magento/Catalog/Model/ImageUploader.php | 7 +++ .../Category/Attribute/Backend/ImageTest.php | 44 ++++++++++++++----- .../Catalog/Model/ImageUploaderTest.php | 28 +++++++++++- 4 files changed, 93 insertions(+), 14 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Category/Attribute/Backend/Image.php b/app/code/Magento/Catalog/Model/Category/Attribute/Backend/Image.php index cd450e26cd83..d7fa32d5ea5c 100644 --- a/app/code/Magento/Catalog/Model/Category/Attribute/Backend/Image.php +++ b/app/code/Magento/Catalog/Model/Category/Attribute/Backend/Image.php @@ -5,7 +5,9 @@ */ namespace Magento\Catalog\Model\Category\Attribute\Backend; +use Magento\Catalog\Model\ImageUploader; use Magento\Framework\App\Filesystem\DirectoryList; +use Magento\Framework\File\Uploader; /** * Catalog category image attribute backend model @@ -84,6 +86,27 @@ private function getUploadedImageName($value) return ''; } + /** + * Check that image name exists in catalog/category directory and return new image name if it already exists. + * + * @param string $imageName + * @return string + */ + private function checkUniqueImageName(string $imageName): string + { + $imageUploader = $this->getImageUploader(); + $mediaDirectory = $this->_filesystem->getDirectoryWrite(DirectoryList::MEDIA); + $imageAbsolutePath = $mediaDirectory->getAbsolutePath( + $imageUploader->getBasePath() . DIRECTORY_SEPARATOR . $imageName + ); + + if ($mediaDirectory->isExist($imageAbsolutePath)) { + $imageName = Uploader::getNewFilename($imageAbsolutePath); + } + + return $imageName; + } + /** * Avoiding saving potential upload data to DB * Will set empty image attribute value if image was not uploaded @@ -103,6 +126,7 @@ public function beforeSave($object) } if ($imageName = $this->getUploadedImageName($value)) { + $imageName = $this->checkUniqueImageName($imageName); $object->setData($this->additionalData . $attributeName, $value); $object->setData($attributeName, $imageName); } elseif (!is_string($value)) { @@ -113,7 +137,7 @@ public function beforeSave($object) } /** - * @return \Magento\Catalog\Model\ImageUploader + * @return ImageUploader * * @deprecated 101.0.0 */ @@ -121,7 +145,7 @@ private function getImageUploader() { if ($this->imageUploader === null) { $this->imageUploader = \Magento\Framework\App\ObjectManager::getInstance() - ->get(\Magento\Catalog\CategoryImageUpload::class); + ->get(ImageUploader::class); } return $this->imageUploader; diff --git a/app/code/Magento/Catalog/Model/ImageUploader.php b/app/code/Magento/Catalog/Model/ImageUploader.php index b5ca0895d6d1..c990d3431310 100644 --- a/app/code/Magento/Catalog/Model/ImageUploader.php +++ b/app/code/Magento/Catalog/Model/ImageUploader.php @@ -5,6 +5,8 @@ */ namespace Magento\Catalog\Model; +use Magento\Framework\File\Uploader; + /** * Catalog image uploader */ @@ -202,6 +204,11 @@ public function moveFileFromTmp($imageName) $baseImagePath = $this->getFilePath($basePath, $imageName); $baseTmpImagePath = $this->getFilePath($baseTmpPath, $imageName); + if ($this->mediaDirectory->isExist($baseImagePath)) { + $newImageName = Uploader::getNewFileName($this->mediaDirectory->getAbsolutePath($baseImagePath)); + $baseImagePath = $this->getFilePath($basePath, $newImageName); + } + try { $this->coreFileStorageDatabase->copyFile( $baseTmpImagePath, diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Category/Attribute/Backend/ImageTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Category/Attribute/Backend/ImageTest.php index f1672d842de4..4aecb8a61b97 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Category/Attribute/Backend/ImageTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Category/Attribute/Backend/ImageTest.php @@ -5,7 +5,9 @@ */ namespace Magento\Catalog\Test\Unit\Model\Category\Attribute\Backend; +use Magento\Catalog\Model\ImageUploader; use Magento\Framework\App\Filesystem\DirectoryList; +use Magento\Framework\Filesystem\Directory\WriteInterface; class ImageTest extends \PHPUnit\Framework\TestCase { @@ -67,7 +69,7 @@ protected function setUp() $this->imageUploader = $this->createPartialMock( \Magento\Catalog\Model\ImageUploader::class, - ['moveFileFromTmp'] + ['moveFileFromTmp', 'getBasePath'] ); $this->filesystem = $this->getMockBuilder(\Magento\Framework\Filesystem::class)->disableOriginalConstructor() @@ -146,8 +148,21 @@ public function testBeforeSaveValueInvalid($value) */ public function testBeforeSaveAttributeFileName() { - $model = $this->objectManager->getObject(\Magento\Catalog\Model\Category\Attribute\Backend\Image::class); - $model->setAttribute($this->attribute); + $model = $this->setUpModelForAfterSave(); + $mediaDirectoryMock = $this->createMock(WriteInterface::class); + $this->filesystem->expects($this->once()) + ->method('getDirectoryWrite') + ->with(DirectoryList::MEDIA) + ->willReturn($mediaDirectoryMock); + $this->imageUploader->expects($this->once())->method('getBasePath')->willReturn('base/path'); + $mediaDirectoryMock->expects($this->once()) + ->method('getAbsolutePath') + ->with('base/path/test123.jpg') + ->willReturn('absolute/path/base/path/test123.jpg'); + $mediaDirectoryMock->expects($this->once()) + ->method('isExist') + ->with('absolute/path/base/path/test123.jpg') + ->willReturn(false); $object = new \Magento\Framework\DataObject([ 'test_attribute' => [ @@ -165,12 +180,14 @@ public function testBeforeSaveAttributeFileName() */ public function testBeforeSaveAttributeFileNameOutsideOfCategoryDir() { - $model = $this->objectManager->getObject(\Magento\Catalog\Model\Category\Attribute\Backend\Image::class, [ - 'filesystem' => $this->filesystem - ]); - + $model = $this->setUpModelForAfterSave(); $model->setAttribute($this->attribute); + $mediaDirectoryMock = $this->createMock(WriteInterface::class); + $this->filesystem->expects($this->once()) + ->method('getDirectoryWrite') + ->with(DirectoryList::MEDIA) + ->willReturn($mediaDirectoryMock); $this->filesystem ->expects($this->once()) ->method('getUri') @@ -200,9 +217,15 @@ public function testBeforeSaveAttributeFileNameOutsideOfCategoryDir() */ public function testBeforeSaveTemporaryAttribute() { - $model = $this->objectManager->getObject(\Magento\Catalog\Model\Category\Attribute\Backend\Image::class); + $model = $this->setUpModelForAfterSave(); $model->setAttribute($this->attribute); + $mediaDirectoryMock = $this->createMock(WriteInterface::class); + $this->filesystem->expects($this->once()) + ->method('getDirectoryWrite') + ->with(DirectoryList::MEDIA) + ->willReturn($mediaDirectoryMock); + $object = new \Magento\Framework\DataObject([ 'test_attribute' => [ ['name' => 'test123.jpg', 'tmp_name' => 'abc123', 'url' => 'http://www.example.com/test123.jpg'] @@ -246,7 +269,7 @@ private function setUpModelForAfterSave() $objectManagerMock->expects($this->any()) ->method('get') ->will($this->returnCallback(function ($class, $params = []) use ($imageUploaderMock) { - if ($class == \Magento\Catalog\CategoryImageUpload::class) { + if ($class == ImageUploader::class) { return $imageUploaderMock; } @@ -255,7 +278,8 @@ private function setUpModelForAfterSave() $model = $this->objectManager->getObject(\Magento\Catalog\Model\Category\Attribute\Backend\Image::class, [ 'objectManager' => $objectManagerMock, - 'logger' => $this->logger + 'logger' => $this->logger, + 'filesystem' => $this->filesystem, ]); $this->objectManager->setBackwardCompatibleProperty($model, 'imageUploader', $this->imageUploader); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ImageUploaderTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ImageUploaderTest.php index 04baef55863f..70ded157e621 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ImageUploaderTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ImageUploaderTest.php @@ -47,8 +47,8 @@ protected function setUp() $this->imageUploader = $this->objectManager->create( \Magento\Catalog\Model\ImageUploader::class, [ - 'baseTmpPath' => $this->mediaDirectory->getRelativePath('tmp'), - 'basePath' => __DIR__, + 'baseTmpPath' => $this->mediaDirectory->getRelativePath('catalog/tmp/category'), + 'basePath' => $this->mediaDirectory->getRelativePath('catalog/category'), 'allowedExtensions' => ['jpg', 'jpeg', 'gif', 'png'], 'allowedMimeTypes' => ['image/jpg', 'image/jpeg', 'image/gif', 'image/png'] ] @@ -79,6 +79,29 @@ public function testSaveFileToTmpDir(): void $this->assertTrue(is_file($this->mediaDirectory->getAbsolutePath($filePath))); } + public function testMoveFileFromTmp(): void + { + $fileName = 'magento_small_image.jpg'; + $expectedFileName = 'magento_small_image_1.jpg'; + $fixtureDir = realpath(__DIR__ . '/../_files'); + $tmpFilePath = $this->imageUploader->getBaseTmpPath() . DIRECTORY_SEPARATOR. $fileName; + $this->mediaDirectory->create($this->imageUploader->getBaseTmpPath()); + + copy($fixtureDir . DIRECTORY_SEPARATOR . $fileName, $this->mediaDirectory->getAbsolutePath($tmpFilePath)); + + $this->imageUploader->moveFileFromTmp($fileName); + + $filePath = $this->imageUploader->getBasePath() . DIRECTORY_SEPARATOR . $fileName; + $this->assertTrue(is_file($this->mediaDirectory->getAbsolutePath($filePath))); + + copy($fixtureDir . DIRECTORY_SEPARATOR . $fileName, $this->mediaDirectory->getAbsolutePath($tmpFilePath)); + + $this->imageUploader->moveFileFromTmp($fileName); + + $expectedFilePath = $this->imageUploader->getBasePath() . DIRECTORY_SEPARATOR . $expectedFileName; + $this->assertTrue(is_file($this->mediaDirectory->getAbsolutePath($expectedFilePath))); + } + /** * @expectedException \Magento\Framework\Exception\LocalizedException * @expectedExceptionMessage File validation failed. @@ -143,5 +166,6 @@ public static function tearDownAfterClass() /** @var \Magento\Framework\Filesystem\Directory\WriteInterface $mediaDirectory */ $mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA); $mediaDirectory->delete('tmp'); + $mediaDirectory->delete('catalog'); } } From 5a5a24667af26979eeaa273e2d3119355bc9cdce Mon Sep 17 00:00:00 2001 From: Stas Kozar <stas.kozar@transoftgroup.com> Date: Mon, 1 Jul 2019 15:32:11 +0300 Subject: [PATCH 014/191] MC-17765: Category A image replaced by uploading to Category B --- .../Catalog/Model/Category/Attribute/Backend/Image.php | 5 ++--- .../Test/Unit/Model/Category/Attribute/Backend/ImageTest.php | 3 +-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Category/Attribute/Backend/Image.php b/app/code/Magento/Catalog/Model/Category/Attribute/Backend/Image.php index d7fa32d5ea5c..ee76e43a1d5c 100644 --- a/app/code/Magento/Catalog/Model/Category/Attribute/Backend/Image.php +++ b/app/code/Magento/Catalog/Model/Category/Attribute/Backend/Image.php @@ -5,7 +5,6 @@ */ namespace Magento\Catalog\Model\Category\Attribute\Backend; -use Magento\Catalog\Model\ImageUploader; use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\File\Uploader; @@ -137,7 +136,7 @@ public function beforeSave($object) } /** - * @return ImageUploader + * @return \Magento\Catalog\Model\ImageUploader * * @deprecated 101.0.0 */ @@ -145,7 +144,7 @@ private function getImageUploader() { if ($this->imageUploader === null) { $this->imageUploader = \Magento\Framework\App\ObjectManager::getInstance() - ->get(ImageUploader::class); + ->get(\Magento\Catalog\CategoryImageUpload::class); } return $this->imageUploader; diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Category/Attribute/Backend/ImageTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Category/Attribute/Backend/ImageTest.php index 4aecb8a61b97..0574f3e77762 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Category/Attribute/Backend/ImageTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Category/Attribute/Backend/ImageTest.php @@ -5,7 +5,6 @@ */ namespace Magento\Catalog\Test\Unit\Model\Category\Attribute\Backend; -use Magento\Catalog\Model\ImageUploader; use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\Filesystem\Directory\WriteInterface; @@ -269,7 +268,7 @@ private function setUpModelForAfterSave() $objectManagerMock->expects($this->any()) ->method('get') ->will($this->returnCallback(function ($class, $params = []) use ($imageUploaderMock) { - if ($class == ImageUploader::class) { + if ($class == \Magento\Catalog\CategoryImageUpload::class) { return $imageUploaderMock; } From eefb665d53364d04f0c6ee46105bbb783f925231 Mon Sep 17 00:00:00 2001 From: Stas Kozar <stas.kozar@transoftgroup.com> Date: Tue, 2 Jul 2019 09:29:54 +0300 Subject: [PATCH 015/191] MC-17765: Category A image replaced by uploading to Category B --- .../Category/Attribute/Backend/Image.php | 8 +- .../Category/Attribute/Backend/ImageTest.php | 94 +++++++++++-------- 2 files changed, 58 insertions(+), 44 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Category/Attribute/Backend/Image.php b/app/code/Magento/Catalog/Model/Category/Attribute/Backend/Image.php index ee76e43a1d5c..f12066bbf771 100644 --- a/app/code/Magento/Catalog/Model/Category/Attribute/Backend/Image.php +++ b/app/code/Magento/Catalog/Model/Category/Attribute/Backend/Image.php @@ -70,8 +70,7 @@ public function __construct( } /** - * Gets image name from $value array. - * Will return empty string in a case when $value is not an array + * Gets image name from $value array. Will return empty string in a case when $value is not an array. * * @param array $value Attribute value * @return string @@ -107,8 +106,7 @@ private function checkUniqueImageName(string $imageName): string } /** - * Avoiding saving potential upload data to DB - * Will set empty image attribute value if image was not uploaded + * Avoiding saving potential upload data to DB. Will set empty image attribute value if image was not uploaded. * * @param \Magento\Framework\DataObject $object * @return $this @@ -136,6 +134,8 @@ public function beforeSave($object) } /** + * Get image uploader. + * * @return \Magento\Catalog\Model\ImageUploader * * @deprecated 101.0.0 diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Category/Attribute/Backend/ImageTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Category/Attribute/Backend/ImageTest.php index 0574f3e77762..3705640a6eb3 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Category/Attribute/Backend/ImageTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Category/Attribute/Backend/ImageTest.php @@ -8,6 +8,10 @@ use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\Filesystem\Directory\WriteInterface; +/** + * Test for Magento\Catalog\Model\Category\Attribute\Backend\Image class. + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ class ImageTest extends \PHPUnit\Framework\TestCase { /** @@ -96,9 +100,7 @@ public function testBeforeSaveValueDeletion($value) $model = $this->objectManager->getObject(\Magento\Catalog\Model\Category\Attribute\Backend\Image::class); $model->setAttribute($this->attribute); - $object = new \Magento\Framework\DataObject([ - 'test_attribute' => $value - ]); + $object = new \Magento\Framework\DataObject(['test_attribute' => $value]); $model->beforeSave($object); @@ -133,9 +135,7 @@ public function testBeforeSaveValueInvalid($value) $model = $this->objectManager->getObject(\Magento\Catalog\Model\Category\Attribute\Backend\Image::class); $model->setAttribute($this->attribute); - $object = new \Magento\Framework\DataObject([ - 'test_attribute' => $value - ]); + $object = new \Magento\Framework\DataObject(['test_attribute' => $value]); $model->beforeSave($object); @@ -163,11 +163,13 @@ public function testBeforeSaveAttributeFileName() ->with('absolute/path/base/path/test123.jpg') ->willReturn(false); - $object = new \Magento\Framework\DataObject([ - 'test_attribute' => [ - ['name' => 'test123.jpg'] + $object = new \Magento\Framework\DataObject( + [ + 'test_attribute' => [ + ['name' => 'test123.jpg'], + ], ] - ]); + ); $model->beforeSave($object); @@ -193,14 +195,16 @@ public function testBeforeSaveAttributeFileNameOutsideOfCategoryDir() ->with(DirectoryList::MEDIA) ->willReturn('pub/media'); - $object = new \Magento\Framework\DataObject([ - 'test_attribute' => [ - [ - 'name' => '/test123.jpg', - 'url' => '/pub/media/wysiwyg/test123.jpg', - ] + $object = new \Magento\Framework\DataObject( + [ + 'test_attribute' => [ + [ + 'name' => '/test123.jpg', + 'url' => '/pub/media/wysiwyg/test123.jpg', + ], + ], ] - ]); + ); $model->beforeSave($object); @@ -225,17 +229,22 @@ public function testBeforeSaveTemporaryAttribute() ->with(DirectoryList::MEDIA) ->willReturn($mediaDirectoryMock); - $object = new \Magento\Framework\DataObject([ - 'test_attribute' => [ - ['name' => 'test123.jpg', 'tmp_name' => 'abc123', 'url' => 'http://www.example.com/test123.jpg'] + $object = new \Magento\Framework\DataObject( + [ + 'test_attribute' => [ + ['name' => 'test123.jpg', 'tmp_name' => 'abc123', 'url' => 'http://www.example.com/test123.jpg'], + ], ] - ]); + ); $model->beforeSave($object); - $this->assertEquals([ - ['name' => 'test123.jpg', 'tmp_name' => 'abc123', 'url' => 'http://www.example.com/test123.jpg'] - ], $object->getData('_additional_data_test_attribute')); + $this->assertEquals( + [ + ['name' => 'test123.jpg', 'tmp_name' => 'abc123', 'url' => 'http://www.example.com/test123.jpg'], + ], + $object->getData('_additional_data_test_attribute') + ); } /** @@ -246,9 +255,7 @@ public function testBeforeSaveAttributeStringValue() $model = $this->objectManager->getObject(\Magento\Catalog\Model\Category\Attribute\Backend\Image::class); $model->setAttribute($this->attribute); - $object = new \Magento\Framework\DataObject([ - 'test_attribute' => 'test123.jpg' - ]); + $object = new \Magento\Framework\DataObject(['test_attribute' => 'test123.jpg']); $model->beforeSave($object); @@ -267,19 +274,26 @@ private function setUpModelForAfterSave() $objectManagerMock->expects($this->any()) ->method('get') - ->will($this->returnCallback(function ($class, $params = []) use ($imageUploaderMock) { - if ($class == \Magento\Catalog\CategoryImageUpload::class) { - return $imageUploaderMock; - } - - return $this->objectManager->get($class, $params); - })); - - $model = $this->objectManager->getObject(\Magento\Catalog\Model\Category\Attribute\Backend\Image::class, [ - 'objectManager' => $objectManagerMock, - 'logger' => $this->logger, - 'filesystem' => $this->filesystem, - ]); + ->will( + $this->returnCallback( + function ($class, $params = []) use ($imageUploaderMock) { + if ($class == \Magento\Catalog\CategoryImageUpload::class) { + return $imageUploaderMock; + } + + return $this->objectManager->get($class, $params); + } + ) + ); + + $model = $this->objectManager->getObject( + \Magento\Catalog\Model\Category\Attribute\Backend\Image::class, + [ + 'objectManager' => $objectManagerMock, + 'logger' => $this->logger, + 'filesystem' => $this->filesystem, + ] + ); $this->objectManager->setBackwardCompatibleProperty($model, 'imageUploader', $this->imageUploader); return $model->setAttribute($this->attribute); From 8cfdffdca145cb34db85045030e5a654a65dabc5 Mon Sep 17 00:00:00 2001 From: Stas Kozar <stas.kozar@transoftgroup.com> Date: Tue, 2 Jul 2019 17:09:10 +0300 Subject: [PATCH 016/191] MC-17765: Category A image replaced by uploading to Category B --- .../Category/Attribute/Backend/Image.php | 12 ++++---- .../Magento/Catalog/Model/ImageUploader.php | 14 +++++---- .../Catalog/Model/ImageUploaderTest.php | 25 ++++++---------- .../Catalog/_files/catalog_category_image.php | 29 +++++++++++++++++++ .../catalog_category_image_rollback.php | 27 +++++++++++++++++ .../_files/catalog_tmp_category_image.php | 28 ++++++++++++++++++ .../catalog_tmp_category_image_rollback.php | 27 +++++++++++++++++ 7 files changed, 135 insertions(+), 27 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/catalog_category_image.php create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/catalog_category_image_rollback.php create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/catalog_tmp_category_image.php create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/catalog_tmp_category_image_rollback.php diff --git a/app/code/Magento/Catalog/Model/Category/Attribute/Backend/Image.php b/app/code/Magento/Catalog/Model/Category/Attribute/Backend/Image.php index f12066bbf771..48d4c305fffa 100644 --- a/app/code/Magento/Catalog/Model/Category/Attribute/Backend/Image.php +++ b/app/code/Magento/Catalog/Model/Category/Attribute/Backend/Image.php @@ -70,7 +70,9 @@ public function __construct( } /** - * Gets image name from $value array. Will return empty string in a case when $value is not an array. + * Gets image name from $value array. + * + * Will return empty string in a case when $value is not an array. * * @param array $value Attribute value * @return string @@ -98,15 +100,15 @@ private function checkUniqueImageName(string $imageName): string $imageUploader->getBasePath() . DIRECTORY_SEPARATOR . $imageName ); - if ($mediaDirectory->isExist($imageAbsolutePath)) { - $imageName = Uploader::getNewFilename($imageAbsolutePath); - } + $imageName = Uploader::getNewFilename($imageAbsolutePath); return $imageName; } /** - * Avoiding saving potential upload data to DB. Will set empty image attribute value if image was not uploaded. + * Avoiding saving potential upload data to DB. + * + * Will set empty image attribute value if image was not uploaded. * * @param \Magento\Framework\DataObject $object * @return $this diff --git a/app/code/Magento/Catalog/Model/ImageUploader.php b/app/code/Magento/Catalog/Model/ImageUploader.php index c990d3431310..825823276261 100644 --- a/app/code/Magento/Catalog/Model/ImageUploader.php +++ b/app/code/Magento/Catalog/Model/ImageUploader.php @@ -201,14 +201,16 @@ public function moveFileFromTmp($imageName) $baseTmpPath = $this->getBaseTmpPath(); $basePath = $this->getBasePath(); - $baseImagePath = $this->getFilePath($basePath, $imageName); + $baseImagePath = $this->getFilePath( + $basePath, + Uploader::getNewFileName( + $this->mediaDirectory->getAbsolutePath( + $this->getFilePath($basePath, $imageName) + ) + ) + ); $baseTmpImagePath = $this->getFilePath($baseTmpPath, $imageName); - if ($this->mediaDirectory->isExist($baseImagePath)) { - $newImageName = Uploader::getNewFileName($this->mediaDirectory->getAbsolutePath($baseImagePath)); - $baseImagePath = $this->getFilePath($basePath, $newImageName); - } - try { $this->coreFileStorageDatabase->copyFile( $baseTmpImagePath, diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ImageUploaderTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ImageUploaderTest.php index 70ded157e621..24a23402bbe3 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ImageUploaderTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ImageUploaderTest.php @@ -79,27 +79,21 @@ public function testSaveFileToTmpDir(): void $this->assertTrue(is_file($this->mediaDirectory->getAbsolutePath($filePath))); } + /** + * Test that method rename files when move it with the same name into base directory. + * + * @return void + * @magentoDataFixture Magento/Catalog/_files/catalog_category_image.php + * @magentoDataFixture Magento/Catalog/_files/catalog_tmp_category_image.php + */ public function testMoveFileFromTmp(): void { - $fileName = 'magento_small_image.jpg'; $expectedFileName = 'magento_small_image_1.jpg'; - $fixtureDir = realpath(__DIR__ . '/../_files'); - $tmpFilePath = $this->imageUploader->getBaseTmpPath() . DIRECTORY_SEPARATOR. $fileName; - $this->mediaDirectory->create($this->imageUploader->getBaseTmpPath()); - - copy($fixtureDir . DIRECTORY_SEPARATOR . $fileName, $this->mediaDirectory->getAbsolutePath($tmpFilePath)); - - $this->imageUploader->moveFileFromTmp($fileName); - - $filePath = $this->imageUploader->getBasePath() . DIRECTORY_SEPARATOR . $fileName; - $this->assertTrue(is_file($this->mediaDirectory->getAbsolutePath($filePath))); - - copy($fixtureDir . DIRECTORY_SEPARATOR . $fileName, $this->mediaDirectory->getAbsolutePath($tmpFilePath)); - $this->imageUploader->moveFileFromTmp($fileName); + $this->imageUploader->moveFileFromTmp('magento_small_image.jpg'); $expectedFilePath = $this->imageUploader->getBasePath() . DIRECTORY_SEPARATOR . $expectedFileName; - $this->assertTrue(is_file($this->mediaDirectory->getAbsolutePath($expectedFilePath))); + $this->assertFileExists($this->mediaDirectory->getAbsolutePath($expectedFilePath)); } /** @@ -166,6 +160,5 @@ public static function tearDownAfterClass() /** @var \Magento\Framework\Filesystem\Directory\WriteInterface $mediaDirectory */ $mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA); $mediaDirectory->delete('tmp'); - $mediaDirectory->delete('catalog'); } } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/catalog_category_image.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/catalog_category_image.php new file mode 100644 index 000000000000..8000c9032f0c --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/catalog_category_image.php @@ -0,0 +1,29 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Framework\App\Filesystem\DirectoryList; + +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + +/** @var $mediaDirectory \Magento\Framework\Filesystem\Directory\WriteInterface */ +$mediaDirectory = $objectManager->get(\Magento\Framework\Filesystem::class) + ->getDirectoryWrite(DirectoryList::MEDIA); +/** @var $imageUploader \Magento\Catalog\Model\ImageUploader */ +$imageUploader = $objectManager->create( + \Magento\Catalog\Model\ImageUploader::class, + [ + 'baseTmpPath' => $mediaDirectory->getRelativePath('catalog/tmp/category'), + 'basePath' => $mediaDirectory->getRelativePath('catalog/category'), + 'allowedExtensions' => ['jpg', 'jpeg', 'gif', 'png'], + 'allowedMimeTypes' => ['image/jpg', 'image/jpeg', 'image/gif', 'image/png'] + ] +); +$fileName = 'magento_small_image.jpg'; +$filePath = $imageUploader->getBasePath() . DIRECTORY_SEPARATOR. $fileName; +$mediaDirectory->create($imageUploader->getBasePath()); + +copy(__DIR__ . DIRECTORY_SEPARATOR . $fileName, $mediaDirectory->getAbsolutePath($filePath)); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/catalog_category_image_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/catalog_category_image_rollback.php new file mode 100644 index 000000000000..37a20b94efa0 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/catalog_category_image_rollback.php @@ -0,0 +1,27 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Framework\App\Filesystem\DirectoryList; + +/** @var \Magento\Framework\Filesystem\Directory\WriteInterface $mediaDirectory */ +$mediaDirectory = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( + \Magento\Framework\Filesystem::class +)->getDirectoryWrite( + DirectoryList::MEDIA +); +/** @var $imageUploader \Magento\Catalog\Model\ImageUploader */ +$imageUploader = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + \Magento\Catalog\Model\ImageUploader::class, + [ + 'baseTmpPath' => $mediaDirectory->getRelativePath('catalog/tmp/category'), + 'basePath' => $mediaDirectory->getRelativePath('catalog/category'), + 'allowedExtensions' => ['jpg', 'jpeg', 'gif', 'png'], + 'allowedMimeTypes' => ['image/jpg', 'image/jpeg', 'image/gif', 'image/png'] + ] +); + +$mediaDirectory->delete($imageUploader->getBasePath()); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/catalog_tmp_category_image.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/catalog_tmp_category_image.php new file mode 100644 index 000000000000..6953753f6b64 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/catalog_tmp_category_image.php @@ -0,0 +1,28 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Framework\App\Filesystem\DirectoryList; + +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + +/** @var $mediaDirectory \Magento\Framework\Filesystem\Directory\WriteInterface */ +$mediaDirectory = $objectManager->get(\Magento\Framework\Filesystem::class) + ->getDirectoryWrite(DirectoryList::MEDIA); +$imageUploader = $objectManager->create( + \Magento\Catalog\Model\ImageUploader::class, + [ + 'baseTmpPath' => $mediaDirectory->getRelativePath('catalog/tmp/category'), + 'basePath' => $mediaDirectory->getRelativePath('catalog/category'), + 'allowedExtensions' => ['jpg', 'jpeg', 'gif', 'png'], + 'allowedMimeTypes' => ['image/jpg', 'image/jpeg', 'image/gif', 'image/png'] + ] +); +$fileName = 'magento_small_image.jpg'; +$tmpFilePath = $imageUploader->getBaseTmpPath() . DIRECTORY_SEPARATOR. $fileName; +$mediaDirectory->create($imageUploader->getBaseTmpPath()); + +copy(__DIR__ . DIRECTORY_SEPARATOR . $fileName, $mediaDirectory->getAbsolutePath($tmpFilePath)); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/catalog_tmp_category_image_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/catalog_tmp_category_image_rollback.php new file mode 100644 index 000000000000..cc8e9099d0e8 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/catalog_tmp_category_image_rollback.php @@ -0,0 +1,27 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Framework\App\Filesystem\DirectoryList; + +/** @var \Magento\Framework\Filesystem\Directory\WriteInterface $mediaDirectory */ +$mediaDirectory = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( + \Magento\Framework\Filesystem::class +)->getDirectoryWrite( + DirectoryList::MEDIA +); +/** @var $imageUploader \Magento\Catalog\Model\ImageUploader */ +$imageUploader = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + \Magento\Catalog\Model\ImageUploader::class, + [ + 'baseTmpPath' => $mediaDirectory->getRelativePath('catalog/tmp/category'), + 'basePath' => $mediaDirectory->getRelativePath('catalog/category'), + 'allowedExtensions' => ['jpg', 'jpeg', 'gif', 'png'], + 'allowedMimeTypes' => ['image/jpg', 'image/jpeg', 'image/gif', 'image/png'] + ] +); + +$mediaDirectory->delete($imageUploader->getBaseTmpPath()); From 573798c6f0b5f1eb5cb9e3868cf05b25b639fbf7 Mon Sep 17 00:00:00 2001 From: Stas Kozar <stas.kozar@transoftgroup.com> Date: Wed, 3 Jul 2019 10:17:52 +0300 Subject: [PATCH 017/191] MC-17765: Category A image replaced by uploading to Category B --- .../Model/Category/Attribute/Backend/ImageTest.php | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Category/Attribute/Backend/ImageTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Category/Attribute/Backend/ImageTest.php index 3705640a6eb3..dc74cdfc642e 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Category/Attribute/Backend/ImageTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Category/Attribute/Backend/ImageTest.php @@ -158,10 +158,6 @@ public function testBeforeSaveAttributeFileName() ->method('getAbsolutePath') ->with('base/path/test123.jpg') ->willReturn('absolute/path/base/path/test123.jpg'); - $mediaDirectoryMock->expects($this->once()) - ->method('isExist') - ->with('absolute/path/base/path/test123.jpg') - ->willReturn(false); $object = new \Magento\Framework\DataObject( [ @@ -194,12 +190,15 @@ public function testBeforeSaveAttributeFileNameOutsideOfCategoryDir() ->method('getUri') ->with(DirectoryList::MEDIA) ->willReturn('pub/media'); + $mediaDirectoryMock->expects($this->once()) + ->method('getAbsolutePath') + ->willReturn('/pub/media/wysiwyg/test123.jpg'); $object = new \Magento\Framework\DataObject( [ 'test_attribute' => [ [ - 'name' => '/test123.jpg', + 'name' => 'test123.jpg', 'url' => '/pub/media/wysiwyg/test123.jpg', ], ], @@ -208,7 +207,7 @@ public function testBeforeSaveAttributeFileNameOutsideOfCategoryDir() $model->beforeSave($object); - $this->assertEquals('/pub/media/wysiwyg/test123.jpg', $object->getTestAttribute()); + $this->assertEquals('test123.jpg', $object->getTestAttribute()); $this->assertEquals( [['name' => '/pub/media/wysiwyg/test123.jpg', 'url' => '/pub/media/wysiwyg/test123.jpg']], $object->getData('_additional_data_test_attribute') From 666e95bb2ebe18bec1fdf5ef3a89a3fb338ca008 Mon Sep 17 00:00:00 2001 From: Stas Kozar <stas.kozar@transoftgroup.com> Date: Wed, 3 Jul 2019 10:58:29 +0300 Subject: [PATCH 018/191] MC-17765: Category A image replaced by uploading to Category B --- .../Magento/Catalog/Model/ImageUploaderTest.php | 4 +++- .../Catalog/_files/catalog_category_image.php | 14 ++------------ .../_files/catalog_category_image_rollback.php | 12 +----------- .../Catalog/_files/catalog_tmp_category_image.php | 13 ++----------- .../_files/catalog_tmp_category_image_rollback.php | 12 +----------- 5 files changed, 9 insertions(+), 46 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ImageUploaderTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ImageUploaderTest.php index 24a23402bbe3..bc517563461a 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ImageUploaderTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ImageUploaderTest.php @@ -89,10 +89,12 @@ public function testSaveFileToTmpDir(): void public function testMoveFileFromTmp(): void { $expectedFileName = 'magento_small_image_1.jpg'; + $expectedFilePath = $this->imageUploader->getBasePath() . DIRECTORY_SEPARATOR . $expectedFileName; + + $this->assertFileNotExists($this->mediaDirectory->getAbsolutePath($expectedFilePath)); $this->imageUploader->moveFileFromTmp('magento_small_image.jpg'); - $expectedFilePath = $this->imageUploader->getBasePath() . DIRECTORY_SEPARATOR . $expectedFileName; $this->assertFileExists($this->mediaDirectory->getAbsolutePath($expectedFilePath)); } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/catalog_category_image.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/catalog_category_image.php index 8000c9032f0c..0764d466898b 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/catalog_category_image.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/catalog_category_image.php @@ -12,18 +12,8 @@ /** @var $mediaDirectory \Magento\Framework\Filesystem\Directory\WriteInterface */ $mediaDirectory = $objectManager->get(\Magento\Framework\Filesystem::class) ->getDirectoryWrite(DirectoryList::MEDIA); -/** @var $imageUploader \Magento\Catalog\Model\ImageUploader */ -$imageUploader = $objectManager->create( - \Magento\Catalog\Model\ImageUploader::class, - [ - 'baseTmpPath' => $mediaDirectory->getRelativePath('catalog/tmp/category'), - 'basePath' => $mediaDirectory->getRelativePath('catalog/category'), - 'allowedExtensions' => ['jpg', 'jpeg', 'gif', 'png'], - 'allowedMimeTypes' => ['image/jpg', 'image/jpeg', 'image/gif', 'image/png'] - ] -); $fileName = 'magento_small_image.jpg'; -$filePath = $imageUploader->getBasePath() . DIRECTORY_SEPARATOR. $fileName; -$mediaDirectory->create($imageUploader->getBasePath()); +$filePath = 'catalog/category/' . $fileName; +$mediaDirectory->create('catalog/category'); copy(__DIR__ . DIRECTORY_SEPARATOR . $fileName, $mediaDirectory->getAbsolutePath($filePath)); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/catalog_category_image_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/catalog_category_image_rollback.php index 37a20b94efa0..977572bbb51f 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/catalog_category_image_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/catalog_category_image_rollback.php @@ -13,15 +13,5 @@ )->getDirectoryWrite( DirectoryList::MEDIA ); -/** @var $imageUploader \Magento\Catalog\Model\ImageUploader */ -$imageUploader = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( - \Magento\Catalog\Model\ImageUploader::class, - [ - 'baseTmpPath' => $mediaDirectory->getRelativePath('catalog/tmp/category'), - 'basePath' => $mediaDirectory->getRelativePath('catalog/category'), - 'allowedExtensions' => ['jpg', 'jpeg', 'gif', 'png'], - 'allowedMimeTypes' => ['image/jpg', 'image/jpeg', 'image/gif', 'image/png'] - ] -); -$mediaDirectory->delete($imageUploader->getBasePath()); +$mediaDirectory->delete('catalog/category'); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/catalog_tmp_category_image.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/catalog_tmp_category_image.php index 6953753f6b64..2562acdda2dc 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/catalog_tmp_category_image.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/catalog_tmp_category_image.php @@ -12,17 +12,8 @@ /** @var $mediaDirectory \Magento\Framework\Filesystem\Directory\WriteInterface */ $mediaDirectory = $objectManager->get(\Magento\Framework\Filesystem::class) ->getDirectoryWrite(DirectoryList::MEDIA); -$imageUploader = $objectManager->create( - \Magento\Catalog\Model\ImageUploader::class, - [ - 'baseTmpPath' => $mediaDirectory->getRelativePath('catalog/tmp/category'), - 'basePath' => $mediaDirectory->getRelativePath('catalog/category'), - 'allowedExtensions' => ['jpg', 'jpeg', 'gif', 'png'], - 'allowedMimeTypes' => ['image/jpg', 'image/jpeg', 'image/gif', 'image/png'] - ] -); $fileName = 'magento_small_image.jpg'; -$tmpFilePath = $imageUploader->getBaseTmpPath() . DIRECTORY_SEPARATOR. $fileName; -$mediaDirectory->create($imageUploader->getBaseTmpPath()); +$tmpFilePath = 'catalog/tmp/category/' . $fileName; +$mediaDirectory->create('catalog/tmp/category'); copy(__DIR__ . DIRECTORY_SEPARATOR . $fileName, $mediaDirectory->getAbsolutePath($tmpFilePath)); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/catalog_tmp_category_image_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/catalog_tmp_category_image_rollback.php index cc8e9099d0e8..a85d349620f6 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/catalog_tmp_category_image_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/catalog_tmp_category_image_rollback.php @@ -13,15 +13,5 @@ )->getDirectoryWrite( DirectoryList::MEDIA ); -/** @var $imageUploader \Magento\Catalog\Model\ImageUploader */ -$imageUploader = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( - \Magento\Catalog\Model\ImageUploader::class, - [ - 'baseTmpPath' => $mediaDirectory->getRelativePath('catalog/tmp/category'), - 'basePath' => $mediaDirectory->getRelativePath('catalog/category'), - 'allowedExtensions' => ['jpg', 'jpeg', 'gif', 'png'], - 'allowedMimeTypes' => ['image/jpg', 'image/jpeg', 'image/gif', 'image/png'] - ] -); -$mediaDirectory->delete($imageUploader->getBaseTmpPath()); +$mediaDirectory->delete('catalog/tmp/category'); From c5b32c8729ea2f6f355184e7a46ded6bc8cc570c Mon Sep 17 00:00:00 2001 From: Stas Kozar <stas.kozar@transoftgroup.com> Date: Wed, 3 Jul 2019 16:57:08 +0300 Subject: [PATCH 019/191] MC-17765: Category A image replaced by uploading to Category B --- .../testsuite/Magento/Catalog/Model/ImageUploaderTest.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ImageUploaderTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ImageUploaderTest.php index bc517563461a..66d04870b3f0 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ImageUploaderTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ImageUploaderTest.php @@ -88,8 +88,7 @@ public function testSaveFileToTmpDir(): void */ public function testMoveFileFromTmp(): void { - $expectedFileName = 'magento_small_image_1.jpg'; - $expectedFilePath = $this->imageUploader->getBasePath() . DIRECTORY_SEPARATOR . $expectedFileName; + $expectedFilePath = $this->imageUploader->getBasePath() . DIRECTORY_SEPARATOR . 'magento_small_image_1.jpg'; $this->assertFileNotExists($this->mediaDirectory->getAbsolutePath($expectedFilePath)); From 2f8764a0979c1b8f784e7373e9cdc4fefb2114f3 Mon Sep 17 00:00:00 2001 From: Stas Kozar <stas.kozar@transoftgroup.com> Date: Wed, 3 Jul 2019 17:00:19 +0300 Subject: [PATCH 020/191] MC-17765: Category A image replaced by uploading to Category B --- .../testsuite/Magento/Catalog/Model/ImageUploaderTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ImageUploaderTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ImageUploaderTest.php index 66d04870b3f0..569cf2357675 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ImageUploaderTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ImageUploaderTest.php @@ -47,8 +47,8 @@ protected function setUp() $this->imageUploader = $this->objectManager->create( \Magento\Catalog\Model\ImageUploader::class, [ - 'baseTmpPath' => $this->mediaDirectory->getRelativePath('catalog/tmp/category'), - 'basePath' => $this->mediaDirectory->getRelativePath('catalog/category'), + 'baseTmpPath' => 'catalog/tmp/category', + 'basePath' => 'catalog/category', 'allowedExtensions' => ['jpg', 'jpeg', 'gif', 'png'], 'allowedMimeTypes' => ['image/jpg', 'image/jpeg', 'image/gif', 'image/png'] ] From 683a87da9f935122fdbb6e00431b0472d732d56e Mon Sep 17 00:00:00 2001 From: DianaRusin <rusind95@gmail.com> Date: Mon, 15 Jul 2019 11:15:28 +0300 Subject: [PATCH 021/191] MC-17003: Update Totals button is missing from Credit Memo page --- .../Order/Creditmemo/Create/Adjustments.php | 16 +++++ .../Order/Creditmemo/Create/Items.php | 15 ++++ .../AdminCreditMemoActionGroup.xml | 23 ++++++- .../Section/AdminCreditMemoTotalSection.xml | 1 + ...dminCheckingCreditMemoUpdateTotalsTest.xml | 69 +++++++++++++++++++ .../order/creditmemo/create/items.phtml | 5 +- .../web/css/source/module/order/_total.less | 4 ++ .../Adminhtml/Order/Creditmemo/Totals.php | 68 ++++++++++++++++++ .../Test/TestStep/CreateCreditMemoStep.php | 33 ++++++++- 9 files changed, 230 insertions(+), 4 deletions(-) create mode 100644 app/code/Magento/Sales/Test/Mftf/Test/AdminCheckingCreditMemoUpdateTotalsTest.xml diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/Create/Adjustments.php b/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/Create/Adjustments.php index 50d29c195968..1210391f70dd 100644 --- a/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/Create/Adjustments.php +++ b/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/Create/Adjustments.php @@ -111,4 +111,20 @@ public function getShippingLabel() } return $label; } + + /** + * Get update totals url. + * + * @return string + */ + public function getUpdateTotalsUrl(): string + { + return $this->getUrl( + 'sales/*/updateQty', + [ + 'order_id' => $this->getSource()->getOrderId(), + 'invoice_id' => $this->getRequest()->getParam('invoice_id', null), + ] + ); + } } diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/Create/Items.php b/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/Create/Items.php index 65163f9ed5d8..3962cbb3da5c 100644 --- a/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/Create/Items.php +++ b/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/Create/Items.php @@ -58,6 +58,11 @@ protected function _prepareLayout() \Magento\Backend\Block\Widget\Button::class, ['label' => __('Update Qty\'s'), 'class' => 'update-button', 'onclick' => $onclick] ); + $this->addChild( + 'update_totals_button', + \Magento\Backend\Block\Widget\Button::class, + ['label' => __('Update Totals'), 'class' => 'update-totals-button secondary', 'onclick' => $onclick] + ); if ($this->getCreditmemo()->canRefund()) { if ($this->getCreditmemo()->getInvoice() && $this->getCreditmemo()->getInvoice()->getTransactionId()) { @@ -176,6 +181,16 @@ public function getUpdateButtonHtml() return $this->getChildHtml('update_button'); } + /** + * Get update totals button html + * + * @return string + */ + public function getUpdateTotalsButtonHtml(): string + { + return $this->getChildHtml('update_totals_button'); + } + /** * Get update url * diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminCreditMemoActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminCreditMemoActionGroup.xml index 58c7752626c8..fded6f904e57 100644 --- a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminCreditMemoActionGroup.xml +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminCreditMemoActionGroup.xml @@ -37,4 +37,25 @@ </arguments> <see selector="{{AdminCreditMemoItemsSection.skuColumn}}" userInput="{{product.sku}}" stepKey="seeProductSkuInGrid"/> </actionGroup> -</actionGroups> \ No newline at end of file + <actionGroup name="StartToCreateCreditMemoActionGroup"> + <arguments> + <argument name="orderId" type="string"/> + </arguments> + <amOnPage url="{{AdminOrderPage.url(orderId)}}" stepKey="navigateToOrderPage"/> + <click selector="{{AdminOrderDetailsMainActionsSection.creditMemo}}" stepKey="clickCreditMemo"/> + <see selector="{{AdminHeaderSection.pageTitle}}" userInput="New Memo" stepKey="seeNewMemoPageTitle"/> + </actionGroup> + <actionGroup name="SubmitCreditMemoActionGroup"> + <waitForElementVisible selector="{{AdminCreditMemoTotalSection.submitRefundOffline}}" stepKey="waitButtonEnabled"/> + <click selector="{{AdminCreditMemoTotalSection.submitRefundOffline}}" stepKey="clickSubmitCreditMemo"/> + <waitForElementVisible selector="{{AdminMessagesSection.successMessage}}" stepKey="waitForMessageAppears"/> + <see selector="{{AdminMessagesSection.successMessage}}" userInput="You created the credit memo." stepKey="seeCreditMemoCreateSuccess"/> + <grabFromCurrentUrl regex="~/order_id/(\d+)/~" stepKey="grabOrderId"/> + <seeInCurrentUrl url="{{AdminOrderDetailsPage.url}}$grabOrderId" stepKey="seeViewOrderPageCreditMemo"/> + </actionGroup> + <actionGroup name="UpdateCreditMemoTotalsActionGroup"> + <waitForElementVisible selector="{{AdminCreditMemoTotalSection.updateTotals}}" stepKey="waitUpdateTotalsButtonEnabled"/> + <click selector="{{AdminCreditMemoTotalSection.updateTotals}}" stepKey="clickUpdateTotals"/> + <waitForLoadingMaskToDisappear stepKey="waitForUpdateTotals"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Sales/Test/Mftf/Section/AdminCreditMemoTotalSection.xml b/app/code/Magento/Sales/Test/Mftf/Section/AdminCreditMemoTotalSection.xml index ee8cf05e3d7c..27612cc079b1 100644 --- a/app/code/Magento/Sales/Test/Mftf/Section/AdminCreditMemoTotalSection.xml +++ b/app/code/Magento/Sales/Test/Mftf/Section/AdminCreditMemoTotalSection.xml @@ -22,5 +22,6 @@ <element name="creditMemoItem" type="text" selector="#sales_order_view_tabs_order_creditmemos"/> <element name="viewMemo" type="text" selector="div#sales_order_view_tabs_order_creditmemos_content a.action-menu-item"/> <element name="refundOffline" type="button" selector=".order-totals-actions button[data-ui-id='order-items-submit-offline']"/> + <element name="updateTotals" type="button" selector=".update-totals-button" timeout="30"/> </section> </sections> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminCheckingCreditMemoUpdateTotalsTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminCheckingCreditMemoUpdateTotalsTest.xml new file mode 100644 index 000000000000..4b3698d89727 --- /dev/null +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminCheckingCreditMemoUpdateTotalsTest.xml @@ -0,0 +1,69 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminCheckingCreditMemoTotalsTest"> + <annotations> + <features value="CreditMemo"/> + <stories value="Create credit memo"/> + <title value="Checking Credit Memo Update Totals button"/> + <description value="Checking Credit Memo Update Totals button"/> + <severity value="MAJOR"/> + <testCaseId value="MC-18159"/> + <useCaseId value="MC-17003"/> + <group value="sales"/> + </annotations> + <before> + <!--Create category--> + <createData entity="_defaultCategory" stepKey="createCategory"/> + <!--Create simple product--> + <createData entity="_defaultProduct" stepKey="createSimpleProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + <!--Create customer--> + <createData entity="Simple_US_CA_Customer" stepKey="createCustomer"/> + <!--Login to admin page--> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + </before> + <after> + <!--Delete category--> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + <!--Delete simple product--> + <deleteData createDataKey="createSimpleProduct" stepKey="deleteSimpleProduct"/> + <!--Delete customer--> + <deleteData createDataKey="createCustomer" stepKey="deleteCustomer"/> + <actionGroup ref="logout" stepKey="logout"/> + </after> + + <actionGroup ref="CreateOrderActionGroup" stepKey="createOrder"> + <argument name="product" value="$$createSimpleProduct$$"/> + <argument name="customer" value="$$createCustomer$$"/> + </actionGroup> + <grabFromCurrentUrl regex="~/order_id/(\d+)/~" stepKey="grabOrderId"/> + <!--Create invoice--> + <actionGroup ref="StartCreateInvoiceFromOrderPage" stepKey="startCreateInvoice"/> + <!--Submit invoice--> + <actionGroup ref="SubmitInvoice" stepKey="submitInvoice"/> + + <!--Create Credit Memo--> + <actionGroup ref="StartToCreateCreditMemoActionGroup" stepKey="startToCreateCreditMemo"> + <argument name="orderId" value="{$grabOrderId}"/> + </actionGroup> + <fillField selector="{{AdminCreditMemoTotalSection.refundShipping}}" userInput="0" stepKey="setRefundShipping"/> + <actionGroup ref="UpdateCreditMemoTotalsActionGroup" stepKey="updateCreditMemoTotals"/> + <actionGroup ref="SubmitCreditMemoActionGroup" stepKey="submitCreditMemo"/> + + <!--Go to Credit Memo tab--> + <click selector="{{AdminOrderDetailsOrderViewSection.creditMemos}}" stepKey="clickCreditMemosTab"/> + <waitForPageLoad stepKey="waitForCreditMemosGridToLoad"/> + + <!--Check refunded total --> + <see selector="{{AdminOrderCreditMemosTabSection.gridRow('1')}}" userInput="$123" stepKey="seeCreditMemoInGrid"/> + </test> +</tests> diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/create/items.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/create/items.phtml index 31d3b281532d..31aefd8d2ca5 100644 --- a/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/create/items.phtml +++ b/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/create/items.phtml @@ -100,6 +100,7 @@ <span class="title"><?= $block->escapeHtml(__('Refund Totals')) ?></span> </div> <?= $block->getChildHtml('creditmemo_totals') ?> + <div class="totals-actions"><?= $block->getUpdateTotalsButtonHtml() ?></div> <div class="order-totals-actions"> <div class="field choice admin__field admin__field-option field-append-comments"> <input id="notify_customer" @@ -139,8 +140,8 @@ require(['jquery'], function(jQuery){ //<![CDATA[ var submitButtons = jQuery('.submit-button'); -var updateButtons = jQuery('.update-button'); -var fields = jQuery('.qty-input'); +var updateButtons = jQuery('.update-button,.update-totals-button'); +var fields = jQuery('.qty-input,.order-subtotal-table input[type="text"]'); function enableButtons(buttons) { buttons.removeClass('disabled').prop('disabled', false); diff --git a/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_total.less b/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_total.less index f2369ad8f35e..6e663b15c89c 100644 --- a/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_total.less +++ b/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_total.less @@ -22,6 +22,10 @@ } } +.totals-actions { + text-align: right; +} + .order-totals-actions { margin-top: @indent__s; .actions { diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Creditmemo/Totals.php b/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Creditmemo/Totals.php index d98c5696c81f..2013c3590019 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Creditmemo/Totals.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Creditmemo/Totals.php @@ -27,6 +27,34 @@ class Totals extends \Magento\Sales\Test\Block\Adminhtml\Order\Totals */ protected $capture = '[name="invoice[capture_case]"]'; + /** + * Refund Shipping css selector. + * + * @var string + */ + private $refundShippingSelector = '//input[@id=\'shipping_amount\']'; + + /** + * Adjustment Refund css selector. + * + * @var string + */ + private $adjustmentRefundSelector = '//input[@id=\'adjustment_positive\']'; + + /** + * Adjustment Fee css selector. + * + * @var string + */ + private $adjustmentFeeSelector = '//input[@id=\'adjustment_negative\']'; + + /** + * 'Update Totals button css selector. + * + * @var string + */ + private $updateTotalsSelector = '.update-totals-button'; + /** * Submit invoice. * @@ -57,4 +85,44 @@ public function setCaptureOption($option) { $this->_rootElement->find($this->capture, Locator::SELECTOR_CSS, 'select')->setValue($option); } + + /** + * Get Refund Shipping input element. + * + * @return \Magento\Mtf\Client\ElementInterface + */ + public function getRefundShippingElement() + { + return $this->_rootElement->find($this->refundShippingSelector, Locator::SELECTOR_XPATH); + } + + /** + * Get Adjustment Refund input element. + * + * @return \Magento\Mtf\Client\ElementInterface + */ + public function getAdjustmentRefundElement() + { + return $this->_rootElement->find($this->adjustmentRefundSelector, Locator::SELECTOR_XPATH); + } + + /** + * Get Adjustment Fee input element. + * + * @return \Magento\Mtf\Client\ElementInterface + */ + public function getAdjustmentFeeElement() + { + return $this->_rootElement->find($this->adjustmentFeeSelector, Locator::SELECTOR_XPATH); + } + + /** + * Click update totals button. + * + * @return void + */ + public function clickUpdateTotals() + { + $this->_rootElement->find($this->updateTotalsSelector)->click(); + } } diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestStep/CreateCreditMemoStep.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestStep/CreateCreditMemoStep.php index 45298c5898c2..d001792d0a18 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestStep/CreateCreditMemoStep.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestStep/CreateCreditMemoStep.php @@ -95,8 +95,12 @@ public function run() if ($this->compare($items, $refundData)) { $this->orderCreditMemoNew->getFormBlock()->updateQty(); } - + $hasChangeTotals = $this->compareRefundTotalsData($refundData); $this->orderCreditMemoNew->getFormBlock()->fillFormData($refundData); + if ($hasChangeTotals) { + $this->orderCreditMemoNew->getTotalsBlock()->clickUpdateTotals(); + } + $this->orderCreditMemoNew->getFormBlock()->submit(); } @@ -116,4 +120,31 @@ protected function getCreditMemoIds() $this->salesOrderView->getOrderForm()->openTab('creditmemos'); return $this->salesOrderView->getOrderForm()->getTab('creditmemos')->getGridBlock()->getIds(); } + + /** + * Compare refund total items. + * + * @param array $data + * @return int + */ + private function compareRefundTotalsData($data) + { + $compareData = [ + 'shipping_amount' => + $this->orderCreditMemoNew->getTotalsBlock()->getRefundShippingElement()->getValue(), + 'adjustment_positive' => + $this->orderCreditMemoNew->getTotalsBlock()->getAdjustmentRefundElement()->getValue(), + 'adjustment_negative' => + $this->orderCreditMemoNew->getTotalsBlock()->getAdjustmentFeeElement()->getValue(), + ]; + + $count = 0; + foreach ($compareData as $key => $val) { + if (isset($data['form_data'][$key])) { + $count += ($val != $data['form_data'][$key] ? 1 : 0); + } + } + + return $count; + } } From ddff1b95b257cfa7cb53af67285b72d9f5c43fc3 Mon Sep 17 00:00:00 2001 From: Myroslav Dobra <dmaraptor@gmail.com> Date: Mon, 15 Jul 2019 12:01:26 +0300 Subject: [PATCH 022/191] MC-13909: [FT] CreateCmsPageEntityMultipleStoreViewsTest fails on variation CreateCmsPageEntityMultipleStoreViewsTestVariation1 --- .../TestCase/CreateCmsPageEntityMultipleStoreViewsTest.xml | 1 - .../Edit/Tab/ParametersType/RecentlyComparedProducts.xml | 4 ++-- .../Edit/Tab/ParametersType/RecentlyViewedProducts.xml | 4 ++-- .../app/Magento/Widget/Test/Block/Adminhtml/WidgetForm.xml | 4 ++-- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsPageEntityMultipleStoreViewsTest.xml b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsPageEntityMultipleStoreViewsTest.xml index 06fe76c5efd0..72a76dacc329 100644 --- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsPageEntityMultipleStoreViewsTest.xml +++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsPageEntityMultipleStoreViewsTest.xml @@ -8,7 +8,6 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Cms\Test\TestCase\CreateCmsPageEntityMultipleStoreViewsTest" summary="Page cache for different CMS pages on multiple store views" ticketId="MAGETWO-52467"> <variation name="CreateCmsPageEntityMultipleStoreViewsTestVariation1"> - <data name="issue" xsi:type="string">MC-13801: Test "Page cache for different CMS pages on multiple store views" fails on Jenkins</data> <data name="cmsPages/0/is_active" xsi:type="string">Yes</data> <data name="cmsPages/0/title" xsi:type="string">NewCmsPage</data> <data name="cmsPages/0/store_id/dataset" xsi:type="string">default</data> diff --git a/dev/tests/functional/tests/app/Magento/Widget/Test/Block/Adminhtml/Widget/Instance/Edit/Tab/ParametersType/RecentlyComparedProducts.xml b/dev/tests/functional/tests/app/Magento/Widget/Test/Block/Adminhtml/Widget/Instance/Edit/Tab/ParametersType/RecentlyComparedProducts.xml index 9da96ab4c8fc..efcf1c43d5d0 100644 --- a/dev/tests/functional/tests/app/Magento/Widget/Test/Block/Adminhtml/Widget/Instance/Edit/Tab/ParametersType/RecentlyComparedProducts.xml +++ b/dev/tests/functional/tests/app/Magento/Widget/Test/Block/Adminhtml/Widget/Instance/Edit/Tab/ParametersType/RecentlyComparedProducts.xml @@ -12,13 +12,13 @@ </page_size> <show_attributes> <selector> - .control [name="parameters[show_attributes][1]"] + .control [name^="parameters[show_attributes]["] </selector> <input>multiselect</input> </show_attributes> <show_buttons> <selector> - .control [name="parameters[show_buttons][2]"] + .control [name^="parameters[show_buttons]["] </selector> <input>multiselect</input> </show_buttons> diff --git a/dev/tests/functional/tests/app/Magento/Widget/Test/Block/Adminhtml/Widget/Instance/Edit/Tab/ParametersType/RecentlyViewedProducts.xml b/dev/tests/functional/tests/app/Magento/Widget/Test/Block/Adminhtml/Widget/Instance/Edit/Tab/ParametersType/RecentlyViewedProducts.xml index 9da96ab4c8fc..efcf1c43d5d0 100644 --- a/dev/tests/functional/tests/app/Magento/Widget/Test/Block/Adminhtml/Widget/Instance/Edit/Tab/ParametersType/RecentlyViewedProducts.xml +++ b/dev/tests/functional/tests/app/Magento/Widget/Test/Block/Adminhtml/Widget/Instance/Edit/Tab/ParametersType/RecentlyViewedProducts.xml @@ -12,13 +12,13 @@ </page_size> <show_attributes> <selector> - .control [name="parameters[show_attributes][1]"] + .control [name^="parameters[show_attributes]["] </selector> <input>multiselect</input> </show_attributes> <show_buttons> <selector> - .control [name="parameters[show_buttons][2]"] + .control [name^="parameters[show_buttons]["] </selector> <input>multiselect</input> </show_buttons> diff --git a/dev/tests/functional/tests/app/Magento/Widget/Test/Block/Adminhtml/WidgetForm.xml b/dev/tests/functional/tests/app/Magento/Widget/Test/Block/Adminhtml/WidgetForm.xml index 374b966861f6..f660de92a025 100644 --- a/dev/tests/functional/tests/app/Magento/Widget/Test/Block/Adminhtml/WidgetForm.xml +++ b/dev/tests/functional/tests/app/Magento/Widget/Test/Block/Adminhtml/WidgetForm.xml @@ -32,13 +32,13 @@ <page_size /> <show_attributes> <selector> - .control [name="parameters[show_attributes][1]"] + .control [name^="parameters[show_attributes]["] </selector> <input>multiselect</input> </show_attributes> <show_buttons> <selector> - .control [name="parameters[show_buttons][2]"] + .control [name^="parameters[show_buttons]["] </selector> <input>multiselect</input> </show_buttons> From 02701a3629b71c8dc4020a48f765267eebe3a462 Mon Sep 17 00:00:00 2001 From: DianaRusin <rusind95@gmail.com> Date: Tue, 16 Jul 2019 09:57:11 +0300 Subject: [PATCH 023/191] MC-17003: Update Totals button is missing from Credit Memo page --- .../Sales/Block/Adminhtml/Order/Creditmemo/Create/Items.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/Create/Items.php b/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/Create/Items.php index 3962cbb3da5c..389c29bedf4c 100644 --- a/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/Create/Items.php +++ b/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/Create/Items.php @@ -56,7 +56,7 @@ protected function _prepareLayout() $this->addChild( 'update_button', \Magento\Backend\Block\Widget\Button::class, - ['label' => __('Update Qty\'s'), 'class' => 'update-button', 'onclick' => $onclick] + ['label' => __('Update Qty\'s'), 'class' => 'update-button secondary', 'onclick' => $onclick] ); $this->addChild( 'update_totals_button', From c0f31fb42350d019fa7d7aa4c68ad545bf24583c Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Tue, 16 Jul 2019 17:31:34 -0500 Subject: [PATCH 024/191] MC-17868: Break jQuery UI into widgets and make a prototype - Update require js config for jquery ui in Theme module; - Swap jquery UI for separate jquery ui widgets in all frontend jquery ui usages; --- app/code/Magento/Bundle/view/frontend/web/js/float.js | 2 +- .../Magento/Bundle/view/frontend/web/js/product-summary.js | 2 +- app/code/Magento/Bundle/view/frontend/web/js/slide.js | 2 +- app/code/Magento/Captcha/view/frontend/web/js/captcha.js | 3 +-- app/code/Magento/Catalog/view/base/web/js/price-box.js | 2 +- .../Magento/Catalog/view/base/web/js/price-option-date.js | 2 +- .../Magento/Catalog/view/base/web/js/price-option-file.js | 2 +- app/code/Magento/Catalog/view/base/web/js/price-options.js | 2 +- .../Catalog/view/frontend/web/js/catalog-add-to-cart.js | 1 - app/code/Magento/Catalog/view/frontend/web/js/gallery.js | 3 +-- app/code/Magento/Catalog/view/frontend/web/js/list.js | 2 +- .../Catalog/view/frontend/web/js/product/list/toolbar.js | 2 +- .../view/frontend/web/js/product/remaining-characters.js | 2 +- .../Catalog/view/frontend/web/js/related-products.js | 2 +- .../Magento/Catalog/view/frontend/web/js/upsell-products.js | 2 +- app/code/Magento/Catalog/view/frontend/web/js/zoom.js | 2 +- .../Catalog/view/frontend/web/product/view/validation.js | 1 - .../view/frontend/web/js/action/update-shopping-cart.js | 2 +- .../Magento/Checkout/view/frontend/web/js/discount-codes.js | 2 +- .../Magento/Checkout/view/frontend/web/js/region-updater.js | 2 +- .../Magento/Checkout/view/frontend/web/js/shopping-cart.js | 2 +- app/code/Magento/Checkout/view/frontend/web/js/sidebar.js | 1 - .../view/frontend/web/js/configurable.js | 2 +- app/code/Magento/Cookie/view/frontend/web/js/notices.js | 2 +- .../Magento/Cookie/view/frontend/web/js/require-cookie.js | 3 +-- app/code/Magento/Customer/view/frontend/web/js/address.js | 1 - .../Customer/view/frontend/web/js/addressValidation.js | 1 - .../Customer/view/frontend/web/js/change-email-password.js | 3 +-- .../Customer/view/frontend/web/js/checkout-balance.js | 3 +-- .../Downloadable/view/frontend/web/js/downloadable.js | 1 - .../GiftMessage/view/frontend/web/js/extra-options.js | 2 +- .../GiftMessage/view/frontend/web/js/gift-options.js | 2 +- app/code/Magento/Msrp/view/base/web/js/msrp.js | 2 +- .../Multishipping/view/frontend/web/js/multi-shipping.js | 2 +- .../Magento/Multishipping/view/frontend/web/js/overview.js | 2 +- .../Magento/Multishipping/view/frontend/web/js/payment.js | 2 +- .../Magento/PageCache/view/frontend/web/js/page-cache.js | 1 - app/code/Magento/Payment/view/frontend/web/js/cc-type.js | 2 +- .../Magento/Payment/view/frontend/web/js/transparent.js | 2 +- .../Magento/Paypal/view/frontend/web/js/order-review.js | 2 +- .../Magento/Paypal/view/frontend/web/js/paypal-checkout.js | 2 +- .../view/frontend/web/js/fotorama-add-video-events.js | 1 - .../ProductVideo/view/frontend/web/js/load-player.js | 1 - .../Magento/Reports/view/frontend/web/js/recently-viewed.js | 2 +- .../Magento/Review/view/frontend/web/js/validate-review.js | 2 -- app/code/Magento/Sales/view/frontend/web/js/gift-message.js | 2 +- .../Magento/Sales/view/frontend/web/js/orders-returns.js | 2 +- .../view/frontend/templates/product/layered/renderer.phtml | 2 +- .../Swatches/view/frontend/web/js/swatch-renderer.js | 1 - app/code/Magento/Theme/view/base/requirejs-config.js | 3 ++- app/code/Magento/Theme/view/frontend/requirejs-config.js | 6 +++--- app/code/Magento/Theme/view/frontend/web/js/row-builder.js | 2 +- app/code/Magento/Theme/view/frontend/web/js/truncate.js | 2 +- .../Magento/Theme/view/frontend/web/js/view/breadcrumbs.js | 2 +- .../Ui/view/base/web/js/lib/knockout/bindings/range.js | 2 +- .../Ui/view/base/web/js/lib/knockout/bindings/resizable.js | 3 +-- .../Magento/Ui/view/base/web/js/lib/validation/rules.js | 1 - app/code/Magento/Ui/view/base/web/js/modal/alert.js | 1 - app/code/Magento/Ui/view/base/web/js/modal/confirm.js | 1 - app/code/Magento/Ui/view/base/web/js/modal/modal.js | 1 - .../Wishlist/view/frontend/web/js/add-to-wishlist.js | 3 +-- app/code/Magento/Wishlist/view/frontend/web/js/search.js | 2 +- app/code/Magento/Wishlist/view/frontend/web/js/wishlist.js | 2 +- .../Framework/Data/Form/Element/Editablemultiselect.php | 4 +--- lib/web/jquery/{composite.js => compat.js} | 0 lib/web/jquery/fileUploader/jquery.fileupload.js | 1 - lib/web/jquery/ui-modules/timepicker.js | 2 -- lib/web/mage/calendar.js | 1 - lib/web/mage/dataPost.js | 3 +-- lib/web/mage/deletable-item.js | 3 +-- lib/web/mage/edit-trigger.js | 3 +-- lib/web/mage/fieldset-controls.js | 3 +-- lib/web/mage/item-table.js | 3 +-- lib/web/mage/list.js | 3 +-- lib/web/mage/loader.js | 1 - lib/web/mage/loader_old.js | 1 - lib/web/mage/multiselect.js | 1 - lib/web/mage/popup-window.js | 3 +-- lib/web/mage/redirect-url.js | 3 +-- lib/web/mage/sticky.js | 3 +-- lib/web/mage/toggle.js | 3 +-- lib/web/mage/validation.js | 1 - lib/web/mage/zoom.js | 3 +-- 83 files changed, 63 insertions(+), 106 deletions(-) rename lib/web/jquery/{composite.js => compat.js} (100%) diff --git a/app/code/Magento/Bundle/view/frontend/web/js/float.js b/app/code/Magento/Bundle/view/frontend/web/js/float.js index 8e78fd069cb3..dd8b1443dcba 100644 --- a/app/code/Magento/Bundle/view/frontend/web/js/float.js +++ b/app/code/Magento/Bundle/view/frontend/web/js/float.js @@ -9,7 +9,7 @@ */ define([ 'jquery', - 'jquery/ui' + 'jquery-ui-modules/widget' ], function ($) { 'use strict'; diff --git a/app/code/Magento/Bundle/view/frontend/web/js/product-summary.js b/app/code/Magento/Bundle/view/frontend/web/js/product-summary.js index 1e7fe6b6673d..d5270569d5bb 100644 --- a/app/code/Magento/Bundle/view/frontend/web/js/product-summary.js +++ b/app/code/Magento/Bundle/view/frontend/web/js/product-summary.js @@ -9,7 +9,7 @@ define([ 'jquery', 'mage/template', - 'jquery/ui', + 'jquery-ui-modules/widget', 'Magento_Bundle/js/price-bundle' ], function ($, mageTemplate) { 'use strict'; diff --git a/app/code/Magento/Bundle/view/frontend/web/js/slide.js b/app/code/Magento/Bundle/view/frontend/web/js/slide.js index 99b01f340fb4..5afe4ad8a9ea 100644 --- a/app/code/Magento/Bundle/view/frontend/web/js/slide.js +++ b/app/code/Magento/Bundle/view/frontend/web/js/slide.js @@ -8,7 +8,7 @@ */ define([ 'jquery', - 'jquery/ui' + 'jquery-ui-modules/widget' ], function ($) { 'use strict'; diff --git a/app/code/Magento/Captcha/view/frontend/web/js/captcha.js b/app/code/Magento/Captcha/view/frontend/web/js/captcha.js index aa173a8be671..b5e5e6b006bf 100644 --- a/app/code/Magento/Captcha/view/frontend/web/js/captcha.js +++ b/app/code/Magento/Captcha/view/frontend/web/js/captcha.js @@ -5,8 +5,7 @@ define([ 'jquery', - 'jquery-ui-modules/widget', - 'jquery-ui-modules/core' + 'jquery-ui-modules/widget' ], function ($) { 'use strict'; diff --git a/app/code/Magento/Catalog/view/base/web/js/price-box.js b/app/code/Magento/Catalog/view/base/web/js/price-box.js index 783d39cddbc7..02ae6eadef67 100644 --- a/app/code/Magento/Catalog/view/base/web/js/price-box.js +++ b/app/code/Magento/Catalog/view/base/web/js/price-box.js @@ -11,7 +11,7 @@ define([ 'Magento_Catalog/js/price-utils', 'underscore', 'mage/template', - 'jquery/ui' + 'jquery-ui-modules/widget' ], function ($, utils, _, mageTemplate) { 'use strict'; diff --git a/app/code/Magento/Catalog/view/base/web/js/price-option-date.js b/app/code/Magento/Catalog/view/base/web/js/price-option-date.js index 4ebfed097e27..6c6299ca9a1f 100644 --- a/app/code/Magento/Catalog/view/base/web/js/price-option-date.js +++ b/app/code/Magento/Catalog/view/base/web/js/price-option-date.js @@ -7,7 +7,7 @@ define([ 'jquery', 'priceUtils', 'priceOptions', - 'jquery/ui' + 'jquery-ui-modules/widget' ], function ($, utils) { 'use strict'; diff --git a/app/code/Magento/Catalog/view/base/web/js/price-option-file.js b/app/code/Magento/Catalog/view/base/web/js/price-option-file.js index fffc2910b3fa..0be38707869e 100644 --- a/app/code/Magento/Catalog/view/base/web/js/price-option-file.js +++ b/app/code/Magento/Catalog/view/base/web/js/price-option-file.js @@ -5,7 +5,7 @@ define([ 'jquery', - 'jquery/ui' + 'jquery-ui-modules/widget' ], function ($) { 'use strict'; diff --git a/app/code/Magento/Catalog/view/base/web/js/price-options.js b/app/code/Magento/Catalog/view/base/web/js/price-options.js index e18abe3af38a..d916d466fe97 100644 --- a/app/code/Magento/Catalog/view/base/web/js/price-options.js +++ b/app/code/Magento/Catalog/view/base/web/js/price-options.js @@ -9,7 +9,7 @@ define([ 'mage/template', 'priceUtils', 'priceBox', - 'jquery/ui' + 'jquery-ui-modules/widget' ], function ($, _, mageTemplate, utils) { 'use strict'; diff --git a/app/code/Magento/Catalog/view/frontend/web/js/catalog-add-to-cart.js b/app/code/Magento/Catalog/view/frontend/web/js/catalog-add-to-cart.js index 6aa477141fe0..d74105fe531e 100644 --- a/app/code/Magento/Catalog/view/frontend/web/js/catalog-add-to-cart.js +++ b/app/code/Magento/Catalog/view/frontend/web/js/catalog-add-to-cart.js @@ -8,7 +8,6 @@ define([ 'mage/translate', 'underscore', 'Magento_Catalog/js/product/view/product-ids-resolver', - 'jquery-ui-modules/core', 'jquery-ui-modules/widget' ], function ($, $t, _, idsResolver) { 'use strict'; diff --git a/app/code/Magento/Catalog/view/frontend/web/js/gallery.js b/app/code/Magento/Catalog/view/frontend/web/js/gallery.js index 5d3d27bf1051..f6be6fd58ca2 100644 --- a/app/code/Magento/Catalog/view/frontend/web/js/gallery.js +++ b/app/code/Magento/Catalog/view/frontend/web/js/gallery.js @@ -9,8 +9,7 @@ if (typeof define === 'function' && define.amd) { define([ 'jquery', - 'jquery-ui-modules/widget', - 'jquery-ui-modules/core' + 'jquery-ui-modules/widget' ], factory); } else { factory(jQuery); diff --git a/app/code/Magento/Catalog/view/frontend/web/js/list.js b/app/code/Magento/Catalog/view/frontend/web/js/list.js index 8017aef2413a..6b1fb7f86a97 100644 --- a/app/code/Magento/Catalog/view/frontend/web/js/list.js +++ b/app/code/Magento/Catalog/view/frontend/web/js/list.js @@ -5,7 +5,7 @@ define([ 'jquery', - 'jquery/ui' + 'jquery-ui-modules/widget' ], function ($) { 'use strict'; diff --git a/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js b/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js index b8b6ff65be2b..6589f7eb0ba4 100644 --- a/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js +++ b/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js @@ -5,7 +5,7 @@ define([ 'jquery', - 'jquery/ui' + 'jquery-ui-modules/widget' ], function ($) { 'use strict'; diff --git a/app/code/Magento/Catalog/view/frontend/web/js/product/remaining-characters.js b/app/code/Magento/Catalog/view/frontend/web/js/product/remaining-characters.js index 3e29e1ebd4d9..da0364386444 100644 --- a/app/code/Magento/Catalog/view/frontend/web/js/product/remaining-characters.js +++ b/app/code/Magento/Catalog/view/frontend/web/js/product/remaining-characters.js @@ -6,7 +6,7 @@ define([ 'jquery', 'mage/translate', - 'jquery/ui' + 'jquery-ui-modules/widget' ], function ($, $t) { 'use strict'; diff --git a/app/code/Magento/Catalog/view/frontend/web/js/related-products.js b/app/code/Magento/Catalog/view/frontend/web/js/related-products.js index 66df48c28bfa..d17c25d421e0 100644 --- a/app/code/Magento/Catalog/view/frontend/web/js/related-products.js +++ b/app/code/Magento/Catalog/view/frontend/web/js/related-products.js @@ -5,7 +5,7 @@ define([ 'jquery', - 'jquery/ui', + 'jquery-ui-modules/widget', 'mage/translate' ], function ($) { 'use strict'; diff --git a/app/code/Magento/Catalog/view/frontend/web/js/upsell-products.js b/app/code/Magento/Catalog/view/frontend/web/js/upsell-products.js index 28e5daabdc3b..da2526d5679c 100644 --- a/app/code/Magento/Catalog/view/frontend/web/js/upsell-products.js +++ b/app/code/Magento/Catalog/view/frontend/web/js/upsell-products.js @@ -5,7 +5,7 @@ define([ 'jquery', - 'jquery/ui' + 'jquery-ui-modules/widget' ], function ($) { 'use strict'; diff --git a/app/code/Magento/Catalog/view/frontend/web/js/zoom.js b/app/code/Magento/Catalog/view/frontend/web/js/zoom.js index f6444223e2c5..1c68818ed9c4 100644 --- a/app/code/Magento/Catalog/view/frontend/web/js/zoom.js +++ b/app/code/Magento/Catalog/view/frontend/web/js/zoom.js @@ -8,7 +8,7 @@ */ define([ 'jquery', - 'jquery/ui' + 'jquery-ui-modules/widget' ], function ($) { 'use strict'; diff --git a/app/code/Magento/Catalog/view/frontend/web/product/view/validation.js b/app/code/Magento/Catalog/view/frontend/web/product/view/validation.js index 8c826411ce4c..ab1753e7b9ed 100644 --- a/app/code/Magento/Catalog/view/frontend/web/product/view/validation.js +++ b/app/code/Magento/Catalog/view/frontend/web/product/view/validation.js @@ -10,7 +10,6 @@ define([ 'jquery', 'jquery-ui-modules/widget', - 'jquery-ui-modules/core', 'mage/validation/validation' ], factory); } else { diff --git a/app/code/Magento/Checkout/view/frontend/web/js/action/update-shopping-cart.js b/app/code/Magento/Checkout/view/frontend/web/js/action/update-shopping-cart.js index 1920bc4d7ac4..a8e70b65019c 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/action/update-shopping-cart.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/action/update-shopping-cart.js @@ -6,7 +6,7 @@ define([ 'Magento_Ui/js/modal/alert', 'jquery', - 'jquery/ui', + 'jquery-ui-modules/widget', 'mage/validation' ], function (alert, $) { 'use strict'; diff --git a/app/code/Magento/Checkout/view/frontend/web/js/discount-codes.js b/app/code/Magento/Checkout/view/frontend/web/js/discount-codes.js index db6e8fef2445..1f38ff28a860 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/discount-codes.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/discount-codes.js @@ -5,7 +5,7 @@ define([ 'jquery', - 'jquery/ui' + 'jquery-ui-modules/widget' ], function ($) { 'use strict'; diff --git a/app/code/Magento/Checkout/view/frontend/web/js/region-updater.js b/app/code/Magento/Checkout/view/frontend/web/js/region-updater.js index 80481826260f..a9cbb1194cfd 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/region-updater.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/region-updater.js @@ -7,7 +7,7 @@ define([ 'jquery', 'mage/template', 'underscore', - 'jquery/ui', + 'jquery-ui-modules/widget', 'mage/validation' ], function ($, mageTemplate, _) { 'use strict'; diff --git a/app/code/Magento/Checkout/view/frontend/web/js/shopping-cart.js b/app/code/Magento/Checkout/view/frontend/web/js/shopping-cart.js index eecfa65b189d..39bd07f0c73a 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/shopping-cart.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/shopping-cart.js @@ -5,7 +5,7 @@ define([ 'jquery', - 'jquery/ui' + 'jquery-ui-modules/widget' ], function ($) { 'use strict'; diff --git a/app/code/Magento/Checkout/view/frontend/web/js/sidebar.js b/app/code/Magento/Checkout/view/frontend/web/js/sidebar.js index fc281ecc3497..e67b04e6104c 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/sidebar.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/sidebar.js @@ -11,7 +11,6 @@ define([ 'Magento_Ui/js/modal/confirm', 'underscore', 'jquery-ui-modules/widget', - 'jquery-ui-modules/core', 'mage/decorate', 'mage/collapsible', 'mage/cookies' diff --git a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js index ef40dcb9a732..c0128dffe704 100644 --- a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js +++ b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js @@ -12,7 +12,7 @@ define([ 'mage/translate', 'priceUtils', 'priceBox', - 'jquery/ui', + 'jquery-ui-modules/widget', 'jquery/jquery.parsequery' ], function ($, _, mageTemplate, $t, priceUtils) { 'use strict'; diff --git a/app/code/Magento/Cookie/view/frontend/web/js/notices.js b/app/code/Magento/Cookie/view/frontend/web/js/notices.js index f1f3754ea54b..2c4a07013080 100644 --- a/app/code/Magento/Cookie/view/frontend/web/js/notices.js +++ b/app/code/Magento/Cookie/view/frontend/web/js/notices.js @@ -8,7 +8,7 @@ */ define([ 'jquery', - 'jquery/ui', + 'jquery-ui-modules/widget', 'mage/cookies' ], function ($) { 'use strict'; diff --git a/app/code/Magento/Cookie/view/frontend/web/js/require-cookie.js b/app/code/Magento/Cookie/view/frontend/web/js/require-cookie.js index aa5b048ae507..0a175136f034 100644 --- a/app/code/Magento/Cookie/view/frontend/web/js/require-cookie.js +++ b/app/code/Magento/Cookie/view/frontend/web/js/require-cookie.js @@ -8,8 +8,7 @@ */ define([ 'jquery', - 'jquery-ui-modules/widget', - 'jquery-ui-modules/core' + 'jquery-ui-modules/widget' ], function ($) { 'use strict'; diff --git a/app/code/Magento/Customer/view/frontend/web/js/address.js b/app/code/Magento/Customer/view/frontend/web/js/address.js index 4e0ddbc5b68e..6ee269e9235c 100644 --- a/app/code/Magento/Customer/view/frontend/web/js/address.js +++ b/app/code/Magento/Customer/view/frontend/web/js/address.js @@ -7,7 +7,6 @@ define([ 'jquery', 'Magento_Ui/js/modal/confirm', 'jquery-ui-modules/widget', - 'jquery-ui-modules/core', 'mage/translate' ], function ($, confirm) { 'use strict'; diff --git a/app/code/Magento/Customer/view/frontend/web/js/addressValidation.js b/app/code/Magento/Customer/view/frontend/web/js/addressValidation.js index 20f61fc02db6..dc2c4bb82af5 100644 --- a/app/code/Magento/Customer/view/frontend/web/js/addressValidation.js +++ b/app/code/Magento/Customer/view/frontend/web/js/addressValidation.js @@ -10,7 +10,6 @@ define([ 'mage/translate', 'Magento_Checkout/js/model/postcode-validator', 'jquery-ui-modules/widget', - 'jquery-ui-modules/core', 'validation' ], function ($, __, utils, $t, postCodeValidator) { 'use strict'; diff --git a/app/code/Magento/Customer/view/frontend/web/js/change-email-password.js b/app/code/Magento/Customer/view/frontend/web/js/change-email-password.js index e790471710ea..8ac5ef8bae99 100644 --- a/app/code/Magento/Customer/view/frontend/web/js/change-email-password.js +++ b/app/code/Magento/Customer/view/frontend/web/js/change-email-password.js @@ -4,8 +4,7 @@ */ define([ 'jquery', - 'jquery-ui-modules/widget', - 'jquery-ui-modules/core' + 'jquery-ui-modules/widget' ], function ($) { 'use strict'; diff --git a/app/code/Magento/Customer/view/frontend/web/js/checkout-balance.js b/app/code/Magento/Customer/view/frontend/web/js/checkout-balance.js index 5c7d59ce6753..9bcea2f8fa18 100644 --- a/app/code/Magento/Customer/view/frontend/web/js/checkout-balance.js +++ b/app/code/Magento/Customer/view/frontend/web/js/checkout-balance.js @@ -5,8 +5,7 @@ define([ 'jquery', - 'jquery-ui-modules/widget', - 'jquery-ui-modules/core' + 'jquery-ui-modules/widget' ], function ($) { 'use strict'; diff --git a/app/code/Magento/Downloadable/view/frontend/web/js/downloadable.js b/app/code/Magento/Downloadable/view/frontend/web/js/downloadable.js index a1abc47acfb3..09a5ad1afa9e 100644 --- a/app/code/Magento/Downloadable/view/frontend/web/js/downloadable.js +++ b/app/code/Magento/Downloadable/view/frontend/web/js/downloadable.js @@ -8,7 +8,6 @@ define([ 'jquery', 'jquery-ui-modules/widget', - 'jquery-ui-modules/core', 'Magento_Catalog/js/price-box' ], function ($) { 'use strict'; diff --git a/app/code/Magento/GiftMessage/view/frontend/web/js/extra-options.js b/app/code/Magento/GiftMessage/view/frontend/web/js/extra-options.js index 1c40f6b7c32e..45e67b5b5937 100644 --- a/app/code/Magento/GiftMessage/view/frontend/web/js/extra-options.js +++ b/app/code/Magento/GiftMessage/view/frontend/web/js/extra-options.js @@ -8,7 +8,7 @@ */ define([ 'jquery', - 'jquery/ui' + 'jquery-ui-modules/widget' ], function ($) { 'use strict'; diff --git a/app/code/Magento/GiftMessage/view/frontend/web/js/gift-options.js b/app/code/Magento/GiftMessage/view/frontend/web/js/gift-options.js index ca190bf28911..cff3324fceaf 100644 --- a/app/code/Magento/GiftMessage/view/frontend/web/js/gift-options.js +++ b/app/code/Magento/GiftMessage/view/frontend/web/js/gift-options.js @@ -5,7 +5,7 @@ define([ 'jquery', - 'jquery/ui' + 'jquery-ui-modules/widget' ], function ($) { 'use strict'; diff --git a/app/code/Magento/Msrp/view/base/web/js/msrp.js b/app/code/Magento/Msrp/view/base/web/js/msrp.js index a0bd3ec132de..2789491137bc 100644 --- a/app/code/Magento/Msrp/view/base/web/js/msrp.js +++ b/app/code/Magento/Msrp/view/base/web/js/msrp.js @@ -6,7 +6,7 @@ define([ 'jquery', 'Magento_Catalog/js/price-utils', 'underscore', - 'jquery/ui', + 'jquery-ui-modules/widget', 'mage/dropdown', 'mage/template' ], function ($, priceUtils, _) { diff --git a/app/code/Magento/Multishipping/view/frontend/web/js/multi-shipping.js b/app/code/Magento/Multishipping/view/frontend/web/js/multi-shipping.js index 88f384758f71..537abb3aa207 100644 --- a/app/code/Magento/Multishipping/view/frontend/web/js/multi-shipping.js +++ b/app/code/Magento/Multishipping/view/frontend/web/js/multi-shipping.js @@ -5,7 +5,7 @@ define([ 'jquery', - 'jquery/ui' + 'jquery-ui-modules/widget' ], function ($) { 'use strict'; diff --git a/app/code/Magento/Multishipping/view/frontend/web/js/overview.js b/app/code/Magento/Multishipping/view/frontend/web/js/overview.js index 3a6d73e30497..4906a2066cec 100644 --- a/app/code/Magento/Multishipping/view/frontend/web/js/overview.js +++ b/app/code/Magento/Multishipping/view/frontend/web/js/overview.js @@ -5,7 +5,7 @@ define([ 'jquery', - 'jquery/ui', + 'jquery-ui-modules/widget', 'mage/translate' ], function ($) { 'use strict'; diff --git a/app/code/Magento/Multishipping/view/frontend/web/js/payment.js b/app/code/Magento/Multishipping/view/frontend/web/js/payment.js index da24b99597d4..e185123372e2 100644 --- a/app/code/Magento/Multishipping/view/frontend/web/js/payment.js +++ b/app/code/Magento/Multishipping/view/frontend/web/js/payment.js @@ -7,7 +7,7 @@ define([ 'jquery', 'mage/template', 'Magento_Ui/js/modal/alert', - 'jquery/ui', + 'jquery-ui-modules/widget', 'mage/translate' ], function ($, mageTemplate, alert) { 'use strict'; diff --git a/app/code/Magento/PageCache/view/frontend/web/js/page-cache.js b/app/code/Magento/PageCache/view/frontend/web/js/page-cache.js index e24d712f17ab..735fe9a6cb23 100644 --- a/app/code/Magento/PageCache/view/frontend/web/js/page-cache.js +++ b/app/code/Magento/PageCache/view/frontend/web/js/page-cache.js @@ -8,7 +8,6 @@ define([ 'domReady', 'consoleLogger', 'jquery-ui-modules/widget', - 'jquery-ui-modules/core', 'mage/cookies' ], function ($, domReady, consoleLogger) { 'use strict'; diff --git a/app/code/Magento/Payment/view/frontend/web/js/cc-type.js b/app/code/Magento/Payment/view/frontend/web/js/cc-type.js index e970c77888d4..d6997e536eaa 100644 --- a/app/code/Magento/Payment/view/frontend/web/js/cc-type.js +++ b/app/code/Magento/Payment/view/frontend/web/js/cc-type.js @@ -6,7 +6,7 @@ /* @api */ define([ 'jquery', - 'jquery/ui' + 'jquery-ui-modules/widget' ], function ($) { 'use strict'; diff --git a/app/code/Magento/Payment/view/frontend/web/js/transparent.js b/app/code/Magento/Payment/view/frontend/web/js/transparent.js index d7c2aa368e7e..d5c51d2d100b 100644 --- a/app/code/Magento/Payment/view/frontend/web/js/transparent.js +++ b/app/code/Magento/Payment/view/frontend/web/js/transparent.js @@ -8,7 +8,7 @@ define([ 'jquery', 'mage/template', 'Magento_Ui/js/modal/alert', - 'jquery/ui', + 'jquery-ui-modules/widget', 'Magento_Payment/js/model/credit-card-validation/validator', 'Magento_Checkout/js/model/full-screen-loader' ], function ($, mageTemplate, alert, ui, validator, fullScreenLoader) { diff --git a/app/code/Magento/Paypal/view/frontend/web/js/order-review.js b/app/code/Magento/Paypal/view/frontend/web/js/order-review.js index 2155b52f4081..1deee1bd7659 100644 --- a/app/code/Magento/Paypal/view/frontend/web/js/order-review.js +++ b/app/code/Magento/Paypal/view/frontend/web/js/order-review.js @@ -6,7 +6,7 @@ define([ 'jquery', 'Magento_Ui/js/modal/alert', - 'jquery/ui', + 'jquery-ui-modules/widget', 'mage/translate', 'mage/mage', 'mage/validation' diff --git a/app/code/Magento/Paypal/view/frontend/web/js/paypal-checkout.js b/app/code/Magento/Paypal/view/frontend/web/js/paypal-checkout.js index 62c9fed0a7dd..6704540ec060 100644 --- a/app/code/Magento/Paypal/view/frontend/web/js/paypal-checkout.js +++ b/app/code/Magento/Paypal/view/frontend/web/js/paypal-checkout.js @@ -7,7 +7,7 @@ define([ 'jquery', 'Magento_Ui/js/modal/confirm', 'Magento_Customer/js/customer-data', - 'jquery/ui', + 'jquery-ui-modules/widget', 'mage/mage' ], function ($, confirm, customerData) { 'use strict'; diff --git a/app/code/Magento/ProductVideo/view/frontend/web/js/fotorama-add-video-events.js b/app/code/Magento/ProductVideo/view/frontend/web/js/fotorama-add-video-events.js index 8bfc4a08bb31..acaf2afeb6c2 100644 --- a/app/code/Magento/ProductVideo/view/frontend/web/js/fotorama-add-video-events.js +++ b/app/code/Magento/ProductVideo/view/frontend/web/js/fotorama-add-video-events.js @@ -6,7 +6,6 @@ define([ 'jquery', 'jquery-ui-modules/widget', - 'jquery-ui-modules/core', 'catalogGallery', 'loadPlayer' ], function ($) { diff --git a/app/code/Magento/ProductVideo/view/frontend/web/js/load-player.js b/app/code/Magento/ProductVideo/view/frontend/web/js/load-player.js index 70220875d716..bd22d2641db0 100644 --- a/app/code/Magento/ProductVideo/view/frontend/web/js/load-player.js +++ b/app/code/Magento/ProductVideo/view/frontend/web/js/load-player.js @@ -10,7 +10,6 @@ define([ 'jquery', 'jquery-ui-modules/widget', - 'jquery-ui-modules/core' ], function ($) { 'use strict'; diff --git a/app/code/Magento/Reports/view/frontend/web/js/recently-viewed.js b/app/code/Magento/Reports/view/frontend/web/js/recently-viewed.js index 26df126a6323..7c914a326969 100644 --- a/app/code/Magento/Reports/view/frontend/web/js/recently-viewed.js +++ b/app/code/Magento/Reports/view/frontend/web/js/recently-viewed.js @@ -8,7 +8,7 @@ */ define([ 'jquery', - 'jquery/ui' + 'jquery-ui-modules/widget' ], function ($) { 'use strict'; diff --git a/app/code/Magento/Review/view/frontend/web/js/validate-review.js b/app/code/Magento/Review/view/frontend/web/js/validate-review.js index 429424e4a187..795dd5958f06 100644 --- a/app/code/Magento/Review/view/frontend/web/js/validate-review.js +++ b/app/code/Magento/Review/view/frontend/web/js/validate-review.js @@ -5,8 +5,6 @@ define([ 'jquery', - 'jquery-ui-modules/widget', - 'jquery-ui-modules/core', 'jquery/validate', 'mage/translate' ], function ($) { diff --git a/app/code/Magento/Sales/view/frontend/web/js/gift-message.js b/app/code/Magento/Sales/view/frontend/web/js/gift-message.js index a5c898194c6d..48ba2dd89af8 100644 --- a/app/code/Magento/Sales/view/frontend/web/js/gift-message.js +++ b/app/code/Magento/Sales/view/frontend/web/js/gift-message.js @@ -5,7 +5,7 @@ define([ 'jquery', - 'jquery/ui' + 'jquery-ui-modules/widget' ], function ($) { 'use strict'; diff --git a/app/code/Magento/Sales/view/frontend/web/js/orders-returns.js b/app/code/Magento/Sales/view/frontend/web/js/orders-returns.js index ee3bf3cda91d..fd54c7e16222 100644 --- a/app/code/Magento/Sales/view/frontend/web/js/orders-returns.js +++ b/app/code/Magento/Sales/view/frontend/web/js/orders-returns.js @@ -5,7 +5,7 @@ define([ 'jquery', - 'jquery/ui' + 'jquery-ui-modules/widget' ], function ($) { 'use strict'; diff --git a/app/code/Magento/Swatches/view/frontend/templates/product/layered/renderer.phtml b/app/code/Magento/Swatches/view/frontend/templates/product/layered/renderer.phtml index 93c19c8068f7..d2f3d4b733ca 100644 --- a/app/code/Magento/Swatches/view/frontend/templates/product/layered/renderer.phtml +++ b/app/code/Magento/Swatches/view/frontend/templates/product/layered/renderer.phtml @@ -75,7 +75,7 @@ </div> <script> - require(["jquery", "jquery/ui", "Magento_Swatches/js/swatch-renderer"], function ($) { + require(["jquery", "jquery-ui-modules/widget", "Magento_Swatches/js/swatch-renderer"], function ($) { $('.swatch-layered.<?= $block->escapeJs($swatchData['attribute_code']) ?>') .find('[option-type="1"], [option-type="2"], [option-type="0"], [option-type="3"]') .SwatchRendererTooltip(); diff --git a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js index 23f890acd6f2..d6302cff83bf 100644 --- a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js +++ b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js @@ -11,7 +11,6 @@ define([ 'mage/translate', 'priceUtils', 'jquery-ui-modules/widget', - 'jquery-ui-modules/core', 'jquery/jquery.parsequery', 'mage/validation/validation' ], function ($, _, mageTemplate, keyboardHandler, $t, priceUtils) { diff --git a/app/code/Magento/Theme/view/base/requirejs-config.js b/app/code/Magento/Theme/view/base/requirejs-config.js index 52e9270952a9..2822d6db008a 100644 --- a/app/code/Magento/Theme/view/base/requirejs-config.js +++ b/app/code/Magento/Theme/view/base/requirejs-config.js @@ -43,7 +43,8 @@ var config = { 'text': 'mage/requirejs/text', 'domReady': 'requirejs/domReady', 'spectrum': 'jquery/spectrum/spectrum', - 'tinycolor': 'jquery/spectrum/tinycolor' + 'tinycolor': 'jquery/spectrum/tinycolor', + 'jquery-ui-modules': 'jquery/ui-modules' }, 'deps': [ 'jquery/jquery-migrate' diff --git a/app/code/Magento/Theme/view/frontend/requirejs-config.js b/app/code/Magento/Theme/view/frontend/requirejs-config.js index 0e63158ae191..952353eb3aff 100644 --- a/app/code/Magento/Theme/view/frontend/requirejs-config.js +++ b/app/code/Magento/Theme/view/frontend/requirejs-config.js @@ -29,12 +29,12 @@ var config = { 'validation': 'mage/validation/validation', 'welcome': 'Magento_Theme/js/view/welcome', 'breadcrumbs': 'Magento_Theme/js/view/breadcrumbs', - 'criticalCssLoader': 'Magento_Theme/js/view/critical-css-loader' + 'criticalCssLoader': 'Magento_Theme/js/view/critical-css-loader', + 'jquery/ui': 'jquery/compat' } }, paths: { - 'jquery/ui': 'jquery/jquery-ui', - 'jquery-ui-modules': 'jquery/ui-modules' + 'jquery/ui': 'jquery/jquery-ui' }, deps: [ 'jquery/jquery.mobile.custom', diff --git a/app/code/Magento/Theme/view/frontend/web/js/row-builder.js b/app/code/Magento/Theme/view/frontend/web/js/row-builder.js index 7785ced2e4bd..18e4c20d4780 100644 --- a/app/code/Magento/Theme/view/frontend/web/js/row-builder.js +++ b/app/code/Magento/Theme/view/frontend/web/js/row-builder.js @@ -11,7 +11,7 @@ define([ 'jquery', 'mage/template', - 'jquery/ui' + 'jquery-ui-modules/widget' ], function ($, mageTemplate) { 'use strict'; diff --git a/app/code/Magento/Theme/view/frontend/web/js/truncate.js b/app/code/Magento/Theme/view/frontend/web/js/truncate.js index 9dd35379595e..139ca5edd0fe 100644 --- a/app/code/Magento/Theme/view/frontend/web/js/truncate.js +++ b/app/code/Magento/Theme/view/frontend/web/js/truncate.js @@ -10,7 +10,7 @@ */ define([ 'jquery', - 'jquery/ui' + 'jquery-ui-modules/widget' ], function ($) { 'use strict'; diff --git a/app/code/Magento/Theme/view/frontend/web/js/view/breadcrumbs.js b/app/code/Magento/Theme/view/frontend/web/js/view/breadcrumbs.js index e9c46354c014..19d8514a4ea8 100644 --- a/app/code/Magento/Theme/view/frontend/web/js/view/breadcrumbs.js +++ b/app/code/Magento/Theme/view/frontend/web/js/view/breadcrumbs.js @@ -8,7 +8,7 @@ define([ 'mage/template', 'Magento_Theme/js/model/breadcrumb-list', 'text!Magento_Theme/templates/breadcrumbs.html', - 'jquery/ui' + 'jquery-ui-modules/widget' ], function ($, mageTemplate, breadcrumbList, tpl) { 'use strict'; diff --git a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/range.js b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/range.js index 708bf56e07a5..1dda3254f461 100644 --- a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/range.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/range.js @@ -8,7 +8,7 @@ define([ 'jquery', 'underscore', '../template/renderer', - 'jquery/ui' + 'jquery-ui-modules/slider' ], function (ko, $, _, renderer) { 'use strict'; diff --git a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/resizable.js b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/resizable.js index 130a351fac57..f55f5fb7c934 100644 --- a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/resizable.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/resizable.js @@ -8,8 +8,7 @@ define([ 'Magento_Ui/js/lib/view/utils/async', 'uiRegistry', 'underscore', - '../template/renderer', - 'jquery/ui' + '../template/renderer' ], function (ko, $, async, registry, _, renderer) { 'use strict'; diff --git a/app/code/Magento/Ui/view/base/web/js/lib/validation/rules.js b/app/code/Magento/Ui/view/base/web/js/lib/validation/rules.js index 6f0dd01f3329..d2523ab43612 100644 --- a/app/code/Magento/Ui/view/base/web/js/lib/validation/rules.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/validation/rules.js @@ -13,7 +13,6 @@ define([ 'moment', 'tinycolor', 'jquery/validate', - 'jquery/ui', 'mage/translate' ], function ($, _, utils, moment, tinycolor) { 'use strict'; diff --git a/app/code/Magento/Ui/view/base/web/js/modal/alert.js b/app/code/Magento/Ui/view/base/web/js/modal/alert.js index c32aee2a89d9..f36fe54a37a9 100644 --- a/app/code/Magento/Ui/view/base/web/js/modal/alert.js +++ b/app/code/Magento/Ui/view/base/web/js/modal/alert.js @@ -10,7 +10,6 @@ define([ 'jquery', 'underscore', 'jquery-ui-modules/widget', - 'jquery-ui-modules/core', 'Magento_Ui/js/modal/confirm', 'mage/translate' ], function ($, _) { diff --git a/app/code/Magento/Ui/view/base/web/js/modal/confirm.js b/app/code/Magento/Ui/view/base/web/js/modal/confirm.js index eb005b2f5d59..e661363d2eae 100644 --- a/app/code/Magento/Ui/view/base/web/js/modal/confirm.js +++ b/app/code/Magento/Ui/view/base/web/js/modal/confirm.js @@ -11,7 +11,6 @@ define([ 'underscore', 'mage/translate', 'jquery-ui-modules/widget', - 'jquery-ui-modules/core', 'Magento_Ui/js/modal/modal' ], function ($, _, $t) { 'use strict'; diff --git a/app/code/Magento/Ui/view/base/web/js/modal/modal.js b/app/code/Magento/Ui/view/base/web/js/modal/modal.js index 7291d5f6ba2f..a8a76206bcd2 100644 --- a/app/code/Magento/Ui/view/base/web/js/modal/modal.js +++ b/app/code/Magento/Ui/view/base/web/js/modal/modal.js @@ -15,7 +15,6 @@ define([ 'text!ui/template/modal/modal-custom.html', 'Magento_Ui/js/lib/key-codes', 'jquery-ui-modules/widget', - 'jquery-ui-modules/core', 'mage/translate' ], function ($, _, template, popupTpl, slideTpl, customTpl, keyCodes) { 'use strict'; diff --git a/app/code/Magento/Wishlist/view/frontend/web/js/add-to-wishlist.js b/app/code/Magento/Wishlist/view/frontend/web/js/add-to-wishlist.js index b639e859766f..033e2e43a3c2 100644 --- a/app/code/Magento/Wishlist/view/frontend/web/js/add-to-wishlist.js +++ b/app/code/Magento/Wishlist/view/frontend/web/js/add-to-wishlist.js @@ -5,8 +5,7 @@ define([ 'jquery', - 'jquery-ui-modules/widget', - 'jquery-ui-modules/core' + 'jquery-ui-modules/widget' ], function ($) { 'use strict'; diff --git a/app/code/Magento/Wishlist/view/frontend/web/js/search.js b/app/code/Magento/Wishlist/view/frontend/web/js/search.js index 64b0fda7ddae..278737d7bb2d 100644 --- a/app/code/Magento/Wishlist/view/frontend/web/js/search.js +++ b/app/code/Magento/Wishlist/view/frontend/web/js/search.js @@ -5,7 +5,7 @@ define([ 'jquery', - 'jquery/ui' + 'jquery-ui-modules/widget' ], function ($) { 'use strict'; diff --git a/app/code/Magento/Wishlist/view/frontend/web/js/wishlist.js b/app/code/Magento/Wishlist/view/frontend/web/js/wishlist.js index 2bb804928a56..b92bd2b21544 100644 --- a/app/code/Magento/Wishlist/view/frontend/web/js/wishlist.js +++ b/app/code/Magento/Wishlist/view/frontend/web/js/wishlist.js @@ -10,7 +10,7 @@ define([ 'jquery', 'mage/template', 'Magento_Ui/js/modal/alert', - 'jquery/ui', + 'jquery-ui-modules/widget', 'mage/validation/validation', 'mage/dataPost' ], function ($, mageTemplate, alert) { diff --git a/lib/internal/Magento/Framework/Data/Form/Element/Editablemultiselect.php b/lib/internal/Magento/Framework/Data/Form/Element/Editablemultiselect.php index c89bf9e38d40..841d54efbccc 100644 --- a/lib/internal/Magento/Framework/Data/Form/Element/Editablemultiselect.php +++ b/lib/internal/Magento/Framework/Data/Form/Element/Editablemultiselect.php @@ -77,9 +77,7 @@ public function getElementHtml() $html .= " <script type='text/javascript'> require([ - 'jquery', - 'jquery-ui-modules/widget', - 'jquery-ui-modules/core' + 'jquery' ], function( $ ){ function isResolved(){ diff --git a/lib/web/jquery/composite.js b/lib/web/jquery/compat.js similarity index 100% rename from lib/web/jquery/composite.js rename to lib/web/jquery/compat.js diff --git a/lib/web/jquery/fileUploader/jquery.fileupload.js b/lib/web/jquery/fileUploader/jquery.fileupload.js index 1aff55e986c5..676f8aa1e805 100644 --- a/lib/web/jquery/fileUploader/jquery.fileupload.js +++ b/lib/web/jquery/fileUploader/jquery.fileupload.js @@ -19,7 +19,6 @@ define([ 'jquery', 'jquery-ui-modules/widget', - 'jquery-ui-modules/core', 'jquery/fileUploader/jquery.iframe-transport' ], factory); } else { diff --git a/lib/web/jquery/ui-modules/timepicker.js b/lib/web/jquery/ui-modules/timepicker.js index eb5d038f0af4..a488e46f5666 100644 --- a/lib/web/jquery/ui-modules/timepicker.js +++ b/lib/web/jquery/ui-modules/timepicker.js @@ -5,8 +5,6 @@ if (typeof define === 'function' && define.amd) { define([ "jquery", - "jquery-ui-modules/core", - "jquery-ui-modules/widget", "jquery-ui-modules/datepicker", "jquery-ui-modules/slider" ], factory); diff --git a/lib/web/mage/calendar.js b/lib/web/mage/calendar.js index 54bb55acc864..85f1904c0e19 100644 --- a/lib/web/mage/calendar.js +++ b/lib/web/mage/calendar.js @@ -11,7 +11,6 @@ define([ 'jquery', 'jquery-ui-modules/widget', - 'jquery-ui-modules/core', 'jquery-ui-modules/datepicker', 'jquery-ui-modules/timepicker' ], factory); diff --git a/lib/web/mage/dataPost.js b/lib/web/mage/dataPost.js index e5691ab677fd..6ed1fdcf0adc 100644 --- a/lib/web/mage/dataPost.js +++ b/lib/web/mage/dataPost.js @@ -7,8 +7,7 @@ define([ 'jquery', 'mage/template', 'Magento_Ui/js/modal/confirm', - 'jquery-ui-modules/widget', - 'jquery-ui-modules/core' + 'jquery-ui-modules/widget' ], function ($, mageTemplate, uiConfirm) { 'use strict'; diff --git a/lib/web/mage/deletable-item.js b/lib/web/mage/deletable-item.js index 268ffe53cea8..7421ee98340e 100644 --- a/lib/web/mage/deletable-item.js +++ b/lib/web/mage/deletable-item.js @@ -8,8 +8,7 @@ */ define([ 'jquery', - 'jquery-ui-modules/widget', - 'jquery-ui-modules/core' + 'jquery-ui-modules/widget' ], function ($) { 'use strict'; diff --git a/lib/web/mage/edit-trigger.js b/lib/web/mage/edit-trigger.js index 1171822e73a6..e28a826ec87e 100644 --- a/lib/web/mage/edit-trigger.js +++ b/lib/web/mage/edit-trigger.js @@ -13,8 +13,7 @@ define([ 'jquery', 'mage/template', - 'jquery-ui-modules/widget', - 'jquery-ui-modules/core' + 'jquery-ui-modules/widget' ], factory); } else { factory(root.jQuery, root.mageTemplate); diff --git a/lib/web/mage/fieldset-controls.js b/lib/web/mage/fieldset-controls.js index 5fa455acb1b0..62418ccea0c5 100644 --- a/lib/web/mage/fieldset-controls.js +++ b/lib/web/mage/fieldset-controls.js @@ -8,8 +8,7 @@ */ define([ 'jquery', - 'jquery-ui-modules/widget', - 'jquery-ui-modules/core' + 'jquery-ui-modules/widget' ], function ($) { 'use strict'; diff --git a/lib/web/mage/item-table.js b/lib/web/mage/item-table.js index 1ca395d3894e..97056bbdad34 100644 --- a/lib/web/mage/item-table.js +++ b/lib/web/mage/item-table.js @@ -9,8 +9,7 @@ define([ 'jquery', 'mage/template', - 'jquery-ui-modules/widget', - 'jquery-ui-modules/core' + 'jquery-ui-modules/widget' ], function ($, mageTemplate) { 'use strict'; diff --git a/lib/web/mage/list.js b/lib/web/mage/list.js index 087e21101ddd..297fffd7ab03 100644 --- a/lib/web/mage/list.js +++ b/lib/web/mage/list.js @@ -9,8 +9,7 @@ define([ 'jquery', 'mage/template', - 'jquery-ui-modules/widget', - 'jquery-ui-modules/core' + 'jquery-ui-modules/widget' ], function ($, mageTemplate) { 'use strict'; diff --git a/lib/web/mage/loader.js b/lib/web/mage/loader.js index b3753388d39f..83299efba422 100644 --- a/lib/web/mage/loader.js +++ b/lib/web/mage/loader.js @@ -7,7 +7,6 @@ define([ 'jquery', 'mage/template', 'jquery-ui-modules/widget', - 'jquery-ui-modules/core', 'mage/translate' ], function ($, mageTemplate) { 'use strict'; diff --git a/lib/web/mage/loader_old.js b/lib/web/mage/loader_old.js index 46248a576991..f759758acd12 100644 --- a/lib/web/mage/loader_old.js +++ b/lib/web/mage/loader_old.js @@ -11,7 +11,6 @@ 'jquery', 'mage/template', 'jquery-ui-modules/widget', - 'jquery-ui-modules/core', 'mage/translate' ], factory); } else { diff --git a/lib/web/mage/multiselect.js b/lib/web/mage/multiselect.js index 4cc6d8fb252f..2e15d80cdc7e 100644 --- a/lib/web/mage/multiselect.js +++ b/lib/web/mage/multiselect.js @@ -9,7 +9,6 @@ define([ 'text!mage/multiselect.html', 'Magento_Ui/js/modal/alert', 'jquery-ui-modules/widget', - 'jquery-ui-modules/core', 'jquery/editableMultiselect/js/jquery.multiselect' ], function (_, $, searchTemplate, alert) { 'use strict'; diff --git a/lib/web/mage/popup-window.js b/lib/web/mage/popup-window.js index 9e2d64afbc6d..5d7b0d1ddfd5 100644 --- a/lib/web/mage/popup-window.js +++ b/lib/web/mage/popup-window.js @@ -5,8 +5,7 @@ define([ 'jquery', - 'jquery-ui-modules/widget', - 'jquery-ui-modules/core' + 'jquery-ui-modules/widget' ], function ($) { 'use strict'; diff --git a/lib/web/mage/redirect-url.js b/lib/web/mage/redirect-url.js index c53de1917f79..9c14d5bbde3d 100644 --- a/lib/web/mage/redirect-url.js +++ b/lib/web/mage/redirect-url.js @@ -5,8 +5,7 @@ define([ 'jquery', - 'jquery-ui-modules/widget', - 'jquery-ui-modules/core' + 'jquery-ui-modules/widget' ], function ($) { 'use strict'; diff --git a/lib/web/mage/sticky.js b/lib/web/mage/sticky.js index c377939fde39..b6e29bb3cae2 100644 --- a/lib/web/mage/sticky.js +++ b/lib/web/mage/sticky.js @@ -5,8 +5,7 @@ define([ 'jquery', - 'jquery-ui-modules/widget', - 'jquery-ui-modules/core' + 'jquery-ui-modules/widget' ], function ($) { 'use strict'; diff --git a/lib/web/mage/toggle.js b/lib/web/mage/toggle.js index 73c04290396a..3e04406c3b75 100644 --- a/lib/web/mage/toggle.js +++ b/lib/web/mage/toggle.js @@ -5,8 +5,7 @@ define([ 'jquery', - 'jquery-ui-modules/widget', - 'jquery-ui-modules/core' + 'jquery-ui-modules/widget' ], function ($) { 'use strict'; diff --git a/lib/web/mage/validation.js b/lib/web/mage/validation.js index cf413df8adee..b284f0002bc6 100644 --- a/lib/web/mage/validation.js +++ b/lib/web/mage/validation.js @@ -11,7 +11,6 @@ 'jquery', 'moment', 'jquery-ui-modules/widget', - 'jquery-ui-modules/core', 'jquery/validate', 'mage/translate' ], factory); diff --git a/lib/web/mage/zoom.js b/lib/web/mage/zoom.js index e8b17e08a07d..a7ad19fb560a 100644 --- a/lib/web/mage/zoom.js +++ b/lib/web/mage/zoom.js @@ -13,8 +13,7 @@ define([ 'jquery', 'mage/template', - 'jquery-ui-modules/widget', - 'jquery-ui-modules/core' + 'jquery-ui-modules/widget' ], factory); } else { factory(root.jQuery, root.mageTemplate); From 98b6f81e74d76ef0ca28642088e7fa20e9181cdd Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Wed, 17 Jul 2019 10:55:03 -0500 Subject: [PATCH 025/191] MC-17868: Break jQuery UI into widgets and make a prototype - Fix static tests fails; --- .../Magento/ProductVideo/view/frontend/web/js/load-player.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/ProductVideo/view/frontend/web/js/load-player.js b/app/code/Magento/ProductVideo/view/frontend/web/js/load-player.js index bd22d2641db0..ede0d2019309 100644 --- a/app/code/Magento/ProductVideo/view/frontend/web/js/load-player.js +++ b/app/code/Magento/ProductVideo/view/frontend/web/js/load-player.js @@ -9,7 +9,7 @@ */ define([ 'jquery', - 'jquery-ui-modules/widget', + 'jquery-ui-modules/widget' ], function ($) { 'use strict'; From c7cf851cb0aabf6b3b68a2e2d760faa685d83412 Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Wed, 17 Jul 2019 13:55:33 -0500 Subject: [PATCH 026/191] MC-17868: Break jQuery UI into widgets and make a prototype - Remove unused jquery UI dependency; --- .../view/frontend/templates/product/layered/renderer.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Swatches/view/frontend/templates/product/layered/renderer.phtml b/app/code/Magento/Swatches/view/frontend/templates/product/layered/renderer.phtml index d2f3d4b733ca..b22429eafc8e 100644 --- a/app/code/Magento/Swatches/view/frontend/templates/product/layered/renderer.phtml +++ b/app/code/Magento/Swatches/view/frontend/templates/product/layered/renderer.phtml @@ -75,7 +75,7 @@ </div> <script> - require(["jquery", "jquery-ui-modules/widget", "Magento_Swatches/js/swatch-renderer"], function ($) { + require(["jquery", "Magento_Swatches/js/swatch-renderer"], function ($) { $('.swatch-layered.<?= $block->escapeJs($swatchData['attribute_code']) ?>') .find('[option-type="1"], [option-type="2"], [option-type="0"], [option-type="3"]') .SwatchRendererTooltip(); From bbe8f49775258f5e19b95052c69058514b00ff2b Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Wed, 17 Jul 2019 18:08:18 -0500 Subject: [PATCH 027/191] MC-17868: Break jQuery UI into widgets and make a prototype - Swap jquery UI with separate jquery ui widget; --- .../Magento/Theme/view/frontend/templates/js/calendar.phtml | 4 ++-- app/code/Magento/Ui/view/base/web/js/modal/prompt.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Theme/view/frontend/templates/js/calendar.phtml b/app/code/Magento/Theme/view/frontend/templates/js/calendar.phtml index e0a3169f4a8e..55798169cdf7 100644 --- a/app/code/Magento/Theme/view/frontend/templates/js/calendar.phtml +++ b/app/code/Magento/Theme/view/frontend/templates/js/calendar.phtml @@ -13,8 +13,8 @@ <script> require([ - "jquery", - "jquery/ui" + 'jquery', + 'jquery-ui-modules/datepicker' ], function($){ //<![CDATA[ diff --git a/app/code/Magento/Ui/view/base/web/js/modal/prompt.js b/app/code/Magento/Ui/view/base/web/js/modal/prompt.js index 4a00d2b6c0ab..13b4d55ea278 100644 --- a/app/code/Magento/Ui/view/base/web/js/modal/prompt.js +++ b/app/code/Magento/Ui/view/base/web/js/modal/prompt.js @@ -11,7 +11,7 @@ define([ 'underscore', 'mage/template', 'text!ui/template/modal/modal-prompt-content.html', - 'jquery/ui', + 'jquery-ui-modules/widget', 'Magento_Ui/js/modal/modal', 'mage/translate' ], function ($, _, template, promptContentTmpl) { From 1447f448485f7613e3771e838539cfca34118e9a Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Thu, 18 Jul 2019 19:04:23 -0500 Subject: [PATCH 028/191] MC-17868: Break jQuery UI into widgets and make a prototype - Add needed jquery ui modules dependencies; --- app/code/Magento/Theme/view/base/requirejs-config.js | 3 ++- app/code/Magento/Theme/view/frontend/requirejs-config.js | 3 +-- .../Magento/Ui/view/base/web/js/lib/knockout/bindings/range.js | 1 + lib/web/mage/dialog.js | 1 + lib/web/mage/dropdown.js | 1 + lib/web/mage/menu.js | 1 + lib/web/mage/tooltip.js | 1 + lib/web/mage/translate-inline.js | 1 + 8 files changed, 9 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Theme/view/base/requirejs-config.js b/app/code/Magento/Theme/view/base/requirejs-config.js index 2822d6db008a..aa540d3cd560 100644 --- a/app/code/Magento/Theme/view/base/requirejs-config.js +++ b/app/code/Magento/Theme/view/base/requirejs-config.js @@ -10,7 +10,8 @@ var config = { 'ko': 'knockoutjs/knockout', 'knockout': 'knockoutjs/knockout', 'mageUtils': 'mage/utils/main', - 'rjsResolver': 'mage/requirejs/resolver' + 'rjsResolver': 'mage/requirejs/resolver', + 'jquery/ui': 'jquery/compat' } }, 'shim': { diff --git a/app/code/Magento/Theme/view/frontend/requirejs-config.js b/app/code/Magento/Theme/view/frontend/requirejs-config.js index 952353eb3aff..aacec30edf18 100644 --- a/app/code/Magento/Theme/view/frontend/requirejs-config.js +++ b/app/code/Magento/Theme/view/frontend/requirejs-config.js @@ -29,8 +29,7 @@ var config = { 'validation': 'mage/validation/validation', 'welcome': 'Magento_Theme/js/view/welcome', 'breadcrumbs': 'Magento_Theme/js/view/breadcrumbs', - 'criticalCssLoader': 'Magento_Theme/js/view/critical-css-loader', - 'jquery/ui': 'jquery/compat' + 'criticalCssLoader': 'Magento_Theme/js/view/critical-css-loader' } }, paths: { diff --git a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/range.js b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/range.js index 1dda3254f461..54c0e6730792 100644 --- a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/range.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/range.js @@ -8,6 +8,7 @@ define([ 'jquery', 'underscore', '../template/renderer', + 'jquery-ui-modules/widget', 'jquery-ui-modules/slider' ], function (ko, $, _, renderer) { 'use strict'; diff --git a/lib/web/mage/dialog.js b/lib/web/mage/dialog.js index 360f8e83dab5..0934c3244a17 100644 --- a/lib/web/mage/dialog.js +++ b/lib/web/mage/dialog.js @@ -8,6 +8,7 @@ */ define([ 'jquery', + 'jquery-ui-modules/widget', 'jquery-ui-modules/dialog' ], function ($) { 'use strict'; diff --git a/lib/web/mage/dropdown.js b/lib/web/mage/dropdown.js index 1f67afa415a7..f02b08ffbbc7 100644 --- a/lib/web/mage/dropdown.js +++ b/lib/web/mage/dropdown.js @@ -5,6 +5,7 @@ define([ 'jquery', + 'jquery-ui-modules/widget', 'jquery-ui-modules/dialog', 'mage/translate' ], function ($) { diff --git a/lib/web/mage/menu.js b/lib/web/mage/menu.js index ee6ad2dc9647..2e5cb59d94eb 100644 --- a/lib/web/mage/menu.js +++ b/lib/web/mage/menu.js @@ -6,6 +6,7 @@ define([ 'jquery', 'matchMedia', + 'jquery-ui-modules/widget', 'jquery-ui-modules/menu', 'jquery/jquery.mobile.custom', 'mage/translate' diff --git a/lib/web/mage/tooltip.js b/lib/web/mage/tooltip.js index 6dc6114cc70a..116fef0a7ddd 100644 --- a/lib/web/mage/tooltip.js +++ b/lib/web/mage/tooltip.js @@ -8,6 +8,7 @@ */ define([ 'jquery', + 'jquery-ui-modules/widget', 'jquery-ui-modules/tooltip' ], function ($) { 'use strict'; diff --git a/lib/web/mage/translate-inline.js b/lib/web/mage/translate-inline.js index cdd2b8ad322f..21f8501ba836 100644 --- a/lib/web/mage/translate-inline.js +++ b/lib/web/mage/translate-inline.js @@ -10,6 +10,7 @@ define([ 'jquery', 'mage/template', + 'jquery-ui-modules/widget', 'jquery-ui-modules/dialog', 'mage/translate' ], factory); From 97e3277637f7821b59867969d4e5439690c7b2db Mon Sep 17 00:00:00 2001 From: DianaRusin <rusind95@gmail.com> Date: Fri, 19 Jul 2019 09:15:25 +0300 Subject: [PATCH 029/191] MC-17003: Update Totals button is missing from Credit Memo page --- .../Test/AdminCheckingCreditMemoUpdateTotalsTest.xml | 10 ++-------- .../Test/Block/Adminhtml/Order/Creditmemo/Totals.php | 6 +++--- .../Sales/Test/TestStep/CreateCreditMemoStep.php | 2 +- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminCheckingCreditMemoUpdateTotalsTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminCheckingCreditMemoUpdateTotalsTest.xml index 4b3698d89727..8cd2b8ee60ed 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminCheckingCreditMemoUpdateTotalsTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminCheckingCreditMemoUpdateTotalsTest.xml @@ -20,20 +20,14 @@ <group value="sales"/> </annotations> <before> - <!--Create category--> - <createData entity="_defaultCategory" stepKey="createCategory"/> - <!--Create simple product--> - <createData entity="_defaultProduct" stepKey="createSimpleProduct"> - <requiredEntity createDataKey="createCategory"/> - </createData> + <!--Create product--> + <createData entity="SimpleProduct2" stepKey="createSimpleProduct"/> <!--Create customer--> <createData entity="Simple_US_CA_Customer" stepKey="createCustomer"/> <!--Login to admin page--> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> </before> <after> - <!--Delete category--> - <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> <!--Delete simple product--> <deleteData createDataKey="createSimpleProduct" stepKey="deleteSimpleProduct"/> <!--Delete customer--> diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Creditmemo/Totals.php b/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Creditmemo/Totals.php index 2013c3590019..6fbfcfca573f 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Creditmemo/Totals.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Creditmemo/Totals.php @@ -32,21 +32,21 @@ class Totals extends \Magento\Sales\Test\Block\Adminhtml\Order\Totals * * @var string */ - private $refundShippingSelector = '//input[@id=\'shipping_amount\']'; + private $refundShippingSelector = '#shipping_amount'; /** * Adjustment Refund css selector. * * @var string */ - private $adjustmentRefundSelector = '//input[@id=\'adjustment_positive\']'; + private $adjustmentRefundSelector = '#adjustment_positive'; /** * Adjustment Fee css selector. * * @var string */ - private $adjustmentFeeSelector = '//input[@id=\'adjustment_negative\']'; + private $adjustmentFeeSelector = '#adjustment_negative'; /** * 'Update Totals button css selector. diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestStep/CreateCreditMemoStep.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestStep/CreateCreditMemoStep.php index d001792d0a18..d2ed6a24d5fa 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestStep/CreateCreditMemoStep.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestStep/CreateCreditMemoStep.php @@ -127,7 +127,7 @@ protected function getCreditMemoIds() * @param array $data * @return int */ - private function compareRefundTotalsData($data) + private function compareRefundTotalsData($data): int { $compareData = [ 'shipping_amount' => From a3d86cd8af0a529dc494fb0c055888a2b30afe61 Mon Sep 17 00:00:00 2001 From: Stepan Furman <furman.stepan@gmail.com> Date: Fri, 19 Jul 2019 10:22:30 +0300 Subject: [PATCH 030/191] Cleaning some gaps --- app/code/Magento/PageCache/Model/Config.php | 12 ++++++------ .../Sales/Model/Order/Email/SenderBuilder.php | 4 +--- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/PageCache/Model/Config.php b/app/code/Magento/PageCache/Model/Config.php index 83db8c0dec3b..595f2f482591 100644 --- a/app/code/Magento/PageCache/Model/Config.php +++ b/app/code/Magento/PageCache/Model/Config.php @@ -199,18 +199,18 @@ protected function _getReplacements() */ protected function _getAccessList() { - $result = ''; - $tpl = " \"%s\";"; + $tpl = ' "%s";'; $accessList = $this->_scopeConfig->getValue(self::XML_VARNISH_PAGECACHE_ACCESS_LIST); if (!empty($accessList)) { - $result = []; + $ipsList = []; $ips = explode(',', $accessList); foreach ($ips as $ip) { - $result[] = sprintf($tpl, trim($ip)); + $ipsList[] = sprintf($tpl, trim($ip)); } - return implode("\n", $result); + return implode('\n', $ipsList); } - return $result; + + return ''; } /** diff --git a/app/code/Magento/Sales/Model/Order/Email/SenderBuilder.php b/app/code/Magento/Sales/Model/Order/Email/SenderBuilder.php index ed9e38822245..1ae5d7479952 100644 --- a/app/code/Magento/Sales/Model/Order/Email/SenderBuilder.php +++ b/app/code/Magento/Sales/Model/Order/Email/SenderBuilder.php @@ -85,11 +85,9 @@ public function sendCopyTo() $copyTo = $this->identityContainer->getEmailCopyTo(); if (!empty($copyTo) && $this->identityContainer->getCopyMethod() == 'copy') { + $this->configureEmailTemplate(); foreach ($copyTo as $email) { - $this->configureEmailTemplate(); - $this->transportBuilder->addTo($email); - $transport = $this->transportBuilder->getTransport(); $transport->sendMessage(); } From a200613547871a5c1ba4430480e4df39e6a25415 Mon Sep 17 00:00:00 2001 From: DianaRusin <rusind95@gmail.com> Date: Fri, 19 Jul 2019 10:58:26 +0300 Subject: [PATCH 031/191] MC-17003: Update Totals button is missing from Credit Memo page --- .../Sales/Test/Block/Adminhtml/Order/Creditmemo/Totals.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Creditmemo/Totals.php b/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Creditmemo/Totals.php index 6fbfcfca573f..a37cd12f0ab0 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Creditmemo/Totals.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Creditmemo/Totals.php @@ -93,7 +93,7 @@ public function setCaptureOption($option) */ public function getRefundShippingElement() { - return $this->_rootElement->find($this->refundShippingSelector, Locator::SELECTOR_XPATH); + return $this->_rootElement->find($this->refundShippingSelector, Locator::SELECTOR_CSS); } /** @@ -103,7 +103,7 @@ public function getRefundShippingElement() */ public function getAdjustmentRefundElement() { - return $this->_rootElement->find($this->adjustmentRefundSelector, Locator::SELECTOR_XPATH); + return $this->_rootElement->find($this->adjustmentRefundSelector, Locator::SELECTOR_CSS); } /** @@ -113,7 +113,7 @@ public function getAdjustmentRefundElement() */ public function getAdjustmentFeeElement() { - return $this->_rootElement->find($this->adjustmentFeeSelector, Locator::SELECTOR_XPATH); + return $this->_rootElement->find($this->adjustmentFeeSelector, Locator::SELECTOR_CSS); } /** From 4a5b47ed92336ecb1cd34c8fb5722cac665502fa Mon Sep 17 00:00:00 2001 From: DianaRusin <rusind95@gmail.com> Date: Fri, 19 Jul 2019 13:34:44 +0300 Subject: [PATCH 032/191] MC-17003: Update Totals button is missing from Credit Memo page --- .../app/Magento/Sales/Test/TestStep/CreateCreditMemoStep.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestStep/CreateCreditMemoStep.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestStep/CreateCreditMemoStep.php index d2ed6a24d5fa..89065afdcb85 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestStep/CreateCreditMemoStep.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestStep/CreateCreditMemoStep.php @@ -127,7 +127,7 @@ protected function getCreditMemoIds() * @param array $data * @return int */ - private function compareRefundTotalsData($data): int + private function compareRefundTotalsData(array $data): int { $compareData = [ 'shipping_amount' => From 959437a67b3b412d1f8ba0250110b000205eb9e6 Mon Sep 17 00:00:00 2001 From: Andrii Meysar <andrii.meysar@transoftgroup.com> Date: Fri, 19 Jul 2019 14:57:05 +0300 Subject: [PATCH 033/191] MC-17929: 2.3.2 - Product Flat Data index taking long time to reindex? --- .../Indexer/Product/Flat/TableBuilder.php | 88 +++++++++---------- 1 file changed, 43 insertions(+), 45 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Indexer/Product/Flat/TableBuilder.php b/app/code/Magento/Catalog/Model/Indexer/Product/Flat/TableBuilder.php index e6c098ab0254..35b33d6f76d5 100644 --- a/app/code/Magento/Catalog/Model/Indexer/Product/Flat/TableBuilder.php +++ b/app/code/Magento/Catalog/Model/Indexer/Product/Flat/TableBuilder.php @@ -6,9 +6,12 @@ namespace Magento\Catalog\Model\Indexer\Product\Flat; use Magento\Catalog\Model\Indexer\Product\Flat\Table\BuilderInterfaceFactory; +use Magento\Store\Model\Store; /** * Class TableBuilder + * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class TableBuilder { @@ -272,75 +275,70 @@ protected function _fillTemporaryTable( $valueFieldSuffix, $storeId ) { - $metadata = $this->getMetadataPool()->getMetadata(\Magento\Catalog\Api\Data\ProductInterface::class); if (!empty($tableColumns)) { - $columnsChunks = array_chunk( - $tableColumns, - Action\Indexer::ATTRIBUTES_CHUNK_SIZE, - true - ); + $columnsChunks = array_chunk($tableColumns, Action\Indexer::ATTRIBUTES_CHUNK_SIZE / 2, true); + + $entityTableName = $this->_productIndexerHelper->getTable('catalog_product_entity'); + $entityTemporaryTableName = $this->_getTemporaryTableName($entityTableName); + $temporaryTableName = $this->_getTemporaryTableName($tableName); + $temporaryValueTableName = $temporaryTableName . $valueFieldSuffix; + $attributeOptionValueTableName = $this->_productIndexerHelper->getTable('eav_attribute_option_value'); + + $flatColumns = $this->_productIndexerHelper->getFlatColumns(); + $defaultStoreId = Store::DEFAULT_STORE_ID; + $linkField = $this->getMetadataPool() + ->getMetadata(\Magento\Catalog\Api\Data\ProductInterface::class) + ->getLinkField(); + foreach ($columnsChunks as $columnsList) { $select = $this->_connection->select(); $selectValue = $this->_connection->select(); - $entityTableName = $this->_getTemporaryTableName( - $this->_productIndexerHelper->getTable('catalog_product_entity') - ); - $temporaryTableName = $this->_getTemporaryTableName($tableName); - $temporaryValueTableName = $temporaryTableName . $valueFieldSuffix; - $keyColumn = array_unique([$metadata->getLinkField(), 'entity_id']); + $keyColumn = array_unique([$linkField, 'entity_id']); $columns = array_merge($keyColumn, array_keys($columnsList)); $valueColumns = $keyColumn; - $flatColumns = $this->_productIndexerHelper->getFlatColumns(); $iterationNum = 1; - $select->from(['et' => $entityTableName], $keyColumn) - ->join( - ['e' => $this->resource->getTableName('catalog_product_entity')], - 'e.entity_id = et.entity_id', - [] - ); + $select->from(['et' => $entityTemporaryTableName], $keyColumn) + ->join(['e' => $entityTableName], 'e.entity_id = et.entity_id', []); $selectValue->from(['e' => $temporaryTableName], $keyColumn); /** @var $attribute \Magento\Catalog\Model\ResourceModel\Eav\Attribute */ foreach ($columnsList as $columnName => $attribute) { $countTableName = 't' . ($iterationNum++); - $joinCondition = sprintf( - 'e.%3$s = %1$s.%3$s' . - ' AND %1$s.attribute_id = %2$d' . - ' AND (%1$s.store_id = %4$d' . - ' OR %1$s.store_id = 0)', - $countTableName, - $attribute->getId(), - $metadata->getLinkField(), - $storeId - ); - + $joinCondition = 'e.%3$s = %1$s.%3$s AND %1$s.attribute_id = %2$d AND %1$s.store_id = %4$d'; $select->joinLeft( [$countTableName => $tableName], - $joinCondition, - [$columnName => 'value'] + sprintf($joinCondition, $countTableName, $attribute->getId(), $linkField, $defaultStoreId), + [] + )->joinLeft( + ['s' . $countTableName => $tableName], + sprintf($joinCondition, 's' . $countTableName, $attribute->getId(), $linkField, $storeId), + [] ); + $columnValue = $this->_connection->getIfNullSql( + 's' . $countTableName . '.value', + $countTableName . '.value' + ); + $select->columns([$columnName => $columnValue]); + if ($attribute->getFlatUpdateSelect($storeId) instanceof \Magento\Framework\DB\Select) { $attributeCode = $attribute->getAttributeCode(); $columnValueName = $attributeCode . $valueFieldSuffix; if (isset($flatColumns[$columnValueName])) { - $valueJoinCondition = sprintf( - 'e.%1$s = %2$s.option_id AND (%2$s.store_id = %3$d OR %2$s.store_id = 0)', - $attributeCode, - $countTableName, - $storeId - ); + $valueJoinCondition = 'e.%1$s = %2$s.option_id AND %2$s.store_id = %3$d'; $selectValue->joinLeft( - [ - $countTableName => $this->_productIndexerHelper->getTable( - 'eav_attribute_option_value' - ), - ], - $valueJoinCondition, - [$columnValueName => $countTableName . '.value'] + [$countTableName => $attributeOptionValueTableName], + sprintf($valueJoinCondition, $attributeCode, $countTableName, $defaultStoreId), + [] + )->joinLeft( + ['s' . $countTableName => $attributeOptionValueTableName], + sprintf($valueJoinCondition, $attributeCode, 's' . $countTableName, $storeId), + [] ); + + $selectValue->columns([$columnValueName => $columnValue]); $valueColumns[] = $columnValueName; } } From 558da0fae8aab61e7a9735484e7e28eb90362809 Mon Sep 17 00:00:00 2001 From: Dmytro Horytskyi <horytsky@adobe.com> Date: Fri, 19 Jul 2019 13:59:51 -0500 Subject: [PATCH 034/191] MC-18254: Catalog rule indexer works incorrectly if Magento timezone offset is greater then system timezone offset --- .../Catalog/Model/Product/Type/Price.php | 16 +------ .../Product/CollectionProcessor.php | 14 +----- ...ProductSelectBuilderByCatalogRulePrice.php | 14 +----- .../CatalogRule/Model/RuleDateFormatter.php | 43 ------------------- .../Model/RuleDateFormatterInterface.php | 30 ------------- ...CatalogProductCollectionPricesObserver.php | 14 +----- .../ProcessAdminFinalPriceObserver.php | 15 +------ .../ProcessFrontFinalPriceObserver.php | 14 +----- .../Pricing/Price/CatalogRulePrice.php | 13 +----- app/code/Magento/CatalogRule/etc/di.xml | 1 - 10 files changed, 14 insertions(+), 160 deletions(-) delete mode 100644 app/code/Magento/CatalogRule/Model/RuleDateFormatter.php delete mode 100644 app/code/Magento/CatalogRule/Model/RuleDateFormatterInterface.php diff --git a/app/code/Magento/Catalog/Model/Product/Type/Price.php b/app/code/Magento/Catalog/Model/Product/Type/Price.php index b53a02aa4201..dc73baef3f76 100644 --- a/app/code/Magento/Catalog/Model/Product/Type/Price.php +++ b/app/code/Magento/Catalog/Model/Product/Type/Price.php @@ -93,11 +93,6 @@ class Price */ private $tierPriceExtensionFactory; - /** - * @var \Magento\CatalogRule\Model\RuleDateFormatterInterface - */ - private $ruleDateFormatter; - /** * Constructor * @@ -111,7 +106,6 @@ class Price * @param \Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory $tierPriceFactory * @param \Magento\Framework\App\Config\ScopeConfigInterface $config * @param ProductTierPriceExtensionFactory|null $tierPriceExtensionFactory - * @param \Magento\CatalogRule\Model\RuleDateFormatterInterface|null $ruleDateFormatter * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -124,8 +118,7 @@ public function __construct( GroupManagementInterface $groupManagement, \Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory $tierPriceFactory, \Magento\Framework\App\Config\ScopeConfigInterface $config, - ProductTierPriceExtensionFactory $tierPriceExtensionFactory = null, - \Magento\CatalogRule\Model\RuleDateFormatterInterface $ruleDateFormatter = null + ProductTierPriceExtensionFactory $tierPriceExtensionFactory = null ) { $this->_ruleFactory = $ruleFactory; $this->_storeManager = $storeManager; @@ -138,8 +131,6 @@ public function __construct( $this->config = $config; $this->tierPriceExtensionFactory = $tierPriceExtensionFactory ?: ObjectManager::getInstance() ->get(ProductTierPriceExtensionFactory::class); - $this->ruleDateFormatter = $ruleDateFormatter ?: ObjectManager::getInstance() - ->get(\Magento\CatalogRule\Model\RuleDateFormatterInterface::class); } /** @@ -605,10 +596,7 @@ public function calculatePrice( ) { \Magento\Framework\Profiler::start('__PRODUCT_CALCULATE_PRICE__'); if ($wId instanceof Store) { - $sId = $wId->getId(); $wId = $wId->getWebsiteId(); - } else { - $sId = $this->_storeManager->getWebsite($wId)->getDefaultGroup()->getDefaultStoreId(); } $finalPrice = $basePrice; @@ -622,7 +610,7 @@ public function calculatePrice( ); if ($rulePrice === false) { - $date = $this->ruleDateFormatter->getDate($sId); + $date = $this->_localeDate->date(null, null, false); $rulePrice = $this->_ruleFactory->create()->getRulePrice($date, $wId, $gId, $productId); } diff --git a/app/code/Magento/CatalogRule/Model/ResourceModel/Product/CollectionProcessor.php b/app/code/Magento/CatalogRule/Model/ResourceModel/Product/CollectionProcessor.php index 79585cd8e857..0dee9eda5b6e 100644 --- a/app/code/Magento/CatalogRule/Model/ResourceModel/Product/CollectionProcessor.php +++ b/app/code/Magento/CatalogRule/Model/ResourceModel/Product/CollectionProcessor.php @@ -10,7 +10,6 @@ use Magento\Catalog\Model\ResourceModel\Product\Collection as ProductCollection; use Magento\CatalogRule\Pricing\Price\CatalogRulePrice; -use Magento\Framework\App\ObjectManager; /** * Add catalog rule prices to collection @@ -44,34 +43,25 @@ class CollectionProcessor */ private $localeDate; - /** - * @var \Magento\CatalogRule\Model\RuleDateFormatterInterface - */ - private $ruleDateFormatter; - /** * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param \Magento\Framework\App\ResourceConnection $resourceConnection * @param \Magento\Customer\Model\Session $customerSession * @param \Magento\Framework\Stdlib\DateTime $dateTime * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate - * @param \Magento\CatalogRule\Model\RuleDateFormatterInterface|null $ruleDateFormatter */ public function __construct( \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Framework\App\ResourceConnection $resourceConnection, \Magento\Customer\Model\Session $customerSession, \Magento\Framework\Stdlib\DateTime $dateTime, - \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate, - \Magento\CatalogRule\Model\RuleDateFormatterInterface $ruleDateFormatter = null + \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate ) { $this->storeManager = $storeManager; $this->resource = $resourceConnection; $this->customerSession = $customerSession; $this->dateTime = $dateTime; $this->localeDate = $localeDate; - $this->ruleDateFormatter = $ruleDateFormatter ?: ObjectManager::getInstance() - ->get(\Magento\CatalogRule\Model\RuleDateFormatterInterface::class); } /** @@ -100,7 +90,7 @@ public function addPriceData(ProductCollection $productCollection, $joinColumn = ), $connection->quoteInto( 'catalog_rule.rule_date = ?', - $this->dateTime->formatDate($this->ruleDateFormatter->getDate($store->getId()), false) + $this->dateTime->formatDate($this->localeDate->date(null, null, false), false) ), ] ), diff --git a/app/code/Magento/CatalogRule/Model/ResourceModel/Product/LinkedProductSelectBuilderByCatalogRulePrice.php b/app/code/Magento/CatalogRule/Model/ResourceModel/Product/LinkedProductSelectBuilderByCatalogRulePrice.php index 11c33633bdfa..02d2631058a1 100644 --- a/app/code/Magento/CatalogRule/Model/ResourceModel/Product/LinkedProductSelectBuilderByCatalogRulePrice.php +++ b/app/code/Magento/CatalogRule/Model/ResourceModel/Product/LinkedProductSelectBuilderByCatalogRulePrice.php @@ -55,11 +55,6 @@ class LinkedProductSelectBuilderByCatalogRulePrice implements LinkedProductSelec */ private $baseSelectProcessor; - /** - * @var \Magento\CatalogRule\Model\RuleDateFormatterInterface - */ - private $ruleDateFormatter; - /** * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param \Magento\Framework\App\ResourceConnection $resourceConnection @@ -68,7 +63,6 @@ class LinkedProductSelectBuilderByCatalogRulePrice implements LinkedProductSelec * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate * @param \Magento\Framework\EntityManager\MetadataPool $metadataPool * @param BaseSelectProcessorInterface $baseSelectProcessor - * @param \Magento\CatalogRule\Model\RuleDateFormatterInterface|null $ruleDateFormatter */ public function __construct( \Magento\Store\Model\StoreManagerInterface $storeManager, @@ -77,8 +71,7 @@ public function __construct( \Magento\Framework\Stdlib\DateTime $dateTime, \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate, \Magento\Framework\EntityManager\MetadataPool $metadataPool, - BaseSelectProcessorInterface $baseSelectProcessor = null, - \Magento\CatalogRule\Model\RuleDateFormatterInterface $ruleDateFormatter = null + BaseSelectProcessorInterface $baseSelectProcessor = null ) { $this->storeManager = $storeManager; $this->resource = $resourceConnection; @@ -88,8 +81,6 @@ public function __construct( $this->metadataPool = $metadataPool; $this->baseSelectProcessor = (null !== $baseSelectProcessor) ? $baseSelectProcessor : ObjectManager::getInstance()->get(BaseSelectProcessorInterface::class); - $this->ruleDateFormatter = $ruleDateFormatter ?: ObjectManager::getInstance() - ->get(\Magento\CatalogRule\Model\RuleDateFormatterInterface::class); } /** @@ -97,8 +88,7 @@ public function __construct( */ public function build($productId) { - $timestamp = $this->ruleDateFormatter->getTimeStamp($this->storeManager->getStore()); - $currentDate = $this->dateTime->formatDate($timestamp, false); + $currentDate = $this->dateTime->formatDate($this->localeDate->date(null, null, false), false); $linkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField(); $productTable = $this->resource->getTableName('catalog_product_entity'); diff --git a/app/code/Magento/CatalogRule/Model/RuleDateFormatter.php b/app/code/Magento/CatalogRule/Model/RuleDateFormatter.php deleted file mode 100644 index 8d55c5bfa6b3..000000000000 --- a/app/code/Magento/CatalogRule/Model/RuleDateFormatter.php +++ /dev/null @@ -1,43 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\CatalogRule\Model; - -/** - * Local date for catalog rule - */ -class RuleDateFormatter implements \Magento\CatalogRule\Model\RuleDateFormatterInterface -{ - /** - * @var \Magento\Framework\Stdlib\DateTime\TimezoneInterface - */ - private $localeDate; - - /** - * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate - */ - public function __construct(\Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate) - { - $this->localeDate = $localeDate; - } - - /** - * @inheritdoc - */ - public function getDate($scope = null): \DateTime - { - return $this->localeDate->scopeDate($scope, null, true); - } - - /** - * @inheritdoc - */ - public function getTimeStamp($scope = null): int - { - return $this->localeDate->scopeTimeStamp($scope); - } -} diff --git a/app/code/Magento/CatalogRule/Model/RuleDateFormatterInterface.php b/app/code/Magento/CatalogRule/Model/RuleDateFormatterInterface.php deleted file mode 100644 index a836f049eb5e..000000000000 --- a/app/code/Magento/CatalogRule/Model/RuleDateFormatterInterface.php +++ /dev/null @@ -1,30 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\CatalogRule\Model; - -/** - * Local date for catalog rule - */ -interface RuleDateFormatterInterface -{ - /** - * Create \DateTime object with date converted to scope timezone for catalog rule - * - * @param mixed $scope Information about scope - * @return \DateTime - */ - public function getDate($scope = null): \DateTime; - - /** - * Get scope timestamp for catalog rule - * - * @param mixed $scope Information about scope - * @return int - */ - public function getTimeStamp($scope = null): int; -} diff --git a/app/code/Magento/CatalogRule/Observer/PrepareCatalogProductCollectionPricesObserver.php b/app/code/Magento/CatalogRule/Observer/PrepareCatalogProductCollectionPricesObserver.php index 2fcdfa9d71d6..d3248ff48275 100644 --- a/app/code/Magento/CatalogRule/Observer/PrepareCatalogProductCollectionPricesObserver.php +++ b/app/code/Magento/CatalogRule/Observer/PrepareCatalogProductCollectionPricesObserver.php @@ -19,7 +19,6 @@ use Magento\Framework\Event\Observer as EventObserver; use Magento\Customer\Api\GroupManagementInterface; use Magento\Framework\Event\ObserverInterface; -use Magento\Framework\App\ObjectManager; /** * Observer for applying catalog rules on product collection @@ -59,11 +58,6 @@ class PrepareCatalogProductCollectionPricesObserver implements ObserverInterface */ protected $groupManagement; - /** - * @var \Magento\CatalogRule\Model\RuleDateFormatterInterface - */ - private $ruleDateFormatter; - /** * @param RulePricesStorage $rulePricesStorage * @param \Magento\CatalogRule\Model\ResourceModel\RuleFactory $resourceRuleFactory @@ -71,7 +65,6 @@ class PrepareCatalogProductCollectionPricesObserver implements ObserverInterface * @param TimezoneInterface $localeDate * @param CustomerModelSession $customerSession * @param GroupManagementInterface $groupManagement - * @param \Magento\CatalogRule\Model\RuleDateFormatterInterface|null $ruleDateFormatter */ public function __construct( RulePricesStorage $rulePricesStorage, @@ -79,8 +72,7 @@ public function __construct( StoreManagerInterface $storeManager, TimezoneInterface $localeDate, CustomerModelSession $customerSession, - GroupManagementInterface $groupManagement, - \Magento\CatalogRule\Model\RuleDateFormatterInterface $ruleDateFormatter = null + GroupManagementInterface $groupManagement ) { $this->rulePricesStorage = $rulePricesStorage; $this->resourceRuleFactory = $resourceRuleFactory; @@ -88,8 +80,6 @@ public function __construct( $this->localeDate = $localeDate; $this->customerSession = $customerSession; $this->groupManagement = $groupManagement; - $this->ruleDateFormatter = $ruleDateFormatter ?: ObjectManager::getInstance() - ->get(\Magento\CatalogRule\Model\RuleDateFormatterInterface::class); } /** @@ -116,7 +106,7 @@ public function execute(\Magento\Framework\Event\Observer $observer) if ($observer->getEvent()->hasDate()) { $date = new \DateTime($observer->getEvent()->getDate()); } else { - $date = (new \DateTime())->setTimestamp($this->ruleDateFormatter->getTimeStamp($store)); + $date = $this->localeDate->date(null, null, false); } $productIds = []; diff --git a/app/code/Magento/CatalogRule/Observer/ProcessAdminFinalPriceObserver.php b/app/code/Magento/CatalogRule/Observer/ProcessAdminFinalPriceObserver.php index bd9593693814..1a8a1fc255b8 100644 --- a/app/code/Magento/CatalogRule/Observer/ProcessAdminFinalPriceObserver.php +++ b/app/code/Magento/CatalogRule/Observer/ProcessAdminFinalPriceObserver.php @@ -14,7 +14,6 @@ use Magento\Framework\Event\Observer as EventObserver; use Magento\Framework\Registry; use Magento\Framework\Event\ObserverInterface; -use Magento\Framework\App\ObjectManager; /** * Observer for applying catalog rules on product for admin area @@ -43,31 +42,22 @@ class ProcessAdminFinalPriceObserver implements ObserverInterface */ protected $rulePricesStorage; - /** - * @var \Magento\CatalogRule\Model\RuleDateFormatterInterface - */ - private $ruleDateFormatter; - /** * @param RulePricesStorage $rulePricesStorage * @param Registry $coreRegistry * @param \Magento\CatalogRule\Model\ResourceModel\RuleFactory $resourceRuleFactory * @param TimezoneInterface $localeDate - * @param \Magento\CatalogRule\Model\RuleDateFormatterInterface|null $ruleDateFormatter */ public function __construct( RulePricesStorage $rulePricesStorage, Registry $coreRegistry, \Magento\CatalogRule\Model\ResourceModel\RuleFactory $resourceRuleFactory, - TimezoneInterface $localeDate, - \Magento\CatalogRule\Model\RuleDateFormatterInterface $ruleDateFormatter = null + TimezoneInterface $localeDate ) { $this->rulePricesStorage = $rulePricesStorage; $this->coreRegistry = $coreRegistry; $this->resourceRuleFactory = $resourceRuleFactory; $this->localeDate = $localeDate; - $this->ruleDateFormatter = $ruleDateFormatter ?: ObjectManager::getInstance() - ->get(\Magento\CatalogRule\Model\RuleDateFormatterInterface::class); } /** @@ -79,8 +69,7 @@ public function __construct( public function execute(\Magento\Framework\Event\Observer $observer) { $product = $observer->getEvent()->getProduct(); - $storeId = $product->getStoreId(); - $date = $this->ruleDateFormatter->getDate($storeId); + $date = $this->localeDate->date(null, null, false); $key = false; $ruleData = $this->coreRegistry->registry('rule_data'); diff --git a/app/code/Magento/CatalogRule/Observer/ProcessFrontFinalPriceObserver.php b/app/code/Magento/CatalogRule/Observer/ProcessFrontFinalPriceObserver.php index 8a2e660ed9aa..bada79ddfeed 100644 --- a/app/code/Magento/CatalogRule/Observer/ProcessFrontFinalPriceObserver.php +++ b/app/code/Magento/CatalogRule/Observer/ProcessFrontFinalPriceObserver.php @@ -14,7 +14,6 @@ use Magento\Framework\Stdlib\DateTime\TimezoneInterface; use Magento\Customer\Model\Session as CustomerModelSession; use Magento\Framework\Event\Observer as EventObserver; -use Magento\Framework\App\ObjectManager; /** * Observer for applying catalog rules on product for frontend area @@ -48,34 +47,25 @@ class ProcessFrontFinalPriceObserver implements ObserverInterface */ protected $rulePricesStorage; - /** - * @var \Magento\CatalogRule\Model\RuleDateFormatterInterface - */ - private $ruleDateFormatter; - /** * @param RulePricesStorage $rulePricesStorage * @param \Magento\CatalogRule\Model\ResourceModel\RuleFactory $resourceRuleFactory * @param StoreManagerInterface $storeManager * @param TimezoneInterface $localeDate * @param CustomerModelSession $customerSession - * @param \Magento\CatalogRule\Model\RuleDateFormatterInterface|null $ruleDateFormatter */ public function __construct( RulePricesStorage $rulePricesStorage, \Magento\CatalogRule\Model\ResourceModel\RuleFactory $resourceRuleFactory, StoreManagerInterface $storeManager, TimezoneInterface $localeDate, - CustomerModelSession $customerSession, - \Magento\CatalogRule\Model\RuleDateFormatterInterface $ruleDateFormatter = null + CustomerModelSession $customerSession ) { $this->rulePricesStorage = $rulePricesStorage; $this->resourceRuleFactory = $resourceRuleFactory; $this->storeManager = $storeManager; $this->localeDate = $localeDate; $this->customerSession = $customerSession; - $this->ruleDateFormatter = $ruleDateFormatter ?: ObjectManager::getInstance() - ->get(\Magento\CatalogRule\Model\RuleDateFormatterInterface::class); } /** @@ -93,7 +83,7 @@ public function execute(\Magento\Framework\Event\Observer $observer) if ($observer->hasDate()) { $date = new \DateTime($observer->getEvent()->getDate()); } else { - $date = $this->ruleDateFormatter->getDate($storeId); + $date = $this->localeDate->date(null, null, false); } if ($observer->hasWebsiteId()) { diff --git a/app/code/Magento/CatalogRule/Pricing/Price/CatalogRulePrice.php b/app/code/Magento/CatalogRule/Pricing/Price/CatalogRulePrice.php index b9db988dd20b..7c68c9d9262f 100644 --- a/app/code/Magento/CatalogRule/Pricing/Price/CatalogRulePrice.php +++ b/app/code/Magento/CatalogRule/Pricing/Price/CatalogRulePrice.php @@ -56,11 +56,6 @@ class CatalogRulePrice extends AbstractPrice implements BasePriceProviderInterfa */ private $ruleResource; - /** - * @var \Magento\CatalogRule\Model\RuleDateFormatterInterface - */ - private $ruleDateFormatter; - /** * @param Product $saleableItem * @param float $quantity @@ -70,7 +65,6 @@ class CatalogRulePrice extends AbstractPrice implements BasePriceProviderInterfa * @param StoreManager $storeManager * @param Session $customerSession * @param RuleFactory $catalogRuleResourceFactory - * @param \Magento\CatalogRule\Model\RuleDateFormatterInterface|null $ruleDateFormatter */ public function __construct( Product $saleableItem, @@ -80,16 +74,13 @@ public function __construct( TimezoneInterface $dateTime, StoreManager $storeManager, Session $customerSession, - RuleFactory $catalogRuleResourceFactory, - \Magento\CatalogRule\Model\RuleDateFormatterInterface $ruleDateFormatter = null + RuleFactory $catalogRuleResourceFactory ) { parent::__construct($saleableItem, $quantity, $calculator, $priceCurrency); $this->dateTime = $dateTime; $this->storeManager = $storeManager; $this->customerSession = $customerSession; $this->resourceRuleFactory = $catalogRuleResourceFactory; - $this->ruleDateFormatter = $ruleDateFormatter ?: ObjectManager::getInstance() - ->get(\Magento\CatalogRule\Model\RuleDateFormatterInterface::class); } /** @@ -105,7 +96,7 @@ public function getValue() } else { $this->value = $this->getRuleResource() ->getRulePrice( - $this->ruleDateFormatter->getDate($this->storeManager->getStore()->getId()), + $this->dateTime->date(null, null, false), $this->storeManager->getStore()->getWebsiteId(), $this->customerSession->getCustomerGroupId(), $this->product->getId() diff --git a/app/code/Magento/CatalogRule/etc/di.xml b/app/code/Magento/CatalogRule/etc/di.xml index c9e0fa46fc67..e0d91db54239 100644 --- a/app/code/Magento/CatalogRule/etc/di.xml +++ b/app/code/Magento/CatalogRule/etc/di.xml @@ -164,5 +164,4 @@ <argument name="customConditionProvider" xsi:type="object">CatalogRuleCustomConditionProvider</argument> </arguments> </type> - <preference for="Magento\CatalogRule\Model\RuleDateFormatterInterface" type="Magento\CatalogRule\Model\RuleDateFormatter" /> </config> From ba4fec890fbf6cc2d7e772654d58ccae1272bc14 Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Fri, 19 Jul 2019 14:15:40 -0500 Subject: [PATCH 035/191] MC-17868: Break jQuery UI into widgets and make a prototype - Remove redundant dependencies; - Move jquery ui compat mapping to frontend area; --- app/code/Magento/Theme/view/base/requirejs-config.js | 3 +-- app/code/Magento/Theme/view/frontend/requirejs-config.js | 3 ++- .../Ui/view/base/web/js/lib/knockout/bindings/range.js | 1 - lib/web/jquery/compat.js | 5 +++-- lib/web/mage/dialog.js | 1 - lib/web/mage/dropdown.js | 1 - lib/web/mage/menu.js | 1 - lib/web/mage/tooltip.js | 1 - lib/web/mage/translate-inline.js | 1 - 9 files changed, 6 insertions(+), 11 deletions(-) diff --git a/app/code/Magento/Theme/view/base/requirejs-config.js b/app/code/Magento/Theme/view/base/requirejs-config.js index aa540d3cd560..2822d6db008a 100644 --- a/app/code/Magento/Theme/view/base/requirejs-config.js +++ b/app/code/Magento/Theme/view/base/requirejs-config.js @@ -10,8 +10,7 @@ var config = { 'ko': 'knockoutjs/knockout', 'knockout': 'knockoutjs/knockout', 'mageUtils': 'mage/utils/main', - 'rjsResolver': 'mage/requirejs/resolver', - 'jquery/ui': 'jquery/compat' + 'rjsResolver': 'mage/requirejs/resolver' } }, 'shim': { diff --git a/app/code/Magento/Theme/view/frontend/requirejs-config.js b/app/code/Magento/Theme/view/frontend/requirejs-config.js index aacec30edf18..952353eb3aff 100644 --- a/app/code/Magento/Theme/view/frontend/requirejs-config.js +++ b/app/code/Magento/Theme/view/frontend/requirejs-config.js @@ -29,7 +29,8 @@ var config = { 'validation': 'mage/validation/validation', 'welcome': 'Magento_Theme/js/view/welcome', 'breadcrumbs': 'Magento_Theme/js/view/breadcrumbs', - 'criticalCssLoader': 'Magento_Theme/js/view/critical-css-loader' + 'criticalCssLoader': 'Magento_Theme/js/view/critical-css-loader', + 'jquery/ui': 'jquery/compat' } }, paths: { diff --git a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/range.js b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/range.js index 54c0e6730792..1dda3254f461 100644 --- a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/range.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/range.js @@ -8,7 +8,6 @@ define([ 'jquery', 'underscore', '../template/renderer', - 'jquery-ui-modules/widget', 'jquery-ui-modules/slider' ], function (ko, $, _, renderer) { 'use strict'; diff --git a/lib/web/jquery/compat.js b/lib/web/jquery/compat.js index dba06a485ae4..0493c594f175 100644 --- a/lib/web/jquery/compat.js +++ b/lib/web/jquery/compat.js @@ -37,12 +37,13 @@ define([ 'jquery-ui-modules/spinner', 'jquery-ui-modules/tabs', 'jquery-ui-modules/timepicker', - 'jquery-ui-modules/tooltip' + 'jquery-ui-modules/tooltip', + 'jquery-ui-modules/widget' ], function() { console.warn( 'Fallback to JQueryUI Compat activated. ' + 'Your store is missing a dependency for a ' + 'jQueryUI widget. Identifying and addressing the dependency ' + - 'will drastically improve the performance of your site' + 'will drastically improve the performance of your site.' ) }); \ No newline at end of file diff --git a/lib/web/mage/dialog.js b/lib/web/mage/dialog.js index 0934c3244a17..360f8e83dab5 100644 --- a/lib/web/mage/dialog.js +++ b/lib/web/mage/dialog.js @@ -8,7 +8,6 @@ */ define([ 'jquery', - 'jquery-ui-modules/widget', 'jquery-ui-modules/dialog' ], function ($) { 'use strict'; diff --git a/lib/web/mage/dropdown.js b/lib/web/mage/dropdown.js index f02b08ffbbc7..1f67afa415a7 100644 --- a/lib/web/mage/dropdown.js +++ b/lib/web/mage/dropdown.js @@ -5,7 +5,6 @@ define([ 'jquery', - 'jquery-ui-modules/widget', 'jquery-ui-modules/dialog', 'mage/translate' ], function ($) { diff --git a/lib/web/mage/menu.js b/lib/web/mage/menu.js index 2e5cb59d94eb..ee6ad2dc9647 100644 --- a/lib/web/mage/menu.js +++ b/lib/web/mage/menu.js @@ -6,7 +6,6 @@ define([ 'jquery', 'matchMedia', - 'jquery-ui-modules/widget', 'jquery-ui-modules/menu', 'jquery/jquery.mobile.custom', 'mage/translate' diff --git a/lib/web/mage/tooltip.js b/lib/web/mage/tooltip.js index 116fef0a7ddd..6dc6114cc70a 100644 --- a/lib/web/mage/tooltip.js +++ b/lib/web/mage/tooltip.js @@ -8,7 +8,6 @@ */ define([ 'jquery', - 'jquery-ui-modules/widget', 'jquery-ui-modules/tooltip' ], function ($) { 'use strict'; diff --git a/lib/web/mage/translate-inline.js b/lib/web/mage/translate-inline.js index 21f8501ba836..cdd2b8ad322f 100644 --- a/lib/web/mage/translate-inline.js +++ b/lib/web/mage/translate-inline.js @@ -10,7 +10,6 @@ define([ 'jquery', 'mage/template', - 'jquery-ui-modules/widget', 'jquery-ui-modules/dialog', 'mage/translate' ], factory); From 85528854abb33801787b75a2025417500ce2c0fd Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Fri, 19 Jul 2019 17:47:04 -0500 Subject: [PATCH 036/191] MC-17868: Break jQuery UI into widgets and make a prototype - Rename jquery ui effect widget; --- lib/web/jquery/compat.js | 2 +- lib/web/jquery/ui-modules/{effect-puff.js => effect-scale.js} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename lib/web/jquery/ui-modules/{effect-puff.js => effect-scale.js} (100%) diff --git a/lib/web/jquery/compat.js b/lib/web/jquery/compat.js index 0493c594f175..518f218599fd 100644 --- a/lib/web/jquery/compat.js +++ b/lib/web/jquery/compat.js @@ -20,7 +20,7 @@ define([ 'jquery-ui-modules/effect-fade', 'jquery-ui-modules/effect-fold', 'jquery-ui-modules/effect-highlight', - 'jquery-ui-modules/effect-puff', + 'jquery-ui-modules/effect-scale', 'jquery-ui-modules/effect-pulsate', 'jquery-ui-modules/effect-shake', 'jquery-ui-modules/effect-slide', diff --git a/lib/web/jquery/ui-modules/effect-puff.js b/lib/web/jquery/ui-modules/effect-scale.js similarity index 100% rename from lib/web/jquery/ui-modules/effect-puff.js rename to lib/web/jquery/ui-modules/effect-scale.js From 9125b5f81dea5e5d9d130be45251c27606fa94f8 Mon Sep 17 00:00:00 2001 From: Stepan Furman <15912461+Stepa4man@users.noreply.github.com> Date: Sun, 21 Jul 2019 12:28:24 +0300 Subject: [PATCH 037/191] Update Config.php --- app/code/Magento/PageCache/Model/Config.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/PageCache/Model/Config.php b/app/code/Magento/PageCache/Model/Config.php index 595f2f482591..6b7db5c7ed17 100644 --- a/app/code/Magento/PageCache/Model/Config.php +++ b/app/code/Magento/PageCache/Model/Config.php @@ -207,7 +207,7 @@ protected function _getAccessList() foreach ($ips as $ip) { $ipsList[] = sprintf($tpl, trim($ip)); } - return implode('\n', $ipsList); + return implode("\n", $ipsList); } return ''; From 6ca9ac262be95a8e42e787119b6bd6f602822df8 Mon Sep 17 00:00:00 2001 From: Anusha Vattam <avattam@adobe.com> Date: Mon, 22 Jul 2019 16:05:52 -0500 Subject: [PATCH 038/191] MC-17120:PayPal :: Additional Payments Support - added integration test for payments advanced --- .../PlaceOrderWithPaymentsAdvancedTest.php | 253 ++++++++++++++++++ 1 file changed, 253 insertions(+) create mode 100644 dev/tests/integration/testsuite/Magento/PaypalGraphQl/Model/Resolver/Guest/PlaceOrderWithPaymentsAdvancedTest.php diff --git a/dev/tests/integration/testsuite/Magento/PaypalGraphQl/Model/Resolver/Guest/PlaceOrderWithPaymentsAdvancedTest.php b/dev/tests/integration/testsuite/Magento/PaypalGraphQl/Model/Resolver/Guest/PlaceOrderWithPaymentsAdvancedTest.php new file mode 100644 index 000000000000..8bb1d6f316b5 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/PaypalGraphQl/Model/Resolver/Guest/PlaceOrderWithPaymentsAdvancedTest.php @@ -0,0 +1,253 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\PaypalGraphQl\Model\Resolver\Guest; + +use Magento\Framework\App\ProductMetadataInterface; +use Magento\Framework\DataObject; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\Serialize\SerializerInterface; +use Magento\GraphQl\Quote\GetMaskedQuoteIdByReservedOrderId; +use Magento\GraphQl\Service\GraphQlRequest; +use Magento\Paypal\Model\Payflow\Request; +use Magento\Paypal\Model\Payflow\RequestFactory; +use Magento\Paypal\Model\Payflow\Service\Gateway; +use Magento\Paypal\Model\Payflowlink; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\ObjectManager; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; + +/** + * End to end place order test using PayPal payments advanced via GraphQl + * + * @magentoAppArea graphql + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ +class PlaceOrderWithPaymentsAdvancedTest extends TestCase +{ + /** @var GraphQlRequest */ + private $graphQlRequest; + + /** @var GetMaskedQuoteIdByReservedOrderId */ + private $getMaskedQuoteIdByReservedOrderId; + + /** @var ObjectManager */ + private $objectManager; + + /** @var Gateway|MockObject */ + private $gateway; + + /** @var Request|MockObject */ + private $paymentRequest; + + protected function setUp() + { + $this->objectManager = Bootstrap::getObjectManager(); + $this->graphQlRequest = $this->objectManager->create(GraphQlRequest::class); + + $this->getMaskedQuoteIdByReservedOrderId = $this->objectManager->get(GetMaskedQuoteIdByReservedOrderId::class); + $this->gateway = $this->getMockBuilder(Gateway::class) + ->disableOriginalConstructor() + ->setMethods(['postRequest']) + ->getMock(); + + $requestFactory = $this->getMockBuilder(RequestFactory::class) + ->setMethods(['create']) + ->disableOriginalConstructor() + ->getMock(); + + $this->paymentRequest = $this->getMockBuilder(Request::class) + ->disableOriginalConstructor() + ->setMethods(['__call','setData']) + ->getMock(); + $this->paymentRequest->method('__call') + ->willReturnCallback( + function ($method) { + if (strpos($method, 'set') === 0) { + return $this->paymentRequest; + } + return null; + } + ); + + $requestFactory->method('create')->willReturn($this->paymentRequest); + $this->objectManager->addSharedInstance($this->gateway, Gateway::class); + } + + /** + * @inheritdoc + */ + protected function tearDown() + { + $this->objectManager->removeSharedInstance(Gateway::class); + } + + /** + * Test successful place Order with Payments Advanced + * + * @magentoConfigFixture default_store payment/payflow_advanced/active 1 + * @magentoConfigFixture default_store payment/payflow_advanced/sandbox_flag 1 + * @magentoDataFixture Magento/Sales/_files/default_rollback.php + * @magentoDataFixture Magento/GraphQl/Catalog/_files/simple_product.php + * @magentoDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php + * @magentoDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php + * @magentoDataFixture Magento/GraphQl/Quote/_files/guest/set_guest_email.php + * @magentoDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php + * @magentoDataFixture Magento/GraphQl/Quote/_files/set_new_billing_address.php + * @magentoDataFixture Magento/GraphQl/Quote/_files/set_flatrate_shipping_method.php + * @return void + */ + public function testResolvePlaceOrderWithPaymentsAdvanced(): void + { + $paymentMethod = 'payflow_advanced'; + $cartId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote'); + + $productMetadata = ObjectManager::getInstance()->get(ProductMetadataInterface::class); + $button = 'Magento_Cart_' . $productMetadata->getEdition(); + + $payflowLinkResponse = new DataObject( + [ + 'result' => '0', + 'respmsg' => 'Approved', + 'pnref' => 'V19A3D27B61E', + 'result_code' => '0' + ] + ); + $this->gateway->expects($this->once()) + ->method('postRequest') + ->willReturn($payflowLinkResponse); + + $this->paymentRequest + ->method('setData') + ->willReturnMap( + [ + [ + 'user' => null, + 'vendor' => null, + 'partner' => null, + 'pwd' => null, + 'verbosity' => null, + 'BUTTONSOURCE' => $button, + 'tender' => 'C', + ], + $this->returnSelf() + ], + ['USER1', 1, $this->returnSelf()], + ['USER2', 'USER2SilentPostHash', $this->returnSelf()] + ); + + $responseData = $this->setPaymentMethodAndPlaceOrder($cartId, $paymentMethod); + + $this->assertArrayNotHasKey('errors', $responseData); + $this->assertArrayHasKey('data', $responseData); + $this->assertEquals( + $paymentMethod, + $responseData['data']['setPaymentMethodOnCart']['cart']['selected_payment_method']['code'] + ); + $this->assertNotEmpty(isset($responseData['data']['placeOrder']['order']['order_id'])); + $this->assertEquals('test_quote', $responseData['data']['placeOrder']['order']['order_id']); + } + + /** + * Test place Order with PaymentAdvanced with a declined status + * + * @magentoConfigFixture default_store payment/payflow_advanced/active 1 + * @magentoConfigFixture default_store payment/payflow_advanced/sandbox_flag 1 + * @magentoDataFixture Magento/Sales/_files/default_rollback.php + * @magentoDataFixture Magento/GraphQl/Catalog/_files/simple_product.php + * @magentoDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php + * @magentoDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php + * @magentoDataFixture Magento/GraphQl/Quote/_files/guest/set_guest_email.php + * @magentoDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php + * @magentoDataFixture Magento/GraphQl/Quote/_files/set_new_billing_address.php + * @magentoDataFixture Magento/GraphQl/Quote/_files/set_flatrate_shipping_method.php + * @return void + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ + public function testResolveWithPaymentAdvancedDeclined(): void + { + $paymentMethod = 'payflow_advanced'; + $cartId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote'); + + $resultCode = Payflowlink::RESPONSE_CODE_DECLINED_BY_FILTER; + $exception = new \Zend_Http_Client_Exception(__('Declined response message from PayPal gateway')); + //Exception message is transformed into more controlled message + $expectedExceptionMessage = + "Unable to place order: Payment Gateway is unreachable at the moment. Please use another payment option."; + + $this->paymentRequest->method('setData') + ->with( + [ + [ + 'invnum' => 'test_quote', + 'amt' => '40.00', + 'pnref' => 'TEST123PNREF', + 'USER2' => '1EncryptedSilentPostHash', + 'result' => $resultCode, + 'trxtype' => 'A', + + ] + ] + ) + ->willReturnSelf(); + + $this->gateway->method('postRequest')->willThrowException($exception); + + $responseData = $this->setPaymentMethodAndPlaceOrder($cartId, $paymentMethod); + $this->assertArrayHasKey('errors', $responseData); + $actualError = $responseData['errors'][0]; + $this->assertEquals($expectedExceptionMessage, $actualError['message']); + $this->assertEquals(GraphQlInputException::EXCEPTION_CATEGORY, $actualError['category']); + } + + /** + * Send setPaymentMethodOnCart and placeOrder mutations and return response content + * + * @param string $cartId + * @param string $paymentMethod + * @return array + */ + private function setPaymentMethodAndPlaceOrder(string $cartId, string $paymentMethod): array + { + $serializer = $this->objectManager->get(SerializerInterface::class); + $query + = <<<QUERY + mutation { + setPaymentMethodOnCart(input: { + cart_id: "$cartId" + payment_method: { + code: "$paymentMethod" + additional_data: { + payflow_link: { + cancel_url:"http://mage.test/paypal/payflowadvanced/cancel" + return_url:"http://mage.test/paypal/payflowadvanced/return" + error_url:"http://mage.test/paypal/payflowadvanced/error" + } + } + } + }) { + cart { + selected_payment_method { + code + } + } + } + placeOrder(input: {cart_id: "$cartId"}) { + order { + order_id + } + } +} +QUERY; + + $response = $this->graphQlRequest->send($query); + $responseContent = $serializer->unserialize($response->getContent()); + + return $responseContent; + } +} From d2a18687800f1b2eab8a2cf8f26e7e66b8894286 Mon Sep 17 00:00:00 2001 From: Dmytro Horytskyi <horytsky@adobe.com> Date: Mon, 22 Jul 2019 16:40:59 -0500 Subject: [PATCH 039/191] MC-18254: Catalog rule indexer works incorrectly if Magento timezone offset is greater then system timezone offset --- ...CatalogProductCollectionPricesObserver.php | 5 +- .../ProcessAdminFinalPriceObserver.php | 4 - .../ProcessFrontFinalPriceObserver.php | 3 - .../Pricing/Price/CatalogRulePrice.php | 61 ++----- .../Pricing/Price/CatalogRulePriceTest.php | 169 ++++++------------ 5 files changed, 77 insertions(+), 165 deletions(-) diff --git a/app/code/Magento/CatalogRule/Observer/PrepareCatalogProductCollectionPricesObserver.php b/app/code/Magento/CatalogRule/Observer/PrepareCatalogProductCollectionPricesObserver.php index d3248ff48275..a635c5611eff 100644 --- a/app/code/Magento/CatalogRule/Observer/PrepareCatalogProductCollectionPricesObserver.php +++ b/app/code/Magento/CatalogRule/Observer/PrepareCatalogProductCollectionPricesObserver.php @@ -12,11 +12,10 @@ namespace Magento\CatalogRule\Observer; use Magento\Catalog\Model\Product; -use Magento\CatalogRule\Model\Rule; +use Magento\Catalog\Model\ResourceModel\Product\Collection as ProductCollection; use Magento\Store\Model\StoreManagerInterface; use Magento\Framework\Stdlib\DateTime\TimezoneInterface; use Magento\Customer\Model\Session as CustomerModelSession; -use Magento\Framework\Event\Observer as EventObserver; use Magento\Customer\Api\GroupManagementInterface; use Magento\Framework\Event\ObserverInterface; @@ -90,7 +89,7 @@ public function __construct( */ public function execute(\Magento\Framework\Event\Observer $observer) { - /* @var $collection ProductCollection */ + /** @var ProductCollection $collection */ $collection = $observer->getEvent()->getCollection(); $store = $this->storeManager->getStore($observer->getEvent()->getStoreId()); $websiteId = $store->getWebsiteId(); diff --git a/app/code/Magento/CatalogRule/Observer/ProcessAdminFinalPriceObserver.php b/app/code/Magento/CatalogRule/Observer/ProcessAdminFinalPriceObserver.php index 1a8a1fc255b8..2fd23ae39147 100644 --- a/app/code/Magento/CatalogRule/Observer/ProcessAdminFinalPriceObserver.php +++ b/app/code/Magento/CatalogRule/Observer/ProcessAdminFinalPriceObserver.php @@ -7,11 +7,7 @@ namespace Magento\CatalogRule\Observer; -use Magento\Catalog\Model\Product; -use Magento\CatalogRule\Model\Rule; use Magento\Framework\Stdlib\DateTime\TimezoneInterface; -use Magento\Customer\Model\Session as CustomerModelSession; -use Magento\Framework\Event\Observer as EventObserver; use Magento\Framework\Registry; use Magento\Framework\Event\ObserverInterface; diff --git a/app/code/Magento/CatalogRule/Observer/ProcessFrontFinalPriceObserver.php b/app/code/Magento/CatalogRule/Observer/ProcessFrontFinalPriceObserver.php index bada79ddfeed..b27768ae091e 100644 --- a/app/code/Magento/CatalogRule/Observer/ProcessFrontFinalPriceObserver.php +++ b/app/code/Magento/CatalogRule/Observer/ProcessFrontFinalPriceObserver.php @@ -8,12 +8,9 @@ namespace Magento\CatalogRule\Observer; use Magento\Framework\Event\ObserverInterface; -use Magento\Catalog\Model\Product; -use Magento\CatalogRule\Model\Rule; use Magento\Store\Model\StoreManagerInterface; use Magento\Framework\Stdlib\DateTime\TimezoneInterface; use Magento\Customer\Model\Session as CustomerModelSession; -use Magento\Framework\Event\Observer as EventObserver; /** * Observer for applying catalog rules on product for frontend area diff --git a/app/code/Magento/CatalogRule/Pricing/Price/CatalogRulePrice.php b/app/code/Magento/CatalogRule/Pricing/Price/CatalogRulePrice.php index 7c68c9d9262f..8bce5456ffa7 100644 --- a/app/code/Magento/CatalogRule/Pricing/Price/CatalogRulePrice.php +++ b/app/code/Magento/CatalogRule/Pricing/Price/CatalogRulePrice.php @@ -9,14 +9,13 @@ use Magento\Catalog\Model\Product; use Magento\CatalogRule\Model\ResourceModel\Rule; -use Magento\CatalogRule\Model\ResourceModel\RuleFactory; use Magento\Customer\Model\Session; -use Magento\Framework\App\ObjectManager; use Magento\Framework\Pricing\Adjustment\Calculator; use Magento\Framework\Pricing\Price\AbstractPrice; use Magento\Framework\Pricing\Price\BasePriceProviderInterface; +use Magento\Framework\Pricing\PriceCurrencyInterface; use Magento\Framework\Stdlib\DateTime\TimezoneInterface; -use Magento\Store\Model\StoreManager; +use Magento\Store\Model\StoreManagerInterface; /** * Class CatalogRulePrice @@ -31,28 +30,22 @@ class CatalogRulePrice extends AbstractPrice implements BasePriceProviderInterfa const PRICE_CODE = 'catalog_rule_price'; /** - * @var \Magento\Framework\Stdlib\DateTime\TimezoneInterface + * @var TimezoneInterface */ protected $dateTime; /** - * @var \Magento\Store\Model\StoreManager + * @var StoreManagerInterface */ protected $storeManager; /** - * @var \Magento\Customer\Model\Session + * @var Session */ protected $customerSession; /** - * @var \Magento\CatalogRule\Model\ResourceModel\RuleFactory - * @deprecated 100.1.1 - */ - protected $resourceRuleFactory; - - /** - * @var \Magento\CatalogRule\Model\ResourceModel\Rule + * @var Rule */ private $ruleResource; @@ -60,27 +53,27 @@ class CatalogRulePrice extends AbstractPrice implements BasePriceProviderInterfa * @param Product $saleableItem * @param float $quantity * @param Calculator $calculator - * @param \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency + * @param PriceCurrencyInterface $priceCurrency * @param TimezoneInterface $dateTime - * @param StoreManager $storeManager + * @param StoreManagerInterface $storeManager * @param Session $customerSession - * @param RuleFactory $catalogRuleResourceFactory + * @param Rule $ruleResource */ public function __construct( Product $saleableItem, $quantity, Calculator $calculator, - \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency, + PriceCurrencyInterface $priceCurrency, TimezoneInterface $dateTime, - StoreManager $storeManager, + StoreManagerInterface $storeManager, Session $customerSession, - RuleFactory $catalogRuleResourceFactory + Rule $ruleResource ) { parent::__construct($saleableItem, $quantity, $calculator, $priceCurrency); $this->dateTime = $dateTime; $this->storeManager = $storeManager; $this->customerSession = $customerSession; - $this->resourceRuleFactory = $catalogRuleResourceFactory; + $this->ruleResource = $ruleResource; } /** @@ -94,13 +87,12 @@ public function getValue() if ($this->product->hasData(self::PRICE_CODE)) { $this->value = (float)$this->product->getData(self::PRICE_CODE) ?: false; } else { - $this->value = $this->getRuleResource() - ->getRulePrice( - $this->dateTime->date(null, null, false), - $this->storeManager->getStore()->getWebsiteId(), - $this->customerSession->getCustomerGroupId(), - $this->product->getId() - ); + $this->value = $this->ruleResource->getRulePrice( + $this->dateTime->date(null, null, false), + $this->storeManager->getStore()->getWebsiteId(), + $this->customerSession->getCustomerGroupId(), + $this->product->getId() + ); $this->value = $this->value ? (float)$this->value : false; } if ($this->value) { @@ -110,19 +102,4 @@ public function getValue() return $this->value; } - - /** - * Retrieve rule resource - * - * @return Rule - * @deprecated 100.1.1 - */ - private function getRuleResource() - { - if (null === $this->ruleResource) { - $this->ruleResource = ObjectManager::getInstance()->get(Rule::class); - } - - return $this->ruleResource; - } } diff --git a/app/code/Magento/CatalogRule/Test/Unit/Pricing/Price/CatalogRulePriceTest.php b/app/code/Magento/CatalogRule/Test/Unit/Pricing/Price/CatalogRulePriceTest.php index 29b040d7299d..cb1a7f53f752 100644 --- a/app/code/Magento/CatalogRule/Test/Unit/Pricing/Price/CatalogRulePriceTest.php +++ b/app/code/Magento/CatalogRule/Test/Unit/Pricing/Price/CatalogRulePriceTest.php @@ -7,8 +7,17 @@ namespace Magento\CatalogRule\Test\Unit\Pricing\Price; +use Magento\Catalog\Model\Product; +use Magento\CatalogRule\Model\ResourceModel\Rule; use Magento\CatalogRule\Pricing\Price\CatalogRulePrice; -use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\Customer\Model\Session; +use Magento\Framework\Pricing\Adjustment\Calculator; +use Magento\Framework\Pricing\PriceCurrencyInterface; +use Magento\Framework\Stdlib\DateTime\TimezoneInterface; +use Magento\Store\Api\Data\StoreInterface; +use Magento\Store\Api\Data\WebsiteInterface; +use Magento\Store\Model\StoreManagerInterface; +use PHPUnit\Framework\MockObject\MockObject; /** * Class CatalogRulePriceTest @@ -18,129 +27,73 @@ class CatalogRulePriceTest extends \PHPUnit\Framework\TestCase { /** - * @var \Magento\CatalogRule\Pricing\Price\CatalogRulePrice + * @var CatalogRulePrice */ - protected $object; + private $object; /** - * @var \Magento\Framework\Pricing\SaleableInterface|\PHPUnit_Framework_MockObject_MockObject + * @var Product|MockObject */ - protected $saleableItemMock; + private $saleableItemMock; /** - * @var \Magento\Framework\Stdlib\DateTime\TimezoneInterface|\PHPUnit_Framework_MockObject_MockObject + * @var TimezoneInterface|MockObject */ - protected $dataTimeMock; + private $dataTimeMock; /** - * @var \Magento\Store\Model\StoreManager|\PHPUnit_Framework_MockObject_MockObject + * @var StoreManagerInterface|MockObject */ - protected $storeManagerMock; + private $storeManagerMock; /** - * @var \Magento\Customer\Model\Session|\PHPUnit_Framework_MockObject_MockObject + * @var Session|MockObject */ - protected $customerSessionMock; + private $customerSessionMock; /** - * @var \Magento\Framework\Pricing\PriceInfo\Base | \PHPUnit_Framework_MockObject_MockObject + * @var Rule|MockObject */ - protected $priceInfoMock; + private $catalogRuleResourceMock; /** - * @var \Magento\CatalogRule\Model\ResourceModel\RuleFactory|\PHPUnit_Framework_MockObject_MockObject + * @var WebsiteInterface|MockObject */ - protected $catalogRuleResourceFactoryMock; + private $coreWebsiteMock; /** - * @var \Magento\CatalogRule\Model\ResourceModel\Rule|\PHPUnit_Framework_MockObject_MockObject + * @var StoreInterface|MockObject */ - protected $catalogRuleResourceMock; + private $coreStoreMock; /** - * @var \Magento\Store\Model\Store|\PHPUnit_Framework_MockObject_MockObject + * @var Calculator|MockObject */ - protected $coreWebsiteMock; + private $calculator; /** - * @var \Magento\Store\Model\Website|\PHPUnit_Framework_MockObject_MockObject + * @var PriceCurrencyInterface|MockObject */ - protected $coreStoreMock; - - /** - * @var \Magento\Framework\Pricing\Adjustment\Calculator|\PHPUnit_Framework_MockObject_MockObject - */ - protected $calculator; - - /** - * @var \Magento\Framework\Pricing\PriceCurrencyInterface|\PHPUnit_Framework_MockObject_MockObject - */ - protected $priceCurrencyMock; - - /** - * @var \Magento\CatalogRule\Model\RuleDateFormatterInterface|\PHPUnit_Framework_MockObject_MockObject - */ - protected $ruleDateFormatter; + private $priceCurrencyMock; /** * Set up */ protected function setUp() { - $this->saleableItemMock = $this->createPartialMock( - \Magento\Catalog\Model\Product::class, - ['getId', '__wakeup', 'getPriceInfo', 'hasData', 'getData'] - ); - $this->dataTimeMock = $this->getMockForAbstractClass( - \Magento\Framework\Stdlib\DateTime\TimezoneInterface::class, - [], - '', - false, - true, - true, - [] - ); - $this->ruleDateFormatter = $this->getMockBuilder(\Magento\CatalogRule\Model\RuleDateFormatterInterface::class) - ->setMethods([]) - ->disableOriginalConstructor() - ->getMock(); - - $this->coreStoreMock = $this->createMock(\Magento\Store\Model\Store::class); - $this->storeManagerMock = $this->createMock(\Magento\Store\Model\StoreManager::class); + $this->saleableItemMock = $this->createMock(Product::class); + $this->dataTimeMock = $this->createMock(TimezoneInterface::class); + $this->coreStoreMock = $this->createMock(StoreInterface::class); + $this->storeManagerMock = $this->createMock(StoreManagerInterface::class); $this->storeManagerMock->expects($this->any()) ->method('getStore') - ->will($this->returnValue($this->coreStoreMock)); - - $this->customerSessionMock = $this->createMock(\Magento\Customer\Model\Session::class); - $this->priceInfoMock = $this->getMockBuilder(\Magento\Framework\Pricing\PriceInfo::class) - ->setMethods(['getAdjustments']) - ->disableOriginalConstructor() - ->getMock(); - $this->catalogRuleResourceFactoryMock = $this->createPartialMock( - \Magento\CatalogRule\Model\ResourceModel\RuleFactory::class, - ['create'] - ); - $this->catalogRuleResourceMock = $this->createMock(\Magento\CatalogRule\Model\ResourceModel\Rule::class); - - $this->coreWebsiteMock = $this->createMock(\Magento\Store\Model\Website::class); - - $this->priceInfoMock->expects($this->any()) - ->method('getAdjustments') - ->will($this->returnValue([])); - $this->saleableItemMock->expects($this->any()) - ->method('getPriceInfo') - ->will($this->returnValue($this->priceInfoMock)); - - $this->catalogRuleResourceFactoryMock->expects($this->any()) - ->method('create') - ->will($this->returnValue($this->catalogRuleResourceMock)); - - $this->calculator = $this->getMockBuilder(\Magento\Framework\Pricing\Adjustment\Calculator::class) - ->disableOriginalConstructor() - ->getMock(); + ->willReturn($this->coreStoreMock); + $this->customerSessionMock = $this->createMock(Session::class); + $this->catalogRuleResourceMock = $this->createMock(Rule::class); + $this->coreWebsiteMock = $this->createMock(WebsiteInterface::class); + $this->calculator = $this->createMock(Calculator::class); $qty = 1; - - $this->priceCurrencyMock = $this->createMock(\Magento\Framework\Pricing\PriceCurrencyInterface::class); + $this->priceCurrencyMock = $this->createMock(PriceCurrencyInterface::class); $this->object = new CatalogRulePrice( $this->saleableItemMock, @@ -150,13 +103,6 @@ protected function setUp() $this->dataTimeMock, $this->storeManagerMock, $this->customerSessionMock, - $this->catalogRuleResourceFactoryMock, - $this->ruleDateFormatter - ); - - (new ObjectManager($this))->setBackwardCompatibleProperty( - $this->object, - 'ruleResource', $this->catalogRuleResourceMock ); } @@ -166,38 +112,35 @@ protected function setUp() */ public function testGetValue() { - $coreStoreId = 1; - $coreWebsiteId = 1; - $productId = 1; - $customerGroupId = 1; - $dateTime = new \DateTime(); + $coreWebsiteId = 2; + $productId = 4; + $customerGroupId = 3; + $date = new \DateTime(); $catalogRulePrice = 55.12; $convertedPrice = 45.34; - $this->coreStoreMock->expects($this->once()) - ->method('getId') - ->will($this->returnValue($coreStoreId)); + $this->dataTimeMock->expects($this->once()) + ->method('date') + ->with(null, null, false) + ->willReturn($date); $this->coreStoreMock->expects($this->once()) ->method('getWebsiteId') - ->will($this->returnValue($coreWebsiteId)); - $this->ruleDateFormatter->expects($this->once()) - ->method('getDate') - ->with($this->equalTo($coreStoreId)) - ->will($this->returnValue($dateTime)); + ->willReturn($coreWebsiteId); $this->customerSessionMock->expects($this->once()) ->method('getCustomerGroupId') - ->will($this->returnValue($customerGroupId)); + ->willReturn($customerGroupId); $this->catalogRuleResourceMock->expects($this->once()) ->method('getRulePrice') - ->will($this->returnValue($catalogRulePrice)); - $this->saleableItemMock->expects($this->any()) + ->with($date, $coreWebsiteId, $customerGroupId, $productId) + ->willReturn($catalogRulePrice); + $this->saleableItemMock->expects($this->once()) ->method('getId') - ->will($this->returnValue($productId)); - $this->priceCurrencyMock->expects($this->any()) + ->willReturn($productId); + $this->priceCurrencyMock->expects($this->once()) ->method('convertAndRound') ->with($catalogRulePrice) - ->will($this->returnValue($convertedPrice)); + ->willReturn($convertedPrice); $this->assertEquals($convertedPrice, $this->object->getValue()); } From 66e9802c402fdfa91c0af1e8c27813426b1f3939 Mon Sep 17 00:00:00 2001 From: DianaRusin <rusind95@gmail.com> Date: Tue, 23 Jul 2019 10:13:47 +0300 Subject: [PATCH 040/191] MC-17003: Update Totals button is missing from Credit Memo page --- .../Magento/Sales/Test/TestStep/CreateCreditMemoStep.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestStep/CreateCreditMemoStep.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestStep/CreateCreditMemoStep.php index 89065afdcb85..3165e90ed78b 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestStep/CreateCreditMemoStep.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestStep/CreateCreditMemoStep.php @@ -138,13 +138,12 @@ private function compareRefundTotalsData(array $data): int $this->orderCreditMemoNew->getTotalsBlock()->getAdjustmentFeeElement()->getValue(), ]; - $count = 0; foreach ($compareData as $key => $val) { - if (isset($data['form_data'][$key])) { - $count += ($val != $data['form_data'][$key] ? 1 : 0); + if (isset($data['form_data'][$key]) && $val != $data['form_data'][$key]) { + return false; } } - return $count; + return true; } } From f33f827c3b0267cb07f84a53cae2b889e99fccf5 Mon Sep 17 00:00:00 2001 From: Stas Kozar <stas.kozar@transoftgroup.com> Date: Tue, 23 Jul 2019 12:28:45 +0300 Subject: [PATCH 041/191] MC-17934: Back in stock alert price customer group discrepancy --- .../Catalog/Pricing/Price/Collection.php | 63 ++++++++++++ .../Catalog/Pricing/Render/FinalPriceBox.php | 16 +-- app/code/Magento/Catalog/etc/di.xml | 4 +- ...oduct_simple_with_wholesale_tier_price.php | 78 +++++++++++++++ ...ple_with_wholesale_tier_price_rollback.php | 28 ++++++ ...stomers_with_different_customer_groups.php | 31 ++++++ ...ith_different_customer_groups_rollback.php | 32 ++++++ .../Magento/ProductAlert/Model/EmailTest.php | 99 +++++++++++++++---- 8 files changed, 324 insertions(+), 27 deletions(-) create mode 100644 app/code/Magento/Catalog/Pricing/Price/Collection.php create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_wholesale_tier_price.php create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_wholesale_tier_price_rollback.php create mode 100644 dev/tests/integration/testsuite/Magento/Customer/_files/two_customers_with_different_customer_groups.php create mode 100644 dev/tests/integration/testsuite/Magento/Customer/_files/two_customers_with_different_customer_groups_rollback.php diff --git a/app/code/Magento/Catalog/Pricing/Price/Collection.php b/app/code/Magento/Catalog/Pricing/Price/Collection.php new file mode 100644 index 000000000000..b48d7e9e3836 --- /dev/null +++ b/app/code/Magento/Catalog/Pricing/Price/Collection.php @@ -0,0 +1,63 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types = 1); + +namespace Magento\Catalog\Pricing\Price; + +use Magento\Framework\App\ObjectManager; +use Magento\Framework\Pricing\SaleableInterface; +use Magento\Store\Model\StoreManagerInterface; +use Magento\Framework\Pricing\Price\Factory; +use Magento\Framework\Pricing\Price\Pool; + +/** + * Price models collection class. + */ +class Collection extends \Magento\Framework\Pricing\Price\Collection +{ + /** + * @var StoreManagerInterface + */ + private $storeManager; + + /** + * @param SaleableInterface $saleableItem + * @param Factory $priceFactory + * @param Pool $pool + * @param float $quantity + * @param StoreManagerInterface|null $storeManager + */ + public function __construct( + SaleableInterface $saleableItem, + Factory $priceFactory, + Pool $pool, + $quantity, + StoreManagerInterface $storeManager = null + ) { + parent::__construct($saleableItem, $priceFactory, $pool, $quantity); + $this->storeManager = $storeManager ?? ObjectManager::getInstance()->get(StoreManagerInterface::class); + } + + /** + * @inheritdoc + */ + public function get($code) + { + $customerGroupId = $this->saleableItem->getCustomerGroupId() ?? ''; + $websiteId = $this->storeManager->getStore($this->saleableItem->getStoreId())->getWebsiteId(); + $codeKey = $code . '-' . $customerGroupId . '-' . $websiteId; + + if (!isset($this->priceModels[$codeKey])) { + $this->priceModels[$codeKey] = $this->priceFactory->create( + $this->saleableItem, + $this->pool[$code], + $this->quantity + ); + } + + return $this->priceModels[$codeKey]; + } +} diff --git a/app/code/Magento/Catalog/Pricing/Render/FinalPriceBox.php b/app/code/Magento/Catalog/Pricing/Render/FinalPriceBox.php index e0a92ea0e0be..71b5f505f97a 100644 --- a/app/code/Magento/Catalog/Pricing/Render/FinalPriceBox.php +++ b/app/code/Magento/Catalog/Pricing/Render/FinalPriceBox.php @@ -60,7 +60,7 @@ public function __construct( } /** - * @return string + * @inheritdoc */ protected function _toHtml() { @@ -182,25 +182,27 @@ public function showMinimalPrice() */ public function getCacheKey() { - return parent::getCacheKey() . ($this->getData('list_category_page') ? '-list-category-page': ''); + return parent::getCacheKey() + . ($this->getData('list_category_page') ? '-list-category-page': '') + . ($this->getSaleableItem()->getCustomerGroupId() ?? ''); } /** - * {@inheritdoc} - * - * @return array + * @inheritdoc */ public function getCacheKeyInfo() { $cacheKeys = parent::getCacheKeyInfo(); $cacheKeys['display_minimal_price'] = $this->getDisplayMinimalPrice(); $cacheKeys['is_product_list'] = $this->isProductList(); + $cacheKeys['customer_group_id'] = $this->getSaleableItem()->getCustomerGroupId(); return $cacheKeys; } /** - * Get flag that price rendering should be done for the list of products - * By default (if flag is not set) is false + * Get flag that price rendering should be done for the list of products. + * + * By default (if flag is not set) is false. * * @return bool */ diff --git a/app/code/Magento/Catalog/etc/di.xml b/app/code/Magento/Catalog/etc/di.xml index e30577a39766..1c0b2daf4d6f 100644 --- a/app/code/Magento/Catalog/etc/di.xml +++ b/app/code/Magento/Catalog/etc/di.xml @@ -377,11 +377,11 @@ </argument> </arguments> </virtualType> - <virtualType name="Magento\Catalog\Pricing\Price\Collection" type="Magento\Framework\Pricing\Price\Collection"> + <type name="Magento\Catalog\Pricing\Price\Collection"> <arguments> <argument name="pool" xsi:type="object">Magento\Catalog\Pricing\Price\Pool</argument> </arguments> - </virtualType> + </type> <type name="Magento\Framework\Pricing\PriceInfo\Factory"> <arguments> <argument name="types" xsi:type="array"> diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_wholesale_tier_price.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_wholesale_tier_price.php new file mode 100644 index 000000000000..5c5db4aee744 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_wholesale_tier_price.php @@ -0,0 +1,78 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types = 1); + +use Magento\Catalog\Api\Data\ProductTierPriceExtensionFactory; +use Magento\Catalog\Api\Data\ProductExtensionInterfaceFactory; +use Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Catalog\Model\Product; +use Magento\Catalog\Model\Product\Attribute\Source\Status; +use Magento\Catalog\Model\Product\Type; +use Magento\Catalog\Model\Product\Visibility; +use Magento\Store\Api\WebsiteRepositoryInterface; +use Magento\TestFramework\Helper\Bootstrap; + +/** @var \Magento\TestFramework\ObjectManager $objectManager */ +$objectManager = Bootstrap::getObjectManager(); + +/** @var ProductTierPriceInterfaceFactory $tierPriceFactory */ +$tierPriceFactory = $objectManager->get(ProductTierPriceInterfaceFactory::class); +/** @var $tpExtensionAttributes */ +$tpExtensionAttributesFactory = $objectManager->get(ProductTierPriceExtensionFactory::class); +/** @var $productExtensionAttributes */ +$productExtensionAttributesFactory = $objectManager->get(ProductExtensionInterfaceFactory::class); + +$adminWebsite = $objectManager->get(WebsiteRepositoryInterface::class)->get('admin'); +$tierPriceExtensionAttributes1 = $tpExtensionAttributesFactory->create() + ->setWebsiteId($adminWebsite->getId()); +$productExtensionAttributesWebsiteIds = $productExtensionAttributesFactory->create( + ['website_ids' => $adminWebsite->getId()] +); + +$tierPrice = $tierPriceFactory->create( + [ + 'data' => [ + 'customer_group_id' => 2, + 'qty' => 1, + 'value' => 5, + ], + ] +)->setExtensionAttributes($tierPriceExtensionAttributes1); + +/** @var $product Product */ +$product = $objectManager->create(Product::class); +$product->isObjectNew(true); +$product->setTypeId(Type::TYPE_SIMPLE) + ->setAttributeSetId($product->getDefaultAttributeSetId()) + ->setWebsiteIds([$adminWebsite->getId()]) + ->setName('Simple Product') + ->setSku('simple') + ->setPrice(10) + ->setWeight(1) + ->setShortDescription("Short description") + ->setTaxClassId(0) + ->setTierPrices([$tierPrice]) + ->setDescription('Description with <b>html tag</b>') + ->setExtensionAttributes($productExtensionAttributesWebsiteIds) + ->setMetaTitle('meta title') + ->setMetaKeyword('meta keyword') + ->setMetaDescription('meta description') + ->setVisibility(Visibility::VISIBILITY_BOTH) + ->setStatus(Status::STATUS_ENABLED) + ->setStockData( + [ + 'use_config_manage_stock' => 1, + 'qty' => 100, + 'is_qty_decimal' => 0, + 'is_in_stock' => 1, + ] + )->setCanSaveCustomOptions(true) + ->setHasOptions(true); + +/** @var ProductRepositoryInterface $productRepository */ +$productRepository = $objectManager->create(ProductRepositoryInterface::class); +$productRepository->save($product); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_wholesale_tier_price_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_wholesale_tier_price_rollback.php new file mode 100644 index 000000000000..eecab1088d6f --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_wholesale_tier_price_rollback.php @@ -0,0 +1,28 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types = 1); + +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\Registry; +use Magento\TestFramework\Helper\Bootstrap; + +/** @var Registry $registry */ +$registry = Bootstrap::getObjectManager()->get(Registry::class); + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); + +/** @var ProductRepositoryInterface $productRepository */ +$productRepository = Bootstrap::getObjectManager() + ->get(ProductRepositoryInterface::class); +try { + $product = $productRepository->get('simple', false, null, true); + $productRepository->delete($product); +} catch (NoSuchEntityException $e) { +} +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false); diff --git a/dev/tests/integration/testsuite/Magento/Customer/_files/two_customers_with_different_customer_groups.php b/dev/tests/integration/testsuite/Magento/Customer/_files/two_customers_with_different_customer_groups.php new file mode 100644 index 000000000000..01e451387c3c --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Customer/_files/two_customers_with_different_customer_groups.php @@ -0,0 +1,31 @@ +<?php +/** + * Fixture for Customer List method. + * + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types = 1); + +use Magento\Customer\Model\Customer; +use Magento\Store\Model\Store; +use Magento\TestFramework\Helper\Bootstrap; + +require 'customer.php'; + +$customer = Bootstrap::getObjectManager()->create( + Customer::class +); +$customer->setWebsiteId(1) + ->setEmail('customer_two@example.com') + ->setPassword('password') + ->setGroupId(2) + ->setStoreId(Store::DEFAULT_STORE_ID) + ->setIsActive(1) + ->setFirstname('Firstname') + ->setLastname('Lastname') + ->setDefaultBilling(1) + ->setDefaultShipping(1); + +$customer->isObjectNew(true); +$customer->save(); diff --git a/dev/tests/integration/testsuite/Magento/Customer/_files/two_customers_with_different_customer_groups_rollback.php b/dev/tests/integration/testsuite/Magento/Customer/_files/two_customers_with_different_customer_groups_rollback.php new file mode 100644 index 000000000000..4054dea0f2a8 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Customer/_files/two_customers_with_different_customer_groups_rollback.php @@ -0,0 +1,32 @@ +<?php +/** + * Fixture for Customer List method. + * + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types = 1); + +use Magento\Customer\Api\CustomerRepositoryInterface; +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\Registry; +use Magento\TestFramework\Helper\Bootstrap; + +require 'customer_rollback.php'; + +/** @var Registry $registry */ +$registry = Bootstrap::getObjectManager()->get(Registry::class); +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); + +/** @var CustomerRepositoryInterface $customerRepository */ +$customerRepository = Bootstrap::getObjectManager()->get(CustomerRepositoryInterface::class); +try { + $customer = $customerRepository->get('customer_two@example.com'); + $customerRepository->delete($customer); +} catch (NoSuchEntityException $e) { + /** Tests which are wrapped with MySQL transaction clear all data by transaction rollback. */ +} + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false); diff --git a/dev/tests/integration/testsuite/Magento/ProductAlert/Model/EmailTest.php b/dev/tests/integration/testsuite/Magento/ProductAlert/Model/EmailTest.php index aed921489923..ad254e1db40b 100644 --- a/dev/tests/integration/testsuite/Magento/ProductAlert/Model/EmailTest.php +++ b/dev/tests/integration/testsuite/Magento/ProductAlert/Model/EmailTest.php @@ -6,13 +6,21 @@ namespace Magento\ProductAlert\Model; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Customer\Api\CustomerRepositoryInterface; +use Magento\ProductAlert\Model\Email; +use Magento\Store\Model\Website; +use Magento\TestFramework\Mail\Template\TransportBuilderMock; + /** + * Test for Magento\ProductAlert\Model\Email class. + * * @magentoAppIsolation enabled */ class EmailTest extends \PHPUnit\Framework\TestCase { /** - * @var \Magento\ProductAlert\Model\Email + * @var Email */ protected $_emailModel; @@ -31,6 +39,24 @@ class EmailTest extends \PHPUnit\Framework\TestCase */ protected $_customerViewHelper; + /** + * @var TransportBuilderMock + */ + private $transportBuilder; + + /** + * @var ProductRepositoryInterface + */ + private $productRepository; + + /** + * @var CustomerRepositoryInterface + */ + private $customerRepository; + + /** + * @inheritdoc + */ protected function setUp() { $this->_objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); @@ -38,9 +64,15 @@ protected function setUp() \Magento\Customer\Api\AccountManagementInterface::class ); $this->_customerViewHelper = $this->_objectManager->create(\Magento\Customer\Helper\View::class); + $this->transportBuilder = $this->_objectManager->get(TransportBuilderMock::class); + $this->customerRepository = $this->_objectManager->create(CustomerRepositoryInterface::class); + $this->productRepository = $this->_objectManager->create(ProductRepositoryInterface::class); + + $this->_emailModel = $this->_objectManager->create(Email::class); } /** + * @magentoAppArea frontend * @magentoDataFixture Magento/Customer/_files/customer.php * @magentoDataFixture Magento/Catalog/_files/product_simple.php * @dataProvider customerFunctionDataProvider @@ -49,19 +81,12 @@ protected function setUp() */ public function testSend($isCustomerIdUsed) { - \Magento\TestFramework\Helper\Bootstrap::getInstance() - ->loadArea(\Magento\Framework\App\Area::AREA_FRONTEND); - - $this->_emailModel = $this->_objectManager->create(\Magento\ProductAlert\Model\Email::class); - - /** @var \Magento\Store\Model\Website $website */ - $website = $this->_objectManager->create(\Magento\Store\Model\Website::class); + /** @var Website $website */ + $website = $this->_objectManager->create(Website::class); $website->load(1); $this->_emailModel->setWebsite($website); - /** @var \Magento\Customer\Api\Data\CustomerInterface $customer */ - $customerRepository = $this->_objectManager->create(\Magento\Customer\Api\CustomerRepositoryInterface::class); - $customer = $customerRepository->getById(1); + $customer = $this->customerRepository->getById(1); if ($isCustomerIdUsed) { $this->_emailModel->setCustomerId(1); @@ -70,19 +95,14 @@ public function testSend($isCustomerIdUsed) } /** @var \Magento\Catalog\Model\Product $product */ - $product = $this->_objectManager->create(\Magento\Catalog\Model\Product::class); - $product->load(1); + $product = $this->productRepository->getById(1); $this->_emailModel->addPriceProduct($product); $this->_emailModel->send(); - /** @var \Magento\TestFramework\Mail\Template\TransportBuilderMock $transportBuilder */ - $transportBuilder = $this->_objectManager->get( - \Magento\TestFramework\Mail\Template\TransportBuilderMock::class - ); $this->assertContains( 'John Smith,', - $transportBuilder->getSentMessage()->getRawMessage() + $this->transportBuilder->getSentMessage()->getRawMessage() ); } @@ -93,4 +113,47 @@ public function customerFunctionDataProvider() [false], ]; } + + /** + * Assert that product price shown correct in email for customers with different customer groups. + * + * @magentoAppArea frontend + * @magentoDataFixture Magento/Catalog/_files/product_simple_with_wholesale_tier_price.php + * @magentoDataFixture Magento/Customer/_files/two_customers_with_different_customer_groups.php + * + * @return void + */ + public function testEmailForDifferentCustomers(): void + { + $customerGeneral = $this->customerRepository->get('customer@example.com'); + $customerWholesale = $this->customerRepository->get('customer_two@example.com'); + $product = $this->productRepository->get('simple'); + + /** @var Website $website */ + $website = $this->_objectManager->create(Website::class); + $website->load(1); + + $data = [ + $customerGeneral->getId() => '10', + $customerWholesale->getId() => '5', + ]; + + foreach ($data as $customerId => $expectedPrice) { + $this->_emailModel->clean(); + $this->_emailModel->setCustomerId($customerId); + $this->_emailModel->setWebsite($website); + $this->_emailModel->addStockProduct($product); + $this->_emailModel->setType('stock'); + $this->_emailModel->send(); + + $expectedPriceBox = '<span id="product-price-' . $product->getId() . '" data-price-amount="' + . $expectedPrice . '" data-price-type="finalPrice" ' + . 'class="price-wrapper "><span class="price">$' . $expectedPrice . '.00</span></span>'; + + $this->assertContains( + $expectedPriceBox, + $this->transportBuilder->getSentMessage()->getBody()->getParts()[0]->getRawContent() + ); + } + } } From adfa33f91c9ecb6bdfd913a6a9296531bd8d278b Mon Sep 17 00:00:00 2001 From: Andrii Meysar <andrii.meysar@transoftgroup.com> Date: Tue, 23 Jul 2019 14:39:17 +0300 Subject: [PATCH 042/191] MC-17929: 2.3.2 - Product Flat Data index taking long time to reindex? --- .../Indexer/Product/Flat/Action/FullTest.php | 84 +++++++++++++++---- .../enable_catalog_product_flat_indexer.php | 18 ++++ ..._catalog_product_flat_indexer_rollback.php | 18 ++++ 3 files changed, 106 insertions(+), 14 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/enable_catalog_product_flat_indexer.php create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/enable_catalog_product_flat_indexer_rollback.php diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Flat/Action/FullTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Flat/Action/FullTest.php index eb9e5664e0d9..dac642deaa66 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Flat/Action/FullTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Flat/Action/FullTest.php @@ -5,29 +5,44 @@ */ namespace Magento\Catalog\Model\Indexer\Product\Flat\Action; +use Magento\Catalog\Api\Data\ProductInterface; +use Magento\Catalog\Block\Product\ListProduct; +use Magento\Catalog\Model\CategoryFactory; +use Magento\Catalog\Model\Indexer\Product\Flat\Processor; +use Magento\Catalog\Model\Indexer\Product\Flat\State; +use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory as ProductCollectionFactory; +use Magento\Store\Model\StoreManagerInterface; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\ObjectManager; + /** * Full reindex Test */ class FullTest extends \Magento\TestFramework\Indexer\TestCase { /** - * @var \Magento\Catalog\Model\Indexer\Product\Flat\State + * @var State */ protected $_state; /** - * @var \Magento\Catalog\Model\Indexer\Product\Flat\Processor + * @var Processor */ protected $_processor; + /** + * @var ObjectManager + */ + private $objectManager; + + /** + * @inheritdoc + */ protected function setUp() { - $this->_state = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( - \Magento\Catalog\Model\Indexer\Product\Flat\State::class - ); - $this->_processor = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( - \Magento\Catalog\Model\Indexer\Product\Flat\Processor::class - ); + $this->objectManager = Bootstrap::getObjectManager(); + $this->_state = $this->objectManager->get(State::class); + $this->_processor = $this->objectManager->get(Processor::class); } /** @@ -41,12 +56,8 @@ public function testReindexAll() $this->assertTrue($this->_state->isFlatEnabled()); $this->_processor->reindexAll(); - $categoryFactory = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( - \Magento\Catalog\Model\CategoryFactory::class - ); - $listProduct = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( - \Magento\Catalog\Block\Product\ListProduct::class - ); + $categoryFactory = $this->objectManager->get(CategoryFactory::class); + $listProduct = $this->objectManager->get(ListProduct::class); $category = $categoryFactory->create()->load(2); $layer = $listProduct->getLayer(); @@ -61,4 +72,49 @@ public function testReindexAll() $this->assertEquals('Short description', $product->getShortDescription()); } } + + /** + * @magentoAppArea frontend + * @magentoDbIsolation disabled + * @magentoAppIsolation enabled + * @magentoDataFixture Magento/Catalog/_files/product_simple_multistore.php + * @magentoDataFixture Magento/Catalog/_files/enable_catalog_product_flat_indexer.php + */ + public function testReindexAllMultipleStores() + { + $this->_state = $this->objectManager->create(State::class); + $this->_processor = $this->objectManager->create(Processor::class); + + $this->assertTrue($this->_state->isFlatEnabled()); + $this->_processor->reindexAll(); + + /** @var ProductCollectionFactory $productCollectionFactory */ + $productCollectionFactory = $this->objectManager->create(ProductCollectionFactory::class); + /** @var StoreManagerInterface $storeManager */ + $storeManager = $this->objectManager->get(StoreManagerInterface::class); + $store = $storeManager->getStore('fixturestore'); + + $expectedData = [ + $storeManager->getDefaultStoreView()->getId() => 'Simple Product One', + $store->getId() => 'StoreTitle', + ]; + + foreach ($expectedData as $storeId => $productName) { + $storeManager->setCurrentStore($storeId); + $productCollection = $productCollectionFactory->create(); + + $this->assertTrue( + $productCollection->isEnabledFlat(), + 'Flat should be enabled for product collection.' + ); + + $productCollection->addIdFilter(1)->addAttributeToSelect(ProductInterface::NAME); + + $this->assertEquals( + $productName, + $productCollection->getFirstItem()->getName(), + 'Wrong product name specified per store.' + ); + } + } } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/enable_catalog_product_flat_indexer.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/enable_catalog_product_flat_indexer.php new file mode 100644 index 000000000000..2bd7c3a71d7e --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/enable_catalog_product_flat_indexer.php @@ -0,0 +1,18 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Catalog\Model\Indexer\Product\Flat\State; +use Magento\Config\Model\ResourceModel\Config; +use Magento\Framework\App\Config\ReinitableConfigInterface; +use Magento\TestFramework\Helper\Bootstrap; + +$objectManager = Bootstrap::getObjectManager(); + +/** @var Config $config */ +$config = $objectManager->create(Config::class); +$config->saveConfig(State::INDEXER_ENABLED_XML_PATH, 1); +$objectManager->get(ReinitableConfigInterface::class)->reinit(); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/enable_catalog_product_flat_indexer_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/enable_catalog_product_flat_indexer_rollback.php new file mode 100644 index 000000000000..9386f5963205 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/enable_catalog_product_flat_indexer_rollback.php @@ -0,0 +1,18 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Catalog\Model\Indexer\Product\Flat\State; +use Magento\Config\Model\ResourceModel\Config; +use Magento\Framework\App\Config\ReinitableConfigInterface; +use Magento\TestFramework\Helper\Bootstrap; + +$objectManager = Bootstrap::getObjectManager(); + +/** @var Config $config */ +$config = $objectManager->create(Config::class); +$config->deleteConfig(State::INDEXER_ENABLED_XML_PATH); +$objectManager->get(ReinitableConfigInterface::class)->reinit(); From 8ebe20492d3809636731368bb45cbed87bb2d996 Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Tue, 23 Jul 2019 08:57:52 -0500 Subject: [PATCH 043/191] MC-17868: Break jQuery UI into widgets and make a prototype - Downgrade jquery ui widget to 1.9.2 version; --- lib/web/jquery/ui-modules/widget.js | 75 ++++++++++++++++------------- 1 file changed, 41 insertions(+), 34 deletions(-) diff --git a/lib/web/jquery/ui-modules/widget.js b/lib/web/jquery/ui-modules/widget.js index ef8c1ef0e60f..91e9565d46f5 100644 --- a/lib/web/jquery/ui-modules/widget.js +++ b/lib/web/jquery/ui-modules/widget.js @@ -29,9 +29,6 @@ define([ $.widget = function (name, base, prototype) { var fullName, existingConstructor, constructor, basePrototype, - // proxiedPrototype allows the provided prototype to remain unmodified - // so that it can be used as a mixin for multiple widgets (#8876) - proxiedPrototype = {}, namespace = name.split(".")[0]; name = name.split(".")[1]; @@ -78,43 +75,43 @@ define([ // inheriting from basePrototype.options = $.widget.extend({}, basePrototype.options); $.each(prototype, function (prop, value) { - if (!$.isFunction(value)) { - proxiedPrototype[prop] = value; - return; - } - proxiedPrototype[prop] = (function () { - var _super = function () { - return base.prototype[prop].apply(this, arguments); - }, - _superApply = function (args) { - return base.prototype[prop].apply(this, args); + if ($.isFunction(value)) { + prototype[prop] = (function () { + var _super = function () { + return base.prototype[prop].apply(this, arguments); + }, + _superApply = function (args) { + return base.prototype[prop].apply(this, args); + }; + return function () { + var __super = this._super, + __superApply = this._superApply, + returnValue; + + this._super = _super; + this._superApply = _superApply; + + returnValue = value.apply(this, arguments); + + this._super = __super; + this._superApply = __superApply; + + return returnValue; }; - return function () { - var __super = this._super, - __superApply = this._superApply, - 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, { + widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name + }, prototype, { constructor: constructor, namespace: namespace, widgetName: name, + // TODO remove widgetBaseClass, see #8155 + widgetBaseClass: fullName, widgetFullName: fullName }); @@ -241,6 +238,9 @@ define([ this.focusable = $(); if (element !== this) { + // 1.9 BC for #7810 + // TODO remove dual storage + $.data(element, this.widgetName, this); $.data(element, this.widgetFullName, this); this._on(true, this.element, { remove: function (event) { @@ -320,12 +320,12 @@ define([ curOption = curOption[parts[i]]; } key = parts.pop(); - if (arguments.length === 1) { + if (value === undefined) { return curOption[key] === undefined ? null : curOption[key]; } curOption[key] = value; } else { - if (arguments.length === 1) { + if (value === undefined) { return this.options[key] === undefined ? null : this.options[key]; } options[key] = value; @@ -508,7 +508,7 @@ define([ if (options.delay) { element.delay(options.delay); } - if (hasOptions && $.effects && $.effects.effect[effectName]) { + if (hasOptions && $.effects && ($.effects.effect[effectName] || $.uiBackCompat !== false && $.effects[effectName])) { element[method](options); } else if (effectName !== method && element[effectName]) { element[effectName](options.duration, options.easing, callback); @@ -524,4 +524,11 @@ define([ }; }); +// DEPRECATED + if ($.uiBackCompat !== false) { + $.Widget.prototype._getCreateOptions = function () { + return $.metadata && $.metadata.get(this.element[0])[this.widgetName]; + }; + } + }); From d73f49ee5a0eaaca9fee22bfc39091b4a0eef853 Mon Sep 17 00:00:00 2001 From: Andrii Meysar <andrii.meysar@transoftgroup.com> Date: Tue, 23 Jul 2019 17:38:38 +0300 Subject: [PATCH 044/191] MC-17929: 2.3.2 - Product Flat Data index taking long time to reindex? --- .../Catalog/Model/Indexer/Product/Flat/Action/FullTest.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Flat/Action/FullTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Flat/Action/FullTest.php index dac642deaa66..686091b12e37 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Flat/Action/FullTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Flat/Action/FullTest.php @@ -116,5 +116,8 @@ public function testReindexAllMultipleStores() 'Wrong product name specified per store.' ); } + + $this->objectManager->removeSharedInstance(State::class); + $this->objectManager->removeSharedInstance(Processor::class); } } From b6490fe11691c153e736a0562a9a7875e5f20d7f Mon Sep 17 00:00:00 2001 From: beltong <gregorybelton@gmail.com> Date: Tue, 23 Jul 2019 16:53:22 +0100 Subject: [PATCH 045/191] Fix regular expression comment on function isNameValid() --- lib/internal/Magento/Framework/Api/ImageContentValidator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Api/ImageContentValidator.php b/lib/internal/Magento/Framework/Api/ImageContentValidator.php index cc5e830f6723..91df08152386 100644 --- a/lib/internal/Magento/Framework/Api/ImageContentValidator.php +++ b/lib/internal/Magento/Framework/Api/ImageContentValidator.php @@ -86,7 +86,7 @@ protected function isMimeTypeValid($mimeType) */ protected function isNameValid($name) { - // Cannot contain \ / : * ? " < > | + // Cannot contain \ / ? * : " ; < > ( ) | { } if (!preg_match('/^[^\\/?*:";<>()|{}\\\\]+$/', $name)) { return false; } From 01af315e8227dfa814125a9a796d91c930b571af Mon Sep 17 00:00:00 2001 From: Andrii Meysar <andrii.meysar@transoftgroup.com> Date: Tue, 23 Jul 2019 20:45:13 +0300 Subject: [PATCH 046/191] MC-17929: 2.3.2 - Product Flat Data index taking long time to reindex? --- .../Catalog/Model/Indexer/Product/Flat/Action/FullTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Flat/Action/FullTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Flat/Action/FullTest.php index 686091b12e37..f23f0b92eeec 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Flat/Action/FullTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Flat/Action/FullTest.php @@ -93,6 +93,7 @@ public function testReindexAllMultipleStores() /** @var StoreManagerInterface $storeManager */ $storeManager = $this->objectManager->get(StoreManagerInterface::class); $store = $storeManager->getStore('fixturestore'); + $currentStore = $storeManager->getStore(); $expectedData = [ $storeManager->getDefaultStoreView()->getId() => 'Simple Product One', @@ -117,6 +118,7 @@ public function testReindexAllMultipleStores() ); } + $storeManager->setCurrentStore($currentStore); $this->objectManager->removeSharedInstance(State::class); $this->objectManager->removeSharedInstance(Processor::class); } From a5c67831e0b6d8974700e7cb134c054c6e9f3131 Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Tue, 23 Jul 2019 13:38:03 -0500 Subject: [PATCH 047/191] MC-17868: Break jQuery UI into widgets and make a prototype - Add separate jquery ui widget component v1.9.2 for adminhtml area; - Update jquery ui components description; - Update requirejs config; --- .../Theme/view/adminhtml/requirejs-config.js | 41 +- .../Theme/view/frontend/requirejs-config.js | 3 - lib/web/jquery/jquery-ui-widget-1.9.2.js | 534 ++++++++++++++++++ lib/web/jquery/ui-modules/accordion.js | 2 +- lib/web/jquery/ui-modules/autocomplete.js | 2 +- lib/web/jquery/ui-modules/button.js | 2 +- lib/web/jquery/ui-modules/core.js | 2 +- lib/web/jquery/ui-modules/datepicker.js | 2 +- lib/web/jquery/ui-modules/dialog.js | 2 +- lib/web/jquery/ui-modules/draggable.js | 2 +- lib/web/jquery/ui-modules/droppable.js | 2 +- lib/web/jquery/ui-modules/effect-blind.js | 2 +- lib/web/jquery/ui-modules/effect-bounce.js | 2 +- lib/web/jquery/ui-modules/effect-clip.js | 2 +- lib/web/jquery/ui-modules/effect-drop.js | 2 +- lib/web/jquery/ui-modules/effect-explode.js | 2 +- lib/web/jquery/ui-modules/effect-fade.js | 2 +- lib/web/jquery/ui-modules/effect-fold.js | 2 +- lib/web/jquery/ui-modules/effect-highlight.js | 2 +- lib/web/jquery/ui-modules/effect-pulsate.js | 2 +- lib/web/jquery/ui-modules/effect-scale.js | 2 +- lib/web/jquery/ui-modules/effect-shake.js | 2 +- lib/web/jquery/ui-modules/effect-slide.js | 2 +- lib/web/jquery/ui-modules/effect-transfer.js | 2 +- lib/web/jquery/ui-modules/effect.js | 2 +- lib/web/jquery/ui-modules/menu.js | 2 +- lib/web/jquery/ui-modules/mouse.js | 5 +- lib/web/jquery/ui-modules/position.js | 2 +- lib/web/jquery/ui-modules/progressbar.js | 2 +- lib/web/jquery/ui-modules/resizable.js | 2 +- lib/web/jquery/ui-modules/selectable.js | 2 +- lib/web/jquery/ui-modules/slider.js | 2 +- lib/web/jquery/ui-modules/sortable.js | 2 +- lib/web/jquery/ui-modules/spinner.js | 2 +- lib/web/jquery/ui-modules/tabs.js | 6 +- lib/web/jquery/ui-modules/tooltip.js | 2 +- lib/web/jquery/ui-modules/widget.js | 77 ++- 37 files changed, 623 insertions(+), 105 deletions(-) create mode 100644 lib/web/jquery/jquery-ui-widget-1.9.2.js diff --git a/app/code/Magento/Theme/view/adminhtml/requirejs-config.js b/app/code/Magento/Theme/view/adminhtml/requirejs-config.js index 81269b87d583..6bb0f79f008e 100644 --- a/app/code/Magento/Theme/view/adminhtml/requirejs-config.js +++ b/app/code/Magento/Theme/view/adminhtml/requirejs-config.js @@ -28,26 +28,27 @@ var config = { }, 'map': { '*': { - 'translateInline': 'mage/translate-inline', - 'form': 'mage/backend/form', - 'button': 'mage/backend/button', - 'accordion': 'mage/accordion', - 'actionLink': 'mage/backend/action-link', - 'validation': 'mage/backend/validation', - 'notification': 'mage/backend/notification', - 'loader': 'mage/loader_old', - 'loaderAjax': 'mage/loader_old', - 'floatingHeader': 'mage/backend/floating-header', - 'suggest': 'mage/backend/suggest', - 'mediabrowser': 'jquery/jstree/jquery.jstree', - 'tabs': 'mage/backend/tabs', - 'treeSuggest': 'mage/backend/tree-suggest', - 'calendar': 'mage/calendar', - 'dropdown': 'mage/dropdown_old', - 'collapsible': 'mage/collapsible', - 'menu': 'mage/backend/menu', - 'jstree': 'jquery/jstree/jquery.jstree', - 'details': 'jquery/jquery.details' + 'translateInline': 'mage/translate-inline', + 'form': 'mage/backend/form', + 'button': 'mage/backend/button', + 'accordion': 'mage/accordion', + 'actionLink': 'mage/backend/action-link', + 'validation': 'mage/backend/validation', + 'notification': 'mage/backend/notification', + 'loader': 'mage/loader_old', + 'loaderAjax': 'mage/loader_old', + 'floatingHeader': 'mage/backend/floating-header', + 'suggest': 'mage/backend/suggest', + 'mediabrowser': 'jquery/jstree/jquery.jstree', + 'tabs': 'mage/backend/tabs', + 'treeSuggest': 'mage/backend/tree-suggest', + 'calendar': 'mage/calendar', + 'dropdown': 'mage/dropdown_old', + 'collapsible': 'mage/collapsible', + 'menu': 'mage/backend/menu', + 'jstree': 'jquery/jstree/jquery.jstree', + 'details': 'jquery/jquery.details', + 'jquery-ui-modules/widget': 'jquery/jquery-ui-widget-1.9.2' } }, 'deps': [ diff --git a/app/code/Magento/Theme/view/frontend/requirejs-config.js b/app/code/Magento/Theme/view/frontend/requirejs-config.js index 952353eb3aff..d1cf76b83ebb 100644 --- a/app/code/Magento/Theme/view/frontend/requirejs-config.js +++ b/app/code/Magento/Theme/view/frontend/requirejs-config.js @@ -33,9 +33,6 @@ var config = { 'jquery/ui': 'jquery/compat' } }, - paths: { - 'jquery/ui': 'jquery/jquery-ui' - }, deps: [ 'jquery/jquery.mobile.custom', 'mage/common', diff --git a/lib/web/jquery/jquery-ui-widget-1.9.2.js b/lib/web/jquery/jquery-ui-widget-1.9.2.js new file mode 100644 index 000000000000..37631850c1dd --- /dev/null +++ b/lib/web/jquery/jquery-ui-widget-1.9.2.js @@ -0,0 +1,534 @@ +/*! + * jQuery UI Widget - v1.9.2 for adminhtml area + * http://jqueryui.com + * + * Copyright 2014 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/jQuery.widget/ + */ + +define([ + 'jquery' +], function ($, undefined) { + + var uuid = 0, + slice = Array.prototype.slice, + _cleanData = $.cleanData; + $.cleanData = function (elems) { + for (var i = 0, elem; (elem = elems[i]) != null; i++) { + try { + $(elem).triggerHandler("remove"); + // http://bugs.jquery.com/ticket/8235 + } catch (e) { + } + } + _cleanData(elems); + }; + + $.widget = function (name, base, prototype) { + var fullName, existingConstructor, constructor, basePrototype, + namespace = name.split(".")[0]; + + name = name.split(".")[1]; + fullName = namespace + "-" + name; + + if (!prototype) { + prototype = base; + base = $.Widget; + } + + // create selector for plugin + $.expr[":"][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._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 ($.isFunction(value)) { + prototype[prop] = (function () { + var _super = function () { + return base.prototype[prop].apply(this, arguments); + }, + _superApply = function (args) { + return base.prototype[prop].apply(this, args); + }; + return function () { + var __super = this._super, + __superApply = this._superApply, + 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 + }, prototype, { + constructor: constructor, + namespace: namespace, + widgetName: name, + // TODO remove widgetBaseClass, see #8155 + widgetBaseClass: fullName, + 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); + }; + + $.widget.extend = function (target) { + var input = slice.call(arguments, 1), + inputIndex = 0, + inputLength = input.length, + key, + value; + for (; inputIndex < inputLength; inputIndex++) { + for (key in input[inputIndex]) { + value = input[inputIndex][key]; + if (input[inputIndex].hasOwnProperty(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", + args = slice.call(arguments, 1), + returnValue = this; + + // allow multiple hashes to be passed on init + options = !isMethodCall && args.length ? + $.widget.extend.apply(null, [options].concat(args)) : + options; + + if (isMethodCall) { + this.each(function () { + var methodValue, + instance = $.data(this, fullName); + if (!instance) { + return $.error("cannot call methods on " + name + " prior to initialization; " + + "attempted to call method '" + options + "'"); + } + if (!$.isFunction(instance[options]) || 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 { + this.each(function () { + var instance = $.data(this, fullName); + if (instance) { + instance.option(options || {})._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: { + disabled: false, + + // callbacks + create: null + }, + _createWidget: function (options, element) { + element = $(element || this.defaultElement || this)[0]; + this.element = $(element); + this.uuid = uuid++; + this.eventNamespace = "." + this.widgetName + this.uuid; + this.options = $.widget.extend({}, + this.options, + this._getCreateOptions(), + options); + + this.bindings = $(); + this.hoverable = $(); + this.focusable = $(); + + if (element !== this) { + // 1.9 BC for #7810 + // TODO remove dual storage + $.data(element, this.widgetName, 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._create(); + this._trigger("create", null, this._getCreateEventData()); + this._init(); + }, + _getCreateOptions: $.noop, + _getCreateEventData: $.noop, + _create: $.noop, + _init: $.noop, + + destroy: function () { + this._destroy(); + // we can probably remove the unbind calls in 2.0 + // all event bindings should go through this._on() + this.element + .unbind(this.eventNamespace) + // 1.9 BC for #7810 + // TODO remove dual storage + .removeData(this.widgetName) + .removeData(this.widgetFullName) + // support: jquery <1.6.3 + // http://bugs.jquery.com/ticket/9413 + .removeData($.camelCase(this.widgetFullName)); + this.widget() + .unbind(this.eventNamespace) + .removeAttr("aria-disabled") + .removeClass( + this.widgetFullName + "-disabled " + + "ui-state-disabled"); + + // clean up events and states + this.bindings.unbind(this.eventNamespace); + this.hoverable.removeClass("ui-state-hover"); + this.focusable.removeClass("ui-state-focus"); + }, + _destroy: $.noop, + + widget: function () { + return this.element; + }, + + option: function (key, value) { + var options = key, + parts, + curOption, + 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 (value === undefined) { + return curOption[key] === undefined ? null : curOption[key]; + } + curOption[key] = value; + } else { + if (value === undefined) { + 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) { + this.options[key] = value; + + if (key === "disabled") { + this.widget() + .toggleClass(this.widgetFullName + "-disabled ui-state-disabled", !!value) + .attr("aria-disabled", value); + this.hoverable.removeClass("ui-state-hover"); + this.focusable.removeClass("ui-state-focus"); + } + + return this; + }, + + enable: function () { + return this._setOption("disabled", false); + }, + disable: function () { + return this._setOption("disabled", true); + }, + + _on: function (suppressDisabledCheck, element, handlers) { + var delegateElement, + 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 { + // accept selectors, DOM elements + 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*(.*)$/), + eventName = match[1] + instance.eventNamespace, + selector = match[2]; + if (selector) { + delegateElement.delegate(selector, eventName, handlerProxy); + } else { + element.bind(eventName, handlerProxy); + } + }); + }, + + _off: function (element, eventName) { + eventName = (eventName || "").split(" ").join(this.eventNamespace + " ") + this.eventNamespace; + element.unbind(eventName).undelegate(eventName); + }, + + _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) { + $(event.currentTarget).addClass("ui-state-hover"); + }, + mouseleave: function (event) { + $(event.currentTarget).removeClass("ui-state-hover"); + } + }); + }, + + _focusable: function (element) { + this.focusable = this.focusable.add(element); + this._on(element, { + focusin: function (event) { + $(event.currentTarget).addClass("ui-state-focus"); + }, + focusout: function (event) { + $(event.currentTarget).removeClass("ui-state-focus"); + } + }); + }, + + _trigger: function (type, event, data) { + var prop, orig, + 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 !($.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, + 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] || $.uiBackCompat !== false && $.effects[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(); + }); + } + }; + }); + +// DEPRECATED + if ($.uiBackCompat !== false) { + $.Widget.prototype._getCreateOptions = function () { + return $.metadata && $.metadata.get(this.element[0])[this.widgetName]; + }; + } + +}); diff --git a/lib/web/jquery/ui-modules/accordion.js b/lib/web/jquery/ui-modules/accordion.js index 7da6ace8d896..de3bf49026fe 100644 --- a/lib/web/jquery/ui-modules/accordion.js +++ b/lib/web/jquery/ui-modules/accordion.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Accordion + * jQuery UI Accordion - v1.10.4 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors diff --git a/lib/web/jquery/ui-modules/autocomplete.js b/lib/web/jquery/ui-modules/autocomplete.js index 34f9d1b150c2..3d70336c08f7 100644 --- a/lib/web/jquery/ui-modules/autocomplete.js +++ b/lib/web/jquery/ui-modules/autocomplete.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Autocomplete + * jQuery UI Autocomplete - v1.10.4 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors diff --git a/lib/web/jquery/ui-modules/button.js b/lib/web/jquery/ui-modules/button.js index 36f93d752c02..571fd97d6c9a 100644 --- a/lib/web/jquery/ui-modules/button.js +++ b/lib/web/jquery/ui-modules/button.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Button + * jQuery UI Button - v1.10.4 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors diff --git a/lib/web/jquery/ui-modules/core.js b/lib/web/jquery/ui-modules/core.js index fdd91cd38d30..ec860f140f26 100644 --- a/lib/web/jquery/ui-modules/core.js +++ b/lib/web/jquery/ui-modules/core.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Core + * jQuery UI Core - v1.10.4 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors diff --git a/lib/web/jquery/ui-modules/datepicker.js b/lib/web/jquery/ui-modules/datepicker.js index e3e725d1f3b7..77684e255874 100644 --- a/lib/web/jquery/ui-modules/datepicker.js +++ b/lib/web/jquery/ui-modules/datepicker.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Datepicker + * jQuery UI Datepicker - v1.10.4 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors diff --git a/lib/web/jquery/ui-modules/dialog.js b/lib/web/jquery/ui-modules/dialog.js index bd9a60a8fbe2..295b1b7942e5 100644 --- a/lib/web/jquery/ui-modules/dialog.js +++ b/lib/web/jquery/ui-modules/dialog.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Dialog + * jQuery UI Dialog - v1.10.4 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors diff --git a/lib/web/jquery/ui-modules/draggable.js b/lib/web/jquery/ui-modules/draggable.js index b17ca262c5ec..3e3a588566b4 100644 --- a/lib/web/jquery/ui-modules/draggable.js +++ b/lib/web/jquery/ui-modules/draggable.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Draggable + * jQuery UI Draggable - v1.10.4 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors diff --git a/lib/web/jquery/ui-modules/droppable.js b/lib/web/jquery/ui-modules/droppable.js index 4231f31ff4d5..22cba124493c 100644 --- a/lib/web/jquery/ui-modules/droppable.js +++ b/lib/web/jquery/ui-modules/droppable.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Droppable + * jQuery UI Droppable - v1.10.4 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors diff --git a/lib/web/jquery/ui-modules/effect-blind.js b/lib/web/jquery/ui-modules/effect-blind.js index 89b2069b82e1..afd1a5285cad 100644 --- a/lib/web/jquery/ui-modules/effect-blind.js +++ b/lib/web/jquery/ui-modules/effect-blind.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Effects Blind + * jQuery UI Effects Blind - v1.10.4 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors diff --git a/lib/web/jquery/ui-modules/effect-bounce.js b/lib/web/jquery/ui-modules/effect-bounce.js index 62a079752660..1902dc1b88f5 100644 --- a/lib/web/jquery/ui-modules/effect-bounce.js +++ b/lib/web/jquery/ui-modules/effect-bounce.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Effects Bounce + * jQuery UI Effects Bounce - v1.10.4 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors diff --git a/lib/web/jquery/ui-modules/effect-clip.js b/lib/web/jquery/ui-modules/effect-clip.js index 2463757151a2..a3651b303f05 100644 --- a/lib/web/jquery/ui-modules/effect-clip.js +++ b/lib/web/jquery/ui-modules/effect-clip.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Effects Clip + * jQuery UI Effects Clip - v1.10.4 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors diff --git a/lib/web/jquery/ui-modules/effect-drop.js b/lib/web/jquery/ui-modules/effect-drop.js index 45058916b759..4b5025a2aa59 100644 --- a/lib/web/jquery/ui-modules/effect-drop.js +++ b/lib/web/jquery/ui-modules/effect-drop.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Effects Drop + * jQuery UI Effects Drop - v1.10.4 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors diff --git a/lib/web/jquery/ui-modules/effect-explode.js b/lib/web/jquery/ui-modules/effect-explode.js index e902ae654e2f..3ec72fbf5a8c 100644 --- a/lib/web/jquery/ui-modules/effect-explode.js +++ b/lib/web/jquery/ui-modules/effect-explode.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Effects Explode + * jQuery UI Effects Explode - v1.10.4 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors diff --git a/lib/web/jquery/ui-modules/effect-fade.js b/lib/web/jquery/ui-modules/effect-fade.js index 71d2ac769abd..ba289cbeb018 100644 --- a/lib/web/jquery/ui-modules/effect-fade.js +++ b/lib/web/jquery/ui-modules/effect-fade.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Effects Fade + * jQuery UI Effects Fade - v1.10.4 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors diff --git a/lib/web/jquery/ui-modules/effect-fold.js b/lib/web/jquery/ui-modules/effect-fold.js index ece8ade1a02c..a9816cc53d7d 100644 --- a/lib/web/jquery/ui-modules/effect-fold.js +++ b/lib/web/jquery/ui-modules/effect-fold.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Effects Fold + * jQuery UI Effects Fold - v1.10.4 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors diff --git a/lib/web/jquery/ui-modules/effect-highlight.js b/lib/web/jquery/ui-modules/effect-highlight.js index a852b51efb4a..caa2596e95d4 100644 --- a/lib/web/jquery/ui-modules/effect-highlight.js +++ b/lib/web/jquery/ui-modules/effect-highlight.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Effects Highlight + * jQuery UI Effects Highlight - v1.10.4 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors diff --git a/lib/web/jquery/ui-modules/effect-pulsate.js b/lib/web/jquery/ui-modules/effect-pulsate.js index c8dd9f7847aa..cd9f202a153c 100644 --- a/lib/web/jquery/ui-modules/effect-pulsate.js +++ b/lib/web/jquery/ui-modules/effect-pulsate.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Effects Pulsate + * jQuery UI Effects Pulsate - v1.10.4 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors diff --git a/lib/web/jquery/ui-modules/effect-scale.js b/lib/web/jquery/ui-modules/effect-scale.js index b3c6675b460b..18968e7183d6 100644 --- a/lib/web/jquery/ui-modules/effect-scale.js +++ b/lib/web/jquery/ui-modules/effect-scale.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Effects Scale + * jQuery UI Effects Scale - v1.10.4 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors diff --git a/lib/web/jquery/ui-modules/effect-shake.js b/lib/web/jquery/ui-modules/effect-shake.js index 8a4d7c21d2be..21dce9ccc70a 100644 --- a/lib/web/jquery/ui-modules/effect-shake.js +++ b/lib/web/jquery/ui-modules/effect-shake.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Effects Shake + * jQuery UI Effects Shake - v1.10.4 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors diff --git a/lib/web/jquery/ui-modules/effect-slide.js b/lib/web/jquery/ui-modules/effect-slide.js index 0cdf366f3778..eb81d8716918 100644 --- a/lib/web/jquery/ui-modules/effect-slide.js +++ b/lib/web/jquery/ui-modules/effect-slide.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Effects Slide + * jQuery UI Effects Slide - v1.10.4 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors diff --git a/lib/web/jquery/ui-modules/effect-transfer.js b/lib/web/jquery/ui-modules/effect-transfer.js index 2328edd79bce..a3d0af86beb8 100644 --- a/lib/web/jquery/ui-modules/effect-transfer.js +++ b/lib/web/jquery/ui-modules/effect-transfer.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Effects Transfer + * jQuery UI Effects Transfer - v1.10.4 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors diff --git a/lib/web/jquery/ui-modules/effect.js b/lib/web/jquery/ui-modules/effect.js index f73a076f2a00..5a1e8adf7cae 100644 --- a/lib/web/jquery/ui-modules/effect.js +++ b/lib/web/jquery/ui-modules/effect.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Effects + * jQuery UI Effects - v1.10.4 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors diff --git a/lib/web/jquery/ui-modules/menu.js b/lib/web/jquery/ui-modules/menu.js index b314075c5c4d..6d575b0462a9 100644 --- a/lib/web/jquery/ui-modules/menu.js +++ b/lib/web/jquery/ui-modules/menu.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Menu + * jQuery UI Menu - v1.10.4 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors diff --git a/lib/web/jquery/ui-modules/mouse.js b/lib/web/jquery/ui-modules/mouse.js index a45b92a5a11c..aefa64a5ea0a 100644 --- a/lib/web/jquery/ui-modules/mouse.js +++ b/lib/web/jquery/ui-modules/mouse.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Mouse + * jQuery UI Mouse - v1.10.4 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors @@ -7,9 +7,6 @@ * http://jquery.org/license * * http://api.jqueryui.com/mouse/ - * - * Depends: - * jquery.ui.widget.js */ define([ diff --git a/lib/web/jquery/ui-modules/position.js b/lib/web/jquery/ui-modules/position.js index 74f8df320d68..eedacebc0174 100644 --- a/lib/web/jquery/ui-modules/position.js +++ b/lib/web/jquery/ui-modules/position.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Position + * jQuery UI Position - v1.10.4 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors diff --git a/lib/web/jquery/ui-modules/progressbar.js b/lib/web/jquery/ui-modules/progressbar.js index 0f177d19f696..f38ece369e87 100644 --- a/lib/web/jquery/ui-modules/progressbar.js +++ b/lib/web/jquery/ui-modules/progressbar.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Progressbar + * jQuery UI Progressbar - v1.10.4 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors diff --git a/lib/web/jquery/ui-modules/resizable.js b/lib/web/jquery/ui-modules/resizable.js index 7758e30fee64..9a27f382eb46 100644 --- a/lib/web/jquery/ui-modules/resizable.js +++ b/lib/web/jquery/ui-modules/resizable.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Resizable + * jQuery UI Resizable - v1.10.4 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors diff --git a/lib/web/jquery/ui-modules/selectable.js b/lib/web/jquery/ui-modules/selectable.js index 5ec60733b9b5..67ba54f27624 100644 --- a/lib/web/jquery/ui-modules/selectable.js +++ b/lib/web/jquery/ui-modules/selectable.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Selectable + * jQuery UI Selectable - v1.10.4 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors diff --git a/lib/web/jquery/ui-modules/slider.js b/lib/web/jquery/ui-modules/slider.js index 963caf156d8f..d6828e1c3bf2 100644 --- a/lib/web/jquery/ui-modules/slider.js +++ b/lib/web/jquery/ui-modules/slider.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Slider + * jQuery UI Slider - v1.10.4 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors diff --git a/lib/web/jquery/ui-modules/sortable.js b/lib/web/jquery/ui-modules/sortable.js index 026516597432..a5bab5d846e4 100644 --- a/lib/web/jquery/ui-modules/sortable.js +++ b/lib/web/jquery/ui-modules/sortable.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Sortable + * jQuery UI Sortable - v1.10.4 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors diff --git a/lib/web/jquery/ui-modules/spinner.js b/lib/web/jquery/ui-modules/spinner.js index cfa4cf1e3676..6412a099f070 100644 --- a/lib/web/jquery/ui-modules/spinner.js +++ b/lib/web/jquery/ui-modules/spinner.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Spinner + * jQuery UI Spinner - v1.10.4 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors diff --git a/lib/web/jquery/ui-modules/tabs.js b/lib/web/jquery/ui-modules/tabs.js index fe1dfbabee55..32c592de959e 100644 --- a/lib/web/jquery/ui-modules/tabs.js +++ b/lib/web/jquery/ui-modules/tabs.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Tabs @VERSION + * jQuery UI Tabs - v1.10.4 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors @@ -7,10 +7,6 @@ * http://jquery.org/license * * http://api.jqueryui.com/tabs/ - * - * Depends: - * jquery.ui.core.js - * jquery.ui.widget.js */ define([ diff --git a/lib/web/jquery/ui-modules/tooltip.js b/lib/web/jquery/ui-modules/tooltip.js index 17aaa49cdbde..61ec01071432 100644 --- a/lib/web/jquery/ui-modules/tooltip.js +++ b/lib/web/jquery/ui-modules/tooltip.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Tooltip + * jQuery UI Tooltip - v1.10.4 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors diff --git a/lib/web/jquery/ui-modules/widget.js b/lib/web/jquery/ui-modules/widget.js index 91e9565d46f5..6c5dcbaa742e 100644 --- a/lib/web/jquery/ui-modules/widget.js +++ b/lib/web/jquery/ui-modules/widget.js @@ -1,5 +1,5 @@ /*! - * jQuery UI Widget + * jQuery UI Widget - v1.10.4 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors @@ -29,6 +29,9 @@ define([ $.widget = function (name, base, prototype) { var fullName, existingConstructor, constructor, basePrototype, + // proxiedPrototype allows the provided prototype to remain unmodified + // so that it can be used as a mixin for multiple widgets (#8876) + proxiedPrototype = {}, namespace = name.split(".")[0]; name = name.split(".")[1]; @@ -75,43 +78,43 @@ define([ // inheriting from basePrototype.options = $.widget.extend({}, basePrototype.options); $.each(prototype, function (prop, value) { - if ($.isFunction(value)) { - prototype[prop] = (function () { - var _super = function () { - return base.prototype[prop].apply(this, arguments); - }, - _superApply = function (args) { - return base.prototype[prop].apply(this, args); - }; - return function () { - var __super = this._super, - __superApply = this._superApply, - returnValue; - - this._super = _super; - this._superApply = _superApply; - - returnValue = value.apply(this, arguments); - - this._super = __super; - this._superApply = __superApply; - - return returnValue; - }; - })(); + if (!$.isFunction(value)) { + proxiedPrototype[prop] = value; + return; } + proxiedPrototype[prop] = (function () { + var _super = function () { + return base.prototype[prop].apply(this, arguments); + }, + _superApply = function (args) { + return base.prototype[prop].apply(this, args); + }; + return function () { + var __super = this._super, + __superApply = this._superApply, + 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 - }, prototype, { + widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name + }, proxiedPrototype, { constructor: constructor, namespace: namespace, widgetName: name, - // TODO remove widgetBaseClass, see #8155 - widgetBaseClass: fullName, widgetFullName: fullName }); @@ -238,9 +241,6 @@ define([ this.focusable = $(); if (element !== this) { - // 1.9 BC for #7810 - // TODO remove dual storage - $.data(element, this.widgetName, this); $.data(element, this.widgetFullName, this); this._on(true, this.element, { remove: function (event) { @@ -320,12 +320,12 @@ define([ curOption = curOption[parts[i]]; } key = parts.pop(); - if (value === undefined) { + if (arguments.length === 1) { return curOption[key] === undefined ? null : curOption[key]; } curOption[key] = value; } else { - if (value === undefined) { + if (arguments.length === 1) { return this.options[key] === undefined ? null : this.options[key]; } options[key] = value; @@ -508,7 +508,7 @@ define([ if (options.delay) { element.delay(options.delay); } - if (hasOptions && $.effects && ($.effects.effect[effectName] || $.uiBackCompat !== false && $.effects[effectName])) { + if (hasOptions && $.effects && $.effects.effect[effectName]) { element[method](options); } else if (effectName !== method && element[effectName]) { element[effectName](options.duration, options.easing, callback); @@ -524,11 +524,4 @@ define([ }; }); -// DEPRECATED - if ($.uiBackCompat !== false) { - $.Widget.prototype._getCreateOptions = function () { - return $.metadata && $.metadata.get(this.element[0])[this.widgetName]; - }; - } - }); From aab7f2e075c568fca80e002ff2b8639c9da3447d Mon Sep 17 00:00:00 2001 From: Dave Macaulay <macaulay@adobe.com> Date: Tue, 23 Jul 2019 16:50:18 -0500 Subject: [PATCH 048/191] MC-4137: TinyMCE Issues within inline WYSIWYG - Upgrade to the latest 4 version of TinyMCE --- lib/web/tiny_mce_4/jquery.tinymce.min.js | 2 +- .../tiny_mce_4/plugins/advlist/plugin.min.js | 2 +- .../tiny_mce_4/plugins/anchor/plugin.min.js | 2 +- .../tiny_mce_4/plugins/autolink/plugin.min.js | 2 +- .../plugins/autoresize/plugin.min.js | 2 +- .../tiny_mce_4/plugins/autosave/plugin.min.js | 2 +- .../tiny_mce_4/plugins/bbcode/plugin.min.js | 2 +- .../tiny_mce_4/plugins/charmap/plugin.min.js | 2 +- lib/web/tiny_mce_4/plugins/code/plugin.min.js | 2 +- .../plugins/codesample/plugin.min.js | 2 +- .../plugins/colorpicker/plugin.min.js | 2 +- .../plugins/contextmenu/plugin.min.js | 2 +- .../plugins/directionality/plugin.min.js | 2 +- .../plugins/emoticons/plugin.min.js | 2 +- .../tiny_mce_4/plugins/fullpage/plugin.min.js | 2 +- .../plugins/fullscreen/plugin.min.js | 2 +- lib/web/tiny_mce_4/plugins/help/img/logo.png | Bin 23101 -> 13208 bytes lib/web/tiny_mce_4/plugins/help/plugin.min.js | 2 +- lib/web/tiny_mce_4/plugins/hr/plugin.min.js | 2 +- .../tiny_mce_4/plugins/image/plugin.min.js | 2 +- .../plugins/imagetools/plugin.min.js | 3 +-- .../plugins/importcss/plugin.min.js | 2 +- .../plugins/insertdatetime/plugin.min.js | 2 +- .../plugins/legacyoutput/plugin.min.js | 2 +- lib/web/tiny_mce_4/plugins/link/plugin.min.js | 2 +- .../tiny_mce_4/plugins/lists/plugin.min.js | 2 +- .../tiny_mce_4/plugins/media/plugin.min.js | 2 +- .../plugins/nonbreaking/plugin.min.js | 2 +- .../plugins/noneditable/plugin.min.js | 2 +- .../plugins/pagebreak/plugin.min.js | 2 +- .../tiny_mce_4/plugins/paste/plugin.min.js | 2 +- .../tiny_mce_4/plugins/preview/plugin.min.js | 2 +- .../tiny_mce_4/plugins/print/plugin.min.js | 2 +- lib/web/tiny_mce_4/plugins/save/plugin.min.js | 2 +- .../plugins/searchreplace/plugin.min.js | 2 +- .../plugins/spellchecker/plugin.min.js | 2 +- .../tiny_mce_4/plugins/tabfocus/plugin.min.js | 2 +- .../tiny_mce_4/plugins/table/plugin.min.js | 3 +-- .../tiny_mce_4/plugins/template/plugin.min.js | 2 +- .../plugins/textcolor/plugin.min.js | 2 +- .../plugins/textpattern/plugin.min.js | 2 +- lib/web/tiny_mce_4/plugins/toc/plugin.min.js | 2 +- .../plugins/visualblocks/plugin.min.js | 2 +- .../plugins/visualchars/plugin.min.js | 2 +- .../plugins/wordcount/plugin.min.js | 2 +- .../skins/lightgray/fonts/tinymce.eot | Bin 17572 -> 18912 bytes .../skins/lightgray/fonts/tinymce.svg | 3 ++- .../skins/lightgray/fonts/tinymce.ttf | Bin 17408 -> 18748 bytes .../skins/lightgray/fonts/tinymce.woff | Bin 17484 -> 18824 bytes lib/web/tiny_mce_4/themes/inlite/theme.min.js | 2 +- lib/web/tiny_mce_4/themes/modern/theme.min.js | 2 +- lib/web/tiny_mce_4/tinymce.min.js | 18 ++---------------- 52 files changed, 50 insertions(+), 65 deletions(-) diff --git a/lib/web/tiny_mce_4/jquery.tinymce.min.js b/lib/web/tiny_mce_4/jquery.tinymce.min.js index 651f1e0745b6..4a69c27b34ee 100755 --- a/lib/web/tiny_mce_4/jquery.tinymce.min.js +++ b/lib/web/tiny_mce_4/jquery.tinymce.min.js @@ -1 +1 @@ -!function(){var a={},b=function(b){for(var c=a[b],e=c.deps,f=c.defn,g=e.length,h=new Array(g),i=0;i<g;++i)h[i]=d(e[i]);var j=f.apply(null,h);if(void 0===j)throw"module ["+b+"] returned undefined";c.instance=j},c=function(b,c,d){if("string"!=typeof b)throw"module id must be a string";if(void 0===c)throw"no dependencies for "+b;if(void 0===d)throw"no definition function for "+b;a[b]={deps:c,defn:d,instance:void 0}},d=function(c){var d=a[c];if(void 0===d)throw"module ["+c+"] was undefined";return void 0===d.instance&&b(c),d.instance},e=function(a,b){for(var c=a.length,e=new Array(c),f=0;f<c;++f)e.push(d(a[f]));b.apply(null,b)},f={};f.bolt={module:{api:{define:c,require:e,demand:d}}};var g=c;g("0",[],function(){return function(a){function b(){function a(a){"remove"===a&&this.each(function(a,b){var c=d(b);c&&c.remove()}),this.find("span.mceEditor,div.mceEditor").each(function(a,b){var c=i().get(b.id.replace(/_parent$/,""));c&&c.remove()})}function b(b){var c,d=this;if(null!=b)a.call(d),d.each(function(a,c){var d;(d=i().get(c.id))&&d.setContent(b)});else if(d.length>0&&(c=i().get(d[0].id)))return c.getContent()}function d(a){var b=null;return a&&a.id&&g.tinymce&&(b=i().get(a.id)),b}function e(a){return!!(a&&a.length&&g.tinymce&&a.is(":tinymce"))}var h={};f.each(["text","html","val"],function(a,g){var i=h[g]=f.fn[g],j="text"===g;f.fn[g]=function(a){var g=this;if(!e(g))return i.apply(g,arguments);if(a!==c)return b.call(g.filter(":tinymce"),a),i.apply(g.not(":tinymce"),arguments),g;var h="",k=arguments;return(j?g:g.eq(0)).each(function(a,b){var c=d(b);h+=c?j?c.getContent().replace(/<(?:"[^"]*"|'[^']*'|[^'">])*>/g,""):c.getContent({save:!0}):i.apply(f(b),k)}),h}}),f.each(["append","prepend"],function(a,b){var g=h[b]=f.fn[b],i="prepend"===b;f.fn[b]=function(a){var b=this;return e(b)?a!==c?("string"==typeof a&&b.filter(":tinymce").each(function(b,c){var e=d(c);e&&e.setContent(i?a+e.getContent():e.getContent()+a)}),g.apply(b.not(":tinymce"),arguments),b):void 0:g.apply(b,arguments)}}),f.each(["remove","replaceWith","replaceAll","empty"],function(b,c){var d=h[c]=f.fn[c];f.fn[c]=function(){return a.call(this,c),d.apply(this,arguments)}}),h.attr=f.fn.attr,f.fn.attr=function(a,g){var i=this,j=arguments;if(!a||"value"!==a||!e(i))return g!==c?h.attr.apply(i,j):h.attr.apply(i,j);if(g!==c)return b.call(i.filter(":tinymce"),g),h.attr.apply(i.not(":tinymce"),j),i;var k=i[0],l=d(k);return l?l.getContent({save:!0}):h.attr.apply(f(k),j)}}var c,d,e,f,g,h=[];g=a?a:window,f=g.jQuery;var i=function(){return g.tinymce};f.fn.tinymce=function(a){function c(){var c=[],d=0;e||(b(),e=!0),m.each(function(b,e){var f,g=e.id,h=a.oninit;g||(e.id=g=i().DOM.uniqueId()),i().get(g)||(f=i().createEditor(g,a),c.push(f),f.on("init",function(){var a,b=h;m.css("visibility",""),h&&++d==c.length&&("string"==typeof b&&(a=b.indexOf(".")===-1?null:i().resolve(b.replace(/\.\w+$/,"")),b=i().resolve(b)),b.apply(a||i(),c))}))}),f.each(c,function(a,b){b.render()})}var j,k,l,m=this,n="";if(!m.length)return m;if(!a)return i()?i().get(m[0].id):null;if(m.css("visibility","hidden"),g.tinymce||d||!(j=a.script_url))1===d?h.push(c):c();else{d=1,k=j.substring(0,j.lastIndexOf("/")),j.indexOf(".min")!=-1&&(n=".min"),g.tinymce=g.tinyMCEPreInit||{base:k,suffix:n},j.indexOf("gzip")!=-1&&(l=a.language||"en",j=j+(/\?/.test(j)?"&":"?")+"js=true&core=true&suffix="+escape(n)+"&themes="+escape(a.theme||"modern")+"&plugins="+escape(a.plugins||"")+"&languages="+(l||""),g.tinyMCE_GZ||(g.tinyMCE_GZ={start:function(){function b(a){i().ScriptLoader.markDone(i().baseURI.toAbsolute(a))}b("langs/"+l+".js"),b("themes/"+a.theme+"/theme"+n+".js"),b("themes/"+a.theme+"/langs/"+l+".js"),f.each(a.plugins.split(","),function(a,c){c&&(b("plugins/"+c+"/plugin"+n+".js"),b("plugins/"+c+"/langs/"+l+".js"))})},end:function(){}}));var o=document.createElement("script");o.type="text/javascript",o.onload=o.onreadystatechange=function(b){b=b||window.event,2===d||"load"!=b.type&&!/complete|loaded/.test(o.readyState)||(i().dom.Event.domLoaded=1,d=2,a.script_loaded&&a.script_loaded(),c(),f.each(h,function(a,b){b()}))},o.src=j,document.body.appendChild(o)}return m},f.extend(f.expr[":"],{tinymce:function(a){var b;return!!(a.id&&"tinymce"in g&&(b=i().get(a.id),b&&b.editorManager===i()))}})}}),d("0")()}(); \ No newline at end of file +!function(){var f,c,u,p,d,s=[];d="undefined"!=typeof global?global:window,p=d.jQuery;var v=function(){return d.tinymce};p.fn.tinymce=function(o){var e,t,i,l=this,r="";if(!l.length)return l;if(!o)return v()?v().get(l[0].id):null;l.css("visibility","hidden");var n=function(){var a=[],c=0;u||(m(),u=!0),l.each(function(e,t){var n,i=t.id,r=o.oninit;i||(t.id=i=v().DOM.uniqueId()),v().get(i)||(n=v().createEditor(i,o),a.push(n),n.on("init",function(){var e,t=r;l.css("visibility",""),r&&++c==a.length&&("string"==typeof t&&(e=-1===t.indexOf(".")?null:v().resolve(t.replace(/\.\w+$/,"")),t=v().resolve(t)),t.apply(e||v(),a))}))}),p.each(a,function(e,t){t.render()})};if(d.tinymce||c||!(e=o.script_url))1===c?s.push(n):n();else{c=1,t=e.substring(0,e.lastIndexOf("/")),-1!=e.indexOf(".min")&&(r=".min"),d.tinymce=d.tinyMCEPreInit||{base:t,suffix:r},-1!=e.indexOf("gzip")&&(i=o.language||"en",e=e+(/\?/.test(e)?"&":"?")+"js=true&core=true&suffix="+escape(r)+"&themes="+escape(o.theme||"modern")+"&plugins="+escape(o.plugins||"")+"&languages="+(i||""),d.tinyMCE_GZ||(d.tinyMCE_GZ={start:function(){var n=function(e){v().ScriptLoader.markDone(v().baseURI.toAbsolute(e))};n("langs/"+i+".js"),n("themes/"+o.theme+"/theme"+r+".js"),n("themes/"+o.theme+"/langs/"+i+".js"),p.each(o.plugins.split(","),function(e,t){t&&(n("plugins/"+t+"/plugin"+r+".js"),n("plugins/"+t+"/langs/"+i+".js"))})},end:function(){}}));var a=document.createElement("script");a.type="text/javascript",a.onload=a.onreadystatechange=function(e){e=e||window.event,2===c||"load"!=e.type&&!/complete|loaded/.test(a.readyState)||(v().dom.Event.domLoaded=1,c=2,o.script_loaded&&o.script_loaded(),n(),p.each(s,function(e,t){t()}))},a.src=e,document.body.appendChild(a)}return l},p.extend(p.expr[":"],{tinymce:function(e){var t;return!!(e.id&&"tinymce"in d&&(t=v().get(e.id))&&t.editorManager===v())}});var m=function(){var r=function(e){"remove"===e&&this.each(function(e,t){var n=l(t);n&&n.remove()}),this.find("span.mceEditor,div.mceEditor").each(function(e,t){var n=v().get(t.id.replace(/_parent$/,""));n&&n.remove()})},o=function(i){var e,t=this;if(null!=i)r.call(t),t.each(function(e,t){var n;(n=v().get(t.id))&&n.setContent(i)});else if(0<t.length&&(e=v().get(t[0].id)))return e.getContent()},l=function(e){var t=null;return e&&e.id&&d.tinymce&&(t=v().get(e.id)),t},u=function(e){return!!(e&&e.length&&d.tinymce&&e.is(":tinymce"))},s={};p.each(["text","html","val"],function(e,t){var a=s[t]=p.fn[t],c="text"===t;p.fn[t]=function(e){var t=this;if(!u(t))return a.apply(t,arguments);if(e!==f)return o.call(t.filter(":tinymce"),e),a.apply(t.not(":tinymce"),arguments),t;var i="",r=arguments;return(c?t:t.eq(0)).each(function(e,t){var n=l(t);i+=n?c?n.getContent().replace(/<(?:"[^"]*"|'[^']*'|[^'">])*>/g,""):n.getContent({save:!0}):a.apply(p(t),r)}),i}}),p.each(["append","prepend"],function(e,t){var n=s[t]=p.fn[t],r="prepend"===t;p.fn[t]=function(i){var e=this;return u(e)?i!==f?("string"==typeof i&&e.filter(":tinymce").each(function(e,t){var n=l(t);n&&n.setContent(r?i+n.getContent():n.getContent()+i)}),n.apply(e.not(":tinymce"),arguments),e):void 0:n.apply(e,arguments)}}),p.each(["remove","replaceWith","replaceAll","empty"],function(e,t){var n=s[t]=p.fn[t];p.fn[t]=function(){return r.call(this,t),n.apply(this,arguments)}}),s.attr=p.fn.attr,p.fn.attr=function(e,t){var n=this,i=arguments;if(!e||"value"!==e||!u(n))return s.attr.apply(n,i);if(t!==f)return o.call(n.filter(":tinymce"),t),s.attr.apply(n.not(":tinymce"),i),n;var r=n[0],a=l(r);return a?a.getContent({save:!0}):s.attr.apply(p(r),i)}}}(); \ No newline at end of file diff --git a/lib/web/tiny_mce_4/plugins/advlist/plugin.min.js b/lib/web/tiny_mce_4/plugins/advlist/plugin.min.js index 440152f6aeb9..122cd8ff6469 100755 --- a/lib/web/tiny_mce_4/plugins/advlist/plugin.min.js +++ b/lib/web/tiny_mce_4/plugins/advlist/plugin.min.js @@ -1 +1 @@ -!function(){var a={},b=function(b){for(var c=a[b],e=c.deps,f=c.defn,g=e.length,h=new Array(g),i=0;i<g;++i)h[i]=d(e[i]);var j=f.apply(null,h);if(void 0===j)throw"module ["+b+"] returned undefined";c.instance=j},c=function(b,c,d){if("string"!=typeof b)throw"module id must be a string";if(void 0===c)throw"no dependencies for "+b;if(void 0===d)throw"no definition function for "+b;a[b]={deps:c,defn:d,instance:void 0}},d=function(c){var d=a[c];if(void 0===d)throw"module ["+c+"] was undefined";return void 0===d.instance&&b(c),d.instance},e=function(a,b){for(var c=a.length,e=new Array(c),f=0;f<c;++f)e.push(d(a[f]));b.apply(null,b)},f={};f.bolt={module:{api:{define:c,require:e,demand:d}}};var g=c,h=function(a,b){g(a,[],function(){return b})};h("3",tinymce.util.Tools.resolve),g("1",["3"],function(a){return a("tinymce.PluginManager")}),g("2",["3"],function(a){return a("tinymce.util.Tools")}),g("0",["1","2"],function(a,b){return a.add("advlist",function(a){function c(b){return a.$.contains(a.getBody(),b)}function d(a){return a&&/^(OL|UL|DL)$/.test(a.nodeName)&&c(a)}function e(a,c){var d=[];return c&&b.each(c.split(/[ ,]/),function(a){d.push({text:a.replace(/\-/g," ").replace(/\b\w/g,function(a){return a.toUpperCase()}),data:"default"==a?"":a})}),d}function f(c,d){a.undoManager.transact(function(){var e,f=a.dom,g=a.selection;if(e=f.getParent(g.getNode(),"ol,ul"),!e||e.nodeName!=c||d===!1){var h={"list-style-type":d?d:""};a.execCommand("UL"==c?"InsertUnorderedList":"InsertOrderedList",!1,h)}e=f.getParent(g.getNode(),"ol,ul"),e&&b.each(f.select("ol,ul",e).concat([e]),function(a){a.nodeName!==c&&d!==!1&&(a=f.rename(a,c)),f.setStyle(a,"listStyleType",d?d:null),a.removeAttribute("data-mce-style")}),a.focus()})}function g(b){var c=a.dom.getStyle(a.dom.getParent(a.selection.getNode(),"ol,ul"),"listStyleType")||"";b.control.items().each(function(a){a.active(a.settings.data===c)})}var h,i,j=function(a,c){var d=a.settings.plugins?a.settings.plugins:"";return b.inArray(d.split(/[ ,]/),c)!==-1};h=e("OL",a.getParam("advlist_number_styles","default,lower-alpha,lower-greek,lower-roman,upper-alpha,upper-roman")),i=e("UL",a.getParam("advlist_bullet_styles","default,circle,disc,square"));var k=function(c){return function(){var e=this;a.on("NodeChange",function(a){var f=b.grep(a.parents,d);e.active(f.length>0&&f[0].nodeName===c)})}};j(a,"lists")&&(a.addCommand("ApplyUnorderedListStyle",function(a,b){f("UL",b["list-style-type"])}),a.addCommand("ApplyOrderedListStyle",function(a,b){f("OL",b["list-style-type"])}),a.addButton("numlist",{type:h.length>0?"splitbutton":"button",tooltip:"Numbered list",menu:h,onPostRender:k("OL"),onshow:g,onselect:function(a){f("OL",a.control.settings.data)},onclick:function(){f("OL",!1)}}),a.addButton("bullist",{type:i.length>0?"splitbutton":"button",tooltip:"Bullet list",onPostRender:k("UL"),menu:i,onshow:g,onselect:function(a){f("UL",a.control.settings.data)},onclick:function(){f("UL",!1)}}))}),function(){}}),d("0")()}(); \ No newline at end of file +!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager"),a=tinymce.util.Tools.resolve("tinymce.util.Tools"),s=function(t,e,n){var r="UL"===e?"InsertUnorderedList":"InsertOrderedList";t.execCommand(r,!1,!1===n?null:{"list-style-type":n})},o=function(n){n.addCommand("ApplyUnorderedListStyle",function(t,e){s(n,"UL",e["list-style-type"])}),n.addCommand("ApplyOrderedListStyle",function(t,e){s(n,"OL",e["list-style-type"])})},e=function(t){var e=t.getParam("advlist_number_styles","default,lower-alpha,lower-greek,lower-roman,upper-alpha,upper-roman");return e?e.split(/[ ,]/):[]},n=function(t){var e=t.getParam("advlist_bullet_styles","default,circle,disc,square");return e?e.split(/[ ,]/):[]},u=function(t){return t&&/^(TH|TD)$/.test(t.nodeName)},c=function(r){return function(t){return t&&/^(OL|UL|DL)$/.test(t.nodeName)&&(n=t,(e=r).$.contains(e.getBody(),n));var e,n}},d=function(t){var e=t.dom.getParent(t.selection.getNode(),"ol,ul");return t.dom.getStyle(e,"listStyleType")||""},p=function(t){return a.map(t,function(t){return{text:t.replace(/\-/g," ").replace(/\b\w/g,function(t){return t.toUpperCase()}),data:"default"===t?"":t}})},f=function(i,l){return function(t){var o=t.control;i.on("NodeChange",function(t){var e=function(t,e){for(var n=0;n<t.length;n++)if(e(t[n]))return n;return-1}(t.parents,u),n=-1!==e?t.parents.slice(0,e):t.parents,r=a.grep(n,c(i));o.active(0<r.length&&r[0].nodeName===l)})}},m=function(e,t,n,r,o,i){var l;e.addButton(t,{active:!1,type:"splitbutton",tooltip:n,menu:p(i),onPostRender:f(e,o),onshow:(l=e,function(t){var e=d(l);t.control.items().each(function(t){t.active(t.settings.data===e)})}),onselect:function(t){s(e,o,t.control.settings.data)},onclick:function(){e.execCommand(r)}})},r=function(t,e,n,r,o,i){var l,a,s,u,c;0<i.length?m(t,e,n,r,o,i):(a=e,s=n,u=r,c=o,(l=t).addButton(a,{active:!1,type:"button",tooltip:s,onPostRender:f(l,c),onclick:function(){l.execCommand(u)}}))},i=function(t){r(t,"numlist","Numbered list","InsertOrderedList","OL",e(t)),r(t,"bullist","Bullet list","InsertUnorderedList","UL",n(t))};t.add("advlist",function(t){var e,n,r;n="lists",r=(e=t).settings.plugins?e.settings.plugins:"",-1!==a.inArray(r.split(/[ ,]/),n)&&(i(t),o(t))})}(); \ No newline at end of file diff --git a/lib/web/tiny_mce_4/plugins/anchor/plugin.min.js b/lib/web/tiny_mce_4/plugins/anchor/plugin.min.js index 6b3361d26fc7..177f5051755a 100755 --- a/lib/web/tiny_mce_4/plugins/anchor/plugin.min.js +++ b/lib/web/tiny_mce_4/plugins/anchor/plugin.min.js @@ -1 +1 @@ -!function(){var a={},b=function(b){for(var c=a[b],e=c.deps,f=c.defn,g=e.length,h=new Array(g),i=0;i<g;++i)h[i]=d(e[i]);var j=f.apply(null,h);if(void 0===j)throw"module ["+b+"] returned undefined";c.instance=j},c=function(b,c,d){if("string"!=typeof b)throw"module id must be a string";if(void 0===c)throw"no dependencies for "+b;if(void 0===d)throw"no definition function for "+b;a[b]={deps:c,defn:d,instance:void 0}},d=function(c){var d=a[c];if(void 0===d)throw"module ["+c+"] was undefined";return void 0===d.instance&&b(c),d.instance},e=function(a,b){for(var c=a.length,e=new Array(c),f=0;f<c;++f)e.push(d(a[f]));b.apply(null,b)},f={};f.bolt={module:{api:{define:c,require:e,demand:d}}};var g=c,h=function(a,b){g(a,[],function(){return b})};h("3",tinymce.util.Tools.resolve),g("1",["3"],function(a){return a("tinymce.Env")}),g("2",["3"],function(a){return a("tinymce.PluginManager")}),g("0",["1","2"],function(a,b){return b.add("anchor",function(b){var c=function(a){return!a.attr("href")&&(a.attr("id")||a.attr("name"))&&!a.firstChild},d=function(a){return function(b){for(var d=0;d<b.length;d++)c(b[d])&&b[d].attr("contenteditable",a)}},e=function(a){return/^[A-Za-z][A-Za-z0-9\-:._]*$/.test(a)},f=function(){var a=b.selection.getNode(),c="A"==a.tagName&&""===b.dom.getAttrib(a,"href"),d="";c&&(d=a.id||a.name||""),b.windowManager.open({title:"Anchor",body:{type:"textbox",name:"id",size:40,label:"Id",value:d},onsubmit:function(d){var f=d.data.id;return e(f)?void(c?(a.removeAttribute("name"),a.id=f):(b.selection.collapse(!0),b.execCommand("mceInsertContent",!1,b.dom.createHTML("a",{id:f})))):(d.preventDefault(),void b.windowManager.alert("Id should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores."))}})};a.ceFalse&&b.on("PreInit",function(){b.parser.addNodeFilter("a",d("false")),b.serializer.addNodeFilter("a",d(null))}),b.addCommand("mceAnchor",f),b.addButton("anchor",{icon:"anchor",tooltip:"Anchor",onclick:f,stateSelector:"a:not([href])"}),b.addMenuItem("anchor",{icon:"anchor",text:"Anchor",context:"insert",onclick:f})}),function(){}}),d("0")()}(); \ No newline at end of file +!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager"),a=function(t){return/^[A-Za-z][A-Za-z0-9\-:._]*$/.test(t)},e=function(t){var e=t.selection.getNode();return"A"===e.tagName&&""===t.dom.getAttrib(e,"href")?e.id||e.name:""},i=function(t,e){var n=t.selection.getNode();"A"===n.tagName&&""===t.dom.getAttrib(n,"href")?(n.removeAttribute("name"),n.id=e,t.undoManager.add()):(t.focus(),t.selection.collapse(!0),t.execCommand("mceInsertContent",!1,t.dom.createHTML("a",{id:e})))},n=function(r){var t=e(r);r.windowManager.open({title:"Anchor",body:{type:"textbox",name:"id",size:40,label:"Id",value:t},onsubmit:function(t){var e,n,o=t.data.id;e=r,(a(n=o)?(i(e,n),0):(e.windowManager.alert("Id should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores."),1))&&t.preventDefault()}})},o=function(t){t.addCommand("mceAnchor",function(){n(t)})},r=function(o){return function(t){for(var e=0;e<t.length;e++)(n=t[e]).attr("href")||!n.attr("id")&&!n.attr("name")||n.firstChild||t[e].attr("contenteditable",o);var n}},c=function(t){t.on("PreInit",function(){t.parser.addNodeFilter("a",r("false")),t.serializer.addNodeFilter("a",r(null))})},d=function(t){t.addButton("anchor",{icon:"anchor",tooltip:"Anchor",cmd:"mceAnchor",stateSelector:"a:not([href])"}),t.addMenuItem("anchor",{icon:"anchor",text:"Anchor",context:"insert",cmd:"mceAnchor"})};t.add("anchor",function(t){c(t),o(t),d(t)})}(); \ No newline at end of file diff --git a/lib/web/tiny_mce_4/plugins/autolink/plugin.min.js b/lib/web/tiny_mce_4/plugins/autolink/plugin.min.js index 5d1231e7373e..1238a1d231cf 100755 --- a/lib/web/tiny_mce_4/plugins/autolink/plugin.min.js +++ b/lib/web/tiny_mce_4/plugins/autolink/plugin.min.js @@ -1 +1 @@ -!function(){var a={},b=function(b){for(var c=a[b],e=c.deps,f=c.defn,g=e.length,h=new Array(g),i=0;i<g;++i)h[i]=d(e[i]);var j=f.apply(null,h);if(void 0===j)throw"module ["+b+"] returned undefined";c.instance=j},c=function(b,c,d){if("string"!=typeof b)throw"module id must be a string";if(void 0===c)throw"no dependencies for "+b;if(void 0===d)throw"no definition function for "+b;a[b]={deps:c,defn:d,instance:void 0}},d=function(c){var d=a[c];if(void 0===d)throw"module ["+c+"] was undefined";return void 0===d.instance&&b(c),d.instance},e=function(a,b){for(var c=a.length,e=new Array(c),f=0;f<c;++f)e.push(d(a[f]));b.apply(null,b)},f={};f.bolt={module:{api:{define:c,require:e,demand:d}}};var g=c,h=function(a,b){g(a,[],function(){return b})};h("3",tinymce.util.Tools.resolve),g("1",["3"],function(a){return a("tinymce.Env")}),g("2",["3"],function(a){return a("tinymce.PluginManager")}),g("0",["1","2"],function(a,b){return b.add("autolink",function(b){function c(a){f(a,-1,"(",!0)}function d(a){f(a,0,"",!0)}function e(a){f(a,-1,"",!1)}function f(a,b,c){function d(a,b){if(b<0&&(b=0),3==a.nodeType){var c=a.data.length;b>c&&(b=c)}return b}function e(a,b){1!=a.nodeType||a.hasChildNodes()?g.setStart(a,d(a,b)):g.setStartBefore(a)}function f(a,b){1!=a.nodeType||a.hasChildNodes()?g.setEnd(a,d(a,b)):g.setEndAfter(a)}var g,i,j,k,l,m,n,o,p,q;if("A"!=a.selection.getNode().tagName){if(g=a.selection.getRng(!0).cloneRange(),g.startOffset<5){if(o=g.endContainer.previousSibling,!o){if(!g.endContainer.firstChild||!g.endContainer.firstChild.nextSibling)return;o=g.endContainer.firstChild.nextSibling}if(p=o.length,e(o,p),f(o,p),g.endOffset<5)return;i=g.endOffset,k=o}else{if(k=g.endContainer,3!=k.nodeType&&k.firstChild){for(;3!=k.nodeType&&k.firstChild;)k=k.firstChild;3==k.nodeType&&(e(k,0),f(k,k.nodeValue.length))}i=1==g.endOffset?2:g.endOffset-1-b}j=i;do e(k,i>=2?i-2:0),f(k,i>=1?i-1:0),i-=1,q=g.toString();while(" "!=q&&""!==q&&160!=q.charCodeAt(0)&&i-2>=0&&q!=c);g.toString()==c||160==g.toString().charCodeAt(0)?(e(k,i),f(k,j),i+=1):0===g.startOffset?(e(k,0),f(k,j)):(e(k,i),f(k,j)),m=g.toString(),"."==m.charAt(m.length-1)&&f(k,j-1),m=g.toString(),n=m.match(h),n&&("www."==n[1]?n[1]="http://www.":/@$/.test(n[1])&&!/^mailto:/.test(n[1])&&(n[1]="mailto:"+n[1]),l=a.selection.getBookmark(),a.selection.setRng(g),a.execCommand("createlink",!1,n[1]+n[2]),a.settings.default_link_target&&a.dom.setAttrib(a.selection.getNode(),"target",a.settings.default_link_target),a.selection.moveToBookmark(l),a.nodeChanged())}}var g,h=/^(https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.|(?:mailto:)?[A-Z0-9._%+\-]+@)(.+)$/i;return b.settings.autolink_pattern&&(h=b.settings.autolink_pattern),b.on("keydown",function(a){if(13==a.keyCode)return e(b)}),a.ie?void b.on("focus",function(){if(!g){g=!0;try{b.execCommand("AutoUrlDetect",!1,!0)}catch(a){}}}):(b.on("keypress",function(a){if(41==a.keyCode)return c(b)}),void b.on("keyup",function(a){if(32==a.keyCode)return d(b)}))}),function(){}}),d("0")()}(); \ No newline at end of file +!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),i=tinymce.util.Tools.resolve("tinymce.Env"),m=function(e){return e.getParam("autolink_pattern",/^(https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.|(?:mailto:)?[A-Z0-9._%+\-]+@)(.+)$/i)},y=function(e){return e.getParam("default_link_target","")},o=function(e,t){if(t<0&&(t=0),3===e.nodeType){var n=e.data.length;n<t&&(t=n)}return t},k=function(e,t,n){1!==t.nodeType||t.hasChildNodes()?e.setStart(t,o(t,n)):e.setStartBefore(t)},p=function(e,t,n){1!==t.nodeType||t.hasChildNodes()?e.setEnd(t,o(t,n)):e.setEndAfter(t)},r=function(e,t,n){var i,o,r,a,f,s,d,l,c,u,g=m(e),h=y(e);if("A"!==e.selection.getNode().tagName){if((i=e.selection.getRng(!0).cloneRange()).startOffset<5){if(!(l=i.endContainer.previousSibling)){if(!i.endContainer.firstChild||!i.endContainer.firstChild.nextSibling)return;l=i.endContainer.firstChild.nextSibling}if(c=l.length,k(i,l,c),p(i,l,c),i.endOffset<5)return;o=i.endOffset,a=l}else{if(3!==(a=i.endContainer).nodeType&&a.firstChild){for(;3!==a.nodeType&&a.firstChild;)a=a.firstChild;3===a.nodeType&&(k(i,a,0),p(i,a,a.nodeValue.length))}o=1===i.endOffset?2:i.endOffset-1-t}for(r=o;k(i,a,2<=o?o-2:0),p(i,a,1<=o?o-1:0),o-=1," "!==(u=i.toString())&&""!==u&&160!==u.charCodeAt(0)&&0<=o-2&&u!==n;);var C;(C=i.toString())===n||" "===C||160===C.charCodeAt(0)?(k(i,a,o),p(i,a,r),o+=1):(0===i.startOffset?k(i,a,0):k(i,a,o),p(i,a,r)),"."===(s=i.toString()).charAt(s.length-1)&&p(i,a,r-1),(d=(s=i.toString().trim()).match(g))&&("www."===d[1]?d[1]="http://www.":/@$/.test(d[1])&&!/^mailto:/.test(d[1])&&(d[1]="mailto:"+d[1]),f=e.selection.getBookmark(),e.selection.setRng(i),e.execCommand("createlink",!1,d[1]+d[2]),h&&e.dom.setAttrib(e.selection.getNode(),"target",h),e.selection.moveToBookmark(f),e.nodeChanged())}},t=function(t){var n;t.on("keydown",function(e){13!==e.keyCode||r(t,-1,"")}),i.ie?t.on("focus",function(){if(!n){n=!0;try{t.execCommand("AutoUrlDetect",!1,!0)}catch(e){}}}):(t.on("keypress",function(e){41!==e.keyCode||r(t,-1,"(")}),t.on("keyup",function(e){32!==e.keyCode||r(t,0,"")}))};e.add("autolink",function(e){t(e)})}(); \ No newline at end of file diff --git a/lib/web/tiny_mce_4/plugins/autoresize/plugin.min.js b/lib/web/tiny_mce_4/plugins/autoresize/plugin.min.js index 081b5d32dc29..f63945671a6e 100755 --- a/lib/web/tiny_mce_4/plugins/autoresize/plugin.min.js +++ b/lib/web/tiny_mce_4/plugins/autoresize/plugin.min.js @@ -1 +1 @@ -!function(){var a={},b=function(b){for(var c=a[b],e=c.deps,f=c.defn,g=e.length,h=new Array(g),i=0;i<g;++i)h[i]=d(e[i]);var j=f.apply(null,h);if(void 0===j)throw"module ["+b+"] returned undefined";c.instance=j},c=function(b,c,d){if("string"!=typeof b)throw"module id must be a string";if(void 0===c)throw"no dependencies for "+b;if(void 0===d)throw"no definition function for "+b;a[b]={deps:c,defn:d,instance:void 0}},d=function(c){var d=a[c];if(void 0===d)throw"module ["+c+"] was undefined";return void 0===d.instance&&b(c),d.instance},e=function(a,b){for(var c=a.length,e=new Array(c),f=0;f<c;++f)e.push(d(a[f]));b.apply(null,b)},f={};f.bolt={module:{api:{define:c,require:e,demand:d}}};var g=c,h=function(a,b){g(a,[],function(){return b})};h("5",tinymce.util.Tools.resolve),g("1",["5"],function(a){return a("tinymce.dom.DOMUtils")}),g("2",["5"],function(a){return a("tinymce.Env")}),g("3",["5"],function(a){return a("tinymce.PluginManager")}),g("4",["5"],function(a){return a("tinymce.util.Delay")}),g("0",["1","2","3","4"],function(a,b,c,d){var e=a.DOM;return c.add("autoresize",function(a){function c(){return a.plugins.fullscreen&&a.plugins.fullscreen.isFullscreen()}function f(d){var g,j,k,l,m,n,o,p,q,r,s,t;if(j=a.getDoc()){if(k=j.body,l=j.documentElement,m=h.autoresize_min_height,!k||d&&"setcontent"===d.type&&d.initial||c())return void(k&&l&&(k.style.overflowY="auto",l.style.overflowY="auto"));o=a.dom.getStyle(k,"margin-top",!0),p=a.dom.getStyle(k,"margin-bottom",!0),q=a.dom.getStyle(k,"padding-top",!0),r=a.dom.getStyle(k,"padding-bottom",!0),s=a.dom.getStyle(k,"border-top-width",!0),t=a.dom.getStyle(k,"border-bottom-width",!0),n=k.offsetHeight+parseInt(o,10)+parseInt(p,10)+parseInt(q,10)+parseInt(r,10)+parseInt(s,10)+parseInt(t,10),(isNaN(n)||n<=0)&&(n=b.ie?k.scrollHeight:b.webkit&&0===k.clientHeight?0:k.offsetHeight),n>h.autoresize_min_height&&(m=n),h.autoresize_max_height&&n>h.autoresize_max_height?(m=h.autoresize_max_height,k.style.overflowY="auto",l.style.overflowY="auto"):(k.style.overflowY="hidden",l.style.overflowY="hidden",k.scrollTop=0),m!==i&&(g=m-i,e.setStyle(a.iframeElement,"height",m+"px"),i=m,b.webKit&&g<0&&f(d))}}function g(b,c,e){d.setEditorTimeout(a,function(){f({}),b--?g(b,c,e):e&&e()},c)}var h=a.settings,i=0;a.settings.inline||(h.autoresize_min_height=parseInt(a.getParam("autoresize_min_height",a.getElement().offsetHeight),10),h.autoresize_max_height=parseInt(a.getParam("autoresize_max_height",0),10),a.on("init",function(){var b,c;b=a.getParam("autoresize_overflow_padding",1),c=a.getParam("autoresize_bottom_margin",50),b!==!1&&a.dom.setStyles(a.getBody(),{paddingLeft:b,paddingRight:b}),c!==!1&&a.dom.setStyles(a.getBody(),{paddingBottom:c})}),a.on("nodechange setcontent keyup FullscreenStateChanged",f),a.getParam("autoresize_on_init",!0)&&a.on("init",function(){g(20,100,function(){g(5,1e3)})}),a.addCommand("mceAutoResize",f))}),function(){}}),d("0")()}(); \ No newline at end of file +!function(){"use strict";var i=function(t){var e=t,n=function(){return e};return{get:n,set:function(t){e=t},clone:function(){return i(n())}}},t=tinymce.util.Tools.resolve("tinymce.PluginManager"),y=tinymce.util.Tools.resolve("tinymce.Env"),r=tinymce.util.Tools.resolve("tinymce.util.Delay"),h=function(t){return parseInt(t.getParam("autoresize_min_height",t.getElement().offsetHeight),10)},v=function(t){return parseInt(t.getParam("autoresize_max_height",0),10)},o=function(t){return t.getParam("autoresize_overflow_padding",1)},a=function(t){return t.getParam("autoresize_bottom_margin",50)},n=function(t){return t.getParam("autoresize_on_init",!0)},u=function(t,e,n,i,o){r.setEditorTimeout(t,function(){_(t,e),n--?u(t,e,n,i,o):o&&o()},i)},S=function(t,e){var n=t.getBody();n&&(n.style.overflowY=e?"":"hidden",e||(n.scrollTop=0))},_=function(t,e){var n,i,o,r,a,u,s,l,g,c,f,d=t.dom;if(i=t.getDoc())if((m=t).plugins.fullscreen&&m.plugins.fullscreen.isFullscreen())S(t,!0);else{var m;o=i.body,r=h(t),u=d.getStyle(o,"margin-top",!0),s=d.getStyle(o,"margin-bottom",!0),l=d.getStyle(o,"padding-top",!0),g=d.getStyle(o,"padding-bottom",!0),c=d.getStyle(o,"border-top-width",!0),f=d.getStyle(o,"border-bottom-width",!0),a=o.offsetHeight+parseInt(u,10)+parseInt(s,10)+parseInt(l,10)+parseInt(g,10)+parseInt(c,10)+parseInt(f,10),(isNaN(a)||a<=0)&&(a=y.ie?o.scrollHeight:y.webkit&&0===o.clientHeight?0:o.offsetHeight),a>h(t)&&(r=a);var p=v(t);p&&p<a?(r=p,S(t,!0)):S(t,!1),r!==e.get()&&(n=r-e.get(),d.setStyle(t.iframeElement,"height",r+"px"),e.set(r),y.webkit&&n<0&&_(t,e))}},s={setup:function(i,e){i.on("init",function(){var t,e,n=i.dom;t=o(i),e=a(i),!1!==t&&n.setStyles(i.getBody(),{paddingLeft:t,paddingRight:t}),!1!==e&&n.setStyles(i.getBody(),{paddingBottom:e})}),i.on("nodechange setcontent keyup FullscreenStateChanged",function(t){_(i,e)}),n(i)&&i.on("init",function(){u(i,e,20,100,function(){u(i,e,5,1e3)})})},resize:_},l=function(t,e){t.addCommand("mceAutoResize",function(){s.resize(t,e)})};t.add("autoresize",function(t){if(!t.inline){var e=i(0);l(t,e),s.setup(t,e)}})}(); \ No newline at end of file diff --git a/lib/web/tiny_mce_4/plugins/autosave/plugin.min.js b/lib/web/tiny_mce_4/plugins/autosave/plugin.min.js index e9eb688964a9..1eab72013822 100755 --- a/lib/web/tiny_mce_4/plugins/autosave/plugin.min.js +++ b/lib/web/tiny_mce_4/plugins/autosave/plugin.min.js @@ -1 +1 @@ -!function(){var a={},b=function(b){for(var c=a[b],e=c.deps,f=c.defn,g=e.length,h=new Array(g),i=0;i<g;++i)h[i]=d(e[i]);var j=f.apply(null,h);if(void 0===j)throw"module ["+b+"] returned undefined";c.instance=j},c=function(b,c,d){if("string"!=typeof b)throw"module id must be a string";if(void 0===c)throw"no dependencies for "+b;if(void 0===d)throw"no definition function for "+b;a[b]={deps:c,defn:d,instance:void 0}},d=function(c){var d=a[c];if(void 0===d)throw"module ["+c+"] was undefined";return void 0===d.instance&&b(c),d.instance},e=function(a,b){for(var c=a.length,e=new Array(c),f=0;f<c;++f)e.push(d(a[f]));b.apply(null,b)},f={};f.bolt={module:{api:{define:c,require:e,demand:d}}};var g=c,h=function(a,b){g(a,[],function(){return b})};h("6",tinymce.util.Tools.resolve),g("1",["6"],function(a){return a("tinymce.EditorManager")}),g("2",["6"],function(a){return a("tinymce.PluginManager")}),g("3",["6"],function(a){return a("tinymce.util.LocalStorage")}),g("4",["6"],function(a){return a("tinymce.util.Tools")}),h("5",window),g("0",["1","2","3","4","5"],function(a,b,c,d,e){return a._beforeUnloadHandler=function(){var b;return d.each(a.editors,function(a){a.plugins.autosave&&a.plugins.autosave.storeDraft(),!b&&a.isDirty()&&a.getParam("autosave_ask_before_unload",!0)&&(b=a.translate("You have unsaved changes are you sure you want to navigate away?"))}),b},b.add("autosave",function(b){function f(a,b){var c={s:1e3,m:6e4};return a=/^(\d+)([ms]?)$/.exec(""+(a||b)),(a[2]?c[a[2]]:1)*parseInt(a,10)}function g(){var a=parseInt(c.getItem(o+"time"),10)||0;return!((new Date).getTime()-a>q.autosave_retention)||(h(!1),!1)}function h(a){c.removeItem(o+"draft"),c.removeItem(o+"time"),a!==!1&&b.fire("RemoveDraft")}function i(){!n()&&b.isDirty()&&(c.setItem(o+"draft",b.getContent({format:"raw",no_events:!0})),c.setItem(o+"time",(new Date).getTime()),b.fire("StoreDraft"))}function j(){g()&&(b.setContent(c.getItem(o+"draft"),{format:"raw"}),b.fire("RestoreDraft"))}function k(){p||(setInterval(function(){b.removed||i()},q.autosave_interval),p=!0)}function l(){var a=this;a.disabled(!g()),b.on("StoreDraft RestoreDraft RemoveDraft",function(){a.disabled(!g())}),k()}function m(){b.undoManager.beforeChange(),j(),h(),b.undoManager.add()}function n(a){var c=b.settings.forced_root_block;return a=d.trim("undefined"==typeof a?b.getBody().innerHTML:a),""===a||new RegExp("^<"+c+"[^>]*>((\xa0| |[ \t]|<br[^>]*>)+?|)</"+c+">|<br>$","i").test(a)}var o,p,q=b.settings;o=q.autosave_prefix||"tinymce-autosave-{path}{query}-{id}-",o=o.replace(/\{path\}/g,document.location.pathname),o=o.replace(/\{query\}/g,document.location.search),o=o.replace(/\{id\}/g,b.id),q.autosave_interval=f(q.autosave_interval,"30s"),q.autosave_retention=f(q.autosave_retention,"20m"),b.addButton("restoredraft",{title:"Restore last draft",onclick:m,onPostRender:l}),b.addMenuItem("restoredraft",{text:"Restore last draft",onclick:m,onPostRender:l,context:"file"}),b.settings.autosave_restore_when_empty!==!1&&(b.on("init",function(){g()&&n()&&j()}),b.on("saveContent",function(){h()})),e.onbeforeunload=a._beforeUnloadHandler,this.hasDraft=g,this.storeDraft=i,this.restoreDraft=j,this.removeDraft=h,this.isEmpty=n}),function(){}}),d("0")()}(); \ No newline at end of file +!function(a){"use strict";var i=function(t){var e=t,n=function(){return e};return{get:n,set:function(t){e=t},clone:function(){return i(n())}}},t=tinymce.util.Tools.resolve("tinymce.PluginManager"),r=tinymce.util.Tools.resolve("tinymce.util.LocalStorage"),o=tinymce.util.Tools.resolve("tinymce.util.Tools"),u=function(t,e){var n=t||e,r=/^(\d+)([ms]?)$/.exec(""+n);return(r[2]?{s:1e3,m:6e4}[r[2]]:1)*parseInt(n,10)},s=function(t){var e=t.getParam("autosave_prefix","tinymce-autosave-{path}{query}{hash}-{id}-");return e=(e=(e=(e=e.replace(/\{path\}/g,a.document.location.pathname)).replace(/\{query\}/g,a.document.location.search)).replace(/\{hash\}/g,a.document.location.hash)).replace(/\{id\}/g,t.id)},c=function(t,e){var n=t.settings.forced_root_block;return""===(e=o.trim(void 0===e?t.getBody().innerHTML:e))||new RegExp("^<"+n+"[^>]*>((\xa0| |[ \t]|<br[^>]*>)+?|)</"+n+">|<br>$","i").test(e)},f=function(t){var e=parseInt(r.getItem(s(t)+"time"),10)||0;return!((new Date).getTime()-e>u(t.settings.autosave_retention,"20m")&&(l(t,!1),1))},l=function(t,e){var n=s(t);r.removeItem(n+"draft"),r.removeItem(n+"time"),!1!==e&&t.fire("RemoveDraft")},m=function(t){var e=s(t);!c(t)&&t.isDirty()&&(r.setItem(e+"draft",t.getContent({format:"raw",no_events:!0})),r.setItem(e+"time",(new Date).getTime().toString()),t.fire("StoreDraft"))},v=function(t){var e=s(t);f(t)&&(t.setContent(r.getItem(e+"draft"),{format:"raw"}),t.fire("RestoreDraft"))},d=function(t,e){var n=u(t.settings.autosave_interval,"30s");e.get()||(setInterval(function(){t.removed||m(t)},n),e.set(!0))},g=function(t){t.undoManager.transact(function(){v(t),l(t)}),t.focus()};function y(r){for(var o=[],t=1;t<arguments.length;t++)o[t-1]=arguments[t];return function(){for(var t=[],e=0;e<arguments.length;e++)t[e]=arguments[e];var n=o.concat(t);return r.apply(null,n)}}var p=tinymce.util.Tools.resolve("tinymce.EditorManager");p._beforeUnloadHandler=function(){var e;return o.each(p.get(),function(t){t.plugins.autosave&&t.plugins.autosave.storeDraft(),!e&&t.isDirty()&&t.getParam("autosave_ask_before_unload",!0)&&(e=t.translate("You have unsaved changes are you sure you want to navigate away?"))}),e};var h=function(n,r){return function(t){var e=t.control;e.disabled(!f(n)),n.on("StoreDraft RestoreDraft RemoveDraft",function(){e.disabled(!f(n))}),d(n,r)}};t.add("autosave",function(t){var e,n,r,o=i(!1);return a.window.onbeforeunload=p._beforeUnloadHandler,n=o,(e=t).addButton("restoredraft",{title:"Restore last draft",onclick:function(){g(e)},onPostRender:h(e,n)}),e.addMenuItem("restoredraft",{text:"Restore last draft",onclick:function(){g(e)},onPostRender:h(e,n),context:"file"}),t.on("init",function(){t.getParam("autosave_restore_when_empty",!1)&&t.dom.isEmpty(t.getBody())&&v(t)}),{hasDraft:y(f,r=t),storeDraft:y(m,r),restoreDraft:y(v,r),removeDraft:y(l,r),isEmpty:y(c,r)}})}(window); \ No newline at end of file diff --git a/lib/web/tiny_mce_4/plugins/bbcode/plugin.min.js b/lib/web/tiny_mce_4/plugins/bbcode/plugin.min.js index 966358a0d26f..b2b9d701c666 100755 --- a/lib/web/tiny_mce_4/plugins/bbcode/plugin.min.js +++ b/lib/web/tiny_mce_4/plugins/bbcode/plugin.min.js @@ -1 +1 @@ -!function(){var a={},b=function(b){for(var c=a[b],e=c.deps,f=c.defn,g=e.length,h=new Array(g),i=0;i<g;++i)h[i]=d(e[i]);var j=f.apply(null,h);if(void 0===j)throw"module ["+b+"] returned undefined";c.instance=j},c=function(b,c,d){if("string"!=typeof b)throw"module id must be a string";if(void 0===c)throw"no dependencies for "+b;if(void 0===d)throw"no definition function for "+b;a[b]={deps:c,defn:d,instance:void 0}},d=function(c){var d=a[c];if(void 0===d)throw"module ["+c+"] was undefined";return void 0===d.instance&&b(c),d.instance},e=function(a,b){for(var c=a.length,e=new Array(c),f=0;f<c;++f)e.push(d(a[f]));b.apply(null,b)},f={};f.bolt={module:{api:{define:c,require:e,demand:d}}};var g=c,h=function(a,b){g(a,[],function(){return b})};h("3",tinymce.util.Tools.resolve),g("1",["3"],function(a){return a("tinymce.PluginManager")}),g("2",["3"],function(a){return a("tinymce.util.Tools")}),g("0",["1","2"],function(a,b){return a.add("bbcode",function(){return{init:function(a){var b=this,c=a.getParam("bbcode_dialect","punbb").toLowerCase();a.on("beforeSetContent",function(a){a.content=b["_"+c+"_bbcode2html"](a.content)}),a.on("postProcess",function(a){a.set&&(a.content=b["_"+c+"_bbcode2html"](a.content)),a.get&&(a.content=b["_"+c+"_html2bbcode"](a.content))})},getInfo:function(){return{longname:"BBCode Plugin",author:"Ephox Corp",authorurl:"http://www.tinymce.com",infourl:"http://www.tinymce.com/wiki.php/Plugin:bbcode"}},_punbb_html2bbcode:function(a){function c(b,c){a=a.replace(b,c)}return a=b.trim(a),c(/<a.*?href=\"(.*?)\".*?>(.*?)<\/a>/gi,"[url=$1]$2[/url]"),c(/<font.*?color=\"(.*?)\".*?class=\"codeStyle\".*?>(.*?)<\/font>/gi,"[code][color=$1]$2[/color][/code]"),c(/<font.*?color=\"(.*?)\".*?class=\"quoteStyle\".*?>(.*?)<\/font>/gi,"[quote][color=$1]$2[/color][/quote]"),c(/<font.*?class=\"codeStyle\".*?color=\"(.*?)\".*?>(.*?)<\/font>/gi,"[code][color=$1]$2[/color][/code]"),c(/<font.*?class=\"quoteStyle\".*?color=\"(.*?)\".*?>(.*?)<\/font>/gi,"[quote][color=$1]$2[/color][/quote]"),c(/<span style=\"color: ?(.*?);\">(.*?)<\/span>/gi,"[color=$1]$2[/color]"),c(/<font.*?color=\"(.*?)\".*?>(.*?)<\/font>/gi,"[color=$1]$2[/color]"),c(/<span style=\"font-size:(.*?);\">(.*?)<\/span>/gi,"[size=$1]$2[/size]"),c(/<font>(.*?)<\/font>/gi,"$1"),c(/<img.*?src=\"(.*?)\".*?\/>/gi,"[img]$1[/img]"),c(/<span class=\"codeStyle\">(.*?)<\/span>/gi,"[code]$1[/code]"),c(/<span class=\"quoteStyle\">(.*?)<\/span>/gi,"[quote]$1[/quote]"),c(/<strong class=\"codeStyle\">(.*?)<\/strong>/gi,"[code][b]$1[/b][/code]"),c(/<strong class=\"quoteStyle\">(.*?)<\/strong>/gi,"[quote][b]$1[/b][/quote]"),c(/<em class=\"codeStyle\">(.*?)<\/em>/gi,"[code][i]$1[/i][/code]"),c(/<em class=\"quoteStyle\">(.*?)<\/em>/gi,"[quote][i]$1[/i][/quote]"),c(/<u class=\"codeStyle\">(.*?)<\/u>/gi,"[code][u]$1[/u][/code]"),c(/<u class=\"quoteStyle\">(.*?)<\/u>/gi,"[quote][u]$1[/u][/quote]"),c(/<\/(strong|b)>/gi,"[/b]"),c(/<(strong|b)>/gi,"[b]"),c(/<\/(em|i)>/gi,"[/i]"),c(/<(em|i)>/gi,"[i]"),c(/<\/u>/gi,"[/u]"),c(/<span style=\"text-decoration: ?underline;\">(.*?)<\/span>/gi,"[u]$1[/u]"),c(/<u>/gi,"[u]"),c(/<blockquote[^>]*>/gi,"[quote]"),c(/<\/blockquote>/gi,"[/quote]"),c(/<br \/>/gi,"\n"),c(/<br\/>/gi,"\n"),c(/<br>/gi,"\n"),c(/<p>/gi,""),c(/<\/p>/gi,"\n"),c(/ |\u00a0/gi," "),c(/"/gi,'"'),c(/</gi,"<"),c(/>/gi,">"),c(/&/gi,"&"),a},_punbb_bbcode2html:function(a){function c(b,c){a=a.replace(b,c)}return a=b.trim(a),c(/\n/gi,"<br />"),c(/\[b\]/gi,"<strong>"),c(/\[\/b\]/gi,"</strong>"),c(/\[i\]/gi,"<em>"),c(/\[\/i\]/gi,"</em>"),c(/\[u\]/gi,"<u>"),c(/\[\/u\]/gi,"</u>"),c(/\[url=([^\]]+)\](.*?)\[\/url\]/gi,'<a href="$1">$2</a>'),c(/\[url\](.*?)\[\/url\]/gi,'<a href="$1">$1</a>'),c(/\[img\](.*?)\[\/img\]/gi,'<img src="$1" />'),c(/\[color=(.*?)\](.*?)\[\/color\]/gi,'<font color="$1">$2</font>'),c(/\[code\](.*?)\[\/code\]/gi,'<span class="codeStyle">$1</span> '),c(/\[quote.*?\](.*?)\[\/quote\]/gi,'<span class="quoteStyle">$1</span> '),a}}}),function(){}}),d("0")()}(); \ No newline at end of file +!function(){"use strict";var o=tinymce.util.Tools.resolve("tinymce.PluginManager"),t=tinymce.util.Tools.resolve("tinymce.util.Tools"),e=function(e){e=t.trim(e);var o=function(o,t){e=e.replace(o,t)};return o(/<a.*?href=\"(.*?)\".*?>(.*?)<\/a>/gi,"[url=$1]$2[/url]"),o(/<font.*?color=\"(.*?)\".*?class=\"codeStyle\".*?>(.*?)<\/font>/gi,"[code][color=$1]$2[/color][/code]"),o(/<font.*?color=\"(.*?)\".*?class=\"quoteStyle\".*?>(.*?)<\/font>/gi,"[quote][color=$1]$2[/color][/quote]"),o(/<font.*?class=\"codeStyle\".*?color=\"(.*?)\".*?>(.*?)<\/font>/gi,"[code][color=$1]$2[/color][/code]"),o(/<font.*?class=\"quoteStyle\".*?color=\"(.*?)\".*?>(.*?)<\/font>/gi,"[quote][color=$1]$2[/color][/quote]"),o(/<span style=\"color: ?(.*?);\">(.*?)<\/span>/gi,"[color=$1]$2[/color]"),o(/<font.*?color=\"(.*?)\".*?>(.*?)<\/font>/gi,"[color=$1]$2[/color]"),o(/<span style=\"font-size:(.*?);\">(.*?)<\/span>/gi,"[size=$1]$2[/size]"),o(/<font>(.*?)<\/font>/gi,"$1"),o(/<img.*?src=\"(.*?)\".*?\/>/gi,"[img]$1[/img]"),o(/<span class=\"codeStyle\">(.*?)<\/span>/gi,"[code]$1[/code]"),o(/<span class=\"quoteStyle\">(.*?)<\/span>/gi,"[quote]$1[/quote]"),o(/<strong class=\"codeStyle\">(.*?)<\/strong>/gi,"[code][b]$1[/b][/code]"),o(/<strong class=\"quoteStyle\">(.*?)<\/strong>/gi,"[quote][b]$1[/b][/quote]"),o(/<em class=\"codeStyle\">(.*?)<\/em>/gi,"[code][i]$1[/i][/code]"),o(/<em class=\"quoteStyle\">(.*?)<\/em>/gi,"[quote][i]$1[/i][/quote]"),o(/<u class=\"codeStyle\">(.*?)<\/u>/gi,"[code][u]$1[/u][/code]"),o(/<u class=\"quoteStyle\">(.*?)<\/u>/gi,"[quote][u]$1[/u][/quote]"),o(/<\/(strong|b)>/gi,"[/b]"),o(/<(strong|b)>/gi,"[b]"),o(/<\/(em|i)>/gi,"[/i]"),o(/<(em|i)>/gi,"[i]"),o(/<\/u>/gi,"[/u]"),o(/<span style=\"text-decoration: ?underline;\">(.*?)<\/span>/gi,"[u]$1[/u]"),o(/<u>/gi,"[u]"),o(/<blockquote[^>]*>/gi,"[quote]"),o(/<\/blockquote>/gi,"[/quote]"),o(/<br \/>/gi,"\n"),o(/<br\/>/gi,"\n"),o(/<br>/gi,"\n"),o(/<p>/gi,""),o(/<\/p>/gi,"\n"),o(/ |\u00a0/gi," "),o(/"/gi,'"'),o(/</gi,"<"),o(/>/gi,">"),o(/&/gi,"&"),e},i=function(e){e=t.trim(e);var o=function(o,t){e=e.replace(o,t)};return o(/\n/gi,"<br />"),o(/\[b\]/gi,"<strong>"),o(/\[\/b\]/gi,"</strong>"),o(/\[i\]/gi,"<em>"),o(/\[\/i\]/gi,"</em>"),o(/\[u\]/gi,"<u>"),o(/\[\/u\]/gi,"</u>"),o(/\[url=([^\]]+)\](.*?)\[\/url\]/gi,'<a href="$1">$2</a>'),o(/\[url\](.*?)\[\/url\]/gi,'<a href="$1">$1</a>'),o(/\[img\](.*?)\[\/img\]/gi,'<img src="$1" />'),o(/\[color=(.*?)\](.*?)\[\/color\]/gi,'<font color="$1">$2</font>'),o(/\[code\](.*?)\[\/code\]/gi,'<span class="codeStyle">$1</span> '),o(/\[quote.*?\](.*?)\[\/quote\]/gi,'<span class="quoteStyle">$1</span> '),e};o.add("bbcode",function(){return{init:function(o){o.on("beforeSetContent",function(o){o.content=i(o.content)}),o.on("postProcess",function(o){o.set&&(o.content=i(o.content)),o.get&&(o.content=e(o.content))})}}})}(); \ No newline at end of file diff --git a/lib/web/tiny_mce_4/plugins/charmap/plugin.min.js b/lib/web/tiny_mce_4/plugins/charmap/plugin.min.js index 3fd9e23d5d87..9ea3f757513c 100755 --- a/lib/web/tiny_mce_4/plugins/charmap/plugin.min.js +++ b/lib/web/tiny_mce_4/plugins/charmap/plugin.min.js @@ -1 +1 @@ -!function(){var a={},b=function(b){for(var c=a[b],e=c.deps,f=c.defn,g=e.length,h=new Array(g),i=0;i<g;++i)h[i]=d(e[i]);var j=f.apply(null,h);if(void 0===j)throw"module ["+b+"] returned undefined";c.instance=j},c=function(b,c,d){if("string"!=typeof b)throw"module id must be a string";if(void 0===c)throw"no dependencies for "+b;if(void 0===d)throw"no definition function for "+b;a[b]={deps:c,defn:d,instance:void 0}},d=function(c){var d=a[c];if(void 0===d)throw"module ["+c+"] was undefined";return void 0===d.instance&&b(c),d.instance},e=function(a,b){for(var c=a.length,e=new Array(c),f=0;f<c;++f)e.push(d(a[f]));b.apply(null,b)},f={};f.bolt={module:{api:{define:c,require:e,demand:d}}};var g=c,h=function(a,b){g(a,[],function(){return b})};h("3",tinymce.util.Tools.resolve),g("1",["3"],function(a){return a("tinymce.PluginManager")}),g("2",["3"],function(a){return a("tinymce.util.Tools")}),g("0",["1","2"],function(a,b){return a.add("charmap",function(a){function c(){return[["160","no-break space"],["173","soft hyphen"],["34","quotation mark"],["162","cent sign"],["8364","euro sign"],["163","pound sign"],["165","yen sign"],["169","copyright sign"],["174","registered sign"],["8482","trade mark sign"],["8240","per mille sign"],["181","micro sign"],["183","middle dot"],["8226","bullet"],["8230","three dot leader"],["8242","minutes / feet"],["8243","seconds / inches"],["167","section sign"],["182","paragraph sign"],["223","sharp s / ess-zed"],["8249","single left-pointing angle quotation mark"],["8250","single right-pointing angle quotation mark"],["171","left pointing guillemet"],["187","right pointing guillemet"],["8216","left single quotation mark"],["8217","right single quotation mark"],["8220","left double quotation mark"],["8221","right double quotation mark"],["8218","single low-9 quotation mark"],["8222","double low-9 quotation mark"],["60","less-than sign"],["62","greater-than sign"],["8804","less-than or equal to"],["8805","greater-than or equal to"],["8211","en dash"],["8212","em dash"],["175","macron"],["8254","overline"],["164","currency sign"],["166","broken bar"],["168","diaeresis"],["161","inverted exclamation mark"],["191","turned question mark"],["710","circumflex accent"],["732","small tilde"],["176","degree sign"],["8722","minus sign"],["177","plus-minus sign"],["247","division sign"],["8260","fraction slash"],["215","multiplication sign"],["185","superscript one"],["178","superscript two"],["179","superscript three"],["188","fraction one quarter"],["189","fraction one half"],["190","fraction three quarters"],["402","function / florin"],["8747","integral"],["8721","n-ary sumation"],["8734","infinity"],["8730","square root"],["8764","similar to"],["8773","approximately equal to"],["8776","almost equal to"],["8800","not equal to"],["8801","identical to"],["8712","element of"],["8713","not an element of"],["8715","contains as member"],["8719","n-ary product"],["8743","logical and"],["8744","logical or"],["172","not sign"],["8745","intersection"],["8746","union"],["8706","partial differential"],["8704","for all"],["8707","there exists"],["8709","diameter"],["8711","backward difference"],["8727","asterisk operator"],["8733","proportional to"],["8736","angle"],["180","acute accent"],["184","cedilla"],["170","feminine ordinal indicator"],["186","masculine ordinal indicator"],["8224","dagger"],["8225","double dagger"],["192","A - grave"],["193","A - acute"],["194","A - circumflex"],["195","A - tilde"],["196","A - diaeresis"],["197","A - ring above"],["256","A - macron"],["198","ligature AE"],["199","C - cedilla"],["200","E - grave"],["201","E - acute"],["202","E - circumflex"],["203","E - diaeresis"],["274","E - macron"],["204","I - grave"],["205","I - acute"],["206","I - circumflex"],["207","I - diaeresis"],["298","I - macron"],["208","ETH"],["209","N - tilde"],["210","O - grave"],["211","O - acute"],["212","O - circumflex"],["213","O - tilde"],["214","O - diaeresis"],["216","O - slash"],["332","O - macron"],["338","ligature OE"],["352","S - caron"],["217","U - grave"],["218","U - acute"],["219","U - circumflex"],["220","U - diaeresis"],["362","U - macron"],["221","Y - acute"],["376","Y - diaeresis"],["562","Y - macron"],["222","THORN"],["224","a - grave"],["225","a - acute"],["226","a - circumflex"],["227","a - tilde"],["228","a - diaeresis"],["229","a - ring above"],["257","a - macron"],["230","ligature ae"],["231","c - cedilla"],["232","e - grave"],["233","e - acute"],["234","e - circumflex"],["235","e - diaeresis"],["275","e - macron"],["236","i - grave"],["237","i - acute"],["238","i - circumflex"],["239","i - diaeresis"],["299","i - macron"],["240","eth"],["241","n - tilde"],["242","o - grave"],["243","o - acute"],["244","o - circumflex"],["245","o - tilde"],["246","o - diaeresis"],["248","o slash"],["333","o macron"],["339","ligature oe"],["353","s - caron"],["249","u - grave"],["250","u - acute"],["251","u - circumflex"],["252","u - diaeresis"],["363","u - macron"],["253","y - acute"],["254","thorn"],["255","y - diaeresis"],["563","y - macron"],["913","Alpha"],["914","Beta"],["915","Gamma"],["916","Delta"],["917","Epsilon"],["918","Zeta"],["919","Eta"],["920","Theta"],["921","Iota"],["922","Kappa"],["923","Lambda"],["924","Mu"],["925","Nu"],["926","Xi"],["927","Omicron"],["928","Pi"],["929","Rho"],["931","Sigma"],["932","Tau"],["933","Upsilon"],["934","Phi"],["935","Chi"],["936","Psi"],["937","Omega"],["945","alpha"],["946","beta"],["947","gamma"],["948","delta"],["949","epsilon"],["950","zeta"],["951","eta"],["952","theta"],["953","iota"],["954","kappa"],["955","lambda"],["956","mu"],["957","nu"],["958","xi"],["959","omicron"],["960","pi"],["961","rho"],["962","final sigma"],["963","sigma"],["964","tau"],["965","upsilon"],["966","phi"],["967","chi"],["968","psi"],["969","omega"],["8501","alef symbol"],["982","pi symbol"],["8476","real part symbol"],["978","upsilon - hook symbol"],["8472","Weierstrass p"],["8465","imaginary part"],["8592","leftwards arrow"],["8593","upwards arrow"],["8594","rightwards arrow"],["8595","downwards arrow"],["8596","left right arrow"],["8629","carriage return"],["8656","leftwards double arrow"],["8657","upwards double arrow"],["8658","rightwards double arrow"],["8659","downwards double arrow"],["8660","left right double arrow"],["8756","therefore"],["8834","subset of"],["8835","superset of"],["8836","not a subset of"],["8838","subset of or equal to"],["8839","superset of or equal to"],["8853","circled plus"],["8855","circled times"],["8869","perpendicular"],["8901","dot operator"],["8968","left ceiling"],["8969","right ceiling"],["8970","left floor"],["8971","right floor"],["9001","left-pointing angle bracket"],["9002","right-pointing angle bracket"],["9674","lozenge"],["9824","black spade suit"],["9827","black club suit"],["9829","black heart suit"],["9830","black diamond suit"],["8194","en space"],["8195","em space"],["8201","thin space"],["8204","zero width non-joiner"],["8205","zero width joiner"],["8206","left-to-right mark"],["8207","right-to-left mark"]]}function d(a){return b.grep(a,function(a){return j(a)&&2==a.length})}function e(a){return j(a)?[].concat(d(a)):"function"==typeof a?a():[]}function f(b){var c=a.settings;return c.charmap&&(b=e(c.charmap)),c.charmap_append?[].concat(b).concat(e(c.charmap_append)):b}function g(){return f(c())}function h(b){a.fire("insertCustomChar",{chr:b}).chr,a.execCommand("mceInsertContent",!1,b)}function i(){function b(a){for(;a;){if("TD"==a.nodeName)return a;a=a.parentNode}}var c,d,e,f;c='<table role="presentation" cellspacing="0" class="mce-charmap"><tbody>';var i=g(),j=Math.min(i.length,25),k=Math.ceil(i.length/j);for(e=0;e<k;e++){for(c+="<tr>",d=0;d<j;d++){var l=e*j+d;if(l<i.length){var m=i[l],n=m?String.fromCharCode(parseInt(m[0],10)):" ";c+='<td title="'+m[1]+'"><div tabindex="-1" title="'+m[1]+'" role="button" data-chr="'+n+'">'+n+"</div></td>"}else c+="<td />"}c+="</tr>"}c+="</tbody></table>";var o={type:"container",html:c,onclick:function(a){var c=a.target;if(/^(TD|DIV)$/.test(c.nodeName)){var d=b(c).firstChild;d&&d.hasAttribute("data-chr")&&(h(d.getAttribute("data-chr")),a.ctrlKey||f.close())}},onmouseover:function(a){var c=b(a.target);c&&c.firstChild?(f.find("#preview").text(c.firstChild.firstChild.data),f.find("#previewTitle").text(c.title)):(f.find("#preview").text(" "),f.find("#previewTitle").text(" "))}};f=a.windowManager.open({title:"Special character",spacing:10,padding:10,items:[o,{type:"container",layout:"flex",direction:"column",align:"center",spacing:5,minWidth:160,minHeight:160,items:[{type:"label",name:"preview",text:" ",style:"font-size: 40px; text-align: center",border:1,minWidth:140,minHeight:80},{type:"spacer",minHeight:20},{type:"label",name:"previewTitle",text:" ",style:"white-space: pre-wrap;",border:1,minWidth:140}]}],buttons:[{text:"Close",onclick:function(){f.close()}}]})}var j=b.isArray;return a.addCommand("mceShowCharmap",i),a.addButton("charmap",{icon:"charmap",tooltip:"Special character",cmd:"mceShowCharmap"}),a.addMenuItem("charmap",{icon:"charmap",text:"Special character",cmd:"mceShowCharmap",context:"insert"}),{getCharMap:g,insertChar:h}}),function(){}}),d("0")()}(); \ No newline at end of file +!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),i=function(e,t){return e.fire("insertCustomChar",{chr:t})},l=function(e,t){var a=i(e,t).chr;e.execCommand("mceInsertContent",!1,a)},a=tinymce.util.Tools.resolve("tinymce.util.Tools"),r=function(e){return e.settings.charmap},n=function(e){return e.settings.charmap_append},o=a.isArray,c=function(e){return o(e)?[].concat((t=e,a.grep(t,function(e){return o(e)&&2===e.length}))):"function"==typeof e?e():[];var t},s=function(e){return function(e,t){var a=r(e);a&&(t=c(a));var i=n(e);return i?[].concat(t).concat(c(i)):t}(e,[["160","no-break space"],["173","soft hyphen"],["34","quotation mark"],["162","cent sign"],["8364","euro sign"],["163","pound sign"],["165","yen sign"],["169","copyright sign"],["174","registered sign"],["8482","trade mark sign"],["8240","per mille sign"],["181","micro sign"],["183","middle dot"],["8226","bullet"],["8230","three dot leader"],["8242","minutes / feet"],["8243","seconds / inches"],["167","section sign"],["182","paragraph sign"],["223","sharp s / ess-zed"],["8249","single left-pointing angle quotation mark"],["8250","single right-pointing angle quotation mark"],["171","left pointing guillemet"],["187","right pointing guillemet"],["8216","left single quotation mark"],["8217","right single quotation mark"],["8220","left double quotation mark"],["8221","right double quotation mark"],["8218","single low-9 quotation mark"],["8222","double low-9 quotation mark"],["60","less-than sign"],["62","greater-than sign"],["8804","less-than or equal to"],["8805","greater-than or equal to"],["8211","en dash"],["8212","em dash"],["175","macron"],["8254","overline"],["164","currency sign"],["166","broken bar"],["168","diaeresis"],["161","inverted exclamation mark"],["191","turned question mark"],["710","circumflex accent"],["732","small tilde"],["176","degree sign"],["8722","minus sign"],["177","plus-minus sign"],["247","division sign"],["8260","fraction slash"],["215","multiplication sign"],["185","superscript one"],["178","superscript two"],["179","superscript three"],["188","fraction one quarter"],["189","fraction one half"],["190","fraction three quarters"],["402","function / florin"],["8747","integral"],["8721","n-ary sumation"],["8734","infinity"],["8730","square root"],["8764","similar to"],["8773","approximately equal to"],["8776","almost equal to"],["8800","not equal to"],["8801","identical to"],["8712","element of"],["8713","not an element of"],["8715","contains as member"],["8719","n-ary product"],["8743","logical and"],["8744","logical or"],["172","not sign"],["8745","intersection"],["8746","union"],["8706","partial differential"],["8704","for all"],["8707","there exists"],["8709","diameter"],["8711","backward difference"],["8727","asterisk operator"],["8733","proportional to"],["8736","angle"],["180","acute accent"],["184","cedilla"],["170","feminine ordinal indicator"],["186","masculine ordinal indicator"],["8224","dagger"],["8225","double dagger"],["192","A - grave"],["193","A - acute"],["194","A - circumflex"],["195","A - tilde"],["196","A - diaeresis"],["197","A - ring above"],["256","A - macron"],["198","ligature AE"],["199","C - cedilla"],["200","E - grave"],["201","E - acute"],["202","E - circumflex"],["203","E - diaeresis"],["274","E - macron"],["204","I - grave"],["205","I - acute"],["206","I - circumflex"],["207","I - diaeresis"],["298","I - macron"],["208","ETH"],["209","N - tilde"],["210","O - grave"],["211","O - acute"],["212","O - circumflex"],["213","O - tilde"],["214","O - diaeresis"],["216","O - slash"],["332","O - macron"],["338","ligature OE"],["352","S - caron"],["217","U - grave"],["218","U - acute"],["219","U - circumflex"],["220","U - diaeresis"],["362","U - macron"],["221","Y - acute"],["376","Y - diaeresis"],["562","Y - macron"],["222","THORN"],["224","a - grave"],["225","a - acute"],["226","a - circumflex"],["227","a - tilde"],["228","a - diaeresis"],["229","a - ring above"],["257","a - macron"],["230","ligature ae"],["231","c - cedilla"],["232","e - grave"],["233","e - acute"],["234","e - circumflex"],["235","e - diaeresis"],["275","e - macron"],["236","i - grave"],["237","i - acute"],["238","i - circumflex"],["239","i - diaeresis"],["299","i - macron"],["240","eth"],["241","n - tilde"],["242","o - grave"],["243","o - acute"],["244","o - circumflex"],["245","o - tilde"],["246","o - diaeresis"],["248","o slash"],["333","o macron"],["339","ligature oe"],["353","s - caron"],["249","u - grave"],["250","u - acute"],["251","u - circumflex"],["252","u - diaeresis"],["363","u - macron"],["253","y - acute"],["254","thorn"],["255","y - diaeresis"],["563","y - macron"],["913","Alpha"],["914","Beta"],["915","Gamma"],["916","Delta"],["917","Epsilon"],["918","Zeta"],["919","Eta"],["920","Theta"],["921","Iota"],["922","Kappa"],["923","Lambda"],["924","Mu"],["925","Nu"],["926","Xi"],["927","Omicron"],["928","Pi"],["929","Rho"],["931","Sigma"],["932","Tau"],["933","Upsilon"],["934","Phi"],["935","Chi"],["936","Psi"],["937","Omega"],["945","alpha"],["946","beta"],["947","gamma"],["948","delta"],["949","epsilon"],["950","zeta"],["951","eta"],["952","theta"],["953","iota"],["954","kappa"],["955","lambda"],["956","mu"],["957","nu"],["958","xi"],["959","omicron"],["960","pi"],["961","rho"],["962","final sigma"],["963","sigma"],["964","tau"],["965","upsilon"],["966","phi"],["967","chi"],["968","psi"],["969","omega"],["8501","alef symbol"],["982","pi symbol"],["8476","real part symbol"],["978","upsilon - hook symbol"],["8472","Weierstrass p"],["8465","imaginary part"],["8592","leftwards arrow"],["8593","upwards arrow"],["8594","rightwards arrow"],["8595","downwards arrow"],["8596","left right arrow"],["8629","carriage return"],["8656","leftwards double arrow"],["8657","upwards double arrow"],["8658","rightwards double arrow"],["8659","downwards double arrow"],["8660","left right double arrow"],["8756","therefore"],["8834","subset of"],["8835","superset of"],["8836","not a subset of"],["8838","subset of or equal to"],["8839","superset of or equal to"],["8853","circled plus"],["8855","circled times"],["8869","perpendicular"],["8901","dot operator"],["8968","left ceiling"],["8969","right ceiling"],["8970","left floor"],["8971","right floor"],["9001","left-pointing angle bracket"],["9002","right-pointing angle bracket"],["9674","lozenge"],["9824","black spade suit"],["9827","black club suit"],["9829","black heart suit"],["9830","black diamond suit"],["8194","en space"],["8195","em space"],["8201","thin space"],["8204","zero width non-joiner"],["8205","zero width joiner"],["8206","left-to-right mark"],["8207","right-to-left mark"]])},t=function(t){return{getCharMap:function(){return s(t)},insertChar:function(e){l(t,e)}}},u=function(e){var t,a,i,r=Math.min(e.length,25),n=Math.ceil(e.length/r);for(t='<table role="presentation" cellspacing="0" class="mce-charmap"><tbody>',i=0;i<n;i++){for(t+="<tr>",a=0;a<r;a++){var o=i*r+a;if(o<e.length){var l=e[o],c=parseInt(l[0],10),s=l?String.fromCharCode(c):" ";t+='<td title="'+l[1]+'"><div tabindex="-1" title="'+l[1]+'" role="button" data-chr="'+c+'">'+s+"</div></td>"}else t+="<td />"}t+="</tr>"}return t+="</tbody></table>"},d=function(e){for(;e;){if("TD"===e.nodeName)return e;e=e.parentNode}},m=function(n){var o,e={type:"container",html:u(s(n)),onclick:function(e){var t=e.target;if(/^(TD|DIV)$/.test(t.nodeName)){var a=d(t).firstChild;if(a&&a.hasAttribute("data-chr")){var i=a.getAttribute("data-chr"),r=parseInt(i,10);isNaN(r)||l(n,String.fromCharCode(r)),e.ctrlKey||o.close()}}},onmouseover:function(e){var t=d(e.target);t&&t.firstChild?(o.find("#preview").text(t.firstChild.firstChild.data),o.find("#previewTitle").text(t.title)):(o.find("#preview").text(" "),o.find("#previewTitle").text(" "))}};o=n.windowManager.open({title:"Special character",spacing:10,padding:10,items:[e,{type:"container",layout:"flex",direction:"column",align:"center",spacing:5,minWidth:160,minHeight:160,items:[{type:"label",name:"preview",text:" ",style:"font-size: 40px; text-align: center",border:1,minWidth:140,minHeight:80},{type:"spacer",minHeight:20},{type:"label",name:"previewTitle",text:" ",style:"white-space: pre-wrap;",border:1,minWidth:140}]}],buttons:[{text:"Close",onclick:function(){o.close()}}]})},g=function(e){e.addCommand("mceShowCharmap",function(){m(e)})},p=function(e){e.addButton("charmap",{icon:"charmap",tooltip:"Special character",cmd:"mceShowCharmap"}),e.addMenuItem("charmap",{icon:"charmap",text:"Special character",cmd:"mceShowCharmap",context:"insert"})};e.add("charmap",function(e){return g(e),p(e),t(e)})}(); \ No newline at end of file diff --git a/lib/web/tiny_mce_4/plugins/code/plugin.min.js b/lib/web/tiny_mce_4/plugins/code/plugin.min.js index 7a0437ed96a9..7afcca644ef7 100755 --- a/lib/web/tiny_mce_4/plugins/code/plugin.min.js +++ b/lib/web/tiny_mce_4/plugins/code/plugin.min.js @@ -1 +1 @@ -!function(){var a={},b=function(b){for(var c=a[b],e=c.deps,f=c.defn,g=e.length,h=new Array(g),i=0;i<g;++i)h[i]=d(e[i]);var j=f.apply(null,h);if(void 0===j)throw"module ["+b+"] returned undefined";c.instance=j},c=function(b,c,d){if("string"!=typeof b)throw"module id must be a string";if(void 0===c)throw"no dependencies for "+b;if(void 0===d)throw"no definition function for "+b;a[b]={deps:c,defn:d,instance:void 0}},d=function(c){var d=a[c];if(void 0===d)throw"module ["+c+"] was undefined";return void 0===d.instance&&b(c),d.instance},e=function(a,b){for(var c=a.length,e=new Array(c),f=0;f<c;++f)e.push(d(a[f]));b.apply(null,b)},f={};f.bolt={module:{api:{define:c,require:e,demand:d}}};var g=c,h=function(a,b){g(a,[],function(){return b})};h("3",tinymce.util.Tools.resolve),g("1",["3"],function(a){return a("tinymce.dom.DOMUtils")}),g("2",["3"],function(a){return a("tinymce.PluginManager")}),g("0",["1","2"],function(a,b){return b.add("code",function(b){function c(){var c=b.windowManager.open({title:"Source code",body:{type:"textbox",name:"code",multiline:!0,minWidth:b.getParam("code_dialog_width",600),minHeight:b.getParam("code_dialog_height",Math.min(a.DOM.getViewPort().h-200,500)),spellcheck:!1,style:"direction: ltr; text-align: left"},onSubmit:function(a){b.focus(),b.undoManager.transact(function(){b.setContent(a.data.code)}),b.selection.setCursorLocation(),b.nodeChanged()}});c.find("#code").value(b.getContent({source_view:!0}))}b.addCommand("mceCodeEditor",c),b.addButton("code",{icon:"code",tooltip:"Source code",onclick:c}),b.addMenuItem("code",{icon:"code",text:"Source code",context:"tools",onclick:c})}),function(){}}),d("0")()}(); \ No newline at end of file +!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager"),n=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),o=function(t){return t.getParam("code_dialog_width",600)},i=function(t){return t.getParam("code_dialog_height",Math.min(n.DOM.getViewPort().h-200,500))},c=function(t,n){t.focus(),t.undoManager.transact(function(){t.setContent(n)}),t.selection.setCursorLocation(),t.nodeChanged()},d=function(t){return t.getContent({source_view:!0})},e=function(n){var t=o(n),e=i(n);n.windowManager.open({title:"Source code",body:{type:"textbox",name:"code",multiline:!0,minWidth:t,minHeight:e,spellcheck:!1,style:"direction: ltr; text-align: left"},onSubmit:function(t){c(n,t.data.code)}}).find("#code").value(d(n))},u=function(t){t.addCommand("mceCodeEditor",function(){e(t)})},a=function(t){t.addButton("code",{icon:"code",tooltip:"Source code",onclick:function(){e(t)}}),t.addMenuItem("code",{icon:"code",text:"Source code",onclick:function(){e(t)}})};t.add("code",function(t){return u(t),a(t),{}})}(); \ No newline at end of file diff --git a/lib/web/tiny_mce_4/plugins/codesample/plugin.min.js b/lib/web/tiny_mce_4/plugins/codesample/plugin.min.js index a0285edc6480..c50f3b25cb9c 100755 --- a/lib/web/tiny_mce_4/plugins/codesample/plugin.min.js +++ b/lib/web/tiny_mce_4/plugins/codesample/plugin.min.js @@ -1 +1 @@ -!function(){var a={},b=function(b){for(var c=a[b],e=c.deps,f=c.defn,g=e.length,h=new Array(g),i=0;i<g;++i)h[i]=d(e[i]);var j=f.apply(null,h);if(void 0===j)throw"module ["+b+"] returned undefined";c.instance=j},c=function(b,c,d){if("string"!=typeof b)throw"module id must be a string";if(void 0===c)throw"no dependencies for "+b;if(void 0===d)throw"no definition function for "+b;a[b]={deps:c,defn:d,instance:void 0}},d=function(c){var d=a[c];if(void 0===d)throw"module ["+c+"] was undefined";return void 0===d.instance&&b(c),d.instance},e=function(a,b){for(var c=a.length,e=new Array(c),f=0;f<c;++f)e.push(d(a[f]));b.apply(null,b)},f={};f.bolt={module:{api:{define:c,require:e,demand:d}}};var g=c,h=function(a,b){g(a,[],function(){return b})};h("6",tinymce.util.Tools.resolve),g("1",["6"],function(a){return a("tinymce.Env")}),g("2",["6"],function(a){return a("tinymce.PluginManager")}),g("3",[],function(){var a={},b="undefined"!=typeof a?a:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},c=function(){var a=/\blang(?:uage)?-(?!\*)(\w+)\b/i,c=b.Prism={util:{encode:function(a){return a instanceof d?new d(a.type,c.util.encode(a.content),a.alias):"Array"===c.util.type(a)?a.map(c.util.encode):a.replace(/&/g,"&").replace(/</g,"<").replace(/\u00a0/g," ")},type:function(a){return Object.prototype.toString.call(a).match(/\[object (\w+)\]/)[1]},clone:function(a){var b=c.util.type(a);switch(b){case"Object":var d={};for(var e in a)a.hasOwnProperty(e)&&(d[e]=c.util.clone(a[e]));return d;case"Array":return a.map&&a.map(function(a){return c.util.clone(a)})}return a}},languages:{extend:function(a,b){var d=c.util.clone(c.languages[a]);for(var e in b)d[e]=b[e];return d},insertBefore:function(a,b,d,e){e=e||c.languages;var f=e[a];if(2==arguments.length){d=arguments[1];for(var g in d)d.hasOwnProperty(g)&&(f[g]=d[g]);return f}var h={};for(var i in f)if(f.hasOwnProperty(i)){if(i==b)for(var g in d)d.hasOwnProperty(g)&&(h[g]=d[g]);h[i]=f[i]}return c.languages.DFS(c.languages,function(b,c){c===e[a]&&b!=a&&(this[b]=h)}),e[a]=h},DFS:function(a,b,d){for(var e in a)a.hasOwnProperty(e)&&(b.call(a,e,a[e],d||e),"Object"===c.util.type(a[e])?c.languages.DFS(a[e],b):"Array"===c.util.type(a[e])&&c.languages.DFS(a[e],b,e))}},plugins:{},highlightAll:function(a,b){for(var d,e=document.querySelectorAll('code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'),f=0;d=e[f++];)c.highlightElement(d,a===!0,b)},highlightElement:function(d,e,f){for(var g,h,i=d;i&&!a.test(i.className);)i=i.parentNode;i&&(g=(i.className.match(a)||[,""])[1],h=c.languages[g]),d.className=d.className.replace(a,"").replace(/\s+/g," ")+" language-"+g,i=d.parentNode,/pre/i.test(i.nodeName)&&(i.className=i.className.replace(a,"").replace(/\s+/g," ")+" language-"+g);var j=d.textContent,k={element:d,language:g,grammar:h,code:j};if(!j||!h)return void c.hooks.run("complete",k);if(c.hooks.run("before-highlight",k),e&&b.Worker){var l=new Worker(c.filename);l.onmessage=function(a){k.highlightedCode=a.data,c.hooks.run("before-insert",k),k.element.innerHTML=k.highlightedCode,f&&f.call(k.element),c.hooks.run("after-highlight",k),c.hooks.run("complete",k)},l.postMessage(JSON.stringify({language:k.language,code:k.code,immediateClose:!0}))}else k.highlightedCode=c.highlight(k.code,k.grammar,k.language),c.hooks.run("before-insert",k),k.element.innerHTML=k.highlightedCode,f&&f.call(d),c.hooks.run("after-highlight",k),c.hooks.run("complete",k)},highlight:function(a,b,e){var f=c.tokenize(a,b);return d.stringify(c.util.encode(f),e)},tokenize:function(a,b,d){var e=c.Token,f=[a],g=b.rest;if(g){for(var h in g)b[h]=g[h];delete b.rest}a:for(var h in b)if(b.hasOwnProperty(h)&&b[h]){var i=b[h];i="Array"===c.util.type(i)?i:[i];for(var j=0;j<i.length;++j){var k=i[j],l=k.inside,m=!!k.lookbehind,n=0,o=k.alias;k=k.pattern||k;for(var p=0;p<f.length;p++){var q=f[p];if(f.length>a.length)break a;if(!(q instanceof e)){k.lastIndex=0;var r=k.exec(q);if(r){m&&(n=r[1].length);var s=r.index-1+n,r=r[0].slice(n),t=r.length,u=s+t,v=q.slice(0,s+1),w=q.slice(u+1),x=[p,1];v&&x.push(v);var y=new e(h,l?c.tokenize(r,l):r,o);x.push(y),w&&x.push(w),Array.prototype.splice.apply(f,x)}}}}}return f},hooks:{all:{},add:function(a,b){var d=c.hooks.all;d[a]=d[a]||[],d[a].push(b)},run:function(a,b){var d=c.hooks.all[a];if(d&&d.length)for(var e,f=0;e=d[f++];)e(b)}}},d=c.Token=function(a,b,c){this.type=a,this.content=b,this.alias=c};if(d.stringify=function(a,b,e){if("string"==typeof a)return a;if("Array"===c.util.type(a))return a.map(function(c){return d.stringify(c,b,a)}).join("");var f={type:a.type,content:d.stringify(a.content,b,e),tag:"span",classes:["token",a.type],attributes:{},language:b,parent:e};if("comment"==f.type&&(f.attributes.spellcheck="true"),a.alias){var g="Array"===c.util.type(a.alias)?a.alias:[a.alias];Array.prototype.push.apply(f.classes,g)}c.hooks.run("wrap",f);var h="";for(var i in f.attributes)h+=(h?" ":"")+i+'="'+(f.attributes[i]||"")+'"';return"<"+f.tag+' class="'+f.classes.join(" ")+'" '+h+">"+f.content+"</"+f.tag+">"},!b.document)return b.addEventListener?(b.addEventListener("message",function(a){var d=JSON.parse(a.data),e=d.language,f=d.code,g=d.immediateClose;b.postMessage(c.highlight(f,c.languages[e],e)),g&&b.close()},!1),b.Prism):b.Prism}();return"undefined"!=typeof module&&module.exports&&(module.exports=c),"undefined"!=typeof global&&(global.Prism=c),c.languages.markup={comment:/<!--[\w\W]*?-->/,prolog:/<\?[\w\W]+?\?>/,doctype:/<!DOCTYPE[\w\W]+?>/,cdata:/<!\[CDATA\[[\w\W]*?]]>/i,tag:{pattern:/<\/?[^\s>\/=.]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\\1|\\?(?!\1)[\w\W])*\1|[^\s'">=]+))?)*\s*\/?>/i,inside:{tag:{pattern:/^<\/?[^\s>\/]+/i,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"attr-value":{pattern:/=(?:('|")[\w\W]*?(\1)|[^\s>]+)/i,inside:{punctuation:/[=>"']/}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:/&#?[\da-z]{1,8};/i},c.hooks.add("wrap",function(a){"entity"===a.type&&(a.attributes.title=a.content.replace(/&/,"&"))}),c.languages.xml=c.languages.markup,c.languages.html=c.languages.markup,c.languages.mathml=c.languages.markup,c.languages.svg=c.languages.markup,c.languages.css={comment:/\/\*[\w\W]*?\*\//,atrule:{pattern:/@[\w-]+?.*?(;|(?=\s*\{))/i,inside:{rule:/@[\w-]+/}},url:/url\((?:(["'])(\\(?:\r\n|[\w\W])|(?!\1)[^\\\r\n])*\1|.*?)\)/i,selector:/[^\{\}\s][^\{\};]*?(?=\s*\{)/,string:/("|')(\\(?:\r\n|[\w\W])|(?!\1)[^\\\r\n])*\1/,property:/(\b|\B)[\w-]+(?=\s*:)/i,important:/\B!important\b/i,"function":/[-a-z0-9]+(?=\()/i,punctuation:/[(){};:]/},c.languages.css.atrule.inside.rest=c.util.clone(c.languages.css),c.languages.markup&&(c.languages.insertBefore("markup","tag",{style:{pattern:/<style[\w\W]*?>[\w\W]*?<\/style>/i,inside:{tag:{pattern:/<style[\w\W]*?>|<\/style>/i,inside:c.languages.markup.tag.inside},rest:c.languages.css},alias:"language-css"}}),c.languages.insertBefore("inside","attr-value",{"style-attr":{pattern:/\s*style=("|').*?\1/i,inside:{"attr-name":{pattern:/^\s*style/i,inside:c.languages.markup.tag.inside},punctuation:/^\s*=\s*['"]|['"]\s*$/,"attr-value":{pattern:/.+/i,inside:c.languages.css}},alias:"language-css"}},c.languages.markup.tag)),c.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\w\W]*?\*\//,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0}],string:/(["'])(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,"class-name":{pattern:/((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/i,lookbehind:!0,inside:{punctuation:/(\.|\\)/}},keyword:/\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,"boolean":/\b(true|false)\b/,"function":/[a-z0-9_]+(?=\()/i,number:/\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)\b/i,operator:/--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/,punctuation:/[{}[\];(),.:]/},c.languages.javascript=c.languages.extend("clike",{keyword:/\b(as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|false|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|true|try|typeof|var|void|while|with|yield)\b/,number:/\b-?(0x[\dA-Fa-f]+|0b[01]+|0o[0-7]+|\d*\.?\d+([Ee][+-]?\d+)?|NaN|Infinity)\b/,"function":/[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*(?=\()/i}),c.languages.insertBefore("javascript","keyword",{regex:{pattern:/(^|[^\/])\/(?!\/)(\[.+?]|\\.|[^\/\\\r\n])+\/[gimyu]{0,5}(?=\s*($|[\r\n,.;})]))/,lookbehind:!0}}),c.languages.insertBefore("javascript","class-name",{"template-string":{pattern:/`(?:\\`|\\?[^`])*`/,inside:{interpolation:{pattern:/\$\{[^}]+\}/,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:c.languages.javascript}},string:/[\s\S]+/}}}),c.languages.markup&&c.languages.insertBefore("markup","tag",{script:{pattern:/<script[\w\W]*?>[\w\W]*?<\/script>/i,inside:{tag:{pattern:/<script[\w\W]*?>|<\/script>/i,inside:c.languages.markup.tag.inside},rest:c.languages.javascript},alias:"language-javascript"}}),c.languages.js=c.languages.javascript,c.languages.c=c.languages.extend("clike",{keyword:/\b(asm|typeof|inline|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|union|unsigned|void|volatile|while)\b/,operator:/\-[>-]?|\+\+?|!=?|<<?=?|>>?=?|==?|&&?|\|?\||[~^%?*\/]/,number:/\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)[ful]*\b/i}),c.languages.insertBefore("c","string",{macro:{pattern:/(^\s*)#\s*[a-z]+([^\r\n\\]|\\.|\\(?:\r\n?|\n))*/im,lookbehind:!0,alias:"property",inside:{string:{pattern:/(#\s*include\s*)(<.+?>|("|')(\\?.)+?\3)/,lookbehind:!0}}}}),delete c.languages.c["class-name"],delete c.languages.c["boolean"],c.languages.csharp=c.languages.extend("clike",{keyword:/\b(abstract|as|async|await|base|bool|break|byte|case|catch|char|checked|class|const|continue|decimal|default|delegate|do|double|else|enum|event|explicit|extern|false|finally|fixed|float|for|foreach|goto|if|implicit|in|int|interface|internal|is|lock|long|namespace|new|null|object|operator|out|override|params|private|protected|public|readonly|ref|return|sbyte|sealed|short|sizeof|stackalloc|static|string|struct|switch|this|throw|true|try|typeof|uint|ulong|unchecked|unsafe|ushort|using|virtual|void|volatile|while|add|alias|ascending|async|await|descending|dynamic|from|get|global|group|into|join|let|orderby|partial|remove|select|set|value|var|where|yield)\b/,string:[/@("|')(\1\1|\\\1|\\?(?!\1)[\s\S])*\1/,/("|')(\\?.)*?\1/],number:/\b-?(0x[\da-f]+|\d*\.?\d+)\b/i}),c.languages.insertBefore("csharp","keyword",{preprocessor:{pattern:/(^\s*)#.*/m,lookbehind:!0}}),c.languages.cpp=c.languages.extend("c",{keyword:/\b(alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|class|compl|const|constexpr|const_cast|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|float|for|friend|goto|if|inline|int|long|mutable|namespace|new|noexcept|nullptr|operator|private|protected|public|register|reinterpret_cast|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,"boolean":/\b(true|false)\b/,operator:/[-+]{1,2}|!=?|<{1,2}=?|>{1,2}=?|\->|:{1,2}|={1,2}|\^|~|%|&{1,2}|\|?\||\?|\*|\/|\b(and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/}),c.languages.insertBefore("cpp","keyword",{"class-name":{pattern:/(class\s+)[a-z0-9_]+/i,lookbehind:!0}}),c.languages.java=c.languages.extend("clike",{keyword:/\b(abstract|continue|for|new|switch|assert|default|goto|package|synchronized|boolean|do|if|private|this|break|double|implements|protected|throw|byte|else|import|public|throws|case|enum|instanceof|return|transient|catch|extends|int|short|try|char|final|interface|static|void|class|finally|long|strictfp|volatile|const|float|native|super|while)\b/,number:/\b0b[01]+\b|\b0x[\da-f]*\.?[\da-fp\-]+\b|\b\d*\.?\d+(?:e[+-]?\d+)?[df]?\b/i,operator:{pattern:/(^|[^.])(?:\+[+=]?|-[-=]?|!=?|<<?=?|>>?>?=?|==?|&[&=]?|\|[|=]?|\*=?|\/=?|%=?|\^=?|[?:~])/m,lookbehind:!0}}),c.languages.php=c.languages.extend("clike",{keyword:/\b(and|or|xor|array|as|break|case|cfunction|class|const|continue|declare|default|die|do|else|elseif|enddeclare|endfor|endforeach|endif|endswitch|endwhile|extends|for|foreach|function|include|include_once|global|if|new|return|static|switch|use|require|require_once|var|while|abstract|interface|public|implements|private|protected|parent|throw|null|echo|print|trait|namespace|final|yield|goto|instanceof|finally|try|catch)\b/i,constant:/\b[A-Z0-9_]{2,}\b/,comment:{pattern:/(^|[^\\])(?:\/\*[\w\W]*?\*\/|\/\/.*)/,lookbehind:!0}}),c.languages.insertBefore("php","class-name",{"shell-comment":{pattern:/(^|[^\\])#.*/,lookbehind:!0,alias:"comment"}}),c.languages.insertBefore("php","keyword",{delimiter:/\?>|<\?(?:php)?/i,variable:/\$\w+\b/i,"package":{pattern:/(\\|namespace\s+|use\s+)[\w\\]+/,lookbehind:!0,inside:{punctuation:/\\/}}}),c.languages.insertBefore("php","operator",{property:{pattern:/(->)[\w]+/,lookbehind:!0}}),c.languages.markup&&(c.hooks.add("before-highlight",function(a){"php"===a.language&&(a.tokenStack=[],a.backupCode=a.code,a.code=a.code.replace(/(?:<\?php|<\?)[\w\W]*?(?:\?>)/gi,function(b){return a.tokenStack.push(b),"{{{PHP"+a.tokenStack.length+"}}}"}))}),c.hooks.add("before-insert",function(a){"php"===a.language&&(a.code=a.backupCode,delete a.backupCode)}),c.hooks.add("after-highlight",function(a){if("php"===a.language){for(var b,d=0;b=a.tokenStack[d];d++)a.highlightedCode=a.highlightedCode.replace("{{{PHP"+(d+1)+"}}}",c.highlight(b,a.grammar,"php").replace(/\$/g,"$$$$"));a.element.innerHTML=a.highlightedCode}}),c.hooks.add("wrap",function(a){"php"===a.language&&"markup"===a.type&&(a.content=a.content.replace(/(\{\{\{PHP[0-9]+\}\}\})/g,'<span class="token php">$1</span>'))}),c.languages.insertBefore("php","comment",{markup:{pattern:/<[^?]\/?(.*?)>/,inside:c.languages.markup},php:/\{\{\{PHP[0-9]+\}\}\}/})),c.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0},string:/"""[\s\S]+?"""|'''[\s\S]+?'''|("|')(?:\\?.)*?\1/,"function":{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_][a-zA-Z0-9_]*(?=\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)[a-z0-9_]+/i,lookbehind:!0},keyword:/\b(?:as|assert|async|await|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|pass|print|raise|return|try|while|with|yield)\b/,"boolean":/\b(?:True|False)\b/,number:/\b-?(?:0[bo])?(?:(?:\d|0x[\da-f])[\da-f]*\.?\d*|\.\d+)(?:e[+-]?\d+)?j?\b/i,operator:/[-+%=]=?|!=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]|\b(?:or|and|not)\b/,punctuation:/[{}[\];(),.:]/},function(a){a.languages.ruby=a.languages.extend("clike",{comment:/#(?!\{[^\r\n]*?\}).*/,keyword:/\b(alias|and|BEGIN|begin|break|case|class|def|define_method|defined|do|each|else|elsif|END|end|ensure|false|for|if|in|module|new|next|nil|not|or|raise|redo|require|rescue|retry|return|self|super|then|throw|true|undef|unless|until|when|while|yield)\b/});var b={pattern:/#\{[^}]+\}/,inside:{delimiter:{pattern:/^#\{|\}$/,alias:"tag"},rest:a.util.clone(a.languages.ruby)}};a.languages.insertBefore("ruby","keyword",{regex:[{pattern:/%r([^a-zA-Z0-9\s\{\(\[<])(?:[^\\]|\\[\s\S])*?\1[gim]{0,3}/,inside:{interpolation:b}},{pattern:/%r\((?:[^()\\]|\\[\s\S])*\)[gim]{0,3}/,inside:{interpolation:b}},{pattern:/%r\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}[gim]{0,3}/,inside:{interpolation:b}},{pattern:/%r\[(?:[^\[\]\\]|\\[\s\S])*\][gim]{0,3}/,inside:{interpolation:b}},{pattern:/%r<(?:[^<>\\]|\\[\s\S])*>[gim]{0,3}/,inside:{interpolation:b}},{pattern:/(^|[^\/])\/(?!\/)(\[.+?]|\\.|[^\/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/,lookbehind:!0}],variable:/[@$]+[a-zA-Z_][a-zA-Z_0-9]*(?:[?!]|\b)/,symbol:/:[a-zA-Z_][a-zA-Z_0-9]*(?:[?!]|\b)/}),a.languages.insertBefore("ruby","number",{builtin:/\b(Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Stat|File|Fixnum|Fload|Hash|Integer|IO|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|String|Struct|TMS|Symbol|ThreadGroup|Thread|Time|TrueClass)\b/,constant:/\b[A-Z][a-zA-Z_0-9]*(?:[?!]|\b)/}),a.languages.ruby.string=[{pattern:/%[qQiIwWxs]?([^a-zA-Z0-9\s\{\(\[<])(?:[^\\]|\\[\s\S])*?\1/,inside:{interpolation:b}},{pattern:/%[qQiIwWxs]?\((?:[^()\\]|\\[\s\S])*\)/,inside:{interpolation:b}},{pattern:/%[qQiIwWxs]?\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}/,inside:{interpolation:b}},{pattern:/%[qQiIwWxs]?\[(?:[^\[\]\\]|\\[\s\S])*\]/,inside:{interpolation:b}},{pattern:/%[qQiIwWxs]?<(?:[^<>\\]|\\[\s\S])*>/,inside:{interpolation:b}},{pattern:/("|')(#\{[^}]+\}|\\(?:\r?\n|\r)|\\?.)*?\1/,inside:{interpolation:b}}]}(c),c}),g("7",["6"],function(a){return a("tinymce.dom.DOMUtils")}),g("5",[],function(){function a(a){return a&&"PRE"==a.nodeName&&a.className.indexOf("language-")!==-1}function b(a){return function(b,c){return a(c)}}return{isCodeSample:a,trimArg:b}}),g("4",["7","3","5"],function(a,b,c){function d(a){var b=[{text:"HTML/XML",value:"markup"},{text:"JavaScript",value:"javascript"},{text:"CSS",value:"css"},{text:"PHP",value:"php"},{text:"Ruby",value:"ruby"},{text:"Python",value:"python"},{text:"Java",value:"java"},{text:"C",value:"c"},{text:"C#",value:"csharp"},{text:"C++",value:"cpp"}],c=a.settings.codesample_languages;return c?c:b}function e(a,c,d){a.undoManager.transact(function(){var e=f(a);d=i.encode(d),e?(a.dom.setAttrib(e,"class","language-"+c),e.innerHTML=d,b.highlightElement(e),a.selection.select(e)):(a.insertContent('<pre id="__new" class="language-'+c+'">'+d+"</pre>"),a.selection.select(a.$("#__new").removeAttr("id")[0]))})}function f(a){var b=a.selection.getNode();return c.isCodeSample(b)?b:null}function g(a){var b=f(a);return b?b.textContent:""}function h(a){var b,c=f(a);return c?(b=c.className.match(/language-(\w+)/),b?b[1]:""):""}var i=a.DOM;return{open:function(a){a.windowManager.open({title:"Insert/Edit code sample",minWidth:Math.min(i.getViewPort().w,a.getParam("codesample_dialog_width",800)),minHeight:Math.min(i.getViewPort().h,a.getParam("codesample_dialog_height",650)),layout:"flex",direction:"column",align:"stretch",body:[{type:"listbox",name:"language",label:"Language",maxWidth:200,value:h(a),values:d(a)},{type:"textbox",name:"code",multiline:!0,spellcheck:!1,ariaLabel:"Code view",flex:1,style:"direction: ltr; text-align: left",classes:"monospace",value:g(a),autofocus:!0}],onSubmit:function(b){e(a,b.data.language,b.data.code)}})}}}),g("0",["1","2","3","4","5"],function(a,b,c,d,e){var f,g=e.trimArg;return b.add("codesample",function(b,h){function i(){var a,c=b.settings.codesample_content_css;b.inline&&f||!b.inline&&j||(b.inline?f=!0:j=!0,c!==!1&&(a=b.dom.create("link",{rel:"stylesheet",href:c?c:h+"/css/prism.css"}),b.getDoc().getElementsByTagName("head")[0].appendChild(a)))}var j,k=b.$;a.ceFalse&&(b.on("PreProcess",function(a){k("pre[contenteditable=false]",a.node).filter(g(e.isCodeSample)).each(function(a,b){var c=k(b),d=b.textContent;c.attr("class",k.trim(c.attr("class"))),c.removeAttr("contentEditable"),c.empty().append(k("<code></code>").each(function(){this.textContent=d}))})}),b.on("SetContent",function(){var a=k("pre").filter(g(e.isCodeSample)).filter(function(a,b){return"false"!==b.contentEditable});a.length&&b.undoManager.transact(function(){a.each(function(a,d){k(d).find("br").each(function(a,c){c.parentNode.replaceChild(b.getDoc().createTextNode("\n"),c)}),d.contentEditable=!1,d.innerHTML=b.dom.encode(d.textContent),c.highlightElement(d),d.className=k.trim(d.className)})})}),b.addCommand("codesample",function(){var a=b.selection.getNode();b.selection.isCollapsed()||e.isCodeSample(a)?d.open(b):b.formatter.toggle("code")}),b.addButton("codesample",{cmd:"codesample",title:"Insert/Edit code sample"}),b.on("init",i))}),function(){}}),d("0")()}(); \ No newline at end of file +!function(u){"use strict";var n=function(e){var t=e,a=function(){return t};return{get:a,set:function(e){t=e},clone:function(){return n(a())}}},e=tinymce.util.Tools.resolve("tinymce.PluginManager"),i=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),s=function(e){return e.settings.codesample_content_css},a=function(e){return e.settings.codesample_languages},o=function(e){return Math.min(i.DOM.getViewPort().w,e.getParam("codesample_dialog_width",800))},l=function(e){return Math.min(i.DOM.getViewPort().w,e.getParam("codesample_dialog_height",650))},t={},r=t,g=void 0!==t?t:"undefined"!=typeof WorkerGlobalScope&&u.self instanceof WorkerGlobalScope?u.self:{},c=function(){var c=/\blang(?:uage)?-(?!\*)(\w+)\b/i,S=g.Prism={util:{encode:function(e){return e instanceof o?new o(e.type,S.util.encode(e.content),e.alias):"Array"===S.util.type(e)?e.map(S.util.encode):e.replace(/&/g,"&").replace(/</g,"<").replace(/\u00a0/g," ")},type:function(e){return Object.prototype.toString.call(e).match(/\[object (\w+)\]/)[1]},clone:function(e){switch(S.util.type(e)){case"Object":var t={};for(var a in e)e.hasOwnProperty(a)&&(t[a]=S.util.clone(e[a]));return t;case"Array":return e.map&&e.map(function(e){return S.util.clone(e)})}return e}},languages:{extend:function(e,t){var a=S.util.clone(S.languages[e]);for(var n in t)a[n]=t[n];return a},insertBefore:function(a,e,t,n){var i=(n=n||S.languages)[a];if(2===arguments.length){for(var r in t=e)t.hasOwnProperty(r)&&(i[r]=t[r]);return i}var s={};for(var o in i)if(i.hasOwnProperty(o)){if(o===e)for(var r in t)t.hasOwnProperty(r)&&(s[r]=t[r]);s[o]=i[o]}return S.languages.DFS(S.languages,function(e,t){t===n[a]&&e!==a&&(this[e]=s)}),n[a]=s},DFS:function(e,t,a){for(var n in e)e.hasOwnProperty(n)&&(t.call(e,n,e[n],a||n),"Object"===S.util.type(e[n])?S.languages.DFS(e[n],t):"Array"===S.util.type(e[n])&&S.languages.DFS(e[n],t,n))}},plugins:{},highlightAll:function(e,t){for(var a=u.document.querySelectorAll('code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'),n=0,i=void 0;i=a[n++];)S.highlightElement(i,!0===e,t)},highlightElement:function(e,t,a){for(var n,i,r=e;r&&!c.test(r.className);)r=r.parentNode;r&&(n=(r.className.match(c)||[,""])[1],i=S.languages[n]),e.className=e.className.replace(c,"").replace(/\s+/g," ")+" language-"+n,r=e.parentNode,/pre/i.test(r.nodeName)&&(r.className=r.className.replace(c,"").replace(/\s+/g," ")+" language-"+n);var s=e.textContent,o={element:e,language:n,grammar:i,code:s};if(s&&i)if(S.hooks.run("before-highlight",o),t&&g.Worker){var l=new u.Worker(S.filename);l.onmessage=function(e){o.highlightedCode=e.data,S.hooks.run("before-insert",o),o.element.innerHTML=o.highlightedCode,a&&a.call(o.element),S.hooks.run("after-highlight",o),S.hooks.run("complete",o)},l.postMessage(JSON.stringify({language:o.language,code:o.code,immediateClose:!0}))}else o.highlightedCode=S.highlight(o.code,o.grammar,o.language),S.hooks.run("before-insert",o),o.element.innerHTML=o.highlightedCode,a&&a.call(e),S.hooks.run("after-highlight",o),S.hooks.run("complete",o);else S.hooks.run("complete",o)},highlight:function(e,t,a){var n=S.tokenize(e,t);return o.stringify(S.util.encode(n),a)},tokenize:function(e,t,a){var n=S.Token,i=[e],r=t.rest;if(r){for(var s in r)t[s]=r[s];delete t.rest}e:for(var s in t)if(t.hasOwnProperty(s)&&t[s]){var o=t[s];o="Array"===S.util.type(o)?o:[o];for(var l=0;l<o.length;++l){var c=o[l],u=c.inside,g=!!c.lookbehind,d=0,p=c.alias;c=c.pattern||c;for(var f=0;f<i.length;f++){var h=i[f];if(i.length>e.length)break e;if(!(h instanceof n)){c.lastIndex=0;var m=c.exec(h);if(m){g&&(d=m[1].length);var b=m.index-1+d,y=b+(m=m[0].slice(d)).length,v=h.slice(0,b+1),k=h.slice(y+1),w=[f,1];v&&w.push(v);var x=new n(s,u?S.tokenize(m,u):m,p);w.push(x),k&&w.push(k),Array.prototype.splice.apply(i,w)}}}}}return i},hooks:{all:{},add:function(e,t){var a=S.hooks.all;a[e]=a[e]||[],a[e].push(t)},run:function(e,t){var a=S.hooks.all[e];if(a&&a.length)for(var n=0,i=void 0;i=a[n++];)i(t)}}},o=S.Token=function(e,t,a){this.type=e,this.content=t,this.alias=a};if(o.stringify=function(t,a,e){if("string"==typeof t)return t;if("Array"===S.util.type(t))return t.map(function(e){return o.stringify(e,a,t)}).join("");var n={type:t.type,content:o.stringify(t.content,a,e),tag:"span",classes:["token",t.type],attributes:{},language:a,parent:e};if("comment"===n.type&&(n.attributes.spellcheck="true"),t.alias){var i="Array"===S.util.type(t.alias)?t.alias:[t.alias];Array.prototype.push.apply(n.classes,i)}S.hooks.run("wrap",n);var r="";for(var s in n.attributes)r+=(r?" ":"")+s+'="'+(n.attributes[s]||"")+'"';return"<"+n.tag+' class="'+n.classes.join(" ")+'" '+r+">"+n.content+"</"+n.tag+">"},!g.document)return g.addEventListener&&g.addEventListener("message",function(e){var t=JSON.parse(e.data),a=t.language,n=t.code,i=t.immediateClose;g.postMessage(S.highlight(n,S.languages[a],a)),i&&g.close()},!1),g.Prism}();void 0!==r&&(r.Prism=c),c.languages.markup={comment:/<!--[\w\W]*?-->/,prolog:/<\?[\w\W]+?\?>/,doctype:/<!DOCTYPE[\w\W]+?>/,cdata:/<!\[CDATA\[[\w\W]*?]]>/i,tag:{pattern:/<\/?[^\s>\/=.]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\\1|\\?(?!\1)[\w\W])*\1|[^\s'">=]+))?)*\s*\/?>/i,inside:{tag:{pattern:/^<\/?[^\s>\/]+/i,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"attr-value":{pattern:/=(?:('|")[\w\W]*?(\1)|[^\s>]+)/i,inside:{punctuation:/[=>"']/}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:/&#?[\da-z]{1,8};/i},c.hooks.add("wrap",function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))}),c.languages.xml=c.languages.markup,c.languages.html=c.languages.markup,c.languages.mathml=c.languages.markup,c.languages.svg=c.languages.markup,c.languages.css={comment:/\/\*[\w\W]*?\*\//,atrule:{pattern:/@[\w-]+?.*?(;|(?=\s*\{))/i,inside:{rule:/@[\w-]+/}},url:/url\((?:(["'])(\\(?:\r\n|[\w\W])|(?!\1)[^\\\r\n])*\1|.*?)\)/i,selector:/[^\{\}\s][^\{\};]*?(?=\s*\{)/,string:/("|')(\\(?:\r\n|[\w\W])|(?!\1)[^\\\r\n])*\1/,property:/(\b|\B)[\w-]+(?=\s*:)/i,important:/\B!important\b/i,"function":/[-a-z0-9]+(?=\()/i,punctuation:/[(){};:]/},c.languages.css.atrule.inside.rest=c.util.clone(c.languages.css),c.languages.markup&&(c.languages.insertBefore("markup","tag",{style:{pattern:/<style[\w\W]*?>[\w\W]*?<\/style>/i,inside:{tag:{pattern:/<style[\w\W]*?>|<\/style>/i,inside:c.languages.markup.tag.inside},rest:c.languages.css},alias:"language-css"}}),c.languages.insertBefore("inside","attr-value",{"style-attr":{pattern:/\s*style=("|').*?\1/i,inside:{"attr-name":{pattern:/^\s*style/i,inside:c.languages.markup.tag.inside},punctuation:/^\s*=\s*['"]|['"]\s*$/,"attr-value":{pattern:/.+/i,inside:c.languages.css}},alias:"language-css"}},c.languages.markup.tag)),c.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\w\W]*?\*\//,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0}],string:/(["'])(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,"class-name":{pattern:/((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/i,lookbehind:!0,inside:{punctuation:/(\.|\\)/}},keyword:/\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,"boolean":/\b(true|false)\b/,"function":/[a-z0-9_]+(?=\()/i,number:/\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)\b/i,operator:/--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/,punctuation:/[{}[\];(),.:]/},c.languages.javascript=c.languages.extend("clike",{keyword:/\b(as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|false|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|true|try|typeof|var|void|while|with|yield)\b/,number:/\b-?(0x[\dA-Fa-f]+|0b[01]+|0o[0-7]+|\d*\.?\d+([Ee][+-]?\d+)?|NaN|Infinity)\b/,"function":/[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*(?=\()/i}),c.languages.insertBefore("javascript","keyword",{regex:{pattern:/(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\\\r\n])+\/[gimyu]{0,5}(?=\s*($|[\r\n,.;})]))/,lookbehind:!0}}),c.languages.insertBefore("javascript","class-name",{"template-string":{pattern:/`(?:\\`|\\?[^`])*`/,inside:{interpolation:{pattern:/\$\{[^}]+\}/,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:c.languages.javascript}},string:/[\s\S]+/}}}),c.languages.markup&&c.languages.insertBefore("markup","tag",{script:{pattern:/<script[\w\W]*?>[\w\W]*?<\/script>/i,inside:{tag:{pattern:/<script[\w\W]*?>|<\/script>/i,inside:c.languages.markup.tag.inside},rest:c.languages.javascript},alias:"language-javascript"}}),c.languages.js=c.languages.javascript,c.languages.c=c.languages.extend("clike",{keyword:/\b(asm|typeof|inline|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|union|unsigned|void|volatile|while)\b/,operator:/\-[>-]?|\+\+?|!=?|<<?=?|>>?=?|==?|&&?|\|?\||[~^%?*\/]/,number:/\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)[ful]*\b/i}),c.languages.insertBefore("c","string",{macro:{pattern:/(^\s*)#\s*[a-z]+([^\r\n\\]|\\.|\\(?:\r\n?|\n))*/im,lookbehind:!0,alias:"property",inside:{string:{pattern:/(#\s*include\s*)(<.+?>|("|')(\\?.)+?\3)/,lookbehind:!0}}}}),delete c.languages.c["class-name"],delete c.languages.c["boolean"],c.languages.csharp=c.languages.extend("clike",{keyword:/\b(abstract|as|async|await|base|bool|break|byte|case|catch|char|checked|class|const|continue|decimal|default|delegate|do|double|else|enum|event|explicit|extern|false|finally|fixed|float|for|foreach|goto|if|implicit|in|int|interface|internal|is|lock|long|namespace|new|null|object|operator|out|override|params|private|protected|public|readonly|ref|return|sbyte|sealed|short|sizeof|stackalloc|static|string|struct|switch|this|throw|true|try|typeof|uint|ulong|unchecked|unsafe|ushort|using|virtual|void|volatile|while|add|alias|ascending|async|await|descending|dynamic|from|get|global|group|into|join|let|orderby|partial|remove|select|set|value|var|where|yield)\b/,string:[/@("|')(\1\1|\\\1|\\?(?!\1)[\s\S])*\1/,/("|')(\\?.)*?\1/],number:/\b-?(0x[\da-f]+|\d*\.?\d+)\b/i}),c.languages.insertBefore("csharp","keyword",{preprocessor:{pattern:/(^\s*)#.*/m,lookbehind:!0}}),c.languages.cpp=c.languages.extend("c",{keyword:/\b(alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|class|compl|const|constexpr|const_cast|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|float|for|friend|goto|if|inline|int|long|mutable|namespace|new|noexcept|nullptr|operator|private|protected|public|register|reinterpret_cast|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,"boolean":/\b(true|false)\b/,operator:/[-+]{1,2}|!=?|<{1,2}=?|>{1,2}=?|\->|:{1,2}|={1,2}|\^|~|%|&{1,2}|\|?\||\?|\*|\/|\b(and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/}),c.languages.insertBefore("cpp","keyword",{"class-name":{pattern:/(class\s+)[a-z0-9_]+/i,lookbehind:!0}}),c.languages.java=c.languages.extend("clike",{keyword:/\b(abstract|continue|for|new|switch|assert|default|goto|package|synchronized|boolean|do|if|private|this|break|double|implements|protected|throw|byte|else|import|public|throws|case|enum|instanceof|return|transient|catch|extends|int|short|try|char|final|interface|static|void|class|finally|long|strictfp|volatile|const|float|native|super|while)\b/,number:/\b0b[01]+\b|\b0x[\da-f]*\.?[\da-fp\-]+\b|\b\d*\.?\d+(?:e[+-]?\d+)?[df]?\b/i,operator:{pattern:/(^|[^.])(?:\+[+=]?|-[-=]?|!=?|<<?=?|>>?>?=?|==?|&[&=]?|\|[|=]?|\*=?|\/=?|%=?|\^=?|[?:~])/m,lookbehind:!0}}),c.languages.php=c.languages.extend("clike",{keyword:/\b(and|or|xor|array|as|break|case|cfunction|class|const|continue|declare|default|die|do|else|elseif|enddeclare|endfor|endforeach|endif|endswitch|endwhile|extends|for|foreach|function|include|include_once|global|if|new|return|static|switch|use|require|require_once|var|while|abstract|interface|public|implements|private|protected|parent|throw|null|echo|print|trait|namespace|final|yield|goto|instanceof|finally|try|catch)\b/i,constant:/\b[A-Z0-9_]{2,}\b/,comment:{pattern:/(^|[^\\])(?:\/\*[\w\W]*?\*\/|\/\/.*)/,lookbehind:!0}}),c.languages.insertBefore("php","class-name",{"shell-comment":{pattern:/(^|[^\\])#.*/,lookbehind:!0,alias:"comment"}}),c.languages.insertBefore("php","keyword",{delimiter:/\?>|<\?(?:php)?/i,variable:/\$\w+\b/i,"package":{pattern:/(\\|namespace\s+|use\s+)[\w\\]+/,lookbehind:!0,inside:{punctuation:/\\/}}}),c.languages.insertBefore("php","operator",{property:{pattern:/(->)[\w]+/,lookbehind:!0}}),c.languages.markup&&(c.hooks.add("before-highlight",function(t){"php"===t.language&&(t.tokenStack=[],t.backupCode=t.code,t.code=t.code.replace(/(?:<\?php|<\?)[\w\W]*?(?:\?>)/gi,function(e){return t.tokenStack.push(e),"{{{PHP"+t.tokenStack.length+"}}}"}))}),c.hooks.add("before-insert",function(e){"php"===e.language&&(e.code=e.backupCode,delete e.backupCode)}),c.hooks.add("after-highlight",function(e){if("php"===e.language){for(var t=0,a=void 0;a=e.tokenStack[t];t++)e.highlightedCode=e.highlightedCode.replace("{{{PHP"+(t+1)+"}}}",c.highlight(a,e.grammar,"php").replace(/\$/g,"$$$$"));e.element.innerHTML=e.highlightedCode}}),c.hooks.add("wrap",function(e){"php"===e.language&&"markup"===e.type&&(e.content=e.content.replace(/(\{\{\{PHP[0-9]+\}\}\})/g,'<span class="token php">$1</span>'))}),c.languages.insertBefore("php","comment",{markup:{pattern:/<[^?]\/?(.*?)>/,inside:c.languages.markup},php:/\{\{\{PHP[0-9]+\}\}\}/})),c.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0},string:/"""[\s\S]+?"""|'''[\s\S]+?'''|("|')(?:\\?.)*?\1/,"function":{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_][a-zA-Z0-9_]*(?=\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)[a-z0-9_]+/i,lookbehind:!0},keyword:/\b(?:as|assert|async|await|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|pass|print|raise|return|try|while|with|yield)\b/,"boolean":/\b(?:True|False)\b/,number:/\b-?(?:0[bo])?(?:(?:\d|0x[\da-f])[\da-f]*\.?\d*|\.\d+)(?:e[+-]?\d+)?j?\b/i,operator:/[-+%=]=?|!=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]|\b(?:or|and|not)\b/,punctuation:/[{}[\];(),.:]/},function(e){e.languages.ruby=e.languages.extend("clike",{comment:/#(?!\{[^\r\n]*?\}).*/,keyword:/\b(alias|and|BEGIN|begin|break|case|class|def|define_method|defined|do|each|else|elsif|END|end|ensure|false|for|if|in|module|new|next|nil|not|or|raise|redo|require|rescue|retry|return|self|super|then|throw|true|undef|unless|until|when|while|yield)\b/});var t={pattern:/#\{[^}]+\}/,inside:{delimiter:{pattern:/^#\{|\}$/,alias:"tag"},rest:e.util.clone(e.languages.ruby)}};e.languages.insertBefore("ruby","keyword",{regex:[{pattern:/%r([^a-zA-Z0-9\s\{\(\[<])(?:[^\\]|\\[\s\S])*?\1[gim]{0,3}/,inside:{interpolation:t}},{pattern:/%r\((?:[^()\\]|\\[\s\S])*\)[gim]{0,3}/,inside:{interpolation:t}},{pattern:/%r\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}[gim]{0,3}/,inside:{interpolation:t}},{pattern:/%r\[(?:[^\[\]\\]|\\[\s\S])*\][gim]{0,3}/,inside:{interpolation:t}},{pattern:/%r<(?:[^<>\\]|\\[\s\S])*>[gim]{0,3}/,inside:{interpolation:t}},{pattern:/(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/,lookbehind:!0}],variable:/[@$]+[a-zA-Z_][a-zA-Z_0-9]*(?:[?!]|\b)/,symbol:/:[a-zA-Z_][a-zA-Z_0-9]*(?:[?!]|\b)/}),e.languages.insertBefore("ruby","number",{builtin:/\b(Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Stat|File|Fixnum|Fload|Hash|Integer|IO|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|String|Struct|TMS|Symbol|ThreadGroup|Thread|Time|TrueClass)\b/,constant:/\b[A-Z][a-zA-Z_0-9]*(?:[?!]|\b)/}),e.languages.ruby.string=[{pattern:/%[qQiIwWxs]?([^a-zA-Z0-9\s\{\(\[<])(?:[^\\]|\\[\s\S])*?\1/,inside:{interpolation:t}},{pattern:/%[qQiIwWxs]?\((?:[^()\\]|\\[\s\S])*\)/,inside:{interpolation:t}},{pattern:/%[qQiIwWxs]?\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}/,inside:{interpolation:t}},{pattern:/%[qQiIwWxs]?\[(?:[^\[\]\\]|\\[\s\S])*\]/,inside:{interpolation:t}},{pattern:/%[qQiIwWxs]?<(?:[^<>\\]|\\[\s\S])*>/,inside:{interpolation:t}},{pattern:/("|')(#\{[^}]+\}|\\(?:\r?\n|\r)|\\?.)*?\1/,inside:{interpolation:t}}]}(c);var d={isCodeSample:function(e){return e&&"PRE"===e.nodeName&&-1!==e.className.indexOf("language-")},trimArg:function(a){return function(e,t){return a(t)}}},p=function(e){var t=e.selection.getNode();return d.isCodeSample(t)?t:null},f=p,h=function(t,a,n){t.undoManager.transact(function(){var e=p(t);n=i.DOM.encode(n),e?(t.dom.setAttrib(e,"class","language-"+a),e.innerHTML=n,c.highlightElement(e),t.selection.select(e)):(t.insertContent('<pre id="__new" class="language-'+a+'">'+n+"</pre>"),t.selection.select(t.$("#__new").removeAttr("id")[0]))})},m=function(e){var t=p(e);return t?t.textContent:""},b=function(e){var t=a(e);return t||[{text:"HTML/XML",value:"markup"},{text:"JavaScript",value:"javascript"},{text:"CSS",value:"css"},{text:"PHP",value:"php"},{text:"Ruby",value:"ruby"},{text:"Python",value:"python"},{text:"Java",value:"java"},{text:"C",value:"c"},{text:"C#",value:"csharp"},{text:"C++",value:"cpp"}]},y=function(e){var t,a=f(e);return a&&(t=a.className.match(/language-(\w+)/))?t[1]:""},v=function(t){var e=o(t),a=l(t),n=y(t),i=b(t),r=m(t);t.windowManager.open({title:"Insert/Edit code sample",minWidth:e,minHeight:a,layout:"flex",direction:"column",align:"stretch",body:[{type:"listbox",name:"language",label:"Language",maxWidth:200,value:n,values:i},{type:"textbox",name:"code",multiline:!0,spellcheck:!1,ariaLabel:"Code view",flex:1,style:"direction: ltr; text-align: left",classes:"monospace",value:r,autofocus:!0}],onSubmit:function(e){h(t,e.data.language,e.data.code)}})},k=function(t){t.addCommand("codesample",function(){var e=t.selection.getNode();t.selection.isCollapsed()||d.isCodeSample(e)?v(t):t.formatter.toggle("code")})},w=function(a){var i=a.$;a.on("PreProcess",function(e){i("pre[contenteditable=false]",e.node).filter(d.trimArg(d.isCodeSample)).each(function(e,t){var a=i(t),n=t.textContent;a.attr("class",i.trim(a.attr("class"))),a.removeAttr("contentEditable"),a.empty().append(i("<code></code>").each(function(){this.textContent=n}))})}),a.on("SetContent",function(){var e=i("pre").filter(d.trimArg(d.isCodeSample)).filter(function(e,t){return"false"!==t.contentEditable});e.length&&a.undoManager.transact(function(){e.each(function(e,t){i(t).find("br").each(function(e,t){t.parentNode.replaceChild(a.getDoc().createTextNode("\n"),t)}),t.contentEditable=!1,t.innerHTML=a.dom.encode(t.textContent),c.highlightElement(t),t.className=i.trim(t.className)})})})},x=function(e,t,a,n){var i,r=s(e);e.inline&&a.get()||!e.inline&&n.get()||(e.inline?a.set(!0):n.set(!0),!1!==r&&(i=e.dom.create("link",{rel:"stylesheet",href:r||t+"/css/prism.css"}),e.getDoc().getElementsByTagName("head")[0].appendChild(i)))},S=function(e){e.addButton("codesample",{cmd:"codesample",title:"Insert/Edit code sample"}),e.addMenuItem("codesample",{cmd:"codesample",text:"Code sample",icon:"codesample"})},C=n(!1);e.add("codesample",function(t,e){var a=n(!1);w(t),S(t),k(t),t.on("init",function(){x(t,e,C,a)}),t.on("dblclick",function(e){d.isCodeSample(e.target)&&v(t)})})}(window); \ No newline at end of file diff --git a/lib/web/tiny_mce_4/plugins/colorpicker/plugin.min.js b/lib/web/tiny_mce_4/plugins/colorpicker/plugin.min.js index 35bfea2141f3..10317a5f6f4b 100755 --- a/lib/web/tiny_mce_4/plugins/colorpicker/plugin.min.js +++ b/lib/web/tiny_mce_4/plugins/colorpicker/plugin.min.js @@ -1 +1 @@ -!function(){var a={},b=function(b){for(var c=a[b],e=c.deps,f=c.defn,g=e.length,h=new Array(g),i=0;i<g;++i)h[i]=d(e[i]);var j=f.apply(null,h);if(void 0===j)throw"module ["+b+"] returned undefined";c.instance=j},c=function(b,c,d){if("string"!=typeof b)throw"module id must be a string";if(void 0===c)throw"no dependencies for "+b;if(void 0===d)throw"no definition function for "+b;a[b]={deps:c,defn:d,instance:void 0}},d=function(c){var d=a[c];if(void 0===d)throw"module ["+c+"] was undefined";return void 0===d.instance&&b(c),d.instance},e=function(a,b){for(var c=a.length,e=new Array(c),f=0;f<c;++f)e.push(d(a[f]));b.apply(null,b)},f={};f.bolt={module:{api:{define:c,require:e,demand:d}}};var g=c,h=function(a,b){g(a,[],function(){return b})};h("3",tinymce.util.Tools.resolve),g("1",["3"],function(a){return a("tinymce.PluginManager")}),g("2",["3"],function(a){return a("tinymce.util.Color")}),g("0",["1","2"],function(a,b){return a.add("colorpicker",function(a){function c(c,d){function e(a){var c=new b(a),d=c.toRgb();g.fromJSON({r:d.r,g:d.g,b:d.b,hex:c.toHex().substr(1)}),f(c.toHex())}function f(a){g.find("#preview")[0].getEl().style.background=a}var g=a.windowManager.open({title:"Color",items:{type:"container",layout:"flex",direction:"row",align:"stretch",padding:5,spacing:10,items:[{type:"colorpicker",value:d,onchange:function(){var a=this.rgb();g&&(g.find("#r").value(a.r),g.find("#g").value(a.g),g.find("#b").value(a.b),g.find("#hex").value(this.value().substr(1)),f(this.value()))}},{type:"form",padding:0,labelGap:5,defaults:{type:"textbox",size:7,value:"0",flex:1,spellcheck:!1,onchange:function(){var a,b,c=g.find("colorpicker")[0];return a=this.name(),b=this.value(),"hex"==a?(b="#"+b,e(b),void c.value(b)):(b={r:g.find("#r").value(),g:g.find("#g").value(),b:g.find("#b").value()},c.value(b),void e(b))}},items:[{name:"r",label:"R",autofocus:1},{name:"g",label:"G"},{name:"b",label:"B"},{name:"hex",label:"#",value:"000000"},{name:"preview",type:"container",border:1}]}]},onSubmit:function(){c("#"+this.toJSON().hex)}});e(d)}a.settings.color_picker_callback||(a.settings.color_picker_callback=c)}),function(){}}),d("0")()}(); \ No newline at end of file +!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),l=tinymce.util.Tools.resolve("tinymce.util.Color"),a=function(e,n){e.find("#preview")[0].getEl().style.background=n},o=function(e,n){var i=l(n),t=i.toRgb();e.fromJSON({r:t.r,g:t.g,b:t.b,hex:i.toHex().substr(1)}),a(e,i.toHex())},t=function(e,n,i){var t=e.windowManager.open({title:"Color",items:{type:"container",layout:"flex",direction:"row",align:"stretch",padding:5,spacing:10,items:[{type:"colorpicker",value:i,onchange:function(){var e=this.rgb();t&&(t.find("#r").value(e.r),t.find("#g").value(e.g),t.find("#b").value(e.b),t.find("#hex").value(this.value().substr(1)),a(t,this.value()))}},{type:"form",padding:0,labelGap:5,defaults:{type:"textbox",size:7,value:"0",flex:1,spellcheck:!1,onchange:function(){var e,n,i=t.find("colorpicker")[0];if(e=this.name(),n=this.value(),"hex"===e)return o(t,n="#"+n),void i.value(n);n={r:t.find("#r").value(),g:t.find("#g").value(),b:t.find("#b").value()},i.value(n),o(t,n)}},items:[{name:"r",label:"R",autofocus:1},{name:"g",label:"G"},{name:"b",label:"B"},{name:"hex",label:"#",value:"000000"},{name:"preview",type:"container",border:1}]}]},onSubmit:function(){n("#"+t.toJSON().hex)}});o(t,i)};e.add("colorpicker",function(i){i.settings.color_picker_callback||(i.settings.color_picker_callback=function(e,n){t(i,e,n)})})}(); \ No newline at end of file diff --git a/lib/web/tiny_mce_4/plugins/contextmenu/plugin.min.js b/lib/web/tiny_mce_4/plugins/contextmenu/plugin.min.js index 5209089240d2..a2e2c7547f1f 100755 --- a/lib/web/tiny_mce_4/plugins/contextmenu/plugin.min.js +++ b/lib/web/tiny_mce_4/plugins/contextmenu/plugin.min.js @@ -1 +1 @@ -!function(){var a={},b=function(b){for(var c=a[b],e=c.deps,f=c.defn,g=e.length,h=new Array(g),i=0;i<g;++i)h[i]=d(e[i]);var j=f.apply(null,h);if(void 0===j)throw"module ["+b+"] returned undefined";c.instance=j},c=function(b,c,d){if("string"!=typeof b)throw"module id must be a string";if(void 0===c)throw"no dependencies for "+b;if(void 0===d)throw"no definition function for "+b;a[b]={deps:c,defn:d,instance:void 0}},d=function(c){var d=a[c];if(void 0===d)throw"module ["+c+"] was undefined";return void 0===d.instance&&b(c),d.instance},e=function(a,b){for(var c=a.length,e=new Array(c),f=0;f<c;++f)e.push(d(a[f]));b.apply(null,b)},f={};f.bolt={module:{api:{define:c,require:e,demand:d}}};var g=c,h=function(a,b){g(a,[],function(){return b})};h("7",tinymce.util.Tools.resolve),g("1",["7"],function(a){return a("tinymce.dom.DOMUtils")}),g("2",["7"],function(a){return a("tinymce.Env")}),g("3",["7"],function(a){return a("tinymce.PluginManager")}),g("4",["7"],function(a){return a("tinymce.ui.Menu")}),g("5",["7"],function(a){return a("tinymce.util.Tools")}),h("a",Array),h("b",Error),g("d",["a","b"],function(a,b){var c=function(){},d=function(a,b){return function(){return a(b.apply(null,arguments))}},e=function(a){return function(){return a}},f=function(a){return a},g=function(a,b){return a===b},h=function(b){for(var c=new a(arguments.length-1),d=1;d<arguments.length;d++)c[d-1]=arguments[d];return function(){for(var d=new a(arguments.length),e=0;e<d.length;e++)d[e]=arguments[e];var f=c.concat(d);return b.apply(null,f)}},i=function(a){return function(){return!a.apply(null,arguments)}},j=function(a){return function(){throw new b(a)}},k=function(a){return a()},l=function(a){a()},m=e(!1),n=e(!0);return{noop:c,compose:d,constant:e,identity:f,tripleEquals:g,curry:h,not:i,die:j,apply:k,call:l,never:m,always:n}}),h("e",Object),g("9",["d","e"],function(a,b){var c=a.never,d=a.always,e=function(){return f},f=function(){var f=function(a){return a.isNone()},g=function(a){return a()},h=function(a){return a},i=function(){},j={fold:function(a,b){return a()},is:c,isSome:c,isNone:d,getOr:h,getOrThunk:g,getOrDie:function(a){throw new Error(a||"error: getOrDie called on none.")},or:h,orThunk:g,map:e,ap:e,each:i,bind:e,flatten:e,exists:c,forall:d,filter:e,equals:f,equals_:f,toArray:function(){return[]},toString:a.constant("none()")};return b.freeze&&b.freeze(j),j}(),g=function(a){var b=function(){return a},h=function(){return k},i=function(b){return g(b(a))},j=function(b){return b(a)},k={fold:function(b,c){return c(a)},is:function(b){return a===b},isSome:d,isNone:c,getOr:b,getOrThunk:b,getOrDie:b,or:h,orThunk:h,map:i,ap:function(b){return b.fold(e,function(b){return g(b(a))})},each:function(b){b(a)},bind:j,flatten:b,exists:j,forall:j,filter:function(b){return b(a)?k:f},equals:function(b){return b.is(a)},equals_:function(b,d){return b.fold(c,function(b){return d(a,b)})},toArray:function(){return[a]},toString:function(){return"some("+a+")"}};return k},h=function(a){return null===a||void 0===a?f:g(a)};return{some:g,none:e,from:h}}),h("c",String),g("8",["9","a","b","c"],function(a,b,c,d){var e=function(){var a=b.prototype.indexOf,c=function(b,c){return a.call(b,c)},d=function(a,b){return u(a,b)};return void 0===a?d:c}(),f=function(b,c){var d=e(b,c);return d===-1?a.none():a.some(d)},g=function(a,b){return e(a,b)>-1},h=function(a,b){return t(a,b).isSome()},i=function(a,b){for(var c=[],d=0;d<a;d++)c.push(b(d));return c},j=function(a,b){for(var c=[],d=0;d<a.length;d+=b){var e=a.slice(d,d+b);c.push(e)}return c},k=function(a,c){for(var d=a.length,e=new b(d),f=0;f<d;f++){var g=a[f];e[f]=c(g,f,a)}return e},l=function(a,b){for(var c=0,d=a.length;c<d;c++){var e=a[c];b(e,c,a)}},m=function(a,b){for(var c=a.length-1;c>=0;c--){var d=a[c];b(d,c,a)}},n=function(a,b){for(var c=[],d=[],e=0,f=a.length;e<f;e++){var g=a[e],h=b(g,e,a)?c:d;h.push(g)}return{pass:c,fail:d}},o=function(a,b){for(var c=[],d=0,e=a.length;d<e;d++){var f=a[d];b(f,d,a)&&c.push(f)}return c},p=function(a,b){if(0===a.length)return[];for(var c=b(a[0]),d=[],e=[],f=0,g=a.length;f<g;f++){var h=a[f],i=b(h);i!==c&&(d.push(e),e=[]),c=i,e.push(h)}return 0!==e.length&&d.push(e),d},q=function(a,b,c){return m(a,function(a){c=b(c,a)}),c},r=function(a,b,c){return l(a,function(a){c=b(c,a)}),c},s=function(b,c){for(var d=0,e=b.length;d<e;d++){var f=b[d];if(c(f,d,b))return a.some(f)}return a.none()},t=function(b,c){for(var d=0,e=b.length;d<e;d++){var f=b[d];if(c(f,d,b))return a.some(d)}return a.none()},u=function(a,b){for(var c=0,d=a.length;c<d;++c)if(a[c]===b)return c;return-1},v=b.prototype.push,w=function(a){for(var d=[],e=0,f=a.length;e<f;++e){if(!b.prototype.isPrototypeOf(a[e]))throw new c("Arr.flatten item "+e+" was not an array, input: "+a);v.apply(d,a[e])}return d},x=function(a,b){var c=k(a,b);return w(c)},y=function(a,b){for(var c=0,d=a.length;c<d;++c){var e=a[c];if(b(e,c,a)!==!0)return!1}return!0},z=function(a,b){return a.length===b.length&&y(a,function(a,c){return a===b[c]})},A=b.prototype.slice,B=function(a){var b=A.call(a,0);return b.reverse(),b},C=function(a,b){return o(a,function(a){return!g(b,a)})},D=function(a,b){for(var c={},e=0,f=a.length;e<f;e++){var g=a[e];c[d(g)]=b(g,e)}return c},E=function(a){return[a]},F=function(a,b){var c=A.call(a,0);return c.sort(b),c};return{map:k,each:l,eachr:m,partition:n,filter:o,groupBy:p,indexOf:f,foldr:q,foldl:r,find:s,findIndex:t,flatten:w,bind:x,forall:y,exists:h,contains:g,equal:z,reverse:B,chunk:j,difference:C,mapToObject:D,pure:E,sort:F,range:i}}),g("6",["8"],function(a){var b=function(a,b,c){return b>=a.left&&b<=a.right&&c>=a.top&&c<=a.bottom},c=function(c,d,e){return!e.collapsed&&a.foldl(e.getClientRects(),function(a,e){return a||b(e,c,d)},!1)};return{isXYWithinRange:c}}),g("0",["1","2","3","4","5","6"],function(a,b,c,d,e,f){var g=a.DOM;return c.add("contextmenu",function(a){var c,h,i=a.settings.contextmenu_never_use_native,j=function(a){return a.ctrlKey&&!i},k=function(){return b.mac&&b.webkit},l=function(){return h===!0},m=function(a){return a&&"IMG"===a.nodeName},n=function(a,b){return m(a.target)&&f.isXYWithinRange(a.clientX,a.clientY,b)===!1};return a.on("mousedown",function(b){k()&&2===b.button&&!j(b)&&a.selection.isCollapsed()&&a.once("contextmenu",function(b){m(b.target)||a.selection.placeCaretAt(b.clientX,b.clientY)})}),a.on("contextmenu",function(b){var f;if(!j(b)){if(n(b,a.selection.getRng())&&a.selection.select(b.target),b.preventDefault(),f=a.settings.contextmenu||"link openlink image inserttable | cell row column deletetable",c)c.show();else{var i=[];e.each(f.split(/[ ,]/),function(b){var c=a.menuItems[b];"|"==b&&(c={text:b}),c&&(c.shortcut="",i.push(c))});for(var k=0;k<i.length;k++)"|"==i[k].text&&(0!==k&&k!=i.length-1||i.splice(k,1));c=new d({items:i,context:"contextmenu",classes:"contextmenu"}).renderTo(),c.on("hide",function(a){a.control===this&&(h=!1)}),a.on("remove",function(){c.remove(),c=null})}var l={x:b.pageX,y:b.pageY};a.inline||(l=g.getPos(a.getContentAreaContainer()),l.x+=b.clientX,l.y+=b.clientY),c.moveTo(l.x,l.y),h=!0}}),{isContextMenuVisible:l}}),function(){}}),d("0")()}(); \ No newline at end of file +!function(){"use strict";var o=function(t){var n=t,e=function(){return n};return{get:e,set:function(t){n=t},clone:function(){return o(e())}}},t=tinymce.util.Tools.resolve("tinymce.PluginManager"),i=function(t){return{isContextMenuVisible:function(){return t.get()}}},r=function(t){return t.settings.contextmenu_never_use_native},u=function(t){return t.getParam("contextmenu","link openlink image inserttable | cell row column deletetable")},l=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),s=function(t){return l.DOM.select(t.settings.ui_container)[0]},a=function(t,n){return{x:t,y:n}},f=function(t,n,e){return a(t.x+n,t.y+e)},m=function(t,n){if(t&&"static"!==l.DOM.getStyle(t,"position",!0)){var e=l.DOM.getPos(t),o=e.x-t.scrollLeft,i=e.y-t.scrollTop;return f(n,-o,-i)}return f(n,0,0)},c=function(t,n){if(t.inline)return m(s(t),a((u=n).pageX,u.pageY));var e,o,i,r,u,c=(e=t.getContentAreaContainer(),o=a((r=n).clientX,r.clientY),i=l.DOM.getPos(e),f(o,i.x,i.y));return m(s(t),c)},g=tinymce.util.Tools.resolve("tinymce.ui.Factory"),v=tinymce.util.Tools.resolve("tinymce.util.Tools"),y=function(t,n,e,o){null===o.get()?o.set(function(e,n){var t,o,i=[];o=u(e),v.each(o.split(/[ ,]/),function(t){var n=e.menuItems[t];"|"===t&&(n={text:t}),n&&(n.shortcut="",i.push(n))});for(var r=0;r<i.length;r++)"|"===i[r].text&&(0!==r&&r!==i.length-1||i.splice(r,1));return(t=g.create("menu",{items:i,context:"contextmenu",classes:"contextmenu"})).uiContainer=s(e),t.renderTo(s(e)),t.on("hide",function(t){t.control===this&&n.set(!1)}),e.on("remove",function(){t.remove(),t=null}),t}(t,e)):o.get().show(),o.get().moveTo(n.x,n.y),e.set(!0)},x=function(e,o,i){e.on("contextmenu",function(t){var n;n=e,(!t.ctrlKey||r(n))&&(t.preventDefault(),y(e,c(e,t),o,i))})};t.add("contextmenu",function(t){var n=o(null),e=o(!1);return x(t,e,n),i(e)})}(); \ No newline at end of file diff --git a/lib/web/tiny_mce_4/plugins/directionality/plugin.min.js b/lib/web/tiny_mce_4/plugins/directionality/plugin.min.js index 226c641aa953..bb48bcf94177 100755 --- a/lib/web/tiny_mce_4/plugins/directionality/plugin.min.js +++ b/lib/web/tiny_mce_4/plugins/directionality/plugin.min.js @@ -1 +1 @@ -!function(){var a={},b=function(b){for(var c=a[b],e=c.deps,f=c.defn,g=e.length,h=new Array(g),i=0;i<g;++i)h[i]=d(e[i]);var j=f.apply(null,h);if(void 0===j)throw"module ["+b+"] returned undefined";c.instance=j},c=function(b,c,d){if("string"!=typeof b)throw"module id must be a string";if(void 0===c)throw"no dependencies for "+b;if(void 0===d)throw"no definition function for "+b;a[b]={deps:c,defn:d,instance:void 0}},d=function(c){var d=a[c];if(void 0===d)throw"module ["+c+"] was undefined";return void 0===d.instance&&b(c),d.instance},e=function(a,b){for(var c=a.length,e=new Array(c),f=0;f<c;++f)e.push(d(a[f]));b.apply(null,b)},f={};f.bolt={module:{api:{define:c,require:e,demand:d}}};var g=c,h=function(a,b){g(a,[],function(){return b})};h("3",tinymce.util.Tools.resolve),g("1",["3"],function(a){return a("tinymce.PluginManager")}),g("2",["3"],function(a){return a("tinymce.util.Tools")}),g("0",["1","2"],function(a,b){return a.add("directionality",function(a){function c(c){var d,e=a.dom,f=a.selection.getSelectedBlocks();f.length&&(d=e.getAttrib(f[0],"dir"),b.each(f,function(a){e.getParent(a.parentNode,"*[dir='"+c+"']",e.getRoot())||(d!=c?e.setAttrib(a,"dir",c):e.setAttrib(a,"dir",null))}),a.nodeChanged())}function d(a){var c=[];return b.each("h1 h2 h3 h4 h5 h6 div p".split(" "),function(b){c.push(b+"[dir="+a+"]")}),c.join(",")}a.addCommand("mceDirectionLTR",function(){c("ltr")}),a.addCommand("mceDirectionRTL",function(){c("rtl")}),a.addButton("ltr",{title:"Left to right",cmd:"mceDirectionLTR",stateSelector:d("ltr")}),a.addButton("rtl",{title:"Right to left",cmd:"mceDirectionRTL",stateSelector:d("rtl")})}),function(){}}),d("0")()}(); \ No newline at end of file +!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager"),c=tinymce.util.Tools.resolve("tinymce.util.Tools"),e=function(t,e){var i,n=t.dom,o=t.selection.getSelectedBlocks();o.length&&(i=n.getAttrib(o[0],"dir"),c.each(o,function(t){n.getParent(t.parentNode,'*[dir="'+e+'"]',n.getRoot())||n.setAttrib(t,"dir",i!==e?e:null)}),t.nodeChanged())},i=function(t){t.addCommand("mceDirectionLTR",function(){e(t,"ltr")}),t.addCommand("mceDirectionRTL",function(){e(t,"rtl")})},n=function(e){var i=[];return c.each("h1 h2 h3 h4 h5 h6 div p".split(" "),function(t){i.push(t+"[dir="+e+"]")}),i.join(",")},o=function(t){t.addButton("ltr",{title:"Left to right",cmd:"mceDirectionLTR",stateSelector:n("ltr")}),t.addButton("rtl",{title:"Right to left",cmd:"mceDirectionRTL",stateSelector:n("rtl")})};t.add("directionality",function(t){i(t),o(t)})}(); \ No newline at end of file diff --git a/lib/web/tiny_mce_4/plugins/emoticons/plugin.min.js b/lib/web/tiny_mce_4/plugins/emoticons/plugin.min.js index e29c829e7781..4e3cd251ab20 100755 --- a/lib/web/tiny_mce_4/plugins/emoticons/plugin.min.js +++ b/lib/web/tiny_mce_4/plugins/emoticons/plugin.min.js @@ -1 +1 @@ -!function(){var a={},b=function(b){for(var c=a[b],e=c.deps,f=c.defn,g=e.length,h=new Array(g),i=0;i<g;++i)h[i]=d(e[i]);var j=f.apply(null,h);if(void 0===j)throw"module ["+b+"] returned undefined";c.instance=j},c=function(b,c,d){if("string"!=typeof b)throw"module id must be a string";if(void 0===c)throw"no dependencies for "+b;if(void 0===d)throw"no definition function for "+b;a[b]={deps:c,defn:d,instance:void 0}},d=function(c){var d=a[c];if(void 0===d)throw"module ["+c+"] was undefined";return void 0===d.instance&&b(c),d.instance},e=function(a,b){for(var c=a.length,e=new Array(c),f=0;f<c;++f)e.push(d(a[f]));b.apply(null,b)},f={};f.bolt={module:{api:{define:c,require:e,demand:d}}};var g=c,h=function(a,b){g(a,[],function(){return b})};h("3",tinymce.util.Tools.resolve),g("1",["3"],function(a){return a("tinymce.PluginManager")}),g("2",["3"],function(a){return a("tinymce.util.Tools")}),g("0",["1","2"],function(a,b){return a.add("emoticons",function(a,c){function d(){var a;return a='<table role="list" class="mce-grid">',b.each(e,function(d){a+="<tr>",b.each(d,function(b){var d=c+"/img/smiley-"+b+".gif";a+='<td><a href="#" data-mce-url="'+d+'" data-mce-alt="'+b+'" tabindex="-1" role="option" aria-label="'+b+'"><img src="'+d+'" style="width: 18px; height: 18px" role="presentation" /></a></td>'}),a+="</tr>"}),a+="</table>"}var e=[["cool","cry","embarassed","foot-in-mouth"],["frown","innocent","kiss","laughing"],["money-mouth","sealed","smile","surprised"],["tongue-out","undecided","wink","yell"]];a.addButton("emoticons",{type:"panelbutton",panel:{role:"application",autohide:!0,html:d,onclick:function(b){var c=a.dom.getParent(b.target,"a");c&&(a.insertContent('<img src="'+c.getAttribute("data-mce-url")+'" alt="'+c.getAttribute("data-mce-alt")+'" />'),this.hide())}},tooltip:"Emoticons"})}),function(){}}),d("0")()}(); \ No newline at end of file +!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager"),e=tinymce.util.Tools.resolve("tinymce.util.Tools"),n=[["cool","cry","embarassed","foot-in-mouth"],["frown","innocent","kiss","laughing"],["money-mouth","sealed","smile","surprised"],["tongue-out","undecided","wink","yell"]],i=function(i){var o;return o='<table role="list" class="mce-grid">',e.each(n,function(t){o+="<tr>",e.each(t,function(t){var e=i+"/img/smiley-"+t+".gif";o+='<td><a href="#" data-mce-url="'+e+'" data-mce-alt="'+t+'" tabindex="-1" role="option" aria-label="'+t+'"><img src="'+e+'" style="width: 18px; height: 18px" role="presentation" /></a></td>'}),o+="</tr>"}),o+="</table>"},o=function(a,t){var e=i(t);a.addButton("emoticons",{type:"panelbutton",panel:{role:"application",autohide:!0,html:e,onclick:function(t){var e,i,o,n=a.dom.getParent(t.target,"a");n&&(e=a,i=n.getAttribute("data-mce-url"),o=n.getAttribute("data-mce-alt"),e.insertContent(e.dom.createHTML("img",{src:i,alt:o})),this.hide())}},tooltip:"Emoticons"})};t.add("emoticons",function(t,e){o(t,e)})}(); \ No newline at end of file diff --git a/lib/web/tiny_mce_4/plugins/fullpage/plugin.min.js b/lib/web/tiny_mce_4/plugins/fullpage/plugin.min.js index 6aa103dd6709..de5221a8e0b0 100755 --- a/lib/web/tiny_mce_4/plugins/fullpage/plugin.min.js +++ b/lib/web/tiny_mce_4/plugins/fullpage/plugin.min.js @@ -1 +1 @@ -!function(){var a={},b=function(b){for(var c=a[b],e=c.deps,f=c.defn,g=e.length,h=new Array(g),i=0;i<g;++i)h[i]=d(e[i]);var j=f.apply(null,h);if(void 0===j)throw"module ["+b+"] returned undefined";c.instance=j},c=function(b,c,d){if("string"!=typeof b)throw"module id must be a string";if(void 0===c)throw"no dependencies for "+b;if(void 0===d)throw"no definition function for "+b;a[b]={deps:c,defn:d,instance:void 0}},d=function(c){var d=a[c];if(void 0===d)throw"module ["+c+"] was undefined";return void 0===d.instance&&b(c),d.instance},e=function(a,b){for(var c=a.length,e=new Array(c),f=0;f<c;++f)e.push(d(a[f]));b.apply(null,b)},f={};f.bolt={module:{api:{define:c,require:e,demand:d}}};var g=c,h=function(a,b){g(a,[],function(){return b})};h("7",tinymce.util.Tools.resolve),g("1",["7"],function(a){return a("tinymce.html.DomParser")}),g("2",["7"],function(a){return a("tinymce.html.Node")}),g("3",["7"],function(a){return a("tinymce.html.Serializer")}),g("4",["7"],function(a){return a("tinymce.PluginManager")}),g("5",["7"],function(a){return a("tinymce.util.Tools")}),g("6",["5"],function(a){var b=function(b,c){return a.each(b,function(a){c=c.replace(a,function(a){return"<!--mce:protected "+escape(a)+"-->"})}),c},c=function(a){return a.replace(/<!--mce:protected ([\s\S]*?)-->/g,function(a,b){return unescape(b)})};return{protectHtml:b,unprotectHtml:c}}),g("0",["1","2","3","4","5","6"],function(a,b,c,d,e,f){return d.add("fullpage",function(d){function g(){var a=h();d.windowManager.open({title:"Document properties",data:a,defaults:{type:"textbox",size:40},body:[{name:"title",label:"Title"},{name:"keywords",label:"Keywords"},{name:"description",label:"Description"},{name:"robots",label:"Robots"},{name:"author",label:"Author"},{name:"docencoding",label:"Encoding"}],onSubmit:function(b){i(e.extend(a,b.data))}})}function h(){function a(a,b){var c=a.attr(b);return c||""}var b,c,f=j(),g={};return g.fontface=d.getParam("fullpage_default_fontface",""),g.fontsize=d.getParam("fullpage_default_fontsize",""),b=f.firstChild,7==b.type&&(g.xml_pi=!0,c=/encoding="([^"]+)"/.exec(b.value),c&&(g.docencoding=c[1])),b=f.getAll("#doctype")[0],b&&(g.doctype="<!DOCTYPE"+b.value+">"),b=f.getAll("title")[0],b&&b.firstChild&&(g.title=b.firstChild.value),p(f.getAll("meta"),function(a){var b,c=a.attr("name"),d=a.attr("http-equiv");c?g[c.toLowerCase()]=a.attr("content"):"Content-Type"==d&&(b=/charset\s*=\s*(.*)\s*/gi.exec(a.attr("content")),b&&(g.docencoding=b[1]))}),b=f.getAll("html")[0],b&&(g.langcode=a(b,"lang")||a(b,"xml:lang")),g.stylesheets=[],e.each(f.getAll("link"),function(a){"stylesheet"==a.attr("rel")&&g.stylesheets.push(a.attr("href"))}),b=f.getAll("body")[0],b&&(g.langdir=a(b,"dir"),g.style=a(b,"style"),g.visited_color=a(b,"vlink"),g.link_color=a(b,"link"),g.active_color=a(b,"alink")),g}function i(a){function f(a,b,c){a.attr(b,c?c:void 0)}function g(a){i.firstChild?i.insert(a,i.firstChild):i.append(a)}var h,i,k,l,m,o=d.dom;h=j(),i=h.getAll("head")[0],i||(l=h.getAll("html")[0],i=new b("head",1),l.firstChild?l.insert(i,l.firstChild,!0):l.append(i)),l=h.firstChild,a.xml_pi?(m='version="1.0"',a.docencoding&&(m+=' encoding="'+a.docencoding+'"'),7!=l.type&&(l=new b("xml",7),h.insert(l,h.firstChild,!0)),l.value=m):l&&7==l.type&&l.remove(),l=h.getAll("#doctype")[0],a.doctype?(l||(l=new b("#doctype",10),a.xml_pi?h.insert(l,h.firstChild):g(l)),l.value=a.doctype.substring(9,a.doctype.length-1)):l&&l.remove(),l=null,p(h.getAll("meta"),function(a){"Content-Type"==a.attr("http-equiv")&&(l=a)}),a.docencoding?(l||(l=new b("meta",1),l.attr("http-equiv","Content-Type"),l.shortEnded=!0,g(l)),l.attr("content","text/html; charset="+a.docencoding)):l&&l.remove(),l=h.getAll("title")[0],a.title?(l?l.empty():(l=new b("title",1),g(l)),l.append(new b("#text",3)).value=a.title):l&&l.remove(),p("keywords,description,author,copyright,robots".split(","),function(c){var d,e,f=h.getAll("meta"),i=a[c];for(d=0;d<f.length;d++)if(e=f[d],e.attr("name")==c)return void(i?e.attr("content",i):e.remove());i&&(l=new b("meta",1),l.attr("name",c),l.attr("content",i),l.shortEnded=!0,g(l))});var q={};e.each(h.getAll("link"),function(a){"stylesheet"==a.attr("rel")&&(q[a.attr("href")]=a)}),e.each(a.stylesheets,function(a){q[a]||(l=new b("link",1),l.attr({rel:"stylesheet",text:"text/css",href:a}),l.shortEnded=!0,g(l)),delete q[a]}),e.each(q,function(a){a.remove()}),l=h.getAll("body")[0],l&&(f(l,"dir",a.langdir),f(l,"style",a.style),f(l,"vlink",a.visited_color),f(l,"link",a.link_color),f(l,"alink",a.active_color),o.setAttribs(d.getBody(),{style:a.style,dir:a.dir,vLink:a.visited_color,link:a.link_color,aLink:a.active_color})),l=h.getAll("html")[0],l&&(f(l,"lang",a.langcode),f(l,"xml:lang",a.langcode)),i.firstChild||i.remove(),k=new c({validate:!1,indent:!0,apply_source_formatting:!0,indent_before:"head,html,body,meta,title,script,link,style",indent_after:"head,html,body,meta,title,script,link,style"}).serialize(h),n=k.substring(0,k.indexOf("</body>"))}function j(){return new a({validate:!1,root_name:"#document"}).parse(n)}function k(a){function b(a){return a.replace(/<\/?[A-Z]+/g,function(a){return a.toLowerCase()})}var c,g,h,i,k,m="",q=d.dom;if(!(a.selection||(h=f.protectHtml(d.settings.protect,a.content),"raw"==a.format&&n||a.source_view&&d.getParam("fullpage_hide_in_source_view")))){0!==h.length||a.source_view||(h=e.trim(n)+"\n"+e.trim(h)+"\n"+e.trim(o)),h=h.replace(/<(\/?)BODY/gi,"<$1body"),c=h.indexOf("<body"),c!=-1?(c=h.indexOf(">",c),n=b(h.substring(0,c+1)),g=h.indexOf("</body",c),g==-1&&(g=h.length),a.content=e.trim(h.substring(c+1,g)),o=b(h.substring(g))):(n=l(),o="\n</body>\n</html>"),i=j(),p(i.getAll("style"),function(a){a.firstChild&&(m+=a.firstChild.value)}),k=i.getAll("body")[0],k&&q.setAttribs(d.getBody(),{style:k.attr("style")||"",dir:k.attr("dir")||"",vLink:k.attr("vlink")||"",link:k.attr("link")||"",aLink:k.attr("alink")||""}),q.remove("fullpage_styles");var r=d.getDoc().getElementsByTagName("head")[0];m&&(q.add(r,"style",{id:"fullpage_styles"},m),k=q.get("fullpage_styles"),k.styleSheet&&(k.styleSheet.cssText=m));var s={};e.each(r.getElementsByTagName("link"),function(a){"stylesheet"==a.rel&&a.getAttribute("data-mce-fullpage")&&(s[a.href]=a)}),e.each(i.getAll("link"),function(a){var b=a.attr("href");return!b||(s[b]||"stylesheet"!=a.attr("rel")||q.add(r,"link",{rel:"stylesheet",text:"text/css",href:b,"data-mce-fullpage":"1"}),void delete s[b])}),e.each(s,function(a){a.parentNode.removeChild(a)})}}function l(){var a,b="",c="";return d.getParam("fullpage_default_xml_pi")&&(b+='<?xml version="1.0" encoding="'+d.getParam("fullpage_default_encoding","ISO-8859-1")+'" ?>\n'),b+=d.getParam("fullpage_default_doctype","<!DOCTYPE html>"),b+="\n<html>\n<head>\n",(a=d.getParam("fullpage_default_title"))&&(b+="<title>"+a+"\n"),(a=d.getParam("fullpage_default_encoding"))&&(b+='\n'),(a=d.getParam("fullpage_default_font_family"))&&(c+="font-family: "+a+";"),(a=d.getParam("fullpage_default_font_size"))&&(c+="font-size: "+a+";"),(a=d.getParam("fullpage_default_text_color"))&&(c+="color: "+a+";"),b+="\n\n"}function m(a){a.selection||a.source_view&&d.getParam("fullpage_hide_in_source_view")||(a.content=f.unprotectHtml(e.trim(n)+"\n"+e.trim(a.content)+"\n"+e.trim(o)))}var n,o,p=e.each;d.addCommand("mceFullPageProperties",g),d.addButton("fullpage",{title:"Document properties",cmd:"mceFullPageProperties"}),d.addMenuItem("fullpage",{text:"Document properties",cmd:"mceFullPageProperties",context:"file"}),d.on("BeforeSetContent",k),d.on("GetContent",m)}),function(){}}),d("0")()}(); \ No newline at end of file +!function(){"use strict";var l=function(e){var t=e,n=function(){return t};return{get:n,set:function(e){t=e},clone:function(){return l(n())}}},e=tinymce.util.Tools.resolve("tinymce.PluginManager"),g=tinymce.util.Tools.resolve("tinymce.util.Tools"),t=tinymce.util.Tools.resolve("tinymce.html.DomParser"),f=tinymce.util.Tools.resolve("tinymce.html.Node"),m=tinymce.util.Tools.resolve("tinymce.html.Serializer"),h=function(e){return e.getParam("fullpage_hide_in_source_view")},r=function(e){return e.getParam("fullpage_default_xml_pi")},o=function(e){return e.getParam("fullpage_default_encoding")},a=function(e){return e.getParam("fullpage_default_font_family")},c=function(e){return e.getParam("fullpage_default_font_size")},s=function(e){return e.getParam("fullpage_default_text_color")},u=function(e){return e.getParam("fullpage_default_title")},d=function(e){return e.getParam("fullpage_default_doctype","")},p=function(e){return t({validate:!1,root_name:"#document"}).parse(e)},y=p,v=function(e,t){var n,l,i=p(t),r={};function o(e,t){return e.attr(t)||""}return r.fontface=a(e),r.fontsize=c(e),7===(n=i.firstChild).type&&(r.xml_pi=!0,(l=/encoding="([^"]+)"/.exec(n.value))&&(r.docencoding=l[1])),(n=i.getAll("#doctype")[0])&&(r.doctype=""),(n=i.getAll("title")[0])&&n.firstChild&&(r.title=n.firstChild.value),g.each(i.getAll("meta"),function(e){var t,n=e.attr("name"),l=e.attr("http-equiv");n?r[n.toLowerCase()]=e.attr("content"):"Content-Type"===l&&(t=/charset\s*=\s*(.*)\s*/gi.exec(e.attr("content")))&&(r.docencoding=t[1])}),(n=i.getAll("html")[0])&&(r.langcode=o(n,"lang")||o(n,"xml:lang")),r.stylesheets=[],g.each(i.getAll("link"),function(e){"stylesheet"===e.attr("rel")&&r.stylesheets.push(e.attr("href"))}),(n=i.getAll("body")[0])&&(r.langdir=o(n,"dir"),r.style=o(n,"style"),r.visited_color=o(n,"vlink"),r.link_color=o(n,"link"),r.active_color=o(n,"alink")),r},_=function(e,r,t){var o,n,l,a,i,c=e.dom;function s(e,t,n){e.attr(t,n||undefined)}function u(e){n.firstChild?n.insert(e,n.firstChild):n.append(e)}o=p(t),(n=o.getAll("head")[0])||(a=o.getAll("html")[0],n=new f("head",1),a.firstChild?a.insert(n,a.firstChild,!0):a.append(n)),a=o.firstChild,r.xml_pi?(i='version="1.0"',r.docencoding&&(i+=' encoding="'+r.docencoding+'"'),7!==a.type&&(a=new f("xml",7),o.insert(a,o.firstChild,!0)),a.value=i):a&&7===a.type&&a.remove(),a=o.getAll("#doctype")[0],r.doctype?(a||(a=new f("#doctype",10),r.xml_pi?o.insert(a,o.firstChild):u(a)),a.value=r.doctype.substring(9,r.doctype.length-1)):a&&a.remove(),a=null,g.each(o.getAll("meta"),function(e){"Content-Type"===e.attr("http-equiv")&&(a=e)}),r.docencoding?(a||((a=new f("meta",1)).attr("http-equiv","Content-Type"),a.shortEnded=!0,u(a)),a.attr("content","text/html; charset="+r.docencoding)):a&&a.remove(),a=o.getAll("title")[0],r.title?(a?a.empty():u(a=new f("title",1)),a.append(new f("#text",3)).value=r.title):a&&a.remove(),g.each("keywords,description,author,copyright,robots".split(","),function(e){var t,n,l=o.getAll("meta"),i=r[e];for(t=0;t"))},n=function(n,l){var i=v(n,l.get());n.windowManager.open({title:"Document properties",data:i,defaults:{type:"textbox",size:40},body:[{name:"title",label:"Title"},{name:"keywords",label:"Keywords"},{name:"description",label:"Description"},{name:"robots",label:"Robots"},{name:"author",label:"Author"},{name:"docencoding",label:"Encoding"}],onSubmit:function(e){var t=_(n,g.extend(i,e.data),l.get());l.set(t)}})},i=function(e,t){e.addCommand("mceFullPageProperties",function(){n(e,t)})},b=function(e,t){return g.each(e,function(e){t=t.replace(e,function(e){return"\x3c!--mce:protected "+escape(e)+"--\x3e"})}),t},x=function(e){return e.replace(//g,function(e,t){return unescape(t)})},k=g.each,C=function(e){return e.replace(/<\/?[A-Z]+/g,function(e){return e.toLowerCase()})},A=function(e){var t,n="",l="";if(r(e)){var i=o(e);n+='\n'}return n+=d(e),n+="\n\n\n",(t=u(e))&&(n+=""+t+"\n"),(t=o(e))&&(n+='\n'),(t=a(e))&&(l+="font-family: "+t+";"),(t=c(e))&&(l+="font-size: "+t+";"),(t=s(e))&&(l+="color: "+t+";"),n+="\n\n"},w=function(r,o,a){r.on("BeforeSetContent",function(e){!function(e,t,n,l){var i,r,o,a,c,s="",u=e.dom;if(!(l.selection||(o=b(e.settings.protect,l.content),"raw"===l.format&&t.get()||l.source_view&&h(e)))){0!==o.length||l.source_view||(o=g.trim(t.get())+"\n"+g.trim(o)+"\n"+g.trim(n.get())),-1!==(i=(o=o.replace(/<(\/?)BODY/gi,"<$1body")).indexOf("",i),t.set(C(o.substring(0,i+1))),-1===(r=o.indexOf("\n")),a=y(t.get()),k(a.getAll("style"),function(e){e.firstChild&&(s+=e.firstChild.value)}),(c=a.getAll("body")[0])&&u.setAttribs(e.getBody(),{style:c.attr("style")||"",dir:c.attr("dir")||"",vLink:c.attr("vlink")||"",link:c.attr("link")||"",aLink:c.attr("alink")||""}),u.remove("fullpage_styles");var d=e.getDoc().getElementsByTagName("head")[0];s&&(u.add(d,"style",{id:"fullpage_styles"},s),(c=u.get("fullpage_styles")).styleSheet&&(c.styleSheet.cssText=s));var f={};g.each(d.getElementsByTagName("link"),function(e){"stylesheet"===e.rel&&e.getAttribute("data-mce-fullpage")&&(f[e.href]=e)}),g.each(a.getAll("link"),function(e){var t=e.attr("href");if(!t)return!0;f[t]||"stylesheet"!==e.attr("rel")||u.add(d,"link",{rel:"stylesheet",text:"text/css",href:t,"data-mce-fullpage":"1"}),delete f[t]}),g.each(f,function(e){e.parentNode.removeChild(e)})}}(r,o,a,e)}),r.on("GetContent",function(e){var t,n,l,i;t=r,n=o.get(),l=a.get(),(i=e).selection||i.source_view&&h(t)||(i.content=x(g.trim(n)+"\n"+g.trim(i.content)+"\n"+g.trim(l)))})},P=function(e){e.addButton("fullpage",{title:"Document properties",cmd:"mceFullPageProperties"}),e.addMenuItem("fullpage",{text:"Document properties",cmd:"mceFullPageProperties",context:"file"})};e.add("fullpage",function(e){var t=l(""),n=l("");i(e,t),P(e),w(e,t,n)})}(); \ No newline at end of file diff --git a/lib/web/tiny_mce_4/plugins/fullscreen/plugin.min.js b/lib/web/tiny_mce_4/plugins/fullscreen/plugin.min.js index 3db217657291..259afc9a5b83 100755 --- a/lib/web/tiny_mce_4/plugins/fullscreen/plugin.min.js +++ b/lib/web/tiny_mce_4/plugins/fullscreen/plugin.min.js @@ -1 +1 @@ -!function(){var a={},b=function(b){for(var c=a[b],e=c.deps,f=c.defn,g=e.length,h=new Array(g),i=0;i*?%_#SM)QlQv9ofJF*6DwEO@qGX zfPA~xoSA+MDd8U>mB)i?C}WSyrkY{{Nc16D27Qnk~^dQWsz>25;EhfTcOh06VW~fcfjIGO%i?mTJjd9j~$P z*-{0Y0(CL&U3!xbuuxfE<3`-0j~7>3HDJk&PJ4|5J{fq`fK^MiGzGA#Z%jQ`uF&TC zM%)=?)@~a5=E&&!F83TB^B$z$*J(DXWo!it5AAMkBH8TevrE ze&%tk<9N7;(EwVp%qPsqF~l0Md{<#z&)Q$)vRhcgy5YcqRZF#0OUI(DY&TFY-)09^ zWAzQ0H*)XME!mSe*2OnGT1I?_K?`?>?fyblM+&q`0M=U*#}|8+Ic4tHq#$dT@J;+E zR3ogx6fK$aBQ;FI*VtM##uk02IA^TYtdD#!#=^0>Z6EsMueuvp7fnB3fZ9@kRmKNa zQUz})7^l>P24@C$@%+?dWPrDM%`C=e#(73%KXW)ki!m}6C@03rc==o7`nLg5Pn-P;)Lk|if3eE)ck zVZ)j1I)8JWTXT7^aVCMm6W-=~ixrA5*_{M~>hc->jo zxbDISvVAlDazj!Mp6a6ABG)+t>`!!g(t>j#EdPS36UfhOQUE?51~ezm{}h$tyG(Tz^(1nt6>vO1`9iw0p74pLG0-j(5EI&*>xJ?jhW&vD-%NM!vp+PjCREnJ<8a7?WBPi=9&D+{{rp4Hwx z@}c(b{7>4t^Vha@5C642IdY|rKT!D(wXNR#5Z5p<^02CK=elFf=BKqKhv%xkUnyTl zeacsW^H}=+&;PR8;?2t;yVr)Yg3EU$k`%UqjoveznejqrNn@ zb&b4k(aIq&47^I(H$~|_|JUpNliR!U&u;4(`MlcuDQ&9{e^L8av?p^v@6h$u?)-BS zt8YKmZJ&A$IX7@xL*@mA9l-w3npF{4g`w4idq_Z~DXl?V%FhR-4rypv-+1kaAWuOz z$5>EOMD}yk-@A0(0!PP`@A0CAdt_W=UAs@`gI;6$5mxoIIjc_bYBGw@A4zw0c;mSKV>l8$jiGm)z*1_`GH(>l#p1neCeUe*m`dXB}2I zDtjfWnz8VsL(H9(Kj4juSgMuf1?9rr%um0B>mU1N;XBjXo%^(mX0!6`GNK_J-^}&a zRrg#ZuzXK{4_&c-yMJYRx1UJu@~^b4zpq%o!`Jze#yT+kT6_5x!~{*@~G zALUVd-s($OeH&Dt`qG{pPPBIAp6!g9;W_%L-h_Q`_{IN!~MHs%_iEv zL*+XKlb00%anTe8U2AIVMVi|N)xBPD8cR&lhs1`Rv_GyNh7IaN)1q}lp4*2*CW1W@ z+wejb*h^DZ#i2C~_mD4s(|(|J2=9uS0zqL2+<9WnfC6(ucGmMIlzlRAckfdkfB-gA zIJQez7fWBy4k1~}^LpU3KVVId_C8q8?*{t3#>2W<;XTH6j~DdTt6zn-0H= z{4?9S@?TY*o36_2@fWS#O8voDwp-iQKKE%`_c!~L*E#u5Qaw*_)nd8stibbeHnyo|GL@vLTm??t+V6gcyVCnv#-Q!4k0qJJlON~uya)9+QfR#>plfRl{@L=v{ ztL{984sbMYZPN=I8$*#xsXILi6oD2hOp0iQ>bnA!q+^$kIqMJLWA_#q>3r2}!Pwez z$NXTqsH*=~#z&T-ybG7qfloPUZycWL`o34_^LF~9dOywe7pQ$xEi#B`pp?dBEPHT` zPy*L(oZ#9xhNj~V-RlipxJ9@z%2`2Wg8MuNkT5d2JD2V?FyB7`_wl*`-={8RV8HoS zJ)3On&Rwf#7fE&e4Fx1P7}WN(>-^e{zTetC{99MK6;qW4HMzG>QynP)3>+DopkQ@x zW_)UUvButxn$zFQQC6M3TdaSyJAO_7IOp3m?oXGhbPOuLTYmS2s{dMprRo?3j0x*Q zS8koIEf$nIIcgr(a$Ws2r8UZPS7*n3T=B%ZtruGT2h9zPG-O`{tQ6s{rVwUN*blopZy0#maWO?`x2QC5xwxfj(MQcLzcS7E7aA9Fw^aCA~&HKZS;b~YE(8*Qa~2|5h`#5LOfGrP8|Ik`sk zWX(OmtDm2FkNUgx?OQ=hc&K_%dy9vkrZ z(J~c^tI0Z+0n5~aR7gB9(h0z$;}$`t@N1t0V8h>UOO8CA^%u99->w`wQ-FD%?q35-= z1#^&E)H6JtvTSfXz;2+yDzs)5O})7YtjdNKZjonkTB@I85ojIqNn`k%?GiGsSuHFe z7oF>pBi&tK0Yktf$c?Hk0BNq?4i?l)1+ZY%TzE;HXEO$^-|SCmd(rjJ=7$Ak7r3>{ ztZyi$a=%}=nSf6a-xHBi)ZagFfo4W0!-}DdPyo0is0%3#j`_Bp;a8N>B#X$nP^c&j zQ=qw3i^pH5E@gnhwL3etpj=XY-6NOs4D|)|`W@XvFPuzam;nn&uSQJ;00mk)=B{r| z4!^aW@7coS@H0_e%nQ&&ZQ&jZz~6Is68F~!HZL@f{gfB*cA%Ejulw4&hCf>B0zN7Z zxN7V}f!f-x`Z#V_nA~!{t&u%IZXiaH60B0&z5h{GWx%RTr6mKr%bE;rKVW`a7~ zyKjp+!VIurg?|+jTf7EoVNCy)+Gb89boMuRDm#ySuHo8 zVxLpFYn8-xv7ThRi+~Gv-Rg69NC`in9N!V#UR!sfOd0<->>5CYOI!F471`H?!5#({ zkO>y3cenL!dQv$C!QwhcJ^Mji7#8Dg(O8Nt-_d>FL(5q(wsOR41%2Bsl?7D4XMMNG z@WPr={$l|scVpOq;@b5i=NKrg-bw>kHJ-o!=?33tQ{b;R`;2LE7_f|y5D(U!v|&JB zxBk9+=*b4mO8Q{WwfAg(DvSS8uDI*K^S+LCJ7-Rv8)(WZZpzBsz`mkxVD**O#>Zml z`=E7w5v6r>0?QOuunV{w!x!lHs;f$OKUqUUHCde&)EnM06r_GcIaC&~>&)@d29!nYPN9SVJ;3Fo`QyG#QA9 z?Lsjr7k1a2z5x^qd}V=KpadjiKv!#4FFz1ig+nubFLzUIWCg;T$#Qi!vT*M9Ly-Co zyNbBKs4Fd;&vAiPVY2#x<~)NkDws`xDRTo^v*1_Nlof7<8@k{cX)#&_V5JwhhI6FyN#16EOw(X1R~lEE~Ns-TpeJd=T~B|1ywXE!_9xCT=&KLmRNG% z8B!`4E#%uqz#X04_g>7sAN{oeVQmb&E!b7uLwkfO6zPB2$?8~evwzBhB_rpsJGwyX zZNZY8PvM>ghDr_IN*{qWaBEEwcUJ`Z<<3P`bD_n2>L+GS^Lz`zz14?RL*`{6H*j2A z^lz!Y8(5Be*!TFleQ{c&f)?;U$Y7^Y`B!Z7j`KV#elVEufg+6Zi~Z}7&dW5)I)tN zSZfFIgRWXBCAo{qC^Q!HgWbZ-sGa{+9{Dx_*LD;q*i8(#R~2X#QDB<0w*V5>>@;>< zwr_C#dwRtNg>@jAHh^O=)~^L~I~u6iH&Hv(eM|M-z{)}%2z&%uC@nxh zT$2l}qZU}iVX-sV%$#JFy1R~*zjAcfX#(L!+NU4Hlo500ma%b2)qOBfSGx<5`RSk7 zcZ*zPvHjB)%HV}V8A2%(hXtqzY{ZrMXjzIV48X43&jSFCv4({)n`=}FAOK)cA9-hc zPwuI9Z}Gs;nF?DN#CXZ@eCc-@Y|8USSHLIRQ9ZlS5CL3R55+ zPW9W4Wi{MFKcuWOJ25VE1BtUL!wo#P@=V<&Kd4+EtYiKQ=fp>^~EE8_sW3m z!{orq#S1PRfWe)~zpD~pnel3U=Q}}t6D$%d9_v-6h$;aVFDCB;R(`ht_>8?UTb+L_ zfv%`8+SI*780=G&!chG?YLfA?@ZP$5=v}E$JxY^!?+BVWQRHW*KelE+v&CJi6n#UnREI`mS%c-#_Bt_s;la1rO@bRAUCA+ zM*opO3n#4;r?nGS;e*y>1uS*AUsDOd;(sppxy=EryQvys_t;HP_nq|0w*KIZ(`Q#` zHhz`+!eUC1P=*MAwNU~z^FJyBuwWa<8DIe<1fP}zSi<e^o`86;C(U z46K=!{(e+5u#!&(`ikn)l5t`l4&=&7?AAdpXiYA_${1j2%vAY+rM{_o23X_{zT}Wq z1AyfNP;LF<4+_BTfGu&&GM>3!pI+bTS$l;tO!q?>ikpO*4+vo4wEl4!fCbyAC}1^p z6bCGE=zkqkkSKj(u!P+mI$HU5cK;|_BW)?>G(bY&E$KXjH}G2N#wsZH6~KaBmIYQa zk-kLi4im~M3lO>x*$iaz=+e44=3At-$`7!a_feXhuUY&gNtxJJQd`UVj0##L-7=wG zIsjTdhgJ%-VuodawX!(F@*Xk*SU0O#N|gLAobN8EF=i()c(a8vV0yZt3=+6U#WoI-6tP;VBWowdL-Oz=a8OE$;4GUJz#G_)s z2g$NWG=U#1ra_d(1Y`f&BeMh2UpBrdpvCgN#c2ru0$MnHebAZ|3~S^8D1y$ zNFNp*w4%w3#ekJA4p_FbIJN7A@;_M1{(8*4l;3fMNGKESI_Qb0cS9MX0v36H)c{!T zB)xdv!>^Ukv(&iKz|lM0K1S<7O8FP=p*r0+P_1G7DY@uBs8$kU2`+TaKsU~c3)}Y+ zE0q0B|3v!wsjT$;nD>#|f2GO(a{gapR=PK~1kidA5LD12;`+$pKns8`|$ zTobo><^RfO8g6ii#Ybrn>#r@?)RL;%x75b@=%?8KFfy}ZWoAm<-k}RHtLR{*lS&)= zSJdpXF=+pcJ-T_g_}vz#g-N1;j7Jm&E$43lq;$}VO+t4(vful7Ao3s#*lu0-9J{Vi zNr*lNsxoY)%BXw%L}gf(XGa)?COvQGyj+i+Z{!04A53DWdt`>CV|UepR$GahT{6B;*aOpQsfAlg>qhDuf{aE&6u|OvJ z!dFqRswAcr1D1|W7j$}lVGoVaJj|S`{asSCS13bw@lb|{aah&DumA!#eFv5m*1_5Z zXdP|Q>E-ycEP1-6YyAfS3Q~heZWd5paS_!&opFf&>hF&xkq6~%ZsqfGfYVd`xlBt< z7kH&|X*4siKJzu9;cn=HGOOrd#eSwID910+mSG}|M58$o zTCmEaU4NC_lk=H8_*&FNS^M&7nb(%Ex)}Sgyx$2vP1%1n$7zY@C1I(e?%psraYY!) zaGDp&Fo8`%*oBQT+12-Ht4!LY5%yMP6tj(MEwQwVCLL$Hs1Hy72zH3lP`w3@+I5o@ zEkM>o04a&&`Vcs*RM29~cF!c3_YW#yu}w=Y&nLfdcxHtb-2k)dDG98c3C0ijBdX-W ziN%_NY8LgO@r#XdP?xkOz`?4YYzN?7HqFUpRf)vt)8#if9BeXzJ@)f?QT? z5|#&8j@eCK>Tw$RzMJ2mw3WQaOdK?nVG;lq_ty56@6OappIb>WVzrKQyEVJmcewMq zl}}+$azCyPnNxNX;}GUF$G?XI^}FVau3;F^N!t^GOy7T8pBErE6fxp^_H*(Fzl8}H zu0V#0J4lcf$a%}|uZ5g4qF?=#-E+{35 z*LB2W9%`zHw(fQGO~P%+ywZySt8#SpVyCh$KeDyPQy0Gl^AmO9avkx+h*1?2&@eR~0GG)P5TG(#Lb1Ep zB#d_awXiH64%~aHYy>R2cqqe!4QpV6`)V~f#swUfUXJ-D{wykgh9#D>b4VbLa&GEv zp$?63gh`xfsKVyvRR3p+U5jgW%DFFw?Gf=#1N2lJ^~bXo4_#Cc)}-n|H>&^zKxyhh z=X$w}o*C#cD}H2V^2le?EqJdAR|88PFJ*!)xmy8?wwWkvwEmF2svua!CZWf&h_&N* zTP+O#2bsvB48`hUReF_h_9z3E3tEY;{43BrWP;<*N>GuJH5sJkxhYe^|zEctkE zLMRovGGeDf`TX2H0IsS)Z&z)?Uh2u)d560PY}Cbf1YEZQdadezk|gbeNGqB-?~!*Q zdB!y*JG0-BaUB6mBw`+47}v}3yia!Kk1rxB8^%I8%xb5afV(gQb)sfqFt(C2DF91B z2)#e#wycD(JmCSWMMPJ-`;7!(vAnO0j&|?90G3SlMWH#rnDKTGEu@;s!CfUSIT*4@eG=z#!M@ttqw(_9xt1|2(V7Wr7+nFd$ow*;D16aty(;p@bAef|F zaT$Om<2nbXL4q@SgQUC^0}jq%=An$^bQqSd-0h)J?;Y?8m3(rWP=!XZ8U};u2Eb@i z@h+}`zonlWk{#<`?*mdq(E1~x2!I}d3EQ%M8Jh~q_5)}p;%b_V1j1qhVus55U%CAc z8nA~@ruwXOf@JpSs$lTs4bmZ|rr%_fbiA2_w2GO8dVQ~{>v|3)d(qdk+T_T$<3AY* zuo|QyK}YQoy@i@X?kfbox&4>CGD;;*isxa*)*ki{X-fgvu~^{j!>cNBFL)h*!Zp?& znFFxqRuHfvw2upH#V$}2CEP2PAY5WbNdy z7RG1~qe8LOPGpkg2ep$QE`SAaQG*>}OcMyOrTZzx6W=>ve^zfdW><0ZFYd zoiqz5%R6FVrkM;MoUw@TV2n8gHxmJ>(iRwQL>U9j=Z!juj`ff}I>RJCmk z02K@p(^J|Vn5}l5$|j4)lZiv~7eufFR+taG2f!R*%){|x5v&Jj!L(e^nowa4dOgUi z!>l~8>cXV4{i@EyEe0;*aZ~n0#agXdhB~w-Fj2Xb6Fwh<{-XasBJ{^Tur0p^dm`2U zYN{y6>fyH&Qml}8tz>Hb7b!oSyrchlzKK~*<%hww9R za6G_c6F;iXVx?=sTjF$7*|f+aAUI=%HQhm}*;lBfI8Qi_b|Z=kXu-hDJX|9`q5!ns z%OoCGsX5pCsW}nNz&oD>SQ)cY&`M1?WcdrnkXb#BHsZ(XzGFRpCwKLe_)mivtOEmv ze`*D5ls(Q~D|w9-@2||wjem*|i#0-}m4_TdX+ViHx28V*Vcxq{4*VYo#qBhRa;GsZ z11%qlXFvlK$ILWt4`qhv~a|` zpjAEPWqb#FX09%qV+I0NZRE6#B3Q+nQvw-nOKGa)gU8@H8xD2R3}PSTU7>DXG;xbh_`t2eOdi_#MQ&cmE0mQD?kab0;H5#@p?0f!jl86$n{bQrJ-`QG&jwn zrP-hN>_5`ui~PBcg(7juj{f&Hr#5_8#5Ui-xcBj-@fL$t_x>7Gx+^-JgIxtNZK$y$6L&_ z>H(|h=HW<#Rreg%45Ypl#rY-+SlRoT?GL_+`q+t7@B7^J4S&BDQAm*t`acO6953~v z4wdZxFOM{6l~&p%_ZBK-YIVvr2qUQINe?X!$G(6-{$~_Xqm~g8QWS&>>LsBI zw`faE)WU86A?73{aObKSN+p0|rYa3~=O53pe$E;DYVD{uQxHz;DJ?UGW#^;~Xa3r` z*pL1F^ZDgdXzq6r_NkUF1}zb1nBkd+YXGegWj2n_3WvHzuIp-G=4z@?Ocn<_0H91{ zDsoL)zBZ@^N%1=BCCzFpU>0iuxV~?)50xsZp`teqyfnRUF8My3QgGhpOIU(3;Ux zXH08kLCXcJheEJ|Sy2O=KvOBB^WJm$e*BerhDlJnsFFW=GmB=;MQ1LzoU*&<$5Ffu zAhNQ!N!7E%oDv3hm(~;C3b0v2VMbWlPO54OtNDkHc}QV`D;D-W7ZHP|PGM}F{XcAI z%YFdn;``K4G)7E;x=k{++5z)bj&EwqepWvFUQjzJ-Typa@RK5OVP(smjB6E6_z-v> zc|FHbm<~};8<)NM0G8-}=otywFFaT7`%UdZ0la6sU?lfv3d%B!b5`5>=ezgVzzcRZ zv%T+Cw2S9GEYj*#`B02OOTZ%pt!V>HYjy1bOI}}5^HBR?Dcl7sWms2mo^b(I9-v%x zX8}RVSpp*I#`eBX*$yC1FXOqeirH5TS}5;m zZrFf%2xuADRLl&l%iN+4_H7DQmk}jBUcky{BRs7El$-8FCaL$Q{(gSVBHkATGMWd7 zuny^evHE$o0wU_e+9?c+$r%Ec)FM|=%%XrLeE?XuGfCZRuyZknWGdePfY31203FOs z{VW8LR9Huy4d!KXU1*V}Ky~RE=Ho}S@lMICt>S_ZTrcwfnF#lEaP=JL=2mp2D zF7wZ0W0UU=Ws++@56BARR8(KYB>XJ(&M`w(C1sO<^LzA|4%-LfmVLe< zbfQ4^Hz+hd-M*98^fWS0l;;oU_Iih^~Ynv=G8IG0D zuM!~my(<=g??*mA7cenhJkO+LpMOc;_hMerm{`OwVP?62g}I37Xl7#*4ad7GvB*UK zl}$!heyVZ7`q#;IZ&n+-DS>Xh9=kdAh|4YC{`^qK|4D~iZR!qPgK+6BdB-l~0 z;rbLymow8+R;ae697w@ z!20Xf6bcAiBGDx8dBQUZP76(vY}4)ez%07QbwVRge$##7DqvCozy%Z+w3<6My#z*s zQ@OD%_Ys5vaCnT+bEem$#m(@SAb03EN0gtG7TD+^DVIhQ!Q z5Qynl#Z%KPLdY0y!ch;9H3LKnyqI?u-eA|nJ>|MsQ8iN(rQ}P~1DbyK!3?il9x%UK z?S2>Hu!e~QTGYVGObtQHF%PFj11&Z0RDUmXvttJG+RS&w!D?Lku-1sFB!GiHTDvY=?aTz{bw}PZ27`VJ*z>2V!>p41XG+151LH z&1}oQ35GR09Vq{<0f>EuVm>q23*!l$?Ac?{unT-xp?K&zxmPcAvDWzC@SN`X3WLf>upk`ae_|b)?c)yG*N?&kC?oMzvkRDp4(965i#Z6(a#!ozR|USm66wz5;#`0W4fcT2 zFlN#)L-v`2-+w~-V;sA2e9QPQLa3C_tqJHh$>+_m6JA+KQy73?{Q*ipL<7bq{obvB)X!M$KHy7) z6`O)Gp%hJ>09wqjCNgM+3Mn(v|5ni2rJ)a=dFYsdfK^@QCIc(g4Q!|;u<`+m$;PB; zMwZ+ItOk)E52eI&eXs#Q3$S8>3z+>I-wMn{CD)aWc(GWi+;8b$lZ3 zgu6C4pTuJ&+H!`=Qh9$cCZ)!REunv1O`LyCSK;Zg(|t1J9!_&XYo$2O zGpj<-!u$&(m@xwZtI!ODS*>L?aAq;EswR^Vr?xJ;`zGPh`d!yRBzG!*`jz4G{sZdx zT}?kWQCvS0EJ6BT$3$0Olpn6JOIPh~R6o&AFyr`)NljDcw8x0rFCBNE*HmKD19Y5ETf4Vz*0svv(2Fl6EN+Hg6Wk5w47CtNu zd05G3@^?MgB>i#y_nWic-B^W`v1D-AV?OeK2*%%@{T#ug%Fvc4<~{UcF|p4FzyLP> zHx`>V(E~4ab_Rx1Bp426YUxhs$mK~V3DSSqul_D^c0wf1($Lj#ub8E zK9AqXWpZx7Dq#yS4PEhE(mcQayA6x7H84X!fuK;C?0mPz{6WNN!TJ=4_Jna(`EJ4| z070VviIHL~8i&R8UTKl;!Ui`GAWEOfJMMm-AI%P6;h4v%55T})NyQNcxeU+&v;cnM zwy3Mcc(hW*GR!^pA;yXv%5%FOcsid0;*3?U=Ubek<*wc-JTw3-{94?@*q=4wK}!WR z>$?Am5)MpDivcdHncn>&0jnz!sQ|1*0tyCpz7JMa3|LuZ2|J0(#^l3y0*Hz8n!j(u z0qn&zU3X;|^3ZE>OH2?Su!uQ=T@?c?fJvA9uTyj92l!^1oc;B6C%^!p`hFT?bC|0# zo||xr!#DsgLNKHeg}xcHOs{WKgD{m~vbV4QASPjW&ipz7k~Xecqw2Te69WhU4~=wR zitj2k+466vU;I;?XE26!aYyfaNxR|PJQ!@Bq%-#Sx`2h*2+#nWpERsd9h7GNds&-R#A)t4@�x8a_6hzULJ1Og=3n8m7@LHN&c08QS_81L zvgm@D&)@(=nRrWaOlvOT9&0cP^BpCGAq0KT&%X_Sm6~d4!`8Km0s_PAV`C^~AOC+ZJL zytniD!W=a3`n|rK@l4Jw_GuxKid^|*7Sy!KbJeoKvq%x4kX)2iD7Q`)CW0Dl#+WcZ;lk1g7~x)@5l#haTG=YiN{ z1+7v|j$%)I0IFF1^5Xkd?piKryO&kc?-KvT0s-fZbqC|E*!F)?_)<-9H<)4o0000< KMNUMnLSTZ+CVU?N literal 23101 zcmY(q1ymftvoE~3y9Eu9;O_1Y3v6)r#oZ;?VgZ7?OK{8L?!kiucXti$@bbU+e)oHC z&Y79&>guYlK6B3es=F!@q#}obN`eXi05BBfrPTlc80LR85E=2`bKxy2>)#9BNadoe}$*QPX=S5pQ6d}#rIpiltd=^rcT5CHIC2LO&u006;s0D#CjyX}kczYY{< zd0jUE01fXyHw+*%`@=sAx;7d*?mEgqL31YuR#OWnGcc>SgY!RW06^GV@E_>_b~mN; zcCdGJ6Z96L{x1o^fAoLYY}AzhCE{);Lan0=qLgxS1yk~{ae=R0Rc94PBubV~-j8b}c?xPA3Lr`Bam&`tT_gZ{5<;ZxO z;nhk{^{HYW5$wn;Oc;JyMjGTTd^>A^Sq3JuFj(6ZZ^a}rE1ZwHTZ}EPIZb`@IjKp& zlOMwDClaYCMZl~l1Ys^+A=0Gu%sP!e{Zvd?Z1*p9c==LMMFut2utKTAZL9~LSlK$} z30XM3F)O87`K|hdc{UD#YXU*kiweclf_x@Nyfh$py1>+`^}8cECtsOWiw{CMx!ocx z&fbkdp7Ml5_z?W$+i9CDm1gE0o24XU<{^^64X0&4Urp!3Jep_?$Sh`xi~M|UmGtU5A-d5CSbT5g6fY|h+pi+h~~&*)p9=XO!y&FW1<57h>2hSl+8 z{i60ykK*7tx4L~6-X9oLm_oW*ZyJKHogcRcDZUz8C`NCHZ;26T6KJNoBy~!`F>vlM zpgxXCT?knjr{u7E2l(NzR$+&{Bb+83GS~&z$EX%HPNiOZ+CgsW?B1c zG~FOP!Y!{8RxSO&JHq)haqSHc#sGVy)cfZSodvQhpD!>Z-8%^JUU!{moq86}Oog*a$1Muj?UX zwrD1B@7#=3T5!rBt%}MXYVd$qltHcAM0{yDJYTEVDwll-P1b>)tb6IHA|&h!J=1y6)XlZX&kcdOXY5u7G_X>lJ zFR}N=9H#}BaJF#!d!_~4v&s@XCVnq2)VDQNA?4GUcrR;BHrETWO-Hd}^k?-p%N#(H zC|}jb3i?sBx-qxVly4bz6%2_9Erh0lOo&)%XCYTx#iav+n7Xt|2Cse|In*NjYH60N z>Pr0sYzmI=x&}1KEcK(wjp|KXNxPj~zrQ`_? zMxLY@NNk{G>0s0Z%>ANe8RVhTxI#Uq#`WkHG;UzI!1axPX*Ow--EkGYxJ|E)@vhw5 z*Y`QKKuFK*Poa#h!icwk`Z_QWr^`nn^0RhYf&CTCO%5h1Df~xn$Bd$H!aZz_j$BGc z4f1L_;d|gj;$*B_4kcdfSd%%Y(eUtT(v9Z)CX?Xl>1XA&2l79dr;A5i-kd6VHl*QH ztFhBrZ|1jIZN2oJHqn}bXPtSA4iPXnGWiW4;)Z^u;^wc`w^>~yj5%$lRvV-nthFZ( z#IIl>SGA+>KNJ<8_)dVUaF{C;jRy}x3r)l>L2%M_+x*D9y~X5>(KKv^qn^X-9=u=u z81S4Q?JoRj1Lq?iuQQMQtzMDCbE>iWxz^vVj#FXJ*^>O%lQ2TntXo;>nPiM0DPkZk z1zu1hQ^h{|b5?#8p_O<5giuFbO|OEwli8+A4Ma&Px|-jxy`VWkao1xiV*`WlJNNTs z$E96^xKLn>W-N1`6J1yHyY#8c(q2C`e2c)?syV}Gm>%$L*j-6LQJAU>H(YLD{Os0} zXJx?APU+mOKOA=|*HQGO1b@T-{_pWTm%&wKeiHiE``7hwGVLm9@l*|wy6YM|yU(7v zpEW`FFO-u+QMsn&SJq?Pap4dJ(NszTgRCB3vok4Q<3H7N7Ar~Rin!%<0|X8XbVWiY z1HJ{plXZ05G_?m41%7Qn@)FKnlO&d#=pb80nTk|)^fV=ph?|n??l(mdNbOJkXkJ}` z%aUc-{$FKU7E2Cxo>B{N}@1de1EJxDEG;uos~GU6YRw(&>g&z z22jE~^tg{ocH5Kt#&Y5XlPiMXMl*%gn`Egrk~T$vg8_J2mHmL-agtr@z z3+RMh_`GJeuXHFF8~^-w2H~{gmjRU}Z<$9i^E3-MB;baQrOrIAe3%>ihc84_^(4kT zc8fD-kQ8+dqy|S=zp^nl$r7F(Me$dOYx-22cip*D({2fnn%)C>VNprGkwxv9JnE2< z6xPA!x6KfGdV#0L&5Nin7+B9@WJvEu>}-PT(HG&A(mtMjf~ROLWmh#@`X8KoZk-;1 z+UFa8BIUjXo9mKth_bEvPkxKf7hR$qxd7~~vPp2=5)`FGbih7fs%o!^Y@?Q_|B^Nhady?6}I^`f2pKske|< zL!6S{?s}n${h-oe_iHXX{4GzxJo;Vme%!FLc9DyGFLU?K+mE3FaRgp(fC2H?h9n$6 zPUbja!7V7Yoi5MdhQb)>k_Ckmo;~6=tGnb*cns>;bHdfp6*TDSI&FUKg0LW+7AN;9 zrp14WyV_V;w0MEBMDB0z^LMz^i+c|V5M8gU<3?i9ke24hQu*Wi1mu-X@7@h%b;Crlr;MBO`#;kti=dQS>PWUr{-#b`kRczNl z0b%p2B(p#4#|%!=Qfz&~uW4f{b-i4jEb1=KNdzd_6k9>(VTgXM>w(AZd*L)9OiVR| zP-<`rhE6S@=rcgC{etW=mr?0J|ME};omK{u-Pdal5dKng+Qc_Vse7V087)e%Te-pK5a6}AzEwH&rM|XU$#v05Xp1rd>K;}a1ScrO~;2hRRGmV+*o?v@mlQWA3%waz`+m#Ll+fiZ#5dPk`pl~&C}WmF8A zTTk9_>J<9l!aw10GZ{MGBj<_Tr^!khhCRHGxz?it)9#PXxnP;q1eJII-&96X#~a{T zQqp)x(~ZmyL{apFEV1ZrookBZnDoWRuI+{gYKSBdcoK5#`xKt)JM>VTwNk5=^o|aH zpmrrZ)OI%weh63SluFkiL;1*yp#4pY!4|uut~&A~;y21>t~n;hR%Bc%R+ISKUpf_n zu%}Hntwv#e=V{eC^_YK?p)D{ZY_&>?((64=IO4|)4UdX99V9_HQF)@on(lkJ4z`daxz6c7v>po;g03v=8gTUZt;UR24R_iJlldUM;kR*By@y+G}3UBg4q z6P+tsQ~+ua*N=qwU9{cAL|c_#)RhVIT>m~-loun#U*_+F+X=gu%SQ@Pg^$-!5I604 z;omomjEv}NjvbSS;+m{_4LVfd+eLjpIllRYu7o6GXFLF(7_Kd+hH{d;VF7DQ*;xDV zv%svmgfNNT_mge_p^$=%FUUAFjXfL~==c^^V$;PD2(FGtLPBu%d=Wur+@tUR^iw+p zV4sWl@QRbvn`X8ZA6xhBi8y>6**O5|?9o7&B*4JH{7>`I#pNT&g8*zjs|loj%kDth zuded<{j;J>1N1VUvJEjICOr@r3DGg^wOX#o}i39(Fyz~gg9ntb7>tv^YsiTJHIPo152lm4yicv(AzOYg9z>fnSo!r5bDra+6 z6A>yUkcd>j2`06^b9GglD)cuzKV2ovZ5yfksN;8MHh4P370{oZ3j6XeBP=IH@39sX5Q_fg%9nno zkP%NZ6h<$(T)QCL=$vrxg`j1jwJ14c$uA)O(!oNENp#cz=ZT13b5eCq7W9TV3m+^( zoZKXl)^|Hu(w#)1sYyldKs=up30pbyPnymCPJ?WHUe)Ze>21Zc&}{;MTJq9f8t#^& zCTFfEWYXOc{!6gqM?4MU<)t?$ zsvnNv^bSDQ*iFh|cJC502huFM7wlt(AMA3JjuvaJGl&&D!bXm3b$0r=HY=C0wXc*g z>zyaIiOMr8qnXA8z;b;(6m5Y%`Jqm!Tq%uj5w<{`I z4JqOfO$-o@16W6)?i-w-F3k;)n+7u>1JcQh2;jh4EoWmo9Uyq zj}Q?*WG{byOHXx6MWO9Fb9ER9?E_vj_f&*oG*l^3vOS&zfVG~PRMkp&Hp653mFIjV z)DWzR^IJ632j%W)#+Am5OK>npGV>;OMOI=}rx z!6Z+hee@ZBme!5gdq>H*wve(2Zh+pS5!3Qtc0$Pj>xj?A4ys1Q>gxg+`h-SSM9FKS z2(z0fns26ice}Xo$Y8>@k^}nlq}OOOz|!73&&>pG1>XXAP^vqa`PvE-Bp8BeKdAwd zt^ZL#OAbdejLC6V5miKvq_fX9oMogII{-lZG27+iZGiN);a{_ya-? zcQ?eOsoS-CRV(9kN+)2mKH8?wljbP|h=u)%a8yXYpMf`+%Ira(e#4y&gC4aH3-X_Y zCDR00hvp+F?nx!@m5i82)rY?gY0YIrbX|FMW`4?Ml5!X;D5^LHJo z<3(AHQ9hm~!^|26f}(!HyI!lJ^UTW#cLiZlYG6=3kDu4d#PL^A?=&0?%MKyVzhaxX zN386eAmpPVxuU(~doN_wom4Rm?#}UZ*4FS5cZXq|a`}t&C?446!)c`-w4qe# zP(+CQVkBU6r_f1Zgb>iTP3G*U?jB_tZVBi@p(eU^X!1g8$2bHJg$7P3DJ5F+fY1 zExpdK3Qnsk`k~-d#ZdaKj8p=$x9!zo2E2@lG>;mT=~oWCd4eOEZUhjfip9IVz7Y8R z1W&|bl3aw?lO_jiS2euR&~^Wn4#o0=Nw3v;5K;dZ#(FDW=Ame*5XU>|`JwJ<4*1A1 zI!>n-BCSPv3ijC6FXTx{2zP(U`sM2)BFkXz_8p;=jLAw?rQ#~mw>BAFJ;9sb9351bugeBaND66BoB7vLdyhbGx^cGhEIY;+gag2+8%}!5$LN?;E)#xjWTO&-U z`WZq_O5*6ad9^Emro9l;{?&c!3Ov?RCnXdH_`*82ZCh3IoFm5flYMm-JN$IyBPLJR zF0uNJG7N4O^Zi3FHXF!3em~KpAWr>btXu{fB63#Hdz^SMEvVE^!bS$f_K{H5F|WDg z@}owlb6G`i^cTSviOLhln*+jZWvygNxYjvYLyoS1y~Fi(LYC#-^$s6s7hBj~gO#2x zJm5~BuAJb#kEkcUk48yWLTN-$sl$3vHEly$5|tmpSiCpe z-__*KIAnai7%+=@!CKn-Z@wuzJ$s*I;UMUqu(Dhv52drj%X8;x&9+mTuBM4g7=5h^b{sfm1$OlI#^hYfy z1${0|*($i0Qs+xEQbuB(8f&lYe$nqJ$%9z262lyoH)Y8D#1dV#w#9vGA`YD2VZDUX z^*CZNk8+W>caRnx(?-~)uds|GC2tYYDenABb?=WtNZV-9%aReVhB;vBtM9=kqr5Po zd7X)#3rIv%J!LS`+Tu?-ZQog|+oI$5NUIN+XmBVB*Y^>>CDGN&{~pFZTdJiLyeE6L zxCc;_F`{rXk8|#vyo{fxol&QPizG*C`-lxL`_D2XKV5GSh=McvqrGeb<*%lWw7xQg z?$2ee^y4cJCpy<^seD*@hU;R3^B6dJBWs>yM_-%{6h{mL8;-;fa0kTvfu!^W8MWc# zBL_jEetu9`z@f(hoKk8aTG)*?cdO~BR)mZ9HVB>||0-(ufK~SQIy|#&T<2*?uf5%o z33+H|zh=>odV_p{n^RY7fd{)z3TEM(OEF&VKd5LwA_!w`6OHygsru6tZUOTx}(KuKxz;t<;PDwjBrG$K#6DTVq88rO&~_L?YR~^1UrjR^v>zkR zH44Y!Df9x_UIQKBl|z&SQ-L*~TZ5KY>Frluy33rrzJF0=7_?l0(zE8$nj4GOsZMZ z{Zi9kL(xw6<@QqTiMK1##D?!dbA;RurtLnv$;$o`#u`Ck2wFCd3^>aun&G9=qC1z( zYaX1NiOf~(l<~JH{h!L}es+YtWf)-lhliwzBV|nT0yb=rBRo){5fv{uJ2zu2=H&Hm zTvk!e1bdxX1u9VT>|;>X(;qgz8tYEyHId(Z@*ul9hCrz>BQnp$vUrXH+`)eIhf%h}Y=8%(R2}l% z)QZ!C=+(zIdsI*;O$%p@x8^aH0pQ!6*q>ITqCjqWe8%(cec?prfUDt_oe6?bs!vUEBqC&?gx&QMN3 z){~r}Af-V#+=0B)R*^)Gz!~pqjPC{S2LfTz)5VoJ6kd#7#Y}j8PU*e_jDRSr)c&J6 znzLz-F#_T}if~L4x?e1dB`JfuAgYnEdci5Q`j(CFb3G~^>GK5pLk=_LXOx(J$clD7 z%A}KjZV#iQNRzdM(G|x6<=)FllXKj{-?zId8vge3gZ^&yF>DfsUUa^6Gn&4HJezcdX1vm z9?ND(u|rUf5#noQV8liidcBav0J7E}tqSxrHSNPx0NngMK&FV^m42n7IKmBn6O`RI zXbr;}1rRSg<;?zcq7aufE<*biX9F{Okc&K(gp|#0?o)5g{ik+hf4W280bYM|{Ogbk zcy`vTn|cf><>wn{*{2(gGX=oulF7Lmj5>zvZ+n0S1z(^H3%pOsq)8;!uP^SU+j$6c zR!gUG6>~e!ge#mvD7Kh}o-8H^_3Q`YGX(#@SX6Qfc>5;wA5cxTrxf!|3oOJvgUf}} z^TJ%o*F)683d>EEy_<40*y<;IVQUju^4?>i(-D7I}MKMH2NTPmYq!|8jl~c z^>M0j=F)aUvW?7qts{pL(9nG|Wnn2}zQ*Bv?7r5tfngf0il^@xMaUpnCLsst)u&CX zm5n2wJMm!K{Q1)4LMgV7&hOaFis|QluT5#8IT3RAzzU53R6`wGUz?@8PIz(dyKx() zGci8Ztnr@CM(^GO2P7y2f@jsQ!hIq|%NR#@Kw*?Utph^3B`Smq)3tWIkA^Bg!MdS05N(_j3#0LQB_+-;LUy;7b*-V zi&w?3A@xLja+vf-hcVgnZ$D2>i%y{#mE#mZYOusI#F7vmXK}kQ6@yXcu0MqRE;Blp74MMy~kLm&R~K)sl!wAK6WGaxLu zS~^=l&0UGZ%U@xutd}d$BM+Cwf2|ZSN;PX8xhZ}}rw)b{>jgj@aPd!EZI-OGs81t* z6*{tXt4>R_a>7L0O;~w$w4aO;!?a3tO8n-|Nj7Z^(%i5iod~gqR0baq$QuY*pa_f@KS*5dtnF@&{XjNz(n*JGJ$Uh8mpU8S*&^AEJ9SM^wzn86bBRk0EMEj0tVQC^l9vV@Pfoqtwa%FN-uV zogMi_eE_G0h^ESS>@o-WTL7v)GRxRdy|9j{`z*7d?JgW+n>sQSO#8e0GzfQvK8vM6 z82Y{5v@abJheaR4{K*PM=b;7vR5SSmuEd`IBPTnAAjK12XKN<};~%n5)}-rEB+CZa zE4PSp?;XOsg9_>INd(VkTzL4?s3A2ME>cPl#?C+cuwSsXq+rTgegkB6i@kA zQ^2VQAuFu*R;j5v?J7!s#PT!?r~2Vmy5TMs?9V9#8jK-7?j-3>7`{f3T6-dr z{y=KEISfO71IaIc8g`tU?J{rmH&6!B=l8LXFt3ZYn`?&q*YDJ0(^>esAU|V#zkhR& zXudN~8&hZgj-ogZrPJb}@H$HGcxP5R=R2+0b~C@)2Y-%EqZ;AFWT;KhJ**hH@X<@DfB|7#)RCRFg1? zuP~Iy3?NAbC~o_Vf-V?Ki)=SGD>&GwR({Q8BVNy&#l55bD~(B_gY#97A^}eI+Re0h zrTbIKHHTeykb|&4haDZW*Cs6)tOOc-vjsfMK7tUC+CeU_45?w+!B$cl33J0b`@u84 zAvd`&W`T;?o9b8X_p!esAD2j&;}Sg@`mQVzjl6gIJhRK}ZQNwq%*Ira1WvDyoeQAZ zW^Q?g0!=kNJsT&BzCN7XYdedo$mae9PM?0;(;0XfFnkKJ>(^VTHXN%}vMYLrOfx!C zIhUU2e$I*8_@PZf)BnQ!m%4Q+i>>WgCmg|P9%Ghg4Nh`-ciN&~&_*B4+X5(nq7~1! z+4Joh=fDZTRK}VgxCO&RlID?#@%d!;Wti8~@~7S)XNeCdOUY5u29A!vAGOo1crSeA zF!J+5M}_O@Ts7FyVm@RVJSSxReqrmuRPV|wQFz;|6J{fPQYTjSBj-q#YO9I?&ho$&5suW8OfpcK}c9*aA& zO-@QSL9H_tI*td$5%W?$1CfyJ$~w>{(2oS-VgF_QeqO%#@*A-Q*|KElYAs}{<)E=L z)(?f)>->1Rw#2q81OtVsD7030AqELm&Md^|8KoH-TvP?ZsS9R}zz8jPj>@SQlF;S& z#66gQBI@3pXLaB82>q}^Ojb`%PICtOhZ=mE-<7j^CIcQAw=v zy*9wE2_&kumT;@vzEjdE!L2|)1jR+ohE9pvyp`na>UV^-pvSEtaKp;!C5p*=<*tWF z_tNDW+|V{%bRZ{j9)yve{9wOu{S54#T3?9?sjTDxI`kYVa)(6q^@Xd>;dNz>vD60M23v^obrkbb8wMEdX`)X6#qj*YH z#r_1`;OE|j8*vh%3O=?ku0x4q4dr4jDhw!yxvu<6g^~=pI;M9eu})FZ4TM>gs-d`} zDK2h-oAI_Zn>#Jwi<+Z{1{81IQ@|7al?o#9EFWEzU?%zyF54svc}$)xA@b75Q|T0v zj>_T|`Z2I~fT4Y3{yR=?W|^^P&yHIY9-)s*!cZcm7wNTiak&Q&NTfk*UjqBOgI(_K z`7vrX3=Tf3WECS`5X*m=6sM^^`N&OsuEP+9=|@9qP_Pp`71<;!SO{NNMNdhm!A2Ex zb}Jw)OIrgzKK=?oh~dE#7Z3>ic_wl5+!sgX8XQe?(=A^xXlKF~fc$&qS4VJmJ)o$$ zzv{|?8*V3=XN42HYLF!)n~XXKfywTt*4p_6H_z+<6lWD~O0QCmjW; zOG;1A^wq3~Z+8n&X&Nm^W1@Pl0NMI$u$1LT%~fJgPT#lU=%o<@azT#y()_BE@bFth zmRz;+UkI?{1oGkkNT^indw8Zi1qp6FdM&Bu!%MYFWx87bQO9=CZdpWyICW)`HTk@` zKe;AqHQY4&*5dect``_T?&{nnQ>vI_(eAZMx6r3}WL&T)gfNRw(2r=E{sIGLPDKAL zlbKe@c`e$(3Qj4A=_pozq@WEB0SgnWf1PIwlG)!g+bQ-%hSzeTs2 z3g=#1g100qLHUsn8-0lfPSx-&s!CVR?RZ_ch2z z@ScMVHYJgJKHHLjReE*XRK}dR)#L}yh*7Oir9eS72_(DZ50-8`p=7A`H`C+0d7ffq z#wFQsdLW-5%G|qIV*n}a9SE7&$yK2irS6#AI`pJfajzD)U>s0+?Oe0YOSMuloXVrH z=Z(BdRy7%K)X04OA&&o)E%gz;Y~kcDhDd&u322rF`Iu?({pgQ%N^h}^=TFzZQmb2; z&Io%O4kB-MPt=A!hFgqAx?bT+9kLhfaKx`Qx$?qdfphC8bg@UbLH&9OgF!w!ymiOD zb6_$oOV`Q#-jL70ALlq^6&$hivZfN;0I7g>!@3hWdleWp1<&dZ16X9;(W0cigZ-MS zoRlnMesXY6?r9lXWq3CvCG5wVrM2P!{j;-%n(DMDc$2ZvVU56qu%Vn+k8r@No5+?F zwc!abcvV=Ne%76|tSOLPtS-wYD8&Mf%7iVa?IXJ;IZs zN=N^kIArGcuwUE$#}PmKy@GSi)J~mWhYza0zHMkv%N%nl?5$78R08m?IW7!SBv&dM zgKr+-glfSoPN{l^j^NqJJ9W05U8`}y)4f^zk9|Mod*iBxE{%p5!j@Ndl6qAN?&!mlWLN)ABlL4@uRCykv~vTNg&hs0}Cq=|vVFLekeZJ(cLnX2gT7qMUUqM=^*fX-owW??o|(T zri|Df8+k@i;TIy0u=stqtMN*pK^)@;W`-*-A+wv}w|C4%ZGSNCKc*uL#~`2mfi}C7 z2Z}Im*v&FS(O(o-)B1La--{}E57`UuEXYXl!t!6$S`SHJuleOM5&2i>Tqs58md}Ir z7$$<2-m|HrFK9KPSG5D$(MobvSs6d5^l%BCXYUzxlF8zgWP5+fxyRg~>WQNCS`_3} zy&oq>nngd=kInpM!2<6W2-6dW$8<_)%~-|?%snP<)`Vb^DKRqD1dpNr>MrH|h80b{Dp*(?T=@d)@~P6#ikmdyBH23VU>6S~g&Z74J) zb`bL#02<0SR1H3hax0*4f!|gzIk8@wA+oL7i0;fGG8Sz!5xA`-vt{XYPfqxQC<@~~ z&CuBu(a{G*c>lC~34165TV)C4Efkc(5><@z; z3<1oMYXyI&)f-{%7(R0ZbS41?f8Ub(0eAkd!Ilstcs>GR(;X}RJVNrBZ~bjFy|y9^ zm6JqGX^C>*$&+QF`DpzZm$PrB!i9MGuvBppc$B|v-Iwpc!e5*ZqaaIok}@+O@&1O7 zO-U)z5j+;dcxSFq^nz2hpe-6fn(+fYsHOz;gcA@1D^>a*3rNV5Igw6f>BCJ8^ zSCo~&CnGTx>*Xf`tx{BRYHHmpU<>*#FTcnydXq#za)UorT4#|B?qzO-z3jfIUXU5h zg?SD$`q5z{st0egL3D){=g=1j`#%)2L@#!HKg;MH4>HE?R=dgSl(Ef6z7Ja3Kc+^5 z7p0gs$Y}AhX|vU#AhXGfYgAdBa$L>GBRmv$LL&&|5M+%Fz*@i$$!i+x?$-Dh|NJ)7 z2h~V*eB8xL)Q@Ui%o?yrF#2pRHGT{IRtnn{fMaSUgs&RAgvQpUa_r*lWZ)nh{8LMbBQf?5w{10l4# zV9v63!Js|rINA+ejtXZ|NmDGe=yhLM1QQ8M9*2IJGQ<)d{cCa&q2L3hgrmrO`g3;Z z1j-2q91Fvh+0iV^f!2h;)J=K1SY+jZra*7I5aX!W& z=Yfy1u42i*2s2GQxomK&e3jP{NfWjwdtqsNDp(7>ubg3lGbUKl1D}(_}`(40QL~oDal7iKxYbomx%%#04U9X0~81CzivXgZG@a zoZsDCV_3&9pvjkVT+5qjpKd>N%%dXWv34@YZoJhTxmX-2be12Bpi}<#9d-P)*%UK_ zv4kGBg^3HR^93c1`r9(p1s7SLJ&YZpNGhe^M2q;BJOWBmifVX1QA-bC#=aJN z1)*OmmUGXP^_RUce7H%O`kDC+sp2y>x=U8dC!K;S9hcCIBlSHjoTCc5d7d@2rknP^ z?<9+pcz-w%qRdc0R)zevn6wmCz91d_zZgcYHph5rv5XJjE{4O+Si&Mkn~n}#HyBRn zq%^lC&Dt^aa*(XeNGgK{AXdc0S6Rm57kh-YL$Rfap9}Lw6Hl^Lg0<9WVW^JF`Ey^C zOZ=d7B>4K(TR)*I0UTC#=m1ZhKQP~}pQp;5g2CXEx^)z@AdTxOFJ zaFyS~Y5~?p#f9KZ-HsJY0b(Hwh}pbxf*j>5o93B#pf_*d5g2I(z@{AbA&fJwLxU&S(>CDiSD zwE4b2k#9!qVo4kEYW^wtQKA>jSKW)6ta(nHFG$VFQ0aY5qBO_0C~{C_OJ`8of^-s0 z?m=6EwPk5`jOIFc)Iy=6`zv6Sc%)Rr;K1Q3ldR*&bV=)(lgvBjghQZneGg**17SgQq$F3W!=zoTwBL>l@bqIGPh)$8&@nRC_b$vu=PyB|r6~CX zKR!dfw-;!GQT|fN$nhW@dpDv$<01_HWq|((8z=g*uI{Wi>a((s?k97I7pw_XqlGYs zlw6)A61Jp}hPY^?qDfAv_Tc125MOM3;#gb&*DHn(zSuYIW0%IJ)U9VGnZa!gdnou6 zRSn`)Ip6l$_Si06bmnt_8u9t(F%u4Avy4q3*eH@#}e!^Zb>)aAm*9VL(WHR(Fx6q(W` z-Wf#nkIf`Xv#J(g_L6e*;E&r%<(a6k`7QdMF6H?cgch<<-#|-hnF0d zo39WCDZ+7EQDGDPobD;toZ=4Dql;e^;L@|uOQ_Cop!_!Z4;(xv0CP&~G{lRkZ65PA za}9k=1j>WO+)6~Gis76}Zq$WkmB#xv8j9Mh2h?&9;G@^1)Q2O~3J^dZ#MwtED8NSv zY2yAl?X3EW(ZtA1B_I?R8bpT7Kp2NM^$Rp+@vKuWUl0OjZvgMII3=Y-D+8n}EHYs~eeU(2#s*SjP=cNc{ICNFl z0dJPe{_zO@b^#XJ_^tGeR1FkC`RK|52t5pS6G!{2W0`&nKi4E7*XWeGln3Y+M_0?7qSdP&y!p=+ycq)oN_s_Xs4W zSWq&fZ{|@rO$09x3P~c>L;DfmJ}~{zdJ#x(!{KD=MI6jbMR?hYu7LED`q5W@R}TCu z?4UIz?-=rg!r*YjkPbvS^R#0n9m!W%ET}u`WinJ9jR2upjQD}+T{3~ubadD3)2Va) z!&>Q6f>sBHbZ=JgAseaY;Nb!^Bl4n@!m9OQ52eRR*s4*9FETJ%MojY$lcB1eWrF-g zKJR;HlC{2t?yIm0rb4{y#!;_sfrH$?#+}2kq3&^g! z0<_NrS=`tcg?nMFmJS5c%7+>yymoeJ5;J22UiPBSA`=Sm?&w_if)i6#D^qYbTluPs zEINP=HsK#5=2@8VN{cPfC!GQ}YeWE}n|TH(MmO`G#*!oC=!CeX{6|y{E0tM^h)0+m z{2~lwi7d_l$^@-Et^CF}%cZ?;xa8E}O4OJK6=;NwjpvYqAeew77eOcI2pT+P5vZ#i z+Qnk;PSfupml|P4vRc#YdRFo_*H;EsFoo5^?G=BSREwTSs38Y8c zbF30X09<~e{}xDG8KFDczzLp0=+-hRZVn$RC zET?v#+M@1NUR?ef$A(%PfsHF759+0c_+vw`zakS(vYgT^$3~DalSjO4r8~);vh}n7 z?9KmIy}VR8lW}FPKm8T8-$_>Bo(1i-9;M$|q~?SLnkP_&hEiG^Q9Q$|oW^}`Xmd(s zp+{?>XFOqc3q|wcQpByY&qx761;-GXs7#F24%J!1_hwu0YNA`o2>+a3GH3DcULCZC z$=ru#WtqC;&W8l4Jj(EQm6v!nt}ru(VEjO4YA^w>$wVpnArev->%g~p%tGoe)yLTw z6G@M4H?EQia|~TV$+jpbxvgR3N52zur4NbrSn%oMo<3l1PHTzop+5nc0$_gyorWM` zg`*^*?nHX{sRBRmYW}N*Sao*mN7|y@+qLV`nl(9?eR86W9}vX&oxx0K(}?LH7Wv}5 zVk9!to3R9Kg)jhDt>(Bkz(Ad_ z-NXYw83vYiafwS%%;Qff41{Pe9KgHhSgbOR0EB>uR6qXr$h*0+i8kl~}{sI8l}x8J1qbE;#@I7(z)zK~&{^m$uJxzD3I`Uzt`$@lnxE-g-wLc! zM$WpH*@4GmXJ;zUzG3AK^4Bg5=ymJnudE+OKX!Z$uH?X`m+dfc+W58ej)u_qDv|Fh z#-)hnase?os)+vLs3-*^6I#0R(G2HvDMK+bN5E7qABhAhhX_;T7I-|`0F_E^BjWmOxSE<#FCO;gH6p^qe$k* zDBDx4AI_$mti{Y#&}@KtWOXs}e8r5IYv!-2oodU_Kq14$!K%{H{H~(N(U334gS>CW z!G$XkXE7?c(9n%H2d%DKI)82LFqV()?tm5TFyVlNpUDyTTXG_?4A#LHYioO#d(+>lMh(4K$N2$l46O!&H@&3oXrhqk*BjsqQ{A3+)6kP42oB#|V`y>MCy zK{A;_+e`9Y!BPxTzMUz+51$$!Ko*VVTCl42F&rlF>p)JyabVRH94>%tEeS_ad2@0L zPQlSpFX8OGD+qW@Bc3pDx`$PQ^Y!>xFn@K;T{*e=j}`YRIu0kONHDxE;aGN@rQ$sX zY0Qp)>8vLn{lpS>*fkYGckBnlsSQX%as%Z4T->+d_Wa_)BCkJJ#6{jJjygXB$EG~@ z_}igUf(+Tshu&%^I>tX@i7z+zK7VfB@Z5r8uco;r{%`_~$D5OP0`k2RmfByM_j+}| zNn?s0$M<*&X}M9aAy5>%mjzzFOpuD!+!fW|!228W@(VpE%nn%45Ar>~AHO5-d)$Gy zz`+A7mMtB$W)GbsC1O)$msfQtEeEtZyZ5kFwbQ^#Rpn=38TD*{R18X?9)Q+gtNcU9 z^I%x%Py(y83M4Sh@mSZ~V1WBk1)*vvpQ z5d$}L0IQ%cCx0?eNWnn_RgrMx4PfWSf-*T92Mo-GpP?a76z_NQR#czFI4Z~>6e5O$ zIQe*l*OxmDN2Kqm-BWi(ZQ)dS9i!Rpo)c%rzZD*-G%MR`s z0LjHQyXyW`Ut2dd(p-NdY>KaBevNgtk(`3UBaL|Me;JS<;+7MS<>VEfONtWdH#9fY z{4N@fOo&CACx#m8eviXMn{fJ!gcBxCmE6iA#`EM9UWH@R-^Jk&*v9I<7`D@YLg1aZ zHq;N4;C)=JL_Ok|IDT;1=;H09lrzcVm{yPLS__DovTISZjOBn9uGlbrH>^BhpO}A6 zQV@TX5s$nCO6%MmcMSd@3+2+*nWnLUQiNcYd$vtk<>8Ri#>G{>VVByVxm3gT(4eeZ z*Fci;;Sqvd31c6qa}3!K++87Aem7X4Pv)(zn?GrE;iH2$OB$Yk0eCwB(DMAm(Zzoz zO9L>{Aygj#LgQA5$a?|S{tUmD2yk2-V|EkA6#WrlK$XZpN7{YphcGx=DF(!9eFPXe zKa@ipSwb{QQf<(3fG08sdA5Y{IT)EYR~RWDnzycDkQLXjrBL6{;}J!6T{&TNe$vVU zV@R)Ir7?Jn#;ddogBu%i38l_sGru+bzk5$dO;PO$$$-SW>?mQgLJ_iUp zg&=}7u6gXOz4z*h+=P-Uq!bZV!HF?XP8wTusfd9;uxb9QK%({qP?u-(gcg*49N)zU z)=%{LaxY|BIHIe@lGTbyV+#K1#KU#L{MGe;1Ld|T)L2&pAjF}db^iw)uX}OQ@wKsN z=pUfqe0n$@T)4VsnW4w74dmt@!@9%WJrO4r6BIjhkV9JDJ+~dSz`>=koQxgN!ZSfj z(xX#g-GS^O^tHOk9;U#m(r-oF6tK5|RkYzrn83ND1*~B1`4DxHW{APzcs?A=s@zf7 zyYNmNYEKk-;w!YnaK;hM@ z%l#cix5R1JxZqd&{ zHC2MbW8&l1;*bO!Jr6xEWDh^e*#NrJFCW!w3x)9<^ourG6tDwy3#S{2#5%C8JQgYd znbp_5rkfIXlawN;tO#Usvl#Y;4=m54OF!}QXmeRoe#^7(kO5ITmx~Y}CoiYU2B}VP zm3K}CSP^)+_`xf|c;e`S*O2y19z(?go*=urgsdn|I(`EQ-NqGEyz2!aJV4o+q~HXz zSS{sO=xyna9D=S>{4A{RGHZa=wIFwf}m*ybj!@!(w9*P-*?3)8tlRSB~)wK_UOZqJ= zZL4+FH9u5T_y0h?bM5@M_JT}w-~Q=;YA*%FaD*P#&qCCvIG|(Awco;#eHifZhbEoc zYc=2oSY=aA1g#*bt$yny_3}~jZp7iQjl+pRv7G!os68aW8iHO!2ph31o(LSns^VYb zx;cdrkv_o?#1`|ht4m9Ek9i*B?SyeO~{sbneUu7PBn+NGhcFI_4+0-0>`y~M4NalkmCrC>CHPjLZ zPy*9p(LDgA9gMqrkdzoa=twaU;Mns@AZr+^8h#Ya&;#l~l;>EKoBCySl5YN;aq8Ad z3fMcLlSkm9pCbGJrY9mdgR<+5GzKYq_I?T8{{hANtNE+yMxxA@;?U3jl(jY0)qd)d z%^xFOai$-xhwLQDx*e|WvjZ%)P#S3MnltQI045B^wR9TU@cDgGV{P3$9MAp37JmsVhqVEWhe@E5 zetOC1+;Yf?mgW}+&c@k#-$b~l;!U-b1)bSg-vk+xC8(ukVg=3~FiB7$HDoS$r{P#5 znm7*wdmtzV@$K;f!hK?s3{|H3>n&)NLPRVEJ0n3zUJvDfcP5Q0cpHxp1=?W6`+Zyy zX+;n`aR{rg@%q$j96Lejq((fdqnwbZdAxz<`nuk3#Z_%uwjV&PraAthSf=FR2u}Ld zgg`iez#aos7y$yHlb^tpha(SRa2D^FbwnI>?L-q-1i^{fJfMkTMBoA}jp9&I;Zx^v z`-I+B;m0lcNlEH4riU7^I=Bb2yWR-yQFNIMykMv2t*&_h+Vz*BeWNIk7vT5IrDIC| zL$K>%1=&gm$9=Yd#X9T*TK%VOz$&!&S1I-omP-j*>oQSVDK>De-w3-&SrM$_FcISc zSk0@NGi;|o zu*0mI=JMjG^+dv(06ULjOq#!X?}CY=zX@;Lsp^oA&TkLh(X&r@m6*v5{d1QdF=o| z4$xel;zT_Dbp-x{B#oqy-gR7)WNnqUa$Fc@JpNT#RlkI=sJ65nm+ee=hqv}-e@^~4 zxx$FDybrH0e3Trf{H8^*NKd)I7NPN`KsjM_{odM--IhzN-lc@# zVBI)i7Ori?X}j{R9OTf6iecPxFlvZw|18Nx!7@gqn7mX;KB}ms=n|}gU4i|CS9tw_ z$$`AQn+z+y3cxp>U`2HamQA>2%S0c7aQh#Ta5Gl{v65(B^~9>ivJSwCR7KoL>ft?QsFtzQCwPqi#0yrXCz8qV#g~+#h%g zd_EMGQ|>fMtLpCI_w}2KZ9JL>;3ZZMk1=R&`NjJHqEr|nwz%v!lsbUQ4}|Gn$^zPjR`lf!G^J2|1+GtsVT3MVcR!OPd-( z*v1pX(wKO|L1);i2+a=yaMo3vT<|d|IjS?vC@bTZ7a7}T)bWn&!sEP+hnNJBm!aS3(Un&t5UMcmu+mh!T=9WCidixs7lpo(9v)b^v=2 zNo-EbB)c8eci#_z-4(t--tp0Js1)UTVgAa!_bak{xekIBGOMouY<{LH+VRw_g8IWp zp8kcmKe)Ei4+{~$1&F)h2PV{-HuTj2Afu$;1{C@o8_nltp*mJ$7#thp7z9=iQUTZZ&Z|EcT8Y7t|;;>owc z%9G=^qRkIswebr8R-z$_xJn48_&Q`=zj2!E@-f9L zaQ|{3C!Z|dUWlF-@ZDw@-E+b?S1kV*sjl{SKamO`Vqx?NHWK+lCQeZkw&Re%vwtqE z{^=OJg#eBVn0CoBQZ~RD03HUZxTo3z^p^gCfh&P!IuXMCr_`vtB5uZB2V%S#$SItb zS6Iksy$wZZph+(L1Cp9h<3J+vwoqg3ilUOj;Q+`-A=-LVQq0%fzMP+6Wl*!hs&P3MA?%C%9D{U?M0-ArqIR8F&d=kj|iH1E@y?;-j3XZ3s*r(Km!ehY6wP#_h<5 zY-~S|FXt|BAD8HFBrq?r6zqstA zl1eDR{wxj!R-ij~>@OE%5mR7V9BE%kK15vq$^}YwJH1>|q=- zPFXn~`%&MNWc4C5T5mwm4yBv$pP zjrDa)uyo%S$MJm$%8s?r`F;d!$M_$dUeZKiE@Kg7;8eFyJUmamCHirI*s1dGI&o_m z=5DND*^S%svgM8{6;yV&tSWjUSrBtj$!ZCaj7w4s&N2n!RF|~`L0Od=t;Qc}Ziqqa{O^__kGw<-9jpQ=H?Z8a`TFS7ZfNNCN$8WlMUtE%T6iW%D4bD))%jcwKm|=pL>Q{xn$9i zjFcnii#D1twq%{lqnrUP_a{MphR}Xkd?<9~78FtapKNCc+U`#(l2HcTs&_#>{uGOW z6pKUfuD$|#VvO_P+O;lcb1;=nlWd)T!bydn;`IcWx_PLvzUDN5KtAH`1!}FBFsATz z#-)b8P?~Mjw^_OBH$Y{2pyA)#U(bgU7~Z38tr<2*Xi~2a04v{$h8jG`r{SH%GQn0e zjmy3wfbUXhv5$a;{i*m3u%H`)FS8SL=37u!UC;DbFT+*$c03w`Dv2Sf9&H1`If!o( zl+lK`BADe0C2olY%$KkQh(xNIFdDc5Db(MYPLKN{wt%o=V0X6CX&bLCz43jk-}KE^ z=`9~w0I}bts!Xu@f;kR=eXGRTxs{L`0WjM?{#un~L00mL6F$={&Vk1Fkc)kL;hF|( z@rIa%xYoQ?H8kL7((k$dh;;sxOh-@x5OCl53~06|-w9a^^Z2?Z>$wjs#`{}G`SBg= zKyY=!Wx7)S#UJ0zT~$8{Wr;ksG0w7W7MkdpA|?HtIsqj1PqpkPj8ldVvXj~iv+uX! z2JnpO?57MFj@-cg#%rGVOjd6o#|*R>CZT}9JHIsh87FcVHLym|iWx@PczS3|;8 zf|Q#YYHI%K(G;wXfs{ZvvVrM&IrpqX5Dy&an^FA1ILLzAR6rdHi=Jg=;xG$iUm!r5 zB8iYxBB;bgn_%;5(9IA1}~G;aqys((9~8X5deSo2}3rP z^>bc3>>AtKu`(*&VdZn2R3`M_`5~SYm-`Q~ zEdL$afC6>)eX+`x444AVw03`NRb%lJYnq1AEQ^z#6V7?=>eT_P1#22cFIZh~E%}g? zUhOA~-m)l}16vnVMB2%EcQv1$cs(uf*|mV^tZAfw+F<(Z3UTP<-1},h=function(a,b){return t(a,b).isSome()},i=function(a,b){for(var c=[],d=0;d=0;c--){var d=a[c];b(d,c,a)}},n=function(a,b){for(var c=[],d=[],e=0,f=a.length;e Ctrl + Shift + P",action:"Focus to contextual toolbar"},{shortcut:b+" + K",action:"Insert link (if link plugin activated)"},{shortcut:b+" + S",action:"Save (if save plugin activated)"},{shortcut:b+" + F",action:"Find (if searchreplace plugin activated)"}];return{shortcuts:d}}),g("5",["8","9"],function(a,b){var c=function(){var c=function(a){return'aria-label="Action: '+a.action+", Shortcut: "+a.shortcut.replace(/Ctrl/g,"Control")+'"'},d=a.map(b.shortcuts,function(a){return'"+a.action+""+a.shortcut+""}).join("");return{title:"Handy Shortcuts",type:"container",style:"overflow-y: auto; overflow-x: hidden; max-height: 250px",items:[{type:"container",html:'
'+d+"
ActionShortcut
"}]}};return{makeTab:c}}),g("a",["e","j"],function(a,b){var c=function(){var a=b.keys,c=function(a){var b=[];for(var c in a)a.hasOwnProperty(c)&&b.push(c);return b};return void 0===a?c:a}(),d=function(a,b){for(var d=c(a),e=0,f=d.length;e${name}',{name:a,url:"https://www.tinymce.com/docs/plugins/"+a})})},h=function(a){var c=b.mapToArray(a.plugins,function(a,b){return"
  • "+g(b)+"
  • "}),d=c.length,e=c.join("");return"

    Plugins installed ("+d+"):

      "+e+"
    "},i=function(a){return{type:"container",html:'
    '+h(a)+"
    ",flex:1}},j=function(){return{type:"container",html:'

    Premium plugins:

    • PowerPaste
    • Spell Checker Pro
    • Accessibility Checker
    • Advanced Code Editor
    • Enhanced Media Embed
    • Link Checker

    Learn more...

    ',flex:1}},k=function(a){return{title:"Plugins",type:"container",style:"overflow-y: auto; overflow-x: hidden;",layout:"flex",padding:10,spacing:10,items:[i(a),j()]}};return{makeTab:k}}),g("7",["4"],function(a){var b=function(a,b){return 0===a.indexOf("@")?"X.X.X":a+"."+b},c=function(){var c=b(a.majorVersion,a.minorVersion),d='TinyMCE '+c+"";return[{type:"label",html:"You are using "+d},{type:"spacer",flex:1},{text:"Close",onclick:function(){this.parent().parent().close()}}]};return{makeRow:c}}),g("2",["4","5","6","7"],function(a,b,c,d){var e=function(a,e){return function(){a.windowManager.open({title:"Help",bodyType:"tabpanel",layout:"flex",body:[b.makeTab(),c.makeTab(a,e)],buttons:d.makeRow(),onPostRender:function(){var a=this.getEl("title");a.innerHTML='TinyMCE Logo'}})}};return{openDialog:e}}),g("0",["1","2"],function(a,b){var c=function(a,c){a.addButton("help",{icon:"help",onclick:b.openDialog(a,c)}),a.addMenuItem("Help",{text:"Help",icon:"help",context:"view",onclick:b.openDialog(a,c)}),a.addCommand("mceHelp",b.openDialog(a,c)),a.shortcuts.add("Alt+0","Open help dialog",b.openDialog(a,c))};return a.add("help",c),function(){}}),d("0")()}(); +!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),t=function(e){return function(){return e}};function l(r){for(var o=[],e=1;e'+A.translate(e.action)+""+e.shortcut+"";var t}).join("");return{title:"Handy Shortcuts",type:"container",style:"overflow-y: auto; overflow-x: hidden; max-height: 250px",items:[{type:"container",html:'
    "+e+"
    '+A.translate("Action")+""+A.translate("Shortcut")+"
    "}]}},P=Object.keys,_=[{key:"advlist",name:"Advanced List"},{key:"anchor",name:"Anchor"},{key:"autolink",name:"Autolink"},{key:"autoresize",name:"Autoresize"},{key:"autosave",name:"Autosave"},{key:"bbcode",name:"BBCode"},{key:"charmap",name:"Character Map"},{key:"code",name:"Code"},{key:"codesample",name:"Code Sample"},{key:"colorpicker",name:"Color Picker"},{key:"compat3x",name:"3.x Compatibility"},{key:"contextmenu",name:"Context Menu"},{key:"directionality",name:"Directionality"},{key:"emoticons",name:"Emoticons"},{key:"fullpage",name:"Full Page"},{key:"fullscreen",name:"Full Screen"},{key:"help",name:"Help"},{key:"hr",name:"Horizontal Rule"},{key:"image",name:"Image"},{key:"imagetools",name:"Image Tools"},{key:"importcss",name:"Import CSS"},{key:"insertdatetime",name:"Insert Date/Time"},{key:"legacyoutput",name:"Legacy Output"},{key:"link",name:"Link"},{key:"lists",name:"Lists"},{key:"media",name:"Media"},{key:"nonbreaking",name:"Nonbreaking"},{key:"noneditable",name:"Noneditable"},{key:"pagebreak",name:"Page Break"},{key:"paste",name:"Paste"},{key:"preview",name:"Preview"},{key:"print",name:"Print"},{key:"save",name:"Save"},{key:"searchreplace",name:"Search and Replace"},{key:"spellchecker",name:"Spell Checker"},{key:"tabfocus",name:"Tab Focus"},{key:"table",name:"Table"},{key:"template",name:"Template"},{key:"textcolor",name:"Text Color"},{key:"textpattern",name:"Text Pattern"},{key:"toc",name:"Table of Contents"},{key:"visualblocks",name:"Visual Blocks"},{key:"visualchars",name:"Visual Characters"},{key:"wordcount",name:"Word Count"}],H=l(function(e,o){return e.replace(/\$\{([^{}]*)\}/g,function(e,t){var n,r=o[t];return"string"==(n=typeof r)||"number"===n?r.toString():e})},'${name}'),F=function(t,n){return function(e,t){for(var n=0,r=e.length;n"+F(t,e)+""}),i=a.length,c=a.join("");return"

    "+A.translate(["Plugins installed ({0}):",i])+"

      "+c+"
    "},E=function(e){return{title:"Plugins",type:"container",style:"overflow-y: auto; overflow-x: hidden;",layout:"flex",padding:10,spacing:10,items:[(t=e,{type:"container",html:'
    '+M(t)+"
    ",flex:1}),{type:"container",html:'

    '+A.translate("Premium plugins:")+'

    • PowerPaste
    • Spell Checker Pro
    • Accessibility Checker
    • Advanced Code Editor
    • Enhanced Media Embed
    • Link Checker

    '+A.translate("Learn more...")+"

    ",flex:1}]};var t},I=tinymce.util.Tools.resolve("tinymce.EditorManager"),j=function(){var e,t,n='TinyMCE '+(e=I.majorVersion,t=I.minorVersion,0===e.indexOf("@")?"X.X.X":e+"."+t)+"";return[{type:"label",html:A.translate(["You are using {0}",n])},{type:"spacer",flex:1},{text:"Close",onclick:function(){this.parent().parent().close()}}]},L=function(e,t){return function(){e.windowManager.open({title:"Help",bodyType:"tabpanel",layout:"flex",body:[T(),E(e)],buttons:j(),onPostRender:function(){this.getEl("title").innerHTML='TinyMCE Logo'}})}},B=function(e,t){e.addCommand("mceHelp",L(e,t))},N=function(e,t){e.addButton("help",{icon:"help",onclick:L(e,t)}),e.addMenuItem("help",{text:"Help",icon:"help",context:"help",onclick:L(e,t)})};e.add("help",function(e,t){N(e,t),B(e,t),e.shortcuts.add("Alt+0","Open help dialog","mceHelp")})}(); \ No newline at end of file diff --git a/lib/web/tiny_mce_4/plugins/hr/plugin.min.js b/lib/web/tiny_mce_4/plugins/hr/plugin.min.js index 6c0dfa44780b..72bc2cabd109 100755 --- a/lib/web/tiny_mce_4/plugins/hr/plugin.min.js +++ b/lib/web/tiny_mce_4/plugins/hr/plugin.min.js @@ -1 +1 @@ -!function(){var a={},b=function(b){for(var c=a[b],e=c.deps,f=c.defn,g=e.length,h=new Array(g),i=0;i")}),a.addButton("hr",{icon:"hr",tooltip:"Horizontal line",cmd:"InsertHorizontalRule"}),a.addMenuItem("hr",{icon:"hr",text:"Horizontal line",cmd:"InsertHorizontalRule",context:"insert"})}),function(){}}),d("0")()}(); \ No newline at end of file +!function(){"use strict";var n=tinymce.util.Tools.resolve("tinymce.PluginManager"),t=function(n){n.addCommand("InsertHorizontalRule",function(){n.execCommand("mceInsertContent",!1,"
    ")})},o=function(n){n.addButton("hr",{icon:"hr",tooltip:"Horizontal line",cmd:"InsertHorizontalRule"}),n.addMenuItem("hr",{icon:"hr",text:"Horizontal line",cmd:"InsertHorizontalRule",context:"insert"})};n.add("hr",function(n){t(n),o(n)})}(); \ No newline at end of file diff --git a/lib/web/tiny_mce_4/plugins/image/plugin.min.js b/lib/web/tiny_mce_4/plugins/image/plugin.min.js index 1a029df23490..d4764ad6251f 100755 --- a/lib/web/tiny_mce_4/plugins/image/plugin.min.js +++ b/lib/web/tiny_mce_4/plugins/image/plugin.min.js @@ -1 +1 @@ -!function(){var a={},b=function(b){for(var c=a[b],e=c.deps,f=c.defn,g=e.length,h=new Array(g),i=0;i0&&/^[0-9]+$/.test(a)&&(a+="px"),a}if(b.settings.image_advtab){var c=o.toJSON(),d=w.parseStyle(c.style);d=l(d),c.vspace&&(d["margin-top"]=d["margin-bottom"]=a(c.vspace)),c.hspace&&(d["margin-left"]=d["margin-right"]=a(c.hspace)),c.border&&(d["border-width"]=a(c.border)),o.find("#style").value(w.serializeStyle(w.parseStyle(w.serializeStyle(d))))}}function n(){if(b.settings.image_advtab){var a=o.toJSON(),c=w.parseStyle(a.style);o.find("#vspace").value(""),o.find("#hspace").value(""),c=l(c),(c["margin-top"]&&c["margin-bottom"]||c["margin-right"]&&c["margin-left"])&&(c["margin-top"]===c["margin-bottom"]?o.find("#vspace").value(i(c["margin-top"])):o.find("#vspace").value(""),c["margin-right"]===c["margin-left"]?o.find("#hspace").value(i(c["margin-right"])):o.find("#hspace").value("")),c["border-width"]&&o.find("#border").value(i(c["border-width"])),o.find("#style").value(w.serializeStyle(w.parseStyle(w.serializeStyle(c))))}}var o,p,q,r,s,t,u,v={},w=b.dom,x=b.settings.image_dimensions!==!1;p=b.selection.getNode(),q=w.getParent(p,"figure.image"),q&&(p=w.select("img",q)[0]),p&&("IMG"!=p.nodeName||p.getAttribute("data-mce-object")||p.getAttribute("data-mce-placeholder"))&&(p=null),p&&(r=w.getAttrib(p,"width"),s=w.getAttrib(p,"height"),v={src:w.getAttrib(p,"src"),alt:w.getAttrib(p,"alt"),title:w.getAttrib(p,"title"),"class":w.getAttrib(p,"class"),width:r,height:s,caption:!!q}),c&&(t={type:"listbox",label:"Image list",values:g(c,function(a){a.value=b.convertURL(a.value||a.url,"src")},[{text:"None",value:""}]),value:v.src&&b.convertURL(v.src,"src"),onselect:function(a){var b=o.find("#alt");(!b.value()||a.lastControl&&b.value()==a.lastControl.text())&&b.value(a.control.text()),o.find("#src").value(a.control.value()).fire("change")},onPostRender:function(){t=this}}),b.settings.image_class_list&&(u={name:"class",type:"listbox",label:"Class",values:g(b.settings.image_class_list,function(a){a.value&&(a.textStyle=function(){return b.formatter.getCssText({inline:"img",classes:[a.value]})})})});var y=[{name:"src",type:"filepicker",filetype:"image",label:"Source",autofocus:!0,onchange:j,onbeforecall:k},t];b.settings.image_description!==!1&&y.push({name:"alt",type:"textbox",label:"Image description"}),b.settings.image_title&&y.push({name:"title",type:"textbox",label:"Image Title"}),x&&y.push({type:"container",label:"Dimensions",layout:"flex",direction:"row",align:"center",spacing:5,items:[{name:"width",type:"textbox",maxLength:5,size:3,onchange:e,ariaLabel:"Width"},{type:"label",text:"x"},{name:"height",type:"textbox",maxLength:5,size:3,onchange:e,ariaLabel:"Height"},{name:"constrain",type:"checkbox",checked:!0,text:"Constrain proportions"}]}),y.push(u),b.settings.image_caption&&a.ceFalse&&y.push({name:"caption",type:"checkbox",label:"Caption"}),b.settings.image_advtab?(p&&(p.style.marginLeft&&p.style.marginRight&&p.style.marginLeft===p.style.marginRight&&(v.hspace=i(p.style.marginLeft)),p.style.marginTop&&p.style.marginBottom&&p.style.marginTop===p.style.marginBottom&&(v.vspace=i(p.style.marginTop)),p.style.borderWidth&&(v.border=i(p.style.borderWidth)),v.style=b.dom.serializeStyle(b.dom.parseStyle(b.dom.getAttrib(p,"style")))),o=b.windowManager.open({title:"Insert/edit image",data:v,bodyType:"tabpanel",body:[{title:"General",type:"form",items:y},{title:"Advanced",type:"form",pack:"start",items:[{label:"Style",name:"style",type:"textbox",onchange:n},{type:"form",layout:"grid",packV:"start",columns:2,padding:0,alignH:["left","right"],defaults:{type:"textbox",maxWidth:50,onchange:m},items:[{label:"Vertical space",name:"vspace"},{label:"Horizontal space",name:"hspace"},{label:"Border",name:"border"}]}]}],onSubmit:h})):o=b.windowManager.open({title:"Insert/edit image",data:v,body:y,onSubmit:h})}b.on("preInit",function(){function a(a){var b=a.attr("class");return b&&/\bimage\b/.test(b)}function c(b){return function(c){function e(a){a.attr("contenteditable",b?"true":null)}for(var f,g=c.length;g--;)f=c[g],a(f)&&(f.attr("contenteditable",b?"false":null),d.each(f.getAll("figcaption"),e))}}b.parser.addNodeFilter("figure",c(!0)),b.serializer.addNodeFilter("figure",c(!1))}),b.addButton("image",{icon:"image",tooltip:"Insert/edit image",onclick:h(i),stateSelector:"img:not([data-mce-object],[data-mce-placeholder]),figure.image"}),b.addMenuItem("image",{icon:"image",text:"Image",onclick:h(i),context:"insert",prependToContext:!0}),b.addCommand("mceImage",h(i))}),function(){}}),d("0")()}(); \ No newline at end of file +!function(l){"use strict";var i,e=tinymce.util.Tools.resolve("tinymce.PluginManager"),d=function(e){return!1!==e.settings.image_dimensions},u=function(e){return!0===e.settings.image_advtab},m=function(e){return e.getParam("image_prepend_url","")},n=function(e){return e.getParam("image_class_list")},r=function(e){return!1!==e.settings.image_description},a=function(e){return!0===e.settings.image_title},o=function(e){return!0===e.settings.image_caption},c=function(e){return e.getParam("image_list",!1)},s=function(e){return e.getParam("images_upload_url",!1)},g=function(e){return e.getParam("images_upload_handler",!1)},f=function(e){return e.getParam("images_upload_url")},p=function(e){return e.getParam("images_upload_handler")},h=function(e){return e.getParam("images_upload_base_path")},v=function(e){return e.getParam("images_upload_credentials")},b="undefined"!=typeof l.window?l.window:Function("return this;")(),y=function(e,t){return function(e,t){for(var n=t!==undefined&&null!==t?t:b,r=0;rc?a=c:a0?3*d:d),f=.3086,g=.6094,h=.082,c(b,[f*(1-e)+e,g*(1-e),h*(1-e),0,0,f*(1-e),g*(1-e)+e,h*(1-e),0,0,f*(1-e),g*(1-e),h*(1-e)+e,0,0,0,0,0,1,0,0,0,0,0,1])}function g(b,d){var e,f,g,h,i;return d=a(d,-180,180)/180*Math.PI,e=Math.cos(d),f=Math.sin(d),g=.213,h=.715,i=.072,c(b,[g+e*(1-g)+f*-g,h+e*-h+f*-h,i+e*-i+f*(1-i),0,0,g+e*-g+.143*f,h+e*(1-h)+.14*f,i+e*-i+f*-.283,0,0,g+e*-g+f*-(1-g),h+e*-h+f*h,i+e*(1-i)+f*i,0,0,0,0,0,1,0,0,0,0,0,1])}function h(b,d){return d=a(255*d,-255,255),c(b,[1,0,0,0,d,0,1,0,0,d,0,0,1,0,d,0,0,0,1,0,0,0,0,0,1])}function i(b,d,e,f){return d=a(d,0,2),e=a(e,0,2),f=a(f,0,2),c(b,[d,0,0,0,0,0,e,0,0,0,0,0,f,0,0,0,0,0,1,0,0,0,0,0,1])}function j(b,e){return e=a(e,0,1),c(b,d([.393,.769,.189,0,0,.349,.686,.168,0,0,.272,.534,.131,0,0,0,0,0,1,0,0,0,0,0,1],e))}function k(b,e){return e=a(e,0,1),c(b,d([.33,.34,.33,0,0,.33,.34,.33,0,0,.33,.34,.33,0,0,0,0,0,1,0,0,0,0,0,1],e))}var l=[0,.01,.02,.04,.05,.06,.07,.08,.1,.11,.12,.14,.15,.16,.17,.18,.2,.21,.22,.24,.25,.27,.28,.3,.32,.34,.36,.38,.4,.42,.44,.46,.48,.5,.53,.56,.59,.62,.65,.68,.71,.74,.77,.8,.83,.86,.89,.92,.95,.98,1,1.06,1.12,1.18,1.24,1.3,1.36,1.42,1.48,1.54,1.6,1.66,1.72,1.78,1.84,1.9,1.96,2,2.12,2.25,2.37,2.5,2.62,2.75,2.87,3,3.2,3.4,3.6,3.8,4,4.3,4.7,4.9,5,5.5,6,6.5,6.8,7,7.3,7.5,7.8,8,8.4,8.7,9,9.4,9.6,9.8,10];return{identity:b,adjust:d,multiply:c,adjustContrast:e,adjustBrightness:h,adjustSaturation:f,adjustHue:g,adjustColors:i,adjustSepia:j,adjustGrayscale:k}}),g("e",["q","d","t"],function(a,b,c){function d(c,d){function e(a,b){var c,d,e,f,g,h=a.data,i=b[0],j=b[1],k=b[2],l=b[3],m=b[4],n=b[5],o=b[6],p=b[7],q=b[8],r=b[9],s=b[10],t=b[11],u=b[12],v=b[13],w=b[14],x=b[15],y=b[16],z=b[17],A=b[18],B=b[19];for(g=0;gc?a=c:a2)&&(i=i<.5?.5:2,k=!0),(j<.5||j>2)&&(j=j<.5?.5:2,k=!0);var l=f(a,i,j);return k?l.then(function(a){return e(a,b,c)}):l}function f(b,e,f){return new a(function(a){var g=d.getWidth(b),h=d.getHeight(b),i=Math.floor(g*e),j=Math.floor(h*f),k=c.create(i,j),l=c.get2dContext(k);l.drawImage(b,0,0,g,h,0,0,i,j),a(k)})}return{scale:e}}),g("f",["q","d","u"],function(a,b,c){function d(c,d){var e=c.toCanvas(),f=a.create(e.width,e.height),g=a.get2dContext(f),h=0,i=0;return d=d<0?360+d:d,90!=d&&270!=d||a.resize(f,f.height,f.width),90!=d&&180!=d||(h=f.width),270!=d&&180!=d||(i=f.height),g.translate(h,i),g.rotate(d*Math.PI/180),g.drawImage(e,0,0),b.fromCanvas(f,c.getType())}function e(c,d){var e=c.toCanvas(),f=a.create(e.width,e.height),g=a.get2dContext(f);return"v"==d?(g.scale(1,-1),g.drawImage(e,0,-f.height)):(g.scale(-1,1),g.drawImage(e,-f.width,0)),b.fromCanvas(f,c.getType())}function f(c,d,e,f,g){var h=c.toCanvas(),i=a.create(f,g),j=a.get2dContext(i);return j.drawImage(h,-d,-e),b.fromCanvas(i,c.getType())}function g(a,d,e){return c.scale(a.toCanvas(),d,e).then(function(c){return b.fromCanvas(c,a.getType())})}return{rotate:d,flip:e,crop:f,resize:g}}),g("2",["e","f"],function(a,b){var c=function(b){return a.invert(b)},d=function(b){return a.sharpen(b)},e=function(b){return a.emboss(b)},f=function(b,c){return a.gamma(b,c)},g=function(b,c){return a.exposure(b,c)},h=function(b,c,d,e){return a.colorize(b,c,d,e)},i=function(b,c){return a.brightness(b,c)},j=function(b,c){return a.hue(b,c)},k=function(b,c){return a.saturate(b,c)},l=function(b,c){return a.contrast(b,c)},m=function(b,c){return a.grayscale(b,c)},n=function(b,c){return a.sepia(b,c)},o=function(a,c){return b.flip(a,c)},p=function(a,c,d,e,f){return b.crop(a,c,d,e,f)},q=function(a,c,d){return b.resize(a,c,d)},r=function(a,c){return b.rotate(a,c)};return{invert:c,sharpen:d,emboss:e,brightness:i,hue:j,saturate:k,contrast:l,grayscale:m,sepia:n,colorize:h,gamma:f,exposure:g,flip:o,crop:p,resize:q,rotate:r}}),h("g",tinymce.util.Tools.resolve),g("3",["g"],function(a){return a("tinymce.Env")}),g("4",["g"],function(a){return a("tinymce.PluginManager")}),g("5",["g"],function(a){return a("tinymce.util.Delay")}),g("6",["g"],function(a){return a("tinymce.util.Promise")}),g("7",["g"],function(a){return a("tinymce.util.Tools")}),g("8",["g"],function(a){return a("tinymce.util.URI")}),g("9",[],function(){function a(a){function b(a){return/^[0-9\.]+px$/.test(a)}var c,d;return c=a.style.width,d=a.style.height,c||d?b(c)&&b(d)?{w:parseInt(c,10),h:parseInt(d,10)}:null:(c=a.width,d=a.height,c&&d?{w:parseInt(c,10),h:parseInt(d,10)}:null)}function b(a,b){var c,d;b&&(c=a.style.width,d=a.style.height,(c||d)&&(a.style.width=b.w+"px",a.style.height=b.h+"px",a.removeAttribute("data-mce-style")),c=a.width,d=a.height,(c||d)&&(a.setAttribute("width",b.w),a.setAttribute("height",b.h)))}function c(a){return{w:a.naturalWidth,h:a.naturalHeight}}return{getImageSize:a,setImageSize:b,getNaturalImageSize:c}}),h("12",Array),h("13",Error),g("w",["12","13"],function(a,b){var c=function(){},d=function(a,b){return function(){return a(b.apply(null,arguments))}},e=function(a){return function(){return a}},f=function(a){return a},g=function(a,b){return a===b},h=function(b){for(var c=new a(arguments.length-1),d=1;d-1},h=function(a,b){return t(a,b).isSome()},i=function(a,b){for(var c=[],d=0;d=0;c--){var d=a[c];b(d,c,a)}},n=function(a,b){for(var c=[],d=[],e=0,f=a.length;e=300?c.handleHttpError(b.status):a.resolve(b.blob)})}var f=function(a,b){var c=a.indexOf("?")===-1?"?":"&";return/[?&]apiKey=/.test(a)||!b?a:a+c+"apiKey="+encodeURIComponent(b)},g=function(b,e){return d.requestUrlAsBlob(f(b,e),{"Content-Type":"application/json;charset=UTF-8","tiny-api-key":e}).then(function(b){return b.status<200||b.status>=300?c.handleServiceErrorResponse(b.status,b.blob):a.resolve(b.blob)})},h=function(a,b){return b?g(a,b):e(a)};return{getUrl:h}}),g("j",["g"],function(a){return a("tinymce.dom.DOMUtils")}),g("k",["g"],function(a){return a("tinymce.ui.Container")}),g("l",["g"],function(a){return a("tinymce.ui.Factory")}),g("m",["g"],function(a){return a("tinymce.ui.Form")}),g("x",["g"],function(a){return a("tinymce.geom.Rect")}),g("y",["g"],function(a){return a("tinymce.ui.Control")}),g("z",["g"],function(a){return a("tinymce.ui.DragHelper")}),g("15",["g"],function(a){return a("tinymce.dom.DomQuery")}),g("16",["g"],function(a){return a("tinymce.util.Observable")}),g("17",["g"],function(a){return a("tinymce.util.VK")}),g("10",["15","z","x","7","16","17"],function(a,b,c,d,e,f){var g=0;return function(h,i,j,k,l){function m(a,b){return{x:b.x+a.x,y:b.y+a.y,w:b.w,h:b.h}}function n(a,b){return{x:b.x-a.x,y:b.y-a.y,w:b.w,h:b.h}}function o(){return n(j,h)}function p(a,b,d,e){var f,g,i,k,l;f=b.x,g=b.y,i=b.w,k=b.h,f+=d*a.deltaX,g+=e*a.deltaY,i+=d*a.deltaW,k+=e*a.deltaH,i<20&&(i=20),k<20&&(k=20),l=h=c.clamp({x:f,y:g,w:i,h:k},j,"move"==a.name),l=n(j,l),y.fire("updateRect",{rect:l}),v(l)}function q(){function c(a){var c;return new b(D,{document:k.ownerDocument,handle:D+"-"+a.name,start:function(){c=h},drag:function(b){p(a,c,b.deltaX,b.deltaY)}})}a('
    ').appendTo(k),d.each(B,function(b){a("#"+D,k).append('